[
  {
    "path": ".clang-format",
    "content": "BasedOnStyle: Microsoft\nIndentWidth: 4\nUseTab: ForIndentation\nSortIncludes: false\nColumnLimit: 100\nAlignEscapedNewlines: Left\nAlwaysBreakTemplateDeclarations : Yes\n"
  },
  {
    "path": ".github/actions/setup_optimizers_linux/action.yml",
    "content": "name: \"Install optimizers on linux\"\ndescription: \"Install optimizers and Setup licenses on linux\"\n\ninputs:\n  GUROBI_WLS:\n    description: \"...\"\n    required: false\n    default: ''\n  COPT_CLIENT_INI:\n    description: \"...\"\n    required: false\n    default: ''\n  MOSEK_LICENSE:\n    description: \"...\"\n    required: false\n    default: ''\n  KNITRO_LICENSE:\n    description: \"...\"\n    required: false\n    default: ''\n  GITHUB_TOKEN:\n    description: \"...\"\n    required: true\n  CHECK_LICENSE:\n    description: \"...\"\n    required: true\n  ARCH:\n    description: \"...\"\n    required: true\n    type: choice\n    default: \"X64\"\n    options:\n      - \"X64\"\n      - \"ARM64\"\n\nruns:\n  using: \"composite\"\n  steps:\n    - name: Create directory to store installers\n      shell: bash\n      run: |\n        mkdir -p ~/installers\n\n    - name: Cache Installers\n      id: cache-installers-linux\n      uses: actions/cache@v4\n      env:\n        cache-name: cache-installers-linux\n      with:\n        path: ~/installers\n        key: ${{ runner.os }}-${{ runner.arch }}-build-${{ env.cache-name }}-${{ hashFiles('optimizer_version.toml') }}\n        restore-keys: |\n          ${{ runner.os }}-${{ runner.arch }}-build-${{ env.cache-name }}-\n\n    - if: ${{ (steps.cache-installers-linux.outputs.cache-hit != 'true') && (inputs.ARCH == 'X64') }}\n      shell: bash\n      name: Download X64 Installers\n      run: |\n        curl -L -o ~/installers/gurobi.tar.gz https://packages.gurobi.com/13.0/gurobi13.0.0_linux64.tar.gz\n        curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/8.0.2/linux64/CardinalOptimizer-8.0.2-lnx64.tar.gz\n        curl -L -o ~/installers/mosek.tar.bz2 https://download.mosek.com/stable/10.2.0/mosektoolslinux64x86.tar.bz2\n        curl -L -o ~/installers/idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-ubuntu2204-x86_64.tar.gz\n\n    - if: ${{ (steps.cache-installers-linux.outputs.cache-hit != 'true') && (inputs.ARCH == 'ARM64') }}\n      shell: bash\n      name: Download ARM64 Installers\n      run: |\n        curl -L -o ~/installers/gurobi.tar.gz https://packages.gurobi.com/13.0/gurobi13.0.0_armlinux64.tar.gz\n        curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/8.0.2/aarch64/CardinalOptimizer-8.0.2-aarch64_lnx.tar.gz\n        curl -L -o ~/installers/mosek.tar.bz2 https://download.mosek.com/stable/10.2.0/mosektoolslinuxaarch64.tar.bz2\n        curl -L -o ~/installers/idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-ubuntu2204-aarch64.tar.gz\n\n    - name: Setup Gurobi Installation Home\n      if: ${{ (inputs.ARCH == 'X64') && (inputs.GUROBI_WLS != '') }}\n      shell: bash\n      run: |\n        tar xfz ~/installers/gurobi.tar.gz -C ~/\n        ls ~/gurobi1300/linux64\n        # set environment variables\n        export GUROBI_HOME=\"${HOME}/gurobi1300/linux64\"\n        echo \"GUROBI_HOME=${GUROBI_HOME}\" >> $GITHUB_ENV\n    - name: Setup Gurobi Installation Home\n      if: ${{ (inputs.ARCH == 'ARM64') && (inputs.GUROBI_WLS != '') }}\n      shell: bash\n      run: |\n        tar xfz ~/installers/gurobi.tar.gz -C ~/\n        ls ~/gurobi1300/armlinux64\n        # set environment variables\n        export GUROBI_HOME=\"${HOME}/gurobi1300/armlinux64\"\n        echo \"GUROBI_HOME=${GUROBI_HOME}\" >> $GITHUB_ENV\n    - name: Setup Gurobi Installation\n      if: ${{ inputs.GUROBI_WLS != '' }}\n      shell: bash\n      env:\n        GUROBI_WLS: ${{ inputs.GUROBI_WLS }}\n      run: |\n        echo \"PATH=${PATH}:${GUROBI_HOME}/bin\" >> $GITHUB_ENV\n        echo \"LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${GUROBI_HOME}/lib\" >> $GITHUB_ENV\n        echo $GUROBI_HOME\n\n        # setup license using secrets\n        echo \"$GUROBI_WLS\" > ~/gurobi.lic\n        echo \"GRB_LICENSE_FILE=${HOME}/gurobi.lic\" >> $GITHUB_ENV\n    - name: Test Gurobi\n      if: ${{ (inputs.CHECK_LICENSE == 'true') && (inputs.GUROBI_WLS != '') }}\n      shell: bash\n      run: |\n        gurobi_cl\n\n    - name: Setup COPT Installation\n      shell: bash\n      env:\n        COPT_CLIENT_INI: ${{ inputs.COPT_CLIENT_INI }}\n      run: |\n        tar xfz ~/installers/copt.tar.gz -C ~/\n        ls ~/copt80\n        # set environment variables\n        export COPT_HOME=\"${HOME}/copt80\"\n        echo \"COPT_HOME=${COPT_HOME}\" >> $GITHUB_ENV\n        echo \"PATH=${PATH}:${COPT_HOME}/bin\" >> $GITHUB_ENV\n        echo \"LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${COPT_HOME}/lib\" >> $GITHUB_ENV\n        echo $COPT_HOME\n\n        # Just use the size-limited license\n        # echo \"$COPT_CLIENT_INI\" > ~/client.ini\n        # echo \"COPT_LICENSE_DIR=${HOME}\" >> $GITHUB_ENV\n    - name: Test COPT\n      if: ${{ inputs.CHECK_LICENSE == 'true' }}\n      shell: bash\n      run: |\n        copt_cmd -c \"quit\"\n\n    - name: Setup MOSEK Installation Env\n      if: ${{ (inputs.ARCH == 'X64') && (inputs.MOSEK_LICENSE != '') }}\n      shell: bash\n      run: |\n        tar jxf ~/installers/mosek.tar.bz2 -C ~/\n        ls ~/mosek\n        # set environment variables\n        export MOSEK_10_2_BINDIR=\"${HOME}/mosek/10.2/tools/platform/linux64x86/bin\"\n        echo \"MOSEK_10_2_BINDIR=${MOSEK_10_2_BINDIR}\" >> $GITHUB_ENV\n    - name: Setup MOSEK Installation Env\n      if: ${{ (inputs.ARCH == 'ARM64') && (inputs.MOSEK_LICENSE != '') }}\n      shell: bash\n      run: |\n        tar jxf ~/installers/mosek.tar.bz2 -C ~/\n        ls ~/mosek\n        # set environment variables\n        export MOSEK_10_2_BINDIR=\"${HOME}/mosek/10.2/tools/platform/linuxaarch64/bin\"\n        echo \"MOSEK_10_2_BINDIR=${MOSEK_10_2_BINDIR}\" >> $GITHUB_ENV\n    - name: Setup MOSEK Installation\n      if: ${{ inputs.MOSEK_LICENSE != '' }}\n      shell: bash\n      env:\n        MOSEK_LICENSE: ${{ inputs.MOSEK_LICENSE }}\n      run: |\n        echo \"PATH=${PATH}:${MOSEK_10_2_BINDIR}\" >> $GITHUB_ENV\n        echo \"LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${MOSEK_10_2_BINDIR}\" >> $GITHUB_ENV\n        echo $MOSEK_10_2_BINDIR\n\n        # setup license using secrets\n        echo \"$MOSEK_LICENSE\" > ~/mosek.lic\n        echo \"MOSEKLM_LICENSE_FILE=${HOME}/mosek.lic\" >> $GITHUB_ENV\n    - name: Test MOSEK\n      if: ${{ (inputs.CHECK_LICENSE == 'true') && (inputs.MOSEK_LICENSE != '') }}\n      shell: bash\n      run: |\n        msktestlic\n\n    - name: Setup IPOPT Installation\n      shell: bash\n      run: |\n        sudo apt-get install -y libopenblas-dev liblapack3 libgfortran5\n        mkdir -p ~/ipopt\n        tar xfz ~/installers/idaes-solvers.tar.gz -C ~/ipopt\n        echo \"PATH=${PATH}:${HOME}/ipopt\" >> $GITHUB_ENV\n        echo \"LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${HOME}/ipopt\" >> $GITHUB_ENV\n        ls ~/ipopt\n    - name: Test IPOPT\n      shell: bash\n      run: |\n        ipopt -v\n\n    - name: Setup KNITRO license\n      if: ${{ inputs.KNITRO_LICENSE != '' }}\n      shell: bash\n      env:\n        KNITRO_LICENSE: ${{ inputs.KNITRO_LICENSE }}\n      run: |\n        echo \"$KNITRO_LICENSE\" > ${HOME}/artelys_lic.txt\n        echo \"ARTELYS_LICENSE=${HOME}/artelys_lic.txt\" >> $GITHUB_ENV\n    - name: Install KNITRO (using pip)\n      if: ${{ inputs.KNITRO_LICENSE != '' }}\n      shell: bash\n      run: |\n        python -m pip install knitro\n"
  },
  {
    "path": ".github/actions/setup_optimizers_macos/action.yml",
    "content": "name: \"Install optimizers on macOS\"\ndescription: \"Install optimizers and Setup licenses on macOS\"\n\ninputs:\n  GUROBI_WLS:\n    description: \"...\"\n    required: false\n    default: ''\n  COPT_CLIENT_INI:\n    description: \"...\"\n    required: false\n    default: ''\n  MOSEK_LICENSE:\n    description: \"...\"\n    required: false\n    default: ''\n  KNITRO_LICENSE:\n    description: \"...\"\n    required: false\n    default: ''\n  GITHUB_TOKEN:\n    description: \"...\"\n    required: true\n  CHECK_LICENSE:\n    description: \"...\"\n    required: true\n  ARCH:\n    description: \"...\"\n    required: true\n    type: choice\n    default: \"X64\"\n    options:\n      - \"X64\"\n      - \"ARM64\"\n\nruns:\n  using: \"composite\"\n  steps:\n    - name: Create directory to store installers\n      shell: bash\n      run: |\n        mkdir -p ~/installers\n\n    - name: Cache Installers\n      id: cache-installers-macos\n      uses: actions/cache@v4\n      env:\n        cache-name: cache-installers-macos\n      with:\n        path: ~/installers\n        key: ${{ runner.os }}-${{ runner.arch }}-build-${{ env.cache-name }}-${{ hashFiles('optimizer_version.toml') }}\n        restore-keys: |\n          ${{ runner.os }}-${{ runner.arch }}-build-${{ env.cache-name }}-\n\n    - if: ${{ steps.cache-installers-macos.outputs.cache-hit != 'true' }}\n      shell: bash\n      name: Download Universal Installers\n      run: |\n        curl -L -o ~/installers/gurobi.pkg https://packages.gurobi.com/13.0/gurobi13.0.0_macos_universal2.pkg\n        curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/8.0.2/osx64/CardinalOptimizer-8.0.2-universal_mac.tar.gz\n\n    - if: ${{ (steps.cache-installers-macos.outputs.cache-hit != 'true') && (inputs.ARCH == 'X64') }}\n      shell: bash\n      name: Download X64 Installers\n      run: |\n        curl -L -o ~/installers/mosek.tar.bz2 https://download.mosek.com/stable/10.2.0/mosektoolsosx64x86.tar.bz2\n        curl -L -o ~/installers/idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-darwin-x86_64.tar.gz\n\n    - if: ${{ (steps.cache-installers-macos.outputs.cache-hit != 'true') && (inputs.ARCH == 'ARM64') }}\n      shell: bash\n      name: Download ARM64 Installers\n      run: |\n        curl -L -o ~/installers/mosek.tar.bz2 https://download.mosek.com/stable/10.2.0/mosektoolsosxaarch64.tar.bz2\n        curl -L -o ~/installers/idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-darwin-aarch64.tar.gz\n\n    - name: Setup Gurobi Installation\n      if: ${{ inputs.GUROBI_WLS != '' }}\n      shell: bash\n      env:\n        GUROBI_WLS: ${{ inputs.GUROBI_WLS }}\n      run: |\n        pkgutil --expand-full ~/installers/gurobi.pkg ~/gurobi\n        ls ~/gurobi\n        # set environment variables\n        export GUROBI_HOME=\"${HOME}/gurobi/gurobi13.0.0_macos_universal2.component.pkg/Payload/Library/gurobi1300/macos_universal2\"\n        echo \"GUROBI_HOME=${GUROBI_HOME}\" >> $GITHUB_ENV\n        echo \"PATH=${PATH}:${GUROBI_HOME}/bin\" >> $GITHUB_ENV\n        echo \"DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${GUROBI_HOME}/lib\" >> $GITHUB_ENV\n        echo $GUROBI_HOME\n        ls $GUROBI_HOME\n\n        # setup license using secrets\n        echo \"$GUROBI_WLS\" > ~/gurobi.lic\n        echo \"GRB_LICENSE_FILE=${HOME}/gurobi.lic\" >> $GITHUB_ENV\n    - name: Test Gurobi\n      if: ${{ (inputs.CHECK_LICENSE == 'true') && (inputs.GUROBI_WLS != '') }}\n      shell: bash\n      run: |\n        gurobi_cl\n\n    - name: Setup COPT Installation\n      shell: bash\n      env:\n        COPT_CLIENT_INI: ${{ inputs.COPT_CLIENT_INI }}\n      run: |\n        tar xfz ~/installers/copt.tar.gz -C ~/\n        ls ~/copt80\n        # set environment variables\n        export COPT_HOME=\"${HOME}/copt80\"\n        echo \"COPT_HOME=${COPT_HOME}\" >> $GITHUB_ENV\n        echo \"PATH=${PATH}:${COPT_HOME}/bin\" >> $GITHUB_ENV\n        echo \"DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${COPT_HOME}/lib\" >> $GITHUB_ENV\n        echo $COPT_HOME\n        ls $COPT_HOME\n\n        # Just use the size-limited license\n        # echo \"$COPT_CLIENT_INI\" > ~/client.ini\n        # echo \"COPT_LICENSE_DIR=${HOME}\" >> $GITHUB_ENV\n    - name: Test COPT\n      if: ${{ inputs.CHECK_LICENSE == 'true' }}\n      shell: bash\n      run: |\n        copt_cmd -c \"quit\"\n\n    - name: Setup MOSEK X64 Installation\n      if: ${{ (inputs.ARCH == 'X64') && (inputs.MOSEK_LICENSE != '') }}\n      shell: bash\n      env:\n        MOSEK_LICENSE: ${{ inputs.MOSEK_LICENSE }}\n      run: |\n        tar jxf ~/installers/mosek.tar.bz2 -C ~/\n        ls ~/mosek/10.2/tools/platform\n        # set environment variables\n        export MOSEK_10_2_BINDIR=\"${HOME}/mosek/10.2/tools/platform/osx64x86/bin\"\n        echo \"MOSEK_10_2_BINDIR=${MOSEK_10_2_BINDIR}\" >> $GITHUB_ENV\n        echo \"PATH=${PATH}:${MOSEK_10_2_BINDIR}\" >> $GITHUB_ENV\n        echo \"DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${MOSEK_10_2_BINDIR}\" >> $GITHUB_ENV\n        echo $MOSEK_10_2_BINDIR\n        ls $MOSEK_10_2_BINDIR\n\n        # setup license using secrets\n        echo \"$MOSEK_LICENSE\" > ~/mosek.lic\n        echo \"MOSEKLM_LICENSE_FILE=${HOME}/mosek.lic\" >> $GITHUB_ENV\n    - name: Setup MOSEK ARM64 Installation\n      if: ${{ (inputs.ARCH == 'ARM64') && (inputs.MOSEK_LICENSE != '') }}\n      shell: bash\n      env:\n        MOSEK_LICENSE: ${{ inputs.MOSEK_LICENSE }}\n      run: |\n        tar jxf ~/installers/mosek.tar.bz2 -C ~/\n        ls ~/mosek/10.2/tools/platform\n        # set environment variables\n        export MOSEK_10_2_BINDIR=\"${HOME}/mosek/10.2/tools/platform/osxaarch64/bin\"\n        echo \"MOSEK_10_2_BINDIR=${MOSEK_10_2_BINDIR}\" >> $GITHUB_ENV\n        echo \"PATH=${PATH}:${MOSEK_10_2_BINDIR}\" >> $GITHUB_ENV\n        echo \"DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${MOSEK_10_2_BINDIR}\" >> $GITHUB_ENV\n        echo $MOSEK_10_2_BINDIR\n        ls $MOSEK_10_2_BINDIR\n\n        # setup license using secrets\n        echo \"$MOSEK_LICENSE\" > ~/mosek.lic\n        echo \"MOSEKLM_LICENSE_FILE=${HOME}/mosek.lic\" >> $GITHUB_ENV\n    - name: Test MOSEK\n      if: ${{ (inputs.CHECK_LICENSE == 'true') && (inputs.MOSEK_LICENSE != '') }}\n      shell: bash\n      run: |\n        msktestlic\n\n    - name: Setup IPOPT Installation\n      shell: bash\n      run: |\n        mkdir -p ~/ipopt\n        tar xfz ~/installers/idaes-solvers.tar.gz -C ~/ipopt\n        echo \"PATH=${PATH}:${HOME}/ipopt\" >> $GITHUB_ENV\n        echo \"DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:${HOME}/ipopt\" >> $GITHUB_ENV\n        ls ~/ipopt\n    - name: Test IPOPT\n      shell: bash\n      run: |\n        ipopt -v\n\n    - name: Setup KNITRO License\n      if: ${{ inputs.KNITRO_LICENSE != '' }}\n      shell: bash\n      env:\n        KNITRO_LICENSE: ${{ inputs.KNITRO_LICENSE }}\n      run: |\n        echo \"$KNITRO_LICENSE\" > ~/artelys_lic.txt\n        echo \"ARTELYS_LICENSE=${HOME}/artelys_lic.txt\" >> $GITHUB_ENV\n    - name: Install KNITRO (using pip)\n      if: ${{ inputs.KNITRO_LICENSE != '' }}\n      shell: bash\n      run: |\n        python -m pip install knitro\n"
  },
  {
    "path": ".github/actions/setup_optimizers_windows/action.yml",
    "content": "name: \"Install optimizers on windows\"\ndescription: \"Install optimizers and Setup licenses on windows\"\n\ninputs:\n  GUROBI_WLS:\n    description: \"...\"\n    required: false\n    default: ''\n  COPT_CLIENT_INI:\n    description: \"...\"\n    required: false\n    default: ''\n  MOSEK_LICENSE:\n    description: \"...\"\n    required: false\n    default: ''\n  KNITRO_LICENSE:\n    description: \"...\"\n    required: false\n    default: ''\n  GITHUB_TOKEN:\n    description: \"...\"\n    required: true\n  CHECK_LICENSE:\n    description: \"...\"\n    required: true\n\nruns:\n  using: \"composite\"\n  steps:\n    - name: Install lessmsi\n      shell: pwsh\n      run: |\n        curl -L -o D:\\lessmsi.zip https://github.com/activescott/lessmsi/releases/download/v1.10.0/lessmsi-v1.10.0.zip\n        7z x D:\\lessmsi.zip -oD:\\lessmsi\n        echo \"PATH=$env:PATH;D:\\lessmsi\" >> $env:GITHUB_ENV\n    - name: Test lessmsi\n      shell: pwsh\n      run: |\n        lessmsi h\n\n    - name: Create directory to store installers\n      shell: pwsh\n      run: |\n        New-Item -ItemType Directory -Force -Path \"D:\\installers\"\n\n    - name: Cache Installers\n      id: cache-installers-windows\n      uses: actions/cache@v4\n      env:\n        cache-name: cache-installers-windows\n      with:\n        path: D:\\installers\n        key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('optimizer_version.toml') }}\n        restore-keys: |\n          ${{ runner.os }}-build-${{ env.cache-name }}-\n\n    - if: ${{ steps.cache-installers-windows.outputs.cache-hit != 'true' }}\n      shell: pwsh\n      name: Download Installers\n      run: |\n        curl -L -o D:\\installers\\gurobi.msi https://packages.gurobi.com/13.0/Gurobi-13.0.0-win64.msi\n        curl -L -o D:\\installers\\copt.zip https://pub.shanshu.ai/download/copt/8.0.2/win64/CardinalOptimizer-8.0.2-win64.zip\n        curl -L -o D:\\installers\\mosek.msi https://download.mosek.com/stable/10.2.0/moseksetupwin64x86.msi\n        curl -L -o D:\\installers\\idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-windows-x86_64.tar.gz\n\n    - name: List Installers\n      shell: pwsh\n      run: |\n        Get-ChildItem -Path D:\\installers\n\n    - name: Setup Gurobi Installation\n      if: ${{ inputs.GUROBI_WLS != '' }}\n      shell: pwsh\n      env:\n        GUROBI_WLS: ${{ inputs.GUROBI_WLS }}\n      run: |\n        lessmsi x D:\\installers\\gurobi.msi \"D:\\\" gurobi_cl.exe\n        lessmsi x D:\\installers\\gurobi.msi \"D:\\\" gurobi130.dll gurobi130.lib\n        lessmsi x D:\\installers\\gurobi.msi \"D:\\\" gurobi_c.h\n        ls D:\\SourceDir\\gurobi1300\\win64\n        # set environment variables\n        echo \"GUROBI_HOME=D:\\SourceDir\\gurobi1300\\win64\" >> $env:GITHUB_ENV\n        echo \"PATH=$env:PATH;D:\\SourceDir\\gurobi1300\\win64\\bin\" >> $env:GITHUB_ENV\n        echo $env:GUROBI_HOME\n\n        # setup license using secrets\n        echo $env:GUROBI_WLS > D:\\gurobi.lic\n        echo \"GRB_LICENSE_FILE=D:\\gurobi.lic\" >> $env:GITHUB_ENV\n    - name: Test Gurobi\n      if: ${{ (inputs.CHECK_LICENSE == 'true') && (inputs.GUROBI_WLS != '') }}\n      shell: pwsh\n      run: |\n        gurobi_cl\n\n    - name: Setup COPT Installation\n      shell: pwsh\n      env:\n        COPT_CLIENT_INI: ${{ inputs.COPT_CLIENT_INI }}\n      run: |\n        # unzip with 7zip\n        7z x D:\\installers\\copt.zip -oD:\\\n        ls D:\\copt80\n        # set environment variables\n        echo \"COPT_HOME=D:\\copt80\" >> $env:GITHUB_ENV\n        echo \"PATH=$env:PATH;D:\\copt80\\bin\" >> $env:GITHUB_ENV\n        echo $env:COPT_HOME\n\n        # Just use the size-limited license\n        # echo $env:COPT_CLIENT_INI > D:\\client.ini\n        # echo \"COPT_LICENSE_DIR=D:\\\" >> $env:GITHUB_ENV\n    - name: Test COPT\n      if: ${{ inputs.CHECK_LICENSE == 'true' }}\n      shell: pwsh\n      run: |\n        copt_cmd -c \"quit\"\n\n    - name: Setup MOSEK Installation\n      if: ${{ inputs.MOSEK_LICENSE != '' }}\n      shell: pwsh\n      env:\n        MOSEK_LICENSE: ${{ inputs.MOSEK_LICENSE }}\n      run: |\n        lessmsi x D:\\installers\\mosek.msi \"D:\\\" msktestlic.exe\n        lessmsi x D:\\installers\\mosek.msi \"D:\\\" mosek64_10_2.dll mosek64_10_2.lib tbb12.dll svml_dispmd.dll\n        lessmsi x D:\\installers\\mosek.msi \"D:\\\" mosek.h\n        ls D:\\SourceDir\\PFiles\\Mosek\\10.2\\tools\\platform\\win64x86\n        # set environment variables\n        echo \"MOSEK_10_2_BINDIR=D:\\SourceDir\\PFiles\\Mosek\\10.2\\tools\\platform\\win64x86\\bin\" >> $env:GITHUB_ENV\n        echo \"PATH=$env:PATH;D:\\SourceDir\\PFiles\\Mosek\\10.2\\tools\\platform\\win64x86\\bin\" >> $env:GITHUB_ENV\n        echo $env:MOSEK_10_2_BINDIR\n\n        # setup license using secrets\n        echo $env:MOSEK_LICENSE > D:\\mosek.lic\n        echo \"MOSEKLM_LICENSE_FILE=D:\\mosek.lic\" >> $env:GITHUB_ENV\n    - name: Test MOSEK\n      if: ${{ (inputs.CHECK_LICENSE == 'true') && (inputs.MOSEK_LICENSE != '') }}\n      shell: pwsh\n      run: |\n        msktestlic\n\n    - name: Setup IPOPT solver\n      shell: pwsh\n      run: |\n        7z x -so D:\\installers\\idaes-solvers.tar.gz | 7z x -si -ttar -oD:\\ipopt\n        echo \"PATH=D:\\ipopt;$env:PATH\" >> $env:GITHUB_ENV\n        ls D:\\ipopt\n    - name: Test IPOPT\n      shell: pwsh\n      run: |\n        ipopt -v\n\n    - name: Setup KNITRO License\n      if: ${{ inputs.KNITRO_LICENSE != '' }}\n      shell: pwsh\n      env:\n        KNITRO_LICENSE: ${{ inputs.KNITRO_LICENSE }}\n      run: |\n        # setup license using secrets\n        echo $env:KNITRO_LICENSE > D:\\artelys_lic.txt\n        echo \"ARTELYS_LICENSE=D:\\artelys_lic.txt\" >> $env:GITHUB_ENV\n    - name: Install KNITRO (using pip)\n      if: ${{ inputs.KNITRO_LICENSE != '' }}\n      shell: pwsh\n      run: |\n        python -m pip install knitro\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file\n\nversion: 2\nupdates:\n  - package-ecosystem: \"github-actions\" # See documentation for possible values\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/doc-build.yml",
    "content": "name: gh-pages\n\non:\n  push:\n    branches:\n      - master\n\npermissions:\n  contents: write\n\njobs:\n  doc_build:\n    runs-on: ubuntu-latest\n\n    strategy:\n      fail-fast: true\n      matrix:\n        python-version: [\"3.13\"]\n\n    env:\n      PYTHON_VERSION: ${{ matrix.python-version }}\n\n    steps:\n      - uses: actions/checkout@v6\n      - uses: actions/setup-python@v6\n        with:\n          python-version: ${{ matrix.python-version }}\n          cache: 'pip'\n\n      - uses: ./.github/actions/setup_optimizers_linux\n        with:\n          GUROBI_WLS: ${{ secrets.GUROBI_WLS }}\n          COPT_CLIENT_INI: ${{ secrets.COPT_CLIENT_INI }}\n          MOSEK_LICENSE: ${{ secrets.MOSEK_LICENSE }}\n          KNITRO_LICENSE: ${{ secrets.KNITRO_LICENSE }}\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          CHECK_LICENSE: false\n\n      - name: Build\n        run: |\n          python -m pip list\n          python -m pip install nanobind scikit-build-core[pyproject] typing_extensions\n          python -m pip install --no-build-isolation -v .\n          python -c \"import pyoptinterface as poi; print(dir(poi))\"\n\n      - name: Build documentation\n        run: |\n          pip install -r docs/requirements.txt\n          cd docs\n          make html\n          cd ..\n\n      - name: Deploy\n        uses: JamesIves/github-pages-deploy-action@v4\n        with:\n          folder: docs/build/html\n"
  },
  {
    "path": ".github/workflows/linux-build.yml",
    "content": "name: linux-build\n\non:\n  pull_request:\n  push:\n    branches:\n      - master\n\njobs:\n\n  linux_build:\n    runs-on: ${{ matrix.os }}\n\n    # Only allow one build at a time otherwise we can run out of licenses\n    concurrency:\n      group: linux_build\n\n    strategy:\n      fail-fast: false\n      matrix:\n        os: [ubuntu-latest, ubuntu-24.04-arm]\n        # python-version: [\"3.9\", \"3.10\", \"3.11\", \"3.12\"]\n        python-version: [\"3.13\"]\n\n    env:\n      PYTHON_VERSION: ${{ matrix.python-version }}\n\n    steps:\n      - uses: actions/checkout@v6\n      - uses: actions/setup-python@v6\n        with:\n          python-version: ${{ matrix.python-version }}\n          cache: 'pip'\n\n      - uses: ./.github/actions/setup_optimizers_linux\n        with:\n          GUROBI_WLS: ${{ secrets.GUROBI_WLS }}\n          COPT_CLIENT_INI: ${{ secrets.COPT_CLIENT_INI }}\n          MOSEK_LICENSE: ${{ secrets.MOSEK_LICENSE }}\n          KNITRO_LICENSE: ${{ secrets.KNITRO_LICENSE }}\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          CHECK_LICENSE: true\n          ARCH: ${{ runner.arch }}\n\n      - name: Build\n        run: |\n          python -m pip list\n          python -m pip install nanobind scikit-build-core[pyproject] typing_extensions\n          python -m pip install --no-build-isolation -v .\n          python -c \"import pyoptinterface as poi; print(dir(poi))\"\n          python -m pip wheel -w dist --no-build-isolation .\n\n      - name: Test\n        run: |\n          python -m pip install pytest numpy scipy highsbox llvmlite tccbox\n          python -m pytest tests -v\n\n      - name: Upload artifact\n        uses: actions/upload-artifact@v7\n        with:\n          name: pyoptinterface-wheel-${{ runner.os }}-${{ runner.arch }}-${{ matrix.python-version }}\n          path: dist/\n"
  },
  {
    "path": ".github/workflows/macos-build.yml",
    "content": "name: macos-build\n\non:\n  pull_request:\n  push:\n    branches:\n      - master\n\njobs:\n\n  macos_build:\n    runs-on: ${{ matrix.os }}\n\n    strategy:\n      fail-fast: false\n      matrix:\n        os: [macos-14]\n        # python-version: [\"3.9\", \"3.10\", \"3.11\", \"3.12\"]\n        python-version: [\"3.11\", \"3.13\"]\n\n    env:\n      PYTHON_VERSION: ${{ matrix.python-version }}\n      MACOSX_DEPLOYMENT_TARGET: 10.14\n\n    steps:\n      - uses: actions/checkout@v6\n      - uses: actions/setup-python@v6\n        with:\n          python-version: ${{ matrix.python-version }}\n          cache: 'pip'\n\n      - uses: ./.github/actions/setup_optimizers_macos\n        with:\n          GUROBI_WLS: ${{ secrets.GUROBI_WLS }}\n          COPT_CLIENT_INI: ${{ secrets.COPT_CLIENT_INI }}\n          MOSEK_LICENSE: ${{ secrets.MOSEK_LICENSE }}\n          KNITRO_LICENSE: ${{ secrets.KNITRO_LICENSE }}\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          CHECK_LICENSE: false\n          ARCH: ${{ runner.arch }}\n\n      - name: Build\n        run: |\n          python -m pip list\n          python -m pip install nanobind scikit-build-core[pyproject] typing_extensions\n          python -m pip install --no-build-isolation -v .\n          python -c \"import pyoptinterface as poi; print(dir(poi))\"\n          python -m pip wheel -w dist --no-build-isolation .\n\n      - name: Test\n        run: |\n          python -m pip install pytest numpy scipy highsbox llvmlite tccbox\n          python -m pytest tests -k \"highs or ipopt\" -v\n\n      - name: Upload artifact\n        uses: actions/upload-artifact@v7\n        with:\n          name: pyoptinterface-wheel-${{ runner.os }}-${{ runner.arch }}-${{ matrix.python-version }}\n          path: dist/\n"
  },
  {
    "path": ".github/workflows/wheel.yml",
    "content": "name: cibuildwheel\n\non:\n  workflow_dispatch:\n    inputs:\n      publish:\n        description: 'Publish wheels to PyPI: (testpypi/pypi/none)'\n        required: false\n        type: choice\n        options:\n          - testpypi\n          - pypi\n          - none\n        default: none\n\n\njobs:\n  build_wheels:\n    name: Build wheels on ${{ matrix.os }}\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, macos-latest-large, macos-latest]\n\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Build wheels\n        uses: pypa/cibuildwheel@v3.4.1\n        env:\n          # Select wheels\n          CIBW_BUILD: \"*-manylinux_x86_64 *-manylinux_aarch64 *-win_amd64 *-macosx_x86_64 *-macosx_arm64\"\n          CIBW_SKIP: \"cp38-* cp3??t-*\"\n          CIBW_ARCHS: \"native\"\n          # use manylinux2014\n          CIBW_MANYLINUX_X86_64_IMAGE: \"quay.io/pypa/manylinux2014_x86_64\"\n          CIBW_MANYLINUX_AARCH64_IMAGE: \"quay.io/pypa/manylinux2014_aarch64\"\n          CIBW_ENVIRONMENT_MACOS: >\n            MACOSX_DEPLOYMENT_TARGET=10.14\n          CIBW_TEST_COMMAND: \"python -c \\\"import pyoptinterface as poi; print(dir(poi))\\\"\"\n        with:\n          package-dir: .\n          output-dir: wheelhouse\n          config-file: \"{package}/pyproject.toml\"\n\n      - uses: actions/upload-artifact@v7\n        with:\n          name: cibw-wheels-${{ runner.os }}-${{ runner.arch }}\n          path: ./wheelhouse/*.whl\n\n  publish-to-testpypi:\n    name: Publish Python wheels to TestPyPI\n    needs:\n    - build_wheels\n    runs-on: ubuntu-latest\n    if: github.event.inputs.publish == 'testpypi'\n\n    environment:\n      name: testpypi\n      url: https://test.pypi.org/p/pyoptinterface\n\n    permissions:\n      id-token: write  # IMPORTANT: mandatory for trusted publishing\n\n    steps:\n    - name: Download all the dists\n      uses: actions/download-artifact@v8\n      with:\n        pattern: cibw-wheels-*\n        merge-multiple: true\n        path: dist/\n    - name: List all the dists\n      run: ls -l dist/\n    - name: Publish distribution 📦 to TestPyPI\n      uses: pypa/gh-action-pypi-publish@release/v1\n      with:\n        repository-url: https://test.pypi.org/legacy/\n\n  publish-to-pypi:\n    name: Publish Python wheels to PyPI\n    needs:\n    - build_wheels\n    runs-on: ubuntu-latest\n    if: github.event.inputs.publish == 'pypi'\n\n    environment:\n      name: pypi\n      url: https://pypi.org/project/pyoptinterface/\n\n    permissions:\n      id-token: write  # IMPORTANT: mandatory for trusted publishing\n\n    steps:\n    - name: Download all the dists\n      uses: actions/download-artifact@v8\n      with:\n        pattern: cibw-wheels-*\n        merge-multiple: true\n        path: dist/\n    - name: List all the dists\n      run: ls -l dist/\n    - name: Publish distribution 📦 to PyPI\n      uses: pypa/gh-action-pypi-publish@release/v1\n      with:\n        repository-url: https://upload.pypi.org/legacy/\n"
  },
  {
    "path": ".github/workflows/windows-build.yml",
    "content": "name: windows-build\n\non:\n  pull_request:\n  push:\n    branches:\n      - master\n\njobs:\n\n  windows_build:\n    runs-on: windows-latest\n\n    # Only allow one build at a time otherwise we can run out of licenses\n    concurrency:\n      group: windows_build\n\n    strategy:\n      fail-fast: false\n      matrix:\n        python-version: [\"3.9\", \"3.13\"]\n\n    env:\n      PYTHON_VERSION: ${{ matrix.python-version }}\n\n    steps:\n      - uses: actions/checkout@v6\n      - uses: actions/setup-python@v6\n        with:\n          python-version: ${{ matrix.python-version }}\n          cache: 'pip'\n\n      - uses: ./.github/actions/setup_optimizers_windows\n        with:\n          GUROBI_WLS: ${{ secrets.GUROBI_WLS }}\n          COPT_CLIENT_INI: ${{ secrets.COPT_CLIENT_INI }}\n          MOSEK_LICENSE: ${{ secrets.MOSEK_LICENSE }}\n          KNITRO_LICENSE: ${{ secrets.KNITRO_LICENSE }}\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          CHECK_LICENSE: true\n\n      - name: Build\n        run: |\n          python -m pip list\n          python -m pip install nanobind scikit-build-core[pyproject] typing_extensions\n          python -m pip install --no-build-isolation -v .\n          python -c \"import pyoptinterface as poi; print(dir(poi))\"\n          python -m pip wheel -w dist --no-build-isolation .\n\n      - name: Test\n        run: |\n          python -m pip install pytest numpy scipy highsbox llvmlite tccbox\n          python -m pytest tests -v\n\n      - name: Upload artifact\n        uses: actions/upload-artifact@v7\n        with:\n          name: pyoptinterface-wheel-${{ runner.os }}-${{ runner.arch }}-${{ matrix.python-version }}\n          path: dist/\n"
  },
  {
    "path": ".gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\nbuild/\n.pytest_cache/\n.mypy_cache/\ndist/\n\n.idea/\n.vscode/\n.claude/\n\nbench/local\ndebug/\n\ndocs/jupyter_execute\ndocs/build\n\n*.lp\n*.sol"
  },
  {
    "path": ".pre-commit-config.yaml",
    "content": "repos:\n  # C++ 格式化 - clang-format\n  - repo: https://github.com/pre-commit/mirrors-clang-format\n    rev: v22.1.1\n    hooks:\n      - id: clang-format\n        types_or: [c++, c]\n        files: \\.(cpp|hpp|c|h|cc|cxx|hxx)$\n        exclude: ^thirdparty/\n\n  # Python 格式化 - black\n  - repo: https://github.com/psf/black\n    rev: 26.3.1\n    hooks:\n      - id: black\n        language_version: python3\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15...3.27)\n\nproject(pyoptinterface)\n\nset(CMAKE_CXX_STANDARD 20)\n# Linux: -fPIC\nset(CMAKE_POSITION_INDEPENDENT_CODE ON)\n\n# we need to ensure all shared libraries can look up its own directory to load other shared libraries\n# this is very important for CppAD users because we extract its thread_alloc as a shared library\nfunction(set_rpath target)\n    if(APPLE)\n        set(CMAKE_MACOSX_RPATH 1)\n        set_target_properties(${target} PROPERTIES INSTALL_RPATH \"@loader_path\")\n    elseif(UNIX)\n        set_target_properties(${target} PROPERTIES INSTALL_RPATH \"$ORIGIN\")\n    elseif(WIN32)\n    endif()\nendfunction()\n\nif(MSVC)\n    # Add /MP flag for multi-processor compilation\n    add_compile_options(/MP)\n    add_compile_options(/utf-8)\n    if(CMAKE_SYSTEM_PROCESSOR MATCHES \"AMD64\")\n        # use AVX2\n        add_compile_options(/arch:AVX2)\n    endif()\nendif()\n\nif(CMAKE_CXX_COMPILER_ID MATCHES \"GNU|Clang\")\n    if(CMAKE_SYSTEM_PROCESSOR MATCHES \"x86_64\")\n        # add_compile_options(-march=haswell)\n    endif()\nendif()\n\nadd_subdirectory(thirdparty/fmt)\nadd_subdirectory(thirdparty/cppad)\n\nset(POI_INSTALL_DIR ${SKBUILD_PLATLIB_DIR}/pyoptinterface/_src)\n\nadd_library(core STATIC)\ntarget_sources(core PRIVATE\n  include/pyoptinterface/cache_model.hpp\n  include/pyoptinterface/core.hpp\n  include/pyoptinterface/container.hpp\n  include/pyoptinterface/dylib.hpp\n  include/pyoptinterface/solver_common.hpp\n  lib/cache_model.cpp\n  lib/core.cpp\n)\ntarget_include_directories(core PUBLIC include thirdparty)\ntarget_link_libraries(core PUBLIC fmt)\n\nadd_library(nlexpr STATIC)\ntarget_sources(nlexpr PRIVATE\n  include/pyoptinterface/nlexpr.hpp\n  lib/nlexpr.cpp\n)\ntarget_include_directories(nlexpr PUBLIC include thirdparty)\ntarget_link_libraries(nlexpr PUBLIC core)\n\nadd_library(nleval STATIC)\ntarget_sources(nleval PRIVATE\n  include/pyoptinterface/nleval.hpp\n  lib/nleval.cpp\n)\ntarget_link_libraries(nleval PUBLIC nlexpr core)\n\nadd_library(cppad_interface STATIC)\ntarget_sources(cppad_interface PRIVATE\n  include/pyoptinterface/cppad_interface.hpp\n  lib/cppad_interface.cpp\n)\ntarget_include_directories(cppad_interface PUBLIC include thirdparty)\ntarget_link_libraries(cppad_interface PUBLIC nlexpr cppad)\n\nadd_library(tcc_interface STATIC)\ntarget_sources(tcc_interface PRIVATE\n  include/pyoptinterface/tcc_interface.hpp\n  lib/tcc_interface.cpp\n)\ntarget_include_directories(tcc_interface PUBLIC include thirdparty)\ntarget_link_libraries(tcc_interface PUBLIC fmt)\n\n# Build Python extensions\nfind_package(Python ${PYTHON_VERSION}\n  REQUIRED COMPONENTS Interpreter Development.Module\n  OPTIONAL_COMPONENTS Development.SABIModule)\n\n# Import nanobind through CMake's find_package mechanism\nfind_package(nanobind CONFIG REQUIRED)\n\nnanobind_add_module(\n  core_ext\n\n  STABLE_ABI NB_STATIC NB_DOMAIN pyoptinterface\n\n  lib/core_ext.cpp\n)\ntarget_link_libraries(core_ext PUBLIC core)\ninstall(TARGETS core_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})\n\nnanobind_add_module(\n  nlexpr_ext\n\n  STABLE_ABI NB_STATIC NB_DOMAIN pyoptinterface\n\n  lib/nlexpr_ext.cpp\n)\ntarget_link_libraries(nlexpr_ext PUBLIC nlexpr)\ninstall(TARGETS nlexpr_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})\n\nnanobind_add_module(\n  nleval_ext\n\n  STABLE_ABI NB_STATIC NB_DOMAIN pyoptinterface\n\n  lib/nleval_ext.cpp\n)\ntarget_link_libraries(nleval_ext PUBLIC nleval)\ninstall(TARGETS nleval_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})\n\nnanobind_add_module(\n  cppad_interface_ext\n\n  STABLE_ABI NB_STATIC NB_DOMAIN pyoptinterface\n\n  lib/cppad_interface_ext.cpp\n)\ntarget_link_libraries(cppad_interface_ext PUBLIC cppad_interface)\ninstall(TARGETS cppad_interface_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})\n\nnanobind_add_module(\n  tcc_interface_ext\n\n  STABLE_ABI NB_STATIC NB_DOMAIN pyoptinterface\n\n  lib/tcc_interface_ext.cpp\n)\ntarget_link_libraries(tcc_interface_ext PUBLIC tcc_interface)\ninstall(TARGETS tcc_interface_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})\n\n# Solvers\n\n# Gurobi\nadd_library(gurobi_model STATIC)\ntarget_sources(gurobi_model PRIVATE\n  include/pyoptinterface/gurobi_model.hpp\n  lib/gurobi_model.cpp\n)\ntarget_link_libraries(gurobi_model PUBLIC core nlexpr)\n\nnanobind_add_module(\n  gurobi_model_ext\n\n  STABLE_ABI NB_STATIC NB_DOMAIN pyoptinterface\n\n  lib/gurobi_model_ext.cpp\n  lib/gurobi_model_ext_constants.cpp\n)\ntarget_link_libraries(gurobi_model_ext PUBLIC gurobi_model)\ninstall(TARGETS gurobi_model_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})\n\n# COPT\nadd_library(copt_model STATIC)\ntarget_sources(copt_model PRIVATE\n  include/pyoptinterface/copt_model.hpp\n  lib/copt_model.cpp\n)\ntarget_link_libraries(copt_model PUBLIC core nlexpr)\n\nnanobind_add_module(\n  copt_model_ext\n\n  STABLE_ABI NB_STATIC NB_DOMAIN pyoptinterface\n\n  lib/copt_model_ext.cpp\n  lib/copt_model_ext_constants.cpp\n)\ntarget_link_libraries(copt_model_ext PUBLIC copt_model)\ninstall(TARGETS copt_model_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})\n\n# MOSEK\nadd_library(mosek_model STATIC)\ntarget_sources(mosek_model PRIVATE\n  include/pyoptinterface/mosek_model.hpp\n  lib/mosek_model.cpp\n)\ntarget_link_libraries(mosek_model PUBLIC core)\n\nnanobind_add_module(\n  mosek_model_ext\n\n  STABLE_ABI NB_STATIC NB_DOMAIN pyoptinterface\n\n  lib/mosek_model_ext.cpp\n  lib/mosek_model_ext_constants.cpp\n)\ntarget_link_libraries(mosek_model_ext PUBLIC mosek_model)\ninstall(TARGETS mosek_model_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})\n\n# HiGHS\nadd_library(highs_model STATIC)\ntarget_sources(highs_model PRIVATE\n  include/pyoptinterface/highs_model.hpp\n  lib/highs_model.cpp\n)\ntarget_include_directories(highs_model PUBLIC thirdparty/solvers/highs)\ntarget_link_libraries(highs_model PUBLIC core)\n# target_link_libraries(highs_model PUBLIC HiGHS::HiGHS)\n\nnanobind_add_module(\n  highs_model_ext\n\n  STABLE_ABI NB_STATIC NB_DOMAIN pyoptinterface\n\n  lib/highs_model_ext.cpp\n  lib/highs_model_ext_constants.cpp\n)\ntarget_link_libraries(highs_model_ext PUBLIC highs_model)\ninstall(TARGETS highs_model_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})\n\n# IPOPT\nadd_library(ipopt_model STATIC)\ntarget_sources(ipopt_model PRIVATE\n  include/pyoptinterface/ipopt_model.hpp\n  lib/ipopt_model.cpp\n)\ntarget_link_libraries(ipopt_model PUBLIC nlexpr nleval)\n\nnanobind_add_module(\n  ipopt_model_ext\n\n  STABLE_ABI NB_STATIC NB_DOMAIN pyoptinterface\n\n  lib/ipopt_model_ext.cpp\n)\ntarget_link_libraries(ipopt_model_ext PUBLIC ipopt_model)\ninstall(TARGETS ipopt_model_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})\n\n# XPRESS\nadd_library(xpress_model STATIC)\ntarget_sources(xpress_model PRIVATE\n    include/pyoptinterface/xpress_model.hpp\n    lib/xpress_model.cpp\n)\ntarget_link_libraries(xpress_model PUBLIC core nlexpr)\n\nnanobind_add_module(\n    xpress_model_ext\n\n    STABLE_ABI NB_STATIC NB_DOMAIN pyoptinterface\n\n    lib/xpress_model_ext.cpp\n    lib/xpress_model_ext_constants.cpp\n)\ntarget_link_libraries(xpress_model_ext PUBLIC xpress_model)\ninstall(TARGETS xpress_model_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})\n\nif(DEFINED ENV{XPRESSDIR})\n    message(STATUS \"Detected Xpress header file: $ENV{XPRESSDIR}/include\")\n    target_include_directories(xpress_model PRIVATE $ENV{XPRESSDIR}/include)\n    target_include_directories(xpress_model_ext PRIVATE $ENV{XPRESSDIR}/include)\nendif()\n\n# KNITRO\nadd_library(knitro_model STATIC)\ntarget_sources(knitro_model PRIVATE\n    include/pyoptinterface/knitro_model.hpp\n    lib/knitro_model.cpp\n)\ntarget_link_libraries(knitro_model PUBLIC core cppad_interface)\n\nnanobind_add_module(\n    knitro_model_ext\n\n    STABLE_ABI NB_STATIC NB_DOMAIN pyoptinterface\n\n    lib/knitro_model_ext.cpp\n    lib/knitro_model_ext_constants.cpp\n)\ntarget_link_libraries(knitro_model_ext PUBLIC knitro_model)\ninstall(TARGETS knitro_model_ext LIBRARY DESTINATION ${POI_INSTALL_DIR})\n\n# stub\nnanobind_add_stub(\n  core_ext_stub\n  INSTALL_TIME\n  MODULE pyoptinterface._src.core_ext\n  OUTPUT ${POI_INSTALL_DIR}/core_ext.pyi\n)\n\nnanobind_add_stub(\n  nlexpr_ext_stub\n  INSTALL_TIME\n  MODULE pyoptinterface._src.nlexpr_ext\n  OUTPUT ${POI_INSTALL_DIR}/nlexpr_ext.pyi\n)\n\nnanobind_add_stub(\n  nleval_ext_stub\n  INSTALL_TIME\n  MODULE pyoptinterface._src.nleval_ext\n  OUTPUT ${POI_INSTALL_DIR}/nleval_ext.pyi\n)\n\nnanobind_add_stub(\n  cppad_interface_ext_stub\n  INSTALL_TIME\n  MODULE pyoptinterface._src.cppad_interface_ext\n  OUTPUT ${POI_INSTALL_DIR}/cppad_interface_ext.pyi\n)\n\nnanobind_add_stub(\n  tcc_interface_ext_stub\n  INSTALL_TIME\n  MODULE pyoptinterface._src.tcc_interface_ext\n  OUTPUT ${POI_INSTALL_DIR}/tcc_interface_ext.pyi\n)\n\nnanobind_add_stub(\n  gurobi_model_ext_stub\n  INSTALL_TIME\n  MODULE pyoptinterface._src.gurobi_model_ext\n  OUTPUT ${POI_INSTALL_DIR}/gurobi_model_ext.pyi\n)\n\nnanobind_add_stub(\n  copt_model_ext_stub\n  INSTALL_TIME\n  MODULE pyoptinterface._src.copt_model_ext\n  OUTPUT ${POI_INSTALL_DIR}/copt_model_ext.pyi\n)\n\nnanobind_add_stub(\n  mosek_model_ext_stub\n  INSTALL_TIME\n  MODULE pyoptinterface._src.mosek_model_ext\n  OUTPUT ${POI_INSTALL_DIR}/mosek_model_ext.pyi\n)\n\nnanobind_add_stub(\n  highs_model_ext_stub\n  INSTALL_TIME\n  MODULE pyoptinterface._src.highs_model_ext\n  OUTPUT ${POI_INSTALL_DIR}/highs_model_ext.pyi\n)\n\nnanobind_add_stub(\n  ipopt_model_ext_stub\n  INSTALL_TIME\n  MODULE pyoptinterface._src.ipopt_model_ext\n  OUTPUT ${POI_INSTALL_DIR}/ipopt_model_ext.pyi\n)\n\nnanobind_add_stub(\n  xpress_model_ext_stub\n  INSTALL_TIME\n  MODULE pyoptinterface._src.xpress_model_ext\n  OUTPUT ${POI_INSTALL_DIR}/xpress_model_ext.pyi\n)\n\nnanobind_add_stub(\n  knitro_model_ext_stub\n  INSTALL_TIME\n  MODULE pyoptinterface._src.knitro_model_ext\n  OUTPUT ${POI_INSTALL_DIR}/knitro_model_ext.pyi\n)\n\nset(ENABLE_TEST_MAIN OFF BOOL \"Enable test c++ function with a main.cpp\")\nif(ENABLE_TEST_MAIN)\n    add_executable(test_main lib/main.cpp)\n    target_link_libraries(test_main PUBLIC core nleval cppad_interface)\nendif()\n"
  },
  {
    "path": "GEMINI.md",
    "content": "# PyOptInterface Modeling Guidelines\n\nWhen modeling with `pyoptinterface_native`, adhere to these patterns.\n\n## Solver Initialization\n- Use `pyoptinterface.<solver>.Model()`. Supported: `highs`, `gurobi`, `copt`, `ipopt`, `knitro`, `mosek`, `xpress`.\n- For Gurobi, you can manage environments with `poi.gurobi.Env()`.\n\n## Variables\n- `model.add_variable(lb=None, ub=None, domain=poi.VariableDomain.Continuous, name=\"\", start=None)`\n- `model.add_m_variables(shape, ...)` returns a NumPy array of variables.\n\n## Constraints\n- Linear: `model.add_linear_constraint(expr, sense, rhs)` or `model.add_linear_constraint(lhs <= rhs)`.\n- Quadratic: `model.add_quadratic_constraint(expr, sense, rhs)`.\n- Matrix: `model.add_m_linear_constraints(A, x, sense, b)`.\n- Nonlinear: Wrap in `with nl.graph():` and use `model.add_nl_constraint(expr)`.\n\n## Objective\n- `model.set_objective(expr, sense)`.\n- Nonlinear: `with nl.graph(): model.add_nl_objective(expr, sense)`.\n\n## Attributes\n- Get: `model.get_model_attribute(poi.ModelAttribute.TerminationStatus)`.\n- Set: `model.set_variable_attribute(v, poi.VariableAttribute.LowerBound, 0.0)`.\n- Results: `model.get_variable_attribute(v, poi.VariableAttribute.Value)`.\n\n## Common Utilities\n- `poi.quicksum(terms)`: Efficiently sum variables/expressions.\n- `poi.Eq`, `poi.Leq`, `poi.Geq`: Aliases for constraint senses.\n"
  },
  {
    "path": "LICENSE.md",
    "content": "Copyright (c) 2023: Yue Yang\n\nThe PyOptInterface is licensed under the **[MPL]** version 2.0:\n\n[MPL]: https://www.mozilla.org/MPL/2.0/\n\n    Mozilla Public License Version 2.0\n    ==================================\n\n    1. Definitions\n    --------------\n\n    1.1. \"Contributor\"\n        means each individual or legal entity that creates, contributes to\n        the creation of, or owns Covered Software.\n\n    1.2. \"Contributor Version\"\n        means the combination of the Contributions of others (if any) used\n        by a Contributor and that particular Contributor's Contribution.\n\n    1.3. \"Contribution\"\n        means Covered Software of a particular Contributor.\n\n    1.4. \"Covered Software\"\n        means Source Code Form to which the initial Contributor has attached\n        the notice in Exhibit A, the Executable Form of such Source Code\n        Form, and Modifications of such Source Code Form, in each case\n        including portions thereof.\n\n    1.5. \"Incompatible With Secondary Licenses\"\n        means\n\n        (a) that the initial Contributor has attached the notice described\n            in Exhibit B to the Covered Software; or\n\n        (b) that the Covered Software was made available under the terms of\n            version 1.1 or earlier of the License, but not also under the\n            terms of a Secondary License.\n\n    1.6. \"Executable Form\"\n        means any form of the work other than Source Code Form.\n\n    1.7. \"Larger Work\"\n        means a work that combines Covered Software with other material, in \n        a separate file or files, that is not Covered Software.\n\n    1.8. \"License\"\n        means this document.\n\n    1.9. \"Licensable\"\n        means having the right to grant, to the maximum extent possible,\n        whether at the time of the initial grant or subsequently, any and\n        all of the rights conveyed by this License.\n\n    1.10. \"Modifications\"\n        means any of the following:\n\n        (a) any file in Source Code Form that results from an addition to,\n            deletion from, or modification of the contents of Covered\n            Software; or\n\n        (b) any new file in Source Code Form that contains any Covered\n            Software.\n\n    1.11. \"Patent Claims\" of a Contributor\n        means any patent claim(s), including without limitation, method,\n        process, and apparatus claims, in any patent Licensable by such\n        Contributor that would be infringed, but for the grant of the\n        License, by the making, using, selling, offering for sale, having\n        made, import, or transfer of either its Contributions or its\n        Contributor Version.\n\n    1.12. \"Secondary License\"\n        means either the GNU General Public License, Version 2.0, the GNU\n        Lesser General Public License, Version 2.1, the GNU Affero General\n        Public License, Version 3.0, or any later versions of those\n        licenses.\n\n    1.13. \"Source Code Form\"\n        means the form of the work preferred for making modifications.\n\n    1.14. \"You\" (or \"Your\")\n        means an individual or a legal entity exercising rights under this\n        License. For legal entities, \"You\" includes any entity that\n        controls, is controlled by, or is under common control with You. For\n        purposes of this definition, \"control\" means (a) the power, direct\n        or indirect, to cause the direction or management of such entity,\n        whether by contract or otherwise, or (b) ownership of more than\n        fifty percent (50%) of the outstanding shares or beneficial\n        ownership of such entity.\n\n    2. License Grants and Conditions\n    --------------------------------\n\n    2.1. Grants\n\n    Each Contributor hereby grants You a world-wide, royalty-free,\n    non-exclusive license:\n\n    (a) under intellectual property rights (other than patent or trademark)\n        Licensable by such Contributor to use, reproduce, make available,\n        modify, display, perform, distribute, and otherwise exploit its\n        Contributions, either on an unmodified basis, with Modifications, or\n        as part of a Larger Work; and\n\n    (b) under Patent Claims of such Contributor to make, use, sell, offer\n        for sale, have made, import, and otherwise transfer either its\n        Contributions or its Contributor Version.\n\n    2.2. Effective Date\n\n    The licenses granted in Section 2.1 with respect to any Contribution\n    become effective for each Contribution on the date the Contributor first\n    distributes such Contribution.\n\n    2.3. Limitations on Grant Scope\n\n    The licenses granted in this Section 2 are the only rights granted under\n    this License. No additional rights or licenses will be implied from the\n    distribution or licensing of Covered Software under this License.\n    Notwithstanding Section 2.1(b) above, no patent license is granted by a\n    Contributor:\n\n    (a) for any code that a Contributor has removed from Covered Software;\n        or\n\n    (b) for infringements caused by: (i) Your and any other third party's\n        modifications of Covered Software, or (ii) the combination of its\n        Contributions with other software (except as part of its Contributor\n        Version); or\n\n    (c) under Patent Claims infringed by Covered Software in the absence of\n        its Contributions.\n\n    This License does not grant any rights in the trademarks, service marks,\n    or logos of any Contributor (except as may be necessary to comply with\n    the notice requirements in Section 3.4).\n\n    2.4. Subsequent Licenses\n\n    No Contributor makes additional grants as a result of Your choice to\n    distribute the Covered Software under a subsequent version of this\n    License (see Section 10.2) or under the terms of a Secondary License (if\n    permitted under the terms of Section 3.3).\n\n    2.5. Representation\n\n    Each Contributor represents that the Contributor believes its\n    Contributions are its original creation(s) or it has sufficient rights\n    to grant the rights to its Contributions conveyed by this License.\n\n    2.6. Fair Use\n\n    This License is not intended to limit any rights You have under\n    applicable copyright doctrines of fair use, fair dealing, or other\n    equivalents.\n\n    2.7. Conditions\n\n    Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted\n    in Section 2.1.\n\n    3. Responsibilities\n    -------------------\n\n    3.1. Distribution of Source Form\n\n    All distribution of Covered Software in Source Code Form, including any\n    Modifications that You create or to which You contribute, must be under\n    the terms of this License. You must inform recipients that the Source\n    Code Form of the Covered Software is governed by the terms of this\n    License, and how they can obtain a copy of this License. You may not\n    attempt to alter or restrict the recipients' rights in the Source Code\n    Form.\n\n    3.2. Distribution of Executable Form\n\n    If You distribute Covered Software in Executable Form then:\n\n    (a) such Covered Software must also be made available in Source Code\n        Form, as described in Section 3.1, and You must inform recipients of\n        the Executable Form how they can obtain a copy of such Source Code\n        Form by reasonable means in a timely manner, at a charge no more\n        than the cost of distribution to the recipient; and\n\n    (b) You may distribute such Executable Form under the terms of this\n        License, or sublicense it under different terms, provided that the\n        license for the Executable Form does not attempt to limit or alter\n        the recipients' rights in the Source Code Form under this License.\n\n    3.3. Distribution of a Larger Work\n\n    You may create and distribute a Larger Work under terms of Your choice,\n    provided that You also comply with the requirements of this License for\n    the Covered Software. If the Larger Work is a combination of Covered\n    Software with a work governed by one or more Secondary Licenses, and the\n    Covered Software is not Incompatible With Secondary Licenses, this\n    License permits You to additionally distribute such Covered Software\n    under the terms of such Secondary License(s), so that the recipient of\n    the Larger Work may, at their option, further distribute the Covered\n    Software under the terms of either this License or such Secondary\n    License(s).\n\n    3.4. Notices\n\n    You may not remove or alter the substance of any license notices\n    (including copyright notices, patent notices, disclaimers of warranty,\n    or limitations of liability) contained within the Source Code Form of\n    the Covered Software, except that You may alter any license notices to\n    the extent required to remedy known factual inaccuracies.\n\n    3.5. Application of Additional Terms\n\n    You may choose to offer, and to charge a fee for, warranty, support,\n    indemnity or liability obligations to one or more recipients of Covered\n    Software. However, You may do so only on Your own behalf, and not on\n    behalf of any Contributor. You must make it absolutely clear that any\n    such warranty, support, indemnity, or liability obligation is offered by\n    You alone, and You hereby agree to indemnify every Contributor for any\n    liability incurred by such Contributor as a result of warranty, support,\n    indemnity or liability terms You offer. You may include additional\n    disclaimers of warranty and limitations of liability specific to any\n    jurisdiction.\n\n    4. Inability to Comply Due to Statute or Regulation\n    ---------------------------------------------------\n\n    If it is impossible for You to comply with any of the terms of this\n    License with respect to some or all of the Covered Software due to\n    statute, judicial order, or regulation then You must: (a) comply with\n    the terms of this License to the maximum extent possible; and (b)\n    describe the limitations and the code they affect. Such description must\n    be placed in a text file included with all distributions of the Covered\n    Software under this License. Except to the extent prohibited by statute\n    or regulation, such description must be sufficiently detailed for a\n    recipient of ordinary skill to be able to understand it.\n\n    5. Termination\n    --------------\n\n    5.1. The rights granted under this License will terminate automatically\n    if You fail to comply with any of its terms. However, if You become\n    compliant, then the rights granted under this License from a particular\n    Contributor are reinstated (a) provisionally, unless and until such\n    Contributor explicitly and finally terminates Your grants, and (b) on an\n    ongoing basis, if such Contributor fails to notify You of the\n    non-compliance by some reasonable means prior to 60 days after You have\n    come back into compliance. Moreover, Your grants from a particular\n    Contributor are reinstated on an ongoing basis if such Contributor\n    notifies You of the non-compliance by some reasonable means, this is the\n    first time You have received notice of non-compliance with this License\n    from such Contributor, and You become compliant prior to 30 days after\n    Your receipt of the notice.\n\n    5.2. If You initiate litigation against any entity by asserting a patent\n    infringement claim (excluding declaratory judgment actions,\n    counter-claims, and cross-claims) alleging that a Contributor Version\n    directly or indirectly infringes any patent, then the rights granted to\n    You by any and all Contributors for the Covered Software under Section\n    2.1 of this License shall terminate.\n\n    5.3. In the event of termination under Sections 5.1 or 5.2 above, all\n    end user license agreements (excluding distributors and resellers) which\n    have been validly granted by You or Your distributors under this License\n    prior to termination shall survive termination.\n\n    ************************************************************************\n    *                                                                      *\n    *  6. Disclaimer of Warranty                                           *\n    *  -------------------------                                           *\n    *                                                                      *\n    *  Covered Software is provided under this License on an \"as is\"       *\n    *  basis, without warranty of any kind, either expressed, implied, or  *\n    *  statutory, including, without limitation, warranties that the       *\n    *  Covered Software is free of defects, merchantable, fit for a        *\n    *  particular purpose or non-infringing. The entire risk as to the     *\n    *  quality and performance of the Covered Software is with You.        *\n    *  Should any Covered Software prove defective in any respect, You     *\n    *  (not any Contributor) assume the cost of any necessary servicing,   *\n    *  repair, or correction. This disclaimer of warranty constitutes an   *\n    *  essential part of this License. No use of any Covered Software is   *\n    *  authorized under this License except under this disclaimer.         *\n    *                                                                      *\n    ************************************************************************\n\n    ************************************************************************\n    *                                                                      *\n    *  7. Limitation of Liability                                          *\n    *  --------------------------                                          *\n    *                                                                      *\n    *  Under no circumstances and under no legal theory, whether tort      *\n    *  (including negligence), contract, or otherwise, shall any           *\n    *  Contributor, or anyone who distributes Covered Software as          *\n    *  permitted above, be liable to You for any direct, indirect,         *\n    *  special, incidental, or consequential damages of any character      *\n    *  including, without limitation, damages for lost profits, loss of    *\n    *  goodwill, work stoppage, computer failure or malfunction, or any    *\n    *  and all other commercial damages or losses, even if such party      *\n    *  shall have been informed of the possibility of such damages. This   *\n    *  limitation of liability shall not apply to liability for death or   *\n    *  personal injury resulting from such party's negligence to the       *\n    *  extent applicable law prohibits such limitation. Some               *\n    *  jurisdictions do not allow the exclusion or limitation of           *\n    *  incidental or consequential damages, so this exclusion and          *\n    *  limitation may not apply to You.                                    *\n    *                                                                      *\n    ************************************************************************\n\n    8. Litigation\n    -------------\n\n    Any litigation relating to this License may be brought only in the\n    courts of a jurisdiction where the defendant maintains its principal\n    place of business and such litigation shall be governed by laws of that\n    jurisdiction, without reference to its conflict-of-law provisions.\n    Nothing in this Section shall prevent a party's ability to bring\n    cross-claims or counter-claims.\n\n    9. Miscellaneous\n    ----------------\n\n    This License represents the complete agreement concerning the subject\n    matter hereof. If any provision of this License is held to be\n    unenforceable, such provision shall be reformed only to the extent\n    necessary to make it enforceable. Any law or regulation which provides\n    that the language of a contract shall be construed against the drafter\n    shall not be used to construe this License against a Contributor.\n\n    10. Versions of the License\n    ---------------------------\n\n    10.1. New Versions\n\n    Mozilla Foundation is the license steward. Except as provided in Section\n    10.3, no one other than the license steward has the right to modify or\n    publish new versions of this License. Each version will be given a\n    distinguishing version number.\n\n    10.2. Effect of New Versions\n\n    You may distribute the Covered Software under the terms of the version\n    of the License under which You originally received the Covered Software,\n    or under the terms of any subsequent version published by the license\n    steward.\n\n    10.3. Modified Versions\n\n    If you create software not governed by this License, and you want to\n    create a new license for such software, you may create and use a\n    modified version of this License if you rename the license and remove\n    any references to the name of the license steward (except to note that\n    such modified license differs from this License).\n\n    10.4. Distributing Source Code Form that is Incompatible With Secondary\n    Licenses\n\n    If You choose to distribute Source Code Form that is Incompatible With\n    Secondary Licenses under the terms of this version of the License, the\n    notice described in Exhibit B of this License must be attached.\n\n    Exhibit A - Source Code Form License Notice\n    -------------------------------------------\n\n      This Source Code Form is subject to the terms of the Mozilla Public\n      License, v. 2.0. If a copy of the MPL was not distributed with this\n      file, You can obtain one at https://mozilla.org/MPL/2.0/.\n\n    If it is not possible or desirable to put the notice in a particular\n    file, then You may include the notice in a location (such as a LICENSE\n    file in a relevant directory) where a recipient would be likely to look\n    for such a notice.\n\n    You may add additional accurate notices of copyright ownership.\n\n    Exhibit B - \"Incompatible With Secondary Licenses\" Notice\n    ---------------------------------------------------------\n\n      This Source Code Form is \"Incompatible With Secondary Licenses\", as\n      defined by the Mozilla Public License, v. 2.0.\n\nThe design and implementation of the PyOptInterface is inspired by the [JuMP.jl] project.\n\n[JuMP.jl]: https://jump.dev"
  },
  {
    "path": "README.md",
    "content": "PyOptInterface (Python Optimization Interface)\n=======\n\n[![](https://img.shields.io/pypi/v/pyoptinterface.svg?color=brightgreen)](https://pypi.org/pypi/pyoptinterface/)\n\n**PyOptInterface** is an open-source Python library to provide a unified API to construct and solve optimization models with various optimizers.\n\nThe detailed documentation can be found [here](https://metab0t.github.io/PyOptInterface/).\n\n## Key features compared with other modeling interfaces\nIt is designed as a very thin wrapper of native C API of optimizers and attempts to provide common abstractions of an algebraic modelling environment including model, variable, constraint and expression with the least overhead of performance.\n\nThe key features of PyOptInterface include:\n- Very fast speed to construct optimization model (10x faster than Pyomo, comparable with JuMP.jl and some official Python bindings provided by vendors of optimizer)\n- Highly efficient structured automatic differentiation for nonlinear optimization with JIT compilation (faster than other NLP frameworks)\n- Low overhead to modify and re-solve the problem incrementally (including adding/removing variables/constraints, changing objective function, etc.)\n- Unified API to cover common usages, write once and the code works for all optimizers\n- You still have escape hatch to query or modify solver-specific parameter/attribute/information for different optimizers directly like the vendor-specific Python binding of optimizer\n\n## Benchmark\nThe benchmark comparing PyOptInterface with some other modeling interfaces can be found [here](https://metab0t.github.io/PyOptInterface/benchmark.html). PyOptInterface is among the fastest modeling interfaces in terms of model construction time and automatic differentiation of nonlinear optimization problems.\n\n## Installation\nPyOptInterface is available on PyPI. You can install it via pip:\n\n```\npip install pyoptinterface\n```\n\nAfter installation, you can import the package in Python console:\n```python\nimport pyoptinterface as poi\n```\n\nPyOptInterface has no dependencies other than Python itself. However, to use it with a specific optimizer, you need to install the corresponding optimizer manually. The details can be found on [the configurations of optimizers](https://metab0t.github.io/PyOptInterface/getting_started.html).\n\nIn order to provide out-of-the-box support for open source optimizers (currently we support [HiGHS](https://github.com/ERGO-Code/HiGHS)), PyOptInterface can also be installed with pre-built optimizers. You can install them via pip:\n\n```\npip install pyoptinterface[highs]\n```\n\nIt will install a full-featured binary version of HiGHS optimizer via [highsbox](http://github.com/metab0t/highsbox), which can be used with PyOptInterface.\n\n## What kind of problems can PyOptInterface solve?\nIt currently supports the following problem types:\n- Linear Programming (LP)\n- Mixed-Integer Linear Programming (MILP)\n- Quadratic Programming (QP)\n- Mixed-Integer Quadratic Programming (MIQP)\n- Quadratically Constrained Quadratic Programming (QCQP)\n- Mixed-Integer Quadratically Constrained Quadratic Programming (MIQCQP)\n- Second-Order Cone Programming (SOCP)\n- Mixed-Integer Second-Order Cone Programming (MISOCP)\n- Exponential Cone Programming (ECP)\n- Mixed-Integer Exponential Cone Programming (MIECP)\n- Nonlinear Programming (NLP)\n\n## What optimizers does PyOptInterface support?\nIt currently supports the following optimizers:\n- [COPT](https://shanshu.ai/copt) ( Commercial )\n- [Gurobi](https://www.gurobi.com/) ( Commercial )\n- [Xpress](https://www.fico.com/en/products/fico-xpress-optimization) ( Commercial )\n- [HiGHS](https://github.com/ERGO-Code/HiGHS) ( Open source )\n- [Mosek](https://www.mosek.com/) ( Commercial )\n- [Ipopt](https://github.com/coin-or/Ipopt) ( Open source )\n- [KNITRO](https://www.artelys.com/solvers/knitro/) ( Commercial )\n\n## Short Example\n```python\nimport pyoptinterface as poi\nfrom pyoptinterface import highs\n\nmodel = highs.Model()\n\nx = model.add_variable(lb=0, ub=1, domain=poi.VariableDomain.Continuous, name=\"x\")\ny = model.add_variable(lb=0, ub=1, domain=poi.VariableDomain.Integer, name=\"y\")\n\ncon = model.add_linear_constraint(x + y >= 1.2, name=\"con\")\n\nobj = 2*x\nmodel.set_objective(obj, poi.ObjectiveSense.Minimize)\n\nmodel.set_model_attribute(poi.ModelAttribute.Silent, False)\nmodel.optimize()\n\nprint(model.get_model_attribute(poi.ModelAttribute.TerminationStatus))\n# TerminationStatusCode.OPTIMAL\n\nx_val = model.get_value(x)\n# 0.2\n\ny_val = model.get_value(y)\n# 1.0\n```\n\n## Citation\nIf you use PyOptInterface in your research, please consider citing [the following paper](https://ieeexplore.ieee.org/document/10721402):\n\n```bibtex\n@article{yang2024accelerating,\n      title={Accelerating Optimal Power Flow with Structure-aware Automatic Differentiation and Code Generation},\n      author={Yang, Yue and Lin, Chenhui and Xu, Luo and Yang, Xiaodong and Wu, Wenchuan and Wang, Bin},\n      journal={IEEE Transactions on Power Systems},\n      year={2024},\n      publisher={IEEE}\n}\n```\n\n## License\nPyOptInterface is licensed under MPL-2.0 License.\n\nIt uses [nanobind](https://github.com/wjakob/nanobind), [fmtlib](https://github.com/fmtlib/fmt) and [martinus/unordered_dense](https://github.com/martinus/unordered_dense) as dependencies.\n\nThe design of PyOptInterface is inspired by [JuMP.jl](https://jump.dev).\n\nSome solver-related code in `src` folder is adapted from the corresponding solver interface package in `JuMP.jl`\necosystem, which is licensed under MIT License.\n\nThe header files in `thirdparty/solvers` directory are from the corresponding distribution of optimizers and are licensed under their own licenses.\n"
  },
  {
    "path": "bench/bench_linopy_cvxpy.py",
    "content": "import time\nfrom numpy import arange\nimport numpy as np\nimport pandas as pd\n\nimport linopy\n\nimport pyoptinterface as poi\nfrom pyoptinterface import copt, gurobi, highs\n\nimport cvxpy\n\n\ndef create_linopy_model(N):\n    m = linopy.Model()\n    x = m.add_variables(coords=[arange(N), arange(N)])\n    y = m.add_variables(coords=[arange(N), arange(N)])\n    m.add_constraints(x - y >= arange(N))\n    m.add_constraints(x + y >= 0)\n    m.add_objective((2 * x).sum() + y.sum())\n    return m\n\n\ndef create_cvxpy_model(N):\n    x = cvxpy.Variable((N, N))\n    y = cvxpy.Variable((N, N))\n    constraints = []\n    for i in range(N):\n        constraints.append(x[:, i] - y[:, i] >= np.arange(N))\n    constraints.append(x + y >= 0)\n    objective = cvxpy.Minimize(2 * cvxpy.sum(x) + cvxpy.sum(y))\n    return cvxpy.Problem(objective, constraints)\n\n\ndef create_poi_model(Model, N):\n    m = Model()\n    x = m.add_m_variables((N, N))\n    y = m.add_m_variables((N, N))\n    for i in range(N):\n        for j in range(N):\n            m.add_linear_constraint(x[i, j] - y[i, j], poi.Geq, i)\n            m.add_linear_constraint(x[i, j] + y[i, j], poi.Geq, 0)\n    expr = poi.ExprBuilder()\n    poi.quicksum_(expr, x, lambda x: 2 * x)\n    poi.quicksum_(expr, y)\n    m.set_objective(expr)\n    return m\n\n\ndef bench(N, solver_name):\n    results = {}\n\n    t0 = time.time()\n    Model = {\n        \"copt\": copt.Model,\n        \"gurobi\": gurobi.Model,\n        \"highs\": highs.Model,\n    }.get(solver_name, None)\n    if Model:\n        model = create_poi_model(Model, N)\n        model.optimize()\n        t1 = time.time()\n        results[\"n_variables\"] = 2 * N * N\n        results[\"poi\"] = t1 - t0\n\n    t0 = time.time()\n    model = create_linopy_model(N)\n    model.solve(solver_name=solver_name, io_api=\"direct\")\n    t1 = time.time()\n    results[\"linopy\"] = t1 - t0\n\n    t0 = time.time()\n    solver = {\"gurobi\": cvxpy.GUROBI, \"copt\": cvxpy.COPT}.get(solver_name, None)\n    if solver:\n        model = create_cvxpy_model(N)\n        model.solve(solver=cvxpy.GUROBI)\n        t1 = time.time()\n        results[\"cvxpy\"] = t1 - t0\n\n    return results\n\n\ndef main(solver_name=\"gurobi\"):\n    Ns = range(100, 501, 100)\n    results = []\n    for N in Ns:\n        results.append(bench(N, solver_name))\n    # create a DataFrame\n    df = pd.DataFrame(results, index=Ns)\n\n    # show result\n    print(df)\n\n\nif __name__ == \"__main__\":\n    # solver_name can be \"copt\", \"gurobi\", \"highs\"\n    main(\"gurobi\")\n"
  },
  {
    "path": "bench/bench_modify.jl",
    "content": "using JuMP\nimport MathOptInterface as MOI\nusing Gurobi\nusing COPT\n\nfunction bench_jump(model, N::Int, M::Int)\n    I = 1:N\n    @variable(model, x[I])\n\n    @constraint(model, sum(x[i] for i = I) == N)\n\n    @objective(model, Min, sum(i / N * x[i] for i = I))\n\n    # for j in 1:M:N\n    for j in [1]\n        last_variable = j + M - 1\n        if last_variable > N\n            last_variable = N\n        end\n        deleted_variables = [x[i] for i in j:last_variable]\n        delete(model, deleted_variables)\n        optimize!(model)\n    end\nend\n\nfunction gurobi_model()\n    optimizer = optimizer_with_attributes(\n        Gurobi.Optimizer,\n        \"Presolve\" => 0,\n        \"TimeLimit\" => 0.0,\n        MOI.Silent() => true,\n    )\n    model = direct_model(optimizer)\n    return model\nend\n\nfunction copt_model()\n    optimizer = optimizer_with_attributes(\n        COPT.Optimizer,\n        \"Presolve\" => 0,\n        \"TimeLimit\" => 0.0,\n        MOI.Silent() => true,\n    )\n    model = direct_model(optimizer)\n    return model\nend\n\nfunction bench_gurobi(N, M)\n    model = gurobi_model()\n    bench_jump(model, N, M)\nend\n\nfunction bench_copt(N, M)\n    model = copt_model()\n    bench_jump(model, N, M)\nend\n\nfunction main(N, M)\n    time_dict = Dict{String,Float64}()\n\n    println(\"N: $N, M: $M\")\n    println(\"Gurobi starts\")\n    t1 = time()\n    bench_gurobi(N, M)\n    t2 = time()\n    println(\"Gurobi ends and takes \", t2 - t1, \" seconds\")\n    time_dict[\"gurobi\"] = t2 - t1\n\n    println(\"COPT starts\")\n    t1 = time()\n    bench_copt(N, M)\n    t2 = time()\n    println(\"COPT ends and takes \", t2 - t1, \" seconds\")\n    time_dict[\"copt\"] = t2 - t1\n\n    return time_dict\nend\n\nmain(5, 1)\n\nresult_dict = Dict()\nfor N in [1000000]\n    for M in [10000]\n        result_dict[(N, M)] = main(N, M)\n    end\nend\n\nresult_dict"
  },
  {
    "path": "bench/bench_modify.mod",
    "content": "param N;\n\nvar x{1..N} >= 0;\n\ns.t. c1: sum {i in 1..N} x[i] = N;\n\nminimize obj: sum {i in 1..N div 2} i / N * x[i];"
  },
  {
    "path": "bench/bench_modify.py",
    "content": "import pyoptinterface as poi\nfrom pyoptinterface import gurobi, copt\n\n\nimport gurobipy as gp\nimport coptpy as cp\n\nimport time\n\n\ndef bench_poi_base(model, N, M):\n    I = range(N)\n    x = poi.make_nd_variable(model, I)\n\n    model.set_model_attribute(poi.ModelAttribute.Silent, True)\n    model.set_model_attribute(poi.ModelAttribute.TimeLimitSec, 0.0)\n    model.set_raw_parameter(\"Presolve\", 0)\n\n    expr = poi.ExprBuilder()\n    for i in range(N):\n        expr.add(i / N * x[i])\n    model.set_objective(expr, poi.ObjectiveSense.Minimize)\n\n    expr = poi.quicksum(x)\n    model.add_linear_constraint(expr, poi.ConstraintSense.GreaterEqual, N)\n\n    # for i in range(0, N, M):\n    for i in [0]:\n        last_variable = min(i + M, N)\n        deleted_variables = [x[j] for j in range(i, last_variable)]\n        model.delete_variables(deleted_variables)\n        model.optimize()\n\n\ndef bench_poi_gurobi(N, M):\n    model = gurobi.Model()\n    bench_poi_base(model, N, M)\n\n\ndef bench_poi_copt(N, M):\n    model = copt.Model()\n    bench_poi_base(model, N, M)\n\n\ndef bench_gp(N, M):\n    model = gp.Model()\n\n    I = range(N)\n    x = model.addVars(I)\n\n    obj = gp.quicksum(i / N * x[i] for i in range(N))\n    model.setObjective(obj)\n\n    model.addConstr(x.sum() == N)\n\n    model.setParam(\"OutputFlag\", 0)\n    model.setParam(\"TimeLimit\", 0.0)\n    model.setParam(\"Presolve\", 0)\n\n    # for j in range(0, N, M):\n    for j in [0]:\n        last_variable = min(j + M, N)\n        for k in range(j, last_variable):\n            model.remove(x[k])\n        model.optimize()\n\n\ndef bench_cp(N, M):\n    env = cp.Envr()\n    model = env.createModel(\"m\")\n\n    I = range(N)\n    x = model.addVars(I)\n\n    model.setParam(\"Logging\", 0)\n    model.setParam(\"TimeLimit\", 0.0)\n    model.setParam(\"Presolve\", 0)\n\n    obj = cp.quicksum(i / N * x[i] for i in range(N))\n    model.setObjective(obj)\n\n    model.addConstr(x.sum() == N)\n\n    # for j in range(0, N, M):\n    for j in [0]:\n        last_variable = min(j + M, N)\n        for k in range(j, last_variable):\n            x[k].remove()\n        model.solve()\n\n\ndef main(N, M):\n    result = dict()\n\n    t1 = time.perf_counter()\n    bench_poi_gurobi(N, M)\n    t2 = time.perf_counter()\n    result[\"poi_gurobi\"] = t2 - t1\n\n    t1 = time.perf_counter()\n    bench_gp(N, M)\n    t2 = time.perf_counter()\n    result[\"gurobipy\"] = t2 - t1\n\n    t1 = time.perf_counter()\n    bench_poi_copt(N, M)\n    t2 = time.perf_counter()\n    result[\"poi_copt\"] = t2 - t1\n\n    t1 = time.perf_counter()\n    bench_cp(N, M)\n    t2 = time.perf_counter()\n    result[\"coptpy\"] = t2 - t1\n\n    return result\n\n\nresult_dict = dict()\nfor N in [1000000]:\n    for M in [100000]:\n        print(f\"N = {N}, M = {M}\")\n        result = main(N, M)\n        result_dict[(N, M)] = result\n\nprint(result_dict)\n"
  },
  {
    "path": "bench/bench_modify.run",
    "content": "param t0;\nparam t1;\nlet t0 := time();\n\nmodel bench_modify.mod;\n\nlet N := 10000;\n\noption solver_msg 0;\noption presolve 0;\noption solver 'gurobi';\noption gurobi_options 'outlev=0 timelim=2 presolve=0';\n\nsolve >NUL;\n\nfor {j in (N div 2 + 1)..N} {\n    let x[j] := 0;\n    solve >NUL;\n}\n\nlet t1 := time();\nprintf \"%d\\n\", t1-t0;"
  },
  {
    "path": "bench/bench_static.jl",
    "content": "using JuMP\nusing Gurobi\nusing COPT\nusing MosekTools\n\nfunction bench_jump(model, M, N)\n    @variable(model, x[1:M, 1:N] >= 0)\n\n    @constraint(model, sum(x) == M * N / 2)\n\n    @objective(model, Min, sum(x[i, j]^2 for i in 1:M, j in 1:N))\n\n    set_silent(model)\n    set_time_limit_sec(model, 0.0)\n    set_optimizer_attribute(model, \"Presolve\", 0)\n\n    optimize!(model)\nend\n\nfunction bench_gurobi(M::Int, N::Int)\n    model = direct_model(Gurobi.Optimizer())\n    bench_jump(model, M, N)\nend\n\nfunction bench_copt(M::Int, N::Int)\n    model = direct_model(COPT.Optimizer())\n    bench_jump(model, M, N)\nend\n\nfunction bench_mosek(M::Int, N::Int)\n    model = direct_model(Mosek.Optimizer())\n    bench_jump(model, M, N)\nend\n\nfunction main(M::Int, N::Int)\n    println(\"Gurobi starts\")\n    t1 = time()\n    bench_gurobi(M, N)\n    t2 = time()\n    println(\"Gurobi ends and takes \", t2 - t1, \" seconds\")\n\n    println(\"COPT starts\")\n    t1 = time()\n    bench_copt(M, N)\n    t2 = time()\n    println(\"COPT ends and takes \", t2 - t1, \" seconds\")\n\n    println(\"Mosek starts\")\n    t1 = time()\n    bench_mosek(M, N)\n    t2 = time()\n    println(\"Mosek ends and takes \", t2 - t1, \" seconds\")\nend"
  },
  {
    "path": "bench/bench_static.py",
    "content": "import pyoptinterface as poi\nfrom pyoptinterface import gurobi, copt, mosek\n\nimport pyomo.environ as pyo\nfrom pyomo.common.timing import TicTocTimer\n\nimport linopy\n\nimport gurobipy as gp\nimport coptpy as cp\nimport mosek as msk\n\n\ndef bench_poi_base(model, M, N):\n    I = range(M)\n    J = range(N)\n    x = poi.make_nd_variable(model, I, J, lb=0.0)\n\n    expr = poi.quicksum(x)\n    con = model.add_linear_constraint(expr, poi.ConstraintSense.Equal, M * N / 2)\n\n    obj = poi.quicksum(x, lambda v: v * v)\n    model.set_objective(obj, poi.ObjectiveSense.Minimize)\n\n    model.set_model_attribute(poi.ModelAttribute.Silent, True)\n    model.set_model_attribute(poi.ModelAttribute.TimeLimitSec, 0.0)\n    if isinstance(model, gurobi.Model) or isinstance(model, copt.Model):\n        model.set_raw_parameter(\"Presolve\", 0)\n    elif isinstance(model, mosek.Model):\n        model.set_raw_parameter(\"MSK_IPAR_PRESOLVE_USE\", 0)\n\n    model.optimize()\n\n\ndef bench_poi_gurobi(M, N):\n    model = gurobi.Model()\n    bench_poi_base(model, M, N)\n\n\ndef bench_poi_copt(M, N):\n    model = copt.Model()\n    bench_poi_base(model, M, N)\n\n\ndef bench_poi_mosek(M, N):\n    model = mosek.Model()\n    bench_poi_base(model, M, N)\n\n\ndef bench_pyomo_base(solver, M, N):\n    model = pyo.ConcreteModel()\n\n    I = range(M)\n    J = range(N)\n    model.x = pyo.Var(I, J)\n\n    for var in model.x.values():\n        var.setlb(0.0)\n\n    model.c = pyo.Constraint(\n        expr=pyo.quicksum(var for var in model.x.values()) == M * N / 2\n    )\n    model.o = pyo.Objective(expr=sum(v * v for v in model.x.values()))\n\n    solver.solve(model, load_solutions=False)\n\n\ndef bench_pyomo_gurobi(M, N):\n    solver = pyo.SolverFactory(\"gurobi_direct\")\n    solver.options[\"timelimit\"] = 0.0\n    solver.options[\"presolve\"] = False\n    bench_pyomo_base(solver, M, N)\n\n\ndef bench_pyomo_mosek(M, N):\n    solver = pyo.SolverFactory(\"mosek_direct\")\n    solver.options[\"dparam.optimizer_max_time\"] = 0.0\n    solver.options[\"iparam.presolve_use\"] = 0\n    bench_pyomo_base(solver, M, N)\n\n\ndef bench_linopy_gurobi(M, N):\n    model = linopy.Model()\n\n    I = range(M)\n    J = range(N)\n    x = model.add_variables(lower=0.0, coords=[I, J], name=\"x\")\n\n    model.add_constraints(x.sum() == M * N / 2)\n    model.add_objective((x * x).sum())\n\n    model.solve(\"gurobi\", io_api=\"direct\", OutputFlag=0, TimeLimit=0.0, Presolve=0)\n\n\ndef bench_gp(M, N):\n    model = gp.Model()\n\n    I = range(M)\n    J = range(N)\n    x = model.addVars(I, J, lb=0.0, name=\"x\")\n\n    expr = x.sum()\n    con = model.addConstr(expr == M * N / 2)\n\n    obj = gp.quicksum(v * v for v in x.values())\n    model.setObjective(obj)\n\n    model.setParam(\"OutputFlag\", 0)\n    model.setParam(\"TimeLimit\", 0.0)\n    model.setParam(\"Presolve\", 0)\n\n    model.optimize()\n\n\ndef bench_cp(M, N):\n    env = cp.Envr()\n    model = env.createModel(\"m\")\n\n    I = range(M)\n    J = range(N)\n    x = model.addVars(I, J, lb=0.0, nameprefix=\"x\")\n\n    expr = x.sum()\n    con = model.addConstr(expr == M * N / 2)\n\n    obj = cp.quicksum(v * v for v in x.values())\n    model.setObjective(obj)\n\n    model.setParam(\"Logging\", 0)\n    model.setParam(\"TimeLimit\", 0.0)\n    model.setParam(\"Presolve\", 0)\n\n    model.solve()\n\n\ndef streamprinter(text):\n    pass\n\n\ndef bench_msk(M, N):\n    with msk.Env() as env:\n        with env.Task(0, 0) as task:\n            task.set_Stream(msk.streamtype.log, streamprinter)\n\n            # Total number of variables (M*N for 'x')\n            numvar = M * N\n\n            # Add variables\n            for j in range(numvar):\n                task.appendvars(1)\n\n            # Variable bounds - All variables are greater than 0.0\n            for j in range(numvar):\n                task.putvarbound(j, msk.boundkey.ra, 0.0, 1e9)\n\n            # Objective\n            indx = list(range(M * N))\n            val = [2.0] * (M * N)\n            task.putqobj(indx, indx, val)\n            task.putobjsense(msk.objsense.minimize)\n\n            # Constraint - Sum of elements in 'x' equals M * N / 2\n            task.appendcons(1)  # One linear constraint\n            indx = list(range(M * N))  # Indices of 'x' variables\n            val = [1.0] * (M * N)  # Coefficients are 1\n            task.putarow(0, indx, val)\n            task.putconbound(0, msk.boundkey.fx, M * N / 2, M * N / 2)\n\n            # Set solver parameters\n            task.putdouparam(msk.dparam.optimizer_max_time, 0.0)\n            task.putintparam(msk.iparam.presolve_use, msk.presolvemode.off)\n\n            # Solve the problem\n            task.optimize()\n\n\nM = 1000\nN = 100\ntimer = TicTocTimer()\n\ntests = [\n    \"gurobi\",\n    \"copt\",\n    # \"mosek\",\n]\n\nif \"gurobi\" in tests:\n    timer.tic(\"poi_gurobi starts\")\n    bench_poi_gurobi(M, N)\n    timer.toc(\"poi_gurobi ends\")\n\n    timer.tic(\"linopy_gurobi starts\")\n    bench_linopy_gurobi(M, N)\n    timer.toc(\"linopy_gurobi ends\")\n\n    timer.tic(\"gurobi starts\")\n    bench_gp(M, N)\n    timer.toc(\"gurobi ends\")\n\n    timer.tic(\"pyomo_gurobi starts\")\n    bench_pyomo_gurobi(M, N)\n    timer.toc(\"pyomo_gurobi ends\")\n\nif \"copt\" in tests:\n    timer.tic(\"poi_copt starts\")\n    bench_poi_copt(M, N)\n    timer.toc(\"poi_copt ends\")\n\n    timer.tic(\"cp starts\")\n    bench_cp(M, N)\n    timer.toc(\"cp ends\")\n\nif \"mosek\" in tests:\n    timer.tic(\"poi_mosek starts\")\n    bench_poi_mosek(M, N)\n    timer.toc(\"poi_mosek ends\")\n\n    timer.tic(\"mosek starts\")\n    bench_msk(M, N)\n    timer.toc(\"mosek ends\")\n\n    timer.tic(\"pyomo_mosek starts\")\n    bench_pyomo_mosek(M, N)\n    timer.toc(\"pyomo_mosek ends\")\n"
  },
  {
    "path": "bench/nqueens/.gitignore",
    "content": "*.csv\n"
  },
  {
    "path": "bench/nqueens/nqueens.jl",
    "content": "using JuMP\nimport Gurobi\nimport LinearAlgebra\n\nfunction solve_nqueens(N)\n    model = direct_model(Gurobi.Optimizer())\n    set_silent(model)\n    set_time_limit_sec(model, 0.0)\n    set_optimizer_attribute(model, \"Presolve\", 0)\n\n    @variable(model, x[1:N, 1:N], Bin)\n\n    for i in 1:N\n        @constraint(model, sum(x[i, :]) == 1)\n        @constraint(model, sum(x[:, i]) == 1)\n    end\n\n    for i in -(N - 1):(N-1)\n        @constraint(model, sum(LinearAlgebra.diag(x, i)) <= 1)\n        @constraint(model, sum(LinearAlgebra.diag(reverse(x; dims=1), i)) <= 1)\n    end\n\n    optimize!(model)\nend\n\nfunction main(io::IO, Ns = 800:400:2000)\n    for n in Ns\n        start = time()\n        model = solve_nqueens(n)\n        run_time = round(Int, time() - start)\n        content = \"jump nqueens-$n $run_time\"\n        println(stdout, content)\n        println(io, content)\n    end\nend\n\nmain(stdout, [5])\nopen(joinpath(@__DIR__, \"benchmarks.csv\"), \"a\") do io\n    main(io)\nend"
  },
  {
    "path": "bench/nqueens/nqueens_gurobipy.py",
    "content": "from gurobipy import *\nimport numpy as np\nimport os\nimport time\n\n\ndef solve_nqueens(N):\n    model = Model(\"queens\")\n    model.setParam(\"OutputFlag\", 0)\n    model.setParam(\"TimeLimit\", 0.0)\n    model.setParam(\"Presolve\", 0)\n\n    x = np.empty((N, N), dtype=object)\n    for i in range(N):\n        for j in range(N):\n            x[i, j] = model.addVar(vtype=GRB.BINARY)\n\n    for i in range(N):\n        # Row and column\n        model.addConstr(quicksum(x[i, :]) == 1.0)\n        model.addConstr(quicksum(x[:, i]) == 1.0)\n    flipx = np.fliplr(x)\n    for i in range(-N + 1, N):\n        # Diagonal\n        model.addConstr(quicksum(x.diagonal(i)) <= 1.0)\n        # Anti-diagonal\n        model.addConstr(quicksum(flipx.diagonal(i)) <= 1.0)\n\n    model.optimize()\n\n\ndef main(Ns=range(800, 2001, 400)):\n    dir = os.path.realpath(os.path.dirname(__file__))\n    for n in Ns:\n        start = time.time()\n        solve_nqueens(n)\n        run_time = round(time.time() - start)\n        content = \"gurobipy nqueens-%i %i\" % (n, run_time)\n        print(content)\n        with open(dir + \"/benchmarks.csv\", \"a\") as io:\n            io.write(f\"{content}\\n\")\n    return\n\n\nmain()\n"
  },
  {
    "path": "bench/nqueens/nqueens_poi.py",
    "content": "import pyoptinterface as poi\nfrom pyoptinterface import gurobi\nimport numpy as np\nimport os\nimport time\n\n\ndef solve_nqueens(N):\n    model = gurobi.Model()\n\n    x = np.empty((N, N), dtype=object)\n    for i in range(N):\n        for j in range(N):\n            x[i, j] = model.add_variable(domain=poi.VariableDomain.Binary)\n\n    for i in range(N):\n        # Row and column\n        model.add_linear_constraint(poi.quicksum(x[i, :]), poi.Eq, 1.0)\n        model.add_linear_constraint(poi.quicksum(x[:, i]), poi.Eq, 1.0)\n    flipx = np.fliplr(x)\n    for i in range(-N + 1, N):\n        # Diagonal\n        model.add_linear_constraint(poi.quicksum(x.diagonal(i)), poi.Leq, 1.0)\n        # Anti-diagonal\n        model.add_linear_constraint(poi.quicksum(flipx.diagonal(i)), poi.Leq, 1.0)\n\n    model.set_model_attribute(poi.ModelAttribute.Silent, True)\n    model.set_model_attribute(poi.ModelAttribute.TimeLimitSec, 0.0)\n    model.set_raw_parameter(\"Presolve\", 0)\n    model.optimize()\n\n\ndef main(Ns=range(800, 2001, 400)):\n    dir = os.path.realpath(os.path.dirname(__file__))\n    for n in Ns:\n        start = time.time()\n        solve_nqueens(n)\n        run_time = round(time.time() - start)\n        content = \"poi nqueens-%i %i\" % (n, run_time)\n        print(content)\n        with open(dir + \"/benchmarks.csv\", \"a\") as io:\n            io.write(f\"{content}\\n\")\n    return\n\n\nmain()\n"
  },
  {
    "path": "bench/nqueens/nqueens_pythonmip.py",
    "content": "from mip.model import *\nfrom mip import GUROBI\nimport numpy as np\nimport os\nimport time\n\n\ndef solve_nqueens(N):\n    model = Model(\"queens\", solver_name=GUROBI)\n    # set parameters\n    model.solver.set_int_param(\"OutputFlag\", 0)\n    model.solver.set_dbl_param(\"TimeLimit\", 0.0)\n    model.solver.set_int_param(\"Presolve\", 0)\n\n    x = np.empty((N, N), dtype=object)\n    for i in range(N):\n        for j in range(N):\n            x[i, j] = model.add_var(var_type=\"B\")\n\n    for i in range(N):\n        # Row and column\n        model.add_constr(xsum(x[i, :]) == 1.0)\n        model.add_constr(xsum(x[:, i]) == 1.0)\n    flipx = np.fliplr(x)\n    for i in range(-N + 1, N):\n        # Diagonal\n        model.add_constr(xsum(x.diagonal(i)) <= 1.0)\n        # Anti-diagonal\n        model.add_constr(xsum(flipx.diagonal(i)) <= 1.0)\n\n    model.optimize()\n\n\ndef main(Ns=range(800, 2001, 400)):\n    dir = os.path.realpath(os.path.dirname(__file__))\n    for n in Ns:\n        start = time.time()\n        solve_nqueens(n)\n        run_time = round(time.time() - start)\n        content = \"pythonmip nqueens-%i %i\" % (n, run_time)\n        print(content)\n        with open(dir + \"/benchmarks.csv\", \"a\") as io:\n            io.write(f\"{content}\\n\")\n    return\n\n\nmain()\n"
  },
  {
    "path": "bench/test_delete.py",
    "content": "import gurobipy as gp\nimport coptpy as cp\nimport pyoptinterface as poi\nfrom pyoptinterface import copt\n\n\ndef bench_poi_base(N):\n    model = copt.Model()\n    I = range(N)\n    x = poi.make_nd_variable(model, I, lb=0.0)\n\n    model.add_linear_constraint(x[0] + x[N - 1], poi.ConstraintSense.GreaterEqual, 1.0)\n\n    model.set_model_attribute(poi.ModelAttribute.Silent, False)\n    model.set_model_attribute(poi.ModelAttribute.TimeLimitSec, 2.0)\n    model.set_raw_parameter(\"Presolve\", 0)\n\n    obj = poi.ExprBuilder()\n    for i in range(N):\n        obj.add(x[i] * x[i])\n    model.set_objective(obj, poi.ObjectiveSense.Minimize)\n\n    for i in range(N // 2):\n        model.delete_variable(x[i])\n    model.optimize()\n\n\ndef gp_delete(N):\n    model = gp.Model()\n\n    I = range(N)\n    x = model.addVars(I, lb=0.0)\n\n    model.addConstr(x[0] + x[N - 1] >= 1.0)\n\n    obj = gp.quicksum(x[i] * x[i] for i in range(N))\n    model.setObjective(obj)\n\n    model.setParam(\"OutputFlag\", 1)\n    model.setParam(\"TimeLimit\", 2.0)\n    model.setParam(\"Presolve\", 0)\n\n    for j in range(N // 2):\n        model.remove(x[j])\n    model.optimize()\n\n\ndef cp_delete(N):\n    env = cp.Envr()\n    model = env.createModel(\"m\")\n\n    I = range(N)\n    x = model.addVars(I, lb=0.0)\n\n    model.addConstr(x[0] + x[N - 1] >= 1.0)\n\n    obj = cp.quicksum(x[i] * x[i] for i in range(N))\n    model.setObjective(obj)\n\n    model.setParam(\"Logging\", 1)\n    model.setParam(\"TimeLimit\", 2.0)\n    model.setParam(\"Presolve\", 0)\n\n    for j in range(N // 2):\n        x[j].remove()\n    model.solve()\n\n\nif __name__ == \"__main__\":\n    N = 20\n    cp_delete(N)\n"
  },
  {
    "path": "docs/Makefile",
    "content": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line, and also\n# from the environment for the first two.\nSPHINXOPTS    ?=\nSPHINXBUILD   ?= sphinx-build\nSOURCEDIR     = source\nBUILDDIR      = build\n\n# Put it first so that \"make\" without argument is like \"make help\".\nhelp:\n\t@$(SPHINXBUILD) -M help \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n\n.PHONY: help Makefile\n\n# Catch-all target: route all unknown targets to Sphinx using the new\n# \"make mode\" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).\n%: Makefile\n\t@$(SPHINXBUILD) -M $@ \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n"
  },
  {
    "path": "docs/make.bat",
    "content": "@ECHO OFF\n\npushd %~dp0\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-build\n)\nset SOURCEDIR=source\nset BUILDDIR=build\n\n%SPHINXBUILD% >NUL 2>NUL\nif errorlevel 9009 (\n\techo.\n\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx\n\techo.installed, then set the SPHINXBUILD environment variable to point\n\techo.to the full path of the 'sphinx-build' executable. Alternatively you\n\techo.may add the Sphinx directory to PATH.\n\techo.\n\techo.If you don't have Sphinx installed, grab it from\n\techo.https://www.sphinx-doc.org/\n\texit /b 1\n)\n\nif \"%1\" == \"\" goto help\n\n%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\ngoto end\n\n:help\n%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\n\n:end\npopd\n"
  },
  {
    "path": "docs/requirements.txt",
    "content": "sphinx\nmyst-parser\nmyst-nb\nsphinx-copybutton\nfuro\nnumpy\nscipy\nhighsbox\ntccbox\nllvmlite\nmatplotlib\n"
  },
  {
    "path": "docs/source/api/pyoptinterface.copt.rst",
    "content": "pyoptinterface.copt package\n====================================\n\n.. automodule:: pyoptinterface.copt\n   :members:\n   :inherited-members:\n   :undoc-members:\n   :show-inheritance:"
  },
  {
    "path": "docs/source/api/pyoptinterface.gurobi.rst",
    "content": "pyoptinterface.gurobi package\n====================================\n\n.. automodule:: pyoptinterface.gurobi\n   :members:\n   :inherited-members:\n   :undoc-members:\n   :show-inheritance:"
  },
  {
    "path": "docs/source/api/pyoptinterface.highs.rst",
    "content": "pyoptinterface.highs package\n====================================\n\n.. automodule:: pyoptinterface.highs\n   :members:\n   :inherited-members:\n   :undoc-members:\n   :show-inheritance:"
  },
  {
    "path": "docs/source/api/pyoptinterface.knitro.rst",
    "content": "pyoptinterface.knitro package\n====================================\n\n.. automodule:: pyoptinterface.knitro\n   :members:\n   :inherited-members:\n   :undoc-members:\n   :show-inheritance:\n"
  },
  {
    "path": "docs/source/api/pyoptinterface.mosek.rst",
    "content": "pyoptinterface.mosek package\n====================================\n\n.. automodule:: pyoptinterface.mosek\n   :members:\n   :inherited-members:\n   :undoc-members:\n   :show-inheritance:"
  },
  {
    "path": "docs/source/api/pyoptinterface.rst",
    "content": "pyoptinterface package\n===========================\n\n.. automodule:: pyoptinterface\n   :members:\n   :undoc-members:\n   :show-inheritance:\n\nSubmodules\n-----------\n\n.. toctree::\n   :maxdepth: 2\n\n   pyoptinterface.gurobi.rst\n   pyoptinterface.copt.rst\n   pyoptinterface.xpress.rst\n   pyoptinterface.mosek.rst\n   pyoptinterface.highs.rst\n"
  },
  {
    "path": "docs/source/api/pyoptinterface.xpress.rst",
    "content": "pyoptinterface.xpress package\n====================================\n\n.. automodule:: pyoptinterface.xpress\n   :members:\n   :inherited-members:\n   :undoc-members:\n   :show-inheritance:"
  },
  {
    "path": "docs/source/attribute/copt.md",
    "content": "### Supported [model attribute](#pyoptinterface.ModelAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Name\n    - ❌\n    - ❌\n*   - ObjectiveSense\n    - ✅\n    - ✅\n*   - DualStatus\n    - ✅\n    - ❌\n*   - PrimalStatus\n    - ✅\n    - ❌\n*   - RawStatusString\n    - ✅\n    - ❌\n*   - TerminationStatus\n    - ✅\n    - ❌\n*   - BarrierIterations\n    - ✅\n    - ❌\n*   - DualObjectiveValue\n    - ✅\n    - ❌\n*   - NodeCount\n    - ✅\n    - ❌\n*   - NumberOfThreads\n    - ✅\n    - ✅\n*   - ObjectiveBound\n    - ✅\n    - ❌\n*   - ObjectiveValue\n    - ✅\n    - ❌\n*   - RelativeGap\n    - ✅\n    - ✅\n*   - Silent\n    - ✅\n    - ✅\n*   - SimplexIterations\n    - ✅\n    - ❌\n*   - SolverName\n    - ✅\n    - ❌\n*   - SolverVersion\n    - ✅\n    - ❌\n*   - SolveTimeSec\n    - ✅\n    - ❌\n*   - TimeLimitSec\n    - ✅\n    - ✅\n:::\n\n### Supported [variable attribute](#pyoptinterface.VariableAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Value\n    - ✅\n    - ❌\n*   - LowerBound\n    - ✅\n    - ✅\n*   - UpperBound\n    - ✅\n    - ✅\n*   - Domain\n    - ✅\n    - ✅\n*   - PrimalStart\n    - ✅\n    - ✅\n*   - Name\n    - ✅\n    - ✅\n*   - IISLowerBound\n    - ✅\n    - ❌\n*   - IISUpperBound\n    - ✅\n    - ❌\n*   - ReducedCost\n    - ✅\n    - ❌\n:::\n\n### Supported [constraint attribute](#pyoptinterface.ConstraintAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Name\n    - ✅\n    - ✅\n*   - Primal\n    - ✅\n    - ❌\n*   - Dual\n    - ✅\n    - ❌\n*   - IIS\n    - ✅\n    - ❌\n:::\n\n"
  },
  {
    "path": "docs/source/attribute/gurobi.md",
    "content": "### Supported [model attribute](#pyoptinterface.ModelAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Name\n    - ✅\n    - ✅\n*   - ObjectiveSense\n    - ✅\n    - ✅\n*   - DualStatus\n    - ✅\n    - ❌\n*   - PrimalStatus\n    - ✅\n    - ❌\n*   - RawStatusString\n    - ✅\n    - ❌\n*   - TerminationStatus\n    - ✅\n    - ❌\n*   - BarrierIterations\n    - ✅\n    - ❌\n*   - DualObjectiveValue\n    - ✅\n    - ❌\n*   - NodeCount\n    - ✅\n    - ❌\n*   - NumberOfThreads\n    - ✅\n    - ✅\n*   - ObjectiveBound\n    - ✅\n    - ❌\n*   - ObjectiveValue\n    - ✅\n    - ❌\n*   - RelativeGap\n    - ✅\n    - ✅\n*   - Silent\n    - ✅\n    - ✅\n*   - SimplexIterations\n    - ✅\n    - ❌\n*   - SolverName\n    - ✅\n    - ❌\n*   - SolverVersion\n    - ✅\n    - ❌\n*   - SolveTimeSec\n    - ✅\n    - ❌\n*   - TimeLimitSec\n    - ✅\n    - ✅\n:::\n\n### Supported [variable attribute](#pyoptinterface.VariableAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Value\n    - ✅\n    - ❌\n*   - LowerBound\n    - ✅\n    - ✅\n*   - UpperBound\n    - ✅\n    - ✅\n*   - Domain\n    - ✅\n    - ✅\n*   - PrimalStart\n    - ✅\n    - ✅\n*   - Name\n    - ✅\n    - ✅\n*   - IISLowerBound\n    - ✅\n    - ❌\n*   - IISUpperBound\n    - ✅\n    - ❌\n*   - ReducedCost\n    - ✅\n    - ❌\n:::\n\n### Supported [constraint attribute](#pyoptinterface.ConstraintAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Name\n    - ✅\n    - ✅\n*   - Primal\n    - ✅\n    - ❌\n*   - Dual\n    - ✅\n    - ❌\n*   - IIS\n    - ✅\n    - ❌\n:::\n\n"
  },
  {
    "path": "docs/source/attribute/highs.md",
    "content": "### Supported [model attribute](#pyoptinterface.ModelAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Name\n    - ❌\n    - ❌\n*   - ObjectiveSense\n    - ✅\n    - ✅\n*   - DualStatus\n    - ✅\n    - ❌\n*   - PrimalStatus\n    - ✅\n    - ❌\n*   - RawStatusString\n    - ✅\n    - ❌\n*   - TerminationStatus\n    - ✅\n    - ❌\n*   - BarrierIterations\n    - ❌\n    - ❌\n*   - DualObjectiveValue\n    - ❌\n    - ❌\n*   - NodeCount\n    - ❌\n    - ❌\n*   - NumberOfThreads\n    - ✅\n    - ✅\n*   - ObjectiveBound\n    - ❌\n    - ❌\n*   - ObjectiveValue\n    - ✅\n    - ❌\n*   - RelativeGap\n    - ✅\n    - ✅\n*   - Silent\n    - ✅\n    - ✅\n*   - SimplexIterations\n    - ❌\n    - ❌\n*   - SolverName\n    - ✅\n    - ❌\n*   - SolverVersion\n    - ✅\n    - ❌\n*   - SolveTimeSec\n    - ✅\n    - ❌\n*   - TimeLimitSec\n    - ✅\n    - ✅\n:::\n\n### Supported [variable attribute](#pyoptinterface.VariableAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Value\n    - ✅\n    - ❌\n*   - LowerBound\n    - ✅\n    - ✅\n*   - UpperBound\n    - ✅\n    - ✅\n*   - Domain\n    - ✅\n    - ✅\n*   - PrimalStart\n    - ✅\n    - ✅\n*   - Name\n    - ✅\n    - ✅\n*   - IISLowerBound\n    - ❌\n    - ❌\n*   - IISUpperBound\n    - ❌\n    - ❌\n*   - ReducedCost\n    - ✅\n    - ❌\n:::\n\n### Supported [constraint attribute](#pyoptinterface.ConstraintAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Name\n    - ✅\n    - ✅\n*   - Primal\n    - ✅\n    - ❌\n*   - Dual\n    - ✅\n    - ❌\n*   - IIS\n    - ❌\n    - ❌\n:::\n\n"
  },
  {
    "path": "docs/source/attribute/ipopt.md",
    "content": "### Supported [model attribute](#pyoptinterface.ModelAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Name\n    - ❌\n    - ❌\n*   - ObjectiveSense\n    - ❌\n    - ❌\n*   - DualStatus\n    - ✅\n    - ❌\n*   - PrimalStatus\n    - ✅\n    - ❌\n*   - RawStatusString\n    - ✅\n    - ❌\n*   - TerminationStatus\n    - ✅\n    - ❌\n*   - BarrierIterations\n    - ❌\n    - ❌\n*   - DualObjectiveValue\n    - ❌\n    - ❌\n*   - NodeCount\n    - ❌\n    - ❌\n*   - NumberOfThreads\n    - ❌\n    - ❌\n*   - ObjectiveBound\n    - ❌\n    - ❌\n*   - ObjectiveValue\n    - ✅\n    - ❌\n*   - RelativeGap\n    - ❌\n    - ❌\n*   - Silent\n    - ❌\n    - ✅\n*   - SimplexIterations\n    - ❌\n    - ❌\n*   - SolverName\n    - ✅\n    - ❌\n*   - SolverVersion\n    - ❌\n    - ❌\n*   - SolveTimeSec\n    - ❌\n    - ❌\n*   - TimeLimitSec\n    - ❌\n    - ✅\n:::\n\n### Supported [variable attribute](#pyoptinterface.VariableAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Value\n    - ✅\n    - ❌\n*   - LowerBound\n    - ✅\n    - ✅\n*   - UpperBound\n    - ✅\n    - ✅\n*   - Domain\n    - ❌\n    - ❌\n*   - PrimalStart\n    - ✅\n    - ✅\n*   - Name\n    - ✅\n    - ✅\n*   - IISLowerBound\n    - ❌\n    - ❌\n*   - IISUpperBound\n    - ❌\n    - ❌\n*   - ReducedCost\n    - ❌\n    - ❌\n:::\n\n### Supported [constraint attribute](#pyoptinterface.ConstraintAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Name\n    - ❌\n    - ❌\n*   - Primal\n    - ✅\n    - ❌\n*   - Dual\n    - ✅\n    - ❌\n*   - IIS\n    - ❌\n    - ❌\n:::\n\n"
  },
  {
    "path": "docs/source/attribute/knitro.md",
    "content": "### Supported [model attribute](#pyoptinterface.ModelAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Name\n    - ❌\n    - ❌\n*   - ObjectiveSense\n    - ✅\n    - ✅\n*   - DualStatus\n    - ❌\n    - ❌\n*   - PrimalStatus\n    - ✅\n    - ❌\n*   - RawStatusString\n    - ✅\n    - ❌\n*   - TerminationStatus\n    - ✅\n    - ❌\n*   - BarrierIterations\n    - ✅\n    - ❌\n*   - DualObjectiveValue\n    - ❌\n    - ❌\n*   - NodeCount\n    - ✅\n    - ❌\n*   - NumberOfThreads\n    - ✅\n    - ✅\n*   - ObjectiveBound\n    - ✅\n    - ❌\n*   - ObjectiveValue\n    - ✅\n    - ❌\n*   - RelativeGap\n    - ✅\n    - ❌\n*   - Silent\n    - ❌\n    - ✅\n*   - SimplexIterations\n    - ❌\n    - ❌\n*   - SolverName\n    - ✅\n    - ❌\n*   - SolverVersion\n    - ✅\n    - ❌\n*   - SolveTimeSec\n    - ✅\n    - ❌\n*   - TimeLimitSec\n    - ✅\n    - ✅\n:::\n\n### Supported [variable attribute](#pyoptinterface.VariableAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Value\n    - ✅\n    - ❌\n*   - LowerBound\n    - ✅\n    - ✅\n*   - UpperBound\n    - ✅\n    - ✅\n*   - Domain\n    - ✅\n    - ✅\n*   - PrimalStart\n    - ❌\n    - ✅\n*   - Name\n    - ✅\n    - ✅\n*   - IISLowerBound\n    - ❌\n    - ❌\n*   - IISUpperBound\n    - ❌\n    - ❌\n*   - ReducedCost\n    - ✅\n    - ❌\n:::\n\n### Supported [constraint attribute](#pyoptinterface.ConstraintAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Name\n    - ✅\n    - ✅\n*   - Primal\n    - ✅\n    - ❌\n*   - Dual\n    - ✅\n    - ❌\n:::\n"
  },
  {
    "path": "docs/source/attribute/mosek.md",
    "content": "### Supported [model attribute](#pyoptinterface.ModelAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Name\n    - ❌\n    - ❌\n*   - ObjectiveSense\n    - ✅\n    - ✅\n*   - DualStatus\n    - ✅\n    - ❌\n*   - PrimalStatus\n    - ✅\n    - ❌\n*   - RawStatusString\n    - ✅\n    - ❌\n*   - TerminationStatus\n    - ✅\n    - ❌\n*   - BarrierIterations\n    - ❌\n    - ❌\n*   - DualObjectiveValue\n    - ✅\n    - ❌\n*   - NodeCount\n    - ❌\n    - ❌\n*   - NumberOfThreads\n    - ✅\n    - ✅\n*   - ObjectiveBound\n    - ❌\n    - ❌\n*   - ObjectiveValue\n    - ✅\n    - ❌\n*   - RelativeGap\n    - ✅\n    - ✅\n*   - Silent\n    - ✅\n    - ✅\n*   - SimplexIterations\n    - ❌\n    - ❌\n*   - SolverName\n    - ✅\n    - ❌\n*   - SolverVersion\n    - ✅\n    - ❌\n*   - SolveTimeSec\n    - ✅\n    - ❌\n*   - TimeLimitSec\n    - ✅\n    - ✅\n:::\n\n### Supported [variable attribute](#pyoptinterface.VariableAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Value\n    - ✅\n    - ❌\n*   - LowerBound\n    - ✅\n    - ✅\n*   - UpperBound\n    - ✅\n    - ✅\n*   - Domain\n    - ✅\n    - ✅\n*   - PrimalStart\n    - ❌\n    - ✅\n*   - Name\n    - ✅\n    - ✅\n*   - IISLowerBound\n    - ❌\n    - ❌\n*   - IISUpperBound\n    - ❌\n    - ❌\n*   - ReducedCost\n    - ✅\n    - ❌\n:::\n\n### Supported [constraint attribute](#pyoptinterface.ConstraintAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Name\n    - ✅\n    - ✅\n*   - Primal\n    - ✅\n    - ❌\n*   - Dual\n    - ✅\n    - ❌\n*   - IIS\n    - ❌\n    - ❌\n:::\n\n"
  },
  {
    "path": "docs/source/attribute/xpress.md",
    "content": "### Supported [model attribute](#pyoptinterface.ModelAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Name\n    - ✅\n    - ✅\n*   - ObjectiveSense\n    - ✅\n    - ✅\n*   - DualStatus\n    - ✅\n    - ❌\n*   - PrimalStatus\n    - ✅\n    - ❌\n*   - RawStatusString\n    - ✅\n    - ❌\n*   - TerminationStatus\n    - ✅\n    - ❌\n*   - BarrierIterations\n    - ✅\n    - ❌\n*   - DualObjectiveValue\n    - ✅\n    - ❌\n*   - NodeCount\n    - ✅\n    - ❌\n*   - NumberOfThreads\n    - ✅\n    - ✅\n*   - ObjectiveBound\n    - ✅\n    - ❌\n*   - ObjectiveValue\n    - ✅\n    - ❌\n*   - RelativeGap\n    - ✅\n    - ✅\n*   - Silent\n    - ✅\n    - ✅\n*   - SimplexIterations\n    - ✅\n    - ❌\n*   - SolverName\n    - ✅\n    - ❌\n*   - SolverVersion\n    - ✅\n    - ❌\n*   - SolveTimeSec\n    - ✅\n    - ❌\n*   - TimeLimitSec\n    - ✅\n    - ✅\n:::\n\n### Supported [variable attribute](#pyoptinterface.VariableAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Value\n    - ✅\n    - ❌\n*   - LowerBound\n    - ✅\n    - ✅\n*   - UpperBound\n    - ✅\n    - ✅\n*   - Domain\n    - ✅\n    - ✅\n*   - PrimalStart\n    - ✅\n    - ✅\n*   - Name\n    - ✅\n    - ✅\n*   - IISLowerBound\n    - ✅\n    - ❌\n*   - IISUpperBound\n    - ✅\n    - ❌\n*   - ReducedCost\n    - ✅\n    - ❌\n:::\n\n### Supported [constraint attribute](#pyoptinterface.ConstraintAttribute)\n\n:::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n*   - Name\n    - ✅\n    - ✅\n*   - Primal\n    - ✅\n    - ❌\n*   - Dual\n    - ✅\n    - ❌\n*   - IIS\n    - ✅\n    - ❌\n:::\n\n"
  },
  {
    "path": "docs/source/benchmark.md",
    "content": "# Benchmark\n\n## Model construction time\n\nThe benchmark is adapted from [the JuMP paper](https://github.com/jump-dev/JuMPPaperBenchmarks). Eight optimization models with different sizes are selected as test cases, including four facility location models and four linear quadratic control problems. We conduct two rounds of benchmark using Gurobi and COPT as optimizer respectively. For each model, we measure the total time of modeling interface to generate model and pass it to the optimizer, and the time limit of optimizer is set to 0.0 seconds to avoid the influence of solution process.\n\nAll code to run the benchmarks is available at [https://github.com/metab0t/PyOptInterface_benchmark](https://github.com/metab0t/PyOptInterface_benchmark).\n\n:::{table} Time (second) to generate model and pass it to Gurobi optimizer.\n:widths: auto\n:align: center\n\n| Model     | Variables | C++  | PyOptInterface | JuMP | gurobipy | Pyomo |\n| --------- | --------- | ---- | -------------- | ---- | -------- | ----- |\n| fac-25    | 67651     | 0.2  | 0.2            | 0.2  | 1.2      | 4.1   |\n| fac-50    | 520301    | 0.8  | 1.2            | 1.8  | 9.7      | 32.7  |\n| fac-75    | 1732951   | 2.7  | 4.1            | 6.6  | 32.5     | 119.3 |\n| fac-100   | 4080601   | 6.3  | 10.0           | 17.8 | 79.1     | 286.3 |\n| lqcp-500  | 251501    | 0.9  | 1.5            | 1.3  | 6.3      | 23.8  |\n| lqcp-1000 | 1003001   | 3.7  | 6.0            | 6.1  | 26.7     | 106.6 |\n| lqcp-1500 | 2254501   | 8.3  | 14.0           | 17.7 | 61.8     | 234.0 |\n| lqcp-2000 | 4006001   | 14.5 | 24.9           | 38.3 | 106.9    | 444.1 |\n\n:::\n\n:::{table} Time (second) to generate model and pass it to COPT optimizer.\n:widths: auto\n:align: center\n\n| Model     | Variables | C++  | PyOptInterface | JuMP | coptpy | Pyomo |\n| --------- | --------- | ---- | -------------- | ---- | ------ | ----- |\n| fac-25    | 67651     | 0.3  | 0.2            | 0.3  | 0.6    | 4.1   |\n| fac-50    | 520301    | 2.2  | 1.5            | 2.7  | 5.4    | 32.8  |\n| fac-75    | 1732951   | 8.1  | 6.6            | 10.2 | 20.3   | 117.4 |\n| fac-100   | 4080601   | 22.4 | 23.4           | 30.3 | 58.0   | 284.0 |\n| lqcp-500  | 251501    | 3.8  | 3.1            | 3.0  | 6.6    | 26.4  |\n| lqcp-1000 | 1003001   | 16.0 | 15.5           | 13.9 | 28.1   | 112.1 |\n| lqcp-1500 | 2254501   | 37.6 | 32.4           | 33.7 | 64.6   | 249.3 |\n| lqcp-2000 | 4006001   | 68.2 | 60.3           | 66.2 | 118.4  | 502.4 |\n\n:::\n\nRecently, there are a lot of requests to test the performance of PyOptInterface compared with [linopy](https://github.com/PyPSA/linopy) and [cvxpy](https://github.com/cvxpy/cvxpy), so we prepare a [benchmark](https://github.com/metab0t/PyOptInterface/blob/master/bench/bench_linopy_cvxpy.py).\n\nThis is the result of benchmark, where the performance of PyOptInterface exceeds linopy and cvxpy significantly.\n\n:::{table} Time (second) to generate and solve a linear programming model with Gurobi optimizer.\n:widths: auto\n:align: center\n\n| N   | Variables | PyOptInterface | linopy   | cvxpy     |\n| --- | --------- | -------------- | -------- | --------- |\n| 100 | 20000     | 0.076867       | 0.433379 | 0.224613  |\n| 200 | 80000     | 0.356767       | 0.959883 | 0.927248  |\n| 300 | 180000    | 0.796876       | 2.080950 | 2.681649  |\n| 400 | 320000    | 1.375459       | 3.715881 | 6.174171  |\n| 500 | 500000    | 2.222600       | 6.297467 | 12.153747 |\n\n:::\n\n## Nonlinear programming\n\nWe use the AC Optimal Power Flow problem to benchmark performance of PyOptInterface against different modeling languages. The code is released at [GitHub](https://github.com/metab0t/opf_benchmark) and the result is published by our paper [Accelerating Optimal Power Flow with Structure-aware Automatic Differentiation and Code Generation](https://ieeexplore.ieee.org/document/10721402)."
  },
  {
    "path": "docs/source/callback.md",
    "content": "# Callback\n\n:::{attention}\nThe behavior of callback function highly depends on the optimizer and the specific problem. Please refer to the official documentation of the optimizer for more details.\n:::\n\nIn most optimization problems, we build the model, set the parameters, and then call the optimizer to solve the problem. However, in some cases, we may want to monitor the optimization process and intervene in the optimization process. For example, we may want to stop the optimization process when a certain condition is met, or we may want to record the intermediate results of the optimization process. In these cases, we can use the callback function. The callback function is a user-defined function that is called by the optimizer at specific points during the optimization process. Callback is especially useful for mixed-integer programming problems, where we can control the branch and bound process in callback functions.\n\nCallback is not supported for all optimizers. Currently, we only support callback for Gurobi, COPT, and Xpress optimizer. Because callback is tightly coupled with the optimizer, we choose not to implement a strictly unified API for callback. Instead, we try to unify the common parts of the callback API and aim to provide all callback features included in the vendored Python bindings.\n\nIn PyOptInterface, the callback function is simply a Python function that takes two arguments:\n- `model`: The instance of the [optimization model](model.md)\n- `where`: The flag indicates the stage of optimization process when our callback function is invoked. For Gurobi, the value of `where` is [CallbackCodes](https://www.gurobi.com/documentation/current/refman/cb_codes.html#sec:CallbackCodes). For COPT, the value of `where` is called as [callback contexts](https://guide.coap.online/copt/en-doc/callback.html) such as `COPT.CBCONTEXT_MIPNODE` and `COPT.CBCONTEXT_MIPRELAX`. For Xpress, the `where` value corresponds to specific callback points such as `XPRS.CB_CONTEXT.PREINTSOL` or `XPRS.CB_CONTEXT.OPTNODE`. A description of supported Xpress callbacks can be found [here](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML/chapter5.html?scroll=section5002).\n\nIn the function body of the callback function, we can do the following four kinds of things:\n- Query the current information of the optimization process. For scalar information, we can use `model.cb_get_info` function to get the information, and its argument is the value of [`what`](https://www.gurobi.com/documentation/current/refman/cb_codes.html) in Gurobi and the value of [callback information](https://guide.coap.online/copt/en-doc/information.html#chapinfo-cbc) in COPT. For Xpress, use regular attribute access methods such as `model.get_raw_attribute`. For array information such as the MIP solution or relaxation, PyOptInterface provides special functions such as `model.cb_get_solution` and `model.cb_get_relaxation`.\n- Add lazy constraint: Use `model.cb_add_lazy_constraint` just like `model.add_linear_constraint` except for the `name` argument.\n- Add user cut: Use `model.cb_add_user_cut` just like `model.add_linear_constraint` except for the `name` argument.\n- Set a heuristic solution: Use `model.cb_set_solution` to set individual values of variables and use `model.cb_submit_solution` to submit the solution to the optimizer immediately (`model.cb_submit_solution` will be called automatically in the end of callback if `model.cb_set_solution` is called).\n- Terminate the optimizer: Use `model.cb_exit`.\n\nHere is an example of a callback function that stops the optimization process when the objective value reaches a certain threshold:\n\n```python\nimport pyoptinterface as poi\nfrom pyoptinterface import gurobi, copt, xpress\n\nGRB = gurobi.GRB\nCOPT = copt.COPT\nXPRS = xpress.XPRS\n\ndef cb_gurobi(model, where):\n    if where == GRB.Callback.MIPSOL:\n        obj = model.cb_get_info(GRB.Callback.MIPSOL_OBJ)\n        if obj < 10:\n            model.cb_exit()\n            \ndef cb_copt(model, where):\n    if where == COPT.CBCONTEXT_MIPSOL:\n        obj = model.cb_get_info(\"MipCandObj\")\n        if obj < 10:\n            model.cb_exit()\n\ndef cb_xpress(model, where):\n    if where == XPRS.CB_CONTEXT.PREINTSOL:\n        obj = model.get_raw_attribute(\"LPOBJVAL\")\n        if obj < 10:\n            model.cb_exit()\n```\n\nTo use the callback function, we need to call `model.set_callback(cb)` to pass the callback function to the optimizer. For COPT and Xpress, `model.set_callback` needs an additional argument `where` to specify the context where the callback function is invoked. For Gurobi, the `where` argument is not needed.\n\n```python\nmodel_gurobi = gurobi.Model()\nmodel_gurobi.set_callback(cb_gurobi)\n\nmodel_copt = copt.Model()\nmodel_copt.set_callback(cb_copt, COPT.CBCONTEXT_MIPSOL)\n# callback can also be registered for multiple contexts\nmodel_copt.set_callback(cb_copt, COPT.CBCONTEXT_MIPSOL + COPT.CBCONTEXT_MIPNODE)\n\nmodel_xpress = xpress.Model()\nmodel_xpress.set_callback(cb_xpress, XPRS.CB_CONTEXT.PREINTSOL)\n# callback can also be registered for multiple contexts\nmodel_xpress.set_callback(cb_xpress, XPRS.CB_CONTEXT.PREINTSOL + XPRS.CB_CONTEXT.CUTROUND)\n```\n\nIn order to help users to migrate code using gurobipy, coptpy, and Xpress Python to PyOptInterface, we list a translation table as follows.\n\n:::{table} Callback in gurobipy and PyOptInterface\n:align: left\n\n| gurobipy                               | PyOptInterface                                          |\n| -------------------------------------- | ------------------------------------------------------- |\n| `model.optimize(cb)`                   | `model.set_callback(cb) `                               |\n| `model.cbGet(GRB.Callback.SPX_OBJVAL)` | `model.cb_get_info(GRB.Callback.SPX_OBJVAL)`            |\n| `model.cbGetSolution(var)`             | `model.cb_get_solution(var)`                            |\n| `model.cbGetNodelRel(var)`             | `model.cb_get_relaxation(var)`                          |\n| `model.cbLazy(x[0] + x[1] <= 3)`       | `model.cb_add_lazy_constraint(x[0] + x[1], poi.Leq, 3)` |\n| `model.cbCut(x[0] + x[1] <= 3)`        | `model.cb_add_user_cut(x[0] + x[1], poi.Leq, 3)`        |\n| `model.cbSetSolution(x, 1.0)`          | `model.cb_set_solution(x, 1.0)`                         |\n| `objval = model.cbUseSolution()`       | `objval = model.cb_submit_solution()`                   |\n| `model.termimate()`                    | `model.cb_exit()`                                       |\n:::\n\n\n:::{table} Callback in coptpy and PyOptInterface\n:align: left\n\n| coptpy                                         | PyOptInterface                                          |\n| ---------------------------------------------- | ------------------------------------------------------- |\n| `model.setCallback(cb, COPT.CBCONTEXT_MIPSOL)` | `model.set_callback(cb, COPT.CBCONTEXT_MIPSOL)`         |\n| `CallbackBase.getInfo(COPT.CbInfo.BestBnd)`    | `model.cb_get_info(COPT.CbInfo.BestBnd)`                |\n| `CallbackBase.getSolution(var)`                | `model.cb_get_solution(var)`                            |\n| `CallbackBase.getRelaxSol(var)`                | `model.cb_get_relaxation(var)`                          |\n| `CallbackBase.getIncumbent(var)`               | `model.cb_get_incumbent(var)`                           |\n| `CallbackBase.addLazyConstr(x[0] + x[1] <= 3)` | `model.cb_add_lazy_constraint(x[0] + x[1], poi.Leq, 3)` |\n| `CallbackBase.addUserCut(x[0] + x[1] <= 3)`    | `model.cb_add_user_cut(x[0] + x[1], poi.Leq, 3)`        |\n| `CallbackBase.setSolution(x, 1.0) `            | `model.cb_set_solution(x, 1.0)`                         |\n| `CallbackBase.loadSolution()`                  | `model.cb_submit_solution()`                            |\n| `CallbackBase.interrupt()`                     | `model.cb_exit()`                                       |\n:::\n\n:::{table} Callback in Xpress Python and PyOptInterface\n:align: left\n| Xpress Python                                          | PyOptInterface                                                |\n| ------------------------------------------------------ | ------------------------------------------------------------- |\n| `model.addPreIntsolCallback(cb)`                       | `model.set_callback(cb, XPRS.CB_CONTEXT.PREINTSOL)`           |\n| `model.attributes.bestbound`                           | `model.get_raw_attribute(\"BESTBOUND\")`                        |\n| `model.getCallbackSolution(var)`                       | `model.cb_get_solution(var)`                                  |\n| `model.getCallbackSolution(var)`                       | `model.cb_get_relaxation(var)`                                |\n| `model.getSolution(var)`                               | `model.cb_get_incumbent(var)`                                 |\n| `model.addCuts(0, 'L', 3, [0], [0, 1], [1, 1])`        | `model.cb_add_lazy_constraint(x[0] + x[1], poi.Leq, 3)`       |\n| `model.addManagedCuts(1, 'L', 3, [0], [0, 1], [1, 1])` | `model.cb_add_user_cut(x[0] + x[1], poi.Leq, 3)`              |\n| `model.addMipSol([x], [1.0])`                          | `model.cb_set_solution(x, 1.0)` + `model.cb_submit_solution()` |\n| `model.interrupt()`                                    | `model.cb_exit()`                                             |\n:::\n\nFor a detailed example to use callbacks in PyOptInterface, we provide a [concrete callback example](https://github.com/metab0t/PyOptInterface/blob/master/tests/tsp_cb.py) to solve the Traveling Salesman Problem (TSP) with callbacks in PyOptInterface, gurobipy, coptpy, and Xpress Python. The example is adapted from the official Gurobi example [tsp.py](https://www.gurobi.com/documentation/current/examples/tsp_py.html).\n"
  },
  {
    "path": "docs/source/changelog.md",
    "content": "# Changelog\n\n## 0.6.1\n- Fix some bugs in Mosek interface\n- Update documentation of Knitro\n\n## 0.6.0\n- Add support for KNITRO solver, including nonlinear optimization, callbacks, license management, and documentation\n- Add support for Xpress solver, including linear, quadratic, NLP, callbacks, and reduced cost support\n- Add `ReducedCost` variable attribute\n- Add checks in IpoptModel to raise an error when accessing variable values, objective value, constraint primal or dual before calling `optimize()` or after modifying the model\n- Fix the sign of dual multiplier in IPOPT\n- Fix Hessian matrix ordering in HiGHS (sort elements in the same column by row number)\n- Fix initial value of nonlinear optimization in COPT\n- Fix `poi.ExprBuilder` operation with itself\n- Allow `poi.quicksum` for high dimensional numpy array directly without needing `.flat`\n- Support Gurobi 13, COPT 8, HiGHS 1.12\n- Support finding Gurobi in pixi environment\n- Update CppAD to 20260000 and fmt to 12.1.0\n\n## 0.5.1\n- Support llvmlite 0.45.0\n\n## 0.5.0\n- Overhaul of the nonlinear programming interface and now PyOptInterface can solve nonlinear programming problems with COPT, Gurobi and IPOPT.\n- Use `model.add_linear_constraint(x+y, (1.0, 2.0))` to add two-sided linear constraints\n- Add `poi.ScalarAffineFunction.from_numpy` to create scalar affine functions from numpy arrays quickly\n\n## 0.4.1\n- Support writing solution files in HiGHS\n- Pass the names of variables and constraints to HiGHS\n- Add `model.close()` and `env.close()` methods to allow users release the license of commercial solvers manually\n\n## 0.4.0\n- Add `model.add_m_variables` and `model.add_m_linear_constraints` matrix modeling API\n- Add `model.computeIIS` and IIS related attributes for constraint and variable\n- Implement constraint based on compare operators, now you can use `model.add_linear_constraint(x + y <= 1.0)` directly\n- Drop support for Python 3.8\n- Add wheels for Linux ARM64\n- Supports HiGHS 1.9.0 and Mosek 11\n\n## 0.3.0\n- Add `model.set_variable_bounds(variable, lb, ub)` to make it easier to change variable bounds\n- Introduce nonlinear programming support of Ipopt\n- Support new versions of optimizers\n- Various minor bug fixes\n\n## 0.2.8\n- Fix bugs in HiGHS and MOSEK when the quadratic objective function contains nondiagonal terms\n\n## 0.2.7\n- Fix bugs in HiGHS termination status\n\n## 0.2.6\n- Add rotated second-order cone support for COPT, Gurobi and Mosek\n- Add exponential cone support for COPT and Mosek\n- Requires COPT version >= 7.1.4 to support exponential cone\n\n## 0.2.5\n- Fix `add_linear_constraint` of HiGHS optimizer to consider the constant term in expression correctly\n- Make `make_tupledict` slightly faster\n\n## 0.2.4\n- Add `map` method for `tupledict` class\n- Add type stubs for C++ extension modules \n\n## 0.2.3\n- Fix a bug when deleting constraint in HiGHS\n\n## 0.2.2\n- Fix the performance issue with HiGHS optimizer\n\n## 0.2.1\n- Fix the DLL search paths on Windows\n\n## 0.2.0\n- Supports callback for Gurobi and COPT\n- Release GIL when calling `model.optimize()`\n\n## 0.1.1\n- Add `Model.write` method to write model to files\n\n## 0.1.0\n- First release on PyPI"
  },
  {
    "path": "docs/source/common_model_interface.md",
    "content": "# Common Model Interface\n\nGenerally speaking, the following APIs are common to all optimizers except for adding constraint\nbecause different optimizers may support different types of constraints.\n\n## Model\n\n### Get/set model attributes\n\n```{py:function} model.set_model_attribute(attr, value)\n\nset the value of a model attribute\n\n:param pyoptinterface.ModelAttribute attr: the attribute to set\n:param value: the value to set\n```\n\n```{py:function} model.get_model_attribute(attr)\n\nget the value of a model attribute\n\n:param pyoptinterface.ModelAttribute attr: the attribute to get\n:return: the value of the attribute\n```\n\n## Variable\n\n### Add a variable to the model\n\n```{py:function} model.add_variable([lb=-inf, ub=+inf, domain=pyoptinterface.VariableDomain.Continuous, name=\"\"])\n\nadd a variable to the model\n\n:param float lb: the lower bound of the variable, optional, defaults to $-\\infty$\n:param float ub: the upper bound of the variable, optional, defaults to $+\\infty$\n:param pyoptinterface.VariableDomain domain: the domain of the variable, optional, defaults to \ncontinuous\n:param str name: the name of the variable, optional\n:return: the handle of the variable\n```\n\n### Add multidimensional variables to the model as <project:#pyoptinterface.tupledict>\n\n```{py:function} model.add_variables(*coords, [lb=-inf, ub=+inf, domain=pyoptinterface.VariableDomain.Continuous, name=\"\"])\n\nadd a multidimensional variable to the model\n\n:param coords: the coordinates of the variable, can be a list of Iterables\n:param float lb: the lower bound of the variable, optional, defaults to $-\\infty$\n:param float ub: the upper bound of the variable, optional, defaults to $+\\infty$\n:param pyoptinterface.VariableDomain domain: the domain of the variable, optional, defaults to \ncontinuous\n:param str name: the name of the variable, optional\n:return: the multi-dimensional variable\n:rtype: pyoptinterface.tupledict\n```\n\n### Add multidimensional variables to the model as `numpy.ndarray`\n\n```{py:function} model.add_m_variables(shape, [lb=-inf, ub=+inf, domain=pyoptinterface.VariableDomain.Continuous, name=\"\"])\n\nadd a multidimensional variable to the model as `numpy.ndarray`\n\n:param shape: the shape of the variable, can be a tuple of integers or an integer\n:param float lb: the lower bound of the variable, optional, defaults to $-\\infty$\n:param float ub: the upper bound of the variable, optional, defaults to $+\\infty$\n:param pyoptinterface.VariableDomain domain: the domain of the variable, optional, defaults to \ncontinuous\n:param str name: the name of the variable, optional\n:return: the multidimensional variable\n:rtype: numpy.ndarray\n```\n\n### Get/set variable attributes\n\n```{py:function} model.set_variable_attribute(var, attr, value)\n\nset the value of a variable attribute\n\n:param var: the handle of the variable\n:param pyoptinterface.VariableAttribute attr: the attribute to set\n:param value: the value to set\n```\n\n```{py:function} model.get_variable_attribute(var, attr)\n\nget the value of a variable attribute\n\n:param var: the handle of the variable\n:param pyoptinterface.VariableAttribute attr: the attribute to get\n:return: the value of the attribute\n```\n\n### Delete variable\n\n```{py:function} model.delete_variable(var)\n\ndelete a variable from the model\n\n:param var: the handle of the variable\n```\n\n```{py:function} model.is_variable_active(var)\n\nquery whether a variable is active\n\n:param var: the handle of the variable\n:return: whether the variable is active\n:rtype: bool\n```\n\n### Modify the bounds of variable\n\n```{py:function} model.set_variable_bounds(var, lb, ub)\n\nset the lower and upper bounds of a variable\n\n:param var: the handle of the variable\n:param float lb: the new lower bound value\n:param float ub: the new upper bound value\n```\n\n## Expression\n\n### Get the value of an expression (including variable)\n\n```{py:function} model.get_value(expr_or_var)\n\nget the value of an expression or a variable after optimization\n\n:param expr_or_var: the handle of the expression or the variable\n:return: the value of the expression or the variable\n:rtype: float\n```\n\n### Pretty print expression (including variable)\n\n```{py:function} model.pprint(expr_or_var)\n\npretty print an expression in a human-readable format\n\n:param expr_or_var: the handle of the expression or the variable\n:return: the human-readable format of the expression\n:rtype: str\n```\n\n## Constraint\n\n### Add a constraint to the model\n\n- <project:#model.add_linear_constraint>\n- <project:#model.add_quadratic_constraint>\n- <project:#model.add_second_order_cone_constraint>\n- <project:#model.add_sos_constraint>\n\n### Add linear constraints as matrix form to the model\n\n```{py:function} model.add_m_linear_constraints(A, vars, sense, b, [name=\"\"])\n\nadd linear constraints as matrix form to the model $Ax \\le b$ or $Ax = b$ or $Ax \\ge b$\n\n:param A: the matrix of coefficients, can be a dense `numpy.ndarray` or a sparse matrix `scipy.sparse.sparray`\n:param vars: the variables in the constraints, can be a list or a 1-d `numpy.ndarray` returned by `add_m_variables`\n:param pyoptinterface.ConstraintSense sense: the sense of the constraints\n:param b: the right-hand side of the constraints, should be a 1-d `numpy.ndarray`\n:param str name: the name of the constraints, optional\n:return: the handles of linear constraints\n:rtype: numpy.ndarray\n```\n\n### Get/set constraint attributes\n\n```{py:function} model.set_constraint_attribute(con, attr, value)\n\nset the value of a constraint attribute\n\n:param con: the handle of the constraint\n:param pyoptinterface.ConstraintAttribute attr: the attribute to set\n:param value: the value to set\n```\n\n```{py:function} model.get_constraint_attribute(con, attr)\n\nget the value of a constraint attribute\n\n:param con: the handle of the constraint\n:param pyoptinterface.ConstraintAttribute attr: the attribute to get\n:return: the value of the attribute\n```\n\n### Delete constraint\n\n```{py:function} model.delete_constraint(con)\n\ndelete a constraint from the model\n\n:param con: the handle of the constraint\n```\n\n```{py:function} model.is_constraint_active(con)\n\nquery whether a constraint is active\n\n:param con: the handle of the constraint\n:return: whether the variable is active\n:rtype: bool\n```\n\n### Modify constraint\n\n```{py:function} model.set_normalized_rhs(con, value)\n\nset the right-hand side of a normalized constraint\n\n:param con: the handle of the constraint\n:param value: the new right-hand side value\n```\n\n```{py:function} model.get_normalized_rhs(con)\n\nget the right-hand side of a normalized constraint\n\n:param con: the handle of the constraint\n:return: the right-hand side value\n```\n\n```{py:function} model.set_normalized_coefficient(con, var, value)\n\nset the coefficient of a variable in a normalized constraint\n\n:param con: the handle of the constraint\n:param var: the handle of the variable\n:param value: the new coefficient value\n```\n\n```{py:function} model.get_normalized_coefficient(con, var)\n\nget the coefficient of a variable in a normalized constraint\n\n:param con: the handle of the constraint\n:param var: the handle of the variable\n:return: the coefficient value\n```\n\n## Objective\n\n### Set the objective function\n\n```{py:function} model.set_objective(expr, [sense=pyoptinterface.ObjectiveSense.Minimize])\n\nset the objective function of the model\n\n:param expr: the handle of the expression\n:param pyoptinterface.ObjectiveSense sense: the sense of the objective function (Minimize/Maximize), defaults to Minimize\n```\n\n### Modify the linear part of the objective function\n\n```{py:function} model.set_objective_coefficient(var, value)\n\nmodify the coefficient of a variable in the linear part of the objective function\n\n:param var: the handle of the variable\n:param float value: the new coefficient value\n```\n\n```{py:function} model.get_objective_coefficient(var)\n\nget the coefficient of a variable in the linear part of the objective function\n\n:param var: the handle of the variable\n:return: the coefficient value\n```"
  },
  {
    "path": "docs/source/conf.py",
    "content": "# Configuration file for the Sphinx documentation builder.\n#\n# For the full list of built-in configuration values, see the documentation:\n# https://www.sphinx-doc.org/en/master/usage/configuration.html\n\n# -- Project information -----------------------------------------------------\n# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information\n\nproject = \"PyOptInterface\"\ncopyright = \"2024, Yue Yang\"\nauthor = \"Yue Yang\"\n\n# -- General configuration ---------------------------------------------------\n# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration\n\nextensions = [\n    \"sphinx.ext.autodoc\",\n    \"sphinx.ext.githubpages\",\n    \"sphinx_copybutton\",\n    \"myst_nb\",\n]\n\nsource_suffix = {\n    \".rst\": \"restructuredtext\",\n    \".ipynb\": \"myst-nb\",\n    \".md\": \"myst-nb\",\n}\n\nmyst_enable_extensions = [\"colon_fence\", \"amsmath\", \"dollarmath\", \"fieldlist\"]\n\ntemplates_path = [\"_templates\"]\nexclude_patterns = []\n\n\n# -- Options for HTML output -------------------------------------------------\n# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output\n\nhtml_theme = \"furo\"\nhtml_static_path = [\"_static\"]\n"
  },
  {
    "path": "docs/source/constraint.md",
    "content": "---\nfile_format: mystnb\nkernelspec:\n  name: python3\n---\n# Constraint\n\nPyOptInterface supports the following types of constraints:\n\n- Linear Constraint\n- Quadratic Constraint\n- Second-Order Cone Constraint\n- Special Ordered Set (SOS) Constraint\n\n:::{note}\n\nNot all optimizers support all types of constraints. Please refer to the documentation of the\noptimizer you are using to see which types of constraints are supported.\n:::\n\n```{code-cell}\nimport pyoptinterface as poi\nfrom pyoptinterface import copt\n\nmodel = copt.Model()\n```\n\n## Constraint Sense\n\nThe sense of a constraint can be one of the following:\n\n- `poi.Eq`: equal\n- `poi.Leq`: less than or equal\n- `poi.Geq`: greater than or equal\n\nThey are the abbreviations of `poi.ConstraintSense.Equal`, `poi.ConstraintSense.LessEqual` or `poi.ConstraintSense.GreaterEqual` and can be used in the `sense` argument of the constraint creation functions.\n\n## Linear Constraint\nIt is defined as:\n\n$$\n\\begin{align}\n    \\text{expr} &= a^T x + b &\\leq \\text{rhs} \\\\\n    \\text{expr} &= a^T x + b &= \\text{rhs} \\\\\n    \\text{expr} &= a^T x + b &\\geq \\text{rhs}\n\\end{align}\n$$\n\nIt can be added to the model using the `add_linear_constraint` method of the `Model` class.\n\n```{code-cell}\nx = model.add_variable(name=\"x\")\ny = model.add_variable(name=\"y\")\n\ncon = model.add_linear_constraint(2.0*x + 3.0*y, poi.Leq, 1.0)\n```\n\n```{py:function} model.add_linear_constraint(expr, sense, rhs, [name=\"\"])\n\nadd a linear constraint to the model\n\n:param expr: the expression of the constraint\n:param pyoptinterface.ConstraintSense sense: the sense of the constraint\n:param float rhs: the right-hand side of the constraint\n:param str name: the name of the constraint, optional\n:return: the handle of the constraint\n```\n\n:::{note}\n\nPyOptInterface provides <project:#pyoptinterface.Eq>, <project:#pyoptinterface.Leq>, and <project:#pyoptinterface.Geq> as alias of <project:#pyoptinterface.ConstraintSense> to represent the sense of the constraint with a shorter name.\n:::\n\nThe linear constraint can also be created with a comparison operator, like `<=`, `==`, or `>=`:\n\n```{code-cell}\nmodel.add_linear_constraint(2.0*x + 3.0*y <= 1.0)\nmodel.add_linear_constraint(2.0*x + 3.0*y == 1.0)\nmodel.add_linear_constraint(2.0*x + 3.0*y >= 1.0)\n```\n\nIf you want to express a two-sided linear constraint, you can use the `add_linear_constraint` method with a tuple to represent the left-hand side and right-hand side of the constraint like:\n\n```{code-cell}\nmodel.add_linear_constraint(2.0*x + 3.0*y, (1.0, 2.0))\n```\n\nwhich is equivalent to:\n```{code-cell}\nmodel.add_linear_constraint(2.0*x + 3.0*y, poi.Leq, 2.0)\nmodel.add_linear_constraint(2.0*x + 3.0*y, poi.Geq, 1.0)\n```\n\n:::{note}\n\nThe two-sided linear constraint is not implemented for Gurobi because of its [special handling of range constraints](https://docs.gurobi.com/projects/optimizer/en/12.0/reference/c/model.html#c.GRBaddrangeconstr).\n:::\n\n## Quadratic Constraint\nLike the linear constraint, it is defined as:\n\n$$\n\\begin{align}\n    \\text{expr} &= x^TQx + a^Tx + b &\\leq \\text{rhs} \\\\\n    \\text{expr} &= x^TQx + a^Tx + b &= \\text{rhs} \\\\\n    \\text{expr} &= x^TQx + a^Tx + b &\\geq \\text{rhs}\n\\end{align}\n$$\n\nIt can be added to the model using the `add_quadratic_constraint` method of the `Model` class.\n\n```{code-cell}\nx = model.add_variable(name=\"x\")\ny = model.add_variable(name=\"y\")\n\nexpr = x*x + 2.0*x*y + 4.0*y*y\ncon = model.add_quadratic_constraint(expr, poi.ConstraintSense.LessEqual, 1.0)\n```\n\n```{py:function} model.add_quadratic_constraint(expr, sense, rhs, [name=\"\"])\n\nadd a quadratic constraint to the model\n\n:param expr: the expression of the constraint\n:param pyoptinterface.ConstraintSense sense: the sense of the constraint, which can be `GreaterEqual`, `Equal`, or `LessEqual`\n:param float rhs: the right-hand side of the constraint\n:param str name: the name of the constraint, optional\n:return: the handle of the constraint\n```\n\nSimilarly, the quadratic constraint can also be created with a comparison operator, like `<=`, `==`, or `>=`:\n\n```python\nmodel.add_quadratic_constraint(x*x + 2.0*x*y + 4.0*y*y <= 1.0)\nmodel.add_quadratic_constraint(x*x + 2.0*x*y + 4.0*y*y == 1.0)\nmodel.add_quadratic_constraint(x*x + 2.0*x*y + 4.0*y*y >= 1.0)\n```\n\n:::{note}\n\nSome solvers like COPT (as of 7.2.9) only supports convex quadratic constraints, which means the quadratic term must be positive semidefinite. If you try to add a non-convex quadratic constraint, an exception will be raised.\n:::\n\nThe two-sided quadratic constraint can also be created with a tuple to represent the left-hand side and right-hand side of the constraint like:\n\n```python\nmodel.add_quadratic_constraint(x*x + 2.0*x*y + 4.0*y*y, (1.0, 2.0))\n```\n:::{note}\n\nCurrently, two-sided quadratic constraint is only implemented for IPOPT.\n:::\n\n## Second-Order Cone Constraint\nIt is defined as:\n\n$$\nvariables=(t,x) \\in \\mathbb{R}^{N} : t \\ge \\lVert x \\rVert_2\n$$\n\nIt can be added to the model using the `add_second_order_cone_constraint` method of the `Model` \nclass.\n\n```{code-cell}\nN = 6\nvars = [model.add_variable() for i in range(N)]\n\ncon = model.add_second_order_cone_constraint(vars)\n```\n\nThere is another form of second-order cone constraint called as rotated second-order cone constraint, which is defined as:\n\n$$\nvariables=(t_{1},t_{2},x) \\in \\mathbb{R}^{N} : 2 t_1 t_2 \\ge \\lVert x \\rVert_2^2\n$$\n\n```{py:function} model.add_second_order_cone_constraint(variables, [name=\"\", rotated=False])\n\nadd a second order cone constraint to the model\n\n:param variables: the variables of the constraint, can be a list of variables\n:param str name: the name of the constraint, optional\n:param bool rotated: whether the constraint is a rotated second-order cone constraint, optional\n:return: the handle of the constraint\n```\n\n## Exponential Cone Constraint\nIt is defined as:\n\n$$\nvariables=(t,s,r) \\in \\mathbb{R}^{3} : t \\ge s \\exp(\\frac{r}{s}), s \\ge 0\n$$\n\nThe dual form is:\n\n$$\nvariables=(t,s,r) \\in \\mathbb{R}^{3} : t \\ge -r \\exp(\\frac{s}{r} - 1), r \\le 0\n$$\n\nCurrently, only COPT(after 7.1.4), Mosek support exponential cone constraint natively. \nXpress supports exponential cones by mapping them into generic NLP formulas at the API level. \nIt can be added to the model using the `add_exp_cone_constraint` method of the `Model` class.\n\n```{py:function} model.add_exp_cone_constraint(variables, [name=\"\", dual=False])\n\nadd a second order cone constraint to the model\n\n:param variables: the variables of the constraint, can be a list of variables\n:param str name: the name of the constraint, optional\n:param bool dual: whether the constraint is dual form of exponential cone, optional\n:return: the handle of the constraint\n```\n\n## Special Ordered Set (SOS) Constraint\nSOS constraints are used to model special structures in the optimization problem.\nIt contains two types: `SOS1` and `SOS2`, the details can be found in [Wikipedia](https://en.wikipedia.org/wiki/Special_ordered_set).\n\nIt can be added to the model using the `add_sos_constraint` method of the `Model` class.\n\n```{code-cell}\nN = 6\nvars = [model.add_variable(domain=poi.VariableDomain.Binary) for i in range(N)]\n\ncon = model.add_sos_constraint(vars, poi.SOSType.SOS1)\n```\n\n```{py:function} model.add_sos_constraint(variables, sos_type, [weights])\n\nadd a special ordered set constraint to the model\n\n:param variables: the variables of the constraint, can be a list of variables\n:param pyoptinterface.SOSType sos_type: the type of the SOS constraint, which can be `SOS1` or `SOS2`\n:param weights: the weights of the variables, optional, will be set to 1 if not provided\n:type weights: list[float]\n:return: the handle of the constraint\n```\n\n## Constraint Attributes\nAfter a constraint is created, we can query or modify its attributes. The following table lists the \nstandard [constraint attributes](#pyoptinterface.ConstraintAttribute):\n\n:::{list-table} **Standard [constraint attributes](#pyoptinterface.ConstraintAttribute)**\n:header-rows: 1\n:widths: 20 20\n\n*   - Attribute name\n    - Type\n*   - Name\n    - str\n*   - Primal\n    - float\n*   - Dual\n    - float\n*   - IIS\n    - bool\n:::\n\nThe most common attribute we will use is the `Dual` attribute, which represents the dual multiplier of the constraint after optimization.\n\n```python\n# get the dual multiplier of the constraint after optimization\ndual = model.get_constraint_attribute(con, poi.ConstraintAttribute.Dual)\n```\n\n## Delete constraint\nWe can delete a constraint by calling the `delete_constraint` method of the model:\n\n```python\nmodel.delete_constraint(con)\n```\n\nAfter a constraint is deleted, it cannot be used in the model anymore, otherwise an exception \nwill be raised.\n\nWe can query whether a constraint is active by calling the `is_constraint_active` method of the \nmodel:\n\n```python\nis_active = model.is_constraint_active(con)\n```\n\n## Modify constraint\nFor linear and quadratic constraints, we can modify the right-hand side of a constraint by \ncalling the `set_normalized_rhs` method of the model.\n\nFor linear constraints, we can modify the coefficients of the linear part of the constraint by\ncalling the `set_normalized_coefficient` method of the model.\n\n```python\ncon = model.add_linear_constraint(x + y, poi.Leq, 1.0)\n\n# modify the right-hand side of the constraint\nmodel.set_normalized_rhs(con, 2.0)\n\n# modify the coefficient of the linear part of the constraint\nmodel.set_normalized_coefficient(con, x, 2.0)\n```\n"
  },
  {
    "path": "docs/source/container.md",
    "content": "---\nfile_format: mystnb\nkernelspec:\n  name: python3\n---\n\n# Container\n\nIn our previous examples, we only use scalar variable, constraint and expression. However, in many cases, we need to handle a large number of variables, constraints and expressions.\n\nIn general, PyOptInterface does not restrict the ways to store these objects. You can use a list, a dictionary, or any other data structure to store them, because PyOptInterface only requires the handle of the object to manipulate it and each handle is a compact C++ object that can be easily stored and passed around. In other words, we follow the Bring Your Own Container (BYOC) principle.\n\nHowever, in the context of optimization, we often needs to represent the model in a more structured way. The most classic example is [`Set`](https://ampl.com/wp-content/uploads/Chapter-5-Simple-Sets-and-Indexing-AMPL-Book.pdf) in AMPL, which provides a flexible way to represent multi-dimensional data with custom indexing. The concept is also widely used in other optimization modeling languages, such as [JuMP](https://jump.dev/JuMP.jl/stable/manual/containers/) in Julia and [Pyomo](https://pyomo.readthedocs.io/en/stable/pyomo_modeling_components/Sets.html) in Python.\n\nIn PyOptInterface, we provide a simple container named `tupledict` to represent multidimensional data. It is a dictionary-like object that can be indexed by multiple keys. It is a convenient way to store and manipulate multi-dimensional data in PyOptInterface. The design and usage of `tupledict` is inspired by the `tupledict` in [gurobipy](https://www.gurobi.com/documentation/current/refman/py_tupledict.html).\n\nWe will use `tupledict` to demonstrate how to use a container to store and manipulate multi-dimensional data in PyOptInterface.\n\nSimply speaking, `tupledict` is a derived class of Python dict where the keys represent multidimensional indices as n-tuple, and the values are typically variables, constraints or expressions.\n\n## Create a `tupledict`\n`tuplelist` can be created by calling the `tupledict` constructor. The following example creates a `tupledict` with two keys:\n\n```{code-cell}\nimport pyoptinterface as poi\n\ntd = poi.tupledict()\ntd[1, 2] = 3\ntd[4, 5] = 6\n\nprint(td)\n```\n\nIt can also be created by passing a dictionary to the constructor:\n\n```{code-cell}\ntd = poi.tupledict({(1, 2): 3, (4, 5): 6})\n```\n\nIn most cases, we have multiple indices as the axis and define a rule to construct the `tupledict`. `make_tupledict` provide a convenient way to create a `tupledict` from a list of indices and a function that maps the indices to the values. The following example creates a `tupledict` with two keys:\n\n```{code-cell}\nI = range(3)\nJ = [6, 7]\nK = (\"Asia\", \"Europe\")\n\ndef f(i, j, k):\n    return f\"value_{i}_{j}_{k}\"\n\ntd = poi.make_tupledict(I, J, K, rule=f)\n\nprint(td)\n```\n\nSometimes we need to create a `tupledict` with a sparse pattern where some combinations of indices are missing. `make_tupledict` also provides a convenient way to create a `tupledict` with a sparse pattern, you only need to return `None` when the corresponding value is unwanted. The following example creates a `tupledict` with a sparse pattern:\n\n```{code-cell}\nI = range(3)\nJ = [6, 7]\nK = (\"Asia\", \"Europe\")\n\ndef f(i, j, k):\n    if i == 0 and j == 6 and k == \"Asia\":\n        return \"value_0_6_Asia\"\n    else:\n        return None\n\ntd = poi.make_tupledict(I, J, K, rule=f)\n    \nprint(td)\n```\n\nFor highly sparse patterns, you can provide the sparse indices directly to make it more efficient.\n\n```\nI = range(2)\nJ = range(8)\nK = range(8)\n\n# We only want to construct (i, j, k) where j=k\nJK = [(j, j) for j in J]\n\ndef f(i, j, k):\n    return f\"value_{i}_{j}_{k}\"\n\n# JK will be flattened as j and k during construction\ntd = poi.make_tupledict(I, JK, rule=f)\n\nprint(td)\n```\n\n## Set/get values\nLike normal dictionary in Python, the values of a `tupledict` can be set or get by using the `[]` operator. The following example sets and gets the values of a `tupledict`:\n\n```{code-cell}\ntd = poi.tupledict({(1, 2): 3, (4, 5): 6})\ntd[1, 2] = 4\nprint(f\"{td[1, 2]=}\")\n\ntd[4, 8] = 7\nprint(f\"{td[4, 8]=}\")\n```\n\nAs a representation of multidimensional data, `tupledict` also provides a way to iterate some axis efficiently.\n`tupledict.select` can be used to select a subset of the `tupledict` by fixing some indices. The following example selects a subset of the `tupledict`: \n\n```{code-cell}\n\ntd = poi.make_tupledict(range(3), range(3), range(3), rule=lambda i, j, k: f\"value_{i}_{j}_{k}\")\n\n# Select the subset where i=1\n# \"*\" means wildcard that matches any value for j and k\n# select returns a generator and can be converted to a list\nsubset_values_iterator = td.select(1, \"*\", \"*\")\nsubset_values = list(subset_values_iterator)\n\n# Select the subset where j=2 and k=1\nsubset_values = list(td.select(\"*\", 2, 1))\n\n# the iterator can retuen the (key, value) pair if we pass with_key=True to select\nsubset_kv_iterator = td.select(1, \"*\", \"*\", with_key=True)\n```\n\n## Apply a function to values with `map` method\n`tupledict` provides a `map` method to apply a function to each value in the `tupledict`. The following example applies a function to each value in the `tupledict`:\n\n```{code-cell}\ntd = poi.make_tupledict(range(3), range(2), rule=lambda i, j: i+j)\ntd_new = td.map(lambda x: x*x)\ntd, td_new\n```\n\n## Building a model with `tupledict`\n`tupledict` can be used to store and manipulate multi-dimensional variables, constraints and expressions. Using it correctly will make building model more easily.\n\nThe following example demonstrates how to use `tupledict` to build a model:\n\n$$\n\n\\min \\quad & \\sum_{i=0}^{I} \\sum_{j=0}^{J} x_{ij}^2 \\\\\n\\textrm{s.t.}  \\quad & \\sum_{i=0}^{I} x_{ij} = 1, \\quad \\forall j \\\\\n                \\quad & x_{ij} \\geq 0, \\quad \\forall i, j\n\n$$\n\n```{code-cell}\nimport pyoptinterface as poi\nfrom pyoptinterface import highs\n\nmodel = highs.Model()\n\nI = range(10)\nJ = range(20)\n\nx = poi.make_tupledict(I, J, rule=lambda i, j: model.add_variable(lb=0, name=f\"x({i},{j})\"))\n\ndef constraint_rule(j):\n    expr = poi.quicksum(x.select(\"*\", j))\n    con = model.add_linear_constraint(expr, poi.ConstraintSense.Equal, 1, name=f\"con_{j}\")\n    return con\n\nconstraint = poi.make_tupledict(J, rule=constraint_rule)\n\nobj = poi.quicksum(x.values(), lambda x: x*x)\nmodel.set_objective(obj, poi.ObjectiveSense.Minimize)\n\nmodel.optimize()\n\nx_value = x.map(model.get_value)\n```\n\nHere we use two utility functions to simplify how we express the sum notation\n\n```{py:function} quicksum(values, [f=None])\n\nCreate a new expression by summing up a list of values (optionally, you can apply a function to\neach value in advance)\n\n:param values: iterator of values\n:param f: a function that takes a value and returns a new value\n:return: the handle of the new expression\n:rtype: pyoptinterface.ExprBuilder\n```\n\nThere is also an in-place version:\n\n```{py:function} quicksum_(expr, values, [f=None])\n\nAdd a list of values to an existing expression (optionally, you can apply a function to each value in advance)\n\n:param pyoptinterface.ExprBuilder expr: the handle of the existing expression\n:param values: iterator of values\n:param f: a function that takes a value and returns a new value\n:return: None\n```\n\nWe notice that `poi.make_tupledict(I, J, rule=lambda i, j: model.add_variable(lb=0, name=f\"x({i},{j})\"))` is a frequently used pattern to create a `tupledict` of variables, so we provide a convenient way to create a `tupledict` of variables by calling [`model.add_variables`](#model.add_variables):\n\n```python\nx = model.add_variables(I, J, lb=0, name=\"x\")\n```\n"
  },
  {
    "path": "docs/source/copt.md",
    "content": "# COPT\n\n## Initial setup\n\n```python\nfrom pyoptinterface import copt\n\nmodel = copt.Model()\n```\n\nYou need to follow the instructions in [Getting Started](getting_started.md#copt) to set up the optimizer correctly.\n\nIf you want to manage the license of COPT manually, you can create a `copt.Env` object and pass it to the constructor of the `copt.Model` object, otherwise we will initialize an implicit global `copt.Env` object automatically and use it.\n\n```python\nenv = copt.Env()\n\nmodel = copt.Model(env)\n```\n\n## The capability of `copt.Model`\n\n### Supported constraints\n\n:::{list-table}\n:header-rows: 1\n\n*   - Constraint\n    - Supported\n*   - <project:#model.add_linear_constraint>\n    - ✅\n*   - <project:#model.add_quadratic_constraint>\n    - ✅\n*   - <project:#model.add_second_order_cone_constraint>\n    - ✅\n*   - <project:#model.add_exp_cone_constraint>\n    - ✅\n*   - <project:#model.add_sos_constraint>\n    - ✅\n\n:::\n\n```{include} attribute/copt.md\n```\n\n\n## Solver-specific operations\n\n### Parameter\n\nFor [solver-specific parameters](https://guide.coap.online/copt/en-doc/parameter.html), we provide `get_raw_parameter` and `set_raw_parameter` methods to get and set the parameters.\n\n```python\nmodel = copt.Model()\n\n# get the value of the parameter\nvalue = model.get_raw_parameter(\"TimeLimit\")\n\n# set the value of the parameter\nmodel.set_raw_parameter(\"TimeLimit\", 10.0)\n```\n\n### Attribute\n\nCOPT supports [attribute](https://guide.coap.online/copt/en-doc/attribute.html) for the model. We provide `model.get_raw_attribute(name:str)` to get the value of attribute.\n\n### Information\n\nCOPT provides [information](https://guide.coap.online/copt/en-doc/information.html) for the model components. We provide methods to access the value of information.\n\n- Information of variable: `model.get_variable_info(variable, name: str)`\n- Information of constraint: `model.get_constraint_info(constraint, name: str)`\n\nWe also provide `copt.COPT` to contain all the constants in `coptpy.COPT`.\n\nFor number of variables (columns) in the problem:\n```python\ncols = model.get_raw_attribute(copt.COPT.Attr.Cols)\n```\n\nFor reduced cost of a variable:\n```python\nrc = model.get_variable_info(variable, copt.COPT.Info.RedCost)\n```\n\nFor upper bound of a constraint:\n```python\nub = model.get_constraint_info(constraint, copt.COPT.Info.UB)\n```"
  },
  {
    "path": "docs/source/develop.md",
    "content": "# Developer Guide\n\nThis section is intended for developers who want to contribute to the PyOptInterface library. It provides an overview of the codebase, the development process, and the guidelines for contributing to the project.\n\n## Codebase Overview\n\nThe PyOptInterface library is a C++/Python mixed library. The core parts are implemented in C++ and exposed to Python via [nanobind](https://github.com/wjakob/nanobind). The build system is based on [scikit-build-core](https://github.com/scikit-build/scikit-build-core).\n\nThe codebase is organized as follows:\n\n- `include/pyoptinterface`: The header files of the C++ library.\n- `lib`: The source files of the C++ library.\n- `src`: The Python interface.\n- `tests`: The test cases.\n- `thirdparty`: The third-party dependencies.\n\n## Development Process\n\nSupposing you want to contribute to PyOptInterface, you can follow these steps:\n\nFirstly, fork the [PyOptInterface repository](https://github.com/metab0t/PyOptInterface) on GitHub and clone your forked repository to your local machine: `git clone https://github.com/<your-username>/PyOptInterface.git`.\n\nNext, you should set up the development environment. The third-party optimizers must be configured following the instructions in [getting started](getting_started.md). In order to build PyOptInterface from source, you need the following dependencies:\n- CMake\n- A recent C++ compiler (We routinely test with GCC 10, latest MSVC and Apple Clang on the CI)\n- Python 3.8 or later\n- Python packages: `scikit-build-core`, can be installed by running `pip install scikit-build-core[pyproject]`\n\nThen, you can build the project by running the following commands:\n```bash\npip install --no-build-isolation -ve .\n```\n\nYou will see a new `build` directory created in the project root. The Python package is installed in editable mode, so you can modify the source code and test the changes without reinstalling the package.\n\nAfter making changes to the code, you should run the test cases to ensure that everything is working as expected. You can run the test cases by executing the following command (installing `pytest` is required):\n```bash\npytest tests\n```\n\nThe tests of PyOptInterface are still scarce, so you are encouraged to write new test cases for the new features you add.\n\nFinally, you can submit a pull request to the [PyOptInterface repository](https://github.com/metab0t/PyOptInterface)\n\n## Building Documentation\n\nThe documentation of PyOptInterface is built using [Sphinx](https://www.sphinx-doc.org/).\n\nFirstly, you should install the dependencies for building the documentation:\n```bash\npip install -r docs/requirements.txt\n```\n\nYou can build the documentation by running the following commands:\n```bash\ncd docs\nmake html\n```\n\nThe docs are built in the `docs/build/html` directory. You can open the `index.html` file in a web browser to view the documentation.\n\n## Contributing Guidelines\n\nWhen contributing to PyOptInterface, please follow these guidelines:\n\n- Make sure that the code is well formatted and documented. The C++ code is formatted using [clang-format](https://clang.llvm.org/docs/ClangFormat.html) and the Python code is formatted using [black](https://black.readthedocs.io/en/stable/).\n- For big changes like adding interface for a new optimizer, please open a thread in [**Discussion**](https://github.com/metab0t/PyOptInterface/discussions) to discuss the design before starting the implementation.\n"
  },
  {
    "path": "docs/source/examples/economic_dispatch.md",
    "content": "---\nfile_format: mystnb\nkernelspec:\n  name: python3\n---\n# Economic Dispatch\n\nEconomic dispatch is a classic optimization problem in power systems. It is used to determine the optimal power output of a set of generators to meet the demand at the lowest cost. The problem can be formulated as a linear programming problem or a quadratic programming problem depending on the formulation used to model the economic cost.\n\nIn this example, we will show how to use PyOptInterface to solve an economic dispatch problem using the quadratic programming formulation.\n\n## Problem Formulation\n\n$$\n\\min \\quad & \\sum_{t=1}^T \\sum_{i=1}^{N_G} a_i P_{i,t}^2 + b_i P_{i,t} + c_i \\\\\n\\textrm{s.t.}  \\quad & \\sum_{i=1}^{N_G} P_{i,t} = \\sum_{i=1}^{N_D} D_{i,t}\\\\\n               \\quad & P_{min,i} \\leq P_{i,t} \\leq P_{max,i} \\\\\n               \\quad & -Rdn_{i} \\leq P_{i,t} - P_{i,t-1} \\leq Rup_{i}\n$$\n\nWe consider a system with $N_G$ generators and $N_D$ demands. The decision variables are the power output of the generators $P_{i,t}$ for $i=1,\\ldots,N_G$ and $t=1,\\ldots,T$. The objective function is the total cost of the generators, which is the sum of the quadratic cost, the linear cost, and the constant cost. The first constraint ensures that the total power output of the generators meets the demand. The second and third constraints are the power output limits of the generators. The last constraint is the ramping limits of the generators.\n\n## Implementation\n\nFirstly, we need to create a model object. We will use the HiGHS solver in this example because it is an excellent open-source solver and supports quadratic programming problems. You need to read the [installation guide](../highs.md#initial-setup) to install the HiGHS solver manually and set the path to shared library of HiGHS as described in the guide.\n\n```{code-cell}\nimport pyoptinterface as poi\nfrom pyoptinterface import highs\n\nmodel = highs.Model()\n```\n\nThen, we need to create new variables in the model to represent the power output of the generators. We will use the [`add_variables`](#model.add_variables) method to add multidimensional variables to the model.\n\n```{code-cell}\nT = 24\nN_G = 3\nP_min = [50, 50, 50]\nP_max = [100, 100, 100]\na_cost = [0.01, 0.015, 0.02]\nb_cost = [1, 1.5, 2]\nc_cost = [0, 0, 0]\nRup = [20, 20, 20]\nRdn = [20, 20, 20]\n\nP = model.add_variables(range(N_G), range(T), name=\"P\")\n```\n\nFor the lower and upper bound of variables, we can set the corresponding [variable attribute](#pyoptinterface.VariableAttribute) to set them.\n\n```{code-cell}\nfor i in range(N_G):\n    for t in range(T):\n        model.set_variable_attribute(P[i, t], poi.VariableAttribute.LowerBound, P_min[i])\n        model.set_variable_attribute(P[i, t], poi.VariableAttribute.UpperBound, P_max[i])\n```\n\nNext, we need to add the power balance constraint to the model. We will use the [`add_linear_constraint`](#model.add_linear_constraint) method to add a linear constraint to the model. The multidimensional constraint is managed by `tupledict` and we use the `make_tupledict` method to create a multidimensional constraint.\n\nThe total demand is assumed to be a constant in this example.\n\n```{code-cell}\ntotal_demand = [220 for _ in range(T)]\n\ndef con(t):\n    lhs = poi.quicksum(P[i, t] for i in range(N_G))\n    rhs = total_demand[t]\n    return model.add_linear_constraint(lhs, poi.Eq, rhs, name=f\"powerbalance_{t}\")\n\npowebalance_constraints = poi.make_tupledict(range(T), rule=con)\n```\n\n```{code-cell}\ndef rampup_con(i, t):\n    if t == 0:\n        return None\n    lhs = P[i, t] - P[i, t-1]\n    rhs = Rup[i]\n    return model.add_linear_constraint(lhs, poi.Leq, rhs, name=f\"rampup_{i}_{t}\")\n\nrampup_constraints = poi.make_tupledict(range(N_G), range(T), rule=rampup_con)\n\ndef rampdown_con(i, t):\n    if t == 0:\n        return None\n    lhs = P[i, t] - P[i, t-1]\n    rhs = -Rdn[i]\n    return model.add_linear_constraint(lhs, poi.Geq, rhs, name=f\"rampdown_{i}_{t}\")\n\nrampdown_constraints = poi.make_tupledict(range(N_G), range(T), rule=rampdown_con)\n```\n\nThen, we need to add the quadratic objective function to the model. We will use the [`set_objective`](#model.set_objective) method to set the objective function of the model.\n\n```{code-cell}\nobj = poi.ExprBuilder()\nfor t in range(T):\n    for i in range(N_G):\n        obj += a_cost[i] * P[i, t] * P[i, t] + b_cost[i] * P[i, t] + c_cost[i]\nmodel.set_objective(obj)\n```\n\nFinally, we can solve the model and query the solution.\n\n```{code-cell}\nmodel.optimize()\n\nprint(model.get_model_attribute(poi.ModelAttribute.TerminationStatus))\nprint(\"Objective value: \", model.get_value(obj))\n```\n\nThe optimal value of decision variables can be queried via `get_value` function.\n\n```{code-cell}\nimport numpy as np\n\nP_value = np.fromiter(\n    (model.get_value(P[i, t]) for i in range(N_G) for t in range(T)), float\n).reshape(N_G, T)\n\nP_value\n```\n\n## Change the load and solve the model again\n\nWe can change the load and solve the model again without creating a new model from scratch by modifying the right-hand side of the power balance constraint.\n\nFor example, we increase the load and solve the model again.\n\n```{code-cell}\ntotal_demand = [220 + 1.0 * t for t in range(T)]\n\nfor t in range(T):\n    model.set_normalized_rhs(powebalance_constraints[t], total_demand[t])\n\nmodel.optimize()\nprint(model.get_model_attribute(poi.ModelAttribute.TerminationStatus))\nprint(\"Objective value: \", model.get_value(obj))\n\nP_value = np.fromiter(\n    (model.get_value(P[i, t]) for i in range(N_G) for t in range(T)), float\n).reshape(N_G, T)\n\nprint(P_value)\n```"
  },
  {
    "path": "docs/source/examples/optimal_control_rocket.md",
    "content": "---\nfile_format: mystnb\nkernelspec:\n  name: python3\n---\n# Optimal Control of a Rocket\n\nThis example is adapted from [the JuMP tutorial](https://jump.dev/JuMP.jl/stable/tutorials/nonlinear/rocket_control/).\n\nThe goal is to show that there are explicit repeated structures in discretized optimal control problem regarded as a nonlinear program (NLP). We will use the optimal control of a rocket as an example to demonstrate how to exploit these structures to solve the problem more efficiently via PyOptInterface.\n\n## Problem Formulation\n\nThe problem is to find the optimal control of a rocket to maximize the altitude at the final time while satisfying the dynamics of the rocket. The dynamics of the rocket are described by the following ordinary differential equations (ODEs):\n\n$$\n\\begin{align*}\n\\frac{dh}{dt} &= v \\\\\n\\frac{dv}{dt} &= -g(h) + \\frac{u-D(h,v)}{m} \\\\\n\\frac{dm}{dt} &= -\\frac{u}{c}\n\\end{align*}\n$$\n\nwhere $h$ is the altitude, $v$ is the velocity, $m$ is the mass, $u$ is the thrust, $g(h)$ is the gravitational acceleration, and $D(h,v)$ is the drag force. The thrust $u$ is the control variable.\n\nThe drag force is given by $D(h,v) = D_c v^2 \\exp(-h_c \\frac{h-h_0}{h_0})$, and the gravitational acceleration is given by $g(h) = g_0 (\\frac{h_0}{h})^2$.\n\nBy discretizing the ODEs, we obtain the following nonlinear program:\n\n$$\n\\begin{align*}\n\\frac{h_{t+1}-h_t}{\\Delta t} &= v_t \\\\\n\\frac{v_{t+1}-v_t}{\\Delta t} &= -g(h_t) + \\frac{u_t-D(h_t,v_t)}{m_t} \\\\\n\\frac{m_{t+1}-m_t}{\\Delta t} &= -\\frac{u_t}{c}\n\\end{align*}\n$$\n\nwhere $h_t$, $v_t$, and $m_t$ are the altitude, velocity, and mass at time $t$, respectively, and $\\Delta t$ is the time step.\n\n## Implementation\n\nIn the discretized optimal control problem, the variables at two adjacent time points share the same algebraic relationship.\n\n```{code-cell}\nimport math\nimport pyoptinterface as poi\nfrom pyoptinterface import nl, ipopt\n\nmodel = ipopt.Model()\n\nh_0 = 1.0\nv_0 = 0.0\nm_0 = 1.0\ng_0 = 1.0\nT_c = 3.5\nh_c = 500.0\nv_c = 620.0\nm_c = 0.6\n\nc = 0.5 * math.sqrt(g_0 * h_0)\nm_f = m_c * m_0\nD_c = 0.5 * v_c * (m_0 / g_0)\nT_max = T_c * m_0 * g_0\n\nnh = 1000\n```\n\nThen, we declare variables and set boundary conditions.\n\n```{code-cell}\nh = model.add_m_variables(nh, lb=1.0)\nv = model.add_m_variables(nh, lb=0.0)\nm = model.add_m_variables(nh, lb=m_f, ub=m_0)\nT = model.add_m_variables(nh, lb=0.0, ub=T_max)\nstep = model.add_variable(lb=0.0)\n\n# Boundary conditions\nmodel.set_variable_bounds(h[0], h_0, h_0)\nmodel.set_variable_bounds(v[0], v_0, v_0)\nmodel.set_variable_bounds(m[0], m_0, m_0)\nmodel.set_variable_bounds(m[-1], m_f, m_f)\n```\n\nNext, we add the dynamics constraints.\n\n```{code-cell}\nfor i in range(nh - 1):\n    with nl.graph():\n        h1 = h[i]\n        h2 = h[i + 1]\n        v1 = v[i]\n        v2 = v[i + 1]\n        m1 = m[i]\n        m2 = m[i + 1]\n        T1 = T[i]\n        T2 = T[i + 1]\n\n        model.add_nl_constraint(h2 - h1 - 0.5 * step * (v1 + v2) == 0)\n\n        D1 = D_c * v1 * v1 * nl.exp(-h_c * (h1 - h_0)) / h_0\n        D2 = D_c * v2 * v2 * nl.exp(-h_c * (h2 - h_0)) / h_0\n        g1 = g_0 * h_0 * h_0 / (h1 * h1)\n        g2 = g_0 * h_0 * h_0 / (h2 * h2)\n        dv1 = (T1 - D1) / m1 - g1\n        dv2 = (T2 - D2) / m2 - g2\n\n        model.add_nl_constraint(v2 - v1 - 0.5 * step * (dv1 + dv2) == 0)\n        model.add_nl_constraint(m2 - m1 + 0.5 * step * (T1 + T2) / c == 0)\n```\n\nFinally, we add the objective function. We want to maximize the altitude at the final time, so we set the objective function to be the negative of the altitude at the final time.\n\n```{code-cell}\nmodel.set_objective(-h[-1])\n```\n\nAfter solving the problem, we can plot the results.\n\n```{code-cell}\nmodel.optimize()\n```\n\n```{code-cell}\nh_value = []\nfor i in range(nh):\n    h_value.append(model.get_value(h[i]))\n\nprint(\"Optimal altitude: \", h_value[-1])\n```\n\nThe plot of the altitude of the rocket is shown below.\n\n```{code-cell}\nimport matplotlib.pyplot as plt\n\nplt.plot(h_value)\nplt.xlabel(\"Time\")\nplt.ylabel(\"Altitude\")\nplt.show()\n```\n"
  },
  {
    "path": "docs/source/examples/optimal_power_flow.md",
    "content": "---\nfile_format: mystnb\nkernelspec:\n  name: python3\n---\n# Optimal Power Flow\n\nAlternating current optimal power flow (ACOPF) is a fundamental nonlinear optimization problem in power systems. It is used to determine the optimal power flow of a power system to minimize the generation cost while satisfying the power flow equations and system constraints.\n\nIn this example, we will show how to use PyOptInterface to solve an single-period optimal power flow problem using the structured nonlinear programming formulation.\n\n## Problem Formulation\n\n$$\n\\min \\quad & \\sum_{i \\in G} a_i P_{i}^2 + b_i P_{i} + c_i \\\\\n\\textrm{s.t.}  \\quad & \\theta_r = 0 \\quad & \\forall r \\in R \\\\\n               \\quad & P_{min,i} \\leq P_{i} \\leq P_{max,i} \\quad & \\forall i \\in G \\\\\n               \\quad & Q_{min,i} \\leq Q_{i} \\leq Q_{max,i} \\quad & \\forall i \\in G \\\\\n               \\quad & V_{min,b} \\leq V_{b} \\leq V_{max,b} \\quad & \\forall b \\in BUS \\\\\n               \\quad & \\sum_{i \\in G_b} P_{i} - \\sum_{i \\in D_b} L^P_{i} - G_{sh,b} V_b^2 = \\sum_{(i, j) \\in BRANCH} P_{ij} \\quad & \\forall b \\in BUS \\\\\n               \\quad & \\sum_{i \\in G_b} Q_{i} - \\sum_{i \\in D_b} L^Q_{i} + B_{sh,b} V_b^2 = \\sum_{(i, j) \\in BRANCH} Q_{ij} \\quad & \\forall b \\in BUS \\\\\n               \\quad & P_{ij} =  G_{ij} V_i^2 - V_i V_j (G_{ij}\\cos(\\theta_i-\\theta_j)+B_{ij}\\sin(\\theta_i-\\theta_j)) \\quad & \\forall (i, j) \\in BRANCH \\\\\n               \\quad & Q_{ij} = -B^C_{ij} V_i^2 - B_{ij} V_i^2 - V_i V_j (G_{ij}\\sin(\\theta_i-\\theta_j)-B_{ij}\\cos(\\theta_i-\\theta_j)) \\quad & \\forall (i, j) \\in BRANCH \\\\\n               \\quad & P_{ji} =  G_{ij} V_j^2 - V_i V_j (G_{ij}\\cos(\\theta_j-\\theta_i)+B_{ij}\\sin(\\theta_j-\\theta_i)) \\quad & \\forall (i, j) \\in BRANCH \\\\\n               \\quad & Q_{ji} = -B^C_{ij} V_j^2 - B_{ij} V_j^2 - V_i V_j (G_{ij}\\sin(\\theta_j-\\theta_i)-B_{ij}\\cos(\\theta_j-\\theta_i)) \\quad & \\forall (i, j) \\in BRANCH \\\\\n               \\quad & -S_{max,ij} \\leq P_{ij}^2 + Q_{ij}^2 \\leq S_{max,ij} \\quad & \\forall (i, j) \\in BRANCH \\\\\n               \\quad & -\\Delta\\theta_{min,ij} \\leq \\theta_i - \\theta_j \\leq -\\Delta\\theta_{max,ij} \\quad & \\forall (i, j) \\in BRANCH\n$$\n\nThe decision variables are the active power output of the generators $P_{i}$, reactive power output of the generators $Q_{i}$, voltage magnitude of the buses $V_{b}$, phase angle of the buses $\\theta_{b}$ for $b \\in BUS$ and the branch power flows $P_{ij}$ and $Q_{ij}$ for $(i, j) \\in BRANCH$.\n\nThe objective function is the total cost of the generators, which is the sum of the quadratic cost, the linear cost, and the constant cost. The first constraint ensures that the phase angle of the reference bus is zero. The second and third constraints are the active and reactive power output limits of the generators. The fourth constraint is the voltage magnitude limits of the buses. The fifth and sixth constraints are the power balance equations of the buses. The seventh and eighth constraints are the power flow equations of the branches. The ninth and tenth constraints are the power flow equations of the branches in the opposite direction. The eleventh and twelfth constraints are the apparent power limits of the branches. The last constraint is the phase angle difference limits of the branches.\n\n## Implementation\n\nWe will use PJM 5-bus system as an example to demonstrate the implementation of the optimal power flow problem. The PJM 5-bus system is a small power system with 5 buses and 6 branches. The system data is shown below.\n\n```{code-cell}\n\nbranches = [\n    # (from, to, R, X, B, angmin, angmax, Smax)\n    (0, 1, 0.00281, 0.0281, 0.00712, -30.0, 30.0, 4.00),\n    (0, 3, 0.00304, 0.0304, 0.00658, -30.0, 30.0, 4.26),\n    (0, 4, 0.00064, 0.0064, 0.03126, -30.0, 30.0, 4.26),\n    (1, 2, 0.00108, 0.0108, 0.01852, -30.0, 30.0, 4.26),\n    (2, 3, 0.00297, 0.0297, 0.00674, -30.0, 30.0, 4.26),\n    (3, 4, 0.00297, 0.0297, 0.00674, -30.0, 30.0, 2.40),\n]\n\nbuses = [\n    # (Pd, Qd, Gs, Bs, Vmin, Vmax)\n    (0.0, 0.0000, 0.0, 0.0, 0.9, 1.1),\n    (3.0, 0.9861, 0.0, 0.0, 0.9, 1.1),\n    (3.0, 0.9861, 0.0, 0.0, 0.9, 1.1),\n    (4.0, 1.3147, 0.0, 0.0, 0.9, 1.1),\n    (0.0, 0.0000, 0.0, 0.0, 0.9, 1.1),\n]\n\ngenerators = [\n    # (bus, Pmin, Pmax, Qmin, Qmax, a, b, c)\n    (0, 0.0, 0.4, -0.300, 0.300, 0.0, 1400, 0.0),\n    (0, 0.0, 1.7, -1.275, 1.275, 0.0, 1500, 0.0),\n    (2, 0.0, 5.2, -3.900, 3.900, 0.0, 3000, 0.0),\n    (3, 0.0, 2.0, -1.500, 1.500, 0.0, 4000, 0.0),\n    (4, 0.0, 6.0, -4.500, 4.500, 0.0, 1000, 0.0),\n]\n\nslack_bus = 3\n```\n\nThen we declare the variables:\n\n```{code-cell}\nimport math\nimport pyoptinterface as poi\nfrom pyoptinterface import nl, ipopt\n\nmodel = ipopt.Model()\n\nN_branch = len(branches)\nN_bus = len(buses)\nN_gen = len(generators)\n\nPbr_from = model.add_m_variables(N_branch)\nQbr_from = model.add_m_variables(N_branch)\nPbr_to = model.add_m_variables(N_branch)\nQbr_to = model.add_m_variables(N_branch)\n\nV = model.add_m_variables(N_bus, name=\"V\")\ntheta = model.add_m_variables(N_bus, name=\"theta\")\n\nfor i in range(N_bus):\n    Vmin, Vmax = buses[i][4], buses[i][5]\n    model.set_variable_bounds(V[i], Vmin, Vmax)\n\nmodel.set_variable_bounds(theta[slack_bus], 0.0, 0.0)\n\nP = model.add_variables(range(N_gen), name=\"P\")\nQ = model.add_variables(range(N_gen), name=\"Q\")\n\nfor i in range(N_gen):\n    model.set_variable_bounds(P[i], generators[i][1], generators[i][2])\n    model.set_variable_bounds(Q[i], generators[i][3], generators[i][4])\n```\n\nNext, we add the constraints:\n\n```{code-cell}\n# nonlinear constraints\nfor k in range(N_branch):\n    with nl.graph():\n        branch = branches[k]\n        R, X, Bc2 = branch[2], branch[3], branch[4]\n\n        G = R / (R**2 + X**2)\n        B = -X / (R**2 + X**2)\n        Bc = Bc2 / 2\n\n        i = branch[0]\n        j = branch[1]\n\n        Vi = V[i]\n        Vj = V[j]\n        theta_i = theta[i]\n        theta_j = theta[j]\n\n        Pij = Pbr_from[k]\n        Qij = Qbr_from[k]\n        Pji = Pbr_to[k]\n        Qji = Qbr_to[k]\n\n        sin_ij = nl.sin(theta_i - theta_j)\n        cos_ij = nl.cos(theta_i - theta_j)\n\n        Pij_eq = G * Vi**2 - Vi * Vj * (G * cos_ij + B * sin_ij) - Pij\n        Qij_eq = -(B + Bc) * Vi**2 - Vi * Vj * (G * sin_ij - B * cos_ij) - Qij\n        Pji_eq = G * Vj**2 - Vi * Vj * (G * cos_ij - B * sin_ij) - Pji\n        Qji_eq = -(B + Bc) * Vj**2 - Vi * Vj * (-G * sin_ij - B * cos_ij) - Qji\n\n        model.add_nl_constraint(\n            Pij_eq == 0.0,\n        )\n        model.add_nl_constraint(\n            Qij_eq == 0.0,\n        )\n        model.add_nl_constraint(\n            Pji_eq == 0.0,\n        )\n        model.add_nl_constraint(\n            Qji_eq == 0.0,\n        )\n\n# power balance constraints\nP_balance_eq = [poi.ExprBuilder() for i in range(N_bus)]\nQ_balance_eq = [poi.ExprBuilder() for i in range(N_bus)]\n\nfor b in range(N_bus):\n    Pd, Qd = buses[b][0], buses[b][1]\n    Gs, Bs = buses[b][2], buses[b][3]\n    Vb = V[b]\n\n    P_balance_eq[b] -= poi.quicksum(\n        Pbr_from[k] for k in range(N_branch) if branches[k][0] == b\n    )\n    P_balance_eq[b] -= poi.quicksum(\n        Pbr_to[k] for k in range(N_branch) if branches[k][1] == b\n    )\n    P_balance_eq[b] += poi.quicksum(\n        P[i] for i in range(N_gen) if generators[i][0] == b\n    )\n    P_balance_eq[b] -= Pd\n    P_balance_eq[b] -= Gs * Vb * Vb\n\n    Q_balance_eq[b] -= poi.quicksum(\n        Qbr_from[k] for k in range(N_branch) if branches[k][0] == b\n    )\n    Q_balance_eq[b] -= poi.quicksum(\n        Qbr_to[k] for k in range(N_branch) if branches[k][1] == b\n    )\n    Q_balance_eq[b] += poi.quicksum(\n        Q[i] for i in range(N_gen) if generators[i][0] == b\n    )\n    Q_balance_eq[b] -= Qd\n    Q_balance_eq[b] += Bs * Vb * Vb\n\n    model.add_quadratic_constraint(P_balance_eq[b], poi.Eq, 0.0)\n    model.add_quadratic_constraint(Q_balance_eq[b], poi.Eq, 0.0)\n\nfor k in range(N_branch):\n    branch = branches[k]\n\n    i = branch[0]\n    j = branch[1]\n\n    theta_i = theta[i]\n    theta_j = theta[j]\n\n    angmin = branch[5] / 180 * math.pi\n    angmax = branch[6] / 180 * math.pi\n\n    model.add_linear_constraint(theta_i - theta_j, (angmin, angmax))\n\n    Smax = branch[7]\n    Pij = Pbr_from[k]\n    Qij = Qbr_from[k]\n    Pji = Pbr_to[k]\n    Qji = Qbr_to[k]\n    model.add_quadratic_constraint(Pij * Pij + Qij * Qij, poi.Leq, Smax * Smax)\n    model.add_quadratic_constraint(Pji * Pji + Qji * Qji, poi.Leq, Smax * Smax)\n```\n\nFinally, we set the objective function:\n\n```{code-cell}\ncost = poi.ExprBuilder()\nfor i in range(N_gen):\n    a, b, c = generators[i][5], generators[i][6], generators[i][7]\n    cost += a * P[i] * P[i] + b * P[i] + c\nmodel.set_objective(cost)\n```\n\nAfter optimization, we can retrieve the optimal solution:\n\n```{code-cell}\nmodel.optimize()\n```\n\n```{code-cell}\nprint(model.get_model_attribute(poi.ModelAttribute.TerminationStatus))\n\nP_value = P.map(model.get_value)\n\nprint(\"Optimal active power output of the generators:\")\n\nfor i in range(N_gen):\n    print(f\"Generator {i}: {P_value[i]}\")\n```\n"
  },
  {
    "path": "docs/source/expression.md",
    "content": "---\nfile_format: mystnb\nkernelspec:\n  name: python3\n---\n# Expression\n\n## Basic expression\n\nPyOptInterface currently supports polynomial expressions with degree up to 2, including\n- quadratic expression\n- linear expression\n- constant expression\n\nThe expression can be expressed by arithmetic operations of variables and constants. For example, we can create a quadratic expression by adding two quadratic expressions, multiplying a linear expression with a constant expression, etc.\n\n```{code-cell}\nimport pyoptinterface as poi\nfrom pyoptinterface import highs\n\nmodel = highs.Model()\n\nx = model.add_variable()\n\n# create a quadratic expression\nexpr1 = x * x + 2 * x + 1\n# create a linear expression\nexpr2 = 2 * x + 1\n\n# create a quadratic expression by adding two quadratic expressions\nexpr3 = x * expr2 + expr1\n```\n\n## Efficient expression construction\nPyOptInterface provides a special class `ExprBuilder` to construct expressions efficiently. It is especially useful when we need to construct a large expression with many terms.\n\nIt supports the following in-place assignment operations:\n- `+=`: add a term to the expression\n- `-=`: subtract a term from the expression\n- `*=`: multiply the expression with a constant or another expression\n- `/=`: divide the expression with a constant\n\nFor example, we can use `ExprBuilder` to construct the following expression efficiently:\n\n$$\n\\frac{1}{2} \\sum_{i=1}^N x_i^2 - \\sum_{i=1}^N x_i\n$$\n\n```{code-cell}\nN = 1000\nx = [model.add_variable() for _ in range(N)]\n\ndef fast_expr():\n    expr = poi.ExprBuilder()\n    for i in range(N):\n        expr += 0.5 * x[i] * x[i]\n        expr -= x[i]\n\ndef slow_expr():\n    expr = 0\n    for i in range(N):\n        expr += 0.5 * x[i] * x[i]\n        expr -= x[i]\n\n```\n\n```{code-cell}\n%time fast_expr()\n```\n\n```{code-cell}\n%time slow_expr()\n```\n\n## Pretty print expression\nIf the names of variables are specified, We can use the `pprint` method to print the expression in a human-readable format:\n\n```{code-cell}\nx = model.add_variable(name=\"x\")\ny = model.add_variable(name=\"y\")\n\nexpr = x * x + 2 * x * y + y * y\n\nmodel.pprint(expr)\n```\n\n## Value of expression\nWe can use the `get_value` method to get the value of an expression after optimization:\n\n```python\nexpr = x*y + x*x\nexpr_value = model.get_value(expr)\n```\n"
  },
  {
    "path": "docs/source/faq.md",
    "content": "# Frequently Asked Questions\n\n## How to suppress the output of the optimizer?\n\nThere are two kinds of output that you may want to suppress:\n\n1. The log of optimization process.\n2. The default license message printed when initializing the optimizer. For example, when using Gurobi, the message is `Academic license - for non-commercial use only - expires yyyy-mm-dd`.\n\nNormally we only want to suppress the log of optimization process, you can use `model.set_model_attribute(poi.ModelAttribute.Silent, True)` to disable the output. For example:\n\n```python\nimport pyoptinterface as poi\nfrom pyoptinterface import gurobi\n\nmodel = gurobi.Model()\nmodel.set_model_attribute(poi.ModelAttribute.Silent, True)\n```\n\nSuppressing the default license message is a bit tricky and solver-specific. For Gurobi, you can use the following code:\n\n```python\nimport pyoptinterface as poi\nfrom pyoptinterface import gurobi\n\nenv = gurobi.Env(empty=True)\nenv.set_raw_parameter(\"OutputFlag\", 0)\nenv.start()\n\nmodel = gurobi.Model(env)\n```\n\n## How to add linear constraints in matrix form like $Ax \\leq b$?\n\nIn YALMIP, you can use the matrix form $Ax \\leq b$ to add linear constraints, which is quite convenient.\n\nIn PyOptInterface, you can use [`model.add_m_linear_constraints`](<project:#model.add_m_linear_constraints>) to add linear constraints in matrix form.\n\n## Will PyOptInterface support new optimizers in the future?\n\nIn short, no, there are no plans to support new optimizers. Supporting a new optimizer is not a trivial task, as it requires a lot of work to implement, test and maintain the interface.\n\nBasically, a new optimizer should satisfy the following criteria to be considered for support:\n\n- Actively maintained\n- Good performance (open source or commercial)\n- Not difficult to acquire an academic license\n- Have well-defined C/C++ API\n\nSupport for a new optimizer will only happen if one or more of the following conditions are met:\n\n- I am personally interested in the optimizer and plan to use it in my research, so I am willing to invest time in implementing it.\n- Someone steps up to implement and maintain the interface for the optimizer in PyOptInterface.\n- External funding or sponsorship become available to support the development and maintenance of the optimizer interface.\n\nFinally, we are always open to external contributions. If you have a specific optimizer in mind and plan to implement it, feel free to open an issue on our GitHub repository to discuss it.\n"
  },
  {
    "path": "docs/source/getting_started.md",
    "content": "---\nfile_format: mystnb\nkernelspec:\n  name: python3\n---\n\n# Getting Started\n\n## Installation\nPyOptInterface is available on PyPI. You can install it via pip:\n\n```\npip install pyoptinterface\n```\n\nAfter installation, you can import the package in Python console:\n```python\nimport pyoptinterface as poi\n```\n\nPyOptInterface has no dependencies other than Python itself. However, to use it with a specific optimizer, you need to install the corresponding optimizer manually. The details can be found on [the configurations of optimizers](https://metab0t.github.io/PyOptInterface/getting-started.html).\n\nIn order to provide out-of-the-box support for open source optimizers (currently we support [HiGHS](https://github.com/ERGO-Code/HiGHS)), PyOptInterface can also be installed with pre-built optimizers. You can install them via pip:\n\n```\npip install pyoptinterface[highs]\n```\n\nIt will install a full-featured binary version of HiGHS optimizer via [highsbox](http://github.com/metab0t/highsbox), which can be used with PyOptInterface.\n\nIn order to use nonlinear programming solvers (currently we only support IPOPT), you should install extra dependencies like:\n\n```\npip install pyoptinterface[nlp]\n```\n\nIt will install the [`llvmlite`](https://github.com/numba/llvmlite) and [`tccbox`](https://github.com/metab0t/tccbox) package as the JIT compilers required by nonlinear programming.\n\nWe will introduce how to set up the optimizers to use with PyOptInterface in this page.\n\n## Setup of optimizers\n\nPyOptInterface uses the `Dynamic Loading` technique to load the dynamic library of optimizers at runtime, so the optimizer it uses can be changed manually without recompiling the code.\n\nThe set up of optimizers includes two approaches:\n1. Automatic detection of the installation directory of the optimizers.\n2. Manually specifying the path of the dynamic library of optimizer.\n\nWe will introduce the automatic detection and manual configuration in details\n\n## Automatic detection of the installation directory of the optimizers\n\nThe automatic detection includes three steps:\n1. Environment variable set by the installer of optimizer\n2. The official Python binding of the optimizer (if available)\n3. Search directly in the system loadable path (e.g. `/usr/lib`, `/usr/local/lib` on Linux or PATH on Windows)\n\nFor the 3rd step, we want to explain more for novices.\n\nFor example, in order to make the dynamic library of HiGHS `highs.dll`/`libhighs.so`/`libhighs.dylib` loadable, we need to put it in a loadable path recognized by the operating system. The typical loadable path on Linux is `/usr/lib`, `/usr/local/lib`, and the typical loadable path on Windows is `PATH`.\n\nOn Linux, we use the `LD_LIBRARY_PATH` environment variable to specify the dynamic library path. On macOS, we use the `DYLD_LIBRARY_PATH` environment variable to specify the dynamic library path.\n\nIf the dynamic library is in path `C:\\highs\\lib`/`/opt/highs/lib`:\n- Windows: `set PATH=%PATH%;C:\\highs\\lib`\n- Linux: `export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/highs/lib`\n- macOS: `export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/opt/highs/lib`\n\nThe typical paths where the dynamic library of optimizers are located are as follows:\n\n:::{list-table}\n:header-rows: 1\n\n*   - Optimizer\n    - Windows\n    - Linux\n    - macOS(ARM)\n    - macOS(Intel)\n*   - Gurobi\n    - `C:\\gurobi1101\\win64\\bin`\n    - `/opt/gurobi1100/linux64/lib`\n    - `/opt/gurobi1100/macos_universal2/lib`\n    - `/opt/gurobi1100/macos_universal2/lib`\n*   - Xpress\n    - `C:\\xpressmp\\bin`\n    - `/opt/xpressmp/lib`\n    - `/Applications/FICO Xpress/xpressmp/lib`\n    - `/Applications/FICO Xpress/xpressmp/lib`\n*   - COPT\n    - `C:\\Program Files\\copt80\\bin`\n    - `/opt/copt80/lib`\n    - `/opt/copt80/lib`\n    - `/opt/copt80/lib`\n*   - Mosek\n    - `C:\\Program Files\\Mosek\\10.2\\tools\\platform\\win64x86\\bin`\n    - `/opt/mosek/10.2/tools/platform/linux64x86/bin`\n    - `/opt/mosek/10.2/tools/platform/osxaarch64/bin`\n    - `/opt/mosek/10.2/tools/platform/osx64x86/bin`\n*   - HiGHS\n    - `D:\\highs\\bin`\n    - `/opt/highs/lib`\n    - `/opt/highs/lib`\n    - `/opt/highs/lib`\n*   - KNITRO\n    - `C:\\Program Files\\Artelys\\KNITRO 15.1\\lib`\n    - `/opt/knitro/15.1/lib`\n    - `/opt/knitro/15.1/lib`\n    - ``\n:::\n\n### Gurobi\n\nThe currently supported version is **13.0.0**. Other versions may work but are not tested.\n\nFor Gurobi, the automatic detection looks for the following things in order:\n1. The environment variable `GUROBI_HOME` set by the installer of Gurobi\n2. The installation of `gurobipy`\n3. `gurobi130.dll`/`libgurobi130.so`/`libgurobi130.dylib` in the system loadable path\n\n### Xpress\n\nThe currently supported version is **9.8**. Other versions may work but are not tested.\n\nFor Xpress, the automatic detection looks for the following things in order:\n1. The environment variable `XPRESSDIR` set by the installer of Xpress\n2. `xprs.dll`/`libxprs.so`/`libxprs.dylib` int the system loadable path\n\n### COPT\n\nThe currently supported version is **8.0.x**. Other versions may work but are not tested.\n\nFor COPT, the automatic detection looks for the following things in order:\n1. The environment variable `COPT_HOME` set by the installer of COPT\n2. `copt.dll`/`libcopt.so`/`libcopt.dylib` in the system loadable path\n\n### Mosek\n\nThe currently supported version is **10.2.x**. Other versions may work but are not tested.\n\nFor Mosek, the automatic detection looks for the following things in order:\n1. The environment variable `MOSEK_10_2_BINDIR` set by the installer of Mosek\n2. The installation of `mosek` PyPI package\n3. `mosek64_10_2.dll`/`libmosek64.so`/`libmosek64.dylib` in the system loadable path\n\n### HiGHS\n\nThe currently supported version is **1.12.x**. Other versions may work but are not tested.\n\nFor HiGHS, the automatic detection looks for the following things in order:\n1. The environment variable `HiGHS_HOME` set by the user\n2. The installation of `highsbox` PyPI package (recommended)\n3. `highs.dll`/`libhighs.so`/`libhighs.dylib` in the system\n\nFor HiGHS, we recommend installing the `highsbox` PyPI package, which provides a full-featured binary version of HiGHS optimizer for you.\n\n### Ipopt\n\nThe currently supported version is **3.14.x**. Other versions may work but are not tested.\n\nFor Ipopt, the automatic detection looks for the following things in order:\n1. `ipopt.dll`/`libipopt.so`/`libipopt.dylib` in the system, we also look for `ipopt-3.dll`/`libipopt.dll`/`libipopt-3.dll` on Windows.\n\nWe recommend using the official binary from [GitHub](https://github.com/coin-or/Ipopt/releases) if you work on Windows, since compiling Ipopt on Windows from source is not an easy task.\n\n### KNITRO\n\nThe currently supported version is **15.1.x**. Other versions may work but are not tested.\n\nFor KNITRO, the automatic detection looks for the following things in order:\n1. The environment variable `KNITRODIR` set by the installer of KNITRO\n2. `knitro.dll`/`libknitro.so`/`libknitro.dylib` in the system loadable path\n3. The installation of `knitro` PyPI package.\n\nKNITRO dropped support for MacOS intel since version 15.0, so using KNITRO on MacOS intel is not supported.\n\n## Manually specifying the path of the dynamic library of optimizer\n\nIf the automatic detection fails or you want to use the optimizer in a customized location, you can manually specify the path of the dynamic library of the optimizer.\n\nWe take HiGHS as an example. Whether the optimizer has been successfully loaded can be checked via the following code:\n\n```python\nfrom pyoptinterface import highs\n\nprint(highs.is_library_loaded())\n```\n\nIf the optimizer has not been successfully loaded, you can manually specify the path of the dynamic library of the optimizer via the following code:\n\n```python\nret = highs.load_library(\"path/to/libhighs.so\")\n\nprint(f\"Loading from custom path manually: {ret}\")\n```\n\nThe `load_library` function returns `True` if the library is successfully loaded, otherwise it returns `False`.\n\nIf you want to revert to use the automatic detection, you can call the `autoload_library` function:\n\n```python\nret = highs.autoload_library()\n\nprint(f\"Loading from automatically detected location: {ret}\")\n```\n\nFor other optimizers, just replace `highs` with the corresponding optimizer name like `gurobi`, `xpress`, `copt`, `mosek`.\n\nThe typical paths where the dynamic library of optimizers are located are as follows:\n\n:::{list-table}\n:header-rows: 1\n\n*   - Optimizer\n    - Windows\n    - Linux\n    - macOS(ARM)\n    - macOS(Intel)\n*   - Gurobi\n    - `C:\\gurobi1101\\win64\\bin\\gurobi110.dll`\n    - `/opt/gurobi1100/linux64/lib/libgurobi110.so`\n    - `/opt/gurobi1100/macos_universal2/lib/libgurobi110.dylib`\n    - `/opt/gurobi1100/macos_universal2/lib/libgurobi110.dylib`\n*   - COPT\n    - `C:\\Program Files\\copt71\\bin\\copt.dll`\n    - `/opt/copt72/lib/libcopt.so`\n    - `/opt/copt72/lib/libcopt.dylib`\n    - `/opt/copt72/lib/libcopt.dylib`\n*   - Xpress\n    - `C:\\xpressmp\\bin\\xprs.dll`\n    - `/opt/xpressmp/lib/libxprs.so`\n    - `/Applications/FICO Xpress/xpressmp/lib/libxprs.dylib`\n    - `/Applications/FICO Xpress/xpressmp/lib/libxprs.dylib`\n*   - Mosek\n    - `C:\\Program Files\\Mosek\\10.2\\tools\\platform\\win64x86\\bin\\mosek64_10_1.dll`\n    - `/opt/mosek/10.2/tools/platform/linux64x86/bin/libmosek64.so`\n    - `/opt/mosek/10.2/tools/platform/osxaarch64/bin/libmosek64.dylib`\n    - `/opt/mosek/10.2/tools/platform/osx64x86/bin/libmosek64.dylib`\n*   - HiGHS\n    - `D:\\highs\\bin\\highs.dll`\n    - `/opt/highs/lib/libhighs.so`\n    - `/opt/highs/lib/libhighs.dylib`\n    - `/opt/highs/lib/libhighs.dylib`\n*   - KNITRO\n    - `C:\\Program Files\\Artelys\\KNITRO 15.1\\lib\\knitro.dll`\n    - `/opt/knitro/15.1/lib/libknitro.so`\n    - `/opt/knitro/15.1/lib/libknitro.dylib`\n    - ``\n:::\n\n## Let's build a simple model and solve it\nAfter setting up the optimizers, we can build a simple model and solve it.\nAs the first step, we will solve the following simple Quadratic Programming (QP) problem:\n\n```{math}\n\\min \\quad & x^{2}_{1} + 2x^{2}_{2} \\\\\n\\textrm{s.t.}  \\quad & x_{1} + x_{2} = 1 \\\\\n               \\quad & x_{1}, x_{2} \\geq 0\n```\n\nFirst, we need to create a model object:\n\n```{code-cell}\nimport pyoptinterface as poi\nfrom pyoptinterface import highs\n# from pyoptinterface import copt, gurobi, xpress, mosek (if you want to use other optimizers)\n\nmodel = highs.Model()\n```\n\nThen, we need to add variables to the model:\n```{code-cell}\nx1 = model.add_variable(lb=0, name=\"x1\")\nx2 = model.add_variable(lb=0, name=\"x2\")\n```\nThe `lb` argument specifies the lower bound of the variable. It is optional and defaults to $-\\infty$.\n\nThe `name` argument is optional and can be used to specify the name of the variable.\n\nThen, we need to add constraints to the model:\n```{code-cell}\ncon = model.add_linear_constraint(x1+x2, poi.ConstraintSense.Equal, 1, name=\"con\")\n```\n`model.add_linear_constraint` adds a linear constraint to the model.\n- The first argument `x1+x2` is the left-hand side of the constraint.\n- The second argument is the sense of the constraint. It can be `poi.ConstraintSense.Equal`, `poi.ConstraintSense.LessEqual` or `poi.ConstraintSense.GreaterEqual` which can also be written as `poi.Eq`, `poi.Leq`, and `poi.Geq`.\n- The third argument is the right-hand side of the constraint. It must be a constant.\n- The fourth argument is optional and can be used to specify the name of the constraint.\n\nFinally, we need to set the objective function and solve the model:\n```{code-cell}\nobj = x1*x1 + 2*x2*x2\nmodel.set_objective(obj, poi.ObjectiveSense.Minimize)\n```\n\nThe model can be solved via:\n```{code-cell}\nmodel.optimize()\n```\nThe HiGHS optimizer will be invoked to solve the model and writes the log to the console.\n\nWe can query the status of the model via:\n```{code-cell}\nmodel.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n```\n\nThe solution of the model can be queried via:\n```{code-cell}\nprint(\"x1 = \", model.get_value(x1))\nprint(\"x2 = \", model.get_value(x2))\nprint(\"obj = \", model.get_value(obj))\n```\n"
  },
  {
    "path": "docs/source/gurobi.md",
    "content": "# Gurobi\n\n## Initial setup\n\n```python\nfrom pyoptinterface import gurobi\n\nmodel = gurobi.Model()\n```\n\nYou need to follow the instructions in [Getting Started](getting_started.md#gurobi) to set up the optimizer correctly.\n\nIf you want to manage the license of Gurobi manually, you can create a `gurobi.Env` object and pass it to the constructor of the `gurobi.Model` object, otherwise we will initialize an implicit global `gurobi.Env` object automatically and use it.\n\n```python\nenv = gurobi.Env()\n\nmodel = gurobi.Model(env)\n```\n\nFor example, you can set the parameter of the `gurobi.Env` object to choose the licensing behavior.\n\n```python\nenv = gurobi.Env(empty=True)\nenv.set_raw_parameter(\"ComputeServer\", \"myserver1:32123\")\nenv.set_raw_parameter(\"ServerPassword\", \"pass\")\nenv.start()\n\nmodel = gurobi.Model(env)\n```\n\nFor users who want to release the license immediately after the optimization, you can call the `close` method of all models created and the `gurobi.Env` object. It applies to other commercial solvers supported as well.\n\n```python\nenv = gurobi.Env()\nmodel = gurobi.Model(env)\n\n# do something with the model\n\nmodel.close()\nenv.close()\n```\n\n## The capability of `gurobi.Model`\n\n### Supported constraints\n\n:::{list-table}\n:header-rows: 1\n\n*   - Constraint\n    - Supported\n*   - <project:#model.add_linear_constraint>\n    - ✅\n*   - <project:#model.add_quadratic_constraint>\n    - ✅\n*   - <project:#model.add_second_order_cone_constraint>\n    - ✅\n*   - <project:#model.add_sos_constraint>\n    - ✅\n\n:::\n\n```{include} attribute/gurobi.md\n```\n\n\n## Solver-specific operations\n\n### Parameter\n\nFor [solver-specific parameters](https://docs.gurobi.com/projects/optimizer/en/current/reference/parameters.html), we provide `get_raw_parameter` and `set_raw_parameter` methods to get and set the parameters.\n\n```python\nmodel = gurobi.Model()\n\n# get the value of the parameter\nvalue = model.get_raw_parameter(\"TimeLimit\")\n\n# set the value of the parameter\nmodel.set_raw_parameter(\"TimeLimit\", 10.0)\n```\n\n### Attribute\n\nGurobi supports a lot of [attributes](https://docs.gurobi.com/projects/optimizer/en/current/reference/attributes.html) for the model, variable, and constraint. We provide methods to get or set the value of the attribute.\n\n- Model attribute: `model.get_model_raw_attribute(name: str)` and `model.set_model_raw_attribute(name: str, value: Any)`\n- Variable attribute: `model.get_variable_raw_attribute(variable, name: str)` and `model.set_variable_raw_attribute(variable, name: str, value: Any)`\n- Constraint attribute: `model.get_constraint_raw_attribute(constraint, name: str)` and `model.set_constraint_raw_attribute(constraint, name: str, value: Any)`\n\nWe also provide `gurobi.GRB` to contain all the constants in `gurobipy.GRB`.\n\nFor model status:\n```python\nstatus = model.get_model_raw_attribute(gurobi.GRB.Attr.Status)\n\nif status == gurobi.GRB.OPTIMAL:\n    ...\nelif status == gurobi.GRB.INFEASIBLE:\n    ...\n```\n\nFor reduced cost of a variable:\n```python\nrc = model.get_variable_raw_attribute(variable, gurobi.GRB.Attr.RC)\n```\n\nFor right-hand side value of a constraint:\n```python\nrhs = model.get_constraint_raw_attribute(constraint, gurobi.GRB.Attr.RHS)\n```\n"
  },
  {
    "path": "docs/source/highs.md",
    "content": "# HiGHS\n\n## Initial setup\n\n```python\nfrom pyoptinterface import highs\n\nmodel = highs.Model()\n```\n\nYou need to follow the instructions in [Getting Started](getting_started.md#highs) to set up the optimizer correctly.\n\n## The capability of `highs.Model`\n\n### Supported constraints\n\n:::{list-table}\n:header-rows: 1\n\n*   - Constraint\n    - Supported\n*   - <project:#model.add_linear_constraint>\n    - ✅\n*   - <project:#model.add_quadratic_constraint>\n    - ❌\n*   - <project:#model.add_second_order_cone_constraint>\n    - ❌\n*   - <project:#model.add_sos_constraint>\n    - ❌\n\n:::\n\n```{include} attribute/highs.md\n```\n\n\n## Solver-specific operations\n\n### Parameter\n\nFor [solver-specific parameters](https://ergo-code.github.io/HiGHS/stable/options/definitions/), we provide `get_raw_parameter` and `set_raw_parameter` methods to get and set the parameters.\n\n```python\nmodel = highs.Model()\n\n# get the value of the parameter\nvalue = model.get_raw_parameter(\"time_limit\")\n\n# set the value of the parameter\nmodel.set_raw_parameter(\"time_limit\", 10.0)\n```\n\n### Information\n\nHiGHS provides [information](https://ergo-code.github.io/HiGHS/stable/structures/classes/HighsInfo/) for the model. We provide `model.get_raw_information(name: str)` method to access the value of information.\n"
  },
  {
    "path": "docs/source/index.md",
    "content": "```{include} ../../README.md\n```\n\n## Contents\n```{toctree}\n:maxdepth: 2\n:titlesonly:\n:caption: User Guide\n\ngetting_started.md\nbenchmark.md\nfaq.md\nmodel.md\nvariable.md\nexpression.md\nconstraint.md\nobjective.md\nnonlinear.md\ncontainer.md\nnumpy.md\nstructure.md\ncommon_model_interface.md\ninfeasibility.md\ncallback.md\ngurobi.md\nxpress.md\ncopt.md\nmosek.md\nhighs.md\nipopt.md\nknitro.md\nchangelog.md\n```\n\n```{toctree}\n:maxdepth: 2\n:titlesonly:\n:caption: Examples\n\nexamples/economic_dispatch.md\nexamples/optimal_power_flow.md\nexamples/optimal_control_rocket.md\n```\n\n```{toctree}\n:maxdepth: 2\n:titlesonly:\n:caption: Advanced\n\ndevelop.md\n```\n\n```{toctree}\n:maxdepth: 1\n:titlesonly:\n:caption: API docs\n\napi/pyoptinterface.rst\n```\n\n## Indices and tables\n\n- {ref}`genindex`\n- {ref}`modindex`\n- {ref}`search`\n"
  },
  {
    "path": "docs/source/infeasibility.md",
    "content": "---\nfile_format: mystnb\nkernelspec:\n  name: python3\n---\n\n# Infeasibility Analysis\n\nThe optimization model is not ways feasible, and the optimizer may tell us some information about the infeasibility to diagnose the problem. There are two ways to  handle the infeasibilities:\n\n- Find the IIS (Irreducible Infeasible Set) to identify the minimal set of constraints that cause the infeasibility.\n- Relax the constraints and solve a weaker problem to find out which constraints are violated and how much.\n\nPyOptInterface currently supports the first method to find the IIS (only with Gurobi, Xpress, and COPT). The following code snippet shows how to find the IIS of an infeasible model:\n\n```{code-cell}\nimport pyoptinterface as poi\nfrom pyoptinterface import copt\n\nmodel = copt.Model()\n\nx = model.add_variable(lb=0.0, name=\"x\")\ny = model.add_variable(lb=0.0, name=\"y\")\n\ncon1 = model.add_linear_constraint(x + y, poi.Geq, 5.0)\ncon2 = model.add_linear_constraint(x + 2 * y, poi.Leq, 1.0)\n\nmodel.set_objective(x)\n\nmodel.computeIIS()\n\ncon1_iis = model.get_constraint_attribute(con1, poi.ConstraintAttribute.IIS)\ncon2_iis = model.get_constraint_attribute(con2, poi.ConstraintAttribute.IIS)\n\nprint(f\"Constraint 1 IIS: {con1_iis}\")\nprint(f\"Constraint 2 IIS: {con2_iis}\")\n```\n\nThis code snippet creates an infeasible model with two constraints and finds the IIS of the model. Obviously, the constraints are contradictory because `x + 2 * y <= 1` and `x + y >= 5` cannot be satisfied at the same time when `x` and `y` are non-negative. The optimizer will detect that the model is infeasible and return the IIS, which is the set of constraints that cause the infeasibility. We can query whether a constraint is in the IIS by calling `get_constraint_attribute` with the `ConstraintAttribute.IIS` attribute.\n\nSometimes, the bounds of the variables are not consistent with the constraints, and we need to query the IIS of the bounds of variables by calling `get_variable_attribute` with the `VariableAttribute.IISLowerBound` and `VariableAttribute.IISUpperBound` attributes.\n\nThe following code snippet shows how to tell if the bounds of a variable are in the IIS:\n\n```{code-cell}\nmodel = copt.Model()\n\nx = model.add_variable(lb=0.0, ub=2.0, name=\"x\")\ny = model.add_variable(lb=0.0, ub=3.0, name=\"y\")\n\ncon1 = model.add_linear_constraint(x + y, poi.Geq, 6.0)\n\nmodel.set_objective(x)\n\nmodel.computeIIS()\n\ncon1_iis = model.get_constraint_attribute(con1, poi.ConstraintAttribute.IIS)\nx_lb_iis = model.get_variable_attribute(x, poi.VariableAttribute.IISLowerBound)\nx_ub_iis = model.get_variable_attribute(x, poi.VariableAttribute.IISUpperBound)\ny_lb_iis = model.get_variable_attribute(y, poi.VariableAttribute.IISLowerBound)\ny_ub_iis = model.get_variable_attribute(y, poi.VariableAttribute.IISUpperBound)\n\nprint(f\"Constraint 1 IIS: {con1_iis}\")\nprint(f\"Variable x lower bound IIS: {x_lb_iis}\")\nprint(f\"Variable x upper bound IIS: {x_ub_iis}\")\nprint(f\"Variable y lower bound IIS: {y_lb_iis}\")\nprint(f\"Variable y upper bound IIS: {y_ub_iis}\")\n```\n"
  },
  {
    "path": "docs/source/ipopt.md",
    "content": "# Ipopt\n\n## Initial setup\n\n```python\nfrom pyoptinterface import ipopt\n\nmodel = ipopt.Model()\n```\n\nYou need to follow the instructions in [Getting Started](getting_started.md#ipopt) to set up the optimizer correctly.\n\n:::{attention}\n\nDue to the internal API design of Ipopt, the `ipopt.Model` lacks some features compared to other solvers. Some of these restrictions may be lifted in the future.\n\n- It does not support `delete_variable` and `delete_constraint` methods.\n- It does not support incremental modification of linear constraint like `set_normalized_rhs` and `set_normalized_coefficient`.\n- It only supports to minimize the objective function. If you want to maximize the objective function, you need to multiply the objective function by -1 manually.\n:::\n\n## The capability of `ipopt.Model`\n\n### Supported constraints\n\n:::{list-table}\n:header-rows: 1\n\n*   - Constraint\n    - Supported\n*   - <project:#model.add_linear_constraint>\n    - ✅\n*   - <project:#model.add_quadratic_constraint>\n    - ✅\n*   - <project:#model.add_second_order_cone_constraint>\n    - ❌\n*   - <project:#model.add_sos_constraint>\n    - ❌\n*   - <project:#model.add_nl_constraint>\n    - ✅\n\n:::\n\n```{include} attribute/ipopt.md\n```\n\n\n## Solver-specific operations\n\n### Parameter\n\nFor [solver-specific parameters](https://coin-or.github.io/Ipopt/OPTIONS.html), we provide `set_raw_parameter` methods to get and set the parameters.\n\n```python\nmodel = ipopt.Model()\n\n# set the value of the parameter\nmodel.set_raw_parameter(\"tol\", 1e-5)\nmodel.set_raw_parameter(\"max_iter\", 200)\n\n# For HSL library\nmodel.set_raw_parameter(\"hsllib\", \"/path/to/libhsl.so\")\nmodel.set_raw_parameter(\"linear_solver\", \"ma27\")\n```\n\n## JIT compiler used by Ipopt interface\n\nThe interface of Ipopt uses the JIT compiler to compile the nonlinear objective function, constraints and their derivatives. We have two implementations of JIT based on `llvmlite` and `tccbox`(Tiny C Compiler). The default JIT compiler is `llvmlite` and we advise you to use it for better performance brought by optimization capability of LLVM. If you want to use `tccbox`, you can specify `jit=\"C\"` when creating the `ipopt.Model` object.\n\n```python\nmodel = ipopt.Model()\n# equivalent to\nmodel = ipopt.Model(jit=\"LLVM\")\n\n# If you want to use tccbox\nmodel = ipopt.Model(jit=\"C\")\n```\n"
  },
  {
    "path": "docs/source/knitro.md",
    "content": "# KNITRO\n\n## Initial setup\n\n```python\nfrom pyoptinterface import knitro\n\nmodel = knitro.Model()\n```\n\nYou need to follow the instructions in [Getting Started](getting_started.md#knitro) to set up the optimizer correctly.\n\nIf you want to manage the license of KNITRO manually, you can create a `knitro.Env` object and pass it to the constructor of the `knitro.Model` object, otherwise a check of the license will be performed when initializing the `knitro.Model` object.\n\n```python\nenv = knitro.Env()\nmodel = knitro.Model(env)\n```\n\nFor users who want to release the license immediately after the optimization, you can call the `close` method of all models created and the `knitro.Env` object.\n\n```python\nenv = knitro.Env()\nmodel = knitro.Model(env)\n# do something with the model\nmodel.close()\nenv.close()\n```\n\n## The capability of `knitro.Model`\n\n### Supported constraints\n\n:::{list-table}\n:header-rows: 1\n*   - Constraint\n    - Supported\n*   - <project:#model.add_linear_constraint>\n    - ✅\n*   - <project:#model.add_quadratic_constraint>\n    - ✅\n*   - <project:#model.add_second_order_cone_constraint>\n    - ✅\n*   - <project:#model.add_exp_cone_constraint>\n    - ❌\n*   - <project:#model.add_sos_constraint>\n    - ❌\n*   - <project:#model.add_nl_constraint>\n    - ✅\n:::\n\n```{include} attribute/knitro.md\n```\n\n## Solver-specific operations\n\n### Parameters\n\nFor [solver-specific parameters](https://www.artelys.com/app/docs/knitro/2_userGuide/knitroOptions.html), we provide `get_raw_parameter` and `set_raw_parameter` methods to get and set the parameters.\n\n```python\nmodel = knitro.Model()\n\n# Set the value of a parameter by name\nmodel.set_raw_parameter(\"nlp_algorithm\", 1)\nmodel.set_raw_parameter(\"feastol\", 1e-8)\nmodel.set_raw_parameter(\"opttol\", 1e-8)\n\n# Set the value of a parameter by ID (using knitro.KN constants)\nmodel.set_raw_parameter(knitro.KN.PARAM_MAXIT, 1000)\n```\n\nWe also provide `knitro.KN` to contain common constants from the KNITRO C API.\n\n```python\n# Using constants for parameter IDs\nmodel.set_raw_parameter(knitro.KN.PARAM_FEASTOL, 1e-6)\n\n# Algorithm selection\nmodel.set_raw_parameter(knitro.KN.PARAM_NLP_ALGORITHM, knitro.KN.NLP_ALG_BAR_DIRECT)\n\n# Output level\nmodel.set_raw_parameter(knitro.KN.PARAM_OUTLEV, knitro.KN.OUTLEV_ITER)\n\n# MIP parameters\nmodel.set_raw_parameter(knitro.KN.PARAM_MIP_METHOD, knitro.KN.MIP_METHOD_BB)\nmodel.set_raw_parameter(knitro.KN.PARAM_MIP_OPTGAPREL, 1e-4)\n```\n\n### Variable and Constraint Properties\n\nCommon variable and constraint properties are provided through PyOptInterface dedicated methods:\n\n**Variable methods:**\n- **Bounds**: `set_variable_lb`, `get_variable_lb`, `set_variable_ub`, `get_variable_ub`\n- **Type and name**: `set_variable_name`, `get_variable_name`, `set_variable_domain`\n- **Starting point**: `set_variable_start`\n- **Solution values**: `get_value`, `get_variable_rc`\n\n**Constraint methods:**\n- **Name**: `set_constraint_name`, `get_constraint_name`\n- **Solution values**: `get_constraint_primal`, `get_constraint_dual`\n\n**Usage examples:**\n\nVariable properties:\n```python\n# Bounds\nmodel.set_variable_lb(variable, 0.0)\nlb = model.get_variable_lb(variable)\nmodel.set_variable_ub(variable, 10.0)\nub = model.get_variable_ub(variable)\n\n# Type and name\nmodel.set_variable_name(variable, \"x\")\nname = model.get_variable_name(variable)\n\n# Starting point\nmodel.set_variable_start(variable, 1.0)\n\n# Solution values\nvalue = model.get_value(variable)\nrc = model.get_variable_rc(variable)\n```\n\nConstraint properties:\n```python\n# Name\nmodel.set_constraint_name(constraint, \"c1\")\nname = model.get_constraint_name(constraint)\n\n# Solution values\nprimal = model.get_constraint_primal(constraint)\ndual = model.get_constraint_dual(constraint)\n```\n\n## Support for KNITRO callbacks\n\nUnfortunately, KNITRO's callback interface is not supported in PyOptInterface at the moment.\n"
  },
  {
    "path": "docs/source/model.md",
    "content": "---\nfile_format: mystnb\nkernelspec:\n  name: python3\n---\n\n# Model\n\nModel is the central class of the PyOptInterface package. It provides the interface to the solver and the user. The user can add variables, constraints and the objective function to the model. The model can be solved and the solution can be queried.\n\nIn this document we will only discuss the common interface of the model. For solver-specific interface, please refer to the documentation of the corresponding solver.\n\n## Create a model\nA model is a concrete instance tied to a specific solver. To create a model, we need to import the corresponding module and call the constructor of the model class. For example, to create a HiGHS model, we can do:\n\n```{code-cell}\nimport pyoptinterface as poi\nfrom pyoptinterface import highs\n\nmodel = highs.Model()\n```\n\nYou can replace `highs` with the name of the solver you want to use. The available solvers includes `copt`, `gurobi`, `highs` and `mosek`.\n\nMost commercial solvers require a `Environment`-like object to be initialized before creating a model in order to manage the license.\n\nBy default, PyOptInterface creates the global environment for each solver. If you want to create a model in a specific environment, you can pass the environment object to the constructor of the model class. The details can be found on the documentation of the corresponding optimizer: [Gurobi](gurobi.md), [HiGHS](highs.md), [COPT](copt.md), [Xpress](xpress.md), [MOSEK](mosek.md).\n\n```python\nenv = gurobi.Env()\nmodel = gurobi.Model(env)\n```\n\n## Inspect and customize the model\nWe can query and modify the parameters of the model to manipulate the behavior of the underlying solver.\n\nLike the design in `JuMP.jl`, we define a small subset of parameters that are common to all solvers. They are defined as [pyoptinterface.ModelAttribute](#pyoptinterface.ModelAttribute) enum class.\nThe meanings of these standard attributes are the same as [Model attributes](https://jump.dev/JuMP.jl/stable/moi/reference/models/#Model-attributes) and [Optimizer attributes](https://jump.dev/JuMP.jl/stable/moi/reference/models/#Optimizer-attributes) in MathOptInterface.jl.\n\n:::{list-table} **Standard [model attributes](#pyoptinterface.ModelAttribute)**\n:header-rows: 1\n:widths: 20 20\n\n*   - Attribute name\n    - Type\n*   - Name\n    - str\n*   - ObjectiveSense\n    - [ObjectiveSense](project:#pyoptinterface.ObjectiveSense)\n*   - DualStatus\n    - [ResultStatusCode](project:#pyoptinterface.ResultStatusCode)\n*   - PrimalStatus\n    - [ResultStatusCode](project:#pyoptinterface.ResultStatusCode)\n*   - RawStatusString\n    - str\n*   - TerminationStatus\n    - [TerminationStatusCode](project:#pyoptinterface.TerminationStatusCode)\n*   - BarrierIterations\n    - int\n*   - DualObjectiveValue\n    - float\n*   - NodeCount\n    - int\n*   - NumberOfThreads\n    - int\n*   - ObjectiveBound\n    - float\n*   - ObjectiveValue\n    - float\n*   - RelativeGap\n    - float\n*   - Silent\n    - float\n*   - SimplexIterations\n    - int\n*   - SolverName\n    - str\n*   - SolverVersion\n    - str\n*   - SolveTimeSec\n    - float\n*   - TimeLimitSec\n    - float\n:::\n\nWe can set the value of a parameter by calling the `set_model_attribute` method of the model:\n\n```{code-cell}\n# suppress the output of the solver\nmodel.set_model_attribute(poi.ModelAttribute.Silent, False)\n# set the time limit to 10 seconds\nmodel.set_model_attribute(poi.ModelAttribute.TimeLimitSec, 10.0)\n```\n\nThe value of parameter can be queried by calling the `get_model_attribute` method of the model.\n\nFor example, we build and solve a simple quadratic programming model, then query the objective value of the model:\n\n```{code-cell}\nx = model.add_variables(range(2), lb=0.0, ub=1.0)\nmodel.add_linear_constraint(x[0] + x[1], poi.Eq, 1.0)\n\nmodel.set_objective(x[0]*x[0] + x[1]*x[1], sense=poi.ObjectiveSense.Minimize)\n\nmodel.optimize()\n\nobjval = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n\nprint(f\"Objective value: {objval}\")\n```\n\nBesides the standard attributes, we can also set/get the solver-specific attributes by calling the `set_raw_parameter`/`get_raw_parameter` method of the model:\n\n```python\n# Gurobi\nmodel.set_raw_parameter(\"OutputFlag\", 0)\n# COPT\nmodel.set_raw_parameter(\"Presolve\", 0)\n# Xpress\nmodel.set_raw_control(\"XPRS_OUTPUTLOG\", 0)\n# MOSEK\nmodel.set_raw_parameter(\"MSK_IPAR_INTPNT_BASIS\", 0)\n```\n\n## Solve the model\nWe can solve the model by calling the `optimize` method of the model:\n\n```python\nmodel.optimize()\n```\n\n## Query the solution\nWe can query the termination status of the model after optimization by query the `TerminationStatus` attribute of the model:\n\n```{code-cell}\n# tell if the optimizer obtains the optimal solution\ntermination_status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\nassert termination_status == poi.TerminationStatusCode.OPTIMAL\n```\n\nFor value of variables and expressions, we can use `get_value` method of the model:\n\n```{code-cell}\nx0_value = model.get_value(x[0])\nexpr_value = model.get_value(x[0]*x[0])\n\nprint(f\"x[0] = {x0_value}\")\nprint(f\"x[0]^2 = {expr_value}\")\n```\n\n## Write the model to file\nThe optimization model can be written to file in LP, MPS or other formats. The `write` method of the model can be used to write the model to file:\n\n```{code-cell}\nmodel.write(\"model.lp\")\n```\n\nThe file format is determined by the file extension. Because we use the native IO procedure of the optimizer, their supported file formats and the content of output files may vary. Please refer to the documentation of the corresponding optimizer for more details.\n\n- COPT: [Doc](https://guide.coap.online/copt/en-doc/fileformats.html)\n- Gurobi: [Doc](https://www.gurobi.com/documentation/current/refman/c_write.html)\n- HiGHS: [Doc](https://ergo-code.github.io/HiGHS/stable/interfaces/c/#Highs_writeModel-Tuple{Any,%20Any})\n- Mosek: [Doc](https://docs.mosek.com/latest/capi/supported-file-formats.html)\n- Xpress: [`.lp`, `.mps`](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.writeProb.html), \n          [`.svf`](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.saveAs.html),\n          [`.bss`](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.writeBasis.html),\n          [`.asc`, `.hdr`](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.writeSol.html),\n          [`.sol`](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.writeBinSol.html),\n          [`.prt`](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.writePrtSol.html),\n          [`.slx`](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/python/HTML/problem.writeSlxSol.html),\n\n"
  },
  {
    "path": "docs/source/mosek.md",
    "content": "# Mosek\n\n## Initial setup\n\n```python\nfrom pyoptinterface import mosek\n\nmodel = mosek.Model()\n```\n\nYou need to follow the instructions in [Getting Started](getting_started.md#mosek) to set up the optimizer correctly.\n\nIf you want to manage the license of Mosek manually, you can create a `mosek.Env` object and pass it to the constructor of the `mosek.Model` object, otherwise we will initialize an implicit global `mosek.Env` object automatically and use it.\n\n```python\nenv = mosek.Env()\n\nmodel = mosek.Model(env)\n```\n\n## The capability of `mosek.Model`\n\n### Supported constraints\n\n:::{list-table}\n:header-rows: 1\n\n*   - Constraint\n    - Supported\n*   - <project:#model.add_linear_constraint>\n    - ✅\n*   - <project:#model.add_quadratic_constraint>\n    - ✅\n*   - <project:#model.add_second_order_cone_constraint>\n    - ✅\n*   - <project:#model.add_exp_cone_constraint>\n    - ✅\n*   - <project:#model.add_sos_constraint>\n    - ❌\n\n:::\n\n```{include} attribute/mosek.md\n```\n\n## Solver-specific operations\n\n### Parameter\n\nFor [solver-specific parameters](https://docs.mosek.com/latest/capi/param-groups.html), we provide `get_raw_parameter` and `set_raw_parameter` methods to get and set the parameters.\n\n```python\nmodel = mosek.Model()\n\n# get the value of the parameter\nvalue = model.get_raw_parameter(\"MSK_DPAR_OPTIMIZER_MAX_TIME\")\n\n# set the value of the parameter\nmodel.set_raw_parameter(\"MSK_DPAR_OPTIMIZER_MAX_TIME\", 10.0)\n```\n\n### Information\n\nMosek provides [information](https://docs.mosek.com/latest/capi/solver-infitems.html) for the model. We provide `model.get_raw_information(name: str)` method to access the value of information.\n"
  },
  {
    "path": "docs/source/nonlinear.md",
    "content": "---\nfile_format: mystnb\nkernelspec:\n  name: python3\n---\n# Nonlinear Programming\n\n## Introduction\n\nCompared with the linear and quadratic expressions and objectives we have discussed in the previous sections, nonlinear programming is more general and can handle a wider range of problems. In this section, we will introduce how to use PyOptInterface to formulate and solve general nonlinear programming problems.\n\n:::{note}\n\nBefore trying out the code snippets, please ensure that you have completed the installation of PyOptInterface with correct dependencies via `pip install pyoptinterface[nlp]` and solvers that support nonlinear programming (IPOPT, COPT, Xpress, Gurobi, KNITRO) as described in the [Getting Started](getting_started.md) section.\n:::\n\n## Construct nonlinear expressions\n\nNonlinear expressions are more complex than linear and quadratic expressions, and they can include various nonlinear functions such as trigonometric functions, exponential functions, logarithmic functions, etc. In PyOptInterface, we must declare a `nl.graph()` context to construct nonlinear expressions. The `nl.graph()` context is used to trace the computational graph of the nonlinear expression, which allows PyOptInterface to automatically differentiate the expression and calculate the gradients and Hessians.\n\n```{code-cell}\nimport pyoptinterface as poi\nfrom pyoptinterface import nl, ipopt\n\nmodel = ipopt.Model()\n\nx = model.add_variable(name=\"x\")\ny = model.add_variable(name=\"y\")\n\nwith nl.graph():\n    z = nl.exp(x) * nl.pow(y, 2)\n    model.add_nl_constraint(z <= 10.0)\n```\n\nIn the code snippet above, we first import the `nl` module, which contains the nonlinear programming utilities including a set of nonlinear functions that can be used in PyOptInterface. Then, we create an `ipopt.Model` object to represent the optimization problem.\n\nWe then add two variables `x` and `y` to the model. After that, we enter the `nl.graph()` context, where we can construct nonlinear expressions using the functions provided by the `nl` module. In this case, we define a nonlinear expression `z = exp(x) * pow(y, 2)` and add a nonlinear constraint `z <= 10.0` to the model.\n\nIn the `nl.graph()` context, we can use various nonlinear functions provided by the `nl` module to construct nonlinear expressions. The functions are designed to be similar to the mathematical notation, making it easy to read and write nonlinear expressions.\n\nPyOptInterface currently supports the following nonlinear operators:\n\n:::{list-table} **Unary functions**\n:header-rows: 1\n\n*   - Operator\n    - Example\n*   - `-` (negation)\n    - `y = -x`\n*   - sin\n    - `y = nl.sin(x)`\n*   - cos\n    - `y = nl.cos(x)`\n*   - tan\n    - `y = nl.tan(x)`\n*   - asin\n    - `y = nl.asin(x)`\n*   - acos\n    - `y = nl.acos(x)`\n*   - atan\n    - `y = nl.atan(x)`\n*   - abs\n    - `y = nl.abs(x)`\n*   - sqrt\n    - `y = nl.sqrt(x)`\n*   - exp\n    - `y = nl.exp(x)`\n*   - log\n    - `y = nl.log(x)`\n*   - log10\n    - `y = nl.log10(x)`\n:::\n\n:::{list-table} **Binary functions**\n:header-rows: 1\n\n*   - Operator\n    - Example\n*   - `+`\n    - `z = x + y`\n*   - `-`\n    - `z = x - y`\n*   - `*`\n    - `z = x * y`\n*   - `/`\n    - `z = x / y`\n*   - `**`\n    - `z = x ** y`\n*   - pow\n    - `z = nl.pow(x, y)`\n:::\n\nWe can also use `nl.ifelse` to implement the conditional operator. For example, the following code snippet defines a absolute value function $f(x) = |x|$:\n\n```{code-cell}\ndef f(x):\n    return nl.ifelse(x >= 0, x, -x)\n\nwith nl.graph():\n    y = f(x)\n    model.add_nl_constraint(y <= 2)\n```\n\n`nl.ifelse` accepts three arguments: a condition, a value when the condition is true, and a value when the condition is false. The function returns the value of the second argument if the condition is true; otherwise, it returns the value of the third argument. The condition variable must be a boolean variable, which can be obtained by comparing two variables using the comparison operators `==`, `!=`, `<`, `<=`, `>`, and `>=`.\n\nAnother interesting fact is that you can construct nonlinear expressions in the context of `nl.graph` that are prohibited outside the context. For example, you can construct $(x+2)^3$ in the following way:\n\n```{code-cell}\nwith nl.graph():\n    z = (x + 2) ** 3\n\n# Illegal outside nl.graph context because it is a nonlinear expression\n# z = (x + 2) ** 3  # This will raise an error\n```\n\n## Nonlinear constraints and objectives\n\nAfter constructing nonlinear expressions, we can use them in constraints and objectives. For example, the following code snippet defines a nonlinear programming problem.\n\n```{code-cell}\nmodel = ipopt.Model()\nx = model.add_variable(lb = 0.0)\ny = model.add_variable(lb = 0.0)\n\nwith nl.graph():\n    model.add_nl_constraint(x ** 4 + y ** 4 <= 4.0)\n    model.add_nl_constraint(x * y >= 1.0)\n\n    model.add_nl_objective(nl.exp(x) + nl.exp(y))\n\nmodel.optimize()\n```\n\n```{code-cell}\nx_value = model.get_value(x)\ny_value = model.get_value(y)\n\nprint(f\"x = {x_value}, y = {y_value}\")\n```\n\nNonlinear constraint can be declared by calling `add_nl_constraint` method. Like the linear and quadratic constraints, you can specify the sense/right-hand-side of constraint, use an interval of values to represent a two-sided constraint, or use a comparison operator like `<=`, `==`, or `>=` to create the constraint.\n\n```{code-cell}\n# One-sided nonlinear constraint\nwith nl.graph():\n    model.add_nl_constraint(x ** 2 + y ** 2 <= 1.0)\n    # equivalent to\n    model.add_nl_constraint(x ** 2 + y ** 2, poi.Leq, 1.0)\n\n# Two-sided nonlinear constraint\nwith nl.graph():\n    model.add_nl_constraint(x ** 2 + y ** 2, (1.0, 2.0))\n    # equivalent to\n    model.add_nl_constraint(x ** 2 + y ** 2, poi.Leq, 2.0)\n    model.add_nl_constraint(x ** 2 + y ** 2, poi.Geq, 1.0)\n```\n\nSimilarly, the nonlinear objective can be declared by calling `add_nl_objective` method. It is noteworthy that `add_nl_objective` only adds a nonlinear term to the objective and can be called multiple times to construct a sum of nonlinear terms as objective.\n\n```{code-cell}\n# Nonlinear objective\nwith nl.graph():\n    model.add_nl_objective(nl.sin(x) + nl.cos(y))\n```\n\nBecause the nonlinear expressions are captured by the current `nl.graph()` context, both `add_nl_constraint` and `add_nl_objective` methods must be called within the same `nl.graph()` context. If you try to call them outside the context, it will raise an error.\n\nFinally, we will use the well-known [Rosenbrock function](https://jump.dev/JuMP.jl/stable/tutorials/nonlinear/simple_examples/#The-Rosenbrock-function) as another example:\n\n```{code-cell}\nfrom pyoptinterface import nl, ipopt\n\nmodel = ipopt.Model()\n\nx = model.add_variable()\ny = model.add_variable()\n\nwith nl.graph():\n    model.add_nl_objective((1 - x) ** 2 + 100 * (y - x ** 2) ** 2)\n\nmodel.optimize()\n```\n\n```{code-cell}\nx_value = model.get_value(x)\ny_value = model.get_value(y)\n\nprint(f\"x = {x_value}, y = {y_value}\")\n```\n\n## Mixing nonlinear and linear/quadratic constraints together\n\nIntroducing nonlinear functions does not prevent you from using the `add_linear_constraint`, `add_quadratic_constraint` methods. You can add both nonlinear constraints and linear/quadratic constraints in the same optimization problem.\n\nWe will use the [clnlbeam problem](https://jump.dev/JuMP.jl/stable/tutorials/nonlinear/simple_examples/#The-clnlbeam-problem) as example:\n\n```{code-cell}\nfrom pyoptinterface import nl, ipopt\nimport pyoptinterface as poi\n\nmodel = ipopt.Model()\n\nN = 1000\nh = 1 / N\nalpha = 350\n\nt = model.add_m_variables(N + 1, lb=-1.0, ub=1.0)\nx = model.add_m_variables(N + 1, lb=-0.05, ub=0.05)\nu = model.add_m_variables(N + 1)\n\nfor i in range(N):\n    with nl.graph():\n        model.add_nl_objective(\n            0.5 * h * (u[i] * u[i] + u[i + 1] * u[i + 1])\n            + 0.5 * alpha * h * (nl.cos(t[i]) + nl.cos(t[i + 1]))\n        )\n        model.add_nl_constraint(\n            x[i + 1] - x[i] - 0.5 * h * (nl.sin(t[i]) + nl.sin(t[i + 1])) == 0.0\n        )\n        model.add_linear_constraint(\n            t[i + 1] - t[i] - 0.5 * h * u[i + 1] - 0.5 * h * u[i] == 0.0\n        )\n\nmodel.optimize()\n```\n\n```{code-cell}\nobjective_value = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n\nprint(f\"Objective value: {objective_value}\")\n```\n\n## How to use `nl.graph` to capture the similar structure\n\nYou might be wondering how to place the `nl.graph()` context manager correctly in your code. The key is to ensure that all nonlinear constraints and objectives that share the same structure are enclosed within the same `nl.graph()` context.\n\nAs a rule of thumb, `nl.graph` should always be used inside the `for` loop instead of outside, so that each graph will have the same pattern and PyOptInterface can recognize the similar structures to accelerate the automatic differentiation process. This is particularly important when you have a large number of nonlinear constraints or objectives that share the same structure, as it can significantly improve the performance of the optimization process as discussed in our research paper [Accelerating Optimal Power Flow with Structure-aware Automatic Differentiation and Code Generation](https://ieeexplore.ieee.org/document/10721402).\n\nIn the clnlbeam example above, we have placed the `nl.graph()` context inside the `for` loop, which allows us to capture the structure of the nonlinear constraints and objectives for each iteration.\n\n## More complex examples\n\nIn practice, the nonlinear constraints may have the same structure but with different parameters, we encourage you to read our [optimal power flow](examples/optimal_power_flow.md) and [optimal control](examples/optimal_control_rocket.md) examples to learn how to construct more complex nonlinear programming problems.\n"
  },
  {
    "path": "docs/source/numpy.md",
    "content": "---\nfile_format: mystnb\nkernelspec:\n  name: python3\n---\n\n# Matrix Modeling\n\nIn the previous [container](container.md) section, we have introduced the `tupledict` container to store and manipulate multidimensional data.\n\nHowever, due to the Bring Your Own Container (BYOC) principle, variables and constraints in PyOptInterface can just simple Python objects that can be stored in Numpy `ndarray` directly as a multidimensional array, and you can enjoy the features of Numpy such like [fancy-indexing](https://numpy.org/doc/stable/user/basics.indexing.html) automatically.\n\n## N-queen problem\n\nWe will use N-queens problem as example to show how to use Numpy `ndarray` as container to store 2-dimensional variables and construct optimization model.\n\nFirstly, we import the necessary modules:\n\n```{code-cell}\nimport numpy as np\nimport pyoptinterface as poi\nfrom pyoptinterface import highs\n\nmodel = highs.Model()\n```\n\nThen we create a 2-dimensional variable `x` with shape $N \\times N$ to represent the placement of queens. Each element of `x` is a binary variable that indicates whether a queen is placed at the corresponding position. We use `object` as the data type of `x` to store the binary variables. The following code snippet creates the variables:\n\n```{code-cell}\nN = 8\n\nx = np.empty((N, N), dtype=object)\nfor i in range(N):\n    for j in range(N):\n        x[i, j] = model.add_variable(domain=poi.VariableDomain.Binary)\n```\n\nNext, we add the constraints to ensure that each row, each column has exact one queen, and each diagonal has at most one queen. \n\n```{code-cell}\nfor i in range(N):\n    # Row and column\n    model.add_linear_constraint(poi.quicksum(x[i, :]), poi.Eq, 1.0)\n    model.add_linear_constraint(poi.quicksum(x[:, i]), poi.Eq, 1.0)\nfor i in range(-N+1, N):\n    # Diagonal\n    model.add_linear_constraint(poi.quicksum(x.diagonal(i)), poi.Leq, 1.0)\n    # Anti-diagonal\n    model.add_linear_constraint(poi.quicksum(np.fliplr(x).diagonal(i)), poi.Leq, 1.0)\n```\n\nFinally, we solve the model.\n\n```{code-cell}\nmodel.optimize()\n\nprint(\"Termination status:\", model.get_model_attribute(poi.ModelAttribute.TerminationStatus))\n```\n\nThe solution can be obtained and visualized by the following code:\n\n```{code-cell}\nget_v = np.vectorize(lambda x: model.get_value(x))\nx_value = get_v(x)\n\nprint(x_value.astype(int))\n```\n\n## Built-in functions to add variables and constraints as Numpy `ndarray`\n\nAlthough you can construct the `ndarray` of variables and constraints manually, PyOptInterface provides built-in functions to simplify the process. The following code snippet shows how to use the built-in functions to add variables and constraints as Numpy `ndarray`:\n\n```{code-cell}\nmodel = highs.Model()\n\nx = model.add_m_variables(N)\n\nA = np.eye(N)\nb_ub = np.ones(N)\nb_lb = np.ones(N)\n\nmodel.add_m_linear_constraints(A, x, poi.Leq, b_ub)\nmodel.add_m_linear_constraints(A, x, poi.Geq, b_lb)\n\nmodel.set_objective(poi.quicksum(x))\n\nmodel.optimize()\n```\n\nHere we use two built-in functions `add_m_variables` and `add_m_linear_constraints` to add variables and constraints as Numpy `ndarray` respectively.\n\nThe reference of these functions are listed in <project:#model.add_m_variables> and <project:#model.add_m_linear_constraints>.\n\n`add_m_variables` returns a `ndarray` of variables with the specified shape.\n\n`add_m_linear_constraints` adds multiple linear constraints to the model at once formulated as $Ax \\le b$ or $Ax = b$ or $Ax \\ge b$ where the matrix $A$ can be a dense `numpy.ndarray` or a sparse matrix `scipy.sparse.sparray`.\n"
  },
  {
    "path": "docs/source/objective.md",
    "content": "# Objective\n\nThe objective is a function of the variables that the optimization algorithm seeks to minimize or maximize.\n\nCurrently PyOptInterface supports the following types of objective functions:\n- Linear objective function\n- Quadratic objective function\n\nThe objective function is typically minimized, but it can also be maximized. The objective function is defined as:\n\n```python\nobjective = x*x\nmodel.set_objective(objective, poi.ObjectiveSense.Minimize)\n```\n\nwhere `objective` is the handle of the objective function and `sense` is the optimization sense, which can be either `pyoptinterface.ObjectiveSense.Minimize` or `pyoptinterface.ObjectiveSense.Maximize`.\n\nThe `set_objective` function can be called multiple times to change the objective function of the model.\n\n## Modify objective function\n\nThe linear part of the objective function can be modified by calling the `set_objective_coefficient` method of the model:\n\n```python\nobj = 2*x + 3*y\nmodel.set_objective(obj, poi.ObjectiveSense.Minimize)\n\n# modify the coefficient of the variable x\nmodel.set_objective_coefficient(x, 5)\n```\n"
  },
  {
    "path": "docs/source/roadmap.md",
    "content": "## Roadmap\n\nThis is the roadmap for the project. It is a living document and will be updated as the project progresses.\n\n- Write model to lp, mps files\n- User-defined callbacks in optimization (like JuMP.jl, we can support lazy constraints and user-cuts to selected solvers)\n- Compute conflict constraints of infeasible model"
  },
  {
    "path": "docs/source/structure.md",
    "content": "---\nfile_format: mystnb\nkernelspec:\n  name: python3\n---\n\n# Building Bigger Optimization Model\n\nIn this document, we will introduce how to decompose the process of building a large optimization model into smaller parts and how to compose them together. This is a common practice in optimization modeling to make the code more readable and maintainable.\n\nGenerally speaking, we need two important parts to build an optimization model:\n\n1. A [model](model.md) object that represents the optimization problem and communicates with the underlying optimizer. Due to the lightweight design philosophy of PyOptInterface, the model object is just a thin wrapper around the optimizer API, and it does not store the optimization problem itself. The model object is responsible for creating and managing variables, constraints, and the objective function, as well as solving the optimization problem.\n2. A dict-like container to store the variables and constraints. We recommend the [`types.SimpleNamespace`](https://docs.python.org/3/library/types.html#types.SimpleNamespace) object as the container to store the variables and constraints. It is a simple way to store and manipulate the optimization problem in Python. You can use attribute access to get and set the variables and constraints.\n```{code-cell}\nimport types\n\ncontainer = types.SimpleNamespace()\ncontainer.x = 1\ncontainer.y = 2\n\nprint(container.x, container.y)\n```\n\nThus, we can define a class to represent the optimization model and use the container to store the variables and constraints.\n```{code-cell}\nimport numpy as np\nimport pyoptinterface as poi\nfrom pyoptinterface import highs\n\nclass OptModel:\n    def __init__(self):\n        self.container = types.SimpleNamespace()\n        self.model = highs.Model()\n```\n\nThen we can define small functions to declare the variables and constraints and add them to the model. We take the N-queens problem as an example.\n```{code-cell}\ndef declare_queen_variables(m:OptModel, N):\n    model = m.model\n    x = np.empty((N, N), dtype=object)\n    for i in range(N):\n        for j in range(N):\n            x[i, j] = model.add_variable(domain=poi.VariableDomain.Binary)\n    container = m.container\n    container.x = x\n    container.N = N\n\ndef add_row_column_constraints(m:OptModel):\n    container = m.container\n    N = container.N\n    x = container.x\n    model = m.model\n\n    for i in range(N):\n        # Row and column\n        model.add_linear_constraint(poi.quicksum(x[i, :]), poi.Eq, 1.0)\n        model.add_linear_constraint(poi.quicksum(x[:, i]), poi.Eq, 1.0)\n\ndef add_diagonal_constraints(m:OptModel):\n    container = m.container\n    N = container.N\n    x = container.x\n    model = m.model\n\n    for i in range(-N+1, N):\n        # Diagonal\n        model.add_linear_constraint(poi.quicksum(x.diagonal(i)), poi.Leq, 1.0)\n        # Anti-diagonal\n        model.add_linear_constraint(poi.quicksum(np.fliplr(x).diagonal(i)), poi.Leq, 1.0)\n```\n\nFinally, we can compose these functions to build the optimization model and solve it.\n```{code-cell}\nm = OptModel()\n\nN = 8\ndeclare_queen_variables(m, N)\nadd_row_column_constraints(m)\nadd_diagonal_constraints(m)\n\nm.model.optimize()\n\nprint(\"Termination status:\", m.model.get_model_attribute(poi.ModelAttribute.TerminationStatus))\n```\n"
  },
  {
    "path": "docs/source/variable.md",
    "content": "# Variable\n\nVariable represents a decision variable in the optimization problem. It can be created by calling the [`add_variable`](#model.add_variable) method of the model:\n\n```python\nimport pyoptinterface as poi\nfrom pyoptinterface import highs\n\nmodel = highs.Model()\n\nx = model.add_variable(lb=0, ub=1.0, domain=poi.VariableDomain.Continuous, name=\"x\")\n```\n\n## Variable Attributes\nAfter a variable is created, we can query or modify its attributes. The following table lists the standard [variable attributes](#pyoptinterface.VariableAttribute):\n\n:::{list-table} **Standard [variable attributes](#pyoptinterface.VariableAttribute)**\n:header-rows: 1\n:widths: 20 20\n\n*   - Attribute name\n    - Type\n*   - Name\n    - str\n*   - LowerBound\n    - float\n*   - UpperBound\n    - float\n*   - Domain\n    - [VariableDomain](project:#pyoptinterface.VariableDomain)\n*   - PrimalStart\n    - float\n*   - Value\n    - float\n*   - IISLowerBound\n    - bool\n*   - IISUpperBound\n    - bool\n*   - ReducedCost\n    - float\n:::\n\n```python\n# set the lower bound of the variable\nmodel.set_variable_attribute(x, poi.VariableAttribute.LowerBound, 0.0)\n# set the upper bound of the variable\nmodel.set_variable_attribute(x, poi.VariableAttribute.UpperBound, 1.0)\n\n# For mixed-integer programming, we can set the initial value of the variable\nmodel.set_variable_attribute(x, poi.VariableAttribute.PrimalStart, 0.5)\n\n# get the value of the variable after optimization\nx_value = model.get_variable_attribute(x, poi.VariableAttribute.Value)\n```\n\nThe most common operation is to set the bounds of the variable. We can use the [`set_variable_bounds`](#model.set_variable_bounds) method of the model to set the lower and upper bounds of the variable at the same time:\n\n```python\nx = model.add_variable(name=\"x\")\nmodel.set_variable_bounds(x, 0.0, 1.0)\n```\n\n## Delete variable\nWe can delete a variable by calling the [`delete_variable`](#model.delete_variable) method of the model:\n\n```python\nmodel.delete_variable(x)\n```\n\nAfter a variable is deleted, it cannot be used in the model anymore, otherwise an exception will be raised.\n\nWe can query whether a variable is active by calling the [`is_variable_active`](#model.is_variable_active) method of the model:\n\n```python\nis_active = model.is_variable_active(x)\n```\n"
  },
  {
    "path": "docs/source/xpress.md",
    "content": "# Xpress\n\n## Initial setup\n\n```python\nfrom pyoptinterface import xpress\nmodel = xpress.Model()\n```\n\nYou need to follow the instructions in [Getting Started](getting_started.md#xpress) to set up the optimizer correctly.\n\nIf you want to manage the license of Xpress manually, you can create a `xpress.Env` object and pass it to the constructor of the `xpress.Model` object, otherwise we will initialize an implicit global `xpress.Env` object automatically and use it.\n\n```python\nenv = xpress.Env()\nmodel = xpress.Model(env)\n```\n\nFor users who want to release the license immediately after the optimization, you can call the `close` method of all models created and the `xpress.Env` object.\n\n```python\nenv = xpress.Env()\nmodel = xpress.Model(env)\n# do something with the model\nmodel.close()\nenv.close()\n```\n\n## The capability of `xpress.Model`\n\n### Supported constraints\n\n:::{list-table}\n:header-rows: 1\n*   - Constraint\n    - Supported\n*   - <project:#model.add_linear_constraint>\n    - ✅\n*   - <project:#model.add_quadratic_constraint>\n    - ✅\n*   - <project:#model.add_second_order_cone_constraint>\n    - ✅\n*   - <project:#model.add_exp_cone_constraint>\n    - ✅\n*   - <project:#model.add_sos_constraint>\n    - ✅\n*   - <project:#model.add_nl_constraint>\n    - ✅\n:::\n\n```{include} attribute/xpress.md\n```\n\n## Solver-specific operations\n\n### Controls and Attributes\n\nXpress uses different terminology than PyOptInterface:\n- **Controls** govern the solution procedure and output format (similar to PyOptInterface parameters)\n- **Attributes** are read-only properties of the problem and solution\n\nPyOptInterface maps these as follows:\n- PyOptInterface **parameters** correspond to Xpress controls\n- PyOptInterface **attributes** may access Xpress controls, attributes, or variable/constraint properties through dedicated methods\n\n### Controls (Parameters)\n\nFor [solver-specific controls](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML/chapter7.html), we provide `get_raw_control` and `set_raw_control` methods.\n\n```python\nmodel = xpress.Model()\n# Get the value of a control\nvalue = model.get_raw_control(\"XPRS_TIMELIMIT\")\n# Set the value of a control\nmodel.set_raw_control(\"XPRS_TIMELIMIT\", 10.0)\n```\n\n### Attributes\n\nFor [problem attributes](https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML/chapter8.html), we provide `get_raw_attribute` method.\n\n```python\n# Get number of columns in the problem\ncols = model.get_raw_attribute(\"XPRS_COLS\")\n```\n\nWe also provide `xpress.XPRS` to contain common constants from the Xpress C API.\n\n```python\n# Using constants\nvalue = model.get_raw_control_dbl_by_id(xpress.XPRS.TIMELIMIT)\n```\n\n### Variable and Constraint Properties\n\nCommon variable and constraint properties are provided through PyOptInterface dedicated methods:\n\n**Variable methods:**\n- **Bounds**: `set_variable_lowerbound`, `get_variable_lowerbound`, `set_variable_upperbound`, `get_variable_upperbound`, `set_variable_bounds`\n- **Objective**: `set_objective_coefficient`, `get_objective_coefficient`\n- **Type and name**: `set_variable_type`, `get_variable_type`, `set_variable_name`, `get_variable_name`\n- **Solution values**: `get_variable_value`, `get_variable_rc`, `get_variable_primal_ray`\n- **Basis status**: `is_variable_basic`, `is_variable_nonbasic_lb`, `is_variable_nonbasic_ub`, `is_variable_superbasic`\n- **IIS information**: `is_variable_lowerbound_IIS`, `is_variable_upperbound_IIS`\n\n**Constraint methods:**\n- **Definition**: `set_constraint_sense`, `get_constraint_sense`, `set_constraint_rhs`, `get_constraint_rhs`, `set_constraint_name`, `get_constraint_name`\n- **Coefficients**: `set_normalized_coefficient`, `get_normalized_coefficient`, `set_normalized_rhs`, `get_normalized_rhs`\n- **Solution values**: `get_constraint_dual`, `get_constraint_slack`, `get_constraint_dual_ray`\n- **Basis status**: `is_constraint_basic`, `is_constraint_nonbasic_lb`, `is_constraint_nonbasic_ub`, `is_constraint_superbasic`\n- **IIS information**: `is_constraint_in_IIS`\n\n**Usage examples:**\n\nVariable properties:\n```python\n# Bounds\nmodel.set_variable_lowerbound(variable, 0.0)\nlb = model.get_variable_lowerbound(variable)\nmodel.set_variable_upperbound(variable, 10.0)\nub = model.get_variable_upperbound(variable)\n\n# Objective coefficient\nmodel.set_objective_coefficient(variable, 2.0)\ncoef = model.get_objective_coefficient(variable)\n\n# Type and name\nmodel.set_variable_type(variable, VariableDomain.Integer)\nvtype = model.get_variable_type(variable)\nmodel.set_variable_name(variable, \"x\")\nname = model.get_variable_name(variable)\n\n# Solution values\nvalue = model.get_variable_value(variable)\nrc = model.get_variable_rc(variable)\nray = model.get_variable_primal_ray(variable)\n\n# Basis status\nif model.is_variable_basic(variable):\n    ...\n```\n\nConstraint properties:\n```python\n# Sense and RHS\nmodel.set_constraint_sense(constraint, ConstraintSense.LessEqual)\nsense = model.get_constraint_sense(constraint)\nmodel.set_constraint_rhs(constraint, 5.0)\nrhs = model.get_constraint_rhs(constraint)\n\n# Name\nmodel.set_constraint_name(constraint, \"c1\")\nname = model.get_constraint_name(constraint)\n\n# Solution values\ndual = model.get_constraint_dual(constraint)\nslack = model.get_constraint_slack(constraint)\nray = model.get_constraint_dual_ray(constraint)\n\n# Basis status\nif model.is_constraint_basic(constraint):\n    ...\n```\n"
  },
  {
    "path": "include/pyoptinterface/cache_model.hpp",
    "content": "#pragma once\n\n#include <concepts>\n#include <vector>\n#include <span>\n\n// This file defines some common utilities to store the optimization model in a compact way\n\ntemplate <std::integral ColumnIndexT, std::integral VariableIndexT,\n          std::floating_point CoefficientT>\nstruct LinearExpressionCache\n{\n\tstd::vector<ColumnIndexT> column_ptr = {0};\n\tstd::vector<VariableIndexT> variables;\n\tstd::vector<CoefficientT> coefficients;\n\n\ttemplate <std::integral IT, std::floating_point FT>\n\tvoid add_row(std::span<const IT> row_variables, std::span<const FT> row_coefficients)\n\t{\n\t\tvariables.insert(variables.end(), row_variables.begin(), row_variables.end());\n\t\tcoefficients.insert(coefficients.end(), row_coefficients.begin(), row_coefficients.end());\n\t\tcolumn_ptr.push_back(variables.size());\n\t}\n};\n\ntemplate <std::integral ColumnIndexT, std::integral VariableIndexT,\n          std::floating_point CoefficientT>\nstruct QuadraticExpressionCache\n{\n\tstd::vector<ColumnIndexT> column_ptr = {0};\n\tstd::vector<VariableIndexT> variable_1s;\n\tstd::vector<VariableIndexT> variable_2s;\n\tstd::vector<CoefficientT> coefficients;\n\n\tstd::vector<ColumnIndexT> lin_column_ptr = {0};\n\tstd::vector<VariableIndexT> lin_variables;\n\tstd::vector<CoefficientT> lin_coefficients;\n\n\ttemplate <std::integral IT, std::floating_point FT>\n\tvoid add_row(std::span<const IT> row_variable_1s, std::span<const IT> row_variable_2s,\n\t             std::span<const FT> row_quadratic_coefficients,\n\t             std::span<const IT> row_lin_variables, std::span<const FT> row_lin_coefficients)\n\t{\n\t\tvariable_1s.insert(variable_1s.end(), row_variable_1s.begin(), row_variable_1s.end());\n\t\tvariable_2s.insert(variable_2s.end(), row_variable_2s.begin(), row_variable_2s.end());\n\t\tcoefficients.insert(coefficients.end(), row_quadratic_coefficients.begin(),\n\t\t                    row_quadratic_coefficients.end());\n\t\tcolumn_ptr.push_back(variable_1s.size());\n\n\t\tlin_variables.insert(lin_variables.end(), row_lin_variables.begin(),\n\t\t                     row_lin_variables.end());\n\t\tlin_coefficients.insert(lin_coefficients.end(), row_lin_coefficients.begin(),\n\t\t                        row_lin_coefficients.end());\n\t\tlin_column_ptr.push_back(lin_variables.size());\n\t}\n};\n"
  },
  {
    "path": "include/pyoptinterface/container.hpp",
    "content": "#pragma once\n\n#include <bit>\n#include <vector>\n#include <concepts>\n#include <assert.h>\n\n#include \"pyoptinterface/core.hpp\"\n\n// index as the key, variable as the value\n// index is monotone increasing\n// if we want to delete\ta index, we can set the value to -1\ntemplate <std::signed_integral T>\nclass MonotoneVector\n{\n  private:\n\tstd::vector<T> m_data;\n\tT m_start = 0;\n\tT m_update_start = 0;\n\tstd::size_t m_last_correct_index = 0;\n\tstd::size_t m_cardinality = 0;\n\n  public:\n\tMonotoneVector() = default;\n\tMonotoneVector(T start) : m_start(start), m_update_start(start)\n\t{\n\t}\n\n\tIndexT add_index()\n\t{\n\t\tIndexT index = m_data.size();\n\t\tm_data.push_back(m_start);\n\t\tm_cardinality += 1;\n\t\treturn index;\n\t}\n\tvoid delete_index(const IndexT &index)\n\t{\n\t\tif (m_data[index] < 0)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tif (index < m_last_correct_index)\n\t\t{\n\t\t\tm_update_start = m_data[index];\n\t\t\tm_last_correct_index = index;\n\t\t}\n\t\tm_data[index] = -1;\n\t\tm_cardinality -= 1;\n\t}\n\tbool has_index(const IndexT &index)\n\t{\n\t\treturn get_index(index) >= 0;\n\t}\n\tT get_index(const IndexT &index)\n\t{\n\t\tif (index >= m_data.size())\n\t\t{\n\t\t\tthrow std::runtime_error(\"Index out of range\");\n\t\t}\n\t\tif (m_data[index] >= 0 && index > m_last_correct_index)\n\t\t{\n\t\t\tupdate_to(index);\n\t\t}\n\t\treturn m_data[index];\n\t}\n\tstd::size_t num_active_indices() const\n\t{\n\t\treturn m_cardinality;\n\t}\n\tstd::vector<IndexT> get_active_indices() const\n\t{\n\t\tstd::vector<IndexT> indices;\n\t\tindices.reserve(m_cardinality);\n\t\tfor (IndexT i = 0; i < m_data.size(); i++)\n\t\t{\n\t\t\tif (m_data[i] >= 0)\n\t\t\t{\n\t\t\t\tindices.push_back(i);\n\t\t\t}\n\t\t}\n\t\treturn indices;\n\t}\n\tvoid update_to(IndexT index)\n\t{\n\t\t// we ensure that m_data[index] >= 0\n\t\tT counter = m_update_start;\n\t\tconstexpr int STEP_STATE = 1;\n\t\tconstexpr int JUMP_STATE = 2;\n\t\tint state;\n\t\tstd::size_t jump_start_index;\n\t\tif (m_data[m_last_correct_index] < 0)\n\t\t{\n\t\t\tstate = JUMP_STATE;\n\t\t\tjump_start_index = m_last_correct_index;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstate = STEP_STATE;\n\t\t\tcounter++;\n\t\t}\n\t\tfor (IndexT i = m_last_correct_index + 1; i <= index;)\n\t\t{\n\t\t\tswitch (state)\n\t\t\t{\n\t\t\tcase JUMP_STATE:\n\t\t\t\tif (m_data[i] >= 0)\n\t\t\t\t{\n\t\t\t\t\tm_data[jump_start_index] = -i;\n\t\t\t\t\tstate = STEP_STATE;\n\t\t\t\t\tgoto CONTINUE_STEP;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\tCONTINUE_JUMP:\n\t\t\t\t\tT new_i = -m_data[i];\n\t\t\t\t\tif (new_i > index)\n\t\t\t\t\t{\n\t\t\t\t\t\ti = new_i;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ti++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase STEP_STATE:\n\t\t\t\tif (m_data[i] < 0)\n\t\t\t\t{\n\t\t\t\t\tstate = JUMP_STATE;\n\t\t\t\t\tjump_start_index = i;\n\t\t\t\t\tgoto CONTINUE_JUMP;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\tCONTINUE_STEP:\n\t\t\t\t\tm_data[i] = counter;\n\t\t\t\t\tcounter++;\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow std::runtime_error(\"Unknown state\");\n\t\t\t}\n\t\t}\n\t\tm_last_correct_index = index;\n\t\tm_update_start = m_data[index];\n\t}\n\tvoid clear()\n\t{\n\t\tm_data.clear();\n\t\tm_update_start = m_start;\n\t\tm_last_correct_index = 0;\n\t\tm_cardinality = 0;\n\t}\n};\n\ntemplate <std::unsigned_integral ChunkT, std::signed_integral ResultT>\nclass ChunkedBitVector\n{\n  public:\n\tChunkedBitVector(ResultT start = 0) : m_start(start)\n\t{\n\t\tclear();\n\t}\n\n\tIndexT add_index()\n\t{\n\t\tIndexT result;\n\t\tif (m_next_bit == CHUNK_WIDTH)\n\t\t{\n\t\t\tresult = m_data.size() << LOG2_CHUNK_WIDTH;\n\n\t\t\tm_data.push_back(1);\n\t\t\tm_cumulated_ranks.push_back(m_cumulated_ranks.back());\n\t\t\tm_chunk_ranks.push_back(-1);\n\t\t\tm_next_bit = 1;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto last_chunk_end = (m_data.size() - 1) << LOG2_CHUNK_WIDTH;\n\t\t\tresult = last_chunk_end + m_next_bit;\n\t\t\tChunkT &last_chunk = m_data.back();\n\t\t\t// set m_next_bit to 1\n\t\t\tlast_chunk |= (ChunkT{1} << m_next_bit);\n\t\t\tm_next_bit++;\n\t\t}\n\t\treturn result;\n\t}\n\n\t// Add N new indices, return the start of index\n\tIndexT add_indices(int N)\n\t{\n\t\tassert(N >= 0);\n\t\tif (N == 1)\n\t\t{\n\t\t\treturn add_index();\n\t\t}\n\n\t\tauto current_size = m_data.size();\n\t\tauto last_chunk_end = (current_size - 1) << LOG2_CHUNK_WIDTH;\n\t\tIndexT result = last_chunk_end + m_next_bit;\n\n\t\t// all bits set to 1\n\t\tChunkT newelement = ~0;\n\n\t\t// The current chunk needs to be filled as 1\n\t\tint extra_bits_in_current_chunk = CHUNK_WIDTH - m_next_bit;\n\t\textra_bits_in_current_chunk = std::min(extra_bits_in_current_chunk, N);\n\t\tif (extra_bits_in_current_chunk > 0)\n\t\t{\n\t\t\tChunkT &last_chunk = m_data.back();\n\t\t\t// set the bits in [m_next_bit, m_next_bit + extra_bits_in_current_chunk) to 1\n\t\t\tChunkT mask = (newelement << (m_next_bit)) &\n\t\t\t              (newelement >> (CHUNK_WIDTH - m_next_bit - extra_bits_in_current_chunk));\n\t\t\tlast_chunk |= mask;\n\t\t}\n\n\t\tN -= extra_bits_in_current_chunk;\n\t\tif (N <= 0)\n\t\t{\n\t\t\tm_next_bit += extra_bits_in_current_chunk;\n\t\t\treturn result;\n\t\t}\n\n\t\tauto N_full_elements = N >> LOG2_CHUNK_WIDTH;\n\t\tauto N_remaining_bits = N & (CHUNK_WIDTH - 1);\n\n\t\tif (N_full_elements > 0)\n\t\t{\n\t\t\tauto new_size = current_size + N_full_elements;\n\t\t\tm_data.resize(new_size, newelement);\n\t\t\tm_cumulated_ranks.resize(new_size, m_cumulated_ranks.back());\n\t\t\tm_chunk_ranks.resize(new_size, CHUNK_WIDTH);\n\t\t}\n\t\tif (N_remaining_bits > 0)\n\t\t{\n\t\t\t// set the bits in [0, N_remaining_bits) to 1\n\t\t\tChunkT remaining_chunk = (ChunkT{1} << N_remaining_bits) - 1;\n\t\t\tm_data.push_back(remaining_chunk);\n\t\t\tm_cumulated_ranks.push_back(m_cumulated_ranks.back());\n\t\t\tm_chunk_ranks.push_back(N_remaining_bits);\n\n\t\t\tm_next_bit = N_remaining_bits;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tm_next_bit = CHUNK_WIDTH;\n\t\t}\n\t\treturn result;\n\t}\n\n\tvoid delete_index(const IndexT &index)\n\t{\n\t\tstd::size_t chunk_index;\n\t\tstd::uint8_t bit_index;\n\t\tlocate_index(index, chunk_index, bit_index);\n\t\tif (chunk_index >= m_data.size())\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tChunkT &chunk = m_data[chunk_index];\n\t\tChunkT mask = ChunkT{1} << bit_index;\n\t\tif (chunk & mask)\n\t\t{\n\t\t\t// set bit_index to 0\n\t\t\tchunk &= ~(mask);\n\t\t\t// m_last_correct_chunk ensures m_cumulated_ranks[0, m_last_correct_chunk]\n\t\t\t// and m_chunk_ranks[0, m_last_correct_chunk) are all correct\n\t\t\t// m_last_correct_chunk > chunk_index means that m_cumulated_ranks(chunk_index, +inf)\n\t\t\t// should be recalculated\n\t\t\tif (m_last_correct_chunk > chunk_index)\n\t\t\t{\n\t\t\t\tm_last_correct_chunk = chunk_index;\n\t\t\t}\n\t\t\t// rank of this chunk should also be recalculated\n\t\t\tm_chunk_ranks[chunk_index] = -1;\n\t\t}\n\t}\n\n\tbool has_index(const IndexT &index) const\n\t{\n\t\tstd::size_t chunk_index;\n\t\tstd::uint8_t bit_index;\n\t\tlocate_index(index, chunk_index, bit_index);\n\t\tconst ChunkT &chunk = m_data[chunk_index];\n\t\treturn chunk & (ChunkT{1} << bit_index);\n\t}\n\n\tResultT get_index(const IndexT &index)\n\t{\n\t\tif (index >= m_data.size() * CHUNK_WIDTH)\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\t\tstd::size_t chunk_index;\n\t\tstd::uint8_t bit_index;\n\t\tlocate_index(index, chunk_index, bit_index);\n\t\tChunkT &chunk = m_data[chunk_index];\n\t\tbool bit = chunk & (ChunkT{1} << bit_index);\n\n\t\tif (!bit)\n\t\t{\n\t\t\treturn -1;\n\t\t}\n\t\tif (chunk_index > m_last_correct_chunk)\n\t\t{\n\t\t\tupdate_to(chunk_index);\n\t\t}\n\t\t// count the 1 on the right of bit_index\n\t\tChunkT mask = (ChunkT{1} << bit_index) - 1;\n\t\tstd::uint8_t current_chunk_index = std::popcount(chunk & mask);\n\t\treturn m_cumulated_ranks[chunk_index] + current_chunk_index;\n\t}\n\n\tvoid update_to(std::size_t chunk_index)\n\t{\n\t\t// m_cumulated_ranks[0, m_last_correct_chunk] and m_chunk_ranks[0, m_last_correct_chunk) are\n\t\t// all correct\n\t\t// we need to update m_cumulated_ranks[m_last_correct_chunk + 1, chunk_index]\n\t\t// and m_chunk_ranks[m_last_correct_chunk, chunk_index)\n\t\tfor (int ichunk = m_last_correct_chunk; ichunk < chunk_index; ichunk++)\n\t\t{\n\t\t\tif (m_chunk_ranks[ichunk] < 0)\n\t\t\t{\n\t\t\t\tm_chunk_ranks[ichunk] = std::popcount(m_data[ichunk]);\n\t\t\t}\n\t\t\tm_cumulated_ranks[ichunk + 1] = m_cumulated_ranks[ichunk] + m_chunk_ranks[ichunk];\n\t\t}\n\t\tm_last_correct_chunk = chunk_index;\n\t}\n\n\tvoid locate_index(IndexT index, std::size_t &chunk_index, std::uint8_t &bit_index) const\n\t{\n\t\tchunk_index = index >> LOG2_CHUNK_WIDTH;\n\t\tbit_index = index & (CHUNK_WIDTH - 1);\n\t}\n\n\tvoid clear()\n\t{\n\t\tm_data.resize(1, 0);\n\t\tm_cumulated_ranks.resize(1, m_start);\n\t\tm_chunk_ranks.resize(1, -1);\n\t\tm_last_correct_chunk = 0;\n\t\tm_next_bit = 0;\n\t}\n\n  private:\n\tenum : std::uint8_t\n\t{\n\t\tCHUNK_WIDTH = sizeof(ChunkT) * 8,\n\t\tLOG2_CHUNK_WIDTH = std::countr_zero(CHUNK_WIDTH)\n\t};\n\n\tResultT m_start;\n\n\tstd::vector<ChunkT> m_data;\n\tstd::vector<ResultT> m_cumulated_ranks;\n\tstd::vector<std::int8_t> m_chunk_ranks; // -1 represents tainted\n\tstd::size_t m_last_correct_chunk;\n\tstd::uint8_t m_next_bit;\n};\n\ntemplate <std::signed_integral T>\nclass SimpleMonotoneVector\n{\n  private:\n\tstd::vector<T> m_data;\n\tT m_start = 0;\n\n  public:\n\tSimpleMonotoneVector() = default;\n\tSimpleMonotoneVector(T start) : m_start(start)\n\t{\n\t}\n\n\tIndexT add_index()\n\t{\n\t\tIndexT index = m_data.size();\n\t\tm_data.push_back(index);\n\t\treturn index;\n\t}\n\tvoid delete_index(const IndexT &index)\n\t{\n\t\tif (m_data[index] < 0)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\tm_data[index] = -1;\n\t\tfor (IndexT i = index + 1; i < m_data.size(); i++)\n\t\t{\n\t\t\tm_data[i] -= 1;\n\t\t}\n\t}\n\tbool has_index(const IndexT &index)\n\t{\n\t\treturn get_index(index) >= 0;\n\t}\n\tT get_index(const IndexT &index)\n\t{\n\t\tif (index >= m_data.size())\n\t\t{\n\t\t\tthrow std::runtime_error(\"Index out of range\");\n\t\t}\n\t\treturn m_data[index];\n\t}\n\tvoid clear()\n\t{\n\t\tm_data.clear();\n\t}\n};\n\ntemplate <typename ResultT>\nusing MonotoneIndexer = ChunkedBitVector<std::uint64_t, ResultT>;\n// using MonotoneIndexer = SimpleMonotoneVector<ResultT>;\n"
  },
  {
    "path": "include/pyoptinterface/copt_model.hpp",
    "content": "#pragma once\n\n#include <memory>\n\n#include \"solvers/copt/copt.h\"\n\n#include \"pyoptinterface/core.hpp\"\n#include \"pyoptinterface/container.hpp\"\n#include \"pyoptinterface/nlexpr.hpp\"\n#define USE_NLMIXIN\n#include \"pyoptinterface/solver_common.hpp\"\n#include \"pyoptinterface/dylib.hpp\"\n\nextern \"C\"\n{\n\tint COPT_SearchParamAttr(copt_prob *prob, const char *name, int *p_type);\n}\n\n#define APILIST                    \\\n\tB(COPT_GetRetcodeMsg);         \\\n\tB(COPT_CreateProb);            \\\n\tB(COPT_DeleteProb);            \\\n\tB(COPT_WriteMps);              \\\n\tB(COPT_WriteLp);               \\\n\tB(COPT_WriteCbf);              \\\n\tB(COPT_WriteBin);              \\\n\tB(COPT_WriteBasis);            \\\n\tB(COPT_WriteSol);              \\\n\tB(COPT_WriteMst);              \\\n\tB(COPT_WriteParam);            \\\n\tB(COPT_AddCol);                \\\n\tB(COPT_DelCols);               \\\n\tB(COPT_AddRow);                \\\n\tB(COPT_AddQConstr);            \\\n\tB(COPT_AddSOSs);               \\\n\tB(COPT_AddCones);              \\\n\tB(COPT_AddExpCones);           \\\n\tB(COPT_AddNLConstr);           \\\n\tB(COPT_DelRows);               \\\n\tB(COPT_DelQConstrs);           \\\n\tB(COPT_DelSOSs);               \\\n\tB(COPT_DelCones);              \\\n\tB(COPT_DelExpCones);           \\\n\tB(COPT_DelQuadObj);            \\\n\tB(COPT_ReplaceColObj);         \\\n\tB(COPT_SetObjConst);           \\\n\tB(COPT_SetObjSense);           \\\n\tB(COPT_SetQuadObj);            \\\n\tB(COPT_SetNLObj);              \\\n\tB(COPT_Solve);                 \\\n\tB(COPT_SearchParamAttr);       \\\n\tB(COPT_SetIntParam);           \\\n\tB(COPT_SetDblParam);           \\\n\tB(COPT_GetIntParam);           \\\n\tB(COPT_GetDblParam);           \\\n\tB(COPT_GetIntAttr);            \\\n\tB(COPT_GetDblAttr);            \\\n\tB(COPT_GetColInfo);            \\\n\tB(COPT_GetColName);            \\\n\tB(COPT_SetColNames);           \\\n\tB(COPT_GetColType);            \\\n\tB(COPT_SetColType);            \\\n\tB(COPT_SetColLower);           \\\n\tB(COPT_SetColUpper);           \\\n\tB(COPT_GetRowInfo);            \\\n\tB(COPT_GetQConstrInfo);        \\\n\tB(COPT_GetNLConstrInfo);       \\\n\tB(COPT_GetRowName);            \\\n\tB(COPT_GetQConstrName);        \\\n\tB(COPT_GetNLConstrName);       \\\n\tB(COPT_SetRowNames);           \\\n\tB(COPT_SetQConstrNames);       \\\n\tB(COPT_SetNLConstrNames);      \\\n\tB(COPT_AddMipStart);           \\\n\tB(COPT_SetNLPrimalStart);      \\\n\tB(COPT_GetQConstrRhs);         \\\n\tB(COPT_SetRowLower);           \\\n\tB(COPT_SetRowUpper);           \\\n\tB(COPT_SetQConstrRhs);         \\\n\tB(COPT_GetElem);               \\\n\tB(COPT_SetElem);               \\\n\tB(COPT_SetColObj);             \\\n\tB(COPT_GetBanner);             \\\n\tB(COPT_SetCallback);           \\\n\tB(COPT_GetCallbackInfo);       \\\n\tB(COPT_AddCallbackSolution);   \\\n\tB(COPT_AddCallbackLazyConstr); \\\n\tB(COPT_AddCallbackUserCut);    \\\n\tB(COPT_Interrupt);             \\\n\tB(COPT_CreateEnv);             \\\n\tB(COPT_CreateEnvWithConfig);   \\\n\tB(COPT_DeleteEnv);             \\\n\tB(COPT_CreateEnvConfig);       \\\n\tB(COPT_DeleteEnvConfig);       \\\n\tB(COPT_SetEnvConfig);          \\\n\tB(COPT_ComputeIIS);            \\\n\tB(COPT_GetColLowerIIS);        \\\n\tB(COPT_GetColUpperIIS);        \\\n\tB(COPT_GetRowLowerIIS);        \\\n\tB(COPT_GetRowUpperIIS);        \\\n\tB(COPT_GetSOSIIS);             \\\n\tB(COPT_SetLogCallback);\n\nnamespace copt\n{\n#define B DYLIB_EXTERN_DECLARE\nAPILIST\n#undef B\n\nbool is_library_loaded();\n\nbool load_library(const std::string &path);\n} // namespace copt\n\nclass COPTEnvConfig\n{\n  public:\n\tCOPTEnvConfig();\n\t~COPTEnvConfig();\n\n\tvoid set(const char *param_name, const char *value);\n\n  private:\n\tcopt_env_config *m_config;\n\n\tfriend class COPTEnv;\n};\n\nclass COPTEnv\n{\n  public:\n\tCOPTEnv();\n\tCOPTEnv(COPTEnvConfig &config);\n\t~COPTEnv();\n\n\tvoid close();\n\n  private:\n\tcopt_env *m_env;\n\n\tfriend class COPTModel;\n};\n\nstruct COPTfreemodelT\n{\n\tvoid operator()(copt_prob *model) const\n\t{\n\t\tcopt::COPT_DeleteProb(&model);\n\t};\n};\n\nclass COPTModel;\nusing COPTCallback = std::function<void(COPTModel *, int)>;\n\nstruct COPTCallbackUserdata\n{\n\tvoid *model = nullptr;\n\tCOPTCallback callback;\n\tint n_variables = 0;\n\tint where = 0;\n\t// store result of cbget\n\tbool cb_get_mipsol_called = false;\n\tstd::vector<double> mipsol;\n\tbool cb_get_mipnoderel_called = false;\n\tstd::vector<double> mipnoderel;\n\tbool cb_get_mipincumbent_called = false;\n\tstd::vector<double> mipincumbent;\n\t// Cache for cbsolution\n\tbool cb_set_solution_called = false;\n\tstd::vector<double> heuristic_solution;\n\tbool cb_requires_submit_solution = false;\n};\n\nusing COPTLoggingCallback = std::function<void(const char *)>;\n\nstruct COPTLoggingCallbackUserdata\n{\n\tCOPTLoggingCallback callback;\n};\n\nclass COPTModel : public OnesideLinearConstraintMixin<COPTModel>,\n                  public TwosideLinearConstraintMixin<COPTModel>,\n                  public OnesideQuadraticConstraintMixin<COPTModel>,\n                  public TwosideNLConstraintMixin<COPTModel>,\n                  public LinearObjectiveMixin<COPTModel>,\n                  public PPrintMixin<COPTModel>,\n                  public GetValueMixin<COPTModel>\n{\n  public:\n\tCOPTModel() = default;\n\tCOPTModel(const COPTEnv &env);\n\tvoid init(const COPTEnv &env);\n\tvoid close();\n\n\tdouble get_infinity() const;\n\n\tvoid write(const std::string &filename);\n\n\tVariableIndex add_variable(VariableDomain domain = VariableDomain::Continuous,\n\t                           double lb = -COPT_INFINITY, double ub = COPT_INFINITY,\n\t                           const char *name = nullptr);\n\tvoid delete_variable(const VariableIndex &variable);\n\tvoid delete_variables(const Vector<VariableIndex> &variables);\n\tbool is_variable_active(const VariableIndex &variable);\n\tdouble get_variable_value(const VariableIndex &variable);\n\tstd::string pprint_variable(const VariableIndex &variable);\n\tvoid set_variable_bounds(const VariableIndex &variable, double lb, double ub);\n\n\tConstraintIndex add_linear_constraint(const ScalarAffineFunction &function,\n\t                                      ConstraintSense sense, CoeffT rhs,\n\t                                      const char *name = nullptr);\n\tConstraintIndex add_linear_constraint(const ScalarAffineFunction &function,\n\t                                      const std::tuple<double, double> &interval,\n\t                                      const char *name = nullptr);\n\tConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &function,\n\t                                         ConstraintSense sense, CoeffT rhs,\n\t                                         const char *name = nullptr);\n\tConstraintIndex add_sos_constraint(const Vector<VariableIndex> &variables, SOSType sos_type);\n\tConstraintIndex add_sos_constraint(const Vector<VariableIndex> &variables, SOSType sos_type,\n\t                                   const Vector<CoeffT> &weights);\n\n\t// x[0]^2 >= x[1]^2 + x[2]^2 + ... + x[n-1]^2\n\tConstraintIndex add_second_order_cone_constraint(const Vector<VariableIndex> &variables,\n\t                                                 const char *name, bool rotated = false);\n\n\tConstraintIndex add_exp_cone_constraint(const Vector<VariableIndex> &variables,\n\t                                        const char *name, bool dual = false);\n\n\t// Nonlinear constraint\n\tvoid decode_expr(const ExpressionGraph &graph, const ExpressionHandle &expr,\n\t                 std::vector<int> &opcodes, std::vector<double> &constants);\n\tvoid decode_graph_prefix_order(ExpressionGraph &graph, const ExpressionHandle &result,\n\t                               std::vector<int> &opcodes, std::vector<double> &constants);\n\tConstraintIndex add_single_nl_constraint(ExpressionGraph &graph, const ExpressionHandle &result,\n\t                                         const std::tuple<double, double> &interval,\n\t                                         const char *name = nullptr);\n\n\tvoid delete_constraint(const ConstraintIndex &constraint);\n\tbool is_constraint_active(const ConstraintIndex &constraint);\n\n\tvoid _set_affine_objective(const ScalarAffineFunction &function, ObjectiveSense sense,\n\t                           bool clear_quadratic);\n\tvoid set_objective(const ScalarAffineFunction &function, ObjectiveSense sense);\n\tvoid set_objective(const ScalarQuadraticFunction &function, ObjectiveSense sense);\n\tvoid set_objective(const ExprBuilder &function, ObjectiveSense sense);\n\n\tvoid add_single_nl_objective(ExpressionGraph &graph, const ExpressionHandle &result);\n\tvoid set_nl_objective();\n\n\tvoid optimize();\n\tvoid *get_raw_model();\n\tstd::string version_string();\n\n\t/*\n\t * Returns the type of a COPT parameter or attribute, given its name.\n\t * -1: unknown\n\t *  0: double parameter\n\t *  1: int parameter\n\t *  2: double attribute\n\t *  3: int attribute\n\t *\n\t * Use undocumented COPT function\n\t * int COPT_SearchParamAttr(copt_prob* prob, const char* name, int* p_type)\n\t */\n\tint raw_parameter_attribute_type(const char *name);\n\n\t// parameter\n\tvoid set_raw_parameter_int(const char *param_name, int value);\n\tvoid set_raw_parameter_double(const char *param_name, double value);\n\tint get_raw_parameter_int(const char *param_name);\n\tdouble get_raw_parameter_double(const char *param_name);\n\n\t// attribute\n\tint get_raw_attribute_int(const char *attr_name);\n\tdouble get_raw_attribute_double(const char *attr_name);\n\n\t// Accessing information of problem\n\tdouble get_variable_info(const VariableIndex &variable, const char *info_name);\n\tstd::string get_variable_name(const VariableIndex &variable);\n\tvoid set_variable_name(const VariableIndex &variable, const char *name);\n\tVariableDomain get_variable_type(const VariableIndex &variable);\n\tvoid set_variable_type(const VariableIndex &variable, VariableDomain domain);\n\tvoid set_variable_lower_bound(const VariableIndex &variable, double lb);\n\tvoid set_variable_upper_bound(const VariableIndex &variable, double ub);\n\n\tdouble get_constraint_info(const ConstraintIndex &constraint, const char *info_name);\n\tstd::string get_constraint_name(const ConstraintIndex &constraint);\n\tvoid set_constraint_name(const ConstraintIndex &constraint, const char *name);\n\n\tvoid set_obj_sense(ObjectiveSense sense);\n\n\t// MIPStart\n\tvoid add_mip_start(const Vector<VariableIndex> &variables, const Vector<double> &values);\n\t// NLP start\n\tvoid add_nl_start(const Vector<VariableIndex> &variables, const Vector<double> &values);\n\n\t// Modifications of model\n\t// 1. set/get RHS of a constraint\n\tdouble get_normalized_rhs(const ConstraintIndex &constraint);\n\tvoid set_normalized_rhs(const ConstraintIndex &constraint, double value);\n\t// 2. set/get coefficient of variable in constraint\n\tdouble get_normalized_coefficient(const ConstraintIndex &constraint,\n\t                                  const VariableIndex &variable);\n\tvoid set_normalized_coefficient(const ConstraintIndex &constraint,\n\t                                const VariableIndex &variable, double value);\n\t// 3. set/get linear coefficient of variable in objective\n\tdouble get_objective_coefficient(const VariableIndex &variable);\n\tvoid set_objective_coefficient(const VariableIndex &variable, double value);\n\n\tint _variable_index(const VariableIndex &variable);\n\tint _checked_variable_index(const VariableIndex &variable);\n\tint _constraint_index(const ConstraintIndex &constraint);\n\tint _checked_constraint_index(const ConstraintIndex &constraint);\n\n\t// Control logging\n\tvoid set_logging(const COPTLoggingCallback &callback);\n\n\tCOPTLoggingCallbackUserdata m_logging_callback_userdata;\n\n\t// Callback\n\tvoid set_callback(const COPTCallback &callback, int cbctx);\n\n\t// For callback\n\tbool has_callback = false;\n\tvoid *m_cbdata = nullptr;\n\tCOPTCallbackUserdata m_callback_userdata;\n\n\tint cb_get_info_int(const std::string &what);\n\tdouble cb_get_info_double(const std::string &what);\n\tvoid cb_get_info_doublearray(const std::string &what);\n\n\tdouble cb_get_solution(const VariableIndex &variable);\n\tdouble cb_get_relaxation(const VariableIndex &variable);\n\tdouble cb_get_incumbent(const VariableIndex &variable);\n\tvoid cb_set_solution(const VariableIndex &variable, double value);\n\tdouble cb_submit_solution();\n\n\tvoid cb_exit();\n\n\tvoid cb_add_lazy_constraint(const ScalarAffineFunction &function, ConstraintSense sense,\n\t                            CoeffT rhs);\n\tvoid cb_add_lazy_constraint(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs);\n\tvoid cb_add_user_cut(const ScalarAffineFunction &function, ConstraintSense sense, CoeffT rhs);\n\tvoid cb_add_user_cut(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs);\n\n\t// IIS related\n\tvoid computeIIS();\n\tint _get_variable_upperbound_IIS(const VariableIndex &variable);\n\tint _get_variable_lowerbound_IIS(const VariableIndex &variable);\n\tint _get_constraint_IIS(const ConstraintIndex &constraint);\n\n  private:\n\tMonotoneIndexer<int> m_variable_index;\n\n\tMonotoneIndexer<int> m_linear_constraint_index;\n\n\tMonotoneIndexer<int> m_quadratic_constraint_index;\n\n\tMonotoneIndexer<int> m_sos_constraint_index;\n\n\tMonotoneIndexer<int> m_cone_constraint_index;\n\n\tMonotoneIndexer<int> m_exp_cone_constraint_index;\n\n\tMonotoneIndexer<int> m_nl_constraint_index;\n\n\t// Store the nonlinear objectives\n\tint m_nl_objective_num = 0;\n\tstd::vector<int> m_nl_objective_opcodes = {COPT_NL_SUM, 0};\n\tstd::vector<double> m_nl_objective_constants;\n\n\t/* COPT part */\n\tstd::unique_ptr<copt_prob, COPTfreemodelT> m_model;\n};\n"
  },
  {
    "path": "include/pyoptinterface/core.hpp",
    "content": "#pragma once\n\n#include <stdint.h>\n#include <vector>\n#include <optional>\n#include \"ankerl/unordered_dense.h\"\n\nusing IndexT = std::int32_t;\nusing CoeffT = double;\n\nconstexpr CoeffT COEFTHRESHOLD = 1e-12;\n\ntemplate <typename K, typename V>\nusing Hashmap = ankerl::unordered_dense::map<K, V>;\n\ntemplate <typename K>\nusing Hashset = ankerl::unordered_dense::set<K>;\n\ntemplate <typename V>\nusing Vector = std::vector<V>;\n\nstruct VariableIndex;\nstruct ScalarAffineFunction;\nstruct ScalarQuadraticFunction;\nstruct ExprBuilder;\n\nenum class VariableDomain\n{\n\tContinuous,\n\tInteger,\n\tBinary,\n\tSemiContinuous,\n};\n\nstruct VariableIndex\n{\n\tIndexT index;\n\n\tVariableIndex() = default;\n\tVariableIndex(IndexT v);\n};\n\nstruct ScalarAffineFunction\n{\n\tVector<CoeffT> coefficients;\n\tVector<IndexT> variables;\n\tstd::optional<CoeffT> constant;\n\n\tScalarAffineFunction() = default;\n\tScalarAffineFunction(CoeffT v);\n\tScalarAffineFunction(const VariableIndex &v);\n\t// v * c\n\tScalarAffineFunction(const VariableIndex &v, CoeffT c);\n\t// v * c1 + c2\n\tScalarAffineFunction(const VariableIndex &v, CoeffT c1, CoeffT c2);\n\tScalarAffineFunction(const Vector<CoeffT> &, const Vector<IndexT> &);\n\tScalarAffineFunction(const Vector<CoeffT> &, const Vector<IndexT> &,\n\t                     const std::optional<CoeffT> &);\n\n\tScalarAffineFunction(const ExprBuilder &t);\n\n\tsize_t size() const;\n\tvoid canonicalize(CoeffT threshold = COEFTHRESHOLD);\n\n\tvoid reserve(size_t n);\n\tvoid add_term(const VariableIndex &v, CoeffT c);\n\tvoid add_constant(CoeffT c);\n};\n\nstruct ScalarQuadraticFunction\n{\n\tVector<CoeffT> coefficients;\n\tVector<IndexT> variable_1s;\n\tVector<IndexT> variable_2s;\n\tstd::optional<ScalarAffineFunction> affine_part;\n\n\tScalarQuadraticFunction() = default;\n\tScalarQuadraticFunction(const Vector<CoeffT> &, const Vector<IndexT> &, const Vector<IndexT> &);\n\tScalarQuadraticFunction(const Vector<CoeffT> &, const Vector<IndexT> &, const Vector<IndexT> &,\n\t                        const std::optional<ScalarAffineFunction> &);\n\tScalarQuadraticFunction(const ExprBuilder &t);\n\n\tsize_t size() const;\n\tvoid canonicalize(CoeffT threshold = COEFTHRESHOLD);\n\n\tvoid reserve_quadratic(size_t n);\n\tvoid reserve_affine(size_t n);\n\tvoid add_quadratic_term(const VariableIndex &v1, const VariableIndex &v2, CoeffT c);\n\tvoid add_affine_term(const VariableIndex &v, CoeffT c);\n\tvoid add_constant(CoeffT c);\n};\n\nstruct VariablePair\n{\n\tIndexT var_1;\n\tIndexT var_2;\n\n\tbool operator==(const VariablePair &x) const;\n\tbool operator<(const VariablePair &x) const;\n\n\tVariablePair() = default;\n\tVariablePair(IndexT v1, IndexT v2) : var_1(v1), var_2(v2)\n\t{\n\t}\n};\n\ntemplate <>\nstruct ankerl::unordered_dense::hash<VariablePair>\n{\n\tusing is_avalanching = void;\n\n\t[[nodiscard]] auto operator()(VariablePair const &x) const noexcept -> uint64_t\n\t{\n\t\tstatic_assert(std::has_unique_object_representations_v<VariablePair>);\n\t\treturn detail::wyhash::hash(&x, sizeof(x));\n\t}\n};\n\nstruct ExprBuilder\n{\n\tHashmap<VariablePair, CoeffT> quadratic_terms;\n\tHashmap<IndexT, CoeffT> affine_terms;\n\tstd::optional<CoeffT> constant_term;\n\n\tExprBuilder() = default;\n\tExprBuilder(CoeffT c);\n\tExprBuilder(const VariableIndex &v);\n\tExprBuilder(const ScalarAffineFunction &a);\n\tExprBuilder(const ScalarQuadraticFunction &q);\n\n\tExprBuilder &operator+=(CoeffT c);\n\tExprBuilder &operator+=(const VariableIndex &v);\n\tExprBuilder &operator+=(const ScalarAffineFunction &a);\n\tExprBuilder &operator+=(const ScalarQuadraticFunction &q);\n\tExprBuilder &operator+=(const ExprBuilder &t);\n\n\tExprBuilder &operator-=(CoeffT c);\n\tExprBuilder &operator-=(const VariableIndex &v);\n\tExprBuilder &operator-=(const ScalarAffineFunction &a);\n\tExprBuilder &operator-=(const ScalarQuadraticFunction &q);\n\tExprBuilder &operator-=(const ExprBuilder &t);\n\n\tExprBuilder &operator*=(CoeffT c);\n\tExprBuilder &operator*=(const VariableIndex &v);\n\tExprBuilder &operator*=(const ScalarAffineFunction &a);\n\tExprBuilder &operator*=(const ScalarQuadraticFunction &q);\n\tExprBuilder &operator*=(const ExprBuilder &t);\n\n\tExprBuilder &operator/=(CoeffT c);\n\n\tbool empty() const;\n\tint degree() const;\n\n\tvoid reserve_quadratic(size_t n);\n\tvoid reserve_affine(size_t n);\n\n\tvoid clear();\n\tvoid clean_nearzero_terms(CoeffT threshold = COEFTHRESHOLD);\n\tvoid _add_quadratic_term(IndexT i, IndexT j, CoeffT coeff);\n\tvoid _set_quadratic_coef(IndexT i, IndexT j, CoeffT coeff);\n\tvoid add_quadratic_term(const VariableIndex &i, const VariableIndex &j, CoeffT coeff);\n\tvoid set_quadratic_coef(const VariableIndex &i, const VariableIndex &j, CoeffT coeff);\n\tvoid _add_affine_term(IndexT i, CoeffT coeff);\n\tvoid _set_affine_coef(IndexT i, CoeffT coeff);\n\tvoid add_affine_term(const VariableIndex &i, CoeffT coeff);\n\tvoid set_affine_coef(const VariableIndex &i, CoeffT coeff);\n};\n\nauto operator+(const VariableIndex &a, CoeffT b) -> ScalarAffineFunction;\nauto operator+(CoeffT a, const VariableIndex &b) -> ScalarAffineFunction;\nauto operator+(const VariableIndex &a, const VariableIndex &b) -> ScalarAffineFunction;\nauto operator+(const ScalarAffineFunction &a, CoeffT b) -> ScalarAffineFunction;\nauto operator+(CoeffT a, const ScalarAffineFunction &b) -> ScalarAffineFunction;\nauto operator+(const ScalarAffineFunction &a, const VariableIndex &b) -> ScalarAffineFunction;\nauto operator+(const VariableIndex &a, const ScalarAffineFunction &b) -> ScalarAffineFunction;\nauto operator+(const ScalarAffineFunction &a, const ScalarAffineFunction &b)\n    -> ScalarAffineFunction;\nauto operator+(const ScalarQuadraticFunction &a, CoeffT b) -> ScalarQuadraticFunction;\nauto operator+(CoeffT a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction;\nauto operator+(const ScalarQuadraticFunction &a, const VariableIndex &b) -> ScalarQuadraticFunction;\nauto operator+(const VariableIndex &a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction;\nauto operator+(const ScalarQuadraticFunction &a, const ScalarAffineFunction &b)\n    -> ScalarQuadraticFunction;\nauto operator+(const ScalarAffineFunction &a, const ScalarQuadraticFunction &b)\n    -> ScalarQuadraticFunction;\nauto operator+(const ScalarQuadraticFunction &a, const ScalarQuadraticFunction &b)\n    -> ScalarQuadraticFunction;\n\nauto operator-(const VariableIndex &a, CoeffT b) -> ScalarAffineFunction;\nauto operator-(CoeffT a, const VariableIndex &b) -> ScalarAffineFunction;\nauto operator-(const VariableIndex &a, const VariableIndex &b) -> ScalarAffineFunction;\nauto operator-(const ScalarAffineFunction &a, CoeffT b) -> ScalarAffineFunction;\nauto operator-(CoeffT a, const ScalarAffineFunction &b) -> ScalarAffineFunction;\nauto operator-(const ScalarAffineFunction &a, const VariableIndex &b) -> ScalarAffineFunction;\nauto operator-(const VariableIndex &a, const ScalarAffineFunction &b) -> ScalarAffineFunction;\nauto operator-(const ScalarAffineFunction &a, const ScalarAffineFunction &b)\n    -> ScalarAffineFunction;\nauto operator-(const ScalarQuadraticFunction &a, CoeffT b) -> ScalarQuadraticFunction;\nauto operator-(CoeffT a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction;\nauto operator-(const ScalarQuadraticFunction &a, const VariableIndex &b) -> ScalarQuadraticFunction;\nauto operator-(const VariableIndex &a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction;\nauto operator-(const ScalarQuadraticFunction &a, const ScalarAffineFunction &b)\n    -> ScalarQuadraticFunction;\nauto operator-(const ScalarAffineFunction &a, const ScalarQuadraticFunction &b)\n    -> ScalarQuadraticFunction;\nauto operator-(const ScalarQuadraticFunction &a, const ScalarQuadraticFunction &b)\n    -> ScalarQuadraticFunction;\n\nauto operator*(const VariableIndex &a, CoeffT b) -> ScalarAffineFunction;\nauto operator*(CoeffT a, const VariableIndex &b) -> ScalarAffineFunction;\nauto operator*(const VariableIndex &a, const VariableIndex &b) -> ScalarQuadraticFunction;\nauto operator*(const ScalarAffineFunction &a, CoeffT b) -> ScalarAffineFunction;\nauto operator*(CoeffT a, const ScalarAffineFunction &b) -> ScalarAffineFunction;\nauto operator*(const ScalarAffineFunction &a, const VariableIndex &b) -> ScalarQuadraticFunction;\nauto operator*(const VariableIndex &a, const ScalarAffineFunction &b) -> ScalarQuadraticFunction;\nauto operator*(const ScalarAffineFunction &a, const ScalarAffineFunction &b)\n    -> ScalarQuadraticFunction;\nauto operator*(const ScalarQuadraticFunction &a, CoeffT b) -> ScalarQuadraticFunction;\nauto operator*(CoeffT a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction;\n\nauto operator/(const VariableIndex &a, CoeffT b) -> ScalarAffineFunction;\nauto operator/(const ScalarAffineFunction &a, CoeffT b) -> ScalarAffineFunction;\nauto operator/(const ScalarQuadraticFunction &a, CoeffT b) -> ScalarQuadraticFunction;\n\n// unary minus operator\nauto operator-(const VariableIndex &a) -> ScalarAffineFunction;\nauto operator-(const ScalarAffineFunction &a) -> ScalarAffineFunction;\nauto operator-(const ScalarQuadraticFunction &a) -> ScalarQuadraticFunction;\nauto operator-(const ExprBuilder &a) -> ExprBuilder;\n\n// Operator overloading for\tExprBuilder\n// Sadly, they are inefficient than the +=,-=,*=,/= functions but they are important for a\n// user-friendly interface\n// The functions are like ScalarQuadraticFunction but returns a ExprBuilder\nauto operator+(const ExprBuilder &a, CoeffT b) -> ExprBuilder;\nauto operator+(CoeffT b, const ExprBuilder &a) -> ExprBuilder;\nauto operator+(const ExprBuilder &a, const VariableIndex &b) -> ExprBuilder;\nauto operator+(const VariableIndex &b, const ExprBuilder &a) -> ExprBuilder;\nauto operator+(const ExprBuilder &a, const ScalarAffineFunction &b) -> ExprBuilder;\nauto operator+(const ScalarAffineFunction &b, const ExprBuilder &a) -> ExprBuilder;\nauto operator+(const ExprBuilder &a, const ScalarQuadraticFunction &b) -> ExprBuilder;\nauto operator+(const ScalarQuadraticFunction &b, const ExprBuilder &a) -> ExprBuilder;\nauto operator+(const ExprBuilder &a, const ExprBuilder &b) -> ExprBuilder;\n\nauto operator-(const ExprBuilder &a, CoeffT b) -> ExprBuilder;\nauto operator-(CoeffT b, const ExprBuilder &a) -> ExprBuilder;\nauto operator-(const ExprBuilder &a, const VariableIndex &b) -> ExprBuilder;\nauto operator-(const VariableIndex &b, const ExprBuilder &a) -> ExprBuilder;\nauto operator-(const ExprBuilder &a, const ScalarAffineFunction &b) -> ExprBuilder;\nauto operator-(const ScalarAffineFunction &b, const ExprBuilder &a) -> ExprBuilder;\nauto operator-(const ExprBuilder &a, const ScalarQuadraticFunction &b) -> ExprBuilder;\nauto operator-(const ScalarQuadraticFunction &b, const ExprBuilder &a) -> ExprBuilder;\nauto operator-(const ExprBuilder &a, const ExprBuilder &b) -> ExprBuilder;\n\nauto operator*(const ExprBuilder &a, CoeffT b) -> ExprBuilder;\nauto operator*(CoeffT b, const ExprBuilder &a) -> ExprBuilder;\nauto operator*(const ExprBuilder &a, const VariableIndex &b) -> ExprBuilder;\nauto operator*(const VariableIndex &b, const ExprBuilder &a) -> ExprBuilder;\nauto operator*(const ExprBuilder &a, const ScalarAffineFunction &b) -> ExprBuilder;\nauto operator*(const ScalarAffineFunction &b, const ExprBuilder &a) -> ExprBuilder;\nauto operator*(const ExprBuilder &a, const ScalarQuadraticFunction &b) -> ExprBuilder;\nauto operator*(const ScalarQuadraticFunction &b, const ExprBuilder &a) -> ExprBuilder;\nauto operator*(const ExprBuilder &a, const ExprBuilder &b) -> ExprBuilder;\n\nauto operator/(const ExprBuilder &a, CoeffT b) -> ExprBuilder;\n\nenum class ConstraintType\n{\n\tLinear,\n\tQuadratic,\n\tSOS,\n\tSecondOrderCone,\n\tExponentialCone,\n\tNL,\n\tSolverDefined,\n};\n\nenum class SOSType\n{\n\tSOS1,\n\tSOS2,\n};\n\nenum class ConstraintSense\n{\n\tLessEqual,\n\tGreaterEqual,\n\tEqual\n};\n\nstruct ConstraintIndex\n{\n\tConstraintType type;\n\tIndexT index;\n\n\tConstraintIndex() = default;\n\tConstraintIndex(ConstraintType t, IndexT i) : type(t), index(i)\n\t{\n\t}\n};\n\n// struct LinearConstraint\n//{\n//\tScalarAffineFunction function;\n//\tConstraintSense sense;\n//\tCoeffT rhs;\n// };\n//\n// struct QuadraticConstraint\n//{\n//\tScalarQuadraticFunction function;\n//\tConstraintSense sense;\n//\tCoeffT rhs;\n// };\n//\n// struct SOSConstraint\n//{\n//\tVector<VariableIndex> variables;\n//\tVector<CoeffT> weights;\n// };\n\nenum class ObjectiveSense\n{\n\tMinimize,\n\tMaximize\n};\n"
  },
  {
    "path": "include/pyoptinterface/cppad_interface.hpp",
    "content": "#pragma once\n\n#include \"cppad/cppad.hpp\"\n#include \"pyoptinterface/nlexpr.hpp\"\n#include \"pyoptinterface/nleval.hpp\"\n\nusing ADFunDouble = CppAD::ADFun<double>;\n\nADFunDouble dense_jacobian(const ADFunDouble &f);\n\nusing sparsity_pattern_t = CppAD::sparse_rc<std::vector<size_t>>;\n\nstruct JacobianHessianSparsityPattern\n{\n\tsparsity_pattern_t jacobian;\n\tsparsity_pattern_t hessian;\n\tsparsity_pattern_t reduced_hessian;\n};\n\nJacobianHessianSparsityPattern jacobian_hessian_sparsity(ADFunDouble &f,\n                                                         HessianSparsityType hessian_sparsity);\n\n// [p, x] -> Jacobian\nADFunDouble sparse_jacobian(const ADFunDouble &f, const sparsity_pattern_t &pattern_jac,\n                            const std::vector<double> &x_values,\n                            const std::vector<double> &p_values);\n\n// [p, w, x] -> \\Sigma w_i * Hessian_i\nADFunDouble sparse_hessian(const ADFunDouble &f, const sparsity_pattern_t &pattern_hes,\n                           const sparsity_pattern_t &pattern_subset,\n                           const std::vector<double> &x_values,\n                           const std::vector<double> &p_values);\n\n// Transform ExpressionGraph to CppAD function\n// selected: indices of outputs to trace, empty means all outputs\nADFunDouble cppad_trace_graph_constraints(const ExpressionGraph &graph,\n                                          const std::vector<size_t> &selected = {});\nADFunDouble cppad_trace_graph_objective(const ExpressionGraph &graph,\n                                        const std::vector<size_t> &selected = {},\n                                        bool aggregate = true);\n\nstruct CppADAutodiffGraph\n{\n\tCppAD::cpp_graph f_graph, jacobian_graph, hessian_graph;\n};\n\n// Generate computational graph for the CppAD function (itself, Jacobian and Hessian)\n// Analyze its sparsity as well\nvoid cppad_autodiff(ADFunDouble &f, AutodiffSymbolicStructure &structure, CppADAutodiffGraph &graph,\n                    const std::vector<double> &x_values, const std::vector<double> &p_values);\n"
  },
  {
    "path": "include/pyoptinterface/dylib.hpp",
    "content": "#pragma once\n\n#if defined(_MSC_VER)\n#define WIN32_LEAN_AND_MEAN\n#define NOMINMAX\n#include <windows.h>\n#else\n#include <dlfcn.h>\n#endif\n\nclass DynamicLibrary\n{\n  public:\n\tDynamicLibrary() : handle(nullptr)\n\t{\n\t}\n\n\t~DynamicLibrary()\n\t{\n\t\tif (handle != nullptr)\n\t\t{\n#if defined(_MSC_VER)\n\t\t\tFreeLibrary(static_cast<HINSTANCE>(handle));\n#else\n\t\t\tdlclose(handle);\n#endif\n\t\t}\n\t}\n\n\tbool try_load(const char *library)\n\t{\n#if defined(_MSC_VER)\n\t\thandle = static_cast<void *>(LoadLibraryA(library));\n\n\t\tif (handle == nullptr)\n\t\t{\n\t\t\thandle = static_cast<void *>(LoadLibraryExA(library, NULL,\n\t\t\t                                            LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |\n\t\t\t                                                LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR));\n\t\t}\n\n#else\n\t\thandle = dlopen(library, RTLD_NOW);\n#endif\n\t\treturn handle != nullptr;\n\t}\n\n\tbool LibraryIsLoaded() const\n\t{\n\t\treturn handle != nullptr;\n\t}\n\n\tvoid *get_symbol(const char *name)\n\t{\n#if defined(_MSC_VER)\n\t\tFARPROC function_address = GetProcAddress(static_cast<HINSTANCE>(handle), name);\n#else\n\t\tvoid *function_address = dlsym(handle, name);\n#endif\n\n\t\treturn reinterpret_cast<void *>(function_address);\n\t}\n\n  private:\n\tvoid *handle = nullptr;\n};\n\n// Next we will introduce some magic macros to declare function pointers and load them from dynamic\n// library robustly\n\n#define DYLIB_EXTERN_DECLARE(f) extern decltype(&::f) f\n#define DYLIB_DECLARE(f) decltype(&::f) f = nullptr\n\n#define DYLIB_LOAD_INIT                                                   \\\n\tankerl::unordered_dense::map<std::string, void *> _function_pointers; \\\n\tbool _load_success = true\n\n#define DYLIB_LOAD_FUNCTION(f)                                        \\\n\t{                                                                 \\\n\t\tauto ptr = reinterpret_cast<decltype(f)>(lib.get_symbol(#f)); \\\n\t\tif (ptr == nullptr)                                           \\\n\t\t{                                                             \\\n\t\t\tfmt::print(\"function {} is not loaded correctly\\n\", #f);  \\\n\t\t\t_load_success = false;                                    \\\n\t\t}                                                             \\\n\t\t_function_pointers[#f] = reinterpret_cast<void *>(ptr);       \\\n\t}\n\n#define IS_DYLIB_LOAD_SUCCESS _load_success\n\n#define DYLIB_SAVE_FUNCTION(f) f = reinterpret_cast<decltype(f)>(_function_pointers[#f])\n"
  },
  {
    "path": "include/pyoptinterface/gurobi_model.hpp",
    "content": "#pragma once\n\n#include <memory>\n\n#include \"solvers/gurobi/gurobi_c.h\"\n\n#include \"pyoptinterface/core.hpp\"\n#include \"pyoptinterface/container.hpp\"\n#include \"pyoptinterface/nlexpr.hpp\"\n#define USE_NLMIXIN\n#include \"pyoptinterface/solver_common.hpp\"\n#include \"pyoptinterface/dylib.hpp\"\n\n// define Gurobi C APIs\n#define APILIST               \\\n\tB(GRBnewmodel);           \\\n\tB(GRBfreemodel);          \\\n\tB(GRBreset);              \\\n\tB(GRBgetenv);             \\\n\tB(GRBwrite);              \\\n\tB(GRBaddvar);             \\\n\tB(GRBdelvars);            \\\n\tB(GRBaddconstr);          \\\n\tB(GRBaddqconstr);         \\\n\tB(GRBaddsos);             \\\n\tB(GRBaddgenconstrNL);     \\\n\tB(GRBdelconstrs);         \\\n\tB(GRBdelqconstrs);        \\\n\tB(GRBdelsos);             \\\n\tB(GRBdelgenconstrs);      \\\n\tB(GRBdelq);               \\\n\tB(GRBsetdblattrarray);    \\\n\tB(GRBaddqpterms);         \\\n\tB(GRBoptimize);           \\\n\tB(GRBupdatemodel);        \\\n\tB(GRBgetparamtype);       \\\n\tB(GRBsetintparam);        \\\n\tB(GRBsetdblparam);        \\\n\tB(GRBsetstrparam);        \\\n\tB(GRBgetintparam);        \\\n\tB(GRBgetdblparam);        \\\n\tB(GRBgetstrparam);        \\\n\tB(GRBgetattrinfo);        \\\n\tB(GRBsetintattr);         \\\n\tB(GRBsetdblattr);         \\\n\tB(GRBsetstrattr);         \\\n\tB(GRBgetintattr);         \\\n\tB(GRBgetdblattr);         \\\n\tB(GRBgetstrattr);         \\\n\tB(GRBgetdblattrarray);    \\\n\tB(GRBgetdblattrlist);     \\\n\tB(GRBsetdblattrlist);     \\\n\tB(GRBsetintattrelement);  \\\n\tB(GRBsetcharattrelement); \\\n\tB(GRBsetdblattrelement);  \\\n\tB(GRBsetstrattrelement);  \\\n\tB(GRBgetintattrelement);  \\\n\tB(GRBgetcharattrelement); \\\n\tB(GRBgetdblattrelement);  \\\n\tB(GRBgetstrattrelement);  \\\n\tB(GRBgetcoeff);           \\\n\tB(GRBchgcoeffs);          \\\n\tB(GRBgeterrormsg);        \\\n\tB(GRBversion);            \\\n\tB(GRBsetcallbackfunc);    \\\n\tB(GRBcbget);              \\\n\tB(GRBcbproceed);          \\\n\tB(GRBterminate);          \\\n\tB(GRBcbsolution);         \\\n\tB(GRBcblazy);             \\\n\tB(GRBcbcut);              \\\n\tB(GRBemptyenv);           \\\n\tB(GRBloadenv);            \\\n\tB(GRBfreeenv);            \\\n\tB(GRBstartenv);           \\\n\tB(GRBsetlogcallbackfunc); \\\n\tB(GRBconverttofixed);     \\\n\tB(GRBcomputeIIS);\n\nnamespace gurobi\n{\n#define B DYLIB_EXTERN_DECLARE\nAPILIST\n#undef B\n\nbool is_library_loaded();\n\nbool load_library(const std::string &path);\n} // namespace gurobi\n\nclass GurobiEnv\n{\n  public:\n\tGurobiEnv(bool empty = false);\n\t~GurobiEnv();\n\n\t// parameter\n\tint raw_parameter_type(const char *param_name);\n\tvoid set_raw_parameter_int(const char *param_name, int value);\n\tvoid set_raw_parameter_double(const char *param_name, double value);\n\tvoid set_raw_parameter_string(const char *param_name, const char *value);\n\n\tvoid start();\n\tvoid close();\n\n\tvoid check_error(int error);\n\n\tGRBenv *m_env = nullptr;\n};\n\nstruct GRBfreemodelT\n{\n\tvoid operator()(GRBmodel *model) const\n\t{\n\t\tgurobi::GRBfreemodel(model);\n\t};\n};\n\nclass GurobiModel;\nusing GurobiCallback = std::function<void(GurobiModel *, int)>;\n\nstruct GurobiCallbackUserdata\n{\n\tvoid *model = nullptr;\n\tGurobiCallback callback;\n\tint n_variables = 0;\n\tint where = 0;\n\t// store result of cbget\n\tbool cb_get_mipsol_called = false;\n\tstd::vector<double> mipsol;\n\tbool cb_get_mipnoderel_called = false;\n\tstd::vector<double> mipnoderel;\n\t// Cache for cbsolution\n\tbool cb_set_solution_called = false;\n\tstd::vector<double> heuristic_solution;\n\tbool cb_requires_submit_solution = false;\n};\n\nusing GurobiLoggingCallback = std::function<void(const char *)>;\n\nstruct GurobiLoggingCallbackUserdata\n{\n\tGurobiLoggingCallback callback;\n};\n\nclass GurobiModel : public OnesideLinearConstraintMixin<GurobiModel>,\n                    public OnesideQuadraticConstraintMixin<GurobiModel>,\n                    public TwosideNLConstraintMixin<GurobiModel>,\n                    public LinearObjectiveMixin<GurobiModel>,\n                    public PPrintMixin<GurobiModel>,\n                    public GetValueMixin<GurobiModel>\n{\n  public:\n\tGurobiModel() = default;\n\tGurobiModel(const GurobiEnv &env);\n\tvoid init(const GurobiEnv &env);\n\tvoid close();\n\n\tvoid _reset(int clearall);\n\n\tdouble get_infinity() const;\n\n\tvoid write(const std::string &filename);\n\n\tVariableIndex add_variable(VariableDomain domain = VariableDomain::Continuous,\n\t                           double lb = -GRB_INFINITY, double ub = GRB_INFINITY,\n\t                           const char *name = nullptr);\n\tvoid delete_variable(const VariableIndex &variable);\n\tvoid delete_variables(const Vector<VariableIndex> &variables);\n\tbool is_variable_active(const VariableIndex &variable);\n\tdouble get_variable_value(const VariableIndex &variable);\n\tstd::string pprint_variable(const VariableIndex &variable);\n\tvoid set_variable_bounds(const VariableIndex &variable, double lb, double ub);\n\n\tvoid set_variable_name(const VariableIndex &variable, const char *name);\n\tvoid set_constraint_name(const ConstraintIndex &constraint, const char *name);\n\n\tConstraintIndex add_linear_constraint(const ScalarAffineFunction &function,\n\t                                      ConstraintSense sense, CoeffT rhs,\n\t                                      const char *name = nullptr);\n\tConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &function,\n\t                                         ConstraintSense sense, CoeffT rhs,\n\t                                         const char *name = nullptr);\n\tConstraintIndex add_sos_constraint(const Vector<VariableIndex> &variables, SOSType sos_type);\n\tConstraintIndex add_sos_constraint(const Vector<VariableIndex> &variables, SOSType sos_type,\n\t                                   const Vector<CoeffT> &weights);\n\n\t// Nonlinear constraint\n\tvoid information_of_expr(const ExpressionGraph &graph, const ExpressionHandle &expr,\n\t                         int &opcode, double &data);\n\tvoid decode_graph(const ExpressionGraph &graph, const ExpressionHandle &result,\n\t                  std::vector<int> &opcodes, std::vector<int> &parents,\n\t                  std::vector<double> &datas);\n\tConstraintIndex add_single_nl_constraint(const ExpressionGraph &graph,\n\t                                         const ExpressionHandle &result,\n\t                                         const std::tuple<double, double> &interval,\n\t                                         const char *name = nullptr);\n\n\tvoid delete_constraint(const ConstraintIndex &constraint);\n\tbool is_constraint_active(const ConstraintIndex &constraint);\n\n\tvoid _set_affine_objective(const ScalarAffineFunction &function, ObjectiveSense sense,\n\t                           bool clear_quadratic);\n\tvoid set_objective(const ScalarAffineFunction &function, ObjectiveSense sense);\n\tvoid set_objective(const ScalarQuadraticFunction &function, ObjectiveSense sense);\n\tvoid set_objective(const ExprBuilder &function, ObjectiveSense sense);\n\n\tvoid add_single_nl_objective(ExpressionGraph &graph, const ExpressionHandle &result);\n\tvoid set_nl_objective();\n\n\tvoid optimize();\n\tvoid update();\n\tvoid *get_raw_model();\n\tstd::string version_string();\n\n\t// parameter\n\tint raw_parameter_type(const char *param_name);\n\tvoid set_raw_parameter_int(const char *param_name, int value);\n\tvoid set_raw_parameter_double(const char *param_name, double value);\n\tvoid set_raw_parameter_string(const char *param_name, const char *value);\n\tint get_raw_parameter_int(const char *param_name);\n\tdouble get_raw_parameter_double(const char *param_name);\n\tstd::string get_raw_parameter_string(const char *param_name);\n\n\t// attribute\n\tint raw_attribute_type(const char *attr_name);\n\n\t// model attribute\n\tvoid set_model_raw_attribute_int(const char *attr_name, int value);\n\tvoid set_model_raw_attribute_double(const char *attr_name, double value);\n\tvoid set_model_raw_attribute_string(const char *attr_name, const char *value);\n\tint get_model_raw_attribute_int(const char *attr_name);\n\tdouble get_model_raw_attribute_double(const char *attr_name);\n\tstd::string get_model_raw_attribute_string(const char *attr_name);\n\n\tstd::vector<double> get_model_raw_attribute_vector_double(const char *attr_name, int start,\n\t                                                          int len);\n\tstd::vector<double> get_model_raw_attribute_list_double(const char *attr_name,\n\t                                                        const std::vector<int> &ind);\n\n\t// variable attribute\n\tvoid set_variable_raw_attribute_int(const VariableIndex &variable, const char *attr_name,\n\t                                    int value);\n\tvoid set_variable_raw_attribute_char(const VariableIndex &variable, const char *attr_name,\n\t                                     char value);\n\tvoid set_variable_raw_attribute_double(const VariableIndex &variable, const char *attr_name,\n\t                                       double value);\n\tvoid set_variable_raw_attribute_string(const VariableIndex &variable, const char *attr_name,\n\t                                       const char *value);\n\tint get_variable_raw_attribute_int(const VariableIndex &variable, const char *attr_name);\n\tchar get_variable_raw_attribute_char(const VariableIndex &variable, const char *attr_name);\n\tdouble get_variable_raw_attribute_double(const VariableIndex &variable, const char *attr_name);\n\tstd::string get_variable_raw_attribute_string(const VariableIndex &variable,\n\t                                              const char *attr_name);\n\n\tint _variable_index(const VariableIndex &variable);\n\tint _checked_variable_index(const VariableIndex &variable);\n\n\t// constraint attribute\n\tvoid set_constraint_raw_attribute_int(const ConstraintIndex &constraint, const char *attr_name,\n\t                                      int value);\n\tvoid set_constraint_raw_attribute_char(const ConstraintIndex &constraint, const char *attr_name,\n\t                                       char value);\n\tvoid set_constraint_raw_attribute_double(const ConstraintIndex &constraint,\n\t                                         const char *attr_name, double value);\n\tvoid set_constraint_raw_attribute_string(const ConstraintIndex &constraint,\n\t                                         const char *attr_name, const char *value);\n\tint get_constraint_raw_attribute_int(const ConstraintIndex &constraint, const char *attr_name);\n\tchar get_constraint_raw_attribute_char(const ConstraintIndex &constraint,\n\t                                       const char *attr_name);\n\tdouble get_constraint_raw_attribute_double(const ConstraintIndex &constraint,\n\t                                           const char *attr_name);\n\tstd::string get_constraint_raw_attribute_string(const ConstraintIndex &constraint,\n\t                                                const char *attr_name);\n\n\tint _constraint_index(const ConstraintIndex &constraint);\n\tint _checked_constraint_index(const ConstraintIndex &constraint);\n\n\t// Modifications of model\n\t// 1. set/get RHS of a constraint\n\tdouble get_normalized_rhs(const ConstraintIndex &constraint);\n\tvoid set_normalized_rhs(const ConstraintIndex &constraint, double value);\n\t// 2. set/get coefficient of variable in constraint\n\tdouble get_normalized_coefficient(const ConstraintIndex &constraint,\n\t                                  const VariableIndex &variable);\n\tvoid set_normalized_coefficient(const ConstraintIndex &constraint,\n\t                                const VariableIndex &variable, double value);\n\t// 3. set/get linear coefficient of variable in objective\n\tdouble get_objective_coefficient(const VariableIndex &variable);\n\tvoid set_objective_coefficient(const VariableIndex &variable, double value);\n\n\t// Gurobi-specific convertofixed\n\tvoid _converttofixed();\n\n\t// IIS related\n\tvoid computeIIS();\n\n\t// Non-exported functions\n\tvoid check_error(int error);\n\n\t// Control logging\n\tvoid set_logging(const GurobiLoggingCallback &callback);\n\n\tGurobiLoggingCallbackUserdata m_logging_callback_userdata;\n\n\t// Callback\n\tvoid set_callback(const GurobiCallback &callback);\n\n\t// For callback\n\tbool has_callback = false;\n\tvoid *m_cbdata = nullptr;\n\tGurobiCallbackUserdata m_callback_userdata;\n\n\tint cb_get_info_int(int what);\n\tdouble cb_get_info_double(int what);\n\tvoid cb_get_info_doublearray(int what);\n\n\tdouble cb_get_solution(const VariableIndex &variable);\n\tdouble cb_get_relaxation(const VariableIndex &variable);\n\tvoid cb_set_solution(const VariableIndex &variable, double value);\n\tdouble cb_submit_solution();\n\n\tvoid cb_exit();\n\n\tvoid cb_add_lazy_constraint(const ScalarAffineFunction &function, ConstraintSense sense,\n\t                            CoeffT rhs);\n\tvoid cb_add_lazy_constraint(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs);\n\tvoid cb_add_user_cut(const ScalarAffineFunction &function, ConstraintSense sense, CoeffT rhs);\n\tvoid cb_add_user_cut(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs);\n\n  private:\n\tMonotoneIndexer<int> m_variable_index;\n\n\tMonotoneIndexer<int> m_linear_constraint_index;\n\n\tMonotoneIndexer<int> m_quadratic_constraint_index;\n\n\tMonotoneIndexer<int> m_sos_constraint_index;\n\n\tMonotoneIndexer<int> m_general_constraint_index;\n\t// Gurobi only accepts y = f(x) style nonlinear constraint\n\t// so for each lb <= f(x) <= ub, we need to convert it to\n\t// lb <= y <= ub, and add y = f(x) as a nonlinear constraint\n\t// y is called the result variable (resvar)\n\tHashmap<IndexT, IndexT> m_nlcon_resvar_map;\n\t// for each nonlinear term in objective function, we need to record the resvar to set their\n\t// coefficient in objective as 1.0\n\t// add f(x) to the objective is divided into two steps:\n\t// 1. add a new nonlinear constraint y = f(x)\n\t// 2. set the coefficient of y in objective to 1.0\n\tint m_nlobj_num = 0;\n\tstd::vector<int> m_nlobj_con_indices;\n\tstd::vector<int> m_nlobj_resvar_indices;\n\n\t/* flag to indicate whether the model needs update */\n\tenum : std::uint64_t\n\t{\n\t\tm_variable_creation = 1,\n\t\tm_variable_deletion = 1 << 1,\n\t\tm_linear_constraint_creation = 1 << 2,\n\t\tm_linear_constraint_deletion = 1 << 3,\n\t\tm_quadratic_constraint_creation = 1 << 4,\n\t\tm_quadratic_constraint_deletion = 1 << 5,\n\t\tm_sos_constraint_creation = 1 << 6,\n\t\tm_sos_constraint_deletion = 1 << 7,\n\t\tm_general_constraint_creation = 1 << 8,\n\t\tm_general_constraint_deletion = 1 << 9,\n\t\tm_objective_update = 1 << 10,\n\t\tm_attribute_update = 1 << 11,\n\t\tm_constraint_coefficient_update = 1 << 12,\n\t};\n\tstd::uint64_t m_update_flag = 0;\n\tvoid _update_for_information();\n\tvoid _update_for_variable_index();\n\tvoid _update_for_constraint_index(ConstraintType type);\n\n\t/* Gurobi part */\n\tGRBenv *m_env = nullptr;\n\tstd::unique_ptr<GRBmodel, GRBfreemodelT> m_model;\n};\n"
  },
  {
    "path": "include/pyoptinterface/highs_model.hpp",
    "content": "#pragma once\n\n#include <memory>\n\n#include \"interfaces/highs_c_api.h\"\n#include \"lp_data/HConst.h\"\n\n#include \"pyoptinterface/core.hpp\"\n#include \"pyoptinterface/container.hpp\"\n#include \"pyoptinterface/solver_common.hpp\"\n#include \"pyoptinterface/dylib.hpp\"\n\n#define APILIST                     \\\n\tB(Highs_create);                \\\n\tB(Highs_destroy);               \\\n\tB(Highs_writeModel);            \\\n\tB(Highs_writeSolution);         \\\n\tB(Highs_writeSolutionPretty);   \\\n\tB(Highs_addCol);                \\\n\tB(Highs_passColName);           \\\n\tB(Highs_getColName);            \\\n\tB(Highs_getNumCol);             \\\n\tB(Highs_changeColIntegrality);  \\\n\tB(Highs_deleteColsBySet);       \\\n\tB(Highs_addRow);                \\\n\tB(Highs_passRowName);           \\\n\tB(Highs_getRowName);            \\\n\tB(Highs_getNumRow);             \\\n\tB(Highs_deleteRowsBySet);       \\\n\tB(Highs_passHessian);           \\\n\tB(Highs_changeColsCostByRange); \\\n\tB(Highs_changeObjectiveOffset); \\\n\tB(Highs_changeObjectiveSense);  \\\n\tB(Highs_run);                   \\\n\tB(Highs_getNumCols);            \\\n\tB(Highs_getNumRows);            \\\n\tB(Highs_getModelStatus);        \\\n\tB(Highs_getDualRay);            \\\n\tB(Highs_getPrimalRay);          \\\n\tB(Highs_getIntInfoValue);       \\\n\tB(Highs_getSolution);           \\\n\tB(Highs_getHessianNumNz);       \\\n\tB(Highs_getBasis);              \\\n\tB(Highs_version);               \\\n\tB(Highs_getRunTime);            \\\n\tB(Highs_getOptionType);         \\\n\tB(Highs_setBoolOptionValue);    \\\n\tB(Highs_setIntOptionValue);     \\\n\tB(Highs_setDoubleOptionValue);  \\\n\tB(Highs_setStringOptionValue);  \\\n\tB(Highs_getBoolOptionValue);    \\\n\tB(Highs_getIntOptionValue);     \\\n\tB(Highs_getDoubleOptionValue);  \\\n\tB(Highs_getStringOptionValue);  \\\n\tB(Highs_getInfoType);           \\\n\tB(Highs_getInt64InfoValue);     \\\n\tB(Highs_getDoubleInfoValue);    \\\n\tB(Highs_getColIntegrality);     \\\n\tB(Highs_changeColsBoundsBySet); \\\n\tB(Highs_getColsBySet);          \\\n\tB(Highs_getObjectiveSense);     \\\n\tB(Highs_getObjectiveValue);     \\\n\tB(Highs_getColsByRange);        \\\n\tB(Highs_setSolution);           \\\n\tB(Highs_getRowsBySet);          \\\n\tB(Highs_changeRowsBoundsBySet); \\\n\tB(Highs_changeCoeff);           \\\n\tB(Highs_changeColCost);\n\nnamespace highs\n{\n#define B DYLIB_EXTERN_DECLARE\nAPILIST\n#undef B\n\nbool is_library_loaded();\n\nbool load_library(const std::string &path);\n} // namespace highs\n\nstruct HighsfreemodelT\n{\n\tvoid operator()(void *model) const\n\t{\n\t\thighs::Highs_destroy(model);\n\t};\n};\n\nenum class HighsSolutionStatus\n{\n\tOPTIMIZE_NOT_CALLED,\n\tOPTIMIZE_OK,\n\tOPTIMIZE_ERROR,\n};\n\nstruct POIHighsSolution\n{\n\tHighsSolutionStatus status = HighsSolutionStatus::OPTIMIZE_NOT_CALLED;\n\tHighsInt model_status;\n\tstd::vector<double> colvalue;\n\tstd::vector<double> coldual;\n\tstd::vector<HighsInt> colstatus;\n\tstd::vector<double> rowvalue;\n\tstd::vector<double> rowdual;\n\tstd::vector<HighsInt> rowstatus;\n\tHighsInt primal_solution_status;\n\tHighsInt dual_solution_status;\n\tbool has_primal_ray;\n\tbool has_dual_ray;\n\tstd::vector<double> primal_ray;\n\tstd::vector<double> dual_ray;\n};\n\nclass POIHighsModel : public OnesideLinearConstraintMixin<POIHighsModel>,\n                      public TwosideLinearConstraintMixin<POIHighsModel>,\n                      public LinearObjectiveMixin<POIHighsModel>,\n                      public PPrintMixin<POIHighsModel>,\n                      public GetValueMixin<POIHighsModel>\n{\n  public:\n\tPOIHighsModel();\n\tvoid init();\n\tvoid close();\n\n\tvoid write(const std::string &filename, bool pretty);\n\n\tVariableIndex add_variable(VariableDomain domain = VariableDomain::Continuous,\n\t                           double lb = -kHighsInf, double ub = kHighsInf,\n\t                           const char *name = nullptr);\n\tvoid delete_variable(const VariableIndex &variable);\n\tvoid delete_variables(const Vector<VariableIndex> &variables);\n\tbool is_variable_active(const VariableIndex &variable);\n\tdouble get_variable_value(const VariableIndex &variable);\n\tstd::string pprint_variable(const VariableIndex &variable);\n\tvoid set_variable_bounds(const VariableIndex &variable, double lb, double ub);\n\n\tConstraintIndex add_linear_constraint(const ScalarAffineFunction &function,\n\t                                      ConstraintSense sense, CoeffT rhs,\n\t                                      const char *name = nullptr);\n\tConstraintIndex add_linear_constraint(const ScalarAffineFunction &function,\n\t                                      const std::tuple<double, double> &interval,\n\t                                      const char *name = nullptr);\n\tConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &function,\n\t                                         ConstraintSense sense, CoeffT rhs,\n\t                                         const char *name = nullptr);\n\n\tvoid delete_constraint(const ConstraintIndex &constraint);\n\tbool is_constraint_active(const ConstraintIndex &constraint);\n\n\tvoid _set_affine_objective(const ScalarAffineFunction &function, ObjectiveSense sense,\n\t                           bool clear_quadratic);\n\tvoid set_objective(const ScalarAffineFunction &function, ObjectiveSense sense);\n\tvoid set_objective(const ScalarQuadraticFunction &function, ObjectiveSense sense);\n\tvoid set_objective(const ExprBuilder &function, ObjectiveSense sense);\n\n\tvoid optimize();\n\tvoid *get_raw_model();\n\tstd::string version_string();\n\n\tdouble getruntime();\n\tint getnumrow();\n\tint getnumcol();\n\n\t// option\n\tint raw_option_type(const char *param_name);\n\tvoid set_raw_option_bool(const char *param_name, bool value);\n\tvoid set_raw_option_int(const char *param_name, int value);\n\tvoid set_raw_option_double(const char *param_name, double value);\n\tvoid set_raw_option_string(const char *param_name, const char *value);\n\tbool get_raw_option_bool(const char *param_name);\n\tint get_raw_option_int(const char *param_name);\n\tdouble get_raw_option_double(const char *param_name);\n\tstd::string get_raw_option_string(const char *param_name);\n\n\t// information\n\tint raw_info_type(const char *info_name);\n\tint get_raw_info_int(const char *info_name);\n\tstd::int64_t get_raw_info_int64(const char *info_name);\n\tdouble get_raw_info_double(const char *info_name);\n\n\t// Accessing information of m_problem\n\tstd::string get_variable_name(const VariableIndex &variable);\n\tvoid set_variable_name(const VariableIndex &variable, const char *name);\n\tVariableDomain get_variable_type(const VariableIndex &variable);\n\tvoid set_variable_type(const VariableIndex &variable, VariableDomain domain);\n\tdouble get_variable_lower_bound(const VariableIndex &variable);\n\tdouble get_variable_upper_bound(const VariableIndex &variable);\n\tvoid set_variable_lower_bound(const VariableIndex &variable, double lb);\n\tvoid set_variable_upper_bound(const VariableIndex &variable, double ub);\n\n\tstd::string get_constraint_name(const ConstraintIndex &constraint);\n\tvoid set_constraint_name(const ConstraintIndex &constraint, const char *name);\n\tdouble get_constraint_primal(const ConstraintIndex &constraint);\n\tdouble get_constraint_dual(const ConstraintIndex &constraint);\n\n\t// dual of variable as reduced cost\n\tdouble get_variable_dual(const VariableIndex &variable);\n\n\tObjectiveSense get_obj_sense();\n\tvoid set_obj_sense(ObjectiveSense sense);\n\tdouble get_obj_value();\n\n\tHighsInt _variable_index(const VariableIndex &variable);\n\tHighsInt _checked_variable_index(const VariableIndex &variable);\n\tHighsInt _constraint_index(const ConstraintIndex &constraint);\n\tHighsInt _checked_constraint_index(const ConstraintIndex &constraint);\n\n\t// Primal start\n\tvoid set_primal_start(const Vector<VariableIndex> &variables, const Vector<double> &values);\n\n\t// Modifications of model\n\t// 1. set/get RHS of a constraint\n\tdouble get_normalized_rhs(const ConstraintIndex &constraint);\n\tvoid set_normalized_rhs(const ConstraintIndex &constraint, double value);\n\t// 2. set/get coefficient of variable in constraint\n\tdouble get_normalized_coefficient(const ConstraintIndex &constraint,\n\t                                  const VariableIndex &variable);\n\tvoid set_normalized_coefficient(const ConstraintIndex &constraint,\n\t                                const VariableIndex &variable, double value);\n\t// 3. set/get linear coefficient of variable in objective\n\tdouble get_objective_coefficient(const VariableIndex &variable);\n\tvoid set_objective_coefficient(const VariableIndex &variable, double value);\n\n  private:\n\tMonotoneIndexer<HighsInt> m_variable_index;\n\n\tMonotoneIndexer<HighsInt> m_linear_constraint_index;\n\n\t// Highs does not discriminate between integer variable and binary variable\n\t// So we need to keep track of binary variables\n\tHashset<IndexT> binary_variables;\n\n\t/* Highs part */\n\tstd::unique_ptr<void, HighsfreemodelT> m_model;\n\n  public:\n\t// cache the solution\n\tPOIHighsSolution m_solution;\n\t// cache the number of variable and constraints because querying them via HiGHS API is very\n\t// expensive\n\tHighsInt m_n_variables = 0;\n\tHighsInt m_n_constraints = 0;\n};\n"
  },
  {
    "path": "include/pyoptinterface/ipopt_model.hpp",
    "content": "#pragma once\n\n#include \"solvers/ipopt/IpStdCInterface.h\"\n#include \"pyoptinterface/nlexpr.hpp\"\n#include \"pyoptinterface/nleval.hpp\"\n#include \"pyoptinterface/dylib.hpp\"\n#include \"pyoptinterface/solver_common.hpp\"\n#include <cmath>\n#include <tuple>\n\n#define APILIST            \\\n\tB(CreateIpoptProblem); \\\n\tB(FreeIpoptProblem);   \\\n\tB(AddIpoptStrOption);  \\\n\tB(AddIpoptNumOption);  \\\n\tB(AddIpoptIntOption);  \\\n\tB(IpoptSolve);\n\nnamespace ipopt\n{\n#define B DYLIB_EXTERN_DECLARE\nAPILIST\n#undef B\n\nbool is_library_loaded();\n\nbool load_library(const std::string &path);\n} // namespace ipopt\n\nstruct IpoptfreeproblemT\n{\n\tvoid operator()(IpoptProblemInfo *model) const\n\t{\n\t\tipopt::FreeIpoptProblem(model);\n\t};\n};\n\nstruct IpoptResult\n{\n\tbool is_valid = false;\n\t// store results\n\tstd::vector<double> x, g, mult_g, mult_x_L, mult_x_U;\n\tdouble obj_val;\n};\n\nstruct IpoptModel : public OnesideLinearConstraintMixin<IpoptModel>,\n                    public TwosideLinearConstraintMixin<IpoptModel>,\n                    public OnesideQuadraticConstraintMixin<IpoptModel>,\n                    public TwosideQuadraticConstraintMixin<IpoptModel>,\n                    public LinearObjectiveMixin<IpoptModel>,\n                    public PPrintMixin<IpoptModel>,\n                    public GetValueMixin<IpoptModel>\n{\n\t/* Methods */\n\tIpoptModel();\n\tvoid close();\n\n\tVariableIndex add_variable(double lb = -INFINITY, double ub = INFINITY, double start = 0.0,\n\t                           const char *name = nullptr);\n\tdouble get_variable_lb(const VariableIndex &variable);\n\tdouble get_variable_ub(const VariableIndex &variable);\n\tvoid set_variable_lb(const VariableIndex &variable, double lb);\n\tvoid set_variable_ub(const VariableIndex &variable, double ub);\n\tvoid set_variable_bounds(const VariableIndex &variable, double lb, double ub);\n\n\tdouble get_variable_start(const VariableIndex &variable);\n\tvoid set_variable_start(const VariableIndex &variable, double start);\n\n\tstd::string get_variable_name(const VariableIndex &variable);\n\tvoid set_variable_name(const VariableIndex &variable, const std::string &name);\n\n\tdouble get_variable_value(const VariableIndex &variable);\n\n\tstd::string pprint_variable(const VariableIndex &variable);\n\n\tdouble get_obj_value();\n\tint _constraint_internal_index(const ConstraintIndex &constraint);\n\tdouble get_constraint_primal(const ConstraintIndex &constraint);\n\tdouble get_constraint_dual(const ConstraintIndex &constraint);\n\n\tConstraintIndex add_linear_constraint(const ScalarAffineFunction &f, ConstraintSense sense,\n\t                                      double rhs, const char *name = nullptr);\n\tConstraintIndex add_linear_constraint(const ScalarAffineFunction &f,\n\t                                      const std::tuple<double, double> &interval,\n\t                                      const char *name = nullptr);\n\n\tConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &f,\n\t                                         ConstraintSense sense, double rhs,\n\t                                         const char *name = nullptr);\n\tConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &f,\n\t                                         const std::tuple<double, double> &interval,\n\t                                         const char *name = nullptr);\n\n\tvoid set_objective(const ScalarAffineFunction &expr, ObjectiveSense sense);\n\tvoid set_objective(const ScalarQuadraticFunction &expr, ObjectiveSense sense);\n\tvoid set_objective(const ExprBuilder &expr, ObjectiveSense sense);\n\n\tvoid _set_linear_objective(const ScalarAffineFunction &expr);\n\tvoid _set_quadratic_objective(const ScalarQuadraticFunction &expr);\n\n\t// new implementation\n\tsize_t n_graph_instances = 0;\n\tstd::vector<std::vector<int>> m_graph_instance_variables;\n\tstd::vector<std::vector<double>> m_graph_instance_constants;\n\t// record graph instances with constraint output and objective output\n\tstruct GraphInstancesInfo\n\t{\n\t\t// hash of this graph instance\n\t\tstd::vector<uint64_t> hashes;\n\t\t// index of this graph instance\n\t\tstd::vector<int> instance_indices;\n\n\t\tsize_t n_instances_since_last_aggregation;\n\t} nl_constraint_info, nl_objective_info;\n\n\t// length = n_graph_instances\n\tstruct GraphInstancesGroupInfo\n\t{\n\t\t// which group it belongs to\n\t\tstd::vector<int> group_indices;\n\t\t// the number in that group\n\t\tstd::vector<int> group_orders;\n\t} nl_constraint_group_info, nl_objective_group_info;\n\n\t// graph groups\n\tstruct\n\t{\n\t\tHashmap<uint64_t, int> hash_to_group;\n\t\tsize_t n_group = 0;\n\t\tstd::vector<int> representative_graph_indices;\n\t\tstd::vector<std::vector<int>> instance_indices;\n\t\tstd::vector<AutodiffSymbolicStructure> autodiff_structures;\n\t\tstd::vector<ConstraintAutodiffEvaluator> autodiff_evaluators;\n\n\t\t// where to store the hessian matrix, each group length = n_instance * local_hessian_nnz\n\t\tstd::vector<std::vector<int>> hessian_indices;\n\t} nl_constraint_groups;\n\n\tstruct\n\t{\n\t\tHashmap<uint64_t, int> hash_to_group;\n\t\tsize_t n_group = 0;\n\t\tstd::vector<int> representative_graph_indices;\n\t\tstd::vector<std::vector<int>> instance_indices;\n\t\tstd::vector<AutodiffSymbolicStructure> autodiff_structures;\n\t\tstd::vector<ObjectiveAutodiffEvaluator> autodiff_evaluators;\n\n\t\t// where to store the gradient vector, each group length = n_instance * local_jacobian_nnz\n\t\tstd::vector<std::vector<int>> gradient_indices;\n\t\t// where to store the hessian matrix, each group length = n_instance * local_hessian_nnz\n\t\tstd::vector<std::vector<int>> hessian_indices;\n\t} nl_objective_groups;\n\n\tint add_graph_index();\n\tvoid finalize_graph_instance(size_t graph_index, const ExpressionGraph &graph);\n\tint aggregate_nl_constraint_groups();\n\tint get_nl_constraint_group_representative(int group_index) const;\n\tint aggregate_nl_objective_groups();\n\tint get_nl_objective_group_representative(int group_index) const;\n\n\tvoid assign_nl_constraint_group_autodiff_structure(int group_index,\n\t                                                   const AutodiffSymbolicStructure &structure);\n\tvoid assign_nl_constraint_group_autodiff_evaluator(\n\t    int group_index, const ConstraintAutodiffEvaluator &evaluator);\n\tvoid assign_nl_objective_group_autodiff_structure(int group_index,\n\t                                                  const AutodiffSymbolicStructure &structure);\n\tvoid assign_nl_objective_group_autodiff_evaluator(int group_index,\n\t                                                  const ObjectiveAutodiffEvaluator &evaluator);\n\n\tConstraintIndex add_single_nl_constraint(size_t graph_index, const ExpressionGraph &graph,\n\t                                         double lb, double ub);\n\n\t// void clear_nl_objective();\n\n\tvoid analyze_structure();\n\tvoid optimize();\n\n\t// load current solution as\tinitial guess\n\tvoid load_current_solution();\n\n\t// set options\n\tvoid set_raw_option_int(const std::string &name, int value);\n\tvoid set_raw_option_double(const std::string &name, double value);\n\tvoid set_raw_option_string(const std::string &name, const std::string &value);\n\n\t/* Members */\n\n\tsize_t n_variables = 0;\n\n\tsize_t n_nl_constraints = 0;\n\t/*\n\t * record the constraint indices mapping from the monotonic one (the order of adding\n\t * constraint) to the reordered one (linear, quadratic, NL group 0 -> con0, con1 ,..., conN0, NL\n\t * group1 -> con0, con1,..., conN1)\n\t */\n\t// this is maintained when adding NL constraint\n\tstruct ConstraintGraphMembership\n\t{\n\t\t// which graph it belongs to\n\t\tint graph;\n\t\t// the rank in that graph\n\t\tint rank;\n\t};\n\t// record the graph a nonlinear constraint belongs to\n\tstd::vector<ConstraintGraphMembership> nl_constraint_graph_memberships;\n\n\t// this vector is constructed before optimization\n\t// ext means the external monotonic order\n\t// int means the internal order that passes to Ipopt\n\tstd::vector<int> nl_constraint_map_ext2int;\n\n\t// we need a sparse vector to store the gradient\n\tstd::vector<double> sparse_gradient_values;\n\tstd::vector<int> sparse_gradient_indices;\n\n\tstd::vector<double> m_var_lb, m_var_ub, m_var_init;\n\tstd::vector<double> m_linear_con_lb, m_linear_con_ub, m_quadratic_con_lb, m_quadratic_con_ub,\n\t    m_nl_con_lb, m_nl_con_ub, m_con_lb, m_con_ub;\n\n\tHashmap<IndexT, std::string> m_var_names;\n\n\tsize_t m_jacobian_nnz = 0;\n\tstd::vector<int> m_jacobian_rows, m_jacobian_cols;\n\n\tsize_t m_hessian_nnz = 0;\n\tstd::vector<int> m_hessian_rows, m_hessian_cols;\n\tHashmap<std::tuple<int, int>, int> m_hessian_index_map;\n\n\tLinearEvaluator m_linear_con_evaluator;\n\tQuadraticEvaluator m_quadratic_con_evaluator;\n\n\tstd::optional<LinearEvaluator> m_linear_obj_evaluator;\n\tstd::optional<QuadraticEvaluator> m_quadratic_obj_evaluator;\n\n\tNonlinearEvaluator m_nl_evaluator;\n\n\t// The options of the Ipopt solver, we cache them before constructing the m_problem\n\tHashmap<std::string, int> m_options_int;\n\tHashmap<std::string, double> m_options_num;\n\tHashmap<std::string, std::string> m_options_str;\n\n\tIpoptResult m_result;\n\tbool m_is_dirty = true;\n\tenum ApplicationReturnStatus m_status;\n\n\tstd::unique_ptr<IpoptProblemInfo, IpoptfreeproblemT> m_problem = nullptr;\n};\n"
  },
  {
    "path": "include/pyoptinterface/knitro_model.hpp",
    "content": "#pragma once\n\n#include <deque>\n#include <memory>\n#include <optional>\n#include <variant>\n\n#include \"solvers/knitro/knitro.h\"\n\n#include \"pyoptinterface/core.hpp\"\n#include \"pyoptinterface/container.hpp\"\n#include \"pyoptinterface/cppad_interface.hpp\"\n#define USE_NLMIXIN\n#include \"pyoptinterface/solver_common.hpp\"\n#include \"pyoptinterface/dylib.hpp\"\n\n// Define Knitro C APIs to be dynamically loaded\n#define APILIST                         \\\n\tB(KN_checkout_license);             \\\n\tB(KN_release_license);              \\\n\tB(KN_new_lm);                       \\\n\tB(KN_new);                          \\\n\tB(KN_free);                         \\\n\tB(KN_update);                       \\\n\tB(KN_solve);                        \\\n\tB(KN_get_param_id);                 \\\n\tB(KN_get_param_type);               \\\n\tB(KN_set_int_param);                \\\n\tB(KN_set_char_param);               \\\n\tB(KN_set_double_param);             \\\n\tB(KN_get_int_param);                \\\n\tB(KN_get_double_param);             \\\n\tB(KN_add_var);                      \\\n\tB(KN_add_con);                      \\\n\tB(KN_set_var_lobnd);                \\\n\tB(KN_set_var_upbnd);                \\\n\tB(KN_get_var_lobnd);                \\\n\tB(KN_get_var_upbnd);                \\\n\tB(KN_set_var_type);                 \\\n\tB(KN_get_var_type);                 \\\n\tB(KN_set_var_name);                 \\\n\tB(KN_get_var_name);                 \\\n\tB(KN_set_con_lobnd);                \\\n\tB(KN_set_con_upbnd);                \\\n\tB(KN_get_con_lobnd);                \\\n\tB(KN_get_con_upbnd);                \\\n\tB(KN_set_con_name);                 \\\n\tB(KN_get_con_name);                 \\\n\tB(KN_set_obj_goal);                 \\\n\tB(KN_get_obj_goal);                 \\\n\tB(KN_set_var_primal_init_value);    \\\n\tB(KN_add_obj_constant);             \\\n\tB(KN_del_obj_constant);             \\\n\tB(KN_add_obj_linear_struct);        \\\n\tB(KN_del_obj_linear_struct_all);    \\\n\tB(KN_add_obj_quadratic_struct);     \\\n\tB(KN_del_obj_quadratic_struct_all); \\\n\tB(KN_chg_obj_linear_term);          \\\n\tB(KN_add_con_constant);             \\\n\tB(KN_add_con_linear_struct);        \\\n\tB(KN_add_con_linear_term);          \\\n\tB(KN_add_con_quadratic_struct);     \\\n\tB(KN_add_con_quadratic_term);       \\\n\tB(KN_chg_con_linear_term);          \\\n\tB(KN_add_eval_callback);            \\\n\tB(KN_set_cb_user_params);           \\\n\tB(KN_set_cb_grad);                  \\\n\tB(KN_set_cb_hess);                  \\\n\tB(KN_del_obj_eval_callback_all);    \\\n\tB(KN_get_var_primal_value);         \\\n\tB(KN_get_var_dual_value);           \\\n\tB(KN_get_con_value);                \\\n\tB(KN_get_con_dual_value);           \\\n\tB(KN_get_obj_value);                \\\n\tB(KN_get_number_iters);             \\\n\tB(KN_get_mip_number_nodes);         \\\n\tB(KN_get_mip_relaxation_bnd);       \\\n\tB(KN_get_mip_rel_gap);              \\\n\tB(KN_get_solve_time_real);          \\\n\tB(KN_get_release);\n\nnamespace knitro\n{\n#define B DYLIB_EXTERN_DECLARE\nAPILIST\n#undef B\n\nbool is_library_loaded();\n\nbool load_library(const std::string &path);\n\nbool has_valid_license();\n} // namespace knitro\n\nstruct KNITROFreeProblemT\n{\n\tvoid operator()(KN_context *kc) const\n\t{\n\t\tif (kc != nullptr)\n\t\t{\n\t\t\tknitro::KN_free(&kc);\n\t\t}\n\t}\n};\n\nstruct KNITROFreeLicenseT\n{\n\tvoid operator()(LM_context *lmc) const\n\t{\n\t\tif (lmc != nullptr)\n\t\t{\n\t\t\tknitro::KN_release_license(&lmc);\n\t\t}\n\t}\n};\n\nenum ObjectiveFlags\n{\n\tOBJ_CONSTANT = 1 << 0,  // 0x01\n\tOBJ_LINEAR = 1 << 1,    // 0x02\n\tOBJ_QUADRATIC = 1 << 2, // 0x04\n\tOBJ_NONLINEAR = 1 << 3  // 0x08\n};\n\nenum ConstraintSenseFlags\n{\n\tCON_LOBND = 1 << 0, // 0x01\n\tCON_UPBND = 1 << 1, // 0x02\n};\n\ntemplate <typename I>\nstruct CallbackPattern\n{\n\tstd::vector<I> indexCons;\n\tstd::vector<I> objGradIndexVars;\n\tstd::vector<I> jacIndexCons;\n\tstd::vector<I> jacIndexVars;\n\tstd::vector<I> hessIndexVars1;\n\tstd::vector<I> hessIndexVars2;\n};\n\nusing namespace CppAD;\n\ntemplate <typename V, typename S, typename I>\nstruct CallbackEvaluator\n{\n\n\tstatic inline constexpr const char *CLRNG = \"cppad\";\n\n\tstd::vector<I> indexVars;\n\tstd::vector<I> indexCons;\n\n\tADFun<V> fun;  /// < CppAD tape.\n\tADFun<V> jfun; /// < CppAD tape for Aggregated Jacobian\n\n\t/// Sparsity patterns\n\tsparse_rc<vector<S>> jp;\n\tsparse_rc<vector<S>> hp;\n\n\t/// Workspaces for Jacobian and Hessian calculations\n\tsparse_jac_work jw;\n\tsparse_jac_work hw;\n\n\t/// Temporary vectors for evaluations\n\tvector<V> x;\n\tvector<V> xw;\n\tsparse_rcv<vector<S>, vector<V>> jac;\n\tsparse_rcv<vector<S>, vector<V>> hes;\n\n\tvoid setup()\n\t{\n\t\tfun.optimize();\n\t\tsize_t nx = fun.Domain();\n\t\tsize_t ny = fun.Range();\n\n\t\tvector<bool> dom(nx, true);\n\t\tvector<bool> rng(ny, true);\n\t\tfun.subgraph_sparsity(dom, rng, false, jp);\n\n\t\tADFun<AD<V>, V> af = fun.base2ad();\n\t\tvector<AD<V>> jaxw(nx + ny);\n\t\tIndependent(jaxw);\n\t\tvector<AD<V>> jax(nx);\n\t\tvector<AD<V>> jaw(ny);\n\t\tvector<AD<V>> jaz(nx);\n\t\tfor (size_t i = 0; i < nx; i++)\n\t\t{\n\t\t\tjax[i] = jaxw[i];\n\t\t}\n\t\tfor (size_t i = 0; i < ny; i++)\n\t\t{\n\t\t\tjaw[i] = jaxw[nx + i];\n\t\t}\n\t\taf.Forward(0, jax);\n\t\tjaz = af.Reverse(1, jaw);\n\t\tjfun.Dependent(jaxw, jaz);\n\t\tjfun.optimize();\n\t\tvector<bool> jdom(nx + ny, false);\n\t\tfor (size_t i = 0; i < nx; i++)\n\t\t{\n\t\t\tjdom[i] = true;\n\t\t}\n\t\tvector<bool> jrng(nx, true);\n\t\tsparse_rc<vector<S>> hsp;\n\t\tjfun.subgraph_sparsity(jdom, jrng, false, hsp);\n\n\t\tauto &hrow = hsp.row();\n\t\tauto &hcol = hsp.col();\n\t\tfor (size_t k = 0; k < hsp.nnz(); k++)\n\t\t{\n\t\t\tif (hrow[k] <= hcol[k])\n\t\t\t{\n\t\t\t\thp.push_back(hrow[k], hcol[k]);\n\t\t\t}\n\t\t}\n\t\tx.resize(nx);\n\t\txw.resize(nx + ny);\n\t\tjac = sparse_rcv<vector<S>, vector<V>>(jp);\n\t\thes = sparse_rcv<vector<S>, vector<V>>(hp);\n\t}\n\n\tbool is_objective() const\n\t{\n\t\treturn indexCons.empty();\n\t}\n\n\tvoid eval_fun(const V *req_x, V *res_y)\n\t{\n\t\tcopy(fun.Domain(), req_x, indexVars.data(), x.data());\n\t\tauto y = fun.Forward(0, x);\n\t\tint mode = is_objective() ? 2 : 0;\n\t\tcopy(fun.Range(), y.data(), (const I *)nullptr, res_y, mode);\n\t}\n\n\tvoid eval_jac(const V *req_x, V *res_jac)\n\t{\n\t\tcopy(fun.Domain(), req_x, indexVars.data(), x.data());\n\t\tfun.sparse_jac_rev(x, jac, jp, CLRNG, jw);\n\t\tcopy(jac.nnz(), jac.val().data(), (const I *)nullptr, res_jac);\n\t}\n\n\tvoid eval_hess(const V *req_x, const V *req_w, V *res_hess)\n\t{\n\t\tcopy(fun.Domain(), req_x, indexVars.data(), xw.data());\n\t\tint mode = is_objective() ? 1 : 0;\n\t\tcopy(fun.Range(), req_w, indexCons.data(), xw.data() + fun.Domain(), mode);\n\t\tjfun.sparse_jac_rev(xw, hes, hp, CLRNG, hw);\n\t\tcopy(hes.nnz(), hes.val().data(), (const I *)nullptr, res_hess);\n\t}\n\n\tCallbackPattern<I> get_callback_pattern() const\n\t{\n\t\tCallbackPattern<I> p;\n\t\tp.indexCons = indexCons;\n\n\t\tauto &jrow = jp.row();\n\t\tauto &jcol = jp.col();\n\t\tif (indexCons.empty())\n\t\t{\n\t\t\tfor (size_t k = 0; k < jp.nnz(); k++)\n\t\t\t{\n\t\t\t\tp.objGradIndexVars.push_back(indexVars[jcol[k]]);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (size_t k = 0; k < jp.nnz(); k++)\n\t\t\t{\n\t\t\t\tp.jacIndexCons.push_back(indexCons[jrow[k]]);\n\t\t\t\tp.jacIndexVars.push_back(indexVars[jcol[k]]);\n\t\t\t}\n\t\t}\n\n\t\tauto &hrow = hp.row();\n\t\tauto &hcol = hp.col();\n\t\tfor (size_t k = 0; k < hp.nnz(); k++)\n\t\t{\n\t\t\tp.hessIndexVars1.push_back(indexVars[hrow[k]]);\n\t\t\tp.hessIndexVars2.push_back(indexVars[hcol[k]]);\n\t\t}\n\n\t\treturn p;\n\t}\n\n  private:\n\t// Copy mode:\n\t// - 0: normal copy\n\t// - 1: duplicate (copy first element of src to all elements of dst)\n\t// - 2: aggregate (sum all elements of src and copy to all elements of dst)\n\tstatic void copy(const size_t n, const V *src, const I *idx, V *dst, int mode = 0)\n\t{\n\t\tif (mode == 1)\n\t\t{\n\t\t\tfor (size_t i = 0; i < n; i++)\n\t\t\t{\n\t\t\t\tdst[i] = src[0];\n\t\t\t}\n\t\t}\n\t\telse if (mode == 2)\n\t\t{\n\t\t\tif (n == 0)\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdst[0] = src[0];\n\t\t\tfor (size_t i = 1; i < n; i++)\n\t\t\t{\n\t\t\t\tdst[0] += src[i];\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (idx == nullptr)\n\t\t\t{\n\t\t\t\tfor (size_t i = 0; i < n; i++)\n\t\t\t\t{\n\t\t\t\t\tdst[i] = src[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfor (size_t i = 0; i < n; i++)\n\t\t\t\t{\n\t\t\t\t\tdst[i] = src[idx[i]];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\ninline bool is_name_empty(const char *name)\n{\n\treturn name == nullptr || name[0] == '\\0';\n}\n\ninline int knitro_var_type(VariableDomain domain)\n{\n\tswitch (domain)\n\t{\n\tcase VariableDomain::Continuous:\n\t\treturn KN_VARTYPE_CONTINUOUS;\n\tcase VariableDomain::Integer:\n\t\treturn KN_VARTYPE_INTEGER;\n\tcase VariableDomain::Binary:\n\t\treturn KN_VARTYPE_BINARY;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown variable domain\");\n\t}\n}\n\ninline VariableDomain knitro_variable_domain(int var_type)\n{\n\tswitch (var_type)\n\t{\n\tcase KN_VARTYPE_CONTINUOUS:\n\t\treturn VariableDomain::Continuous;\n\tcase KN_VARTYPE_INTEGER:\n\t\treturn VariableDomain::Integer;\n\tcase KN_VARTYPE_BINARY:\n\t\treturn VariableDomain::Binary;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown variable type\");\n\t}\n}\n\ninline int knitro_obj_goal(ObjectiveSense sense)\n{\n\tswitch (sense)\n\t{\n\tcase ObjectiveSense::Minimize:\n\t\treturn KN_OBJGOAL_MINIMIZE;\n\tcase ObjectiveSense::Maximize:\n\t\treturn KN_OBJGOAL_MAXIMIZE;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown objective sense\");\n\t}\n}\n\ninline ObjectiveSense knitro_obj_sense(int goal)\n{\n\tswitch (goal)\n\t{\n\tcase KN_OBJGOAL_MINIMIZE:\n\t\treturn ObjectiveSense::Minimize;\n\tcase KN_OBJGOAL_MAXIMIZE:\n\t\treturn ObjectiveSense::Maximize;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown objective goal\");\n\t}\n}\n\ninline void knitro_throw(int error)\n{\n\tif (error != 0)\n\t{\n\t\tthrow std::runtime_error(fmt::format(\"KNITRO error code: {}\", error));\n\t}\n}\n\nclass KNITROEnv\n{\n  public:\n\tKNITROEnv(bool empty = false);\n\n\tKNITROEnv(const KNITROEnv &) = delete;\n\tKNITROEnv &operator=(const KNITROEnv &) = delete;\n\n\tKNITROEnv(KNITROEnv &&) = default;\n\tKNITROEnv &operator=(KNITROEnv &&) = default;\n\n\tvoid start();\n\tbool empty() const;\n\tstd::shared_ptr<LM_context> get_lm() const;\n\tvoid close();\n\n  private:\n\tvoid _check_error(int code) const;\n\tstd::shared_ptr<LM_context> m_lm = nullptr;\n};\n\nclass KNITROModel : public OnesideLinearConstraintMixin<KNITROModel>,\n                    public TwosideLinearConstraintMixin<KNITROModel>,\n                    public OnesideQuadraticConstraintMixin<KNITROModel>,\n                    public TwosideQuadraticConstraintMixin<KNITROModel>,\n                    public TwosideNLConstraintMixin<KNITROModel>,\n                    public LinearObjectiveMixin<KNITROModel>,\n                    public PPrintMixin<KNITROModel>,\n                    public GetValueMixin<KNITROModel>\n{\n  public:\n\t// Constructor/Init/Close\n\tKNITROModel();\n\tKNITROModel(const KNITROEnv &env);\n\n\tKNITROModel(const KNITROModel &) = delete;\n\tKNITROModel &operator=(const KNITROModel &) = delete;\n\n\tKNITROModel(KNITROModel &&) = default;\n\tKNITROModel &operator=(KNITROModel &&) = default;\n\n\tvoid init();\n\tvoid init(const KNITROEnv &env);\n\tvoid close();\n\n\t// Model information\n\tdouble get_infinity() const;\n\tstd::string get_solver_name() const;\n\tstd::string get_release() const;\n\n\t// Variable functions\n\tVariableIndex add_variable(VariableDomain domain = VariableDomain::Continuous,\n\t                           double lb = -KN_INFINITY, double ub = KN_INFINITY,\n\t                           const char *name = nullptr);\n\tvoid delete_variable(const VariableIndex &variable);\n\tdouble get_variable_lb(const VariableIndex &variable) const;\n\tdouble get_variable_ub(const VariableIndex &variable) const;\n\tvoid set_variable_lb(const VariableIndex &variable, double lb);\n\tvoid set_variable_ub(const VariableIndex &variable, double ub);\n\tvoid set_variable_bounds(const VariableIndex &variable, double lb, double ub);\n\tdouble get_variable_value(const VariableIndex &variable) const;\n\tvoid set_variable_start(const VariableIndex &variable, double start);\n\tstd::string get_variable_name(const VariableIndex &variable) const;\n\tvoid set_variable_name(const VariableIndex &variable, const std::string &name);\n\tvoid set_variable_domain(const VariableIndex &variable, VariableDomain domain);\n\tVariableDomain get_variable_domain(const VariableIndex &variable) const;\n\tdouble get_variable_rc(const VariableIndex &variable) const;\n\tstd::string pprint_variable(const VariableIndex &variable) const;\n\n\t// Constraint functions\n\tConstraintIndex add_linear_constraint(const ScalarAffineFunction &f, ConstraintSense sense,\n\t                                      double rhs, const char *name = nullptr);\n\tConstraintIndex add_linear_constraint(const ScalarAffineFunction &f,\n\t                                      const std::tuple<double, double> &interval,\n\t                                      const char *name = nullptr);\n\tConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &f,\n\t                                         ConstraintSense sense, double rhs,\n\t                                         const char *name = nullptr);\n\tConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &f,\n\t                                         const std::tuple<double, double> &interval,\n\t                                         const char *name = nullptr);\n\tConstraintIndex add_second_order_cone_constraint(const Vector<VariableIndex> &variables,\n\t                                                 const char *name, bool rotated);\n\tConstraintIndex add_single_nl_constraint(ExpressionGraph &graph, const ExpressionHandle &result,\n\t                                         const std::tuple<double, double> &interval,\n\t                                         const char *name = nullptr);\n\tConstraintIndex add_single_nl_constraint_sense_rhs(ExpressionGraph &graph,\n\t                                                   const ExpressionHandle &result,\n\t                                                   ConstraintSense sense, double rhs,\n\t                                                   const char *name = nullptr);\n\tvoid delete_constraint(const ConstraintIndex &constraint);\n\tvoid set_constraint_name(const ConstraintIndex &constraint, const std::string &name);\n\tstd::string get_constraint_name(const ConstraintIndex &constraint) const;\n\tdouble get_constraint_primal(const ConstraintIndex &constraint) const;\n\tdouble get_constraint_dual(const ConstraintIndex &constraint) const;\n\tvoid set_normalized_rhs(const ConstraintIndex &constraint, double rhs);\n\tdouble get_normalized_rhs(const ConstraintIndex &constraint) const;\n\tvoid set_normalized_coefficient(const ConstraintIndex &constraint,\n\t                                const VariableIndex &variable, double coefficient);\n\n\t// Objective functions\n\tvoid set_objective(const ScalarAffineFunction &f, ObjectiveSense sense);\n\tvoid set_objective(const ScalarQuadraticFunction &f, ObjectiveSense sense);\n\tvoid set_objective(const ExprBuilder &expr, ObjectiveSense sense);\n\tvoid add_single_nl_objective(ExpressionGraph &graph, const ExpressionHandle &result);\n\tdouble get_obj_value() const;\n\tvoid set_obj_sense(ObjectiveSense sense);\n\tObjectiveSense get_obj_sense() const;\n\tvoid set_objective_coefficient(const VariableIndex &variable, double coefficient);\n\n\t// Solve functions\n\tvoid optimize();\n\n\t// Solve information\n\tsize_t get_number_iterations() const;\n\tsize_t get_mip_node_count() const;\n\tdouble get_obj_bound() const;\n\tdouble get_mip_relative_gap() const;\n\tdouble get_solve_time() const;\n\n\t// Model state\n\tbool dirty() const;\n\tbool empty() const;\n\n\t// Solve status\n\tint get_solve_status() const;\n\n\t// Parameter management\n\ttemplate <typename T>\n\tvoid set_raw_parameter(const std::string &name, T value)\n\t{\n\t\tint param_id = _get_value<const char *, int>(knitro::KN_get_param_id, name.c_str());\n\t\tset_raw_parameter<T>(param_id, value);\n\t}\n\n\ttemplate <typename T>\n\tvoid set_raw_parameter(int param_id, T value)\n\t{\n\t\tif constexpr (std::is_same_v<T, int>)\n\t\t{\n\t\t\t_set_value<int, T>(knitro::KN_set_int_param, param_id, value);\n\t\t}\n\t\telse if constexpr (std::is_same_v<T, double>)\n\t\t{\n\t\t\t_set_value<int, T>(knitro::KN_set_double_param, param_id, value);\n\t\t}\n\t\telse if constexpr (std::is_same_v<T, std::string> || std::is_same_v<T, const char *>)\n\t\t{\n\t\t\tif constexpr (std::is_same_v<T, std::string>)\n\t\t\t{\n\t\t\t\t_set_value<int, const char *>(knitro::KN_set_char_param, param_id, value.c_str());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t_set_value<int, const char *>(knitro::KN_set_char_param, param_id, value);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstatic_assert(std::is_same_v<T, int> || std::is_same_v<T, double> ||\n\t\t\t                  std::is_same_v<T, std::string> || std::is_same_v<T, const char *>,\n\t\t\t              \"T must be int, double, std::string, or const char*\");\n\t\t}\n\t}\n\n\ttemplate <typename T>\n\tT get_raw_parameter(const std::string &name)\n\t{\n\t\tint param_id = _get_value<const char *, int>(knitro::KN_get_param_id, name.c_str());\n\t\treturn get_raw_parameter<T>(param_id);\n\t}\n\n\ttemplate <typename T>\n\tT get_raw_parameter(int param_id)\n\t{\n\t\tif constexpr (std::is_same_v<T, int>)\n\t\t{\n\t\t\treturn _get_value<int, T>(knitro::KN_get_int_param, param_id);\n\t\t}\n\t\telse if constexpr (std::is_same_v<T, double>)\n\t\t{\n\t\t\treturn _get_value<int, T>(knitro::KN_get_double_param, param_id);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tstatic_assert(std::is_same_v<T, int> || std::is_same_v<T, double>,\n\t\t\t              \"T must be int or double for get_raw_parameter\");\n\t\t}\n\t}\n\n\t// Internal helpers\n\tvoid _check_error(int error) const;\n\tvoid _mark_dirty();\n\tvoid _unmark_dirty();\n\tvoid _check_dirty() const;\n\tKNINT _variable_index(const VariableIndex &variable) const;\n\tKNINT _constraint_index(const ConstraintIndex &constraint) const;\n\n\tsize_t get_num_vars() const;\n\tsize_t get_num_cons(std::optional<ConstraintType> type = std::nullopt) const;\n\n  private:\n\t// Member variables\n\tsize_t m_n_vars = 0;\n\tstd::unordered_map<ConstraintType, size_t> m_n_cons_map;\n\tstd::shared_ptr<LM_context> m_lm = nullptr;\n\tstd::unique_ptr<KN_context, KNITROFreeProblemT> m_kc = nullptr;\n\n\tstd::unordered_map<KNINT, std::variant<KNINT, std::pair<KNINT, KNINT>>> m_soc_aux_cons;\n\tstd::unordered_map<KNINT, uint8_t> m_con_sense_flags;\n\tuint8_t m_obj_flag = 0;\n\n\tstruct Outputs\n\t{\n\t\tstd::vector<size_t> objective_outputs;\n\t\tstd::vector<size_t> constraint_outputs;\n\t\tstd::vector<ConstraintIndex> constraints;\n\t};\n\n\tusing Evaluator = CallbackEvaluator<double, size_t, KNINT>;\n\n\tstd::unordered_map<ExpressionGraph *, Outputs> m_pending_outputs;\n\tstd::vector<std::unique_ptr<Evaluator>> m_evaluators;\n\tbool m_has_pending_callbacks = false;\n\tint m_solve_status = 0;\n\tbool m_is_dirty = true;\n\n  private:\n\tvoid _init();\n\tvoid _reset_state();\n\tstd::tuple<double, double> _sense_to_interval(ConstraintSense sense, double rhs);\n\tvoid _update_con_sense_flags(const ConstraintIndex &constraint, ConstraintSense sense);\n\n\tvoid _set_linear_constraint(const ConstraintIndex &constraint, const ScalarAffineFunction &f);\n\tvoid _set_quadratic_constraint(const ConstraintIndex &constraint,\n\t                               const ScalarQuadraticFunction &f);\n\tvoid _set_second_order_cone_constraint(const ConstraintIndex &constraint,\n\t                                       const Vector<VariableIndex> &variables);\n\tvoid _set_second_order_cone_constraint_rotated(const ConstraintIndex &constraint,\n\t                                               const Vector<VariableIndex> &variables);\n\tvoid _set_linear_objective(const ScalarAffineFunction &f);\n\tvoid _set_quadratic_objective(const ScalarQuadraticFunction &f);\n\tvoid _reset_objective();\n\tvoid _add_graph(ExpressionGraph &graph);\n\tvoid _add_pending_callbacks();\n\tvoid _add_callbacks(const ExpressionGraph &graph, const Outputs &outputs);\n\tvoid _add_callback(const ExpressionGraph &graph, const std::vector<size_t> &outputs,\n\t                   const std::vector<ConstraintIndex> &constraints);\n\tvoid _register_callback(Evaluator *evaluator);\n\tvoid _update();\n\tvoid _pre_solve();\n\tvoid _solve();\n\tvoid _post_solve();\n\n\ttemplate <typename F>\n\tConstraintIndex _add_constraint_impl(ConstraintType type,\n\t                                     const std::tuple<double, double> &interval,\n\t                                     const char *name, const F &setter)\n\t{\n\t\tKNINT indexCon;\n\t\tint error = knitro::KN_add_con(m_kc.get(), &indexCon);\n\t\t_check_error(error);\n\n\t\tIndexT index = indexCon;\n\t\tConstraintIndex constraint(type, index);\n\n\t\tdouble lb = std::get<0>(interval);\n\t\tdouble ub = std::get<1>(interval);\n\n\t\terror = knitro::KN_set_con_lobnd(m_kc.get(), indexCon, lb);\n\t\t_check_error(error);\n\t\terror = knitro::KN_set_con_upbnd(m_kc.get(), indexCon, ub);\n\t\t_check_error(error);\n\n\t\tsetter(constraint);\n\n\t\tif (!is_name_empty(name))\n\t\t{\n\t\t\terror = knitro::KN_set_con_name(m_kc.get(), indexCon, name);\n\t\t\t_check_error(error);\n\t\t}\n\n\t\tm_con_sense_flags[indexCon] = CON_UPBND;\n\n\t\tauto it = m_n_cons_map.find(type);\n\t\tif (it != m_n_cons_map.end())\n\t\t{\n\t\t\tit->second++;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tm_n_cons_map[type] = 1;\n\t\t}\n\n\t\tm_is_dirty = true;\n\n\t\treturn constraint;\n\t}\n\n\ttemplate <typename S, typename F>\n\tConstraintIndex _add_constraint_with_sense(const S &function, ConstraintSense sense, double rhs,\n\t                                           const char *name, const F &add)\n\t{\n\t\tauto interval = _sense_to_interval(sense, rhs);\n\t\tauto constraint = add(function, interval, name);\n\t\t_update_con_sense_flags(constraint, sense);\n\t\treturn constraint;\n\t}\n\n\ttemplate <typename F>\n\tvoid _set_objective_impl(ObjectiveSense sense, const F &setter)\n\t{\n\t\t_reset_objective();\n\t\tsetter();\n\t\tset_obj_sense(sense);\n\t\tm_is_dirty = true;\n\t}\n\n\ttemplate <typename V>\n\tusing Getter = std::function<int(KN_context *, V *)>;\n\ttemplate <typename V>\n\tusing Setter = std::function<int(KN_context *, V)>;\n\n\ttemplate <typename V>\n\tV _get_value(Getter<V> get) const\n\t{\n\t\tV value;\n\t\tint error = get(m_kc.get(), &value);\n\t\t_check_error(error);\n\t\treturn value;\n\t}\n\n\ttemplate <typename V>\n\tvoid _set_value(Setter<V> set, V value)\n\t{\n\t\tint error = set(m_kc.get(), value);\n\t\t_check_error(error);\n\t}\n\n\ttemplate <typename K, typename V>\n\tusing GetterMap = std::function<int(KN_context *, K, V *)>;\n\ttemplate <typename K, typename V>\n\tusing SetterMap = std::function<int(KN_context *, K, V)>;\n\n\ttemplate <typename K, typename V>\n\tV _get_value(GetterMap<K, V> get, K key) const\n\t{\n\t\tV value;\n\t\tint error = get(m_kc.get(), key, &value);\n\t\t_check_error(error);\n\t\treturn value;\n\t}\n\n\ttemplate <typename K, typename V>\n\tvoid _set_value(SetterMap<K, V> set, K key, V value)\n\t{\n\t\tint error = set(m_kc.get(), key, value);\n\t\t_check_error(error);\n\t}\n\n\ttemplate <typename F, typename K>\n\tstd::string _get_name(F get, K key, const char *prefix) const\n\t{\n\t\tchar name[1024];\n\t\tname[0] = '\\0';\n\t\tint error = get(m_kc.get(), key, 1024, name);\n\t\t_check_error(error);\n\n\t\tif (name[0] != '\\0')\n\t\t{\n\t\t\treturn std::string(name);\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn fmt::format(\"{}{}\", prefix, key);\n\t\t}\n\t}\n\n\ttemplate <typename I>\n\tKNINT _get_index(const I &index) const\n\t{\n\t\treturn index.index;\n\t}\n};\n"
  },
  {
    "path": "include/pyoptinterface/mosek_model.hpp",
    "content": "#pragma once\n\n#include <memory>\n\n#ifdef _MSC_VER\n#include \"solvers/mosek/mosek_win.h\"\n#else\n#include \"solvers/mosek/mosek_linux.h\"\n#endif\n\n#include \"pyoptinterface/core.hpp\"\n#include \"pyoptinterface/container.hpp\"\n#include \"pyoptinterface/solver_common.hpp\"\n#include \"pyoptinterface/dylib.hpp\"\n\n#define APILIST                        \\\n\tB(MSK_getcodedesc);                \\\n\tB(MSK_makeemptytask);              \\\n\tB(MSK_deletetask);                 \\\n\tB(MSK_writedata);                  \\\n\tB(MSK_writesolution);              \\\n\tB(MSK_appendvars);                 \\\n\tB(MSK_getnumvar);                  \\\n\tB(MSK_putvartype);                 \\\n\tB(MSK_putvarbound);                \\\n\tB(MSK_putvarname);                 \\\n\tB(MSK_removevars);                 \\\n\tB(MSK_getxxslice);                 \\\n\tB(MSK_appendcons);                 \\\n\tB(MSK_getnumcon);                  \\\n\tB(MSK_putarow);                    \\\n\tB(MSK_putconbound);                \\\n\tB(MSK_putconname);                 \\\n\tB(MSK_putqconk);                   \\\n\tB(MSK_getnumafe);                  \\\n\tB(MSK_appendafes);                 \\\n\tB(MSK_putafefentrylist);           \\\n\tB(MSK_appendquadraticconedomain);  \\\n\tB(MSK_appendrquadraticconedomain); \\\n\tB(MSK_appendprimalexpconedomain);  \\\n\tB(MSK_appenddualexpconedomain);    \\\n\tB(MSK_appendacc);                  \\\n\tB(MSK_putaccname);                 \\\n\tB(MSK_getaccn);                    \\\n\tB(MSK_getaccafeidxlist);           \\\n\tB(MSK_appendrdomain);              \\\n\tB(MSK_putacc);                     \\\n\tB(MSK_removecons);                 \\\n\tB(MSK_putqobj);                    \\\n\tB(MSK_putcslice);                  \\\n\tB(MSK_putcfix);                    \\\n\tB(MSK_optimize);                   \\\n\tB(MSK_whichparam);                 \\\n\tB(MSK_putnaintparam);              \\\n\tB(MSK_putnadouparam);              \\\n\tB(MSK_putnastrparam);              \\\n\tB(MSK_getnaintparam);              \\\n\tB(MSK_getnadouparam);              \\\n\tB(MSK_getnastrparam);              \\\n\tB(MSK_getnaintinf);                \\\n\tB(MSK_getnadouinf);                \\\n\tB(MSK_getprosta);                  \\\n\tB(MSK_getsolsta);                  \\\n\tB(MSK_getprimalobj);               \\\n\tB(MSK_getdualobj);                 \\\n\tB(MSK_linkfunctotaskstream);       \\\n\tB(MSK_getvarname);                 \\\n\tB(MSK_getvartype);                 \\\n\tB(MSK_getvarbound);                \\\n\tB(MSK_putxxslice);                 \\\n\tB(MSK_getxcslice);                 \\\n\tB(MSK_getyslice);                  \\\n\tB(MSK_getslxslice);                \\\n\tB(MSK_getsuxslice);                \\\n\tB(MSK_getconnamelen);              \\\n\tB(MSK_getconname);                 \\\n\tB(MSK_getobjsense);                \\\n\tB(MSK_putobjsense);                \\\n\tB(MSK_getconbound);                \\\n\tB(MSK_getaij);                     \\\n\tB(MSK_putaij);                     \\\n\tB(MSK_getcj);                      \\\n\tB(MSK_putcj);                      \\\n\tB(MSK_getversion);                 \\\n\tB(MSK_solutiondef);                \\\n\tB(MSK_makeenv);                    \\\n\tB(MSK_deleteenv);                  \\\n\tB(MSK_putlicensecode);\n\nnamespace mosek\n{\n#define B(f) extern decltype(&::f) f\n\nAPILIST\n\n#undef B\n\nbool is_library_loaded();\n\nbool load_library(const std::string &path);\n} // namespace mosek\n\nclass MOSEKEnv\n{\n  public:\n\tMOSEKEnv();\n\t~MOSEKEnv();\n\tvoid close();\n\n\tvoid putlicensecode(const std::vector<MSKint32t> &code);\n\n  private:\n\tMSKenv_t m_env;\n\n\tfriend class MOSEKModel;\n};\n\nstruct MOSEKfreemodelT\n{\n\tvoid operator()(MSKtask *model) const\n\t{\n\t\tmosek::MSK_deletetask(&model);\n\t};\n};\n\nusing MOSEKLoggingCallback = std::function<void(const char *)>;\n\nstruct MOSEKLoggingCallbackUserdata\n{\n\tMOSEKLoggingCallback callback;\n};\n\nclass MOSEKModel : public OnesideLinearConstraintMixin<MOSEKModel>,\n                   public TwosideLinearConstraintMixin<MOSEKModel>,\n                   public OnesideQuadraticConstraintMixin<MOSEKModel>,\n                   public LinearObjectiveMixin<MOSEKModel>,\n                   public PPrintMixin<MOSEKModel>,\n                   public GetValueMixin<MOSEKModel>\n{\n  public:\n\tbool m_is_dirty = true;\n\tMOSEKModel() = default;\n\tMOSEKModel(const MOSEKEnv &env);\n\tvoid init(const MOSEKEnv &env);\n\tvoid close();\n\n\tvoid write(const std::string &filename);\n\n\tVariableIndex add_variable(VariableDomain domain = VariableDomain::Continuous,\n\t                           double lb = -MSK_INFINITY, double ub = MSK_INFINITY,\n\t                           const char *name = nullptr);\n\t/*VariableIndex add_variables(int N, VariableDomain domain = VariableDomain::Continuous,\n\t                            double lb = -MSK_INFINITY, double ub = MSK_INFINITY);*/\n\tvoid delete_variable(const VariableIndex &variable);\n\tvoid delete_variables(const Vector<VariableIndex> &variables);\n\tbool is_variable_active(const VariableIndex &variable);\n\tdouble get_variable_value(const VariableIndex &variable);\n\tstd::string pprint_variable(const VariableIndex &variable);\n\tvoid set_variable_bounds(const VariableIndex &variable, double lb, double ub);\n\n\tConstraintIndex add_linear_constraint(const ScalarAffineFunction &function,\n\t                                      ConstraintSense sense, CoeffT rhs,\n\t                                      const char *name = nullptr);\n\tConstraintIndex add_linear_constraint(const ScalarAffineFunction &function,\n\t                                      const std::tuple<double, double> &interval,\n\t                                      const char *name = nullptr);\n\tConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &function,\n\t                                         ConstraintSense sense, CoeffT rhs,\n\t                                         const char *name = nullptr);\n\n\tstd::vector<MSKint64t> add_variables_as_afe(const Vector<VariableIndex> &variables);\n\tConstraintIndex add_variables_in_cone_constraint(const Vector<VariableIndex> &variables,\n\t                                                 MSKint64t domain_index, ConstraintType type,\n\t                                                 const char *name);\n\n\tConstraintIndex add_second_order_cone_constraint(const Vector<VariableIndex> &variables,\n\t                                                 const char *name, bool rotated = false);\n\n\tConstraintIndex add_exp_cone_constraint(const Vector<VariableIndex> &variables,\n\t                                        const char *name, bool dual = false);\n\n\tvoid delete_constraint(const ConstraintIndex &constraint);\n\tbool is_constraint_active(const ConstraintIndex &constraint);\n\n\tvoid _set_affine_objective(const ScalarAffineFunction &function, ObjectiveSense sense,\n\t                           bool clear_quadratic);\n\tvoid set_objective(const ScalarAffineFunction &function, ObjectiveSense sense);\n\tvoid set_objective(const ScalarQuadraticFunction &function, ObjectiveSense sense);\n\tvoid set_objective(const ExprBuilder &function, ObjectiveSense sense);\n\n\tint optimize();\n\tvoid *get_raw_model();\n\tstd::string version_string();\n\n\t// solution\n\tMSKsoltypee get_current_solution();\n\tstd::optional<MSKsoltypee> select_available_solution_after_optimization();\n\n\t// parameter\n\tint raw_parameter_type(const char *name);\n\n\tvoid set_raw_parameter_int(const char *param_name, int value);\n\tvoid set_raw_parameter_double(const char *param_name, double value);\n\tvoid set_raw_parameter_string(const char *param_name, const char *value);\n\tint get_raw_parameter_int(const char *param_name);\n\tdouble get_raw_parameter_double(const char *param_name);\n\tstd::string get_raw_parameter_string(const char *param_name);\n\n\t// information\n\tint get_raw_information_int(const char *attr_name);\n\tdouble get_raw_information_double(const char *attr_name);\n\n\tMSKint32t getnumvar();\n\tMSKint32t getnumcon();\n\tint getprosta();\n\tint getsolsta();\n\tdouble getprimalobj();\n\tdouble getdualobj();\n\n\tvoid disable_log();\n\n\t// Accessing information of problem\n\tstd::string get_variable_name(const VariableIndex &variable);\n\tvoid set_variable_name(const VariableIndex &variable, const char *name);\n\tVariableDomain get_variable_type(const VariableIndex &variable);\n\tvoid set_variable_type(const VariableIndex &variable, VariableDomain domain);\n\tdouble get_variable_lower_bound(const VariableIndex &variable);\n\tdouble get_variable_upper_bound(const VariableIndex &variable);\n\tvoid set_variable_lower_bound(const VariableIndex &variable, double lb);\n\tvoid set_variable_upper_bound(const VariableIndex &variable, double ub);\n\tvoid set_variable_primal(const VariableIndex &variable, double primal);\n\n\t// reduced cost of variable\n\tdouble get_variable_dual(const VariableIndex &variable);\n\n\tdouble get_constraint_primal(const ConstraintIndex &constraint);\n\tdouble get_constraint_dual(const ConstraintIndex &constraint);\n\tstd::string get_constraint_name(const ConstraintIndex &constraint);\n\tvoid set_constraint_name(const ConstraintIndex &constraint, const char *name);\n\n\tObjectiveSense get_obj_sense();\n\tvoid set_obj_sense(ObjectiveSense sense);\n\n\t// Modifications of model\n\t// 1. set/get RHS of a constraint\n\tdouble get_normalized_rhs(const ConstraintIndex &constraint);\n\tvoid set_normalized_rhs(const ConstraintIndex &constraint, double value);\n\t// 2. set/get coefficient of variable in constraint\n\tdouble get_normalized_coefficient(const ConstraintIndex &constraint,\n\t                                  const VariableIndex &variable);\n\tvoid set_normalized_coefficient(const ConstraintIndex &constraint,\n\t                                const VariableIndex &variable, double value);\n\t// 3. set/get linear coefficient of variable in objective\n\tdouble get_objective_coefficient(const VariableIndex &variable);\n\tvoid set_objective_coefficient(const VariableIndex &variable, double value);\n\n\tMSKint32t _variable_index(const VariableIndex &variable);\n\tMSKint32t _checked_variable_index(const VariableIndex &variable);\n\tMSKint32t _constraint_index(const ConstraintIndex &constraint);\n\tMSKint32t _checked_constraint_index(const ConstraintIndex &constraint);\n\n\t// Control logging\n\tvoid set_logging(const MOSEKLoggingCallback &callback);\n\n\tMOSEKLoggingCallbackUserdata m_logging_callback_userdata;\n\n  private:\n\tMonotoneIndexer<MSKint32t> m_variable_index;\n\n\tMonotoneIndexer<MSKint32t> m_linear_quadratic_constraint_index;\n\n\t// ACC cannot be removed from the model, so we just keeps track of the state whether it is\n\t// deleted If a constraint is deleted, we will not remove it from the model, but just mark it as\n\t// deleted and set the domain to R^n (i.e. no constraint)\n\tstd::vector<bool> m_acc_index;\n\n\t// Mosek does not discriminate between integer variable and binary variable\n\t// So we need to keep track of binary variables\n\tHashset<IndexT> binary_variables;\n\n\t// Cache current available solution after optimization\n\tstd::optional<MSKsoltypee> m_soltype;\n\n\t/* MOSEK part */\n\tstd::unique_ptr<MSKtask, MOSEKfreemodelT> m_model;\n};\n"
  },
  {
    "path": "include/pyoptinterface/nleval.hpp",
    "content": "#pragma once\n\n#include <cstdint>\n#include <vector>\n\n#include \"pyoptinterface/core.hpp\"\n#include \"pyoptinterface/nlexpr.hpp\"\n\nenum class HessianSparsityType\n{\n\tUpper,\n\tLower\n};\n\nstruct AutodiffSymbolicStructure\n{\n\tsize_t nx = 0, np = 0, ny = 0;\n\n\tstd::vector<size_t> m_jacobian_rows, m_jacobian_cols;\n\tsize_t m_jacobian_nnz = 0;\n\tstd::vector<size_t> m_hessian_rows, m_hessian_cols;\n\tsize_t m_hessian_nnz = 0;\n\n\tbool has_parameter = false;\n\tbool has_jacobian = false;\n\tbool has_hessian = false;\n};\n\n// define the jit-compiled function pointer\nusing f_funcptr = void (*)(const double *x, const double *p, double *y, const int *xi);\nusing jacobian_funcptr = void (*)(const double *x, const double *p, double *jacobian,\n                                  const int *xi);\nusing additive_grad_funcptr = void (*)(const double *x, const double *p, double *grad,\n                                       const int *xi, const int *gradi);\nusing hessian_funcptr = void (*)(const double *x, const double *p, const double *w, double *hessian,\n                                 const int *xi, const int *hessiani);\n\n// no parameter version\nusing f_funcptr_noparam = void (*)(const double *x, double *y, const int *xi);\nusing jacobian_funcptr_noparam = void (*)(const double *x, double *jacobian, const int *xi);\nusing additive_grad_funcptr_noparam = void (*)(const double *x, double *grad, const int *xi,\n                                               const int *gradi);\nusing hessian_funcptr_noparam = void (*)(const double *x, const double *w, double *hessian,\n                                         const int *xi, const int *hessiani);\n\nstruct ConstraintAutodiffEvaluator\n{\n\tunion {\n\t\tf_funcptr p = nullptr;\n\t\tf_funcptr_noparam nop;\n\t} f_eval;\n\tunion {\n\t\tjacobian_funcptr p = nullptr;\n\t\tjacobian_funcptr_noparam nop;\n\t} jacobian_eval;\n\tunion {\n\t\thessian_funcptr p = nullptr;\n\t\thessian_funcptr_noparam nop;\n\t} hessian_eval;\n\n\tConstraintAutodiffEvaluator() = default;\n\n\tConstraintAutodiffEvaluator(bool has_parameter, uintptr_t fp, uintptr_t jp, uintptr_t hp);\n};\n\nstruct ObjectiveAutodiffEvaluator\n{\n\tunion {\n\t\tf_funcptr p = nullptr;\n\t\tf_funcptr_noparam nop;\n\t} f_eval;\n\tunion {\n\t\tadditive_grad_funcptr p = nullptr;\n\t\tadditive_grad_funcptr_noparam nop;\n\t} grad_eval;\n\tunion {\n\t\thessian_funcptr p = nullptr;\n\t\thessian_funcptr_noparam nop;\n\t} hessian_eval;\n\n\tObjectiveAutodiffEvaluator() = default;\n\n\tObjectiveAutodiffEvaluator(bool has_parameter, uintptr_t fp, uintptr_t ajp, uintptr_t hp);\n};\n\n#define restrict __restrict\n\nstruct LinearEvaluator\n{\n\tint n_constraints = 0;\n\n\tstd::vector<double> coefs;\n\tstd::vector<int> indices;\n\n\tstd::vector<double> constant_values;\n\tstd::vector<int> constant_indices;\n\n\tstd::vector<int> constraint_intervals = {0};\n\n\tvoid add_row(const ScalarAffineFunction &f);\n\n\tvoid eval_function(const double *restrict x, double *restrict f);\n\tvoid analyze_jacobian_structure(size_t &global_jacobian_nnz,\n\t                                std::vector<int> &global_jacobian_rows,\n\t                                std::vector<int> &global_jacobian_cols) const;\n\tvoid eval_jacobian(const double *restrict x, double *restrict jacobian) const;\n};\n\nstruct QuadraticEvaluator\n{\n\tint n_constraints = 0;\n\n\tstd::vector<double> diag_coefs;\n\tstd::vector<int> diag_indices;\n\tstd::vector<int> diag_intervals = {0};\n\n\tstd::vector<double> offdiag_coefs;\n\tstd::vector<int> offdiag_rows;\n\tstd::vector<int> offdiag_cols;\n\tstd::vector<int> offdiag_intervals = {0};\n\n\tstd::vector<double> linear_coefs;\n\tstd::vector<int> linear_indices;\n\tstd::vector<int> linear_intervals = {0};\n\n\tstd::vector<double> linear_constant_values;\n\tstd::vector<int> linear_constant_indices;\n\n\tint jacobian_nnz = 0;\n\n\t// This is the constant part\n\t// jacobian_constant.size() = jacobian_nnz\n\tstd::vector<double> jacobian_constant;\n\tstd::vector<int> jacobian_variable_indices;\n\tstd::vector<int> jacobian_constraint_intervals = {0};\n\t// jacobian_diag_indices.size() = diag_indices.size()\n\tstd::vector<int> jacobian_diag_indices;\n\t// jacobian_offdiag_row_indices.size() = offdiag_rows.size()\n\tstd::vector<int> jacobian_offdiag_row_indices;\n\tstd::vector<int> jacobian_offdiag_col_indices;\n\n\t// Hessian\n\t// = diag_coefs.size()\n\tstd::vector<int> hessian_diag_indices;\n\t// = offdiag_coefs.size()\n\tstd::vector<int> hessian_offdiag_indices;\n\n\tvoid add_row(const ScalarQuadraticFunction &f);\n\n\tvoid eval_function(const double *restrict x, double *restrict f) const;\n\tvoid analyze_jacobian_structure(size_t row_base, size_t &global_jacobian_nnz,\n\t                                std::vector<int> &global_jacobian_rows,\n\t                                std::vector<int> &global_jacobian_cols) const;\n\tvoid eval_jacobian(const double *restrict x, double *restrict jacobian) const;\n\tvoid analyze_hessian_structure(size_t &global_hessian_nnz,\n\t                               std::vector<int> &global_hessian_rows,\n\t                               std::vector<int> &global_hessian_cols,\n\t                               Hashmap<std::tuple<int, int>, int> &hessian_index_map,\n\t                               HessianSparsityType hessian_type);\n\tvoid eval_lagrangian_hessian(const double *restrict lambda, double *restrict hessian) const;\n};\n\nstruct NonlinearEvaluator\n{\n\t// How many graph instances are there\n\tsize_t n_graph_instances = 0;\n\t// record the inputs of graph instances\n\tstruct GraphInput\n\t{\n\t\tstd::vector<int> variables;\n\t\tstd::vector<double> constants;\n\t};\n\tstd::vector<GraphInput> graph_inputs;\n\t// record graph instances with constraint output and objective output\n\tstruct GraphHash\n\t{\n\t\t// hash of this graph instance\n\t\tuint64_t hash;\n\t\t// index of this graph instance\n\t\tint index;\n\t};\n\tstruct GraphHashes\n\t{\n\t\tstd::vector<GraphHash> hashes;\n\t\tsize_t n_hashes_since_last_aggregation = 0;\n\t} constraint_graph_hashes, objective_graph_hashes;\n\n\t// length = n_graph_instances\n\t// record which group this graph instance belongs to\n\tstruct GraphGroupMembership\n\t{\n\t\t// which group it belongs to\n\t\tint group;\n\t\t// the rank in that group\n\t\tint rank;\n\t};\n\tstd::vector<GraphGroupMembership> constraint_group_memberships, objective_group_memberships;\n\t// record which index of constraint this graph starts\n\tstd::vector<int> constraint_indices_offsets;\n\n\t// graph groups\n\tstruct ConstraintGraphGroup\n\t{\n\t\tstd::vector<int> instance_indices;\n\t\tAutodiffSymbolicStructure autodiff_structure;\n\t\tConstraintAutodiffEvaluator autodiff_evaluator;\n\n\t\t// where to store the hessian matrix\n\t\t// length = instance_indices.size() * hessian_nnz\n\t\tstd::vector<int> hessian_indices;\n\t};\n\tstd::vector<ConstraintGraphGroup> constraint_groups;\n\tHashmap<uint64_t, int> hash_to_constraint_group;\n\n\tstruct ObjectiveGraphGroup\n\t{\n\t\tstd::vector<int> instance_indices;\n\t\tAutodiffSymbolicStructure autodiff_structure;\n\t\tObjectiveAutodiffEvaluator autodiff_evaluator;\n\t\t// where to store the gradient vector\n\t\t// length = instance_indices.size() * jacobian_nnz\n\t\tstd::vector<int> gradient_indices;\n\t\t// where to store the hessian matrix\n\t\t// length = instance_indices.size() * hessian_nnz\n\t\tstd::vector<int> hessian_indices;\n\t};\n\tstd::vector<ObjectiveGraphGroup> objective_groups;\n\tHashmap<uint64_t, int> hash_to_objective_group;\n\n\tint add_graph_instance();\n\tvoid finalize_graph_instance(size_t graph_index, const ExpressionGraph &graph);\n\tint aggregate_constraint_groups();\n\tint get_constraint_group_representative(int group_index) const;\n\tint aggregate_objective_groups();\n\tint get_objective_group_representative(int group_index) const;\n\n\tvoid assign_constraint_group_autodiff_structure(int group_index,\n\t                                                const AutodiffSymbolicStructure &structure);\n\tvoid assign_constraint_group_autodiff_evaluator(int group_index,\n\t                                                const ConstraintAutodiffEvaluator &evaluator);\n\tvoid assign_objective_group_autodiff_structure(int group_index,\n\t                                               const AutodiffSymbolicStructure &structure);\n\tvoid assign_objective_group_autodiff_evaluator(int group_index,\n\t                                               const ObjectiveAutodiffEvaluator &evaluator);\n\n\tvoid calculate_constraint_graph_instances_offset();\n\n\t// functions to evaluate the nonlinear constraints and objectives\n\n\t// f\n\tvoid eval_constraints(const double *restrict x, double *restrict f) const;\n\tdouble eval_objective(const double *restrict x) const;\n\n\t// first order derivative\n\tvoid analyze_constraints_jacobian_structure(size_t row_base, size_t &global_jacobian_nnz,\n\t                                            std::vector<int> &global_jacobian_rows,\n\t                                            std::vector<int> &global_jacobian_cols);\n\tvoid analyze_objective_gradient_structure(std::vector<int> &global_gradient_cols,\n\t                                          Hashmap<int, int> &sparse_gradient_map);\n\n\tvoid eval_constraints_jacobian(const double *restrict x, double *restrict jacobian) const;\n\tvoid eval_objective_gradient(const double *restrict x, double *restrict grad_f) const;\n\n\t// second order derivative\n\tvoid analyze_constraints_hessian_structure(\n\t    size_t &global_hessian_nnz, std::vector<int> &global_hessian_rows,\n\t    std::vector<int> &global_hessian_cols,\n\t    Hashmap<std::tuple<int, int>, int> &hessian_index_map, HessianSparsityType hessian_type);\n\tvoid analyze_objective_hessian_structure(size_t &global_hessian_nnz,\n\t                                         std::vector<int> &global_hessian_rows,\n\t                                         std::vector<int> &global_hessian_cols,\n\t                                         Hashmap<std::tuple<int, int>, int> &hessian_index_map,\n\t                                         HessianSparsityType hessian_type);\n\n\tvoid eval_lagrangian_hessian(const double *restrict x, const double *restrict lambda,\n\t                             const double sigma, double *restrict hessian) const;\n};"
  },
  {
    "path": "include/pyoptinterface/nlexpr.hpp",
    "content": "#pragma once\n\n#include <cstdint>\n#include <vector>\n\n#include \"ankerl/unordered_dense.h\"\n#include \"core.hpp\"\n\nusing NodeId = uint32_t;\nusing EntityId = int;\n\nusing VariableNode = EntityId;\nusing ConstantNode = double;\nusing ParameterNode = EntityId;\n\nenum class ArrayType\n{\n\tConstant,\n\tVariable,\n\tParameter,\n\tUnary,\n\tBinary,\n\tTernary,\n\tNary\n};\n\nenum class UnaryOperator\n{\n\tNeg,\n\tSin,\n\tCos,\n\tTan,\n\tAsin,\n\tAcos,\n\tAtan,\n\tAbs,\n\tSqrt,\n\tExp,\n\tLog,\n\tLog10\n};\n\nenum class BinaryOperator\n{\n\tSub,\n\tDiv,\n\tPow,\n\n\t// compare\n\tLessThan,\n\tLessEqual,\n\tEqual,\n\tNotEqual,\n\tGreaterEqual,\n\tGreaterThan,\n\n\t// Compatibility issue where some solvers only accepts two-arg multiplication\n\tAdd2,\n\tMul2\n};\n\nbool is_binary_compare_op(BinaryOperator op);\n\nenum class TernaryOperator\n{\n\tIfThenElse,\n};\n\nenum class NaryOperator\n{\n\tAdd,\n\tMul,\n};\n\nstd::string unary_operator_to_string(UnaryOperator op);\nstd::string binary_operator_to_string(BinaryOperator op);\nstd::string ternary_operator_to_string(TernaryOperator op);\nstd::string nary_operator_to_string(NaryOperator op);\n\nstruct ExpressionHandle\n{\n\tArrayType array;\n\tNodeId id;\n\n\tbool operator==(const ExpressionHandle &x) const;\n\n\tExpressionHandle() = default;\n\tExpressionHandle(ArrayType array, NodeId id) : array(array), id(id)\n\t{\n\t}\n\n\tstd::string to_string() const;\n};\n\ntemplate <>\nstruct ankerl::unordered_dense::hash<ExpressionHandle>\n{\n\tusing is_avalanching = void;\n\n\t[[nodiscard]] auto operator()(ExpressionHandle const &x) const noexcept -> uint64_t\n\t{\n\t\tstatic_assert(std::has_unique_object_representations_v<ExpressionHandle>);\n\t\treturn detail::wyhash::hash(&x, sizeof(x));\n\t}\n};\n\nstruct UnaryNode\n{\n\tUnaryOperator op;\n\tExpressionHandle operand;\n\n\tUnaryNode(UnaryOperator op, ExpressionHandle operand) : op(op), operand(operand)\n\t{\n\t}\n};\n\nstruct BinaryNode\n{\n\tBinaryOperator op;\n\tExpressionHandle left;\n\tExpressionHandle right;\n\n\tBinaryNode(BinaryOperator op, ExpressionHandle left, ExpressionHandle right)\n\t    : op(op), left(left), right(right)\n\t{\n\t}\n};\n\nstruct TernaryNode\n{\n\tTernaryOperator op;\n\tExpressionHandle left;\n\tExpressionHandle middle;\n\tExpressionHandle right;\n\n\tTernaryNode(TernaryOperator op, ExpressionHandle left, ExpressionHandle middle,\n\t            ExpressionHandle right)\n\t    : op(op), left(left), middle(middle), right(right)\n\t{\n\t}\n};\n\nstruct NaryNode\n{\n\tNaryOperator op;\n\tstd::vector<ExpressionHandle> operands;\n\n\tNaryNode(NaryOperator op, const std::vector<ExpressionHandle> &operands)\n\t    : op(op), operands(operands)\n\t{\n\t}\n};\n\nstruct ExpressionGraph\n{\n\tHashmap<EntityId, size_t> m_variable_index_map;\n\tstd::vector<VariableNode> m_variables;\n\tstd::vector<ConstantNode> m_constants;\n\tstd::vector<ParameterNode> m_parameters;\n\tstd::vector<UnaryNode> m_unaries;\n\tstd::vector<BinaryNode> m_binaries;\n\tstd::vector<TernaryNode> m_ternaries;\n\tstd::vector<NaryNode> m_naries;\n\n\tstd::vector<ExpressionHandle> m_constraint_outputs;\n\tstd::vector<ExpressionHandle> m_objective_outputs;\n\n\tExpressionGraph() = default;\n\n\tstd::string to_string() const;\n\n\tsize_t n_variables() const;\n\tsize_t n_constants() const;\n\tsize_t n_parameters() const;\n\n\tExpressionHandle add_variable(EntityId id);\n\n\tExpressionHandle add_constant(double value);\n\n\tExpressionHandle add_parameter(EntityId id);\n\n\tExpressionHandle add_unary(UnaryOperator op, ExpressionHandle operand);\n\n\tExpressionHandle add_binary(BinaryOperator op, ExpressionHandle left, ExpressionHandle right);\n\n\tExpressionHandle add_ternary(TernaryOperator op, ExpressionHandle left, ExpressionHandle middle,\n\t                             ExpressionHandle right);\n\n\tExpressionHandle add_nary(NaryOperator op, const std::vector<ExpressionHandle> &operands);\n\tExpressionHandle add_repeat_nary(NaryOperator op, ExpressionHandle operand, int N);\n\n\tvoid append_nary(const ExpressionHandle &expression, const ExpressionHandle &operand);\n\n\tNaryOperator get_nary_operator(const ExpressionHandle &expression) const;\n\n\tvoid add_constraint_output(const ExpressionHandle &expression);\n\tvoid add_objective_output(const ExpressionHandle &expression);\n\tbool has_constraint_output() const;\n\tbool has_objective_output() const;\n\n\t// Merge VariableIndex/ScalarAffineFunction/ScalarQuadraticFunction/ExprBuilder into\n\t// ExpressionGraph\n\tExpressionHandle merge_variableindex(const VariableIndex &v);\n\tExpressionHandle merge_scalaraffinefunction(const ScalarAffineFunction &f);\n\tExpressionHandle merge_scalarquadraticfunction(const ScalarQuadraticFunction &f);\n\tExpressionHandle merge_exprbuilder(const ExprBuilder &expr);\n\n\t// recognize compare expression\n\tbool is_compare_expression(const ExpressionHandle &expr) const;\n\n\t// tag the structure\n\tuint64_t main_structure_hash() const;\n\tuint64_t constraint_structure_hash(uint64_t hash) const;\n\tuint64_t objective_structure_hash(uint64_t hash) const;\n};\n\nvoid unpack_comparison_expression(ExpressionGraph &graph, const ExpressionHandle &expr,\n                                  ExpressionHandle &real_expr, double &lb, double &ub);\n"
  },
  {
    "path": "include/pyoptinterface/solver_common.hpp",
    "content": "#pragma once\n\n#include <algorithm>\n#include <string>\n#include <concepts>\n#include <tuple>\n#include <numeric>\n#include \"fmt/format.h\"\n#include \"fmt/ranges.h\"\n#include \"pyoptinterface/core.hpp\"\n\ntemplate <typename T>\nconcept OnesideLinearConstraintMixinConcept = requires(T &model) {\n\t{\n\t\tmodel.add_linear_constraint(ScalarAffineFunction(), ConstraintSense::Equal, 0.0, \"\")\n\t} -> std::same_as<ConstraintIndex>;\n};\n\ntemplate <typename T>\nclass OnesideLinearConstraintMixin\n{\n  private:\n\tT *get_base()\n\t{\n\t\tstatic_assert(OnesideLinearConstraintMixinConcept<T>);\n\t\treturn static_cast<T *>(this);\n\t}\n\n  public:\n\tConstraintIndex add_linear_constraint_from_var(const VariableIndex &variable,\n\t                                               ConstraintSense sense, CoeffT rhs,\n\t                                               const char *name = nullptr)\n\t{\n\t\tScalarAffineFunction f(variable);\n\t\treturn get_base()->add_linear_constraint(f, sense, rhs, name);\n\t}\n\tConstraintIndex add_linear_constraint_from_expr(const ExprBuilder &function,\n\t                                                ConstraintSense sense, CoeffT rhs,\n\t                                                const char *name = nullptr)\n\t{\n\t\tif (function.degree() >= 2)\n\t\t{\n\t\t\tthrow std::runtime_error(\"add_linear_constraint expects linear expression but receives \"\n\t\t\t                         \"a quadratic expression.\");\n\t\t}\n\t\tScalarAffineFunction f(function);\n\t\treturn get_base()->add_linear_constraint(f, sense, rhs, name);\n\t}\n};\n\ntemplate <typename T>\nconcept TwosideLinearConstraintMixinConcept = requires(T &model) {\n\t{\n\t\tmodel.add_linear_constraint(ScalarAffineFunction(), std::make_tuple(0.0, 1.0), \"\")\n\t} -> std::same_as<ConstraintIndex>;\n};\n\ntemplate <typename T>\nclass TwosideLinearConstraintMixin\n{\n  private:\n\tT *get_base()\n\t{\n\t\tstatic_assert(TwosideLinearConstraintMixinConcept<T>);\n\t\treturn static_cast<T *>(this);\n\t}\n\n  public:\n\tConstraintIndex add_linear_interval_constraint_from_var(\n\t    const VariableIndex &variable, const std::tuple<double, double> &interval,\n\t    const char *name = nullptr)\n\t{\n\t\tScalarAffineFunction f(variable);\n\t\treturn get_base()->add_linear_constraint(f, interval, name);\n\t}\n\tConstraintIndex add_linear_interval_constraint_from_expr(\n\t    const ExprBuilder &function, const std::tuple<double, double> &interval,\n\t    const char *name = nullptr)\n\t{\n\t\tScalarAffineFunction f(function);\n\t\treturn get_base()->add_linear_constraint(f, interval, name);\n\t}\n};\n\ntemplate <typename T>\nconcept OnesideQuadraticConstraintMixinConcept = requires(T &model) {\n\t{\n\t\tmodel.add_quadratic_constraint(ScalarQuadraticFunction(), ConstraintSense::Equal, 0.0, \"\")\n\t} -> std::same_as<ConstraintIndex>;\n};\n\ntemplate <typename T>\nclass OnesideQuadraticConstraintMixin\n{\n  private:\n\tT *get_base()\n\t{\n\t\tstatic_assert(OnesideQuadraticConstraintMixinConcept<T>);\n\t\treturn static_cast<T *>(this);\n\t}\n\n  public:\n\tConstraintIndex add_quadratic_constraint_from_var(const VariableIndex &variable,\n\t                                                  ConstraintSense sense, CoeffT rhs,\n\t                                                  const char *name = nullptr)\n\t{\n\t\tScalarQuadraticFunction f(variable);\n\t\treturn get_base()->add_quadratic_constraint(f, sense, rhs, name);\n\t}\n\tConstraintIndex add_quadratic_constraint_from_saf(const ScalarAffineFunction &function,\n\t                                                  ConstraintSense sense, CoeffT rhs,\n\t                                                  const char *name = nullptr)\n\t{\n\t\tScalarQuadraticFunction f(function);\n\t\treturn get_base()->add_quadratic_constraint(f, sense, rhs, name);\n\t}\n\tConstraintIndex add_quadratic_constraint_from_expr(const ExprBuilder &function,\n\t                                                   ConstraintSense sense, CoeffT rhs,\n\t                                                   const char *name = nullptr)\n\t{\n\t\tScalarQuadraticFunction f(function);\n\t\treturn get_base()->add_quadratic_constraint(f, sense, rhs, name);\n\t}\n};\n\ntemplate <typename T>\nconcept TwosideQuadraticConstraintMixinConcept = requires(T &model) {\n\t{\n\t\tmodel.add_quadratic_constraint(ScalarQuadraticFunction(), std::make_tuple(0.0, 1.0), \"\")\n\t} -> std::same_as<ConstraintIndex>;\n};\n\ntemplate <typename T>\nclass TwosideQuadraticConstraintMixin\n{\n  private:\n\tT *get_base()\n\t{\n\t\tstatic_assert(TwosideQuadraticConstraintMixinConcept<T>);\n\t\treturn static_cast<T *>(this);\n\t}\n\n  public:\n\tConstraintIndex add_quadratic_interval_constraint_from_var(\n\t    const VariableIndex &variable, const std::tuple<double, double> &interval,\n\t    const char *name = nullptr)\n\t{\n\t\tScalarQuadraticFunction f(variable);\n\t\treturn get_base()->add_quadratic_constraint(f, interval, name);\n\t}\n\tConstraintIndex add_quadratic_interval_constraint_from_expr(\n\t    const ExprBuilder &function, const std::tuple<double, double> &interval,\n\t    const char *name = nullptr)\n\t{\n\t\tScalarQuadraticFunction f(function);\n\t\treturn get_base()->add_quadratic_constraint(f, interval, name);\n\t}\n};\n\n#ifdef USE_NLMIXIN\n#include \"pyoptinterface/nlexpr.hpp\"\n\ntemplate <typename T>\nconcept TwosideNLConstraintMixinConcept = requires(T &model) {\n\t{\n\t\tmodel.add_single_nl_constraint(std::declval<ExpressionGraph &>(), ExpressionHandle(),\n\t\t                               std::make_tuple(0.0, 1.0), \"\")\n\t} -> std::same_as<ConstraintIndex>;\n\t{ model.get_infinity() } -> std::convertible_to<double>;\n};\n\ntemplate <typename T>\nclass TwosideNLConstraintMixin\n{\n  private:\n\tT *get_base()\n\t{\n\t\tstatic_assert(TwosideNLConstraintMixinConcept<T>);\n\t\treturn static_cast<T *>(this);\n\t}\n\n  public:\n\tConstraintIndex add_single_nl_constraint_sense_rhs(ExpressionGraph &graph,\n\t                                                   const ExpressionHandle &result,\n\t                                                   ConstraintSense sense, CoeffT rhs,\n\t                                                   const char *name = nullptr)\n\t{\n\t\tdouble infinity = get_base()->get_infinity();\n\n\t\tdouble lb, ub;\n\n\t\tif (sense == ConstraintSense::Equal)\n\t\t{\n\t\t\tlb = rhs;\n\t\t\tub = rhs;\n\t\t}\n\t\telse if (sense == ConstraintSense::LessEqual)\n\t\t{\n\t\t\tlb = -infinity;\n\t\t\tub = rhs;\n\t\t}\n\t\telse if (sense == ConstraintSense::GreaterEqual)\n\t\t{\n\t\t\tlb = rhs;\n\t\t\tub = infinity;\n\t\t}\n\n\t\treturn get_base()->add_single_nl_constraint(graph, result, {lb, ub}, name);\n\t}\n\n\tConstraintIndex add_single_nl_constraint_from_comparison(ExpressionGraph &graph,\n\t                                                         const ExpressionHandle &expr,\n\t                                                         const char *name)\n\t{\n\t\tExpressionHandle real_expr;\n\t\tdouble lb = -get_base()->get_infinity(), ub = get_base()->get_infinity();\n\t\tunpack_comparison_expression(graph, expr, real_expr, lb, ub);\n\t\tauto constraint = get_base()->add_single_nl_constraint(graph, real_expr, {lb, ub}, name);\n\t\treturn constraint;\n\t}\n};\n#endif\n\ntemplate <typename T>\nconcept GetValueMixinConcept = requires(T &model) {\n\t{ model.get_variable_value(VariableIndex()) } -> std::convertible_to<double>;\n};\n\ntemplate <typename T>\nclass GetValueMixin\n{\n  private:\n\tT *get_base()\n\t{\n\t\tstatic_assert(GetValueMixinConcept<T>);\n\t\treturn static_cast<T *>(this);\n\t}\n\n  public:\n\tdouble get_expression_value(const ScalarAffineFunction &function)\n\t{\n\t\tT *model = get_base();\n\t\tauto N = function.size();\n\t\tdouble value = 0.0;\n\t\tfor (auto i = 0; i < N; ++i)\n\t\t{\n\t\t\tvalue += function.coefficients[i] * model->get_variable_value(function.variables[i]);\n\t\t}\n\t\tvalue += function.constant.value_or(0.0);\n\t\treturn value;\n\t}\n\tdouble get_expression_value(const ScalarQuadraticFunction &function)\n\t{\n\t\tT *model = get_base();\n\t\tauto N = function.size();\n\t\tdouble value = 0.0;\n\t\tfor (auto i = 0; i < N; ++i)\n\t\t{\n\t\t\tauto var1 = function.variable_1s[i];\n\t\t\tauto var2 = function.variable_2s[i];\n\t\t\tauto coef = function.coefficients[i];\n\t\t\tauto v1 = model->get_variable_value(var1);\n\t\t\tif (var1 == var2)\n\t\t\t{\n\t\t\t\tvalue += coef * v1 * v1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto v2 = model->get_variable_value(var2);\n\t\t\t\tvalue += coef * v1 * v2;\n\t\t\t}\n\t\t}\n\t\tif (function.affine_part)\n\t\t{\n\t\t\tauto affine_value = model->get_expression_value(function.affine_part.value());\n\t\t\tvalue += affine_value;\n\t\t}\n\t\treturn value;\n\t}\n\tdouble get_expression_value(const ExprBuilder &function)\n\t{\n\t\tT *model = get_base();\n\t\tdouble value = 0.0;\n\t\tfor (const auto &[varpair, coef] : function.quadratic_terms)\n\t\t{\n\t\t\tauto var1 = varpair.var_1;\n\t\t\tauto var2 = varpair.var_2;\n\n\t\t\tauto v1 = model->get_variable_value(var1);\n\t\t\tif (var1 == var2)\n\t\t\t{\n\t\t\t\tvalue += coef * v1 * v1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto v2 = model->get_variable_value(var2);\n\t\t\t\tvalue += coef * v1 * v2;\n\t\t\t}\n\t\t}\n\t\tfor (const auto &[var, coef] : function.affine_terms)\n\t\t{\n\t\t\tvalue += coef * model->get_variable_value(var);\n\t\t}\n\t\tvalue += function.constant_term.value_or(0.0);\n\t\treturn value;\n\t}\n};\n\ntemplate <typename T>\nconcept PPrintMixinConcept = requires(T &model) {\n\t{ model.pprint_variable(VariableIndex()) } -> std::convertible_to<std::string>;\n};\n\ntemplate <typename T>\nclass PPrintMixin\n{\n  private:\n\tT *get_base()\n\t{\n\t\tstatic_assert(PPrintMixinConcept<T>);\n\t\treturn static_cast<T *>(this);\n\t}\n\n  public:\n\tstd::string pprint_expression(const ScalarAffineFunction &function, int precision = 4)\n\t{\n\t\tT *model = get_base();\n\t\tauto N = function.size();\n\t\tstd::vector<std::string> terms;\n\t\tterms.reserve(N + 1);\n\t\tfor (auto i = 0; i < N; ++i)\n\t\t{\n\t\t\tauto &coef = function.coefficients[i];\n\t\t\tstd::string var_str = model->pprint_variable(function.variables[i]);\n\t\t\tstd::string term;\n\t\t\tif (coef > 0)\n\t\t\t{\n\t\t\t\tterm = fmt::format(\"{:.{}g}*{}\", coef, precision, var_str);\n\t\t\t}\n\t\t\telse if (coef < 0)\n\t\t\t{\n\t\t\t\tterm = fmt::format(\"({:.{}g})*{}\", coef, precision, var_str);\n\t\t\t}\n\t\t\tterms.push_back(term);\n\t\t}\n\t\tif (function.constant)\n\t\t{\n\t\t\tterms.push_back(fmt::format(\"{:.{}g}\", function.constant.value(), precision));\n\t\t}\n\t\treturn fmt::format(\"{}\", fmt::join(terms, \"+\"));\n\t}\n\tstd::string pprint_expression(const ScalarQuadraticFunction &function, int precision = 4)\n\t{\n\t\tT *model = get_base();\n\t\tauto N = function.size();\n\t\tstd::vector<std::string> terms;\n\t\tterms.reserve(N + 1);\n\t\tfor (auto i = 0; i < N; ++i)\n\t\t{\n\t\t\tauto &coef = function.coefficients[i];\n\t\t\tstd::string var1_str = model->pprint_variable(function.variable_1s[i]);\n\t\t\tstd::string var2_str;\n\t\t\tif (function.variable_1s[i] == function.variable_2s[i])\n\t\t\t{\n\t\t\t\tvar2_str = var1_str;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar2_str = model->pprint_variable(function.variable_2s[i]);\n\t\t\t}\n\t\t\tstd::string term;\n\t\t\tif (coef > 0)\n\t\t\t{\n\t\t\t\tterm = fmt::format(\"{:.{}g}*{}*{}\", coef, precision, var1_str, var2_str);\n\t\t\t}\n\t\t\telse if (coef < 0)\n\t\t\t{\n\t\t\t\tterm = fmt::format(\"({:.{}g})*{}*{}\", coef, precision, var1_str, var2_str);\n\t\t\t}\n\t\t\tterms.push_back(term);\n\t\t}\n\t\tif (function.affine_part)\n\t\t{\n\t\t\tauto affine_value = model->pprint_expression(function.affine_part.value(), precision);\n\t\t\tterms.push_back(affine_value);\n\t\t}\n\t\treturn fmt::format(\"{}\", fmt::join(terms, \"+\"));\n\t}\n\tstd::string pprint_expression(const ExprBuilder &function, int precision = 4)\n\t{\n\t\tT *model = get_base();\n\t\tstd::vector<std::string> terms;\n\t\tterms.reserve(function.quadratic_terms.size() + function.affine_terms.size() + 1);\n\t\tfor (const auto &[varpair, coef] : function.quadratic_terms)\n\t\t{\n\t\t\tstd::string var1_str = model->pprint_variable(varpair.var_1);\n\t\t\tstd::string var2_str;\n\t\t\tif (varpair.var_1 == varpair.var_2)\n\t\t\t{\n\t\t\t\tvar2_str = var1_str;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar2_str = model->pprint_variable(varpair.var_2);\n\t\t\t}\n\t\t\tstd::string term;\n\t\t\tif (coef > 0)\n\t\t\t{\n\t\t\t\tterm = fmt::format(\"{:.{}g}*{}*{}\", coef, precision, var1_str, var2_str);\n\t\t\t}\n\t\t\telse if (coef < 0)\n\t\t\t{\n\t\t\t\tterm = fmt::format(\"({:.{}g})*{}*{}\", coef, precision, var1_str, var2_str);\n\t\t\t}\n\t\t\tterms.push_back(term);\n\t\t}\n\t\tfor (const auto &[var, coef] : function.affine_terms)\n\t\t{\n\t\t\tauto term = fmt::format(\"{:.{}g}*{}\", coef, precision, model->pprint_variable(var));\n\t\t\tterms.push_back(term);\n\t\t}\n\t\tif (function.constant_term)\n\t\t{\n\t\t\tauto term = fmt::format(\"{:.{}g}\", function.constant_term.value(), precision);\n\t\t\tterms.push_back(term);\n\t\t}\n\t\treturn fmt::format(\"{}\", fmt::join(terms, \"+\"));\n\t}\n};\n\ntemplate <typename T>\nconcept LinearObjectiveMixinConcept = requires(T &model) {\n\t{ model.set_objective(ScalarAffineFunction(), ObjectiveSense()) } -> std::same_as<void>;\n};\n\ntemplate <typename T>\nclass LinearObjectiveMixin\n{\n  private:\n\tT *get_base()\n\t{\n\t\tstatic_assert(LinearObjectiveMixinConcept<T>);\n\t\treturn static_cast<T *>(this);\n\t}\n\n  public:\n\tvoid set_objective_as_constant(CoeffT c, ObjectiveSense sense)\n\t{\n\t\tT *model = get_base();\n\t\tmodel->set_objective(ScalarAffineFunction(c), sense);\n\t}\n\tvoid set_objective_as_variable(const VariableIndex &variable, ObjectiveSense sense)\n\t{\n\t\tT *model = get_base();\n\t\tmodel->set_objective(ScalarAffineFunction(variable), sense);\n\t}\n};\n\n/* This concept combined with partial specialization causes ICE on gcc 10 */\n// template <typename T>\n// concept VarIndexModel = requires(T *model, const VariableIndex &v) {\n//\t{\n//\t\tmodel->_variable_index(v)\n//\t} -> std::convertible_to<IndexT>;\n// };\n#define VarIndexModel typename\n\ntemplate <std::integral NZT, std::integral IDXT, std::floating_point VALT>\nstruct AffineFunctionPtrForm\n{\n\tNZT numnz;\n\tIDXT *index;\n\tVALT *value;\n\tstd::vector<IDXT> index_storage;\n\tstd::vector<VALT> value_storage;\n\n\ttemplate <VarIndexModel T>\n\tvoid make(T *model, const ScalarAffineFunction &function)\n\t{\n\t\tauto f_numnz = function.size();\n\t\tnumnz = f_numnz;\n\t\tindex_storage.resize(numnz);\n\t\tfor (int i = 0; i < numnz; ++i)\n\t\t{\n\t\t\tindex_storage[i] = model->_variable_index(function.variables[i]);\n\t\t}\n\t\tindex = index_storage.data();\n\t\tif constexpr (std::is_same_v<VALT, CoeffT>)\n\t\t{\n\t\t\tvalue = (VALT *)function.coefficients.data();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvalue_storage.resize(numnz);\n\t\t\tfor (int i = 0; i < numnz; ++i)\n\t\t\t{\n\t\t\t\tvalue_storage[i] = function.coefficients[i];\n\t\t\t}\n\t\t}\n\t}\n};\n\ntemplate <std::integral NZT, std::integral IDXT, std::floating_point VALT>\nstruct QuadraticFunctionPtrForm\n{\n\tNZT numnz;\n\tIDXT *row;\n\tIDXT *col;\n\tVALT *value;\n\tstd::vector<IDXT> row_storage;\n\tstd::vector<IDXT> col_storage;\n\tstd::vector<VALT> value_storage;\n\n\ttemplate <VarIndexModel T>\n\tvoid make(T *model, const ScalarQuadraticFunction &function)\n\t{\n\t\tauto f_numnz = function.size();\n\t\tnumnz = f_numnz;\n\t\trow_storage.resize(numnz);\n\t\tcol_storage.resize(numnz);\n\t\tfor (int i = 0; i < numnz; ++i)\n\t\t{\n\t\t\trow_storage[i] = model->_variable_index(function.variable_1s[i]);\n\t\t\tif (function.variable_1s[i] == function.variable_2s[i])\n\t\t\t{\n\t\t\t\tcol_storage[i] = row_storage[i];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcol_storage[i] = model->_variable_index(function.variable_2s[i]);\n\t\t\t}\n\t\t}\n\t\trow = row_storage.data();\n\t\tcol = col_storage.data();\n\t\tif constexpr (std::is_same_v<VALT, CoeffT>)\n\t\t{\n\t\t\tvalue = (VALT *)function.coefficients.data();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvalue_storage.resize(numnz);\n\t\t\tfor (int i = 0; i < numnz; ++i)\n\t\t\t{\n\t\t\t\tvalue_storage[i] = function.coefficients[i];\n\t\t\t}\n\t\t}\n\t}\n};\n\nenum class HessianTriangular\n{\n\tUpper,\n\tLower,\n};\n\ntemplate <std::integral NZT, std::integral IDXT, std::floating_point VALT>\nstruct CSCMatrix\n{\n\tNZT numnz;\n\tNZT numcol;\n\tstd::vector<VALT> values_CSC;\n\tstd::vector<IDXT> rows_CSC;\n\tstd::vector<IDXT> colStarts_CSC;\n\n\ttemplate <VarIndexModel T>\n\tvoid make(T *model, const ScalarQuadraticFunction &function, int i_numcol,\n\t          HessianTriangular triangular_format)\n\t{\n\t\tauto f_numnz = function.size();\n\t\tnumnz = f_numnz;\n\t\tnumcol = i_numcol;\n\n\t\tstd::vector<IDXT> rows(numnz);   // Row indices\n\t\tstd::vector<IDXT> cols(numnz);   // Column indices\n\t\tstd::vector<VALT> values(numnz); // Values\n\t\tfor (int i = 0; i < numnz; ++i)\n\t\t{\n\t\t\tauto v1 = model->_variable_index(function.variable_1s[i]);\n\t\t\tauto v2 = v1;\n\t\t\tif (function.variable_1s[i] != function.variable_2s[i])\n\t\t\t{\n\t\t\t\tv2 = model->_variable_index(function.variable_2s[i]);\n\t\t\t}\n\n\t\t\tif (triangular_format == HessianTriangular::Upper)\n\t\t\t{\n\t\t\t\tif (v1 > v2)\n\t\t\t\t{\n\t\t\t\t\tstd::swap(v1, v2);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (v1 < v2)\n\t\t\t\t{\n\t\t\t\t\tstd::swap(v1, v2);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (v1 < 0 || v2 < 0)\n\t\t\t{\n\t\t\t\tthrow std::runtime_error(\n\t\t\t\t    \"Variable index in quadratic function cannot be negative!\");\n\t\t\t}\n\n\t\t\trows[i] = v1;\n\t\t\tcols[i] = v2;\n\n\t\t\tauto coef = function.coefficients[i];\n\t\t\tif (v1 != v2)\n\t\t\t{\n\t\t\t\t// Non-diagonal element, should multiply by 0.5\n\t\t\t\tcoef *= 0.5;\n\t\t\t}\n\t\t\tvalues[i] = coef;\n\t\t}\n\n\t\t// Sorting based on column indices\n\t\tstd::vector<IDXT> idx(numnz);\n\t\tstd::iota(idx.begin(), idx.end(), 0);\n\t\tstd::sort(idx.begin(), idx.end(), [&](int i, int j) {\n\t\t\tif (cols[i] == cols[j])\n\t\t\t{\n\t\t\t\treturn rows[i] < rows[j];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn cols[i] < cols[j];\n\t\t\t}\n\t\t});\n\n\t\t// Creating CSC arrays\n\t\tvalues_CSC.reserve(numnz);\n\t\trows_CSC.reserve(numnz);\n\t\tcolStarts_CSC.resize(numcol + 1, 0);\n\n\t\tint currentCol = 0;\n\t\tfor (auto i : idx)\n\t\t{\n\t\t\twhile (currentCol < cols[i])\n\t\t\t{\n\t\t\t\tcolStarts_CSC[currentCol + 1] = values_CSC.size();\n\t\t\t\tcurrentCol++;\n\t\t\t}\n\t\t\tvalues_CSC.push_back(values[i]);\n\t\t\trows_CSC.push_back(rows[i]);\n\t\t}\n\n\t\t// Filling up remaining columns in colStarts_CSC\n\t\tstd::fill(colStarts_CSC.begin() + currentCol + 1, colStarts_CSC.end(), numnz);\n\t}\n};\n"
  },
  {
    "path": "include/pyoptinterface/tcc_interface.hpp",
    "content": "#pragma once\n\n#include <memory>\n#include <string>\n\n#include \"tcc/libtcc.h\"\n\n#include \"ankerl/unordered_dense.h\"\n#include \"pyoptinterface/dylib.hpp\"\n\n#define APILIST                 \\\n\tB(tcc_new);                 \\\n\tB(tcc_delete);              \\\n\tB(tcc_add_include_path);    \\\n\tB(tcc_add_sysinclude_path); \\\n\tB(tcc_define_symbol);       \\\n\tB(tcc_undefine_symbol);     \\\n\tB(tcc_compile_string);      \\\n\tB(tcc_set_output_type);     \\\n\tB(tcc_add_library_path);    \\\n\tB(tcc_add_library);         \\\n\tB(tcc_add_symbol);          \\\n\tB(tcc_relocate);            \\\n\tB(tcc_get_symbol);\n\nnamespace tcc\n{\n#define B DYLIB_EXTERN_DECLARE\nAPILIST\n#undef B\n\nbool is_library_loaded();\n\nbool load_library(const std::string &path);\n} // namespace tcc\n\nstruct TCCFreeT\n{\n\tvoid operator()(TCCState *state) const\n\t{\n\t\ttcc::tcc_delete(state);\n\t};\n};\n\nstruct TCCInstance\n{\n\tTCCInstance() = default;\n\tvoid init();\n\n\tvoid add_include_path(const std::string &path);\n\tvoid add_sysinclude_path(const std::string &path);\n\n\tvoid add_library_path(const std::string &path);\n\tvoid add_library(const std::string &name);\n\n\tvoid import_math_symbols();\n\tvoid compile_string(const std::string &code);\n\n\tuintptr_t get_symbol(const std::string &name);\n\n\tstd::unique_ptr<TCCState, TCCFreeT> m_state;\n};"
  },
  {
    "path": "include/pyoptinterface/xpress_model.hpp",
    "content": "#pragma\n\n#include <exception>\n#include <memory>\n#include <variant>\n\n// #include <xprs.h>\n#include \"../thirdparty/solvers/xpress/xpress_forward_decls.h\"\n\n#include \"pyoptinterface/core.hpp\"\n#include \"pyoptinterface/container.hpp\"\n#define USE_NLMIXIN\n#include \"pyoptinterface/solver_common.hpp\"\n#include \"pyoptinterface/dylib.hpp\"\n\n// PyOptInterface has been compiled and tested with Xpress version 46.1.1\n#define XPRS_VER_MAJOR 46\n#define XPRS_VER_MINOR 1\n#define XPRS_VER_BUILD 1\n\n#if POI_XPVERSION_MAJOR < XPRS_VER_MAJOR\n#warning \"System Xpress library major version is older than the officially supported version. \" \\\n    \"Some features may not work correctly.\"\n#endif\n\n// Xpress Callback Abstraction Layer\n//\n// Xpress supports multiple callbacks that we want to expose to PyOptInterface as \"contexts\" to\n// match the design of other solver interfaces. To bridge Xpress's multiple-callback system to\n// PyOptInterface's single-callback-with-context model, we need to repeat the same setup for each\n// callback: define the low-level C function, register it with Xpress, handle its arguments, and\n// bind everything through Nanobind.\n//\n// Rather than copy-paste this boilerplate for each callback (error-prone and hard to maintain), we\n// use macros to generate everything from a single list.\n//\n// How does it work:\n// We define XPRSCB_LIST below with all supported callbacks and their signatures. This list is\n// parameterized by two macros that let us generate different code from the same data:\n//\n//   MACRO - Receives callback metadata (ID, name, return type, arguments) and expands to whatever\n//   we're generating (function declarations, enum values, registration code, etc.)\n//\n//   ARG - Formats each callback *optional* argument. MACRO receives arguments wrapped by ARG, so it\n//   can extract type/name information as needed.\n//\n// When we need to do something with all callbacks (e.g., declare wrapper functions), we pass\n// specific MACRO and ARG definitions to XPRSCB_LIST, and it generates the code.\n//\n// MACRO is invoked with:\n//   1. ID - Unique number for enum bit-flags (0-63, used for callback identification)\n//   2. NAME - Xpress callback name (e.g., \"optnode\" for XPRSaddcboptnode)\n//   3. RET - Return type of the Xpress callback function\n//   4. ...ARGS - Callback arguments (excluding XPRSprob and void* which are always first),\n//                     each wrapped in ARG(TYPE, NAME)\n//\n// ARG is invoked with:\n//   1. TYPE - Argument type from Xpress documentation\n//   2. NAME - Argument name from Xpress documentation\n//\n// Example: To declare all callback wrappers, define MACRO to generate a function declaration and\n// ARG to format parameters, then invoke XPRSCB_LIST(MACRO, ARG).\n\n// clang-format off\n#define XPRSCB_LIST(MACRO, ARG)                  \\\n\tMACRO(0, bariteration, void,                 \\\n        ARG(int *, p_action))                    \\\n\tMACRO(1, barlog, int)                        \\\n\tMACRO(2, afterobjective, void)               \\\n\tMACRO(3, beforeobjective, void)              \\\n\tMACRO(5, presolve, void)                     \\\n\tMACRO(6, checktime,int)                      \\\n\tMACRO(7, chgbranchobject, void,              \\\n        ARG(XPRSbranchobject, obranch)           \\\n        ARG(XPRSbranchobject *, p_newobject))    \\\n\tMACRO(8, cutlog, int)                        \\\n\tMACRO(9, cutround, void,                     \\\n        ARG(int, ifxpresscuts)                   \\\n        ARG(int*, p_action))                     \\\n\tMACRO(10, destroymt, void)                   \\\n\tMACRO(11, gapnotify, void,                   \\\n        ARG(double*, p_relgapnotifytarget)       \\\n        ARG(double*, p_absgapnotifytarget)       \\\n        ARG(double*, p_absgapnotifyobjtarget)    \\\n        ARG(double*, p_absgapnotifyboundtarget)) \\\n\tMACRO(12, miplog, int)                       \\\n\tMACRO(13, infnode, void)                     \\\n\tMACRO(14, intsol, void)                      \\\n\tMACRO(15, lplog, int)                        \\\n\tMACRO(16, message, void,                     \\\n        ARG(const char*, msg)                    \\\n        ARG(int, msglen)                         \\\n        ARG(int, msgtype))                       \\\n    /* This CB is currently incompatible with this wapper design \n    MACRO(17, mipthread, void,                   \\\n        ARG(XPRSprob, threadprob))  */           \\\n\tMACRO(18, newnode, void,                     \\\n        ARG(int, parentnode)                     \\\n        ARG(int, node)                           \\\n        ARG(int, branch))                        \\\n\tMACRO(19, nodecutoff, void,                  \\\n        ARG(int, node))                          \\\n\tMACRO(20, nodelpsolved, void)                \\\n\tMACRO(21, optnode, void,                     \\\n        ARG(int*, p_infeasible))                 \\\n\tMACRO(22, preintsol, void,                   \\\n        ARG(int, soltype)                        \\\n        ARG(int*, p_reject)                      \\\n        ARG(double*, p_cutoff))                  \\\n\tMACRO(23, prenode, void,                     \\\n        ARG(int*, p_infeasible))                 \\\n\tMACRO(24, usersolnotify, void,               \\\n        ARG(const char*, solname)                \\\n        ARG(int, status))\n// clang-format on\n\n// Common callbacks optional arguments formatting macros:\n#define XPRSCB_ARG_IGNORE(TYPE, NAME)         // Ingore arguments\n#define XPRSCB_ARG_FN(TYPE, NAME) , TYPE NAME // As args of a function\n#define XPRSCB_ARG_TYPE(TYPE, NAME) , TYPE    // As args of a template\n\n// Expand to 2 elements of APILIST\n#define XPRSCB_ADDREMOVE_FN(ID, NAME, ...) \\\n\tB(XPRSaddcb##NAME);                    \\\n\tB(XPRSremovecb##NAME);\n\n// Define Xpress C APIs list.\n// Similar idea to the CBs list, here the B macro is externally provided as in the other solvers\n// interface implementation.\n#define APILIST                 \\\n\tB(XPRSaddcols64);           \\\n\tB(XPRSaddcuts64);           \\\n\tB(XPRSaddmanagedcuts64);    \\\n\tB(XPRSaddmipsol);           \\\n\tB(XPRSaddnames);            \\\n\tB(XPRSaddqmatrix64);        \\\n\tB(XPRSaddrows64);           \\\n\tB(XPRSaddsets64);           \\\n\tB(XPRSbeginlicensing);      \\\n\tB(XPRSchgbounds);           \\\n\tB(XPRSchgcoef);             \\\n\tB(XPRSchgcoltype);          \\\n\tB(XPRSchgmqobj64);          \\\n\tB(XPRSchgobj);              \\\n\tB(XPRSchgobjsense);         \\\n\tB(XPRSchgrhs);              \\\n\tB(XPRSchgrowtype);          \\\n\tB(XPRScreateprob);          \\\n\tB(XPRSdelcols);             \\\n\tB(XPRSdelobj);              \\\n\tB(XPRSdelqmatrix);          \\\n\tB(XPRSdelrows);             \\\n\tB(XPRSdelsets);             \\\n\tB(XPRSdestroyprob);         \\\n\tB(XPRSendlicensing);        \\\n\tB(XPRSfree);                \\\n\tB(XPRSgetattribinfo);       \\\n\tB(XPRSgetbasisval);         \\\n\tB(XPRSgetcallbacksolution); \\\n\tB(XPRSgetcoef);             \\\n\tB(XPRSgetcoltype);          \\\n\tB(XPRSgetcontrolinfo);      \\\n\tB(XPRSgetdblattrib);        \\\n\tB(XPRSgetdblcontrol);       \\\n\tB(XPRSgetdualray);          \\\n\tB(XPRSgetduals);            \\\n\tB(XPRSgetiisdata);          \\\n\tB(XPRSgetintattrib64);      \\\n\tB(XPRSgetintcontrol64);     \\\n\tB(XPRSgetlasterror);        \\\n\tB(XPRSgetlb);               \\\n\tB(XPRSgetlicerrmsg);        \\\n\tB(XPRSgetlpsol);            \\\n\tB(XPRSgetnamelist);         \\\n\tB(XPRSgetobj);              \\\n\tB(XPRSgetprimalray);        \\\n\tB(XPRSgetprobname);         \\\n\tB(XPRSgetredcosts);         \\\n\tB(XPRSgetrhs);              \\\n\tB(XPRSgetrowtype);          \\\n\tB(XPRSgetslacks);           \\\n\tB(XPRSgetsolution);         \\\n\tB(XPRSgetstrattrib);        \\\n\tB(XPRSgetstrcontrol);       \\\n\tB(XPRSgetstringattrib);     \\\n\tB(XPRSgetstringcontrol);    \\\n\tB(XPRSgetub);               \\\n\tB(XPRSgetversion);          \\\n\tB(XPRSgetversionnumbers);   \\\n\tB(XPRSiisall);              \\\n\tB(XPRSiisfirst);            \\\n\tB(XPRSinit);                \\\n\tB(XPRSinterrupt);           \\\n\tB(XPRSlicense);             \\\n\tB(XPRSnlpaddformulas);      \\\n\tB(XPRSnlploadformulas);     \\\n\tB(XPRSnlppostsolve);        \\\n\tB(XPRSoptimize);            \\\n\tB(XPRSpostsolve);           \\\n\tB(XPRSpresolverow);         \\\n\tB(XPRSsaveas);              \\\n\tB(XPRSsetdblcontrol);       \\\n\tB(XPRSsetintcontrol);       \\\n\tB(XPRSsetintcontrol64);     \\\n\tB(XPRSsetlogfile);          \\\n\tB(XPRSsetprobname);         \\\n\tB(XPRSsetstrcontrol);       \\\n\tB(XPRSwritebasis);          \\\n\tB(XPRSwritebinsol);         \\\n\tB(XPRSwriteprob);           \\\n\tB(XPRSwriteprtsol);         \\\n\tB(XPRSwriteslxsol);         \\\n\tB(XPRSwritesol);            \\\n\tXPRSCB_LIST(XPRSCB_ADDREMOVE_FN, XPRSCB_ARG_IGNORE);\n\nnamespace xpress\n{\n// Define xpress function inside the xpress namespace\n#define B DYLIB_EXTERN_DECLARE\nAPILIST\n#undef B\n\n// Libray loading functions\nbool is_library_loaded();\nbool load_library(const std::string &path);\nstd::pair<int, std::string> license(int p_i, const char *p_c);\nbool beginlicensing();\nvoid endlicensing();\n\n// Xpress doesn't have an Env pointer, however, POI manages environment\n// initialization with an OOP interface.\nstruct Env\n{\n\tEnv(const char *path = nullptr);\n\t~Env();\n\tvoid close();\n\n\tstatic inline std::mutex mtx;\n\tstatic inline int init_count = 0;\n\tbool initialized = false;\n};\n\n// Some of the Xpress enums are here re-defined to enforce type safety\n// Types associated with Xpress attribute and controls\nenum class CATypes : int\n{\n\tNOTDEFINED = POI_XPRS_TYPE_NOTDEFINED,\n\tINT = POI_XPRS_TYPE_INT,\n\tINT64 = POI_XPRS_TYPE_INT64,\n\tDOUBLE = POI_XPRS_TYPE_DOUBLE,\n\tSTRING = POI_XPRS_TYPE_STRING,\n};\n\nenum class SOLSTATUS : int\n{\n\tNOTFOUND = POI_XPRS_SOLSTATUS_NOTFOUND,\n\tOPTIMAL = POI_XPRS_SOLSTATUS_OPTIMAL,\n\tFEASIBLE = POI_XPRS_SOLSTATUS_FEASIBLE,\n\tINFEASIBLE = POI_XPRS_SOLSTATUS_INFEASIBLE,\n\tUNBOUNDED = POI_XPRS_SOLSTATUS_UNBOUNDED\n};\n\nenum class SOLVESTATUS : int\n{\n\tUNSTARTED = POI_XPRS_SOLVESTATUS_UNSTARTED,\n\tSTOPPED = POI_XPRS_SOLVESTATUS_STOPPED,\n\tFAILED = POI_XPRS_SOLVESTATUS_FAILED,\n\tCOMPLETED = POI_XPRS_SOLVESTATUS_COMPLETED\n};\n\nenum class LPSTATUS : int\n{\n\tUNSTARTED = POI_XPRS_LP_UNSTARTED,\n\tOPTIMAL = POI_XPRS_LP_OPTIMAL,\n\tINFEAS = POI_XPRS_LP_INFEAS,\n\tCUTOFF = POI_XPRS_LP_CUTOFF,\n\tUNFINISHED = POI_XPRS_LP_UNFINISHED,\n\tUNBOUNDED = POI_XPRS_LP_UNBOUNDED,\n\tCUTOFF_IN_DUAL = POI_XPRS_LP_CUTOFF_IN_DUAL,\n\tUNSOLVED = POI_XPRS_LP_UNSOLVED,\n\tNONCONVEX = POI_XPRS_LP_NONCONVEX\n};\n\nenum class MIPSTATUS : int\n{\n\tNOT_LOADED = POI_XPRS_MIP_NOT_LOADED,\n\tLP_NOT_OPTIMAL = POI_XPRS_MIP_LP_NOT_OPTIMAL,\n\tLP_OPTIMAL = POI_XPRS_MIP_LP_OPTIMAL,\n\tNO_SOL_FOUND = POI_XPRS_MIP_NO_SOL_FOUND,\n\tSOLUTION = POI_XPRS_MIP_SOLUTION,\n\tINFEAS = POI_XPRS_MIP_INFEAS,\n\tOPTIMAL = POI_XPRS_MIP_OPTIMAL,\n\tUNBOUNDED = POI_XPRS_MIP_UNBOUNDED\n};\n\nenum class NLPSTATUS : int\n{\n\tUNSTARTED = POI_XPRS_NLPSTATUS_UNSTARTED,\n\tSOLUTION = POI_XPRS_NLPSTATUS_SOLUTION,\n\tLOCALLY_OPTIMAL = POI_XPRS_NLPSTATUS_LOCALLY_OPTIMAL,\n\tOPTIMAL = POI_XPRS_NLPSTATUS_OPTIMAL,\n\tNOSOLUTION = POI_XPRS_NLPSTATUS_NOSOLUTION,\n\tLOCALLY_INFEASIBLE = POI_XPRS_NLPSTATUS_LOCALLY_INFEASIBLE,\n\tINFEASIBLE = POI_XPRS_NLPSTATUS_INFEASIBLE,\n\tUNBOUNDED = POI_XPRS_NLPSTATUS_UNBOUNDED,\n\tUNFINISHED = POI_XPRS_NLPSTATUS_UNFINISHED,\n\tUNSOLVED = POI_XPRS_NLPSTATUS_UNSOLVED,\n};\n\nenum class IISSOLSTATUS : int\n{\n\tUNSTARTED = POI_XPRS_IIS_UNSTARTED,\n\tFEASIBLE = POI_XPRS_IIS_FEASIBLE,\n\tCOMPLETED = POI_XPRS_IIS_COMPLETED,\n\tUNFINISHED = POI_XPRS_IIS_UNFINISHED\n};\n\nenum class SOLAVAILABLE : int\n{\n\tNOTFOUND = POI_XPRS_SOLAVAILABLE_NOTFOUND,\n\tOPTIMAL = POI_XPRS_SOLAVAILABLE_OPTIMAL,\n\tFEASIBLE = POI_XPRS_SOLAVAILABLE_FEASIBLE\n};\n\nenum class OPTIMIZETYPE : int\n{\n\tNONE = POI_XPRS_OPTIMIZETYPE_NONE,\n\tLP = POI_XPRS_OPTIMIZETYPE_LP,\n\tMIP = POI_XPRS_OPTIMIZETYPE_MIP,\n\tLOCAL = POI_XPRS_OPTIMIZETYPE_LOCAL,\n\tGLOBAL = POI_XPRS_OPTIMIZETYPE_GLOBAL\n};\n\n////////////////////////////////////////////////////////////////////////////////\n//                      CALLBACKS TYPES AND DEFINITIONS                       //\n////////////////////////////////////////////////////////////////////////////////\n\n// Callback contexts enum. Defines an unique id for each callback/context.\n// The values of this enum class are defined as bitflags, to allow for multiple context manipulation\n// using a single uint64 value.\nenum class CB_CONTEXT : unsigned long long\n{\n// Define a enum element\n#define XPRSCB_ENUM(ID, NAME, ...) NAME = (1ULL << ID),\n\tXPRSCB_LIST(XPRSCB_ENUM, XPRSCB_ARG_IGNORE)\n#undef XPRSCB_ENUM\n};\n\nclass Model;                                               // Define later in this file\nusing Callback = std::function<void(Model *, CB_CONTEXT)>; // Callback opaque container\n\n// xpress::Model operates in two modes to handle callback local XPRSprob objects:\n//\n// MAIN mode - The model owns its XPRSprob and manages all optimization state normally.\n// CALLBACK mode - A temporary, non-owning wrapper around Xpress's thread-local problem clone that\n// gets passed to callbacks. Since Xpress creates separate problem clones for callbacks, we need to\n// temporarily \"borrow\" this clone while preserving xpress::Model's internal state\n// (variable/constraint indexers, etc.) without copies.\n//\n// During a callback, we swap the XPRSprob pointer from the main model into the callback pointer,\n// execute the user's callback with a full xpress::Model object, then swap it back.\n//\n// Thread safety: This swap-based design assumes callbacks execute sequentially. Python's GIL\n// enforces this anyway (only one callback can execute Python code at a time), and we configure\n// Xpress to mutex callbacks invocations, so concurrent callback execution isn't an issue.\nenum class XPRESS_MODEL_MODE\n{\n\tMAIN,      // Owns XPRSprob; holds global callback state\n\tCALLBACK_, // Non-owning wrapper around Xpress's callback problem clone\n};\n\n// Simple conditional struct that define the ret_code field only if it is not void\ntemplate <typename T>\nstruct ReturnValue\n{\n\tT ret_code;\n\tT get_return_value() const\n\t{\n\t\treturn ret_code;\n\t}\n};\n\ntemplate <>\nstruct ReturnValue<void>\n{\n\tvoid get_return_value() const {};\n};\n\n// Since we use the CB macro list, we get the original types passed at the low-level CBs\n// This helper struct is used to inject type-exceptions on the callback struct field types. In most\n// cases this is not required, except when dealing with pointers to opaque objects, which Nanobind\n// doesn't handle automatically.\ntemplate <typename T>\nstruct StructFieldType\n{\n\tusing type = T; // Default behavior: just use the original type\n};\n\n// (At the best of my knowledge) Nanobind does not support binding for opaque types (pointers to\n// declared structs but whose definition is not available in that point). Some callbacks works with\n// opaque objects that are passed around (e.g., branch object), we don't need to access them,\n// just to pass them back to other Xpress APIs.\n\n// XPRSbranchobject is a pointer to an opaque type, which nanobind struggle with. So we pass it\n// as an opaque void*, which nanobind knows how to handle.\ntemplate <>\nstruct StructFieldType<XPRSbranchobject>\n{\n\tusing type = void *;\n};\n\ntemplate <>\nstruct StructFieldType<XPRSbranchobject *>\n{\n\tusing type = void *;\n};\n\n// Callback Argument Structs\n//\n// PyOptInterface callbacks have a uniform signature: callback(model, context). On the other hand,\n// Xpress callbacks have varying signatures with callback-specific arguments (e.g., node IDs,\n// branching info, solution status). To bridge this gap, we generate a struct for each callback type\n// that holds its specific arguments.\n//\n// During a callback, we populate the appropriate struct with the current arguments, and we provide\n// it to the CB through the \"Model.cb_get_arguments\" function. The Python callback can then access\n// these arguments as named fields.\n//\n// For example, the 'optnode' callback receives an int* p_infeasible parameter. We generate:\n//   struct optnode_struct { int* p_infeasible; };\n// The Python callback accesses this as: model.cb_get_arguments().p_infeasible\n\n#define XPRSCB_ARG_STRUCT(TYPE, NAME) StructFieldType<TYPE>::type NAME;\n#define XPRSCB_STRUCT(ID, NAME, RET, ...)   \\\n\tstruct NAME##_struct : ReturnValue<RET> \\\n\t{                                       \\\n\t\t__VA_ARGS__                         \\\n\t};\nXPRSCB_LIST(XPRSCB_STRUCT, XPRSCB_ARG_STRUCT)\n#undef XPRSCB_STRUCT\n\n// Callback Data Variant\n//\n// We use std::variant to store pointers to callback-specific argument structs, rather than\n// a generic void*. This provides two benefits:\n//\n// 1. Type safety - The variant ensures we can only store pointers to known callback structs,\n//    catching type errors at compile time.\n//\n// 2. Automatic Python binding - Nanobind automatically converts std::variant to Python union\n//    types, giving Python callbacks properly-typed access to callback arguments without manual\n//    type casting or wrapper code.\n//\n// The variant contains nullptr_t plus a pointer type for each callback struct (e.g.,\n// optnode_struct*, intsol_struct*, etc.)\n#define XPRSCB_STRUCT_NAME(ID, NAME, RET, ...) , NAME##_struct *\nusing xpress_cbs_data =\n    std::variant<std::nullptr_t XPRSCB_LIST(XPRSCB_STRUCT_NAME, XPRSCB_ARG_IGNORE)>;\n#undef XPRSCB_STRUCT_NAME\n\n// Type-value pair mainly used for NLP formulas\nstruct Tvp\n{\n\tint type;\n\tdouble value;\n};\n\n// xpress::Model - Main solver interface for building and solving Xpress optimization models.\n// Inherits standard PyOptInterface modeling API through CRTP mixins for constraints, objectives,\n// and solution queries.\nclass Model : public OnesideLinearConstraintMixin<Model>,\n              public TwosideLinearConstraintMixin<Model>,\n              public OnesideQuadraticConstraintMixin<Model>,\n              public TwosideNLConstraintMixin<Model>,\n              public LinearObjectiveMixin<Model>,\n              public PPrintMixin<Model>,\n              public GetValueMixin<Model>\n{\n\n  public:\n\tModel() = default;\n\t~Model();\n\n\t// Avoid involuntary copies\n\tModel(const Model &) = delete;\n\tModel &operator=(const Model &) = delete;\n\n\t// Move is fine, and we need it to wrap callback XPRSprob\n\tModel(Model &&) noexcept = default;\n\tModel &operator=(Model &&) noexcept = default;\n\n\tModel(const Env &env);\n\tvoid init(const Env &env);\n\tvoid close();\n\n\tvoid optimize();\n\tbool _is_mip();\n\tstatic double get_infinity();\n\tvoid write(const std::string &filename);\n\tstd::string get_problem_name();\n\tvoid set_problem_name(const std::string &probname);\n\tvoid add_mip_start(const std::vector<VariableIndex> &variables,\n\t                   const std::vector<double> &values);\n\tvoid *get_raw_model();\n\tvoid computeIIS();\n\tstd::string version_string();\n\n\t// Index mappings\n\tint _constraint_index(ConstraintIndex constraint);\n\tint _variable_index(VariableIndex variable);\n\tint _checked_constraint_index(ConstraintIndex constraint);\n\tint _checked_variable_index(VariableIndex variable);\n\n\t// Variables\n\tVariableIndex add_variable(VariableDomain domain = VariableDomain::Continuous,\n\t                           double lb = POI_XPRS_MINUSINFINITY,\n\t                           double ub = POI_XPRS_PLUSINFINITY, const char *name = nullptr);\n\tvoid delete_variable(VariableIndex variable);\n\tvoid delete_variables(const Vector<VariableIndex> &variables);\n\tvoid set_objective_coefficient(VariableIndex variable, double value);\n\tvoid set_variable_bounds(VariableIndex variable, double lb, double ub);\n\tvoid set_variable_lowerbound(VariableIndex variable, double lb);\n\tvoid set_variable_name(VariableIndex variable, const char *name);\n\tvoid set_variable_type(VariableIndex variable, VariableDomain vtype);\n\tvoid set_variable_upperbound(VariableIndex variable, double ub);\n\tbool is_variable_active(VariableIndex variable);\n\tbool is_variable_basic(VariableIndex variable);\n\tbool is_variable_lowerbound_IIS(VariableIndex variable);\n\tbool is_variable_nonbasic_lb(VariableIndex variable);\n\tbool is_variable_nonbasic_ub(VariableIndex variable);\n\tbool is_variable_superbasic(VariableIndex variable);\n\tbool is_variable_upperbound_IIS(VariableIndex variable);\n\tdouble get_objective_coefficient(VariableIndex variable);\n\tdouble get_variable_lowerbound(VariableIndex variable);\n\tdouble get_variable_primal_ray(VariableIndex variable);\n\tdouble get_variable_rc(VariableIndex variable);\n\tdouble get_variable_upperbound(VariableIndex variable);\n\tdouble get_variable_value(VariableIndex variable);\n\tstd::string get_variable_name(VariableIndex variable);\n\tstd::string pprint_variable(VariableIndex variable);\n\tVariableDomain get_variable_type(VariableIndex variable);\n\n\t// Constraints\n\tConstraintIndex add_exp_cone_constraint(const Vector<VariableIndex> &variables,\n\t                                        const char *name, bool dual);\n\tConstraintIndex add_linear_constraint(const ScalarAffineFunction &function,\n\t                                      const std::tuple<double, double> &interval,\n\t                                      const char *name);\n\tConstraintIndex add_linear_constraint(const ScalarAffineFunction &function,\n\t                                      ConstraintSense sense, CoeffT rhs,\n\t                                      const char *name = nullptr);\n\tConstraintIndex add_quadratic_constraint(const ScalarQuadraticFunction &function,\n\t                                         ConstraintSense sense, CoeffT rhs,\n\t                                         const char *name = nullptr);\n\tConstraintIndex add_second_order_cone_constraint(const Vector<VariableIndex> &variables,\n\t                                                 const char *name, bool rotated);\n\tConstraintIndex add_single_nl_constraint(ExpressionGraph &graph, const ExpressionHandle &result,\n\t                                         const std::tuple<double, double> &interval,\n\t                                         const char *name = nullptr);\n\tConstraintIndex add_sos_constraint(const Vector<VariableIndex> &variables, SOSType sos_type,\n\t                                   const Vector<CoeffT> &weights);\n\tConstraintIndex add_sos_constraint(const Vector<VariableIndex> &variables, SOSType sos_type);\n\tvoid delete_constraint(ConstraintIndex constraint);\n\tvoid set_constraint_name(ConstraintIndex constraint, const char *name);\n\tvoid set_constraint_rhs(ConstraintIndex constraint, CoeffT rhs);\n\tvoid set_constraint_sense(ConstraintIndex constraint, ConstraintSense sense);\n\tvoid set_normalized_coefficient(ConstraintIndex constraint, VariableIndex variable,\n\t                                double value);\n\tvoid set_normalized_rhs(ConstraintIndex constraint, double value);\n\tbool is_constraint_active(ConstraintIndex constraint);\n\tbool is_constraint_basic(ConstraintIndex constraint);\n\tbool is_constraint_in_IIS(ConstraintIndex constraint);\n\tbool is_constraint_nonbasic_lb(ConstraintIndex constraint);\n\tbool is_constraint_nonbasic_ub(ConstraintIndex constraint);\n\tbool is_constraint_superbasic(ConstraintIndex constraint);\n\tdouble get_constraint_dual_ray(ConstraintIndex constraint);\n\tdouble get_constraint_dual(ConstraintIndex constraint);\n\tdouble get_constraint_slack(ConstraintIndex constraint);\n\tdouble get_normalized_coefficient(ConstraintIndex constraint, VariableIndex variable);\n\tdouble get_normalized_rhs(ConstraintIndex constraint);\n\tCoeffT get_constraint_rhs(ConstraintIndex constraint);\n\tstd::string get_constraint_name(ConstraintIndex constraint);\n\tConstraintSense get_constraint_sense(ConstraintIndex constraint);\n\n\t// Objective function\n\tvoid set_objective(const ScalarAffineFunction &function, ObjectiveSense sense);\n\tvoid set_objective(const ScalarQuadraticFunction &function, ObjectiveSense sense);\n\tvoid set_objective(const ExprBuilder &function, ObjectiveSense sense);\n\tvoid add_single_nl_objective(ExpressionGraph &graph, const ExpressionHandle &result);\n\n\t// Xpress->POI exit status mappings\n\tLPSTATUS get_lp_status();\n\tMIPSTATUS get_mip_status();\n\tNLPSTATUS get_nlp_status();\n\tSOLSTATUS get_sol_status();\n\tSOLVESTATUS get_solve_status();\n\tOPTIMIZETYPE get_optimize_type();\n\tIISSOLSTATUS get_iis_sol_status();\n\n\t// Native Attribute/Control access using integer IDs\n\tvoid set_raw_control_dbl_by_id(int control, double value);\n\tvoid set_raw_control_int_by_id(int control, XPRSint64 value);\n\tvoid set_raw_control_str_by_id(int control, const char *value);\n\tXPRSint64 get_raw_control_int_by_id(int control);\n\tdouble get_raw_control_dbl_by_id(int control);\n\tstd::string get_raw_control_str_by_id(int control);\n\n\tXPRSint64 get_raw_attribute_int_by_id(int attrib);\n\tdouble get_raw_attribute_dbl_by_id(int attrib);\n\tstd::string get_raw_attribute_str_by_id(int attrib);\n\n\t// Attribute/Control access through string IDs (converted to integer IDs)\n\tvoid set_raw_control_int(const char *control, XPRSint64 value);\n\tvoid set_raw_control_dbl(const char *control, double value);\n\tvoid set_raw_control_str(const char *control, const char *value);\n\tXPRSint64 get_raw_control_int(const char *control);\n\tdouble get_raw_control_dbl(const char *control);\n\tstd::string get_raw_control_str(const char *control);\n\n\tXPRSint64 get_raw_attribute_int(const char *attrib);\n\tdouble get_raw_attribute_dbl(const char *attrib);\n\tstd::string get_raw_attribute_str(const char *attrib);\n\n\t// Type generic Attribute/Control access through string IDs\n\tusing xprs_type_variant_t = std::variant<int, XPRSint64, double, std::string>;\n\tvoid set_raw_control(const char *control, xprs_type_variant_t &value);\n\txprs_type_variant_t get_raw_attribute(const char *attrib);\n\txprs_type_variant_t get_raw_control(const char *control);\n\n\t// Callback\n\tvoid set_callback(const Callback &callback, unsigned long long cbctx);\n\txpress_cbs_data cb_get_arguments();\n\n\tdouble cb_get_solution(VariableIndex variable);\n\tdouble cb_get_relaxation(VariableIndex variable);\n\tdouble cb_get_incumbent(VariableIndex variable);\n\tvoid cb_set_solution(VariableIndex variable, double value);\n\tvoid cb_submit_solution();\n\n\tvoid cb_exit();\n\n\t// NOTE: Xpress only provide ways to add local cuts, so, all these functions map to the same\n\t// XPRSaddcuts operation\n\tvoid cb_add_lazy_constraint(const ScalarAffineFunction &function, ConstraintSense sense,\n\t                            CoeffT rhs);\n\tvoid cb_add_lazy_constraint(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs);\n\tvoid cb_add_user_cut(const ScalarAffineFunction &function, ConstraintSense sense, CoeffT rhs);\n\tvoid cb_add_user_cut(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs);\n\n  private: // HELPER FUNCTIONS\n\tvoid _check(int error);\n\tvoid _clear_caches();\n\n\t// Modeling helpers\n\tvoid _set_entity_name(int etype, int index, const char *name);\n\tConstraintIndex _add_sos_constraint(const Vector<VariableIndex> &variables, SOSType sos_type,\n\t                                    const Vector<double> &weights);\n\tstd::string _get_entity_name(int etype, int eidx);\n\tchar _get_variable_bound_IIS(VariableIndex variable);\n\tint _get_basis_stat(int entity_idx, bool is_row = false);\n\n\t// NLP helpers\n\tTvp _decode_expr(const ExpressionGraph &graph, const ExpressionHandle &expr);\n\tstd::pair<std::vector<int>, std::vector<double>> _decode_graph_postfix_order(\n\t    ExpressionGraph &graph, const ExpressionHandle &result);\n\n\t// Attributes/Controls helpers\n\tint _get_checked_attribute_id(const char *attrib, CATypes expected,\n\t                              CATypes backup = CATypes::NOTDEFINED);\n\tint _get_checked_control_id(const char *control, CATypes expected,\n\t                            CATypes backup = CATypes::NOTDEFINED);\n\tstd::pair<int, CATypes> _get_attribute_info(const char *attrib);\n\tstd::pair<int, CATypes> _get_control_info(const char *control);\n\n\t// Callback/Mode helpers\n\tvoid _check_expected_mode(XPRESS_MODEL_MODE mode);\n\tvoid _ensure_postsolved();\n\tdouble _cb_get_context_solution(VariableIndex variable);\n\tvoid _cb_add_cut(const ScalarAffineFunction &function, ConstraintSense sense, CoeffT rhs);\n\tXPRSprob _toggle_model_mode(XPRSprob model);\n\n  private: // TYPES\n\t// Helper struct used to spawn lower level C callbacks with matching signature\n\ttemplate <unsigned long long, typename, typename, typename...>\n\tstruct CbWrap;\n\n\t// XPRSprob deleter to automatically RAII using unique_ptr\n\tstruct ProbDeleter\n\t{\n\t\tvoid operator()(XPRSprob prob)\n\t\t{\n\t\t\tif (xpress::XPRSdestroyprob(prob) != 0)\n\t\t\t{\n\t\t\t\tthrow std::runtime_error(\"Error while destroying Xpress problem object\");\n\t\t\t}\n\t\t}\n\t};\n\n  private: // MEMBER VARIABLES\n\t// Xpress problem pointer\n\tstd::unique_ptr<xo_prob_struct, ProbDeleter> m_model;\n\n\t// Current operating mode (MAIN or CALLBACK) - enables runtime validation that\n\t// callback-only methods aren't called outside callbacks and vice versa\n\tXPRESS_MODEL_MODE m_mode;\n\n\t// Index management for variables and constraints\n\t// Note that Xpress uses the same index set to refer to almost all its constraint types. The\n\t// only exception are SOS which are handled in a separate pool.\n\tMonotoneIndexer<int> m_variable_index;\n\tMonotoneIndexer<int> m_constraint_index;\n\tMonotoneIndexer<int> m_sos_constraint_index;\n\n\t// Tracks whether the model requires postsolving before queries can be made.\n\t// When optimization is interrupted, the model remains in a presolved state where variable\n\t// and constraint indices don't match the original problem structure. Querying model data\n\t// in this state would return incorrect results. Postsolving restores the original index\n\t// mappings but discards all optimization progress, forcing any subsequent optimization\n\t// to restart from scratch.\n\tbool m_need_postsolve = false;\n\n\t// Any non-linear or non-convex quadratic constraint is handled with Xpress non linear solver.\n\t// We keep count of all the non-linear (strictly speaking) constraints.\n\tint m_quad_nl_constr_num = 0;\n\tbool has_quad_objective = false;\n\n\tbool has_nlp_objective = false;\n\tVariableIndex m_nlp_obj_variable;\n\tConstraintIndex m_nlp_obj_constraint;\n\n\t// Cached vectors\n\tstd::vector<double> m_primal_ray;\n\tstd::vector<double> m_dual_ray;\n\tstd::vector<int> m_iis_cols;\n\tstd::vector<int> m_iss_rows;\n\tstd::vector<char> m_iis_bound_types;\n\n\t// Message callback state - we register a default handler but allow user override\n\tbool is_default_message_cb_set;\n\n\t// User callback and active contexts\n\tCallback m_callback = nullptr;\n\tunsigned long long m_curr_contexts = 0; // Bitwise OR of enabled callback contexts\n\n\t// Exception propagation - if a callback throws, we capture it here to let Xpress\n\t// complete cleanup gracefully before rethrowing to Python\n\tstd::vector<std::exception_ptr> m_captured_exceptions;\n\n\t// Current callback context being executed\n\tCB_CONTEXT cb_where;\n\n\t// Heuristic solution builder - accumulates (variable, value) pairs during callback;\n\t// submitted to Xpress when callback completes\n\tstd::vector<std::pair<int, double>> cb_sol_cache;\n\n\t// Callback-specific arguments - variant holding pointers to context-specific structs\n\t// (e.g., optnode_struct*, intsol_struct*) based on current callback type\n\txpress_cbs_data cb_args = nullptr;\n};\n} // namespace xpress\n"
  },
  {
    "path": "lib/cache_model.cpp",
    "content": "// #include <optional>\n//\n// #include \"pyoptinterface/core.hpp\"\n// #include \"pyoptinterface/container.hpp\"\n//\n// struct VariableInfo\n//{\n//\tVariableDomain domain;\n// };\n//\n// class CacheModel\n//{\n//   public:\n//\tVariableIndex add_variable(VariableDomain domain = VariableDomain::Continuous);\n//\tvoid delete_variable(const VariableIndex &variable);\n//\tbool is_variable_active(const VariableIndex &variable) const;\n//\n//\tConstraintIndex add_linear_constraint(const LinearConstraint &constraint);\n//\tConstraintIndex add_quadratic_constraint(const QuadraticConstraint &constraint);\n//\tConstraintIndex add_sos1_constraint(const SOSConstraint &constraint);\n//\tConstraintIndex add_sos2_constraint(const SOSConstraint &constraint);\n//\n//\tvoid delete_constraint(const ConstraintIndex &constraint);\n//\n//\tbool is_constraint_active(const ConstraintIndex &constraint) const;\n//\n//   private:\n//\tint num_variable = 0;\n//\tMonotoneVector<int> m_variable_index;\n//\tVector<std::optional<VariableInfo>> m_variables;\n//\n//\tint num_linear_constraint = 0;\n//\tMonotoneVector<int> m_linear_constraint_index;\n//\tVector<std::optional<LinearConstraint>> m_linear_constraints;\n//\n//\tint num_quadratic_constraint = 0;\n//\tMonotoneVector<int> m_quadratic_constraint_index;\n//\tVector<std::optional<QuadraticConstraint>> m_quadratic_constraints;\n//\n//\tint num_sos1_constraint = 0;\n//\tMonotoneVector<int> m_sos1_constraint_index;\n//\tVector<std::optional<SOSConstraint>> m_sos1_constraints;\n//\n//\tint num_sos2_constraint = 0;\n//\tMonotoneVector<int> m_sos2_constraint_index;\n//\tVector<std::optional<SOSConstraint>> m_sos2_constraints;\n// };\n//\n// VariableIndex CacheModel::add_variable(VariableDomain domain)\n//{\n//\tIndexT index = m_variable_index.add_index();\n//\tm_variables.push_back(VariableInfo{domain});\n//\tnum_variable++;\n//\treturn VariableIndex(index);\n// }\n//\n// void CacheModel::delete_variable(const VariableIndex &variable)\n//{\n//\tm_variable_index.delete_index(variable.index);\n//\tm_variables[variable.index] = std::nullopt;\n//\tnum_variable--;\n// }\n//\n// bool CacheModel::is_variable_active(const VariableIndex &variable) const\n//{\n//\treturn m_variables[variable.index].has_value();\n// }\n//\n// ConstraintIndex CacheModel::add_linear_constraint(const LinearConstraint &constraint)\n//{\n//\tIndexT index = m_linear_constraint_index.add_index();\n//\tm_linear_constraints.push_back(constraint);\n//\tnum_linear_constraint++;\n//\treturn ConstraintIndex{ConstraintType::Linear, index};\n// }\n//\n// ConstraintIndex CacheModel::add_quadratic_constraint(const QuadraticConstraint &constraint)\n//{\n//\tIndexT index = m_quadratic_constraint_index.add_index();\n//\tm_quadratic_constraints.push_back(constraint);\n//\tnum_quadratic_constraint++;\n//\treturn ConstraintIndex{ConstraintType::Quadratic, index};\n// }\n//\n// ConstraintIndex CacheModel::add_sos1_constraint(const SOSConstraint &constraint)\n//{\n//\tIndexT index = m_sos1_constraint_index.add_index();\n//\tm_sos1_constraints.push_back(constraint);\n//\tnum_sos1_constraint++;\n//\treturn ConstraintIndex{ConstraintType::SOS1, index};\n// }\n//\n// ConstraintIndex CacheModel::add_sos2_constraint(const SOSConstraint &constraint)\n//{\n//\tIndexT index = m_sos2_constraint_index.add_index();\n//\tm_sos2_constraints.push_back(constraint);\n//\tnum_sos2_constraint++;\n//\treturn ConstraintIndex{ConstraintType::SOS2, index};\n// }\n//\n// void CacheModel::delete_constraint(const ConstraintIndex &constraint)\n//{\n//\tauto index = constraint.index;\n//\tswitch (constraint.type)\n//\t{\n//\tcase ConstraintType::Linear:\n//\t\tm_linear_constraint_index.delete_index(index);\n//\t\tm_linear_constraints[index] = std::nullopt;\n//\t\tnum_linear_constraint--;\n//\t\tbreak;\n//\tcase ConstraintType::Quadratic:\n//\t\tm_quadratic_constraint_index.delete_index(index);\n//\t\tm_quadratic_constraints[index] = std::nullopt;\n//\t\tnum_quadratic_constraint--;\n//\t\tbreak;\n//\tcase ConstraintType::SOS1:\n//\t\tm_sos1_constraint_index.delete_index(index);\n//\t\tm_sos1_constraints[index] = std::nullopt;\n//\t\tnum_sos1_constraint--;\n//\t\tbreak;\n//\tcase ConstraintType::SOS2:\n//\t\tm_sos2_constraint_index.delete_index(index);\n//\t\tm_sos2_constraints[index] = std::nullopt;\n//\t\tnum_sos2_constraint--;\n//\t\tbreak;\n//\t}\n// }\n//\n// bool CacheModel::is_constraint_active(const ConstraintIndex &constraint) const\n//{\n//\tauto index = constraint.index;\n//\tswitch (constraint.type)\n//\t{\n//\tcase ConstraintType::Linear:\n//\t\treturn m_linear_constraint_index.has_index(index);\n//\tcase ConstraintType::Quadratic:\n//\t\treturn m_quadratic_constraint_index.has_index(index);\n//\tcase ConstraintType::SOS1:\n//\t\treturn m_sos1_constraint_index.has_index(index);\n//\tcase ConstraintType::SOS2:\n//\t\treturn m_sos2_constraint_index.has_index(index);\n//\t}\n// }\n"
  },
  {
    "path": "lib/copt_model.cpp",
    "content": "#include \"pyoptinterface/copt_model.hpp\"\n#include \"fmt/core.h\"\n\n#include <stack>\n\nnamespace copt\n{\n#define B DYLIB_DECLARE\nAPILIST\n#undef B\n\nstatic DynamicLibrary lib;\nstatic bool is_loaded = false;\n\nbool is_library_loaded()\n{\n\treturn is_loaded;\n}\n\nbool load_library(const std::string &path)\n{\n\tbool success = lib.try_load(path.c_str());\n\tif (!success)\n\t{\n\t\treturn false;\n\t}\n\n\tDYLIB_LOAD_INIT;\n\n#define B DYLIB_LOAD_FUNCTION\n\tAPILIST\n#undef B\n\n\tif (IS_DYLIB_LOAD_SUCCESS)\n\t{\n#define B DYLIB_SAVE_FUNCTION\n\t\tAPILIST\n#undef B\n\t\tis_loaded = true;\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\treturn false;\n\t}\n}\n} // namespace copt\n\nstatic void check_error(int error)\n{\n\tif (error)\n\t{\n\t\tchar errmsg[COPT_BUFFSIZE];\n\n\t\tcopt::COPT_GetRetcodeMsg(error, errmsg, COPT_BUFFSIZE);\n\t\tthrow std::runtime_error(errmsg);\n\t}\n}\n\nstatic char copt_con_sense(ConstraintSense sense)\n{\n\tswitch (sense)\n\t{\n\tcase ConstraintSense::LessEqual:\n\t\treturn COPT_LESS_EQUAL;\n\tcase ConstraintSense::Equal:\n\t\treturn COPT_EQUAL;\n\tcase ConstraintSense::GreaterEqual:\n\t\treturn COPT_GREATER_EQUAL;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint sense\");\n\t}\n}\n\nstatic int copt_obj_sense(ObjectiveSense sense)\n{\n\tswitch (sense)\n\t{\n\tcase ObjectiveSense::Minimize:\n\t\treturn COPT_MINIMIZE;\n\tcase ObjectiveSense::Maximize:\n\t\treturn COPT_MAXIMIZE;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown objective sense\");\n\t}\n}\n\nstatic char copt_vtype(VariableDomain domain)\n{\n\tswitch (domain)\n\t{\n\tcase VariableDomain::Continuous:\n\t\treturn COPT_CONTINUOUS;\n\tcase VariableDomain::Integer:\n\t\treturn COPT_INTEGER;\n\tcase VariableDomain::Binary:\n\t\treturn COPT_BINARY;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown variable domain\");\n\t}\n}\n\nstatic VariableDomain copt_vtype_to_domain(char vtype)\n{\n\tswitch (vtype)\n\t{\n\tcase COPT_CONTINUOUS:\n\t\treturn VariableDomain::Continuous;\n\tcase COPT_INTEGER:\n\t\treturn VariableDomain::Integer;\n\tcase COPT_BINARY:\n\t\treturn VariableDomain::Binary;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown variable domain\");\n\t}\n}\n\nstatic int copt_sostype(SOSType type)\n{\n\tswitch (type)\n\t{\n\tcase SOSType::SOS1:\n\t\treturn COPT_SOS_TYPE1;\n\tcase SOSType::SOS2:\n\t\treturn COPT_SOS_TYPE2;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown SOS type\");\n\t}\n}\n\nCOPTModel::COPTModel(const COPTEnv &env)\n{\n\tinit(env);\n}\n\nvoid COPTModel::init(const COPTEnv &env)\n{\n\tif (!copt::is_library_loaded())\n\t{\n\t\tthrow std::runtime_error(\"COPT library is not loaded\");\n\t}\n\tcopt_prob *model;\n\tint error = copt::COPT_CreateProb(env.m_env, &model);\n\tcheck_error(error);\n\tm_model = std::unique_ptr<copt_prob, COPTfreemodelT>(model);\n}\n\nvoid COPTModel::close()\n{\n\tm_model.reset();\n}\n\ndouble COPTModel::get_infinity() const\n{\n\treturn COPT_INFINITY;\n}\n\nvoid COPTModel::write(const std::string &filename)\n{\n\tint error;\n\tif (filename.ends_with(\".mps\"))\n\t{\n\t\terror = copt::COPT_WriteMps(m_model.get(), filename.c_str());\n\t}\n\telse if (filename.ends_with(\".lp\"))\n\t{\n\t\terror = copt::COPT_WriteLp(m_model.get(), filename.c_str());\n\t}\n\telse if (filename.ends_with(\".cbf\"))\n\t{\n\t\terror = copt::COPT_WriteCbf(m_model.get(), filename.c_str());\n\t}\n\telse if (filename.ends_with(\".bin\"))\n\t{\n\t\terror = copt::COPT_WriteBin(m_model.get(), filename.c_str());\n\t}\n\telse if (filename.ends_with(\".bas\"))\n\t{\n\t\terror = copt::COPT_WriteBasis(m_model.get(), filename.c_str());\n\t}\n\telse if (filename.ends_with(\".sol\"))\n\t{\n\t\terror = copt::COPT_WriteSol(m_model.get(), filename.c_str());\n\t}\n\telse if (filename.ends_with(\".mst\"))\n\t{\n\t\terror = copt::COPT_WriteMst(m_model.get(), filename.c_str());\n\t}\n\telse if (filename.ends_with(\".par\"))\n\t{\n\t\terror = copt::COPT_WriteParam(m_model.get(), filename.c_str());\n\t}\n\telse\n\t{\n\t\tthrow std::runtime_error(\"Unknown file extension\");\n\t}\n\tcheck_error(error);\n}\n\nVariableIndex COPTModel::add_variable(VariableDomain domain, double lb, double ub, const char *name)\n{\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\tIndexT index = m_variable_index.add_index();\n\tVariableIndex variable(index);\n\n\tchar vtype = copt_vtype(domain);\n\tint error = copt::COPT_AddCol(m_model.get(), 0.0, 0, NULL, NULL, vtype, lb, ub, name);\n\tcheck_error(error);\n\n\treturn variable;\n}\n\nvoid COPTModel::delete_variable(const VariableIndex &variable)\n{\n\tif (!is_variable_active(variable))\n\t{\n\t\tthrow std::runtime_error(\"Variable does not exist\");\n\t}\n\n\tint variable_column = _variable_index(variable);\n\tint error = copt::COPT_DelCols(m_model.get(), 1, &variable_column);\n\tcheck_error(error);\n\n\tm_variable_index.delete_index(variable.index);\n}\n\nvoid COPTModel::delete_variables(const Vector<VariableIndex> &variables)\n{\n\tint n_variables = variables.size();\n\tif (n_variables == 0)\n\t\treturn;\n\n\tstd::vector<int> columns;\n\tcolumns.reserve(n_variables);\n\tfor (int i = 0; i < n_variables; i++)\n\t{\n\t\tif (!is_variable_active(variables[i]))\n\t\t{\n\t\t\tcontinue;\n\t\t}\n\t\tauto column = _variable_index(variables[i]);\n\t\tcolumns.push_back(column);\n\t}\n\n\tint error = copt::COPT_DelCols(m_model.get(), columns.size(), columns.data());\n\tcheck_error(error);\n\n\tfor (int i = 0; i < n_variables; i++)\n\t{\n\t\tm_variable_index.delete_index(variables[i].index);\n\t}\n}\n\nbool COPTModel::is_variable_active(const VariableIndex &variable)\n{\n\treturn m_variable_index.has_index(variable.index);\n}\n\ndouble COPTModel::get_variable_value(const VariableIndex &variable)\n{\n\treturn get_variable_info(variable, COPT_DBLINFO_VALUE);\n}\n\nstd::string COPTModel::pprint_variable(const VariableIndex &variable)\n{\n\treturn get_variable_name(variable);\n}\n\nvoid COPTModel::set_variable_bounds(const VariableIndex &variable, double lb, double ub)\n{\n\tauto column = _checked_variable_index(variable);\n\tint error;\n\terror = copt::COPT_SetColLower(m_model.get(), 1, &column, &lb);\n\tcheck_error(error);\n\terror = copt::COPT_SetColUpper(m_model.get(), 1, &column, &ub);\n\tcheck_error(error);\n}\n\nConstraintIndex COPTModel::add_linear_constraint(const ScalarAffineFunction &function,\n                                                 ConstraintSense sense, CoeffT rhs,\n                                                 const char *name)\n{\n\tIndexT index = m_linear_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::Linear, index);\n\n\tAffineFunctionPtrForm<int, int, double> ptr_form;\n\tptr_form.make(this, function);\n\n\tint numnz = ptr_form.numnz;\n\tint *cind = ptr_form.index;\n\tdouble *cval = ptr_form.value;\n\tchar g_sense = copt_con_sense(sense);\n\tdouble g_rhs = rhs - function.constant.value_or(0.0);\n\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\n\tint error = copt::COPT_AddRow(m_model.get(), numnz, cind, cval, g_sense, g_rhs, g_rhs, name);\n\tcheck_error(error);\n\treturn constraint_index;\n}\n\nConstraintIndex COPTModel::add_linear_constraint(const ScalarAffineFunction &function,\n                                                 const std::tuple<double, double> &interval,\n                                                 const char *name)\n{\n\tauto lb = std::get<0>(interval);\n\tauto ub = std::get<1>(interval);\n\n\tif (function.constant.has_value())\n\t{\n\t\tlb -= function.constant.value_or(0.0);\n\t\tub -= function.constant.value_or(0.0);\n\t}\n\n\tIndexT index = m_linear_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::Linear, index);\n\n\tAffineFunctionPtrForm<int, int, double> ptr_form;\n\tptr_form.make(this, function);\n\n\tint numnz = ptr_form.numnz;\n\tint *cind = ptr_form.index;\n\tdouble *cval = ptr_form.value;\n\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\n\tint error = copt::COPT_AddRow(m_model.get(), numnz, cind, cval, 0, lb, ub, name);\n\tcheck_error(error);\n\treturn constraint_index;\n\n\treturn ConstraintIndex();\n}\n\nConstraintIndex COPTModel::add_quadratic_constraint(const ScalarQuadraticFunction &function,\n                                                    ConstraintSense sense, CoeffT rhs,\n                                                    const char *name)\n{\n\tIndexT index = m_quadratic_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::Quadratic, index);\n\n\tconst auto &affine_part = function.affine_part;\n\n\tint numlnz = 0;\n\tint *lind = NULL;\n\tdouble *lval = NULL;\n\tAffineFunctionPtrForm<int, int, double> affine_ptr_form;\n\tif (affine_part.has_value())\n\t{\n\t\tconst auto &affine_function = affine_part.value();\n\t\taffine_ptr_form.make(this, affine_function);\n\t\tnumlnz = affine_ptr_form.numnz;\n\t\tlind = affine_ptr_form.index;\n\t\tlval = affine_ptr_form.value;\n\t}\n\n\tQuadraticFunctionPtrForm<int, int, double> ptr_form;\n\tptr_form.make(this, function);\n\tint numqnz = ptr_form.numnz;\n\tint *qrow = ptr_form.row;\n\tint *qcol = ptr_form.col;\n\tdouble *qval = ptr_form.value;\n\n\tchar g_sense = copt_con_sense(sense);\n\tdouble g_rhs = rhs;\n\tif (affine_part)\n\t\tg_rhs -= affine_part->constant.value_or(0.0);\n\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\n\tint error = copt::COPT_AddQConstr(m_model.get(), numlnz, lind, lval, numqnz, qrow, qcol, qval,\n\t                                  g_sense, g_rhs, name);\n\tcheck_error(error);\n\treturn constraint_index;\n}\n\nConstraintIndex COPTModel::add_sos_constraint(const Vector<VariableIndex> &variables,\n                                              SOSType sos_type)\n{\n\tVector<CoeffT> weights(variables.size(), 1.0);\n\treturn add_sos_constraint(variables, sos_type, weights);\n}\n\nConstraintIndex COPTModel::add_sos_constraint(const Vector<VariableIndex> &variables,\n                                              SOSType sos_type, const Vector<CoeffT> &weights)\n{\n\tIndexT index = m_sos_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::SOS, index);\n\n\tint numsos = 1;\n\tint nummembers = variables.size();\n\tint types = copt_sostype(sos_type);\n\tint beg[] = {0};\n\tint cnt[] = {nummembers};\n\tstd::vector<int> ind_v(nummembers);\n\tfor (int i = 0; i < nummembers; i++)\n\t{\n\t\tind_v[i] = _variable_index(variables[i].index);\n\t}\n\tint *ind = ind_v.data();\n\tdouble *weight = (double *)weights.data();\n\n\tint error = copt::COPT_AddSOSs(m_model.get(), numsos, &types, beg, cnt, ind, weight);\n\tcheck_error(error);\n\treturn constraint_index;\n}\n\nConstraintIndex COPTModel::add_second_order_cone_constraint(const Vector<VariableIndex> &variables,\n                                                            const char *name, bool rotated)\n{\n\tIndexT index = m_cone_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::SecondOrderCone, index);\n\n\tint N = variables.size();\n\tstd::vector<int> ind_v(N);\n\tfor (int i = 0; i < N; i++)\n\t{\n\t\tind_v[i] = _checked_variable_index(variables[i]);\n\t}\n\n\tint cone = COPT_CONE_QUAD;\n\tif (rotated)\n\t{\n\t\tcone = COPT_CONE_RQUAD;\n\t}\n\n\tint coneType[] = {cone};\n\tint coneBeg[] = {0};\n\tint coneCnt[] = {N};\n\tint *coneIdx = ind_v.data();\n\n\tint error = copt::COPT_AddCones(m_model.get(), 1, coneType, coneBeg, coneCnt, coneIdx);\n\tcheck_error(error);\n\n\t// COPT does not support name for cone constraints\n\n\treturn constraint_index;\n}\n\nConstraintIndex COPTModel::add_exp_cone_constraint(const Vector<VariableIndex> &variables,\n                                                   const char *name, bool dual)\n{\n\tIndexT index = m_exp_cone_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::ExponentialCone, index);\n\n\tint N = variables.size();\n\tif (N != 3)\n\t{\n\t\tthrow std::runtime_error(\"Exponential cone constraint must have 3 variables\");\n\t}\n\n\tstd::vector<int> ind_v(N);\n\tfor (int i = 0; i < N; i++)\n\t{\n\t\tind_v[i] = _checked_variable_index(variables[i]);\n\t}\n\n\tint cone = COPT_EXPCONE_PRIMAL;\n\tif (dual)\n\t{\n\t\tcone = COPT_EXPCONE_DUAL;\n\t}\n\n\tint coneType[] = {cone};\n\tint coneBeg[] = {0};\n\tint coneCnt[] = {N};\n\tint *coneIdx = ind_v.data();\n\n\tint error = copt::COPT_AddExpCones(m_model.get(), 1, coneType, coneIdx);\n\tcheck_error(error);\n\n\t// COPT does not support name for cone constraints\n\n\treturn constraint_index;\n}\n\nint unary_opcode(const UnaryOperator &op)\n{\n\tswitch (op)\n\t{\n\tcase UnaryOperator::Neg:\n\t\treturn COPT_NL_NEG;\n\tcase UnaryOperator::Sin:\n\t\treturn COPT_NL_SIN;\n\tcase UnaryOperator::Cos:\n\t\treturn COPT_NL_COS;\n\tcase UnaryOperator::Tan:\n\t\treturn COPT_NL_TAN;\n\tcase UnaryOperator::Asin:\n\t\treturn COPT_NL_ASIN;\n\tcase UnaryOperator::Acos:\n\t\treturn COPT_NL_ACOS;\n\tcase UnaryOperator::Atan:\n\t\treturn COPT_NL_ATAN;\n\tcase UnaryOperator::Abs:\n\t\treturn COPT_NL_ABS;\n\tcase UnaryOperator::Sqrt:\n\t\treturn COPT_NL_SQRT;\n\tcase UnaryOperator::Exp:\n\t\treturn COPT_NL_EXP;\n\tcase UnaryOperator::Log:\n\t\treturn COPT_NL_LOG;\n\tcase UnaryOperator::Log10:\n\t\treturn COPT_NL_LOG10;\n\tdefault: {\n\t\tauto opname = unary_operator_to_string(op);\n\t\tauto msg = fmt::format(\"Unknown unary operator for COPT: {}\", opname);\n\t\tthrow std::runtime_error(msg);\n\t}\n\t}\n}\n\nint binary_opcode(const BinaryOperator &op)\n{\n\tswitch (op)\n\t{\n\tcase BinaryOperator::Sub:\n\t\treturn COPT_NL_MINUS;\n\tcase BinaryOperator::Div:\n\t\treturn COPT_NL_DIV;\n\tcase BinaryOperator::Pow:\n\t\treturn COPT_NL_POW;\n\tcase BinaryOperator::Mul2:\n\t\treturn COPT_NL_MULT;\n\tdefault: {\n\t\tauto opname = binary_operator_to_string(op);\n\t\tauto msg = fmt::format(\"Unknown binary operator for COPT: {}\", opname);\n\t\tthrow std::runtime_error(msg);\n\t}\n\t}\n}\n\nint nary_opcode(const NaryOperator &op)\n{\n\tswitch (op)\n\t{\n\tcase NaryOperator::Add:\n\t\treturn COPT_NL_SUM;\n\tdefault: {\n\t\tauto opname = nary_operator_to_string(op);\n\t\tauto msg = fmt::format(\"Unknown n-ary operator for COPT: {}\", opname);\n\t\tthrow std::runtime_error(msg);\n\t}\n\t}\n}\n\nvoid COPTModel::decode_expr(const ExpressionGraph &graph, const ExpressionHandle &expr,\n                            std::vector<int> &opcodes, std::vector<double> &constants)\n{\n\tauto array_type = expr.array;\n\tauto index = expr.id;\n\tswitch (array_type)\n\t{\n\tcase ArrayType::Constant: {\n\t\topcodes.push_back(COPT_NL_GET);\n\t\tconstants.push_back(graph.m_constants[index]);\n\t\tbreak;\n\t}\n\tcase ArrayType::Variable: {\n\t\tauto column = _checked_variable_index(graph.m_variables[index]);\n\t\topcodes.push_back(column);\n\t\tbreak;\n\t}\n\tcase ArrayType::Parameter: {\n\t\tthrow std::runtime_error(\"Parameter is not supported in COPT\");\n\t\tbreak;\n\t}\n\tcase ArrayType::Unary: {\n\t\tauto &unary = graph.m_unaries[index];\n\t\tint opcode = unary_opcode(unary.op);\n\t\topcodes.push_back(opcode);\n\t\tbreak;\n\t}\n\tcase ArrayType::Binary: {\n\t\tauto &binary = graph.m_binaries[index];\n\t\tint opcode = binary_opcode(binary.op);\n\t\topcodes.push_back(opcode);\n\t\tbreak;\n\t}\n\tcase ArrayType::Ternary: {\n\t\tthrow std::runtime_error(\"Ternary operator is not supported in COPT\");\n\t\tbreak;\n\t}\n\tcase ArrayType::Nary: {\n\t\tauto &nary = graph.m_naries[index];\n\t\tint opcode = nary_opcode(nary.op);\n\t\tint n_operands = nary.operands.size();\n\n\t\tif (opcode == COPT_NL_SUM && n_operands == 1)\n\t\t{\n\t\t\t// COPT errors when sum 1 operand\n\t\t}\n\t\telse\n\t\t{\n\t\t\topcodes.push_back(opcode);\n\t\t\topcodes.push_back(n_operands);\n\t\t}\n\t}\n\tbreak;\n\t}\n}\n\nvoid COPTModel::decode_graph_prefix_order(ExpressionGraph &graph, const ExpressionHandle &result,\n                                          std::vector<int> &opcodes, std::vector<double> &constants)\n{\n\tstd::stack<ExpressionHandle> expr_stack;\n\n\t// init stack\n\texpr_stack.push(result);\n\n\twhile (!expr_stack.empty())\n\t{\n\t\tauto expr = expr_stack.top();\n\t\texpr_stack.pop();\n\n\t\t// We need to convert the n-arg multiplication to 2-arg multiplication\n\t\tif (expr.array == ArrayType::Nary && graph.m_naries[expr.id].op == NaryOperator::Mul)\n\t\t{\n\t\t\tauto &nary = graph.m_naries[expr.id];\n\t\t\tint n_operands = nary.operands.size();\n\n\t\t\tif (n_operands == 1)\n\t\t\t{\n\t\t\t\texpr = nary.operands[0];\n\t\t\t}\n\t\t\telse if (n_operands >= 2)\n\t\t\t{\n\t\t\t\tExpressionHandle left = nary.operands[0];\n\t\t\t\tExpressionHandle right = nary.operands[1];\n\t\t\t\tExpressionHandle new_expr = graph.add_binary(BinaryOperator::Mul2, left, right);\n\t\t\t\tfor (int i = 2; i < n_operands; i++)\n\t\t\t\t{\n\t\t\t\t\tnew_expr = graph.add_binary(BinaryOperator::Mul2, new_expr, nary.operands[i]);\n\t\t\t\t}\n\t\t\t\texpr = new_expr;\n\t\t\t}\n\t\t}\n\n\t\tdecode_expr(graph, expr, opcodes, constants);\n\n\t\tauto array_type = expr.array;\n\t\tauto index = expr.id;\n\t\tswitch (array_type)\n\t\t{\n\t\tcase ArrayType::Unary: {\n\t\t\tauto &unary = graph.m_unaries[index];\n\t\t\texpr_stack.push(unary.operand);\n\t\t\tbreak;\n\t\t}\n\t\tcase ArrayType::Binary: {\n\t\t\tauto &binary = graph.m_binaries[index];\n\t\t\texpr_stack.push(binary.right);\n\t\t\texpr_stack.push(binary.left);\n\t\t\tbreak;\n\t\t}\n\t\tcase ArrayType::Nary: {\n\t\t\tauto &nary = graph.m_naries[index];\n\t\t\tfor (int i = nary.operands.size() - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\texpr_stack.push(nary.operands[i]);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nConstraintIndex COPTModel::add_single_nl_constraint(ExpressionGraph &graph,\n                                                    const ExpressionHandle &result,\n                                                    const std::tuple<double, double> &interval,\n                                                    const char *name)\n{\n\tdouble lb = std::get<0>(interval);\n\tdouble ub = std::get<1>(interval);\n\n\tstd::vector<int> opcodes;\n\tstd::vector<double> constants;\n\n\tdecode_graph_prefix_order(graph, result, opcodes, constants);\n\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\n\t// add NL constraint\n\tint error =\n\t    copt::COPT_AddNLConstr(m_model.get(), opcodes.size(), constants.size(), opcodes.data(),\n\t                           constants.data(), 0, nullptr, nullptr, 0, lb, ub, name);\n\tcheck_error(error);\n\n\tIndexT constraint_index = m_nl_constraint_index.add_index();\n\n\tConstraintIndex constraint(ConstraintType::NL, constraint_index);\n\n\treturn constraint;\n}\n\nvoid COPTModel::delete_constraint(const ConstraintIndex &constraint)\n{\n\tint error = 0;\n\tint constraint_row = _constraint_index(constraint);\n\tif (constraint_row >= 0)\n\t{\n\t\tswitch (constraint.type)\n\t\t{\n\t\tcase ConstraintType::Linear:\n\t\t\tm_linear_constraint_index.delete_index(constraint.index);\n\t\t\terror = copt::COPT_DelRows(m_model.get(), 1, &constraint_row);\n\t\t\tbreak;\n\t\tcase ConstraintType::Quadratic:\n\t\t\tm_quadratic_constraint_index.delete_index(constraint.index);\n\t\t\terror = copt::COPT_DelQConstrs(m_model.get(), 1, &constraint_row);\n\t\t\tbreak;\n\t\tcase ConstraintType::SOS:\n\t\t\tm_sos_constraint_index.delete_index(constraint.index);\n\t\t\terror = copt::COPT_DelSOSs(m_model.get(), 1, &constraint_row);\n\t\t\tbreak;\n\t\tcase ConstraintType::SecondOrderCone:\n\t\t\tm_cone_constraint_index.delete_index(constraint.index);\n\t\t\terror = copt::COPT_DelCones(m_model.get(), 1, &constraint_row);\n\t\t\tbreak;\n\t\tcase ConstraintType::ExponentialCone:\n\t\t\tm_exp_cone_constraint_index.delete_index(constraint.index);\n\t\t\terror = copt::COPT_DelExpCones(m_model.get(), 1, &constraint_row);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t\t}\n\t}\n\tcheck_error(error);\n}\n\nbool COPTModel::is_constraint_active(const ConstraintIndex &constraint)\n{\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\t\treturn m_linear_constraint_index.has_index(constraint.index);\n\tcase ConstraintType::Quadratic:\n\t\treturn m_quadratic_constraint_index.has_index(constraint.index);\n\tcase ConstraintType::SOS:\n\t\treturn m_sos_constraint_index.has_index(constraint.index);\n\tcase ConstraintType::SecondOrderCone:\n\t\treturn m_cone_constraint_index.has_index(constraint.index);\n\tcase ConstraintType::ExponentialCone:\n\t\treturn m_exp_cone_constraint_index.has_index(constraint.index);\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n}\n\nvoid COPTModel::_set_affine_objective(const ScalarAffineFunction &function, ObjectiveSense sense,\n                                      bool clear_quadratic)\n{\n\tint error = 0;\n\tif (clear_quadratic)\n\t{\n\t\t// First delete all quadratic terms\n\t\terror = copt::COPT_DelQuadObj(m_model.get());\n\t\tcheck_error(error);\n\t}\n\n\t// Set Obj attribute of each variable\n\tint n_variables = get_raw_attribute_int(COPT_INTATTR_COLS);\n\tstd::vector<int> ind_v(n_variables);\n\tfor (int i = 0; i < n_variables; i++)\n\t{\n\t\tind_v[i] = i;\n\t}\n\tstd::vector<double> obj_v(n_variables, 0.0);\n\n\tint numnz = function.size();\n\tfor (int i = 0; i < numnz; i++)\n\t{\n\t\tauto column = _variable_index(function.variables[i]);\n\t\tif (column < 0)\n\t\t{\n\t\t\tthrow std::runtime_error(\"Variable does not exist\");\n\t\t}\n\t\tobj_v[column] = function.coefficients[i];\n\t}\n\n\terror = copt::COPT_ReplaceColObj(m_model.get(), n_variables, ind_v.data(), obj_v.data());\n\tcheck_error(error);\n\terror = copt::COPT_SetObjConst(m_model.get(), function.constant.value_or(0.0));\n\tcheck_error(error);\n\n\tint obj_sense = copt_obj_sense(sense);\n\terror = copt::COPT_SetObjSense(m_model.get(), obj_sense);\n\tcheck_error(error);\n}\n\nvoid COPTModel::set_objective(const ScalarAffineFunction &function, ObjectiveSense sense)\n{\n\t_set_affine_objective(function, sense, true);\n}\n\nvoid COPTModel::set_objective(const ScalarQuadraticFunction &function, ObjectiveSense sense)\n{\n\tint error = 0;\n\t// First delete all quadratic terms\n\terror = copt::COPT_DelQuadObj(m_model.get());\n\tcheck_error(error);\n\n\t// Add quadratic term\n\tint numqnz = function.size();\n\tif (numqnz > 0)\n\t{\n\t\tQuadraticFunctionPtrForm<int, int, double> ptr_form;\n\t\tptr_form.make(this, function);\n\t\tint numqnz = ptr_form.numnz;\n\t\tint *qrow = ptr_form.row;\n\t\tint *qcol = ptr_form.col;\n\t\tdouble *qval = ptr_form.value;\n\n\t\terror = copt::COPT_SetQuadObj(m_model.get(), numqnz, qrow, qcol, qval);\n\t\tcheck_error(error);\n\t}\n\n\t// Affine part\n\tconst auto &affine_part = function.affine_part;\n\tif (affine_part)\n\t{\n\t\tconst auto &affine_function = affine_part.value();\n\t\t_set_affine_objective(affine_function, sense, false);\n\t}\n\telse\n\t{\n\t\tScalarAffineFunction zero;\n\t\t_set_affine_objective(zero, sense, false);\n\t}\n}\n\nvoid COPTModel::set_objective(const ExprBuilder &function, ObjectiveSense sense)\n{\n\tauto deg = function.degree();\n\tif (deg <= 1)\n\t{\n\t\tScalarAffineFunction f(function);\n\t\tset_objective(f, sense);\n\t}\n\telse if (deg == 2)\n\t{\n\t\tScalarQuadraticFunction f(function);\n\t\tset_objective(f, sense);\n\t}\n\telse\n\t{\n\t\tthrow std::runtime_error(\"Objective must be linear or quadratic\");\n\t}\n}\n\nvoid COPTModel::add_single_nl_objective(ExpressionGraph &graph, const ExpressionHandle &result)\n{\n\tdecode_graph_prefix_order(graph, result, m_nl_objective_opcodes, m_nl_objective_constants);\n\n\tm_nl_objective_num += 1;\n\tm_nl_objective_opcodes[1] = m_nl_objective_num;\n}\n\nvoid COPTModel::set_nl_objective()\n{\n\tint error = 0;\n\tif (m_nl_objective_num > 0)\n\t{\n\t\tint nToken = m_nl_objective_opcodes.size();\n\t\tint nTokenElem = m_nl_objective_constants.size();\n\t\tint *token = m_nl_objective_opcodes.data();\n\t\tdouble *tokenElem = m_nl_objective_constants.data();\n\n\t\tif (m_nl_objective_num == 1)\n\t\t{\n\t\t\tnToken -= 2;\n\t\t\ttoken += 2;\n\t\t}\n\n\t\t/*fmt::print(\"COPT_SetNLObj opcodes: {}\\n\", std::vector<int>(token, token + nToken));\n\t\tfmt::print(\"COPT_SetNLObj constants: {}\\n\",\n\t\t           std::vector<double>(tokenElem, tokenElem + nTokenElem));*/\n\n\t\terror = copt::COPT_SetNLObj(m_model.get(), nToken, nTokenElem, token, tokenElem);\n\t\tcheck_error(error);\n\t}\n}\n\nvoid COPTModel::optimize()\n{\n\tif (has_callback)\n\t{\n\t\t// Store the number of variables for the callback\n\t\tm_callback_userdata.n_variables = get_raw_attribute_int(\"Cols\");\n\t}\n\tset_nl_objective();\n\tint error = copt::COPT_Solve(m_model.get());\n\tcheck_error(error);\n}\n\nint COPTModel::raw_parameter_attribute_type(const char *name)\n{\n\tint retval;\n\tint error = copt::COPT_SearchParamAttr(m_model.get(), name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nvoid COPTModel::set_raw_parameter_int(const char *param_name, int value)\n{\n\tint error = copt::COPT_SetIntParam(m_model.get(), param_name, value);\n\tcheck_error(error);\n}\n\nvoid COPTModel::set_raw_parameter_double(const char *param_name, double value)\n{\n\tint error = copt::COPT_SetDblParam(m_model.get(), param_name, value);\n\tcheck_error(error);\n}\n\nint COPTModel::get_raw_parameter_int(const char *param_name)\n{\n\tint retval;\n\tint error = copt::COPT_GetIntParam(m_model.get(), param_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble COPTModel::get_raw_parameter_double(const char *param_name)\n{\n\tdouble retval;\n\tint error = copt::COPT_GetDblParam(m_model.get(), param_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nint COPTModel::get_raw_attribute_int(const char *attr_name)\n{\n\tint retval;\n\tint error = copt::COPT_GetIntAttr(m_model.get(), attr_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble COPTModel::get_raw_attribute_double(const char *attr_name)\n{\n\tdouble retval;\n\tint error = copt::COPT_GetDblAttr(m_model.get(), attr_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble COPTModel::get_variable_info(const VariableIndex &variable, const char *info_name)\n{\n\tauto column = _checked_variable_index(variable);\n\tdouble retval;\n\tint error = copt::COPT_GetColInfo(m_model.get(), info_name, 1, &column, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nstd::string COPTModel::get_variable_name(const VariableIndex &variable)\n{\n\tauto column = _checked_variable_index(variable);\n\tint error;\n\tint reqsize;\n\terror = copt::COPT_GetColName(m_model.get(), column, NULL, 0, &reqsize);\n\tcheck_error(error);\n\tstd::string retval(reqsize - 1, '\\0');\n\terror = copt::COPT_GetColName(m_model.get(), column, retval.data(), reqsize, &reqsize);\n\tcheck_error(error);\n\treturn retval;\n}\n\nvoid COPTModel::set_variable_name(const VariableIndex &variable, const char *name)\n{\n\tauto column = _checked_variable_index(variable);\n\tconst char *names[] = {name};\n\tint error = copt::COPT_SetColNames(m_model.get(), 1, &column, names);\n\tcheck_error(error);\n}\n\nVariableDomain COPTModel::get_variable_type(const VariableIndex &variable)\n{\n\tauto column = _checked_variable_index(variable);\n\tchar vtype;\n\tint error = copt::COPT_GetColType(m_model.get(), 1, &column, &vtype);\n\tcheck_error(error);\n\treturn copt_vtype_to_domain(vtype);\n}\n\nvoid COPTModel::set_variable_type(const VariableIndex &variable, VariableDomain domain)\n{\n\tchar vtype = copt_vtype(domain);\n\tauto column = _checked_variable_index(variable);\n\tint error = copt::COPT_SetColType(m_model.get(), 1, &column, &vtype);\n\tcheck_error(error);\n}\n\nvoid COPTModel::set_variable_lower_bound(const VariableIndex &variable, double lb)\n{\n\tauto column = _checked_variable_index(variable);\n\tint error = copt::COPT_SetColLower(m_model.get(), 1, &column, &lb);\n\tcheck_error(error);\n}\n\nvoid COPTModel::set_variable_upper_bound(const VariableIndex &variable, double ub)\n{\n\tauto column = _checked_variable_index(variable);\n\tint error = copt::COPT_SetColUpper(m_model.get(), 1, &column, &ub);\n\tcheck_error(error);\n}\n\ndouble COPTModel::get_constraint_info(const ConstraintIndex &constraint, const char *info_name)\n{\n\tint row = _checked_constraint_index(constraint);\n\tdouble retval;\n\tint num = 1;\n\tint error;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\t\terror = copt::COPT_GetRowInfo(m_model.get(), info_name, num, &row, &retval);\n\t\tbreak;\n\tcase ConstraintType::Quadratic:\n\t\terror = copt::COPT_GetQConstrInfo(m_model.get(), info_name, num, &row, &retval);\n\t\tbreak;\n\tcase ConstraintType::NL:\n\t\terror = copt::COPT_GetNLConstrInfo(m_model.get(), info_name, num, &row, &retval);\n\t\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n\tcheck_error(error);\n\treturn retval;\n}\n\nstd::string COPTModel::get_constraint_name(const ConstraintIndex &constraint)\n{\n\tint row = _checked_constraint_index(constraint);\n\tint error;\n\tint reqsize;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\t\terror = copt::COPT_GetRowName(m_model.get(), row, NULL, 0, &reqsize);\n\t\tbreak;\n\tcase ConstraintType::Quadratic:\n\t\terror = copt::COPT_GetQConstrName(m_model.get(), row, NULL, 0, &reqsize);\n\t\tbreak;\n\tcase ConstraintType::NL:\n\t\terror = copt::COPT_GetNLConstrName(m_model.get(), row, NULL, 0, &reqsize);\n\t\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n\tcheck_error(error);\n\tstd::string retval(reqsize - 1, '\\0');\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\t\terror = copt::COPT_GetRowName(m_model.get(), row, retval.data(), reqsize, &reqsize);\n\t\tbreak;\n\tcase ConstraintType::Quadratic:\n\t\terror = copt::COPT_GetQConstrName(m_model.get(), row, retval.data(), reqsize, &reqsize);\n\t\tbreak;\n\t}\n\tcheck_error(error);\n\treturn retval;\n}\n\nvoid COPTModel::set_constraint_name(const ConstraintIndex &constraint, const char *name)\n{\n\tint row = _checked_constraint_index(constraint);\n\tconst char *names[] = {name};\n\tint error;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\t\terror = copt::COPT_SetRowNames(m_model.get(), 1, &row, names);\n\t\tbreak;\n\tcase ConstraintType::Quadratic:\n\t\terror = copt::COPT_SetQConstrNames(m_model.get(), 1, &row, names);\n\t\tbreak;\n\tcase ConstraintType::NL:\n\t\terror = copt::COPT_SetNLConstrNames(m_model.get(), 1, &row, names);\n\t\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n\tcheck_error(error);\n}\n\nvoid COPTModel::set_obj_sense(ObjectiveSense sense)\n{\n\tint obj_sense = copt_obj_sense(sense);\n\tint error = copt::COPT_SetObjSense(m_model.get(), obj_sense);\n\tcheck_error(error);\n}\n\nvoid COPTModel::add_mip_start(const Vector<VariableIndex> &variables, const Vector<double> &values)\n{\n\tif (variables.size() != values.size())\n\t{\n\t\tthrow std::runtime_error(\"Number of variables and values do not match\");\n\t}\n\tint numnz = variables.size();\n\tif (numnz == 0)\n\t\treturn;\n\n\tstd::vector<int> ind_v(numnz);\n\tfor (int i = 0; i < numnz; i++)\n\t{\n\t\tind_v[i] = _variable_index(variables[i].index);\n\t}\n\tint *ind = ind_v.data();\n\tdouble *val = (double *)values.data();\n\n\tint error = copt::COPT_AddMipStart(m_model.get(), numnz, ind, val);\n\tcheck_error(error);\n}\n\nvoid COPTModel::add_nl_start(const Vector<VariableIndex> &variables, const Vector<double> &values)\n{\n\tif (variables.size() != values.size())\n\t{\n\t\tthrow std::runtime_error(\"Number of variables and values do not match\");\n\t}\n\tint numnz = variables.size();\n\tif (numnz == 0)\n\t\treturn;\n\n\tstd::vector<int> ind_v(numnz);\n\tfor (int i = 0; i < numnz; i++)\n\t{\n\t\tind_v[i] = _variable_index(variables[i].index);\n\t}\n\tint *ind = ind_v.data();\n\tdouble *val = (double *)values.data();\n\n\tint error = copt::COPT_SetNLPrimalStart(m_model.get(), numnz, ind, val);\n\tcheck_error(error);\n}\n\ndouble COPTModel::get_normalized_rhs(const ConstraintIndex &constraint)\n{\n\tint row = _checked_constraint_index(constraint);\n\tint num = 1;\n\tint error;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear: {\n\t\tdouble lb, ub;\n\t\terror = copt::COPT_GetRowInfo(m_model.get(), COPT_DBLINFO_LB, num, &row, &lb);\n\t\tcheck_error(error);\n\t\terror = copt::COPT_GetRowInfo(m_model.get(), COPT_DBLINFO_UB, num, &row, &ub);\n\t\tcheck_error(error);\n\n\t\tbool lb_inf = lb < -COPT_INFINITY + 1.0;\n\t\tbool ub_inf = ub > COPT_INFINITY - 1.0;\n\n\t\tif (!lb_inf)\n\t\t\treturn lb;\n\t\tif (!ub_inf)\n\t\t\treturn ub;\n\n\t\tthrow std::runtime_error(\"Constraint has no finite bound\");\n\t}\n\tbreak;\n\tcase ConstraintType::Quadratic: {\n\t\tdouble rhs;\n\t\terror = copt::COPT_GetQConstrRhs(m_model.get(), num, &row, &rhs);\n\t\tcheck_error(error);\n\t\treturn rhs;\n\t}\n\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type to get_normalized_rhs\");\n\t}\n}\n\nvoid COPTModel::set_normalized_rhs(const ConstraintIndex &constraint, double value)\n{\n\tint row = _checked_constraint_index(constraint);\n\tint num = 1;\n\tint error;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear: {\n\t\tdouble lb, ub;\n\n\t\terror = copt::COPT_GetRowInfo(m_model.get(), COPT_DBLINFO_LB, num, &row, &lb);\n\t\tcheck_error(error);\n\t\terror = copt::COPT_GetRowInfo(m_model.get(), COPT_DBLINFO_UB, num, &row, &ub);\n\t\tcheck_error(error);\n\n\t\tbool lb_inf = lb < -COPT_INFINITY + 1.0;\n\t\tbool ub_inf = ub > COPT_INFINITY - 1.0;\n\n\t\tif (!lb_inf)\n\t\t{\n\t\t\terror = copt::COPT_SetRowLower(m_model.get(), num, &row, &value);\n\t\t\tcheck_error(error);\n\t\t}\n\t\tif (!ub_inf)\n\t\t{\n\t\t\terror = copt::COPT_SetRowUpper(m_model.get(), num, &row, &value);\n\t\t\tcheck_error(error);\n\t\t}\n\n\t\tif (lb_inf && ub_inf)\n\t\t{\n\t\t\tthrow std::runtime_error(\"Constraint has no finite bound\");\n\t\t}\n\t}\n\tbreak;\n\tcase ConstraintType::Quadratic: {\n\t\terror = copt::COPT_SetQConstrRhs(m_model.get(), num, &row, &value);\n\t\tcheck_error(error);\n\t}\n\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type to set_normalized_rhs\");\n\t}\n}\n\ndouble COPTModel::get_normalized_coefficient(const ConstraintIndex &constraint,\n                                             const VariableIndex &variable)\n{\n\tif (constraint.type != ConstraintType::Linear)\n\t{\n\t\tthrow std::runtime_error(\"Only linear constraint supports get_normalized_coefficient\");\n\t}\n\tint row = _checked_constraint_index(constraint);\n\tint col = _checked_variable_index(variable);\n\tdouble retval;\n\tint error = copt::COPT_GetElem(m_model.get(), col, row, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nvoid COPTModel::set_normalized_coefficient(const ConstraintIndex &constraint,\n                                           const VariableIndex &variable, double value)\n{\n\tif (constraint.type != ConstraintType::Linear)\n\t{\n\t\tthrow std::runtime_error(\"Only linear constraint supports set_normalized_coefficient\");\n\t}\n\tint row = _checked_constraint_index(constraint);\n\tint col = _checked_variable_index(variable);\n\tint error = copt::COPT_SetElem(m_model.get(), col, row, value);\n\tcheck_error(error);\n}\n\ndouble COPTModel::get_objective_coefficient(const VariableIndex &variable)\n{\n\treturn get_variable_info(variable, COPT_DBLINFO_OBJ);\n}\n\nvoid COPTModel::set_objective_coefficient(const VariableIndex &variable, double value)\n{\n\tauto column = _checked_variable_index(variable);\n\tint error = copt::COPT_SetColObj(m_model.get(), 1, &column, &value);\n\tcheck_error(error);\n}\n\nint COPTModel::_variable_index(const VariableIndex &variable)\n{\n\treturn m_variable_index.get_index(variable.index);\n}\n\nint COPTModel::_checked_variable_index(const VariableIndex &variable)\n{\n\tint column = _variable_index(variable);\n\tif (column < 0)\n\t{\n\t\tthrow std::runtime_error(\"Variable does not exist\");\n\t}\n\treturn column;\n}\n\nint COPTModel::_constraint_index(const ConstraintIndex &constraint)\n{\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\t\treturn m_linear_constraint_index.get_index(constraint.index);\n\tcase ConstraintType::Quadratic:\n\t\treturn m_quadratic_constraint_index.get_index(constraint.index);\n\tcase ConstraintType::SOS:\n\t\treturn m_sos_constraint_index.get_index(constraint.index);\n\tcase ConstraintType::SecondOrderCone:\n\t\treturn m_cone_constraint_index.get_index(constraint.index);\n\tcase ConstraintType::ExponentialCone:\n\t\treturn m_exp_cone_constraint_index.get_index(constraint.index);\n\tcase ConstraintType::NL:\n\t\treturn m_nl_constraint_index.get_index(constraint.index);\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n}\n\nint COPTModel::_checked_constraint_index(const ConstraintIndex &constraint)\n{\n\tint row = _constraint_index(constraint);\n\tif (row < 0)\n\t{\n\t\tthrow std::runtime_error(\"Constraint does not exist\");\n\t}\n\treturn row;\n}\n\nvoid *COPTModel::get_raw_model()\n{\n\treturn m_model.get();\n}\n\nstd::string COPTModel::version_string()\n{\n\tchar buffer[COPT_BUFFSIZE];\n\tcopt::COPT_GetBanner(buffer, COPT_BUFFSIZE);\n\treturn buffer;\n}\n\nCOPTEnv::COPTEnv()\n{\n\tif (!copt::is_library_loaded())\n\t{\n\t\tthrow std::runtime_error(\"COPT library is not loaded\");\n\t}\n\tint error = copt::COPT_CreateEnv(&m_env);\n\tcheck_error(error);\n}\n\nCOPTEnv::COPTEnv(COPTEnvConfig &config)\n{\n\tif (!copt::is_library_loaded())\n\t{\n\t\tthrow std::runtime_error(\"COPT library is not loaded\");\n\t}\n\tint error = copt::COPT_CreateEnvWithConfig(config.m_config, &m_env);\n\tcheck_error(error);\n}\n\nCOPTEnv::~COPTEnv()\n{\n\tint error = copt::COPT_DeleteEnv(&m_env);\n\tcheck_error(error);\n}\n\nvoid COPTEnv::close()\n{\n\tif (m_env != nullptr)\n\t{\n\t\tcopt::COPT_DeleteEnv(&m_env);\n\t}\n\tm_env = nullptr;\n}\n\nCOPTEnvConfig::COPTEnvConfig()\n{\n\tif (!copt::is_library_loaded())\n\t{\n\t\tthrow std::runtime_error(\"COPT library is not loaded\");\n\t}\n\tint error = copt::COPT_CreateEnvConfig(&m_config);\n\tcheck_error(error);\n}\n\nCOPTEnvConfig::~COPTEnvConfig()\n{\n\tint error = copt::COPT_DeleteEnvConfig(&m_config);\n\tcheck_error(error);\n}\n\nvoid COPTEnvConfig::set(const char *param_name, const char *value)\n{\n\tint error = copt::COPT_SetEnvConfig(m_config, param_name, value);\n\tcheck_error(error);\n}\n\n// Logging callback\nstatic void RealLoggingCallbackFunction(char *msg, void *logdata)\n{\n\tauto real_logdata = static_cast<COPTLoggingCallbackUserdata *>(logdata);\n\tauto &callback = real_logdata->callback;\n\tcallback(msg);\n}\n\nvoid COPTModel::set_logging(const COPTLoggingCallback &callback)\n{\n\tm_logging_callback_userdata.callback = callback;\n\tint error = copt::COPT_SetLogCallback(m_model.get(), &RealLoggingCallbackFunction,\n\t                                      &m_logging_callback_userdata);\n\tcheck_error(error);\n}\n\n// Callback\nstatic int RealCOPTCallbackFunction(copt_prob *prob, void *cbdata, int cbctx, void *userdata)\n{\n\tauto real_userdata = static_cast<COPTCallbackUserdata *>(userdata);\n\tauto model = static_cast<COPTModel *>(real_userdata->model);\n\tauto &callback = real_userdata->callback;\n\n\tmodel->m_cbdata = cbdata;\n\tmodel->m_callback_userdata.where = cbctx;\n\tmodel->m_callback_userdata.cb_get_mipsol_called = false;\n\tmodel->m_callback_userdata.cb_get_mipnoderel_called = false;\n\tmodel->m_callback_userdata.cb_get_mipincumbent_called = false;\n\tmodel->m_callback_userdata.cb_set_solution_called = false;\n\tmodel->m_callback_userdata.cb_requires_submit_solution = false;\n\tcallback(model, cbctx);\n\n\tif (model->m_callback_userdata.cb_requires_submit_solution)\n\t{\n\t\tmodel->cb_submit_solution();\n\t}\n\n\treturn COPT_RETCODE_OK;\n}\n\nvoid COPTModel::set_callback(const COPTCallback &callback, int cbctx)\n{\n\tm_callback_userdata.model = this;\n\tm_callback_userdata.callback = callback;\n\n\tint error = copt::COPT_SetCallback(m_model.get(), RealCOPTCallbackFunction, cbctx,\n\t                                   &m_callback_userdata);\n\tcheck_error(error);\n\n\thas_callback = true;\n}\n\nint COPTModel::cb_get_info_int(const std::string &what)\n{\n\tint retval;\n\tint error = copt::COPT_GetCallbackInfo(m_cbdata, what.c_str(), &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble COPTModel::cb_get_info_double(const std::string &what)\n{\n\tdouble retval;\n\tint error = copt::COPT_GetCallbackInfo(m_cbdata, what.c_str(), &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nvoid COPTModel::cb_get_info_doublearray(const std::string &what)\n{\n\tint n_vars = m_callback_userdata.n_variables;\n\tdouble *val = nullptr;\n\tif (what == COPT_CBINFO_MIPCANDIDATE)\n\t{\n\t\tm_callback_userdata.mipsol.resize(n_vars);\n\t\tval = m_callback_userdata.mipsol.data();\n\t}\n\telse if (what == COPT_CBINFO_RELAXSOLUTION)\n\t{\n\t\tm_callback_userdata.mipnoderel.resize(n_vars);\n\t\tval = m_callback_userdata.mipnoderel.data();\n\t}\n\telse if (what == COPT_CBINFO_INCUMBENT)\n\t{\n\t\tm_callback_userdata.mipincumbent.resize(n_vars);\n\t\tval = m_callback_userdata.mipincumbent.data();\n\t}\n\telse\n\t{\n\t\tthrow std::runtime_error(\"Invalid what for cb_get_info_doublearray\");\n\t}\n\tint error = copt::COPT_GetCallbackInfo(m_cbdata, what.c_str(), val);\n\tcheck_error(error);\n}\n\ndouble COPTModel::cb_get_solution(const VariableIndex &variable)\n{\n\tauto &userdata = m_callback_userdata;\n\tif (!userdata.cb_get_mipsol_called)\n\t{\n\t\tcb_get_info_doublearray(COPT_CBINFO_MIPCANDIDATE);\n\t\tuserdata.cb_get_mipsol_called = true;\n\t}\n\tauto index = _variable_index(variable);\n\treturn userdata.mipsol[index];\n}\n\ndouble COPTModel::cb_get_relaxation(const VariableIndex &variable)\n{\n\tauto &userdata = m_callback_userdata;\n\tif (!userdata.cb_get_mipnoderel_called)\n\t{\n\t\tcb_get_info_doublearray(COPT_CBINFO_RELAXSOLUTION);\n\t\tuserdata.cb_get_mipnoderel_called = true;\n\t}\n\tauto index = _variable_index(variable);\n\treturn userdata.mipnoderel[index];\n}\n\ndouble COPTModel::cb_get_incumbent(const VariableIndex &variable)\n{\n\tauto &userdata = m_callback_userdata;\n\tif (!userdata.cb_get_mipincumbent_called)\n\t{\n\t\tcb_get_info_doublearray(COPT_CBINFO_INCUMBENT);\n\t\tuserdata.cb_get_mipincumbent_called = true;\n\t}\n\tauto index = _variable_index(variable);\n\treturn userdata.mipincumbent[index];\n}\n\nvoid COPTModel::cb_set_solution(const VariableIndex &variable, double value)\n{\n\tauto &userdata = m_callback_userdata;\n\tif (!userdata.cb_set_solution_called)\n\t{\n\t\tuserdata.heuristic_solution.resize(userdata.n_variables, COPT_UNDEFINED);\n\t\tuserdata.cb_set_solution_called = true;\n\t}\n\tuserdata.heuristic_solution[_variable_index(variable)] = value;\n\tm_callback_userdata.cb_requires_submit_solution = true;\n}\n\ndouble COPTModel::cb_submit_solution()\n{\n\tif (!m_callback_userdata.cb_set_solution_called)\n\t{\n\t\tthrow std::runtime_error(\"No solution is set in the callback!\");\n\t}\n\tdouble obj;\n\tint error = copt::COPT_AddCallbackSolution(m_cbdata,\n\t                                           m_callback_userdata.heuristic_solution.data(), &obj);\n\tcheck_error(error);\n\tm_callback_userdata.cb_requires_submit_solution = false;\n\treturn obj;\n}\n\nvoid COPTModel::cb_exit()\n{\n\tint error = copt::COPT_Interrupt(m_model.get());\n\tcheck_error(error);\n}\n\nvoid COPTModel::cb_add_lazy_constraint(const ScalarAffineFunction &function, ConstraintSense sense,\n                                       CoeffT rhs)\n{\n\tAffineFunctionPtrForm<int, int, double> ptr_form;\n\tptr_form.make(this, function);\n\n\tint numnz = ptr_form.numnz;\n\tint *cind = ptr_form.index;\n\tdouble *cval = ptr_form.value;\n\tchar g_sense = copt_con_sense(sense);\n\tdouble g_rhs = rhs - function.constant.value_or(0.0);\n\n\tint error = copt::COPT_AddCallbackLazyConstr(m_cbdata, numnz, cind, cval, g_sense, g_rhs);\n\tcheck_error(error);\n}\n\nvoid COPTModel::cb_add_lazy_constraint(const ExprBuilder &function, ConstraintSense sense,\n                                       CoeffT rhs)\n{\n\tScalarAffineFunction f(function);\n\tcb_add_lazy_constraint(f, sense, rhs);\n}\n\nvoid COPTModel::cb_add_user_cut(const ScalarAffineFunction &function, ConstraintSense sense,\n                                CoeffT rhs)\n{\n\tAffineFunctionPtrForm<int, int, double> ptr_form;\n\tptr_form.make(this, function);\n\n\tint numnz = ptr_form.numnz;\n\tint *cind = ptr_form.index;\n\tdouble *cval = ptr_form.value;\n\tchar g_sense = copt_con_sense(sense);\n\tdouble g_rhs = rhs - function.constant.value_or(0.0);\n\n\tint error = copt::COPT_AddCallbackUserCut(m_cbdata, numnz, cind, cval, g_sense, g_rhs);\n\tcheck_error(error);\n}\n\nvoid COPTModel::cb_add_user_cut(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs)\n{\n\tScalarAffineFunction f(function);\n\tcb_add_user_cut(f, sense, rhs);\n}\n\nvoid COPTModel::computeIIS()\n{\n\tint error = copt::COPT_ComputeIIS(m_model.get());\n\tcheck_error(error);\n}\n\nint COPTModel::_get_variable_upperbound_IIS(const VariableIndex &variable)\n{\n\tauto column = _checked_variable_index(variable);\n\tint retval;\n\tint error = copt::COPT_GetColUpperIIS(m_model.get(), 1, &column, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nint COPTModel::_get_variable_lowerbound_IIS(const VariableIndex &variable)\n{\n\tauto column = _checked_variable_index(variable);\n\tint retval;\n\tint error = copt::COPT_GetColLowerIIS(m_model.get(), 1, &column, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nint COPTModel::_get_constraint_IIS(const ConstraintIndex &constraint)\n{\n\tint row = _checked_constraint_index(constraint);\n\tint num = 1;\n\tint error;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear: {\n\t\tint lb_iis, ub_iis;\n\n\t\terror = copt::COPT_GetRowLowerIIS(m_model.get(), num, &row, &lb_iis);\n\t\tcheck_error(error);\n\n\t\terror = copt::COPT_GetRowUpperIIS(m_model.get(), num, &row, &ub_iis);\n\t\tcheck_error(error);\n\n\t\treturn lb_iis + ub_iis;\n\t}\n\tbreak;\n\tcase ConstraintType::SOS: {\n\t\tint iis;\n\t\terror = copt::COPT_GetSOSIIS(m_model.get(), num, &row, &iis);\n\t\tcheck_error(error);\n\t\treturn iis;\n\t}\n\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type to get IIS state\");\n\t}\n}\n"
  },
  {
    "path": "lib/copt_model_ext.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include <nanobind/stl/string.h>\n#include <nanobind/stl/vector.h>\n#include <nanobind/stl/function.h>\n#include <nanobind/stl/tuple.h>\n\n#include \"pyoptinterface/copt_model.hpp\"\n\nnamespace nb = nanobind;\n\nextern void bind_copt_constants(nb::module_ &m);\n\nNB_MODULE(copt_model_ext, m)\n{\n\tm.import_(\"pyoptinterface._src.core_ext\");\n\n\tm.def(\"is_library_loaded\", &copt::is_library_loaded);\n\tm.def(\"load_library\", &copt::load_library);\n\n\tbind_copt_constants(m);\n\n\tnb::class_<COPTEnvConfig>(m, \"EnvConfig\").def(nb::init<>()).def(\"set\", &COPTEnvConfig::set);\n\n\tnb::class_<COPTEnv>(m, \"Env\")\n\t    .def(nb::init<>())\n\t    .def(nb::init<COPTEnvConfig &>())\n\t    .def(\"close\", &COPTEnv::close);\n\n#define BIND_F(f) .def(#f, &COPTModel::f)\n\tnb::class_<COPTModel>(m, \"RawModel\")\n\t    .def(nb::init<>())\n\t    .def(nb::init<const COPTEnv &>())\n\t    // clang-format off\n\t    BIND_F(init)\n\t    BIND_F(write)\n\t    BIND_F(close)\n\t    // clang-format on\n\n\t    .def(\"add_variable\", &COPTModel::add_variable,\n\t         nb::arg(\"domain\") = VariableDomain::Continuous, nb::arg(\"lb\") = -COPT_INFINITY,\n\t         nb::arg(\"ub\") = COPT_INFINITY, nb::arg(\"name\") = \"\")\n\t    // clang-format off\n\t    BIND_F(delete_variable)\n\t    BIND_F(delete_variables)\n\t    BIND_F(is_variable_active)\n\t    // clang-format on\n\t    .def(\"set_variable_bounds\", &COPTModel::set_variable_bounds, nb::arg(\"variable\"),\n\t         nb::arg(\"lb\"), nb::arg(\"ub\"))\n\n\t    .def(\"get_value\", nb::overload_cast<const VariableIndex &>(&COPTModel::get_variable_value))\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ScalarAffineFunction &>(&COPTModel::get_expression_value))\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &>(&COPTModel::get_expression_value))\n\t    .def(\"get_value\", nb::overload_cast<const ExprBuilder &>(&COPTModel::get_expression_value))\n\n\t    .def(\"pprint\", &COPTModel::pprint_variable)\n\t    .def(\"pprint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, int>(&COPTModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\t    .def(\"pprint\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, int>(&COPTModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\t    .def(\"pprint\", nb::overload_cast<const ExprBuilder &, int>(&COPTModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\n\t    .def(\"_add_linear_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ConstraintSense, CoeffT, const char *>(\n\t             &COPTModel::add_linear_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, const std::tuple<double, double> &,\n\t                           const char *>(&COPTModel::add_linear_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &COPTModel::add_linear_constraint_from_var, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &COPTModel::add_linear_interval_constraint_from_var,\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &COPTModel::add_linear_constraint_from_expr, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &COPTModel::add_linear_interval_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\n\t    .def(\"_add_quadratic_constraint\", &COPTModel::add_quadratic_constraint, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_quadratic_constraint\", &COPTModel::add_quadratic_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"add_second_order_cone_constraint\", &COPTModel::add_second_order_cone_constraint,\n\t         nb::arg(\"variables\"), nb::arg(\"name\") = \"\", nb::arg(\"rotated\") = false)\n\t    .def(\"add_exp_cone_constraint\", &COPTModel::add_exp_cone_constraint, nb::arg(\"variables\"),\n\t         nb::arg(\"name\") = \"\", nb::arg(\"dual\") = false)\n\t    .def(\"add_sos_constraint\", nb::overload_cast<const Vector<VariableIndex> &, SOSType>(\n\t                                   &COPTModel::add_sos_constraint))\n\t    .def(\"add_sos_constraint\",\n\t         nb::overload_cast<const Vector<VariableIndex> &, SOSType, const Vector<CoeffT> &>(\n\t             &COPTModel::add_sos_constraint))\n\n\t    .def(\"_add_single_nl_constraint\", &COPTModel::add_single_nl_constraint, nb::arg(\"graph\"),\n\t         nb::arg(\"result\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_single_nl_constraint\", &COPTModel::add_single_nl_constraint_sense_rhs,\n\t         nb::arg(\"graph\"), nb::arg(\"result\"), nb::arg(\"sense\"), nb::arg(\"rhs\"),\n\t         nb::arg(\"name\") = \"\")\n\t    .def(\"_add_single_nl_constraint\", &COPTModel::add_single_nl_constraint_from_comparison,\n\t         nb::arg(\"graph\"), nb::arg(\"expr\"), nb::arg(\"name\") = \"\")\n\n\t    // clang-format off\n\t\tBIND_F(delete_constraint)\n\t\tBIND_F(is_constraint_active)\n\t    // clang-format on\n\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, ObjectiveSense>(\n\t             &COPTModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ObjectiveSense>(\n\t             &COPTModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ExprBuilder &, ObjectiveSense>(&COPTModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\", &COPTModel::set_objective_as_variable, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\", &COPTModel::set_objective_as_constant, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\n\t    .def(\"_add_single_nl_objective\", &COPTModel::add_single_nl_objective)\n\n\t    .def(\"cb_add_lazy_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ConstraintSense, CoeffT>(\n\t             &COPTModel::cb_add_lazy_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"))\n\t    .def(\"cb_add_lazy_constraint\",\n\t         nb::overload_cast<const ExprBuilder &, ConstraintSense, CoeffT>(\n\t             &COPTModel::cb_add_lazy_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"))\n\t    .def(\"cb_add_user_cut\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ConstraintSense, CoeffT>(\n\t             &COPTModel::cb_add_user_cut),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"))\n\t    .def(\"cb_add_user_cut\",\n\t         nb::overload_cast<const ExprBuilder &, ConstraintSense, CoeffT>(\n\t             &COPTModel::cb_add_user_cut),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"))\n\n\t    .def(\"optimize\", &COPTModel::optimize, nb::call_guard<nb::gil_scoped_release>())\n\n\t    // clang-format off\n\t    BIND_F(version_string)\n\t    BIND_F(get_raw_model)\n\n\t\tBIND_F(set_logging)\n\n\t\tBIND_F(set_callback)\n\t\tBIND_F(cb_get_info_int)\n\t\tBIND_F(cb_get_info_double)\n\t\tBIND_F(cb_get_solution)\n\t\tBIND_F(cb_get_relaxation)\n\t\tBIND_F(cb_get_incumbent)\n\t\tBIND_F(cb_set_solution)\n\t\tBIND_F(cb_submit_solution)\n\t\tBIND_F(cb_exit)\n\n\t    BIND_F(raw_parameter_attribute_type)\n\n\t    BIND_F(set_raw_parameter_int)\n\t    BIND_F(set_raw_parameter_double)\n\t    BIND_F(get_raw_parameter_int)\n\t    BIND_F(get_raw_parameter_double)\n\n\t    BIND_F(get_raw_attribute_int)\n\t    BIND_F(get_raw_attribute_double)\n\n\t\tBIND_F(get_variable_info)\n\t    BIND_F(set_variable_name)\n\t    BIND_F(get_variable_name)\n\t    BIND_F(set_variable_type)\n\t    BIND_F(get_variable_type)\n\t    BIND_F(set_variable_lower_bound)\n\t    BIND_F(set_variable_upper_bound)\n\n\t\tBIND_F(get_constraint_info)\n\t    BIND_F(set_constraint_name)\n\t    BIND_F(get_constraint_name)\n\n\t    BIND_F(set_obj_sense)\n\n\t    BIND_F(add_mip_start)\n\t    BIND_F(add_nl_start)\n\n\t\tBIND_F(get_normalized_rhs)\n\t\tBIND_F(set_normalized_rhs)\n\t\tBIND_F(get_normalized_coefficient)\n\t\tBIND_F(set_normalized_coefficient)\n\t\tBIND_F(get_objective_coefficient)\n\t\tBIND_F(set_objective_coefficient)\n\n\t\tBIND_F(computeIIS)\n\t\tBIND_F(_get_variable_upperbound_IIS)\n\t\tBIND_F(_get_variable_lowerbound_IIS)\n\t\tBIND_F(_get_constraint_IIS)\n\t    // clang-format on\n\t    ;\n}"
  },
  {
    "path": "lib/copt_model_ext_constants.cpp",
    "content": "#include <nanobind/nanobind.h>\n\nnamespace nb = nanobind;\n\nvoid bind_copt_constants(nb::module_ &m)\n{\n\tnb::module_ COPT = m.def_submodule(\"COPT\");\n\tCOPT.attr(\"BASIS_BASIC\") = 1;\n\tCOPT.attr(\"BASIS_FIXED\") = 4;\n\tCOPT.attr(\"BASIS_LOWER\") = 0;\n\tCOPT.attr(\"BASIS_SUPERBASIC\") = 3;\n\tCOPT.attr(\"BASIS_UPPER\") = 2;\n\tCOPT.attr(\"BINARY\") = \"B\";\n\tCOPT.attr(\"CBCONTEXT_INCUMBENT\") = 8;\n\tCOPT.attr(\"CBCONTEXT_MIPNODE\") = 4;\n\tCOPT.attr(\"CBCONTEXT_MIPRELAX\") = 1;\n\tCOPT.attr(\"CBCONTEXT_MIPSOL\") = 2;\n\tCOPT.attr(\"CLIENT_CAFILE\") = \"CaFile\";\n\tCOPT.attr(\"CLIENT_CERTFILE\") = \"CertFile\";\n\tCOPT.attr(\"CLIENT_CERTKEYFILE\") = \"CertKeyFile\";\n\tCOPT.attr(\"CLIENT_CLUSTER\") = \"Cluster\";\n\tCOPT.attr(\"CLIENT_FLOATING\") = \"Floating\";\n\tCOPT.attr(\"CLIENT_PASSWORD\") = \"PassWord\";\n\tCOPT.attr(\"CLIENT_PORT\") = \"Port\";\n\tCOPT.attr(\"CLIENT_PRIORITY\") = \"Priority\";\n\tCOPT.attr(\"CLIENT_WAITTIME\") = \"WaitTime\";\n\tCOPT.attr(\"CLIENT_WEBACESSKEY\") = \"WebAccessKey\";\n\tCOPT.attr(\"CLIENT_WEBLICENSEID\") = \"WebLicenseId\";\n\tCOPT.attr(\"CLIENT_WEBSERVER\") = \"WebServer\";\n\tCOPT.attr(\"CLIENT_WEBTOKENDURATION\") = \"WebTokenDuration\";\n\tCOPT.attr(\"CONE_QUAD\") = 1;\n\tCOPT.attr(\"CONE_RQUAD\") = 2;\n\tCOPT.attr(\"CONTINUOUS\") = \"C\";\n\tCOPT.attr(\"EQUAL\") = \"E\";\n\tCOPT.attr(\"EXPCONE_DUAL\") = 4;\n\tCOPT.attr(\"EXPCONE_PRIMAL\") = 3;\n\tCOPT.attr(\"FREE\") = \"N\";\n\tCOPT.attr(\"GENCONSTR_ABS\") = 1;\n\tCOPT.attr(\"GENCONSTR_AND\") = 2;\n\tCOPT.attr(\"GENCONSTR_MAX\") = 3;\n\tCOPT.attr(\"GENCONSTR_MIN\") = 4;\n\tCOPT.attr(\"GENCONSTR_OR\") = 5;\n\tCOPT.attr(\"GENCONSTR_PWL\") = 6;\n\tCOPT.attr(\"GREATER_EQUAL\") = \"G\";\n\tCOPT.attr(\"IMPRECISE\") = 7;\n\tCOPT.attr(\"INDICATOR_IF\") = 1;\n\tCOPT.attr(\"INDICATOR_IFANDONLYIF\") = 3;\n\tCOPT.attr(\"INDICATOR_ONLYIF\") = 2;\n\tCOPT.attr(\"INFEASIBLE\") = 2;\n\tCOPT.attr(\"INFINITY\") = 1e+30;\n\tCOPT.attr(\"INF_OR_UNB\") = 4;\n\tCOPT.attr(\"INTEGER\") = \"I\";\n\tCOPT.attr(\"INTERRUPTED\") = 10;\n\tCOPT.attr(\"ITERLIMIT\") = 11;\n\tCOPT.attr(\"LESS_EQUAL\") = \"L\";\n\tCOPT.attr(\"MAXIMIZE\") = -1;\n\tCOPT.attr(\"MINIMIZE\") = 1;\n\tCOPT.attr(\"NODELIMIT\") = 6;\n\tCOPT.attr(\"NUMERICAL\") = 5;\n\tCOPT.attr(\"OPTIMAL\") = 1;\n\tCOPT.attr(\"RANGE\") = \"R\";\n\tCOPT.attr(\"SOS_TYPE1\") = 1;\n\tCOPT.attr(\"SOS_TYPE2\") = 2;\n\tCOPT.attr(\"TIMEOUT\") = 8;\n\tCOPT.attr(\"UNBOUNDED\") = 3;\n\tCOPT.attr(\"UNDEFINED\") = 1e+40;\n\tCOPT.attr(\"UNFINISHED\") = 9;\n\tCOPT.attr(\"UNSTARTED\") = 0;\n\tCOPT.attr(\"VERSION_MAJOR\") = 8;\n\tCOPT.attr(\"VERSION_MINOR\") = 0;\n\tCOPT.attr(\"VERSION_TECHNICAL\") = 1;\n\n\tnb::module_ Attr = COPT.def_submodule(\"Attr\");\n\tAttr.attr(\"AffineCones\") = \"AffineCones\";\n\tAttr.attr(\"BarrierIter\") = \"BarrierIter\";\n\tAttr.attr(\"BestBnd\") = \"BestBnd\";\n\tAttr.attr(\"BestGap\") = \"BestGap\";\n\tAttr.attr(\"BestObj\") = \"BestObj\";\n\tAttr.attr(\"Bins\") = \"Bins\";\n\tAttr.attr(\"Cols\") = \"Cols\";\n\tAttr.attr(\"Cones\") = \"Cones\";\n\tAttr.attr(\"Elems\") = \"Elems\";\n\tAttr.attr(\"ExpCones\") = \"ExpCones\";\n\tAttr.attr(\"FeasRelaxObj\") = \"FeasRelaxObj\";\n\tAttr.attr(\"HasBasis\") = \"HasBasis\";\n\tAttr.attr(\"HasBranchFactor\") = \"HasBranchFactor\";\n\tAttr.attr(\"HasDualFarkas\") = \"HasDualFarkas\";\n\tAttr.attr(\"HasFeasRelaxSol\") = \"HasFeasRelaxSol\";\n\tAttr.attr(\"HasIIS\") = \"HasIIS\";\n\tAttr.attr(\"HasLpSol\") = \"HasLpSol\";\n\tAttr.attr(\"HasMipSol\") = \"HasMipSol\";\n\tAttr.attr(\"HasNLObj\") = \"HasNLObj\";\n\tAttr.attr(\"HasPrimalRay\") = \"HasPrimalRay\";\n\tAttr.attr(\"HasPsdObj\") = \"HasPSDObj\";\n\tAttr.attr(\"HasQObj\") = \"HasQObj\";\n\tAttr.attr(\"HasSensitivity\") = \"HasSensitivity\";\n\tAttr.attr(\"IISCols\") = \"IISCols\";\n\tAttr.attr(\"IISIndicators\") = \"IISIndicators\";\n\tAttr.attr(\"IISRows\") = \"IISRows\";\n\tAttr.attr(\"IISSOSs\") = \"IISSOSs\";\n\tAttr.attr(\"Indicators\") = \"Indicators\";\n\tAttr.attr(\"Ints\") = \"Ints\";\n\tAttr.attr(\"IsMIP\") = \"IsMIP\";\n\tAttr.attr(\"IsMinIIS\") = \"IsMinIIS\";\n\tAttr.attr(\"LmiConstrs\") = \"LMIConstrs\";\n\tAttr.attr(\"LpObjVal\") = \"LpObjVal\";\n\tAttr.attr(\"LpStatus\") = \"LpStatus\";\n\tAttr.attr(\"MipStatus\") = \"MipStatus\";\n\tAttr.attr(\"MultiObjs\") = \"MultiObjs\";\n\tAttr.attr(\"NLConstrs\") = \"NLConstrs\";\n\tAttr.attr(\"NLElems\") = \"NLElems\";\n\tAttr.attr(\"NodeCnt\") = \"NodeCnt\";\n\tAttr.attr(\"ObjConst\") = \"ObjConst\";\n\tAttr.attr(\"ObjSense\") = \"ObjSense\";\n\tAttr.attr(\"PDLPIter\") = \"PDLPIter\";\n\tAttr.attr(\"PoolSols\") = \"PoolSols\";\n\tAttr.attr(\"PsdCols\") = \"PSDCols\";\n\tAttr.attr(\"PsdConstrs\") = \"PSDConstrs\";\n\tAttr.attr(\"PsdElems\") = \"PSDElems\";\n\tAttr.attr(\"QConstrs\") = \"QConstrs\";\n\tAttr.attr(\"QElems\") = \"QElems\";\n\tAttr.attr(\"Rows\") = \"Rows\";\n\tAttr.attr(\"SimplexIter\") = \"SimplexIter\";\n\tAttr.attr(\"SolvingTime\") = \"SolvingTime\";\n\tAttr.attr(\"Soss\") = \"Soss\";\n\tAttr.attr(\"SymMats\") = \"SymMats\";\n\tAttr.attr(\"TuneResults\") = \"TuneResults\";\n\n\tnb::module_ Param = COPT.def_submodule(\"Param\");\n\tParam.attr(\"AbsGap\") = \"AbsGap\";\n\tParam.attr(\"BarHomogeneous\") = \"BarHomogeneous\";\n\tParam.attr(\"BarIterLimit\") = \"BarIterLimit\";\n\tParam.attr(\"BarOrder\") = \"BarOrder\";\n\tParam.attr(\"BarStart\") = \"BarStart\";\n\tParam.attr(\"BarThreads\") = \"BarThreads\";\n\tParam.attr(\"ConflictAnalysis\") = \"ConflictAnalysis\";\n\tParam.attr(\"Crossover\") = \"Crossover\";\n\tParam.attr(\"CrossoverThreads\") = \"CrossoverThreads\";\n\tParam.attr(\"CutLevel\") = \"CutLevel\";\n\tParam.attr(\"DivingHeurLevel\") = \"DivingHeurLevel\";\n\tParam.attr(\"DualPerturb\") = \"DualPerturb\";\n\tParam.attr(\"DualPrice\") = \"DualPrice\";\n\tParam.attr(\"DualTol\") = \"DualTol\";\n\tParam.attr(\"Dualize\") = \"Dualize\";\n\tParam.attr(\"FAPHeurLevel\") = \"FAPHeurLevel\";\n\tParam.attr(\"FeasRelaxMode\") = \"FeasRelaxMode\";\n\tParam.attr(\"FeasTol\") = \"FeasTol\";\n\tParam.attr(\"GPUDevice\") = \"GPUDevice\";\n\tParam.attr(\"GPUMode\") = \"GPUMode\";\n\tParam.attr(\"HeurLevel\") = \"HeurLevel\";\n\tParam.attr(\"IISMethod\") = \"IISMethod\";\n\tParam.attr(\"IntTol\") = \"IntTol\";\n\tParam.attr(\"LazyConstraints\") = \"LazyConstraints\";\n\tParam.attr(\"LinearizeIndicators\") = \"LinearizeIndicators\";\n\tParam.attr(\"LinearizeSos\") = \"LinearizeSos\";\n\tParam.attr(\"LogToConsole\") = \"LogToConsole\";\n\tParam.attr(\"Logging\") = \"Logging\";\n\tParam.attr(\"LpMethod\") = \"LpMethod\";\n\tParam.attr(\"MatrixTol\") = \"MatrixTol\";\n\tParam.attr(\"MipStartMode\") = \"MipStartMode\";\n\tParam.attr(\"MipStartNodeLimit\") = \"MipStartNodeLimit\";\n\tParam.attr(\"MipTasks\") = \"MipTasks\";\n\tParam.attr(\"MultiObjAbsTol\") = \"MultiObjAbsTol\";\n\tParam.attr(\"MultiObjParamMode\") = \"MultiObjParamMode\";\n\tParam.attr(\"MultiObjPriority\") = \"MultiObjPriority\";\n\tParam.attr(\"MultiObjRelTol\") = \"MultiObjRelTol\";\n\tParam.attr(\"MultiObjTimeLimit\") = \"MultiObjTimeLimit\";\n\tParam.attr(\"MultiObjWeight\") = \"MultiObjWeight\";\n\tParam.attr(\"NLPIterLimit\") = \"NLPIterLimit\";\n\tParam.attr(\"NLPLinScale\") = \"NLPLinScale\";\n\tParam.attr(\"NLPMuUpdate\") = \"NLPMuUpdate\";\n\tParam.attr(\"NLPTol\") = \"NLPTol\";\n\tParam.attr(\"NodeCutRounds\") = \"NodeCutRounds\";\n\tParam.attr(\"NodeLimit\") = \"NodeLimit\";\n\tParam.attr(\"NonConvex\") = \"NonConvex\";\n\tParam.attr(\"PDLPTol\") = \"PDLPTol\";\n\tParam.attr(\"Presolve\") = \"Presolve\";\n\tParam.attr(\"RelGap\") = \"RelGap\";\n\tParam.attr(\"ReqFarkasRay\") = \"ReqFarkasRay\";\n\tParam.attr(\"ReqSensitivity\") = \"ReqSensitivity\";\n\tParam.attr(\"RootCutLevel\") = \"RootCutLevel\";\n\tParam.attr(\"RootCutRounds\") = \"RootCutRounds\";\n\tParam.attr(\"RoundingHeurLevel\") = \"RoundingHeurLevel\";\n\tParam.attr(\"SDPMethod\") = \"SDPMethod\";\n\tParam.attr(\"Scaling\") = \"Scaling\";\n\tParam.attr(\"SimplexThreads\") = \"SimplexThreads\";\n\tParam.attr(\"SolTimeLimit\") = \"SolTimeLimit\";\n\tParam.attr(\"StrongBranching\") = \"StrongBranching\";\n\tParam.attr(\"SubMipHeurLevel\") = \"SubMipHeurLevel\";\n\tParam.attr(\"Threads\") = \"Threads\";\n\tParam.attr(\"TimeLimit\") = \"TimeLimit\";\n\tParam.attr(\"TreeCutLevel\") = \"TreeCutLevel\";\n\tParam.attr(\"TuneMeasure\") = \"TuneMeasure\";\n\tParam.attr(\"TuneMethod\") = \"TuneMethod\";\n\tParam.attr(\"TuneMode\") = \"TuneMode\";\n\tParam.attr(\"TuneOutputLevel\") = \"TuneOutputLevel\";\n\tParam.attr(\"TunePermutes\") = \"TunePermutes\";\n\tParam.attr(\"TuneTargetRelGap\") = \"TuneTargetRelGap\";\n\tParam.attr(\"TuneTargetTime\") = \"TuneTargetTime\";\n\tParam.attr(\"TuneTimeLimit\") = \"TuneTimeLimit\";\n\n\tnb::module_ Info = COPT.def_submodule(\"Info\");\n\tInfo.attr(\"BranchFactor\") = \"BranchFactor\";\n\tInfo.attr(\"Dual\") = \"Dual\";\n\tInfo.attr(\"DualFarkas\") = \"DualFarkas\";\n\tInfo.attr(\"LB\") = \"LB\";\n\tInfo.attr(\"Obj\") = \"Obj\";\n\tInfo.attr(\"PrimalRay\") = \"PrimalRay\";\n\tInfo.attr(\"RedCost\") = \"RedCost\";\n\tInfo.attr(\"RelaxLB\") = \"RelaxLB\";\n\tInfo.attr(\"RelaxUB\") = \"RelaxUB\";\n\tInfo.attr(\"RelaxValue\") = \"RelaxValue\";\n\tInfo.attr(\"SALBLow\") = \"SALBLow\";\n\tInfo.attr(\"SALBUp\") = \"SALBUp\";\n\tInfo.attr(\"SAObjLow\") = \"SAObjLow\";\n\tInfo.attr(\"SAObjUp\") = \"SAObjUp\";\n\tInfo.attr(\"SAUBLow\") = \"SAUBLow\";\n\tInfo.attr(\"SAUBUp\") = \"SAUBUp\";\n\tInfo.attr(\"Slack\") = \"Slack\";\n\tInfo.attr(\"UB\") = \"UB\";\n\tInfo.attr(\"Value\") = \"Value\";\n\n\tnb::module_ CbInfo = COPT.def_submodule(\"CbInfo\");\n\tCbInfo.attr(\"BestBnd\") = \"BestBnd\";\n\tCbInfo.attr(\"BestObj\") = \"BestObj\";\n\tCbInfo.attr(\"HasIncumbent\") = \"HasIncumbent\";\n\tCbInfo.attr(\"Incumbent\") = \"Incumbent\";\n\tCbInfo.attr(\"MipCandObj\") = \"MipCandObj\";\n\tCbInfo.attr(\"MipCandidate\") = \"MipCandidate\";\n\tCbInfo.attr(\"NodeStatus\") = \"NodeStatus\";\n\tCbInfo.attr(\"RelaxSolObj\") = \"RelaxSolObj\";\n\tCbInfo.attr(\"RelaxSolution\") = \"RelaxSolution\";\n}\n"
  },
  {
    "path": "lib/core.cpp",
    "content": "#include \"pyoptinterface/core.hpp\"\n#include <algorithm>\n#include <stdexcept>\n\n#include \"fmt/core.h\"\n\nVariableIndex::VariableIndex(IndexT v) : index(v)\n{\n}\n\nScalarAffineFunction::ScalarAffineFunction(CoeffT c) : constant(c)\n{\n}\nScalarAffineFunction::ScalarAffineFunction(const VariableIndex &v)\n    : coefficients({1.0}), variables({v.index})\n{\n}\nScalarAffineFunction::ScalarAffineFunction(const VariableIndex &v, CoeffT c)\n    : coefficients({c}), variables({v.index})\n{\n}\nScalarAffineFunction::ScalarAffineFunction(const VariableIndex &v, CoeffT c1, CoeffT c2)\n    : coefficients({c1}), variables({v.index}), constant(c2)\n{\n}\nScalarAffineFunction::ScalarAffineFunction(const Vector<CoeffT> &a, const Vector<IndexT> &b)\n    : coefficients(a), variables(b)\n{\n}\nScalarAffineFunction::ScalarAffineFunction(const Vector<CoeffT> &a, const Vector<IndexT> &b,\n                                           const std::optional<CoeffT> &c)\n    : coefficients(a), variables(b), constant(c)\n{\n}\nScalarAffineFunction::ScalarAffineFunction(const ExprBuilder &t)\n{\n\tconst auto &affine_terms = t.affine_terms;\n\n\tauto N = affine_terms.size();\n\tcoefficients.reserve(N);\n\tvariables.reserve(N);\n\n\tfor (auto &[v, c] : affine_terms)\n\t{\n\t\tcoefficients.push_back(c);\n\t\tvariables.push_back(v);\n\t}\n\tif (t.constant_term)\n\t{\n\t\tconstant = t.constant_term.value();\n\t}\n}\n\nsize_t ScalarAffineFunction::size() const\n{\n\treturn coefficients.size();\n}\nvoid ScalarAffineFunction::canonicalize(CoeffT threshold)\n{\n\tExprBuilder t(*this);\n\tt.clean_nearzero_terms(threshold);\n\n\t// *this = ScalarAffineFunction(t);\n\t// sort coefficients and variable lock by lock with std::views::zip\n\t// std::ranges::sort(std::views::zip(variables, coefficients));\n\n\tvariables.clear();\n\tvariables.reserve(t.affine_terms.size());\n\tfor (const auto &it : t.affine_terms)\n\t{\n\t\tvariables.push_back(it.first);\n\t}\n\tstd::sort(variables.begin(), variables.end());\n\tcoefficients.clear();\n\tcoefficients.reserve(variables.size());\n\tfor (const auto &it : variables)\n\t{\n\t\tcoefficients.push_back(t.affine_terms[it]);\n\t}\n\tconstant = t.constant_term;\n}\n\nvoid ScalarAffineFunction::reserve(size_t n)\n{\n\tcoefficients.reserve(n);\n\tvariables.reserve(n);\n}\n\nvoid ScalarAffineFunction::add_term(const VariableIndex &v, CoeffT c)\n{\n\tcoefficients.push_back(c);\n\tvariables.push_back(v.index);\n}\n\nvoid ScalarAffineFunction::add_constant(CoeffT c)\n{\n\tconstant = constant.value_or(0.0) + c;\n}\n\nScalarQuadraticFunction::ScalarQuadraticFunction(const Vector<CoeffT> &c, const Vector<IndexT> &v1,\n                                                 const Vector<IndexT> &v2)\n    : coefficients(c), variable_1s(v1), variable_2s(v2)\n{\n}\nScalarQuadraticFunction::ScalarQuadraticFunction(const Vector<CoeffT> &c, const Vector<IndexT> &v1,\n                                                 const Vector<IndexT> &v2,\n                                                 const std::optional<ScalarAffineFunction> &a)\n    : coefficients(c), variable_1s(v1), variable_2s(v2), affine_part(a)\n{\n}\nScalarQuadraticFunction::ScalarQuadraticFunction(const ExprBuilder &t)\n{\n\tconst auto &quadratic_terms = t.quadratic_terms;\n\tauto N = quadratic_terms.size();\n\tcoefficients.reserve(N);\n\tvariable_1s.reserve(N);\n\tvariable_2s.reserve(N);\n\n\tfor (auto &[vp, c] : quadratic_terms)\n\t{\n\t\tcoefficients.push_back(c);\n\t\tvariable_1s.push_back(vp.var_1);\n\t\tvariable_2s.push_back(vp.var_2);\n\t}\n\tif (!t.affine_terms.empty() || t.constant_term)\n\t{\n\t\taffine_part = ScalarAffineFunction(t);\n\t}\n}\nsize_t ScalarQuadraticFunction::size() const\n{\n\treturn coefficients.size();\n}\nvoid ScalarQuadraticFunction::canonicalize(CoeffT threshold)\n{\n\tExprBuilder t(*this);\n\tt.clean_nearzero_terms(threshold);\n\n\t// *this = ScalarQuadraticFunction(t);\n\t// std::ranges::sort(std::views::zip(variable_1s, variable_2s, coefficients));\n\n\tauto N = t.quadratic_terms.size();\n\tstd::vector<VariablePair> varpairs;\n\tvarpairs.reserve(N);\n\tfor (const auto &it : t.quadratic_terms)\n\t{\n\t\tvarpairs.emplace_back(it.first);\n\t}\n\tstd::sort(varpairs.begin(), varpairs.end());\n\tvariable_1s.clear();\n\tvariable_1s.reserve(N);\n\tvariable_2s.clear();\n\tvariable_2s.reserve(N);\n\tcoefficients.clear();\n\tcoefficients.reserve(N);\n\tfor (const auto &it : varpairs)\n\t{\n\t\tvariable_1s.push_back(it.var_1);\n\t\tvariable_2s.push_back(it.var_2);\n\t\tcoefficients.push_back(t.quadratic_terms[it]);\n\t}\n\n\tif (affine_part)\n\t{\n\t\tauto &affine_function = affine_part.value();\n\t\taffine_function.canonicalize(threshold);\n\t}\n}\n\nvoid ScalarQuadraticFunction::reserve_quadratic(size_t n)\n{\n\tcoefficients.reserve(n);\n\tvariable_1s.reserve(n);\n\tvariable_2s.reserve(n);\n}\n\nvoid ScalarQuadraticFunction::reserve_affine(size_t n)\n{\n\tif (n > 0)\n\t{\n\t\tif (!affine_part)\n\t\t{\n\t\t\taffine_part = ScalarAffineFunction();\n\t\t}\n\t\taffine_part.value().reserve(n);\n\t}\n}\n\nvoid ScalarQuadraticFunction::add_quadratic_term(const VariableIndex &v1, const VariableIndex &v2,\n                                                 CoeffT c)\n{\n\tcoefficients.push_back(c);\n\tvariable_1s.push_back(v1.index);\n\tvariable_2s.push_back(v2.index);\n}\n\nvoid ScalarQuadraticFunction::add_affine_term(const VariableIndex &v, CoeffT c)\n{\n\tif (!affine_part)\n\t{\n\t\taffine_part = ScalarAffineFunction();\n\t}\n\taffine_part.value().add_term(v, c);\n}\n\nvoid ScalarQuadraticFunction::add_constant(CoeffT c)\n{\n\tif (!affine_part)\n\t{\n\t\taffine_part = ScalarAffineFunction(c);\n\t}\n\telse\n\t{\n\t\taffine_part.value().add_constant(c);\n\t}\n}\n\nbool VariablePair::operator==(const VariablePair &x) const\n{\n\treturn var_1 == x.var_1 && var_2 == x.var_2;\n}\nbool VariablePair::operator<(const VariablePair &x) const\n{\n\tif (var_1 != x.var_1)\n\t\treturn var_1 < x.var_1;\n\telse\n\t\treturn var_2 < x.var_2;\n}\n\nExprBuilder::ExprBuilder(CoeffT c)\n{\n\toperator+=(c);\n}\n\nExprBuilder::ExprBuilder(const VariableIndex &v)\n{\n\toperator+=(v);\n}\n\nExprBuilder::ExprBuilder(const ScalarAffineFunction &a)\n{\n\tauto N = a.coefficients.size();\n\taffine_terms.reserve(N);\n\n\toperator+=(a);\n}\n\nExprBuilder::ExprBuilder(const ScalarQuadraticFunction &q)\n{\n\tif (q.affine_part)\n\t{\n\t\taffine_terms.reserve(q.affine_part.value().coefficients.size());\n\t}\n\tauto N = q.coefficients.size();\n\tquadratic_terms.reserve(N);\n\n\toperator+=(q);\n}\n\nbool ExprBuilder::empty() const\n{\n\treturn quadratic_terms.empty() && affine_terms.empty() && !constant_term;\n}\n\nint ExprBuilder::degree() const\n{\n\tif (!quadratic_terms.empty())\n\t{\n\t\treturn 2;\n\t}\n\tif (!affine_terms.empty())\n\t{\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nvoid ExprBuilder::reserve_quadratic(size_t n)\n{\n\tquadratic_terms.reserve(n);\n}\n\nvoid ExprBuilder::reserve_affine(size_t n)\n{\n\taffine_terms.reserve(n);\n}\n\nvoid ExprBuilder::clear()\n{\n\tquadratic_terms.clear();\n\taffine_terms.clear();\n\tconstant_term.reset();\n}\n\nvoid ExprBuilder::clean_nearzero_terms(CoeffT threshold)\n{\n\t// clear all coefficients if abs(coefficient) < threshold\n\tfor (auto it = quadratic_terms.begin(); it != quadratic_terms.end();)\n\t{\n\t\tif (std::abs(it->second) < threshold)\n\t\t{\n\t\t\tit = quadratic_terms.erase(it);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t++it;\n\t\t}\n\t}\n\tfor (auto it = affine_terms.begin(); it != affine_terms.end();)\n\t{\n\t\tif (std::abs(it->second) < threshold)\n\t\t{\n\t\t\tit = affine_terms.erase(it);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t++it;\n\t\t}\n\t}\n\tif (constant_term && std::abs(*constant_term) < threshold)\n\t{\n\t\tconstant_term.reset();\n\t}\n}\n\nvoid ExprBuilder::_add_quadratic_term(IndexT i, IndexT j, CoeffT coeff)\n{\n\tif (i > j)\n\t{\n\t\tstd::swap(i, j);\n\t}\n\tVariablePair vp{i, j};\n\tauto ret = quadratic_terms.emplace(vp, coeff);\n\tif (!ret.second)\n\t{\n\t\tauto &iter = ret.first;\n\t\titer->second += coeff;\n\t}\n}\nvoid ExprBuilder::_set_quadratic_coef(IndexT i, IndexT j, CoeffT coeff)\n{\n\tif (i > j)\n\t{\n\t\tstd::swap(i, j);\n\t}\n\tVariablePair vp{i, j};\n\tauto ret = quadratic_terms.emplace(vp, coeff);\n\tif (!ret.second)\n\t{\n\t\tauto &iter = ret.first;\n\t\titer->second = coeff;\n\t}\n}\nvoid ExprBuilder::add_quadratic_term(const VariableIndex &i, const VariableIndex &j, CoeffT coeff)\n{\n\t_add_quadratic_term(i.index, j.index, coeff);\n}\nvoid ExprBuilder::set_quadratic_coef(const VariableIndex &i, const VariableIndex &j, CoeffT coeff)\n{\n\t_set_quadratic_coef(i.index, j.index, coeff);\n}\n\nvoid ExprBuilder::_add_affine_term(IndexT i, CoeffT coeff)\n{\n\tauto ret = affine_terms.emplace(i, coeff);\n\tif (!ret.second)\n\t{\n\t\tauto &iter = ret.first;\n\t\titer->second += coeff;\n\t}\n}\nvoid ExprBuilder::_set_affine_coef(IndexT i, CoeffT coeff)\n{\n\tauto ret = affine_terms.emplace(i, coeff);\n\tif (!ret.second)\n\t{\n\t\tauto &iter = ret.first;\n\t\titer->second = coeff;\n\t}\n}\nvoid ExprBuilder::add_affine_term(const VariableIndex &i, CoeffT coeff)\n{\n\t_add_affine_term(i.index, coeff);\n}\nvoid ExprBuilder::set_affine_coef(const VariableIndex &i, CoeffT coeff)\n{\n\t_set_affine_coef(i.index, coeff);\n}\n\nExprBuilder &ExprBuilder::operator+=(CoeffT c)\n{\n\tconstant_term = constant_term.value_or(0.0) + c;\n\treturn *this;\n}\nExprBuilder &ExprBuilder::operator+=(const VariableIndex &v)\n{\n\t_add_affine_term(v.index, 1.0);\n\treturn *this;\n}\nExprBuilder &ExprBuilder::operator+=(const ScalarAffineFunction &a)\n{\n\tauto N = a.coefficients.size();\n\tfor (auto i = 0; i < N; i++)\n\t{\n\t\t_add_affine_term(a.variables[i], a.coefficients[i]);\n\t}\n\n\tif (a.constant)\n\t{\n\t\tconstant_term = constant_term.value_or(0.0) + a.constant.value();\n\t}\n\treturn *this;\n}\nExprBuilder &ExprBuilder::operator+=(const ScalarQuadraticFunction &q)\n{\n\tif (q.affine_part)\n\t{\n\t\toperator+=(q.affine_part.value());\n\t}\n\n\tauto N = q.coefficients.size();\n\tfor (auto i = 0; i < N; i++)\n\t{\n\t\t_add_quadratic_term(q.variable_1s[i], q.variable_2s[i], q.coefficients[i]);\n\t}\n\treturn *this;\n}\nExprBuilder &ExprBuilder::operator+=(const ExprBuilder &t)\n{\n\tif (this == &t)\n\t{\n\t\tfor (auto &[varpair, c] : quadratic_terms)\n\t\t{\n\t\t\tc *= 2.0;\n\t\t}\n\t\tfor (auto &[v, c] : affine_terms)\n\t\t{\n\t\t\tc *= 2.0;\n\t\t}\n\t\tif (constant_term)\n\t\t{\n\t\t\tconstant_term = constant_term.value() * 2.0;\n\t\t}\n\t}\n\telse\n\t{\n\t\tfor (const auto &[varpair, c] : t.quadratic_terms)\n\t\t{\n\t\t\t_add_quadratic_term(varpair.var_1, varpair.var_2, c);\n\t\t}\n\t\tfor (const auto &[v, c] : t.affine_terms)\n\t\t{\n\t\t\t_add_affine_term(v, c);\n\t\t}\n\t\tif (t.constant_term)\n\t\t{\n\t\t\tconstant_term = constant_term.value_or(0.0) + t.constant_term.value();\n\t\t}\n\t}\n\treturn *this;\n}\n\nExprBuilder &ExprBuilder::operator-=(CoeffT c)\n{\n\tconstant_term = constant_term.value_or(0.0) - c;\n\treturn *this;\n}\nExprBuilder &ExprBuilder::operator-=(const VariableIndex &v)\n{\n\t_add_affine_term(v.index, -1.0);\n\treturn *this;\n}\nExprBuilder &ExprBuilder::operator-=(const ScalarAffineFunction &a)\n{\n\tauto N = a.coefficients.size();\n\tfor (auto i = 0; i < N; i++)\n\t{\n\t\t_add_affine_term(a.variables[i], -a.coefficients[i]);\n\t}\n\n\tif (a.constant)\n\t{\n\t\tconstant_term = constant_term.value_or(0.0) - a.constant.value();\n\t}\n\treturn *this;\n}\nExprBuilder &ExprBuilder::operator-=(const ScalarQuadraticFunction &q)\n{\n\tif (q.affine_part)\n\t{\n\t\toperator-=(q.affine_part.value());\n\t}\n\n\tauto N = q.coefficients.size();\n\tfor (auto i = 0; i < N; i++)\n\t{\n\t\t_add_quadratic_term(q.variable_1s[i], q.variable_2s[i], -q.coefficients[i]);\n\t}\n\treturn *this;\n}\nExprBuilder &ExprBuilder::operator-=(const ExprBuilder &t)\n{\n\tif (this == &t)\n\t{\n\t\tquadratic_terms.clear();\n\t\taffine_terms.clear();\n\t\tconstant_term.reset();\n\t}\n\telse\n\t{\n\t\tfor (const auto &[varpair, c] : t.quadratic_terms)\n\t\t{\n\t\t\t_add_quadratic_term(varpair.var_1, varpair.var_2, -c);\n\t\t}\n\t\tfor (const auto &[v, c] : t.affine_terms)\n\t\t{\n\t\t\t_add_affine_term(v, -c);\n\t\t}\n\t\tif (t.constant_term)\n\t\t{\n\t\t\tconstant_term = constant_term.value_or(0.0) - t.constant_term.value();\n\t\t}\n\t}\n\treturn *this;\n}\n\nExprBuilder &ExprBuilder::operator*=(CoeffT c)\n{\n\tfor (auto &[varpair, cc] : quadratic_terms)\n\t{\n\t\tcc *= c;\n\t}\n\tfor (auto &[v, cc] : affine_terms)\n\t{\n\t\tcc *= c;\n\t}\n\tif (constant_term)\n\t{\n\t\tconstant_term = constant_term.value() * c;\n\t}\n\treturn *this;\n}\nExprBuilder &ExprBuilder::operator*=(const VariableIndex &v)\n{\n\tauto deg = degree();\n\tif (deg > 1)\n\t{\n\t\tthrow std::logic_error(\n\t\t    fmt::format(\"ExprBuilder with degree {} cannot multiply with VariableIndex\", deg));\n\t}\n\n\tauto N = affine_terms.size();\n\tquadratic_terms.reserve(N);\n\tfor (const auto &[var2, c] : affine_terms)\n\t{\n\t\t_add_quadratic_term(v.index, var2, c);\n\t}\n\n\tif (constant_term)\n\t{\n\t\taffine_terms = {{v.index, constant_term.value()}};\n\t\tconstant_term.reset();\n\t}\n\telse\n\t{\n\t\taffine_terms.clear();\n\t}\n\treturn *this;\n}\nExprBuilder &ExprBuilder::operator*=(const ScalarAffineFunction &a)\n{\n\tauto deg = degree();\n\tif (deg > 1)\n\t{\n\t\tthrow std::logic_error(fmt::format(\n\t\t    \"ExprBuilder with degree {} cannot multiply with ScalarAffineFunction\", deg));\n\t}\n\n\tauto N1 = affine_terms.size();\n\tauto N2 = a.size();\n\tquadratic_terms.reserve(N1 * N2 / 2);\n\tfor (const auto &[xi, ci] : affine_terms)\n\t{\n\t\tfor (int j = 0; j < a.size(); j++)\n\t\t{\n\t\t\tauto dj = a.coefficients[j];\n\t\t\tauto xj = a.variables[j];\n\t\t\t_add_quadratic_term(xi, xj, ci * dj);\n\t\t}\n\t}\n\n\tif (a.constant)\n\t{\n\t\tauto d0 = a.constant.value();\n\t\tfor (auto &[_, ci] : affine_terms)\n\t\t{\n\t\t\tci *= d0;\n\t\t}\n\t}\n\telse\n\t{\n\t\taffine_terms.clear();\n\t}\n\n\tif (constant_term)\n\t{\n\t\tauto c0 = constant_term.value();\n\t\tfor (int j = 0; j < a.size(); j++)\n\t\t{\n\t\t\tauto dj = a.coefficients[j];\n\t\t\tauto xj = a.variables[j];\n\t\t\t_add_affine_term(xj, c0 * dj);\n\t\t}\n\t}\n\n\tif (a.constant && constant_term)\n\t{\n\t\tconstant_term = a.constant.value() * constant_term.value();\n\t}\n\telse\n\t{\n\t\tconstant_term.reset();\n\t}\n\treturn *this;\n}\nExprBuilder &ExprBuilder::operator*=(const ScalarQuadraticFunction &q)\n{\n\tauto deg = degree();\n\tif (deg > 0)\n\t{\n\t\tthrow std::logic_error(fmt::format(\n\t\t    \"ExprBuilder with degree {} cannot multiply with ScalarQuadraticFunction\", deg));\n\t}\n\n\tif (!constant_term)\n\t\treturn *this;\n\n\tauto c = constant_term.value();\n\t{\n\t\tauto N = q.coefficients.size();\n\t\tquadratic_terms.reserve(N);\n\t\tfor (auto i = 0; i < N; i++)\n\t\t{\n\t\t\t_add_quadratic_term(q.variable_1s[i], q.variable_2s[i], c * q.coefficients[i]);\n\t\t}\n\t}\n\tif (q.affine_part)\n\t{\n\t\tauto &affine_part = q.affine_part.value();\n\t\tauto N = affine_part.coefficients.size();\n\t\taffine_terms.reserve(N);\n\t\tfor (auto i = 0; i < N; i++)\n\t\t{\n\t\t\t_add_affine_term(affine_part.variables[i], c * affine_part.coefficients[i]);\n\t\t}\n\n\t\tif (affine_part.constant)\n\t\t{\n\t\t\tconstant_term = c * affine_part.constant.value();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tconstant_term.reset();\n\t\t}\n\t}\n\telse\n\t{\n\t\tconstant_term.reset();\n\t}\n\treturn *this;\n}\nExprBuilder &ExprBuilder::operator*=(const ExprBuilder &t)\n{\n\tauto deg1 = degree();\n\tauto deg2 = t.degree();\n\tif (deg1 + deg2 > 2)\n\t{\n\t\tthrow std::logic_error(fmt::format(\n\t\t    \"ExprBuilder with degree {} cannot multiply with ExprBuilder with degree {}\", deg1,\n\t\t    deg2));\n\t}\n\n\tif (this == &t)\n\t{\n\t\tauto deg = deg1;\n\n\t\tif (deg == 0)\n\t\t{\n\t\t\tif (constant_term)\n\t\t\t{\n\t\t\t\tauto c = constant_term.value();\n\t\t\t\tconstant_term = c * c;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t// deg = 1\n\t\t{\n\t\t\tauto N = affine_terms.size();\n\t\t\tquadratic_terms.reserve(N * N / 2);\n\t\t\tfor (const auto &[xi, ci] : affine_terms)\n\t\t\t{\n\t\t\t\tfor (const auto &[xj, cj] : affine_terms)\n\t\t\t\t{\n\t\t\t\t\t_add_quadratic_term(xi, xj, ci * cj);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (constant_term)\n\t\t\t{\n\t\t\t\tauto d0 = constant_term.value();\n\t\t\t\tfor (auto &[_, ci] : affine_terms)\n\t\t\t\t{\n\t\t\t\t\tci *= 2.0 * d0;\n\t\t\t\t}\n\t\t\t\tconstant_term = d0 * d0;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\taffine_terms.clear();\n\t\t\t}\n\t\t}\n\t}\n\telse\n\t{\n\t\tif (deg1 == 0)\n\t\t{\n\t\t\tif (constant_term)\n\t\t\t{\n\t\t\t\tauto c = constant_term.value();\n\n\t\t\t\tauto N = t.quadratic_terms.size();\n\t\t\t\tquadratic_terms.reserve(N);\n\t\t\t\tfor (const auto &[varpair, c2] : t.quadratic_terms)\n\t\t\t\t{\n\t\t\t\t\t_add_quadratic_term(varpair.var_1, varpair.var_2, c * c2);\n\t\t\t\t}\n\n\t\t\t\tN = t.affine_terms.size();\n\t\t\t\taffine_terms.reserve(N);\n\t\t\t\tfor (const auto &[v, c1] : t.affine_terms)\n\t\t\t\t{\n\t\t\t\t\t_add_affine_term(v, c * c1);\n\t\t\t\t}\n\n\t\t\t\tif (t.constant_term)\n\t\t\t\t{\n\t\t\t\t\tconstant_term = c * t.constant_term.value();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tconstant_term.reset();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse if (deg1 == 1)\n\t\t{\n\t\t\tif (deg2 == 1)\n\t\t\t{\n\t\t\t\tauto N1 = affine_terms.size();\n\t\t\t\tauto N2 = t.affine_terms.size();\n\t\t\t\tquadratic_terms.reserve(N1 * N2 / 2);\n\t\t\t\tfor (const auto &[xi, ci] : affine_terms)\n\t\t\t\t{\n\t\t\t\t\tfor (const auto &[xj, dj] : t.affine_terms)\n\t\t\t\t\t{\n\t\t\t\t\t\t_add_quadratic_term(xi, xj, ci * dj);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (t.constant_term)\n\t\t\t{\n\t\t\t\tauto d0 = t.constant_term.value();\n\t\t\t\tfor (auto &[_, ci] : affine_terms)\n\t\t\t\t{\n\t\t\t\t\tci *= d0;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\taffine_terms.clear();\n\t\t\t}\n\n\t\t\tif (constant_term)\n\t\t\t{\n\t\t\t\tauto c0 = constant_term.value();\n\t\t\t\tfor (const auto &[xj, dj] : t.affine_terms)\n\t\t\t\t{\n\t\t\t\t\t_add_affine_term(xj, c0 * dj);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (t.constant_term && constant_term)\n\t\t\t{\n\t\t\t\tconstant_term = t.constant_term.value() * constant_term.value();\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tconstant_term.reset();\n\t\t\t}\n\t\t}\n\t\telse if (deg1 == 2)\n\t\t{\n\t\t\tif (t.constant_term)\n\t\t\t{\n\t\t\t\tauto c = t.constant_term.value();\n\n\t\t\t\tfor (auto &[_, c2] : quadratic_terms)\n\t\t\t\t{\n\t\t\t\t\tc2 *= c;\n\t\t\t\t}\n\n\t\t\t\tfor (auto &[_, c1] : affine_terms)\n\t\t\t\t{\n\t\t\t\t\tc1 *= c;\n\t\t\t\t}\n\n\t\t\t\tif (constant_term)\n\t\t\t\t{\n\t\t\t\t\tconstant_term = c * constant_term.value();\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tclear();\n\t\t\t}\n\t\t}\n\t}\n\treturn *this;\n}\n\nExprBuilder &ExprBuilder::operator/=(CoeffT c)\n{\n\tfor (auto &[varpair, cc] : quadratic_terms)\n\t{\n\t\tcc /= c;\n\t}\n\tfor (auto &[v, cc] : affine_terms)\n\t{\n\t\tcc /= c;\n\t}\n\tif (constant_term)\n\t{\n\t\tconstant_term = constant_term.value() / c;\n\t}\n\treturn *this;\n}\n\n// Operator overloading functions\n\nauto operator+(const VariableIndex &a, CoeffT b) -> ScalarAffineFunction\n{\n\treturn ScalarAffineFunction(a, 1.0, b);\n}\nauto operator+(CoeffT a, const VariableIndex &b) -> ScalarAffineFunction\n{\n\treturn b + a;\n}\n\nauto operator+(const VariableIndex &a, const VariableIndex &b) -> ScalarAffineFunction\n{\n\treturn ScalarAffineFunction({1.0, 1.0}, {a.index, b.index});\n}\n\nauto operator+(const ScalarAffineFunction &a, CoeffT b) -> ScalarAffineFunction\n{\n\tCoeffT new_constant = a.constant.value_or(0.0) + b;\n\treturn ScalarAffineFunction(a.coefficients, a.variables, new_constant);\n}\nauto operator+(CoeffT a, const ScalarAffineFunction &b) -> ScalarAffineFunction\n{\n\treturn b + a;\n}\n\nauto operator+(const ScalarAffineFunction &a, const VariableIndex &b) -> ScalarAffineFunction\n{\n\tauto coefficients = a.coefficients;\n\tauto variables = a.variables;\n\tcoefficients.push_back(1.0);\n\tvariables.push_back(b.index);\n\treturn ScalarAffineFunction(coefficients, variables, a.constant);\n}\nauto operator+(const VariableIndex &a, const ScalarAffineFunction &b) -> ScalarAffineFunction\n{\n\treturn b + a;\n}\n\nauto operator+(const ScalarAffineFunction &a, const ScalarAffineFunction &b) -> ScalarAffineFunction\n{\n\tExprBuilder t(a);\n\tt.operator+=(b);\n\treturn ScalarAffineFunction(t);\n}\n\nauto operator+(const ScalarQuadraticFunction &a, CoeffT b) -> ScalarQuadraticFunction\n{\n\tScalarAffineFunction affine_part;\n\tif (a.affine_part)\n\t{\n\t\taffine_part = operator+(a.affine_part.value(), b);\n\t}\n\telse\n\t{\n\t\taffine_part = ScalarAffineFunction(b);\n\t}\n\treturn ScalarQuadraticFunction(a.coefficients, a.variable_1s, a.variable_2s, affine_part);\n}\nauto operator+(CoeffT a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction\n{\n\treturn b + a;\n}\n\nauto operator+(const ScalarQuadraticFunction &a, const VariableIndex &b) -> ScalarQuadraticFunction\n{\n\tScalarAffineFunction affine_part;\n\tif (a.affine_part)\n\t{\n\t\taffine_part = operator+(a.affine_part.value(), b);\n\t}\n\telse\n\t{\n\t\taffine_part = ScalarAffineFunction(b);\n\t}\n\treturn ScalarQuadraticFunction(a.coefficients, a.variable_1s, a.variable_2s, affine_part);\n}\nauto operator+(const VariableIndex &a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction\n{\n\treturn b + a;\n}\n\nauto operator+(const ScalarQuadraticFunction &a, const ScalarAffineFunction &b)\n    -> ScalarQuadraticFunction\n{\n\tScalarAffineFunction affine_part;\n\tif (a.affine_part)\n\t{\n\t\taffine_part = operator+(a.affine_part.value(), b);\n\t}\n\telse\n\t{\n\t\taffine_part = b;\n\t}\n\treturn ScalarQuadraticFunction(a.coefficients, a.variable_1s, a.variable_2s, affine_part);\n}\nauto operator+(const ScalarAffineFunction &a, const ScalarQuadraticFunction &b)\n    -> ScalarQuadraticFunction\n{\n\treturn b + a;\n}\n\nauto operator+(const ScalarQuadraticFunction &a, const ScalarQuadraticFunction &b)\n    -> ScalarQuadraticFunction\n{\n\tExprBuilder t(a);\n\tt.operator+=(b);\n\treturn ScalarQuadraticFunction(t);\n}\n\nauto operator-(const VariableIndex &a, CoeffT b) -> ScalarAffineFunction\n{\n\treturn ScalarAffineFunction(a, 1.0, -b);\n}\n\nauto operator-(CoeffT a, const VariableIndex &b) -> ScalarAffineFunction\n{\n\treturn ScalarAffineFunction(b, -1.0, a);\n}\n\nauto operator-(const VariableIndex &a, const VariableIndex &b) -> ScalarAffineFunction\n{\n\treturn ScalarAffineFunction({1.0, -1.0}, {a.index, b.index});\n}\n\nauto operator-(const ScalarAffineFunction &a, CoeffT b) -> ScalarAffineFunction\n{\n\treturn operator+(a, -b);\n}\n\nauto operator-(CoeffT a, const ScalarAffineFunction &b) -> ScalarAffineFunction\n{\n\treturn operator+(operator*(b, -1.0), a);\n}\n\nauto operator-(const ScalarAffineFunction &a, const VariableIndex &b) -> ScalarAffineFunction\n{\n\tauto coefficients = a.coefficients;\n\tauto variables = a.variables;\n\tcoefficients.push_back(-1.0);\n\tvariables.push_back(b.index);\n\treturn ScalarAffineFunction(coefficients, variables, a.constant);\n}\n\nauto operator-(const VariableIndex &a, const ScalarAffineFunction &b) -> ScalarAffineFunction\n{\n\treturn operator+(operator*(b, -1.0), a);\n}\n\nauto operator-(const ScalarAffineFunction &a, const ScalarAffineFunction &b) -> ScalarAffineFunction\n{\n\treturn operator+(a, operator*(b, -1.0));\n}\n\nauto operator-(const ScalarQuadraticFunction &a, CoeffT b) -> ScalarQuadraticFunction\n{\n\treturn operator+(a, -b);\n}\n\nauto operator-(CoeffT a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction\n{\n\treturn operator+(operator*(b, -1.0), a);\n}\n\nauto operator-(const ScalarQuadraticFunction &a, const VariableIndex &b) -> ScalarQuadraticFunction\n{\n\treturn operator+(a, ScalarAffineFunction(b, -1.0));\n}\n\nauto operator-(const VariableIndex &a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction\n{\n\treturn operator+(operator*(b, -1.0), a);\n}\n\nauto operator-(const ScalarQuadraticFunction &a, const ScalarAffineFunction &b)\n    -> ScalarQuadraticFunction\n{\n\treturn operator+(a, operator*(b, -1.0));\n}\n\nauto operator-(const ScalarAffineFunction &a, const ScalarQuadraticFunction &b)\n    -> ScalarQuadraticFunction\n{\n\treturn operator+(operator*(b, -1.0), a);\n}\n\nauto operator-(const ScalarQuadraticFunction &a, const ScalarQuadraticFunction &b)\n    -> ScalarQuadraticFunction\n{\n\treturn operator+(a, operator*(b, -1.0));\n}\n\nauto operator*(const VariableIndex &a, CoeffT b) -> ScalarAffineFunction\n{\n\treturn ScalarAffineFunction(a, b);\n}\nauto operator*(CoeffT a, const VariableIndex &b) -> ScalarAffineFunction\n{\n\treturn b * a;\n}\n\nauto operator*(const VariableIndex &a, const VariableIndex &b) -> ScalarQuadraticFunction\n{\n\treturn ScalarQuadraticFunction({1.0}, {a.index}, {b.index});\n}\n\nauto operator*(const ScalarAffineFunction &a, CoeffT b) -> ScalarAffineFunction\n{\n\tScalarAffineFunction aa = a;\n\tfor (auto &c : aa.coefficients)\n\t{\n\t\tc *= b;\n\t}\n\tif (aa.constant)\n\t{\n\t\taa.constant = aa.constant.value() * b;\n\t}\n\treturn aa;\n}\nauto operator*(CoeffT a, const ScalarAffineFunction &b) -> ScalarAffineFunction\n{\n\treturn b * a;\n}\n\nauto operator*(const ScalarAffineFunction &a, const VariableIndex &b) -> ScalarQuadraticFunction\n{\n\tauto &coefficients = a.coefficients;\n\tauto &variable_1s = a.variables;\n\tauto variable_2s = Vector<IndexT>(variable_1s.size(), b.index);\n\n\tstd::optional<ScalarAffineFunction> affine_part;\n\tif (a.constant)\n\t{\n\t\taffine_part = operator*(b, a.constant.value());\n\t}\n\n\treturn ScalarQuadraticFunction(coefficients, variable_1s, variable_2s, affine_part);\n}\nauto operator*(const VariableIndex &a, const ScalarAffineFunction &b) -> ScalarQuadraticFunction\n{\n\treturn b * a;\n}\n\nauto operator*(const ScalarAffineFunction &a, const ScalarAffineFunction &b)\n    -> ScalarQuadraticFunction\n{\n\tauto t = ExprBuilder();\n\n\tfor (int i = 0; i < a.coefficients.size(); i++)\n\t{\n\t\tauto ci = a.coefficients[i];\n\t\tauto xi = a.variables[i];\n\t\tfor (int j = 0; j < b.coefficients.size(); j++)\n\t\t{\n\t\t\tauto dj = b.coefficients[j];\n\t\t\tauto xj = b.variables[j];\n\t\t\tt._add_quadratic_term(xi, xj, ci * dj);\n\t\t}\n\t}\n\tif (b.constant)\n\t{\n\t\tauto d0 = b.constant.value();\n\t\tfor (int i = 0; i < a.coefficients.size(); i++)\n\t\t{\n\t\t\tauto ci = a.coefficients[i];\n\t\t\tauto xi = a.variables[i];\n\t\t\tt._add_affine_term(xi, ci * d0);\n\t\t}\n\t}\n\tif (a.constant)\n\t{\n\t\tauto c0 = a.constant.value();\n\t\tfor (int j = 0; j < b.coefficients.size(); j++)\n\t\t{\n\t\t\tauto dj = b.coefficients[j];\n\t\t\tauto xj = b.variables[j];\n\t\t\tt._add_affine_term(xj, c0 * dj);\n\t\t}\n\t}\n\tif (a.constant && b.constant)\n\t{\n\t\tt.constant_term = a.constant.value() * b.constant.value();\n\t}\n\treturn ScalarQuadraticFunction(t);\n}\n\nauto operator*(const ScalarQuadraticFunction &a, CoeffT b) -> ScalarQuadraticFunction\n{\n\tScalarQuadraticFunction aa = a;\n\tfor (auto &c : aa.coefficients)\n\t{\n\t\tc *= b;\n\t}\n\tif (aa.affine_part)\n\t{\n\t\taa.affine_part = operator*(aa.affine_part.value(), b);\n\t}\n\treturn aa;\n}\nauto operator*(CoeffT a, const ScalarQuadraticFunction &b) -> ScalarQuadraticFunction\n{\n\treturn b * a;\n}\n\nauto operator/(const VariableIndex &a, CoeffT b) -> ScalarAffineFunction\n{\n\treturn a * (1.0 / b);\n}\n\nauto operator/(const ScalarAffineFunction &a, CoeffT b) -> ScalarAffineFunction\n{\n\treturn a * (1.0 / b);\n}\n\nauto operator/(const ScalarQuadraticFunction &a, CoeffT b) -> ScalarQuadraticFunction\n{\n\treturn a * (1.0 / b);\n}\n\nauto operator-(const VariableIndex &a) -> ScalarAffineFunction\n{\n\treturn a * -1.0;\n}\n\nauto operator-(const ScalarAffineFunction &a) -> ScalarAffineFunction\n{\n\treturn a * -1.0;\n}\n\nauto operator-(const ScalarQuadraticFunction &a) -> ScalarQuadraticFunction\n{\n\treturn a * -1.0;\n}\n\nauto operator-(const ExprBuilder &a) -> ExprBuilder\n{\n\treturn a * -1.0;\n}\n\nauto operator+(const ExprBuilder &a, CoeffT b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator+=(b);\n\treturn e;\n}\nauto operator+(CoeffT b, const ExprBuilder &a) -> ExprBuilder\n{\n\treturn a + b;\n}\n\nauto operator+(const ExprBuilder &a, const VariableIndex &b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator+=(b);\n\treturn e;\n}\nauto operator+(const VariableIndex &b, const ExprBuilder &a) -> ExprBuilder\n{\n\treturn a + b;\n}\n\nauto operator+(const ExprBuilder &a, const ScalarAffineFunction &b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator+=(b);\n\treturn e;\n}\nauto operator+(const ScalarAffineFunction &b, const ExprBuilder &a) -> ExprBuilder\n{\n\treturn a + b;\n}\n\nauto operator+(const ExprBuilder &a, const ScalarQuadraticFunction &b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator+=(b);\n\treturn e;\n}\nauto operator+(const ScalarQuadraticFunction &b, const ExprBuilder &a) -> ExprBuilder\n{\n\treturn a + b;\n}\n\nauto operator+(const ExprBuilder &a, const ExprBuilder &b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator+=(b);\n\treturn e;\n}\n\nauto operator-(const ExprBuilder &a, CoeffT b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator-=(b);\n\treturn e;\n}\nauto operator-(CoeffT b, const ExprBuilder &a) -> ExprBuilder\n{\n\tExprBuilder e = a - b;\n\te.operator*=(-1.0);\n\treturn e;\n}\n\nauto operator-(const ExprBuilder &a, const VariableIndex &b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator-=(b);\n\treturn e;\n}\nauto operator-(const VariableIndex &b, const ExprBuilder &a) -> ExprBuilder\n{\n\tExprBuilder e = a - b;\n\te.operator*=(-1.0);\n\treturn e;\n}\n\nauto operator-(const ExprBuilder &a, const ScalarAffineFunction &b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator-=(b);\n\treturn e;\n}\nauto operator-(const ScalarAffineFunction &b, const ExprBuilder &a) -> ExprBuilder\n{\n\tExprBuilder e = a - b;\n\te.operator*=(-1.0);\n\treturn e;\n}\n\nauto operator-(const ExprBuilder &a, const ScalarQuadraticFunction &b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator-=(b);\n\treturn e;\n}\nauto operator-(const ScalarQuadraticFunction &b, const ExprBuilder &a) -> ExprBuilder\n{\n\tExprBuilder e = a - b;\n\te.operator*=(-1.0);\n\treturn e;\n}\n\nauto operator-(const ExprBuilder &a, const ExprBuilder &b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator-=(b);\n\treturn e;\n}\n\nauto operator*(const ExprBuilder &a, CoeffT b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator*=(b);\n\treturn e;\n}\nauto operator*(CoeffT b, const ExprBuilder &a) -> ExprBuilder\n{\n\treturn a * b;\n}\n\nauto operator*(const ExprBuilder &a, const VariableIndex &b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator*=(b);\n\treturn e;\n}\nauto operator*(const VariableIndex &b, const ExprBuilder &a) -> ExprBuilder\n{\n\treturn a * b;\n}\n\nauto operator*(const ExprBuilder &a, const ScalarAffineFunction &b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator*=(b);\n\treturn e;\n}\nauto operator*(const ScalarAffineFunction &b, const ExprBuilder &a) -> ExprBuilder\n{\n\treturn a * b;\n}\n\nauto operator*(const ExprBuilder &a, const ScalarQuadraticFunction &b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator*=(b);\n\treturn e;\n}\nauto operator*(const ScalarQuadraticFunction &b, const ExprBuilder &a) -> ExprBuilder\n{\n\treturn a * b;\n}\n\nauto operator*(const ExprBuilder &a, const ExprBuilder &b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator*=(b);\n\treturn e;\n}\n\nauto operator/(const ExprBuilder &a, CoeffT b) -> ExprBuilder\n{\n\tExprBuilder e = a;\n\te.operator/=(b);\n\treturn e;\n}\n"
  },
  {
    "path": "lib/core_ext.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include <nanobind/operators.h>\n#include <nanobind/stl/vector.h>\n#include <nanobind/stl/optional.h>\n#include <nanobind/ndarray.h>\n\n#include \"pyoptinterface/core.hpp\"\n#include \"pyoptinterface/container.hpp\"\n\n#include <span>\n#include <algorithm>\n\nnamespace nb = nanobind;\n\nusing CoeffNdarrayT = nb::ndarray<const double, nb::ndim<1>, nb::any_contig>;\nusing IndexNdarrayT = nb::ndarray<const int, nb::ndim<1>, nb::any_contig>;\n\nNB_MODULE(core_ext, m)\n{\n\tnb::set_leak_warnings(false);\n\n\t// VariableDomain\n\tnb::enum_<VariableDomain>(m, \"VariableDomain\", nb::is_arithmetic())\n\t    .value(\"Continuous\", VariableDomain::Continuous)\n\t    .value(\"Integer\", VariableDomain::Integer)\n\t    .value(\"Binary\", VariableDomain::Binary)\n\t    .value(\"SemiContinuous\", VariableDomain::SemiContinuous);\n\n\t// ConstraintSense\n\tnb::enum_<ConstraintSense>(m, \"ConstraintSense\")\n\t    .value(\"LessEqual\", ConstraintSense::LessEqual)\n\t    .value(\"Equal\", ConstraintSense::Equal)\n\t    .value(\"GreaterEqual\", ConstraintSense::GreaterEqual);\n\n\t// ConstraintType\n\tnb::enum_<ConstraintType>(m, \"ConstraintType\")\n\t    .value(\"Linear\", ConstraintType::Linear)\n\t    .value(\"Quadratic\", ConstraintType::Quadratic)\n\t    .value(\"SOS\", ConstraintType::SOS)\n\t    .value(\"SecondOrderCone\", ConstraintType::SecondOrderCone)\n\t    .value(\"ExponentialCone\", ConstraintType::ExponentialCone);\n\n\tnb::enum_<SOSType>(m, \"SOSType\").value(\"SOS1\", SOSType::SOS1).value(\"SOS2\", SOSType::SOS2);\n\n\t// ObjectiveSense\n\tnb::enum_<ObjectiveSense>(m, \"ObjectiveSense\")\n\t    .value(\"Minimize\", ObjectiveSense::Minimize)\n\t    .value(\"Maximize\", ObjectiveSense::Maximize);\n\n\tnb::class_<VariableIndex>(m, \"VariableIndex\")\n\t    .def(nb::init<IndexT>())\n\t    .def_ro(\"index\", &VariableIndex::index)\n\t    .def(-nb::self)\n\t    .def(nb::self + CoeffT())\n\t    .def(CoeffT() + nb::self)\n\t    .def(nb::self + VariableIndex())\n\t    .def(nb::self + ScalarAffineFunction())\n\t    .def(nb::self + ScalarQuadraticFunction())\n\t    .def(nb::self - CoeffT())\n\t    .def(CoeffT() - nb::self)\n\t    .def(nb::self - VariableIndex())\n\t    .def(nb::self - ScalarAffineFunction())\n\t    .def(nb::self - ScalarQuadraticFunction())\n\t    .def(nb::self * CoeffT())\n\t    .def(CoeffT() * nb::self)\n\t    .def(nb::self * VariableIndex())\n\t    .def(nb::self * ScalarAffineFunction())\n\t    .def(nb::self / CoeffT());\n\n\tnb::class_<ConstraintIndex>(m, \"ConstraintIndex\")\n\t    .def(nb::init<ConstraintType, IndexT>())\n\t    .def_ro(\"type\", &ConstraintIndex::type)\n\t    .def_ro(\"index\", &ConstraintIndex::index);\n\n\tnb::class_<ScalarAffineFunction>(m, \"ScalarAffineFunction\")\n\t    .def(nb::init<>())\n\t    .def(nb::init<CoeffT>())\n\t    .def(nb::init<const VariableIndex &>())\n\t    .def(nb::init<const VariableIndex &, CoeffT>())\n\t    .def(nb::init<const VariableIndex &, CoeffT, CoeffT>())\n\t    .def(nb::init<const Vector<CoeffT> &, const Vector<IndexT> &>(), nb::arg(\"coefficients\"),\n\t         nb::arg(\"variables\"))\n\t    .def(nb::init<const Vector<CoeffT> &, const Vector<IndexT> &, CoeffT>(),\n\t         nb::arg(\"coefficients\"), nb::arg(\"variables\"), nb::arg(\"constant\"))\n\n\t    // ndarray constructor\n\t    .def_static(\n\t        \"from_numpy\",\n\t        [](CoeffNdarrayT coefficients, IndexNdarrayT variables) {\n\t\t        auto *expr = new ScalarAffineFunction();\n\n\t\t        auto n = coefficients.size();\n\n\t\t        expr->coefficients.resize(n);\n\t\t        std::span<const double> coeffs(coefficients.data(), n);\n\t\t        std::ranges::copy(coeffs, expr->coefficients.begin());\n\n\t\t        n = variables.size();\n\t\t        expr->variables.resize(n);\n\t\t        std::span<const int> vars(variables.data(), n);\n\t\t        std::ranges::copy(vars, expr->variables.begin());\n\n\t\t        expr->constant.reset();\n\n\t\t        return expr;\n\t        },\n\t        nb::arg(\"coefficients\"), nb::arg(\"variables\"), nb::rv_policy::take_ownership)\n\t    .def_static(\n\t        \"from_numpy\",\n\t        [](CoeffNdarrayT coefficients, IndexNdarrayT variables, CoeffT constant) {\n\t\t        auto *expr = new ScalarAffineFunction();\n\n\t\t        auto n = coefficients.size();\n\n\t\t        expr->coefficients.resize(n);\n\t\t        std::span<const double> coeffs(coefficients.data(), n);\n\t\t        std::ranges::copy(coeffs, expr->coefficients.begin());\n\n\t\t        n = variables.size();\n\t\t        expr->variables.resize(n);\n\t\t        std::span<const int> vars(variables.data(), n);\n\t\t        std::ranges::copy(vars, expr->variables.begin());\n\n\t\t        expr->constant = constant;\n\n\t\t        return expr;\n\t        },\n\t        nb::arg(\"coefficients\"), nb::arg(\"variables\"), nb::arg(\"constant\"),\n\t        nb::rv_policy::take_ownership)\n\n\t    .def(nb::init<const ExprBuilder &>())\n\t    .def_ro(\"coefficients\", &ScalarAffineFunction::coefficients)\n\t    .def_ro(\"variables\", &ScalarAffineFunction::variables)\n\t    .def_ro(\"constant\", &ScalarAffineFunction::constant)\n\t    .def(\"size\", &ScalarAffineFunction::size)\n\t    .def(\"canonicalize\", &ScalarAffineFunction::canonicalize,\n\t         nb::arg(\"threshold\") = COEFTHRESHOLD)\n\t    .def(\"reserve\", &ScalarAffineFunction::reserve)\n\t    .def(\"add_term\", &ScalarAffineFunction::add_term)\n\t    .def(\"add_constant\", &ScalarAffineFunction::add_constant)\n\t    .def(-nb::self)\n\t    .def(nb::self + CoeffT())\n\t    .def(CoeffT() + nb::self)\n\t    .def(nb::self + VariableIndex())\n\t    .def(nb::self + ScalarAffineFunction())\n\t    .def(nb::self + ScalarQuadraticFunction())\n\t    .def(nb::self - CoeffT())\n\t    .def(CoeffT() - nb::self)\n\t    .def(nb::self - VariableIndex())\n\t    .def(nb::self - ScalarAffineFunction())\n\t    .def(nb::self - ScalarQuadraticFunction())\n\t    .def(nb::self * CoeffT())\n\t    .def(CoeffT() * nb::self)\n\t    .def(nb::self * VariableIndex())\n\t    .def(nb::self * ScalarAffineFunction())\n\t    .def(nb::self / CoeffT());\n\n\tnb::class_<ScalarQuadraticFunction>(m, \"ScalarQuadraticFunction\")\n\t    .def(nb::init<>())\n\t    .def(nb::init<const Vector<CoeffT> &, const Vector<IndexT> &, const Vector<IndexT> &>(),\n\t         nb::arg(\"coefficients\"), nb::arg(\"var1s\"), nb::arg(\"var2s\"))\n\t    .def(nb::init<const Vector<CoeffT> &, const Vector<IndexT> &, const Vector<IndexT> &,\n\t                  const ScalarAffineFunction &>(),\n\t         nb::arg(\"coefficients\"), nb::arg(\"var1s\"), nb::arg(\"var2s\"), nb::arg(\"affine_part\"))\n\t    .def(nb::init<const ExprBuilder &>())\n\t    .def_ro(\"coefficients\", &ScalarQuadraticFunction::coefficients)\n\t    .def_ro(\"variable_1s\", &ScalarQuadraticFunction::variable_1s)\n\t    .def_ro(\"variable_2s\", &ScalarQuadraticFunction::variable_2s)\n\t    .def_ro(\"affine_part\", &ScalarQuadraticFunction::affine_part)\n\t    .def(\"size\", &ScalarQuadraticFunction::size)\n\t    .def(\"canonicalize\", &ScalarQuadraticFunction::canonicalize,\n\t         nb::arg(\"threshold\") = COEFTHRESHOLD)\n\t    .def(\"reserve_quadratic\", &ScalarQuadraticFunction::reserve_quadratic)\n\t    .def(\"reserve_affine\", &ScalarQuadraticFunction::reserve_affine)\n\t    .def(\"add_quadratic_term\", &ScalarQuadraticFunction::add_quadratic_term)\n\t    .def(\"add_affine_term\", &ScalarQuadraticFunction::add_affine_term)\n\t    .def(\"add_constant\", &ScalarQuadraticFunction::add_constant)\n\t    .def(-nb::self)\n\t    .def(nb::self + CoeffT())\n\t    .def(CoeffT() + nb::self)\n\t    .def(nb::self + VariableIndex())\n\t    .def(nb::self + ScalarAffineFunction())\n\t    .def(nb::self + ScalarQuadraticFunction())\n\t    .def(nb::self - CoeffT())\n\t    .def(CoeffT() - nb::self)\n\t    .def(nb::self - VariableIndex())\n\t    .def(nb::self - ScalarAffineFunction())\n\t    .def(nb::self - ScalarQuadraticFunction())\n\t    .def(nb::self * CoeffT())\n\t    .def(CoeffT() * nb::self)\n\t    .def(nb::self / CoeffT());\n\n\tnb::class_<VariablePair>(m, \"VariablePair\").def(nb::init<IndexT, IndexT>());\n\n\tnb::class_<ExprBuilder>(m, \"ExprBuilder\")\n\t    .def(nb::init<>())\n\t    .def(nb::init<CoeffT>())\n\t    .def(nb::init<const VariableIndex &>())\n\t    .def(nb::init<const ScalarAffineFunction &>())\n\t    .def(nb::init<const ScalarQuadraticFunction &>())\n\t    .def(\"empty\", &ExprBuilder::empty)\n\t    .def(\"degree\", &ExprBuilder::degree)\n\t    .def(\"reserve_quadratic\", &ExprBuilder::reserve_quadratic)\n\t    .def(\"reserve_affine\", &ExprBuilder::reserve_affine)\n\t    .def(\"clear\", &ExprBuilder::clear)\n\t    .def(\"clean_nearzero_terms\", &ExprBuilder::clean_nearzero_terms,\n\t         nb::arg(\"threshold\") = COEFTHRESHOLD)\n\t    .def(\"add_quadratic_term\", &ExprBuilder::add_quadratic_term)\n\t    .def(\"set_quadratic_coef\", &ExprBuilder::set_quadratic_coef)\n\t    .def(\"add_affine_term\", &ExprBuilder::add_affine_term)\n\t    .def(\"set_affine_coef\", &ExprBuilder::set_affine_coef)\n\t    .def(-nb::self)\n\t    .def(nb::self += CoeffT(), nb::rv_policy::none)\n\t    .def(nb::self += VariableIndex(), nb::rv_policy::none)\n\t    .def(nb::self += ScalarAffineFunction(), nb::rv_policy::none)\n\t    .def(nb::self += ScalarQuadraticFunction(), nb::rv_policy::none)\n\t    .def(nb::self += ExprBuilder(), nb::rv_policy::none)\n\t    .def(nb::self -= CoeffT(), nb::rv_policy::none)\n\t    .def(nb::self -= VariableIndex(), nb::rv_policy::none)\n\t    .def(nb::self -= ScalarAffineFunction(), nb::rv_policy::none)\n\t    .def(nb::self -= ScalarQuadraticFunction(), nb::rv_policy::none)\n\t    .def(nb::self -= ExprBuilder(), nb::rv_policy::none)\n\t    .def(nb::self *= CoeffT(), nb::rv_policy::none)\n\t    .def(nb::self *= VariableIndex(), nb::rv_policy::none)\n\t    .def(nb::self *= ScalarAffineFunction(), nb::rv_policy::none)\n\t    .def(nb::self *= ScalarQuadraticFunction(), nb::rv_policy::none)\n\t    .def(nb::self *= ExprBuilder(), nb::rv_policy::none)\n\t    .def(nb::self /= CoeffT(), nb::rv_policy::none)\n\t    .def(nb::self + CoeffT())\n\t    .def(CoeffT() + nb::self)\n\t    .def(nb::self + VariableIndex())\n\t    .def(nb::self + ScalarAffineFunction())\n\t    .def(nb::self + ScalarQuadraticFunction())\n\t    .def(nb::self + ExprBuilder())\n\t    .def(VariableIndex() + nb::self)\n\t    .def(ScalarAffineFunction() + nb::self)\n\t    .def(ScalarQuadraticFunction() + nb::self)\n\t    .def(nb::self - CoeffT())\n\t    .def(CoeffT() - nb::self)\n\t    .def(nb::self - VariableIndex())\n\t    .def(nb::self - ScalarAffineFunction())\n\t    .def(nb::self - ScalarQuadraticFunction())\n\t    .def(nb::self - ExprBuilder())\n\t    .def(VariableIndex() - nb::self)\n\t    .def(ScalarAffineFunction() - nb::self)\n\t    .def(ScalarQuadraticFunction() - nb::self)\n\t    .def(nb::self * CoeffT())\n\t    .def(CoeffT() * nb::self)\n\t    .def(nb::self * VariableIndex())\n\t    .def(nb::self * ScalarAffineFunction())\n\t    .def(nb::self * ScalarQuadraticFunction())\n\t    .def(nb::self * ExprBuilder())\n\t    .def(VariableIndex() * nb::self)\n\t    .def(ScalarAffineFunction() * nb::self)\n\t    .def(ScalarQuadraticFunction() * nb::self)\n\t    .def(nb::self / CoeffT());\n\n\t// We need to test the functionality of MonotoneIndexer\n\tusing IntMonotoneIndexer = MonotoneIndexer<int>;\n\tnb::class_<IntMonotoneIndexer>(m, \"IntMonotoneIndexer\")\n\t    .def(nb::init<>())\n\t    .def(\"add_index\", &IntMonotoneIndexer::add_index)\n\t    .def(\"get_index\", &IntMonotoneIndexer::get_index)\n\t    .def(\"delete_index\", &IntMonotoneIndexer::delete_index);\n}\n"
  },
  {
    "path": "lib/cppad_interface.cpp",
    "content": "#include \"pyoptinterface/cppad_interface.hpp\"\n\n#include \"fmt/core.h\"\n\nstatic const std::string opt_options = \"no_compare_op no_conditional_skip no_cumulative_sum_op\";\n\nADFunDouble dense_jacobian(const ADFunDouble &f)\n{\n\tusing CppAD::AD;\n\tusing CppAD::ADFun;\n\tusing CppAD::Independent;\n\tusing Base = double;\n\n\tsize_t nx = f.Domain();\n\tsize_t ny = f.Range();\n\tsize_t np = f.size_dyn_ind();\n\tstd::vector<AD<Base>> apx(np + nx), ax(nx), ap(np), aj(nx * ny);\n\tADFun<AD<Base>, Base> af = f.base2ad();\n\tIndependent(apx);\n\tfor (size_t i = 0; i < np; i++)\n\t\tap[i] = apx[i];\n\tfor (size_t i = 0; i < nx; i++)\n\t\tax[i] = apx[np + i];\n\taf.new_dynamic(ap);\n\taj = af.Jacobian(ax);\n\tADFun<Base> jac;\n\tjac.Dependent(apx, aj);\n\n\tjac.optimize(opt_options);\n\n\treturn jac;\n}\n\nJacobianHessianSparsityPattern jacobian_hessian_sparsity(ADFunDouble &f,\n                                                         HessianSparsityType hessian_sparsity)\n{\n\tusing s_vector = std::vector<size_t>;\n\tusing CppAD::sparse_rc;\n\n\tsize_t nx = f.Domain();\n\tsize_t ny = f.Range();\n\tsize_t np = f.size_dyn_ind();\n\n\tJacobianHessianSparsityPattern jachess;\n\n\t// We must compute the jacobian sparsity first\n\t{\n\t\t// sparsity pattern for the identity matrix\n\t\tsize_t nr = nx;\n\t\tsize_t nc = nx;\n\t\tsize_t nnz_in = nx;\n\t\tsparsity_pattern_t pattern_jac_in(nr, nc, nnz_in);\n\t\tfor (size_t k = 0; k < nnz_in; k++)\n\t\t{\n\t\t\tsize_t r = k;\n\t\t\tsize_t c = k;\n\t\t\tpattern_jac_in.set(k, r, c);\n\t\t}\n\t\t// compute sparsity pattern for J(x) = F'(x)\n\t\tconst bool transpose = false;\n\t\tconst bool dependency = false;\n\t\tconst bool internal_bool = true;\n\t\tsparsity_pattern_t pattern_jac;\n\t\tf.for_jac_sparsity(pattern_jac_in, transpose, dependency, internal_bool, pattern_jac);\n\n\t\tjachess.jacobian = pattern_jac;\n\t}\n\n\tstd::vector<bool> select_range(ny, true);\n\tconst bool transpose = false;\n\tconst bool internal_bool = true;\n\tsparsity_pattern_t pattern_hes;\n\tf.rev_hes_sparsity(select_range, transpose, internal_bool, pattern_hes);\n\n\tjachess.hessian = pattern_hes;\n\n\t// Filter the sparsity pattern\n\tsparsity_pattern_t pattern_hes_partial;\n\tpattern_hes_partial.resize(nx, nx, 0);\n\tif (hessian_sparsity == HessianSparsityType::Upper)\n\t{\n\t\tfor (int i = 0; i < pattern_hes.nnz(); i++)\n\t\t{\n\t\t\tauto r = pattern_hes.row()[i];\n\t\t\tauto c = pattern_hes.col()[i];\n\t\t\tif (r <= c)\n\t\t\t{\n\t\t\t\tpattern_hes_partial.push_back(r, c);\n\t\t\t}\n\t\t}\n\t}\n\telse if (hessian_sparsity == HessianSparsityType::Lower)\n\t{\n\t\tfor (int i = 0; i < pattern_hes.nnz(); i++)\n\t\t{\n\t\t\tauto r = pattern_hes.row()[i];\n\t\t\tauto c = pattern_hes.col()[i];\n\t\t\tif (r >= c)\n\t\t\t{\n\t\t\t\tpattern_hes_partial.push_back(r, c);\n\t\t\t}\n\t\t}\n\t}\n\tjachess.reduced_hessian = pattern_hes_partial;\n\treturn jachess;\n}\n\nADFunDouble sparse_jacobian(const ADFunDouble &f, const sparsity_pattern_t &pattern_jac,\n                            const std::vector<double> &x_values,\n                            const std::vector<double> &p_values)\n{\n\tusing CppAD::AD;\n\tusing CppAD::ADFun;\n\tusing CppAD::Independent;\n\tusing Base = double;\n\n\tsize_t nx = f.Domain();\n\tsize_t ny = f.Range();\n\tsize_t np = f.size_dyn_ind();\n\tstd::vector<AD<Base>> apx(np + nx), ax(nx), ap(np);\n\tfor (size_t i = 0; i < np; i++)\n\t{\n\t\tapx[i] = p_values[i];\n\t}\n\tfor (size_t i = 0; i < nx; i++)\n\t{\n\t\tapx[np + i] = x_values[i];\n\t}\n\tADFun<AD<Base>, Base> af = f.base2ad();\n\tIndependent(apx);\n\tfor (size_t i = 0; i < np; i++)\n\t{\n\t\tap[i] = apx[i];\n\t}\n\tfor (size_t i = 0; i < nx; i++)\n\t{\n\t\tax[i] = apx[np + i];\n\t}\n\taf.new_dynamic(ap);\n\tCppAD::sparse_rcv<std::vector<size_t>, std::vector<AD<Base>>> subset(pattern_jac);\n\tCppAD::sparse_jac_work work;\n\tstd::string coloring = \"cppad\";\n\tsize_t n_color = af.sparse_jac_rev(ax, subset, pattern_jac, coloring, work);\n\tADFun<double> jacobian;\n\tjacobian.Dependent(apx, subset.val());\n\n\tjacobian.optimize(opt_options);\n\n\treturn jacobian;\n}\n\nADFunDouble sparse_hessian(const ADFunDouble &f, const sparsity_pattern_t &pattern_hes,\n                           const sparsity_pattern_t &pattern_subset,\n                           const std::vector<double> &x_values, const std::vector<double> &p_values)\n{\n\tusing CppAD::AD;\n\tusing CppAD::ADFun;\n\tusing CppAD::Independent;\n\tusing Base = double;\n\n\tsize_t nx = f.Domain();\n\tsize_t ny = f.Range();\n\tsize_t np = f.size_dyn_ind();\n\tsize_t nw = ny;\n\tstd::vector<AD<Base>> apwx(np + nw + nx), ax(nx), ap(np), aw(nw);\n\tfor (size_t i = 0; i < np; i++)\n\t{\n\t\tapwx[i] = p_values[i];\n\t}\n\tfor (size_t i = 0; i < nw; i++)\n\t{\n\t\tapwx[np + i] = 1.0;\n\t}\n\tfor (size_t i = 0; i < nx; i++)\n\t{\n\t\tapwx[np + nw + i] = x_values[i];\n\t}\n\tADFun<AD<Base>, Base> af = f.base2ad();\n\tIndependent(apwx);\n\tfor (size_t i = 0; i < np; i++)\n\t{\n\t\tap[i] = apwx[i];\n\t}\n\tfor (size_t i = 0; i < nw; i++)\n\t{\n\t\taw[i] = apwx[np + i];\n\t}\n\tfor (size_t i = 0; i < nx; i++)\n\t{\n\t\tax[i] = apwx[np + nw + i];\n\t}\n\taf.new_dynamic(ap);\n\tCppAD::sparse_rcv<std::vector<size_t>, std::vector<AD<Base>>> subset(pattern_subset);\n\tCppAD::sparse_hes_work work;\n\tstd::string coloring = \"cppad.symmetric\";\n\tsize_t n_sweep = af.sparse_hes(ax, aw, subset, pattern_hes, coloring, work);\n\tADFun<double> hessian;\n\thessian.Dependent(apwx, subset.val());\n\n\thessian.optimize(opt_options);\n\n\treturn hessian;\n}\n\nCppAD::AD<double> cppad_build_unary_expression(UnaryOperator op, const CppAD::AD<double> &operand)\n{\n\tswitch (op)\n\t{\n\tcase UnaryOperator::Neg: {\n\t\treturn -operand;\n\t}\n\tcase UnaryOperator::Sin: {\n\t\treturn CppAD::sin(operand);\n\t}\n\tcase UnaryOperator::Cos: {\n\t\treturn CppAD::cos(operand);\n\t}\n\tcase UnaryOperator::Tan: {\n\t\treturn CppAD::tan(operand);\n\t}\n\tcase UnaryOperator::Asin: {\n\t\treturn CppAD::asin(operand);\n\t}\n\tcase UnaryOperator::Acos: {\n\t\treturn CppAD::acos(operand);\n\t}\n\tcase UnaryOperator::Atan: {\n\t\treturn CppAD::atan(operand);\n\t}\n\tcase UnaryOperator::Abs: {\n\t\treturn CppAD::abs(operand);\n\t}\n\tcase UnaryOperator::Sqrt: {\n\t\treturn CppAD::sqrt(operand);\n\t}\n\tcase UnaryOperator::Exp: {\n\t\treturn CppAD::exp(operand);\n\t}\n\tcase UnaryOperator::Log: {\n\t\treturn CppAD::log(operand);\n\t}\n\tcase UnaryOperator::Log10: {\n\t\treturn CppAD::log10(operand);\n\t}\n\tdefault: {\n\t\tauto msg = \"Invalid unary operator \" + unary_operator_to_string(op);\n\t\tthrow std::runtime_error(msg);\n\t}\n\t}\n}\n\nCppAD::AD<double> cppad_build_binary_expression(BinaryOperator op, const CppAD::AD<double> &left,\n                                                const CppAD::AD<double> &right)\n{\n\tswitch (op)\n\t{\n\tcase BinaryOperator::Sub: {\n\t\treturn left - right;\n\t}\n\tcase BinaryOperator::Div: {\n\t\treturn left / right;\n\t}\n\tcase BinaryOperator::Pow: {\n\t\treturn CppAD::pow(left, right);\n\t}\n\tcase BinaryOperator::LessThan:\n\tcase BinaryOperator::LessEqual:\n\tcase BinaryOperator::Equal:\n\tcase BinaryOperator::NotEqual:\n\tcase BinaryOperator::GreaterEqual:\n\tcase BinaryOperator::GreaterThan: {\n\t\tthrow std::runtime_error(\"Currently comparision operator can only be used with ifelse \"\n\t\t                         \"function and cannot be evaluated as value\");\n\t}\n\tdefault: {\n\t\tauto msg = \"Invalid binary operator \" + binary_operator_to_string(op);\n\t\tthrow std::runtime_error(msg);\n\t}\n\t}\n}\n\nCppAD::AD<double> cppad_build_ternary_expression(BinaryOperator compare_op,\n                                                 const CppAD::AD<double> &compare_left,\n                                                 const CppAD::AD<double> &compare_right,\n                                                 const CppAD::AD<double> &then_result,\n                                                 const CppAD::AD<double> &else_result)\n{\n\tswitch (compare_op)\n\t{\n\tcase BinaryOperator::LessThan: {\n\t\treturn CppAD::CondExpLt(compare_left, compare_right, then_result, else_result);\n\t}\n\tcase BinaryOperator::LessEqual: {\n\t\treturn CppAD::CondExpLe(compare_left, compare_right, then_result, else_result);\n\t}\n\tcase BinaryOperator::Equal: {\n\t\treturn CppAD::CondExpEq(compare_left, compare_right, then_result, else_result);\n\t}\n\tcase BinaryOperator::NotEqual: {\n\t\treturn CppAD::CondExpEq(compare_left, compare_right, else_result, then_result);\n\t}\n\tcase BinaryOperator::GreaterEqual: {\n\t\treturn CppAD::CondExpGe(compare_left, compare_right, then_result, else_result);\n\t}\n\tcase BinaryOperator::GreaterThan: {\n\t\treturn CppAD::CondExpGt(compare_left, compare_right, then_result, else_result);\n\t}\n\tdefault: {\n\t\tauto msg = \"Invalid compare operator \" + binary_operator_to_string(compare_op);\n\t\tthrow std::runtime_error(msg);\n\t}\n\t}\n}\n\nCppAD::AD<double> cppad_build_nary_expression(NaryOperator op,\n                                              const std::vector<CppAD::AD<double>> &operands)\n{\n\tif (operands.size() == 0)\n\t\treturn CppAD::AD<double>(0.0);\n\n\tCppAD::AD<double> result = operands[0];\n\tswitch (op)\n\t{\n\tcase NaryOperator::Add: {\n\t\tfor (auto i = 1; i < operands.size(); i++)\n\t\t{\n\t\t\tresult += operands[i];\n\t\t}\n\t\tbreak;\n\t}\n\tcase NaryOperator::Mul: {\n\t\tfor (auto i = 1; i < operands.size(); i++)\n\t\t{\n\t\t\tresult *= operands[i];\n\t\t}\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tauto msg = \"Invalid nary operator \" + nary_operator_to_string(op);\n\t\tthrow std::runtime_error(msg);\n\t}\n\t}\n\treturn result;\n}\n\nCppAD::AD<double> cppad_trace_expression(\n    const ExpressionGraph &graph, const ExpressionHandle &expression,\n    const std::vector<CppAD::AD<double>> &x, const std::vector<CppAD::AD<double>> &p,\n    ankerl::unordered_dense::map<ExpressionHandle, CppAD::AD<double>> &seen_expressions)\n{\n\tauto it = seen_expressions.find(expression);\n\tif (it != seen_expressions.end())\n\t{\n\t\treturn it->second;\n\t}\n\tCppAD::AD<double> result;\n\tauto id = expression.id;\n\tswitch (expression.array)\n\t{\n\tcase ArrayType::Variable: {\n\t\tresult = x[id];\n\t\tbreak;\n\t}\n\tcase ArrayType::Constant: {\n\t\tresult = p[id];\n\t\tbreak;\n\t}\n\tcase ArrayType::Parameter: {\n\t\tthrow std::runtime_error(\"Parameter is not supported in cppad_trace_expression\");\n\t\tbreak;\n\t}\n\tcase ArrayType::Unary: {\n\t\tauto &unary = graph.m_unaries[id];\n\t\tauto operand = cppad_trace_expression(graph, unary.operand, x, p, seen_expressions);\n\t\tresult = cppad_build_unary_expression(unary.op, operand);\n\t\tseen_expressions[expression] = result;\n\t\tbreak;\n\t}\n\tcase ArrayType::Binary: {\n\t\tauto &binary = graph.m_binaries[id];\n\t\tauto left = cppad_trace_expression(graph, binary.left, x, p, seen_expressions);\n\t\tauto right = cppad_trace_expression(graph, binary.right, x, p, seen_expressions);\n\t\tresult = cppad_build_binary_expression(binary.op, left, right);\n\t\tseen_expressions[expression] = result;\n\t\tbreak;\n\t}\n\tcase ArrayType::Ternary: {\n\t\tauto &ifelsethen_body = graph.m_ternaries[id];\n\t\tauto &condition = ifelsethen_body.left;\n\t\tassert(condition.array == ArrayType::Binary);\n\n\t\tauto &condition_body = graph.m_binaries[condition.id];\n\t\tBinaryOperator compare_op = condition_body.op;\n\t\tassert(is_binary_compare_op(compare_op));\n\n\t\tCppAD::AD<double> compare_left =\n\t\t    cppad_trace_expression(graph, condition_body.left, x, p, seen_expressions);\n\t\tCppAD::AD<double> compare_right =\n\t\t    cppad_trace_expression(graph, condition_body.right, x, p, seen_expressions);\n\n\t\tCppAD::AD<double> then_result =\n\t\t    cppad_trace_expression(graph, ifelsethen_body.middle, x, p, seen_expressions);\n\t\tCppAD::AD<double> else_result =\n\t\t    cppad_trace_expression(graph, ifelsethen_body.right, x, p, seen_expressions);\n\n\t\tresult = cppad_build_ternary_expression(compare_op, compare_left, compare_right,\n\t\t                                        then_result, else_result);\n\t\tseen_expressions[expression] = result;\n\t\tbreak;\n\t}\n\tcase ArrayType::Nary: {\n\t\tauto &nary = graph.m_naries[id];\n\t\tstd::vector<CppAD::AD<double>> operand_values;\n\t\tfor (auto &operand : nary.operands)\n\t\t{\n\t\t\tauto operand_value = cppad_trace_expression(graph, operand, x, p, seen_expressions);\n\t\t\toperand_values.push_back(operand_value);\n\t\t}\n\t\tresult = cppad_build_nary_expression(nary.op, operand_values);\n\t\tseen_expressions[expression] = result;\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tthrow std::runtime_error(\"Invalid array type\");\n\t}\n\t}\n\treturn result;\n}\n\nADFunDouble cppad_trace_graph_constraints(const ExpressionGraph &graph,\n                                          const std::vector<size_t> &selected)\n{\n\tankerl::unordered_dense::map<ExpressionHandle, CppAD::AD<double>> seen_expressions;\n\n\tauto N_inputs = graph.n_variables();\n\tstd::vector<CppAD::AD<double>> x(N_inputs);\n\n\tauto N_parameters = graph.n_constants();\n\tstd::vector<CppAD::AD<double>> p(N_parameters);\n\t// Must assign value to parameter, otherwise p will be zero\n\t// and CppAD::pow(x, p) will be 0\n\tfor (size_t i = 0; i < N_parameters; i++)\n\t{\n\t\tp[i] = graph.m_constants[i];\n\t}\n\n\tif (N_parameters > 0)\n\t{\n\t\tCppAD::Independent(x, p);\n\t}\n\telse\n\t{\n\t\tCppAD::Independent(x);\n\t}\n\n\tauto &outputs = graph.m_constraint_outputs;\n\n\tstd::vector<size_t> indices;\n\tif (selected.empty())\n\t{\n\t\tindices.reserve(outputs.size());\n\t\tfor (size_t i = 0; i < outputs.size(); i++)\n\t\t{\n\t\t\tindices.push_back(i);\n\t\t}\n\t}\n\telse\n\t{\n\t\tindices = selected;\n\t}\n\n\tauto N_outputs = indices.size();\n\tstd::vector<CppAD::AD<double>> y(N_outputs);\n\n\t// Trace the selected outputs\n\tfor (size_t i = 0; i < N_outputs; i++)\n\t{\n\t\tauto idx = indices[i];\n\t\tauto &output = outputs[idx];\n\t\ty[i] = cppad_trace_expression(graph, output, x, p, seen_expressions);\n\t}\n\n\tADFunDouble f;\n\tf.Dependent(x, y);\n\n\treturn f;\n}\n\nADFunDouble cppad_trace_graph_objective(const ExpressionGraph &graph,\n                                        const std::vector<size_t> &selected, bool aggregate)\n{\n\tankerl::unordered_dense::map<ExpressionHandle, CppAD::AD<double>> seen_expressions;\n\n\tauto N_inputs = graph.n_variables();\n\tstd::vector<CppAD::AD<double>> x(N_inputs);\n\n\tauto N_parameters = graph.n_constants();\n\tstd::vector<CppAD::AD<double>> p(N_parameters);\n\tfor (size_t i = 0; i < N_parameters; i++)\n\t{\n\t\tp[i] = graph.m_constants[i];\n\t}\n\n\tif (N_parameters > 0)\n\t{\n\t\tCppAD::Independent(x, p);\n\t}\n\telse\n\t{\n\t\tCppAD::Independent(x);\n\t}\n\n\tauto &outputs = graph.m_objective_outputs;\n\n\tstd::vector<size_t> indices;\n\tif (selected.empty())\n\t{\n\t\tindices.reserve(outputs.size());\n\t\tfor (size_t i = 0; i < outputs.size(); i++)\n\t\t{\n\t\t\tindices.push_back(i);\n\t\t}\n\t}\n\telse\n\t{\n\t\tindices = selected;\n\t}\n\n\tauto N_outputs = indices.size();\n\tstd::vector<CppAD::AD<double>> y(N_outputs);\n\n\tfor (size_t i = 0; i < N_outputs; i++)\n\t{\n\t\tauto idx = indices[i];\n\t\tauto &output = outputs[idx];\n\t\ty[i] = cppad_trace_expression(graph, output, x, p, seen_expressions);\n\t}\n\n\tADFunDouble f;\n\n\tif (aggregate)\n\t{\n\t\tCppAD::AD<double> y_sum = 0.0;\n\t\tfor (size_t i = 0; i < N_outputs; i++)\n\t\t{\n\t\t\ty_sum += y[i];\n\t\t}\n\t\tf.Dependent(x, {y_sum});\n\t}\n\telse\n\t{\n\t\tf.Dependent(x, y);\n\t}\n\n\treturn f;\n}\n\nvoid cppad_autodiff(ADFunDouble &f, AutodiffSymbolicStructure &structure, CppADAutodiffGraph &graph,\n                    const std::vector<double> &x_values, const std::vector<double> &p_values)\n{\n\tauto nx = f.Domain();\n\tauto np = f.size_dyn_ind();\n\tassert(x_values.size() == nx);\n\tassert(p_values.size() == np);\n\n\tauto ny = f.Range();\n\n\tstructure.nx = nx;\n\tstructure.np = np;\n\tstructure.ny = ny;\n\tstructure.has_parameter = np > 0;\n\n\tf.to_graph(graph.f_graph);\n\n\tauto sparsity = jacobian_hessian_sparsity(f, HessianSparsityType::Upper);\n\n\t{\n\t\tauto &pattern = sparsity.jacobian;\n\t\tauto &m_jacobian_rows = structure.m_jacobian_rows;\n\t\tauto &m_jacobian_cols = structure.m_jacobian_cols;\n\t\tauto &m_jacobian_nnz = structure.m_jacobian_nnz;\n\t\tfor (int i = 0; i < pattern.nnz(); i++)\n\t\t{\n\t\t\tauto r = pattern.row()[i];\n\t\t\tauto c = pattern.col()[i];\n\t\t\tm_jacobian_rows.push_back(r);\n\t\t\tm_jacobian_cols.push_back(c);\n\t\t}\n\t\tm_jacobian_nnz = pattern.nnz();\n\t}\n\n\t{\n\t\tauto &pattern = sparsity.reduced_hessian;\n\t\tauto &m_hessian_rows = structure.m_hessian_rows;\n\t\tauto &m_hessian_cols = structure.m_hessian_cols;\n\t\tauto &m_hessian_nnz = structure.m_hessian_nnz;\n\t\tfor (int i = 0; i < pattern.nnz(); i++)\n\t\t{\n\t\t\tauto r = pattern.row()[i];\n\t\t\tauto c = pattern.col()[i];\n\t\t\tm_hessian_rows.push_back(r);\n\t\t\tm_hessian_cols.push_back(c);\n\t\t}\n\t\tm_hessian_nnz = pattern.nnz();\n\t}\n\n\tif (structure.m_jacobian_nnz > 0)\n\t{\n\t\tstructure.has_jacobian = true;\n\t\tADFunDouble jacobian = sparse_jacobian(f, sparsity.jacobian, x_values, p_values);\n\t\tjacobian.to_graph(graph.jacobian_graph);\n\t}\n\n\tif (structure.m_hessian_nnz > 0)\n\t{\n\t\tstructure.has_hessian = true;\n\t\tADFunDouble hessian =\n\t\t    sparse_hessian(f, sparsity.hessian, sparsity.reduced_hessian, x_values, p_values);\n\t\thessian.to_graph(graph.hessian_graph);\n\t}\n}\n"
  },
  {
    "path": "lib/cppad_interface_ext.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include <nanobind/make_iterator.h>\n#include <nanobind/stl/vector.h>\n#include <nanobind/stl/string.h>\n#include <nanobind/stl/optional.h>\n\nnamespace nb = nanobind;\n\n#include \"pyoptinterface/cppad_interface.hpp\"\n\nusing graph_op_enum = CppAD::graph::graph_op_enum;\n\nstruct cpp_graph_cursor\n{\n\tsize_t op_index = 0;\n\tsize_t arg_index = 0;\n};\n\ngraph_op_enum cursor_op(CppAD::cpp_graph &graph, cpp_graph_cursor &cursor)\n{\n\treturn graph.operator_vec_get(cursor.op_index);\n}\n\nsize_t cursor_n_arg(CppAD::cpp_graph &graph, cpp_graph_cursor &cursor)\n{\n\tauto op = cursor_op(graph, cursor);\n\n\tsize_t n_arg = 0;\n\n\tswitch (op)\n\t{\n\t// unary operators\n\tcase graph_op_enum::abs_graph_op:\n\tcase graph_op_enum::acos_graph_op:\n\tcase graph_op_enum::acosh_graph_op:\n\tcase graph_op_enum::asin_graph_op:\n\tcase graph_op_enum::asinh_graph_op:\n\tcase graph_op_enum::atan_graph_op:\n\tcase graph_op_enum::atanh_graph_op:\n\tcase graph_op_enum::cos_graph_op:\n\tcase graph_op_enum::cosh_graph_op:\n\tcase graph_op_enum::erf_graph_op:\n\tcase graph_op_enum::erfc_graph_op:\n\tcase graph_op_enum::exp_graph_op:\n\tcase graph_op_enum::expm1_graph_op:\n\tcase graph_op_enum::log1p_graph_op:\n\tcase graph_op_enum::log_graph_op:\n\tcase graph_op_enum::neg_graph_op:\n\tcase graph_op_enum::sign_graph_op:\n\tcase graph_op_enum::sin_graph_op:\n\tcase graph_op_enum::sinh_graph_op:\n\tcase graph_op_enum::sqrt_graph_op:\n\tcase graph_op_enum::tan_graph_op:\n\tcase graph_op_enum::tanh_graph_op:\n\t\tn_arg = 1;\n\t\tbreak;\n\n\t// binary operators\n\tcase graph_op_enum::add_graph_op:\n\tcase graph_op_enum::azmul_graph_op:\n\tcase graph_op_enum::div_graph_op:\n\tcase graph_op_enum::mul_graph_op:\n\tcase graph_op_enum::pow_graph_op:\n\tcase graph_op_enum::sub_graph_op:\n\t\tn_arg = 2;\n\t\tbreak;\n\n\t// conditional operators\n\tcase graph_op_enum::cexp_eq_graph_op:\n\tcase graph_op_enum::cexp_le_graph_op:\n\tcase graph_op_enum::cexp_lt_graph_op:\n\t\tn_arg = 4;\n\t\tbreak;\n\n\tdefault: {\n\t\tstd::string op_name = CppAD::local::graph::op_enum2name[op];\n\t\tauto message = \"Unknown graph_op: \" + op_name;\n\t\tthrow std::runtime_error(message);\n\t}\n\tbreak;\n\t}\n\n\treturn n_arg;\n}\n\nvoid advance_graph_cursor(CppAD::cpp_graph &graph, cpp_graph_cursor &cursor)\n{\n\tauto n_arg = cursor_n_arg(graph, cursor);\n\tcursor.arg_index += n_arg;\n\tcursor.op_index++;\n}\n\nNB_MODULE(cppad_interface_ext, m)\n{\n\tnb::enum_<graph_op_enum>(m, \"graph_op\")\n\t    .value(\"abs\", graph_op_enum::abs_graph_op)\n\t    .value(\"acos\", graph_op_enum::acos_graph_op)\n\t    .value(\"acosh\", graph_op_enum::acosh_graph_op)\n\t    .value(\"add\", graph_op_enum::add_graph_op)\n\t    .value(\"asin\", graph_op_enum::asin_graph_op)\n\t    .value(\"asinh\", graph_op_enum::asinh_graph_op)\n\t    .value(\"atan\", graph_op_enum::atan_graph_op)\n\t    .value(\"atanh\", graph_op_enum::atanh_graph_op)\n\t    .value(\"atom4\", graph_op_enum::atom4_graph_op)\n\t    .value(\"atom\", graph_op_enum::atom_graph_op)\n\t    .value(\"azmul\", graph_op_enum::azmul_graph_op)\n\t    .value(\"cexp_eq\", graph_op_enum::cexp_eq_graph_op)\n\t    .value(\"cexp_le\", graph_op_enum::cexp_le_graph_op)\n\t    .value(\"cexp_lt\", graph_op_enum::cexp_lt_graph_op)\n\t    .value(\"comp_eq\", graph_op_enum::comp_eq_graph_op)\n\t    .value(\"comp_le\", graph_op_enum::comp_le_graph_op)\n\t    .value(\"comp_lt\", graph_op_enum::comp_lt_graph_op)\n\t    .value(\"comp_ne\", graph_op_enum::comp_ne_graph_op)\n\t    .value(\"cos\", graph_op_enum::cos_graph_op)\n\t    .value(\"cosh\", graph_op_enum::cosh_graph_op)\n\t    .value(\"discrete\", graph_op_enum::discrete_graph_op)\n\t    .value(\"div\", graph_op_enum::div_graph_op)\n\t    .value(\"erf\", graph_op_enum::erf_graph_op)\n\t    .value(\"erfc\", graph_op_enum::erfc_graph_op)\n\t    .value(\"exp\", graph_op_enum::exp_graph_op)\n\t    .value(\"expm1\", graph_op_enum::expm1_graph_op)\n\t    .value(\"log1p\", graph_op_enum::log1p_graph_op)\n\t    .value(\"log\", graph_op_enum::log_graph_op)\n\t    .value(\"mul\", graph_op_enum::mul_graph_op)\n\t    .value(\"neg\", graph_op_enum::neg_graph_op)\n\t    .value(\"pow\", graph_op_enum::pow_graph_op)\n\t    .value(\"print\", graph_op_enum::print_graph_op)\n\t    .value(\"sign\", graph_op_enum::sign_graph_op)\n\t    .value(\"sin\", graph_op_enum::sin_graph_op)\n\t    .value(\"sinh\", graph_op_enum::sinh_graph_op)\n\t    .value(\"sqrt\", graph_op_enum::sqrt_graph_op)\n\t    .value(\"sub\", graph_op_enum::sub_graph_op)\n\t    .value(\"sum\", graph_op_enum::sum_graph_op)\n\t    .value(\"tan\", graph_op_enum::tan_graph_op)\n\t    .value(\"tanh\", graph_op_enum::tanh_graph_op);\n\n\tnb::class_<cpp_graph_cursor>(m, \"cpp_graph_cursor\")\n\t    .def(nb::init<>())\n\t    .def_ro(\"op_index\", &cpp_graph_cursor::op_index)\n\t    .def_ro(\"arg_index\", &cpp_graph_cursor::arg_index);\n\n\tnb::class_<CppAD::cpp_graph>(m, \"cpp_graph\")\n\t    .def(nb::init<>())\n\t    .def_prop_ro(\"n_dynamic_ind\", [](CppAD::cpp_graph &g) { return g.n_dynamic_ind_get(); })\n\t    .def_prop_ro(\"n_variable_ind\", [](CppAD::cpp_graph &g) { return g.n_variable_ind_get(); })\n\t    .def_prop_ro(\"n_constant\", [](CppAD::cpp_graph &g) { return g.constant_vec_size(); })\n\t    .def_prop_ro(\"n_dependent\", [](CppAD::cpp_graph &g) { return g.dependent_vec_size(); })\n\t    .def_prop_ro(\"n_operator\", [](CppAD::cpp_graph &g) { return g.operator_vec_size(); })\n\t    .def_prop_ro(\"n_operator_arg\", [](CppAD::cpp_graph &g) { return g.operator_arg_size(); })\n\t    .def(\"constant_vec_get\", &CppAD::cpp_graph::constant_vec_get)\n\t    .def(\"dependent_vec_get\", &CppAD::cpp_graph::dependent_vec_get)\n\t    .def(\"__str__\",\n\t         [](CppAD::cpp_graph &g) {\n\t\t         std::ostringstream oss;\n\t\t         g.print(oss);\n\t\t         return oss.str();\n\t         })\n\t    .def(\"get_cursor_op\", &cursor_op)\n\t    .def(\"get_cursor_n_arg\", &cursor_n_arg)\n\t    .def(\"get_cursor_args\",\n\t         [](CppAD::cpp_graph &graph, cpp_graph_cursor &cursor) {\n\t\t         auto n_arg = cursor_n_arg(graph, cursor);\n\t\t         nb::list args;\n\t\t         for (size_t i = 0; i < n_arg; i++)\n\t\t         {\n\t\t\t         auto arg = graph.operator_arg_get(cursor.arg_index + i);\n\t\t\t         args.append(nb::int_(arg));\n\t\t         }\n\t\t         return args;\n\t         })\n\t    .def(\"next_cursor\", &advance_graph_cursor);\n\n\tnb::class_<ADFunDouble>(m, \"ADFunDouble\")\n\t    .def(nb::init<>())\n\t    .def_prop_ro(\"nx\", [](const ADFunDouble &f) { return f.Domain(); })\n\t    .def_prop_ro(\"ny\", [](const ADFunDouble &f) { return f.Range(); })\n\t    .def_prop_ro(\"np\", [](const ADFunDouble &f) { return f.size_dyn_ind(); })\n\t    .def(\"to_graph\", &ADFunDouble::to_graph);\n\n\tnb::class_<CppADAutodiffGraph>(m, \"CppADAutodiffGraph\")\n\t    .def(nb::init<>())\n\t    .def_ro(\"f\", &CppADAutodiffGraph::f_graph)\n\t    .def_ro(\"jacobian\", &CppADAutodiffGraph::jacobian_graph)\n\t    .def_ro(\"hessian\", &CppADAutodiffGraph::hessian_graph);\n\n\tm.def(\"cppad_trace_graph_constraints\", cppad_trace_graph_constraints, nb::arg(\"graph\"),\n\t      nb::arg(\"selected\") = std::vector<size_t>{});\n\tm.def(\"cppad_trace_graph_objective\", cppad_trace_graph_objective, nb::arg(\"graph\"),\n\t      nb::arg(\"selected\") = std::vector<size_t>{}, nb::arg(\"aggregate\") = true);\n\tm.def(\"cppad_autodiff\", &cppad_autodiff);\n}\n"
  },
  {
    "path": "lib/gurobi_model.cpp",
    "content": "#include \"pyoptinterface/gurobi_model.hpp\"\n#include \"fmt/core.h\"\n\n#include <stack>\n\nextern \"C\"\n{\n\tint __stdcall GRBloadenvinternal(GRBenv **envP, const char *logfilename, int major, int minor,\n\t                                 int tech);\n\tint __stdcall GRBemptyenvinternal(GRBenv **envP, int major, int minor, int tech);\n\tint __stdcall GRBloadenv_1200(GRBenv **envP, const char *logfile);\n\tint __stdcall GRBemptyenv_1200(GRBenv **envP);\n}\n\nnamespace gurobi\n{\n#define B DYLIB_DECLARE\nAPILIST\n#undef B\n\n// Gurobi 12.0.0 workarounds\nDYLIB_DECLARE(GRBloadenvinternal);\nDYLIB_DECLARE(GRBemptyenvinternal);\n\nstatic DynamicLibrary lib;\nstatic bool is_loaded = false;\n\nbool is_library_loaded()\n{\n\treturn is_loaded;\n}\n\nbool load_library(const std::string &path)\n{\n\tbool success = lib.try_load(path.c_str());\n\tif (!success)\n\t{\n\t\treturn false;\n\t}\n\n\tDYLIB_LOAD_INIT;\n\n#define B DYLIB_LOAD_FUNCTION\n\tAPILIST\n#undef B\n\n\t// We have to deal with Gurobi 12.0.0 where some functions are absent from the dynamic library\n\t{\n\t\tint major, minor, techinical;\n\t\tauto GRBversion_p =\n\t\t    reinterpret_cast<decltype(GRBversion)>(_function_pointers[\"GRBversion\"]);\n\t\tif (GRBversion_p != nullptr)\n\t\t{\n\t\t\tGRBversion_p(&major, &minor, &techinical);\n\n\t\t\tif (major == 12 && minor == 0 && techinical == 0)\n\t\t\t{\n\t\t\t\tDYLIB_LOAD_FUNCTION(GRBloadenvinternal);\n\t\t\t\tDYLIB_LOAD_FUNCTION(GRBemptyenvinternal);\n\t\t\t\t_function_pointers[\"GRBloadenv\"] = reinterpret_cast<void *>(&GRBloadenv_1200);\n\t\t\t\t_function_pointers[\"GRBemptyenv\"] = reinterpret_cast<void *>(&GRBemptyenv_1200);\n\n\t\t\t\t// Now check there is no nullptr in _function_pointers\n\t\t\t\t_load_success = true;\n\t\t\t\tfor (auto &pair : _function_pointers)\n\t\t\t\t{\n\t\t\t\t\tif (pair.second == nullptr)\n\t\t\t\t\t{\n\t\t\t\t\t\tfmt::print(\"function {} is not loaded correctly\\n\", pair.first);\n\t\t\t\t\t\t_load_success = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (_load_success)\n\t\t\t\t{\n\t\t\t\t\tDYLIB_SAVE_FUNCTION(GRBloadenvinternal);\n\t\t\t\t\tDYLIB_SAVE_FUNCTION(GRBemptyenvinternal);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (IS_DYLIB_LOAD_SUCCESS)\n\t{\n#define B DYLIB_SAVE_FUNCTION\n\t\tAPILIST\n#undef B\n\t\tis_loaded = true;\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\treturn false;\n\t}\n}\n} // namespace gurobi\n\nint GRBloadenv_1200(GRBenv **envP, const char *logfile)\n{\n\treturn gurobi::GRBloadenvinternal(envP, logfile, 12, 0, 0);\n}\n\nint GRBemptyenv_1200(GRBenv **envP)\n{\n\treturn gurobi::GRBemptyenvinternal(envP, 12, 0, 0);\n}\n\nstatic char gurobi_con_sense(ConstraintSense sense)\n{\n\tswitch (sense)\n\t{\n\tcase ConstraintSense::LessEqual:\n\t\treturn GRB_LESS_EQUAL;\n\tcase ConstraintSense::Equal:\n\t\treturn GRB_EQUAL;\n\tcase ConstraintSense::GreaterEqual:\n\t\treturn GRB_GREATER_EQUAL;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint sense\");\n\t}\n}\n\nstatic int gurobi_obj_sense(ObjectiveSense sense)\n{\n\tswitch (sense)\n\t{\n\tcase ObjectiveSense::Minimize:\n\t\treturn GRB_MINIMIZE;\n\tcase ObjectiveSense::Maximize:\n\t\treturn GRB_MAXIMIZE;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown objective sense\");\n\t}\n}\n\nstatic char gurobi_vtype(VariableDomain domain)\n{\n\tswitch (domain)\n\t{\n\tcase VariableDomain::Continuous:\n\t\treturn GRB_CONTINUOUS;\n\tcase VariableDomain::Integer:\n\t\treturn GRB_INTEGER;\n\tcase VariableDomain::Binary:\n\t\treturn GRB_BINARY;\n\tcase VariableDomain::SemiContinuous:\n\t\treturn GRB_SEMICONT;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown variable domain\");\n\t}\n}\n\nstatic int gurobi_sostype(SOSType type)\n{\n\tswitch (type)\n\t{\n\tcase SOSType::SOS1:\n\t\treturn GRB_SOS_TYPE1;\n\tcase SOSType::SOS2:\n\t\treturn GRB_SOS_TYPE2;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown SOS type\");\n\t}\n}\n\nGurobiModel::GurobiModel(const GurobiEnv &env)\n{\n\tinit(env);\n}\n\nvoid GurobiModel::init(const GurobiEnv &env)\n{\n\tif (!gurobi::is_library_loaded())\n\t{\n\t\tthrow std::runtime_error(\"Gurobi library is not loaded\");\n\t}\n\n\tGRBmodel *model;\n\tint error = gurobi::GRBnewmodel(env.m_env, &model, NULL, 0, NULL, NULL, NULL, NULL, NULL);\n\tcheck_error(error);\n\tm_env = gurobi::GRBgetenv(model);\n\tm_model = std::unique_ptr<GRBmodel, GRBfreemodelT>(model);\n}\n\nvoid GurobiModel::close()\n{\n\tm_model.reset();\n}\n\nvoid GurobiModel::_reset(int clearall)\n{\n\tint error = gurobi::GRBreset(m_model.get(), clearall);\n\tcheck_error(error);\n}\n\ndouble GurobiModel::get_infinity() const\n{\n\treturn GRB_INFINITY;\n}\n\nvoid GurobiModel::write(const std::string &filename)\n{\n\tint error = gurobi::GRBwrite(m_model.get(), filename.c_str());\n\tcheck_error(error);\n}\n\nVariableIndex GurobiModel::add_variable(VariableDomain domain, double lb, double ub,\n                                        const char *name)\n{\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\tIndexT index = m_variable_index.add_index();\n\tVariableIndex variable(index);\n\n\t// Create a new Gurobi variable\n\tchar vtype = gurobi_vtype(domain);\n\tint error = gurobi::GRBaddvar(m_model.get(), 0, NULL, NULL, 0.0, lb, ub, vtype, name);\n\tcheck_error(error);\n\n\tm_update_flag |= m_variable_creation;\n\n\treturn variable;\n}\n\nvoid GurobiModel::delete_variable(const VariableIndex &variable)\n{\n\tif (!is_variable_active(variable))\n\t{\n\t\tthrow std::runtime_error(\"Variable does not exist\");\n\t}\n\n\t// Delete the corresponding Gurobi variable\n\tint variable_column = _variable_index(variable);\n\tint error = gurobi::GRBdelvars(m_model.get(), 1, &variable_column);\n\tcheck_error(error);\n\n\tm_variable_index.delete_index(variable.index);\n\n\tm_update_flag |= m_variable_deletion;\n}\n\nvoid GurobiModel::delete_variables(const Vector<VariableIndex> &variables)\n{\n\tint n_variables = variables.size();\n\tif (n_variables == 0)\n\t\treturn;\n\n\tstd::vector<int> columns;\n\tcolumns.reserve(n_variables);\n\tfor (int i = 0; i < n_variables; i++)\n\t{\n\t\tif (!is_variable_active(variables[i]))\n\t\t{\n\t\t\tcontinue;\n\t\t}\n\t\tauto column = _variable_index(variables[i]);\n\t\tcolumns.push_back(column);\n\t}\n\n\tint error = gurobi::GRBdelvars(m_model.get(), columns.size(), columns.data());\n\tcheck_error(error);\n\n\tfor (int i = 0; i < n_variables; i++)\n\t{\n\t\tm_variable_index.delete_index(variables[i].index);\n\t}\n\n\tm_update_flag |= m_variable_deletion;\n}\n\nbool GurobiModel::is_variable_active(const VariableIndex &variable)\n{\n\treturn m_variable_index.has_index(variable.index);\n}\n\ndouble GurobiModel::get_variable_value(const VariableIndex &variable)\n{\n\treturn get_variable_raw_attribute_double(variable, GRB_DBL_ATTR_X);\n}\n\nstd::string GurobiModel::pprint_variable(const VariableIndex &variable)\n{\n\treturn get_variable_raw_attribute_string(variable, GRB_STR_ATTR_VARNAME);\n}\n\nvoid GurobiModel::set_variable_bounds(const VariableIndex &variable, double lb, double ub)\n{\n\tauto column = _checked_variable_index(variable);\n\tint error;\n\terror = gurobi::GRBsetdblattrelement(m_model.get(), GRB_DBL_ATTR_LB, column, lb);\n\tcheck_error(error);\n\terror = gurobi::GRBsetdblattrelement(m_model.get(), GRB_DBL_ATTR_UB, column, ub);\n\tcheck_error(error);\n\tm_update_flag |= m_attribute_update;\n}\n\nvoid GurobiModel::set_variable_name(const VariableIndex &variable, const char *name)\n{\n\tset_variable_raw_attribute_string(variable, GRB_STR_ATTR_VARNAME, name);\n}\n\nvoid GurobiModel::set_constraint_name(const ConstraintIndex &constraint, const char *name)\n{\n\tconst char *attr_name;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\t\tattr_name = GRB_STR_ATTR_CONSTRNAME;\n\t\tbreak;\n\tcase ConstraintType::Quadratic:\n\t\tattr_name = GRB_STR_ATTR_QCNAME;\n\t\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type to set name!\");\n\t}\n\tset_constraint_raw_attribute_string(constraint, attr_name, name);\n}\n\nConstraintIndex GurobiModel::add_linear_constraint(const ScalarAffineFunction &function,\n                                                   ConstraintSense sense, CoeffT rhs,\n                                                   const char *name)\n{\n\tIndexT index = m_linear_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::Linear, index);\n\n\t// Create a new Gurobi linear constraint\n\tAffineFunctionPtrForm<int, int, double> ptr_form;\n\tptr_form.make(this, function);\n\n\tint numnz = ptr_form.numnz;\n\tint *cind = ptr_form.index;\n\tdouble *cval = ptr_form.value;\n\tchar g_sense = gurobi_con_sense(sense);\n\tdouble g_rhs = rhs - function.constant.value_or(0.0);\n\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\n\tint error = gurobi::GRBaddconstr(m_model.get(), numnz, cind, cval, g_sense, g_rhs, name);\n\tcheck_error(error);\n\t// _require_update();\n\n\tm_update_flag |= m_linear_constraint_creation;\n\n\treturn constraint_index;\n}\n\nConstraintIndex GurobiModel::add_quadratic_constraint(const ScalarQuadraticFunction &function,\n                                                      ConstraintSense sense, CoeffT rhs,\n                                                      const char *name)\n{\n\tIndexT index = m_quadratic_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::Quadratic, index);\n\n\t// Create a new Gurobi quadratic constraint\n\tconst auto &affine_part = function.affine_part;\n\n\tint numlnz = 0;\n\tint *lind = NULL;\n\tdouble *lval = NULL;\n\tAffineFunctionPtrForm<int, int, double> affine_ptr_form;\n\tif (affine_part.has_value())\n\t{\n\t\tconst auto &affine_function = affine_part.value();\n\t\taffine_ptr_form.make(this, affine_function);\n\t\tnumlnz = affine_ptr_form.numnz;\n\t\tlind = affine_ptr_form.index;\n\t\tlval = affine_ptr_form.value;\n\t}\n\n\tQuadraticFunctionPtrForm<int, int, double> ptr_form;\n\tptr_form.make(this, function);\n\tint numqnz = ptr_form.numnz;\n\tint *qrow = ptr_form.row;\n\tint *qcol = ptr_form.col;\n\tdouble *qval = ptr_form.value;\n\n\tchar g_sense = gurobi_con_sense(sense);\n\tdouble g_rhs = rhs;\n\tif (affine_part)\n\t\tg_rhs -= affine_part->constant.value_or(0.0);\n\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\n\tint error = gurobi::GRBaddqconstr(m_model.get(), numlnz, lind, lval, numqnz, qrow, qcol, qval,\n\t                                  g_sense, g_rhs, name);\n\tcheck_error(error);\n\n\tm_update_flag |= m_quadratic_constraint_creation;\n\n\treturn constraint_index;\n}\n\nConstraintIndex GurobiModel::add_sos_constraint(const Vector<VariableIndex> &variables,\n                                                SOSType sos_type)\n{\n\tVector<CoeffT> weights(variables.size(), 1.0);\n\treturn add_sos_constraint(variables, sos_type, weights);\n}\n\nConstraintIndex GurobiModel::add_sos_constraint(const Vector<VariableIndex> &variables,\n                                                SOSType sos_type, const Vector<CoeffT> &weights)\n{\n\tIndexT index = m_sos_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::SOS, index);\n\n\t// Create a new Gurobi SOS constraint\n\tint numsos = 1;\n\tint nummembers = variables.size();\n\tint types = gurobi_sostype(sos_type);\n\tint beg[] = {0, nummembers};\n\tstd::vector<int> ind_v(nummembers);\n\tfor (int i = 0; i < nummembers; i++)\n\t{\n\t\tind_v[i] = _variable_index(variables[i].index);\n\t}\n\tint *ind = ind_v.data();\n\tdouble *weight = (double *)weights.data();\n\n\tint error = gurobi::GRBaddsos(m_model.get(), numsos, nummembers, &types, beg, ind, weight);\n\tcheck_error(error);\n\n\tm_update_flag |= m_sos_constraint_creation;\n\n\treturn constraint_index;\n}\n\nint unary_opcode(const UnaryOperator &op)\n{\n\tswitch (op)\n\t{\n\tcase UnaryOperator::Neg:\n\t\treturn GRB_OPCODE_UMINUS;\n\tcase UnaryOperator::Sin:\n\t\treturn GRB_OPCODE_SIN;\n\tcase UnaryOperator::Cos:\n\t\treturn GRB_OPCODE_COS;\n\tcase UnaryOperator::Tan:\n\t\treturn GRB_OPCODE_TAN;\n\tcase UnaryOperator::Sqrt:\n\t\treturn GRB_OPCODE_SQRT;\n\tcase UnaryOperator::Exp:\n\t\treturn GRB_OPCODE_EXP;\n\tcase UnaryOperator::Log:\n\t\treturn GRB_OPCODE_LOG;\n\tcase UnaryOperator::Log10:\n\t\treturn GRB_OPCODE_LOG10;\n\tdefault: {\n\t\tauto opname = unary_operator_to_string(op);\n\t\tauto msg = fmt::format(\"Unknown unary operator for Gurobi: {}\", opname);\n\t\tthrow std::runtime_error(msg);\n\t}\n\t}\n}\n\nint binary_opcode(const BinaryOperator &op)\n{\n\tswitch (op)\n\t{\n\tcase BinaryOperator::Sub:\n\t\treturn GRB_OPCODE_MINUS;\n\tcase BinaryOperator::Div:\n\t\treturn GRB_OPCODE_DIVIDE;\n\tcase BinaryOperator::Pow:\n\t\treturn GRB_OPCODE_POW;\n\tdefault: {\n\t\tauto opname = binary_operator_to_string(op);\n\t\tauto msg = fmt::format(\"Unknown binary operator for Gurobi: {}\", opname);\n\t\tthrow std::runtime_error(msg);\n\t}\n\t}\n}\n\nint nary_opcode(const NaryOperator &op)\n{\n\tswitch (op)\n\t{\n\tcase NaryOperator::Add:\n\t\treturn GRB_OPCODE_PLUS;\n\tcase NaryOperator::Mul:\n\t\treturn GRB_OPCODE_MULTIPLY;\n\tdefault: {\n\t\tauto opname = nary_operator_to_string(op);\n\t\tauto msg = fmt::format(\"Unknown n-ary operator for Gurobi: {}\", opname);\n\t\tthrow std::runtime_error(msg);\n\t}\n\t}\n}\n\nvoid GurobiModel::information_of_expr(const ExpressionGraph &graph, const ExpressionHandle &expr,\n                                      int &opcode, double &data)\n{\n\tauto array_type = expr.array;\n\tauto index = expr.id;\n\tswitch (array_type)\n\t{\n\tcase ArrayType::Constant: {\n\t\topcode = GRB_OPCODE_CONSTANT;\n\t\tdata = graph.m_constants[index];\n\t\tbreak;\n\t}\n\tcase ArrayType::Variable: {\n\t\topcode = GRB_OPCODE_VARIABLE;\n\t\tdata = _checked_variable_index(graph.m_variables[index]);\n\t\tbreak;\n\t}\n\tcase ArrayType::Parameter: {\n\t\tthrow std::runtime_error(\"Parameter is not supported in Gurobi\");\n\t\tbreak;\n\t}\n\tcase ArrayType::Unary: {\n\t\tauto &unary = graph.m_unaries[index];\n\t\topcode = unary_opcode(unary.op);\n\t\tdata = 0.0;\n\t\tbreak;\n\t}\n\tcase ArrayType::Binary: {\n\t\tauto &binary = graph.m_binaries[index];\n\t\topcode = binary_opcode(binary.op);\n\t\tdata = 0.0;\n\t\tbreak;\n\t}\n\tcase ArrayType::Ternary: {\n\t\tthrow std::runtime_error(\"Ternary operator is not supported in Gurobi\");\n\t\tbreak;\n\t}\n\tcase ArrayType::Nary: {\n\t\tauto &nary = graph.m_naries[index];\n\t\topcode = nary_opcode(nary.op);\n\t\tdata = 0.0;\n\t\tbreak;\n\t}\n\t}\n}\n\nvoid GurobiModel::decode_graph(const ExpressionGraph &graph, const ExpressionHandle &result,\n                               std::vector<int> &opcodes, std::vector<int> &parents,\n                               std::vector<double> &datas)\n{\n\tstd::stack<ExpressionHandle> expr_stack;\n\tstd::stack<int> parent_stack;\n\n\t// init stack\n\texpr_stack.push(result);\n\tparent_stack.push(-1);\n\n\twhile (!expr_stack.empty())\n\t{\n\t\tauto expr = expr_stack.top();\n\t\texpr_stack.pop();\n\t\tauto parent = parent_stack.top();\n\t\tparent_stack.pop();\n\n\t\tint opcode;\n\t\tdouble data;\n\t\tinformation_of_expr(graph, expr, opcode, data);\n\n\t\tauto current_parent = opcodes.size();\n\t\topcodes.push_back(opcode);\n\t\tparents.push_back(parent);\n\t\tdatas.push_back(data);\n\n\t\tauto array_type = expr.array;\n\t\tauto index = expr.id;\n\t\tswitch (array_type)\n\t\t{\n\t\tcase ArrayType::Unary: {\n\t\t\tauto &unary = graph.m_unaries[index];\n\t\t\texpr_stack.push(unary.operand);\n\t\t\tparent_stack.push(current_parent);\n\t\t\tbreak;\n\t\t}\n\t\tcase ArrayType::Binary: {\n\t\t\tauto &binary = graph.m_binaries[index];\n\t\t\texpr_stack.push(binary.right);\n\t\t\texpr_stack.push(binary.left);\n\t\t\tparent_stack.push(current_parent);\n\t\t\tparent_stack.push(current_parent);\n\t\t\tbreak;\n\t\t}\n\t\tcase ArrayType::Nary: {\n\t\t\tauto &nary = graph.m_naries[index];\n\t\t\tfor (int i = nary.operands.size() - 1; i >= 0; i--)\n\t\t\t{\n\t\t\t\texpr_stack.push(nary.operands[i]);\n\t\t\t\tparent_stack.push(current_parent);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nConstraintIndex GurobiModel::add_single_nl_constraint(const ExpressionGraph &graph,\n                                                      const ExpressionHandle &result,\n                                                      const std::tuple<double, double> &interval,\n                                                      const char *name)\n{\n\tdouble lb = std::get<0>(interval);\n\tdouble ub = std::get<1>(interval);\n\n\tstd::vector<int> opcodes, parents;\n\tstd::vector<double> datas;\n\n\tdecode_graph(graph, result, opcodes, parents, datas);\n\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\n\t// add a slack variable\n\tVariableIndex resvar = add_variable(VariableDomain::Continuous, lb, ub, name);\n\tauto resvar_column = _variable_index(resvar);\n\n\t// add NL constraint\n\tint error = gurobi::GRBaddgenconstrNL(m_model.get(), name, resvar_column, opcodes.size(),\n\t                                      opcodes.data(), datas.data(), parents.data());\n\tcheck_error(error);\n\n\tIndexT constraint_index = m_general_constraint_index.add_index();\n\n\tConstraintIndex constraint(ConstraintType::NL, constraint_index);\n\tm_nlcon_resvar_map.emplace(constraint_index, resvar.index);\n\n\tm_update_flag |= m_general_constraint_creation;\n\n\treturn constraint;\n}\n\nvoid GurobiModel::delete_constraint(const ConstraintIndex &constraint)\n{\n\t// Delete the corresponding Gurobi constraint\n\tint error = 0;\n\tint constraint_row = _constraint_index(constraint);\n\tif (constraint_row >= 0)\n\t{\n\t\tswitch (constraint.type)\n\t\t{\n\t\tcase ConstraintType::Linear:\n\t\t\tm_linear_constraint_index.delete_index(constraint.index);\n\t\t\terror = gurobi::GRBdelconstrs(m_model.get(), 1, &constraint_row);\n\t\t\tm_update_flag |= m_linear_constraint_deletion;\n\t\t\tbreak;\n\t\tcase ConstraintType::Quadratic:\n\t\t\tm_quadratic_constraint_index.delete_index(constraint.index);\n\t\t\terror = gurobi::GRBdelqconstrs(m_model.get(), 1, &constraint_row);\n\t\t\tm_update_flag |= m_quadratic_constraint_deletion;\n\t\t\tbreak;\n\t\tcase ConstraintType::SOS:\n\t\t\tm_sos_constraint_index.delete_index(constraint.index);\n\t\t\terror = gurobi::GRBdelsos(m_model.get(), 1, &constraint_row);\n\t\t\tm_update_flag |= m_sos_constraint_deletion;\n\t\t\tbreak;\n\t\tcase ConstraintType::NL: {\n\t\t\tm_general_constraint_index.delete_index(constraint.index);\n\t\t\terror = gurobi::GRBdelgenconstrs(m_model.get(), 1, &constraint_row);\n\t\t\t// delete the corresponding resvar variable as well\n\t\t\tauto resvar = m_nlcon_resvar_map.at(constraint.index);\n\t\t\tdelete_variable(VariableIndex(resvar));\n\t\t\tm_update_flag |= m_general_constraint_deletion;\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t\t}\n\t}\n\tcheck_error(error);\n}\n\nbool GurobiModel::is_constraint_active(const ConstraintIndex &constraint)\n{\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\t\treturn m_linear_constraint_index.has_index(constraint.index);\n\tcase ConstraintType::Quadratic:\n\t\treturn m_quadratic_constraint_index.has_index(constraint.index);\n\tcase ConstraintType::SOS:\n\t\treturn m_sos_constraint_index.has_index(constraint.index);\n\tcase ConstraintType::NL:\n\t\treturn m_general_constraint_index.has_index(constraint.index);\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n}\n\nvoid GurobiModel::_set_affine_objective(const ScalarAffineFunction &function, ObjectiveSense sense,\n                                        bool clear_quadratic)\n{\n\tint error = 0;\n\tif (clear_quadratic)\n\t{\n\t\t// First delete all quadratic terms\n\t\terror = gurobi::GRBdelq(m_model.get());\n\t\tcheck_error(error);\n\t}\n\n\t// Set Obj attribute of each variable\n\tint n_variables = get_model_raw_attribute_int(GRB_INT_ATTR_NUMVARS);\n\tstd::vector<double> obj_v(n_variables, 0.0);\n\n\tint numnz = function.size();\n\tfor (int i = 0; i < numnz; i++)\n\t{\n\t\tauto column = _variable_index(function.variables[i]);\n\t\tif (column < 0)\n\t\t{\n\t\t\tthrow std::runtime_error(\"Variable does not exist\");\n\t\t}\n\t\tobj_v[column] = function.coefficients[i];\n\t}\n\n\terror = gurobi::GRBsetdblattrarray(m_model.get(), \"Obj\", 0, n_variables, obj_v.data());\n\tcheck_error(error);\n\terror = gurobi::GRBsetdblattr(m_model.get(), \"ObjCon\", function.constant.value_or(0.0));\n\tcheck_error(error);\n\n\tint obj_sense = gurobi_obj_sense(sense);\n\tset_model_raw_attribute_int(\"ModelSense\", obj_sense);\n\n\tm_update_flag |= m_objective_update;\n}\n\nvoid GurobiModel::set_objective(const ScalarAffineFunction &function, ObjectiveSense sense)\n{\n\t_set_affine_objective(function, sense, true);\n}\n\nvoid GurobiModel::set_objective(const ScalarQuadraticFunction &function, ObjectiveSense sense)\n{\n\tint error = 0;\n\t// First delete all quadratic terms\n\terror = gurobi::GRBdelq(m_model.get());\n\tcheck_error(error);\n\n\t// Add quadratic term\n\tint numqnz = function.size();\n\tif (numqnz > 0)\n\t{\n\t\tQuadraticFunctionPtrForm<int, int, double> ptr_form;\n\t\tptr_form.make(this, function);\n\t\tint numqnz = ptr_form.numnz;\n\t\tint *qrow = ptr_form.row;\n\t\tint *qcol = ptr_form.col;\n\t\tdouble *qval = ptr_form.value;\n\n\t\terror = gurobi::GRBaddqpterms(m_model.get(), numqnz, qrow, qcol, qval);\n\t\tcheck_error(error);\n\t}\n\n\t// Affine part\n\tconst auto &affine_part = function.affine_part;\n\tif (affine_part)\n\t{\n\t\tconst auto &affine_function = affine_part.value();\n\t\t_set_affine_objective(affine_function, sense, false);\n\t}\n\telse\n\t{\n\t\tScalarAffineFunction zero;\n\t\t_set_affine_objective(zero, sense, false);\n\t}\n}\n\nvoid GurobiModel::set_objective(const ExprBuilder &function, ObjectiveSense sense)\n{\n\tauto deg = function.degree();\n\tif (deg <= 1)\n\t{\n\t\tScalarAffineFunction f(function);\n\t\tset_objective(f, sense);\n\t}\n\telse if (deg == 2)\n\t{\n\t\tScalarQuadraticFunction f(function);\n\t\tset_objective(f, sense);\n\t}\n\telse\n\t{\n\t\tthrow std::runtime_error(\"Objective must be linear or quadratic\");\n\t}\n}\n\nvoid GurobiModel::add_single_nl_objective(ExpressionGraph &graph, const ExpressionHandle &result)\n{\n\tstd::vector<int> opcodes, parents;\n\tstd::vector<double> datas;\n\n\tdecode_graph(graph, result, opcodes, parents, datas);\n\n\t// add a slack variable\n\tVariableIndex resvar = add_variable(VariableDomain::Continuous);\n\tauto resvar_column = _variable_index(resvar);\n\n\t// add NL constraint\n\tint error = gurobi::GRBaddgenconstrNL(m_model.get(), nullptr, resvar_column, opcodes.size(),\n\t                                      opcodes.data(), datas.data(), parents.data());\n\tcheck_error(error);\n\n\tIndexT constraint_index = m_general_constraint_index.add_index();\n\n\tm_nlobj_num += 1;\n\tm_nlobj_con_indices.push_back(constraint_index);\n\tm_nlobj_resvar_indices.push_back(resvar.index);\n\n\tm_update_flag |= m_general_constraint_creation;\n}\n\nvoid GurobiModel::set_nl_objective()\n{\n\tif (m_nlobj_num > 0)\n\t{\n\t\tstd::vector<int> resvar_columns(m_nlobj_num);\n\t\tstd::vector<double> resvar_objcoefs(m_nlobj_num);\n\t\tstd::fill(resvar_objcoefs.begin(), resvar_objcoefs.end(), 1.0);\n\n\t\tfor (int i = 0; i < m_nlobj_num; i++)\n\t\t{\n\t\t\tauto resvar = m_nlobj_resvar_indices[i];\n\t\t\tresvar_columns[i] = _variable_index(resvar);\n\t\t}\n\n\t\tint error = gurobi::GRBsetdblattrlist(m_model.get(), GRB_DBL_ATTR_OBJ, m_nlobj_num,\n\t\t                                      resvar_columns.data(), resvar_objcoefs.data());\n\t\tcheck_error(error);\n\t}\n}\n\nvoid GurobiModel::optimize()\n{\n\tif (has_callback)\n\t{\n\t\t// Store the number of variables for the callback\n\t\tm_callback_userdata.n_variables = get_model_raw_attribute_int(GRB_INT_ATTR_NUMVARS);\n\t}\n\tset_nl_objective();\n\tm_update_flag = 0;\n\tint error = gurobi::GRBoptimize(m_model.get());\n\tcheck_error(error);\n}\n\nvoid GurobiModel::update()\n{\n\tint error = gurobi::GRBupdatemodel(m_model.get());\n\tcheck_error(error);\n\tm_update_flag = 0;\n}\n\nint GurobiModel::raw_parameter_type(const char *param_name)\n{\n\treturn gurobi::GRBgetparamtype(m_env, param_name);\n}\n\nvoid GurobiModel::set_raw_parameter_int(const char *param_name, int value)\n{\n\tint error = gurobi::GRBsetintparam(m_env, param_name, value);\n\tcheck_error(error);\n}\n\nvoid GurobiModel::set_raw_parameter_double(const char *param_name, double value)\n{\n\tint error = gurobi::GRBsetdblparam(m_env, param_name, value);\n\tcheck_error(error);\n}\n\nvoid GurobiModel::set_raw_parameter_string(const char *param_name, const char *value)\n{\n\tint error = gurobi::GRBsetstrparam(m_env, param_name, value);\n\tcheck_error(error);\n}\n\nint GurobiModel::get_raw_parameter_int(const char *param_name)\n{\n\tint retval;\n\tint error = gurobi::GRBgetintparam(m_env, param_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble GurobiModel::get_raw_parameter_double(const char *param_name)\n{\n\tdouble retval;\n\tint error = gurobi::GRBgetdblparam(m_env, param_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nstd::string GurobiModel::get_raw_parameter_string(const char *param_name)\n{\n\tchar retval[GRB_MAX_STRLEN];\n\tint error = gurobi::GRBgetstrparam(m_env, param_name, retval);\n\tcheck_error(error);\n\treturn std::string(retval);\n}\n\nint GurobiModel::raw_attribute_type(const char *attr_name)\n{\n\tint datatypeP;\n\tint error = gurobi::GRBgetattrinfo(m_model.get(), attr_name, &datatypeP, NULL, NULL);\n\tcheck_error(error);\n\treturn datatypeP;\n}\n\nvoid GurobiModel::set_model_raw_attribute_int(const char *attr_name, int value)\n{\n\tint error = gurobi::GRBsetintattr(m_model.get(), attr_name, value);\n\tcheck_error(error);\n\tm_update_flag |= m_attribute_update;\n}\n\nvoid GurobiModel::set_model_raw_attribute_double(const char *attr_name, double value)\n{\n\tint error = gurobi::GRBsetdblattr(m_model.get(), attr_name, value);\n\tcheck_error(error);\n\tm_update_flag |= m_attribute_update;\n}\n\nvoid GurobiModel::set_model_raw_attribute_string(const char *attr_name, const char *value)\n{\n\tint error = gurobi::GRBsetstrattr(m_model.get(), attr_name, value);\n\tcheck_error(error);\n\tm_update_flag |= m_attribute_update;\n}\n\nint GurobiModel::get_model_raw_attribute_int(const char *attr_name)\n{\n\t_update_for_information();\n\tint retval;\n\tint error = gurobi::GRBgetintattr(m_model.get(), attr_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble GurobiModel::get_model_raw_attribute_double(const char *attr_name)\n{\n\t_update_for_information();\n\tdouble retval;\n\tint error = gurobi::GRBgetdblattr(m_model.get(), attr_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nstd::string GurobiModel::get_model_raw_attribute_string(const char *attr_name)\n{\n\t_update_for_information();\n\tchar *retval;\n\tint error = gurobi::GRBgetstrattr(m_model.get(), attr_name, &retval);\n\tcheck_error(error);\n\treturn std::string(retval);\n}\n\nstd::vector<double> GurobiModel::get_model_raw_attribute_vector_double(const char *attr_name,\n                                                                       int start, int len)\n{\n\t_update_for_information();\n\tstd::vector<double> retval(len);\n\tint error = gurobi::GRBgetdblattrarray(m_model.get(), attr_name, start, len, retval.data());\n\tcheck_error(error);\n\treturn retval;\n}\n\nstd::vector<double> GurobiModel::get_model_raw_attribute_list_double(const char *attr_name,\n                                                                     const std::vector<int> &ind)\n{\n\t_update_for_information();\n\tstd::vector<double> retval(ind.size());\n\tint error = gurobi::GRBgetdblattrlist(m_model.get(), attr_name, ind.size(), (int *)ind.data(),\n\t                                      retval.data());\n\tcheck_error(error);\n\treturn retval;\n}\n\nvoid GurobiModel::set_variable_raw_attribute_int(const VariableIndex &variable,\n                                                 const char *attr_name, int value)\n{\n\tauto column = _checked_variable_index(variable);\n\tint error = gurobi::GRBsetintattrelement(m_model.get(), attr_name, column, value);\n\tcheck_error(error);\n\tm_update_flag |= m_attribute_update;\n}\n\nvoid GurobiModel::set_variable_raw_attribute_char(const VariableIndex &variable,\n                                                  const char *attr_name, char value)\n{\n\tauto column = _checked_variable_index(variable);\n\tint error = gurobi::GRBsetcharattrelement(m_model.get(), attr_name, column, value);\n\tcheck_error(error);\n\tm_update_flag |= m_attribute_update;\n}\n\nvoid GurobiModel::set_variable_raw_attribute_double(const VariableIndex &variable,\n                                                    const char *attr_name, double value)\n{\n\tauto column = _checked_variable_index(variable);\n\tint error = gurobi::GRBsetdblattrelement(m_model.get(), attr_name, column, value);\n\tcheck_error(error);\n\tm_update_flag |= m_attribute_update;\n}\n\nvoid GurobiModel::set_variable_raw_attribute_string(const VariableIndex &variable,\n                                                    const char *attr_name, const char *value)\n{\n\tauto column = _checked_variable_index(variable);\n\tint error = gurobi::GRBsetstrattrelement(m_model.get(), attr_name, column, value);\n\tcheck_error(error);\n\tm_update_flag |= m_attribute_update;\n}\n\nint GurobiModel::get_variable_raw_attribute_int(const VariableIndex &variable,\n                                                const char *attr_name)\n{\n\t_update_for_information();\n\tauto column = _checked_variable_index(variable);\n\tint retval;\n\tint error = gurobi::GRBgetintattrelement(m_model.get(), attr_name, column, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nchar GurobiModel::get_variable_raw_attribute_char(const VariableIndex &variable,\n                                                  const char *attr_name)\n{\n\t_update_for_information();\n\tauto column = _checked_variable_index(variable);\n\tchar retval;\n\tint error = gurobi::GRBgetcharattrelement(m_model.get(), attr_name, column, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble GurobiModel::get_variable_raw_attribute_double(const VariableIndex &variable,\n                                                      const char *attr_name)\n{\n\t_update_for_information();\n\tauto column = _checked_variable_index(variable);\n\tdouble retval;\n\tint error = gurobi::GRBgetdblattrelement(m_model.get(), attr_name, column, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nstd::string GurobiModel::get_variable_raw_attribute_string(const VariableIndex &variable,\n                                                           const char *attr_name)\n{\n\t_update_for_information();\n\tauto column = _checked_variable_index(variable);\n\tchar *retval;\n\tint error = gurobi::GRBgetstrattrelement(m_model.get(), attr_name, column, &retval);\n\tcheck_error(error);\n\treturn std::string(retval);\n}\n\nint GurobiModel::_variable_index(const VariableIndex &variable)\n{\n\t_update_for_variable_index();\n\treturn m_variable_index.get_index(variable.index);\n}\n\nint GurobiModel::_checked_variable_index(const VariableIndex &variable)\n{\n\tint column = _variable_index(variable);\n\tif (column < 0)\n\t{\n\t\tthrow std::runtime_error(\"Variable does not exist\");\n\t}\n\treturn column;\n}\n\nvoid GurobiModel::set_constraint_raw_attribute_int(const ConstraintIndex &constraint,\n                                                   const char *attr_name, int value)\n{\n\tint row = _checked_constraint_index(constraint);\n\tint error = gurobi::GRBsetintattrelement(m_model.get(), attr_name, row, value);\n\tcheck_error(error);\n\tm_update_flag |= m_attribute_update;\n}\n\nvoid GurobiModel::set_constraint_raw_attribute_char(const ConstraintIndex &constraint,\n                                                    const char *attr_name, char value)\n{\n\tint row = _checked_constraint_index(constraint);\n\tint error = gurobi::GRBsetcharattrelement(m_model.get(), attr_name, row, value);\n\tcheck_error(error);\n\tm_update_flag |= m_attribute_update;\n}\n\nvoid GurobiModel::set_constraint_raw_attribute_double(const ConstraintIndex &constraint,\n                                                      const char *attr_name, double value)\n{\n\tint row = _checked_constraint_index(constraint);\n\tint error = gurobi::GRBsetdblattrelement(m_model.get(), attr_name, row, value);\n\tcheck_error(error);\n\tm_update_flag |= m_attribute_update;\n}\n\nvoid GurobiModel::set_constraint_raw_attribute_string(const ConstraintIndex &constraint,\n                                                      const char *attr_name, const char *value)\n{\n\tint row = _checked_constraint_index(constraint);\n\tint error = gurobi::GRBsetstrattrelement(m_model.get(), attr_name, row, value);\n\tcheck_error(error);\n\tm_update_flag |= m_attribute_update;\n}\n\nint GurobiModel::get_constraint_raw_attribute_int(const ConstraintIndex &constraint,\n                                                  const char *attr_name)\n{\n\t_update_for_information();\n\tint row = _checked_constraint_index(constraint);\n\tint retval;\n\tint error = gurobi::GRBgetintattrelement(m_model.get(), attr_name, row, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nchar GurobiModel::get_constraint_raw_attribute_char(const ConstraintIndex &constraint,\n                                                    const char *attr_name)\n{\n\t_update_for_information();\n\tint row = _checked_constraint_index(constraint);\n\tchar retval;\n\tint error = gurobi::GRBgetcharattrelement(m_model.get(), attr_name, row, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble GurobiModel::get_constraint_raw_attribute_double(const ConstraintIndex &constraint,\n                                                        const char *attr_name)\n{\n\t_update_for_information();\n\tint row = _checked_constraint_index(constraint);\n\tdouble retval;\n\tint error = gurobi::GRBgetdblattrelement(m_model.get(), attr_name, row, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nstd::string GurobiModel::get_constraint_raw_attribute_string(const ConstraintIndex &constraint,\n                                                             const char *attr_name)\n{\n\t_update_for_information();\n\tint row = _checked_constraint_index(constraint);\n\tchar *retval;\n\tint error = gurobi::GRBgetstrattrelement(m_model.get(), attr_name, row, &retval);\n\tcheck_error(error);\n\treturn std::string(retval);\n}\n\ndouble GurobiModel::get_normalized_rhs(const ConstraintIndex &constraint)\n{\n\tconst char *name;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\t\tname = GRB_DBL_ATTR_RHS;\n\t\tbreak;\n\tcase ConstraintType::Quadratic:\n\t\tname = GRB_DBL_ATTR_QCRHS;\n\t\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type to get_normalized_rhs\");\n\t}\n\treturn get_constraint_raw_attribute_double(constraint, name);\n}\n\nvoid GurobiModel::set_normalized_rhs(const ConstraintIndex &constraint, double value)\n{\n\tconst char *name;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\t\tname = GRB_DBL_ATTR_RHS;\n\t\tbreak;\n\tcase ConstraintType::Quadratic:\n\t\tname = GRB_DBL_ATTR_QCRHS;\n\t\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type to set_normalized_rhs\");\n\t}\n\tset_constraint_raw_attribute_double(constraint, name, value);\n}\n\ndouble GurobiModel::get_normalized_coefficient(const ConstraintIndex &constraint,\n                                               const VariableIndex &variable)\n{\n\tif (constraint.type != ConstraintType::Linear)\n\t{\n\t\tthrow std::runtime_error(\"Only linear constraint supports get_normalized_coefficient\");\n\t}\n\t_update_for_information();\n\tint row = _checked_constraint_index(constraint);\n\tint col = _checked_variable_index(variable);\n\tdouble retval;\n\tint error = gurobi::GRBgetcoeff(m_model.get(), row, col, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nvoid GurobiModel::set_normalized_coefficient(const ConstraintIndex &constraint,\n                                             const VariableIndex &variable, double value)\n{\n\tif (constraint.type != ConstraintType::Linear)\n\t{\n\t\tthrow std::runtime_error(\"Only linear constraint supports set_normalized_coefficient\");\n\t}\n\tint row = _checked_constraint_index(constraint);\n\tint col = _checked_variable_index(variable);\n\tint error = gurobi::GRBchgcoeffs(m_model.get(), 1, &row, &col, &value);\n\tcheck_error(error);\n\tm_update_flag |= m_constraint_coefficient_update;\n}\n\ndouble GurobiModel::get_objective_coefficient(const VariableIndex &variable)\n{\n\treturn get_variable_raw_attribute_double(variable, GRB_DBL_ATTR_OBJ);\n}\n\nvoid GurobiModel::set_objective_coefficient(const VariableIndex &variable, double value)\n{\n\tset_variable_raw_attribute_double(variable, GRB_DBL_ATTR_OBJ, value);\n}\n\nvoid GurobiModel::_converttofixed()\n{\n\tint error = gurobi::GRBconverttofixed(m_model.get());\n\tcheck_error(error);\n}\n\nvoid GurobiModel::computeIIS()\n{\n\tint error = gurobi::GRBcomputeIIS(m_model.get());\n\tcheck_error(error);\n}\n\nint GurobiModel::_constraint_index(const ConstraintIndex &constraint)\n{\n\t_update_for_constraint_index(constraint.type);\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\t\treturn m_linear_constraint_index.get_index(constraint.index);\n\tcase ConstraintType::Quadratic:\n\t\treturn m_quadratic_constraint_index.get_index(constraint.index);\n\tcase ConstraintType::SOS:\n\t\treturn m_sos_constraint_index.get_index(constraint.index);\n\tcase ConstraintType::NL:\n\t\treturn m_general_constraint_index.get_index(constraint.index);\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n}\n\nint GurobiModel::_checked_constraint_index(const ConstraintIndex &constraint)\n{\n\tint row = _constraint_index(constraint);\n\tif (row < 0)\n\t{\n\t\tthrow std::runtime_error(\"Variable does not exist\");\n\t}\n\treturn row;\n}\n\nvoid GurobiModel::check_error(int error)\n{\n\tif (error)\n\t{\n\t\tthrow std::runtime_error(gurobi::GRBgeterrormsg(m_env));\n\t}\n}\n\nvoid GurobiModel::_update_for_information()\n{\n\tif (m_update_flag)\n\t{\n\t\tupdate();\n\t}\n}\n\nvoid GurobiModel::_update_for_variable_index()\n{\n\tif (m_update_flag & m_variable_deletion)\n\t{\n\t\tupdate();\n\t}\n}\n\nvoid GurobiModel::_update_for_constraint_index(ConstraintType type)\n{\n\tbool need_update = false;\n\tswitch (type)\n\t{\n\tcase ConstraintType::Linear:\n\t\t// Adding new linear constraints does not need to update the model\n\t\tneed_update = m_update_flag & m_linear_constraint_deletion;\n\t\tbreak;\n\tcase ConstraintType::Quadratic:\n\t\tneed_update =\n\t\t    m_update_flag & (m_quadratic_constraint_creation | m_quadratic_constraint_deletion);\n\t\tbreak;\n\tcase ConstraintType::SOS:\n\t\tneed_update = m_update_flag & (m_sos_constraint_creation | m_sos_constraint_deletion);\n\t\tbreak;\n\tcase ConstraintType::NL:\n\t\tneed_update =\n\t\t    m_update_flag & (m_general_constraint_creation | m_general_constraint_deletion);\n\t\tbreak;\n\t}\n\tif (need_update)\n\t{\n\t\tupdate();\n\t}\n}\n\nvoid *GurobiModel::get_raw_model()\n{\n\treturn m_model.get();\n}\n\nstd::string GurobiModel::version_string()\n{\n\tint major, minor, techinical;\n\tgurobi::GRBversion(&major, &minor, &techinical);\n\tstd::string version = fmt::format(\"v{}.{}.{}\", major, minor, techinical);\n\treturn version;\n}\n\nGurobiEnv::GurobiEnv(bool empty)\n{\n\tif (!gurobi::is_library_loaded())\n\t{\n\t\tthrow std::runtime_error(\"Gurobi library is not loaded\");\n\t}\n\n\tint error = 0;\n\tif (empty)\n\t{\n\t\terror = gurobi::GRBemptyenv(&m_env);\n\t}\n\telse\n\t{\n\t\terror = gurobi::GRBloadenv(&m_env, NULL);\n\t}\n\tcheck_error(error);\n}\n\nGurobiEnv::~GurobiEnv()\n{\n\tclose();\n}\n\nint GurobiEnv::raw_parameter_type(const char *param_name)\n{\n\treturn gurobi::GRBgetparamtype(m_env, param_name);\n}\n\nvoid GurobiEnv::set_raw_parameter_int(const char *param_name, int value)\n{\n\tint error = gurobi::GRBsetintparam(m_env, param_name, value);\n\tcheck_error(error);\n}\n\nvoid GurobiEnv::set_raw_parameter_double(const char *param_name, double value)\n{\n\tint error = gurobi::GRBsetdblparam(m_env, param_name, value);\n\tcheck_error(error);\n}\n\nvoid GurobiEnv::set_raw_parameter_string(const char *param_name, const char *value)\n{\n\tint error = gurobi::GRBsetstrparam(m_env, param_name, value);\n\tcheck_error(error);\n}\n\nvoid GurobiEnv::start()\n{\n\tint error = gurobi::GRBstartenv(m_env);\n\tcheck_error(error);\n}\n\nvoid GurobiEnv::close()\n{\n\tif (m_env != nullptr)\n\t{\n\t\tgurobi::GRBfreeenv(m_env);\n\t}\n\tm_env = nullptr;\n}\n\nvoid GurobiEnv::check_error(int error)\n{\n\tif (error)\n\t{\n\t\tthrow std::runtime_error(gurobi::GRBgeterrormsg(m_env));\n\t}\n}\n\n// Logging callback\nstatic int RealLoggingCallbackFunction(char *msg, void *logdata)\n{\n\tauto real_logdata = static_cast<GurobiLoggingCallbackUserdata *>(logdata);\n\tauto &callback = real_logdata->callback;\n\tcallback(msg);\n\treturn 0;\n}\n\nvoid GurobiModel::set_logging(const GurobiLoggingCallback &callback)\n{\n\tm_logging_callback_userdata.callback = callback;\n\tint error = gurobi::GRBsetlogcallbackfunc(m_model.get(), &RealLoggingCallbackFunction,\n\t                                          &m_logging_callback_userdata);\n\tcheck_error(error);\n}\n\n// Callback\nstatic int RealGurobiCallbackFunction(GRBmodel *, void *cbdata, int where, void *usrdata)\n{\n\tauto real_userdata = static_cast<GurobiCallbackUserdata *>(usrdata);\n\tauto model = static_cast<GurobiModel *>(real_userdata->model);\n\tauto &callback = real_userdata->callback;\n\n\tmodel->m_cbdata = cbdata;\n\tmodel->m_callback_userdata.where = where;\n\tmodel->m_callback_userdata.cb_get_mipsol_called = false;\n\tmodel->m_callback_userdata.cb_get_mipnoderel_called = false;\n\tmodel->m_callback_userdata.cb_set_solution_called = false;\n\tmodel->m_callback_userdata.cb_requires_submit_solution = false;\n\tcallback(model, where);\n\n\tif (model->m_callback_userdata.cb_requires_submit_solution)\n\t{\n\t\tmodel->cb_submit_solution();\n\t}\n\n\treturn 0;\n}\n\nvoid GurobiModel::set_callback(const GurobiCallback &callback)\n{\n\tm_callback_userdata.model = this;\n\tm_callback_userdata.callback = callback;\n\n\tint error =\n\t    gurobi::GRBsetcallbackfunc(m_model.get(), RealGurobiCallbackFunction, &m_callback_userdata);\n\tcheck_error(error);\n\n\thas_callback = true;\n}\n\nint GurobiModel::cb_get_info_int(int what)\n{\n\tint retval;\n\tint error = gurobi::GRBcbget(m_cbdata, m_callback_userdata.where, what, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble GurobiModel::cb_get_info_double(int what)\n{\n\tdouble retval;\n\tint error = gurobi::GRBcbget(m_cbdata, m_callback_userdata.where, what, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nvoid GurobiModel::cb_get_info_doublearray(int what)\n{\n\tint n_vars = m_callback_userdata.n_variables;\n\tdouble *val = nullptr;\n\tif (what == GRB_CB_MIPSOL_SOL)\n\t{\n\t\tm_callback_userdata.mipsol.resize(n_vars);\n\t\tval = m_callback_userdata.mipsol.data();\n\t}\n\telse if (what == GRB_CB_MIPNODE_REL)\n\t{\n\t\tm_callback_userdata.mipnoderel.resize(n_vars);\n\t\tval = m_callback_userdata.mipnoderel.data();\n\t}\n\telse\n\t{\n\t\tthrow std::runtime_error(\"Invalid what for cb_get_info_doublearray\");\n\t}\n\tint error = gurobi::GRBcbget(m_cbdata, m_callback_userdata.where, what, val);\n\tcheck_error(error);\n}\n\ndouble GurobiModel::cb_get_solution(const VariableIndex &variable)\n{\n\tauto &userdata = m_callback_userdata;\n\tif (!userdata.cb_get_mipsol_called)\n\t{\n\t\tcb_get_info_doublearray(GRB_CB_MIPSOL_SOL);\n\t\tuserdata.cb_get_mipsol_called = true;\n\t}\n\tauto index = _variable_index(variable);\n\treturn userdata.mipsol[index];\n}\n\ndouble GurobiModel::cb_get_relaxation(const VariableIndex &variable)\n{\n\tauto &userdata = m_callback_userdata;\n\tif (!userdata.cb_get_mipnoderel_called)\n\t{\n\t\tcb_get_info_doublearray(GRB_CB_MIPNODE_REL);\n\t\tuserdata.cb_get_mipnoderel_called = true;\n\t}\n\tauto index = _variable_index(variable);\n\treturn userdata.mipnoderel[index];\n}\n\nvoid GurobiModel::cb_set_solution(const VariableIndex &variable, double value)\n{\n\tauto &userdata = m_callback_userdata;\n\tif (!userdata.cb_set_solution_called)\n\t{\n\t\tuserdata.heuristic_solution.resize(userdata.n_variables, GRB_UNDEFINED);\n\t\tuserdata.cb_set_solution_called = true;\n\t}\n\tuserdata.heuristic_solution[_variable_index(variable)] = value;\n\tm_callback_userdata.cb_requires_submit_solution = true;\n}\n\ndouble GurobiModel::cb_submit_solution()\n{\n\tif (!m_callback_userdata.cb_set_solution_called)\n\t{\n\t\tthrow std::runtime_error(\"No solution is set in the callback!\");\n\t}\n\tdouble obj;\n\tint error =\n\t    gurobi::GRBcbsolution(m_cbdata, m_callback_userdata.heuristic_solution.data(), &obj);\n\tcheck_error(error);\n\tm_callback_userdata.cb_requires_submit_solution = false;\n\treturn obj;\n}\n\nvoid GurobiModel::cb_add_lazy_constraint(const ScalarAffineFunction &function,\n                                         ConstraintSense sense, CoeffT rhs)\n{\n\tAffineFunctionPtrForm<int, int, double> ptr_form;\n\tptr_form.make(this, function);\n\n\tint numnz = ptr_form.numnz;\n\tint *cind = ptr_form.index;\n\tdouble *cval = ptr_form.value;\n\tchar g_sense = gurobi_con_sense(sense);\n\tdouble g_rhs = rhs - function.constant.value_or(0.0);\n\n\tint error = gurobi::GRBcblazy(m_cbdata, numnz, cind, cval, g_sense, g_rhs);\n\tcheck_error(error);\n}\n\nvoid GurobiModel::cb_exit()\n{\n\tgurobi::GRBterminate(m_model.get());\n}\n\nvoid GurobiModel::cb_add_lazy_constraint(const ExprBuilder &function, ConstraintSense sense,\n                                         CoeffT rhs)\n{\n\tScalarAffineFunction f(function);\n\tcb_add_lazy_constraint(f, sense, rhs);\n}\n\nvoid GurobiModel::cb_add_user_cut(const ScalarAffineFunction &function, ConstraintSense sense,\n                                  CoeffT rhs)\n{\n\tAffineFunctionPtrForm<int, int, double> ptr_form;\n\tptr_form.make(this, function);\n\n\tint numnz = ptr_form.numnz;\n\tint *cind = ptr_form.index;\n\tdouble *cval = ptr_form.value;\n\tchar g_sense = gurobi_con_sense(sense);\n\tdouble g_rhs = rhs - function.constant.value_or(0.0);\n\n\tint error = gurobi::GRBcbcut(m_cbdata, numnz, cind, cval, g_sense, g_rhs);\n\tcheck_error(error);\n}\n\nvoid GurobiModel::cb_add_user_cut(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs)\n{\n\tScalarAffineFunction f(function);\n\tcb_add_user_cut(f, sense, rhs);\n}\n"
  },
  {
    "path": "lib/gurobi_model_ext.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include <nanobind/stl/string.h>\n#include <nanobind/stl/vector.h>\n#include <nanobind/stl/tuple.h>\n#include <nanobind/stl/function.h>\n\n#include \"pyoptinterface/gurobi_model.hpp\"\n\nnamespace nb = nanobind;\n\nextern void bind_gurobi_constants(nb::module_ &m);\n\nNB_MODULE(gurobi_model_ext, m)\n{\n\tm.import_(\"pyoptinterface._src.core_ext\");\n\n\tm.def(\"is_library_loaded\", &gurobi::is_library_loaded);\n\tm.def(\"load_library\", &gurobi::load_library);\n\n\tbind_gurobi_constants(m);\n\n#define BIND_F(f) .def(#f, &GurobiEnv::f)\n\tnb::class_<GurobiEnv>(m, \"RawEnv\")\n\t    .def(nb::init<bool>(), nb::arg(\"empty\") = false)\n\t    // clang-format off\n\t\tBIND_F(start)\n\t\tBIND_F(close)\n\t\tBIND_F(raw_parameter_type)\n\t\tBIND_F(set_raw_parameter_int)\n\t\tBIND_F(set_raw_parameter_double)\n\t\tBIND_F(set_raw_parameter_string)\n\t    // clang-format on\n\t    ;\n\n#undef BIND_F\n#define BIND_F(f) .def(#f, &GurobiModel::f)\n\tnb::class_<GurobiModel>(m, \"RawModel\")\n\t    .def(nb::init<>())\n\t    .def(nb::init<const GurobiEnv &>())\n\t    // clang-format off\n\t\tBIND_F(init)\n\t\tBIND_F(close)\n\t\tBIND_F(write)\n\t    // clang-format on\n\t    .def(\"_reset\", &GurobiModel::_reset, nb::arg(\"clearall\") = 0)\n\n\t    .def(\"add_variable\", &GurobiModel::add_variable,\n\t         nb::arg(\"domain\") = VariableDomain::Continuous, nb::arg(\"lb\") = -GRB_INFINITY,\n\t         nb::arg(\"ub\") = GRB_INFINITY, nb::arg(\"name\") = \"\")\n\t    // clang-format off\n\t\tBIND_F(delete_variable)\n\t\tBIND_F(delete_variables)\n\t\tBIND_F(is_variable_active)\n\t    // clang-format on\n\t    .def(\"set_variable_bounds\", &GurobiModel::set_variable_bounds, nb::arg(\"variable\"),\n\t         nb::arg(\"lb\"), nb::arg(\"ub\"))\n\n\t    .def(\"get_value\", &GurobiModel::get_variable_value)\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ScalarAffineFunction &>(&GurobiModel::get_expression_value))\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &>(&GurobiModel::get_expression_value))\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ExprBuilder &>(&GurobiModel::get_expression_value))\n\n\t    .def(\"pprint\", &GurobiModel::pprint_variable)\n\t    .def(\"pprint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, int>(&GurobiModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\t    .def(\"pprint\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, int>(\n\t             &GurobiModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\t    .def(\"pprint\", nb::overload_cast<const ExprBuilder &, int>(&GurobiModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\n\t    // clang-format off\n\t\tBIND_F(set_variable_name)\n\t\tBIND_F(set_constraint_name)\n\t    // clang-format on\n\n\t    .def(\"_add_linear_constraint\", &GurobiModel::add_linear_constraint, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &GurobiModel::add_linear_constraint_from_var,\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &GurobiModel::add_linear_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_quadratic_constraint\", &GurobiModel::add_quadratic_constraint, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_quadratic_constraint\", &GurobiModel::add_quadratic_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"add_sos_constraint\", nb::overload_cast<const Vector<VariableIndex> &, SOSType>(\n\t                                   &GurobiModel::add_sos_constraint))\n\t    .def(\"add_sos_constraint\",\n\t         nb::overload_cast<const Vector<VariableIndex> &, SOSType, const Vector<CoeffT> &>(\n\t             &GurobiModel::add_sos_constraint))\n\n\t    .def(\"_add_single_nl_constraint\", &GurobiModel::add_single_nl_constraint, nb::arg(\"graph\"),\n\t         nb::arg(\"result\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_single_nl_constraint\", &GurobiModel::add_single_nl_constraint_sense_rhs,\n\t         nb::arg(\"graph\"), nb::arg(\"result\"), nb::arg(\"sense\"), nb::arg(\"rhs\"),\n\t         nb::arg(\"name\") = \"\")\n\t    .def(\"_add_single_nl_constraint\", &GurobiModel::add_single_nl_constraint_from_comparison,\n\t         nb::arg(\"graph\"), nb::arg(\"expr\"), nb::arg(\"name\") = \"\")\n\n\t    // clang-format off\n\t\tBIND_F(delete_constraint)\n\t\tBIND_F(is_constraint_active)\n\t    // clang-format on\n\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, ObjectiveSense>(\n\t             &GurobiModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ObjectiveSense>(\n\t             &GurobiModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ExprBuilder &, ObjectiveSense>(&GurobiModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const VariableIndex &, ObjectiveSense>(\n\t             &GurobiModel::set_objective_as_variable),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<CoeffT, ObjectiveSense>(&GurobiModel::set_objective_as_constant),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\n\t    .def(\"_add_single_nl_objective\", &GurobiModel::add_single_nl_objective)\n\n\t    .def(\"cb_add_lazy_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ConstraintSense, CoeffT>(\n\t             &GurobiModel::cb_add_lazy_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"))\n\t    .def(\"cb_add_lazy_constraint\",\n\t         nb::overload_cast<const ExprBuilder &, ConstraintSense, CoeffT>(\n\t             &GurobiModel::cb_add_lazy_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"))\n\t    .def(\"cb_add_user_cut\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ConstraintSense, CoeffT>(\n\t             &GurobiModel::cb_add_user_cut),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"))\n\t    .def(\"cb_add_user_cut\",\n\t         nb::overload_cast<const ExprBuilder &, ConstraintSense, CoeffT>(\n\t             &GurobiModel::cb_add_user_cut),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"))\n\n\t    .def(\"optimize\", &GurobiModel::optimize, nb::call_guard<nb::gil_scoped_release>())\n\n\t    // clang-format off\n\t\tBIND_F(update)\n\t\tBIND_F(version_string)\n\t\tBIND_F(get_raw_model)\n\n\t\tBIND_F(set_logging)\n\n\t\tBIND_F(set_callback)\n\t\tBIND_F(cb_get_info_int)\n\t\tBIND_F(cb_get_info_double)\n\t\tBIND_F(cb_get_solution)\n\t\tBIND_F(cb_get_relaxation)\n\t\tBIND_F(cb_set_solution)\n\t\tBIND_F(cb_submit_solution)\n\t\tBIND_F(cb_exit)\n\n\t\tBIND_F(raw_parameter_type)\n\t\tBIND_F(set_raw_parameter_int)\n\t\tBIND_F(set_raw_parameter_double)\n\t\tBIND_F(set_raw_parameter_string)\n\t\tBIND_F(get_raw_parameter_int)\n\t\tBIND_F(get_raw_parameter_double)\n\t\tBIND_F(get_raw_parameter_string)\n\n\t\tBIND_F(raw_attribute_type)\n\n\t\tBIND_F(set_model_raw_attribute_int)\n\t\tBIND_F(set_model_raw_attribute_double)\n\t\tBIND_F(set_model_raw_attribute_string)\n\t\tBIND_F(get_model_raw_attribute_int)\n\t\tBIND_F(get_model_raw_attribute_double)\n\t\tBIND_F(get_model_raw_attribute_string)\n\t\tBIND_F(get_model_raw_attribute_vector_double)\n\t\tBIND_F(get_model_raw_attribute_list_double)\n\n\t\tBIND_F(set_variable_raw_attribute_int)\n\t\tBIND_F(set_variable_raw_attribute_char)\n\t\tBIND_F(set_variable_raw_attribute_double)\n\t\tBIND_F(set_variable_raw_attribute_string)\n\t\tBIND_F(get_variable_raw_attribute_int)\n\t\tBIND_F(get_variable_raw_attribute_char)\n\t\tBIND_F(get_variable_raw_attribute_double)\n\t\tBIND_F(get_variable_raw_attribute_string)\n\n\t\tBIND_F(set_constraint_raw_attribute_int)\n\t\tBIND_F(set_constraint_raw_attribute_char)\n\t\tBIND_F(set_constraint_raw_attribute_double)\n\t\tBIND_F(set_constraint_raw_attribute_string)\n\t\tBIND_F(get_constraint_raw_attribute_int)\n\t\tBIND_F(get_constraint_raw_attribute_char)\n\t\tBIND_F(get_constraint_raw_attribute_double)\n\t\tBIND_F(get_constraint_raw_attribute_string)\n\n\t\tBIND_F(get_normalized_rhs)\n\t\tBIND_F(set_normalized_rhs)\n\t\tBIND_F(get_normalized_coefficient)\n\t\tBIND_F(set_normalized_coefficient)\n\t\tBIND_F(get_objective_coefficient)\n\t\tBIND_F(set_objective_coefficient)\n\n\t\tBIND_F(_converttofixed)\n\n\t\tBIND_F(computeIIS)\n\t    // clang-format on\n\t    ;\n}"
  },
  {
    "path": "lib/gurobi_model_ext_constants.cpp",
    "content": "#include <nanobind/nanobind.h>\n\nnamespace nb = nanobind;\n\nvoid bind_gurobi_constants(nb::module_ &m)\n{\n\tnb::module_ GRB = m.def_submodule(\"GRB\");\n\tGRB.attr(\"BARHOMOGENEOUS_AUTO\") = -1;\n\tGRB.attr(\"BARHOMOGENEOUS_OFF\") = 0;\n\tGRB.attr(\"BARHOMOGENEOUS_ON\") = 1;\n\tGRB.attr(\"BARORDER_AMD\") = 0;\n\tGRB.attr(\"BARORDER_AUTOMATIC\") = -1;\n\tGRB.attr(\"BARORDER_NESTEDDISSECTION\") = 1;\n\tGRB.attr(\"BASIC\") = 0;\n\tGRB.attr(\"BATCH_ABORTED\") = 3;\n\tGRB.attr(\"BATCH_COMPLETED\") = 5;\n\tGRB.attr(\"BATCH_CREATED\") = 1;\n\tGRB.attr(\"BATCH_FAILED\") = 4;\n\tGRB.attr(\"BATCH_SUBMITTED\") = 2;\n\tGRB.attr(\"BINARY\") = \"B\";\n\tGRB.attr(\"CONTINUOUS\") = \"C\";\n\tGRB.attr(\"CUTOFF\") = 6;\n\tGRB.attr(\"CUTS_AGGRESSIVE\") = 2;\n\tGRB.attr(\"CUTS_AUTO\") = -1;\n\tGRB.attr(\"CUTS_CONSERVATIVE\") = 1;\n\tGRB.attr(\"CUTS_OFF\") = 0;\n\tGRB.attr(\"CUTS_VERYAGGRESSIVE\") = 3;\n\tGRB.attr(\"DEFAULT_CS_PORT\") = 61000;\n\tGRB.attr(\"EQUAL\") = \"=\";\n\tGRB.attr(\"ERROR_CALLBACK\") = 10011;\n\tGRB.attr(\"ERROR_CLOUD\") = 10028;\n\tGRB.attr(\"ERROR_CSWORKER\") = 10030;\n\tGRB.attr(\"ERROR_DATA_NOT_AVAILABLE\") = 10005;\n\tGRB.attr(\"ERROR_DUPLICATES\") = 10018;\n\tGRB.attr(\"ERROR_EXCEED_2B_NONZEROS\") = 10025;\n\tGRB.attr(\"ERROR_FAILED_TO_CREATE_MODEL\") = 20002;\n\tGRB.attr(\"ERROR_FILE_READ\") = 10012;\n\tGRB.attr(\"ERROR_FILE_WRITE\") = 10013;\n\tGRB.attr(\"ERROR_IIS_NOT_INFEASIBLE\") = 10015;\n\tGRB.attr(\"ERROR_INDEX_OUT_OF_RANGE\") = 10006;\n\tGRB.attr(\"ERROR_INTERNAL\") = 20003;\n\tGRB.attr(\"ERROR_INVALID_ARGUMENT\") = 10003;\n\tGRB.attr(\"ERROR_INVALID_PIECEWISE_OBJ\") = 10026;\n\tGRB.attr(\"ERROR_JOB_REJECTED\") = 10023;\n\tGRB.attr(\"ERROR_MODEL_MODIFICATION\") = 10029;\n\tGRB.attr(\"ERROR_NETWORK\") = 10022;\n\tGRB.attr(\"ERROR_NODEFILE\") = 10019;\n\tGRB.attr(\"ERROR_NOT_FOR_MIP\") = 10016;\n\tGRB.attr(\"ERROR_NOT_IN_MODEL\") = 20001;\n\tGRB.attr(\"ERROR_NOT_SUPPORTED\") = 10024;\n\tGRB.attr(\"ERROR_NO_LICENSE\") = 10009;\n\tGRB.attr(\"ERROR_NULL_ARGUMENT\") = 10002;\n\tGRB.attr(\"ERROR_NUMERIC\") = 10014;\n\tGRB.attr(\"ERROR_OPTIMIZATION_IN_PROGRESS\") = 10017;\n\tGRB.attr(\"ERROR_OUT_OF_MEMORY\") = 10001;\n\tGRB.attr(\"ERROR_QCP_EQUALITY_CONSTRAINT\") = 10021;\n\tGRB.attr(\"ERROR_Q_NOT_PSD\") = 10020;\n\tGRB.attr(\"ERROR_SECURITY\") = 10032;\n\tGRB.attr(\"ERROR_SIZE_LIMIT_EXCEEDED\") = 10010;\n\tGRB.attr(\"ERROR_TUNE_MODEL_TYPES\") = 10031;\n\tGRB.attr(\"ERROR_UNKNOWN_ATTRIBUTE\") = 10004;\n\tGRB.attr(\"ERROR_UNKNOWN_PARAMETER\") = 10007;\n\tGRB.attr(\"ERROR_UPDATEMODE_CHANGE\") = 10027;\n\tGRB.attr(\"ERROR_VALUE_OUT_OF_RANGE\") = 10008;\n\tGRB.attr(\"FEASRELAX_CARDINALITY\") = 2;\n\tGRB.attr(\"FEASRELAX_LINEAR\") = 0;\n\tGRB.attr(\"FEASRELAX_QUADRATIC\") = 1;\n\tGRB.attr(\"GENCONSTR_ABS\") = 2;\n\tGRB.attr(\"GENCONSTR_AND\") = 3;\n\tGRB.attr(\"GENCONSTR_COS\") = 16;\n\tGRB.attr(\"GENCONSTR_EXP\") = 10;\n\tGRB.attr(\"GENCONSTR_EXPA\") = 11;\n\tGRB.attr(\"GENCONSTR_INDICATOR\") = 7;\n\tGRB.attr(\"GENCONSTR_LOG\") = 12;\n\tGRB.attr(\"GENCONSTR_LOGA\") = 13;\n\tGRB.attr(\"GENCONSTR_LOGISTIC\") = 18;\n\tGRB.attr(\"GENCONSTR_MAX\") = 0;\n\tGRB.attr(\"GENCONSTR_MIN\") = 1;\n\tGRB.attr(\"GENCONSTR_NL\") = 6;\n\tGRB.attr(\"GENCONSTR_NORM\") = 5;\n\tGRB.attr(\"GENCONSTR_OR\") = 4;\n\tGRB.attr(\"GENCONSTR_POLY\") = 9;\n\tGRB.attr(\"GENCONSTR_POW\") = 14;\n\tGRB.attr(\"GENCONSTR_PWL\") = 8;\n\tGRB.attr(\"GENCONSTR_SIN\") = 15;\n\tGRB.attr(\"GENCONSTR_TAN\") = 17;\n\tGRB.attr(\"GREATER_EQUAL\") = \">\";\n\tGRB.attr(\"INFEASIBLE\") = 3;\n\tGRB.attr(\"INFINITY\") = 1e+100;\n\tGRB.attr(\"INF_OR_UNBD\") = 4;\n\tGRB.attr(\"INPROGRESS\") = 14;\n\tGRB.attr(\"INTEGER\") = \"I\";\n\tGRB.attr(\"INTERRUPTED\") = 11;\n\tGRB.attr(\"ITERATION_LIMIT\") = 7;\n\tGRB.attr(\"LESS_EQUAL\") = \"<\";\n\tGRB.attr(\"LOADED\") = 1;\n\tGRB.attr(\"LOCALLY_INFEASIBLE\") = 19;\n\tGRB.attr(\"LOCALLY_OPTIMAL\") = 18;\n\tGRB.attr(\"MAXIMIZE\") = -1;\n\tGRB.attr(\"MAXINT\") = 2000000000;\n\tGRB.attr(\"MAX_CONCURRENT\") = 64;\n\tGRB.attr(\"MAX_NAMELEN\") = 255;\n\tGRB.attr(\"MAX_STRLEN\") = 512;\n\tGRB.attr(\"MAX_TAGLEN\") = 10240;\n\tGRB.attr(\"MEM_LIMIT\") = 17;\n\tGRB.attr(\"METHOD_AUTO\") = -1;\n\tGRB.attr(\"METHOD_BARRIER\") = 2;\n\tGRB.attr(\"METHOD_CONCURRENT\") = 3;\n\tGRB.attr(\"METHOD_DETERMINISTIC_CONCURRENT\") = 4;\n\tGRB.attr(\"METHOD_DETERMINISTIC_CONCURRENT_SIMPLEX\") = 5;\n\tGRB.attr(\"METHOD_DUAL\") = 1;\n\tGRB.attr(\"METHOD_NONE\") = -1;\n\tGRB.attr(\"METHOD_PDHG\") = 6;\n\tGRB.attr(\"METHOD_PRIMAL\") = 0;\n\tGRB.attr(\"MINIMIZE\") = 1;\n\tGRB.attr(\"MIPFOCUS_BALANCED\") = 0;\n\tGRB.attr(\"MIPFOCUS_BESTBOUND\") = 3;\n\tGRB.attr(\"MIPFOCUS_FEASIBILITY\") = 1;\n\tGRB.attr(\"MIPFOCUS_OPTIMALITY\") = 2;\n\tGRB.attr(\"NODE_LIMIT\") = 8;\n\tGRB.attr(\"NONBASIC_LOWER\") = -1;\n\tGRB.attr(\"NONBASIC_UPPER\") = -2;\n\tGRB.attr(\"NUMERIC\") = 12;\n\tGRB.attr(\"OPCODE_CONSTANT\") = 0;\n\tGRB.attr(\"OPCODE_COS\") = 10;\n\tGRB.attr(\"OPCODE_DIVIDE\") = 5;\n\tGRB.attr(\"OPCODE_EXP\") = 13;\n\tGRB.attr(\"OPCODE_LOG\") = 14;\n\tGRB.attr(\"OPCODE_LOG10\") = 16;\n\tGRB.attr(\"OPCODE_LOG2\") = 15;\n\tGRB.attr(\"OPCODE_LOGISTIC\") = 17;\n\tGRB.attr(\"OPCODE_MINUS\") = 3;\n\tGRB.attr(\"OPCODE_MULTIPLY\") = 4;\n\tGRB.attr(\"OPCODE_PLUS\") = 2;\n\tGRB.attr(\"OPCODE_POW\") = 12;\n\tGRB.attr(\"OPCODE_SIGNPOW\") = 19;\n\tGRB.attr(\"OPCODE_SIN\") = 9;\n\tGRB.attr(\"OPCODE_SQRT\") = 8;\n\tGRB.attr(\"OPCODE_SQUARE\") = 7;\n\tGRB.attr(\"OPCODE_TAN\") = 11;\n\tGRB.attr(\"OPCODE_TANH\") = 18;\n\tGRB.attr(\"OPCODE_UMINUS\") = 6;\n\tGRB.attr(\"OPCODE_VARIABLE\") = 1;\n\tGRB.attr(\"OPTIMAL\") = 2;\n\tGRB.attr(\"PARTITION_CLEANUP\") = 1;\n\tGRB.attr(\"PARTITION_EARLY\") = 16;\n\tGRB.attr(\"PARTITION_NODES\") = 2;\n\tGRB.attr(\"PARTITION_ROOTEND\") = 4;\n\tGRB.attr(\"PARTITION_ROOTSTART\") = 8;\n\tGRB.attr(\"PHASE_MIP_IMPROVE\") = 2;\n\tGRB.attr(\"PHASE_MIP_NOREL\") = 0;\n\tGRB.attr(\"PHASE_MIP_SEARCH\") = 1;\n\tGRB.attr(\"PRESOLVE_AGGRESSIVE\") = 2;\n\tGRB.attr(\"PRESOLVE_AUTO\") = -1;\n\tGRB.attr(\"PRESOLVE_CONSERVATIVE\") = 1;\n\tGRB.attr(\"PRESOLVE_OFF\") = 0;\n\tGRB.attr(\"SEMICONT\") = \"S\";\n\tGRB.attr(\"SEMIINT\") = \"N\";\n\tGRB.attr(\"SIMPLEXPRICING_AUTO\") = -1;\n\tGRB.attr(\"SIMPLEXPRICING_DEVEX\") = 2;\n\tGRB.attr(\"SIMPLEXPRICING_PARTIAL\") = 0;\n\tGRB.attr(\"SIMPLEXPRICING_STEEPEST_EDGE\") = 1;\n\tGRB.attr(\"SIMPLEXPRICING_STEEPEST_QUICK\") = 3;\n\tGRB.attr(\"SOLUTION_LIMIT\") = 10;\n\tGRB.attr(\"SOS_TYPE1\") = 1;\n\tGRB.attr(\"SOS_TYPE2\") = 2;\n\tGRB.attr(\"SUBOPTIMAL\") = 13;\n\tGRB.attr(\"SUPERBASIC\") = -3;\n\tGRB.attr(\"TIME_LIMIT\") = 9;\n\tGRB.attr(\"UNBOUNDED\") = 5;\n\tGRB.attr(\"UNDEFINED\") = 1e+101;\n\tGRB.attr(\"USER_OBJ_LIMIT\") = 15;\n\tGRB.attr(\"VARBRANCH_AUTO\") = -1;\n\tGRB.attr(\"VARBRANCH_MAX_INFEAS\") = 2;\n\tGRB.attr(\"VARBRANCH_PSEUDO_REDUCED\") = 0;\n\tGRB.attr(\"VARBRANCH_PSEUDO_SHADOW\") = 1;\n\tGRB.attr(\"VARBRANCH_STRONG\") = 3;\n\tGRB.attr(\"VERSION_MAJOR\") = 13;\n\tGRB.attr(\"VERSION_MINOR\") = 0;\n\tGRB.attr(\"VERSION_TECHNICAL\") = 0;\n\tGRB.attr(\"WORK_LIMIT\") = 16;\n\n\tnb::module_ Attr = GRB.def_submodule(\"Attr\");\n\tAttr.attr(\"BarIterCount\") = \"BarIterCount\";\n\tAttr.attr(\"BarPi\") = \"BarPi\";\n\tAttr.attr(\"BarStatus\") = \"BarStatus\";\n\tAttr.attr(\"BarX\") = \"BarX\";\n\tAttr.attr(\"BatchErrorCode\") = \"BatchErrorCode\";\n\tAttr.attr(\"BatchErrorMessage\") = \"BatchErrorMessage\";\n\tAttr.attr(\"BatchID\") = \"BatchID\";\n\tAttr.attr(\"BatchStatus\") = \"BatchStatus\";\n\tAttr.attr(\"BoundSVio\") = \"BoundSVio\";\n\tAttr.attr(\"BoundSVioIndex\") = \"BoundSVioIndex\";\n\tAttr.attr(\"BoundSVioSum\") = \"BoundSVioSum\";\n\tAttr.attr(\"BoundVio\") = \"BoundVio\";\n\tAttr.attr(\"BoundVioIndex\") = \"BoundVioIndex\";\n\tAttr.attr(\"BoundVioSum\") = \"BoundVioSum\";\n\tAttr.attr(\"BranchPriority\") = \"BranchPriority\";\n\tAttr.attr(\"CBasis\") = \"CBasis\";\n\tAttr.attr(\"CTag\") = \"CTag\";\n\tAttr.attr(\"ComplVio\") = \"ComplVio\";\n\tAttr.attr(\"ComplVioIndex\") = \"ComplVioIndex\";\n\tAttr.attr(\"ComplVioSum\") = \"ComplVioSum\";\n\tAttr.attr(\"ConcurrentWinMethod\") = \"ConcurrentWinMethod\";\n\tAttr.attr(\"ConstrName\") = \"ConstrName\";\n\tAttr.attr(\"ConstrResidual\") = \"ConstrResidual\";\n\tAttr.attr(\"ConstrResidualIndex\") = \"ConstrResidualIndex\";\n\tAttr.attr(\"ConstrResidualSum\") = \"ConstrResidualSum\";\n\tAttr.attr(\"ConstrSResidual\") = \"ConstrSResidual\";\n\tAttr.attr(\"ConstrSResidualIndex\") = \"ConstrSResidualIndex\";\n\tAttr.attr(\"ConstrSResidualSum\") = \"ConstrSResidualSum\";\n\tAttr.attr(\"ConstrSVio\") = \"ConstrSVio\";\n\tAttr.attr(\"ConstrSVioIndex\") = \"ConstrSVioIndex\";\n\tAttr.attr(\"ConstrSVioSum\") = \"ConstrSVioSum\";\n\tAttr.attr(\"ConstrVio\") = \"ConstrVio\";\n\tAttr.attr(\"ConstrVioIndex\") = \"ConstrVioIndex\";\n\tAttr.attr(\"ConstrVioSum\") = \"ConstrVioSum\";\n\tAttr.attr(\"DNumNZs\") = \"DNumNZs\";\n\tAttr.attr(\"DStart\") = \"DStart\";\n\tAttr.attr(\"DualResidual\") = \"DualResidual\";\n\tAttr.attr(\"DualResidualIndex\") = \"DualResidualIndex\";\n\tAttr.attr(\"DualResidualSum\") = \"DualResidualSum\";\n\tAttr.attr(\"DualSResidual\") = \"DualSResidual\";\n\tAttr.attr(\"DualSResidualIndex\") = \"DualSResidualIndex\";\n\tAttr.attr(\"DualSResidualSum\") = \"DualSResidualSum\";\n\tAttr.attr(\"DualSVio\") = \"DualSVio\";\n\tAttr.attr(\"DualSVioIndex\") = \"DualSVioIndex\";\n\tAttr.attr(\"DualSVioSum\") = \"DualSVioSum\";\n\tAttr.attr(\"DualVio\") = \"DualVio\";\n\tAttr.attr(\"DualVioIndex\") = \"DualVioIndex\";\n\tAttr.attr(\"DualVioSum\") = \"DualVioSum\";\n\tAttr.attr(\"FarkasDual\") = \"FarkasDual\";\n\tAttr.attr(\"FarkasProof\") = \"FarkasProof\";\n\tAttr.attr(\"Fingerprint\") = \"Fingerprint\";\n\tAttr.attr(\"FuncNonlinear\") = \"FuncNonlinear\";\n\tAttr.attr(\"FuncPieceError\") = \"FuncPieceError\";\n\tAttr.attr(\"FuncPieceLength\") = \"FuncPieceLength\";\n\tAttr.attr(\"FuncPieceRatio\") = \"FuncPieceRatio\";\n\tAttr.attr(\"FuncPieces\") = \"FuncPieces\";\n\tAttr.attr(\"GenConstrName\") = \"GenConstrName\";\n\tAttr.attr(\"GenConstrType\") = \"GenConstrType\";\n\tAttr.attr(\"IISConstr\") = \"IISConstr\";\n\tAttr.attr(\"IISConstrForce\") = \"IISConstrForce\";\n\tAttr.attr(\"IISGenConstr\") = \"IISGenConstr\";\n\tAttr.attr(\"IISGenConstrForce\") = \"IISGenConstrForce\";\n\tAttr.attr(\"IISLB\") = \"IISLB\";\n\tAttr.attr(\"IISLBForce\") = \"IISLBForce\";\n\tAttr.attr(\"IISMinimal\") = \"IISMinimal\";\n\tAttr.attr(\"IISQConstr\") = \"IISQConstr\";\n\tAttr.attr(\"IISQConstrForce\") = \"IISQConstrForce\";\n\tAttr.attr(\"IISSOS\") = \"IISSOS\";\n\tAttr.attr(\"IISSOSForce\") = \"IISSOSForce\";\n\tAttr.attr(\"IISUB\") = \"IISUB\";\n\tAttr.attr(\"IISUBForce\") = \"IISUBForce\";\n\tAttr.attr(\"IntVio\") = \"IntVio\";\n\tAttr.attr(\"IntVioIndex\") = \"IntVioIndex\";\n\tAttr.attr(\"IntVioSum\") = \"IntVioSum\";\n\tAttr.attr(\"IsMIP\") = \"IsMIP\";\n\tAttr.attr(\"IsMultiObj\") = \"IsMultiObj\";\n\tAttr.attr(\"IsQCP\") = \"IsQCP\";\n\tAttr.attr(\"IsQP\") = \"IsQP\";\n\tAttr.attr(\"IterCount\") = \"IterCount\";\n\tAttr.attr(\"Kappa\") = \"Kappa\";\n\tAttr.attr(\"KappaExact\") = \"KappaExact\";\n\tAttr.attr(\"LB\") = \"LB\";\n\tAttr.attr(\"Lazy\") = \"Lazy\";\n\tAttr.attr(\"LicenseExpiration\") = \"LicenseExpiration\";\n\tAttr.attr(\"MIPGap\") = \"MIPGap\";\n\tAttr.attr(\"MaxBound\") = \"MaxBound\";\n\tAttr.attr(\"MaxCoeff\") = \"MaxCoeff\";\n\tAttr.attr(\"MaxMemUsed\") = \"MaxMemUsed\";\n\tAttr.attr(\"MaxObjCoeff\") = \"MaxObjCoeff\";\n\tAttr.attr(\"MaxQCCoeff\") = \"MaxQCCoeff\";\n\tAttr.attr(\"MaxQCLCoeff\") = \"MaxQCLCoeff\";\n\tAttr.attr(\"MaxQCRHS\") = \"MaxQCRHS\";\n\tAttr.attr(\"MaxQObjCoeff\") = \"MaxQObjCoeff\";\n\tAttr.attr(\"MaxRHS\") = \"MaxRHS\";\n\tAttr.attr(\"MaxVio\") = \"MaxVio\";\n\tAttr.attr(\"MemUsed\") = \"MemUsed\";\n\tAttr.attr(\"MinBound\") = \"MinBound\";\n\tAttr.attr(\"MinCoeff\") = \"MinCoeff\";\n\tAttr.attr(\"MinObjCoeff\") = \"MinObjCoeff\";\n\tAttr.attr(\"MinQCCoeff\") = \"MinQCCoeff\";\n\tAttr.attr(\"MinQCLCoeff\") = \"MinQCLCoeff\";\n\tAttr.attr(\"MinQCRHS\") = \"MinQCRHS\";\n\tAttr.attr(\"MinQObjCoeff\") = \"MinQObjCoeff\";\n\tAttr.attr(\"MinRHS\") = \"MinRHS\";\n\tAttr.attr(\"ModelName\") = \"ModelName\";\n\tAttr.attr(\"ModelSense\") = \"ModelSense\";\n\tAttr.attr(\"NLBarIterCount\") = \"NLBarIterCount\";\n\tAttr.attr(\"NodeCount\") = \"NodeCount\";\n\tAttr.attr(\"NumBinVars\") = \"NumBinVars\";\n\tAttr.attr(\"NumConstrs\") = \"NumConstrs\";\n\tAttr.attr(\"NumGenConstrs\") = \"NumGenConstrs\";\n\tAttr.attr(\"NumIntVars\") = \"NumIntVars\";\n\tAttr.attr(\"NumNZs\") = \"NumNZs\";\n\tAttr.attr(\"NumObj\") = \"NumObj\";\n\tAttr.attr(\"NumObjPasses\") = \"NumObjPasses\";\n\tAttr.attr(\"NumPWLObjVars\") = \"NumPWLObjVars\";\n\tAttr.attr(\"NumQCNZs\") = \"NumQCNZs\";\n\tAttr.attr(\"NumQConstrs\") = \"NumQConstrs\";\n\tAttr.attr(\"NumQNZs\") = \"NumQNZs\";\n\tAttr.attr(\"NumSOS\") = \"NumSOS\";\n\tAttr.attr(\"NumScenarios\") = \"NumScenarios\";\n\tAttr.attr(\"NumStart\") = \"NumStart\";\n\tAttr.attr(\"NumVars\") = \"NumVars\";\n\tAttr.attr(\"Obj\") = \"Obj\";\n\tAttr.attr(\"ObjBound\") = \"ObjBound\";\n\tAttr.attr(\"ObjBoundC\") = \"ObjBoundC\";\n\tAttr.attr(\"ObjCon\") = \"ObjCon\";\n\tAttr.attr(\"ObjN\") = \"ObjN\";\n\tAttr.attr(\"ObjNAbsTol\") = \"ObjNAbsTol\";\n\tAttr.attr(\"ObjNCon\") = \"ObjNCon\";\n\tAttr.attr(\"ObjNName\") = \"ObjNName\";\n\tAttr.attr(\"ObjNPass\") = \"ObjNPass\";\n\tAttr.attr(\"ObjNPriority\") = \"ObjNPriority\";\n\tAttr.attr(\"ObjNRelTol\") = \"ObjNRelTol\";\n\tAttr.attr(\"ObjNVal\") = \"ObjNVal\";\n\tAttr.attr(\"ObjNWeight\") = \"ObjNWeight\";\n\tAttr.attr(\"ObjPassNIterCount\") = \"ObjPassNIterCount\";\n\tAttr.attr(\"ObjPassNMIPGap\") = \"ObjPassNMIPGap\";\n\tAttr.attr(\"ObjPassNNodeCount\") = \"ObjPassNNodeCount\";\n\tAttr.attr(\"ObjPassNObjBound\") = \"ObjPassNObjBound\";\n\tAttr.attr(\"ObjPassNObjVal\") = \"ObjPassNObjVal\";\n\tAttr.attr(\"ObjPassNOpenNodeCount\") = \"ObjPassNOpenNodeCount\";\n\tAttr.attr(\"ObjPassNRuntime\") = \"ObjPassNRuntime\";\n\tAttr.attr(\"ObjPassNStatus\") = \"ObjPassNStatus\";\n\tAttr.attr(\"ObjPassNWork\") = \"ObjPassNWork\";\n\tAttr.attr(\"ObjVal\") = \"ObjVal\";\n\tAttr.attr(\"PDHGIterCount\") = \"PDHGIterCount\";\n\tAttr.attr(\"PStart\") = \"PStart\";\n\tAttr.attr(\"PWLObjCvx\") = \"PWLObjCvx\";\n\tAttr.attr(\"Partition\") = \"Partition\";\n\tAttr.attr(\"Pi\") = \"Pi\";\n\tAttr.attr(\"PoolIgnore\") = \"PoolIgnore\";\n\tAttr.attr(\"PoolNBoundVio\") = \"PoolNBoundVio\";\n\tAttr.attr(\"PoolNBoundVioIndex\") = \"PoolNBoundVioIndex\";\n\tAttr.attr(\"PoolNBoundVioSum\") = \"PoolNBoundVioSum\";\n\tAttr.attr(\"PoolNConstrVio\") = \"PoolNConstrVio\";\n\tAttr.attr(\"PoolNConstrVioIndex\") = \"PoolNConstrVioIndex\";\n\tAttr.attr(\"PoolNConstrVioSum\") = \"PoolNConstrVioSum\";\n\tAttr.attr(\"PoolNIntVio\") = \"PoolNIntVio\";\n\tAttr.attr(\"PoolNIntVioIndex\") = \"PoolNIntVioIndex\";\n\tAttr.attr(\"PoolNIntVioSum\") = \"PoolNIntVioSum\";\n\tAttr.attr(\"PoolNMaxVio\") = \"PoolNMaxVio\";\n\tAttr.attr(\"PoolNObjVal\") = \"PoolNObjVal\";\n\tAttr.attr(\"PoolNX\") = \"PoolNX\";\n\tAttr.attr(\"PoolObjBound\") = \"PoolObjBound\";\n\tAttr.attr(\"PoolObjVal\") = \"PoolObjVal\";\n\tAttr.attr(\"PreFixVal\") = \"PreFixVal\";\n\tAttr.attr(\"QCName\") = \"QCName\";\n\tAttr.attr(\"QCPi\") = \"QCPi\";\n\tAttr.attr(\"QCRHS\") = \"QCRHS\";\n\tAttr.attr(\"QCSense\") = \"QCSense\";\n\tAttr.attr(\"QCSlack\") = \"QCSlack\";\n\tAttr.attr(\"QCTag\") = \"QCTag\";\n\tAttr.attr(\"RC\") = \"RC\";\n\tAttr.attr(\"RHS\") = \"RHS\";\n\tAttr.attr(\"Runtime\") = \"Runtime\";\n\tAttr.attr(\"SALBLow\") = \"SALBLow\";\n\tAttr.attr(\"SALBUp\") = \"SALBUp\";\n\tAttr.attr(\"SAObjLow\") = \"SAObjLow\";\n\tAttr.attr(\"SAObjUp\") = \"SAObjUp\";\n\tAttr.attr(\"SARHSLow\") = \"SARHSLow\";\n\tAttr.attr(\"SARHSUp\") = \"SARHSUp\";\n\tAttr.attr(\"SAUBLow\") = \"SAUBLow\";\n\tAttr.attr(\"SAUBUp\") = \"SAUBUp\";\n\tAttr.attr(\"ScenNLB\") = \"ScenNLB\";\n\tAttr.attr(\"ScenNName\") = \"ScenNName\";\n\tAttr.attr(\"ScenNObj\") = \"ScenNObj\";\n\tAttr.attr(\"ScenNObjBound\") = \"ScenNObjBound\";\n\tAttr.attr(\"ScenNObjVal\") = \"ScenNObjVal\";\n\tAttr.attr(\"ScenNRHS\") = \"ScenNRHS\";\n\tAttr.attr(\"ScenNUB\") = \"ScenNUB\";\n\tAttr.attr(\"ScenNX\") = \"ScenNX\";\n\tAttr.attr(\"Sense\") = \"Sense\";\n\tAttr.attr(\"Slack\") = \"Slack\";\n\tAttr.attr(\"SolCount\") = \"SolCount\";\n\tAttr.attr(\"Start\") = \"Start\";\n\tAttr.attr(\"Status\") = \"Status\";\n\tAttr.attr(\"TuneResultCount\") = \"TuneResultCount\";\n\tAttr.attr(\"UB\") = \"UB\";\n\tAttr.attr(\"UnbdRay\") = \"UnbdRay\";\n\tAttr.attr(\"VBasis\") = \"VBasis\";\n\tAttr.attr(\"VTag\") = \"VTag\";\n\tAttr.attr(\"VType\") = \"VType\";\n\tAttr.attr(\"VarHintPri\") = \"VarHintPri\";\n\tAttr.attr(\"VarHintVal\") = \"VarHintVal\";\n\tAttr.attr(\"VarName\") = \"VarName\";\n\tAttr.attr(\"VarPreStat\") = \"VarPreStat\";\n\tAttr.attr(\"Work\") = \"Work\";\n\tAttr.attr(\"X\") = \"X\";\n\tAttr.attr(\"Xn\") = \"Xn\";\n\n\tnb::module_ Param = GRB.def_submodule(\"Param\");\n\tParam.attr(\"AggFill\") = \"AggFill\";\n\tParam.attr(\"Aggregate\") = \"Aggregate\";\n\tParam.attr(\"BQPCuts\") = \"BQPCuts\";\n\tParam.attr(\"BarConvTol\") = \"BarConvTol\";\n\tParam.attr(\"BarCorrectors\") = \"BarCorrectors\";\n\tParam.attr(\"BarHomogeneous\") = \"BarHomogeneous\";\n\tParam.attr(\"BarIterLimit\") = \"BarIterLimit\";\n\tParam.attr(\"BarOrder\") = \"BarOrder\";\n\tParam.attr(\"BarQCPConvTol\") = \"BarQCPConvTol\";\n\tParam.attr(\"BestBdStop\") = \"BestBdStop\";\n\tParam.attr(\"BestObjStop\") = \"BestObjStop\";\n\tParam.attr(\"BranchDir\") = \"BranchDir\";\n\tParam.attr(\"CSAPIAccessID\") = \"CSAPIAccessID\";\n\tParam.attr(\"CSAPISecret\") = \"CSAPISecret\";\n\tParam.attr(\"CSAppName\") = \"CSAppName\";\n\tParam.attr(\"CSAuthToken\") = \"CSAuthToken\";\n\tParam.attr(\"CSBatchMode\") = \"CSBatchMode\";\n\tParam.attr(\"CSClientLog\") = \"CSClientLog\";\n\tParam.attr(\"CSGroup\") = \"CSGroup\";\n\tParam.attr(\"CSIdleTimeout\") = \"CSIdleTimeout\";\n\tParam.attr(\"CSManager\") = \"CSManager\";\n\tParam.attr(\"CSPriority\") = \"CSPriority\";\n\tParam.attr(\"CSQueueTimeout\") = \"CSQueueTimeout\";\n\tParam.attr(\"CSRouter\") = \"CSRouter\";\n\tParam.attr(\"CSTLSInsecure\") = \"CSTLSInsecure\";\n\tParam.attr(\"CliqueCuts\") = \"CliqueCuts\";\n\tParam.attr(\"CloudAccessID\") = \"CloudAccessID\";\n\tParam.attr(\"CloudHost\") = \"CloudHost\";\n\tParam.attr(\"CloudPool\") = \"CloudPool\";\n\tParam.attr(\"CloudSecretKey\") = \"CloudSecretKey\";\n\tParam.attr(\"ComputeServer\") = \"ComputeServer\";\n\tParam.attr(\"ConcurrentJobs\") = \"ConcurrentJobs\";\n\tParam.attr(\"ConcurrentMIP\") = \"ConcurrentMIP\";\n\tParam.attr(\"ConcurrentMethod\") = \"ConcurrentMethod\";\n\tParam.attr(\"CoverCuts\") = \"CoverCuts\";\n\tParam.attr(\"Crossover\") = \"Crossover\";\n\tParam.attr(\"CrossoverBasis\") = \"CrossoverBasis\";\n\tParam.attr(\"CutAggPasses\") = \"CutAggPasses\";\n\tParam.attr(\"CutPasses\") = \"CutPasses\";\n\tParam.attr(\"Cutoff\") = \"Cutoff\";\n\tParam.attr(\"Cuts\") = \"Cuts\";\n\tParam.attr(\"DegenMoves\") = \"DegenMoves\";\n\tParam.attr(\"Disconnected\") = \"Disconnected\";\n\tParam.attr(\"DisplayInterval\") = \"DisplayInterval\";\n\tParam.attr(\"DistributedMIPJobs\") = \"DistributedMIPJobs\";\n\tParam.attr(\"DualImpliedCuts\") = \"DualImpliedCuts\";\n\tParam.attr(\"DualReductions\") = \"DualReductions\";\n\tParam.attr(\"FeasRelaxBigM\") = \"FeasRelaxBigM\";\n\tParam.attr(\"FeasibilityTol\") = \"FeasibilityTol\";\n\tParam.attr(\"FixVarsInIndicators\") = \"FixVarsInIndicators\";\n\tParam.attr(\"FlowCoverCuts\") = \"FlowCoverCuts\";\n\tParam.attr(\"FlowPathCuts\") = \"FlowPathCuts\";\n\tParam.attr(\"FuncMaxVal\") = \"FuncMaxVal\";\n\tParam.attr(\"FuncNonlinear\") = \"FuncNonlinear\";\n\tParam.attr(\"FuncPieceError\") = \"FuncPieceError\";\n\tParam.attr(\"FuncPieceLength\") = \"FuncPieceLength\";\n\tParam.attr(\"FuncPieceRatio\") = \"FuncPieceRatio\";\n\tParam.attr(\"FuncPieces\") = \"FuncPieces\";\n\tParam.attr(\"GUBCoverCuts\") = \"GUBCoverCuts\";\n\tParam.attr(\"GomoryPasses\") = \"GomoryPasses\";\n\tParam.attr(\"Heuristics\") = \"Heuristics\";\n\tParam.attr(\"IISMethod\") = \"IISMethod\";\n\tParam.attr(\"IgnoreNames\") = \"IgnoreNames\";\n\tParam.attr(\"ImpliedCuts\") = \"ImpliedCuts\";\n\tParam.attr(\"ImproveStartGap\") = \"ImproveStartGap\";\n\tParam.attr(\"ImproveStartNodes\") = \"ImproveStartNodes\";\n\tParam.attr(\"ImproveStartTime\") = \"ImproveStartTime\";\n\tParam.attr(\"ImproveStartWork\") = \"ImproveStartWork\";\n\tParam.attr(\"InfProofCuts\") = \"InfProofCuts\";\n\tParam.attr(\"InfUnbdInfo\") = \"InfUnbdInfo\";\n\tParam.attr(\"InheritParams\") = \"InheritParams\";\n\tParam.attr(\"IntFeasTol\") = \"IntFeasTol\";\n\tParam.attr(\"IntegralityFocus\") = \"IntegralityFocus\";\n\tParam.attr(\"IterationLimit\") = \"IterationLimit\";\n\tParam.attr(\"JSONSolDetail\") = \"JSONSolDetail\";\n\tParam.attr(\"JobID\") = \"JobID\";\n\tParam.attr(\"LPWarmStart\") = \"LPWarmStart\";\n\tParam.attr(\"LazyConstraints\") = \"LazyConstraints\";\n\tParam.attr(\"LicenseID\") = \"LicenseID\";\n\tParam.attr(\"LiftProjectCuts\") = \"LiftProjectCuts\";\n\tParam.attr(\"LogFile\") = \"LogFile\";\n\tParam.attr(\"LogToConsole\") = \"LogToConsole\";\n\tParam.attr(\"MIPFocus\") = \"MIPFocus\";\n\tParam.attr(\"MIPGap\") = \"MIPGap\";\n\tParam.attr(\"MIPGapAbs\") = \"MIPGapAbs\";\n\tParam.attr(\"MIPSepCuts\") = \"MIPSepCuts\";\n\tParam.attr(\"MIQCPMethod\") = \"MIQCPMethod\";\n\tParam.attr(\"MIRCuts\") = \"MIRCuts\";\n\tParam.attr(\"MarkowitzTol\") = \"MarkowitzTol\";\n\tParam.attr(\"MasterKnapsackCuts\") = \"MasterKnapsackCuts\";\n\tParam.attr(\"MemLimit\") = \"MemLimit\";\n\tParam.attr(\"Method\") = \"Method\";\n\tParam.attr(\"MinRelNodes\") = \"MinRelNodes\";\n\tParam.attr(\"MixingCuts\") = \"MixingCuts\";\n\tParam.attr(\"ModKCuts\") = \"ModKCuts\";\n\tParam.attr(\"MultiObjMethod\") = \"MultiObjMethod\";\n\tParam.attr(\"MultiObjPre\") = \"MultiObjPre\";\n\tParam.attr(\"NLBarCFeasTol\") = \"NLBarCFeasTol\";\n\tParam.attr(\"NLBarDFeasTol\") = \"NLBarDFeasTol\";\n\tParam.attr(\"NLBarIterLimit\") = \"NLBarIterLimit\";\n\tParam.attr(\"NLBarPFeasTol\") = \"NLBarPFeasTol\";\n\tParam.attr(\"NLPHeur\") = \"NLPHeur\";\n\tParam.attr(\"NetworkAlg\") = \"NetworkAlg\";\n\tParam.attr(\"NetworkCuts\") = \"NetworkCuts\";\n\tParam.attr(\"NoRelHeurSolutions\") = \"NoRelHeurSolutions\";\n\tParam.attr(\"NoRelHeurTime\") = \"NoRelHeurTime\";\n\tParam.attr(\"NoRelHeurWork\") = \"NoRelHeurWork\";\n\tParam.attr(\"NodeLimit\") = \"NodeLimit\";\n\tParam.attr(\"NodeMethod\") = \"NodeMethod\";\n\tParam.attr(\"NodefileDir\") = \"NodefileDir\";\n\tParam.attr(\"NodefileStart\") = \"NodefileStart\";\n\tParam.attr(\"NonConvex\") = \"NonConvex\";\n\tParam.attr(\"NormAdjust\") = \"NormAdjust\";\n\tParam.attr(\"NumericFocus\") = \"NumericFocus\";\n\tParam.attr(\"OBBT\") = \"OBBT\";\n\tParam.attr(\"ObjNumber\") = \"ObjNumber\";\n\tParam.attr(\"ObjPassNumber\") = \"ObjPassNumber\";\n\tParam.attr(\"ObjScale\") = \"ObjScale\";\n\tParam.attr(\"OptimalityTarget\") = \"OptimalityTarget\";\n\tParam.attr(\"OptimalityTol\") = \"OptimalityTol\";\n\tParam.attr(\"OutputFlag\") = \"OutputFlag\";\n\tParam.attr(\"PDHGAbsTol\") = \"PDHGAbsTol\";\n\tParam.attr(\"PDHGConvTol\") = \"PDHGConvTol\";\n\tParam.attr(\"PDHGGPU\") = \"PDHGGPU\";\n\tParam.attr(\"PDHGIterLimit\") = \"PDHGIterLimit\";\n\tParam.attr(\"PDHGRelTol\") = \"PDHGRelTol\";\n\tParam.attr(\"PSDCuts\") = \"PSDCuts\";\n\tParam.attr(\"PSDTol\") = \"PSDTol\";\n\tParam.attr(\"PartitionPlace\") = \"PartitionPlace\";\n\tParam.attr(\"PerturbValue\") = \"PerturbValue\";\n\tParam.attr(\"PoolGap\") = \"PoolGap\";\n\tParam.attr(\"PoolGapAbs\") = \"PoolGapAbs\";\n\tParam.attr(\"PoolSearchMode\") = \"PoolSearchMode\";\n\tParam.attr(\"PoolSolutions\") = \"PoolSolutions\";\n\tParam.attr(\"PreCrush\") = \"PreCrush\";\n\tParam.attr(\"PreDepRow\") = \"PreDepRow\";\n\tParam.attr(\"PreDual\") = \"PreDual\";\n\tParam.attr(\"PreMIQCPForm\") = \"PreMIQCPForm\";\n\tParam.attr(\"PrePasses\") = \"PrePasses\";\n\tParam.attr(\"PreQLinearize\") = \"PreQLinearize\";\n\tParam.attr(\"PreSOS1BigM\") = \"PreSOS1BigM\";\n\tParam.attr(\"PreSOS1Encoding\") = \"PreSOS1Encoding\";\n\tParam.attr(\"PreSOS2BigM\") = \"PreSOS2BigM\";\n\tParam.attr(\"PreSOS2Encoding\") = \"PreSOS2Encoding\";\n\tParam.attr(\"PreSparsify\") = \"PreSparsify\";\n\tParam.attr(\"Presolve\") = \"Presolve\";\n\tParam.attr(\"ProjImpliedCuts\") = \"ProjImpliedCuts\";\n\tParam.attr(\"PumpPasses\") = \"PumpPasses\";\n\tParam.attr(\"QCPDual\") = \"QCPDual\";\n\tParam.attr(\"Quad\") = \"Quad\";\n\tParam.attr(\"RINS\") = \"RINS\";\n\tParam.attr(\"RLTCuts\") = \"RLTCuts\";\n\tParam.attr(\"Record\") = \"Record\";\n\tParam.attr(\"RelaxLiftCuts\") = \"RelaxLiftCuts\";\n\tParam.attr(\"ResultFile\") = \"ResultFile\";\n\tParam.attr(\"ScaleFlag\") = \"ScaleFlag\";\n\tParam.attr(\"ScenarioNumber\") = \"ScenarioNumber\";\n\tParam.attr(\"Seed\") = \"Seed\";\n\tParam.attr(\"ServerPassword\") = \"ServerPassword\";\n\tParam.attr(\"ServerTimeout\") = \"ServerTimeout\";\n\tParam.attr(\"SiftMethod\") = \"SiftMethod\";\n\tParam.attr(\"Sifting\") = \"Sifting\";\n\tParam.attr(\"SimplexPricing\") = \"SimplexPricing\";\n\tParam.attr(\"SoftMemLimit\") = \"SoftMemLimit\";\n\tParam.attr(\"SolFiles\") = \"SolFiles\";\n\tParam.attr(\"SolutionLimit\") = \"SolutionLimit\";\n\tParam.attr(\"SolutionNumber\") = \"SolutionNumber\";\n\tParam.attr(\"SolutionTarget\") = \"SolutionTarget\";\n\tParam.attr(\"StartNodeLimit\") = \"StartNodeLimit\";\n\tParam.attr(\"StartNumber\") = \"StartNumber\";\n\tParam.attr(\"StartTimeLimit\") = \"StartTimeLimit\";\n\tParam.attr(\"StartWorkLimit\") = \"StartWorkLimit\";\n\tParam.attr(\"StrongCGCuts\") = \"StrongCGCuts\";\n\tParam.attr(\"SubMIPCuts\") = \"SubMIPCuts\";\n\tParam.attr(\"SubMIPNodes\") = \"SubMIPNodes\";\n\tParam.attr(\"Symmetry\") = \"Symmetry\";\n\tParam.attr(\"TSPort\") = \"TSPort\";\n\tParam.attr(\"ThreadLimit\") = \"ThreadLimit\";\n\tParam.attr(\"Threads\") = \"Threads\";\n\tParam.attr(\"TimeLimit\") = \"TimeLimit\";\n\tParam.attr(\"TokenServer\") = \"TokenServer\";\n\tParam.attr(\"TuneCleanup\") = \"TuneCleanup\";\n\tParam.attr(\"TuneCriterion\") = \"TuneCriterion\";\n\tParam.attr(\"TuneDynamicJobs\") = \"TuneDynamicJobs\";\n\tParam.attr(\"TuneJobs\") = \"TuneJobs\";\n\tParam.attr(\"TuneMetric\") = \"TuneMetric\";\n\tParam.attr(\"TuneOutput\") = \"TuneOutput\";\n\tParam.attr(\"TuneResults\") = \"TuneResults\";\n\tParam.attr(\"TuneTargetMIPGap\") = \"TuneTargetMIPGap\";\n\tParam.attr(\"TuneTargetTime\") = \"TuneTargetTime\";\n\tParam.attr(\"TuneTimeLimit\") = \"TuneTimeLimit\";\n\tParam.attr(\"TuneTrials\") = \"TuneTrials\";\n\tParam.attr(\"UpdateMode\") = \"UpdateMode\";\n\tParam.attr(\"UserName\") = \"UserName\";\n\tParam.attr(\"VarBranch\") = \"VarBranch\";\n\tParam.attr(\"WLSAccessID\") = \"WLSAccessID\";\n\tParam.attr(\"WLSConfig\") = \"WLSConfig\";\n\tParam.attr(\"WLSProxy\") = \"WLSProxy\";\n\tParam.attr(\"WLSSecret\") = \"WLSSecret\";\n\tParam.attr(\"WLSToken\") = \"WLSToken\";\n\tParam.attr(\"WLSTokenDuration\") = \"WLSTokenDuration\";\n\tParam.attr(\"WLSTokenRefresh\") = \"WLSTokenRefresh\";\n\tParam.attr(\"WorkLimit\") = \"WorkLimit\";\n\tParam.attr(\"WorkerPassword\") = \"WorkerPassword\";\n\tParam.attr(\"WorkerPool\") = \"WorkerPool\";\n\tParam.attr(\"ZeroHalfCuts\") = \"ZeroHalfCuts\";\n\tParam.attr(\"ZeroObjNodes\") = \"ZeroObjNodes\";\n\n\tnb::module_ Callback = GRB.def_submodule(\"Callback\");\n\tCallback.attr(\"BARRIER\") = 7;\n\tCallback.attr(\"BARRIER_COMPL\") = 7006;\n\tCallback.attr(\"BARRIER_DUALINF\") = 7005;\n\tCallback.attr(\"BARRIER_DUALOBJ\") = 7003;\n\tCallback.attr(\"BARRIER_ITRCNT\") = 7001;\n\tCallback.attr(\"BARRIER_PRIMINF\") = 7004;\n\tCallback.attr(\"BARRIER_PRIMOBJ\") = 7002;\n\tCallback.attr(\"IIS\") = 9;\n\tCallback.attr(\"IIS_BOUNDGUESS\") = 9006;\n\tCallback.attr(\"IIS_BOUNDMAX\") = 9005;\n\tCallback.attr(\"IIS_BOUNDMIN\") = 9004;\n\tCallback.attr(\"IIS_CONSTRGUESS\") = 9003;\n\tCallback.attr(\"IIS_CONSTRMAX\") = 9002;\n\tCallback.attr(\"IIS_CONSTRMIN\") = 9001;\n\tCallback.attr(\"MAXMEMUSED\") = 6005;\n\tCallback.attr(\"MEMUSED\") = 6004;\n\tCallback.attr(\"MESSAGE\") = 6;\n\tCallback.attr(\"MIP\") = 3;\n\tCallback.attr(\"MIPNODE\") = 5;\n\tCallback.attr(\"MIPNODE_BRVAR\") = 5007;\n\tCallback.attr(\"MIPNODE_NODCNT\") = 5005;\n\tCallback.attr(\"MIPNODE_OBJBND\") = 5004;\n\tCallback.attr(\"MIPNODE_OBJBST\") = 5003;\n\tCallback.attr(\"MIPNODE_OPENSCENARIOS\") = 5008;\n\tCallback.attr(\"MIPNODE_PHASE\") = 5009;\n\tCallback.attr(\"MIPNODE_REL\") = 5002;\n\tCallback.attr(\"MIPNODE_SOLCNT\") = 5006;\n\tCallback.attr(\"MIPNODE_STATUS\") = 5001;\n\tCallback.attr(\"MIPSOL\") = 4;\n\tCallback.attr(\"MIPSOL_NODCNT\") = 4005;\n\tCallback.attr(\"MIPSOL_OBJ\") = 4002;\n\tCallback.attr(\"MIPSOL_OBJBND\") = 4004;\n\tCallback.attr(\"MIPSOL_OBJBST\") = 4003;\n\tCallback.attr(\"MIPSOL_OPENSCENARIOS\") = 4007;\n\tCallback.attr(\"MIPSOL_PHASE\") = 4008;\n\tCallback.attr(\"MIPSOL_SOL\") = 4001;\n\tCallback.attr(\"MIPSOL_SOLCNT\") = 4006;\n\tCallback.attr(\"MIP_CUTCNT\") = 3004;\n\tCallback.attr(\"MIP_ITRCNT\") = 3006;\n\tCallback.attr(\"MIP_NODCNT\") = 3002;\n\tCallback.attr(\"MIP_NODLFT\") = 3005;\n\tCallback.attr(\"MIP_OBJBND\") = 3001;\n\tCallback.attr(\"MIP_OBJBST\") = 3000;\n\tCallback.attr(\"MIP_OPENSCENARIOS\") = 3007;\n\tCallback.attr(\"MIP_PHASE\") = 3008;\n\tCallback.attr(\"MIP_SOLCNT\") = 3003;\n\tCallback.attr(\"MSG_STRING\") = 6001;\n\tCallback.attr(\"MULTIOBJ\") = 8;\n\tCallback.attr(\"MULTIOBJ_ITRCNT\") = 8004;\n\tCallback.attr(\"MULTIOBJ_MIPGAP\") = 8008;\n\tCallback.attr(\"MULTIOBJ_NODCNT\") = 8009;\n\tCallback.attr(\"MULTIOBJ_NODLFT\") = 8010;\n\tCallback.attr(\"MULTIOBJ_OBJBND\") = 8006;\n\tCallback.attr(\"MULTIOBJ_OBJBST\") = 8005;\n\tCallback.attr(\"MULTIOBJ_OBJCNT\") = 8001;\n\tCallback.attr(\"MULTIOBJ_RUNTIME\") = 8011;\n\tCallback.attr(\"MULTIOBJ_SOL\") = 8003;\n\tCallback.attr(\"MULTIOBJ_SOLCNT\") = 8002;\n\tCallback.attr(\"MULTIOBJ_STATUS\") = 8007;\n\tCallback.attr(\"MULTIOBJ_WORK\") = 8012;\n\tCallback.attr(\"NLBAR\") = 11;\n\tCallback.attr(\"NLBAR_COMPL\") = 11005;\n\tCallback.attr(\"NLBAR_DUALINF\") = 11004;\n\tCallback.attr(\"NLBAR_ITRCNT\") = 11001;\n\tCallback.attr(\"NLBAR_PRIMINF\") = 11003;\n\tCallback.attr(\"NLBAR_PRIMOBJ\") = 11002;\n\tCallback.attr(\"PDHG\") = 10;\n\tCallback.attr(\"PDHG_COMPL\") = 10006;\n\tCallback.attr(\"PDHG_DUALINF\") = 10005;\n\tCallback.attr(\"PDHG_DUALOBJ\") = 10003;\n\tCallback.attr(\"PDHG_ITRCNT\") = 10001;\n\tCallback.attr(\"PDHG_PRIMINF\") = 10004;\n\tCallback.attr(\"PDHG_PRIMOBJ\") = 10002;\n\tCallback.attr(\"POLLING\") = 0;\n\tCallback.attr(\"PRESOLVE\") = 1;\n\tCallback.attr(\"PRE_BNDCHG\") = 1003;\n\tCallback.attr(\"PRE_COECHG\") = 1004;\n\tCallback.attr(\"PRE_COLDEL\") = 1000;\n\tCallback.attr(\"PRE_ROWDEL\") = 1001;\n\tCallback.attr(\"PRE_SENCHG\") = 1002;\n\tCallback.attr(\"RUNTIME\") = 6002;\n\tCallback.attr(\"SIMPLEX\") = 2;\n\tCallback.attr(\"SPX_DUALINF\") = 2003;\n\tCallback.attr(\"SPX_ISPERT\") = 2004;\n\tCallback.attr(\"SPX_ITRCNT\") = 2000;\n\tCallback.attr(\"SPX_OBJVAL\") = 2001;\n\tCallback.attr(\"SPX_PRIMINF\") = 2002;\n\tCallback.attr(\"WORK\") = 6003;\n}\n"
  },
  {
    "path": "lib/highs_model.cpp",
    "content": "#include \"pyoptinterface/highs_model.hpp\"\n#include \"fmt/core.h\"\n\nnamespace highs\n{\n#define B DYLIB_DECLARE\nAPILIST\n#undef B\n\nstatic DynamicLibrary lib;\nstatic bool is_loaded = false;\n\nbool is_library_loaded()\n{\n\treturn is_loaded;\n}\n\nbool load_library(const std::string &path)\n{\n\tbool success = lib.try_load(path.c_str());\n\tif (!success)\n\t{\n\t\treturn false;\n\t}\n\n\tDYLIB_LOAD_INIT;\n\n#define B DYLIB_LOAD_FUNCTION\n\tAPILIST\n#undef B\n\n\tif (IS_DYLIB_LOAD_SUCCESS)\n\t{\n#define B DYLIB_SAVE_FUNCTION\n\t\tAPILIST\n#undef B\n\t\tis_loaded = true;\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\treturn false;\n\t}\n}\n} // namespace highs\n\nstatic void check_error(HighsInt error)\n{\n\tif (error == kHighsStatusError)\n\t{\n\t\tstd::string errmsg = fmt::format(\n\t\t    \"Encountered an error in HiGHS (Status {}). Check the log for details.\", error);\n\n\t\tthrow std::runtime_error(errmsg);\n\t}\n}\n\nstatic HighsInt highs_vtype(VariableDomain domain)\n{\n\tswitch (domain)\n\t{\n\tcase VariableDomain::Continuous:\n\t\treturn kHighsVarTypeContinuous;\n\tcase VariableDomain::Integer:\n\tcase VariableDomain::Binary:\n\t\treturn kHighsVarTypeInteger;\n\tcase VariableDomain::SemiContinuous:\n\t\treturn kHighsVarTypeSemiContinuous;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown variable domain\");\n\t}\n}\n\nstatic VariableDomain highs_vtype_to_domain(HighsInt vtype)\n{\n\tswitch (vtype)\n\t{\n\tcase kHighsVarTypeContinuous:\n\t\treturn VariableDomain::Continuous;\n\tcase kHighsVarTypeInteger:\n\t\treturn VariableDomain::Integer;\n\tcase kHighsVarTypeSemiContinuous:\n\t\treturn VariableDomain::SemiContinuous;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown variable domain\");\n\t}\n}\n\nstatic HighsInt highs_obj_sense(ObjectiveSense sense)\n{\n\tswitch (sense)\n\t{\n\tcase ObjectiveSense::Minimize:\n\t\treturn kHighsObjSenseMinimize;\n\tcase ObjectiveSense::Maximize:\n\t\treturn kHighsObjSenseMaximize;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown objective sense\");\n\t}\n}\n\nPOIHighsModel::POIHighsModel()\n{\n\tinit();\n}\n\nvoid POIHighsModel::init()\n{\n\tif (!highs::is_library_loaded())\n\t{\n\t\tthrow std::runtime_error(\"HiGHS library is not loaded\");\n\t}\n\tvoid *model = highs::Highs_create();\n\tm_model = std::unique_ptr<void, HighsfreemodelT>(model);\n}\n\nvoid POIHighsModel::close()\n{\n\tm_model.reset();\n}\n\nvoid POIHighsModel::write(const std::string &filename, bool pretty)\n{\n\tbool is_solution = false;\n\tif (filename.ends_with(\".sol\"))\n\t{\n\t\tis_solution = true;\n\t}\n\tHighsInt error;\n\tif (is_solution)\n\t{\n\t\tif (pretty)\n\t\t\terror = highs::Highs_writeSolutionPretty(m_model.get(), filename.c_str());\n\t\telse\n\t\t\terror = highs::Highs_writeSolution(m_model.get(), filename.c_str());\n\t}\n\telse\n\t{\n\t\terror = highs::Highs_writeModel(m_model.get(), filename.c_str());\n\t}\n\tcheck_error(error);\n}\n\nVariableIndex POIHighsModel::add_variable(VariableDomain domain, double lb, double ub,\n                                          const char *name)\n{\n\tIndexT index = m_variable_index.add_index();\n\tVariableIndex variable(index);\n\n\tif (domain == VariableDomain::Binary)\n\t{\n\t\tlb = 0.0;\n\t\tub = 1.0;\n\t}\n\tauto error = highs::Highs_addCol(m_model.get(), 0.0, lb, ub, 0, nullptr, nullptr);\n\tcheck_error(error);\n\n\tauto column = m_n_variables;\n\n\tif (domain != VariableDomain::Continuous)\n\t{\n\t\tauto vtype = highs_vtype(domain);\n\t\tif (domain == VariableDomain::Binary)\n\t\t{\n\t\t\tbinary_variables.insert(index);\n\t\t}\n\t\terror = highs::Highs_changeColIntegrality(m_model.get(), column, vtype);\n\t\tcheck_error(error);\n\t}\n\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\tif (name)\n\t{\n\t\terror = highs::Highs_passColName(m_model.get(), column, name);\n\t\tcheck_error(error);\n\t}\n\n\tm_n_variables++;\n\treturn variable;\n}\n\nvoid POIHighsModel::delete_variable(const VariableIndex &variable)\n{\n\tif (!is_variable_active(variable))\n\t{\n\t\tthrow std::runtime_error(\"Variable does not exist\");\n\t}\n\n\tint variable_column = _variable_index(variable);\n\tauto error = highs::Highs_deleteColsBySet(m_model.get(), 1, &variable_column);\n\tcheck_error(error);\n\n\tm_variable_index.delete_index(variable.index);\n\tbinary_variables.erase(variable.index);\n\n\tm_n_variables--;\n}\n\nvoid POIHighsModel::delete_variables(const Vector<VariableIndex> &variables)\n{\n\tint n_variables = variables.size();\n\tif (n_variables == 0)\n\t\treturn;\n\n\tstd::vector<HighsInt> columns;\n\tcolumns.reserve(n_variables);\n\tfor (int i = 0; i < n_variables; i++)\n\t{\n\t\tif (!is_variable_active(variables[i]))\n\t\t{\n\t\t\tcontinue;\n\t\t}\n\t\tauto column = _variable_index(variables[i]);\n\t\tcolumns.push_back(column);\n\t}\n\n\tint error = highs::Highs_deleteColsBySet(m_model.get(), columns.size(), columns.data());\n\tcheck_error(error);\n\n\tfor (int i = 0; i < n_variables; i++)\n\t{\n\t\tm_variable_index.delete_index(variables[i].index);\n\t}\n\tm_n_variables -= columns.size();\n}\n\nbool POIHighsModel::is_variable_active(const VariableIndex &variable)\n{\n\treturn m_variable_index.has_index(variable.index);\n}\n\ndouble POIHighsModel::get_variable_value(const VariableIndex &variable)\n{\n\tauto column = _checked_variable_index(variable);\n\tif (m_solution.primal_solution_status != kHighsSolutionStatusNone)\n\t{\n\t\treturn m_solution.colvalue[column];\n\t}\n\tthrow std::runtime_error(\"No solution available\");\n}\n\nstd::string POIHighsModel::pprint_variable(const VariableIndex &variable)\n{\n\treturn get_variable_name(variable);\n}\n\nvoid POIHighsModel::set_variable_bounds(const VariableIndex &variable, double lb, double ub)\n{\n\tauto column = _checked_variable_index(variable);\n\tauto error = highs::Highs_changeColsBoundsBySet(m_model.get(), 1, &column, &lb, &ub);\n\tcheck_error(error);\n}\n\nConstraintIndex POIHighsModel::add_linear_constraint(const ScalarAffineFunction &function,\n                                                     ConstraintSense sense, CoeffT rhs,\n                                                     const char *name)\n{\n\tdouble lb = -kHighsInf;\n\tdouble ub = kHighsInf;\n\tswitch (sense)\n\t{\n\tcase ConstraintSense::LessEqual:\n\t\tub = rhs;\n\t\tbreak;\n\tcase ConstraintSense::GreaterEqual:\n\t\tlb = rhs;\n\t\tbreak;\n\tcase ConstraintSense::Equal:\n\t\tlb = rhs;\n\t\tub = rhs;\n\t\tbreak;\n\t}\n\n\tauto con = add_linear_constraint(function, std::make_tuple(lb, ub), name);\n\treturn con;\n}\n\nConstraintIndex POIHighsModel::add_linear_constraint(const ScalarAffineFunction &function,\n                                                     const std::tuple<double, double> &interval,\n                                                     const char *name)\n{\n\tIndexT index = m_linear_constraint_index.add_index();\n\tConstraintIndex constraint(ConstraintType::Linear, index);\n\n\tAffineFunctionPtrForm<HighsInt, HighsInt, double> ptr_form;\n\tptr_form.make(this, function);\n\n\tHighsInt numnz = ptr_form.numnz;\n\tHighsInt *cind = ptr_form.index;\n\tdouble *cval = ptr_form.value;\n\n\tdouble lb = std::get<0>(interval);\n\tdouble ub = std::get<1>(interval);\n\tif (function.constant.has_value())\n\t{\n\t\tlb -= function.constant.value();\n\t\tub -= function.constant.value();\n\t}\n\n\tauto error = highs::Highs_addRow(m_model.get(), lb, ub, numnz, cind, cval);\n\tcheck_error(error);\n\n\tHighsInt row = m_n_constraints;\n\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\tif (name)\n\t{\n\t\terror = highs::Highs_passRowName(m_model.get(), row, name);\n\t\tcheck_error(error);\n\t}\n\n\tm_n_constraints++;\n\n\treturn constraint;\n}\n\nConstraintIndex POIHighsModel::add_quadratic_constraint(const ScalarQuadraticFunction &function,\n                                                        ConstraintSense sense, CoeffT rhs,\n                                                        const char *name)\n{\n\tthrow std::runtime_error(\"HIGHS does not support quadratic constraint!\");\n}\n\nvoid POIHighsModel::delete_constraint(const ConstraintIndex &constraint)\n{\n\tif (!is_constraint_active(constraint))\n\t{\n\t\tthrow std::runtime_error(\"Constraint does not exist\");\n\t}\n\n\tint constraint_row = _constraint_index(constraint);\n\tauto error = highs::Highs_deleteRowsBySet(m_model.get(), 1, &constraint_row);\n\tcheck_error(error);\n\n\tm_linear_constraint_index.delete_index(constraint.index);\n\n\tm_n_constraints--;\n}\n\nbool POIHighsModel::is_constraint_active(const ConstraintIndex &constraint)\n{\n\treturn m_linear_constraint_index.has_index(constraint.index);\n}\n\nvoid POIHighsModel::_set_affine_objective(const ScalarAffineFunction &function,\n                                          ObjectiveSense sense, bool clear_quadratic)\n{\n\tHighsInt error;\n\n\tHighsInt n_variables = m_n_variables;\n\tif (clear_quadratic)\n\t{\n\t\t// First delete all quadratic terms\n\t\tstd::vector<HighsInt> colstarts(n_variables, 0);\n\t\terror =\n\t\t    highs::Highs_passHessian(m_model.get(), n_variables, 0, kHighsHessianFormatTriangular,\n\t\t                             colstarts.data(), nullptr, nullptr);\n\n\t\tcheck_error(error);\n\t}\n\n\t// Set Obj attribute of each variable\n\tstd::vector<double> obj_v(n_variables, 0.0);\n\n\tint numnz = function.size();\n\tfor (int i = 0; i < numnz; i++)\n\t{\n\t\tauto column = _variable_index(function.variables[i]);\n\t\tif (column < 0)\n\t\t{\n\t\t\tthrow std::runtime_error(\"Variable does not exist\");\n\t\t}\n\t\tobj_v[column] = function.coefficients[i];\n\t}\n\n\terror = highs::Highs_changeColsCostByRange(m_model.get(), 0, n_variables - 1, obj_v.data());\n\tcheck_error(error);\n\terror = highs::Highs_changeObjectiveOffset(m_model.get(), function.constant.value_or(0.0));\n\tcheck_error(error);\n\n\tHighsInt obj_sense = highs_obj_sense(sense);\n\terror = highs::Highs_changeObjectiveSense(m_model.get(), obj_sense);\n\tcheck_error(error);\n}\n\nvoid POIHighsModel::set_objective(const ScalarAffineFunction &function, ObjectiveSense sense)\n{\n\t_set_affine_objective(function, sense, true);\n}\n\nvoid POIHighsModel::set_objective(const ScalarQuadraticFunction &function, ObjectiveSense sense)\n{\n\tHighsInt error;\n\n\t// Add quadratic term\n\tint numqnz = function.size();\n\tHighsInt n_variables = m_n_variables;\n\tif (numqnz > 0)\n\t{\n\t\tCSCMatrix<HighsInt, HighsInt, double> csc;\n\t\tcsc.make(this, function, n_variables, HessianTriangular::Lower);\n\n\t\t// Highs optimizes 0.5 * x' * Q * x\n\t\t// so the coefficient must be multiplied by 2.0\n\t\tfor (auto &v : csc.values_CSC)\n\t\t{\n\t\t\tv *= 2.0;\n\t\t}\n\n\t\terror = highs::Highs_passHessian(m_model.get(), n_variables, numqnz,\n\t\t                                 kHighsHessianFormatTriangular, csc.colStarts_CSC.data(),\n\t\t                                 csc.rows_CSC.data(), csc.values_CSC.data());\n\t\tcheck_error(error);\n\t}\n\telse\n\t{\n\t\tstd::vector<HighsInt> colstarts(n_variables, 0);\n\t\terror =\n\t\t    highs::Highs_passHessian(m_model.get(), n_variables, 0, kHighsHessianFormatTriangular,\n\t\t                             colstarts.data(), nullptr, nullptr);\n\t\tcheck_error(error);\n\t}\n\n\t// Affine part\n\tconst auto &affine_part = function.affine_part;\n\tif (affine_part)\n\t{\n\t\tconst auto &affine_function = affine_part.value();\n\t\t_set_affine_objective(affine_function, sense, false);\n\t}\n\telse\n\t{\n\t\tScalarAffineFunction zero;\n\t\t_set_affine_objective(zero, sense, false);\n\t}\n}\n\nvoid POIHighsModel::set_objective(const ExprBuilder &function, ObjectiveSense sense)\n{\n\tauto deg = function.degree();\n\tif (deg <= 1)\n\t{\n\t\tScalarAffineFunction f(function);\n\t\tset_objective(f, sense);\n\t}\n\telse if (deg == 2)\n\t{\n\t\tScalarQuadraticFunction f(function);\n\t\tset_objective(f, sense);\n\t}\n\telse\n\t{\n\t\tthrow std::runtime_error(\"Objective must be linear or quadratic\");\n\t}\n}\n\nvoid POIHighsModel::optimize()\n{\n\tHighsInt error = highs::Highs_run(m_model.get());\n\n\tPOIHighsSolution &x = m_solution;\n\tx.status = error == kHighsStatusError ? HighsSolutionStatus::OPTIMIZE_ERROR\n\t                                      : HighsSolutionStatus::OPTIMIZE_OK;\n\n\tvoid *model = m_model.get();\n\n\tx.primal_solution_status = kHighsSolutionStatusNone;\n\tx.dual_solution_status = kHighsSolutionStatusNone;\n\tx.has_dual_ray = false;\n\tx.has_primal_ray = false;\n\tauto numCols = m_n_variables;\n\tauto numRows = m_n_constraints;\n\tx.model_status = highs::Highs_getModelStatus(model);\n\n\tHighsInt status;\n\tHighsInt *statusP = &status;\n\tif (x.model_status == kHighsModelStatusInfeasible)\n\t{\n\t\tx.dual_ray.resize(numRows);\n\t\terror = highs::Highs_getDualRay(model, statusP, x.dual_ray.data());\n\t\tx.has_dual_ray = (error == kHighsStatusOk) && (*statusP == 1);\n\t}\n\telse if (x.model_status == kHighsModelStatusUnbounded)\n\t{\n\t\tx.primal_ray.resize(numCols);\n\t\terror = highs::Highs_getPrimalRay(model, statusP, x.primal_ray.data());\n\t\tx.has_primal_ray = (error == kHighsStatusOk) && (*statusP == 1);\n\t}\n\telse\n\t{\n\t\thighs::Highs_getIntInfoValue(model, \"primal_solution_status\", statusP);\n\t\tx.primal_solution_status = *statusP;\n\t\thighs::Highs_getIntInfoValue(model, \"dual_solution_status\", statusP);\n\t\tx.dual_solution_status = *statusP;\n\t\tif (x.primal_solution_status != kHighsSolutionStatusNone)\n\t\t{\n\t\t\tx.colvalue.resize(numCols);\n\t\t\tx.coldual.resize(numCols);\n\t\t\tx.rowvalue.resize(numRows);\n\t\t\tx.rowdual.resize(numRows);\n\t\t\thighs::Highs_getSolution(model, x.colvalue.data(), x.coldual.data(), x.rowvalue.data(),\n\t\t\t                         x.rowdual.data());\n\n\t\t\t// HighsModel &h_model = ((Highs *)m_model.get())->model_;\n\t\t\t// auto &hessian = h_model.hessian_;\n\t\t\tauto hessian_nz = highs::Highs_getHessianNumNz(model);\n\t\t\tif (hessian_nz == 0)\n\t\t\t{\n\t\t\t\t// No basis is present in a QP.\n\t\t\t\tx.colstatus.resize(numCols);\n\t\t\t\tx.rowstatus.resize(numRows);\n\t\t\t\thighs::Highs_getBasis(model, x.colstatus.data(), x.rowstatus.data());\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid *POIHighsModel::get_raw_model()\n{\n\treturn m_model.get();\n}\n\nstd::string POIHighsModel::version_string()\n{\n\tauto version = highs::Highs_version();\n\treturn version;\n}\n\ndouble POIHighsModel::getruntime()\n{\n\tdouble runtime = highs::Highs_getRunTime(m_model.get());\n\treturn runtime;\n}\n\nint POIHighsModel::getnumrow()\n{\n\treturn highs::Highs_getNumRow(m_model.get());\n}\n\nint POIHighsModel::getnumcol()\n{\n\treturn highs::Highs_getNumCol(m_model.get());\n}\n\nint POIHighsModel::raw_option_type(const char *param_name)\n{\n\tHighsInt retval;\n\tauto error = highs::Highs_getOptionType(m_model.get(), param_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nvoid POIHighsModel::set_raw_option_bool(const char *param_name, bool value)\n{\n\tauto error = highs::Highs_setBoolOptionValue(m_model.get(), param_name, value);\n\tcheck_error(error);\n}\n\nvoid POIHighsModel::set_raw_option_int(const char *param_name, int value)\n{\n\tauto error = highs::Highs_setIntOptionValue(m_model.get(), param_name, value);\n\tcheck_error(error);\n}\n\nvoid POIHighsModel::set_raw_option_double(const char *param_name, double value)\n{\n\tauto error = highs::Highs_setDoubleOptionValue(m_model.get(), param_name, value);\n\tcheck_error(error);\n}\n\nvoid POIHighsModel::set_raw_option_string(const char *param_name, const char *value)\n{\n\tauto error = highs::Highs_setStringOptionValue(m_model.get(), param_name, value);\n\tcheck_error(error);\n}\n\nbool POIHighsModel::get_raw_option_bool(const char *param_name)\n{\n\tHighsInt retval;\n\tauto error = highs::Highs_getBoolOptionValue(m_model.get(), param_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nint POIHighsModel::get_raw_option_int(const char *param_name)\n{\n\tHighsInt retval;\n\tauto error = highs::Highs_getIntOptionValue(m_model.get(), param_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble POIHighsModel::get_raw_option_double(const char *param_name)\n{\n\tdouble retval;\n\tauto error = highs::Highs_getDoubleOptionValue(m_model.get(), param_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nstd::string POIHighsModel::get_raw_option_string(const char *param_name)\n{\n\tchar retval[kHighsMaximumStringLength];\n\tauto error = highs::Highs_getStringOptionValue(m_model.get(), param_name, retval);\n\tcheck_error(error);\n\treturn std::string(retval);\n}\n\nint POIHighsModel::raw_info_type(const char *info_name)\n{\n\tHighsInt retval;\n\tauto error = highs::Highs_getInfoType(m_model.get(), info_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nint POIHighsModel::get_raw_info_int(const char *info_name)\n{\n\tHighsInt retval;\n\tauto error = highs::Highs_getIntInfoValue(m_model.get(), info_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nstd::int64_t POIHighsModel::get_raw_info_int64(const char *info_name)\n{\n\tint64_t retval;\n\tauto error = highs::Highs_getInt64InfoValue(m_model.get(), info_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble POIHighsModel::get_raw_info_double(const char *info_name)\n{\n\tdouble retval;\n\tauto error = highs::Highs_getDoubleInfoValue(m_model.get(), info_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nstd::string POIHighsModel::get_variable_name(const VariableIndex &variable)\n{\n\tauto column = _checked_variable_index(variable);\n\tchar name[kHighsMaximumStringLength];\n\tauto error = highs::Highs_getColName(m_model.get(), column, name);\n\tcheck_error(error);\n\treturn std::string(name);\n}\n\nvoid POIHighsModel::set_variable_name(const VariableIndex &variable, const char *name)\n{\n\tauto column = _checked_variable_index(variable);\n\tauto error = highs::Highs_passColName(m_model.get(), column, name);\n\tcheck_error(error);\n}\n\nVariableDomain POIHighsModel::get_variable_type(const VariableIndex &variable)\n{\n\tif (binary_variables.contains(variable.index))\n\t{\n\t\treturn VariableDomain::Binary;\n\t}\n\tauto column = _checked_variable_index(variable);\n\tHighsInt vtype;\n\tauto error = highs::Highs_getColIntegrality(m_model.get(), column, &vtype);\n\tcheck_error(error);\n\treturn highs_vtype_to_domain(vtype);\n}\n\nvoid POIHighsModel::set_variable_type(const VariableIndex &variable, VariableDomain domain)\n{\n\tauto vtype = highs_vtype(domain);\n\tauto column = _checked_variable_index(variable);\n\tauto error = highs::Highs_changeColIntegrality(m_model.get(), column, vtype);\n\tcheck_error(error);\n\n\tif (domain == VariableDomain::Binary)\n\t{\n\t\tdouble lb = 0.0;\n\t\tdouble ub = 1.0;\n\t\tbinary_variables.insert(variable.index);\n\t\terror = highs::Highs_changeColsBoundsBySet(m_model.get(), 1, &column, &lb, &ub);\n\t\tcheck_error(error);\n\t}\n\telse\n\t{\n\t\tbinary_variables.erase(variable.index);\n\t}\n}\n\ndouble POIHighsModel::get_variable_lower_bound(const VariableIndex &variable)\n{\n\tauto column = _checked_variable_index(variable);\n\tHighsInt numcol, nz;\n\tdouble c, lb, ub;\n\tauto error = highs::Highs_getColsBySet(m_model.get(), 1, &column, &numcol, &c, &lb, &ub, &nz,\n\t                                       nullptr, nullptr, nullptr);\n\tcheck_error(error);\n\treturn lb;\n}\n\ndouble POIHighsModel::get_variable_upper_bound(const VariableIndex &variable)\n{\n\tauto column = _checked_variable_index(variable);\n\tHighsInt numcol, nz;\n\tdouble c, lb, ub;\n\tauto error = highs::Highs_getColsBySet(m_model.get(), 1, &column, &numcol, &c, &lb, &ub, &nz,\n\t                                       nullptr, nullptr, nullptr);\n\tcheck_error(error);\n\treturn ub;\n}\n\nvoid POIHighsModel::set_variable_lower_bound(const VariableIndex &variable, double lb)\n{\n\tdouble new_lb = lb;\n\tauto column = _checked_variable_index(variable);\n\tHighsInt numcol, nz;\n\tdouble c, ub;\n\tauto error = highs::Highs_getColsBySet(m_model.get(), 1, &column, &numcol, &c, &lb, &ub, &nz,\n\t                                       nullptr, nullptr, nullptr);\n\tcheck_error(error);\n\terror = highs::Highs_changeColsBoundsBySet(m_model.get(), 1, &column, &new_lb, &ub);\n\tcheck_error(error);\n}\n\nvoid POIHighsModel::set_variable_upper_bound(const VariableIndex &variable, double ub)\n{\n\tdouble new_ub = ub;\n\tauto column = _checked_variable_index(variable);\n\tHighsInt numcol, nz;\n\tdouble c, lb;\n\tauto error = highs::Highs_getColsBySet(m_model.get(), 1, &column, &numcol, &c, &lb, &ub, &nz,\n\t                                       nullptr, nullptr, nullptr);\n\tcheck_error(error);\n\terror = highs::Highs_changeColsBoundsBySet(m_model.get(), 1, &column, &lb, &new_ub);\n\tcheck_error(error);\n}\n\nstd::string POIHighsModel::get_constraint_name(const ConstraintIndex &constraint)\n{\n\tauto row = _checked_constraint_index(constraint);\n\tchar name[kHighsMaximumStringLength];\n\tauto error = highs::Highs_getRowName(m_model.get(), row, name);\n\tcheck_error(error);\n\treturn std::string(name);\n}\n\nvoid POIHighsModel::set_constraint_name(const ConstraintIndex &constraint, const char *name)\n{\n\tauto row = _checked_constraint_index(constraint);\n\tauto error = highs::Highs_passRowName(m_model.get(), row, name);\n\tcheck_error(error);\n}\n\ndouble POIHighsModel::get_constraint_primal(const ConstraintIndex &constraint)\n{\n\tauto row = _checked_constraint_index(constraint);\n\tif (m_solution.primal_solution_status != kHighsSolutionStatusNone)\n\t{\n\t\treturn m_solution.rowvalue[row];\n\t}\n\tthrow std::runtime_error(\"No solution available\");\n}\n\ndouble POIHighsModel::get_constraint_dual(const ConstraintIndex &constraint)\n{\n\tauto row = _checked_constraint_index(constraint);\n\tif (m_solution.primal_solution_status != kHighsSolutionStatusNone)\n\t{\n\t\treturn m_solution.rowdual[row];\n\t}\n\tthrow std::runtime_error(\"No solution available\");\n}\n\ndouble POIHighsModel::get_variable_dual(const VariableIndex &variable)\n{\n\tauto col = _checked_variable_index(variable);\n\tif (m_solution.primal_solution_status != kHighsSolutionStatusNone)\n\t{\n\t\treturn m_solution.coldual[col];\n\t}\n\tthrow std::runtime_error(\"No solution available\");\n}\n\nObjectiveSense POIHighsModel::get_obj_sense()\n{\n\tHighsInt obj_sense;\n\tauto error = highs::Highs_getObjectiveSense(m_model.get(), &obj_sense);\n\tcheck_error(error);\n\treturn obj_sense == kHighsObjSenseMinimize ? ObjectiveSense::Minimize\n\t                                           : ObjectiveSense::Maximize;\n}\n\nvoid POIHighsModel::set_obj_sense(ObjectiveSense sense)\n{\n\tauto obj_sense = highs_obj_sense(sense);\n\tauto error = highs::Highs_changeObjectiveSense(m_model.get(), obj_sense);\n\tcheck_error(error);\n}\n\ndouble POIHighsModel::get_obj_value()\n{\n\tdouble obj = highs::Highs_getObjectiveValue(m_model.get());\n\treturn obj;\n}\n\nHighsInt POIHighsModel::_variable_index(const VariableIndex &variable)\n{\n\treturn m_variable_index.get_index(variable.index);\n}\n\nHighsInt POIHighsModel::_checked_variable_index(const VariableIndex &variable)\n{\n\tHighsInt column = _variable_index(variable);\n\tif (column < 0)\n\t{\n\t\tthrow std::runtime_error(\"Variable does not exist\");\n\t}\n\treturn column;\n}\n\nHighsInt POIHighsModel::_constraint_index(const ConstraintIndex &constraint)\n{\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\t\treturn m_linear_constraint_index.get_index(constraint.index);\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n}\n\nHighsInt POIHighsModel::_checked_constraint_index(const ConstraintIndex &constraint)\n{\n\tHighsInt row = _constraint_index(constraint);\n\tif (row < 0)\n\t{\n\t\tthrow std::runtime_error(\"Constraint does not exist\");\n\t}\n\treturn row;\n}\n\nvoid POIHighsModel::set_primal_start(const Vector<VariableIndex> &variables,\n                                     const Vector<double> &values)\n{\n\tif (variables.size() != values.size())\n\t{\n\t\tthrow std::runtime_error(\"Number of variables and values do not match\");\n\t}\n\tint numnz = variables.size();\n\tif (numnz == 0)\n\t\treturn;\n\n\tauto numcol = m_n_variables;\n\tif (numcol == 0)\n\t\treturn;\n\n\tHighsInt _numcol, nz;\n\tstd::vector<double> c(numcol), lb(numcol), ub(numcol);\n\tauto error = highs::Highs_getColsByRange(m_model.get(), 0, numcol - 1, &_numcol, c.data(),\n\t                                         lb.data(), ub.data(), &nz, nullptr, nullptr, nullptr);\n\tstd::vector<double> vals(numcol);\n\tfor (int i = 0; i < numcol; i++)\n\t{\n\t\tdouble L = lb[i];\n\t\tdouble U = ub[i];\n\t\tbool L_inf = L < -kHighsInf + 1.0;\n\t\tbool U_inf = U > kHighsInf - 1.0;\n\n\t\tdouble initial = L;\n\t\tif (L_inf)\n\t\t{\n\t\t\tif (U_inf)\n\t\t\t{\n\t\t\t\tinitial = 0.0;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tinitial = U;\n\t\t\t}\n\t\t}\n\t\tvals[i] = initial;\n\t}\n\n\tfor (auto i = 0; i < variables.size(); i++)\n\t{\n\t\tauto column = _checked_variable_index(variables[i]);\n\t\tvals[column] = values[i];\n\t}\n\terror = highs::Highs_setSolution(m_model.get(), vals.data(), nullptr, nullptr, nullptr);\n\tcheck_error(error);\n}\n\ndouble POIHighsModel::get_normalized_rhs(const ConstraintIndex &constraint)\n{\n\tauto row = _checked_constraint_index(constraint);\n\tHighsInt numrow, nz;\n\tdouble ub, lb;\n\tauto error = highs::Highs_getRowsBySet(m_model.get(), 1, &row, &numrow, &lb, &ub, &nz, nullptr,\n\t                                       nullptr, nullptr);\n\tcheck_error(error);\n\n\tbool lb_inf = lb < -kHighsInf + 1.0;\n\tbool ub_inf = ub > kHighsInf - 1.0;\n\n\tif (!lb_inf)\n\t\treturn lb;\n\tif (!ub_inf)\n\t\treturn ub;\n\n\tthrow std::runtime_error(\"Constraint has no finite bound\");\n}\n\nvoid POIHighsModel::set_normalized_rhs(const ConstraintIndex &constraint, double value)\n{\n\tauto row = _checked_constraint_index(constraint);\n\tHighsInt numrow, nz;\n\tdouble ub, lb;\n\tauto error = highs::Highs_getRowsBySet(m_model.get(), 1, &row, &numrow, &lb, &ub, &nz, nullptr,\n\t                                       nullptr, nullptr);\n\tcheck_error(error);\n\n\tbool lb_inf = lb < -kHighsInf + 1.0;\n\tbool ub_inf = ub > kHighsInf - 1.0;\n\n\tif (!lb_inf)\n\t\tlb = value;\n\tif (!ub_inf)\n\t\tub = value;\n\tif (lb_inf && ub_inf)\n\t{\n\t\tthrow std::runtime_error(\"Constraint has no finite bound\");\n\t}\n\n\terror = highs::Highs_changeRowsBoundsBySet(m_model.get(), 1, &row, &lb, &ub);\n\tcheck_error(error);\n}\n\ndouble POIHighsModel::get_normalized_coefficient(const ConstraintIndex &constraint,\n                                                 const VariableIndex &variable)\n{\n\tauto row = _checked_constraint_index(constraint);\n\tHighsInt numrow, nz;\n\tdouble ub, lb;\n\tauto error = highs::Highs_getRowsBySet(m_model.get(), 1, &row, &numrow, &lb, &ub, &nz, nullptr,\n\t                                       nullptr, nullptr);\n\tcheck_error(error);\n\n\tstd::vector<HighsInt> matrix_start(nz);\n\tstd::vector<HighsInt> matrix_index(nz);\n\tstd::vector<double> matrix_value(nz);\n\n\terror =\n\t    highs::Highs_getRowsBySet(m_model.get(), 1, &row, &numrow, &lb, &ub, &nz,\n\t                              matrix_start.data(), matrix_index.data(), matrix_value.data());\n\tcheck_error(error);\n\n\tdouble coef = 0.0;\n\tauto col = _checked_variable_index(variable);\n\tfor (auto i = 0; i < nz; i++)\n\t{\n\t\tif (matrix_index[i] == col)\n\t\t{\n\t\t\tcoef = matrix_value[i];\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn coef;\n}\n\nvoid POIHighsModel::set_normalized_coefficient(const ConstraintIndex &constraint,\n                                               const VariableIndex &variable, double value)\n{\n\tauto row = _checked_constraint_index(constraint);\n\tauto col = _checked_variable_index(variable);\n\tauto error = highs::Highs_changeCoeff(m_model.get(), row, col, value);\n\tcheck_error(error);\n}\n\ndouble POIHighsModel::get_objective_coefficient(const VariableIndex &variable)\n{\n\tauto column = _checked_variable_index(variable);\n\tHighsInt numcol, nz;\n\tdouble c, lb, ub;\n\tauto error = highs::Highs_getColsBySet(m_model.get(), 1, &column, &numcol, &c, &lb, &ub, &nz,\n\t                                       nullptr, nullptr, nullptr);\n\tcheck_error(error);\n\treturn c;\n}\n\nvoid POIHighsModel::set_objective_coefficient(const VariableIndex &variable, double value)\n{\n\tauto column = _checked_variable_index(variable);\n\tauto error = highs::Highs_changeColCost(m_model.get(), column, value);\n\tcheck_error(error);\n}\n"
  },
  {
    "path": "lib/highs_model_ext.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include <nanobind/stl/string.h>\n#include <nanobind/stl/tuple.h>\n#include <nanobind/stl/vector.h>\n\n#include \"pyoptinterface/highs_model.hpp\"\n\nnamespace nb = nanobind;\n\nextern void bind_highs_constants(nb::module_ &m);\n\nNB_MODULE(highs_model_ext, m)\n{\n\tm.import_(\"pyoptinterface._src.core_ext\");\n\n\tm.def(\"is_library_loaded\", &highs::is_library_loaded);\n\tm.def(\"load_library\", &highs::load_library);\n\n\tbind_highs_constants(m);\n\n\tnb::enum_<HighsSolutionStatus>(m, \"HighsSolutionStatus\")\n\t    .value(\"OPTIMIZE_NOT_CALLED\", HighsSolutionStatus::OPTIMIZE_NOT_CALLED)\n\t    .value(\"OPTIMIZE_OK\", HighsSolutionStatus::OPTIMIZE_OK)\n\t    .value(\"OPTIMIZE_ERROR\", HighsSolutionStatus::OPTIMIZE_ERROR);\n\n\tnb::class_<POIHighsSolution>(m, \"HighsSolution\")\n\t    .def_ro(\"status\", &POIHighsSolution::status)\n\t    .def_ro(\"model_status\", &POIHighsSolution::model_status)\n\t    .def_ro(\"primal_solution_status\", &POIHighsSolution::primal_solution_status)\n\t    .def_ro(\"dual_solution_status\", &POIHighsSolution::dual_solution_status)\n\t    .def_ro(\"has_primal_ray\", &POIHighsSolution::has_primal_ray)\n\t    .def_ro(\"has_dual_ray\", &POIHighsSolution::has_dual_ray);\n\n\tusing HighsModel = POIHighsModel;\n\n#define BIND_F(f) .def(#f, &HighsModel::f)\n\tnb::class_<HighsModel>(m, \"RawModel\")\n\t    .def(nb::init<>())\n\t    .def_ro(\"m_n_variables\", &HighsModel::m_n_variables)\n\t    .def_ro(\"m_n_constraints\", &HighsModel::m_n_constraints)\n\t    // clang-format off\n\t    BIND_F(init)\n\t    BIND_F(close)\n\t    // clang-format on\n\t    .def(\"write\", &HighsModel::write, nb::arg(\"filename\"), nb::arg(\"pretty\") = false)\n\n\t    .def_ro(\"solution\", &HighsModel::m_solution)\n\n\t    .def(\"add_variable\", &HighsModel::add_variable,\n\t         nb::arg(\"domain\") = VariableDomain::Continuous, nb::arg(\"lb\") = -kHighsInf,\n\t         nb::arg(\"ub\") = kHighsInf, nb::arg(\"name\") = \"\")\n\t    // clang-format off\n\t    BIND_F(delete_variable)\n\t    BIND_F(delete_variables)\n\t    BIND_F(is_variable_active)\n\t    // clang-format on\n\t    .def(\"set_variable_bounds\", &HighsModel::set_variable_bounds, nb::arg(\"variable\"),\n\t         nb::arg(\"lb\"), nb::arg(\"ub\"))\n\n\t    .def(\"get_value\", nb::overload_cast<const VariableIndex &>(&HighsModel::get_variable_value))\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ScalarAffineFunction &>(&HighsModel::get_expression_value))\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &>(&HighsModel::get_expression_value))\n\t    .def(\"get_value\", nb::overload_cast<const ExprBuilder &>(&HighsModel::get_expression_value))\n\n\t    .def(\"pprint\", &HighsModel::pprint_variable)\n\t    .def(\"pprint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, int>(&HighsModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\t    .def(\n\t        \"pprint\",\n\t        nb::overload_cast<const ScalarQuadraticFunction &, int>(&HighsModel::pprint_expression),\n\t        nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\t    .def(\"pprint\", nb::overload_cast<const ExprBuilder &, int>(&HighsModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\n\t    .def(\"_add_linear_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ConstraintSense, CoeffT, const char *>(\n\t             &HighsModel::add_linear_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, const std::tuple<double, double> &,\n\t                           const char *>(&HighsModel::add_linear_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &HighsModel::add_linear_constraint_from_var, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &HighsModel::add_linear_interval_constraint_from_var,\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &HighsModel::add_linear_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &HighsModel::add_linear_interval_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\n\t    .def(\"delete_constraint\", &HighsModel::delete_constraint)\n\t    .def(\"is_constraint_active\", &HighsModel::is_constraint_active)\n\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, ObjectiveSense>(\n\t             &HighsModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ObjectiveSense>(\n\t             &HighsModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ExprBuilder &, ObjectiveSense>(&HighsModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const VariableIndex &, ObjectiveSense>(\n\t             &HighsModel::set_objective_as_variable),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<CoeffT, ObjectiveSense>(&HighsModel::set_objective_as_constant),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\n\t    .def(\"optimize\", &HighsModel::optimize, nb::call_guard<nb::gil_scoped_release>())\n\n\t    // clang-format off\n\t    BIND_F(version_string)\n\t    BIND_F(get_raw_model)\n\n\t\tBIND_F(getruntime)\n\t\tBIND_F(getnumrow)\n\t\tBIND_F(getnumcol)\n\n\t    BIND_F(raw_option_type)\n\n\t    BIND_F(set_raw_option_bool)\n\t    BIND_F(set_raw_option_int)\n\t    BIND_F(set_raw_option_double)\n\t    BIND_F(set_raw_option_string)\n\t    BIND_F(get_raw_option_bool)\n\t    BIND_F(get_raw_option_int)\n\t    BIND_F(get_raw_option_double)\n\t    BIND_F(get_raw_option_string)\n\n\t\tBIND_F(raw_info_type)\n\t    BIND_F(get_raw_info_int)\n\t    BIND_F(get_raw_info_int64)\n\t    BIND_F(get_raw_info_double)\n\n\t    BIND_F(set_variable_name)\n\t    BIND_F(get_variable_name)\n\t    BIND_F(set_variable_type)\n\t    BIND_F(get_variable_type)\n\t    BIND_F(set_variable_lower_bound)\n\t    BIND_F(set_variable_upper_bound)\n\t\tBIND_F(get_variable_lower_bound)\n\t    BIND_F(get_variable_upper_bound)\n\n\t\tBIND_F(get_variable_dual)\n\n\t    BIND_F(get_constraint_primal)\n\t    BIND_F(get_constraint_dual)\n\t    BIND_F(get_constraint_name)\n\t    BIND_F(set_constraint_name)\n\n\t    BIND_F(set_obj_sense)\n\t    BIND_F(get_obj_sense)\n\t    BIND_F(get_obj_value)\n\n\t\tBIND_F(set_primal_start)\n\n\t\tBIND_F(get_normalized_rhs)\n\t\tBIND_F(set_normalized_rhs)\n\t\tBIND_F(get_normalized_coefficient)\n\t\tBIND_F(set_normalized_coefficient)\n\t\tBIND_F(get_objective_coefficient)\n\t\tBIND_F(set_objective_coefficient)\n\t    // clang-format on\n\t    ;\n}"
  },
  {
    "path": "lib/highs_model_ext_constants.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include \"interfaces/highs_c_api.h\"\n\nnamespace nb = nanobind;\n\nvoid bind_highs_constants(nb::module_ &m)\n{\n\tnb::module_ Enum = m.def_submodule(\"Enum\");\n\n#define BIND_C(x) Enum.attr(#x) = x\n\n\tBIND_C(kHighsOptionTypeBool);\n\tBIND_C(kHighsOptionTypeInt);\n\tBIND_C(kHighsOptionTypeDouble);\n\tBIND_C(kHighsOptionTypeString);\n\n\tBIND_C(kHighsInfoTypeInt64);\n\tBIND_C(kHighsInfoTypeInt);\n\tBIND_C(kHighsInfoTypeDouble);\n\n\tBIND_C(kHighsSolutionStatusNone);\n\tBIND_C(kHighsSolutionStatusInfeasible);\n\tBIND_C(kHighsSolutionStatusFeasible);\n\n\tBIND_C(kHighsModelStatusNotset);\n\tBIND_C(kHighsModelStatusLoadError);\n\tBIND_C(kHighsModelStatusModelError);\n\tBIND_C(kHighsModelStatusPresolveError);\n\tBIND_C(kHighsModelStatusSolveError);\n\tBIND_C(kHighsModelStatusPostsolveError);\n\tBIND_C(kHighsModelStatusModelEmpty);\n\tBIND_C(kHighsModelStatusOptimal);\n\tBIND_C(kHighsModelStatusInfeasible);\n\tBIND_C(kHighsModelStatusUnboundedOrInfeasible);\n\tBIND_C(kHighsModelStatusUnbounded);\n\tBIND_C(kHighsModelStatusObjectiveBound);\n\tBIND_C(kHighsModelStatusObjectiveTarget);\n\tBIND_C(kHighsModelStatusTimeLimit);\n\tBIND_C(kHighsModelStatusIterationLimit);\n\tBIND_C(kHighsModelStatusUnknown);\n\tBIND_C(kHighsModelStatusSolutionLimit);\n\tBIND_C(kHighsModelStatusInterrupt);\n}"
  },
  {
    "path": "lib/ipopt_model.cpp",
    "content": "#include \"pyoptinterface/ipopt_model.hpp\"\n#include \"pyoptinterface/solver_common.hpp\"\n\n#include \"fmt/core.h\"\n#include \"fmt/ranges.h\"\n#include \"pyoptinterface/dylib.hpp\"\n#include <cassert>\n\nstatic bool is_name_empty(const char *name)\n{\n\treturn name == nullptr || name[0] == '\\0';\n}\n\nnamespace ipopt\n{\n#define B DYLIB_DECLARE\nAPILIST\n#undef B\n\nstatic DynamicLibrary lib;\nstatic bool is_loaded = false;\n\nbool is_library_loaded()\n{\n\treturn is_loaded;\n}\n\nbool load_library(const std::string &path)\n{\n\tbool success = lib.try_load(path.c_str());\n\tif (!success)\n\t{\n\t\treturn false;\n\t}\n\n\tDYLIB_LOAD_INIT;\n\n#define B DYLIB_LOAD_FUNCTION\n\tAPILIST\n#undef B\n\n\tif (IS_DYLIB_LOAD_SUCCESS)\n\t{\n#define B DYLIB_SAVE_FUNCTION\n\t\tAPILIST\n#undef B\n\t\tis_loaded = true;\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\treturn false;\n\t}\n}\n} // namespace ipopt\n\nIpoptModel::IpoptModel()\n{\n\tif (!ipopt::is_library_loaded())\n\t{\n\t\tthrow std::runtime_error(\"IPOPT library is not loaded\");\n\t}\n}\n\nvoid IpoptModel::close()\n{\n\tm_problem.reset();\n}\n\nVariableIndex IpoptModel::add_variable(double lb, double ub, double start, const char *name)\n{\n\tVariableIndex vi(n_variables);\n\tm_var_lb.push_back(lb);\n\tm_var_ub.push_back(ub);\n\tm_var_init.push_back(start);\n\tn_variables += 1;\n\n\tif (!is_name_empty(name))\n\t{\n\t\tm_var_names.emplace(vi.index, name);\n\t}\n\n\tm_is_dirty = true;\n\n\treturn vi;\n}\n\ndouble IpoptModel::get_variable_lb(const VariableIndex &variable)\n{\n\treturn m_var_lb[variable.index];\n}\n\ndouble IpoptModel::get_variable_ub(const VariableIndex &variable)\n{\n\treturn m_var_ub[variable.index];\n}\n\nvoid IpoptModel::set_variable_lb(const VariableIndex &variable, double lb)\n{\n\tm_var_lb[variable.index] = lb;\n}\n\nvoid IpoptModel::set_variable_ub(const VariableIndex &variable, double ub)\n{\n\tm_var_ub[variable.index] = ub;\n}\n\nvoid IpoptModel::set_variable_bounds(const VariableIndex &variable, double lb, double ub)\n{\n\tm_var_lb[variable.index] = lb;\n\tm_var_ub[variable.index] = ub;\n}\n\ndouble IpoptModel::get_variable_start(const VariableIndex &variable)\n{\n\treturn m_var_init[variable.index];\n}\n\nvoid IpoptModel::set_variable_start(const VariableIndex &variable, double start)\n{\n\tm_var_init[variable.index] = start;\n}\n\ndouble IpoptModel::get_variable_value(const VariableIndex &variable)\n{\n\tif (m_is_dirty)\n\t{\n\t\tthrow std::runtime_error(\n\t\t    \"Variable value is not available before optimization. Call optimize() first.\");\n\t}\n\treturn m_result.x[variable.index];\n}\n\nstd::string IpoptModel::get_variable_name(const VariableIndex &variable)\n{\n\tauto iter = m_var_names.find(variable.index);\n\tif (iter != m_var_names.end())\n\t{\n\t\treturn iter->second;\n\t}\n\telse\n\t{\n\t\treturn fmt::format(\"x{}\", variable.index);\n\t}\n}\n\nvoid IpoptModel::set_variable_name(const VariableIndex &variable, const std::string &name)\n{\n\tm_var_names[variable.index] = name;\n}\n\nstd::string IpoptModel::pprint_variable(const VariableIndex &variable)\n{\n\treturn get_variable_name(variable);\n}\n\ndouble IpoptModel::get_obj_value()\n{\n\tif (m_is_dirty)\n\t{\n\t\tthrow std::runtime_error(\n\t\t    \"Objective value is not available before optimization. Call optimize() first.\");\n\t}\n\treturn m_result.obj_val;\n}\n\nint IpoptModel::_constraint_internal_index(const ConstraintIndex &constraint)\n{\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\t\treturn constraint.index;\n\tcase ConstraintType::Quadratic:\n\t\treturn m_linear_con_evaluator.n_constraints + constraint.index;\n\tcase ConstraintType::NL: {\n\t\tauto base = m_linear_con_evaluator.n_constraints + m_quadratic_con_evaluator.n_constraints;\n\t\tauto internal_nl_index = nl_constraint_map_ext2int[constraint.index];\n\t\treturn base + internal_nl_index;\n\t}\n\tdefault:\n\t\tthrow std::runtime_error(\"Invalid constraint type\");\n\t}\n}\n\ndouble IpoptModel::get_constraint_primal(const ConstraintIndex &constraint)\n{\n\tif (m_is_dirty)\n\t{\n\t\tthrow std::runtime_error(\n\t\t    \"Constraint primal value is not available before optimization. Call optimize() first.\");\n\t}\n\tint index = _constraint_internal_index(constraint);\n\treturn m_result.g[index];\n}\n\ndouble IpoptModel::get_constraint_dual(const ConstraintIndex &constraint)\n{\n\tif (m_is_dirty)\n\t{\n\t\tthrow std::runtime_error(\n\t\t    \"Constraint dual value is not available before optimization. Call optimize() first.\");\n\t}\n\tint index = _constraint_internal_index(constraint);\n\tauto dual = -m_result.mult_g[index];\n\treturn dual;\n}\n\nConstraintIndex IpoptModel::add_linear_constraint(const ScalarAffineFunction &f,\n                                                  ConstraintSense sense, double rhs,\n                                                  const char *name)\n{\n\tdouble lb = -INFINITY;\n\tdouble ub = INFINITY;\n\tif (sense == ConstraintSense::LessEqual)\n\t{\n\t\tub = rhs;\n\t}\n\telse if (sense == ConstraintSense::GreaterEqual)\n\t{\n\t\tlb = rhs;\n\t}\n\telse if (sense == ConstraintSense::Equal)\n\t{\n\t\tlb = rhs;\n\t\tub = rhs;\n\t}\n\treturn add_linear_constraint(f, {lb, ub}, name);\n}\n\nConstraintIndex IpoptModel::add_linear_constraint(const ScalarAffineFunction &f,\n                                                  const std::tuple<double, double> &interval,\n                                                  const char *name)\n{\n\tConstraintIndex con(ConstraintType::Linear, m_linear_con_evaluator.n_constraints);\n\tm_linear_con_evaluator.add_row(f);\n\n\tauto lb = std::get<0>(interval);\n\tauto ub = std::get<1>(interval);\n\tm_linear_con_lb.push_back(lb);\n\tm_linear_con_ub.push_back(ub);\n\n\tm_is_dirty = true;\n\n\treturn con;\n}\n\nConstraintIndex IpoptModel::add_quadratic_constraint(const ScalarQuadraticFunction &f,\n                                                     ConstraintSense sense, double rhs,\n                                                     const char *name)\n{\n\tdouble lb = -INFINITY;\n\tdouble ub = INFINITY;\n\tif (sense == ConstraintSense::LessEqual)\n\t{\n\t\tub = rhs;\n\t}\n\telse if (sense == ConstraintSense::GreaterEqual)\n\t{\n\t\tlb = rhs;\n\t}\n\telse if (sense == ConstraintSense::Equal)\n\t{\n\t\tlb = rhs;\n\t\tub = rhs;\n\t}\n\telse\n\t{\n\t\tthrow std::runtime_error(\"'Within' constraint sense must have both LB and UB\");\n\t}\n\treturn add_quadratic_constraint(f, {lb, ub}, name);\n}\n\nConstraintIndex IpoptModel::add_quadratic_constraint(const ScalarQuadraticFunction &f,\n                                                     const std::tuple<double, double> &interval,\n                                                     const char *name)\n{\n\tConstraintIndex con(ConstraintType::Quadratic, m_quadratic_con_evaluator.n_constraints);\n\tm_quadratic_con_evaluator.add_row(f);\n\n\tauto lb = std::get<0>(interval);\n\tauto ub = std::get<1>(interval);\n\tm_quadratic_con_lb.push_back(lb);\n\tm_quadratic_con_ub.push_back(ub);\n\n\tm_is_dirty = true;\n\n\treturn con;\n}\n\nvoid IpoptModel::set_objective(const ScalarAffineFunction &expr, ObjectiveSense sense)\n{\n\t_set_linear_objective(expr);\n}\n\nvoid IpoptModel::set_objective(const ScalarQuadraticFunction &expr, ObjectiveSense sense)\n{\n\t_set_quadratic_objective(expr);\n}\n\nvoid IpoptModel::set_objective(const ExprBuilder &expr, ObjectiveSense sense)\n{\n\tauto degree = expr.degree();\n\tif (degree <= 1)\n\t{\n\t\t_set_linear_objective(expr);\n\t}\n\telse if (degree == 2)\n\t{\n\t\t_set_quadratic_objective(expr);\n\t}\n\telse\n\t{\n\t\tthrow std::runtime_error(\"Only linear and quadratic objective is supported\");\n\t}\n\n\tm_is_dirty = true;\n}\n\nvoid IpoptModel::_set_linear_objective(const ScalarAffineFunction &expr)\n{\n\tLinearEvaluator evaluator;\n\tevaluator.add_row(expr);\n\tm_linear_obj_evaluator = evaluator;\n\tm_quadratic_obj_evaluator.reset();\n}\n\nvoid IpoptModel::_set_quadratic_objective(const ScalarQuadraticFunction &expr)\n{\n\tQuadraticEvaluator evaluator;\n\tevaluator.add_row(expr);\n\tm_linear_obj_evaluator.reset();\n\tm_quadratic_obj_evaluator = evaluator;\n}\n\nint IpoptModel::add_graph_index()\n{\n\treturn m_nl_evaluator.add_graph_instance();\n}\n\nvoid IpoptModel::finalize_graph_instance(size_t graph_index, const ExpressionGraph &graph)\n{\n\tm_nl_evaluator.finalize_graph_instance(graph_index, graph);\n}\n\nint IpoptModel::aggregate_nl_constraint_groups()\n{\n\treturn m_nl_evaluator.aggregate_constraint_groups();\n}\n\nint IpoptModel::get_nl_constraint_group_representative(int group_index) const\n{\n\treturn m_nl_evaluator.get_constraint_group_representative(group_index);\n}\n\nint IpoptModel::aggregate_nl_objective_groups()\n{\n\treturn m_nl_evaluator.aggregate_objective_groups();\n}\n\nint IpoptModel::get_nl_objective_group_representative(int group_index) const\n{\n\treturn m_nl_evaluator.get_objective_group_representative(group_index);\n}\n\nvoid IpoptModel::assign_nl_constraint_group_autodiff_structure(\n    int group_index, const AutodiffSymbolicStructure &structure)\n{\n\tm_nl_evaluator.assign_constraint_group_autodiff_structure(group_index, structure);\n}\n\nvoid IpoptModel::assign_nl_constraint_group_autodiff_evaluator(\n    int group_index, const ConstraintAutodiffEvaluator &evaluator)\n{\n\tm_nl_evaluator.assign_constraint_group_autodiff_evaluator(group_index, evaluator);\n}\n\nvoid IpoptModel::assign_nl_objective_group_autodiff_structure(\n    int group_index, const AutodiffSymbolicStructure &structure)\n{\n\tm_nl_evaluator.assign_objective_group_autodiff_structure(group_index, structure);\n}\n\nvoid IpoptModel::assign_nl_objective_group_autodiff_evaluator(\n    int group_index, const ObjectiveAutodiffEvaluator &evaluator)\n{\n\tm_nl_evaluator.assign_objective_group_autodiff_evaluator(group_index, evaluator);\n}\n\nConstraintIndex IpoptModel::add_single_nl_constraint(size_t graph_index,\n                                                     const ExpressionGraph &graph, double lb,\n                                                     double ub)\n{\n\tm_nl_con_lb.push_back(lb);\n\tm_nl_con_ub.push_back(ub);\n\tauto constraint_index = n_nl_constraints;\n\tn_nl_constraints += 1;\n\n\tnl_constraint_graph_memberships.push_back(ConstraintGraphMembership{\n\t    .graph = (int)graph_index, .rank = (int)graph.m_constraint_outputs.size() - 1});\n\n\tm_is_dirty = true;\n\n\treturn ConstraintIndex(ConstraintType::NL, constraint_index);\n}\n\nstatic bool eval_f(ipindex n, ipnumber *x, bool new_x, ipnumber *obj_value, UserDataPtr user_data)\n{\n\tIpoptModel &model = *static_cast<IpoptModel *>(user_data);\n\t*obj_value = 0.0;\n\t// fmt::print(\"Before linear and quad objective, obj_value: {}\\n\", *obj_value);\n\tif (model.m_linear_obj_evaluator)\n\t{\n\t\tmodel.m_linear_obj_evaluator->eval_function(x, obj_value);\n\t}\n\telse if (model.m_quadratic_obj_evaluator)\n\t{\n\t\tmodel.m_quadratic_obj_evaluator->eval_function(x, obj_value);\n\t}\n\t// fmt::print(\"After linear and quad objective, obj_value: {}\\n\", *obj_value);\n\n\t// nonlinear part\n\tdouble nl_obj = model.m_nl_evaluator.eval_objective(x);\n\n\t*obj_value += nl_obj;\n\n\treturn true;\n}\n\nstatic bool eval_grad_f(ipindex n, ipnumber *x, bool new_x, ipnumber *grad_f, UserDataPtr user_data)\n{\n\tIpoptModel &model = *static_cast<IpoptModel *>(user_data);\n\tstd::fill(grad_f, grad_f + n, 0.0);\n\n\t// fmt::print(\"Enters eval_grad_f\\n\");\n\n\t// fill sparse_gradient_values\n\tauto &sparse_gradient_values = model.sparse_gradient_values;\n\tstd::fill(sparse_gradient_values.begin(), sparse_gradient_values.end(), 0.0);\n\n\t// analytical part\n\tif (model.m_linear_obj_evaluator)\n\t{\n\t\tmodel.m_linear_obj_evaluator->eval_jacobian(x, sparse_gradient_values.data());\n\t}\n\telse if (model.m_quadratic_obj_evaluator)\n\t{\n\t\tmodel.m_quadratic_obj_evaluator->eval_jacobian(x, sparse_gradient_values.data());\n\t}\n\n\t// nonlinear part\n\tmodel.m_nl_evaluator.eval_objective_gradient(x, sparse_gradient_values.data());\n\n\t// copy to grad_f\n\tfor (size_t i = 0; i < model.sparse_gradient_indices.size(); i++)\n\t{\n\t\tauto index = model.sparse_gradient_indices[i];\n\t\tauto value = sparse_gradient_values[i];\n\t\tgrad_f[index] += value;\n\t}\n\n\t// debug\n\t/*fmt::print(\"Current x: {}\\n\", std::vector<double>(x, x + n));\n\tfmt::print(\"Current gradient: {}\\n\", std::vector<double>(grad_f, grad_f + n));*/\n\n\treturn true;\n}\n\nstatic bool eval_g(ipindex n, ipnumber *x, bool new_x, ipindex m, ipnumber *g,\n                   UserDataPtr user_data)\n{\n\tIpoptModel &model = *static_cast<IpoptModel *>(user_data);\n\t// std::fill(g, g + m, 0.0);\n\n\t// fmt::print(\"Enters eval_g\\n\");\n\tauto original_g = g;\n\n\t// linear part\n\tmodel.m_linear_con_evaluator.eval_function(x, g);\n\n\t// quadratic part\n\tg += model.m_linear_con_evaluator.n_constraints;\n\tmodel.m_quadratic_con_evaluator.eval_function(x, g);\n\n\t// nonlinear part\n\tg += model.m_quadratic_con_evaluator.n_constraints;\n\tmodel.m_nl_evaluator.eval_constraints(x, g);\n\n\t// debug\n\t/*fmt::print(\"Current x: {}\\n\", std::vector<double>(x, x + n));\n\tfmt::print(\"Current g: {}\\n\", std::vector<double>(original_g, original_g + m));*/\n\n\treturn true;\n}\n\nstatic bool eval_jac_g(ipindex n, ipnumber *x, bool new_x, ipindex m, ipindex nele_jac,\n                       ipindex *iRow, ipindex *jCol, ipnumber *values, UserDataPtr user_data)\n{\n\tIpoptModel &model = *static_cast<IpoptModel *>(user_data);\n\n\t// fmt::print(\"Enters eval_jac_g\\n\");\n\n\tif (iRow != nullptr)\n\t{\n\t\tauto &rows = model.m_jacobian_rows;\n\t\tauto &cols = model.m_jacobian_cols;\n\t\tstd::copy(rows.begin(), rows.end(), iRow);\n\t\tstd::copy(cols.begin(), cols.end(), jCol);\n\t}\n\telse\n\t{\n\t\t// std::fill(values, values + nele_jac, 0.0);\n\t\tauto original_jacobian = values;\n\n\t\t// fmt::print(\"Initial jacobian: {}\\n\", std::vector<double>(values, values + nele_jac));\n\n\t\t// linear part\n\t\tmodel.m_linear_con_evaluator.eval_jacobian(x, values);\n\n\t\t// quadratic part\n\t\t/*fmt::print(\"jacobian forwards {} for linear part\\n\",\n\t\t           model.m_linear_con_evaluator.coefs.size());*/\n\t\tvalues += model.m_linear_con_evaluator.coefs.size();\n\t\tmodel.m_quadratic_con_evaluator.eval_jacobian(x, values);\n\n\t\t// nonlinear part\n\t\t/*fmt::print(\"jacobian forwards {} for quadratic part\\n\",\n\t\t           model.m_quadratic_con_evaluator.jacobian_nnz);*/\n\t\tvalues += model.m_quadratic_con_evaluator.jacobian_nnz;\n\t\tmodel.m_nl_evaluator.eval_constraints_jacobian(x, values);\n\n\t\t// debug\n\t\t/*fmt::print(\"Current x: {}\\n\", std::vector<double>(x, x + n));\n\t\tfmt::print(\"Current jacobian: {}\\n\",\n\t\t           std::vector<double>(original_jacobian, original_jacobian + nele_jac));*/\n\t}\n\treturn true;\n}\n\nstatic bool eval_h(ipindex n, ipnumber *x, bool new_x, ipnumber obj_factor, ipindex m,\n                   ipnumber *lambda, bool new_lambda, ipindex nele_hess, ipindex *iRow,\n                   ipindex *jCol, ipnumber *values, UserDataPtr user_data)\n{\n\tIpoptModel &model = *static_cast<IpoptModel *>(user_data);\n\n\t// fmt::print(\"Enters eval_h\\n\");\n\n\tif (iRow != nullptr)\n\t{\n\t\tauto &rows = model.m_hessian_rows;\n\t\tauto &cols = model.m_hessian_cols;\n\t\tstd::copy(rows.begin(), rows.end(), iRow);\n\t\tstd::copy(cols.begin(), cols.end(), jCol);\n\t}\n\telse\n\t{\n\t\tstd::fill(values, values + nele_hess, 0.0);\n\n\t\t// objective\n\n\t\t// quadratic part\n\t\tif (model.m_quadratic_obj_evaluator)\n\t\t{\n\t\t\tmodel.m_quadratic_obj_evaluator->eval_lagrangian_hessian(&obj_factor, values);\n\t\t}\n\n\t\t// constraint\n\n\t\t// quadratic part\n\t\tlambda += model.m_linear_con_evaluator.n_constraints;\n\t\tmodel.m_quadratic_con_evaluator.eval_lagrangian_hessian(lambda, values);\n\n\t\t// nonlinear part\n\t\tlambda += model.m_quadratic_con_evaluator.n_constraints;\n\t\tmodel.m_nl_evaluator.eval_lagrangian_hessian(x, lambda, obj_factor, values);\n\n\t\t// debug\n\t\t/*fmt::print(\"Current x: {}\\n\", std::vector<double>(x, x + n));\n\t\tfmt::print(\"Current obj_factor: {}\\n\", obj_factor);\n\t\tfmt::print(\"Current lambda: {}\\n\", std::vector<double>(lambda, lambda + m));\n\t\tfmt::print(\"Current hessian: {}\\n\", std::vector<double>(values, values + nele_hess));*/\n\t}\n\treturn true;\n}\n\nvoid IpoptModel::analyze_structure()\n{\n\t// init variables\n\tm_jacobian_nnz = 0;\n\tm_jacobian_rows.clear();\n\tm_jacobian_cols.clear();\n\tm_hessian_nnz = 0;\n\tm_hessian_rows.clear();\n\tm_hessian_cols.clear();\n\tm_hessian_index_map.clear();\n\n\t// constraints\n\n\t// analyze linear part\n\tm_linear_con_evaluator.analyze_jacobian_structure(m_jacobian_nnz, m_jacobian_rows,\n\t                                                  m_jacobian_cols);\n\n\t// analyze quadratic part\n\tm_quadratic_con_evaluator.analyze_jacobian_structure(\n\t    m_linear_con_evaluator.n_constraints, m_jacobian_nnz, m_jacobian_rows, m_jacobian_cols);\n\tm_quadratic_con_evaluator.analyze_hessian_structure(m_hessian_nnz, m_hessian_rows,\n\t                                                    m_hessian_cols, m_hessian_index_map,\n\t                                                    HessianSparsityType::Lower);\n\n\t// objective\n\tsparse_gradient_indices.clear();\n\tsparse_gradient_values.clear();\n\tHashmap<int, int> sparse_gradient_map;\n\n\t// linear and quadratic objective\n\tif (m_linear_obj_evaluator)\n\t{\n\t\tauto &evaluator = m_linear_obj_evaluator.value();\n\t\tsparse_gradient_indices.insert(sparse_gradient_indices.end(), evaluator.indices.begin(),\n\t\t                               evaluator.indices.end());\n\t}\n\telse if (m_quadratic_obj_evaluator)\n\t{\n\t\tauto &evaluator = m_quadratic_obj_evaluator.value();\n\t\tsparse_gradient_indices.insert(sparse_gradient_indices.end(),\n\t\t                               evaluator.jacobian_variable_indices.begin(),\n\t\t                               evaluator.jacobian_variable_indices.end());\n\t\tevaluator.analyze_hessian_structure(m_hessian_nnz, m_hessian_rows, m_hessian_cols,\n\t\t                                    m_hessian_index_map, HessianSparsityType::Lower);\n\t}\n\t// update map\n\tfor (int i = 0; i < sparse_gradient_indices.size(); i++)\n\t{\n\t\tauto index = sparse_gradient_indices[i];\n\t\tsparse_gradient_map.emplace(index, i);\n\t}\n\n\t// analyze nonlinear constraints and objectives\n\t{\n\t\tauto &evaluator = m_nl_evaluator;\n\n\t\tauto constraint_counter =\n\t\t    m_linear_con_evaluator.n_constraints + m_quadratic_con_evaluator.n_constraints;\n\t\tevaluator.analyze_constraints_jacobian_structure(constraint_counter, m_jacobian_nnz,\n\t\t                                                 m_jacobian_rows, m_jacobian_cols);\n\t\tevaluator.analyze_objective_gradient_structure(sparse_gradient_indices,\n\t\t                                               sparse_gradient_map);\n\t\tevaluator.analyze_constraints_hessian_structure(m_hessian_nnz, m_hessian_rows,\n\t\t                                                m_hessian_cols, m_hessian_index_map,\n\t\t                                                HessianSparsityType::Lower);\n\t\tevaluator.analyze_objective_hessian_structure(m_hessian_nnz, m_hessian_rows, m_hessian_cols,\n\t\t                                              m_hessian_index_map,\n\t\t                                              HessianSparsityType::Lower);\n\t}\n\n\tsparse_gradient_values.resize(sparse_gradient_indices.size());\n\n\t// update the mapping of nl constraint\n\tnl_constraint_map_ext2int.resize(n_nl_constraints);\n\tm_nl_evaluator.calculate_constraint_graph_instances_offset();\n\tfor (int i = 0; i < n_nl_constraints; i++)\n\t{\n\t\tauto i_nl_con = i;\n\t\tauto i_graph_instance = nl_constraint_graph_memberships[i].graph;\n\t\tauto i_graph_rank = nl_constraint_graph_memberships[i].rank;\n\n\t\tauto index_base = m_nl_evaluator.constraint_indices_offsets[i_graph_instance];\n\n\t\tnl_constraint_map_ext2int[i_nl_con] = index_base + i_graph_rank;\n\t}\n\n\t// construct the lower bound and upper bound of the constraints\n\tauto n_constraints = m_linear_con_evaluator.n_constraints +\n\t                     m_quadratic_con_evaluator.n_constraints + n_nl_constraints;\n\tm_con_lb.resize(n_constraints);\n\tm_con_ub.resize(n_constraints);\n\tstd::copy(m_linear_con_lb.begin(), m_linear_con_lb.end(), m_con_lb.begin());\n\tstd::copy(m_linear_con_ub.begin(), m_linear_con_ub.end(), m_con_ub.begin());\n\tstd::copy(m_quadratic_con_lb.begin(), m_quadratic_con_lb.end(),\n\t          m_con_lb.begin() + m_linear_con_evaluator.n_constraints);\n\tstd::copy(m_quadratic_con_ub.begin(), m_quadratic_con_ub.end(),\n\t          m_con_ub.begin() + m_linear_con_evaluator.n_constraints);\n\n\t// nonlinear parts need mapping\n\tauto nl_constraint_start =\n\t    m_linear_con_evaluator.n_constraints + m_quadratic_con_evaluator.n_constraints;\n\tfor (int i = 0; i < n_nl_constraints; i++)\n\t{\n\t\tauto index = nl_constraint_map_ext2int[i];\n\t\tm_con_lb[nl_constraint_start + index] = m_nl_con_lb[i];\n\t\tm_con_ub[nl_constraint_start + index] = m_nl_con_ub[i];\n\t}\n}\n\nvoid IpoptModel::optimize()\n{\n\tanalyze_structure();\n\n\tauto n_constraints = m_linear_con_evaluator.n_constraints +\n\t                     m_quadratic_con_evaluator.n_constraints + n_nl_constraints;\n\n\t/*fmt::print(\"Problem has {} variables and {} constraints.\\n\", n_variables, n_constraints);\n\tfmt::print(\"Variable LB: {}\\n\", m_var_lb);\n\tfmt::print(\"Variable UB: {}\\n\", m_var_ub);\n\tfmt::print(\"Constraint LB: {}\\n\", m_con_lb);\n\tfmt::print(\"Constraint UB: {}\\n\", m_con_ub);\n\tfmt::print(\"Jacobian has {} nonzeros\\n\", m_jacobian_nnz);\n\tfmt::print(\"Jacobian rows : {}\\n\", m_jacobian_rows);\n\tfmt::print(\"Jacobian cols : {}\\n\", m_jacobian_cols);\n\tfmt::print(\"Hessian has {} nonzeros\\n\", m_hessian_nnz);\n\tfmt::print(\"Hessian rows : {}\\n\", m_hessian_rows);\n\tfmt::print(\"Hessian cols : {}\\n\", m_hessian_cols);*/\n\n\t/*if (m_quadratic_obj_evaluator)\n\t{\n\t    auto &evaluator = m_quadratic_obj_evaluator.value();\n\t    fmt::print(\"Diag coefs : {}\\n\", evaluator.diag_coefs);\n\t    fmt::print(\"Diag indices : {}\\n\", evaluator.diag_indices);\n\t    fmt::print(\"Diag intervals : {}\\n\", evaluator.diag_intervals);\n\t    fmt::print(\"OffDiag coefs : {}\\n\", evaluator.offdiag_coefs);\n\t    fmt::print(\"OffDiag rows : {}\\n\", evaluator.offdiag_rows);\n\t    fmt::print(\"OffDiag cols : {}\\n\", evaluator.offdiag_cols);\n\t    fmt::print(\"OffDiag intervals : {}\\n\", evaluator.offdiag_intervals);\n\t    fmt::print(\"hessian_diag_indices : {}\\n\", evaluator.hessian_diag_indices);\n\t    fmt::print(\"hessian_offdiag_indices : {}\\n\", evaluator.hessian_offdiag_indices);\n\t}\n\n\t{\n\t    auto &evaluator = m_quadratic_con_evaluator;\n\t    fmt::print(\"Diag coefs : {}\\n\", evaluator.diag_coefs);\n\t    fmt::print(\"Diag indices : {}\\n\", evaluator.diag_indices);\n\t    fmt::print(\"Diag intervals : {}\\n\", evaluator.diag_intervals);\n\t    fmt::print(\"OffDiag coefs : {}\\n\", evaluator.offdiag_coefs);\n\t    fmt::print(\"OffDiag rows : {}\\n\", evaluator.offdiag_rows);\n\t    fmt::print(\"OffDiag cols : {}\\n\", evaluator.offdiag_cols);\n\t    fmt::print(\"OffDiag intervals : {}\\n\", evaluator.offdiag_intervals);\n\t    fmt::print(\"hessian_diag_indices : {}\\n\", evaluator.hessian_diag_indices);\n\t    fmt::print(\"hessian_offdiag_indices : {}\\n\", evaluator.hessian_offdiag_indices);\n\t}*/\n\n\tauto problem_ptr =\n\t    ipopt::CreateIpoptProblem(n_variables, m_var_lb.data(), m_var_ub.data(), n_constraints,\n\t                              m_con_lb.data(), m_con_ub.data(), m_jacobian_nnz, m_hessian_nnz,\n\t                              0, &eval_f, &eval_g, &eval_grad_f, &eval_jac_g, &eval_h);\n\n\tm_problem = std::unique_ptr<IpoptProblemInfo, IpoptfreeproblemT>(problem_ptr);\n\n\t// set options\n\tfor (auto &[key, value] : m_options_int)\n\t{\n\t\tbool ret = ipopt::AddIpoptIntOption(problem_ptr, (char *)key.c_str(), value);\n\t\tif (!ret)\n\t\t{\n\t\t\tfmt::print(\"Failed to set integer option {}\\n\", key);\n\t\t}\n\t}\n\tfor (auto &[key, value] : m_options_num)\n\t{\n\t\tbool ret = ipopt::AddIpoptNumOption(problem_ptr, (char *)key.c_str(), value);\n\t\tif (!ret)\n\t\t{\n\t\t\tfmt::print(\"Failed to set number option {}\\n\", key);\n\t\t}\n\t}\n\tfor (auto &[key, value] : m_options_str)\n\t{\n\t\tbool ret =\n\t\t    ipopt::AddIpoptStrOption(problem_ptr, (char *)key.c_str(), (char *)value.c_str());\n\t\tif (!ret)\n\t\t{\n\t\t\tfmt::print(\"Failed to set string option {}\\n\", key);\n\t\t}\n\t}\n\n\t// initialize the solution\n\tm_result.x.resize(n_variables);\n\tstd::copy(m_var_init.begin(), m_var_init.end(), m_result.x.begin());\n\tm_result.mult_x_L.resize(n_variables);\n\tm_result.mult_x_U.resize(n_variables);\n\tm_result.g.resize(n_constraints);\n\tm_result.mult_g.resize(n_constraints);\n\n\tm_status = ipopt::IpoptSolve(problem_ptr, m_result.x.data(), m_result.g.data(),\n\t                             &m_result.obj_val, m_result.mult_g.data(),\n\t                             m_result.mult_x_L.data(), m_result.mult_x_U.data(), (void *)this);\n\tm_result.is_valid = true;\n\tm_is_dirty = false;\n}\n\nvoid IpoptModel::load_current_solution()\n{\n\tif (!m_result.is_valid)\n\t{\n\t\tthrow std::runtime_error(\"No valid solution to load\");\n\t}\n\n\tstd::copy(m_result.x.begin(), m_result.x.end(), m_var_init.begin());\n}\n\nvoid IpoptModel::set_raw_option_int(const std::string &name, int value)\n{\n\tm_options_int[name] = value;\n}\n\nvoid IpoptModel::set_raw_option_double(const std::string &name, double value)\n{\n\tm_options_num[name] = value;\n}\n\nvoid IpoptModel::set_raw_option_string(const std::string &name, const std::string &value)\n{\n\tm_options_str[name] = value;\n}\n"
  },
  {
    "path": "lib/ipopt_model_ext.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include <nanobind/stl/vector.h>\n#include <nanobind/stl/string.h>\n#include <nanobind/stl/tuple.h>\n\nnamespace nb = nanobind;\n\n#include \"pyoptinterface/ipopt_model.hpp\"\n\nNB_MODULE(ipopt_model_ext, m)\n{\n\tm.import_(\"pyoptinterface._src.core_ext\");\n\tm.import_(\"pyoptinterface._src.nleval_ext\");\n\n\tm.def(\"is_library_loaded\", &ipopt::is_library_loaded);\n\tm.def(\"load_library\", &ipopt::load_library);\n\n\tnb::enum_<ApplicationReturnStatus>(m, \"ApplicationReturnStatus\")\n\t    .value(\"Solve_Succeeded\", ApplicationReturnStatus::Solve_Succeeded)\n\t    .value(\"Solved_To_Acceptable_Level\", ApplicationReturnStatus::Solved_To_Acceptable_Level)\n\t    .value(\"Infeasible_Problem_Detected\", ApplicationReturnStatus::Infeasible_Problem_Detected)\n\t    .value(\"Search_Direction_Becomes_Too_Small\",\n\t           ApplicationReturnStatus::Search_Direction_Becomes_Too_Small)\n\t    .value(\"Diverging_Iterates\", ApplicationReturnStatus::Diverging_Iterates)\n\t    .value(\"User_Requested_Stop\", ApplicationReturnStatus::User_Requested_Stop)\n\t    .value(\"Feasible_Point_Found\", ApplicationReturnStatus::Feasible_Point_Found)\n\t    .value(\"Maximum_Iterations_Exceeded\", ApplicationReturnStatus::Maximum_Iterations_Exceeded)\n\t    .value(\"Restoration_Failed\", ApplicationReturnStatus::Restoration_Failed)\n\t    .value(\"Error_In_Step_Computation\", ApplicationReturnStatus::Error_In_Step_Computation)\n\t    .value(\"Maximum_CpuTime_Exceeded\", ApplicationReturnStatus::Maximum_CpuTime_Exceeded)\n\t    .value(\"Maximum_WallTime_Exceeded\", ApplicationReturnStatus::Maximum_WallTime_Exceeded)\n\t    .value(\"Not_Enough_Degrees_Of_Freedom\",\n\t           ApplicationReturnStatus::Not_Enough_Degrees_Of_Freedom)\n\t    .value(\"Invalid_Problem_Definition\", ApplicationReturnStatus::Invalid_Problem_Definition)\n\t    .value(\"Invalid_Option\", ApplicationReturnStatus::Invalid_Option)\n\t    .value(\"Invalid_Number_Detected\", ApplicationReturnStatus::Invalid_Number_Detected)\n\t    .value(\"Unrecoverable_Exception\", ApplicationReturnStatus::Unrecoverable_Exception)\n\t    .value(\"NonIpopt_Exception_Thrown\", ApplicationReturnStatus::NonIpopt_Exception_Thrown)\n\t    .value(\"Insufficient_Memory\", ApplicationReturnStatus::Insufficient_Memory)\n\t    .value(\"Internal_Error\", ApplicationReturnStatus::Internal_Error);\n\n\tnb::class_<IpoptModel>(m, \"RawModel\")\n\t    .def(nb::init<>())\n\t    .def(\"close\", &IpoptModel::close)\n\t    .def_ro(\"m_status\", &IpoptModel::m_status)\n\t    .def_rw(\"m_is_dirty\", &IpoptModel::m_is_dirty)\n\t    .def(\"add_variable\", &IpoptModel::add_variable, nb::arg(\"lb\") = -INFINITY,\n\t         nb::arg(\"ub\") = INFINITY, nb::arg(\"start\") = 0.0, nb::arg(\"name\") = \"\")\n\t    .def(\"get_variable_lb\", &IpoptModel::get_variable_lb)\n\t    .def(\"get_variable_ub\", &IpoptModel::get_variable_ub)\n\t    .def(\"set_variable_lb\", &IpoptModel::set_variable_lb)\n\t    .def(\"set_variable_ub\", &IpoptModel::set_variable_ub)\n\t    .def(\"set_variable_bounds\", &IpoptModel::set_variable_bounds, nb::arg(\"variable\"),\n\t         nb::arg(\"lb\"), nb::arg(\"ub\"))\n\n\t    .def(\"get_variable_start\", &IpoptModel::get_variable_start)\n\t    .def(\"set_variable_start\", &IpoptModel::set_variable_start)\n\n\t    .def(\"get_variable_name\", &IpoptModel::get_variable_name)\n\t    .def(\"set_variable_name\", &IpoptModel::set_variable_name)\n\n\t    .def(\"get_value\", nb::overload_cast<const VariableIndex &>(&IpoptModel::get_variable_value))\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ScalarAffineFunction &>(&IpoptModel::get_expression_value))\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &>(&IpoptModel::get_expression_value))\n\t    .def(\"get_value\", nb::overload_cast<const ExprBuilder &>(&IpoptModel::get_expression_value))\n\n\t    .def(\"pprint\", &IpoptModel::pprint_variable)\n\t    .def(\"pprint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, int>(&IpoptModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\t    .def(\n\t        \"pprint\",\n\t        nb::overload_cast<const ScalarQuadraticFunction &, int>(&IpoptModel::pprint_expression),\n\t        nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\t    .def(\"pprint\", nb::overload_cast<const ExprBuilder &, int>(&IpoptModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\n\t    .def(\"get_obj_value\", &IpoptModel::get_obj_value)\n\t    .def(\"get_constraint_primal\", &IpoptModel::get_constraint_primal)\n\t    .def(\"get_constraint_dual\", &IpoptModel::get_constraint_dual)\n\n\t    .def(\"_add_linear_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ConstraintSense, CoeffT, const char *>(\n\t             &IpoptModel::add_linear_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, const std::tuple<double, double> &,\n\t                           const char *>(&IpoptModel::add_linear_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &IpoptModel::add_linear_constraint_from_var, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &IpoptModel::add_linear_interval_constraint_from_var,\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &IpoptModel::add_linear_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &IpoptModel::add_linear_interval_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\n\t    .def(\"_add_quadratic_constraint\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, ConstraintSense, CoeffT,\n\t                           const char *>(&IpoptModel::add_quadratic_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_quadratic_constraint\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, const std::tuple<double, double> &,\n\t                           const char *>(&IpoptModel::add_quadratic_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_quadratic_constraint\", &IpoptModel::add_quadratic_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_quadratic_constraint\", &IpoptModel::add_quadratic_interval_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\n\t    .def(\"set_objective\", &IpoptModel::set_objective_as_constant, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\", &IpoptModel::set_objective_as_variable, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ObjectiveSense>(\n\t             &IpoptModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, ObjectiveSense>(\n\t             &IpoptModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ExprBuilder &, ObjectiveSense>(&IpoptModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\n\t    // New API\n\t    .def(\"_add_graph_index\", &IpoptModel::add_graph_index)\n\t    .def(\"_finalize_graph_instance\", &IpoptModel::finalize_graph_instance)\n\t    .def(\"_aggregate_nl_constraint_groups\", &IpoptModel::aggregate_nl_constraint_groups)\n\t    .def(\"_get_nl_constraint_group_representative\",\n\t         &IpoptModel::get_nl_constraint_group_representative)\n\t    .def(\"_aggregate_nl_objective_groups\", &IpoptModel::aggregate_nl_objective_groups)\n\t    .def(\"_get_nl_objective_group_representative\",\n\t         &IpoptModel::get_nl_objective_group_representative)\n\t    .def(\"_assign_nl_constraint_group_autodiff_structure\",\n\t         &IpoptModel::assign_nl_constraint_group_autodiff_structure)\n\t    .def(\"_assign_nl_constraint_group_autodiff_evaluator\",\n\t         &IpoptModel::assign_nl_constraint_group_autodiff_evaluator)\n\t    .def(\"_assign_nl_objective_group_autodiff_structure\",\n\t         &IpoptModel::assign_nl_objective_group_autodiff_structure)\n\t    .def(\"_assign_nl_objective_group_autodiff_evaluator\",\n\t         &IpoptModel::assign_nl_objective_group_autodiff_evaluator)\n\n\t    .def(\"_add_single_nl_constraint\", &IpoptModel::add_single_nl_constraint)\n\n\t    .def(\"_optimize\", &IpoptModel::optimize, nb::call_guard<nb::gil_scoped_release>())\n\n\t    .def(\"load_current_solution\", &IpoptModel::load_current_solution)\n\n\t    .def(\"set_raw_option_int\", &IpoptModel::set_raw_option_int)\n\t    .def(\"set_raw_option_double\", &IpoptModel::set_raw_option_double)\n\t    .def(\"set_raw_option_string\", &IpoptModel::set_raw_option_string);\n}\n"
  },
  {
    "path": "lib/knitro_model.cpp",
    "content": "#include \"pyoptinterface/knitro_model.hpp\"\n#include \"pyoptinterface/solver_common.hpp\"\n\n#include \"fmt/core.h\"\n#include \"fmt/ranges.h\"\n#include <cassert>\n#include <cmath>\n#include <iostream>\n\nnamespace knitro\n{\n#define B DYLIB_DECLARE\nAPILIST\n#undef B\n\nstatic DynamicLibrary lib;\nstatic bool is_loaded = false;\n\nbool is_library_loaded()\n{\n\treturn is_loaded;\n}\n\nbool load_library(const std::string &path)\n{\n\tbool success = lib.try_load(path.c_str());\n\tif (!success)\n\t{\n\t\treturn false;\n\t}\n\n\tDYLIB_LOAD_INIT;\n\n#define B DYLIB_LOAD_FUNCTION\n\tAPILIST\n#undef B\n\n\tif (IS_DYLIB_LOAD_SUCCESS)\n\t{\n#define B DYLIB_SAVE_FUNCTION\n\t\tAPILIST\n#undef B\n\t\tis_loaded = true;\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\treturn false;\n\t}\n}\n\nbool has_valid_license()\n{\n\tif (!is_library_loaded())\n\t{\n\t\tthrow std::runtime_error(\"KNITRO library not loaded\");\n\t}\n\n\tLM_context *lm = nullptr;\n\tint error = KN_checkout_license(&lm);\n\tif (error == 0)\n\t{\n\t\tKN_release_license(&lm);\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\treturn false;\n\t}\n}\n} // namespace knitro\n\nvoid ensure_library_loaded()\n{\n\tif (!knitro::is_library_loaded())\n\t{\n\t\tthrow std::runtime_error(\"KNITRO library not loaded\");\n\t}\n}\n\nKNITROEnv::KNITROEnv(bool empty)\n{\n\tif (!empty)\n\t{\n\t\tstart();\n\t}\n}\n\nvoid KNITROEnv::start()\n{\n\tif (!empty())\n\t{\n\t\treturn;\n\t}\n\tensure_library_loaded();\n\tLM_context *lm = nullptr;\n\tint error = knitro::KN_checkout_license(&lm);\n\t_check_error(error);\n\tm_lm = std::shared_ptr<LM_context>(lm, KNITROFreeLicenseT());\n}\n\nbool KNITROEnv::empty() const\n{\n\treturn m_lm == nullptr;\n}\n\nstd::shared_ptr<LM_context> KNITROEnv::get_lm() const\n{\n\treturn m_lm;\n}\n\nvoid KNITROEnv::close()\n{\n\tm_lm.reset();\n}\n\nvoid KNITROEnv::_check_error(int code) const\n{\n\tknitro_throw(code);\n}\n\nKNITROModel::KNITROModel()\n{\n\tinit();\n}\n\nKNITROModel::KNITROModel(const KNITROEnv &env)\n{\n\tinit(env);\n}\n\nvoid KNITROModel::init()\n{\n\tm_lm.reset();\n\t_init();\n}\n\nvoid KNITROModel::init(const KNITROEnv &env)\n{\n\tif (env.empty())\n\t{\n\t\tthrow std::runtime_error(\"Empty environment provided. Call start()...\");\n\t}\n\tm_lm = env.get_lm();\n\t_init();\n}\n\nvoid KNITROModel::close()\n{\n\t_reset_state();\n\tm_lm.reset();\n}\n\nvoid KNITROModel::_check_error(int code) const\n{\n\tknitro_throw(code);\n}\n\n// Model information\ndouble KNITROModel::get_infinity() const\n{\n\treturn KN_INFINITY;\n}\n\nstd::string KNITROModel::get_solver_name() const\n{\n\treturn std::string(\"KNITRO\");\n}\n\nstd::string KNITROModel::get_release() const\n{\n\tconstexpr int buf_size = 20;\n\tchar release[buf_size];\n\tint error = knitro::KN_get_release(buf_size, release);\n\t_check_error(error);\n\treturn std::string(release);\n}\n\n// Variable functions\nVariableIndex KNITROModel::add_variable(VariableDomain domain, double lb, double ub,\n                                        const char *name)\n{\n\tKNINT indexVar;\n\tint error = knitro::KN_add_var(m_kc.get(), &indexVar);\n\t_check_error(error);\n\n\tVariableIndex variable(indexVar);\n\n\tint var_type = knitro_var_type(domain);\n\t_set_value<KNINT, int>(knitro::KN_set_var_type, indexVar, var_type);\n\n\tif (var_type == KN_VARTYPE_BINARY)\n\t{\n\t\tlb = (lb < 0.0) ? 0.0 : lb;\n\t\tub = (ub > 1.0) ? 1.0 : ub;\n\t}\n\n\t_set_value<KNINT, double>(knitro::KN_set_var_lobnd, indexVar, lb);\n\t_set_value<KNINT, double>(knitro::KN_set_var_upbnd, indexVar, ub);\n\n\tif (!is_name_empty(name))\n\t{\n\t\t_set_value<KNINT, const char *>(knitro::KN_set_var_name, indexVar, name);\n\t}\n\n\tm_n_vars++;\n\t_mark_dirty();\n\n\treturn variable;\n}\n\ndouble KNITROModel::get_variable_lb(const VariableIndex &variable) const\n{\n\tKNINT indexVar = _variable_index(variable);\n\treturn _get_value<KNINT, double>(knitro::KN_get_var_lobnd, indexVar);\n}\n\ndouble KNITROModel::get_variable_ub(const VariableIndex &variable) const\n{\n\tKNINT indexVar = _variable_index(variable);\n\treturn _get_value<KNINT, double>(knitro::KN_get_var_upbnd, indexVar);\n}\n\nvoid KNITROModel::set_variable_lb(const VariableIndex &variable, double lb)\n{\n\tKNINT indexVar = _variable_index(variable);\n\t_set_value<KNINT, double>(knitro::KN_set_var_lobnd, indexVar, lb);\n}\n\nvoid KNITROModel::set_variable_ub(const VariableIndex &variable, double ub)\n{\n\tKNINT indexVar = _variable_index(variable);\n\t_set_value<KNINT, double>(knitro::KN_set_var_upbnd, indexVar, ub);\n}\n\nvoid KNITROModel::set_variable_bounds(const VariableIndex &variable, double lb, double ub)\n{\n\tset_variable_lb(variable, lb);\n\tset_variable_ub(variable, ub);\n}\n\ndouble KNITROModel::get_variable_value(const VariableIndex &variable) const\n{\n\t_check_dirty();\n\tKNINT indexVar = _variable_index(variable);\n\treturn _get_value<KNINT, double>(knitro::KN_get_var_primal_value, indexVar);\n}\n\nvoid KNITROModel::set_variable_start(const VariableIndex &variable, double start)\n{\n\tKNINT indexVar = _variable_index(variable);\n\t_set_value<KNINT, double>(knitro::KN_set_var_primal_init_value, indexVar, start);\n}\n\nstd::string KNITROModel::get_variable_name(const VariableIndex &variable) const\n{\n\tKNINT indexVar = _variable_index(variable);\n\treturn _get_name(knitro::KN_get_var_name, indexVar, \"x\");\n}\n\nvoid KNITROModel::set_variable_name(const VariableIndex &variable, const std::string &name)\n{\n\tKNINT indexVar = _variable_index(variable);\n\t_set_value<KNINT, const char *>(knitro::KN_set_var_name, indexVar, name.c_str());\n}\n\nvoid KNITROModel::set_variable_domain(const VariableIndex &variable, VariableDomain domain)\n{\n\tKNINT indexVar = _variable_index(variable);\n\tint var_type = knitro_var_type(domain);\n\tdouble lb = -get_infinity();\n\tdouble ub = get_infinity();\n\n\tif (var_type == KN_VARTYPE_BINARY)\n\t{\n\t\tlb = _get_value<KNINT, double>(knitro::KN_get_var_lobnd, indexVar);\n\t\tub = _get_value<KNINT, double>(knitro::KN_get_var_upbnd, indexVar);\n\t}\n\n\t_set_value<KNINT, int>(knitro::KN_set_var_type, indexVar, var_type);\n\n\tif (var_type == KN_VARTYPE_BINARY)\n\t{\n\t\tlb = (lb < 0.0) ? 0.0 : lb;\n\t\tub = (ub > 1.0) ? 1.0 : ub;\n\t\t_set_value<KNINT, double>(knitro::KN_set_var_lobnd, indexVar, lb);\n\t\t_set_value<KNINT, double>(knitro::KN_set_var_upbnd, indexVar, ub);\n\t}\n\n\t_mark_dirty();\n}\n\nVariableDomain KNITROModel::get_variable_domain(const VariableIndex &variable) const\n{\n\tKNINT indexVar = _variable_index(variable);\n\tint var_type = _get_value<KNINT, int>(knitro::KN_get_var_type, indexVar);\n\treturn knitro_variable_domain(var_type);\n}\n\ndouble KNITROModel::get_variable_rc(const VariableIndex &variable) const\n{\n\t_check_dirty();\n\tKNINT indexVar = _variable_index(variable);\n\tdouble dual = _get_value<KNINT, double>(knitro::KN_get_var_dual_value, indexVar);\n\treturn -dual;\n}\n\nvoid KNITROModel::delete_variable(const VariableIndex &variable)\n{\n\tKNINT indexVar = _variable_index(variable);\n\t_set_value<KNINT, int>(knitro::KN_set_var_type, indexVar, KN_VARTYPE_CONTINUOUS);\n\t_set_value<KNINT, double>(knitro::KN_set_var_lobnd, indexVar, -get_infinity());\n\t_set_value<KNINT, double>(knitro::KN_set_var_upbnd, indexVar, get_infinity());\n\tm_n_vars--;\n\t_mark_dirty();\n}\n\nstd::string KNITROModel::pprint_variable(const VariableIndex &variable) const\n{\n\treturn get_variable_name(variable);\n}\n\n// Constraint functions\nConstraintIndex KNITROModel::add_linear_constraint(const ScalarAffineFunction &function,\n                                                   ConstraintSense sense, double rhs,\n                                                   const char *name)\n{\n\tauto add = [this](const ScalarAffineFunction &f, const std::tuple<double, double> &interval,\n\t                  const char *n) { return add_linear_constraint(f, interval, n); };\n\treturn _add_constraint_with_sense(function, sense, rhs, name, add);\n}\n\nConstraintIndex KNITROModel::add_linear_constraint(const ScalarAffineFunction &function,\n                                                   const std::tuple<double, double> &interval,\n                                                   const char *name)\n{\n\tauto setter = [this, &function](const ConstraintIndex &constraint) {\n\t\t_set_linear_constraint(constraint, function);\n\t};\n\treturn _add_constraint_impl(ConstraintType::Linear, interval, name, setter);\n}\n\nConstraintIndex KNITROModel::add_quadratic_constraint(const ScalarQuadraticFunction &function,\n                                                      ConstraintSense sense, double rhs,\n                                                      const char *name)\n{\n\tauto add = [this](const ScalarQuadraticFunction &f, const std::tuple<double, double> &interval,\n\t                  const char *n) { return add_quadratic_constraint(f, interval, n); };\n\treturn _add_constraint_with_sense(function, sense, rhs, name, add);\n}\n\nConstraintIndex KNITROModel::add_quadratic_constraint(const ScalarQuadraticFunction &function,\n                                                      const std::tuple<double, double> &interval,\n                                                      const char *name)\n{\n\tauto setter = [this, &function](const ConstraintIndex &constraint) {\n\t\t_set_quadratic_constraint(constraint, function);\n\t};\n\treturn _add_constraint_impl(ConstraintType::Quadratic, interval, name, setter);\n}\n\nConstraintIndex KNITROModel::add_second_order_cone_constraint(\n    const Vector<VariableIndex> &variables, const char *name, bool rotated)\n{\n\n\tif (rotated)\n\t{\n\t\tauto setter = [this, &variables](const ConstraintIndex &constraint) {\n\t\t\t_set_second_order_cone_constraint_rotated(constraint, variables);\n\t\t};\n\t\tstd::pair<double, double> interval = {0.0, get_infinity()};\n\t\treturn _add_constraint_impl(ConstraintType::SecondOrderCone, interval, name, setter);\n\t}\n\telse\n\t{\n\t\tauto setter = [this, &variables](const ConstraintIndex &constraint) {\n\t\t\t_set_second_order_cone_constraint(constraint, variables);\n\t\t};\n\t\tstd::pair<double, double> interval = {0.0, get_infinity()};\n\t\treturn _add_constraint_impl(ConstraintType::SecondOrderCone, interval, name, setter);\n\t}\n}\n\nConstraintIndex KNITROModel::add_single_nl_constraint(ExpressionGraph &graph,\n                                                      const ExpressionHandle &result,\n                                                      const std::tuple<double, double> &interval,\n                                                      const char *name)\n{\n\t_add_graph(graph);\n\tgraph.add_constraint_output(result);\n\tsize_t i = graph.m_constraint_outputs.size() - 1;\n\tm_pending_outputs[&graph].constraint_outputs.push_back(i);\n\tauto setter = [this, &graph](const ConstraintIndex &constraint) {\n\t\tm_pending_outputs[&graph].constraints.push_back(constraint);\n\t\tm_has_pending_callbacks = true;\n\t};\n\treturn _add_constraint_impl(ConstraintType::NL, interval, name, setter);\n}\n\nConstraintIndex KNITROModel::add_single_nl_constraint_sense_rhs(ExpressionGraph &graph,\n                                                                const ExpressionHandle &result,\n                                                                ConstraintSense sense, double rhs,\n                                                                const char *name)\n{\n\tauto add = [this, &graph, &result](void *, const std::tuple<double, double> &interval,\n\t                                   const char *n) {\n\t\treturn add_single_nl_constraint(graph, result, interval, n);\n\t};\n\treturn _add_constraint_with_sense(nullptr, sense, rhs, name, add);\n}\n\nstd::tuple<double, double> KNITROModel::_sense_to_interval(ConstraintSense sense, double rhs)\n{\n\tswitch (sense)\n\t{\n\tcase ConstraintSense::LessEqual:\n\t\treturn {-get_infinity(), rhs};\n\tcase ConstraintSense::Equal:\n\t\treturn {rhs, rhs};\n\tcase ConstraintSense::GreaterEqual:\n\t\treturn {rhs, get_infinity()};\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint sense\");\n\t}\n}\n\nvoid KNITROModel::_update_con_sense_flags(const ConstraintIndex &constraint, ConstraintSense sense)\n{\n\tKNINT indexCon = _constraint_index(constraint);\n\tswitch (sense)\n\t{\n\tcase ConstraintSense::Equal:\n\t\tm_con_sense_flags[indexCon] |= CON_LOBND;\n\t\tbreak;\n\tcase ConstraintSense::GreaterEqual:\n\t\tm_con_sense_flags[indexCon] = CON_LOBND;\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nvoid KNITROModel::_set_second_order_cone_constraint(const ConstraintIndex &constraint,\n                                                    const Vector<VariableIndex> &variables)\n{\n\tKNINT indexCon = _constraint_index(constraint);\n\n\tKNINT indexCon0;\n\tint error = knitro::KN_add_con(m_kc.get(), &indexCon0);\n\t_check_error(error);\n\n\tKNINT indexVar0 = _variable_index(variables[0]);\n\terror = knitro::KN_add_con_linear_term(m_kc.get(), indexCon0, indexVar0, 1.0);\n\t_check_error(error);\n\n\t_set_value<KNINT, double>(knitro::KN_set_con_lobnd, indexCon0, 0.0);\n\t_set_value<KNINT, double>(knitro::KN_set_con_upbnd, indexCon0, KN_INFINITY);\n\n\terror = knitro::KN_add_con_quadratic_term(m_kc.get(), indexCon, indexVar0, indexVar0, 1.0);\n\t_check_error(error);\n\tsize_t nnz = variables.size() - 1;\n\tstd::vector<KNINT> indexCons(nnz, indexCon);\n\tstd::vector<KNINT> indexVars(nnz);\n\tfor (size_t i = 0; i < nnz; ++i)\n\t{\n\t\tindexVars[i] = _variable_index(variables[i + 1]);\n\t}\n\tstd::vector<double> coefs(nnz, -1.0);\n\terror = knitro::KN_add_con_quadratic_struct(m_kc.get(), nnz, indexCons.data(), indexVars.data(),\n\t                                            indexVars.data(), coefs.data());\n\t_check_error(error);\n\n\tm_soc_aux_cons[indexCon] = indexCon0;\n}\n\nvoid KNITROModel::_set_second_order_cone_constraint_rotated(const ConstraintIndex &constraint,\n                                                            const Vector<VariableIndex> &variables)\n{\n\tKNINT indexCon = _constraint_index(constraint);\n\n\tKNINT indexCon0, indexCon1;\n\tint error = knitro::KN_add_con(m_kc.get(), &indexCon0);\n\t_check_error(error);\n\terror = knitro::KN_add_con(m_kc.get(), &indexCon1);\n\t_check_error(error);\n\n\tKNINT indexVar0 = _variable_index(variables[0]);\n\tKNINT indexVar1 = _variable_index(variables[1]);\n\terror = knitro::KN_add_con_linear_term(m_kc.get(), indexCon0, indexVar0, 1.0);\n\t_check_error(error);\n\terror = knitro::KN_add_con_linear_term(m_kc.get(), indexCon1, indexVar1, 1.0);\n\t_check_error(error);\n\n\t_set_value<KNINT, double>(knitro::KN_set_con_lobnd, indexCon0, 0.0);\n\t_set_value<KNINT, double>(knitro::KN_set_con_upbnd, indexCon0, KN_INFINITY);\n\t_set_value<KNINT, double>(knitro::KN_set_con_lobnd, indexCon1, 0.0);\n\t_set_value<KNINT, double>(knitro::KN_set_con_upbnd, indexCon1, KN_INFINITY);\n\n\tsize_t nnz = variables.size() - 2;\n\tstd::vector<KNINT> indexCons(nnz, indexCon);\n\tstd::vector<KNINT> indexVars(nnz);\n\tfor (size_t i = 0; i < nnz; ++i)\n\t{\n\t\tindexVars[i] = _variable_index(variables[i + 2]);\n\t}\n\tstd::vector<double> coefs(nnz, -1.0);\n\terror = knitro::KN_add_con_quadratic_struct(m_kc.get(), nnz, indexCons.data(), indexVars.data(),\n\t                                            indexVars.data(), coefs.data());\n\t_check_error(error);\n\terror = knitro::KN_add_con_quadratic_term(m_kc.get(), indexCon, indexVar0, indexVar1, 2.0);\n\t_check_error(error);\n\n\tm_soc_aux_cons[indexCon] = std::make_pair(indexCon0, indexCon1);\n}\n\nvoid KNITROModel::delete_constraint(const ConstraintIndex &constraint)\n{\n\tKNINT indexCon = _constraint_index(constraint);\n\t_set_value<KNINT, double>(knitro::KN_set_con_lobnd, indexCon, -get_infinity());\n\t_set_value<KNINT, double>(knitro::KN_set_con_upbnd, indexCon, get_infinity());\n\n\tm_n_cons_map[constraint.type]--;\n\n\tauto it = m_soc_aux_cons.find(indexCon);\n\tif (it != m_soc_aux_cons.end())\n\t{\n\t\tstd::vector<KNINT> aux_cons;\n\t\tif (std::holds_alternative<KNINT>(it->second))\n\t\t{\n\t\t\taux_cons.push_back(std::get<KNINT>(it->second));\n\t\t}\n\t\telse if (std::holds_alternative<std::pair<KNINT, KNINT>>(it->second))\n\t\t{\n\t\t\tauto p = std::get<std::pair<KNINT, KNINT>>(it->second);\n\t\t\taux_cons.push_back(p.first);\n\t\t\taux_cons.push_back(p.second);\n\t\t}\n\n\t\tfor (auto const &con : aux_cons)\n\t\t{\n\t\t\t_set_value<KNINT, double>(knitro::KN_set_con_lobnd, con, -get_infinity());\n\t\t\t_set_value<KNINT, double>(knitro::KN_set_con_upbnd, con, get_infinity());\n\t\t}\n\n\t\tm_soc_aux_cons.erase(it);\n\t}\n\n\t_mark_dirty();\n}\n\nvoid KNITROModel::set_constraint_name(const ConstraintIndex &constraint, const std::string &name)\n{\n\tKNINT indexCon = _constraint_index(constraint);\n\t_set_value<KNINT, const char *>(knitro::KN_set_con_name, indexCon, name.c_str());\n}\n\nstd::string KNITROModel::get_constraint_name(const ConstraintIndex &constraint) const\n{\n\tKNINT indexCon = _constraint_index(constraint);\n\treturn _get_name(knitro::KN_get_con_name, indexCon, \"c\");\n}\n\ndouble KNITROModel::get_constraint_primal(const ConstraintIndex &constraint) const\n{\n\t_check_dirty();\n\tKNINT indexCon = _constraint_index(constraint);\n\treturn _get_value<KNINT, double>(knitro::KN_get_con_value, indexCon);\n}\n\ndouble KNITROModel::get_constraint_dual(const ConstraintIndex &constraint) const\n{\n\t_check_dirty();\n\tKNINT indexCon = _constraint_index(constraint);\n\tdouble dual = _get_value<KNINT, double>(knitro::KN_get_con_dual_value, indexCon);\n\treturn -dual;\n}\n\nvoid KNITROModel::set_normalized_rhs(const ConstraintIndex &constraint, double rhs)\n{\n\tKNINT indexCon = _constraint_index(constraint);\n\tauto flag = m_con_sense_flags[indexCon];\n\n\tif (flag & CON_LOBND)\n\t{\n\t\t_set_value<KNINT, double>(knitro::KN_set_con_lobnd, indexCon, rhs);\n\t}\n\n\tif (flag & CON_UPBND)\n\t{\n\t\t_set_value<KNINT, double>(knitro::KN_set_con_upbnd, indexCon, rhs);\n\t}\n\n\t_mark_dirty();\n}\n\ndouble KNITROModel::get_normalized_rhs(const ConstraintIndex &constraint) const\n{\n\tKNINT indexCon = _constraint_index(constraint);\n\tauto it = m_con_sense_flags.find(indexCon);\n\tuint8_t flag = (it != m_con_sense_flags.end()) ? it->second : CON_UPBND;\n\tdouble rhs;\n\tif (flag & CON_UPBND)\n\t{\n\t\trhs = _get_value<KNINT, double>(knitro::KN_get_con_upbnd, indexCon);\n\t}\n\telse\n\t{\n\t\trhs = _get_value<KNINT, double>(knitro::KN_get_con_lobnd, indexCon);\n\t}\n\treturn rhs;\n}\n\nvoid KNITROModel::set_normalized_coefficient(const ConstraintIndex &constraint,\n                                             const VariableIndex &variable, double coefficient)\n{\n\tKNINT indexCon = _constraint_index(constraint);\n\tKNINT indexVar = _variable_index(variable);\n\n\t// NOTE: To make sure the coefficient is updated correctly,\n\t// we need to call KN_update before changing the linear term\n\t_update();\n\tint error = knitro::KN_chg_con_linear_term(m_kc.get(), indexCon, indexVar, coefficient);\n\t_check_error(error);\n\t_mark_dirty();\n}\n\nvoid KNITROModel::_set_linear_constraint(const ConstraintIndex &constraint,\n                                         const ScalarAffineFunction &function)\n{\n\tKNINT indexCon = _constraint_index(constraint);\n\n\tif (function.constant.has_value())\n\t{\n\t\tdouble constant = function.constant.value();\n\t\tif (constant != 0.0)\n\t\t{\n\t\t\tint error = knitro::KN_add_con_constant(m_kc.get(), indexCon, constant);\n\t\t\t_check_error(error);\n\t\t}\n\t}\n\n\tAffineFunctionPtrForm<KNLONG, KNINT, double> ptr_form;\n\tptr_form.make(this, function);\n\n\tKNLONG nnz = ptr_form.numnz;\n\tif (nnz > 0)\n\t{\n\t\tstd::vector<KNINT> indexCons(nnz, indexCon);\n\t\tKNINT *indexVars = ptr_form.index;\n\t\tdouble *coefs = ptr_form.value;\n\n\t\tint error =\n\t\t    knitro::KN_add_con_linear_struct(m_kc.get(), nnz, indexCons.data(), indexVars, coefs);\n\t\t_check_error(error);\n\t}\n}\n\nvoid KNITROModel::_set_quadratic_constraint(const ConstraintIndex &constraint,\n                                            const ScalarQuadraticFunction &function)\n{\n\tKNINT indexCon = _constraint_index(constraint);\n\n\tif (function.affine_part.has_value())\n\t{\n\t\t_set_linear_constraint(constraint, function.affine_part.value());\n\t}\n\n\tQuadraticFunctionPtrForm<KNLONG, KNINT, double> ptr_form;\n\tptr_form.make(this, function);\n\tKNLONG nnz = ptr_form.numnz;\n\tif (nnz > 0)\n\t{\n\t\tstd::vector<KNINT> indexCons(nnz, indexCon);\n\t\tKNINT *indexVars1 = ptr_form.row;\n\t\tKNINT *indexVars2 = ptr_form.col;\n\t\tdouble *coefs = ptr_form.value;\n\t\tint error = knitro::KN_add_con_quadratic_struct(m_kc.get(), nnz, indexCons.data(),\n\t\t                                                indexVars1, indexVars2, coefs);\n\t\t_check_error(error);\n\t}\n}\n\n// Objective functions\nvoid KNITROModel::set_objective(const ScalarAffineFunction &function, ObjectiveSense sense)\n{\n\t_set_objective_impl(sense, [this, &function]() { _set_linear_objective(function); });\n}\n\nvoid KNITROModel::set_objective(const ScalarQuadraticFunction &function, ObjectiveSense sense)\n{\n\t_set_objective_impl(sense, [this, &function]() { _set_quadratic_objective(function); });\n}\n\nvoid KNITROModel::set_objective(const ExprBuilder &expr, ObjectiveSense sense)\n{\n\tauto degree = expr.degree();\n\tif (degree <= 1)\n\t{\n\t\tScalarAffineFunction linear(expr);\n\t\tset_objective(linear, sense);\n\t}\n\telse if (degree == 2)\n\t{\n\t\tScalarQuadraticFunction quadratic(expr);\n\t\tset_objective(quadratic, sense);\n\t}\n\telse\n\t{\n\t\tthrow std::runtime_error(\"Objective must be linear or quadratic\");\n\t}\n}\n\nvoid KNITROModel::set_objective_coefficient(const VariableIndex &variable, double coefficient)\n{\n\tKNINT indexVar = _variable_index(variable);\n\t// NOTE: To make sure the coefficient is updated correctly,\n\t// we need to call KN_update before changing the linear term\n\t_update();\n\tint error = knitro::KN_chg_obj_linear_term(m_kc.get(), indexVar, coefficient);\n\t_check_error(error);\n\t_mark_dirty();\n}\n\nvoid KNITROModel::add_single_nl_objective(ExpressionGraph &graph, const ExpressionHandle &result)\n{\n\t_add_graph(graph);\n\tgraph.add_objective_output(result);\n\tsize_t i = graph.m_objective_outputs.size() - 1;\n\tm_pending_outputs[&graph].objective_outputs.push_back(i);\n\tm_has_pending_callbacks = true;\n\tm_obj_flag |= OBJ_NONLINEAR;\n\t_mark_dirty();\n}\n\nvoid KNITROModel::set_obj_sense(ObjectiveSense sense)\n{\n\tint goal = knitro_obj_goal(sense);\n\t_set_value<int>(knitro::KN_set_obj_goal, goal);\n}\n\nObjectiveSense KNITROModel::get_obj_sense() const\n{\n\tint goal = _get_value<int>(knitro::KN_get_obj_goal);\n\treturn knitro_obj_sense(goal);\n}\n\nvoid KNITROModel::_add_graph(ExpressionGraph &graph)\n{\n\tif (m_pending_outputs.find(&graph) == m_pending_outputs.end())\n\t{\n\t\tm_pending_outputs[&graph] = Outputs();\n\t}\n}\n\nvoid KNITROModel::_reset_objective()\n{\n\tif (m_obj_flag & OBJ_CONSTANT)\n\t{\n\t\tint error = knitro::KN_del_obj_constant(m_kc.get());\n\t\t_check_error(error);\n\t}\n\tif (m_obj_flag & OBJ_LINEAR)\n\t{\n\t\tint error = knitro::KN_del_obj_linear_struct_all(m_kc.get());\n\t\t_check_error(error);\n\t}\n\tif (m_obj_flag & OBJ_QUADRATIC)\n\t{\n\t\tint error = knitro::KN_del_obj_quadratic_struct_all(m_kc.get());\n\t\t_check_error(error);\n\t}\n\tif (m_obj_flag & OBJ_NONLINEAR)\n\t{\n\t\tint error = knitro::KN_del_obj_eval_callback_all(m_kc.get());\n\t\t_check_error(error);\n\t\tfor (auto &[graph, outputs] : m_pending_outputs)\n\t\t{\n\t\t\toutputs.objective_outputs.clear();\n\t\t}\n\t}\n\tm_obj_flag = 0;\n\t_update();\n}\n\nvoid KNITROModel::_set_linear_objective(const ScalarAffineFunction &function)\n{\n\tif (function.constant.has_value())\n\t{\n\t\tdouble constant = function.constant.value();\n\t\tif (constant != 0.0)\n\t\t{\n\t\t\tint error = knitro::KN_add_obj_constant(m_kc.get(), constant);\n\t\t\t_check_error(error);\n\t\t\tm_obj_flag |= OBJ_CONSTANT;\n\t\t}\n\t}\n\n\tAffineFunctionPtrForm<KNLONG, KNINT, double> ptr_form;\n\tptr_form.make(this, function);\n\tKNLONG nnz = ptr_form.numnz;\n\tif (nnz > 0)\n\t{\n\t\tKNINT *indexVars = ptr_form.index;\n\t\tdouble *coefs = ptr_form.value;\n\t\tint error = knitro::KN_add_obj_linear_struct(m_kc.get(), nnz, indexVars, coefs);\n\t\t_check_error(error);\n\t\tm_obj_flag |= OBJ_LINEAR;\n\t}\n}\n\nvoid KNITROModel::_set_quadratic_objective(const ScalarQuadraticFunction &function)\n{\n\tif (function.affine_part.has_value())\n\t{\n\t\t_set_linear_objective(function.affine_part.value());\n\t}\n\n\tQuadraticFunctionPtrForm<KNLONG, KNINT, double> ptr_form;\n\tptr_form.make(this, function);\n\tKNLONG nnz = ptr_form.numnz;\n\tif (nnz > 0)\n\t{\n\t\tKNINT *indexVars1 = ptr_form.row;\n\t\tKNINT *indexVars2 = ptr_form.col;\n\t\tdouble *coefs = ptr_form.value;\n\t\tint error =\n\t\t    knitro::KN_add_obj_quadratic_struct(m_kc.get(), nnz, indexVars1, indexVars2, coefs);\n\t\t_check_error(error);\n\t\tm_obj_flag |= OBJ_QUADRATIC;\n\t}\n}\n\ndouble KNITROModel::get_obj_value() const\n{\n\t_check_dirty();\n\treturn _get_value<double>(knitro::KN_get_obj_value);\n}\n\nvoid KNITROModel::_register_callback(Evaluator *evaluator)\n{\n\tauto f = [](KN_context *, CB_context *cb, KN_eval_request *req, KN_eval_result *res,\n\t            void *data) -> int {\n\t\tauto evaluator = static_cast<Evaluator *>(data);\n\t\tif (evaluator->is_objective())\n\t\t{\n\t\t\tevaluator->eval_fun(req->x, res->obj);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tevaluator->eval_fun(req->x, res->c);\n\t\t}\n\t\treturn 0;\n\t};\n\n\tauto g = [](KN_context *, CB_context *cb, KN_eval_request *req, KN_eval_result *res,\n\t            void *data) -> int {\n\t\tauto evaluator = static_cast<Evaluator *>(data);\n\t\tif (evaluator->is_objective())\n\t\t{\n\t\t\tevaluator->eval_jac(req->x, res->objGrad);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tevaluator->eval_jac(req->x, res->jac);\n\t\t}\n\t\treturn 0;\n\t};\n\n\tauto h = [](KN_context *, CB_context *cb, KN_eval_request *req, KN_eval_result *res,\n\t            void *data) -> int {\n\t\tauto evaluator = static_cast<Evaluator *>(data);\n\t\tif (evaluator->is_objective())\n\t\t{\n\t\t\tevaluator->eval_hess(req->x, req->sigma, res->hess);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tevaluator->eval_hess(req->x, req->lambda, res->hess);\n\t\t}\n\t\treturn 0;\n\t};\n\n\tCB_context *cb = nullptr;\n\tauto p = evaluator->get_callback_pattern();\n\tint error;\n\terror = knitro::KN_add_eval_callback(m_kc.get(), p.indexCons.empty(), p.indexCons.size(),\n\t                                     p.indexCons.data(), f, &cb);\n\t_check_error(error);\n\terror = knitro::KN_set_cb_user_params(m_kc.get(), cb, evaluator);\n\t_check_error(error);\n\terror = knitro::KN_set_cb_grad(m_kc.get(), cb, p.objGradIndexVars.size(),\n\t                               p.objGradIndexVars.data(), p.jacIndexCons.size(),\n\t                               p.jacIndexCons.data(), p.jacIndexVars.data(), g);\n\t_check_error(error);\n\terror = knitro::KN_set_cb_hess(m_kc.get(), cb, p.hessIndexVars1.size(), p.hessIndexVars1.data(),\n\t                               p.hessIndexVars2.data(), h);\n\t_check_error(error);\n}\n\nvoid KNITROModel::_add_callback(const ExpressionGraph &graph, const std::vector<size_t> &outputs,\n                                const std::vector<ConstraintIndex> &constraints)\n{\n\tauto evaluator_ptr = std::make_unique<Evaluator>();\n\tauto *evaluator = evaluator_ptr.get();\n\tevaluator->indexVars.resize(graph.n_variables());\n\tfor (size_t i = 0; i < graph.n_variables(); i++)\n\t{\n\t\tevaluator->indexVars[i] = _variable_index(graph.m_variables[i]);\n\t}\n\tevaluator->indexCons.resize(constraints.size());\n\tfor (size_t i = 0; i < constraints.size(); i++)\n\t{\n\t\tevaluator->indexCons[i] = _constraint_index(constraints[i]);\n\t}\n\tif (evaluator->is_objective())\n\t{\n\t\tevaluator->fun = cppad_trace_graph_objective(graph, outputs, true);\n\t}\n\telse\n\t{\n\t\tevaluator->fun = cppad_trace_graph_constraints(graph, outputs);\n\t}\n\tevaluator->setup();\n\t_register_callback(evaluator);\n\tm_evaluators.push_back(std::move(evaluator_ptr));\n}\n\nvoid KNITROModel::_add_callbacks(const ExpressionGraph &graph, const Outputs &outputs)\n{\n\tif (graph.has_constraint_output() && !outputs.constraint_outputs.empty())\n\t{\n\t\t_add_callback(graph, outputs.constraint_outputs, outputs.constraints);\n\t}\n\n\tif (graph.has_objective_output() && !outputs.objective_outputs.empty())\n\t{\n\t\t_add_callback(graph, outputs.objective_outputs, {});\n\t}\n}\n\nvoid KNITROModel::_add_pending_callbacks()\n{\n\tif (!m_has_pending_callbacks)\n\t{\n\t\treturn;\n\t}\n\n\tfor (const auto &[graph, outputs] : m_pending_outputs)\n\t{\n\t\t_add_callbacks(*graph, outputs);\n\t}\n\n\tm_pending_outputs.clear();\n\tm_has_pending_callbacks = false;\n}\n\n// Solve functions\nvoid KNITROModel::_update()\n{\n\t_add_pending_callbacks();\n\tint error = knitro::KN_update(m_kc.get());\n\t_check_error(error);\n}\n\nvoid KNITROModel::_pre_solve()\n{\n\t_add_pending_callbacks();\n}\n\nvoid KNITROModel::_solve()\n{\n\tm_solve_status = knitro::KN_solve(m_kc.get());\n}\n\nvoid KNITROModel::_post_solve()\n{\n}\n\nvoid KNITROModel::optimize()\n{\n\t_pre_solve();\n\t_solve();\n\t_post_solve();\n\t_unmark_dirty();\n}\n\n// Solve information\nsize_t KNITROModel::get_number_iterations() const\n{\n\t_check_dirty();\n\tint iters = _get_value<int>(knitro::KN_get_number_iters);\n\treturn static_cast<size_t>(iters);\n}\n\nsize_t KNITROModel::get_mip_node_count() const\n{\n\t_check_dirty();\n\tint nodes = _get_value<int>(knitro::KN_get_mip_number_nodes);\n\treturn static_cast<size_t>(nodes);\n}\n\ndouble KNITROModel::get_obj_bound() const\n{\n\t_check_dirty();\n\treturn _get_value<double>(knitro::KN_get_mip_relaxation_bnd);\n}\n\ndouble KNITROModel::get_mip_relative_gap() const\n{\n\t_check_dirty();\n\treturn _get_value<double>(knitro::KN_get_mip_rel_gap);\n}\n\ndouble KNITROModel::get_solve_time() const\n{\n\t_check_dirty();\n\treturn _get_value<double>(knitro::KN_get_solve_time_real);\n}\n\n// Dirty state management\nvoid KNITROModel::_mark_dirty()\n{\n\tm_is_dirty = true;\n}\n\nvoid KNITROModel::_unmark_dirty()\n{\n\tm_is_dirty = false;\n}\n\nbool KNITROModel::dirty() const\n{\n\treturn m_is_dirty;\n}\n\n// Model state\nbool KNITROModel::empty() const\n{\n\treturn m_kc == nullptr;\n}\n\nsize_t KNITROModel::get_num_vars() const\n{\n\treturn m_n_vars;\n}\n\nsize_t KNITROModel::get_num_cons(std::optional<ConstraintType> type) const\n{\n\tif (!type.has_value())\n\t{\n\t\tsize_t total = 0;\n\t\tfor (const auto &[_, count] : m_n_cons_map)\n\t\t{\n\t\t\ttotal += count;\n\t\t}\n\t\treturn total;\n\t}\n\telse\n\t{\n\t\tauto it = m_n_cons_map.find(type.value());\n\t\treturn it != m_n_cons_map.end() ? it->second : 0;\n\t}\n}\n\nint KNITROModel::get_solve_status() const\n{\n\t_check_dirty();\n\treturn m_solve_status;\n}\n\n// Internal helpers\nvoid KNITROModel::_check_dirty() const\n{\n\tif (dirty())\n\t{\n\t\tthrow std::runtime_error(\"Model has been modified since last solve. Call optimize()...\");\n\t}\n}\n\nvoid KNITROModel::_reset_state()\n{\n\tm_kc.reset();\n\tm_n_vars = 0;\n\tm_n_cons_map.clear();\n\tm_soc_aux_cons.clear();\n\tm_con_sense_flags.clear();\n\tm_obj_flag = 0;\n\tm_pending_outputs.clear();\n\tm_evaluators.clear();\n\tm_has_pending_callbacks = false;\n\t_mark_dirty();\n\tm_solve_status = 0;\n}\n\nvoid KNITROModel::_init()\n{\n\tensure_library_loaded();\n\t_reset_state();\n\n\t// Create new KNITRO problem\n\tKN_context *kc = nullptr;\n\tint error = m_lm ? knitro::KN_new_lm(m_lm.get(), &kc) : knitro::KN_new(&kc);\n\tknitro_throw(error);\n\tm_kc = std::unique_ptr<KN_context, KNITROFreeProblemT>(kc);\n}\n\nKNINT KNITROModel::_variable_index(const VariableIndex &variable) const\n{\n\treturn _get_index(variable);\n}\n\nKNINT KNITROModel::_constraint_index(const ConstraintIndex &constraint) const\n{\n\treturn _get_index(constraint);\n}\n"
  },
  {
    "path": "lib/knitro_model_ext.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include <nanobind/stl/optional.h>\n#include <nanobind/stl/string.h>\n#include <nanobind/stl/vector.h>\n#include <nanobind/stl/tuple.h>\n\n#include \"pyoptinterface/knitro_model.hpp\"\n\nnamespace nb = nanobind;\n\nextern void bind_knitro_constants(nb::module_ &m);\n\nNB_MODULE(knitro_model_ext, m)\n{\n\tm.import_(\"pyoptinterface._src.core_ext\");\n\n\tm.def(\"is_library_loaded\", &knitro::is_library_loaded);\n\tm.def(\"load_library\", &knitro::load_library);\n\tm.def(\"has_valid_license\", &knitro::has_valid_license);\n\n\tbind_knitro_constants(m);\n\n\tnb::class_<KNITROEnv>(m, \"RawEnv\")\n\t    .def(nb::init<bool>(), nb::arg(\"empty\") = false)\n\t    .def(\"start\", &KNITROEnv::start)\n\t    .def(\"empty\", &KNITROEnv::empty)\n\t    .def(\"close\", &KNITROEnv::close);\n\n#define BIND_F(f) .def(#f, &KNITROModel::f)\n\tnb::class_<KNITROModel>(m, \"RawModel\")\n\t    .def(nb::init<>())\n\t    .def(nb::init<const KNITROEnv &>())\n\t    .def(\"init\", nb::overload_cast<>(&KNITROModel::init))\n\t    .def(\"init\", nb::overload_cast<const KNITROEnv &>(&KNITROModel::init))\n\n\t    // clang-format off\n\t\tBIND_F(close)\n\t\tBIND_F(get_infinity)\n\t\tBIND_F(get_number_iterations)\n\t\tBIND_F(get_mip_node_count)\n\t\tBIND_F(get_obj_bound)\n\t\tBIND_F(get_mip_relative_gap)\n\t\tBIND_F(get_solve_time)\n\t\tBIND_F(get_solver_name)\n\t\tBIND_F(get_release)\n\t    // clang-format on\n\n\t    .def(\"number_of_variables\", &KNITROModel::get_num_vars)\n\t    .def(\"number_of_constraints\", &KNITROModel::get_num_cons, nb::arg(\"type\") = nb::none())\n\n\t    .def(\"add_variable\", &KNITROModel::add_variable,\n\t         nb::arg(\"domain\") = VariableDomain::Continuous, nb::arg(\"lb\") = -KN_INFINITY,\n\t         nb::arg(\"ub\") = KN_INFINITY, nb::arg(\"name\") = \"\")\n\n\t    // clang-format off\n\t\tBIND_F(get_variable_lb)\n\t\tBIND_F(get_variable_ub)\n\t\tBIND_F(set_variable_lb)\n\t\tBIND_F(set_variable_ub)\n\t\tBIND_F(set_variable_bounds)\n\t\tBIND_F(set_variable_start)\n\t\tBIND_F(get_variable_name)\n\t\tBIND_F(set_variable_name)\n\t\tBIND_F(set_variable_domain)\n\t\tBIND_F(get_variable_domain)\n\t\tBIND_F(get_variable_rc)\n\t\tBIND_F(delete_variable)\n\t    // clang-format on\n\n\t    .def(\"get_value\", &KNITROModel::get_variable_value)\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ScalarAffineFunction &>(&KNITROModel::get_expression_value))\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &>(&KNITROModel::get_expression_value))\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ExprBuilder &>(&KNITROModel::get_expression_value))\n\n\t    .def(\"pprint\", &KNITROModel::pprint_variable)\n\t    .def(\"pprint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, int>(&KNITROModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\t    .def(\"pprint\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, int>(\n\t             &KNITROModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\t    .def(\"pprint\", nb::overload_cast<const ExprBuilder &, int>(&KNITROModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\n\t    // clang-format off\n\t\tBIND_F(set_constraint_name)\n\t\tBIND_F(get_constraint_name)\n\t\tBIND_F(get_constraint_primal)\n\t\tBIND_F(get_constraint_dual)\n\t\tBIND_F(set_normalized_rhs)\n\t\tBIND_F(get_normalized_rhs)\n\t\tBIND_F(set_normalized_coefficient)\n\t    // clang-format on\n\n\t    .def(\"_add_linear_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ConstraintSense, CoeffT, const char *>(\n\t             &KNITROModel::add_linear_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, const std::tuple<double, double> &,\n\t                           const char *>(&KNITROModel::add_linear_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &KNITROModel::add_linear_constraint_from_var,\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &KNITROModel::add_linear_interval_constraint_from_var,\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &KNITROModel::add_linear_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &KNITROModel::add_linear_interval_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\n\t    .def(\"_add_quadratic_constraint\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, ConstraintSense, CoeffT,\n\t                           const char *>(&KNITROModel::add_quadratic_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_quadratic_constraint\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, const std::tuple<double, double> &,\n\t                           const char *>(&KNITROModel::add_quadratic_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_quadratic_constraint\", &KNITROModel::add_quadratic_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_quadratic_constraint\", &KNITROModel::add_quadratic_interval_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\n\t    .def(\"add_second_order_cone_constraint\", &KNITROModel::add_second_order_cone_constraint,\n\t         nb::arg(\"variables\"), nb::arg(\"name\") = \"\", nb::arg(\"rotated\") = false)\n\n\t    .def(\"_add_single_nl_constraint\", &KNITROModel::add_single_nl_constraint, nb::arg(\"graph\"),\n\t         nb::arg(\"result\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_single_nl_constraint\", &KNITROModel::add_single_nl_constraint_sense_rhs,\n\t         nb::arg(\"graph\"), nb::arg(\"result\"), nb::arg(\"sense\"), nb::arg(\"rhs\"),\n\t         nb::arg(\"name\") = \"\")\n\t    .def(\"_add_single_nl_constraint\", &KNITROModel::add_single_nl_constraint_from_comparison,\n\t         nb::arg(\"graph\"), nb::arg(\"expr\"), nb::arg(\"name\") = \"\")\n\n\t    // clang-format off\n\t    BIND_F(delete_constraint)\n\t    // clang-format on\n\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ObjectiveSense>(\n\t             &KNITROModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, ObjectiveSense>(\n\t             &KNITROModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ExprBuilder &, ObjectiveSense>(&KNITROModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const VariableIndex &, ObjectiveSense>(\n\t             &KNITROModel::set_objective_as_variable),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<CoeffT, ObjectiveSense>(&KNITROModel::set_objective_as_constant),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"_add_single_nl_objective\", &KNITROModel::add_single_nl_objective, nb::arg(\"graph\"),\n\t         nb::arg(\"result\"))\n\n\t    // clang-format off\n\t\tBIND_F(set_objective_coefficient)\n\t\tBIND_F(get_obj_value)\n\t\tBIND_F(set_obj_sense)\n\t\tBIND_F(get_obj_sense)\n\t    // clang-format on\n\n\t    .def(\"optimize\", &KNITROModel::optimize, nb::call_guard<nb::gil_scoped_release>())\n\n\t    .def(\n\t        \"set_raw_parameter\",\n\t        [](KNITROModel &m, const std::string &name, int value) {\n\t\t        m.set_raw_parameter<int>(name, value);\n\t        },\n\t        nb::arg(\"name\"), nb::arg(\"value\"))\n\t    .def(\n\t        \"set_raw_parameter\",\n\t        [](KNITROModel &m, const std::string &name, double value) {\n\t\t        m.set_raw_parameter<double>(name, value);\n\t        },\n\t        nb::arg(\"name\"), nb::arg(\"value\"))\n\t    .def(\n\t        \"set_raw_parameter\",\n\t        [](KNITROModel &m, const std::string &name, const std::string &value) {\n\t\t        m.set_raw_parameter<std::string>(name, value);\n\t        },\n\t        nb::arg(\"name\"), nb::arg(\"value\"))\n\t    .def(\n\t        \"set_raw_parameter\",\n\t        [](KNITROModel &m, int param_id, int value) {\n\t\t        m.set_raw_parameter<int>(param_id, value);\n\t        },\n\t        nb::arg(\"param_id\"), nb::arg(\"value\"))\n\t    .def(\n\t        \"set_raw_parameter\",\n\t        [](KNITROModel &m, int param_id, double value) {\n\t\t        m.set_raw_parameter<double>(param_id, value);\n\t        },\n\t        nb::arg(\"param_id\"), nb::arg(\"value\"))\n\t    .def(\n\t        \"set_raw_parameter\",\n\t        [](KNITROModel &m, int param_id, const std::string &value) {\n\t\t        m.set_raw_parameter<std::string>(param_id, value);\n\t        },\n\t        nb::arg(\"param_id\"), nb::arg(\"value\"))\n\n\t    .def(\n\t        \"get_raw_parameter\",\n\t        [](KNITROModel &m, const std::string &name) -> int {\n\t\t        return m.get_raw_parameter<int>(name);\n\t        },\n\t        nb::arg(\"name\"))\n\t    .def(\n\t        \"get_raw_parameter\",\n\t        [](KNITROModel &m, const std::string &name) -> double {\n\t\t        return m.get_raw_parameter<double>(name);\n\t        },\n\t        nb::arg(\"name\"))\n\t    .def(\n\t        \"get_raw_parameter\",\n\t        [](KNITROModel &m, int param_id) -> int { return m.get_raw_parameter<int>(param_id); },\n\t        nb::arg(\"param_id\"))\n\t    .def(\n\t        \"get_raw_parameter\",\n\t        [](KNITROModel &m, int param_id) -> double {\n\t\t        return m.get_raw_parameter<double>(param_id);\n\t        },\n\t        nb::arg(\"param_id\"))\n\n\t    // clang-format off\n\t\tBIND_F(dirty)\n\t\tBIND_F(empty)\n\t    // clang-format on\n\n\t    // clang-format off\n\t\tBIND_F(get_solve_status)\n\t    // clang-format on\n\t    ;\n\n#undef BIND_F\n}\n"
  },
  {
    "path": "lib/knitro_model_ext_constants.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include \"pyoptinterface/knitro_model.hpp\"\n\nnamespace nb = nanobind;\n\nvoid bind_knitro_constants(nb::module_ &m)\n{\n\tnb::module_ KN = m.def_submodule(\"KN\");\n\n\t// Objective goal\n\tKN.attr(\"OBJGOAL_MINIMIZE\") = KN_OBJGOAL_MINIMIZE;\n\tKN.attr(\"OBJGOAL_MAXIMIZE\") = KN_OBJGOAL_MAXIMIZE;\n\n\t// Variable types\n\tKN.attr(\"VARTYPE_CONTINUOUS\") = KN_VARTYPE_CONTINUOUS;\n\tKN.attr(\"VARTYPE_INTEGER\") = KN_VARTYPE_INTEGER;\n\tKN.attr(\"VARTYPE_BINARY\") = KN_VARTYPE_BINARY;\n\n\t// Infinity\n\tKN.attr(\"INFINITY\") = KN_INFINITY;\n\n\t// Return codes - Optimal/Satisfactory\n\tKN.attr(\"RC_OPTIMAL_OR_SATISFACTORY\") = KN_RC_OPTIMAL_OR_SATISFACTORY;\n\tKN.attr(\"RC_OPTIMAL\") = KN_RC_OPTIMAL;\n\n\t// Return codes - Feasible\n\tKN.attr(\"RC_NEAR_OPT\") = KN_RC_NEAR_OPT;\n\tKN.attr(\"RC_FEAS_XTOL\") = KN_RC_FEAS_XTOL;\n\tKN.attr(\"RC_FEAS_NO_IMPROVE\") = KN_RC_FEAS_NO_IMPROVE;\n\tKN.attr(\"RC_FEAS_FTOL\") = KN_RC_FEAS_FTOL;\n\tKN.attr(\"RC_FEAS_BEST\") = KN_RC_FEAS_BEST;\n\tKN.attr(\"RC_FEAS_MULTISTART\") = KN_RC_FEAS_MULTISTART;\n\n\t// Return codes - Infeasible\n\tKN.attr(\"RC_INFEASIBLE\") = KN_RC_INFEASIBLE;\n\tKN.attr(\"RC_INFEAS_XTOL\") = KN_RC_INFEAS_XTOL;\n\tKN.attr(\"RC_INFEAS_NO_IMPROVE\") = KN_RC_INFEAS_NO_IMPROVE;\n\tKN.attr(\"RC_INFEAS_MULTISTART\") = KN_RC_INFEAS_MULTISTART;\n\tKN.attr(\"RC_INFEAS_CON_BOUNDS\") = KN_RC_INFEAS_CON_BOUNDS;\n\tKN.attr(\"RC_INFEAS_VAR_BOUNDS\") = KN_RC_INFEAS_VAR_BOUNDS;\n\n\t// Return codes - Unbounded\n\tKN.attr(\"RC_UNBOUNDED\") = KN_RC_UNBOUNDED;\n\tKN.attr(\"RC_UNBOUNDED_OR_INFEAS\") = KN_RC_UNBOUNDED_OR_INFEAS;\n\n\t// Return codes - Limit exceeded (feasible)\n\tKN.attr(\"RC_ITER_LIMIT_FEAS\") = KN_RC_ITER_LIMIT_FEAS;\n\tKN.attr(\"RC_TIME_LIMIT_FEAS\") = KN_RC_TIME_LIMIT_FEAS;\n\tKN.attr(\"RC_FEVAL_LIMIT_FEAS\") = KN_RC_FEVAL_LIMIT_FEAS;\n\tKN.attr(\"RC_MIP_EXH_FEAS\") = KN_RC_MIP_EXH_FEAS;\n\tKN.attr(\"RC_MIP_TERM_FEAS\") = KN_RC_MIP_TERM_FEAS;\n\tKN.attr(\"RC_MIP_SOLVE_LIMIT_FEAS\") = KN_RC_MIP_SOLVE_LIMIT_FEAS;\n\tKN.attr(\"RC_MIP_NODE_LIMIT_FEAS\") = KN_RC_MIP_NODE_LIMIT_FEAS;\n\n\t// Return codes - Limit exceeded (infeasible)\n\tKN.attr(\"RC_ITER_LIMIT_INFEAS\") = KN_RC_ITER_LIMIT_INFEAS;\n\tKN.attr(\"RC_TIME_LIMIT_INFEAS\") = KN_RC_TIME_LIMIT_INFEAS;\n\tKN.attr(\"RC_FEVAL_LIMIT_INFEAS\") = KN_RC_FEVAL_LIMIT_INFEAS;\n\tKN.attr(\"RC_MIP_EXH_INFEAS\") = KN_RC_MIP_EXH_INFEAS;\n\tKN.attr(\"RC_MIP_SOLVE_LIMIT_INFEAS\") = KN_RC_MIP_SOLVE_LIMIT_INFEAS;\n\tKN.attr(\"RC_MIP_NODE_LIMIT_INFEAS\") = KN_RC_MIP_NODE_LIMIT_INFEAS;\n\n\t// Return codes - Other failures\n\tKN.attr(\"RC_CALLBACK_ERR\") = KN_RC_CALLBACK_ERR;\n\tKN.attr(\"RC_LP_SOLVER_ERR\") = KN_RC_LP_SOLVER_ERR;\n\tKN.attr(\"RC_EVAL_ERR\") = KN_RC_EVAL_ERR;\n\tKN.attr(\"RC_OUT_OF_MEMORY\") = KN_RC_OUT_OF_MEMORY;\n\tKN.attr(\"RC_USER_TERMINATION\") = KN_RC_USER_TERMINATION;\n\tKN.attr(\"RC_OPEN_FILE_ERR\") = KN_RC_OPEN_FILE_ERR;\n\n\t// Return codes - Problem definition errors\n\tKN.attr(\"RC_BAD_N_OR_F\") = KN_RC_BAD_N_OR_F;\n\tKN.attr(\"RC_BAD_CONSTRAINT\") = KN_RC_BAD_CONSTRAINT;\n\tKN.attr(\"RC_BAD_JACOBIAN\") = KN_RC_BAD_JACOBIAN;\n\tKN.attr(\"RC_BAD_HESSIAN\") = KN_RC_BAD_HESSIAN;\n\tKN.attr(\"RC_BAD_CON_INDEX\") = KN_RC_BAD_CON_INDEX;\n\tKN.attr(\"RC_BAD_JAC_INDEX\") = KN_RC_BAD_JAC_INDEX;\n\tKN.attr(\"RC_BAD_HESS_INDEX\") = KN_RC_BAD_HESS_INDEX;\n\tKN.attr(\"RC_BAD_CON_BOUNDS\") = KN_RC_BAD_CON_BOUNDS;\n\tKN.attr(\"RC_BAD_VAR_BOUNDS\") = KN_RC_BAD_VAR_BOUNDS;\n\tKN.attr(\"RC_ILLEGAL_CALL\") = KN_RC_ILLEGAL_CALL;\n\tKN.attr(\"RC_BAD_KCPTR\") = KN_RC_BAD_KCPTR;\n\tKN.attr(\"RC_NULL_POINTER\") = KN_RC_NULL_POINTER;\n\tKN.attr(\"RC_BAD_INIT_VALUE\") = KN_RC_BAD_INIT_VALUE;\n\tKN.attr(\"RC_LICENSE_ERROR\") = KN_RC_LICENSE_ERROR;\n\tKN.attr(\"RC_BAD_PARAMINPUT\") = KN_RC_BAD_PARAMINPUT;\n\tKN.attr(\"RC_LINEAR_SOLVER_ERR\") = KN_RC_LINEAR_SOLVER_ERR;\n\tKN.attr(\"RC_DERIV_CHECK_FAILED\") = KN_RC_DERIV_CHECK_FAILED;\n\tKN.attr(\"RC_DERIV_CHECK_TERMINATE\") = KN_RC_DERIV_CHECK_TERMINATE;\n\tKN.attr(\"RC_OVERFLOW_ERR\") = KN_RC_OVERFLOW_ERR;\n\tKN.attr(\"RC_BAD_SIZE\") = KN_RC_BAD_SIZE;\n\tKN.attr(\"RC_BAD_VARIABLE\") = KN_RC_BAD_VARIABLE;\n\tKN.attr(\"RC_BAD_VAR_INDEX\") = KN_RC_BAD_VAR_INDEX;\n\tKN.attr(\"RC_BAD_OBJECTIVE\") = KN_RC_BAD_OBJECTIVE;\n\tKN.attr(\"RC_BAD_OBJ_INDEX\") = KN_RC_BAD_OBJ_INDEX;\n\tKN.attr(\"RC_BAD_RESIDUAL\") = KN_RC_BAD_RESIDUAL;\n\tKN.attr(\"RC_BAD_RSD_INDEX\") = KN_RC_BAD_RSD_INDEX;\n\tKN.attr(\"RC_INTERNAL_ERROR\") = KN_RC_INTERNAL_ERROR;\n\n\t// Callback request codes\n\tKN.attr(\"RC_EVALFC\") = KN_RC_EVALFC;\n\tKN.attr(\"RC_EVALGA\") = KN_RC_EVALGA;\n\tKN.attr(\"RC_EVALH\") = KN_RC_EVALH;\n\tKN.attr(\"RC_EVALHV\") = KN_RC_EVALHV;\n\tKN.attr(\"RC_EVALH_NO_F\") = KN_RC_EVALH_NO_F;\n\tKN.attr(\"RC_EVALHV_NO_F\") = KN_RC_EVALHV_NO_F;\n\tKN.attr(\"RC_EVALR\") = KN_RC_EVALR;\n\tKN.attr(\"RC_EVALRJ\") = KN_RC_EVALRJ;\n\tKN.attr(\"RC_EVALFCGA\") = KN_RC_EVALFCGA;\n\n\t// Parameter types\n\tKN.attr(\"PARAMTYPE_INTEGER\") = KN_PARAMTYPE_INTEGER;\n\tKN.attr(\"PARAMTYPE_FLOAT\") = KN_PARAMTYPE_FLOAT;\n\tKN.attr(\"PARAMTYPE_STRING\") = KN_PARAMTYPE_STRING;\n\n\t// Parameter IDs\n\tKN.attr(\"PARAM_NEWPOINT\") = KN_PARAM_NEWPOINT;\n\tKN.attr(\"PARAM_HONORBNDS\") = KN_PARAM_HONORBNDS;\n\tKN.attr(\"PARAM_ALGORITHM\") = KN_PARAM_ALGORITHM;\n\tKN.attr(\"PARAM_ALG\") = KN_PARAM_ALG;\n\tKN.attr(\"PARAM_NLP_ALGORITHM\") = KN_PARAM_NLP_ALGORITHM;\n\tKN.attr(\"PARAM_BAR_MURULE\") = KN_PARAM_BAR_MURULE;\n\tKN.attr(\"PARAM_BAR_FEASIBLE\") = KN_PARAM_BAR_FEASIBLE;\n\tKN.attr(\"PARAM_GRADOPT\") = KN_PARAM_GRADOPT;\n\tKN.attr(\"PARAM_HESSOPT\") = KN_PARAM_HESSOPT;\n\tKN.attr(\"PARAM_BAR_INITPT\") = KN_PARAM_BAR_INITPT;\n\tKN.attr(\"PARAM_ACT_LPSOLVER\") = KN_PARAM_ACT_LPSOLVER;\n\tKN.attr(\"PARAM_CG_MAXIT\") = KN_PARAM_CG_MAXIT;\n\tKN.attr(\"PARAM_MAXIT\") = KN_PARAM_MAXIT;\n\tKN.attr(\"PARAM_OUTLEV\") = KN_PARAM_OUTLEV;\n\tKN.attr(\"PARAM_OUTMODE\") = KN_PARAM_OUTMODE;\n\tKN.attr(\"PARAM_SCALE\") = KN_PARAM_SCALE;\n\tKN.attr(\"PARAM_SOC\") = KN_PARAM_SOC;\n\tKN.attr(\"PARAM_DELTA\") = KN_PARAM_DELTA;\n\tKN.attr(\"PARAM_BAR_FEASMODETOL\") = KN_PARAM_BAR_FEASMODETOL;\n\tKN.attr(\"PARAM_FEASTOL\") = KN_PARAM_FEASTOL;\n\tKN.attr(\"PARAM_FEASTOLABS\") = KN_PARAM_FEASTOLABS;\n\tKN.attr(\"PARAM_MAXTIMECPU\") = KN_PARAM_MAXTIMECPU;\n\tKN.attr(\"PARAM_BAR_INITMU\") = KN_PARAM_BAR_INITMU;\n\tKN.attr(\"PARAM_OBJRANGE\") = KN_PARAM_OBJRANGE;\n\tKN.attr(\"PARAM_OPTTOL\") = KN_PARAM_OPTTOL;\n\tKN.attr(\"PARAM_OPTTOLABS\") = KN_PARAM_OPTTOLABS;\n\tKN.attr(\"PARAM_LINSOLVER_PIVOTTOL\") = KN_PARAM_LINSOLVER_PIVOTTOL;\n\tKN.attr(\"PARAM_XTOL\") = KN_PARAM_XTOL;\n\tKN.attr(\"PARAM_DEBUG\") = KN_PARAM_DEBUG;\n\tKN.attr(\"PARAM_MULTISTART\") = KN_PARAM_MULTISTART;\n\tKN.attr(\"PARAM_MS_ENABLE\") = KN_PARAM_MS_ENABLE;\n\tKN.attr(\"PARAM_MS_MAXSOLVES\") = KN_PARAM_MS_MAXSOLVES;\n\tKN.attr(\"PARAM_MS_MAXBNDRANGE\") = KN_PARAM_MS_MAXBNDRANGE;\n\tKN.attr(\"PARAM_MS_MAXTIMECPU\") = KN_PARAM_MS_MAXTIMECPU;\n\tKN.attr(\"PARAM_MS_MAXTIMEREAL\") = KN_PARAM_MS_MAXTIMEREAL;\n\tKN.attr(\"PARAM_LMSIZE\") = KN_PARAM_LMSIZE;\n\tKN.attr(\"PARAM_BAR_MAXCROSSIT\") = KN_PARAM_BAR_MAXCROSSIT;\n\tKN.attr(\"PARAM_MAXTIMEREAL\") = KN_PARAM_MAXTIMEREAL;\n\tKN.attr(\"PARAM_CG_PRECOND\") = KN_PARAM_CG_PRECOND;\n\tKN.attr(\"PARAM_BLASOPTION\") = KN_PARAM_BLASOPTION;\n\tKN.attr(\"PARAM_BAR_MAXREFACTOR\") = KN_PARAM_BAR_MAXREFACTOR;\n\tKN.attr(\"PARAM_LINESEARCH_MAXTRIALS\") = KN_PARAM_LINESEARCH_MAXTRIALS;\n\tKN.attr(\"PARAM_BLASOPTIONLIB\") = KN_PARAM_BLASOPTIONLIB;\n\tKN.attr(\"PARAM_OUTAPPEND\") = KN_PARAM_OUTAPPEND;\n\tKN.attr(\"PARAM_OUTDIR\") = KN_PARAM_OUTDIR;\n\tKN.attr(\"PARAM_CPLEXLIB\") = KN_PARAM_CPLEXLIB;\n\tKN.attr(\"PARAM_BAR_PENRULE\") = KN_PARAM_BAR_PENRULE;\n\tKN.attr(\"PARAM_BAR_PENCONS\") = KN_PARAM_BAR_PENCONS;\n\tKN.attr(\"PARAM_MS_NUMTOSAVE\") = KN_PARAM_MS_NUMTOSAVE;\n\tKN.attr(\"PARAM_MS_SAVETOL\") = KN_PARAM_MS_SAVETOL;\n\tKN.attr(\"PARAM_MS_TERMINATE\") = KN_PARAM_MS_TERMINATE;\n\tKN.attr(\"PARAM_MS_STARTPTRANGE\") = KN_PARAM_MS_STARTPTRANGE;\n\tKN.attr(\"PARAM_INFEASTOL\") = KN_PARAM_INFEASTOL;\n\tKN.attr(\"PARAM_LINSOLVER\") = KN_PARAM_LINSOLVER;\n\tKN.attr(\"PARAM_BAR_DIRECTINTERVAL\") = KN_PARAM_BAR_DIRECTINTERVAL;\n\tKN.attr(\"PARAM_PRESOLVE\") = KN_PARAM_PRESOLVE;\n\tKN.attr(\"PARAM_PRESOLVE_TOL\") = KN_PARAM_PRESOLVE_TOL;\n\tKN.attr(\"PARAM_BAR_SWITCHRULE\") = KN_PARAM_BAR_SWITCHRULE;\n\tKN.attr(\"PARAM_HESSIAN_NO_F\") = KN_PARAM_HESSIAN_NO_F;\n\tKN.attr(\"PARAM_MA_TERMINATE\") = KN_PARAM_MA_TERMINATE;\n\tKN.attr(\"PARAM_MA_MAXTIMECPU\") = KN_PARAM_MA_MAXTIMECPU;\n\tKN.attr(\"PARAM_MA_MAXTIMEREAL\") = KN_PARAM_MA_MAXTIMEREAL;\n\tKN.attr(\"PARAM_MS_SEED\") = KN_PARAM_MS_SEED;\n\tKN.attr(\"PARAM_MA_OUTSUB\") = KN_PARAM_MA_OUTSUB;\n\tKN.attr(\"PARAM_MS_OUTSUB\") = KN_PARAM_MS_OUTSUB;\n\tKN.attr(\"PARAM_XPRESSLIB\") = KN_PARAM_XPRESSLIB;\n\tKN.attr(\"PARAM_TUNER\") = KN_PARAM_TUNER;\n\tKN.attr(\"PARAM_TUNER_OPTIONSFILE\") = KN_PARAM_TUNER_OPTIONSFILE;\n\tKN.attr(\"PARAM_TUNER_MAXTIMECPU\") = KN_PARAM_TUNER_MAXTIMECPU;\n\tKN.attr(\"PARAM_TUNER_MAXTIMEREAL\") = KN_PARAM_TUNER_MAXTIMEREAL;\n\tKN.attr(\"PARAM_TUNER_OUTSUB\") = KN_PARAM_TUNER_OUTSUB;\n\tKN.attr(\"PARAM_TUNER_TERMINATE\") = KN_PARAM_TUNER_TERMINATE;\n\tKN.attr(\"PARAM_LINSOLVER_OOC\") = KN_PARAM_LINSOLVER_OOC;\n\tKN.attr(\"PARAM_BAR_RELAXCONS\") = KN_PARAM_BAR_RELAXCONS;\n\tKN.attr(\"PARAM_MS_DETERMINISTIC\") = KN_PARAM_MS_DETERMINISTIC;\n\tKN.attr(\"PARAM_BAR_REFINEMENT\") = KN_PARAM_BAR_REFINEMENT;\n\tKN.attr(\"PARAM_DERIVCHECK\") = KN_PARAM_DERIVCHECK;\n\tKN.attr(\"PARAM_DERIVCHECK_TYPE\") = KN_PARAM_DERIVCHECK_TYPE;\n\tKN.attr(\"PARAM_DERIVCHECK_TOL\") = KN_PARAM_DERIVCHECK_TOL;\n\tKN.attr(\"PARAM_MAXFEVALS\") = KN_PARAM_MAXFEVALS;\n\tKN.attr(\"PARAM_FSTOPVAL\") = KN_PARAM_FSTOPVAL;\n\tKN.attr(\"PARAM_DATACHECK\") = KN_PARAM_DATACHECK;\n\tKN.attr(\"PARAM_DERIVCHECK_TERMINATE\") = KN_PARAM_DERIVCHECK_TERMINATE;\n\tKN.attr(\"PARAM_BAR_WATCHDOG\") = KN_PARAM_BAR_WATCHDOG;\n\tKN.attr(\"PARAM_FTOL\") = KN_PARAM_FTOL;\n\tKN.attr(\"PARAM_FTOL_ITERS\") = KN_PARAM_FTOL_ITERS;\n\tKN.attr(\"PARAM_ACT_QPALG\") = KN_PARAM_ACT_QPALG;\n\tKN.attr(\"PARAM_BAR_INITPI_MPEC\") = KN_PARAM_BAR_INITPI_MPEC;\n\tKN.attr(\"PARAM_XTOL_ITERS\") = KN_PARAM_XTOL_ITERS;\n\tKN.attr(\"PARAM_LINESEARCH\") = KN_PARAM_LINESEARCH;\n\tKN.attr(\"PARAM_OUT_CSVINFO\") = KN_PARAM_OUT_CSVINFO;\n\tKN.attr(\"PARAM_INITPENALTY\") = KN_PARAM_INITPENALTY;\n\tKN.attr(\"PARAM_ACT_LPFEASTOL\") = KN_PARAM_ACT_LPFEASTOL;\n\tKN.attr(\"PARAM_CG_STOPTOL\") = KN_PARAM_CG_STOPTOL;\n\tKN.attr(\"PARAM_RESTARTS\") = KN_PARAM_RESTARTS;\n\tKN.attr(\"PARAM_RESTARTS_MAXIT\") = KN_PARAM_RESTARTS_MAXIT;\n\tKN.attr(\"PARAM_BAR_SLACKBOUNDPUSH\") = KN_PARAM_BAR_SLACKBOUNDPUSH;\n\tKN.attr(\"PARAM_CG_PMEM\") = KN_PARAM_CG_PMEM;\n\tKN.attr(\"PARAM_BAR_SWITCHOBJ\") = KN_PARAM_BAR_SWITCHOBJ;\n\tKN.attr(\"PARAM_OUTNAME\") = KN_PARAM_OUTNAME;\n\tKN.attr(\"PARAM_OUT_CSVNAME\") = KN_PARAM_OUT_CSVNAME;\n\tKN.attr(\"PARAM_ACT_PARAMETRIC\") = KN_PARAM_ACT_PARAMETRIC;\n\tKN.attr(\"PARAM_ACT_LPDUMPMPS\") = KN_PARAM_ACT_LPDUMPMPS;\n\tKN.attr(\"PARAM_ACT_LPALG\") = KN_PARAM_ACT_LPALG;\n\tKN.attr(\"PARAM_ACT_LPPRESOLVE\") = KN_PARAM_ACT_LPPRESOLVE;\n\tKN.attr(\"PARAM_ACT_LPPENALTY\") = KN_PARAM_ACT_LPPENALTY;\n\tKN.attr(\"PARAM_BNDRANGE\") = KN_PARAM_BNDRANGE;\n\tKN.attr(\"PARAM_BAR_CONIC_ENABLE\") = KN_PARAM_BAR_CONIC_ENABLE;\n\tKN.attr(\"PARAM_CONVEX\") = KN_PARAM_CONVEX;\n\tKN.attr(\"PARAM_OUT_HINTS\") = KN_PARAM_OUT_HINTS;\n\tKN.attr(\"PARAM_EVAL_FCGA\") = KN_PARAM_EVAL_FCGA;\n\tKN.attr(\"PARAM_BAR_MAXCORRECTORS\") = KN_PARAM_BAR_MAXCORRECTORS;\n\tKN.attr(\"PARAM_STRAT_WARM_START\") = KN_PARAM_STRAT_WARM_START;\n\tKN.attr(\"PARAM_FINDIFF_TERMINATE\") = KN_PARAM_FINDIFF_TERMINATE;\n\tKN.attr(\"PARAM_CPUPLATFORM\") = KN_PARAM_CPUPLATFORM;\n\tKN.attr(\"PARAM_PRESOLVE_PASSES\") = KN_PARAM_PRESOLVE_PASSES;\n\tKN.attr(\"PARAM_PRESOLVE_LEVEL\") = KN_PARAM_PRESOLVE_LEVEL;\n\tKN.attr(\"PARAM_FINDIFF_RELSTEPSIZE\") = KN_PARAM_FINDIFF_RELSTEPSIZE;\n\tKN.attr(\"PARAM_INFEASTOL_ITERS\") = KN_PARAM_INFEASTOL_ITERS;\n\tKN.attr(\"PARAM_PRESOLVEOP_TIGHTEN\") = KN_PARAM_PRESOLVEOP_TIGHTEN;\n\tKN.attr(\"PARAM_BAR_LINSYS\") = KN_PARAM_BAR_LINSYS;\n\tKN.attr(\"PARAM_PRESOLVE_INITPT\") = KN_PARAM_PRESOLVE_INITPT;\n\tKN.attr(\"PARAM_ACT_QPPENALTY\") = KN_PARAM_ACT_QPPENALTY;\n\tKN.attr(\"PARAM_BAR_LINSYS_STORAGE\") = KN_PARAM_BAR_LINSYS_STORAGE;\n\tKN.attr(\"PARAM_LINSOLVER_MAXITREF\") = KN_PARAM_LINSOLVER_MAXITREF;\n\tKN.attr(\"PARAM_BFGS_SCALING\") = KN_PARAM_BFGS_SCALING;\n\tKN.attr(\"PARAM_BAR_INITSHIFTTOL\") = KN_PARAM_BAR_INITSHIFTTOL;\n\tKN.attr(\"PARAM_NUMTHREADS\") = KN_PARAM_NUMTHREADS;\n\tKN.attr(\"PARAM_CONCURRENT_EVALS\") = KN_PARAM_CONCURRENT_EVALS;\n\tKN.attr(\"PARAM_BLAS_NUMTHREADS\") = KN_PARAM_BLAS_NUMTHREADS;\n\tKN.attr(\"PARAM_LINSOLVER_NUMTHREADS\") = KN_PARAM_LINSOLVER_NUMTHREADS;\n\tKN.attr(\"PARAM_MS_NUMTHREADS\") = KN_PARAM_MS_NUMTHREADS;\n\tKN.attr(\"PARAM_CONIC_NUMTHREADS\") = KN_PARAM_CONIC_NUMTHREADS;\n\tKN.attr(\"PARAM_NCVX_QCQP_INIT\") = KN_PARAM_NCVX_QCQP_INIT;\n\tKN.attr(\"PARAM_FINDIFF_ESTNOISE\") = KN_PARAM_FINDIFF_ESTNOISE;\n\tKN.attr(\"PARAM_FINDIFF_NUMTHREADS\") = KN_PARAM_FINDIFF_NUMTHREADS;\n\tKN.attr(\"PARAM_BAR_MPEC_HEURISTIC\") = KN_PARAM_BAR_MPEC_HEURISTIC;\n\tKN.attr(\"PARAM_PRESOLVEOP_REDUNDANT\") = KN_PARAM_PRESOLVEOP_REDUNDANT;\n\tKN.attr(\"PARAM_LINSOLVER_ORDERING\") = KN_PARAM_LINSOLVER_ORDERING;\n\tKN.attr(\"PARAM_LINSOLVER_NODEAMALG\") = KN_PARAM_LINSOLVER_NODEAMALG;\n\tKN.attr(\"PARAM_PRESOLVEOP_SUBSTITUTION\") = KN_PARAM_PRESOLVEOP_SUBSTITUTION;\n\tKN.attr(\"PARAM_PRESOLVEOP_SUBSTITUTION_TOL\") = KN_PARAM_PRESOLVEOP_SUBSTITUTION_TOL;\n\tKN.attr(\"PARAM_MS_INITPT_CLUSTER\") = KN_PARAM_MS_INITPT_CLUSTER;\n\tKN.attr(\"PARAM_SCALE_VARS\") = KN_PARAM_SCALE_VARS;\n\tKN.attr(\"PARAM_BAR_MAXMU\") = KN_PARAM_BAR_MAXMU;\n\tKN.attr(\"PARAM_BAR_GLOBALIZE\") = KN_PARAM_BAR_GLOBALIZE;\n\tKN.attr(\"PARAM_LINSOLVER_SCALING\") = KN_PARAM_LINSOLVER_SCALING;\n\tKN.attr(\"PARAM_INITPT_STRATEGY\") = KN_PARAM_INITPT_STRATEGY;\n\tKN.attr(\"PARAM_EVAL_COST\") = KN_PARAM_EVAL_COST;\n\tKN.attr(\"PARAM_MS_TERMINATERULE_TOL\") = KN_PARAM_MS_TERMINATERULE_TOL;\n\tKN.attr(\"PARAM_SOLTYPE\") = KN_PARAM_SOLTYPE;\n\tKN.attr(\"PARAM_MAXTIME\") = KN_PARAM_MAXTIME;\n\tKN.attr(\"PARAM_LP_ALGORITHM\") = KN_PARAM_LP_ALGORITHM;\n\tKN.attr(\"PARAM_LP_ALG\") = KN_PARAM_LP_ALG;\n\tKN.attr(\"PARAM_AL_INITPENALTY\") = KN_PARAM_AL_INITPENALTY;\n\tKN.attr(\"PARAM_AL_MAXPENALTY\") = KN_PARAM_AL_MAXPENALTY;\n\tKN.attr(\"PARAM_PRESOLVEOP_PROBING\") = KN_PARAM_PRESOLVEOP_PROBING;\n\n\t// Algorithm values\n\tKN.attr(\"ALG_AUTOMATIC\") = KN_ALG_AUTOMATIC;\n\tKN.attr(\"ALG_AUTO\") = KN_ALG_AUTO;\n\tKN.attr(\"ALG_BAR_DIRECT\") = KN_ALG_BAR_DIRECT;\n\tKN.attr(\"ALG_BAR_CG\") = KN_ALG_BAR_CG;\n\tKN.attr(\"ALG_ACT_CG\") = KN_ALG_ACT_CG;\n\tKN.attr(\"ALG_ACT_SQP\") = KN_ALG_ACT_SQP;\n\tKN.attr(\"ALG_MULTI\") = KN_ALG_MULTI;\n\tKN.attr(\"ALG_AL\") = KN_ALG_AL;\n\n\t// NLP Algorithm values\n\tKN.attr(\"NLP_ALG_AUTOMATIC\") = KN_NLP_ALG_AUTOMATIC;\n\tKN.attr(\"NLP_ALG_AUTO\") = KN_NLP_ALG_AUTO;\n\tKN.attr(\"NLP_ALG_BAR_DIRECT\") = KN_NLP_ALG_BAR_DIRECT;\n\tKN.attr(\"NLP_ALG_BAR_CG\") = KN_NLP_ALG_BAR_CG;\n\tKN.attr(\"NLP_ALG_ACT_CG\") = KN_NLP_ALG_ACT_CG;\n\tKN.attr(\"NLP_ALG_ACT_SQP\") = KN_NLP_ALG_ACT_SQP;\n\tKN.attr(\"NLP_ALG_MULTI\") = KN_NLP_ALG_MULTI;\n\tKN.attr(\"NLP_ALG_AL\") = KN_NLP_ALG_AL;\n\n\t// Bar murule values\n\tKN.attr(\"BAR_MURULE_AUTOMATIC\") = KN_BAR_MURULE_AUTOMATIC;\n\tKN.attr(\"BAR_MURULE_AUTO\") = KN_BAR_MURULE_AUTO;\n\tKN.attr(\"BAR_MURULE_MONOTONE\") = KN_BAR_MURULE_MONOTONE;\n\tKN.attr(\"BAR_MURULE_ADAPTIVE\") = KN_BAR_MURULE_ADAPTIVE;\n\tKN.attr(\"BAR_MURULE_PROBING\") = KN_BAR_MURULE_PROBING;\n\tKN.attr(\"BAR_MURULE_DAMPMPC\") = KN_BAR_MURULE_DAMPMPC;\n\tKN.attr(\"BAR_MURULE_FULLMPC\") = KN_BAR_MURULE_FULLMPC;\n\tKN.attr(\"BAR_MURULE_QUALITY\") = KN_BAR_MURULE_QUALITY;\n\n\t// Gradient options\n\tKN.attr(\"GRADOPT_EXACT\") = KN_GRADOPT_EXACT;\n\tKN.attr(\"GRADOPT_FORWARD\") = KN_GRADOPT_FORWARD;\n\tKN.attr(\"GRADOPT_CENTRAL\") = KN_GRADOPT_CENTRAL;\n\tKN.attr(\"GRADOPT_USER_FORWARD\") = KN_GRADOPT_USER_FORWARD;\n\tKN.attr(\"GRADOPT_USER_CENTRAL\") = KN_GRADOPT_USER_CENTRAL;\n\n\t// Hessian options\n\tKN.attr(\"HESSOPT_AUTO\") = KN_HESSOPT_AUTO;\n\tKN.attr(\"HESSOPT_EXACT\") = KN_HESSOPT_EXACT;\n\tKN.attr(\"HESSOPT_BFGS\") = KN_HESSOPT_BFGS;\n\tKN.attr(\"HESSOPT_SR1\") = KN_HESSOPT_SR1;\n\tKN.attr(\"HESSOPT_PRODUCT_FINDIFF\") = KN_HESSOPT_PRODUCT_FINDIFF;\n\tKN.attr(\"HESSOPT_PRODUCT\") = KN_HESSOPT_PRODUCT;\n\tKN.attr(\"HESSOPT_LBFGS\") = KN_HESSOPT_LBFGS;\n\tKN.attr(\"HESSOPT_GAUSS_NEWTON\") = KN_HESSOPT_GAUSS_NEWTON;\n\n\t// Output level values\n\tKN.attr(\"OUTLEV_NONE\") = KN_OUTLEV_NONE;\n\tKN.attr(\"OUTLEV_SUMMARY\") = KN_OUTLEV_SUMMARY;\n\tKN.attr(\"OUTLEV_ITER_10\") = KN_OUTLEV_ITER_10;\n\tKN.attr(\"OUTLEV_ITER\") = KN_OUTLEV_ITER;\n\tKN.attr(\"OUTLEV_ITER_VERBOSE\") = KN_OUTLEV_ITER_VERBOSE;\n\tKN.attr(\"OUTLEV_ITER_X\") = KN_OUTLEV_ITER_X;\n\tKN.attr(\"OUTLEV_ALL\") = KN_OUTLEV_ALL;\n\n\t// Linear solver values\n\tKN.attr(\"LINSOLVER_AUTO\") = KN_LINSOLVER_AUTO;\n\tKN.attr(\"LINSOLVER_INTERNAL\") = KN_LINSOLVER_INTERNAL;\n\tKN.attr(\"LINSOLVER_HYBRID\") = KN_LINSOLVER_HYBRID;\n\tKN.attr(\"LINSOLVER_DENSEQR\") = KN_LINSOLVER_DENSEQR;\n\tKN.attr(\"LINSOLVER_MA27\") = KN_LINSOLVER_MA27;\n\tKN.attr(\"LINSOLVER_MA57\") = KN_LINSOLVER_MA57;\n\tKN.attr(\"LINSOLVER_MKLPARDISO\") = KN_LINSOLVER_MKLPARDISO;\n\tKN.attr(\"LINSOLVER_MA97\") = KN_LINSOLVER_MA97;\n\tKN.attr(\"LINSOLVER_MA86\") = KN_LINSOLVER_MA86;\n\tKN.attr(\"LINSOLVER_APPLE\") = KN_LINSOLVER_APPLE;\n\n\t// Presolve values\n\tKN.attr(\"PRESOLVE_NO\") = KN_PRESOLVE_NO;\n\tKN.attr(\"PRESOLVE_YES\") = KN_PRESOLVE_YES;\n\n\t// Derivative check values\n\tKN.attr(\"DERIVCHECK_NONE\") = KN_DERIVCHECK_NONE;\n\tKN.attr(\"DERIVCHECK_FIRST\") = KN_DERIVCHECK_FIRST;\n\tKN.attr(\"DERIVCHECK_SECOND\") = KN_DERIVCHECK_SECOND;\n\tKN.attr(\"DERIVCHECK_ALL\") = KN_DERIVCHECK_ALL;\n\n\t// Linesearch values\n\tKN.attr(\"LINESEARCH_AUTO\") = KN_LINESEARCH_AUTO;\n\tKN.attr(\"LINESEARCH_BACKTRACK\") = KN_LINESEARCH_BACKTRACK;\n\tKN.attr(\"LINESEARCH_INTERPOLATE\") = KN_LINESEARCH_INTERPOLATE;\n\tKN.attr(\"LINESEARCH_WEAKWOLFE\") = KN_LINESEARCH_WEAKWOLFE;\n\n\t// LP Algorithm values\n\tKN.attr(\"LP_ALG_AUTO\") = KN_LP_ALG_AUTO;\n\tKN.attr(\"LP_ALG_NLPALGORITHM\") = KN_LP_ALG_NLPALGORITHM;\n\tKN.attr(\"LP_ALG_PRIMALSIMPLEX\") = KN_LP_ALG_PRIMALSIMPLEX;\n\tKN.attr(\"LP_ALG_DUALSIMPLEX\") = KN_LP_ALG_DUALSIMPLEX;\n\tKN.attr(\"LP_ALG_BARRIER\") = KN_LP_ALG_BARRIER;\n\tKN.attr(\"LP_ALG_PDLP\") = KN_LP_ALG_PDLP;\n\n\t// MIP parameter IDs\n\tKN.attr(\"PARAM_MIP_METHOD\") = KN_PARAM_MIP_METHOD;\n\tKN.attr(\"PARAM_MIP_BRANCHRULE\") = KN_PARAM_MIP_BRANCHRULE;\n\tKN.attr(\"PARAM_MIP_SELECTRULE\") = KN_PARAM_MIP_SELECTRULE;\n\tKN.attr(\"PARAM_MIP_OPTGAPABS\") = KN_PARAM_MIP_OPTGAPABS;\n\tKN.attr(\"PARAM_MIP_OPTGAPREL\") = KN_PARAM_MIP_OPTGAPREL;\n\tKN.attr(\"PARAM_MIP_MAXTIMECPU\") = KN_PARAM_MIP_MAXTIMECPU;\n\tKN.attr(\"PARAM_MIP_MAXTIMEREAL\") = KN_PARAM_MIP_MAXTIMEREAL;\n\tKN.attr(\"PARAM_MIP_MAXSOLVES\") = KN_PARAM_MIP_MAXSOLVES;\n\tKN.attr(\"PARAM_MIP_INTEGERTOL\") = KN_PARAM_MIP_INTEGERTOL;\n\tKN.attr(\"PARAM_MIP_OUTLEVEL\") = KN_PARAM_MIP_OUTLEVEL;\n\tKN.attr(\"PARAM_MIP_OUTINTERVAL\") = KN_PARAM_MIP_OUTINTERVAL;\n\tKN.attr(\"PARAM_MIP_OUTSUB\") = KN_PARAM_MIP_OUTSUB;\n\tKN.attr(\"PARAM_MIP_DEBUG\") = KN_PARAM_MIP_DEBUG;\n\tKN.attr(\"PARAM_MIP_IMPLICATIONS\") = KN_PARAM_MIP_IMPLICATIONS;\n\tKN.attr(\"PARAM_MIP_GUB_BRANCH\") = KN_PARAM_MIP_GUB_BRANCH;\n\tKN.attr(\"PARAM_MIP_KNAPSACK\") = KN_PARAM_MIP_KNAPSACK;\n\tKN.attr(\"PARAM_MIP_ROUNDING\") = KN_PARAM_MIP_ROUNDING;\n\tKN.attr(\"PARAM_MIP_ROOT_NLPALG\") = KN_PARAM_MIP_ROOT_NLPALG;\n\tKN.attr(\"PARAM_MIP_TERMINATE\") = KN_PARAM_MIP_TERMINATE;\n\tKN.attr(\"PARAM_MIP_MAXNODES\") = KN_PARAM_MIP_MAXNODES;\n\tKN.attr(\"PARAM_MIP_HEUR_MAXIT\") = KN_PARAM_MIP_HEUR_MAXIT;\n\tKN.attr(\"PARAM_MIP_PSEUDOINIT\") = KN_PARAM_MIP_PSEUDOINIT;\n\tKN.attr(\"PARAM_MIP_STRONG_MAXIT\") = KN_PARAM_MIP_STRONG_MAXIT;\n\tKN.attr(\"PARAM_MIP_STRONG_CANDLIM\") = KN_PARAM_MIP_STRONG_CANDLIM;\n\tKN.attr(\"PARAM_MIP_STRONG_LEVEL\") = KN_PARAM_MIP_STRONG_LEVEL;\n\tKN.attr(\"PARAM_MIP_INTVAR_STRATEGY\") = KN_PARAM_MIP_INTVAR_STRATEGY;\n\tKN.attr(\"PARAM_MIP_RELAXABLE\") = KN_PARAM_MIP_RELAXABLE;\n\tKN.attr(\"PARAM_MIP_NODE_NLPALG\") = KN_PARAM_MIP_NODE_NLPALG;\n\tKN.attr(\"PARAM_MIP_HEUR_TERMINATE\") = KN_PARAM_MIP_HEUR_TERMINATE;\n\tKN.attr(\"PARAM_MIP_SELECTDIR\") = KN_PARAM_MIP_SELECTDIR;\n\tKN.attr(\"PARAM_MIP_CUTFACTOR\") = KN_PARAM_MIP_CUTFACTOR;\n\tKN.attr(\"PARAM_MIP_ZEROHALF\") = KN_PARAM_MIP_ZEROHALF;\n\tKN.attr(\"PARAM_MIP_MIR\") = KN_PARAM_MIP_MIR;\n\tKN.attr(\"PARAM_MIP_CLIQUE\") = KN_PARAM_MIP_CLIQUE;\n\tKN.attr(\"PARAM_MIP_HEUR_STRATEGY\") = KN_PARAM_MIP_HEUR_STRATEGY;\n\tKN.attr(\"PARAM_MIP_HEUR_FEASPUMP\") = KN_PARAM_MIP_HEUR_FEASPUMP;\n\tKN.attr(\"PARAM_MIP_HEUR_MPEC\") = KN_PARAM_MIP_HEUR_MPEC;\n\tKN.attr(\"PARAM_MIP_HEUR_DIVING\") = KN_PARAM_MIP_HEUR_DIVING;\n\tKN.attr(\"PARAM_MIP_CUTTINGPLANE\") = KN_PARAM_MIP_CUTTINGPLANE;\n\tKN.attr(\"PARAM_MIP_CUTOFF\") = KN_PARAM_MIP_CUTOFF;\n\tKN.attr(\"PARAM_MIP_HEUR_LNS\") = KN_PARAM_MIP_HEUR_LNS;\n\tKN.attr(\"PARAM_MIP_MULTISTART\") = KN_PARAM_MIP_MULTISTART;\n\tKN.attr(\"PARAM_MIP_LIFTPROJECT\") = KN_PARAM_MIP_LIFTPROJECT;\n\tKN.attr(\"PARAM_MIP_NUMTHREADS\") = KN_PARAM_MIP_NUMTHREADS;\n\tKN.attr(\"PARAM_MIP_HEUR_MISQP\") = KN_PARAM_MIP_HEUR_MISQP;\n\tKN.attr(\"PARAM_MIP_RESTART\") = KN_PARAM_MIP_RESTART;\n\tKN.attr(\"PARAM_MIP_GOMORY\") = KN_PARAM_MIP_GOMORY;\n\tKN.attr(\"PARAM_MIP_CUT_PROBING\") = KN_PARAM_MIP_CUT_PROBING;\n\tKN.attr(\"PARAM_MIP_CUT_FLOWCOVER\") = KN_PARAM_MIP_CUT_FLOWCOVER;\n\tKN.attr(\"PARAM_MIP_HEUR_LOCALSEARCH\") = KN_PARAM_MIP_HEUR_LOCALSEARCH;\n\tKN.attr(\"PARAM_MIP_ROOT_LPALG\") = KN_PARAM_MIP_ROOT_LPALG;\n\tKN.attr(\"PARAM_MIP_NODE_LPALG\") = KN_PARAM_MIP_NODE_LPALG;\n\n\t// MIP method values\n\tKN.attr(\"MIP_METHOD_AUTO\") = KN_MIP_METHOD_AUTO;\n\tKN.attr(\"MIP_METHOD_BB\") = KN_MIP_METHOD_BB;\n\tKN.attr(\"MIP_METHOD_HQG\") = KN_MIP_METHOD_HQG;\n\tKN.attr(\"MIP_METHOD_MISQP\") = KN_MIP_METHOD_MISQP;\n\n\t// MIP branch rule values\n\tKN.attr(\"MIP_BRANCH_AUTO\") = KN_MIP_BRANCH_AUTO;\n\tKN.attr(\"MIP_BRANCH_MOSTFRAC\") = KN_MIP_BRANCH_MOSTFRAC;\n\tKN.attr(\"MIP_BRANCH_PSEUDOCOST\") = KN_MIP_BRANCH_PSEUDOCOST;\n\tKN.attr(\"MIP_BRANCH_STRONG\") = KN_MIP_BRANCH_STRONG;\n\n\t// MIP select rule values\n\tKN.attr(\"MIP_SEL_AUTO\") = KN_MIP_SEL_AUTO;\n\tKN.attr(\"MIP_SEL_DEPTHFIRST\") = KN_MIP_SEL_DEPTHFIRST;\n\tKN.attr(\"MIP_SEL_BESTBOUND\") = KN_MIP_SEL_BESTBOUND;\n\tKN.attr(\"MIP_SEL_COMBO_1\") = KN_MIP_SEL_COMBO_1;\n\n\t// MIP terminate values\n\tKN.attr(\"MIP_TERMINATE_OPTIMAL\") = KN_MIP_TERMINATE_OPTIMAL;\n\tKN.attr(\"MIP_TERMINATE_FEASIBLE\") = KN_MIP_TERMINATE_FEASIBLE;\n\n\t// MIP output level values\n\tKN.attr(\"MIP_OUTLEVEL_NONE\") = KN_MIP_OUTLEVEL_NONE;\n\tKN.attr(\"MIP_OUTLEVEL_ITERS\") = KN_MIP_OUTLEVEL_ITERS;\n\tKN.attr(\"MIP_OUTLEVEL_ITERSTIME\") = KN_MIP_OUTLEVEL_ITERSTIME;\n\tKN.attr(\"MIP_OUTLEVEL_ROOT\") = KN_MIP_OUTLEVEL_ROOT;\n\n\t// MIP rounding values\n\tKN.attr(\"MIP_ROUND_AUTO\") = KN_MIP_ROUND_AUTO;\n\tKN.attr(\"MIP_ROUND_NONE\") = KN_MIP_ROUND_NONE;\n\tKN.attr(\"MIP_ROUND_HEURISTIC\") = KN_MIP_ROUND_HEURISTIC;\n\tKN.attr(\"MIP_ROUND_NLP_SOME\") = KN_MIP_ROUND_NLP_SOME;\n\tKN.attr(\"MIP_ROUND_NLP_ALWAYS\") = KN_MIP_ROUND_NLP_ALWAYS;\n\n\t// MIP heuristic strategy values\n\tKN.attr(\"MIP_HEUR_STRATEGY_AUTO\") = KN_MIP_HEUR_STRATEGY_AUTO;\n\tKN.attr(\"MIP_HEUR_STRATEGY_NONE\") = KN_MIP_HEUR_STRATEGY_NONE;\n\tKN.attr(\"MIP_HEUR_STRATEGY_BASIC\") = KN_MIP_HEUR_STRATEGY_BASIC;\n\tKN.attr(\"MIP_HEUR_STRATEGY_ADVANCED\") = KN_MIP_HEUR_STRATEGY_ADVANCED;\n\tKN.attr(\"MIP_HEUR_STRATEGY_EXTENSIVE\") = KN_MIP_HEUR_STRATEGY_EXTENSIVE;\n}\n"
  },
  {
    "path": "lib/main.cpp",
    "content": "#include \"pyoptinterface/nleval.hpp\"\n#include \"pyoptinterface/cppad_interface.hpp\"\n\nvoid test_linear_eval()\n{\n\tLinearEvaluator evaluator;\n\t{\n\t\tScalarAffineFunction f;\n\t\tf.add_constant(1.0);\n\t\tf.add_term(0, 2.0);\n\n\t\tevaluator.add_row(f);\n\t}\n\n\t{\n\t\tScalarAffineFunction f;\n\t\tf.add_term(1, 3.0);\n\t\tf.add_term(0, 4.0);\n\t\tevaluator.add_row(f);\n\t}\n\n\tstd::vector<double> x = {1.0, 2.0};\n\tstd::vector<double> f(2);\n\tevaluator.eval_function(x.data(), f.data());\n\n\tsize_t global_jabobian_nnz = 0;\n\tstd::vector<int> global_jacobian_rows, global_jacobian_cols;\n\tevaluator.analyze_jacobian_structure(global_jabobian_nnz, global_jacobian_rows,\n\t                                     global_jacobian_cols);\n\n\tstd::vector<double> jacobian(global_jabobian_nnz);\n\tevaluator.eval_jacobian(x.data(), jacobian.data());\n}\n\nvoid test_quadratic_eval()\n{\n\tQuadraticEvaluator evaluator;\n\t{\n\t\tScalarQuadraticFunction f;\n\t\tf.add_constant(1.0);\n\t\tf.add_quadratic_term(0, 1, 4.0);\n\t\tf.add_quadratic_term(0, 0, 1.0);\n\t\tf.add_affine_term(0, 4.0);\n\t\tevaluator.add_row(f);\n\t}\n\tstd::vector<double> x = {1.0, 2.0};\n\tstd::vector<double> f(1);\n\tevaluator.eval_function(x.data(), f.data());\n\tsize_t global_jabobian_nnz = 0;\n\tstd::vector<int> global_jacobian_rows, global_jacobian_cols;\n\tevaluator.analyze_jacobian_structure(0, global_jabobian_nnz, global_jacobian_rows,\n\t                                     global_jacobian_cols);\n\tstd::vector<double> jacobian(global_jabobian_nnz);\n\tevaluator.eval_jacobian(x.data(), jacobian.data());\n\tsize_t global_hessian_nnz = 0;\n\tstd::vector<int> global_hessian_rows, global_hessian_cols;\n\tHashmap<std::tuple<int, int>, int> global_hessian_index_map;\n\tHessianSparsityType global_hessian_type = HessianSparsityType::Upper;\n\tevaluator.analyze_hessian_structure(global_hessian_nnz, global_hessian_rows,\n\t                                    global_hessian_cols, global_hessian_index_map,\n\t                                    global_hessian_type);\n\tstd::vector<double> hessian(global_hessian_nnz);\n\tstd::vector<double> lambda = {1.0};\n\tevaluator.eval_lagrangian_hessian(lambda.data(), hessian.data());\n}\n\nvoid test_cppad_pow_var_par()\n{\n\tstd::vector<CppAD::AD<double>> x(2);\n\n\tauto N_parameters = 2;\n\tstd::vector<CppAD::AD<double>> p(N_parameters);\n\tfor (size_t i = 0; i < N_parameters; i++)\n\t{\n\t\tp[i] = CppAD::AD<double>(i + 1);\n\t}\n\tif (N_parameters > 0)\n\t{\n\t\tCppAD::Independent(x, p);\n\t}\n\telse\n\t{\n\t\tCppAD::Independent(x);\n\t}\n\n\tauto N_outputs = 1;\n\tstd::vector<CppAD::AD<double>> y(N_outputs);\n\n\t// Trace the outputs\n\tfor (size_t i = 0; i < N_outputs; i++)\n\t{\n\t\ty[i] = CppAD::pow(x[i], p[i]);\n\t}\n\n\tADFunDouble f;\n\tf.Dependent(x, y);\n\n\tCppAD::cpp_graph f_graph;\n\tf.to_graph(f_graph);\n\n\t// Print the graph\n\tf_graph.print(std::cout);\n}\n\nauto main() -> int\n{\n\ttest_cppad_pow_var_par();\n\treturn 0;\n}"
  },
  {
    "path": "lib/mosek_model.cpp",
    "content": "#include \"pyoptinterface/mosek_model.hpp\"\n#include \"fmt/core.h\"\n\nnamespace mosek\n{\n#define B DYLIB_DECLARE\nAPILIST\n#undef B\n\nstatic DynamicLibrary lib;\nstatic bool is_loaded = false;\n\nbool is_library_loaded()\n{\n\treturn is_loaded;\n}\n\nbool load_library(const std::string &path)\n{\n\tbool success = lib.try_load(path.c_str());\n\tif (!success)\n\t{\n\t\treturn false;\n\t}\n\n\tDYLIB_LOAD_INIT;\n\n#define B DYLIB_LOAD_FUNCTION\n\tAPILIST\n#undef B\n\n\tif (IS_DYLIB_LOAD_SUCCESS)\n\t{\n#define B DYLIB_SAVE_FUNCTION\n\t\tAPILIST\n#undef B\n\t\tis_loaded = true;\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\treturn false;\n\t}\n}\n} // namespace mosek\n\n// specialize the template for MOSEK\ntemplate <>\ntemplate <>\nvoid QuadraticFunctionPtrForm<MSKint32t, MSKint32t, MSKrealt>::make<MOSEKModel>(\n    MOSEKModel *model, const ScalarQuadraticFunction &function)\n{\n\tauto f_numnz = function.size();\n\tnumnz = f_numnz;\n\trow_storage.resize(numnz);\n\tcol_storage.resize(numnz);\n\tfor (int i = 0; i < numnz; ++i)\n\t{\n\t\tauto v1 = model->_variable_index(function.variable_1s[i]);\n\t\tauto v2 = v1;\n\t\tif (function.variable_1s[i] != function.variable_2s[i])\n\t\t{\n\t\t\tv2 = model->_variable_index(function.variable_2s[i]);\n\t\t\t// MOSEK only accepts the lower triangle (i >= j)\n\t\t\tif (v1 < v2)\n\t\t\t{\n\t\t\t\tstd::swap(v1, v2);\n\t\t\t}\n\t\t}\n\n\t\trow_storage[i] = v1;\n\t\tcol_storage[i] = v2;\n\t}\n\trow = row_storage.data();\n\tcol = col_storage.data();\n\n\t// MOSEK has 1/2 * x^T @ Q @ x, so we need to multiply the coefficient by 2 for diagonal terms\n\tvalue_storage.resize(numnz);\n\tfor (int i = 0; i < numnz; ++i)\n\t{\n\t\tif (function.variable_1s[i] == function.variable_2s[i])\n\t\t{\n\t\t\tvalue_storage[i] = 2 * function.coefficients[i];\n\t\t}\n\t\telse\n\t\t{\n\t\t\tvalue_storage[i] = function.coefficients[i];\n\t\t}\n\t}\n\tvalue = value_storage.data();\n}\n\nstatic void check_error(MSKrescodee error)\n{\n\tif (error != MSK_RES_OK)\n\t{\n\t\tchar symname[MSK_MAX_STR_LEN];\n\t\tchar desc[MSK_MAX_STR_LEN];\n\t\tmosek::MSK_getcodedesc(error, symname, desc);\n\n\t\tstd::string errmsg = fmt::format(\"Error {} : {}\", symname, desc);\n\n\t\tthrow std::runtime_error(errmsg);\n\t}\n}\n\nstatic MSKboundkeye mosek_con_sense(ConstraintSense sense)\n{\n\tswitch (sense)\n\t{\n\tcase ConstraintSense::LessEqual:\n\t\treturn MSK_BK_UP;\n\tcase ConstraintSense::Equal:\n\t\treturn MSK_BK_FX;\n\tcase ConstraintSense::GreaterEqual:\n\t\treturn MSK_BK_LO;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint sense\");\n\t}\n}\n\nstatic MSKobjsensee mosek_obj_sense(ObjectiveSense sense)\n{\n\tswitch (sense)\n\t{\n\tcase ObjectiveSense::Minimize:\n\t\treturn MSK_OBJECTIVE_SENSE_MINIMIZE;\n\tcase ObjectiveSense::Maximize:\n\t\treturn MSK_OBJECTIVE_SENSE_MAXIMIZE;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown objective sense\");\n\t}\n}\n\nstatic MSKvariabletypee mosek_vtype(VariableDomain domain)\n{\n\tswitch (domain)\n\t{\n\tcase VariableDomain::Continuous:\n\t\treturn MSK_VAR_TYPE_CONT;\n\tcase VariableDomain::Integer:\n\tcase VariableDomain::Binary:\n\t\treturn MSK_VAR_TYPE_INT;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown variable domain\");\n\t}\n}\n\nstatic VariableDomain mosek_vtype_to_domain(MSKvariabletypee vtype)\n{\n\tswitch (vtype)\n\t{\n\tcase MSK_VAR_TYPE_CONT:\n\t\treturn VariableDomain::Continuous;\n\tcase MSK_VAR_TYPE_INT:\n\t\treturn VariableDomain::Integer;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown variable domain\");\n\t}\n}\n\nMOSEKModel::MOSEKModel(const MOSEKEnv &env)\n{\n\tinit(env);\n}\n\nvoid MOSEKModel::init(const MOSEKEnv &env)\n{\n\tif (!mosek::is_library_loaded())\n\t{\n\t\tthrow std::runtime_error(\"Mosek library is not loaded\");\n\t}\n\tMSKtask_t model;\n\tauto error = mosek::MSK_makeemptytask(env.m_env, &model);\n\tcheck_error(error);\n\tm_model = std::unique_ptr<MSKtask, MOSEKfreemodelT>(model);\n}\n\nvoid MOSEKModel::close()\n{\n\tm_model.reset();\n}\n\nvoid MOSEKModel::write(const std::string &filename)\n{\n\tbool is_solution = false;\n\tif (filename.ends_with(\".sol\") || filename.ends_with(\".bas\") || filename.ends_with(\".int\") ||\n\t    filename.ends_with(\".jsol\"))\n\t{\n\t\tis_solution = true;\n\t}\n\tMSKrescodee error;\n\tif (is_solution)\n\t{\n\t\tif (m_soltype)\n\t\t{\n\t\t\terror = mosek::MSK_writesolution(m_model.get(), m_soltype.value(), filename.c_str());\n\t\t}\n\t\telse\n\t\t{\n\t\t\tthrow std::runtime_error(\n\t\t\t    \"Solution type is unavailable. Please optimize before writing solution.\");\n\t\t}\n\t}\n\telse\n\t{\n\t\terror = mosek::MSK_writedata(m_model.get(), filename.c_str());\n\t}\n\tcheck_error(error);\n}\n\nVariableIndex MOSEKModel::add_variable(VariableDomain domain, double lb, double ub,\n                                       const char *name)\n{\n\tm_is_dirty = true;\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\tIndexT index = m_variable_index.add_index();\n\tVariableIndex variable(index);\n\n\tauto error = mosek::MSK_appendvars(m_model.get(), 1);\n\tcheck_error(error);\n\n\tMSKint32t column;\n\terror = mosek::MSK_getnumvar(m_model.get(), &column);\n\tcheck_error(error);\n\t// 0-based indexing\n\tcolumn -= 1;\n\n\tauto vtype = mosek_vtype(domain);\n\terror = mosek::MSK_putvartype(m_model.get(), column, vtype);\n\tcheck_error(error);\n\n\tMSKboundkeye bk;\n\tif (domain == VariableDomain::Binary)\n\t{\n\t\tbk = MSK_BK_RA;\n\t\tlb = 0.0;\n\t\tub = 1.0;\n\t\tbinary_variables.insert(index);\n\t}\n\telse\n\t{\n\t\tbool lb_inf = lb < 1.0 - MSK_INFINITY;\n\t\tbool ub_inf = ub > MSK_INFINITY - 1.0;\n\t\tif (lb_inf && ub_inf)\n\t\t\tbk = MSK_BK_FR;\n\t\telse if (lb_inf)\n\t\t\tbk = MSK_BK_UP;\n\t\telse if (ub_inf)\n\t\t\tbk = MSK_BK_LO;\n\t\telse\n\t\t\tbk = MSK_BK_RA;\n\t}\n\terror = mosek::MSK_putvarbound(m_model.get(), column, bk, lb, ub);\n\tcheck_error(error);\n\n\tif (name)\n\t{\n\t\terror = mosek::MSK_putvarname(m_model.get(), column, name);\n\t\tcheck_error(error);\n\t}\n\n\treturn variable;\n}\n\n// VariableIndex MOSEKModel::add_variables(int N, VariableDomain domain, double lb, double ub)\n//{\n//\tIndexT index = m_variable_index.add_indices(N);\n//\tVariableIndex variable(index);\n//\n//\tauto error = MSK_appendvars(m_model.get(), N);\n//\tcheck_error(error);\n//\n//\tMSKint32t column;\n//\terror = MSK_getnumvar(m_model.get(), &column);\n//\tcheck_error(error);\n//\t// 0-based indexing\n//\tcolumn -= N;\n//\tstd::vector<MSKint32t> columns(N);\n//\tfor (int i = 0; i < N; i++)\n//\t{\n//\t\tcolumns[i] = column + i;\n//\t}\n//\n//\tMSKvariabletypee vtype = mosek_vtype(domain);\n//\tstd::vector<MSKvariabletypee> vtypes(N, vtype);\n//\terror = MSK_putvartypelist(m_model.get(), N, columns.data(), vtypes.data());\n//\tcheck_error(error);\n//\n//\tMSKboundkeye bk;\n//\tif (domain == VariableDomain::Binary)\n//\t{\n//\t\tbk = MSK_BK_RA;\n//\t\tlb = 0.0;\n//\t\tub = 1.0;\n//\t\tfor (int i = 0; i < N; i++)\n//\t\t{\n//\t\t\tbinary_variables.insert(index + i);\n//\t\t}\n//\t}\n//\telse\n//\t{\n//\t\tbool lb_inf = lb < 1.0 - MSK_INFINITY;\n//\t\tbool ub_inf = ub > MSK_INFINITY - 1.0;\n//\t\tif (lb_inf && ub_inf)\n//\t\t\tbk = MSK_BK_FR;\n//\t\telse if (lb_inf)\n//\t\t\tbk = MSK_BK_UP;\n//\t\telse if (ub_inf)\n//\t\t\tbk = MSK_BK_LO;\n//\t\telse\n//\t\t\tbk = MSK_BK_RA;\n//\t}\n//\tstd::vector<MSKboundkeye> bks(N, bk);\n//\tstd::vector<MSKrealt> lbs(N, lb);\n//\tstd::vector<MSKrealt> ubs(N, ub);\n//\terror =\n//\t    MSK_putvarboundlist(m_model.get(), N, columns.data(), bks.data(), lbs.data(), ubs.data());\n//\tcheck_error(error);\n//\n//\treturn variable;\n// }\n\nvoid MOSEKModel::delete_variable(const VariableIndex &variable)\n{\n\tm_is_dirty = true;\n\tif (!is_variable_active(variable))\n\t{\n\t\tthrow std::runtime_error(\"Variable does not exist\");\n\t}\n\n\tint variable_column = _variable_index(variable);\n\tauto error = mosek::MSK_removevars(m_model.get(), 1, &variable_column);\n\tcheck_error(error);\n\n\tm_variable_index.delete_index(variable.index);\n\tbinary_variables.erase(variable.index);\n}\n\nvoid MOSEKModel::delete_variables(const Vector<VariableIndex> &variables)\n{\n\tm_is_dirty = true;\n\tint n_variables = variables.size();\n\tif (n_variables == 0)\n\t\treturn;\n\n\tstd::vector<MSKint32t> columns;\n\tcolumns.reserve(n_variables);\n\tfor (int i = 0; i < n_variables; i++)\n\t{\n\t\tif (!is_variable_active(variables[i]))\n\t\t{\n\t\t\tcontinue;\n\t\t}\n\t\tauto column = _variable_index(variables[i]);\n\t\tcolumns.push_back(column);\n\t}\n\n\tauto error = mosek::MSK_removevars(m_model.get(), columns.size(), columns.data());\n\tcheck_error(error);\n\n\tfor (int i = 0; i < n_variables; i++)\n\t{\n\t\tm_variable_index.delete_index(variables[i].index);\n\t}\n}\n\nbool MOSEKModel::is_variable_active(const VariableIndex &variable)\n{\n\treturn m_variable_index.has_index(variable.index);\n}\n\ndouble MOSEKModel::get_variable_value(const VariableIndex &variable)\n{\n\tauto column = _checked_variable_index(variable);\n\tMSKrealt retval;\n\tauto soltype = get_current_solution();\n\tauto error = mosek::MSK_getxxslice(m_model.get(), soltype, column, column + 1, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nstd::string MOSEKModel::pprint_variable(const VariableIndex &variable)\n{\n\treturn get_variable_name(variable);\n}\n\nvoid MOSEKModel::set_variable_bounds(const VariableIndex &variable, double lb, double ub)\n{\n\tm_is_dirty = true;\n\tauto column = _checked_variable_index(variable);\n\tMSKboundkeye bk;\n\tif (lb == ub)\n\t{\n\t\tbk = MSK_BK_FX;\n\t}\n\telse\n\t{\n\t\tbk = MSK_BK_RA;\n\t}\n\tauto error = mosek::MSK_putvarbound(m_model.get(), column, bk, lb, ub);\n\tcheck_error(error);\n}\n\nConstraintIndex MOSEKModel::add_linear_constraint(const ScalarAffineFunction &function,\n                                                  ConstraintSense sense, CoeffT rhs,\n                                                  const char *name)\n{\n\tm_is_dirty = true;\n\tIndexT index = m_linear_quadratic_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::Linear, index);\n\n\tauto error = mosek::MSK_appendcons(m_model.get(), 1);\n\tcheck_error(error);\n\n\tMSKint32t row;\n\terror = mosek::MSK_getnumcon(m_model.get(), &row);\n\tcheck_error(error);\n\t// 0-based indexing\n\trow -= 1;\n\n\tAffineFunctionPtrForm<MSKint32t, MSKint32t, MSKrealt> ptr_form;\n\tptr_form.make(this, function);\n\n\tMSKint32t numnz = ptr_form.numnz;\n\tMSKint32t *cind = ptr_form.index;\n\tMSKrealt *cval = ptr_form.value;\n\tMSKboundkeye g_sense = mosek_con_sense(sense);\n\tMSKrealt g_rhs = rhs - function.constant.value_or(0.0);\n\n\terror = mosek::MSK_putarow(m_model.get(), row, numnz, cind, cval);\n\tcheck_error(error);\n\terror = mosek::MSK_putconbound(m_model.get(), row, g_sense, g_rhs, g_rhs);\n\tcheck_error(error);\n\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\tif (name)\n\t{\n\t\terror = mosek::MSK_putconname(m_model.get(), row, name);\n\t\tcheck_error(error);\n\t}\n\n\treturn constraint_index;\n}\n\nConstraintIndex MOSEKModel::add_linear_constraint(const ScalarAffineFunction &function,\n                                                  const std::tuple<double, double> &interval,\n                                                  const char *name)\n{\n\tm_is_dirty = true;\n\tIndexT index = m_linear_quadratic_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::Linear, index);\n\n\tauto error = mosek::MSK_appendcons(m_model.get(), 1);\n\tcheck_error(error);\n\n\tMSKint32t row;\n\terror = mosek::MSK_getnumcon(m_model.get(), &row);\n\tcheck_error(error);\n\t// 0-based indexing\n\trow -= 1;\n\n\tAffineFunctionPtrForm<MSKint32t, MSKint32t, MSKrealt> ptr_form;\n\tptr_form.make(this, function);\n\n\tMSKint32t numnz = ptr_form.numnz;\n\tMSKint32t *cind = ptr_form.index;\n\tMSKrealt *cval = ptr_form.value;\n\tdouble lb = std::get<0>(interval);\n\tdouble ub = std::get<1>(interval);\n\tif (function.constant.has_value())\n\t{\n\t\tlb -= function.constant.value();\n\t\tub -= function.constant.value();\n\t}\n\n\terror = mosek::MSK_putarow(m_model.get(), row, numnz, cind, cval);\n\tcheck_error(error);\n\terror = mosek::MSK_putconbound(m_model.get(), row, MSK_BK_RA, lb, ub);\n\tcheck_error(error);\n\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\tif (name)\n\t{\n\t\terror = mosek::MSK_putconname(m_model.get(), row, name);\n\t\tcheck_error(error);\n\t}\n\n\treturn constraint_index;\n}\n\nConstraintIndex MOSEKModel::add_quadratic_constraint(const ScalarQuadraticFunction &function,\n                                                     ConstraintSense sense, CoeffT rhs,\n                                                     const char *name)\n{\n\tm_is_dirty = true;\n\tIndexT index = m_linear_quadratic_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::Quadratic, index);\n\n\tauto error = mosek::MSK_appendcons(m_model.get(), 1);\n\tcheck_error(error);\n\n\tMSKint32t row;\n\terror = mosek::MSK_getnumcon(m_model.get(), &row);\n\tcheck_error(error);\n\t// 0-based indexing\n\trow -= 1;\n\n\tconst auto &affine_part = function.affine_part;\n\n\tMSKint32t numlnz = 0;\n\tMSKint32t *lind = NULL;\n\tMSKrealt *lval = NULL;\n\tAffineFunctionPtrForm<MSKint32t, MSKint32t, MSKrealt> affine_ptr_form;\n\tif (affine_part.has_value())\n\t{\n\t\tconst auto &affine_function = affine_part.value();\n\t\taffine_ptr_form.make(this, affine_function);\n\t\tnumlnz = affine_ptr_form.numnz;\n\t\tlind = affine_ptr_form.index;\n\t\tlval = affine_ptr_form.value;\n\t}\n\n\tQuadraticFunctionPtrForm<MSKint32t, MSKint32t, MSKrealt> ptr_form;\n\tptr_form.make(this, function);\n\tMSKint32t numqnz = ptr_form.numnz;\n\tMSKint32t *qrow = ptr_form.row;\n\tMSKint32t *qcol = ptr_form.col;\n\tMSKrealt *qval = ptr_form.value;\n\n\tMSKboundkeye g_sense = mosek_con_sense(sense);\n\tMSKrealt g_rhs = rhs;\n\tif (affine_part)\n\t\tg_rhs -= affine_part->constant.value_or(0.0);\n\n\terror = mosek::MSK_putarow(m_model.get(), row, numlnz, lind, lval);\n\tcheck_error(error);\n\terror = mosek::MSK_putqconk(m_model.get(), row, numqnz, qrow, qcol, qval);\n\tcheck_error(error);\n\terror = mosek::MSK_putconbound(m_model.get(), row, g_sense, g_rhs, g_rhs);\n\tcheck_error(error);\n\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\tif (name)\n\t{\n\t\terror = mosek::MSK_putconname(m_model.get(), row, name);\n\t\tcheck_error(error);\n\t}\n\n\treturn constraint_index;\n}\n\nstd::vector<MSKint64t> MOSEKModel::add_variables_as_afe(const Vector<VariableIndex> &variables)\n{\n\tm_is_dirty = true;\n\tauto N = variables.size();\n\n\t// afe part\n\tMSKint64t numafe;\n\tauto error = mosek::MSK_getnumafe(m_model.get(), &numafe);\n\tcheck_error(error);\n\n\tstd::vector<MSKint64t> afe_index(N);\n\tfor (int i = 0; i < N; i++)\n\t{\n\t\tafe_index[i] = numafe + i;\n\t}\n\n\tstd::vector<MSKint32t> var_index(N);\n\tfor (int i = 0; i < N; i++)\n\t{\n\t\tvar_index[i] = _checked_variable_index(variables[i]);\n\t}\n\n\tstd::vector<MSKrealt> vals(N, 1.0);\n\n\terror = mosek::MSK_appendafes(m_model.get(), N);\n\tcheck_error(error);\n\n\terror = mosek::MSK_putafefentrylist(m_model.get(), N, afe_index.data(), var_index.data(),\n\t                                    vals.data());\n\tcheck_error(error);\n\n\treturn afe_index;\n}\n\nConstraintIndex MOSEKModel::add_variables_in_cone_constraint(const Vector<VariableIndex> &variables,\n                                                             MSKint64t domain_index,\n                                                             ConstraintType type, const char *name)\n{\n\tm_is_dirty = true;\n\tauto N = variables.size();\n\n\tIndexT index = m_acc_index.size();\n\tm_acc_index.push_back(true);\n\tConstraintIndex constraint_index(type, index);\n\n\t// afe part\n\tstd::vector<MSKint64t> afe_index = add_variables_as_afe(variables);\n\n\t// domain part\n\n\t// add acc\n\tauto error = mosek::MSK_appendacc(m_model.get(), domain_index, N, afe_index.data(), nullptr);\n\tcheck_error(error);\n\n\t// set name\n\tif (name != nullptr && name[0] == '\\0')\n\t{\n\t\tname = nullptr;\n\t}\n\tif (name)\n\t{\n\t\terror = mosek::MSK_putaccname(m_model.get(), index, name);\n\t\tcheck_error(error);\n\t}\n\n\treturn constraint_index;\n}\n\nConstraintIndex MOSEKModel::add_second_order_cone_constraint(const Vector<VariableIndex> &variables,\n                                                             const char *name, bool rotated)\n{\n\tm_is_dirty = true;\n\tauto N = variables.size();\n\n\t// domain part\n\tMSKint64t domain_index;\n\tMSKrescodee error;\n\tif (rotated)\n\t{\n\t\terror = mosek::MSK_appendrquadraticconedomain(m_model.get(), N, &domain_index);\n\t}\n\telse\n\t{\n\t\terror = mosek::MSK_appendquadraticconedomain(m_model.get(), N, &domain_index);\n\t}\n\tcheck_error(error);\n\n\tauto con = add_variables_in_cone_constraint(variables, domain_index,\n\t                                            ConstraintType::SecondOrderCone, name);\n\n\treturn con;\n}\n\nConstraintIndex MOSEKModel::add_exp_cone_constraint(const Vector<VariableIndex> &variables,\n                                                    const char *name, bool dual)\n{\n\tm_is_dirty = true;\n\tauto N = variables.size();\n\tif (N != 3)\n\t{\n\t\tthrow std::runtime_error(\"Exponential cone constraint must have 3 variables\");\n\t}\n\n\t// domain part\n\tMSKint64t domain_index;\n\tMSKrescodee error;\n\tif (dual)\n\t{\n\t\terror = mosek::MSK_appenddualexpconedomain(m_model.get(), &domain_index);\n\t}\n\telse\n\t{\n\t\terror = mosek::MSK_appendprimalexpconedomain(m_model.get(), &domain_index);\n\t}\n\tcheck_error(error);\n\n\tauto con = add_variables_in_cone_constraint(variables, domain_index,\n\t                                            ConstraintType::ExponentialCone, name);\n\n\treturn con;\n}\n\nvoid MOSEKModel::delete_constraint(const ConstraintIndex &constraint)\n{\n\tm_is_dirty = true;\n\tMSKrescodee error;\n\tMSKint32t constraint_row = _constraint_index(constraint);\n\tif (constraint_row < 0)\n\t\treturn;\n\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\tcase ConstraintType::Quadratic:\n\t\tm_linear_quadratic_constraint_index.delete_index(constraint.index);\n\t\terror = mosek::MSK_removecons(m_model.get(), 1, &constraint_row);\n\t\tbreak;\n\tcase ConstraintType::SecondOrderCone:\n\tcase ConstraintType::ExponentialCone: {\n\t\tm_acc_index[constraint.index] = false;\n\t\t// ACC cannot be deleted, we just set its domain to R^n (no constraint)\n\t\t// get the dimension of this ACC\n\t\tMSKint64t N;\n\t\terror = mosek::MSK_getaccn(m_model.get(), constraint_row, &N);\n\t\tcheck_error(error);\n\t\t// get AFE list of ACC\n\t\tstd::vector<MSKint64t> afeidxlist(N);\n\t\terror = mosek::MSK_getaccafeidxlist(m_model.get(), constraint_row, afeidxlist.data());\n\t\tcheck_error(error);\n\t\t// add a N-dim Rn domain\n\t\tMSKint64t domain_index;\n\t\terror = mosek::MSK_appendrdomain(m_model.get(), N, &domain_index);\n\t\tcheck_error(error);\n\t\t// set the ACC to this domain\n\t\terror = mosek::MSK_putacc(m_model.get(), constraint_row, domain_index, N, afeidxlist.data(),\n\t\t                          nullptr);\n\t\tcheck_error(error);\n\t}\n\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n\tcheck_error(error);\n}\n\nbool MOSEKModel::is_constraint_active(const ConstraintIndex &constraint)\n{\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\tcase ConstraintType::Quadratic:\n\t\treturn m_linear_quadratic_constraint_index.has_index(constraint.index);\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n}\n\nvoid MOSEKModel::_set_affine_objective(const ScalarAffineFunction &function, ObjectiveSense sense,\n                                       bool clear_quadratic)\n{\n\tMSKrescodee error;\n\tif (clear_quadratic)\n\t{\n\t\t// First delete all quadratic terms\n\t\terror = mosek::MSK_putqobj(m_model.get(), 0, nullptr, nullptr, nullptr);\n\t\tcheck_error(error);\n\t}\n\n\t// Set Obj attribute of each variable\n\tMSKint32t n_variables;\n\terror = mosek::MSK_getnumvar(m_model.get(), &n_variables);\n\tcheck_error(error);\n\tstd::vector<MSKrealt> obj_v(n_variables, 0.0);\n\n\tint numnz = function.size();\n\tfor (int i = 0; i < numnz; i++)\n\t{\n\t\tauto column = _variable_index(function.variables[i]);\n\t\tif (column < 0)\n\t\t{\n\t\t\tthrow std::runtime_error(\"Variable does not exist\");\n\t\t}\n\t\tobj_v[column] = function.coefficients[i];\n\t}\n\n\terror = mosek::MSK_putcslice(m_model.get(), 0, n_variables, obj_v.data());\n\tcheck_error(error);\n\terror = mosek::MSK_putcfix(m_model.get(), function.constant.value_or(0.0));\n\tcheck_error(error);\n\n\tMSKobjsensee obj_sense = mosek_obj_sense(sense);\n\terror = mosek::MSK_putobjsense(m_model.get(), obj_sense);\n\tcheck_error(error);\n}\n\nvoid MOSEKModel::set_objective(const ScalarAffineFunction &function, ObjectiveSense sense)\n{\n\tm_is_dirty = true;\n\t_set_affine_objective(function, sense, true);\n}\n\nvoid MOSEKModel::set_objective(const ScalarQuadraticFunction &function, ObjectiveSense sense)\n{\n\tm_is_dirty = true;\n\tMSKrescodee error;\n\n\t// Add quadratic term\n\tint numqnz = function.size();\n\tif (numqnz > 0)\n\t{\n\t\tQuadraticFunctionPtrForm<MSKint32t, MSKint32t, MSKrealt> ptr_form;\n\t\tptr_form.make(this, function);\n\t\tMSKint32t numqnz = ptr_form.numnz;\n\t\tMSKint32t *qrow = ptr_form.row;\n\t\tMSKint32t *qcol = ptr_form.col;\n\t\tMSKrealt *qval = ptr_form.value;\n\n\t\terror = mosek::MSK_putqobj(m_model.get(), numqnz, qrow, qcol, qval);\n\t\tcheck_error(error);\n\t}\n\telse\n\t{\n\t\t// delete all quadratic terms\n\t\terror = mosek::MSK_putqobj(m_model.get(), 0, nullptr, nullptr, nullptr);\n\t\tcheck_error(error);\n\t}\n\n\t// Affine part\n\tconst auto &affine_part = function.affine_part;\n\tif (affine_part)\n\t{\n\t\tconst auto &affine_function = affine_part.value();\n\t\t_set_affine_objective(affine_function, sense, false);\n\t}\n\telse\n\t{\n\t\tScalarAffineFunction zero;\n\t\t_set_affine_objective(zero, sense, false);\n\t}\n}\n\nvoid MOSEKModel::set_objective(const ExprBuilder &function, ObjectiveSense sense)\n{\n\tm_is_dirty = true;\n\tauto deg = function.degree();\n\tif (deg <= 1)\n\t{\n\t\tScalarAffineFunction f(function);\n\t\tset_objective(f, sense);\n\t}\n\telse if (deg == 2)\n\t{\n\t\tScalarQuadraticFunction f(function);\n\t\tset_objective(f, sense);\n\t}\n\telse\n\t{\n\t\tthrow std::runtime_error(\"Objective must be linear or quadratic\");\n\t}\n}\n\nint MOSEKModel::optimize()\n{\n\tm_is_dirty = false;\n\tauto error = mosek::MSK_optimize(m_model.get());\n\tm_soltype = select_available_solution_after_optimization();\n\treturn error;\n}\n\nint MOSEKModel::raw_parameter_type(const char *name)\n{\n\tMSKparametertypee type;\n\tMSKint32t index;\n\tauto error = mosek::MSK_whichparam(m_model.get(), name, &type, &index);\n\tcheck_error(error);\n\treturn type;\n}\n\nvoid MOSEKModel::set_raw_parameter_int(const char *param_name, int value)\n{\n\tm_is_dirty = true;\n\tauto error = mosek::MSK_putnaintparam(m_model.get(), param_name, value);\n\tcheck_error(error);\n}\n\nvoid MOSEKModel::set_raw_parameter_double(const char *param_name, double value)\n{\n\tm_is_dirty = true;\n\tauto error = mosek::MSK_putnadouparam(m_model.get(), param_name, value);\n\tcheck_error(error);\n}\n\nvoid MOSEKModel::set_raw_parameter_string(const char *param_name, const char *value)\n{\n\tm_is_dirty = true;\n\tauto error = mosek::MSK_putnastrparam(m_model.get(), param_name, value);\n\tcheck_error(error);\n}\n\nint MOSEKModel::get_raw_parameter_int(const char *param_name)\n{\n\tint retval;\n\tauto error = mosek::MSK_getnaintparam(m_model.get(), param_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble MOSEKModel::get_raw_parameter_double(const char *param_name)\n{\n\tdouble retval;\n\tauto error = mosek::MSK_getnadouparam(m_model.get(), param_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nstd::string MOSEKModel::get_raw_parameter_string(const char *param_name)\n{\n\tchar retval[MSK_MAX_STR_LEN];\n\tMSKint32t len;\n\tauto error =\n\t    mosek::MSK_getnastrparam(m_model.get(), param_name, strlen(param_name), &len, retval);\n\tcheck_error(error);\n\treturn std::string(retval, len);\n}\n\nint MOSEKModel::get_raw_information_int(const char *attr_name)\n{\n\tint retval;\n\tauto error = mosek::MSK_getnaintinf(m_model.get(), attr_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble MOSEKModel::get_raw_information_double(const char *attr_name)\n{\n\tdouble retval;\n\tauto error = mosek::MSK_getnadouinf(m_model.get(), attr_name, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nMSKint32t MOSEKModel::getnumvar()\n{\n\tMSKint32t retval;\n\tauto error = mosek::MSK_getnumvar(m_model.get(), &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nMSKint32t MOSEKModel::getnumcon()\n{\n\tMSKint32t retval;\n\tauto error = mosek::MSK_getnumcon(m_model.get(), &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nint MOSEKModel::getprosta()\n{\n\tMSKprostae retval;\n\tauto error = mosek::MSK_getprosta(m_model.get(), get_current_solution(), &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nint MOSEKModel::getsolsta()\n{\n\tMSKsolstae retval;\n\tauto error = mosek::MSK_getsolsta(m_model.get(), get_current_solution(), &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble MOSEKModel::getprimalobj()\n{\n\tMSKrealt retval;\n\tauto error = mosek::MSK_getprimalobj(m_model.get(), get_current_solution(), &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble MOSEKModel::getdualobj()\n{\n\tMSKrealt retval;\n\tauto error = mosek::MSK_getdualobj(m_model.get(), get_current_solution(), &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nvoid MOSEKModel::disable_log()\n{\n\tauto error = mosek::MSK_linkfunctotaskstream(m_model.get(), MSK_STREAM_LOG, NULL, NULL);\n\tcheck_error(error);\n}\n\nstd::string MOSEKModel::get_variable_name(const VariableIndex &variable)\n{\n\tauto column = _checked_variable_index(variable);\n\tchar name[MSK_MAX_STR_LEN];\n\tauto error = mosek::MSK_getvarname(m_model.get(), column, MSK_MAX_STR_LEN, name);\n\tcheck_error(error);\n\treturn name;\n}\n\nvoid MOSEKModel::set_variable_name(const VariableIndex &variable, const char *name)\n{\n\tm_is_dirty = true;\n\tauto column = _checked_variable_index(variable);\n\tauto error = mosek::MSK_putvarname(m_model.get(), column, name);\n\tcheck_error(error);\n}\n\nVariableDomain MOSEKModel::get_variable_type(const VariableIndex &variable)\n{\n\tif (binary_variables.contains(variable.index))\n\t{\n\t\treturn VariableDomain::Binary;\n\t}\n\tauto column = _checked_variable_index(variable);\n\tMSKvariabletypee vtype;\n\tauto error = mosek::MSK_getvartype(m_model.get(), column, &vtype);\n\tcheck_error(error);\n\treturn mosek_vtype_to_domain(vtype);\n}\n\nvoid MOSEKModel::set_variable_type(const VariableIndex &variable, VariableDomain domain)\n{\n\tm_is_dirty = true;\n\tMSKvariabletypee vtype = mosek_vtype(domain);\n\tauto column = _checked_variable_index(variable);\n\tauto error = mosek::MSK_putvartype(m_model.get(), column, vtype);\n\tcheck_error(error);\n\n\tif (domain == VariableDomain::Binary)\n\t{\n\t\tMSKrealt lb = 0.0;\n\t\tMSKrealt ub = 1.0;\n\t\tbinary_variables.insert(variable.index);\n\t\terror = mosek::MSK_putvarbound(m_model.get(), column, MSK_BK_RA, lb, ub);\n\t\tcheck_error(error);\n\t}\n\telse\n\t{\n\t\tbinary_variables.erase(variable.index);\n\t}\n}\n\ndouble MOSEKModel::get_variable_lower_bound(const VariableIndex &variable)\n{\n\tMSKboundkeye bound_type;\n\tMSKrealt lb, ub;\n\tauto column = _checked_variable_index(variable);\n\tauto error = mosek::MSK_getvarbound(m_model.get(), column, &bound_type, &lb, &ub);\n\tcheck_error(error);\n\n\tswitch (bound_type)\n\t{\n\tcase MSK_BK_FR:\n\tcase MSK_BK_UP:\n\t\tlb = -MSK_INFINITY;\n\t\tbreak;\n\tcase MSK_BK_LO:\n\tcase MSK_BK_RA:\n\tcase MSK_BK_FX:\n\t\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown bound type\");\n\t}\n\treturn lb;\n}\n\ndouble MOSEKModel::get_variable_upper_bound(const VariableIndex &variable)\n{\n\tMSKboundkeye bound_type;\n\tMSKrealt lb, ub;\n\tauto column = _checked_variable_index(variable);\n\tauto error = mosek::MSK_getvarbound(m_model.get(), column, &bound_type, &lb, &ub);\n\tcheck_error(error);\n\n\tswitch (bound_type)\n\t{\n\tcase MSK_BK_FR:\n\tcase MSK_BK_LO:\n\t\tub = MSK_INFINITY;\n\t\tbreak;\n\tcase MSK_BK_UP:\n\tcase MSK_BK_RA:\n\tcase MSK_BK_FX:\n\t\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown bound type\");\n\t}\n\treturn ub;\n}\n\nvoid MOSEKModel::set_variable_lower_bound(const VariableIndex &variable, double lb)\n{\n\tm_is_dirty = true;\n\tMSKboundkeye bound_type_old, bound_key;\n\tMSKrealt lb_old, ub_old;\n\tauto column = _checked_variable_index(variable);\n\tauto error = mosek::MSK_getvarbound(m_model.get(), column, &bound_type_old, &lb_old, &ub_old);\n\tcheck_error(error);\n\n\tswitch (bound_type_old)\n\t{\n\tcase MSK_BK_FR:\n\t\tbound_key = MSK_BK_LO;\n\t\tbreak;\n\tcase MSK_BK_LO:\n\t\tbound_key = MSK_BK_LO;\n\t\tbreak;\n\tcase MSK_BK_UP:\n\t\tbound_key = MSK_BK_RA;\n\t\tbreak;\n\tcase MSK_BK_RA:\n\t\tbound_key = MSK_BK_RA;\n\t\tbreak;\n\tcase MSK_BK_FX:\n\t\tthrow std::runtime_error(\"Cannot set lower bound for fixed variable\");\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown bound type\");\n\t}\n\n\terror = mosek::MSK_putvarbound(m_model.get(), column, bound_key, lb, ub_old);\n\tcheck_error(error);\n}\n\nvoid MOSEKModel::set_variable_upper_bound(const VariableIndex &variable, double ub)\n{\n\tm_is_dirty = true;\n\tMSKboundkeye bound_type_old, bound_key;\n\tMSKrealt lb_old, ub_old;\n\tauto column = _checked_variable_index(variable);\n\tauto error = mosek::MSK_getvarbound(m_model.get(), column, &bound_type_old, &lb_old, &ub_old);\n\tcheck_error(error);\n\n\tswitch (bound_type_old)\n\t{\n\tcase MSK_BK_FR:\n\t\tbound_key = MSK_BK_UP;\n\t\tbreak;\n\tcase MSK_BK_UP:\n\t\tbound_key = MSK_BK_UP;\n\t\tbreak;\n\tcase MSK_BK_LO:\n\t\tbound_key = MSK_BK_RA;\n\t\tbreak;\n\tcase MSK_BK_RA:\n\t\tbound_key = MSK_BK_RA;\n\t\tbreak;\n\tcase MSK_BK_FX:\n\t\tthrow std::runtime_error(\"Cannot set upper bound for fixed variable\");\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown bound type\");\n\t}\n\n\terror = mosek::MSK_putvarbound(m_model.get(), column, bound_key, lb_old, ub);\n\tcheck_error(error);\n}\n\nvoid MOSEKModel::set_variable_primal(const VariableIndex &variable, double primal)\n{\n\tm_is_dirty = true;\n\tauto column = _checked_variable_index(variable);\n\tMSKrealt val = primal;\n\tauto error = mosek::MSK_putxxslice(m_model.get(), MSK_SOL_ITG, column, column + 1, &val);\n\tcheck_error(error);\n}\n\ndouble MOSEKModel::get_variable_dual(const VariableIndex &variable)\n{\n\tMSKrealt slx, sux;\n\tauto column = _checked_variable_index(variable);\n\tauto error =\n\t    mosek::MSK_getslxslice(m_model.get(), get_current_solution(), column, column + 1, &slx);\n\tcheck_error(error);\n\terror = mosek::MSK_getsuxslice(m_model.get(), get_current_solution(), column, column + 1, &sux);\n\tcheck_error(error);\n\n\tdouble retval = slx - sux;\n\treturn retval;\n}\n\ndouble MOSEKModel::get_constraint_primal(const ConstraintIndex &constraint)\n{\n\tint row = _checked_constraint_index(constraint);\n\tauto soltype = get_current_solution();\n\tMSKrealt retval;\n\tint num = 1;\n\tMSKrescodee error;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\tcase ConstraintType::Quadratic:\n\t\terror = mosek::MSK_getxcslice(m_model.get(), soltype, constraint.index,\n\t\t                              constraint.index + num, &retval);\n\t\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n\tcheck_error(error);\n\treturn retval;\n}\n\ndouble MOSEKModel::get_constraint_dual(const ConstraintIndex &constraint)\n{\n\tint row = _checked_constraint_index(constraint);\n\tauto soltype = get_current_solution();\n\tMSKrealt retval;\n\tint num = 1;\n\tMSKrescodee error;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\tcase ConstraintType::Quadratic:\n\t\terror = mosek::MSK_getyslice(m_model.get(), soltype, constraint.index,\n\t\t                             constraint.index + num, &retval);\n\t\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n\tcheck_error(error);\n\treturn retval;\n}\n\nstd::string MOSEKModel::get_constraint_name(const ConstraintIndex &constraint)\n{\n\tauto row = _checked_constraint_index(constraint);\n\tMSKrescodee error;\n\tMSKint32t reqsize;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\tcase ConstraintType::Quadratic:\n\t\terror = mosek::MSK_getconnamelen(m_model.get(), row, &reqsize);\n\t\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n\tcheck_error(error);\n\tstd::string retval(reqsize - 1, '\\0');\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\tcase ConstraintType::Quadratic:\n\t\terror = mosek::MSK_getconname(m_model.get(), row, reqsize, retval.data());\n\t\tbreak;\n\t}\n\tcheck_error(error);\n\treturn retval;\n}\n\nvoid MOSEKModel::set_constraint_name(const ConstraintIndex &constraint, const char *name)\n{\n\tm_is_dirty = true;\n\tauto row = _checked_constraint_index(constraint);\n\tMSKrescodee error;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\tcase ConstraintType::Quadratic:\n\t\terror = mosek::MSK_putconname(m_model.get(), row, name);\n\t\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n\tcheck_error(error);\n}\n\nObjectiveSense MOSEKModel::get_obj_sense()\n{\n\tMSKobjsensee obj_sense;\n\tauto error = mosek::MSK_getobjsense(m_model.get(), &obj_sense);\n\tcheck_error(error);\n\tauto sense = obj_sense == MSK_OBJECTIVE_SENSE_MINIMIZE ? ObjectiveSense::Minimize\n\t                                                       : ObjectiveSense::Maximize;\n\treturn sense;\n}\n\nvoid MOSEKModel::set_obj_sense(ObjectiveSense sense)\n{\n\tm_is_dirty = true;\n\tauto obj_sense = mosek_obj_sense(sense);\n\tauto error = mosek::MSK_putobjsense(m_model.get(), obj_sense);\n\tcheck_error(error);\n}\n\ndouble MOSEKModel::get_normalized_rhs(const ConstraintIndex &constraint)\n{\n\tauto row = _checked_constraint_index(constraint);\n\tMSKrescodee error;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\tcase ConstraintType::Quadratic: {\n\t\tMSKboundkeye bk;\n\t\tMSKrealt lb, ub;\n\t\terror = mosek::MSK_getconbound(m_model.get(), row, &bk, &lb, &ub);\n\t\tcheck_error(error);\n\n\t\tdouble rhs;\n\t\tswitch (bk)\n\t\t{\n\t\tcase MSK_BK_UP:\n\t\t\trhs = ub;\n\t\t\tbreak;\n\t\tcase MSK_BK_LO:\n\t\t\trhs = lb;\n\t\t\tbreak;\n\t\tcase MSK_BK_FX:\n\t\t\trhs = lb;\n\t\t\tbreak;\n\t\tcase MSK_BK_FR:\n\t\t\tthrow std::runtime_error(\"Constraint has no finite bound\");\n\t\t\tbreak;\n\t\tcase MSK_BK_RA:\n\t\t\tthrow std::runtime_error(\"Constraint has two finite bounds\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow std::runtime_error(\"Unknown bound type\");\n\t\t}\n\n\t\treturn rhs;\n\t}\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type to get_normalized_rhs\");\n\t}\n}\n\nvoid MOSEKModel::set_normalized_rhs(const ConstraintIndex &constraint, double value)\n{\n\tm_is_dirty = true;\n\tauto row = _checked_constraint_index(constraint);\n\tMSKrescodee error;\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\tcase ConstraintType::Quadratic: {\n\t\tMSKboundkeye bk;\n\t\tMSKrealt lb, ub;\n\t\terror = mosek::MSK_getconbound(m_model.get(), row, &bk, &lb, &ub);\n\t\tcheck_error(error);\n\n\t\tswitch (bk)\n\t\t{\n\t\tcase MSK_BK_UP:\n\t\t\tub = value;\n\t\t\tbreak;\n\t\tcase MSK_BK_LO:\n\t\t\tlb = value;\n\t\t\tbreak;\n\t\tcase MSK_BK_FX:\n\t\t\tub = value;\n\t\t\tlb = value;\n\t\t\tbreak;\n\t\tcase MSK_BK_FR:\n\t\t\tthrow std::runtime_error(\"Constraint has no finite bound\");\n\t\t\tbreak;\n\t\tcase MSK_BK_RA:\n\t\t\tthrow std::runtime_error(\"Constraint has two finite bounds\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow std::runtime_error(\"Unknown bound type\");\n\t\t}\n\n\t\terror = mosek::MSK_putconbound(m_model.get(), row, bk, lb, ub);\n\t\tcheck_error(error);\n\t}\n\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type to set_normalized_rhs\");\n\t}\n}\n\ndouble MOSEKModel::get_normalized_coefficient(const ConstraintIndex &constraint,\n                                              const VariableIndex &variable)\n{\n\tif (constraint.type != ConstraintType::Linear && constraint.type != ConstraintType::Quadratic)\n\t{\n\t\tthrow std::runtime_error(\n\t\t    \"Only linear and quadratic constraint supports get_normalized_coefficient\");\n\t}\n\tauto row = _checked_constraint_index(constraint);\n\tauto col = _checked_variable_index(variable);\n\tMSKrealt retval;\n\tauto error = mosek::MSK_getaij(m_model.get(), row, col, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nvoid MOSEKModel::set_normalized_coefficient(const ConstraintIndex &constraint,\n                                            const VariableIndex &variable, double value)\n{\n\tm_is_dirty = true;\n\tif (constraint.type != ConstraintType::Linear && constraint.type != ConstraintType::Quadratic)\n\t{\n\t\tthrow std::runtime_error(\n\t\t    \"Only linear and quadratic constraint supports set_normalized_coefficient\");\n\t}\n\tauto row = _checked_constraint_index(constraint);\n\tauto col = _checked_variable_index(variable);\n\tauto error = mosek::MSK_putaij(m_model.get(), row, col, value);\n\tcheck_error(error);\n}\n\ndouble MOSEKModel::get_objective_coefficient(const VariableIndex &variable)\n{\n\tauto column = _checked_variable_index(variable);\n\tMSKrealt retval;\n\tauto error = mosek::MSK_getcj(m_model.get(), column, &retval);\n\tcheck_error(error);\n\treturn retval;\n}\n\nvoid MOSEKModel::set_objective_coefficient(const VariableIndex &variable, double value)\n{\n\tm_is_dirty = true;\n\tauto column = _checked_variable_index(variable);\n\tauto error = mosek::MSK_putcj(m_model.get(), column, value);\n\tcheck_error(error);\n}\n\nMSKint32t MOSEKModel::_variable_index(const VariableIndex &variable)\n{\n\treturn m_variable_index.get_index(variable.index);\n}\n\nMSKint32t MOSEKModel::_checked_variable_index(const VariableIndex &variable)\n{\n\tMSKint32t column = _variable_index(variable);\n\tif (column < 0)\n\t{\n\t\tthrow std::runtime_error(\"Variable does not exist\");\n\t}\n\treturn column;\n}\n\nMSKint32t MOSEKModel::_constraint_index(const ConstraintIndex &constraint)\n{\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\tcase ConstraintType::Quadratic:\n\t\treturn m_linear_quadratic_constraint_index.get_index(constraint.index);\n\t\tbreak;\n\tcase ConstraintType::SecondOrderCone:\n\tcase ConstraintType::ExponentialCone:\n\t\treturn m_acc_index[constraint.index] ? constraint.index : -1;\n\t\tbreak;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n}\n\nMSKint32t MOSEKModel::_checked_constraint_index(const ConstraintIndex &constraint)\n{\n\tMSKint32t row = _constraint_index(constraint);\n\tif (row < 0)\n\t{\n\t\tthrow std::runtime_error(\"Constraint does not exist\");\n\t}\n\treturn row;\n}\n\n// Logging callback\nstatic void RealLoggingCallbackFunction(void *handle, const char *msg)\n{\n\tauto real_logdata = static_cast<MOSEKLoggingCallbackUserdata *>(handle);\n\tauto &callback = real_logdata->callback;\n\tcallback(msg);\n}\n\nvoid MOSEKModel::set_logging(const MOSEKLoggingCallback &callback)\n{\n\tm_is_dirty = true;\n\tm_logging_callback_userdata.callback = callback;\n\tauto error = mosek::MSK_linkfunctotaskstream(\n\t    m_model.get(), MSK_STREAM_LOG, &m_logging_callback_userdata, &RealLoggingCallbackFunction);\n\tcheck_error(error);\n}\n\nvoid *MOSEKModel::get_raw_model()\n{\n\treturn m_model.get();\n}\n\nstd::string MOSEKModel::version_string()\n{\n\tMSKint32t major, minor, revision;\n\tauto error = mosek::MSK_getversion(&major, &minor, &revision);\n\tstd::string version = fmt::format(\"v{}.{}.{}\", major, minor, revision);\n\treturn version;\n}\n\nMSKsoltypee MOSEKModel::get_current_solution()\n{\n\tif (m_soltype)\n\t{\n\t\treturn m_soltype.value();\n\t}\n\tthrow std::runtime_error(\"No solution type is available\");\n}\n\nstd::optional<MSKsoltypee> MOSEKModel::select_available_solution_after_optimization()\n{\n\tstd::vector<MSKsoltypee> soltypes{\n\t    MSK_SOL_ITR,\n\t    MSK_SOL_ITG,\n\t    MSK_SOL_BAS,\n\t};\n\tstd::vector<MSKsoltypee> available_soltypes;\n\tstd::vector<MSKsoltypee> optimal_soltypes;\n\tfor (auto soltype : soltypes)\n\t{\n\t\tMSKbooleant available;\n\t\tauto error = mosek::MSK_solutiondef(m_model.get(), soltype, &available);\n\t\tcheck_error(error);\n\t\tif (available)\n\t\t{\n\t\t\tavailable_soltypes.push_back(soltype);\n\n\t\t\tMSKsolstae solsta;\n\t\t\tauto error = mosek::MSK_getsolsta(m_model.get(), soltype, &solsta);\n\t\t\tcheck_error(error);\n\n\t\t\tif (solsta == MSK_SOL_STA_OPTIMAL || solsta == MSK_SOL_STA_INTEGER_OPTIMAL)\n\t\t\t{\n\t\t\t\toptimal_soltypes.push_back(soltype);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!optimal_soltypes.empty())\n\t{\n\t\treturn optimal_soltypes[0];\n\t}\n\tif (!available_soltypes.empty())\n\t{\n\t\treturn available_soltypes[0];\n\t}\n\treturn std::nullopt;\n}\n\nMOSEKEnv::MOSEKEnv()\n{\n\tif (!mosek::is_library_loaded())\n\t{\n\t\tthrow std::runtime_error(\"Mosek library is not loaded\");\n\t}\n\tauto error = mosek::MSK_makeenv(&m_env, NULL);\n\tcheck_error(error);\n}\n\nMOSEKEnv::~MOSEKEnv()\n{\n\tauto error = mosek::MSK_deleteenv(&m_env);\n\tcheck_error(error);\n}\n\nvoid MOSEKEnv::close()\n{\n\tif (m_env != nullptr)\n\t{\n\t\tauto error = mosek::MSK_deleteenv(&m_env);\n\t\tcheck_error(error);\n\t}\n\tm_env = nullptr;\n}\n\nvoid MOSEKEnv::putlicensecode(const std::vector<MSKint32t> &code)\n{\n\tauto error = mosek::MSK_putlicensecode(m_env, code.data());\n\tcheck_error(error);\n}\n"
  },
  {
    "path": "lib/mosek_model_ext.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include <nanobind/stl/tuple.h>\n#include <nanobind/stl/string.h>\n#include <nanobind/stl/vector.h>\n#include <nanobind/stl/function.h>\n\n#include \"pyoptinterface/mosek_model.hpp\"\n\nnamespace nb = nanobind;\n\nextern void bind_mosek_constants(nb::module_ &m);\n\nNB_MODULE(mosek_model_ext, m)\n{\n\tm.import_(\"pyoptinterface._src.core_ext\");\n\n\tm.def(\"is_library_loaded\", &mosek::is_library_loaded);\n\tm.def(\"load_library\", &mosek::load_library);\n\n\tbind_mosek_constants(m);\n\n\tnb::class_<MOSEKEnv>(m, \"Env\")\n\t    .def(nb::init<>())\n\t    .def(\"close\", &MOSEKEnv::close)\n\t    .def(\"putlicensecode\", &MOSEKEnv::putlicensecode);\n\n#define BIND_F(f) .def(#f, &MOSEKModel::f)\n\tnb::class_<MOSEKModel>(m, \"RawModel\")\n\t    .def(nb::init<>())\n\t    .def(nb::init<const MOSEKEnv &>())\n\t    // clang-format off\n\t    BIND_F(init)\n\t    BIND_F(write)\n\t    BIND_F(close)\n\t    // clang-format on\n\n\t    .def(\"add_variable\", &MOSEKModel::add_variable,\n\t         nb::arg(\"domain\") = VariableDomain::Continuous, nb::arg(\"lb\") = -MSK_INFINITY,\n\t         nb::arg(\"ub\") = MSK_INFINITY, nb::arg(\"name\") = \"\")\n\t    // clang-format off\n\t    BIND_F(delete_variable)\n\t    BIND_F(delete_variables)\n\t    BIND_F(is_variable_active)\n\t    // clang-format on\n\t    .def(\"set_variable_bounds\", &MOSEKModel::set_variable_bounds, nb::arg(\"variable\"),\n\t         nb::arg(\"lb\"), nb::arg(\"ub\"))\n\n\t    .def(\"get_value\", nb::overload_cast<const VariableIndex &>(&MOSEKModel::get_variable_value))\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ScalarAffineFunction &>(&MOSEKModel::get_expression_value))\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &>(&MOSEKModel::get_expression_value))\n\t    .def(\"get_value\", nb::overload_cast<const ExprBuilder &>(&MOSEKModel::get_expression_value))\n\n\t    .def(\"pprint\", &MOSEKModel::pprint_variable)\n\t    .def(\"pprint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, int>(&MOSEKModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\t    .def(\n\t        \"pprint\",\n\t        nb::overload_cast<const ScalarQuadraticFunction &, int>(&MOSEKModel::pprint_expression),\n\t        nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\t    .def(\"pprint\", nb::overload_cast<const ExprBuilder &, int>(&MOSEKModel::pprint_expression),\n\t         nb::arg(\"expr\"), nb::arg(\"precision\") = 4)\n\n\t    .def(\"_add_linear_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ConstraintSense, CoeffT, const char *>(\n\t             &MOSEKModel::add_linear_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, const std::tuple<double, double> &,\n\t                           const char *>(&MOSEKModel::add_linear_constraint),\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &MOSEKModel::add_linear_constraint_from_var, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &MOSEKModel::add_linear_interval_constraint_from_var,\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &MOSEKModel::add_linear_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_linear_constraint\", &MOSEKModel::add_linear_interval_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"interval\"), nb::arg(\"name\") = \"\")\n\n\t    .def(\"_add_quadratic_constraint\", &MOSEKModel::add_quadratic_constraint, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\t    .def(\"_add_quadratic_constraint\", &MOSEKModel::add_quadratic_constraint_from_expr,\n\t         nb::arg(\"expr\"), nb::arg(\"sense\"), nb::arg(\"rhs\"), nb::arg(\"name\") = \"\")\n\n\t    .def(\"add_second_order_cone_constraint\", &MOSEKModel::add_second_order_cone_constraint,\n\t         nb::arg(\"variables\"), nb::arg(\"name\") = \"\", nb::arg(\"rotated\") = false)\n\t    .def(\"add_exp_cone_constraint\", &MOSEKModel::add_exp_cone_constraint, nb::arg(\"variables\"),\n\t         nb::arg(\"name\") = \"\", nb::arg(\"dual\") = false)\n\n\t    // clang-format off\n\t\tBIND_F(delete_constraint)\n\t\tBIND_F(is_constraint_active)\n\t    // clang-format on\n\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, ObjectiveSense>(\n\t             &MOSEKModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ObjectiveSense>(\n\t             &MOSEKModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ExprBuilder &, ObjectiveSense>(&MOSEKModel::set_objective),\n\t         nb::arg(\"expr\"), nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\", &MOSEKModel::set_objective_as_variable, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\", &MOSEKModel::set_objective_as_constant, nb::arg(\"expr\"),\n\t         nb::arg(\"sense\") = ObjectiveSense::Minimize)\n\n\t    .def(\"optimize\", &MOSEKModel::optimize, nb::call_guard<nb::gil_scoped_release>())\n\n\t    // clang-format off\n\t    BIND_F(version_string)\n\t    BIND_F(get_raw_model)\n\n\t    BIND_F(raw_parameter_type)\n\n\t    BIND_F(set_raw_parameter_int)\n\t    BIND_F(set_raw_parameter_double)\n\t    BIND_F(set_raw_parameter_string)\n\t    BIND_F(get_raw_parameter_int)\n\t    BIND_F(get_raw_parameter_double)\n\t    BIND_F(get_raw_parameter_string)\n\n\t    BIND_F(get_raw_information_int)\n\t    BIND_F(get_raw_information_double)\n\n\t    BIND_F(getnumvar)\n\t    BIND_F(getnumcon)\n\t    BIND_F(getprosta)\n\t    BIND_F(getsolsta)\n\t\tBIND_F(getprimalobj)\n\t\tBIND_F(getdualobj)\n\n\t\tBIND_F(set_logging)\n\t    BIND_F(disable_log)\n\n\t    BIND_F(set_variable_name)\n\t    BIND_F(get_variable_name)\n\t    BIND_F(set_variable_type)\n\t    BIND_F(get_variable_type)\n\t    BIND_F(set_variable_lower_bound)\n\t    BIND_F(set_variable_upper_bound)\n\t\tBIND_F(get_variable_lower_bound)\n\t    BIND_F(get_variable_upper_bound)\n\t    BIND_F(set_variable_primal)\n\n\t\tBIND_F(get_variable_dual)\n\n\t    BIND_F(get_constraint_primal)\n\t    BIND_F(get_constraint_dual)\n\t    BIND_F(get_constraint_name)\n\t    BIND_F(set_constraint_name)\n\n\t    BIND_F(set_obj_sense)\n\t    BIND_F(get_obj_sense)\n\n\t\tBIND_F(get_normalized_rhs)\n\t\tBIND_F(set_normalized_rhs)\n\t\tBIND_F(get_normalized_coefficient)\n\t\tBIND_F(set_normalized_coefficient)\n\t\tBIND_F(get_objective_coefficient)\n\t\tBIND_F(set_objective_coefficient)\n\t    // clang-format on\n\t    .def_rw(\"m_is_dirty\", &MOSEKModel::m_is_dirty);\n}"
  },
  {
    "path": "lib/mosek_model_ext_constants.cpp",
    "content": "#include <nanobind/nanobind.h>\n#ifdef _MSC_VER\n#include \"solvers/mosek/mosek_win.h\"\n#else\n#include \"solvers/mosek/mosek_linux.h\"\n#endif\n\nnamespace nb = nanobind;\n\nvoid bind_mosek_constants(nb::module_ &m)\n{\n\tnb::module_ Enum = m.def_submodule(\"Enum\");\n\n\t// must cast these enums to int, otherwise C++ compilation passes but we get bad cast when\n\t// import it in Python\n#define BIND_C(x) Enum.attr(#x) = static_cast<int>(x)\n\n\tBIND_C(MSK_PRO_STA_UNKNOWN);\n\tBIND_C(MSK_PRO_STA_PRIM_AND_DUAL_FEAS);\n\tBIND_C(MSK_PRO_STA_PRIM_FEAS);\n\tBIND_C(MSK_PRO_STA_DUAL_FEAS);\n\tBIND_C(MSK_PRO_STA_PRIM_INFEAS);\n\tBIND_C(MSK_PRO_STA_DUAL_INFEAS);\n\tBIND_C(MSK_PRO_STA_PRIM_AND_DUAL_INFEAS);\n\tBIND_C(MSK_PRO_STA_ILL_POSED);\n\tBIND_C(MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED);\n\n\tBIND_C(MSK_SOL_STA_UNKNOWN);\n\tBIND_C(MSK_SOL_STA_OPTIMAL);\n\tBIND_C(MSK_SOL_STA_PRIM_FEAS);\n\tBIND_C(MSK_SOL_STA_DUAL_FEAS);\n\tBIND_C(MSK_SOL_STA_PRIM_AND_DUAL_FEAS);\n\tBIND_C(MSK_SOL_STA_PRIM_INFEAS_CER);\n\tBIND_C(MSK_SOL_STA_DUAL_INFEAS_CER);\n\tBIND_C(MSK_SOL_STA_PRIM_ILLPOSED_CER);\n\tBIND_C(MSK_SOL_STA_DUAL_ILLPOSED_CER);\n\tBIND_C(MSK_SOL_STA_INTEGER_OPTIMAL);\n\n\tBIND_C(MSK_RES_OK);\n\tBIND_C(MSK_RES_TRM_MAX_ITERATIONS);\n\tBIND_C(MSK_RES_TRM_MAX_TIME);\n\tBIND_C(MSK_RES_TRM_OBJECTIVE_RANGE);\n\tBIND_C(MSK_RES_TRM_STALL);\n\tBIND_C(MSK_RES_TRM_USER_CALLBACK);\n\tBIND_C(MSK_RES_TRM_MIO_NUM_RELAXS);\n\tBIND_C(MSK_RES_TRM_MIO_NUM_BRANCHES);\n\tBIND_C(MSK_RES_TRM_NUM_MAX_NUM_INT_SOLUTIONS);\n\tBIND_C(MSK_RES_TRM_MAX_NUM_SETBACKS);\n\tBIND_C(MSK_RES_TRM_NUMERICAL_PROBLEM);\n\tBIND_C(MSK_RES_TRM_LOST_RACE);\n\tBIND_C(MSK_RES_TRM_INTERNAL);\n\tBIND_C(MSK_RES_TRM_INTERNAL_STOP);\n}"
  },
  {
    "path": "lib/nleval.cpp",
    "content": "#include \"pyoptinterface/nleval.hpp\"\n#include <cassert>\n#include <span>\n\nConstraintAutodiffEvaluator::ConstraintAutodiffEvaluator(bool has_parameter, uintptr_t fp,\n                                                         uintptr_t jp, uintptr_t hp)\n{\n\tif (has_parameter)\n\t{\n\t\tf_eval.p = (f_funcptr)fp;\n\t\tjacobian_eval.p = (jacobian_funcptr)jp;\n\t\thessian_eval.p = (hessian_funcptr)hp;\n\t}\n\telse\n\t{\n\t\tf_eval.nop = (f_funcptr_noparam)fp;\n\t\tjacobian_eval.nop = (jacobian_funcptr_noparam)jp;\n\t\thessian_eval.nop = (hessian_funcptr_noparam)hp;\n\t}\n}\n\nObjectiveAutodiffEvaluator::ObjectiveAutodiffEvaluator(bool has_parameter, uintptr_t fp,\n                                                       uintptr_t ajp, uintptr_t hp)\n{\n\tif (has_parameter)\n\t{\n\t\tf_eval.p = (f_funcptr)fp;\n\t\tgrad_eval.p = (additive_grad_funcptr)ajp;\n\t\thessian_eval.p = (hessian_funcptr)hp;\n\t}\n\telse\n\t{\n\t\tf_eval.nop = (f_funcptr_noparam)fp;\n\t\tgrad_eval.nop = (additive_grad_funcptr_noparam)ajp;\n\t\thessian_eval.nop = (hessian_funcptr_noparam)hp;\n\t}\n}\n\nvoid LinearEvaluator::add_row(const ScalarAffineFunction &f)\n{\n\tcoefs.insert(coefs.end(), f.coefficients.begin(), f.coefficients.end());\n\tindices.insert(indices.end(), f.variables.begin(), f.variables.end());\n\tconstraint_intervals.push_back(coefs.size());\n\n\tif (f.constant)\n\t{\n\t\tconstant_values.push_back(f.constant.value());\n\t\tconstant_indices.push_back(n_constraints);\n\t}\n\n\tn_constraints += 1;\n}\n\nvoid LinearEvaluator::eval_function(const double *restrict x, double *restrict f)\n{\n\tfor (size_t i = 0; i < n_constraints; i++)\n\t{\n\t\tauto start = constraint_intervals[i];\n\t\tauto end = constraint_intervals[i + 1];\n\n\t\tdouble sum = 0.0;\n\t\tfor (size_t j = start; j < end; j++)\n\t\t{\n\t\t\tsum += coefs[j] * x[indices[j]];\n\t\t}\n\t\tf[i] = sum;\n\t}\n\tfor (size_t i = 0; i < constant_indices.size(); i++)\n\t{\n\t\tauto index = constant_indices[i];\n\t\tauto value = constant_values[i];\n\t\tf[index] += value;\n\t}\n}\n\nvoid LinearEvaluator::analyze_jacobian_structure(size_t &global_jacobian_nnz,\n                                                 std::vector<int> &global_jacobian_rows,\n                                                 std::vector<int> &global_jacobian_cols) const\n{\n\tglobal_jacobian_nnz += indices.size();\n\tglobal_jacobian_rows.reserve(global_jacobian_nnz);\n\tfor (size_t i = 0; i < n_constraints; i++)\n\t{\n\t\tauto start = constraint_intervals[i];\n\t\tauto end = constraint_intervals[i + 1];\n\t\tfor (size_t j = start; j < end; j++)\n\t\t{\n\t\t\tglobal_jacobian_rows.push_back(i);\n\t\t}\n\t}\n\tglobal_jacobian_cols.insert(global_jacobian_cols.end(), indices.begin(), indices.end());\n}\n\nvoid LinearEvaluator::eval_jacobian(const double *restrict x, double *restrict jacobian) const\n{\n\tstd::copy(coefs.begin(), coefs.end(), jacobian);\n}\n\nvoid QuadraticEvaluator::add_row(const ScalarQuadraticFunction &f)\n{\n\tfor (int i = 0; i < f.size(); i++)\n\t{\n\t\tauto coef = f.coefficients[i];\n\t\tauto x1 = f.variable_1s[i];\n\t\tauto x2 = f.variable_2s[i];\n\n\t\tif (x1 == x2)\n\t\t{\n\t\t\tdiag_coefs.push_back(coef);\n\t\t\tdiag_indices.push_back(x1);\n\t\t}\n\t\telse\n\t\t{\n\t\t\toffdiag_coefs.push_back(coef);\n\t\t\toffdiag_rows.push_back(x1);\n\t\t\toffdiag_cols.push_back(x2);\n\t\t}\n\t}\n\n\tdiag_intervals.push_back(diag_coefs.size());\n\toffdiag_intervals.push_back(offdiag_coefs.size());\n\n\tif (f.affine_part)\n\t{\n\t\tauto &affine = f.affine_part.value();\n\t\tlinear_coefs.insert(linear_coefs.end(), affine.coefficients.begin(),\n\t\t                    affine.coefficients.end());\n\t\tlinear_indices.insert(linear_indices.end(), affine.variables.begin(),\n\t\t                      affine.variables.end());\n\n\t\tif (affine.constant)\n\t\t{\n\t\t\tlinear_constant_values.push_back(affine.constant.value());\n\t\t\tlinear_constant_indices.push_back(n_constraints);\n\t\t}\n\t}\n\tlinear_intervals.push_back(linear_coefs.size());\n\n\tHashmap<int, int> variable_to_jacobian_nnz;\n\n\tfor (int i = 0; i < f.size(); i++)\n\t{\n\t\tauto coef = f.coefficients[i];\n\t\tauto x1 = f.variable_1s[i];\n\t\tauto x2 = f.variable_2s[i];\n\n\t\tif (x1 == x2)\n\t\t{\n\t\t\tauto [iter, inserted] = variable_to_jacobian_nnz.try_emplace(x1, jacobian_nnz);\n\t\t\tif (inserted)\n\t\t\t{\n\t\t\t\tjacobian_constant.push_back(0.0);\n\t\t\t\tjacobian_variable_indices.push_back(x1);\n\t\t\t\tjacobian_nnz += 1;\n\t\t\t}\n\t\t\tjacobian_diag_indices.push_back(iter->second);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t{\n\t\t\t\tauto [iter, inserted] = variable_to_jacobian_nnz.try_emplace(x1, jacobian_nnz);\n\t\t\t\tif (inserted)\n\t\t\t\t{\n\t\t\t\t\tjacobian_constant.push_back(0.0);\n\t\t\t\t\tjacobian_variable_indices.push_back(x1);\n\t\t\t\t\tjacobian_nnz += 1;\n\t\t\t\t}\n\t\t\t\tjacobian_offdiag_row_indices.push_back(iter->second);\n\t\t\t}\n\t\t\t{\n\t\t\t\tauto [iter, inserted] = variable_to_jacobian_nnz.try_emplace(x2, jacobian_nnz);\n\t\t\t\tif (inserted)\n\t\t\t\t{\n\t\t\t\t\tjacobian_constant.push_back(0.0);\n\t\t\t\t\tjacobian_variable_indices.push_back(x2);\n\t\t\t\t\tjacobian_nnz += 1;\n\t\t\t\t}\n\t\t\t\tjacobian_offdiag_col_indices.push_back(iter->second);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (f.affine_part)\n\t{\n\t\tauto &affine = f.affine_part.value();\n\n\t\tfor (int i = 0; i < affine.size(); i++)\n\t\t{\n\t\t\tauto coef = affine.coefficients[i];\n\t\t\tauto x = affine.variables[i];\n\t\t\tauto [iter, inserted] = variable_to_jacobian_nnz.try_emplace(x, jacobian_nnz);\n\t\t\tif (inserted)\n\t\t\t{\n\t\t\t\tjacobian_constant.push_back(coef);\n\t\t\t\tjacobian_variable_indices.push_back(x);\n\t\t\t\tjacobian_nnz += 1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tauto jacobian_index = iter->second;\n\t\t\t\tjacobian_constant[jacobian_index] += coef;\n\t\t\t}\n\t\t}\n\t}\n\tjacobian_constraint_intervals.push_back(jacobian_variable_indices.size());\n\n\tn_constraints += 1;\n}\n\nvoid QuadraticEvaluator::eval_function(const double *restrict x, double *restrict f) const\n{\n\tfor (size_t i = 0; i < n_constraints; i++)\n\t{\n\t\tauto start = diag_intervals[i];\n\t\tauto end = diag_intervals[i + 1];\n\t\tdouble sum = 0.0;\n\t\tfor (size_t j = start; j < end; j++)\n\t\t{\n\t\t\tauto c = diag_coefs[j];\n\t\t\tauto v = x[diag_indices[j]];\n\t\t\tsum += c * v * v;\n\t\t}\n\t\tf[i] = sum;\n\t}\n\tfor (size_t i = 0; i < n_constraints; i++)\n\t{\n\t\tauto start = offdiag_intervals[i];\n\t\tauto end = offdiag_intervals[i + 1];\n\t\tdouble sum = 0.0;\n\t\tfor (size_t j = start; j < end; j++)\n\t\t{\n\t\t\tauto c = offdiag_coefs[j];\n\t\t\tauto v1 = x[offdiag_rows[j]];\n\t\t\tauto v2 = x[offdiag_cols[j]];\n\t\t\tsum += c * v1 * v2;\n\t\t}\n\t\tf[i] += sum;\n\t}\n\tfor (size_t i = 0; i < n_constraints; i++)\n\t{\n\t\tauto start = linear_intervals[i];\n\t\tauto end = linear_intervals[i + 1];\n\n\t\tdouble sum = 0.0;\n\t\tfor (size_t j = start; j < end; j++)\n\t\t{\n\t\t\tsum += linear_coefs[j] * x[linear_indices[j]];\n\t\t}\n\t\tf[i] += sum;\n\t}\n\tfor (size_t i = 0; i < linear_constant_indices.size(); i++)\n\t{\n\t\tauto index = linear_constant_indices[i];\n\t\tauto value = linear_constant_values[i];\n\t\tf[index] += value;\n\t}\n}\n\nvoid QuadraticEvaluator::analyze_jacobian_structure(size_t row_base, size_t &global_jacobian_nnz,\n                                                    std::vector<int> &global_jacobian_rows,\n                                                    std::vector<int> &global_jacobian_cols) const\n{\n\tglobal_jacobian_nnz += jacobian_nnz;\n\tglobal_jacobian_rows.reserve(global_jacobian_nnz);\n\tfor (size_t i = 0; i < n_constraints; i++)\n\t{\n\t\tauto start = jacobian_constraint_intervals[i];\n\t\tauto end = jacobian_constraint_intervals[i + 1];\n\t\tfor (size_t j = start; j < end; j++)\n\t\t{\n\t\t\tglobal_jacobian_rows.push_back(row_base + i);\n\t\t}\n\t}\n\tglobal_jacobian_cols.insert(global_jacobian_cols.end(), jacobian_variable_indices.begin(),\n\t                            jacobian_variable_indices.end());\n}\n\nvoid QuadraticEvaluator::eval_jacobian(const double *restrict x, double *restrict jacobian) const\n{\n\tstd::copy(jacobian_constant.begin(), jacobian_constant.end(), jacobian);\n\n\tfor (int i = 0; i < diag_coefs.size(); i++)\n\t{\n\t\tauto coef = diag_coefs[i];\n\t\tauto x_index = diag_indices[i];\n\t\tauto jacobian_index = jacobian_diag_indices[i];\n\t\tjacobian[jacobian_index] += 2.0 * coef * x[x_index];\n\t}\n\n\tfor (int i = 0; i < offdiag_coefs.size(); i++)\n\t{\n\t\tauto coef = offdiag_coefs[i];\n\t\tauto x1_index = offdiag_rows[i];\n\t\tauto x2_index = offdiag_cols[i];\n\t\tauto jacobian_index = jacobian_offdiag_row_indices[i];\n\t\tjacobian[jacobian_index] += coef * x[x2_index];\n\t\tjacobian_index = jacobian_offdiag_col_indices[i];\n\t\tjacobian[jacobian_index] += coef * x[x1_index];\n\t}\n}\n\nvoid QuadraticEvaluator::analyze_hessian_structure(\n    size_t &global_hessian_nnz, std::vector<int> &global_hessian_rows,\n    std::vector<int> &global_hessian_cols, Hashmap<std::tuple<int, int>, int> &hessian_index_map,\n    HessianSparsityType hessian_type)\n{\n\thessian_diag_indices.resize(diag_coefs.size());\n\thessian_offdiag_indices.resize(offdiag_coefs.size());\n\n\tfor (int i = 0; i < diag_coefs.size(); i++)\n\t{\n\t\tauto x = diag_indices[i];\n\n\t\tauto [iter, inserted] = hessian_index_map.try_emplace({x, x}, global_hessian_nnz);\n\t\tif (inserted)\n\t\t{\n\t\t\tglobal_hessian_rows.push_back(x);\n\t\t\tglobal_hessian_cols.push_back(x);\n\t\t\tglobal_hessian_nnz += 1;\n\t\t}\n\t\tauto hessian_index = iter->second;\n\t\thessian_diag_indices[i] = hessian_index;\n\t}\n\n\tfor (int i = 0; i < offdiag_coefs.size(); i++)\n\t{\n\t\tauto x1 = offdiag_rows[i];\n\t\tauto x2 = offdiag_cols[i];\n\t\tif (hessian_type == HessianSparsityType::Upper)\n\t\t{\n\t\t\tif (x1 > x2)\n\t\t\t\tstd::swap(x1, x2);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif (x1 < x2)\n\t\t\t\tstd::swap(x1, x2);\n\t\t}\n\t\tauto [iter, inserted] = hessian_index_map.try_emplace({x1, x2}, global_hessian_nnz);\n\t\tif (inserted)\n\t\t{\n\t\t\tglobal_hessian_rows.push_back(x1);\n\t\t\tglobal_hessian_cols.push_back(x2);\n\t\t\tglobal_hessian_nnz += 1;\n\t\t}\n\t\tauto hessian_index = iter->second;\n\t\thessian_offdiag_indices[i] = hessian_index;\n\t}\n}\n\nvoid QuadraticEvaluator::eval_lagrangian_hessian(const double *restrict lambda,\n                                                 double *restrict hessian) const\n{\n\tfor (size_t i = 0; i < n_constraints; i++)\n\t{\n\t\tauto start = diag_intervals[i];\n\t\tauto end = diag_intervals[i + 1];\n\t\tauto multiplier = lambda[i];\n\t\tfor (size_t j = start; j < end; j++)\n\t\t{\n\t\t\tauto coef = diag_coefs[j];\n\t\t\tauto hessian_index = hessian_diag_indices[j];\n\t\t\thessian[hessian_index] += 2.0 * coef * multiplier;\n\t\t}\n\t}\n\tfor (size_t i = 0; i < n_constraints; i++)\n\t{\n\t\tauto start = offdiag_intervals[i];\n\t\tauto end = offdiag_intervals[i + 1];\n\t\tauto multiplier = lambda[i];\n\t\tfor (size_t j = start; j < end; j++)\n\t\t{\n\t\t\tauto coef = offdiag_coefs[j];\n\t\t\tauto hessian_index = hessian_offdiag_indices[j];\n\t\t\thessian[hessian_index] += coef * multiplier;\n\t\t}\n\t}\n}\n\nint NonlinearEvaluator::add_graph_instance()\n{\n\tauto current_graph_index = n_graph_instances;\n\tn_graph_instances += 1;\n\tgraph_inputs.emplace_back();\n\treturn current_graph_index;\n}\n\nvoid NonlinearEvaluator::finalize_graph_instance(size_t graph_index, const ExpressionGraph &graph)\n{\n\tauto bodyhash = graph.main_structure_hash();\n\n\tgraph_inputs[graph_index].variables = graph.m_variables;\n\tgraph_inputs[graph_index].constants = graph.m_constants;\n\n\tif (graph.has_constraint_output())\n\t{\n\t\tauto hash = graph.constraint_structure_hash(bodyhash);\n\t\tconstraint_graph_hashes.hashes.push_back(\n\t\t    GraphHash{.hash = hash, .index = (int)graph_index});\n\t}\n\n\tif (graph.has_objective_output())\n\t{\n\t\tauto hash = graph.objective_structure_hash(bodyhash);\n\t\tobjective_graph_hashes.hashes.push_back(GraphHash{.hash = hash, .index = (int)graph_index});\n\t}\n}\n\nint NonlinearEvaluator::aggregate_constraint_groups()\n{\n\tauto &graph_hashes = constraint_graph_hashes;\n\tauto &group_memberships = constraint_group_memberships;\n\n\t// ensure we have enough space for every graph instance\n\tgroup_memberships.resize(n_graph_instances, GraphGroupMembership{.group = -1, .rank = -1});\n\n\t// graph hashes that has not been aggregated\n\tstd::span<const GraphHash> hashes_to_analyze(graph_hashes.hashes.begin() +\n\t                                                 graph_hashes.n_hashes_since_last_aggregation,\n\t                                             graph_hashes.hashes.end());\n\n\tfor (const auto &graph_hash : hashes_to_analyze)\n\t{\n\t\tauto index = graph_hash.index;\n\t\tauto hash = graph_hash.hash;\n\t\tauto [iter, inserted] =\n\t\t    hash_to_constraint_group.try_emplace(hash, constraint_groups.size());\n\t\tauto group_index = iter->second;\n\t\tif (inserted)\n\t\t{\n\t\t\tconstraint_groups.emplace_back();\n\t\t}\n\t\tgroup_memberships[index].group = group_index;\n\t\tgroup_memberships[index].rank = (int)constraint_groups[group_index].instance_indices.size();\n\t\tconstraint_groups[group_index].instance_indices.push_back(index);\n\t}\n\n\tgraph_hashes.n_hashes_since_last_aggregation = graph_hashes.hashes.size();\n\n\treturn constraint_groups.size();\n}\n\nint NonlinearEvaluator::get_constraint_group_representative(int group_index) const\n{\n\tauto index = constraint_groups.at(group_index).instance_indices.at(0);\n\treturn index;\n}\n\nint NonlinearEvaluator::aggregate_objective_groups()\n{\n\tauto &graph_hashes = objective_graph_hashes;\n\tauto &group_memberships = objective_group_memberships;\n\n\t// ensure we have enough space for every graph instance\n\tgroup_memberships.resize(n_graph_instances, GraphGroupMembership{.group = -1, .rank = -1});\n\n\t// graph hashes that has not been aggregated\n\tstd::span<const GraphHash> hashes_to_analyze(graph_hashes.hashes.begin() +\n\t                                                 graph_hashes.n_hashes_since_last_aggregation,\n\t                                             graph_hashes.hashes.end());\n\n\tfor (const auto &graph_hash : hashes_to_analyze)\n\t{\n\t\tauto index = graph_hash.index;\n\t\tauto hash = graph_hash.hash;\n\t\tauto [iter, inserted] = hash_to_objective_group.try_emplace(hash, objective_groups.size());\n\t\tauto group_index = iter->second;\n\t\tif (inserted)\n\t\t{\n\t\t\tobjective_groups.emplace_back();\n\t\t}\n\t\tgroup_memberships[index].group = group_index;\n\t\tgroup_memberships[index].rank = (int)objective_groups[group_index].instance_indices.size();\n\t\tobjective_groups[group_index].instance_indices.push_back(index);\n\t}\n\n\tgraph_hashes.n_hashes_since_last_aggregation = graph_hashes.hashes.size();\n\n\treturn objective_groups.size();\n}\n\nint NonlinearEvaluator::get_objective_group_representative(int group_index) const\n{\n\tauto index = objective_groups.at(group_index).instance_indices.at(0);\n\treturn index;\n}\n\nvoid NonlinearEvaluator::assign_constraint_group_autodiff_structure(\n    int group_index, const AutodiffSymbolicStructure &structure)\n{\n\tconstraint_groups[group_index].autodiff_structure = structure;\n}\n\nvoid NonlinearEvaluator::assign_constraint_group_autodiff_evaluator(\n    int group_index, const ConstraintAutodiffEvaluator &evaluator)\n{\n\tconstraint_groups[group_index].autodiff_evaluator = evaluator;\n}\n\nvoid NonlinearEvaluator::assign_objective_group_autodiff_structure(\n    int group_index, const AutodiffSymbolicStructure &structure)\n{\n\tobjective_groups[group_index].autodiff_structure = structure;\n}\n\nvoid NonlinearEvaluator::assign_objective_group_autodiff_evaluator(\n    int group_index, const ObjectiveAutodiffEvaluator &evaluator)\n{\n\tobjective_groups[group_index].autodiff_evaluator = evaluator;\n}\n\nvoid NonlinearEvaluator::calculate_constraint_graph_instances_offset()\n{\n\t// now all graphs are aggregated we need to figure out which index each graph starts\n\tconstraint_indices_offsets.resize(n_graph_instances, -1);\n\tint counter = 0;\n\tfor (const auto &group : constraint_groups)\n\t{\n\t\tconst auto &instance_indices = group.instance_indices;\n\t\tauto ny = group.autodiff_structure.ny;\n\t\tfor (auto instance_index : instance_indices)\n\t\t{\n\t\t\tconstraint_indices_offsets[instance_index] = counter;\n\t\t\tcounter += ny;\n\t\t}\n\t}\n}\n\nvoid NonlinearEvaluator::eval_constraints(const double *restrict x, double *restrict f) const\n{\n\tauto &groups = constraint_groups;\n\tfor (const auto &group : groups)\n\t{\n\t\tauto &instance_indices = group.instance_indices;\n\t\tauto n_instances = instance_indices.size();\n\t\tauto &structure = group.autodiff_structure;\n\t\tauto &evaluator = group.autodiff_evaluator;\n\n\t\tauto ny = structure.ny;\n\n\t\tif (!structure.has_parameter)\n\t\t{\n\t\t\tfor (int j = 0; j < n_instances; j++)\n\t\t\t{\n\t\t\t\tauto instance_index = instance_indices[j];\n\t\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\t\t\t\tevaluator.f_eval.nop(x, f, variables.data());\n\t\t\t\tf += ny;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (int j = 0; j < n_instances; j++)\n\t\t\t{\n\t\t\t\tauto instance_index = instance_indices[j];\n\t\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\t\t\t\tauto &constant = graph_inputs[instance_index].constants;\n\t\t\t\tevaluator.f_eval.p(x, constant.data(), f, variables.data());\n\t\t\t\tf += ny;\n\t\t\t}\n\t\t}\n\t}\n}\n\ndouble NonlinearEvaluator::eval_objective(const double *restrict x) const\n{\n\tauto &groups = objective_groups;\n\tdouble obj_value = 0.0;\n\tfor (const auto &group : groups)\n\t{\n\t\tauto &instance_indices = group.instance_indices;\n\t\tauto n_instances = instance_indices.size();\n\t\tauto &structure = group.autodiff_structure;\n\t\tauto &evaluator = group.autodiff_evaluator;\n\n\t\tif (!structure.has_parameter)\n\t\t{\n\t\t\tfor (int j = 0; j < n_instances; j++)\n\t\t\t{\n\t\t\t\tauto instance_index = instance_indices[j];\n\t\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\t\t\t\tevaluator.f_eval.nop(x, &obj_value, variables.data());\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (int j = 0; j < n_instances; j++)\n\t\t\t{\n\t\t\t\tauto instance_index = instance_indices[j];\n\t\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\t\t\t\tauto &constant = graph_inputs[instance_index].constants;\n\t\t\t\tevaluator.f_eval.p(x, constant.data(), &obj_value, variables.data());\n\t\t\t}\n\t\t}\n\t}\n\treturn obj_value;\n}\n\nvoid NonlinearEvaluator::analyze_constraints_jacobian_structure(\n    size_t row_base, size_t &global_jacobian_nnz, std::vector<int> &global_jacobian_rows,\n    std::vector<int> &global_jacobian_cols)\n{\n\tauto &groups = constraint_groups;\n\n\tfor (const auto &group : groups)\n\t{\n\t\tauto &instance_indices = group.instance_indices;\n\t\tauto n_instances = instance_indices.size();\n\t\tauto &structure = group.autodiff_structure;\n\n\t\tif (!structure.has_jacobian)\n\t\t{\n\t\t\tcontinue;\n\t\t}\n\n\t\tauto local_jacobian_nnz = structure.m_jacobian_nnz;\n\t\tauto &local_jacobian_rows = structure.m_jacobian_rows;\n\t\tauto &local_jacobian_cols = structure.m_jacobian_cols;\n\n\t\tfor (int j = 0; j < n_instances; j++)\n\t\t{\n\t\t\tauto instance_index = instance_indices[j];\n\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\n\t\t\tfor (int k = 0; k < local_jacobian_nnz; k++)\n\t\t\t{\n\t\t\t\tauto row = local_jacobian_rows[k] + row_base;\n\t\t\t\tauto col = variables[local_jacobian_cols[k]];\n\t\t\t\tglobal_jacobian_rows.push_back(row);\n\t\t\t\tglobal_jacobian_cols.push_back(col);\n\t\t\t}\n\n\t\t\trow_base += structure.ny;\n\t\t}\n\n\t\tglobal_jacobian_nnz += local_jacobian_nnz * n_instances;\n\t}\n}\n\nvoid NonlinearEvaluator::analyze_objective_gradient_structure(\n    std::vector<int> &global_gradient_cols, Hashmap<int, int> &sparse_gradient_map)\n{\n\tauto &groups = objective_groups;\n\n\tfor (auto &group : groups)\n\t{\n\t\tauto &instance_indices = group.instance_indices;\n\t\tauto n_instances = instance_indices.size();\n\t\tauto &structure = group.autodiff_structure;\n\n\t\tif (!structure.has_jacobian)\n\t\t{\n\t\t\tcontinue;\n\t\t}\n\n\t\tauto local_jacobian_nnz = structure.m_jacobian_nnz;\n\t\tauto &local_jacobian_cols = structure.m_jacobian_cols;\n\n\t\tstd::vector<int> jacobian_index_buffer(local_jacobian_nnz);\n\t\tgroup.gradient_indices.resize(n_instances * local_jacobian_nnz);\n\n\t\tfor (int j = 0; j < n_instances; j++)\n\t\t{\n\t\t\tauto instance_index = instance_indices[j];\n\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\n\t\t\tfor (int k = 0; k < local_jacobian_nnz; k++)\n\t\t\t{\n\t\t\t\tauto col = variables[local_jacobian_cols[k]];\n\n\t\t\t\tauto [iter, inserted] =\n\t\t\t\t    sparse_gradient_map.try_emplace(col, global_gradient_cols.size());\n\t\t\t\tif (inserted)\n\t\t\t\t{\n\t\t\t\t\tglobal_gradient_cols.push_back(col);\n\t\t\t\t}\n\t\t\t\tjacobian_index_buffer[k] = iter->second;\n\t\t\t}\n\t\t\tstd::copy(jacobian_index_buffer.begin(), jacobian_index_buffer.end(),\n\t\t\t          group.gradient_indices.begin() + j * local_jacobian_nnz);\n\t\t}\n\t}\n}\n\nvoid NonlinearEvaluator::eval_constraints_jacobian(const double *restrict x,\n                                                   double *restrict jacobian) const\n{\n\tauto &groups = constraint_groups;\n\n\tfor (const auto &group : groups)\n\t{\n\t\tauto &instance_indices = group.instance_indices;\n\t\tauto n_instances = instance_indices.size();\n\t\tauto &structure = group.autodiff_structure;\n\t\tauto &evaluator = group.autodiff_evaluator;\n\t\tif (!structure.has_jacobian)\n\t\t{\n\t\t\tcontinue;\n\t\t}\n\t\tauto local_jacobian_nnz = structure.m_jacobian_nnz;\n\t\tif (!structure.has_parameter)\n\t\t{\n\t\t\tfor (int j = 0; j < n_instances; j++)\n\t\t\t{\n\t\t\t\tauto instance_index = instance_indices[j];\n\t\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\t\t\t\tevaluator.jacobian_eval.nop(x, jacobian, variables.data());\n\t\t\t\tjacobian += local_jacobian_nnz;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (int j = 0; j < n_instances; j++)\n\t\t\t{\n\t\t\t\tauto instance_index = instance_indices[j];\n\t\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\t\t\t\tauto &constant = graph_inputs[instance_index].constants;\n\t\t\t\tevaluator.jacobian_eval.p(x, constant.data(), jacobian, variables.data());\n\t\t\t\tjacobian += local_jacobian_nnz;\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid NonlinearEvaluator::eval_objective_gradient(const double *restrict x,\n                                                 double *restrict grad_f) const\n{\n\tauto &groups = objective_groups;\n\n\tfor (const auto &group : groups)\n\t{\n\t\tauto &instance_indices = group.instance_indices;\n\t\tauto n_instances = instance_indices.size();\n\t\tauto &structure = group.autodiff_structure;\n\t\tauto &evaluator = group.autodiff_evaluator;\n\t\tif (!structure.has_jacobian)\n\t\t{\n\t\t\tcontinue;\n\t\t}\n\t\tauto local_jacobian_nnz = structure.m_jacobian_nnz;\n\t\tconst int *grad_index = group.gradient_indices.data();\n\t\tif (!structure.has_parameter)\n\t\t{\n\t\t\tfor (int j = 0; j < n_instances; j++)\n\t\t\t{\n\t\t\t\tauto instance_index = instance_indices[j];\n\t\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\t\t\t\tevaluator.grad_eval.nop(x, grad_f, variables.data(), grad_index);\n\t\t\t\tgrad_index += local_jacobian_nnz;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor (int j = 0; j < n_instances; j++)\n\t\t\t{\n\t\t\t\tauto instance_index = instance_indices[j];\n\t\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\t\t\t\tauto &constant = graph_inputs[instance_index].constants;\n\t\t\t\tevaluator.grad_eval.p(x, constant.data(), grad_f, variables.data(), grad_index);\n\t\t\t\tgrad_index += local_jacobian_nnz;\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid NonlinearEvaluator::analyze_constraints_hessian_structure(\n    size_t &global_hessian_nnz, std::vector<int> &global_hessian_rows,\n    std::vector<int> &global_hessian_cols, Hashmap<std::tuple<int, int>, int> &hessian_index_map,\n    HessianSparsityType hessian_type)\n{\n\tauto &groups = constraint_groups;\n\n\tfor (auto &group : groups)\n\t{\n\t\tauto &instance_indices = group.instance_indices;\n\t\tauto n_instances = instance_indices.size();\n\t\tauto &structure = group.autodiff_structure;\n\n\t\tif (!structure.has_hessian)\n\t\t{\n\t\t\tcontinue;\n\t\t}\n\n\t\tauto local_hessian_nnz = structure.m_hessian_nnz;\n\t\tauto &local_hessian_rows = structure.m_hessian_rows;\n\t\tauto &local_hessian_cols = structure.m_hessian_cols;\n\n\t\tstd::vector<int> hessian_index_buffer(local_hessian_nnz);\n\t\tgroup.hessian_indices.resize(n_instances * local_hessian_nnz);\n\n\t\tfor (int j = 0; j < n_instances; j++)\n\t\t{\n\t\t\tauto instance_index = instance_indices[j];\n\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\n\t\t\tfor (int k = 0; k < local_hessian_nnz; k++)\n\t\t\t{\n\t\t\t\tauto row = variables[local_hessian_rows[k]];\n\t\t\t\tauto col = variables[local_hessian_cols[k]];\n\n\t\t\t\tif (hessian_type == HessianSparsityType::Upper)\n\t\t\t\t{\n\t\t\t\t\tif (row > col)\n\t\t\t\t\t\tstd::swap(row, col);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (row < col)\n\t\t\t\t\t\tstd::swap(row, col);\n\t\t\t\t}\n\n\t\t\t\tauto [iter, inserted] =\n\t\t\t\t    hessian_index_map.try_emplace({row, col}, global_hessian_nnz);\n\t\t\t\tif (inserted)\n\t\t\t\t{\n\t\t\t\t\tglobal_hessian_rows.push_back(row);\n\t\t\t\t\tglobal_hessian_cols.push_back(col);\n\t\t\t\t\tglobal_hessian_nnz += 1;\n\t\t\t\t}\n\t\t\t\tauto hessian_index = iter->second;\n\t\t\t\thessian_index_buffer[k] = hessian_index;\n\t\t\t}\n\t\t\tstd::copy(hessian_index_buffer.begin(), hessian_index_buffer.end(),\n\t\t\t          group.hessian_indices.begin() + j * local_hessian_nnz);\n\t\t}\n\t}\n}\n\nvoid NonlinearEvaluator::analyze_objective_hessian_structure(\n    size_t &global_hessian_nnz, std::vector<int> &global_hessian_rows,\n    std::vector<int> &global_hessian_cols, Hashmap<std::tuple<int, int>, int> &hessian_index_map,\n    HessianSparsityType hessian_type)\n{\n\tauto &groups = objective_groups;\n\n\tfor (auto &group : groups)\n\t{\n\t\tauto &instance_indices = group.instance_indices;\n\t\tauto n_instances = instance_indices.size();\n\t\tauto &structure = group.autodiff_structure;\n\n\t\tif (!structure.has_hessian)\n\t\t{\n\t\t\tcontinue;\n\t\t}\n\n\t\tauto local_hessian_nnz = structure.m_hessian_nnz;\n\t\tauto &local_hessian_rows = structure.m_hessian_rows;\n\t\tauto &local_hessian_cols = structure.m_hessian_cols;\n\n\t\tstd::vector<int> hessian_index_buffer(local_hessian_nnz);\n\t\tgroup.hessian_indices.resize(n_instances * local_hessian_nnz);\n\n\t\tfor (int j = 0; j < n_instances; j++)\n\t\t{\n\t\t\tauto instance_index = instance_indices[j];\n\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\n\t\t\tfor (int k = 0; k < local_hessian_nnz; k++)\n\t\t\t{\n\t\t\t\tauto row = variables[local_hessian_rows[k]];\n\t\t\t\tauto col = variables[local_hessian_cols[k]];\n\n\t\t\t\tif (hessian_type == HessianSparsityType::Upper)\n\t\t\t\t{\n\t\t\t\t\tif (row > col)\n\t\t\t\t\t\tstd::swap(row, col);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (row < col)\n\t\t\t\t\t\tstd::swap(row, col);\n\t\t\t\t}\n\n\t\t\t\tauto [iter, inserted] =\n\t\t\t\t    hessian_index_map.try_emplace({row, col}, global_hessian_nnz);\n\t\t\t\tif (inserted)\n\t\t\t\t{\n\t\t\t\t\tglobal_hessian_rows.push_back(row);\n\t\t\t\t\tglobal_hessian_cols.push_back(col);\n\t\t\t\t\tglobal_hessian_nnz += 1;\n\t\t\t\t}\n\t\t\t\tauto hessian_index = iter->second;\n\t\t\t\thessian_index_buffer[k] = hessian_index;\n\t\t\t}\n\t\t\tstd::copy(hessian_index_buffer.begin(), hessian_index_buffer.end(),\n\t\t\t          group.hessian_indices.begin() + j * local_hessian_nnz);\n\t\t}\n\t}\n}\n\nvoid NonlinearEvaluator::eval_lagrangian_hessian(const double *restrict x,\n                                                 const double *restrict lambda,\n                                                 const double obj_factor,\n                                                 double *restrict hessian) const\n{\n\t// lambda are the multipliers of constraints\n\t// obj_factor is the multiplier of objective function\n\n\t// objective\n\t{\n\t\tauto &groups = objective_groups;\n\t\tfor (const auto &group : groups)\n\t\t{\n\t\t\tauto &instance_indices = group.instance_indices;\n\t\t\tauto n_instances = instance_indices.size();\n\t\t\tauto &structure = group.autodiff_structure;\n\t\t\tauto &evaluator = group.autodiff_evaluator;\n\n\t\t\tif (!structure.has_hessian)\n\t\t\t{\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tauto local_hessian_nnz = structure.m_hessian_nnz;\n\t\t\tconst int *hessian_index = group.hessian_indices.data();\n\n\t\t\tif (!structure.has_parameter)\n\t\t\t{\n\t\t\t\tfor (int j = 0; j < n_instances; j++)\n\t\t\t\t{\n\t\t\t\t\tauto instance_index = instance_indices[j];\n\t\t\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\t\t\t\t\tevaluator.hessian_eval.nop(x, &obj_factor, hessian, variables.data(),\n\t\t\t\t\t                           hessian_index);\n\t\t\t\t\thessian_index += local_hessian_nnz;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfor (int j = 0; j < n_instances; j++)\n\t\t\t\t{\n\t\t\t\t\tauto instance_index = instance_indices[j];\n\t\t\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\t\t\t\t\tauto &constant = graph_inputs[instance_index].constants;\n\t\t\t\t\tevaluator.hessian_eval.p(x, constant.data(), &obj_factor, hessian,\n\t\t\t\t\t                         variables.data(), hessian_index);\n\t\t\t\t\thessian_index += local_hessian_nnz;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// constraints\n\t{\n\t\tauto &groups = constraint_groups;\n\t\tfor (const auto &group : groups)\n\t\t{\n\t\t\tauto &instance_indices = group.instance_indices;\n\t\t\tauto n_instances = instance_indices.size();\n\t\t\tauto &structure = group.autodiff_structure;\n\t\t\tauto &evaluator = group.autodiff_evaluator;\n\t\t\tif (!structure.has_hessian)\n\t\t\t{\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tauto local_hessian_nnz = structure.m_hessian_nnz;\n\t\t\tauto ny = structure.ny;\n\t\t\tconst int *hessian_index = group.hessian_indices.data();\n\t\t\tif (!structure.has_parameter)\n\t\t\t{\n\t\t\t\tfor (int j = 0; j < n_instances; j++)\n\t\t\t\t{\n\t\t\t\t\tauto instance_index = instance_indices[j];\n\t\t\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\t\t\t\t\tevaluator.hessian_eval.nop(x, lambda, hessian, variables.data(), hessian_index);\n\t\t\t\t\thessian_index += local_hessian_nnz;\n\t\t\t\t\tlambda += ny;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfor (int j = 0; j < n_instances; j++)\n\t\t\t\t{\n\t\t\t\t\tauto instance_index = instance_indices[j];\n\t\t\t\t\tauto &variables = graph_inputs[instance_index].variables;\n\t\t\t\t\tauto &constant = graph_inputs[instance_index].constants;\n\t\t\t\t\tevaluator.hessian_eval.p(x, constant.data(), lambda, hessian, variables.data(),\n\t\t\t\t\t                         hessian_index);\n\t\t\t\t\thessian_index += local_hessian_nnz;\n\t\t\t\t\tlambda += ny;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "lib/nleval_ext.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include <nanobind/stl/vector.h>\n\n#include \"pyoptinterface/nleval.hpp\"\n\nnamespace nb = nanobind;\n\nNB_MODULE(nleval_ext, m)\n{\n\tnb::class_<AutodiffSymbolicStructure>(m, \"AutodiffSymbolicStructure\")\n\t    .def(nb::init<>())\n\t    .def_ro(\"nx\", &AutodiffSymbolicStructure::nx)\n\t    .def_ro(\"np\", &AutodiffSymbolicStructure::np)\n\t    .def_ro(\"ny\", &AutodiffSymbolicStructure::ny)\n\t    .def_ro(\"m_jacobian_rows\", &AutodiffSymbolicStructure::m_jacobian_rows)\n\t    .def_ro(\"m_jacobian_cols\", &AutodiffSymbolicStructure::m_jacobian_cols)\n\t    .def_ro(\"m_jacobian_nnz\", &AutodiffSymbolicStructure::m_jacobian_nnz)\n\t    .def_ro(\"m_hessian_rows\", &AutodiffSymbolicStructure::m_hessian_rows)\n\t    .def_ro(\"m_hessian_cols\", &AutodiffSymbolicStructure::m_hessian_cols)\n\t    .def_ro(\"m_hessian_nnz\", &AutodiffSymbolicStructure::m_hessian_nnz)\n\t    .def_ro(\"has_parameter\", &AutodiffSymbolicStructure::has_parameter)\n\t    .def_ro(\"has_jacobian\", &AutodiffSymbolicStructure::has_jacobian)\n\t    .def_ro(\"has_hessian\", &AutodiffSymbolicStructure::has_hessian);\n\n\tnb::class_<ConstraintAutodiffEvaluator>(m, \"ConstraintAutodiffEvaluator\")\n\t    .def(nb::init<>())\n\t    .def(nb::init<bool, uintptr_t, uintptr_t, uintptr_t>());\n\n\tnb::class_<ObjectiveAutodiffEvaluator>(m, \"ObjectiveAutodiffEvaluator\")\n\t    .def(nb::init<>())\n\t    .def(nb::init<bool, uintptr_t, uintptr_t, uintptr_t>());\n}\n"
  },
  {
    "path": "lib/nlexpr.cpp",
    "content": "#include \"pyoptinterface/nlexpr.hpp\"\n\n#include <cassert>\n#include <cmath>\n#include \"fmt/core.h\"\n\nbool ExpressionHandle::operator==(const ExpressionHandle &x) const\n{\n\treturn array == x.array && id == x.id;\n}\n\nstd::string ExpressionHandle::to_string() const\n{\n\tswitch (array)\n\t{\n\tcase ArrayType::Constant:\n\t\treturn fmt::format(\"c{}\", id);\n\tcase ArrayType::Variable:\n\t\treturn fmt::format(\"v{}\", id);\n\tcase ArrayType::Parameter:\n\t\treturn fmt::format(\"p{}\", id);\n\tcase ArrayType::Unary:\n\t\treturn fmt::format(\"u{}\", id);\n\tcase ArrayType::Binary:\n\t\treturn fmt::format(\"b{}\", id);\n\tcase ArrayType::Ternary:\n\t\treturn fmt::format(\"t{}\", id);\n\tcase ArrayType::Nary:\n\t\treturn fmt::format(\"n{}\", id);\n\tdefault:\n\t\treturn fmt::format(\"?{}\", id);\n\t}\n}\n\nstd::string ExpressionGraph::to_string() const\n{\n\tfmt::memory_buffer buf;\n\n\tfmt::format_to(fmt::appender(buf), \"Variables: {}\\n\", m_variables.size());\n\tfor (size_t i = 0; i < m_variables.size(); i++)\n\t{\n\t\tfmt::format_to(fmt::appender(buf), \"\\tv{}: {}\\n\", i, m_variables[i]);\n\t}\n\n\tfmt::format_to(fmt::appender(buf), \"Constants: {}\\n\", m_constants.size());\n\tfor (size_t i = 0; i < m_constants.size(); i++)\n\t{\n\t\tfmt::format_to(fmt::appender(buf), \"\\tc{}: {}\\n\", i, m_constants[i]);\n\t}\n\n\tfmt::format_to(fmt::appender(buf), \"Parameters: {}\\n\", m_parameters.size());\n\tfor (size_t i = 0; i < m_parameters.size(); i++)\n\t{\n\t\tfmt::format_to(fmt::appender(buf), \"\\tp{}: {}\\n\", i, m_parameters[i]);\n\t}\n\n\tfmt::format_to(fmt::appender(buf), \"Unary: {}\\n\", m_unaries.size());\n\tfor (size_t i = 0; i < m_unaries.size(); i++)\n\t{\n\t\tfmt::format_to(fmt::appender(buf), \"\\tu{}: {}({})\\n\", i,\n\t\t               unary_operator_to_string(m_unaries[i].op), m_unaries[i].operand.to_string());\n\t}\n\n\tfmt::format_to(fmt::appender(buf), \"Binary: {}\\n\", m_binaries.size());\n\tfor (size_t i = 0; i < m_binaries.size(); i++)\n\t{\n\t\tfmt::format_to(fmt::appender(buf), \"\\tb{}: {}({},{})\\n\", i,\n\t\t               binary_operator_to_string(m_binaries[i].op), m_binaries[i].left.to_string(),\n\t\t               m_binaries[i].right.to_string());\n\t}\n\n\tfmt::format_to(fmt::appender(buf), \"Ternary: {}\\n\", m_ternaries.size());\n\tfor (size_t i = 0; i < m_ternaries.size(); i++)\n\t{\n\t\tfmt::format_to(fmt::appender(buf), \"\\tt{}: {}({},{},{})\\n\", i,\n\t\t               ternary_operator_to_string(m_ternaries[i].op),\n\t\t               m_ternaries[i].left.to_string(), m_ternaries[i].middle.to_string(),\n\t\t               m_ternaries[i].right.to_string());\n\t}\n\n\tfmt::format_to(fmt::appender(buf), \"Nary: {}\\n\", m_naries.size());\n\tfor (size_t i = 0; i < m_naries.size(); i++)\n\t{\n\t\tfmt::format_to(fmt::appender(buf), \"\\tn{}: {}(\", i,\n\t\t               nary_operator_to_string(m_naries[i].op));\n\t\tfor (size_t j = 0; j < m_naries[i].operands.size(); j++)\n\t\t{\n\t\t\tfmt::format_to(fmt::appender(buf), \"{}, \", m_naries[i].operands[j].to_string());\n\t\t}\n\t\tfmt::format_to(fmt::appender(buf), \")\\n\");\n\t}\n\n\tfmt::format_to(fmt::appender(buf), \"Constraint outputs: {}\\n\", m_constraint_outputs.size());\n\tfor (size_t i = 0; i < m_constraint_outputs.size(); i++)\n\t{\n\t\tfmt::format_to(fmt::appender(buf), \"\\tcon{}: {}\\n\", i, m_constraint_outputs[i].to_string());\n\t}\n\n\tfmt::format_to(fmt::appender(buf), \"Objective outputs: {}\\n\", m_objective_outputs.size());\n\tfor (size_t i = 0; i < m_objective_outputs.size(); i++)\n\t{\n\t\tfmt::format_to(fmt::appender(buf), \"\\tobj{}: {}\\n\", i, m_objective_outputs[i].to_string());\n\t}\n\n\treturn fmt::to_string(buf);\n}\n\nsize_t ExpressionGraph::n_variables() const\n{\n\treturn m_variables.size();\n}\n\nsize_t ExpressionGraph::n_constants() const\n{\n\treturn m_constants.size();\n}\n\nsize_t ExpressionGraph::n_parameters() const\n{\n\treturn m_parameters.size();\n}\n\nExpressionHandle ExpressionGraph::add_variable(EntityId id)\n{\n\tauto iter = m_variable_index_map.find(id);\n\tif (iter != m_variable_index_map.end())\n\t{\n\t\treturn {ArrayType::Variable, static_cast<NodeId>(iter->second)};\n\t}\n\telse\n\t{\n\t\tauto index = m_variables.size();\n\t\tm_variables.emplace_back(id);\n\t\tm_variable_index_map.emplace(id, index);\n\t\treturn {ArrayType::Variable, static_cast<NodeId>(index)};\n\t}\n}\n\nExpressionHandle ExpressionGraph::add_constant(double value)\n{\n\tm_constants.emplace_back(value);\n\treturn {ArrayType::Constant, static_cast<NodeId>(m_constants.size() - 1)};\n}\n\nExpressionHandle ExpressionGraph::add_parameter(EntityId id)\n{\n\tm_parameters.emplace_back(id);\n\treturn {ArrayType::Parameter, static_cast<NodeId>(m_parameters.size() - 1)};\n}\n\nExpressionHandle ExpressionGraph::add_unary(UnaryOperator op, ExpressionHandle operand)\n{\n\t// Constant folding: if the operand is a constant, compute the result directly\n\tif (operand.array == ArrayType::Constant)\n\t{\n\t\tdouble val = m_constants[operand.id];\n\t\tdouble result;\n\t\tswitch (op)\n\t\t{\n\t\tcase UnaryOperator::Neg:\n\t\t\tresult = -val;\n\t\t\tbreak;\n\t\tcase UnaryOperator::Sin:\n\t\t\tresult = std::sin(val);\n\t\t\tbreak;\n\t\tcase UnaryOperator::Cos:\n\t\t\tresult = std::cos(val);\n\t\t\tbreak;\n\t\tcase UnaryOperator::Tan:\n\t\t\tresult = std::tan(val);\n\t\t\tbreak;\n\t\tcase UnaryOperator::Asin:\n\t\t\tresult = std::asin(val);\n\t\t\tbreak;\n\t\tcase UnaryOperator::Acos:\n\t\t\tresult = std::acos(val);\n\t\t\tbreak;\n\t\tcase UnaryOperator::Atan:\n\t\t\tresult = std::atan(val);\n\t\t\tbreak;\n\t\tcase UnaryOperator::Abs:\n\t\t\tresult = std::abs(val);\n\t\t\tbreak;\n\t\tcase UnaryOperator::Sqrt:\n\t\t\tresult = std::sqrt(val);\n\t\t\tbreak;\n\t\tcase UnaryOperator::Exp:\n\t\t\tresult = std::exp(val);\n\t\t\tbreak;\n\t\tcase UnaryOperator::Log:\n\t\t\tresult = std::log(val);\n\t\t\tbreak;\n\t\tcase UnaryOperator::Log10:\n\t\t\tresult = std::log10(val);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t// Unknown operator, fall through to create the node\n\t\t\tgoto create_node;\n\t\t}\n\t\treturn add_constant(result);\n\t}\ncreate_node:\n\tm_unaries.emplace_back(op, operand);\n\treturn {ArrayType::Unary, static_cast<NodeId>(m_unaries.size() - 1)};\n}\n\nExpressionHandle ExpressionGraph::add_binary(BinaryOperator op, ExpressionHandle left,\n                                             ExpressionHandle right)\n{\n\t// Constant folding: if both operands are constants, compute the result directly\n\t// Note: comparison operators are not folded as they produce boolean results\n\tif (left.array == ArrayType::Constant && right.array == ArrayType::Constant &&\n\t    !is_binary_compare_op(op))\n\t{\n\t\tdouble lval = m_constants[left.id];\n\t\tdouble rval = m_constants[right.id];\n\t\tdouble result;\n\t\tswitch (op)\n\t\t{\n\t\tcase BinaryOperator::Sub:\n\t\t\tresult = lval - rval;\n\t\t\tbreak;\n\t\tcase BinaryOperator::Div:\n\t\t\tresult = lval / rval;\n\t\t\tbreak;\n\t\tcase BinaryOperator::Pow:\n\t\t\tresult = std::pow(lval, rval);\n\t\t\tbreak;\n\t\tcase BinaryOperator::Mul2:\n\t\t\tresult = lval * rval;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t// Comparison operators or unknown, fall through to create the node\n\t\t\tgoto create_node;\n\t\t}\n\t\treturn add_constant(result);\n\t}\ncreate_node:\n\tm_binaries.emplace_back(op, left, right);\n\treturn {ArrayType::Binary, static_cast<NodeId>(m_binaries.size() - 1)};\n}\n\nExpressionHandle ExpressionGraph::add_ternary(TernaryOperator op, ExpressionHandle left,\n                                              ExpressionHandle middle, ExpressionHandle right)\n{\n\tm_ternaries.emplace_back(op, left, middle, right);\n\treturn {ArrayType::Ternary, static_cast<NodeId>(m_ternaries.size() - 1)};\n}\n\nExpressionHandle ExpressionGraph::add_nary(NaryOperator op,\n                                           const std::vector<ExpressionHandle> &operands)\n{\n\t// Constant folding: if all operands are constants, compute the result directly\n\tbool all_constants = true;\n\tfor (const auto &operand : operands)\n\t{\n\t\tif (operand.array != ArrayType::Constant)\n\t\t{\n\t\t\tall_constants = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (all_constants && !operands.empty())\n\t{\n\t\tdouble result;\n\t\tswitch (op)\n\t\t{\n\t\tcase NaryOperator::Add:\n\t\t\tresult = 0.0;\n\t\t\tfor (const auto &operand : operands)\n\t\t\t{\n\t\t\t\tresult += m_constants[operand.id];\n\t\t\t}\n\t\t\tbreak;\n\t\tcase NaryOperator::Mul:\n\t\t\tresult = 1.0;\n\t\t\tfor (const auto &operand : operands)\n\t\t\t{\n\t\t\t\tresult *= m_constants[operand.id];\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tgoto create_node;\n\t\t}\n\t\treturn add_constant(result);\n\t}\n\ncreate_node:\n\tm_naries.emplace_back(op, operands);\n\treturn {ArrayType::Nary, static_cast<NodeId>(m_naries.size() - 1)};\n}\n\nExpressionHandle ExpressionGraph::add_repeat_nary(NaryOperator op, ExpressionHandle operand, int N)\n{\n\tstd::vector<ExpressionHandle> operands(N, operand);\n\treturn add_nary(op, operands);\n}\n\nvoid ExpressionGraph::append_nary(const ExpressionHandle &expression,\n                                  const ExpressionHandle &operand)\n{\n\tassert(expression.array == ArrayType::Nary);\n\tm_naries[expression.id].operands.push_back(operand);\n}\n\nNaryOperator ExpressionGraph::get_nary_operator(const ExpressionHandle &expression) const\n{\n\tassert(expression.array == ArrayType::Nary);\n\treturn m_naries[expression.id].op;\n}\n\nvoid ExpressionGraph::add_constraint_output(const ExpressionHandle &expression)\n{\n\tm_constraint_outputs.push_back(expression);\n}\n\nvoid ExpressionGraph::add_objective_output(const ExpressionHandle &expression)\n{\n\tm_objective_outputs.push_back(expression);\n}\n\nbool ExpressionGraph::has_constraint_output() const\n{\n\treturn !m_constraint_outputs.empty();\n}\n\nbool ExpressionGraph::has_objective_output() const\n{\n\treturn !m_objective_outputs.empty();\n}\n\nExpressionHandle ExpressionGraph::merge_variableindex(const VariableIndex &v)\n{\n\treturn add_variable(v.index);\n}\n\nExpressionHandle ExpressionGraph::merge_scalaraffinefunction(const ScalarAffineFunction &f)\n{\n\t// Convert it to a n-ary sum of multiplication nodes\n\tauto N = f.size();\n\tstd::vector<ExpressionHandle> terms;\n\tterms.reserve(N);\n\tfor (size_t i = 0; i < N; i++)\n\t{\n\t\tauto x = add_variable(f.variables[i]);\n\t\tauto coef = f.coefficients[i];\n\t\tif (coef == 1.0)\n\t\t{\n\t\t\tterms.push_back(x);\n\t\t}\n\t\telse if (coef == -1.0)\n\t\t{\n\t\t\tauto neg = add_unary(UnaryOperator::Neg, x);\n\t\t\tterms.push_back(neg);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto c = add_constant(coef);\n\t\t\tterms.push_back(add_nary(NaryOperator::Mul, {c, x}));\n\t\t}\n\t}\n\tif (f.constant)\n\t{\n\t\tterms.push_back(add_constant(f.constant.value()));\n\t}\n\tif (terms.size() == 1)\n\t{\n\t\treturn terms[0];\n\t}\n\telse\n\t{\n\t\treturn add_nary(NaryOperator::Add, terms);\n\t}\n}\n\nExpressionHandle ExpressionGraph::merge_scalarquadraticfunction(const ScalarQuadraticFunction &f)\n{\n\tauto N = f.size();\n\tstd::vector<ExpressionHandle> terms;\n\tterms.reserve(N + 1);\n\tfor (size_t i = 0; i < N; i++)\n\t{\n\t\tauto x1 = f.variable_1s[i];\n\t\tauto x2 = f.variable_2s[i];\n\t\tauto coef = f.coefficients[i];\n\n\t\tExpressionHandle x1_var = add_variable(x1);\n\t\tExpressionHandle x2_var;\n\n\t\tif (x1 == x2)\n\t\t{\n\t\t\tx2_var = x1_var;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tx2_var = add_variable(x2);\n\t\t}\n\n\t\tif (coef == 1.0)\n\t\t{\n\t\t\tterms.push_back(add_nary(NaryOperator::Mul, {x1_var, x2_var}));\n\t\t}\n\t\telse if (coef == -1.0)\n\t\t{\n\t\t\tauto neg = add_unary(UnaryOperator::Neg, add_nary(NaryOperator::Mul, {x1_var, x2_var}));\n\t\t\tterms.push_back(neg);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto c = add_constant(coef);\n\t\t\tterms.push_back(add_nary(NaryOperator::Mul, {c, x1_var, x2_var}));\n\t\t}\n\t}\n\tif (f.affine_part)\n\t{\n\t\tterms.push_back(merge_scalaraffinefunction(f.affine_part.value()));\n\t}\n\tif (terms.size() == 1)\n\t{\n\t\treturn terms[0];\n\t}\n\telse\n\t{\n\t\treturn add_nary(NaryOperator::Add, terms);\n\t}\n}\n\nExpressionHandle ExpressionGraph::merge_exprbuilder(const ExprBuilder &expr)\n{\n\tstd::vector<ExpressionHandle> terms;\n\tterms.reserve(expr.quadratic_terms.size() + expr.affine_terms.size() + 1);\n\tfor (const auto &[varpair, coef] : expr.quadratic_terms)\n\t{\n\t\tauto x1 = varpair.var_1;\n\t\tauto x2 = varpair.var_2;\n\n\t\tExpressionHandle x1_var = add_variable(x1);\n\t\tExpressionHandle x2_var;\n\n\t\tif (x1 == x2)\n\t\t{\n\t\t\tx2_var = x1_var;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tx2_var = add_variable(x2);\n\t\t}\n\n\t\tif (coef == 1.0)\n\t\t{\n\t\t\tterms.push_back(add_nary(NaryOperator::Mul, {x1_var, x2_var}));\n\t\t}\n\t\telse if (coef == -1.0)\n\t\t{\n\t\t\tauto neg = add_unary(UnaryOperator::Neg, add_nary(NaryOperator::Mul, {x1_var, x2_var}));\n\t\t\tterms.push_back(neg);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto c = add_constant(coef);\n\t\t\tterms.push_back(add_nary(NaryOperator::Mul, {c, x1_var, x2_var}));\n\t\t}\n\t}\n\tfor (const auto &[var, coef] : expr.affine_terms)\n\t{\n\t\tauto x = add_variable(var);\n\t\tif (coef == 1.0)\n\t\t{\n\t\t\tterms.push_back(x);\n\t\t}\n\t\telse if (coef == -1.0)\n\t\t{\n\t\t\tauto neg = add_unary(UnaryOperator::Neg, x);\n\t\t\tterms.push_back(neg);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tauto c = add_constant(coef);\n\t\t\tterms.push_back(add_nary(NaryOperator::Mul, {c, x}));\n\t\t}\n\t}\n\tif (expr.constant_term)\n\t{\n\t\tterms.push_back(add_constant(expr.constant_term.value()));\n\t}\n\tif (terms.size() == 1)\n\t{\n\t\treturn terms[0];\n\t}\n\telse\n\t{\n\t\treturn add_nary(NaryOperator::Add, terms);\n\t}\n}\n\nbool is_binary_compare_op(BinaryOperator op)\n{\n\treturn (op >= BinaryOperator::LessThan) && (op <= BinaryOperator::GreaterThan);\n}\n\nbool ExpressionGraph::is_compare_expression(const ExpressionHandle &expr) const\n{\n\tif (expr.array != ArrayType::Binary)\n\t{\n\t\treturn false;\n\t}\n\tauto &binary = m_binaries[expr.id];\n\tauto op = binary.op;\n\treturn is_binary_compare_op(op);\n}\n\nstd::string unary_operator_to_string(UnaryOperator op)\n{\n\tswitch (op)\n\t{\n\tcase UnaryOperator::Neg:\n\t\treturn \"Neg\";\n\tcase UnaryOperator::Sin:\n\t\treturn \"Sin\";\n\tcase UnaryOperator::Cos:\n\t\treturn \"Cos\";\n\tcase UnaryOperator::Tan:\n\t\treturn \"Tan\";\n\tcase UnaryOperator::Asin:\n\t\treturn \"Asin\";\n\tcase UnaryOperator::Acos:\n\t\treturn \"Acos\";\n\tcase UnaryOperator::Atan:\n\t\treturn \"Atan\";\n\tcase UnaryOperator::Abs:\n\t\treturn \"Abs\";\n\tcase UnaryOperator::Sqrt:\n\t\treturn \"Sqrt\";\n\tcase UnaryOperator::Exp:\n\t\treturn \"Exp\";\n\tcase UnaryOperator::Log:\n\t\treturn \"Log\";\n\tcase UnaryOperator::Log10:\n\t\treturn \"Log10\";\n\tdefault:\n\t\treturn \"UnknownUnary\";\n\t}\n}\n\nstd::string binary_operator_to_string(BinaryOperator op)\n{\n\tswitch (op)\n\t{\n\tcase BinaryOperator::Sub:\n\t\treturn \"Sub\";\n\tcase BinaryOperator::Div:\n\t\treturn \"Div\";\n\tcase BinaryOperator::Pow:\n\t\treturn \"Pow\";\n\tcase BinaryOperator::LessThan:\n\t\treturn \"LessThan\";\n\tcase BinaryOperator::LessEqual:\n\t\treturn \"LessEqual\";\n\tcase BinaryOperator::Equal:\n\t\treturn \"Equal\";\n\tcase BinaryOperator::NotEqual:\n\t\treturn \"NotEqual\";\n\tcase BinaryOperator::GreaterEqual:\n\t\treturn \"GreaterEqual\";\n\tcase BinaryOperator::GreaterThan:\n\t\treturn \"GreaterThan\";\n\tcase BinaryOperator::Add2:\n\t\treturn \"Add2\";\n\tcase BinaryOperator::Mul2:\n\t\treturn \"Mul2\";\n\tdefault:\n\t\treturn \"UnknownBinary\";\n\t}\n}\n\nstd::string ternary_operator_to_string(TernaryOperator op)\n{\n\tswitch (op)\n\t{\n\tcase TernaryOperator::IfThenElse:\n\t\treturn \"IfThenElse\";\n\tdefault:\n\t\treturn \"UnknownTernary\";\n\t}\n}\n\nstd::string nary_operator_to_string(NaryOperator op)\n{\n\tswitch (op)\n\t{\n\tcase NaryOperator::Add:\n\t\treturn \"Add\";\n\tcase NaryOperator::Mul:\n\t\treturn \"Mul\";\n\tdefault:\n\t\treturn \"UnknownNary\";\n\t}\n}\n\ninline static void hash_combine(uint64_t &hash, const uint64_t subhash)\n{\n\thash ^= subhash + 0x9e3779b9 + (hash << 6) + (hash >> 2);\n}\n\ninline static uint64_t to_i64(const ExpressionHandle &expr)\n{\n\tuint32_t array = static_cast<uint32_t>(expr.array);\n\tuint32_t id = static_cast<uint32_t>(expr.id);\n\treturn (static_cast<uint64_t>(array) << 32) | id;\n}\n\nuint64_t ExpressionGraph::main_structure_hash() const\n{\n\tuint64_t hash = 0;\n\thash_combine(hash, m_variables.size());\n\thash_combine(hash, m_constants.size());\n\thash_combine(hash, m_parameters.size());\n\n\tfor (const auto &unary : m_unaries)\n\t{\n\t\thash_combine(hash, (uint64_t)unary.op);\n\t\thash_combine(hash, to_i64(unary.operand));\n\t}\n\tfor (const auto &binary : m_binaries)\n\t{\n\t\thash_combine(hash, (uint64_t)binary.op);\n\t\thash_combine(hash, to_i64(binary.left));\n\t\thash_combine(hash, to_i64(binary.right));\n\t}\n\tfor (const auto &ternary : m_ternaries)\n\t{\n\t\thash_combine(hash, (uint64_t)ternary.op);\n\t\thash_combine(hash, to_i64(ternary.left));\n\t\thash_combine(hash, to_i64(ternary.middle));\n\t\thash_combine(hash, to_i64(ternary.right));\n\t}\n\tfor (const auto &nary : m_naries)\n\t{\n\t\thash_combine(hash, (uint64_t)nary.op);\n\t\tfor (const auto &operand : nary.operands)\n\t\t{\n\t\t\thash_combine(hash, to_i64(operand));\n\t\t}\n\t}\n\treturn hash;\n}\n\nuint64_t ExpressionGraph::constraint_structure_hash(uint64_t hash) const\n{\n\tfor (const auto &output : m_constraint_outputs)\n\t{\n\t\thash_combine(hash, to_i64(output));\n\t}\n\treturn hash;\n}\n\nuint64_t ExpressionGraph::objective_structure_hash(uint64_t hash) const\n{\n\tfor (const auto &output : m_objective_outputs)\n\t{\n\t\thash_combine(hash, to_i64(output));\n\t}\n\treturn hash;\n}\n\nvoid unpack_comparison_expression(ExpressionGraph &graph, const ExpressionHandle &expr,\n                                  ExpressionHandle &real_expr, double &lb, double &ub)\n{\n\t// Only handles constraint in the form of f <= g or f >= g or f == g\n\t// We need to tell if f or g is constant\n\t// if not, it will be converted into f-g <= 0 or f-g >= 0\n\tauto array_type = expr.array;\n\tauto index = expr.id;\n\n\tif (array_type != ArrayType::Binary)\n\t{\n\t\tthrow std::runtime_error(\"Only binary operator is supported for comparison constraint\");\n\t}\n\n\tauto &binary = graph.m_binaries[index];\n\tauto op = binary.op;\n\tif (op != BinaryOperator::LessEqual && op != BinaryOperator::GreaterEqual &&\n\t    op != BinaryOperator::Equal)\n\t{\n\t\tthrow std::runtime_error(\"Only <= or >= or == is supported for comparison constraint\");\n\t}\n\n\tauto f = binary.left;\n\tauto g = binary.right;\n\n\tif (op == BinaryOperator::GreaterEqual)\n\t{\n\t\t// swap f and g\n\t\tauto temp = f;\n\t\tf = g;\n\t\tg = temp;\n\n\t\top = BinaryOperator::LessEqual;\n\t}\n\n\t// Now we only handle f <= g or f == g\n\n\t// test if f or g is constant\n\tbool f_is_constant = f.array == ArrayType::Constant;\n\tbool g_is_constant = g.array == ArrayType::Constant;\n\n\tif (op == BinaryOperator::LessEqual)\n\t{\n\t\tif (f_is_constant)\n\t\t{\n\t\t\tlb = graph.m_constants[f.id];\n\t\t\treal_expr = g;\n\t\t}\n\t\telse if (g_is_constant)\n\t\t{\n\t\t\tub = graph.m_constants[g.id];\n\t\t\treal_expr = f;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// f - g <= 0\n\t\t\treal_expr = graph.add_binary(BinaryOperator::Sub, f, g);\n\t\t\tub = 0.0;\n\t\t}\n\t}\n\telse\n\t{\n\t\tif (f_is_constant)\n\t\t{\n\t\t\tlb = ub = graph.m_constants[f.id];\n\t\t\treal_expr = g;\n\t\t}\n\t\telse if (g_is_constant)\n\t\t{\n\t\t\tlb = ub = graph.m_constants[g.id];\n\t\t\treal_expr = f;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// f - g == 0\n\t\t\treal_expr = graph.add_binary(BinaryOperator::Sub, f, g);\n\t\t\tlb = ub = 0.0;\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "lib/nlexpr_ext.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include <nanobind/stl/vector.h>\n#include <nanobind/stl/tuple.h>\n#include <nanobind/stl/string.h>\n\n#include \"pyoptinterface/nlexpr.hpp\"\n\nnamespace nb = nanobind;\n\nNB_MODULE(nlexpr_ext, m)\n{\n\tm.import_(\"pyoptinterface._src.core_ext\");\n\n\tnb::enum_<ArrayType>(m, \"ArrayType\")\n\t    .value(\"Constant\", ArrayType::Constant)\n\t    .value(\"Variable\", ArrayType::Variable)\n\t    .value(\"Parameter\", ArrayType::Parameter)\n\t    .value(\"Unary\", ArrayType::Unary)\n\t    .value(\"Binary\", ArrayType::Binary)\n\t    .value(\"Ternary\", ArrayType::Ternary)\n\t    .value(\"Nary\", ArrayType::Nary);\n\n\tnb::enum_<UnaryOperator>(m, \"UnaryOperator\")\n\t    .value(\"Neg\", UnaryOperator::Neg)\n\t    .value(\"Sin\", UnaryOperator::Sin)\n\t    .value(\"Cos\", UnaryOperator::Cos)\n\t    .value(\"Tan\", UnaryOperator::Tan)\n\t    .value(\"Asin\", UnaryOperator::Asin)\n\t    .value(\"Acos\", UnaryOperator::Acos)\n\t    .value(\"Atan\", UnaryOperator::Atan)\n\t    .value(\"Abs\", UnaryOperator::Abs)\n\t    .value(\"Sqrt\", UnaryOperator::Sqrt)\n\t    .value(\"Exp\", UnaryOperator::Exp)\n\t    .value(\"Log\", UnaryOperator::Log)\n\t    .value(\"Log10\", UnaryOperator::Log10);\n\n\tnb::enum_<BinaryOperator>(m, \"BinaryOperator\")\n\t    .value(\"Sub\", BinaryOperator::Sub)\n\t    .value(\"Div\", BinaryOperator::Div)\n\t    .value(\"Pow\", BinaryOperator::Pow)\n\t    // compare ops\n\t    .value(\"LessThan\", BinaryOperator::LessThan)\n\t    .value(\"LessEqual\", BinaryOperator::LessEqual)\n\t    .value(\"Equal\", BinaryOperator::Equal)\n\t    .value(\"NotEqual\", BinaryOperator::NotEqual)\n\t    .value(\"GreaterEqual\", BinaryOperator::GreaterEqual)\n\t    .value(\"GreaterThan\", BinaryOperator::GreaterThan);\n\n\tnb::enum_<TernaryOperator>(m, \"TernaryOperator\")\n\t    .value(\"IfThenElse\", TernaryOperator::IfThenElse);\n\n\tnb::enum_<NaryOperator>(m, \"NaryOperator\")\n\t    .value(\"Add\", NaryOperator::Add)\n\t    .value(\"Mul\", NaryOperator::Mul);\n\n\tnb::class_<ExpressionHandle>(m, \"ExpressionHandle\")\n\t    .def(nb::init<ArrayType, NodeId>())\n\t    .def_ro(\"array\", &ExpressionHandle::array)\n\t    .def_ro(\"id\", &ExpressionHandle::id);\n\n\tnb::class_<UnaryNode>(m, \"UnaryNode\")\n\t    .def(nb::init<UnaryOperator, ExpressionHandle>())\n\t    .def_ro(\"op\", &UnaryNode::op)\n\t    .def_ro(\"operand\", &UnaryNode::operand);\n\n\tnb::class_<BinaryNode>(m, \"BinaryNode\")\n\t    .def(nb::init<BinaryOperator, ExpressionHandle, ExpressionHandle>())\n\t    .def_ro(\"op\", &BinaryNode::op)\n\t    .def_ro(\"left\", &BinaryNode::left)\n\t    .def_ro(\"right\", &BinaryNode::right);\n\n\tnb::class_<NaryNode>(m, \"NaryNode\")\n\t    .def(nb::init<NaryOperator, const std::vector<ExpressionHandle> &>())\n\t    .def_ro(\"op\", &NaryNode::op)\n\t    .def_ro(\"operands\", &NaryNode::operands);\n\n\tnb::class_<ExpressionGraph>(m, \"ExpressionGraph\")\n\t    .def(nb::init<>())\n\t    .def(\"__str__\", &ExpressionGraph::to_string)\n\t    .def(\"n_variables\", &ExpressionGraph::n_variables)\n\t    .def(\"n_parameters\", &ExpressionGraph::n_parameters)\n\t    .def(\"add_variable\", &ExpressionGraph::add_variable, nb::arg(\"id\") = 0)\n\t    .def(\"add_constant\", &ExpressionGraph::add_constant, nb::arg(\"value\"))\n\t    .def(\"add_parameter\", &ExpressionGraph::add_parameter, nb::arg(\"id\") = 0)\n\t    .def(\"add_unary\", &ExpressionGraph::add_unary)\n\t    .def(\"add_binary\", &ExpressionGraph::add_binary)\n\t    .def(\"add_ternary\", &ExpressionGraph::add_ternary)\n\t    .def(\"add_nary\", &ExpressionGraph::add_nary)\n\t    .def(\"add_repeat_nary\", &ExpressionGraph::add_repeat_nary)\n\t    .def(\"append_nary\", &ExpressionGraph::append_nary)\n\t    .def(\"get_nary_operator\", &ExpressionGraph::get_nary_operator)\n\t    .def(\"add_constraint_output\", &ExpressionGraph::add_constraint_output)\n\t    .def(\"add_objective_output\", &ExpressionGraph::add_objective_output)\n\t    .def(\"merge_variableindex\", &ExpressionGraph::merge_variableindex)\n\t    .def(\"merge_scalaraffinefunction\", &ExpressionGraph::merge_scalaraffinefunction)\n\t    .def(\"merge_scalarquadraticfunction\", &ExpressionGraph::merge_scalarquadraticfunction)\n\t    .def(\"merge_exprbuilder\", &ExpressionGraph::merge_exprbuilder)\n\t    .def(\"is_compare_expression\", &ExpressionGraph::is_compare_expression);\n\n\tm.def(\"unpack_comparison_expression\",\n\t      [](ExpressionGraph &graph, const ExpressionHandle &expr, double INF) {\n\t\t      ExpressionHandle real_expr;\n\t\t      double lb = -INF, ub = INF;\n\t\t      unpack_comparison_expression(graph, expr, real_expr, lb, ub);\n\t\t      return std::make_tuple(real_expr, lb, ub);\n\t      });\n}\n"
  },
  {
    "path": "lib/tcc_interface.cpp",
    "content": "#include \"pyoptinterface/tcc_interface.hpp\"\n#include <stdexcept>\n#include <math.h>\n#include \"fmt/core.h\"\n\nnamespace tcc\n{\n#define B DYLIB_DECLARE\nAPILIST\n#undef B\n\nstatic DynamicLibrary lib;\nstatic bool is_loaded = false;\n\nbool is_library_loaded()\n{\n\treturn is_loaded;\n}\n\nbool load_library(const std::string &path)\n{\n\tbool success = lib.try_load(path.c_str());\n\tif (!success)\n\t{\n\t\treturn false;\n\t}\n\n\tDYLIB_LOAD_INIT;\n\n#define B DYLIB_LOAD_FUNCTION\n\tAPILIST\n#undef B\n\n\tif (IS_DYLIB_LOAD_SUCCESS)\n\t{\n#define B DYLIB_SAVE_FUNCTION\n\t\tAPILIST\n#undef B\n\t\tis_loaded = true;\n\t\treturn true;\n\t}\n\telse\n\t{\n\t\treturn false;\n\t}\n}\n} // namespace tcc\n\nvoid TCCInstance::init()\n{\n\tTCCState *state = tcc::tcc_new();\n\n\tif (state == nullptr)\n\t{\n\t\tthrow std::runtime_error(\"Failed to create TCC state\");\n\t}\n\n\tm_state.reset(state);\n\n\tint ret = tcc::tcc_set_output_type(m_state.get(), TCC_OUTPUT_MEMORY);\n\tif (ret == -1)\n\t{\n\t\tthrow std::runtime_error(\"Failed to set output type\");\n\t}\n}\n\nvoid TCCInstance::add_include_path(const std::string &path)\n{\n\tint ret = tcc::tcc_add_include_path(m_state.get(), path.c_str());\n\tif (ret == -1)\n\t{\n\t\tthrow std::runtime_error(fmt::format(\"Failed to add include path {}\", path));\n\t}\n}\n\nvoid TCCInstance::add_sysinclude_path(const std::string &path)\n{\n\tint ret = tcc::tcc_add_sysinclude_path(m_state.get(), path.c_str());\n\tif (ret == -1)\n\t{\n\t\tthrow std::runtime_error(fmt::format(\"Failed to add sysinclude path {}\", path));\n\t}\n}\n\nvoid TCCInstance::add_library_path(const std::string &path)\n{\n\tint ret = tcc::tcc_add_library_path(m_state.get(), path.c_str());\n\tif (ret == -1)\n\t{\n\t\tthrow std::runtime_error(fmt::format(\"Failed to add library path {}\", path));\n\t}\n}\n\nvoid TCCInstance::add_library(const std::string &name)\n{\n\tint ret = tcc::tcc_add_library(m_state.get(), name.c_str());\n\tif (ret == -1)\n\t{\n\t\tthrow std::runtime_error(fmt::format(\"Failed to add library {}\", name));\n\t}\n}\n\nvoid TCCInstance::import_math_symbols()\n{\n\tint ret;\n\n#define UNARY_MATH_SYMBOL(name)                                                         \\\n\t{                                                                                   \\\n\t\tauto ptr = static_cast<double (*)(double)>(name);                               \\\n\t\tret = tcc::tcc_add_symbol(m_state.get(), #name, reinterpret_cast<void *>(ptr)); \\\n\t\tif (ret == -1)                                                                  \\\n\t\t{                                                                               \\\n\t\t\tthrow std::runtime_error(fmt::format(\"Failed to add symbol {}\", #name));    \\\n\t\t}                                                                               \\\n\t}\n\n\tUNARY_MATH_SYMBOL(sin);\n\tUNARY_MATH_SYMBOL(cos);\n\tUNARY_MATH_SYMBOL(tan);\n\tUNARY_MATH_SYMBOL(asin);\n\tUNARY_MATH_SYMBOL(acos);\n\tUNARY_MATH_SYMBOL(atan);\n\tUNARY_MATH_SYMBOL(fabs);\n\tUNARY_MATH_SYMBOL(sqrt);\n\tUNARY_MATH_SYMBOL(exp);\n\tUNARY_MATH_SYMBOL(log);\n\tUNARY_MATH_SYMBOL(log10);\n\n#define BINARY_MATH_SYMBOL(name)                                                        \\\n\t{                                                                                   \\\n\t\tauto ptr = static_cast<double (*)(double, double)>(name);                       \\\n\t\tret = tcc::tcc_add_symbol(m_state.get(), #name, reinterpret_cast<void *>(ptr)); \\\n\t\tif (ret == -1)                                                                  \\\n\t\t{                                                                               \\\n\t\t\tthrow std::runtime_error(fmt::format(\"Failed to add symbol {}\", #name));    \\\n\t\t}                                                                               \\\n\t}\n\n\tBINARY_MATH_SYMBOL(pow);\n\n#undef UNARY_MATH_SYMBOL\n#undef BINARY_MATH_SYMBOL\n}\n\nvoid TCCInstance::compile_string(const std::string &code)\n{\n\tint ret = tcc::tcc_compile_string(m_state.get(), code.c_str());\n\tif (ret == -1)\n\t{\n\t\tthrow std::runtime_error(\"Failed to compile code\");\n\t}\n\n\tret = tcc::tcc_relocate(m_state.get());\n\tif (ret == -1)\n\t{\n\t\tthrow std::runtime_error(\"Failed to relocate code\");\n\t}\n}\n\nuintptr_t TCCInstance::get_symbol(const std::string &name)\n{\n\tvoid *ptr = tcc::tcc_get_symbol(m_state.get(), name.c_str());\n\tif (ptr == nullptr)\n\t{\n\t\tthrow std::runtime_error(fmt::format(\"Failed to get symbol {}\", name));\n\t}\n\treturn reinterpret_cast<uintptr_t>(ptr);\n}\n"
  },
  {
    "path": "lib/tcc_interface_ext.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include <nanobind/stl/string.h>\n\n#include \"pyoptinterface/tcc_interface.hpp\"\n\nnamespace nb = nanobind;\n\nNB_MODULE(tcc_interface_ext, m)\n{\n\tm.def(\"is_library_loaded\", &tcc::is_library_loaded);\n\tm.def(\"load_library\", &tcc::load_library);\n\n\tnb::class_<TCCInstance>(m, \"TCCInstance\")\n\t    .def(nb::init<>())\n\t    .def(\"init\", &TCCInstance::init)\n\t    .def(\"add_include_path\", &TCCInstance::add_include_path)\n\t    .def(\"add_sysinclude_path\", &TCCInstance::add_sysinclude_path)\n\t    .def(\"add_library_path\", &TCCInstance::add_library_path)\n\t    .def(\"add_library\", &TCCInstance::add_library)\n\t    .def(\"import_math_symbols\", &TCCInstance::import_math_symbols)\n\t    .def(\"compile_string\", &TCCInstance::compile_string)\n\t    .def(\"get_symbol\", &TCCInstance::get_symbol);\n}"
  },
  {
    "path": "lib/xpress_model.cpp",
    "content": "#include \"pyoptinterface/xpress_model.hpp\"\n#include \"fmt/core.h\"\n#include \"pyoptinterface/core.hpp\"\n\n#include <concepts>\n#include <cstdio>\n#include <exception>\n#include <mutex>\n#include <stack>\n#include <stdexcept>\n#ifndef _WIN32\n#include <unistd.h>\n#endif\n\nnamespace xpress\n{\n\n// Simple helper to have a Go-like defer functionality.\n// Mainly used to move resource release closer to its acquisition.\ntemplate <typename LmdT>\nstruct Defer : LmdT\n{\n\tDefer(LmdT l) : LmdT(l) {};\n\t~Defer() noexcept\n\t{\n\t\t(*this)();\n\t}\n};\n\n// Mimics what is done to load the other solvers.\n#define B DYLIB_DECLARE\nAPILIST\n#undef B\n\nstatic DynamicLibrary lib;\nstatic bool is_loaded = false;\n\nbool is_library_loaded()\n{\n\treturn is_loaded;\n}\n\nbool load_library(const std::string &path)\n{\n\tbool success = lib.try_load(path.c_str());\n\tif (!success)\n\t{\n\t\treturn false;\n\t}\n\n\tDYLIB_LOAD_INIT;\n\n#define B DYLIB_LOAD_FUNCTION\n\tAPILIST\n#undef B\n\n\tif (IS_DYLIB_LOAD_SUCCESS)\n\t{\n#define B DYLIB_SAVE_FUNCTION\n\t\tAPILIST\n#undef B\n\t\tis_loaded = true;\n\t\tint major = {};\n\t\tint minor = {};\n\t\tint build = {};\n\t\tXPRSgetversionnumbers(&major, &minor, &build);\n\t\t// Use tuple comparison operator\n\t\tif (major < XPRS_VER_MAJOR)\n\t\t{\n\t\t\tfmt::print(\n\t\t\t    stderr,\n\t\t\t    \"Warning: loaded Xpress version is older than the officially supported one.\\n\");\n\t\t}\n\t}\n\treturn is_loaded;\n}\n\nstatic void check_license(int error)\n{\n\tif (error == 0)\n\t{\n\t\treturn;\n\t}\n\n\tchar buffer[POI_XPRS_MAXMESSAGELENGTH];\n\tif (XPRSgetlicerrmsg(buffer, sizeof buffer) != 0)\n\t{\n\t\tthrow std::runtime_error(\"Error while getting the Xpress license error message\");\n\t}\n\tthrow std::runtime_error(\n\t    fmt::format(\"Error while initializing Xpress Environment: {}\", buffer));\n}\n\nEnv::Env(const char *path)\n{\n\tif (!xpress::is_library_loaded())\n\t{\n\t\tthrow std::runtime_error(\"Xpress library is not loaded\");\n\t}\n\n\tauto lg = std::lock_guard(mtx);\n\tassert(init_count >= 0);\n\n\tif (init_count <= 0)\n\t{\n\t\tcheck_license(XPRSinit(path));\n\t}\n\t++init_count;\n\tinitialized = true;\n}\n\nEnv::~Env()\n{\n\ttry\n\t{\n\t\tclose();\n\t}\n\tcatch (std::exception e)\n\t{\n\t\tfmt::print(stderr, \"{}\\n\", e.what());\n\t\tfflush(stderr);\n\t}\n}\n\nvoid Env::close()\n{\n\tif (!initialized)\n\t{\n\t\treturn;\n\t}\n\tinitialized = false;\n\n\tauto lg = std::lock_guard(mtx);\n\t--init_count;\n\tassert(init_count >= 0);\n\n\tif (init_count <= 0 && XPRSfree() != 0)\n\t{\n\t\tthrow std::runtime_error(\"Error while freeing Xpress environment\");\n\t}\n}\n\nstd::pair<int, std::string> license(int p_i, const char *p_c)\n{\n\tint i = p_i;\n\tstd::string c(p_c);\n\tcheck_license(XPRSlicense(&i, c.data()));\n\tc.resize(strlen(c.data()));\n\treturn std::make_pair(i, c);\n}\n\nbool beginlicensing()\n{\n\tint notyet = {};\n\tcheck_license(XPRSbeginlicensing(&notyet));\n\treturn notyet != 0;\n}\n\nvoid endlicensing()\n{\n\tcheck_license(XPRSendlicensing());\n}\n\nstatic char poi_to_xprs_cons_sense(ConstraintSense sense)\n{\n\tswitch (sense)\n\t{\n\tcase ConstraintSense::LessEqual:\n\t\treturn 'L';\n\tcase ConstraintSense::Equal:\n\t\treturn 'E';\n\tcase ConstraintSense::GreaterEqual:\n\t\treturn 'G';\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint sense\");\n\t}\n}\n\nstatic ConstraintSense xprs_to_poi_cons_sense(int ctype)\n{\n\tswitch (ctype)\n\t{\n\tcase 'L':\n\t\treturn ConstraintSense::LessEqual;\n\tcase 'E':\n\t\treturn ConstraintSense::Equal;\n\tcase 'G':\n\t\treturn ConstraintSense::GreaterEqual;\n\tcase 'R': // Range constraints\n\tcase 'N': // Free constraints\n\tdefault:\n\t\tthrow std::runtime_error(\"Unsupported constraint sense\");\n\t}\n}\nstatic int poi_to_xprs_obj_sense(ObjectiveSense sense)\n{\n\tswitch (sense)\n\t{\n\tcase ObjectiveSense::Minimize:\n\t\treturn POI_XPRS_OBJ_MINIMIZE;\n\tcase ObjectiveSense::Maximize:\n\t\treturn POI_XPRS_OBJ_MAXIMIZE;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown objective function sense\");\n\t}\n}\n\nstatic char poi_to_xprs_var_type(VariableDomain domain)\n{\n\tswitch (domain)\n\t{\n\tcase VariableDomain::Continuous:\n\t\treturn 'C';\n\tcase VariableDomain::Integer:\n\t\treturn 'I';\n\tcase VariableDomain::Binary:\n\t\treturn 'B';\n\tcase VariableDomain::SemiContinuous:\n\t\treturn 'S';\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown variable domain\");\n\t}\n}\n\nstatic VariableDomain xprs_to_poi_var_type(char vtype)\n{\n\tswitch (vtype)\n\t{\n\tcase 'C':\n\t\treturn VariableDomain::Continuous;\n\tcase 'I':\n\t\treturn VariableDomain::Integer;\n\tcase 'B':\n\t\treturn VariableDomain::Binary;\n\tcase 'S':\n\t\treturn VariableDomain::SemiContinuous;\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown variable domain\");\n\t}\n}\n\nstatic char poi_to_xprs_sos_type(SOSType type)\n{\n\tswitch (type)\n\t{\n\tcase SOSType::SOS1:\n\t\treturn '1';\n\tcase SOSType::SOS2:\n\t\treturn '2';\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown SOS type\");\n\t}\n}\n\n// Check Xpress APIs return value for error and throws in case it is non-zero\nvoid Model::_check(int error)\n{\n\t// We allow users to define custom message callbacks which may throw exceptions. Since\n\t// Xpress APIs can trigger messages at any point, exceptions might be thrown even from\n\t// apparently \"safe\" operations. We always check for captured exceptions before returning.\n\tif (m_mode == XPRESS_MODEL_MODE::MAIN && !m_captured_exceptions.empty())\n\t{\n\t\tDefer exceptions_clear = [&] { m_captured_exceptions.clear(); };\n\n\t\t// Single exception - rethrow directly\n\t\tif (m_captured_exceptions.size() == 1)\n\t\t{\n\t\t\tstd::rethrow_exception(m_captured_exceptions[0]);\n\t\t}\n\n\t\t// Multiple exceptions - aggregate into single message\n\t\tstd::string new_what = \"Multiple exceptions raised:\\n\";\n\t\tfor (int i = 0; const auto &exc : m_captured_exceptions)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tstd::rethrow_exception(exc);\n\t\t\t}\n\t\t\tcatch (const std::exception &e)\n\t\t\t{\n\t\t\t\tfmt::format_to(std::back_inserter(new_what), \"{}. {}\\n\", ++i, e.what());\n\t\t\t}\n\t\t\tcatch (...)\n\t\t\t{\n\t\t\t\tfmt::format_to(std::back_inserter(new_what), \"{}. Unknown exception\\n\", ++i);\n\t\t\t}\n\t\t}\n\t\tthrow std::runtime_error(new_what);\n\t}\n\n\tif (error == 0)\n\t{\n\t\treturn;\n\t}\n\n\tchar error_buffer[POI_XPRS_MAXMESSAGELENGTH];\n\tif (XPRSgetlasterror(m_model.get(), error_buffer) != 0)\n\t{\n\t\tthrow std::runtime_error(\"Error while getting Xpress message error\");\n\t}\n\tthrow std::runtime_error(error_buffer);\n}\n\n// The default behavior of Xpress C APIs is to don't print anything unless a message CB is\n// registered. Thus, this is the default print callback that redirect to standard streams.\nstatic void default_print(XPRSprob prob, void *, char const *msg, int msgsize, int msgtype)\n{\n\tif (msgtype < 0)\n\t{\n\t\t// Negative values are used to signal output end, and can be use as flush trigger\n\t\t// But we flush at every message, so no problem need to flush again.\n\t\treturn;\n\t}\n\n\tFILE *out = (msgtype == 1 ? stdout : stderr);\n\tfmt::print(out, \"{}\\n\", msgsize > 0 ? msg : \"\");\n\tfflush(out);\n}\n\nModel::Model(const Env &env)\n{\n\tinit(env);\n\n\t// The default behavior expected by POI differ a bit from Xpress default behavior. Here we\n\t// adjust some controls:\n\n\t// Verbose by default, the user can silence if needed\n\tset_raw_control_int_by_id(POI_XPRS_OUTPUTLOG, 1);\n\n\t// Register a message callback (can be overridden)\n\t_check(XPRSaddcbmessage(m_model.get(), &default_print, nullptr, 0));\n\tis_default_message_cb_set = true;\n\n\t// We do not support concurrent CBs invocation since each callback have to acquire Python GIL\n\t_check(XPRSsetintcontrol64(m_model.get(), POI_XPRS_MUTEXCALLBACKS, 1));\n\n\t// Use global solver if the model contains non linear formulas\n\tset_raw_control_int_by_id(POI_XPRS_NLPSOLVER, POI_XPRS_NLPSOLVER_GLOBAL);\n}\n\nvoid Model::init(const Env &env)\n{\n\tif (!xpress::is_library_loaded())\n\t{\n\t\tthrow std::runtime_error(\"Xpress library is not loaded\");\n\t}\n\tif (auto lg = std::lock_guard(Env::mtx); Env::init_count <= 0)\n\t{\n\t\tthrow std::runtime_error(\"Xpress environment is not initialized\");\n\t}\n\tXPRSprob prob = nullptr;\n\t_check(XPRScreateprob(&prob));\n\tm_model.reset(prob);\n\t_clear_caches();\n}\n\nXPRSprob Model::_toggle_model_mode(XPRSprob model)\n{\n\tif (m_mode == XPRESS_MODEL_MODE::MAIN)\n\t{\n\t\tm_mode = XPRESS_MODEL_MODE::CALLBACK_;\n\t}\n\telse\n\t{\n\t\tm_mode = XPRESS_MODEL_MODE::MAIN;\n\t}\n\tXPRSprob old = m_model.release();\n\tm_model.reset(model);\n\treturn old;\n}\n\nModel::~Model()\ntry\n{\n\tclose();\n}\ncatch (std::exception e)\n{\n\tfmt::print(stderr, \"{}\\n\", e.what());\n\tfflush(stderr);\n}\n\nvoid Model::close()\n{\n\t// In CALLBACK mode we cannot destroy the problem, we release the unique_ptr instead\n\tif (m_mode == XPRESS_MODEL_MODE::CALLBACK_)\n\t{\n\t\t[[maybe_unused]] auto _ = m_model.release();\n\t}\n\telse\n\t{\n\t\tm_model.reset();\n\t}\n}\n\nvoid Model::_clear_caches()\n{\n\tm_primal_ray.clear();\n\tm_dual_ray.clear();\n\tm_iis_cols.clear();\n\tm_iss_rows.clear();\n\tm_iis_bound_types.clear();\n}\n\ndouble Model::get_infinity()\n{\n\treturn POI_XPRS_PLUSINFINITY;\n}\n\nvoid Model::write(const std::string &filename)\n{\n\t// Detect if the file should be compressed by looking at the last file\n\t// extension. We exploit short-circuiting and fold expressions to avoid long\n\t// else if branches.\n\tauto find_compress_ext_len = [&](auto &...extensions) {\n\t\tsize_t ext_len = 0;\n\t\t((filename.ends_with(extensions) && (ext_len = sizeof extensions - 1)) || ...);\n\t\treturn ext_len;\n\t};\n\tsize_t compress_ext_len = find_compress_ext_len(\".gz\", \".zip\", \".tar\", \".tgz\", \".bz2\", \".bzip\",\n\t                                                \".7z\", \".xz\", \".lz4\", \".Z\");\n\tstd::string_view fname = filename;\n\tfname.remove_suffix(compress_ext_len);\n\n\t// Based on the second last extension, we deduce what the user wants.\n\tif (fname.ends_with(\".mps\"))\n\t{\n\t\t_check(XPRSwriteprob(m_model.get(), filename.c_str(), \"v\"));\n\t}\n\telse if (fname.ends_with(\".lp\"))\n\t{\n\t\t_check(XPRSwriteprob(m_model.get(), filename.c_str(), \"lv\"));\n\t}\n\telse if (fname.ends_with(\".bss\"))\n\t{\n\t\t_check(XPRSwritebasis(m_model.get(), filename.c_str(), \"v\"));\n\t}\n\telse if (fname.ends_with(\".hdr\") || fname.ends_with(\".asc\"))\n\t{\n\t\t_check(XPRSwritesol(m_model.get(), filename.c_str(), \"v\"));\n\t}\n\telse if (fname.ends_with(\".sol\"))\n\t{\n\t\t_check(XPRSwritebinsol(m_model.get(), filename.c_str(), \"v\"));\n\t}\n\telse if (fname.ends_with(\".prt\"))\n\t{\n\t\t_check(XPRSwriteprtsol(m_model.get(), filename.c_str(), \"v\"));\n\t}\n\telse if (fname.ends_with(\".slx\"))\n\t{\n\t\t_check(XPRSwriteslxsol(m_model.get(), filename.c_str(), \"v\"));\n\t}\n\telse if (fname.ends_with(\".svf\"))\n\t{\n\t\t_check(XPRSsaveas(m_model.get(), filename.c_str()));\n\t}\n\telse\n\t{\n\t\tthrow std::runtime_error(\"Unknow file extension\");\n\t}\n}\n\nstd::string Model::get_problem_name()\n{\n\tint size = get_raw_attribute_int_by_id(POI_XPRS_MAXPROBNAMELENGTH) + 1;\n\tstd::string probname;\n\tprobname.resize(size);\n\t_check(XPRSgetprobname(m_model.get(), probname.data()));\n\t// Align string size with string length\n\tprobname.resize(strlen(probname.c_str()));\n\treturn probname;\n}\n\nvoid Model::set_problem_name(const std::string &probname)\n{\n\t_check(XPRSsetprobname(m_model.get(), probname.c_str()));\n}\n\nVariableIndex Model::add_variable(VariableDomain domain, double lb, double ub, const char *name)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tIndexT index = m_variable_index.add_index();\n\tVariableIndex variable(index);\n\n\tdouble zero[] = {0.0};\n\tint colidx = get_raw_attribute_int_by_id(POI_XPRS_COLS);\n\t_check(XPRSaddcols64(m_model.get(), 1, 0, zero, nullptr, nullptr, nullptr, &lb, &ub));\n\t_set_entity_name(POI_XPRS_NAMES_COLUMN, colidx, name);\n\tchar vtype = poi_to_xprs_var_type(domain);\n\tif (domain != VariableDomain::Continuous)\n\t{\n\t\tchar vtype = poi_to_xprs_var_type(domain);\n\t\tint icol = colidx;\n\t\t_check(XPRSchgcoltype(m_model.get(), 1, &icol, &vtype));\n\t}\n\treturn variable;\n}\n\nvoid Model::delete_variable(VariableIndex variable)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tif (!is_variable_active(variable))\n\t{\n\t\tthrow std::runtime_error(\"Variable does not exist\");\n\t}\n\tint colidx = _variable_index(variable);\n\t_check(XPRSdelcols(m_model.get(), 1, &colidx));\n\tm_variable_index.delete_index(variable.index);\n}\n\nvoid Model::delete_variables(const Vector<VariableIndex> &variables)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tint n_variables = variables.size();\n\tif (n_variables == 0)\n\t\treturn;\n\n\tstd::vector<int> columns;\n\tcolumns.reserve(n_variables);\n\tfor (int i = {}; i < n_variables; i++)\n\t{\n\t\tif (!is_variable_active(variables[i]))\n\t\t{\n\t\t\tcontinue;\n\t\t}\n\t\tauto column = _variable_index(variables[i]);\n\t\tcolumns.push_back(column);\n\t}\n\t_check(XPRSdelcols(m_model.get(), columns.size(), columns.data()));\n\n\tfor (int i = {}; i < n_variables; i++)\n\t{\n\t\tm_variable_index.delete_index(variables[i].index);\n\t}\n}\n\nbool Model::is_variable_active(VariableIndex variable)\n{\n\treturn m_variable_index.has_index(variable.index);\n}\n\nstd::string Model::pprint_variable(VariableIndex variable)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\treturn get_variable_name(variable);\n}\n\nstd::string Model::_get_entity_name(int etype, int eidx)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tint req_size = {};\n\t_check(XPRSgetnamelist(m_model.get(), etype, nullptr, 0, &req_size, eidx, eidx));\n\tstd::string value = {};\n\tvalue.resize(req_size);\n\t_check(XPRSgetnamelist(m_model.get(), etype, value.data(), req_size, &req_size, eidx, eidx));\n\twhile (value.back() == '\\0')\n\t{\n\t\tvalue.pop_back();\n\t}\n\treturn value;\n}\n\nstd::string Model::get_variable_name(VariableIndex variable)\n{\n\tint colidx = _checked_variable_index(variable);\n\treturn _get_entity_name(POI_XPRS_NAMES_COLUMN, colidx);\n}\n\nstd::string Model::get_constraint_name(ConstraintIndex constraint)\n{\n\tint rowidx = _checked_constraint_index(constraint);\n\treturn _get_entity_name(POI_XPRS_NAMES_ROW, rowidx);\n}\n\nvoid Model::set_variable_bounds(VariableIndex variable, double lb, double ub)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tint column = _checked_variable_index(variable);\n\tint columns[] = {column, column};\n\tchar btypes[] = \"LU\";\n\tdouble bounds[] = {lb, ub};\n\t_check(XPRSchgbounds(m_model.get(), 2, columns, btypes, bounds));\n}\n\nvoid Model::set_variable_lowerbound(VariableIndex variable, double lb)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tint colidx = _checked_variable_index(variable);\n\t_check(XPRSchgbounds(m_model.get(), 1, &colidx, \"L\", &lb));\n}\n\nvoid Model::set_variable_upperbound(VariableIndex variable, double ub)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tint colidx = _checked_variable_index(variable);\n\t_check(XPRSchgbounds(m_model.get(), 1, &colidx, \"U\", &ub));\n}\n\nvoid Model::set_variable_type(VariableIndex variable, VariableDomain vdomain)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tint colidx = _checked_variable_index(variable);\n\tchar vtype = poi_to_xprs_var_type(vdomain);\n\t_check(XPRSchgcoltype(m_model.get(), 1, &colidx, &vtype));\n}\n\nvoid Model::_set_entity_name(int etype, int index, const char *name)\n{\n\tif (name == nullptr || name[0] == '\\0')\n\t{\n\t\treturn;\n\t}\n\t_check(XPRSaddnames(m_model.get(), etype, name, index, index));\n}\n\nvoid Model::add_mip_start(const std::vector<VariableIndex> &variables,\n                          const std::vector<double> &values)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\tif (variables.size() != values.size())\n\t{\n\t\tthrow std::runtime_error(\"Number of variables and values do not match\");\n\t}\n\tint numnz = variables.size();\n\tif (numnz == 0)\n\t{\n\t\treturn;\n\t}\n\n\tstd::vector<int> ind_v(numnz);\n\tfor (int i = {}; i < numnz; i++)\n\t{\n\t\tind_v[i] = _checked_variable_index(variables[i].index);\n\t}\n\t_check(XPRSaddmipsol(m_model.get(), numnz, values.data(), ind_v.data(), nullptr));\n}\n\nvoid Model::set_variable_name(VariableIndex variable, const char *name)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tint column = _checked_variable_index(variable);\n\t_set_entity_name(POI_XPRS_NAMES_COLUMN, column, name);\n}\n\nvoid Model::set_constraint_name(ConstraintIndex constraint, const char *name)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tint row = _checked_constraint_index(constraint);\n\t_set_entity_name(POI_XPRS_NAMES_ROW, row, name);\n}\n\nConstraintIndex Model::add_linear_constraint(const ScalarAffineFunction &function,\n                                             const std::tuple<double, double> &interval,\n                                             const char *name)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tauto [lb, ub] = interval;\n\tdouble constant = static_cast<double>(function.constant.value_or(CoeffT{}));\n\tlb = std::clamp(lb - constant, POI_XPRS_MINUSINFINITY, POI_XPRS_PLUSINFINITY);\n\tub = std::clamp(ub - constant, POI_XPRS_MINUSINFINITY, POI_XPRS_PLUSINFINITY);\n\tif (lb > ub - 1e-10)\n\t{\n\t\tthrow std::runtime_error(\"LB > UB in the provieded interval.\");\n\t}\n\n\t// Handle infinity bounds\n\tbool lb_inf = lb <= POI_XPRS_MINUSINFINITY;\n\tbool ub_inf = ub >= POI_XPRS_PLUSINFINITY;\n\n\t// Determine constraint type and parameters\n\tchar g_sense = {};\n\tdouble g_rhs = {};\n\tdouble range_val = {};\n\tconst double *g_range = {};\n\n\tif (lb_inf && ub_inf)\n\t{\n\t\tg_sense = 'N'; // Free row\n\t\tg_rhs = 0.0;\n\t}\n\telse if (lb_inf)\n\t{\n\t\tg_sense = 'L';\n\t\tg_rhs = ub;\n\t}\n\telse if (ub_inf)\n\t{\n\t\tg_sense = 'G';\n\t\tg_rhs = lb;\n\t}\n\telse if (std::abs(ub - lb) < 1e-10)\n\t{\n\t\tg_sense = 'E';\n\t\tg_rhs = ub;\n\t}\n\telse\n\t{\n\t\tg_sense = 'R';\n\t\tg_rhs = ub;\n\t\trange_val = ub - lb;\n\t\tg_range = &range_val;\n\t}\n\n\tIndexT index = m_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::Linear, index);\n\tint rowidx = get_raw_attribute_int_by_id(POI_XPRS_ROWS);\n\n\tAffineFunctionPtrForm<int, int, double> ptr_form;\n\tptr_form.make(this, function);\n\tint numnz = ptr_form.numnz;\n\tXPRSint64 beg[] = {0};\n\tconst int *cind = ptr_form.index;\n\tconst double *cval = ptr_form.value;\n\n\t_check(XPRSaddrows64(m_model.get(), 1, numnz, &g_sense, &g_rhs, g_range, beg, cind, cval));\n\t_set_entity_name(POI_XPRS_NAMES_ROW, rowidx, name);\n\n\treturn constraint_index;\n}\n\nConstraintIndex Model::add_linear_constraint(const ScalarAffineFunction &function,\n                                             ConstraintSense sense, CoeffT rhs, const char *name)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tIndexT index = m_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::Linear, index);\n\tint rowidx = get_raw_attribute_int_by_id(POI_XPRS_ROWS);\n\n\tAffineFunctionPtrForm<int, int, double> ptr_form;\n\tptr_form.make(this, function);\n\tint numnz = ptr_form.numnz;\n\n\tdouble g_rhs = static_cast<double>(rhs - function.constant.value_or(CoeffT{}));\n\tg_rhs = std::clamp(g_rhs, POI_XPRS_MINUSINFINITY, POI_XPRS_PLUSINFINITY);\n\n\t// Map expr >= -inf and expr <= +inf to free rows\n\tchar g_sense = poi_to_xprs_cons_sense(sense);\n\tif ((g_sense == 'G' && g_rhs <= POI_XPRS_MINUSINFINITY) ||\n\t    (g_sense == 'L' && g_rhs >= POI_XPRS_PLUSINFINITY))\n\t{\n\t\tg_sense = 'N'; // Free row\n\t\tg_rhs = 0.0;\n\t}\n\n\tXPRSint64 beg[] = {0};\n\tconst int *cind = ptr_form.index;\n\tconst double *cval = ptr_form.value;\n\t_check(XPRSaddrows64(m_model.get(), 1, numnz, &g_sense, &g_rhs, nullptr, beg, cind, cval));\n\t_set_entity_name(POI_XPRS_NAMES_ROW, rowidx, name);\n\n\treturn constraint_index;\n}\n\nstatic QuadraticFunctionPtrForm<int, int, double> poi_to_xprs_quad_formula(\n    Model &model, const ScalarQuadraticFunction &function, bool is_objective)\n{\n\tQuadraticFunctionPtrForm<int, int, double> ptr_form;\n\tptr_form.make(&model, function);\n\tint numqnz = ptr_form.numnz;\n\n\t// Xpress uses different quadratic representations for objectives vs constraints:\n\t//\n\t// OBJECTIVES: Use 0.5*x'Qx form with automatic symmetry.\n\t//   - Diagonal terms (i,i): Need 2× multiplication to compensate for the 0.5 factor\n\t//   - Off-diagonal terms (i,j): Used as-is; Xpress automatically mirrors to (j,i)\n\t//\n\t// CONSTRAINTS: Use x'Qx form with upper-triangular specification.\n\t//   - Diagonal terms (i,i): Used as-is\n\t//   - Off-diagonal terms (i,j): Need 0.5× division; Xpress expects coefficients\n\t//     for the upper triangular part only, which will be mirrored\n\t//\n\t// PyOptInterface provides coefficients in the standard x'Qx form through\n\t// QuadraticFunctionPtrForm, so we adjust based on whether this is for an objective function or\n\t// a constraint.\n\n\t// Copy coefficients (ptr_form.value may reference function.coefficients directly)\n\tif (ptr_form.value_storage.empty())\n\t{\n\t\tptr_form.value_storage.reserve(numqnz);\n\t\tfor (CoeffT c : function.coefficients)\n\t\t{\n\t\t\tptr_form.value_storage.push_back(static_cast<double>(c));\n\t\t}\n\t}\n\n\t// Apply Xpress-specific coefficient adjustments\n\tfor (int i = 0; i < numqnz; ++i)\n\t{\n\t\tif (is_objective && (ptr_form.row[i] == ptr_form.col[i]))\n\t\t{\n\t\t\t// Objective diagonal terms: multiply by 2 for 0.5*x'Qx convention\n\t\t\tptr_form.value_storage[i] *= 2.0;\n\t\t}\n\t\tif (!is_objective && (ptr_form.row[i] != ptr_form.col[i]))\n\t\t{\n\t\t\t// Constraint off-diagonal terms: divide by 2 for upper-triangular specification\n\t\t\tptr_form.value_storage[i] /= 2.0;\n\t\t}\n\t}\n\n\tptr_form.value = ptr_form.value_storage.data();\n\treturn ptr_form;\n}\n\n// Quadratic constraints are regular rows with a quadratic term.\nConstraintIndex Model::add_quadratic_constraint(const ScalarQuadraticFunction &function,\n                                                ConstraintSense sense, CoeffT rhs, const char *name)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tint rowidx = get_raw_attribute_int_by_id(POI_XPRS_ROWS);\n\n\tconst auto &affine_part = function.affine_part.value_or(ScalarAffineFunction{});\n\tConstraintIndex constraint_index = add_linear_constraint(affine_part, sense, rhs, name);\n\tconstraint_index.type = ConstraintType::Quadratic; // Fix constraint type\n\n\t// Add quadratic term\n\tQuadraticFunctionPtrForm<int, int, double> ptr_form =\n\t    poi_to_xprs_quad_formula(*this, function, false);\n\tint numqnz = ptr_form.numnz;\n\tconst int *qrow = ptr_form.row;\n\tconst int *qcol = ptr_form.col;\n\tconst double *qval = ptr_form.value;\n\n\t_check(XPRSaddqmatrix64(m_model.get(), rowidx, numqnz, qrow, qcol, qval));\n\t++m_quad_nl_constr_num;\n\treturn constraint_index;\n}\n\nConstraintIndex Model::add_second_order_cone_constraint(const Vector<VariableIndex> &variables,\n                                                        const char *name, bool rotated)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tint rot_offset = rotated ? 1 : 0;\n\tif (variables.size() <= rot_offset)\n\t{\n\t\tthrow std::runtime_error(\"Not enough variables in SOC constraint.\");\n\t}\n\n\t// SOC:           1 x_0 x_0 >= \\sum_{i : [1,N)} x_i^2\n\t// Rotated SOC:   2 x_0 x_1 >= \\sum_{i : [2,N)} x_i^2\n\tScalarQuadraticFunction quadconstr;\n\tquadconstr.add_quadratic_term(variables[0], variables[rot_offset], 1.0 + rot_offset);\n\tfor (int i = 1 + rot_offset; i < variables.size(); ++i)\n\t{\n\t\tquadconstr.add_quadratic_term(variables[i], variables[i], -1.0);\n\t}\n\tConstraintIndex constraint_index =\n\t    add_quadratic_constraint(quadconstr, ConstraintSense::GreaterEqual, 0.0, name);\n\tconstraint_index.type = ConstraintType::SecondOrderCone;\n\treturn constraint_index;\n}\n\nnamespace\n{\ntemplate <size_t N>\nstruct NlpArrays\n{\n\tint types[N];\n\tdouble values[N];\n};\n} // namespace\n\nConstraintIndex Model::add_exp_cone_constraint(const Vector<VariableIndex> &variables,\n                                               const char *name, bool dual)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tif (variables.size() != 3)\n\t{\n\t\tthrow std::runtime_error(\"Exponential cone constraint must have 3 variables\");\n\t}\n\n\t// Add affine part\n\tauto constraint_index =\n\t    add_linear_constraint_from_var(variables[0], ConstraintSense::GreaterEqual, 0.0);\n\tconstraint_index.type = ConstraintType::ExponentialCone; // Fix constraint type\n\n\tint nnz = 0;\n\tconst int *types = {};\n\tconst double *values = {};\n\tdouble var1_idx = static_cast<double>(_checked_variable_index(variables[1]));\n\tdouble var2_idx = static_cast<double>(_checked_variable_index(variables[2]));\n\n\tint rowidx = _constraint_index(constraint_index);\n\n\t// Syntactic sugar to make hand written NLP formulas more readable\n\tauto make_type_value_arrays = [](auto... terms) {\n\t\treturn NlpArrays<sizeof...(terms)>{{terms.type...}, {terms.value...}};\n\t};\n\tif (dual)\n\t{\n\t\t// linear_term + x_2 * exp(x_1 / x_2 - 1) >= 0\n\t\tauto [types, values] = make_type_value_arrays(  //\n\t\t    Tvp{POI_XPRS_TOK_COL, var2_idx},            // x_2\n\t\t    Tvp{POI_XPRS_TOK_RB, {}},                   // )\n\t\t    Tvp{POI_XPRS_TOK_COL, var1_idx},            // x_1\n\t\t    Tvp{POI_XPRS_TOK_COL, var2_idx},            // x_2\n\t\t    Tvp{POI_XPRS_TOK_OP, POI_XPRS_OP_DIVIDE},   // /\n\t\t    Tvp{POI_XPRS_TOK_CON, 1.0},                 // 1.0\n\t\t    Tvp{POI_XPRS_TOK_OP, POI_XPRS_OP_MINUS},    // -\n\t\t    Tvp{POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_EXP},  // exp(\n\t\t    Tvp{POI_XPRS_TOK_OP, POI_XPRS_OP_MULTIPLY}, // *\n\t\t    Tvp{POI_XPRS_TOK_EOF, {}});                 // EOF\n\n\t\tint begs[] = {0, static_cast<int>(std::ssize(types))};\n\t\t_check(XPRSnlpaddformulas(m_model.get(), 1, &rowidx, begs, 1, types, values));\n\t}\n\telse\n\t{\n\t\t// linear_term - x_1 * exp(x_2 / x_1) >= 0\n\t\tauto [types, values] = make_type_value_arrays(  //\n\t\t    Tvp{POI_XPRS_TOK_COL, var1_idx},            // x_1\n\t\t    Tvp{POI_XPRS_TOK_RB, {}},                   // )\n\t\t    Tvp{POI_XPRS_TOK_COL, var2_idx},            // x_2\n\t\t    Tvp{POI_XPRS_TOK_COL, var1_idx},            // x_1\n\t\t    Tvp{POI_XPRS_TOK_OP, POI_XPRS_OP_DIVIDE},   // /\n\t\t    Tvp{POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_EXP},  // exp(\n\t\t    Tvp{POI_XPRS_TOK_OP, POI_XPRS_OP_MULTIPLY}, // *\n\t\t    Tvp{POI_XPRS_TOK_OP, POI_XPRS_OP_UMINUS},   // -\n\t\t    Tvp{POI_XPRS_TOK_EOF, {}});                 // EOF\n\n\t\tint begs[] = {0, static_cast<int>(std::ssize(types))};\n\t\t_check(XPRSnlpaddformulas(m_model.get(), 1, &rowidx, begs, 1, types, values));\n\t}\n\n\t++m_quad_nl_constr_num;\n\treturn constraint_index;\n}\n\nConstraintIndex Model::_add_sos_constraint(const Vector<VariableIndex> &variables, SOSType sos_type,\n                                           const Vector<double> &weights)\n{\n\tIndexT index = m_sos_constraint_index.add_index();\n\tConstraintIndex constraint_index(ConstraintType::SOS, index);\n\n\tconst int nnz = variables.size();\n\tconst char type[] = {poi_to_xprs_sos_type(sos_type)};\n\tconst XPRSint64 beg[] = {0};\n\tstd::vector<int> ind_v(nnz);\n\tfor (int i = 0; i < nnz; i++)\n\t{\n\t\tind_v[i] = _checked_variable_index(variables[i]);\n\t}\n\t_check(XPRSaddsets64(m_model.get(), 1, nnz, type, beg, ind_v.data(), weights.data()));\n\treturn constraint_index;\n}\n\nConstraintIndex Model::add_sos_constraint(const Vector<VariableIndex> &variables, SOSType sos_type)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tVector<double> weights(variables.size());\n\tstd::iota(weights.begin(), weights.end(), 1.0);\n\treturn _add_sos_constraint(variables, sos_type, weights);\n}\n\nConstraintIndex Model::add_sos_constraint(const Vector<VariableIndex> &variables, SOSType sos_type,\n                                          const Vector<CoeffT> &weights)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\t// If CoeffT will ever be not a double, we need to convert weights\n\tif constexpr (std::is_same_v<CoeffT, double>)\n\t{\n\t\tstd::vector<double> double_weights;\n\t\tdouble_weights.reserve(weights.size());\n\t\tfor (CoeffT w : weights)\n\t\t{\n\t\t\tdouble_weights.push_back(static_cast<double>(w));\n\t\t}\n\t\treturn _add_sos_constraint(variables, sos_type, double_weights);\n\t}\n\telse\n\t{\n\t\treturn _add_sos_constraint(variables, sos_type, weights);\n\t}\n}\n\nTvp to_xprs_opcode(UnaryOperator opcode_enum)\n{\n\tswitch (opcode_enum)\n\t{\n\tcase UnaryOperator::Neg:\n\t\treturn {POI_XPRS_TOK_OP, POI_XPRS_OP_UMINUS};\n\tcase UnaryOperator::Sin:\n\t\treturn {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_SIN};\n\tcase UnaryOperator::Cos:\n\t\treturn {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_COS};\n\tcase UnaryOperator::Tan:\n\t\treturn {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_TAN};\n\tcase UnaryOperator::Asin:\n\t\treturn {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_ARCSIN};\n\tcase UnaryOperator::Acos:\n\t\treturn {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_ARCCOS};\n\tcase UnaryOperator::Atan:\n\t\treturn {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_ARCTAN};\n\tcase UnaryOperator::Abs:\n\t\treturn {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_ABS};\n\tcase UnaryOperator::Sqrt:\n\t\treturn {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_SQRT};\n\tcase UnaryOperator::Exp:\n\t\treturn {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_EXP};\n\tcase UnaryOperator::Log:\n\t\treturn {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_LN};\n\tcase UnaryOperator::Log10:\n\t\treturn {POI_XPRS_TOK_IFUN, POI_XPRS_IFUN_LOG10};\n\tdefault: {\n\t\tauto opname = unary_operator_to_string(opcode_enum);\n\t\tauto msg = fmt::format(\"Unknown unary operator for Xpress: {}\", opname);\n\t\tthrow std::runtime_error(msg);\n\t}\n\t}\n}\n\nTvp to_xprs_opcode(BinaryOperator opcode_enum)\n{\n\tswitch (opcode_enum)\n\t{\n\tcase BinaryOperator::Sub:\n\t\treturn {POI_XPRS_TOK_OP, POI_XPRS_OP_MINUS};\n\tcase BinaryOperator::Div:\n\t\treturn {POI_XPRS_TOK_OP, POI_XPRS_OP_DIVIDE};\n\tcase BinaryOperator::Pow:\n\t\treturn {POI_XPRS_TOK_OP, POI_XPRS_OP_EXPONENT};\n\tcase BinaryOperator::Add2:\n\t\treturn {POI_XPRS_TOK_OP, POI_XPRS_OP_PLUS};\n\tcase BinaryOperator::Mul2:\n\t\treturn {POI_XPRS_TOK_OP, POI_XPRS_OP_MULTIPLY};\n\tdefault:\n\t\tauto opname = binary_operator_to_string(opcode_enum);\n\t\tauto msg = fmt::format(\"Unknown unary operator for Xpress: {}\", opname);\n\t\tthrow std::runtime_error(msg);\n\t}\n}\n\nTvp to_xprs_opcode(TernaryOperator opcode_enum)\n{\n\tauto opname = ternary_operator_to_string(opcode_enum);\n\tauto msg = fmt::format(\"Unknown unary operator for Xpress: {}\", opname);\n\tthrow std::runtime_error(msg);\n}\n\nTvp to_xprs_opcode(NaryOperator opcode_enum)\n{\n\tswitch (opcode_enum)\n\t{\n\tcase NaryOperator::Add:\n\t\treturn {POI_XPRS_TOK_OP, POI_XPRS_OP_PLUS};\n\tcase NaryOperator::Mul:\n\t\treturn {POI_XPRS_TOK_OP, POI_XPRS_OP_MULTIPLY};\n\tdefault:\n\t\tauto opname = nary_operator_to_string(opcode_enum);\n\t\tauto msg = fmt::format(\"Unknown nary operator for Xpress: {}\", opname);\n\t\tthrow std::runtime_error(msg);\n\t}\n}\n\nBinaryOperator nary_to_binary_op(NaryOperator opcode_enum)\n{\n\tswitch (opcode_enum)\n\t{\n\tcase NaryOperator::Add:\n\t\treturn BinaryOperator::Add2;\n\tcase NaryOperator::Mul:\n\t\treturn BinaryOperator::Mul2;\n\tdefault: {\n\t\tauto opname = nary_operator_to_string(opcode_enum);\n\t\tauto msg = fmt::format(\"Unknown nary operator for Xpress: {}\", opname);\n\t\tthrow std::runtime_error(msg);\n\t}\n\t}\n}\n\nTvp Model::_decode_expr(const ExpressionGraph &graph, const ExpressionHandle &expr)\n{\n\tauto array_type = expr.array;\n\tauto index = expr.id;\n\n\tswitch (array_type)\n\t{\n\tcase ArrayType::Constant:\n\t\treturn {POI_XPRS_TOK_CON, static_cast<double>(graph.m_constants[index])};\n\tcase ArrayType::Variable:\n\t\treturn {POI_XPRS_TOK_COL,\n\t\t        static_cast<double>(_checked_variable_index(graph.m_variables[index]))};\n\tcase ArrayType::Parameter:\n\t\tbreak;\n\tcase ArrayType::Unary:\n\t\treturn to_xprs_opcode(graph.m_unaries[index].op);\n\tcase ArrayType::Binary:\n\t\treturn to_xprs_opcode(graph.m_binaries[index].op);\n\tcase ArrayType::Ternary:\n\t\treturn to_xprs_opcode(graph.m_ternaries[index].op);\n\tcase ArrayType::Nary:\n\t\treturn to_xprs_opcode(graph.m_naries[index].op);\n\tdefaut:\n\t\tbreak;\n\t}\n\tthrow std::runtime_error(\"Not supported expression.\");\n}\n\nExpressionHandle nary_to_binary(ExpressionGraph &graph, const ExpressionHandle &expr)\n{\n\tauto &nary = graph.m_naries[expr.id];\n\tNaryOperator n_op = nary.op;\n\tBinaryOperator bin_opcode = nary_to_binary_op(n_op);\n\tint n_operands = nary.operands.size();\n\tif (n_operands == 0 || (n_op != NaryOperator::Add && n_op != NaryOperator::Mul))\n\t{\n\t\treturn expr;\n\t}\n\n\tauto new_expr = nary.operands[0];\n\tfor (int i = 1; i < n_operands; ++i)\n\t{\n\t\tnew_expr = graph.add_binary(bin_opcode, new_expr, nary.operands[i]);\n\t}\n\treturn new_expr;\n}\n\nstd::pair<std::vector<int>, std::vector<double>> Model::_decode_graph_postfix_order(\n    ExpressionGraph &graph, const ExpressionHandle &result)\n{\n\tstd::vector<int> types;\n\tstd::vector<double> values;\n\n\t// Xpress uses a reversed Polish notation (post fix). So we need to visit the expression tree\n\t// in post-order depth first. We keep a stack to go depth first and visit each element\n\t// twice. First time process its children, second time decode it.\n\tstd::stack<std::pair<ExpressionHandle, bool>> expr_stack;\n\texpr_stack.emplace(result, true);\n\n\twhile (!expr_stack.empty())\n\t{\n\t\tauto &[expr, visit_children] = expr_stack.top();\n\t\tauto [type, value] = _decode_expr(graph, expr);\n\n\t\t// If its children have already been processed and we can add it to the expression\n\t\tif (!visit_children)\n\t\t{\n\t\t\ttypes.push_back(type);\n\t\t\tvalues.push_back(value);\n\t\t\texpr_stack.pop();\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Xpress requires a parenthesis to start an internal or user function\n\t\tif (type == POI_XPRS_TOK_IFUN || type == POI_XPRS_TOK_FUN)\n\t\t{\n\t\t\ttypes.push_back(POI_XPRS_TOK_RB);\n\t\t\tvalues.push_back({});\n\t\t}\n\n\t\tswitch (expr.array)\n\t\t{\n\t\tcase ArrayType::Constant:\n\t\tcase ArrayType::Variable:\n\t\t\tbreak;\n\t\tcase ArrayType::Unary:\n\t\t\texpr_stack.emplace(graph.m_unaries[expr.id].operand, true);\n\t\t\tbreak;\n\t\tcase ArrayType::Nary:\n\t\t\t// Xpress does not have nary operators out of the box, we have to translate them into a\n\t\t\t// sequence of binary operators\n\t\t\texpr = nary_to_binary(graph, expr);\n\t\t\t[[fallthrough]];\n\t\tcase ArrayType::Binary:\n\t\t\texpr_stack.emplace(graph.m_binaries[expr.id].right, true);\n\t\t\texpr_stack.emplace(graph.m_binaries[expr.id].left, true);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow std::runtime_error(\"Unrecognized token.\");\n\t\t}\n\n\t\t// Children has been processed and added to the stack, next time we'll add it to the\n\t\t// expression.\n\t\tvisit_children = false;\n\t}\n\n\ttypes.push_back(POI_XPRS_TOK_EOF);\n\tvalues.push_back({});\n\treturn {std::move(types), std::move(values)};\n}\n\nConstraintIndex Model::add_single_nl_constraint(ExpressionGraph &graph,\n                                                const ExpressionHandle &result,\n                                                const std::tuple<double, double> &interval,\n                                                const char *name)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tint rowidx = get_raw_attribute_int_by_id(POI_XPRS_ROWS);\n\tConstraintIndex constraint = add_linear_constraint(ScalarAffineFunction{}, interval, name);\n\tconstraint.type = ConstraintType::NL;\n\n\tauto [types, values] = _decode_graph_postfix_order(graph, result);\n\n\tint nnz = values.size();\n\tint begs[] = {0, nnz};\n\t_check(XPRSnlpaddformulas(m_model.get(), 1, &rowidx, begs, 1, types.data(), values.data()));\n\t++m_quad_nl_constr_num;\n\treturn constraint;\n}\n\nvoid Model::delete_constraint(ConstraintIndex constraint)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tif (!is_constraint_active(constraint))\n\t{\n\t\tthrow std::runtime_error(\"Constraint does not exist\");\n\t}\n\n\tint constraint_row = _checked_constraint_index(constraint);\n\tif (constraint_row >= 0)\n\t{\n\t\tswitch (constraint.type)\n\t\t{\n\t\tcase ConstraintType::Quadratic:\n\t\tcase ConstraintType::SecondOrderCone:\n\t\tcase ConstraintType::ExponentialCone:\n\t\tcase ConstraintType::NL:\n\t\t\t--m_quad_nl_constr_num;\n\t\t\t[[fallthrough]];\n\t\tcase ConstraintType::Linear:\n\t\t\tm_constraint_index.delete_index(constraint.index);\n\t\t\t_check(XPRSdelrows(m_model.get(), 1, &constraint_row));\n\t\t\tbreak;\n\t\tcase ConstraintType::SOS:\n\t\t\tm_sos_constraint_index.delete_index(constraint.index);\n\t\t\t_check(XPRSdelsets(m_model.get(), 1, &constraint_row));\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t\t}\n\t}\n}\n\nbool Model::is_constraint_active(ConstraintIndex constraint)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\tcase ConstraintType::Quadratic:\n\tcase ConstraintType::SecondOrderCone:\n\tcase ConstraintType::ExponentialCone:\n\tcase ConstraintType::NL:\n\t\treturn m_constraint_index.has_index(constraint.index);\n\tcase ConstraintType::SOS:\n\t\treturn m_sos_constraint_index.has_index(constraint.index);\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n\treturn false;\n}\n\nvoid Model::set_objective(const ScalarAffineFunction &function, ObjectiveSense sense)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\t// Delete linear and quadratic term of the objective function\n\t_check(XPRSdelobj(m_model.get(), 0));\n\t_check(XPRSdelqmatrix(m_model.get(), -1));\n\thas_quad_objective = false;\n\tif (has_nlp_objective)\n\t{\n\t\tdelete_constraint(m_nlp_obj_constraint);\n\t\tdelete_variable(m_nlp_obj_variable);\n\t\thas_nlp_objective = false;\n\t}\n\n\tif (function.size() > 0)\n\t{\n\t\tAffineFunctionPtrForm<int, int, double> ptr_form;\n\t\tptr_form.make(this, function);\n\t\tint numnz = ptr_form.numnz;\n\t\tconst int *cind = ptr_form.index;\n\t\tconst double *cval = ptr_form.value;\n\t\t_check(XPRSchgobj(m_model.get(), numnz, cind, cval));\n\t}\n\tif (function.constant.has_value())\n\t{\n\t\tint obj_constant_magic_index = -1;\n\t\tdouble obj_constant = -static_cast<double>(function.constant.value());\n\t\t_check(XPRSchgobj(m_model.get(), 1, &obj_constant_magic_index, &obj_constant));\n\t}\n\tint stype = poi_to_xprs_obj_sense(sense);\n\t_check(XPRSchgobjsense(m_model.get(), stype));\n}\n\n// Set quadratic objective function, replacing any previous objective.\n// Handles Xpress's symmetric matrix convention where off-diagonal terms are doubled.\nvoid Model::set_objective(const ScalarQuadraticFunction &function, ObjectiveSense sense)\n{\n\t// Set affine part (also clears any previous quadratic terms)\n\tconst auto &affine_part = function.affine_part.value_or(ScalarAffineFunction{});\n\tset_objective(affine_part, sense);\n\n\t// Add quadratic terms if present\n\tif (function.size() > 0)\n\t{\n\t\tQuadraticFunctionPtrForm<int, int, double> ptr_form =\n\t\t    poi_to_xprs_quad_formula(*this, function, true);\n\t\tint numqnz = ptr_form.numnz;\n\t\tconst int *qrow = ptr_form.row;\n\t\tconst int *qcol = ptr_form.col;\n\t\tconst double *qval = ptr_form.value;\n\t\t_check(XPRSchgmqobj64(m_model.get(), numqnz, qrow, qcol, qval));\n\t\thas_quad_objective = true;\n\t}\n}\n\nvoid Model::set_objective(const ExprBuilder &function, ObjectiveSense sense)\n{\n\tauto deg = function.degree();\n\tif (deg <= 1)\n\t{\n\t\tScalarAffineFunction f(function);\n\t\tset_objective(f, sense);\n\t}\n\telse if (deg == 2)\n\t{\n\t\tScalarQuadraticFunction f(function);\n\t\tset_objective(f, sense);\n\t}\n\telse\n\t{\n\t\tthrow std::runtime_error(\"Objective must be linear or quadratic\");\n\t}\n}\n\nvoid Model::add_single_nl_objective(ExpressionGraph &graph, const ExpressionHandle &result)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tif (!has_nlp_objective)\n\t{\n\t\thas_nlp_objective = true;\n\t\tm_nlp_obj_variable = add_variable();\n\t\tm_nlp_obj_constraint = add_linear_constraint(ScalarAffineFunction(m_nlp_obj_variable, -1.0),\n\t\t                                             ConstraintSense::Equal, 0.0, NULL);\n\t\tset_objective_coefficient(m_nlp_obj_variable, 1.0);\n\t}\n\n\tauto [types, values] = _decode_graph_postfix_order(graph, result);\n\tint nnz = values.size();\n\tint begs[] = {0, nnz};\n\tint rowidx = _constraint_index(m_nlp_obj_constraint);\n\t_check(XPRSnlpaddformulas(m_model.get(), 1, &rowidx, begs, 1, types.data(), values.data()));\n}\n\ndouble Model::get_normalized_rhs(ConstraintIndex constraint)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tdouble rhs = {};\n\tint rowidx = _checked_constraint_index(constraint);\n\t_check(XPRSgetrhs(m_model.get(), &rhs, rowidx, rowidx));\n\treturn rhs;\n}\n\nvoid Model::set_normalized_rhs(ConstraintIndex constraint, double value)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tint rowidx = _checked_constraint_index(constraint);\n\t_check(XPRSchgrhs(m_model.get(), 1, &rowidx, &value));\n}\n\ndouble Model::get_normalized_coefficient(ConstraintIndex constraint, VariableIndex variable)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tint rowidx = _checked_constraint_index(constraint);\n\tint colidx = _checked_variable_index(variable);\n\tdouble coeff = {};\n\t_check(XPRSgetcoef(m_model.get(), rowidx, colidx, &coeff));\n\treturn coeff;\n}\nvoid Model::set_normalized_coefficient(ConstraintIndex constraint, VariableIndex variable,\n                                       double value)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tint rowidx = _checked_constraint_index(constraint);\n\tint colidx = _checked_variable_index(variable);\n\t_check(XPRSchgcoef(m_model.get(), rowidx, colidx, value));\n}\n\ndouble Model::get_objective_coefficient(VariableIndex variable)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tint colidx = _checked_variable_index(variable);\n\tdouble coeff = {};\n\t_check(XPRSgetobj(m_model.get(), &coeff, colidx, colidx));\n\treturn coeff;\n}\nvoid Model::set_objective_coefficient(VariableIndex variable, double value)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\t_clear_caches();\n\n\tint colidx = _checked_variable_index(variable);\n\t_check(XPRSchgobj(m_model.get(), 1, &colidx, &value));\n}\n\nint Model::_constraint_index(ConstraintIndex constraint)\n{\n\tswitch (constraint.type)\n\t{\n\tcase ConstraintType::Linear:\n\tcase ConstraintType::Quadratic:\n\tcase ConstraintType::SecondOrderCone:\n\tcase ConstraintType::ExponentialCone:\n\tcase ConstraintType::NL:\n\t\treturn m_constraint_index.get_index(constraint.index);\n\tcase ConstraintType::SOS:\n\t\treturn m_sos_constraint_index.get_index(constraint.index);\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown constraint type\");\n\t}\n}\n\nint Model::_variable_index(VariableIndex variable)\n{\n\treturn m_variable_index.get_index(variable.index);\n}\n\nint Model::_checked_constraint_index(ConstraintIndex constraint)\n{\n\tint rowidx = _constraint_index(constraint);\n\tif (rowidx < 0)\n\t{\n\t\tthrow std::runtime_error(\"Constraint does not exists\");\n\t}\n\treturn rowidx;\n}\n\nint Model::_checked_variable_index(VariableIndex variable)\n{\n\tint colidx = _variable_index(variable);\n\tif (colidx < 0)\n\t{\n\t\tthrow std::runtime_error(\"Variable does not exists\");\n\t}\n\treturn colidx;\n}\n\nbool Model::_is_mip()\n{\n\treturn get_raw_attribute_int_by_id(POI_XPRS_MIPENTS) > 0 ||\n\t       get_raw_attribute_int_by_id(POI_XPRS_SETS) > 0;\n}\n\nvoid Model::optimize()\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_clear_caches();\n\n\tint stop_status = 0;\n\t_check(XPRSoptimize(m_model.get(), \"\", &stop_status, nullptr));\n\tm_need_postsolve = (stop_status == POI_XPRS_SOLVESTATUS_STOPPED);\n}\n\ndouble Model::get_variable_value(VariableIndex variable)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\tint colidx = _checked_variable_index(variable);\n\tint status = POI_XPRS_SOLAVAILABLE_NOTFOUND;\n\tdouble value = {};\n\t_check(XPRSgetsolution(m_model.get(), &status, &value, colidx, colidx));\n\tif (status == POI_XPRS_SOLAVAILABLE_NOTFOUND)\n\t{\n\t\tthrow std::runtime_error(\"No solution found\");\n\t}\n\treturn value;\n}\n\ndouble Model::get_variable_rc(VariableIndex variable)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\tint colidx = _checked_variable_index(variable);\n\tint status = POI_XPRS_SOLAVAILABLE_NOTFOUND;\n\tdouble value = {};\n\t_check(XPRSgetredcosts(m_model.get(), &status, &value, colidx, colidx));\n\tif (status == POI_XPRS_SOLAVAILABLE_NOTFOUND)\n\t{\n\t\tthrow std::runtime_error(\"No solution found\");\n\t}\n\treturn value;\n}\n\ndouble Model::get_variable_primal_ray(VariableIndex variable)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tif (m_primal_ray.empty())\n\t{\n\t\tint has_ray = 0;\n\t\t_check(XPRSgetprimalray(m_model.get(), nullptr, &has_ray));\n\t\tif (has_ray == 0)\n\t\t{\n\t\t\tthrow std::runtime_error(\"Primal ray not available\");\n\t\t}\n\t\tm_primal_ray.resize(get_raw_attribute_int_by_id(POI_XPRS_COLS));\n\t\t_check(XPRSgetprimalray(m_model.get(), m_primal_ray.data(), &has_ray));\n\t\tassert(has_ray != 0);\n\t}\n\n\tint colidx = _checked_variable_index(variable);\n\treturn m_primal_ray[colidx];\n}\n\nint Model::_get_basis_stat(int entity_idx, bool is_row)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tint entity_stat = {};\n\tif (is_row)\n\t{\n\t\t_check(XPRSgetbasisval(m_model.get(), entity_idx, 0, &entity_stat, nullptr));\n\t}\n\telse\n\t{\n\t\t_check(XPRSgetbasisval(m_model.get(), 0, entity_idx, nullptr, &entity_stat));\n\t}\n\treturn entity_stat;\n}\n\nbool Model::is_variable_basic(VariableIndex variable)\n{\n\treturn _get_basis_stat(_checked_variable_index(variable), false) == POI_XPRS_BASISSTATUS_BASIC;\n}\n\nbool Model::is_variable_nonbasic_lb(VariableIndex variable)\n{\n\treturn _get_basis_stat(_checked_variable_index(variable), false) ==\n\t       POI_XPRS_BASISSTATUS_NONBASIC_LOWER;\n}\n\nbool Model::is_variable_nonbasic_ub(VariableIndex variable)\n{\n\treturn _get_basis_stat(_checked_variable_index(variable), false) ==\n\t       POI_XPRS_BASISSTATUS_NONBASIC_UPPER;\n}\nbool Model::is_variable_superbasic(VariableIndex variable)\n{\n\treturn _get_basis_stat(_checked_variable_index(variable), false) ==\n\t       POI_XPRS_BASISSTATUS_SUPERBASIC;\n}\n\ndouble Model::get_variable_lowerbound(VariableIndex variable)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tdouble lb = {};\n\tint colidx = _checked_variable_index(variable);\n\t_check(XPRSgetlb(m_model.get(), &lb, colidx, colidx));\n\treturn lb;\n}\n\ndouble Model::get_variable_upperbound(VariableIndex variable)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tdouble ub = {};\n\tint colidx = _checked_variable_index(variable);\n\t_check(XPRSgetub(m_model.get(), &ub, colidx, colidx));\n\treturn ub;\n}\n\nVariableDomain Model::get_variable_type(VariableIndex variable)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tint colidex = _checked_variable_index(variable);\n\tchar vtype = {};\n\t_check(XPRSgetcoltype(m_model.get(), &vtype, colidex, colidex));\n\treturn xprs_to_poi_var_type(vtype);\n}\n\nchar Model::_get_variable_bound_IIS(VariableIndex variable)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tif (m_iis_cols.empty() || m_iis_bound_types.empty())\n\t{\n\t\tint m_nrows = {};\n\t\tint m_ncols = {};\n\t\t_check(XPRSgetiisdata(m_model.get(), 1, &m_nrows, &m_ncols, nullptr, nullptr, nullptr,\n\t\t                      nullptr, nullptr, nullptr, nullptr, nullptr));\n\n\t\tm_iis_cols.resize(m_ncols);\n\t\tm_iis_bound_types.resize(m_ncols);\n\t\t_check(XPRSgetiisdata(m_model.get(), 1, &m_nrows, &m_ncols, nullptr, m_iis_cols.data(),\n\t\t                      nullptr, m_iis_bound_types.data(), nullptr, nullptr, nullptr,\n\t\t                      nullptr));\n\t}\n\n\tint colidx = _checked_variable_index(variable);\n\tfor (int j = 0; j < m_iis_cols.size(); ++j)\n\t{\n\t\tif (m_iis_cols[j] == colidx)\n\t\t{\n\t\t\treturn m_iis_bound_types[j];\n\t\t}\n\t}\n\treturn '\\0';\n}\n\nbool Model::is_variable_lowerbound_IIS(VariableIndex variable)\n{\n\treturn _get_variable_bound_IIS(variable) == 'L';\n}\n\nbool Model::is_variable_upperbound_IIS(VariableIndex variable)\n{\n\treturn _get_variable_bound_IIS(variable) == 'U';\n}\n\nvoid Model::set_constraint_sense(ConstraintIndex constraint, ConstraintSense sense)\n{\n\tconst int rowidx = _checked_constraint_index(constraint);\n\tconst char rowtype = poi_to_xprs_cons_sense(sense);\n\t_check(XPRSchgrowtype(m_model.get(), 1, &rowidx, &rowtype));\n}\n\nConstraintSense Model::get_constraint_sense(ConstraintIndex constraint)\n{\n\tconst int rowidx = _checked_constraint_index(constraint);\n\tchar rowtype = {};\n\t_check(XPRSgetrowtype(m_model.get(), &rowtype, rowidx, rowidx));\n\treturn xprs_to_poi_cons_sense(rowtype);\n}\n\nvoid Model::set_constraint_rhs(ConstraintIndex constraint, CoeffT rhs)\n{\n\tconst int rowidx = _checked_constraint_index(constraint);\n\tconst double g_rhs[] = {static_cast<double>(rhs)};\n\t_check(XPRSchgrhs(m_model.get(), 1, &rowidx, g_rhs));\n}\n\nCoeffT Model::get_constraint_rhs(ConstraintIndex constraint)\n{\n\tconst int rowidx = _checked_constraint_index(constraint);\n\tdouble rhs = {};\n\t_check(XPRSgetrhs(m_model.get(), &rhs, rowidx, rowidx));\n\treturn static_cast<CoeffT>(rhs);\n}\n\ndouble Model::get_constraint_slack(ConstraintIndex constraint)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tint rowidx = _checked_constraint_index(constraint);\n\tint status = POI_XPRS_SOLAVAILABLE_NOTFOUND;\n\tdouble value = {};\n\t_check(XPRSgetslacks(m_model.get(), &status, &value, rowidx, rowidx));\n\tif (status == POI_XPRS_SOLAVAILABLE_NOTFOUND)\n\t{\n\t\tthrow std::runtime_error(\"No solution found\");\n\t}\n\treturn value;\n}\n\ndouble Model::get_constraint_dual(ConstraintIndex constraint)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tint rowidx = _checked_constraint_index(constraint);\n\tint status = POI_XPRS_SOLAVAILABLE_NOTFOUND;\n\tdouble value = {};\n\t_check(XPRSgetduals(m_model.get(), &status, &value, rowidx, rowidx));\n\tif (status == POI_XPRS_SOLAVAILABLE_NOTFOUND)\n\t{\n\t\tthrow std::runtime_error(\"No solution found\");\n\t}\n\treturn value;\n}\n\ndouble Model::get_constraint_dual_ray(ConstraintIndex constraint)\n{\n\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tif (m_dual_ray.empty())\n\t{\n\t\tint has_ray = 0;\n\t\t_check(XPRSgetdualray(m_model.get(), nullptr, &has_ray));\n\t\tif (has_ray == 0)\n\t\t{\n\t\t\tthrow std::runtime_error(\"Dual ray not available\");\n\t\t}\n\t\tm_dual_ray.resize(get_raw_attribute_int_by_id(POI_XPRS_ROWS));\n\t\t_check(XPRSgetdualray(m_model.get(), m_dual_ray.data(), &has_ray));\n\t\tassert(has_ray != 0);\n\t}\n\n\tint rowidx = _checked_constraint_index(constraint);\n\treturn m_dual_ray[rowidx];\n}\n\nbool Model::is_constraint_basic(ConstraintIndex constraint)\n{\n\treturn _get_basis_stat(_checked_constraint_index(constraint), true) ==\n\t       POI_XPRS_BASISSTATUS_BASIC;\n}\n\nbool Model::is_constraint_nonbasic_lb(ConstraintIndex constraint)\n{\n\treturn _get_basis_stat(_checked_constraint_index(constraint), true) ==\n\t       POI_XPRS_BASISSTATUS_NONBASIC_LOWER;\n}\n\nbool Model::is_constraint_nonbasic_ub(ConstraintIndex constraint)\n{\n\treturn _get_basis_stat(_checked_constraint_index(constraint), true) ==\n\t       POI_XPRS_BASISSTATUS_NONBASIC_UPPER;\n}\n\nbool Model::is_constraint_superbasic(ConstraintIndex constraint)\n{\n\treturn _get_basis_stat(_checked_constraint_index(constraint), true) ==\n\t       POI_XPRS_BASISSTATUS_SUPERBASIC;\n}\n\nbool Model::is_constraint_in_IIS(ConstraintIndex constraint)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\t_ensure_postsolved();\n\n\tif (m_iss_rows.empty())\n\t{\n\t\tint nrow = {};\n\t\tint ncol = {};\n\t\t_check(XPRSgetiisdata(m_model.get(), 1, &nrow, &ncol, nullptr, nullptr, nullptr, nullptr,\n\t\t                      nullptr, nullptr, nullptr, nullptr));\n\n\t\tm_iss_rows.resize(nrow);\n\t\t_check(XPRSgetiisdata(m_model.get(), 1, &nrow, &ncol, m_iss_rows.data(), nullptr, nullptr,\n\t\t                      nullptr, nullptr, nullptr, nullptr, nullptr));\n\t}\n\n\tint rowidx = _constraint_index(constraint);\n\tfor (int ridx : m_iss_rows)\n\t{\n\t\tif (ridx == rowidx)\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\nvoid *Model::get_raw_model()\n{\n\treturn m_model.get();\n}\n\nstd::string Model::version_string()\n{\n\tchar buffer[32];\n\tXPRSgetversion(buffer);\n\treturn buffer;\n}\n\nvoid Model::computeIIS()\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\tint status = 0;\n\n\t// passing 1 emphasizes simplicity of the IIS\n\t// passing 2 emphasizes a quick result\n\t_check(XPRSiisfirst(m_model.get(), 2, &status));\n\tswitch (status)\n\t{\n\tcase 0:\n\t\treturn;\n\tcase 1:\n\t\tthrow std::runtime_error(\"IIS: problem is feasible\");\n\tcase 2:\n\t\tthrow std::runtime_error(\"IIS: generic error\");\n\tcase 3:\n\t\tthrow std::runtime_error(\"IIS: timeout or interruption\");\n\tdefault:\n\t\tthrow std::runtime_error(fmt::format(\"IIS: unknown exit status {}\", status));\n\t}\n}\n\n////////////////////////////////////////////////////////////////////////////////\n//                       ATTRIBUTES AND CONTROLS ACCESS                       //\n////////////////////////////////////////////////////////////////////////////////\n\nstatic const char *xpress_type_to_string(CATypes type)\n{\n\tswitch (type)\n\t{\n\tcase CATypes::INT:\n\t\treturn \"int\";\n\tcase CATypes::INT64:\n\t\treturn \"int64\";\n\tcase CATypes::DOUBLE:\n\t\treturn \"double\";\n\tcase CATypes::STRING:\n\t\treturn \"string\";\n\tdefault:\n\t\treturn \"unknown\";\n\t}\n}\n\nstd::pair<int, CATypes> Model::_get_control_info(const char *control)\n{\n\tint control_id = {};\n\tint control_type = {};\n\t_check(XPRSgetcontrolinfo(m_model.get(), control, &control_id, &control_type));\n\treturn std::make_pair(control_id, static_cast<CATypes>(control_type));\n}\n\nstd::pair<int, CATypes> Model::_get_attribute_info(const char *attrib)\n{\n\tint attrib_id = {};\n\tint attrib_type = {};\n\t_check(XPRSgetattribinfo(m_model.get(), attrib, &attrib_id, &attrib_type));\n\treturn std::make_pair(attrib_id, static_cast<CATypes>(attrib_type));\n}\n\nint Model::_get_checked_control_id(const char *control, CATypes expected, CATypes backup)\n{\n\tauto [id, type] = _get_control_info(control);\n\tif (type == CATypes::NOTDEFINED)\n\t{\n\t\tthrow std::runtime_error(\"Error, unknown control type.\");\n\t}\n\tif (type != expected && type != backup)\n\t{\n\t\tauto error_msg = fmt::format(\n\t\t    \"Error retriving control '{}'. Control type is '{}', but '{}' was expected.\", control,\n\t\t    xpress_type_to_string(type), xpress_type_to_string(expected));\n\t\tthrow std::runtime_error(error_msg);\n\t}\n\treturn id;\n}\n\nint Model::_get_checked_attribute_id(const char *attrib, CATypes expected, CATypes backup)\n{\n\tauto [id, type] = _get_attribute_info(attrib);\n\tif (type == CATypes::NOTDEFINED)\n\t{\n\t\tthrow std::runtime_error(\"Error, unknown attribute type.\");\n\t}\n\tif (type != expected)\n\t{\n\t\tauto error_msg = fmt::format(\n\t\t    \"Error retriving attribute '{}'. Attribute type is '{}', but '{}' was expected.\",\n\t\t    attrib, xpress_type_to_string(type), xpress_type_to_string(expected));\n\t\tthrow std::runtime_error(error_msg);\n\t}\n\treturn id;\n}\n\n// Generic access to attributes and controls\nModel::xprs_type_variant_t Model::get_raw_attribute(const char *attrib)\n{\n\tauto [id, type] = _get_attribute_info(attrib);\n\tswitch (type)\n\t{\n\tcase CATypes::INT:\n\tcase CATypes::INT64:\n\t\treturn get_raw_attribute_int_by_id(id);\n\tcase CATypes::DOUBLE:\n\t\treturn get_raw_attribute_dbl_by_id(id);\n\tcase CATypes::STRING:\n\t\treturn get_raw_attribute_str_by_id(id);\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown attribute type\");\n\t}\n}\n\nModel::xprs_type_variant_t Model::get_raw_control(const char *control)\n{\n\tauto [id, type] = _get_control_info(control);\n\tswitch (type)\n\t{\n\tcase CATypes::INT:\n\tcase CATypes::INT64:\n\t\treturn get_raw_control_int_by_id(id);\n\tcase CATypes::DOUBLE:\n\t\treturn get_raw_control_dbl_by_id(id);\n\tcase CATypes::STRING:\n\t\treturn get_raw_control_str_by_id(id);\n\tdefault:\n\t\tthrow std::runtime_error(\"Unknown attribute type\");\n\t}\n}\n\n// Helper struct to achieve a sort of pattern matching with the visitor pattern.\n// It basically exploit the overload resolution to get the equivalent of a series of\n// if constexpr(std::is_same_v<ArgT,...>)\ntemplate <typename... Ts>\nstruct OverloadSet : public Ts...\n{\n\tusing Ts::operator()...;\n};\n\n// Deduction guide for OverloadSet\ntemplate <typename... Ts>\nOverloadSet(Ts...) -> OverloadSet<Ts...>;\n\nvoid Model::set_raw_control(const char *control, Model::xprs_type_variant_t &value)\n{\n\tstd::visit(OverloadSet{[&](double d) { set_raw_control_dbl(control, d); },\n\t                       [&](std::integral auto i) { set_raw_control_int(control, i); },\n\t                       [&](const std::string &s) { set_raw_control_str(control, s.c_str()); }},\n\t           value);\n}\n\nvoid Model::set_raw_control_int(const char *control, XPRSint64 value)\n{\n\tint id = _get_checked_control_id(control, CATypes::INT64, CATypes::INT);\n\treturn set_raw_control_int_by_id(id, value);\n}\n\nvoid Model::set_raw_control_dbl(const char *control, double value)\n{\n\tint id = _get_checked_control_id(control, CATypes::DOUBLE);\n\treturn set_raw_control_dbl_by_id(id, value);\n}\n\nvoid Model::set_raw_control_str(const char *control, const char *value)\n{\n\tint id = _get_checked_control_id(control, CATypes::STRING);\n\treturn set_raw_control_str_by_id(id, value);\n}\n\nXPRSint64 Model::get_raw_control_int(const char *control)\n{\n\tint id = _get_checked_control_id(control, CATypes::INT64, CATypes::INT);\n\treturn get_raw_control_int_by_id(id);\n}\n\ndouble Model::get_raw_control_dbl(const char *control)\n{\n\tint id = _get_checked_control_id(control, CATypes::DOUBLE);\n\treturn get_raw_control_dbl_by_id(id);\n}\n\nstd::string Model::get_raw_control_str(const char *control)\n{\n\tint id = _get_checked_control_id(control, CATypes::STRING);\n\treturn get_raw_control_str_by_id(id);\n}\n\nXPRSint64 Model::get_raw_attribute_int(const char *attrib)\n{\n\tint id = _get_checked_attribute_id(attrib, CATypes::INT64, CATypes::INT);\n\treturn get_raw_attribute_int_by_id(id);\n}\n\ndouble Model::get_raw_attribute_dbl(const char *attrib)\n{\n\tint id = _get_checked_attribute_id(attrib, CATypes::DOUBLE);\n\treturn get_raw_attribute_dbl_by_id(id);\n}\n\nstd::string Model::get_raw_attribute_str(const char *attrib)\n{\n\tint id = _get_checked_attribute_id(attrib, CATypes::STRING);\n\treturn get_raw_attribute_str_by_id(id);\n}\n\nvoid Model::set_raw_control_int_by_id(int control, XPRSint64 value)\n{\n\t// Disabling Xpress internal callback mutex is forbidden since this could easily create race\n\t// condition and deadlocks since it's used in conjunction with Python GIL.\n\tif (control == POI_XPRS_MUTEXCALLBACKS)\n\t{\n\t\tthrow std::runtime_error(\n\t\t    \"Changing Xpress callback mutex setting is currently not supported.\");\n\t}\n\t_check(XPRSsetintcontrol64(m_model.get(), control, value));\n}\n\nvoid Model::set_raw_control_dbl_by_id(int control, double value)\n{\n\t_check(XPRSsetdblcontrol(m_model.get(), control, value));\n}\n\nvoid Model::set_raw_control_str_by_id(int control, const char *value)\n{\n\t_check(XPRSsetstrcontrol(m_model.get(), control, value));\n}\n\nXPRSint64 Model::get_raw_control_int_by_id(int control)\n{\n\tXPRSint64 value = {};\n\t_check(XPRSgetintcontrol64(m_model.get(), control, &value));\n\treturn value;\n}\n\ndouble Model::get_raw_control_dbl_by_id(int control)\n{\n\tdouble value = {};\n\t_check(XPRSgetdblcontrol(m_model.get(), control, &value));\n\treturn value;\n}\n\nstd::string Model::get_raw_control_str_by_id(int control)\n{\n\tint req_size = {};\n\t_check(XPRSgetstringcontrol(m_model.get(), control, nullptr, 0, &req_size));\n\tstd::string value = {};\n\tvalue.resize(req_size);\n\t_check(XPRSgetstringcontrol(m_model.get(), control, value.data(), req_size, &req_size));\n\tif (value.size() != req_size)\n\t{\n\t\tthrow std::runtime_error(\"Error while getting control string\");\n\t}\n\t// Align string size with string length\n\tvalue.resize(strlen(value.c_str()));\n\treturn value;\n}\n\nXPRSint64 Model::get_raw_attribute_int_by_id(int attrib)\n{\n\tXPRSint64 value = {};\n\t_check(XPRSgetintattrib64(m_model.get(), attrib, &value));\n\treturn value;\n}\n\ndouble Model::get_raw_attribute_dbl_by_id(int attrib)\n{\n\tdouble value = {};\n\t_check(XPRSgetdblattrib(m_model.get(), attrib, &value));\n\treturn value;\n}\n\nstd::string Model::get_raw_attribute_str_by_id(int attrib)\n{\n\tint req_size = {};\n\t_check(XPRSgetstringattrib(m_model.get(), attrib, nullptr, 0, &req_size));\n\tstd::string value = {};\n\tvalue.resize(req_size);\n\t_check(XPRSgetstringattrib(m_model.get(), attrib, value.data(), req_size, &req_size));\n\tif (value.size() != req_size)\n\t{\n\t\tthrow std::runtime_error(\"Error while getting control string\");\n\t}\n\treturn value;\n}\n\nLPSTATUS Model::get_lp_status()\n{\n\treturn static_cast<LPSTATUS>(get_raw_attribute_int_by_id(POI_XPRS_LPSTATUS));\n}\n\nMIPSTATUS Model::get_mip_status()\n{\n\treturn static_cast<MIPSTATUS>(get_raw_attribute_int_by_id(POI_XPRS_MIPSTATUS));\n}\n\nNLPSTATUS Model::get_nlp_status()\n{\n\treturn static_cast<NLPSTATUS>(get_raw_attribute_int_by_id(POI_XPRS_NLPSTATUS));\n}\n\nSOLVESTATUS Model::get_solve_status()\n{\n\treturn static_cast<SOLVESTATUS>(get_raw_attribute_int_by_id(POI_XPRS_SOLVESTATUS));\n}\n\nSOLSTATUS Model::get_sol_status()\n{\n\treturn static_cast<SOLSTATUS>(get_raw_attribute_int_by_id(POI_XPRS_SOLSTATUS));\n}\n\nIISSOLSTATUS Model::get_iis_sol_status()\n{\n\treturn static_cast<IISSOLSTATUS>(get_raw_attribute_int_by_id(POI_XPRS_IISSOLSTATUS));\n}\n\nOPTIMIZETYPE Model::get_optimize_type()\n{\n\treturn static_cast<OPTIMIZETYPE>(get_raw_attribute_int_by_id(POI_XPRS_OPTIMIZETYPEUSED));\n}\n\nvoid Model::_ensure_postsolved()\n{\n\tif (m_need_postsolve)\n\t{\n\t\t_check(XPRSpostsolve(m_model.get()));\n\n\t\t// Non-convex quadratic constraint might be solved with the non linear solver, so we have to\n\t\t// make sure that the problem is nl-postsolved, even if it is not always strictly necessary\n\t\t// and could introduce minor overhead.\n\t\tif (m_quad_nl_constr_num >= 0 || has_quad_objective || has_nlp_objective)\n\t\t{\n\t\t\t_check(XPRSnlppostsolve(m_model.get()));\n\t\t}\n\t\tm_need_postsolve = false;\n\t}\n}\n\nvoid Model::_check_expected_mode(XPRESS_MODEL_MODE mode)\n{\n\tif (mode == XPRESS_MODEL_MODE::MAIN && m_mode == XPRESS_MODEL_MODE::CALLBACK_)\n\t{\n\t\tthrow std::runtime_error(\"Cannot call this function from within a callback. \"\n\t\t                         \"This operation is only available on the main model.\");\n\t}\n\tif (mode == XPRESS_MODEL_MODE::CALLBACK_ && m_mode == XPRESS_MODEL_MODE::MAIN)\n\t{\n\t\tthrow std::runtime_error(\"This function can only be called from within a callback. \"\n\t\t                         \"It is not available on the main model.\");\n\t}\n}\n\nxpress_cbs_data Model::cb_get_arguments()\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::CALLBACK_);\n\treturn cb_args;\n}\n\n// NOTE: XPRSgetcallbacksolution return a context dependent solution\ndouble Model::_cb_get_context_solution(VariableIndex variable)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::CALLBACK_);\n\t// Xpress already caches solutions internally\n\tint p_available = 0;\n\tint colidx = _checked_variable_index(variable);\n\tdouble value[] = {0.0};\n\t_check(XPRSgetcallbacksolution(m_model.get(), &p_available, value, colidx, colidx));\n\tif (p_available == 0)\n\t{\n\t\tthrow std::runtime_error(\"No solution available\");\n\t}\n\treturn value[0];\n}\n\n// Get MIP solution value for a variable in callback context.\n// Returns the callback's candidate integer solution if available (intsol, preintsol contexts),\n// otherwise falls back to the current incumbent solution.\ndouble Model::cb_get_solution(VariableIndex variable)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::CALLBACK_);\n\tif (cb_where == CB_CONTEXT::intsol || cb_where == CB_CONTEXT::preintsol)\n\t{\n\t\t// Context provides a candidate integer solution - return it directly\n\t\treturn _cb_get_context_solution(variable);\n\t}\n\n\t// No integer solution in current context - return best known incumbent instead\n\treturn cb_get_incumbent(variable);\n}\n\n// Get LP relaxation solution value for a variable in callback context. Returns the callback's LP\n// relaxation solution when available in contexts that solve LPs (bariteration, cutround,\n// chgbranchobject, nodelpsolved, optnode). It throws in other contexts.\ndouble Model::cb_get_relaxation(VariableIndex variable)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::CALLBACK_);\n\tif (cb_where != CB_CONTEXT::bariteration && cb_where != CB_CONTEXT::cutround &&\n\t    cb_where != CB_CONTEXT::chgbranchobject && cb_where != CB_CONTEXT::nodelpsolved &&\n\t    cb_where != CB_CONTEXT::optnode)\n\t{\n\t\tthrow std::runtime_error(\"LP relaxation solution not available.\");\n\t}\n\treturn _cb_get_context_solution(variable);\n}\n\ndouble Model::cb_get_incumbent(VariableIndex variable)\n{\n\treturn get_variable_value(variable);\n}\n\nvoid Model::cb_set_solution(VariableIndex variable, double value)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::CALLBACK_);\n\tcb_sol_cache.emplace_back(_checked_variable_index(variable), value);\n}\n\nvoid Model::cb_submit_solution()\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::CALLBACK_);\n\n\tauto &sol = cb_sol_cache;\n\tif (sol.empty())\n\t{\n\t\treturn;\n\t}\n\n\t// Merge together coefficient of duplicated indices\n\tstd::ranges::sort(sol);\n\tstd::vector<int> indices;\n\tstd::vector<double> values;\n\tint curr_idx = std::numeric_limits<int>::lowest();\n\tfor (auto [idx, val] : sol)\n\t{\n\t\tif (curr_idx != idx)\n\t\t{\n\t\t\tcurr_idx = idx;\n\t\t\tindices.push_back(idx);\n\t\t\tvalues.emplace_back();\n\t\t}\n\t\tvalues.back() += val;\n\t}\n\n\tint ncol = static_cast<int>(indices.size());\n\t_check(XPRSaddmipsol(m_model.get(), ncol, values.data(), indices.data(), nullptr));\n}\n\nvoid Model::cb_exit()\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::CALLBACK_);\n\t_check(XPRSinterrupt(m_model.get(), POI_XPRS_STOP_USER));\n}\n\nvoid Model::_cb_add_cut(const ScalarAffineFunction &function, ConstraintSense sense, CoeffT rhs)\n{\n\tAffineFunctionPtrForm<int, int, double> ptr_form;\n\tptr_form.make(this, function);\n\tint numnz = ptr_form.numnz;\n\tchar g_sense = poi_to_xprs_cons_sense(sense);\n\tdouble g_rhs = static_cast<double>(rhs - function.constant.value_or(CoeffT{}));\n\tconst int *cind = ptr_form.index;\n\tconst double *cval = ptr_form.value;\n\n\t// Before adding the cut, we must translate it to the presolved model. If this translation fails\n\t// then we cannot continue. The translation can only fail if we have presolve operations enabled\n\t// that should be disabled in case of dynamically separated constraints.\n\tint ncols = get_raw_attribute_int_by_id(POI_XPRS_COLS);\n\tint ps_numnz = 0;\n\tstd::vector<int> ps_cind(ncols);\n\tstd::vector<double> ps_cval(ncols);\n\tdouble ps_rhs = 0.0;\n\tint ps_status = 0;\n\t_check(XPRSpresolverow(m_model.get(), g_sense, numnz, cind, cval, g_rhs, ncols, &ps_numnz,\n\t                       ps_cind.data(), ps_cval.data(), &ps_rhs, &ps_status));\n\tif (ps_status != 0)\n\t{\n\t\tthrow std::runtime_error(\"Failed to presolve new cut.\");\n\t}\n\n\tXPRSint64 start[] = {0, ps_numnz};\n\tint ctype = 1;\n\tif (cb_where == CB_CONTEXT::cutround)\n\t{\n\t\t// NOTE: we assume cuts to be global since other solvers only support those\n\t\t_check(XPRSaddmanagedcuts64(m_model.get(), 1, 1, &g_sense, &ps_rhs, start, ps_cind.data(),\n\t\t                            ps_cval.data()));\n\t}\n\telse\n\t{\n\t\t_check(XPRSaddcuts64(m_model.get(), 1, &ctype, &g_sense, &ps_rhs, start, ps_cind.data(),\n\t\t                     ps_cval.data()));\n\t}\n}\n\n// Tries to add a lazy constraints. If the context is right, but we are not in a node of the tree,\n// it fallbacks to simply rejecting the solution, since no cut can be added at that moment.\nvoid Model::cb_add_lazy_constraint(const ScalarAffineFunction &function, ConstraintSense sense,\n                                   CoeffT rhs)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::CALLBACK_);\n\tif (cb_where != CB_CONTEXT::nodelpsolved && cb_where != CB_CONTEXT::optnode &&\n\t    cb_where != CB_CONTEXT::preintsol && cb_where != CB_CONTEXT::prenode)\n\t{\n\t\tthrow std::runtime_error(\"New constraints can be added only in NODELPSOLVED, OPTNODE, \"\n\t\t                         \"PREINTSOL, and PRENODE callbacks.\");\n\t}\n\n\tif (cb_where != CB_CONTEXT::preintsol)\n\t{\n\t\t_cb_add_cut(function, sense, rhs);\n\t\treturn;\n\t}\n\n\tauto *args = std::get<preintsol_struct *>(cb_args);\n\tif (args->soltype == 0)\n\t{\n\t\t_cb_add_cut(function, sense, rhs);\n\t\treturn;\n\t}\n\n\t// If the solution didn't originated from a node of the tree, we can't reject it with a cut.\n\t// However, if the user cut makes the solution infeasible, we have to reject it.\n\tdouble pos_activity = 0.0;\n\tdouble neg_anctivity = 0.0;\n\tconst int nnz = function.size();\n\tfor (int i = 0; i < nnz; ++i)\n\t{\n\t\tdouble col_val = _cb_get_context_solution(function.variables[i]);\n\t\tdouble term_val = col_val * function.coefficients[i];\n\t\t(term_val > 0.0 ? pos_activity : neg_anctivity) += term_val;\n\t}\n\tconst double activity = pos_activity + neg_anctivity;\n\tconst double real_rhs = static_cast<double>(rhs - function.constant.value_or(0.0));\n\tdouble infeas = 0.0; // > 0 if solution violates constraint\n\tif (sense == ConstraintSense::Equal || sense == ConstraintSense::LessEqual)\n\t{\n\t\tinfeas = std::max(infeas, activity - real_rhs);\n\t}\n\tif (sense == ConstraintSense::Equal || sense == ConstraintSense::GreaterEqual)\n\t{\n\t\tinfeas = std::max(infeas, real_rhs - activity);\n\t}\n\tconst double feastol = get_raw_control_dbl_by_id(POI_XPRS_FEASTOL);\n\tif (infeas > feastol)\n\t{\n\t\t// The user added a cut, but we are not in a context where it can be added. So, the only\n\t\t// thing we can reasonably do is to reject the solution iff it is made infeasible by the\n\t\t// user provided cut.\n\t\t*args->p_reject = 1;\n\t}\n}\n\nvoid Model::cb_add_lazy_constraint(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs)\n{\n\tScalarAffineFunction f(function);\n\tcb_add_lazy_constraint(f, sense, rhs);\n}\n\nvoid Model::cb_add_user_cut(const ScalarAffineFunction &function, ConstraintSense sense, CoeffT rhs)\n{\n\t_cb_add_cut(function, sense, rhs);\n}\n\nvoid Model::cb_add_user_cut(const ExprBuilder &function, ConstraintSense sense, CoeffT rhs)\n{\n\tScalarAffineFunction f(function);\n\tcb_add_user_cut(f, sense, rhs);\n}\n\n// Helper struct that defines a static function when instantiated.\n// The defined static function is the actual Xpress CB that will be registered to the context\n// selected by the Where argument.\n// It collects the due-diligence common to all CBs, to minimize code duplication.\ntemplate <unsigned long long Where, typename CbStruct, typename RetT, typename... ArgsT>\nstruct Model::CbWrap\n{\n\tstatic RetT cb(XPRSprob cb_prob, void *user_data, ArgsT... args) noexcept\n\t{\n\t\tauto *model = reinterpret_cast<Model *>(user_data);\n\t\tassert(model->m_mode == XPRESS_MODEL_MODE::MAIN);\n\n\t\tauto cb_args = CbStruct{{/*ret_code*/}, args...}; // Store additional arguments\n\n\t\t// Temporarily swap the XpressModel's problem pointer with the callback's thread-local\n\t\t// clone. This allows reusing the model's indexers and helper data without copying.\n\t\t//\n\t\t// Current design assumes serialized callback invocation (enforced by Python GIL). The swap\n\t\t// is safe because only one callback executes at a time.\n\t\t//\n\t\t// NOTE: Free-threading compatibility will require redesign. The approach would be to split\n\t\t// Model state into:\n\t\t//   - Immutable shared state (indexers, problem structure) shared through a common pointer,\n\t\t//   read-only when in callbacks\n\t\t//   - Thread-local state (callback context, temporary buffers)\n\t\t//\n\t\t// Instead of swapping problem pointers, create lightweight callback problem objects that\n\t\t// reference the shared state. This is conceptually simple but requires refactoring all\n\t\t// Model methods to access shared state through indirection.\n\t\tXPRSprob main_prob = model->_toggle_model_mode(cb_prob);\n\t\t// Ensure restoration on all exit paths\n\t\tDefer main_prob_restore = [&] { model->_toggle_model_mode(main_prob); };\n\n\t\ttry\n\t\t{\n\t\t\tmodel->_check_expected_mode(XPRESS_MODEL_MODE::CALLBACK_);\n\t\t\tmodel->cb_sol_cache.clear();\n\t\t\tmodel->cb_where = static_cast<CB_CONTEXT>(Where);\n\t\t\tmodel->cb_args = &cb_args;\n\t\t\tmodel->m_callback(model, static_cast<CB_CONTEXT>(Where));\n\t\t\tmodel->cb_submit_solution();\n\t\t}\n\t\tcatch (...)\n\t\t{\n\t\t\t// We cannot let any exception slip through a callback, we have to catch it,\n\t\t\t// terminate Xpress gracefully and then we can throw it again.\n\t\t\tif (XPRSinterrupt(cb_prob, POI_XPRS_STOP_USER) != 0)\n\t\t\t{\n\t\t\t\tstd::rethrow_exception(std::current_exception()); // We have to terminate somehow\n\t\t\t}\n\t\t\tmodel->m_captured_exceptions.push_back(std::current_exception());\n\t\t}\n\n\t\treturn cb_args.get_return_value();\n\t}\n};\n\nstatic constexpr unsigned long long as_flag(int ID)\n{\n\tassert(\"ID must be in the [0, 63] range\" && ID >= 0 && ID < 63);\n\treturn (1ULL << ID);\n}\n\nstatic constexpr bool test_ctx(CB_CONTEXT dest_ctx, unsigned long long curr_ctx)\n{\n\tauto ctx = static_cast<unsigned long long>(dest_ctx);\n\treturn (curr_ctx & ctx) != 0; // The context matches the ID\n}\n\nvoid Model::set_callback(const Callback &cb, unsigned long long new_contexts)\n{\n\t_check_expected_mode(XPRESS_MODEL_MODE::MAIN);\n\n\t// Default message callback management - we always register a default message handler\n\t// unless the user explicitly registers their own. When the user callback is removed,\n\t// restore the default handler.\n\tif (is_default_message_cb_set && test_ctx(CB_CONTEXT::message, new_contexts))\n\t{\n\t\t_check(XPRSremovecbmessage(m_model.get(), &default_print, nullptr));\n\t\tis_default_message_cb_set = false;\n\t}\n\tif (!is_default_message_cb_set && !test_ctx(CB_CONTEXT::message, new_contexts))\n\t{\n\t\t_check(XPRSaddcbmessage(m_model.get(), &default_print, nullptr, 0));\n\t\tis_default_message_cb_set = true;\n\t}\n\n\t// Register/unregister Xpress callbacks based on context changes. For each callback type,\n\t// compare the old context set (m_curr_contexts) with the new one. If a context needs to be\n\t// added or removed, register/unregister the corresponding low-level wrapper function.\n\t//\n\t// Note: The wrapper functions are stateless - they just forward to the user callback pointer.\n\t// Updating the callback for an already-registered context only requires updating m_callback;\n\t// the wrapper stays registered.\n\n#define XPRSCB_SET_CTX(ID, NAME, RET, ...)                                       \\\n\t{                                                                            \\\n\t\tbool has_cb = test_ctx(CB_CONTEXT::NAME, m_curr_contexts);               \\\n\t\tbool needs_cb = test_ctx(CB_CONTEXT::NAME, new_contexts);                \\\n\t\tif (has_cb != needs_cb)                                                  \\\n\t\t{                                                                        \\\n\t\t\tauto *cb = &CbWrap<as_flag(ID), NAME##_struct, RET __VA_ARGS__>::cb; \\\n\t\t\tif (has_cb)                                                          \\\n\t\t\t{                                                                    \\\n\t\t\t\t_check(XPRSremovecb##NAME(m_model.get(), cb, this));             \\\n\t\t\t}                                                                    \\\n\t\t\telse /* needs_cb */                                                  \\\n\t\t\t{                                                                    \\\n\t\t\t\t_check(XPRSaddcb##NAME(m_model.get(), cb, this, 0));             \\\n\t\t\t}                                                                    \\\n\t\t}                                                                        \\\n\t}\n\tXPRSCB_LIST(XPRSCB_SET_CTX, XPRSCB_ARG_TYPE)\n#undef XPRSCB_SET_CTX\n\n\tm_curr_contexts = new_contexts;\n\tm_callback = cb;\n}\n} // namespace xpress\n"
  },
  {
    "path": "lib/xpress_model_ext.cpp",
    "content": "#include <nanobind/nanobind.h>\n#include <nanobind/stl/string.h>\n#include <nanobind/stl/pair.h>\n#include <nanobind/stl/tuple.h>\n#include <nanobind/stl/vector.h>\n#include <nanobind/stl/variant.h>\n#include <nanobind/stl/function.h>\n#include <nanobind/trampoline.h>\n#include \"pyoptinterface/core.hpp\"\n#include \"pyoptinterface/xpress_model.hpp\"\n\nnamespace nb = nanobind;\n\nusing namespace nb::literals;\nusing namespace xpress;\n\nextern void bind_xpress_constants(nb::module_ &m);\n\nNB_MODULE(xpress_model_ext, m)\n{\n\tm.import_(\"pyoptinterface._src.core_ext\");\n\n\tm.def(\"is_library_loaded\", &xpress::is_library_loaded);\n\tm.def(\"load_library\", &xpress::load_library);\n\tm.def(\"license\", &xpress::license, \"i\"_a, \"c\"_a);\n\tm.def(\"beginlicensing\", &xpress::beginlicensing);\n\tm.def(\"endlicensing\", &xpress::endlicensing);\n\n\tbind_xpress_constants(m);\n\n\tnb::class_<Env>(m, \"Env\")\n\t    .def(nb::init<>())\n\t    .def(nb::init<const char *>(), \"path\"_a = nullptr)\n\t    .def(\"close\", &Env::close);\n\n\tnb::class_<Model>(m, \"RawModel\")\n\t    .def(nb::init<>())\n\t    .def(nb::init<const Env &>(), nb::keep_alive<1, 2>())\n\n\t    // Model management\n\t    .def(\"init\", &Model::init, \"env\"_a)\n\t    .def(\"close\", &Model::close)\n\t    .def(\"optimize\", &Model::optimize, nb::call_guard<nb::gil_scoped_release>())\n\t    .def(\"computeIIS\", &Model::computeIIS, nb::call_guard<nb::gil_scoped_release>())\n\t    .def(\"write\", &Model::write, \"filename\"_a, nb::call_guard<nb::gil_scoped_release>())\n\t    .def(\"_is_mip\", &Model::_is_mip)\n\t    .def_static(\"get_infinity\", &Model::get_infinity)\n\t    .def(\"get_problem_name\", &Model::get_problem_name)\n\t    .def(\"set_problem_name\", &Model::set_problem_name, \"probname\"_a)\n\t    .def(\"add_mip_start\", &Model::add_mip_start, \"variables\"_a, \"values\"_a)\n\t    .def(\"get_raw_model\", &Model::get_raw_model)\n\t    .def(\"version_string\", &Model::version_string)\n\n\t    // Index mappings\n\t    .def(\"_constraint_index\", &Model::_constraint_index, \"constraint\"_a)\n\t    .def(\"_variable_index\", &Model::_variable_index, \"variable\"_a)\n\t    .def(\"_checked_constraint_index\", &Model::_checked_constraint_index, \"constraint\"_a)\n\t    .def(\"_checked_variable_index\", &Model::_checked_variable_index, \"variable\"_a)\n\n\t    // Variables\n\t    .def(\"add_variable\", &Model::add_variable, \"domain\"_a = VariableDomain::Continuous,\n\t         \"lb\"_a = POI_XPRS_MINUSINFINITY, \"ub\"_a = POI_XPRS_PLUSINFINITY, \"name\"_a = \"\")\n\t    .def(\"delete_variable\", &Model::delete_variable, \"variable\"_a)\n\t    .def(\"delete_variables\", &Model::delete_variables, \"variables\"_a)\n\t    .def(\"set_objective_coefficient\", &Model::set_objective_coefficient, \"variable\"_a,\n\t         \"value\"_a)\n\t    .def(\"set_variable_bounds\", &Model::set_variable_bounds, \"variable\"_a, \"lb\"_a, \"ub\"_a)\n\t    .def(\"set_variable_lowerbound\", &Model::set_variable_lowerbound, \"variable\"_a, \"lb\"_a)\n\t    .def(\"set_variable_name\", &Model::set_variable_name, \"variable\"_a, \"name\"_a)\n\t    .def(\"set_variable_type\", &Model::set_variable_type, \"variable\"_a, \"vtype\"_a)\n\t    .def(\"set_variable_upperbound\", &Model::set_variable_upperbound, \"variable\"_a, \"ub\"_a)\n\t    .def(\"is_variable_active\", &Model::is_variable_active, \"variable\"_a)\n\t    .def(\"is_variable_basic\", &Model::is_variable_basic, \"variable\"_a)\n\t    .def(\"get_variable_lowerbound_IIS\", &Model::is_variable_lowerbound_IIS, \"variable\"_a)\n\t    .def(\"is_variable_nonbasic_lb\", &Model::is_variable_nonbasic_lb, \"variable\"_a)\n\t    .def(\"is_variable_nonbasic_ub\", &Model::is_variable_nonbasic_ub, \"variable\"_a)\n\t    .def(\"is_variable_superbasic\", &Model::is_variable_superbasic, \"variable\"_a)\n\t    .def(\"get_variable_upperbound_IIS\", &Model::is_variable_upperbound_IIS, \"variable\"_a)\n\t    .def(\"get_objective_coefficient\", &Model::get_objective_coefficient, \"variable\"_a)\n\t    .def(\"get_variable_lowerbound\", &Model::get_variable_lowerbound, \"variable\"_a)\n\t    .def(\"get_variable_primal_ray\", &Model::get_variable_primal_ray, \"variable\"_a)\n\t    .def(\"get_variable_rc\", &Model::get_variable_rc, \"variable\"_a)\n\t    .def(\"get_variable_upperbound\", &Model::get_variable_upperbound, \"variable\"_a)\n\t    .def(\"get_variable_value\", &Model::get_variable_value, \"variable\"_a)\n\t    .def(\"get_variable_name\", &Model::get_variable_name, \"variable\"_a)\n\t    .def(\"pprint\", &Model::pprint_variable, \"variable\"_a)\n\t    .def(\"get_variable_type\", &Model::get_variable_type, \"variable\"_a)\n\n\t    // Constraints\n\t    .def(\"add_exp_cone_constraint\", &Model::add_exp_cone_constraint, \"variables\"_a,\n\t         \"name\"_a = \"\", \"dual\"_a = false)\n\t    .def(\"_add_linear_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, const std::tuple<double, double> &,\n\t                           const char *>(&Model::add_linear_constraint),\n\t         \"function\"_a, \"interval\"_a, \"name\"_a = \"\")\n\t    .def(\"_add_linear_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ConstraintSense, CoeffT, const char *>(\n\t             &Model::add_linear_constraint),\n\t         \"function\"_a, \"sense\"_a, \"rhs\"_a, \"name\"_a = \"\")\n\t    .def(\"add_quadratic_constraint\", &Model::add_quadratic_constraint, \"function\"_a, \"sense\"_a,\n\t         \"rhs\"_a, \"name\"_a = \"\")\n\t    .def(\"_add_quadratic_constraint\", &Model::add_quadratic_constraint, \"function\"_a, \"sense\"_a,\n\t         \"rhs\"_a, \"name\"_a = \"\")\n\t    .def(\"add_second_order_cone_constraint\", &Model::add_second_order_cone_constraint,\n\t         \"variables\"_a, \"name\"_a = \"\", \"rotated\"_a = false)\n\t    .def(\"_add_single_nl_constraint\", &Model::add_single_nl_constraint, \"graph\"_a, \"result\"_a,\n\n\t         \"interval\"_a, \"name\"_a = \"\")\n\t    .def(\"add_sos_constraint\",\n\t         nb::overload_cast<const Vector<VariableIndex> &, SOSType, const Vector<CoeffT> &>(\n\t             &Model::add_sos_constraint),\n\t         \"variables\"_a, \"sos_type\"_a, \"weights\"_a)\n\t    .def(\"add_sos_constraint\",\n\t         nb::overload_cast<const Vector<VariableIndex> &, SOSType>(&Model::add_sos_constraint),\n\t         \"variables\"_a, \"sos_type\"_a)\n\t    .def(\"delete_constraint\", &Model::delete_constraint, \"constraint\"_a)\n\t    .def(\"set_constraint_name\", &Model::set_constraint_name, \"constraint\"_a, \"name\"_a)\n\t    .def(\"set_constraint_rhs\", &Model::set_constraint_rhs, \"constraint\"_a, \"rhs\"_a)\n\t    .def(\"set_constraint_sense\", &Model::set_constraint_sense, \"constraint\"_a, \"sense\"_a)\n\t    .def(\"set_normalized_coefficient\", &Model::set_normalized_coefficient, \"constraint\"_a,\n\t         \"variable\"_a, \"value\"_a)\n\t    .def(\"set_normalized_rhs\", &Model::set_normalized_rhs, \"constraint\"_a, \"value\"_a)\n\t    .def(\"is_constraint_active\", &Model::is_constraint_active, \"constraint\"_a)\n\t    .def(\"is_constraint_basic\", &Model::is_constraint_basic, \"constraint\"_a)\n\t    .def(\"is_constraint_in_IIS\", &Model::is_constraint_in_IIS, \"constraint\"_a)\n\t    .def(\"is_constraint_nonbasic_lb\", &Model::is_constraint_nonbasic_lb, \"constraint\"_a)\n\t    .def(\"is_constraint_nonbasic_ub\", &Model::is_constraint_nonbasic_ub, \"constraint\"_a)\n\t    .def(\"is_constraint_superbasic\", &Model::is_constraint_superbasic, \"constraint\"_a)\n\t    .def(\"get_constraint_dual_ray\", &Model::get_constraint_dual_ray, \"constraint\"_a)\n\t    .def(\"get_constraint_dual\", &Model::get_constraint_dual, \"constraint\"_a)\n\t    .def(\"get_constraint_slack\", &Model::get_constraint_slack, \"constraint\"_a)\n\t    .def(\"get_normalized_coefficient\", &Model::get_normalized_coefficient, \"constraint\"_a,\n\t         \"variable\"_a)\n\t    .def(\"get_normalized_rhs\", &Model::get_normalized_rhs, \"constraint\"_a)\n\t    .def(\"get_constraint_rhs\", &Model::get_constraint_rhs, \"constraint\"_a)\n\t    .def(\"get_constraint_name\", &Model::get_constraint_name, \"constraint\"_a)\n\t    .def(\"get_constraint_sense\", &Model::get_constraint_sense, \"constraint\"_a)\n\n\t    // Objective function\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ObjectiveSense>(&Model::set_objective),\n\t         \"function\"_a, \"sense\"_a = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, ObjectiveSense>(\n\t             &Model::set_objective),\n\t         \"function\"_a, \"sense\"_a = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\",\n\t         nb::overload_cast<const ExprBuilder &, ObjectiveSense>(&Model::set_objective),\n\t         \"function\"_a, \"sense\"_a = ObjectiveSense::Minimize)\n\t    .def(\"_add_single_nl_objective\", &Model::add_single_nl_objective, \"graph\"_a, \"result\"_a)\n\n\t    // Status queries\n\t    .def(\"get_lp_status\", &Model::get_lp_status)\n\t    .def(\"get_mip_status\", &Model::get_mip_status)\n\t    .def(\"get_nlp_status\", &Model::get_nlp_status)\n\t    .def(\"get_sol_status\", &Model::get_sol_status)\n\t    .def(\"get_solve_status\", &Model::get_solve_status)\n\t    .def(\"get_optimize_type\", &Model::get_optimize_type)\n\t    .def(\"get_iis_sol_status\", &Model::get_iis_sol_status)\n\n\t    // Raw control/attribute access by ID\n\t    .def(\"set_raw_control_dbl_by_id\", &Model::set_raw_control_dbl_by_id, \"control\"_a, \"value\"_a)\n\t    .def(\"set_raw_control_int_by_id\", &Model::set_raw_control_int_by_id, \"control\"_a, \"value\"_a)\n\t    .def(\"set_raw_control_str_by_id\", &Model::set_raw_control_str_by_id, \"control\"_a, \"value\"_a)\n\t    .def(\"get_raw_control_int_by_id\", &Model::get_raw_control_int_by_id, \"control\"_a)\n\t    .def(\"get_raw_control_dbl_by_id\", &Model::get_raw_control_dbl_by_id, \"control\"_a)\n\t    .def(\"get_raw_control_str_by_id\", &Model::get_raw_control_str_by_id, \"control\"_a)\n\t    .def(\"get_raw_attribute_int_by_id\", &Model::get_raw_attribute_int_by_id, \"attrib\"_a)\n\t    .def(\"get_raw_attribute_dbl_by_id\", &Model::get_raw_attribute_dbl_by_id, \"attrib\"_a)\n\t    .def(\"get_raw_attribute_str_by_id\", &Model::get_raw_attribute_str_by_id, \"attrib\"_a)\n\n\t    // Raw control/attribute access by string\n\t    .def(\"set_raw_control_int\", &Model::set_raw_control_int, \"control\"_a, \"value\"_a)\n\t    .def(\"set_raw_control_dbl\", &Model::set_raw_control_dbl, \"control\"_a, \"value\"_a)\n\t    .def(\"set_raw_control_str\", &Model::set_raw_control_str, \"control\"_a, \"value\"_a)\n\t    .def(\"get_raw_control_int\", &Model::get_raw_control_int, \"control\"_a)\n\t    .def(\"get_raw_control_dbl\", &Model::get_raw_control_dbl, \"control\"_a)\n\t    .def(\"get_raw_control_str\", &Model::get_raw_control_str, \"control\"_a)\n\t    .def(\"get_raw_attribute_int\", &Model::get_raw_attribute_int, \"attrib\"_a)\n\t    .def(\"get_raw_attribute_dbl\", &Model::get_raw_attribute_dbl, \"attrib\"_a)\n\t    .def(\"get_raw_attribute_str\", &Model::get_raw_attribute_str, \"attrib\"_a)\n\n\t    // Generic variant access\n\t    .def(\"set_raw_control\", &Model::set_raw_control, \"control\"_a, \"value\"_a)\n\t    .def(\"get_raw_attribute\", &Model::get_raw_attribute, \"attrib\"_a)\n\t    .def(\"get_raw_control\", &Model::get_raw_control, \"control\"_a)\n\n\t    // Callback methods\n\t    .def(\"set_callback\", &Model::set_callback, \"callback\"_a, \"cbctx\"_a)\n\t    .def(\"cb_get_arguments\", &Model::cb_get_arguments, nb::rv_policy::reference)\n\t    .def(\"cb_get_solution\", &Model::cb_get_solution, \"variable\"_a)\n\t    .def(\"cb_get_relaxation\", &Model::cb_get_relaxation, \"variable\"_a)\n\t    .def(\"cb_get_incumbent\", &Model::cb_get_incumbent, \"variable\"_a)\n\t    .def(\"cb_set_solution\", &Model::cb_set_solution, \"variable\"_a, \"value\"_a)\n\t    .def(\"cb_submit_solution\", &Model::cb_submit_solution)\n\t    .def(\"cb_exit\", &Model::cb_exit)\n\t    .def(\"cb_add_lazy_constraint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ConstraintSense, CoeffT>(\n\t             &Model::cb_add_lazy_constraint),\n\t         \"function\"_a, \"sense\"_a, \"rhs\"_a)\n\t    .def(\"cb_add_lazy_constraint\",\n\t         nb::overload_cast<const ExprBuilder &, ConstraintSense, CoeffT>(\n\t             &Model::cb_add_lazy_constraint),\n\t         \"function\"_a, \"sense\"_a, \"rhs\"_a)\n\t    .def(\"cb_add_user_cut\",\n\t         nb::overload_cast<const ScalarAffineFunction &, ConstraintSense, CoeffT>(\n\t             &Model::cb_add_user_cut),\n\t         \"function\"_a, \"sense\"_a, \"rhs\"_a)\n\t    .def(\"cb_add_user_cut\",\n\t         nb::overload_cast<const ExprBuilder &, ConstraintSense, CoeffT>(\n\t             &Model::cb_add_user_cut),\n\t         \"function\"_a, \"sense\"_a, \"rhs\"_a)\n\n\t    // Functions defined in CRTP Mixins\n\t    .def(\"pprint\",\n\t         nb::overload_cast<const ScalarAffineFunction &, int>(&Model::pprint_expression),\n\t         \"expr\"_a, \"precision\"_a = 4)\n\t    .def(\"pprint\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &, int>(&Model::pprint_expression),\n\t         \"expr\"_a, \"precision\"_a = 4)\n\t    .def(\"pprint\", nb::overload_cast<const ExprBuilder &, int>(&Model::pprint_expression),\n\t         \"expr\"_a, \"precision\"_a = 4)\n\n\t    .def(\"get_value\", nb::overload_cast<VariableIndex>(&Model::get_variable_value))\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ScalarAffineFunction &>(&Model::get_expression_value))\n\t    .def(\"get_value\",\n\t         nb::overload_cast<const ScalarQuadraticFunction &>(&Model::get_expression_value))\n\t    .def(\"get_value\", nb::overload_cast<const ExprBuilder &>(&Model::get_expression_value))\n\n\t    .def(\"_add_linear_constraint\", &Model::add_linear_constraint_from_var, \"expr\"_a, \"sense\"_a,\n\t         \"rhs\"_a, \"name\"_a = \"\")\n\t    .def(\"_add_linear_constraint\", &Model::add_linear_interval_constraint_from_var, \"expr\"_a,\n\t         \"interval\"_a, \"name\"_a = \"\")\n\t    .def(\"_add_linear_constraint\", &Model::add_linear_constraint_from_expr, \"expr\"_a, \"sense\"_a,\n\t         \"rhs\"_a, \"name\"_a = \"\")\n\t    .def(\"_add_linear_constraint\", &Model::add_linear_interval_constraint_from_expr, \"expr\"_a,\n\t         \"interval\"_a, \"name\"_a = \"\")\n\t    .def(\"_add_linear_constraint\", &Model::add_linear_constraint_from_var, \"expr\"_a, \"sense\"_a,\n\t         \"rhs\"_a, \"name\"_a = \"\")\n\t    .def(\"_add_linear_constraint\", &Model::add_linear_interval_constraint_from_var, \"expr\"_a,\n\t         \"interval\"_a, \"name\"_a = \"\")\n\t    .def(\"_add_linear_constraint\", &Model::add_linear_constraint_from_expr, \"expr\"_a, \"sense\"_a,\n\t         \"rhs\"_a, \"name\"_a = \"\")\n\t    .def(\"_add_linear_constraint\", &Model::add_linear_interval_constraint_from_expr, \"expr\"_a,\n\t         \"interval\"_a, \"name\"_a = \"\")\n\n\t    .def(\"_add_single_nl_constraint\", &Model::add_single_nl_constraint_sense_rhs, \"graph\"_a,\n\t         \"result\"_a, \"sense\"_a, \"rhs\"_a, \"name\"_a = \"\")\n\t    .def(\"_add_single_nl_constraint\", &Model::add_single_nl_constraint_from_comparison,\n\t         \"graph\"_a, \"expr\"_a, \"name\"_a = \"\")\n\n\t    .def(\"set_objective\", &Model::set_objective_as_variable, \"expr\"_a,\n\t         \"sense\"_a = ObjectiveSense::Minimize)\n\t    .def(\"set_objective\", &Model::set_objective_as_constant, \"expr\"_a,\n\t         \"sense\"_a = ObjectiveSense::Minimize);\n\n\t// Bind the return value only it the CB has one\n\tauto bind_ret_code = []<class S>(nb::class_<S> s) {\n\t\t// \"if constexpr + templates\" conditionally instantiates only the true branch.\n\t\tif constexpr (requires { &S::ret_code; })\n\t\t\ts.def_rw(\"ret_code\", &S::ret_code);\n\t};\n\n// When callbacks provide pointer arguments, those are usually meant as output arguments.\n// An exception is with pointer to structs, which usually are just opaque objects passed around\n// between API calls.\n// We define pointer arguments as read-write, while all the other arguments stays read-only\n#define XPRSCB_ARG_NB_FIELD(TYPE, NAME)                        \\\n\tif constexpr (std::is_pointer_v<decltype(struct_t::NAME)>) \\\n\t\ts.def_rw(#NAME, &struct_t::NAME);                      \\\n\telse                                                       \\\n\t\ts.def_ro(#NAME, &struct_t::NAME);\n\n// Define the binding for the argument struct of each CB. In this way, Nanobind will be able to\n// translate our std::variant of CB-struct pointers into the proper Python union object\n#define XPRSCB_NB_STRUCTS(ID, NAME, RET, ...)              \\\n\t{                                                      \\\n\t\tusing struct_t = NAME##_struct;                    \\\n\t\tauto s = nb::class_<struct_t>(m, #NAME \"_struct\"); \\\n\t\t__VA_ARGS__                                        \\\n\t\tbind_ret_code(s);                                  \\\n\t}\n\tXPRSCB_LIST(XPRSCB_NB_STRUCTS, XPRSCB_ARG_NB_FIELD)\n#undef XPRSCB_NB_STRUCTS\n}\n"
  },
  {
    "path": "lib/xpress_model_ext_constants.cpp",
    "content": "#include <nanobind/nanobind.h>\n\n#include \"pyoptinterface/xpress_model.hpp\"\n\nnamespace nb = nanobind;\nusing namespace xpress;\n\nvoid bind_xpress_constants(nb::module_ &m)\n{\n\tnb::module_ XPRS = m.def_submodule(\"XPRS\");\n\t/* useful constants */\n\tXPRS.attr(\"PLUSINFINITY\") = POI_XPRS_PLUSINFINITY;\n\tXPRS.attr(\"MINUSINFINITY\") = POI_XPRS_MINUSINFINITY;\n\tXPRS.attr(\"MAXINT\") = POI_XPRS_MAXINT;\n\tXPRS.attr(\"MAXBANNERLENGTH\") = POI_XPRS_MAXBANNERLENGTH;\n\tXPRS.attr(\"VERSION\") = POI_XPVERSION;\n\tXPRS.attr(\"VERSION_MAJOR\") = POI_XPVERSION_FULL;\n\tXPRS.attr(\"VERSION_MINOR\") = POI_XPVERSION_BUILD;\n\tXPRS.attr(\"VERSION_BUILD\") = POI_XPVERSION_MINOR;\n\tXPRS.attr(\"VERSION_FULL\") = POI_XPVERSION_MAJOR;\n\tXPRS.attr(\"MAXMESSAGELENGTH\") = POI_XPRS_MAXMESSAGELENGTH;\n\n\t/* control parameters for XPRSprob */\n\t/* String control parameters */\n\tXPRS.attr(\"MPSRHSNAME\") = POI_XPRS_MPSRHSNAME;\n\tXPRS.attr(\"MPSOBJNAME\") = POI_XPRS_MPSOBJNAME;\n\tXPRS.attr(\"MPSRANGENAME\") = POI_XPRS_MPSRANGENAME;\n\tXPRS.attr(\"MPSBOUNDNAME\") = POI_XPRS_MPSBOUNDNAME;\n\tXPRS.attr(\"OUTPUTMASK\") = POI_XPRS_OUTPUTMASK;\n\tXPRS.attr(\"TUNERMETHODFILE\") = POI_XPRS_TUNERMETHODFILE;\n\tXPRS.attr(\"TUNEROUTPUTPATH\") = POI_XPRS_TUNEROUTPUTPATH;\n\tXPRS.attr(\"TUNERSESSIONNAME\") = POI_XPRS_TUNERSESSIONNAME;\n\tXPRS.attr(\"COMPUTEEXECSERVICE\") = POI_XPRS_COMPUTEEXECSERVICE;\n\t/* Double control parameters */\n\tXPRS.attr(\"MAXCUTTIME\") = POI_XPRS_MAXCUTTIME;\n\tXPRS.attr(\"MAXSTALLTIME\") = POI_XPRS_MAXSTALLTIME;\n\tXPRS.attr(\"TUNERMAXTIME\") = POI_XPRS_TUNERMAXTIME;\n\tXPRS.attr(\"MATRIXTOL\") = POI_XPRS_MATRIXTOL;\n\tXPRS.attr(\"PIVOTTOL\") = POI_XPRS_PIVOTTOL;\n\tXPRS.attr(\"FEASTOL\") = POI_XPRS_FEASTOL;\n\tXPRS.attr(\"OUTPUTTOL\") = POI_XPRS_OUTPUTTOL;\n\tXPRS.attr(\"SOSREFTOL\") = POI_XPRS_SOSREFTOL;\n\tXPRS.attr(\"OPTIMALITYTOL\") = POI_XPRS_OPTIMALITYTOL;\n\tXPRS.attr(\"ETATOL\") = POI_XPRS_ETATOL;\n\tXPRS.attr(\"RELPIVOTTOL\") = POI_XPRS_RELPIVOTTOL;\n\tXPRS.attr(\"MIPTOL\") = POI_XPRS_MIPTOL;\n\tXPRS.attr(\"MIPTOLTARGET\") = POI_XPRS_MIPTOLTARGET;\n\tXPRS.attr(\"BARPERTURB\") = POI_XPRS_BARPERTURB;\n\tXPRS.attr(\"MIPADDCUTOFF\") = POI_XPRS_MIPADDCUTOFF;\n\tXPRS.attr(\"MIPABSCUTOFF\") = POI_XPRS_MIPABSCUTOFF;\n\tXPRS.attr(\"MIPRELCUTOFF\") = POI_XPRS_MIPRELCUTOFF;\n\tXPRS.attr(\"PSEUDOCOST\") = POI_XPRS_PSEUDOCOST;\n\tXPRS.attr(\"PENALTY\") = POI_XPRS_PENALTY;\n\tXPRS.attr(\"BIGM\") = POI_XPRS_BIGM;\n\tXPRS.attr(\"MIPABSSTOP\") = POI_XPRS_MIPABSSTOP;\n\tXPRS.attr(\"MIPRELSTOP\") = POI_XPRS_MIPRELSTOP;\n\tXPRS.attr(\"CROSSOVERACCURACYTOL\") = POI_XPRS_CROSSOVERACCURACYTOL;\n\tXPRS.attr(\"PRIMALPERTURB\") = POI_XPRS_PRIMALPERTURB;\n\tXPRS.attr(\"DUALPERTURB\") = POI_XPRS_DUALPERTURB;\n\tXPRS.attr(\"BAROBJSCALE\") = POI_XPRS_BAROBJSCALE;\n\tXPRS.attr(\"BARRHSSCALE\") = POI_XPRS_BARRHSSCALE;\n\tXPRS.attr(\"CHOLESKYTOL\") = POI_XPRS_CHOLESKYTOL;\n\tXPRS.attr(\"BARGAPSTOP\") = POI_XPRS_BARGAPSTOP;\n\tXPRS.attr(\"BARDUALSTOP\") = POI_XPRS_BARDUALSTOP;\n\tXPRS.attr(\"BARPRIMALSTOP\") = POI_XPRS_BARPRIMALSTOP;\n\tXPRS.attr(\"BARSTEPSTOP\") = POI_XPRS_BARSTEPSTOP;\n\tXPRS.attr(\"ELIMTOL\") = POI_XPRS_ELIMTOL;\n\tXPRS.attr(\"MARKOWITZTOL\") = POI_XPRS_MARKOWITZTOL;\n\tXPRS.attr(\"MIPABSGAPNOTIFY\") = POI_XPRS_MIPABSGAPNOTIFY;\n\tXPRS.attr(\"MIPRELGAPNOTIFY\") = POI_XPRS_MIPRELGAPNOTIFY;\n\tXPRS.attr(\"BARLARGEBOUND\") = POI_XPRS_BARLARGEBOUND;\n\tXPRS.attr(\"PPFACTOR\") = POI_XPRS_PPFACTOR;\n\tXPRS.attr(\"REPAIRINDEFINITEQMAX\") = POI_XPRS_REPAIRINDEFINITEQMAX;\n\tXPRS.attr(\"BARGAPTARGET\") = POI_XPRS_BARGAPTARGET;\n\tXPRS.attr(\"DUMMYCONTROL\") = POI_XPRS_DUMMYCONTROL;\n\tXPRS.attr(\"BARSTARTWEIGHT\") = POI_XPRS_BARSTARTWEIGHT;\n\tXPRS.attr(\"BARFREESCALE\") = POI_XPRS_BARFREESCALE;\n\tXPRS.attr(\"SBEFFORT\") = POI_XPRS_SBEFFORT;\n\tXPRS.attr(\"HEURDIVERANDOMIZE\") = POI_XPRS_HEURDIVERANDOMIZE;\n\tXPRS.attr(\"HEURSEARCHEFFORT\") = POI_XPRS_HEURSEARCHEFFORT;\n\tXPRS.attr(\"CUTFACTOR\") = POI_XPRS_CUTFACTOR;\n\tXPRS.attr(\"EIGENVALUETOL\") = POI_XPRS_EIGENVALUETOL;\n\tXPRS.attr(\"INDLINBIGM\") = POI_XPRS_INDLINBIGM;\n\tXPRS.attr(\"TREEMEMORYSAVINGTARGET\") = POI_XPRS_TREEMEMORYSAVINGTARGET;\n\tXPRS.attr(\"INDPRELINBIGM\") = POI_XPRS_INDPRELINBIGM;\n\tXPRS.attr(\"RELAXTREEMEMORYLIMIT\") = POI_XPRS_RELAXTREEMEMORYLIMIT;\n\tXPRS.attr(\"MIPABSGAPNOTIFYOBJ\") = POI_XPRS_MIPABSGAPNOTIFYOBJ;\n\tXPRS.attr(\"MIPABSGAPNOTIFYBOUND\") = POI_XPRS_MIPABSGAPNOTIFYBOUND;\n\tXPRS.attr(\"PRESOLVEMAXGROW\") = POI_XPRS_PRESOLVEMAXGROW;\n\tXPRS.attr(\"HEURSEARCHTARGETSIZE\") = POI_XPRS_HEURSEARCHTARGETSIZE;\n\tXPRS.attr(\"CROSSOVERRELPIVOTTOL\") = POI_XPRS_CROSSOVERRELPIVOTTOL;\n\tXPRS.attr(\"CROSSOVERRELPIVOTTOLSAFE\") = POI_XPRS_CROSSOVERRELPIVOTTOLSAFE;\n\tXPRS.attr(\"DETLOGFREQ\") = POI_XPRS_DETLOGFREQ;\n\tXPRS.attr(\"MAXIMPLIEDBOUND\") = POI_XPRS_MAXIMPLIEDBOUND;\n\tXPRS.attr(\"FEASTOLTARGET\") = POI_XPRS_FEASTOLTARGET;\n\tXPRS.attr(\"OPTIMALITYTOLTARGET\") = POI_XPRS_OPTIMALITYTOLTARGET;\n\tXPRS.attr(\"PRECOMPONENTSEFFORT\") = POI_XPRS_PRECOMPONENTSEFFORT;\n\tXPRS.attr(\"LPLOGDELAY\") = POI_XPRS_LPLOGDELAY;\n\tXPRS.attr(\"HEURDIVEITERLIMIT\") = POI_XPRS_HEURDIVEITERLIMIT;\n\tXPRS.attr(\"BARKERNEL\") = POI_XPRS_BARKERNEL;\n\tXPRS.attr(\"FEASTOLPERTURB\") = POI_XPRS_FEASTOLPERTURB;\n\tXPRS.attr(\"CROSSOVERFEASWEIGHT\") = POI_XPRS_CROSSOVERFEASWEIGHT;\n\tXPRS.attr(\"LUPIVOTTOL\") = POI_XPRS_LUPIVOTTOL;\n\tXPRS.attr(\"MIPRESTARTGAPTHRESHOLD\") = POI_XPRS_MIPRESTARTGAPTHRESHOLD;\n\tXPRS.attr(\"NODEPROBINGEFFORT\") = POI_XPRS_NODEPROBINGEFFORT;\n\tXPRS.attr(\"INPUTTOL\") = POI_XPRS_INPUTTOL;\n\tXPRS.attr(\"MIPRESTARTFACTOR\") = POI_XPRS_MIPRESTARTFACTOR;\n\tXPRS.attr(\"BAROBJPERTURB\") = POI_XPRS_BAROBJPERTURB;\n\tXPRS.attr(\"CPIALPHA\") = POI_XPRS_CPIALPHA;\n\tXPRS.attr(\"GLOBALSPATIALBRANCHPROPAGATIONEFFORT\") =\n\t    POI_XPRS_GLOBALSPATIALBRANCHPROPAGATIONEFFORT;\n\tXPRS.attr(\"GLOBALSPATIALBRANCHCUTTINGEFFORT\") = POI_XPRS_GLOBALSPATIALBRANCHCUTTINGEFFORT;\n\tXPRS.attr(\"GLOBALBOUNDINGBOX\") = POI_XPRS_GLOBALBOUNDINGBOX;\n\tXPRS.attr(\"TIMELIMIT\") = POI_XPRS_TIMELIMIT;\n\tXPRS.attr(\"SOLTIMELIMIT\") = POI_XPRS_SOLTIMELIMIT;\n\tXPRS.attr(\"REPAIRINFEASTIMELIMIT\") = POI_XPRS_REPAIRINFEASTIMELIMIT;\n\tXPRS.attr(\"BARHGEXTRAPOLATE\") = POI_XPRS_BARHGEXTRAPOLATE;\n\tXPRS.attr(\"WORKLIMIT\") = POI_XPRS_WORKLIMIT;\n\tXPRS.attr(\"CALLBACKCHECKTIMEWORKDELAY\") = POI_XPRS_CALLBACKCHECKTIMEWORKDELAY;\n\tXPRS.attr(\"PREROOTWORKLIMIT\") = POI_XPRS_PREROOTWORKLIMIT;\n\tXPRS.attr(\"PREROOTEFFORT\") = POI_XPRS_PREROOTEFFORT;\n\t/* Integer control parameters */\n\tXPRS.attr(\"EXTRAROWS\") = POI_XPRS_EXTRAROWS;\n\tXPRS.attr(\"EXTRACOLS\") = POI_XPRS_EXTRACOLS;\n\tXPRS.attr(\"LPITERLIMIT\") = POI_XPRS_LPITERLIMIT;\n\tXPRS.attr(\"LPLOG\") = POI_XPRS_LPLOG;\n\tXPRS.attr(\"SCALING\") = POI_XPRS_SCALING;\n\tXPRS.attr(\"PRESOLVE\") = POI_XPRS_PRESOLVE;\n\tXPRS.attr(\"CRASH\") = POI_XPRS_CRASH;\n\tXPRS.attr(\"PRICINGALG\") = POI_XPRS_PRICINGALG;\n\tXPRS.attr(\"INVERTFREQ\") = POI_XPRS_INVERTFREQ;\n\tXPRS.attr(\"INVERTMIN\") = POI_XPRS_INVERTMIN;\n\tXPRS.attr(\"MAXNODE\") = POI_XPRS_MAXNODE;\n\tXPRS.attr(\"MAXMIPSOL\") = POI_XPRS_MAXMIPSOL;\n\tXPRS.attr(\"SIFTPASSES\") = POI_XPRS_SIFTPASSES;\n\tXPRS.attr(\"DEFAULTALG\") = POI_XPRS_DEFAULTALG;\n\tXPRS.attr(\"VARSELECTION\") = POI_XPRS_VARSELECTION;\n\tXPRS.attr(\"NODESELECTION\") = POI_XPRS_NODESELECTION;\n\tXPRS.attr(\"BACKTRACK\") = POI_XPRS_BACKTRACK;\n\tXPRS.attr(\"MIPLOG\") = POI_XPRS_MIPLOG;\n\tXPRS.attr(\"KEEPNROWS\") = POI_XPRS_KEEPNROWS;\n\tXPRS.attr(\"MPSECHO\") = POI_XPRS_MPSECHO;\n\tXPRS.attr(\"MAXPAGELINES\") = POI_XPRS_MAXPAGELINES;\n\tXPRS.attr(\"OUTPUTLOG\") = POI_XPRS_OUTPUTLOG;\n\tXPRS.attr(\"BARSOLUTION\") = POI_XPRS_BARSOLUTION;\n\tXPRS.attr(\"CROSSOVER\") = POI_XPRS_CROSSOVER;\n\tXPRS.attr(\"BARITERLIMIT\") = POI_XPRS_BARITERLIMIT;\n\tXPRS.attr(\"CHOLESKYALG\") = POI_XPRS_CHOLESKYALG;\n\tXPRS.attr(\"BAROUTPUT\") = POI_XPRS_BAROUTPUT;\n\tXPRS.attr(\"EXTRAMIPENTS\") = POI_XPRS_EXTRAMIPENTS;\n\tXPRS.attr(\"REFACTOR\") = POI_XPRS_REFACTOR;\n\tXPRS.attr(\"BARTHREADS\") = POI_XPRS_BARTHREADS;\n\tXPRS.attr(\"KEEPBASIS\") = POI_XPRS_KEEPBASIS;\n\tXPRS.attr(\"CROSSOVEROPS\") = POI_XPRS_CROSSOVEROPS;\n\tXPRS.attr(\"VERSION\") = POI_XPRS_VERSION;\n\tXPRS.attr(\"CROSSOVERTHREADS\") = POI_XPRS_CROSSOVERTHREADS;\n\tXPRS.attr(\"BIGMMETHOD\") = POI_XPRS_BIGMMETHOD;\n\tXPRS.attr(\"MPSNAMELENGTH\") = POI_XPRS_MPSNAMELENGTH;\n\tXPRS.attr(\"ELIMFILLIN\") = POI_XPRS_ELIMFILLIN;\n\tXPRS.attr(\"PRESOLVEOPS\") = POI_XPRS_PRESOLVEOPS;\n\tXPRS.attr(\"MIPPRESOLVE\") = POI_XPRS_MIPPRESOLVE;\n\tXPRS.attr(\"MIPTHREADS\") = POI_XPRS_MIPTHREADS;\n\tXPRS.attr(\"BARORDER\") = POI_XPRS_BARORDER;\n\tXPRS.attr(\"BREADTHFIRST\") = POI_XPRS_BREADTHFIRST;\n\tXPRS.attr(\"AUTOPERTURB\") = POI_XPRS_AUTOPERTURB;\n\tXPRS.attr(\"DENSECOLLIMIT\") = POI_XPRS_DENSECOLLIMIT;\n\tXPRS.attr(\"CALLBACKFROMMAINTHREAD\") = POI_XPRS_CALLBACKFROMMAINTHREAD;\n\tXPRS.attr(\"MAXMCOEFFBUFFERELEMS\") = POI_XPRS_MAXMCOEFFBUFFERELEMS;\n\tXPRS.attr(\"REFINEOPS\") = POI_XPRS_REFINEOPS;\n\tXPRS.attr(\"LPREFINEITERLIMIT\") = POI_XPRS_LPREFINEITERLIMIT;\n\tXPRS.attr(\"MIPREFINEITERLIMIT\") = POI_XPRS_MIPREFINEITERLIMIT;\n\tXPRS.attr(\"DUALIZEOPS\") = POI_XPRS_DUALIZEOPS;\n\tXPRS.attr(\"CROSSOVERITERLIMIT\") = POI_XPRS_CROSSOVERITERLIMIT;\n\tXPRS.attr(\"PREBASISRED\") = POI_XPRS_PREBASISRED;\n\tXPRS.attr(\"PRESORT\") = POI_XPRS_PRESORT;\n\tXPRS.attr(\"PREPERMUTE\") = POI_XPRS_PREPERMUTE;\n\tXPRS.attr(\"PREPERMUTESEED\") = POI_XPRS_PREPERMUTESEED;\n\tXPRS.attr(\"MAXMEMORYSOFT\") = POI_XPRS_MAXMEMORYSOFT;\n\tXPRS.attr(\"CUTFREQ\") = POI_XPRS_CUTFREQ;\n\tXPRS.attr(\"SYMSELECT\") = POI_XPRS_SYMSELECT;\n\tXPRS.attr(\"SYMMETRY\") = POI_XPRS_SYMMETRY;\n\tXPRS.attr(\"MAXMEMORYHARD\") = POI_XPRS_MAXMEMORYHARD;\n\tXPRS.attr(\"MIQCPALG\") = POI_XPRS_MIQCPALG;\n\tXPRS.attr(\"QCCUTS\") = POI_XPRS_QCCUTS;\n\tXPRS.attr(\"QCROOTALG\") = POI_XPRS_QCROOTALG;\n\tXPRS.attr(\"PRECONVERTSEPARABLE\") = POI_XPRS_PRECONVERTSEPARABLE;\n\tXPRS.attr(\"ALGAFTERNETWORK\") = POI_XPRS_ALGAFTERNETWORK;\n\tXPRS.attr(\"TRACE\") = POI_XPRS_TRACE;\n\tXPRS.attr(\"MAXIIS\") = POI_XPRS_MAXIIS;\n\tXPRS.attr(\"CPUTIME\") = POI_XPRS_CPUTIME;\n\tXPRS.attr(\"COVERCUTS\") = POI_XPRS_COVERCUTS;\n\tXPRS.attr(\"GOMCUTS\") = POI_XPRS_GOMCUTS;\n\tXPRS.attr(\"LPFOLDING\") = POI_XPRS_LPFOLDING;\n\tXPRS.attr(\"MPSFORMAT\") = POI_XPRS_MPSFORMAT;\n\tXPRS.attr(\"CUTSTRATEGY\") = POI_XPRS_CUTSTRATEGY;\n\tXPRS.attr(\"CUTDEPTH\") = POI_XPRS_CUTDEPTH;\n\tXPRS.attr(\"TREECOVERCUTS\") = POI_XPRS_TREECOVERCUTS;\n\tXPRS.attr(\"TREEGOMCUTS\") = POI_XPRS_TREEGOMCUTS;\n\tXPRS.attr(\"CUTSELECT\") = POI_XPRS_CUTSELECT;\n\tXPRS.attr(\"TREECUTSELECT\") = POI_XPRS_TREECUTSELECT;\n\tXPRS.attr(\"DUALIZE\") = POI_XPRS_DUALIZE;\n\tXPRS.attr(\"DUALGRADIENT\") = POI_XPRS_DUALGRADIENT;\n\tXPRS.attr(\"SBITERLIMIT\") = POI_XPRS_SBITERLIMIT;\n\tXPRS.attr(\"SBBEST\") = POI_XPRS_SBBEST;\n\tXPRS.attr(\"BARINDEFLIMIT\") = POI_XPRS_BARINDEFLIMIT;\n\tXPRS.attr(\"HEURFREQ\") = POI_XPRS_HEURFREQ;\n\tXPRS.attr(\"HEURDEPTH\") = POI_XPRS_HEURDEPTH;\n\tXPRS.attr(\"HEURMAXSOL\") = POI_XPRS_HEURMAXSOL;\n\tXPRS.attr(\"HEURNODES\") = POI_XPRS_HEURNODES;\n\tXPRS.attr(\"LNPBEST\") = POI_XPRS_LNPBEST;\n\tXPRS.attr(\"LNPITERLIMIT\") = POI_XPRS_LNPITERLIMIT;\n\tXPRS.attr(\"BRANCHCHOICE\") = POI_XPRS_BRANCHCHOICE;\n\tXPRS.attr(\"BARREGULARIZE\") = POI_XPRS_BARREGULARIZE;\n\tXPRS.attr(\"SBSELECT\") = POI_XPRS_SBSELECT;\n\tXPRS.attr(\"IISLOG\") = POI_XPRS_IISLOG;\n\tXPRS.attr(\"LOCALCHOICE\") = POI_XPRS_LOCALCHOICE;\n\tXPRS.attr(\"LOCALBACKTRACK\") = POI_XPRS_LOCALBACKTRACK;\n\tXPRS.attr(\"DUALSTRATEGY\") = POI_XPRS_DUALSTRATEGY;\n\tXPRS.attr(\"HEURDIVESTRATEGY\") = POI_XPRS_HEURDIVESTRATEGY;\n\tXPRS.attr(\"HEURSELECT\") = POI_XPRS_HEURSELECT;\n\tXPRS.attr(\"BARSTART\") = POI_XPRS_BARSTART;\n\tXPRS.attr(\"PRESOLVEPASSES\") = POI_XPRS_PRESOLVEPASSES;\n\tXPRS.attr(\"BARORDERTHREADS\") = POI_XPRS_BARORDERTHREADS;\n\tXPRS.attr(\"EXTRASETS\") = POI_XPRS_EXTRASETS;\n\tXPRS.attr(\"FEASIBILITYPUMP\") = POI_XPRS_FEASIBILITYPUMP;\n\tXPRS.attr(\"PRECOEFELIM\") = POI_XPRS_PRECOEFELIM;\n\tXPRS.attr(\"PREDOMCOL\") = POI_XPRS_PREDOMCOL;\n\tXPRS.attr(\"HEURSEARCHFREQ\") = POI_XPRS_HEURSEARCHFREQ;\n\tXPRS.attr(\"HEURDIVESPEEDUP\") = POI_XPRS_HEURDIVESPEEDUP;\n\tXPRS.attr(\"SBESTIMATE\") = POI_XPRS_SBESTIMATE;\n\tXPRS.attr(\"BARCORES\") = POI_XPRS_BARCORES;\n\tXPRS.attr(\"MAXCHECKSONMAXTIME\") = POI_XPRS_MAXCHECKSONMAXTIME;\n\tXPRS.attr(\"MAXCHECKSONMAXCUTTIME\") = POI_XPRS_MAXCHECKSONMAXCUTTIME;\n\tXPRS.attr(\"HISTORYCOSTS\") = POI_XPRS_HISTORYCOSTS;\n\tXPRS.attr(\"ALGAFTERCROSSOVER\") = POI_XPRS_ALGAFTERCROSSOVER;\n\tXPRS.attr(\"MUTEXCALLBACKS\") = POI_XPRS_MUTEXCALLBACKS;\n\tXPRS.attr(\"BARCRASH\") = POI_XPRS_BARCRASH;\n\tXPRS.attr(\"HEURDIVESOFTROUNDING\") = POI_XPRS_HEURDIVESOFTROUNDING;\n\tXPRS.attr(\"HEURSEARCHROOTSELECT\") = POI_XPRS_HEURSEARCHROOTSELECT;\n\tXPRS.attr(\"HEURSEARCHTREESELECT\") = POI_XPRS_HEURSEARCHTREESELECT;\n\tXPRS.attr(\"MPS18COMPATIBLE\") = POI_XPRS_MPS18COMPATIBLE;\n\tXPRS.attr(\"ROOTPRESOLVE\") = POI_XPRS_ROOTPRESOLVE;\n\tXPRS.attr(\"CROSSOVERDRP\") = POI_XPRS_CROSSOVERDRP;\n\tXPRS.attr(\"FORCEOUTPUT\") = POI_XPRS_FORCEOUTPUT;\n\tXPRS.attr(\"PRIMALOPS\") = POI_XPRS_PRIMALOPS;\n\tXPRS.attr(\"DETERMINISTIC\") = POI_XPRS_DETERMINISTIC;\n\tXPRS.attr(\"PREPROBING\") = POI_XPRS_PREPROBING;\n\tXPRS.attr(\"TREEMEMORYLIMIT\") = POI_XPRS_TREEMEMORYLIMIT;\n\tXPRS.attr(\"TREECOMPRESSION\") = POI_XPRS_TREECOMPRESSION;\n\tXPRS.attr(\"TREEDIAGNOSTICS\") = POI_XPRS_TREEDIAGNOSTICS;\n\tXPRS.attr(\"MAXTREEFILESIZE\") = POI_XPRS_MAXTREEFILESIZE;\n\tXPRS.attr(\"PRECLIQUESTRATEGY\") = POI_XPRS_PRECLIQUESTRATEGY;\n\tXPRS.attr(\"IFCHECKCONVEXITY\") = POI_XPRS_IFCHECKCONVEXITY;\n\tXPRS.attr(\"PRIMALUNSHIFT\") = POI_XPRS_PRIMALUNSHIFT;\n\tXPRS.attr(\"REPAIRINDEFINITEQ\") = POI_XPRS_REPAIRINDEFINITEQ;\n\tXPRS.attr(\"MIPRAMPUP\") = POI_XPRS_MIPRAMPUP;\n\tXPRS.attr(\"MAXLOCALBACKTRACK\") = POI_XPRS_MAXLOCALBACKTRACK;\n\tXPRS.attr(\"USERSOLHEURISTIC\") = POI_XPRS_USERSOLHEURISTIC;\n\tXPRS.attr(\"PRECONVERTOBJTOCONS\") = POI_XPRS_PRECONVERTOBJTOCONS;\n\tXPRS.attr(\"FORCEPARALLELDUAL\") = POI_XPRS_FORCEPARALLELDUAL;\n\tXPRS.attr(\"BACKTRACKTIE\") = POI_XPRS_BACKTRACKTIE;\n\tXPRS.attr(\"BRANCHDISJ\") = POI_XPRS_BRANCHDISJ;\n\tXPRS.attr(\"MIPFRACREDUCE\") = POI_XPRS_MIPFRACREDUCE;\n\tXPRS.attr(\"CONCURRENTTHREADS\") = POI_XPRS_CONCURRENTTHREADS;\n\tXPRS.attr(\"MAXSCALEFACTOR\") = POI_XPRS_MAXSCALEFACTOR;\n\tXPRS.attr(\"HEURTHREADS\") = POI_XPRS_HEURTHREADS;\n\tXPRS.attr(\"THREADS\") = POI_XPRS_THREADS;\n\tXPRS.attr(\"HEURBEFORELP\") = POI_XPRS_HEURBEFORELP;\n\tXPRS.attr(\"PREDOMROW\") = POI_XPRS_PREDOMROW;\n\tXPRS.attr(\"BRANCHSTRUCTURAL\") = POI_XPRS_BRANCHSTRUCTURAL;\n\tXPRS.attr(\"QUADRATICUNSHIFT\") = POI_XPRS_QUADRATICUNSHIFT;\n\tXPRS.attr(\"BARPRESOLVEOPS\") = POI_XPRS_BARPRESOLVEOPS;\n\tXPRS.attr(\"QSIMPLEXOPS\") = POI_XPRS_QSIMPLEXOPS;\n\tXPRS.attr(\"MIPRESTART\") = POI_XPRS_MIPRESTART;\n\tXPRS.attr(\"CONFLICTCUTS\") = POI_XPRS_CONFLICTCUTS;\n\tXPRS.attr(\"PREPROTECTDUAL\") = POI_XPRS_PREPROTECTDUAL;\n\tXPRS.attr(\"CORESPERCPU\") = POI_XPRS_CORESPERCPU;\n\tXPRS.attr(\"RESOURCESTRATEGY\") = POI_XPRS_RESOURCESTRATEGY;\n\tXPRS.attr(\"CLAMPING\") = POI_XPRS_CLAMPING;\n\tXPRS.attr(\"PREDUPROW\") = POI_XPRS_PREDUPROW;\n\tXPRS.attr(\"CPUPLATFORM\") = POI_XPRS_CPUPLATFORM;\n\tXPRS.attr(\"BARALG\") = POI_XPRS_BARALG;\n\tXPRS.attr(\"SIFTING\") = POI_XPRS_SIFTING;\n\tXPRS.attr(\"BARKEEPLASTSOL\") = POI_XPRS_BARKEEPLASTSOL;\n\tXPRS.attr(\"LPLOGSTYLE\") = POI_XPRS_LPLOGSTYLE;\n\tXPRS.attr(\"RANDOMSEED\") = POI_XPRS_RANDOMSEED;\n\tXPRS.attr(\"TREEQCCUTS\") = POI_XPRS_TREEQCCUTS;\n\tXPRS.attr(\"PRELINDEP\") = POI_XPRS_PRELINDEP;\n\tXPRS.attr(\"DUALTHREADS\") = POI_XPRS_DUALTHREADS;\n\tXPRS.attr(\"PREOBJCUTDETECT\") = POI_XPRS_PREOBJCUTDETECT;\n\tXPRS.attr(\"PREBNDREDQUAD\") = POI_XPRS_PREBNDREDQUAD;\n\tXPRS.attr(\"PREBNDREDCONE\") = POI_XPRS_PREBNDREDCONE;\n\tXPRS.attr(\"PRECOMPONENTS\") = POI_XPRS_PRECOMPONENTS;\n\tXPRS.attr(\"MAXMIPTASKS\") = POI_XPRS_MAXMIPTASKS;\n\tXPRS.attr(\"MIPTERMINATIONMETHOD\") = POI_XPRS_MIPTERMINATIONMETHOD;\n\tXPRS.attr(\"PRECONEDECOMP\") = POI_XPRS_PRECONEDECOMP;\n\tXPRS.attr(\"HEURFORCESPECIALOBJ\") = POI_XPRS_HEURFORCESPECIALOBJ;\n\tXPRS.attr(\"HEURSEARCHROOTCUTFREQ\") = POI_XPRS_HEURSEARCHROOTCUTFREQ;\n\tXPRS.attr(\"PREELIMQUAD\") = POI_XPRS_PREELIMQUAD;\n\tXPRS.attr(\"PREIMPLICATIONS\") = POI_XPRS_PREIMPLICATIONS;\n\tXPRS.attr(\"TUNERMODE\") = POI_XPRS_TUNERMODE;\n\tXPRS.attr(\"TUNERMETHOD\") = POI_XPRS_TUNERMETHOD;\n\tXPRS.attr(\"TUNERTARGET\") = POI_XPRS_TUNERTARGET;\n\tXPRS.attr(\"TUNERTHREADS\") = POI_XPRS_TUNERTHREADS;\n\tXPRS.attr(\"TUNERHISTORY\") = POI_XPRS_TUNERHISTORY;\n\tXPRS.attr(\"TUNERPERMUTE\") = POI_XPRS_TUNERPERMUTE;\n\tXPRS.attr(\"TUNERVERBOSE\") = POI_XPRS_TUNERVERBOSE;\n\tXPRS.attr(\"TUNEROUTPUT\") = POI_XPRS_TUNEROUTPUT;\n\tXPRS.attr(\"PREANALYTICCENTER\") = POI_XPRS_PREANALYTICCENTER;\n\tXPRS.attr(\"LPFLAGS\") = POI_XPRS_LPFLAGS;\n\tXPRS.attr(\"MIPKAPPAFREQ\") = POI_XPRS_MIPKAPPAFREQ;\n\tXPRS.attr(\"OBJSCALEFACTOR\") = POI_XPRS_OBJSCALEFACTOR;\n\tXPRS.attr(\"TREEFILELOGINTERVAL\") = POI_XPRS_TREEFILELOGINTERVAL;\n\tXPRS.attr(\"IGNORECONTAINERCPULIMIT\") = POI_XPRS_IGNORECONTAINERCPULIMIT;\n\tXPRS.attr(\"IGNORECONTAINERMEMORYLIMIT\") = POI_XPRS_IGNORECONTAINERMEMORYLIMIT;\n\tXPRS.attr(\"MIPDUALREDUCTIONS\") = POI_XPRS_MIPDUALREDUCTIONS;\n\tXPRS.attr(\"GENCONSDUALREDUCTIONS\") = POI_XPRS_GENCONSDUALREDUCTIONS;\n\tXPRS.attr(\"PWLDUALREDUCTIONS\") = POI_XPRS_PWLDUALREDUCTIONS;\n\tXPRS.attr(\"BARFAILITERLIMIT\") = POI_XPRS_BARFAILITERLIMIT;\n\tXPRS.attr(\"AUTOSCALING\") = POI_XPRS_AUTOSCALING;\n\tXPRS.attr(\"GENCONSABSTRANSFORMATION\") = POI_XPRS_GENCONSABSTRANSFORMATION;\n\tXPRS.attr(\"COMPUTEJOBPRIORITY\") = POI_XPRS_COMPUTEJOBPRIORITY;\n\tXPRS.attr(\"PREFOLDING\") = POI_XPRS_PREFOLDING;\n\tXPRS.attr(\"COMPUTE\") = POI_XPRS_COMPUTE;\n\tXPRS.attr(\"NETSTALLLIMIT\") = POI_XPRS_NETSTALLLIMIT;\n\tXPRS.attr(\"SERIALIZEPREINTSOL\") = POI_XPRS_SERIALIZEPREINTSOL;\n\tXPRS.attr(\"NUMERICALEMPHASIS\") = POI_XPRS_NUMERICALEMPHASIS;\n\tXPRS.attr(\"PWLNONCONVEXTRANSFORMATION\") = POI_XPRS_PWLNONCONVEXTRANSFORMATION;\n\tXPRS.attr(\"MIPCOMPONENTS\") = POI_XPRS_MIPCOMPONENTS;\n\tXPRS.attr(\"MIPCONCURRENTNODES\") = POI_XPRS_MIPCONCURRENTNODES;\n\tXPRS.attr(\"MIPCONCURRENTSOLVES\") = POI_XPRS_MIPCONCURRENTSOLVES;\n\tXPRS.attr(\"OUTPUTCONTROLS\") = POI_XPRS_OUTPUTCONTROLS;\n\tXPRS.attr(\"SIFTSWITCH\") = POI_XPRS_SIFTSWITCH;\n\tXPRS.attr(\"HEUREMPHASIS\") = POI_XPRS_HEUREMPHASIS;\n\tXPRS.attr(\"BARREFITER\") = POI_XPRS_BARREFITER;\n\tXPRS.attr(\"COMPUTELOG\") = POI_XPRS_COMPUTELOG;\n\tXPRS.attr(\"SIFTPRESOLVEOPS\") = POI_XPRS_SIFTPRESOLVEOPS;\n\tXPRS.attr(\"CHECKINPUTDATA\") = POI_XPRS_CHECKINPUTDATA;\n\tXPRS.attr(\"ESCAPENAMES\") = POI_XPRS_ESCAPENAMES;\n\tXPRS.attr(\"IOTIMEOUT\") = POI_XPRS_IOTIMEOUT;\n\tXPRS.attr(\"AUTOCUTTING\") = POI_XPRS_AUTOCUTTING;\n\tXPRS.attr(\"GLOBALNUMINITNLPCUTS\") = POI_XPRS_GLOBALNUMINITNLPCUTS;\n\tXPRS.attr(\"CALLBACKCHECKTIMEDELAY\") = POI_XPRS_CALLBACKCHECKTIMEDELAY;\n\tXPRS.attr(\"MULTIOBJOPS\") = POI_XPRS_MULTIOBJOPS;\n\tXPRS.attr(\"MULTIOBJLOG\") = POI_XPRS_MULTIOBJLOG;\n\tXPRS.attr(\"BACKGROUNDMAXTHREADS\") = POI_XPRS_BACKGROUNDMAXTHREADS;\n\tXPRS.attr(\"GLOBALLSHEURSTRATEGY\") = POI_XPRS_GLOBALLSHEURSTRATEGY;\n\tXPRS.attr(\"GLOBALSPATIALBRANCHIFPREFERORIG\") = POI_XPRS_GLOBALSPATIALBRANCHIFPREFERORIG;\n\tXPRS.attr(\"PRECONFIGURATION\") = POI_XPRS_PRECONFIGURATION;\n\tXPRS.attr(\"FEASIBILITYJUMP\") = POI_XPRS_FEASIBILITYJUMP;\n\tXPRS.attr(\"IISOPS\") = POI_XPRS_IISOPS;\n\tXPRS.attr(\"RLTCUTS\") = POI_XPRS_RLTCUTS;\n\tXPRS.attr(\"ALTERNATIVEREDCOSTS\") = POI_XPRS_ALTERNATIVEREDCOSTS;\n\tXPRS.attr(\"HEURSHIFTPROP\") = POI_XPRS_HEURSHIFTPROP;\n\tXPRS.attr(\"HEURSEARCHCOPYCONTROLS\") = POI_XPRS_HEURSEARCHCOPYCONTROLS;\n\tXPRS.attr(\"GLOBALNLPCUTS\") = POI_XPRS_GLOBALNLPCUTS;\n\tXPRS.attr(\"GLOBALTREENLPCUTS\") = POI_XPRS_GLOBALTREENLPCUTS;\n\tXPRS.attr(\"BARHGOPS\") = POI_XPRS_BARHGOPS;\n\tXPRS.attr(\"BARHGMAXRESTARTS\") = POI_XPRS_BARHGMAXRESTARTS;\n\tXPRS.attr(\"MCFCUTSTRATEGY\") = POI_XPRS_MCFCUTSTRATEGY;\n\tXPRS.attr(\"PREROOTTHREADS\") = POI_XPRS_PREROOTTHREADS;\n\tXPRS.attr(\"BARITERATIVE\") = POI_XPRS_BARITERATIVE;\n\t/* Integer control parameters that support 64-bit values  */\n\tXPRS.attr(\"EXTRAELEMS\") = POI_XPRS_EXTRAELEMS;\n\tXPRS.attr(\"EXTRASETELEMS\") = POI_XPRS_EXTRASETELEMS;\n\tXPRS.attr(\"BACKGROUNDSELECT\") = POI_XPRS_BACKGROUNDSELECT;\n\tXPRS.attr(\"HEURSEARCHBACKGROUNDSELECT\") = POI_XPRS_HEURSEARCHBACKGROUNDSELECT;\n\n\t/* attributes for XPRSprob */\n\t/* String attributes */\n\tXPRS.attr(\"MATRIXNAME\") = POI_XPRS_MATRIXNAME;\n\tXPRS.attr(\"BOUNDNAME\") = POI_XPRS_BOUNDNAME;\n\tXPRS.attr(\"RHSNAME\") = POI_XPRS_RHSNAME;\n\tXPRS.attr(\"RANGENAME\") = POI_XPRS_RANGENAME;\n\tXPRS.attr(\"XPRESSVERSION\") = POI_XPRS_XPRESSVERSION;\n\tXPRS.attr(\"UUID\") = POI_XPRS_UUID;\n\t/* Double attributes */\n\tXPRS.attr(\"MIPSOLTIME\") = POI_XPRS_MIPSOLTIME;\n\tXPRS.attr(\"TIME\") = POI_XPRS_TIME;\n\tXPRS.attr(\"LPOBJVAL\") = POI_XPRS_LPOBJVAL;\n\tXPRS.attr(\"SUMPRIMALINF\") = POI_XPRS_SUMPRIMALINF;\n\tXPRS.attr(\"MIPOBJVAL\") = POI_XPRS_MIPOBJVAL;\n\tXPRS.attr(\"BESTBOUND\") = POI_XPRS_BESTBOUND;\n\tXPRS.attr(\"OBJRHS\") = POI_XPRS_OBJRHS;\n\tXPRS.attr(\"MIPBESTOBJVAL\") = POI_XPRS_MIPBESTOBJVAL;\n\tXPRS.attr(\"OBJSENSE\") = POI_XPRS_OBJSENSE;\n\tXPRS.attr(\"BRANCHVALUE\") = POI_XPRS_BRANCHVALUE;\n\tXPRS.attr(\"PENALTYVALUE\") = POI_XPRS_PENALTYVALUE;\n\tXPRS.attr(\"CURRMIPCUTOFF\") = POI_XPRS_CURRMIPCUTOFF;\n\tXPRS.attr(\"BARCONDA\") = POI_XPRS_BARCONDA;\n\tXPRS.attr(\"BARCONDD\") = POI_XPRS_BARCONDD;\n\tXPRS.attr(\"MAXABSPRIMALINFEAS\") = POI_XPRS_MAXABSPRIMALINFEAS;\n\tXPRS.attr(\"MAXRELPRIMALINFEAS\") = POI_XPRS_MAXRELPRIMALINFEAS;\n\tXPRS.attr(\"MAXABSDUALINFEAS\") = POI_XPRS_MAXABSDUALINFEAS;\n\tXPRS.attr(\"MAXRELDUALINFEAS\") = POI_XPRS_MAXRELDUALINFEAS;\n\tXPRS.attr(\"PRIMALDUALINTEGRAL\") = POI_XPRS_PRIMALDUALINTEGRAL;\n\tXPRS.attr(\"MAXMIPINFEAS\") = POI_XPRS_MAXMIPINFEAS;\n\tXPRS.attr(\"ATTENTIONLEVEL\") = POI_XPRS_ATTENTIONLEVEL;\n\tXPRS.attr(\"MAXKAPPA\") = POI_XPRS_MAXKAPPA;\n\tXPRS.attr(\"TREECOMPLETION\") = POI_XPRS_TREECOMPLETION;\n\tXPRS.attr(\"PREDICTEDATTLEVEL\") = POI_XPRS_PREDICTEDATTLEVEL;\n\tXPRS.attr(\"OBSERVEDPRIMALINTEGRAL\") = POI_XPRS_OBSERVEDPRIMALINTEGRAL;\n\tXPRS.attr(\"CPISCALEFACTOR\") = POI_XPRS_CPISCALEFACTOR;\n\tXPRS.attr(\"OBJVAL\") = POI_XPRS_OBJVAL;\n\tXPRS.attr(\"WORK\") = POI_XPRS_WORK;\n\tXPRS.attr(\"BARPRIMALOBJ\") = POI_XPRS_BARPRIMALOBJ;\n\tXPRS.attr(\"BARDUALOBJ\") = POI_XPRS_BARDUALOBJ;\n\tXPRS.attr(\"BARPRIMALINF\") = POI_XPRS_BARPRIMALINF;\n\tXPRS.attr(\"BARDUALINF\") = POI_XPRS_BARDUALINF;\n\tXPRS.attr(\"BARCGAP\") = POI_XPRS_BARCGAP;\n\t/* Integer attributes */\n\tXPRS.attr(\"ROWS\") = POI_XPRS_ROWS;\n\tXPRS.attr(\"SETS\") = POI_XPRS_SETS;\n\tXPRS.attr(\"PRIMALINFEAS\") = POI_XPRS_PRIMALINFEAS;\n\tXPRS.attr(\"DUALINFEAS\") = POI_XPRS_DUALINFEAS;\n\tXPRS.attr(\"SIMPLEXITER\") = POI_XPRS_SIMPLEXITER;\n\tXPRS.attr(\"LPSTATUS\") = POI_XPRS_LPSTATUS;\n\tXPRS.attr(\"MIPSTATUS\") = POI_XPRS_MIPSTATUS;\n\tXPRS.attr(\"CUTS\") = POI_XPRS_CUTS;\n\tXPRS.attr(\"NODES\") = POI_XPRS_NODES;\n\tXPRS.attr(\"NODEDEPTH\") = POI_XPRS_NODEDEPTH;\n\tXPRS.attr(\"ACTIVENODES\") = POI_XPRS_ACTIVENODES;\n\tXPRS.attr(\"MIPSOLNODE\") = POI_XPRS_MIPSOLNODE;\n\tXPRS.attr(\"MIPSOLS\") = POI_XPRS_MIPSOLS;\n\tXPRS.attr(\"COLS\") = POI_XPRS_COLS;\n\tXPRS.attr(\"SPAREROWS\") = POI_XPRS_SPAREROWS;\n\tXPRS.attr(\"SPARECOLS\") = POI_XPRS_SPARECOLS;\n\tXPRS.attr(\"SPAREMIPENTS\") = POI_XPRS_SPAREMIPENTS;\n\tXPRS.attr(\"ERRORCODE\") = POI_XPRS_ERRORCODE;\n\tXPRS.attr(\"MIPINFEAS\") = POI_XPRS_MIPINFEAS;\n\tXPRS.attr(\"PRESOLVESTATE\") = POI_XPRS_PRESOLVESTATE;\n\tXPRS.attr(\"PARENTNODE\") = POI_XPRS_PARENTNODE;\n\tXPRS.attr(\"NAMELENGTH\") = POI_XPRS_NAMELENGTH;\n\tXPRS.attr(\"QELEMS\") = POI_XPRS_QELEMS;\n\tXPRS.attr(\"NUMIIS\") = POI_XPRS_NUMIIS;\n\tXPRS.attr(\"MIPENTS\") = POI_XPRS_MIPENTS;\n\tXPRS.attr(\"BRANCHVAR\") = POI_XPRS_BRANCHVAR;\n\tXPRS.attr(\"MIPTHREADID\") = POI_XPRS_MIPTHREADID;\n\tXPRS.attr(\"ALGORITHM\") = POI_XPRS_ALGORITHM;\n\tXPRS.attr(\"CROSSOVERITER\") = POI_XPRS_CROSSOVERITER;\n\tXPRS.attr(\"SOLSTATUS\") = POI_XPRS_SOLSTATUS;\n\tXPRS.attr(\"CUTROUNDS\") = POI_XPRS_CUTROUNDS;\n\tXPRS.attr(\"ORIGINALROWS\") = POI_XPRS_ORIGINALROWS;\n\tXPRS.attr(\"CALLBACKCOUNT_OPTNODE\") = POI_XPRS_CALLBACKCOUNT_OPTNODE;\n\tXPRS.attr(\"ORIGINALQELEMS\") = POI_XPRS_ORIGINALQELEMS;\n\tXPRS.attr(\"MAXPROBNAMELENGTH\") = POI_XPRS_MAXPROBNAMELENGTH;\n\tXPRS.attr(\"STOPSTATUS\") = POI_XPRS_STOPSTATUS;\n\tXPRS.attr(\"ORIGINALMIPENTS\") = POI_XPRS_ORIGINALMIPENTS;\n\tXPRS.attr(\"ORIGINALSETS\") = POI_XPRS_ORIGINALSETS;\n\tXPRS.attr(\"SPARESETS\") = POI_XPRS_SPARESETS;\n\tXPRS.attr(\"CHECKSONMAXTIME\") = POI_XPRS_CHECKSONMAXTIME;\n\tXPRS.attr(\"CHECKSONMAXCUTTIME\") = POI_XPRS_CHECKSONMAXCUTTIME;\n\tXPRS.attr(\"ORIGINALCOLS\") = POI_XPRS_ORIGINALCOLS;\n\tXPRS.attr(\"QCELEMS\") = POI_XPRS_QCELEMS;\n\tXPRS.attr(\"QCONSTRAINTS\") = POI_XPRS_QCONSTRAINTS;\n\tXPRS.attr(\"ORIGINALQCELEMS\") = POI_XPRS_ORIGINALQCELEMS;\n\tXPRS.attr(\"ORIGINALQCONSTRAINTS\") = POI_XPRS_ORIGINALQCONSTRAINTS;\n\tXPRS.attr(\"PEAKTOTALTREEMEMORYUSAGE\") = POI_XPRS_PEAKTOTALTREEMEMORYUSAGE;\n\tXPRS.attr(\"CURRENTNODE\") = POI_XPRS_CURRENTNODE;\n\tXPRS.attr(\"TREEMEMORYUSAGE\") = POI_XPRS_TREEMEMORYUSAGE;\n\tXPRS.attr(\"TREEFILESIZE\") = POI_XPRS_TREEFILESIZE;\n\tXPRS.attr(\"TREEFILEUSAGE\") = POI_XPRS_TREEFILEUSAGE;\n\tXPRS.attr(\"INDICATORS\") = POI_XPRS_INDICATORS;\n\tXPRS.attr(\"ORIGINALINDICATORS\") = POI_XPRS_ORIGINALINDICATORS;\n\tXPRS.attr(\"CORESPERCPUDETECTED\") = POI_XPRS_CORESPERCPUDETECTED;\n\tXPRS.attr(\"CPUSDETECTED\") = POI_XPRS_CPUSDETECTED;\n\tXPRS.attr(\"CORESDETECTED\") = POI_XPRS_CORESDETECTED;\n\tXPRS.attr(\"PHYSICALCORESDETECTED\") = POI_XPRS_PHYSICALCORESDETECTED;\n\tXPRS.attr(\"PHYSICALCORESPERCPUDETECTED\") = POI_XPRS_PHYSICALCORESPERCPUDETECTED;\n\tXPRS.attr(\"OPTIMIZETYPEUSED\") = POI_XPRS_OPTIMIZETYPEUSED;\n\tXPRS.attr(\"BARSING\") = POI_XPRS_BARSING;\n\tXPRS.attr(\"BARSINGR\") = POI_XPRS_BARSINGR;\n\tXPRS.attr(\"PRESOLVEINDEX\") = POI_XPRS_PRESOLVEINDEX;\n\tXPRS.attr(\"CONES\") = POI_XPRS_CONES;\n\tXPRS.attr(\"CONEELEMS\") = POI_XPRS_CONEELEMS;\n\tXPRS.attr(\"PWLCONS\") = POI_XPRS_PWLCONS;\n\tXPRS.attr(\"GENCONS\") = POI_XPRS_GENCONS;\n\tXPRS.attr(\"TREERESTARTS\") = POI_XPRS_TREERESTARTS;\n\tXPRS.attr(\"ORIGINALPWLS\") = POI_XPRS_ORIGINALPWLS;\n\tXPRS.attr(\"ORIGINALGENCONS\") = POI_XPRS_ORIGINALGENCONS;\n\tXPRS.attr(\"COMPUTEEXECUTIONS\") = POI_XPRS_COMPUTEEXECUTIONS;\n\tXPRS.attr(\"RESTARTS\") = POI_XPRS_RESTARTS;\n\tXPRS.attr(\"SOLVESTATUS\") = POI_XPRS_SOLVESTATUS;\n\tXPRS.attr(\"GLOBALBOUNDINGBOXAPPLIED\") = POI_XPRS_GLOBALBOUNDINGBOXAPPLIED;\n\tXPRS.attr(\"OBJECTIVES\") = POI_XPRS_OBJECTIVES;\n\tXPRS.attr(\"SOLVEDOBJS\") = POI_XPRS_SOLVEDOBJS;\n\tXPRS.attr(\"OBJSTOSOLVE\") = POI_XPRS_OBJSTOSOLVE;\n\tXPRS.attr(\"GLOBALNLPINFEAS\") = POI_XPRS_GLOBALNLPINFEAS;\n\tXPRS.attr(\"IISSOLSTATUS\") = POI_XPRS_IISSOLSTATUS;\n\tXPRS.attr(\"INPUTROWS\") = POI_XPRS_INPUTROWS;\n\tXPRS.attr(\"INPUTCOLS\") = POI_XPRS_INPUTCOLS;\n\tXPRS.attr(\"BARITER\") = POI_XPRS_BARITER;\n\tXPRS.attr(\"BARDENSECOL\") = POI_XPRS_BARDENSECOL;\n\tXPRS.attr(\"BARCROSSOVER\") = POI_XPRS_BARCROSSOVER;\n\t/* Integer attributes that support 64-bit values */\n\tXPRS.attr(\"SETMEMBERS\") = POI_XPRS_SETMEMBERS;\n\tXPRS.attr(\"ELEMS\") = POI_XPRS_ELEMS;\n\tXPRS.attr(\"SPAREELEMS\") = POI_XPRS_SPAREELEMS;\n\tXPRS.attr(\"SYSTEMMEMORY\") = POI_XPRS_SYSTEMMEMORY;\n\tXPRS.attr(\"ORIGINALSETMEMBERS\") = POI_XPRS_ORIGINALSETMEMBERS;\n\tXPRS.attr(\"SPARESETELEMS\") = POI_XPRS_SPARESETELEMS;\n\tXPRS.attr(\"CURRENTMEMORY\") = POI_XPRS_CURRENTMEMORY;\n\tXPRS.attr(\"PEAKMEMORY\") = POI_XPRS_PEAKMEMORY;\n\tXPRS.attr(\"TOTALMEMORY\") = POI_XPRS_TOTALMEMORY;\n\tXPRS.attr(\"AVAILABLEMEMORY\") = POI_XPRS_AVAILABLEMEMORY;\n\tXPRS.attr(\"PWLPOINTS\") = POI_XPRS_PWLPOINTS;\n\tXPRS.attr(\"GENCONCOLS\") = POI_XPRS_GENCONCOLS;\n\tXPRS.attr(\"GENCONVALS\") = POI_XPRS_GENCONVALS;\n\tXPRS.attr(\"ORIGINALPWLPOINTS\") = POI_XPRS_ORIGINALPWLPOINTS;\n\tXPRS.attr(\"ORIGINALGENCONCOLS\") = POI_XPRS_ORIGINALGENCONCOLS;\n\tXPRS.attr(\"ORIGINALGENCONVALS\") = POI_XPRS_ORIGINALGENCONVALS;\n\tXPRS.attr(\"MEMORYLIMITDETECTED\") = POI_XPRS_MEMORYLIMITDETECTED;\n\tXPRS.attr(\"BARAASIZE\") = POI_XPRS_BARAASIZE;\n\tXPRS.attr(\"BARLSIZE\") = POI_XPRS_BARLSIZE;\n\n\t// Nonlinear solver related controls and attributes\n\tXPRS.attr(\"NLPFUNCEVAL\") = POI_XPRS_NLPFUNCEVAL;\n\tXPRS.attr(\"NLPLOG\") = POI_XPRS_NLPLOG;\n\tXPRS.attr(\"NLPKEEPEQUALSCOLUMN\") = POI_XPRS_NLPKEEPEQUALSCOLUMN;\n\tXPRS.attr(\"NLPEVALUATE\") = POI_XPRS_NLPEVALUATE;\n\tXPRS.attr(\"NLPPRESOLVE\") = POI_XPRS_NLPPRESOLVE;\n\tXPRS.attr(\"SLPLOG\") = POI_XPRS_SLPLOG;\n\tXPRS.attr(\"LOCALSOLVER\") = POI_XPRS_LOCALSOLVER;\n\tXPRS.attr(\"NLPSTOPOUTOFRANGE\") = POI_XPRS_NLPSTOPOUTOFRANGE;\n\tXPRS.attr(\"NLPTHREADSAFEUSERFUNC\") = POI_XPRS_NLPTHREADSAFEUSERFUNC;\n\tXPRS.attr(\"NLPJACOBIAN\") = POI_XPRS_NLPJACOBIAN;\n\tXPRS.attr(\"NLPHESSIAN\") = POI_XPRS_NLPHESSIAN;\n\tXPRS.attr(\"MULTISTART\") = POI_XPRS_MULTISTART;\n\tXPRS.attr(\"MULTISTART_THREADS\") = POI_XPRS_MULTISTART_THREADS;\n\tXPRS.attr(\"MULTISTART_MAXSOLVES\") = POI_XPRS_MULTISTART_MAXSOLVES;\n\tXPRS.attr(\"MULTISTART_MAXTIME\") = POI_XPRS_MULTISTART_MAXTIME;\n\tXPRS.attr(\"NLPMAXTIME\") = POI_XPRS_NLPMAXTIME;\n\tXPRS.attr(\"NLPDERIVATIVES\") = POI_XPRS_NLPDERIVATIVES;\n\tXPRS.attr(\"NLPREFORMULATE\") = POI_XPRS_NLPREFORMULATE;\n\tXPRS.attr(\"NLPPRESOLVEOPS\") = POI_XPRS_NLPPRESOLVEOPS;\n\tXPRS.attr(\"MULTISTART_LOG\") = POI_XPRS_MULTISTART_LOG;\n\tXPRS.attr(\"MULTISTART_SEED\") = POI_XPRS_MULTISTART_SEED;\n\tXPRS.attr(\"MULTISTART_POOLSIZE\") = POI_XPRS_MULTISTART_POOLSIZE;\n\tXPRS.attr(\"NLPPOSTSOLVE\") = POI_XPRS_NLPPOSTSOLVE;\n\tXPRS.attr(\"NLPDETERMINISTIC\") = POI_XPRS_NLPDETERMINISTIC;\n\tXPRS.attr(\"NLPPRESOLVELEVEL\") = POI_XPRS_NLPPRESOLVELEVEL;\n\tXPRS.attr(\"NLPPROBING\") = POI_XPRS_NLPPROBING;\n\tXPRS.attr(\"NLPCALCTHREADS\") = POI_XPRS_NLPCALCTHREADS;\n\tXPRS.attr(\"NLPTHREADS\") = POI_XPRS_NLPTHREADS;\n\tXPRS.attr(\"NLPFINDIV\") = POI_XPRS_NLPFINDIV;\n\tXPRS.attr(\"NLPLINQUADBR\") = POI_XPRS_NLPLINQUADBR;\n\tXPRS.attr(\"NLPSOLVER\") = POI_XPRS_NLPSOLVER;\n\t// SLP related integer controls\n\tXPRS.attr(\"SLPALGORITHM\") = POI_XPRS_SLPALGORITHM;\n\tXPRS.attr(\"SLPAUGMENTATION\") = POI_XPRS_SLPAUGMENTATION;\n\tXPRS.attr(\"SLPBARLIMIT\") = POI_XPRS_SLPBARLIMIT;\n\tXPRS.attr(\"SLPCASCADE\") = POI_XPRS_SLPCASCADE;\n\tXPRS.attr(\"SLPCASCADENLIMIT\") = POI_XPRS_SLPCASCADENLIMIT;\n\tXPRS.attr(\"SLPDAMPSTART\") = POI_XPRS_SLPDAMPSTART;\n\tXPRS.attr(\"SLPCUTSTRATEGY\") = POI_XPRS_SLPCUTSTRATEGY;\n\tXPRS.attr(\"SLPDELTAZLIMIT\") = POI_XPRS_SLPDELTAZLIMIT;\n\tXPRS.attr(\"SLPINFEASLIMIT\") = POI_XPRS_SLPINFEASLIMIT;\n\tXPRS.attr(\"SLPITERLIMIT\") = POI_XPRS_SLPITERLIMIT;\n\tXPRS.attr(\"SLPSAMECOUNT\") = POI_XPRS_SLPSAMECOUNT;\n\tXPRS.attr(\"SLPSAMEDAMP\") = POI_XPRS_SLPSAMEDAMP;\n\tXPRS.attr(\"SLPSBSTART\") = POI_XPRS_SLPSBSTART;\n\tXPRS.attr(\"SLPXCOUNT\") = POI_XPRS_SLPXCOUNT;\n\tXPRS.attr(\"SLPXLIMIT\") = POI_XPRS_SLPXLIMIT;\n\tXPRS.attr(\"SLPDELAYUPDATEROWS\") = POI_XPRS_SLPDELAYUPDATEROWS;\n\tXPRS.attr(\"SLPAUTOSAVE\") = POI_XPRS_SLPAUTOSAVE;\n\tXPRS.attr(\"SLPANALYZE\") = POI_XPRS_SLPANALYZE;\n\tXPRS.attr(\"SLPOCOUNT\") = POI_XPRS_SLPOCOUNT;\n\tXPRS.attr(\"SLPMIPALGORITHM\") = POI_XPRS_SLPMIPALGORITHM;\n\tXPRS.attr(\"SLPMIPRELAXSTEPBOUNDS\") = POI_XPRS_SLPMIPRELAXSTEPBOUNDS;\n\tXPRS.attr(\"SLPMIPFIXSTEPBOUNDS\") = POI_XPRS_SLPMIPFIXSTEPBOUNDS;\n\tXPRS.attr(\"SLPMIPITERLIMIT\") = POI_XPRS_SLPMIPITERLIMIT;\n\tXPRS.attr(\"SLPMIPCUTOFFLIMIT\") = POI_XPRS_SLPMIPCUTOFFLIMIT;\n\tXPRS.attr(\"SLPMIPOCOUNT\") = POI_XPRS_SLPMIPOCOUNT;\n\tXPRS.attr(\"SLPMIPDEFAULTALGORITHM\") = POI_XPRS_SLPMIPDEFAULTALGORITHM;\n\tXPRS.attr(\"SLPMIPLOG\") = POI_XPRS_SLPMIPLOG;\n\tXPRS.attr(\"SLPDELTAOFFSET\") = POI_XPRS_SLPDELTAOFFSET;\n\tXPRS.attr(\"SLPUPDATEOFFSET\") = POI_XPRS_SLPUPDATEOFFSET;\n\tXPRS.attr(\"SLPERROROFFSET\") = POI_XPRS_SLPERROROFFSET;\n\tXPRS.attr(\"SLPSBROWOFFSET\") = POI_XPRS_SLPSBROWOFFSET;\n\tXPRS.attr(\"SLPVCOUNT\") = POI_XPRS_SLPVCOUNT;\n\tXPRS.attr(\"SLPVLIMIT\") = POI_XPRS_SLPVLIMIT;\n\tXPRS.attr(\"SLPSCALE\") = POI_XPRS_SLPSCALE;\n\tXPRS.attr(\"SLPSCALECOUNT\") = POI_XPRS_SLPSCALECOUNT;\n\tXPRS.attr(\"SLPECFCHECK\") = POI_XPRS_SLPECFCHECK;\n\tXPRS.attr(\"SLPMIPCUTOFFCOUNT\") = POI_XPRS_SLPMIPCUTOFFCOUNT;\n\tXPRS.attr(\"SLPWCOUNT\") = POI_XPRS_SLPWCOUNT;\n\tXPRS.attr(\"SLPUNFINISHEDLIMIT\") = POI_XPRS_SLPUNFINISHEDLIMIT;\n\tXPRS.attr(\"SLPCONVERGENCEOPS\") = POI_XPRS_SLPCONVERGENCEOPS;\n\tXPRS.attr(\"SLPZEROCRITERION\") = POI_XPRS_SLPZEROCRITERION;\n\tXPRS.attr(\"SLPZEROCRITERIONSTART\") = POI_XPRS_SLPZEROCRITERIONSTART;\n\tXPRS.attr(\"SLPZEROCRITERIONCOUNT\") = POI_XPRS_SLPZEROCRITERIONCOUNT;\n\tXPRS.attr(\"SLPLSPATTERNLIMIT\") = POI_XPRS_SLPLSPATTERNLIMIT;\n\tXPRS.attr(\"SLPLSITERLIMIT\") = POI_XPRS_SLPLSITERLIMIT;\n\tXPRS.attr(\"SLPLSSTART\") = POI_XPRS_SLPLSSTART;\n\tXPRS.attr(\"SLPPENALTYINFOSTART\") = POI_XPRS_SLPPENALTYINFOSTART;\n\tXPRS.attr(\"SLPFILTER\") = POI_XPRS_SLPFILTER;\n\tXPRS.attr(\"SLPTRACEMASKOPS\") = POI_XPRS_SLPTRACEMASKOPS;\n\tXPRS.attr(\"SLPLSZEROLIMIT\") = POI_XPRS_SLPLSZEROLIMIT;\n\tXPRS.attr(\"SLPHEURSTRATEGY\") = POI_XPRS_SLPHEURSTRATEGY;\n\tXPRS.attr(\"SLPBARCROSSOVERSTART\") = POI_XPRS_SLPBARCROSSOVERSTART;\n\tXPRS.attr(\"SLPBARSTALLINGLIMIT\") = POI_XPRS_SLPBARSTALLINGLIMIT;\n\tXPRS.attr(\"SLPBARSTALLINGOBJLIMIT\") = POI_XPRS_SLPBARSTALLINGOBJLIMIT;\n\tXPRS.attr(\"SLPBARSTARTOPS\") = POI_XPRS_SLPBARSTARTOPS;\n\tXPRS.attr(\"SLPGRIDHEURSELECT\") = POI_XPRS_SLPGRIDHEURSELECT;\n\t// Nonlinear related double controls\n\tXPRS.attr(\"NLPINFINITY\") = POI_XPRS_NLPINFINITY;\n\tXPRS.attr(\"NLPZERO\") = POI_XPRS_NLPZERO;\n\tXPRS.attr(\"NLPDEFAULTIV\") = POI_XPRS_NLPDEFAULTIV;\n\tXPRS.attr(\"NLPOPTTIME\") = POI_XPRS_NLPOPTTIME;\n\tXPRS.attr(\"NLPVALIDATIONTOL_A\") = POI_XPRS_NLPVALIDATIONTOL_A;\n\tXPRS.attr(\"NLPVALIDATIONTOL_R\") = POI_XPRS_NLPVALIDATIONTOL_R;\n\tXPRS.attr(\"NLPVALIDATIONINDEX_A\") = POI_XPRS_NLPVALIDATIONINDEX_A;\n\tXPRS.attr(\"NLPVALIDATIONINDEX_R\") = POI_XPRS_NLPVALIDATIONINDEX_R;\n\tXPRS.attr(\"NLPPRIMALINTEGRALREF\") = POI_XPRS_NLPPRIMALINTEGRALREF;\n\tXPRS.attr(\"NLPPRIMALINTEGRALALPHA\") = POI_XPRS_NLPPRIMALINTEGRALALPHA;\n\tXPRS.attr(\"NLPOBJVAL\") = POI_XPRS_NLPOBJVAL;\n\tXPRS.attr(\"NLPPRESOLVEZERO\") = POI_XPRS_NLPPRESOLVEZERO;\n\tXPRS.attr(\"NLPMERITLAMBDA\") = POI_XPRS_NLPMERITLAMBDA;\n\tXPRS.attr(\"MSMAXBOUNDRANGE\") = POI_XPRS_MSMAXBOUNDRANGE;\n\tXPRS.attr(\"NLPVALIDATIONTOL_K\") = POI_XPRS_NLPVALIDATIONTOL_K;\n\tXPRS.attr(\"NLPPRESOLVE_ELIMTOL\") = POI_XPRS_NLPPRESOLVE_ELIMTOL;\n\tXPRS.attr(\"NLPVALIDATIONTARGET_R\") = POI_XPRS_NLPVALIDATIONTARGET_R;\n\tXPRS.attr(\"NLPVALIDATIONTARGET_K\") = POI_XPRS_NLPVALIDATIONTARGET_K;\n\tXPRS.attr(\"NLPVALIDATIONFACTOR\") = POI_XPRS_NLPVALIDATIONFACTOR;\n\tXPRS.attr(\"NLPRELTOLBOUNDTHRESHOLD\") = POI_XPRS_NLPRELTOLBOUNDTHRESHOLD;\n\t// SLP related double controls\n\tXPRS.attr(\"SLPDAMP\") = POI_XPRS_SLPDAMP;\n\tXPRS.attr(\"SLPDAMPEXPAND\") = POI_XPRS_SLPDAMPEXPAND;\n\tXPRS.attr(\"SLPDAMPSHRINK\") = POI_XPRS_SLPDAMPSHRINK;\n\tXPRS.attr(\"SLPDELTA_A\") = POI_XPRS_SLPDELTA_A;\n\tXPRS.attr(\"SLPDELTA_R\") = POI_XPRS_SLPDELTA_R;\n\tXPRS.attr(\"SLPDELTA_Z\") = POI_XPRS_SLPDELTA_Z;\n\tXPRS.attr(\"SLPDELTACOST\") = POI_XPRS_SLPDELTACOST;\n\tXPRS.attr(\"SLPDELTAMAXCOST\") = POI_XPRS_SLPDELTAMAXCOST;\n\tXPRS.attr(\"SLPDJTOL\") = POI_XPRS_SLPDJTOL;\n\tXPRS.attr(\"SLPERRORCOST\") = POI_XPRS_SLPERRORCOST;\n\tXPRS.attr(\"SLPERRORMAXCOST\") = POI_XPRS_SLPERRORMAXCOST;\n\tXPRS.attr(\"SLPERRORTOL_A\") = POI_XPRS_SLPERRORTOL_A;\n\tXPRS.attr(\"SLPEXPAND\") = POI_XPRS_SLPEXPAND;\n\tXPRS.attr(\"SLPMAXWEIGHT\") = POI_XPRS_SLPMAXWEIGHT;\n\tXPRS.attr(\"SLPMINWEIGHT\") = POI_XPRS_SLPMINWEIGHT;\n\tXPRS.attr(\"SLPSHRINK\") = POI_XPRS_SLPSHRINK;\n\tXPRS.attr(\"SLPCTOL\") = POI_XPRS_SLPCTOL;\n\tXPRS.attr(\"SLPATOL_A\") = POI_XPRS_SLPATOL_A;\n\tXPRS.attr(\"SLPATOL_R\") = POI_XPRS_SLPATOL_R;\n\tXPRS.attr(\"SLPMTOL_A\") = POI_XPRS_SLPMTOL_A;\n\tXPRS.attr(\"SLPMTOL_R\") = POI_XPRS_SLPMTOL_R;\n\tXPRS.attr(\"SLPITOL_A\") = POI_XPRS_SLPITOL_A;\n\tXPRS.attr(\"SLPITOL_R\") = POI_XPRS_SLPITOL_R;\n\tXPRS.attr(\"SLPSTOL_A\") = POI_XPRS_SLPSTOL_A;\n\tXPRS.attr(\"SLPSTOL_R\") = POI_XPRS_SLPSTOL_R;\n\tXPRS.attr(\"SLPMVTOL\") = POI_XPRS_SLPMVTOL;\n\tXPRS.attr(\"SLPXTOL_A\") = POI_XPRS_SLPXTOL_A;\n\tXPRS.attr(\"SLPXTOL_R\") = POI_XPRS_SLPXTOL_R;\n\tXPRS.attr(\"SLPDEFAULTSTEPBOUND\") = POI_XPRS_SLPDEFAULTSTEPBOUND;\n\tXPRS.attr(\"SLPDAMPMAX\") = POI_XPRS_SLPDAMPMAX;\n\tXPRS.attr(\"SLPDAMPMIN\") = POI_XPRS_SLPDAMPMIN;\n\tXPRS.attr(\"SLPDELTACOSTFACTOR\") = POI_XPRS_SLPDELTACOSTFACTOR;\n\tXPRS.attr(\"SLPERRORCOSTFACTOR\") = POI_XPRS_SLPERRORCOSTFACTOR;\n\tXPRS.attr(\"SLPERRORTOL_P\") = POI_XPRS_SLPERRORTOL_P;\n\tXPRS.attr(\"SLPCASCADETOL_PA\") = POI_XPRS_SLPCASCADETOL_PA;\n\tXPRS.attr(\"SLPCASCADETOL_PR\") = POI_XPRS_SLPCASCADETOL_PR;\n\tXPRS.attr(\"SLPCASCADETOL_Z\") = POI_XPRS_SLPCASCADETOL_Z;\n\tXPRS.attr(\"SLPOTOL_A\") = POI_XPRS_SLPOTOL_A;\n\tXPRS.attr(\"SLPOTOL_R\") = POI_XPRS_SLPOTOL_R;\n\tXPRS.attr(\"SLPDELTA_X\") = POI_XPRS_SLPDELTA_X;\n\tXPRS.attr(\"SLPERRORCOSTS\") = POI_XPRS_SLPERRORCOSTS;\n\tXPRS.attr(\"SLPGRANULARITY\") = POI_XPRS_SLPGRANULARITY;\n\tXPRS.attr(\"SLPMIPCUTOFF_A\") = POI_XPRS_SLPMIPCUTOFF_A;\n\tXPRS.attr(\"SLPMIPCUTOFF_R\") = POI_XPRS_SLPMIPCUTOFF_R;\n\tXPRS.attr(\"SLPMIPOTOL_A\") = POI_XPRS_SLPMIPOTOL_A;\n\tXPRS.attr(\"SLPMIPOTOL_R\") = POI_XPRS_SLPMIPOTOL_R;\n\tXPRS.attr(\"SLPESCALATION\") = POI_XPRS_SLPESCALATION;\n\tXPRS.attr(\"SLPOBJTOPENALTYCOST\") = POI_XPRS_SLPOBJTOPENALTYCOST;\n\tXPRS.attr(\"SLPSHRINKBIAS\") = POI_XPRS_SLPSHRINKBIAS;\n\tXPRS.attr(\"SLPFEASTOLTARGET\") = POI_XPRS_SLPFEASTOLTARGET;\n\tXPRS.attr(\"SLPOPTIMALITYTOLTARGET\") = POI_XPRS_SLPOPTIMALITYTOLTARGET;\n\tXPRS.attr(\"SLPDELTA_INFINITY\") = POI_XPRS_SLPDELTA_INFINITY;\n\tXPRS.attr(\"SLPVTOL_A\") = POI_XPRS_SLPVTOL_A;\n\tXPRS.attr(\"SLPVTOL_R\") = POI_XPRS_SLPVTOL_R;\n\tXPRS.attr(\"SLPETOL_A\") = POI_XPRS_SLPETOL_A;\n\tXPRS.attr(\"SLPETOL_R\") = POI_XPRS_SLPETOL_R;\n\tXPRS.attr(\"SLPEVTOL_A\") = POI_XPRS_SLPEVTOL_A;\n\tXPRS.attr(\"SLPEVTOL_R\") = POI_XPRS_SLPEVTOL_R;\n\tXPRS.attr(\"SLPDELTA_ZERO\") = POI_XPRS_SLPDELTA_ZERO;\n\tXPRS.attr(\"SLPMINSBFACTOR\") = POI_XPRS_SLPMINSBFACTOR;\n\tXPRS.attr(\"SLPCLAMPVALIDATIONTOL_A\") = POI_XPRS_SLPCLAMPVALIDATIONTOL_A;\n\tXPRS.attr(\"SLPCLAMPVALIDATIONTOL_R\") = POI_XPRS_SLPCLAMPVALIDATIONTOL_R;\n\tXPRS.attr(\"SLPCLAMPSHRINK\") = POI_XPRS_SLPCLAMPSHRINK;\n\tXPRS.attr(\"SLPECFTOL_A\") = POI_XPRS_SLPECFTOL_A;\n\tXPRS.attr(\"SLPECFTOL_R\") = POI_XPRS_SLPECFTOL_R;\n\tXPRS.attr(\"SLPWTOL_A\") = POI_XPRS_SLPWTOL_A;\n\tXPRS.attr(\"SLPWTOL_R\") = POI_XPRS_SLPWTOL_R;\n\tXPRS.attr(\"SLPMATRIXTOL\") = POI_XPRS_SLPMATRIXTOL;\n\tXPRS.attr(\"SLPDRFIXRANGE\") = POI_XPRS_SLPDRFIXRANGE;\n\tXPRS.attr(\"SLPDRCOLTOL\") = POI_XPRS_SLPDRCOLTOL;\n\tXPRS.attr(\"SLPMIPERRORTOL_A\") = POI_XPRS_SLPMIPERRORTOL_A;\n\tXPRS.attr(\"SLPMIPERRORTOL_R\") = POI_XPRS_SLPMIPERRORTOL_R;\n\tXPRS.attr(\"SLPCDTOL_A\") = POI_XPRS_SLPCDTOL_A;\n\tXPRS.attr(\"SLPCDTOL_R\") = POI_XPRS_SLPCDTOL_R;\n\tXPRS.attr(\"SLPENFORCEMAXCOST\") = POI_XPRS_SLPENFORCEMAXCOST;\n\tXPRS.attr(\"SLPENFORCECOSTSHRINK\") = POI_XPRS_SLPENFORCECOSTSHRINK;\n\tXPRS.attr(\"SLPDRCOLDJTOL\") = POI_XPRS_SLPDRCOLDJTOL;\n\tXPRS.attr(\"SLPBARSTALLINGTOL\") = POI_XPRS_SLPBARSTALLINGTOL;\n\tXPRS.attr(\"SLPOBJTHRESHOLD\") = POI_XPRS_SLPOBJTHRESHOLD;\n\tXPRS.attr(\"SLPBOUNDTHRESHOLD\") = POI_XPRS_SLPBOUNDTHRESHOLD;\n\t// Nonlinear related string controls\n\tXPRS.attr(\"NLPIVNAME\") = POI_XPRS_NLPIVNAME;\n\t// SLP related string controls\n\tXPRS.attr(\"SLPDELTAFORMAT\") = POI_XPRS_SLPDELTAFORMAT;\n\tXPRS.attr(\"SLPMINUSDELTAFORMAT\") = POI_XPRS_SLPMINUSDELTAFORMAT;\n\tXPRS.attr(\"SLPMINUSERRORFORMAT\") = POI_XPRS_SLPMINUSERRORFORMAT;\n\tXPRS.attr(\"SLPPLUSDELTAFORMAT\") = POI_XPRS_SLPPLUSDELTAFORMAT;\n\tXPRS.attr(\"SLPPLUSERRORFORMAT\") = POI_XPRS_SLPPLUSERRORFORMAT;\n\tXPRS.attr(\"SLPSBNAME\") = POI_XPRS_SLPSBNAME;\n\tXPRS.attr(\"SLPTOLNAME\") = POI_XPRS_SLPTOLNAME;\n\tXPRS.attr(\"SLPUPDATEFORMAT\") = POI_XPRS_SLPUPDATEFORMAT;\n\tXPRS.attr(\"SLPPENALTYROWFORMAT\") = POI_XPRS_SLPPENALTYROWFORMAT;\n\tXPRS.attr(\"SLPPENALTYCOLFORMAT\") = POI_XPRS_SLPPENALTYCOLFORMAT;\n\tXPRS.attr(\"SLPSBLOROWFORMAT\") = POI_XPRS_SLPSBLOROWFORMAT;\n\tXPRS.attr(\"SLPSBUPROWFORMAT\") = POI_XPRS_SLPSBUPROWFORMAT;\n\tXPRS.attr(\"SLPTRACEMASK\") = POI_XPRS_SLPTRACEMASK;\n\tXPRS.attr(\"SLPITERFALLBACKOPS\") = POI_XPRS_SLPITERFALLBACKOPS;\n\t// Nonlinear related integer attributes\n\tXPRS.attr(\"NLPVALIDATIONSTATUS\") = POI_XPRS_NLPVALIDATIONSTATUS;\n\tXPRS.attr(\"NLPSOLSTATUS\") = POI_XPRS_NLPSOLSTATUS;\n\tXPRS.attr(\"NLPORIGINALROWS\") = POI_XPRS_NLPORIGINALROWS;\n\tXPRS.attr(\"NLPORIGINALCOLS\") = POI_XPRS_NLPORIGINALCOLS;\n\tXPRS.attr(\"NLPUFS\") = POI_XPRS_NLPUFS;\n\tXPRS.attr(\"NLPIFS\") = POI_XPRS_NLPIFS;\n\tXPRS.attr(\"NLPEQUALSCOLUMN\") = POI_XPRS_NLPEQUALSCOLUMN;\n\tXPRS.attr(\"NLPVARIABLES\") = POI_XPRS_NLPVARIABLES;\n\tXPRS.attr(\"NLPIMPLICITVARIABLES\") = POI_XPRS_NLPIMPLICITVARIABLES;\n\tXPRS.attr(\"NONLINEARCONSTRAINTS\") = POI_XPRS_NONLINEARCONSTRAINTS;\n\tXPRS.attr(\"NLPUSERFUNCCALLS\") = POI_XPRS_NLPUSERFUNCCALLS;\n\tXPRS.attr(\"NLPUSEDERIVATIVES\") = POI_XPRS_NLPUSEDERIVATIVES;\n\tXPRS.attr(\"NLPKEEPBESTITER\") = POI_XPRS_NLPKEEPBESTITER;\n\tXPRS.attr(\"NLPSTATUS\") = POI_XPRS_NLPSTATUS;\n\tXPRS.attr(\"LOCALSOLVERSELECTED\") = POI_XPRS_LOCALSOLVERSELECTED;\n\tXPRS.attr(\"NLPMODELROWS\") = POI_XPRS_NLPMODELROWS;\n\tXPRS.attr(\"NLPMODELCOLS\") = POI_XPRS_NLPMODELCOLS;\n\tXPRS.attr(\"NLPJOBID\") = POI_XPRS_NLPJOBID;\n\tXPRS.attr(\"MSJOBS\") = POI_XPRS_MSJOBS;\n\tXPRS.attr(\"NLPSTOPSTATUS\") = POI_XPRS_NLPSTOPSTATUS;\n\tXPRS.attr(\"NLPPRESOLVEELIMINATIONS\") = POI_XPRS_NLPPRESOLVEELIMINATIONS;\n\tXPRS.attr(\"NLPTOTALEVALUATIONERRORS\") = POI_XPRS_NLPTOTALEVALUATIONERRORS;\n\t// SLP related integer attributes\n\tXPRS.attr(\"SLPEXPLOREDELTAS\") = POI_XPRS_SLPEXPLOREDELTAS;\n\tXPRS.attr(\"SLPSEMICONTDELTAS\") = POI_XPRS_SLPSEMICONTDELTAS;\n\tXPRS.attr(\"SLPINTEGERDELTAS\") = POI_XPRS_SLPINTEGERDELTAS;\n\tXPRS.attr(\"SLPITER\") = POI_XPRS_SLPITER;\n\tXPRS.attr(\"SLPSTATUS\") = POI_XPRS_SLPSTATUS;\n\tXPRS.attr(\"SLPUNCONVERGED\") = POI_XPRS_SLPUNCONVERGED;\n\tXPRS.attr(\"SLPSBXCONVERGED\") = POI_XPRS_SLPSBXCONVERGED;\n\tXPRS.attr(\"SLPPENALTYDELTAROW\") = POI_XPRS_SLPPENALTYDELTAROW;\n\tXPRS.attr(\"SLPPENALTYDELTACOLUMN\") = POI_XPRS_SLPPENALTYDELTACOLUMN;\n\tXPRS.attr(\"SLPPENALTYERRORROW\") = POI_XPRS_SLPPENALTYERRORROW;\n\tXPRS.attr(\"SLPPENALTYERRORCOLUMN\") = POI_XPRS_SLPPENALTYERRORCOLUMN;\n\tXPRS.attr(\"SLPCOEFFICIENTS\") = POI_XPRS_SLPCOEFFICIENTS;\n\tXPRS.attr(\"SLPPENALTYDELTAS\") = POI_XPRS_SLPPENALTYDELTAS;\n\tXPRS.attr(\"SLPPENALTYERRORS\") = POI_XPRS_SLPPENALTYERRORS;\n\tXPRS.attr(\"SLPPLUSPENALTYERRORS\") = POI_XPRS_SLPPLUSPENALTYERRORS;\n\tXPRS.attr(\"SLPMINUSPENALTYERRORS\") = POI_XPRS_SLPMINUSPENALTYERRORS;\n\tXPRS.attr(\"SLPUCCONSTRAINEDCOUNT\") = POI_XPRS_SLPUCCONSTRAINEDCOUNT;\n\tXPRS.attr(\"SLPMIPNODES\") = POI_XPRS_SLPMIPNODES;\n\tXPRS.attr(\"SLPMIPITER\") = POI_XPRS_SLPMIPITER;\n\tXPRS.attr(\"SLPTOLSETS\") = POI_XPRS_SLPTOLSETS;\n\tXPRS.attr(\"SLPECFCOUNT\") = POI_XPRS_SLPECFCOUNT;\n\tXPRS.attr(\"SLPDELTAS\") = POI_XPRS_SLPDELTAS;\n\tXPRS.attr(\"SLPZEROESRESET\") = POI_XPRS_SLPZEROESRESET;\n\tXPRS.attr(\"SLPZEROESTOTAL\") = POI_XPRS_SLPZEROESTOTAL;\n\tXPRS.attr(\"SLPZEROESRETAINED\") = POI_XPRS_SLPZEROESRETAINED;\n\tXPRS.attr(\"SLPNONCONSTANTCOEFFS\") = POI_XPRS_SLPNONCONSTANTCOEFFS;\n\tXPRS.attr(\"SLPMIPSOLS\") = POI_XPRS_SLPMIPSOLS;\n\t// Nonlinear related double attributes\n\tXPRS.attr(\"NLPVALIDATIONINDEX_K\") = POI_XPRS_NLPVALIDATIONINDEX_K;\n\tXPRS.attr(\"NLPVALIDATIONNETOBJ\") = POI_XPRS_NLPVALIDATIONNETOBJ;\n\tXPRS.attr(\"NLPPRIMALINTEGRAL\") = POI_XPRS_NLPPRIMALINTEGRAL;\n\t// SLP related double attributes\n\tXPRS.attr(\"SLPCURRENTDELTACOST\") = POI_XPRS_SLPCURRENTDELTACOST;\n\tXPRS.attr(\"SLPCURRENTERRORCOST\") = POI_XPRS_SLPCURRENTERRORCOST;\n\tXPRS.attr(\"SLPPENALTYERRORTOTAL\") = POI_XPRS_SLPPENALTYERRORTOTAL;\n\tXPRS.attr(\"SLPPENALTYERRORVALUE\") = POI_XPRS_SLPPENALTYERRORVALUE;\n\tXPRS.attr(\"SLPPENALTYDELTATOTAL\") = POI_XPRS_SLPPENALTYDELTATOTAL;\n\tXPRS.attr(\"SLPPENALTYDELTAVALUE\") = POI_XPRS_SLPPENALTYDELTAVALUE;\n\t// Nonlinear related string attributes\n\t// SLP related string attributes\n\t// Knitro's parameters\n\tXPRS.attr(\"KNITRO_PARAM_NEWPOINT\") = POI_XPRS_KNITRO_PARAM_NEWPOINT;\n\tXPRS.attr(\"KNITRO_PARAM_HONORBNDS\") = POI_XPRS_KNITRO_PARAM_HONORBNDS;\n\tXPRS.attr(\"KNITRO_PARAM_ALGORITHM\") = POI_XPRS_KNITRO_PARAM_ALGORITHM;\n\tXPRS.attr(\"KNITRO_PARAM_BAR_MURULE\") = POI_XPRS_KNITRO_PARAM_BAR_MURULE;\n\tXPRS.attr(\"KNITRO_PARAM_BAR_FEASIBLE\") = POI_XPRS_KNITRO_PARAM_BAR_FEASIBLE;\n\tXPRS.attr(\"KNITRO_PARAM_GRADOPT\") = POI_XPRS_KNITRO_PARAM_GRADOPT;\n\tXPRS.attr(\"KNITRO_PARAM_HESSOPT\") = POI_XPRS_KNITRO_PARAM_HESSOPT;\n\tXPRS.attr(\"KNITRO_PARAM_BAR_INITPT\") = POI_XPRS_KNITRO_PARAM_BAR_INITPT;\n\tXPRS.attr(\"KNITRO_PARAM_MAXCGIT\") = POI_XPRS_KNITRO_PARAM_MAXCGIT;\n\tXPRS.attr(\"KNITRO_PARAM_MAXIT\") = POI_XPRS_KNITRO_PARAM_MAXIT;\n\tXPRS.attr(\"KNITRO_PARAM_OUTLEV\") = POI_XPRS_KNITRO_PARAM_OUTLEV;\n\tXPRS.attr(\"KNITRO_PARAM_SCALE\") = POI_XPRS_KNITRO_PARAM_SCALE;\n\tXPRS.attr(\"KNITRO_PARAM_SOC\") = POI_XPRS_KNITRO_PARAM_SOC;\n\tXPRS.attr(\"KNITRO_PARAM_DELTA\") = POI_XPRS_KNITRO_PARAM_DELTA;\n\tXPRS.attr(\"KNITRO_PARAM_BAR_FEASMODETOL\") = POI_XPRS_KNITRO_PARAM_BAR_FEASMODETOL;\n\tXPRS.attr(\"KNITRO_PARAM_FEASTOL\") = POI_XPRS_KNITRO_PARAM_FEASTOL;\n\tXPRS.attr(\"KNITRO_PARAM_FEASTOLABS\") = POI_XPRS_KNITRO_PARAM_FEASTOLABS;\n\tXPRS.attr(\"KNITRO_PARAM_BAR_INITMU\") = POI_XPRS_KNITRO_PARAM_BAR_INITMU;\n\tXPRS.attr(\"KNITRO_PARAM_OBJRANGE\") = POI_XPRS_KNITRO_PARAM_OBJRANGE;\n\tXPRS.attr(\"KNITRO_PARAM_OPTTOL\") = POI_XPRS_KNITRO_PARAM_OPTTOL;\n\tXPRS.attr(\"KNITRO_PARAM_OPTTOLABS\") = POI_XPRS_KNITRO_PARAM_OPTTOLABS;\n\tXPRS.attr(\"KNITRO_PARAM_PIVOT\") = POI_XPRS_KNITRO_PARAM_PIVOT;\n\tXPRS.attr(\"KNITRO_PARAM_XTOL\") = POI_XPRS_KNITRO_PARAM_XTOL;\n\tXPRS.attr(\"KNITRO_PARAM_DEBUG\") = POI_XPRS_KNITRO_PARAM_DEBUG;\n\tXPRS.attr(\"KNITRO_PARAM_MULTISTART\") = POI_XPRS_KNITRO_PARAM_MULTISTART;\n\tXPRS.attr(\"KNITRO_PARAM_MSMAXSOLVES\") = POI_XPRS_KNITRO_PARAM_MSMAXSOLVES;\n\tXPRS.attr(\"KNITRO_PARAM_MSMAXBNDRANGE\") = POI_XPRS_KNITRO_PARAM_MSMAXBNDRANGE;\n\tXPRS.attr(\"KNITRO_PARAM_LMSIZE\") = POI_XPRS_KNITRO_PARAM_LMSIZE;\n\tXPRS.attr(\"KNITRO_PARAM_BAR_MAXCROSSIT\") = POI_XPRS_KNITRO_PARAM_BAR_MAXCROSSIT;\n\tXPRS.attr(\"KNITRO_PARAM_BLASOPTION\") = POI_XPRS_KNITRO_PARAM_BLASOPTION;\n\tXPRS.attr(\"KNITRO_PARAM_BAR_MAXREFACTOR\") = POI_XPRS_KNITRO_PARAM_BAR_MAXREFACTOR;\n\tXPRS.attr(\"KNITRO_PARAM_BAR_MAXBACKTRACK\") = POI_XPRS_KNITRO_PARAM_BAR_MAXBACKTRACK;\n\tXPRS.attr(\"KNITRO_PARAM_BAR_PENRULE\") = POI_XPRS_KNITRO_PARAM_BAR_PENRULE;\n\tXPRS.attr(\"KNITRO_PARAM_BAR_PENCONS\") = POI_XPRS_KNITRO_PARAM_BAR_PENCONS;\n\tXPRS.attr(\"KNITRO_PARAM_MSNUMTOSAVE\") = POI_XPRS_KNITRO_PARAM_MSNUMTOSAVE;\n\tXPRS.attr(\"KNITRO_PARAM_MSSAVETOL\") = POI_XPRS_KNITRO_PARAM_MSSAVETOL;\n\tXPRS.attr(\"KNITRO_PARAM_MSTERMINATE\") = POI_XPRS_KNITRO_PARAM_MSTERMINATE;\n\tXPRS.attr(\"KNITRO_PARAM_MSSTARTPTRANGE\") = POI_XPRS_KNITRO_PARAM_MSSTARTPTRANGE;\n\tXPRS.attr(\"KNITRO_PARAM_INFEASTOL\") = POI_XPRS_KNITRO_PARAM_INFEASTOL;\n\tXPRS.attr(\"KNITRO_PARAM_LINSOLVER\") = POI_XPRS_KNITRO_PARAM_LINSOLVER;\n\tXPRS.attr(\"KNITRO_PARAM_BAR_DIRECTINTERVAL\") = POI_XPRS_KNITRO_PARAM_BAR_DIRECTINTERVAL;\n\tXPRS.attr(\"KNITRO_PARAM_PRESOLVE\") = POI_XPRS_KNITRO_PARAM_PRESOLVE;\n\tXPRS.attr(\"KNITRO_PARAM_PRESOLVE_TOL\") = POI_XPRS_KNITRO_PARAM_PRESOLVE_TOL;\n\tXPRS.attr(\"KNITRO_PARAM_BAR_SWITCHRULE\") = POI_XPRS_KNITRO_PARAM_BAR_SWITCHRULE;\n\tXPRS.attr(\"KNITRO_PARAM_MA_TERMINATE\") = POI_XPRS_KNITRO_PARAM_MA_TERMINATE;\n\tXPRS.attr(\"KNITRO_PARAM_MSSEED\") = POI_XPRS_KNITRO_PARAM_MSSEED;\n\tXPRS.attr(\"KNITRO_PARAM_BAR_RELAXCONS\") = POI_XPRS_KNITRO_PARAM_BAR_RELAXCONS;\n\tXPRS.attr(\"KNITRO_PARAM_SOLTYPE\") = POI_XPRS_KNITRO_PARAM_SOLTYPE;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_METHOD\") = POI_XPRS_KNITRO_PARAM_MIP_METHOD;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_BRANCHRULE\") = POI_XPRS_KNITRO_PARAM_MIP_BRANCHRULE;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_SELECTRULE\") = POI_XPRS_KNITRO_PARAM_MIP_SELECTRULE;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_INTGAPABS\") = POI_XPRS_KNITRO_PARAM_MIP_INTGAPABS;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_INTGAPREL\") = POI_XPRS_KNITRO_PARAM_MIP_INTGAPREL;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_OUTLEVEL\") = POI_XPRS_KNITRO_PARAM_MIP_OUTLEVEL;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_OUTINTERVAL\") = POI_XPRS_KNITRO_PARAM_MIP_OUTINTERVAL;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_DEBUG\") = POI_XPRS_KNITRO_PARAM_MIP_DEBUG;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_IMPLICATNS\") = POI_XPRS_KNITRO_PARAM_MIP_IMPLICATNS;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_GUB_BRANCH\") = POI_XPRS_KNITRO_PARAM_MIP_GUB_BRANCH;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_KNAPSACK\") = POI_XPRS_KNITRO_PARAM_MIP_KNAPSACK;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_ROUNDING\") = POI_XPRS_KNITRO_PARAM_MIP_ROUNDING;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_ROOTALG\") = POI_XPRS_KNITRO_PARAM_MIP_ROOTALG;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_LPALG\") = POI_XPRS_KNITRO_PARAM_MIP_LPALG;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_MAXNODES\") = POI_XPRS_KNITRO_PARAM_MIP_MAXNODES;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_HEURISTIC\") = POI_XPRS_KNITRO_PARAM_MIP_HEURISTIC;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_HEUR_MAXIT\") = POI_XPRS_KNITRO_PARAM_MIP_HEUR_MAXIT;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_PSEUDOINIT\") = POI_XPRS_KNITRO_PARAM_MIP_PSEUDOINIT;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_STRONG_MAXIT\") = POI_XPRS_KNITRO_PARAM_MIP_STRONG_MAXIT;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_STRONG_CANDLIM\") = POI_XPRS_KNITRO_PARAM_MIP_STRONG_CANDLIM;\n\tXPRS.attr(\"KNITRO_PARAM_MIP_STRONG_LEVEL\") = POI_XPRS_KNITRO_PARAM_MIP_STRONG_LEVEL;\n\tXPRS.attr(\"KNITRO_PARAM_PAR_NUMTHREADS\") = POI_XPRS_KNITRO_PARAM_PAR_NUMTHREADS;\n\n\tnb::enum_<SOLSTATUS>(XPRS, \"SOLSTATUS\")\n\t    .value(\"NOTFOUND\", SOLSTATUS::NOTFOUND)\n\t    .value(\"OPTIMAL\", SOLSTATUS::OPTIMAL)\n\t    .value(\"FEASIBLE\", SOLSTATUS::FEASIBLE)\n\t    .value(\"INFEASIBLE\", SOLSTATUS::INFEASIBLE)\n\t    .value(\"UNBOUNDED\", SOLSTATUS::UNBOUNDED);\n\n\tnb::enum_<SOLVESTATUS>(XPRS, \"SOLVESTATUS\")\n\t    .value(\"UNSTARTED\", SOLVESTATUS::UNSTARTED)\n\t    .value(\"STOPPED\", SOLVESTATUS::STOPPED)\n\t    .value(\"FAILED\", SOLVESTATUS::FAILED)\n\t    .value(\"COMPLETED\", SOLVESTATUS::COMPLETED);\n\n\tnb::enum_<LPSTATUS>(XPRS, \"LPSTATUS\")\n\t    .value(\"UNSTARTED\", LPSTATUS::UNSTARTED)\n\t    .value(\"OPTIMAL\", LPSTATUS::OPTIMAL)\n\t    .value(\"INFEAS\", LPSTATUS::INFEAS)\n\t    .value(\"CUTOFF\", LPSTATUS::CUTOFF)\n\t    .value(\"UNFINISHED\", LPSTATUS::UNFINISHED)\n\t    .value(\"UNBOUNDED\", LPSTATUS::UNBOUNDED)\n\t    .value(\"CUTOFF_IN_DUAL\", LPSTATUS::CUTOFF_IN_DUAL)\n\t    .value(\"UNSOLVED\", LPSTATUS::UNSOLVED)\n\t    .value(\"NONCONVEX\", LPSTATUS::NONCONVEX);\n\n\tnb::enum_<MIPSTATUS>(XPRS, \"MIPSTATUS\")\n\t    .value(\"NOT_LOADED\", MIPSTATUS::NOT_LOADED)\n\t    .value(\"LP_NOT_OPTIMAL\", MIPSTATUS::LP_NOT_OPTIMAL)\n\t    .value(\"LP_OPTIMAL\", MIPSTATUS::LP_OPTIMAL)\n\t    .value(\"NO_SOL_FOUND\", MIPSTATUS::NO_SOL_FOUND)\n\t    .value(\"SOLUTION\", MIPSTATUS::SOLUTION)\n\t    .value(\"INFEAS\", MIPSTATUS::INFEAS)\n\t    .value(\"OPTIMAL\", MIPSTATUS::OPTIMAL)\n\t    .value(\"UNBOUNDED\", MIPSTATUS::UNBOUNDED);\n\n\tnb::enum_<NLPSTATUS>(XPRS, \"NLPSTATUS\")\n\t    .value(\"UNSTARTED\", NLPSTATUS::UNSTARTED)\n\t    .value(\"SOLUTION\", NLPSTATUS::SOLUTION)\n\t    .value(\"LOCALLY_OPTIMAL\", NLPSTATUS::LOCALLY_OPTIMAL)\n\t    .value(\"OPTIMAL\", NLPSTATUS::OPTIMAL)\n\t    .value(\"NOSOLUTION\", NLPSTATUS::NOSOLUTION)\n\t    .value(\"LOCALLY_INFEASIBLE\", NLPSTATUS::LOCALLY_INFEASIBLE)\n\t    .value(\"INFEASIBLE\", NLPSTATUS::INFEASIBLE)\n\t    .value(\"UNBOUNDED\", NLPSTATUS::UNBOUNDED)\n\t    .value(\"UNFINISHED\", NLPSTATUS::UNFINISHED)\n\t    .value(\"UNSOLVED\", NLPSTATUS::UNSOLVED);\n\n\tnb::enum_<IISSOLSTATUS>(XPRS, \"IISSOLSTATUS\")\n\t    .value(\"UNSTARTED\", IISSOLSTATUS::UNSTARTED)\n\t    .value(\"FEASIBLE\", IISSOLSTATUS::FEASIBLE)\n\t    .value(\"COMPLETED\", IISSOLSTATUS::COMPLETED)\n\t    .value(\"UNFINISHED\", IISSOLSTATUS::UNFINISHED);\n\n\tnb::enum_<SOLAVAILABLE>(XPRS, \"SOLAVAILABLE\")\n\t    .value(\"NOTFOUND\", SOLAVAILABLE::NOTFOUND)\n\t    .value(\"OPTIMAL\", SOLAVAILABLE::OPTIMAL)\n\t    .value(\"FEASIBLE\", SOLAVAILABLE::FEASIBLE);\n\n\tnb::enum_<OPTIMIZETYPE>(XPRS, \"OPTIMIZETYPE\")\n\t    .value(\"NONE\", OPTIMIZETYPE::NONE)\n\t    .value(\"LP\", OPTIMIZETYPE::LP)\n\t    .value(\"MIP\", OPTIMIZETYPE::MIP)\n\t    .value(\"LOCAL\", OPTIMIZETYPE::LOCAL)\n\t    .value(\"GLOBAL\", OPTIMIZETYPE::GLOBAL);\n\n\t// Define Callbacks context enum\n\tauto to_upper = [](char const *name) {\n\t\tstd::string res(name);\n\t\tfor (char &c : res)\n\t\t\tc = std::toupper(c);\n\t\treturn res;\n\t};\n\tnb::enum_<CB_CONTEXT>(XPRS, \"CB_CONTEXT\", nb::is_arithmetic())\n\t// Use the callback list to define a value for each callback\n#define XPRSCB_NB_ENUM(ID, NAME, ...) .value(to_upper(#NAME).c_str(), CB_CONTEXT::NAME)\n\t    XPRSCB_LIST(XPRSCB_NB_ENUM, XPRSCB_ARG_IGNORE);\n#undef XPRSCB_NB_ENUM\n}\n"
  },
  {
    "path": "optimizer_version.toml",
    "content": "Gurobi = \"13.0.0\"\nCOPT = \"8.0.2\"\nMOSEK = \"10.2.0\"\nHiGHS = \"1.12.0\"\nIPOPT = \"3.13.2\"\nXpress = \"9.8\"\nKNITRO = \"15.1.0\"\n"
  },
  {
    "path": "pyproject.toml",
    "content": "[build-system]\nrequires = [\"scikit-build-core\", \"nanobind\", \"typing_extensions\"]\nbuild-backend = \"scikit_build_core.build\"\n\n[project]\nname = \"pyoptinterface\"\nversion = \"0.6.1\"\ndescription = \"Python interface to multiple optimization solvers\"\nreadme = \"README.md\"\nrequires-python = \">=3.9\"\nauthors = [{ name = \"Yue Yang\", email = \"metab0t@outlook.com\" }]\nclassifiers = [\n    'Development Status :: 5 - Production/Stable',\n    'Intended Audience :: Science/Research',\n    'Topic :: Scientific/Engineering',\n    'License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)',\n]\n\n[project.urls]\nHomepage = \"https://github.com/metab0t/pyoptinterface\"\n\n[project.optional-dependencies]\nmatrix = [\"numpy\", \"scipy\"]\nhighs = [\"highsbox\"]\nnlp = [\"llvmlite\", \"tccbox\"]\ntest = [\"pytest\", \"numpy\", \"scipy>=1.11.0\", \"highsbox\", \"llvmlite\", \"tccbox\"]\n\n[tool.scikit-build]\neditable.rebuild = true\nbuild-dir = \"build/{wheel_tag}\"\ncmake.build-type = \"Release\"\n# Build stable ABI wheels for CPython 3.12+\nwheel.py-api = \"cp312\"\n\n[tool.scikit-build.cmake.define]\nPYTHON_VERSION = { env = \"PYTHON_VERSION\", default = \"3.9\" }\nCMAKE_FIND_DEBUG_MODE = \"OFF\"\nENABLE_TEST_MAIN = \"OFF\"\n"
  },
  {
    "path": "scripts/generate_attribute_table.py",
    "content": "from typing import IO\nfrom pathlib import Path\n\n\nimport pyoptinterface as poi\nfrom pyoptinterface import gurobi, copt, mosek, highs, ipopt\n\n\ndef attribute_support_table(f, attribute_enum):\n    results = []\n    for attribute in attribute_enum:\n        support_get = f(attribute)\n        support_set = f(attribute, settable=True)\n        results.append((attribute, support_get, support_set))\n    return results\n\n\nemoji_map = {True: \"✅\", False: \"❌\"}\n\n\ndef print_table(io: IO[str], results):\n    io.write(\"\"\":::{list-table}\n:header-rows: 1\n\n*   - Attribute\n    - Get\n    - Set\n\"\"\")\n\n    for attribute, support_get, support_set in results:\n        io.write(f\"*   - {attribute.name}\\n\")\n        io.write(f\"    - {emoji_map[support_get]}\\n\")\n        io.write(f\"    - {emoji_map[support_set]}\\n\")\n\n    io.write(\":::\\n\\n\")\n\n\nio_pairs = [\n    (gurobi.Model, \"gurobi\"),\n    (copt.Model, \"copt\"),\n    (mosek.Model, \"mosek\"),\n    (highs.Model, \"highs\"),\n    (ipopt.Model, \"ipopt\"),\n]\n\nrootdir = Path(__file__).parent.parent\ndocsource_dir = rootdir / \"docs\" / \"source\" / \"attribute\"\n\nfor model, name in io_pairs:\n    path = docsource_dir / f\"{name}.md\"\n    with open(path, \"w\", encoding=\"utf-8\") as io:\n        io.write(f\"### Supported [model attribute](#pyoptinterface.ModelAttribute)\\n\\n\")\n        print_table(\n            io,\n            attribute_support_table(model.supports_model_attribute, poi.ModelAttribute),\n        )\n        io.write(\n            f\"### Supported [variable attribute](#pyoptinterface.VariableAttribute)\\n\\n\"\n        )\n        print_table(\n            io,\n            attribute_support_table(\n                model.supports_variable_attribute, poi.VariableAttribute\n            ),\n        )\n        io.write(\n            f\"### Supported [constraint attribute](#pyoptinterface.ConstraintAttribute)\\n\\n\"\n        )\n        print_table(\n            io,\n            attribute_support_table(\n                model.supports_constraint_attribute, poi.ConstraintAttribute\n            ),\n        )\n"
  },
  {
    "path": "scripts/generate_solver_constants.py",
    "content": "from typing import IO\nfrom pathlib import Path\n\nimport gurobipy as gp\n\nGRB = gp.GRB\n\nimport coptpy as cp\n\nCOPT = cp.COPT\n\n\ndef value_to_str(value):\n    if isinstance(value, str):\n        return f'\"{value}\"'\n    return str(value)\n\n\ndef extract_gurobi_constants():\n    # we want to extract all variables with all UPPERCASE names in dir(GRB)\n    GRB_constants = []\n    for name in dir(GRB):\n        if name.isupper():\n            GRB_constants.append(name)\n\n    # extract all variables with first letter in UPPERCASE in dir(GRB.Attr) and dir(GRB.Param) and dir(GRB.Callback)\n    GRB_Attr_constants = []\n    for name in dir(GRB.Attr):\n        if name[0].isupper():\n            GRB_Attr_constants.append(name)\n\n    GRB_Param_constants = []\n    for name in dir(GRB.Param):\n        if name[0].isupper():\n            GRB_Param_constants.append(name)\n\n    GRB_Callback_constants = []\n    for name in dir(GRB.Callback):\n        if name[0].isupper():\n            GRB_Callback_constants.append(name)\n\n    return {\n        \"GRB\": GRB_constants,\n        \"GRB.Attr\": GRB_Attr_constants,\n        \"GRB.Param\": GRB_Param_constants,\n        \"GRB.Callback\": GRB_Callback_constants,\n    }\n\n\ndef export_gurobi_constants(io: IO[str], gurobi_constants):\n    io.write('nb::module_ GRB = m.def_submodule(\"GRB\");\\n')\n    for name in gurobi_constants[\"GRB\"]:\n        value = getattr(GRB, name)\n        value = value_to_str(value)\n        io.write(f'GRB.attr(\"{name}\") = {value};\\n')\n    io.write(\"\\n\")\n\n    io.write('nb::module_ Attr = GRB.def_submodule(\"Attr\");\\n')\n    Attr = GRB.Attr\n    for name in gurobi_constants[\"GRB.Attr\"]:\n        value = getattr(Attr, name)\n        value = value_to_str(value)\n        io.write(f'Attr.attr(\"{name}\") = {value};\\n')\n    io.write(\"\\n\")\n\n    io.write('nb::module_ Param = GRB.def_submodule(\"Param\");\\n')\n    Param = GRB.Param\n    for name in gurobi_constants[\"GRB.Param\"]:\n        value = getattr(Param, name)\n        value = value_to_str(value)\n        io.write(f'Param.attr(\"{name}\") = {value};\\n')\n    io.write(\"\\n\")\n\n    io.write('nb::module_ Callback = GRB.def_submodule(\"Callback\");\\n')\n    Callback = GRB.Callback\n    for name in gurobi_constants[\"GRB.Callback\"]:\n        value = getattr(Callback, name)\n        value = value_to_str(value)\n        io.write(f'Callback.attr(\"{name}\") = {value};\\n')\n\n\ndef extract_copt_constants():\n    # dir(COPT)\n    COPT_constants = []\n    for name in dir(COPT):\n        if name.isupper():\n            COPT_constants.append(name)\n\n    # dir(COPT.Attr)\n    COPT_Attr_constants = []\n    for name in dir(COPT.Attr):\n        if name[0].isupper():\n            COPT_Attr_constants.append(name)\n\n    # dir(COPT.Param)\n    COPT_Param_constants = []\n    for name in dir(COPT.Param):\n        if name[0].isupper():\n            COPT_Param_constants.append(name)\n\n    # dir(COPT.Info)\n    COPT_Info_constants = []\n    for name in dir(COPT.Info):\n        if name[0].isupper():\n            COPT_Info_constants.append(name)\n\n    # dir(COPT.CbInfo)\n    COPT_CbInfo_constants = []\n    for name in dir(COPT.CbInfo):\n        if name[0].isupper():\n            COPT_CbInfo_constants.append(name)\n\n    return {\n        \"COPT\": COPT_constants,\n        \"COPT.Attr\": COPT_Attr_constants,\n        \"COPT.Param\": COPT_Param_constants,\n        \"COPT.Info\": COPT_Info_constants,\n        \"COPT.CbInfo\": COPT_CbInfo_constants,\n    }\n\n\ndef export_copt_constants(io: IO[str], copt_constants):\n    io.write('nb::module_ COPT = m.def_submodule(\"COPT\");\\n')\n    for name in copt_constants[\"COPT\"]:\n        value = getattr(COPT, name)\n        value = value_to_str(value)\n        io.write(f'COPT.attr(\"{name}\") = {value};\\n')\n    io.write(\"\\n\")\n\n    io.write('nb::module_ Attr = COPT.def_submodule(\"Attr\");\\n')\n    Attr = COPT.Attr\n    for name in copt_constants[\"COPT.Attr\"]:\n        value = getattr(Attr, name)\n        value = value_to_str(value)\n        io.write(f'Attr.attr(\"{name}\") = {value};\\n')\n    io.write(\"\\n\")\n\n    io.write('nb::module_ Param = COPT.def_submodule(\"Param\");\\n')\n    Param = COPT.Param\n    for name in copt_constants[\"COPT.Param\"]:\n        value = getattr(Param, name)\n        value = value_to_str(value)\n        io.write(f'Param.attr(\"{name}\") = {value};\\n')\n    io.write(\"\\n\")\n\n    io.write('nb::module_ Info = COPT.def_submodule(\"Info\");\\n')\n    Info = COPT.Info\n    for name in copt_constants[\"COPT.Info\"]:\n        value = getattr(Info, name)\n        value = value_to_str(value)\n        io.write(f'Info.attr(\"{name}\") = {value};\\n')\n    io.write(\"\\n\")\n\n    io.write('nb::module_ CbInfo = COPT.def_submodule(\"CbInfo\");\\n')\n    CbInfo = COPT.CbInfo\n    for name in copt_constants[\"COPT.CbInfo\"]:\n        value = getattr(CbInfo, name)\n        value = value_to_str(value)\n        io.write(f'CbInfo.attr(\"{name}\") = {value};\\n')\n\n\nif __name__ == \"__main__\":\n    current_dir = Path(__file__).parent.resolve()\n\n    with open(current_dir / \"gurobi_constants.txt\", \"w\") as io:\n        gurobi_constants = extract_gurobi_constants()\n        export_gurobi_constants(io, gurobi_constants)\n        print(\"Done!\")\n\n    with open(current_dir / \"copt_constants.txt\", \"w\") as io:\n        copt_constants = extract_copt_constants()\n        export_copt_constants(io, copt_constants)\n        print(\"Done!\")\n"
  },
  {
    "path": "skills/pyoptinterface-expert/SKILL.md",
    "content": "---\nname: pyoptinterface-expert\ndescription: Specialized guidance for modeling mathematical optimization problems using the pyoptinterface_native library. Use when building optimization models (LP, QP, MIP, NLP), interfacing with solvers (Gurobi, HiGHS, Ipopt, etc.), and performing matrix-based or nonlinear modeling in Python.\n---\n\n# PyOptInterface Expert Skill\n\nThis skill provides expert guidance for using `pyoptinterface` (POI), a high-performance Python modeling interface for mathematical optimization solvers.\n\n## Core Concepts\n\nPOI follows a common modeling pattern:\n1. Create a solver-specific model (e.g., `poi.highs.Model()`).\n2. Add variables using `model.add_variable()` or `model.add_m_variables()`.\n3. Set the objective using `model.set_objective()`.\n4. Add constraints using `model.add_linear_constraint()`, `model.add_quadratic_constraint()`, or `model.add_nl_constraint()`.\n5. Call `model.optimize()` and retrieve results.\n\n## Key Workflows\n\n### 1. Basic Modeling\n```python\nimport pyoptinterface as poi\nfrom pyoptinterface import highs\n\nmodel = highs.Model()\nx = model.add_variable(lb=0, name=\"x\")\ny = model.add_variable(lb=0, name=\"y\")\n\nmodel.set_objective(x + 2 * y, poi.ObjectiveSense.Minimize)\nmodel.add_linear_constraint(x + y >= 10, name=\"c1\")\n\nmodel.optimize()\nstatus = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\nif status == poi.TerminationStatusCode.OPTIMAL:\n    print(f\"x: {model.get_variable_attribute(x, poi.VariableAttribute.Value)}\")\n```\n\n### 2. Matrix-based Modeling\nUse `add_m_variables` and `add_m_linear_constraints` for performance with NumPy/SciPy.\n```python\nimport numpy as np\nx = model.add_m_variables((10,), lb=0)\nA = np.random.rand(5, 10)\nb = np.ones(5)\nmodel.add_m_linear_constraints(A, x, poi.Leq, b)\n```\n\n### 3. Nonlinear Modeling\nNonlinear expressions must be wrapped in `nl.graph()` context.\n```python\nfrom pyoptinterface import nl\nwith nl.graph():\n    model.add_nl_objective(x * x + nl.sin(y))\n    model.add_nl_constraint(x * y >= 5)\n```\n\n## Reference Documentation\n- API Reference: [references/api.md](references/api.md)\n- Modeling Examples: [references/examples.md](references/examples.md)\n\n## Best Practices\n- Use `poi.quicksum()` for large summations.\n- Check `TerminationStatus` before accessing variable values.\n- For large-scale models, prefer the Matrix API (`add_m_...`).\n"
  },
  {
    "path": "skills/pyoptinterface-expert/references/api.md",
    "content": "# API Reference\n\n## Model Classes\nImported from solver submodules:\n- `pyoptinterface.highs.Model`\n- `pyoptinterface.gurobi.Model`\n- `pyoptinterface.copt.Model`\n- `pyoptinterface.ipopt.Model`\n- `pyoptinterface.knitro.Model`\n- `pyoptinterface.mosek.Model`\n- `pyoptinterface.xpress.Model`\n\n## Core Methods\n### Model\n- `add_variable(lb, ub, domain, name, start)`: Add a single variable.\n- `add_m_variables(shape, lb, ub, domain, name, start)`: Add a NumPy array of variables.\n- `add_linear_constraint(expr, sense, rhs, name)`: Add a linear constraint.\n- `add_quadratic_constraint(expr, sense, rhs, name)`: Add a quadratic constraint.\n- `add_m_linear_constraints(A, x, sense, rhs)`: Add constraints in matrix form $Ax \\sim b$.\n- `add_nl_constraint(expr)`: Add a nonlinear constraint (within `nl.graph()`).\n- `set_objective(expr, sense)`: Set objective function.\n- `set_nl_objective(expr, sense)`: Set nonlinear objective.\n- `optimize()`: Solve the model.\n- `get_model_attribute(attr)`: Get model information (Status, ObjVal, etc.).\n- `get_variable_attribute(v, attr)`: Get variable information (Value, ReducedCost, etc.).\n- `set_variable_attribute(v, attr, value)`: Set variable bounds, starts, etc.\n- `get_value(expr)`: Evaluate expression at the current solution.\n\n## Enums\n### `poi.VariableDomain`\n- `Continuous`\n- `Integer`\n- `Binary`\n\n### `poi.ConstraintSense`\n- `Equal` (or `poi.Eq`)\n- `LessEqual` (or `poi.Leq`)\n- `GreaterEqual` (or `poi.Geq`)\n\n### `poi.ObjectiveSense`\n- `Minimize`\n- `Maximize`\n- `Feasibility`\n\n### `poi.TerminationStatusCode`\n- `OPTIMAL`\n- `INFEASIBLE`\n- `UNBOUNDED`\n- `TIME_LIMIT`\n- `ITERATION_LIMIT`\n\n### `poi.ModelAttribute`\n- `TerminationStatus`\n- `ObjectiveValue`\n- `SolveTimeSec`\n- `RelativeGap`\n- `Silent`\n\n### `poi.VariableAttribute`\n- `Value`\n- `Name`\n- `LowerBound`\n- `UpperBound`\n- `Domain`\n- `PrimalStart`\n"
  },
  {
    "path": "skills/pyoptinterface-expert/references/examples.md",
    "content": "# Modeling Examples\n\n## 1. Knapsack Problem (MIP)\nMaximize total value given a weight limit.\n```python\nimport pyoptinterface as poi\nfrom pyoptinterface import highs\n\nvalues = [10, 15, 20, 8]\nweights = [2, 3, 5, 2]\nlimit = 8\n\nmodel = highs.Model()\nx = model.add_m_variables(len(values), domain=poi.VariableDomain.Binary)\n\nmodel.set_objective(poi.quicksum(values[i] * x[i] for i in range(len(values))), poi.ObjectiveSense.Maximize)\nmodel.add_linear_constraint(poi.quicksum(weights[i] * x[i] for i in range(len(weights))) <= limit)\n\nmodel.optimize()\nif model.get_model_attribute(poi.ModelAttribute.TerminationStatus) == poi.TerminationStatusCode.OPTIMAL:\n    print(\"Selected items:\", [i for i in range(len(values)) if model.get_variable_attribute(x[i], poi.VariableAttribute.Value) > 0.5])\n```\n\n## 2. Sparse Matrix Model (LP)\nSolve $Ax \\le b$ using the matrix API.\n```python\nimport numpy as np\nfrom scipy import sparse\nimport pyoptinterface as poi\nfrom pyoptinterface import highs\n\nm, n = 100, 500\nA = sparse.random(m, n, density=0.1)\nb = np.random.rand(m)\nc = np.random.rand(n)\n\nmodel = highs.Model()\nx = model.add_m_variables(n, lb=0)\n\nmodel.set_objective(poi.quicksum(c[i] * x[i] for i in range(n)))\nmodel.add_m_linear_constraints(A, x, poi.Leq, b)\n\nmodel.optimize()\n```\n\n## 3. Nonlinear Rosenbrock Function (NLP)\nMinimize $f(x, y) = (1-x)^2 + 100(y-x^2)^2$.\n```python\nimport pyoptinterface as poi\nfrom pyoptinterface import ipopt, nl\n\nmodel = ipopt.Model()\nx = model.add_variable(lb=-5, ub=5)\ny = model.add_variable(lb=-5, ub=5)\n\nwith nl.graph():\n    model.add_nl_objective((1 - x)**2 + 100 * (y - x**2)**2, poi.ObjectiveSense.Minimize)\n\nmodel.optimize()\nprint(f\"Optimal x: {model.get_value(x)}, y: {model.get_value(y)}\")\n```\n"
  },
  {
    "path": "src/pyoptinterface/__init__.py",
    "content": "from pyoptinterface._src.core_ext import (\n    VariableIndex,\n    ConstraintIndex,\n    ExprBuilder,\n    VariableDomain,\n    ConstraintSense,\n    ConstraintType,\n    SOSType,\n    ObjectiveSense,\n    ScalarAffineFunction,\n    ScalarQuadraticFunction,\n)\n\nfrom pyoptinterface._src.attributes import (\n    VariableAttribute,\n    ModelAttribute,\n    TerminationStatusCode,\n    ResultStatusCode,\n    ConstraintAttribute,\n)\n\nfrom pyoptinterface._src.tupledict import (\n    tupledict,\n    make_tupledict,\n)\n\nfrom pyoptinterface._src.aml import quicksum, quicksum_\n\n# Alias of ConstraintSense\nEq = ConstraintSense.Equal\n\"\"\"Alias of `ConstraintSense.Equal` for equality constraints.\n\"\"\"\nLeq = ConstraintSense.LessEqual\n\"\"\"Alias of `ConstraintSense.LessEqual` for less-than-or-equal-to constraints.\n\"\"\"\nGeq = ConstraintSense.GreaterEqual\n\"\"\"Alias of `ConstraintSense.GreaterEqual` for greater-than-or-equal-to constraints.\n\"\"\"\n\nfrom pyoptinterface._src.monkeypatch import _monkeypatch_all\n\n_monkeypatch_all()\n\n__all__ = [\n    \"VariableIndex\",\n    \"ConstraintIndex\",\n    \"ExprBuilder\",\n    \"VariableDomain\",\n    \"ConstraintSense\",\n    \"ConstraintType\",\n    \"SOSType\",\n    \"ObjectiveSense\",\n    \"ScalarAffineFunction\",\n    \"ScalarQuadraticFunction\",\n    \"VariableAttribute\",\n    \"ModelAttribute\",\n    \"TerminationStatusCode\",\n    \"ResultStatusCode\",\n    \"ConstraintAttribute\",\n    \"tupledict\",\n    \"make_tupledict\",\n    \"quicksum\",\n    \"quicksum_\",\n    \"Eq\",\n    \"Leq\",\n    \"Geq\",\n]\n"
  },
  {
    "path": "src/pyoptinterface/_src/__init__.py",
    "content": ""
  },
  {
    "path": "src/pyoptinterface/_src/aml.py",
    "content": "from .core_ext import ExprBuilder, VariableDomain\nfrom .tupledict import make_tupledict\n\nfrom collections.abc import Collection\nfrom typing import Tuple, Union, Optional\n\n\ndef make_variable_ndarray(\n    model,\n    shape: Union[Tuple[int, ...], int],\n    domain: Optional[VariableDomain] = None,\n    lb: Optional[float] = None,\n    ub: Optional[float] = None,\n    name: Optional[str] = None,\n    start: Optional[float] = None,\n):\n    import numpy as np\n\n    if isinstance(shape, int):\n        shape = (shape,)\n\n    variables = np.empty(shape, dtype=object)\n\n    kw_args = dict()\n    if domain is not None:\n        kw_args[\"domain\"] = domain\n    if lb is not None:\n        kw_args[\"lb\"] = lb\n    if ub is not None:\n        kw_args[\"ub\"] = ub\n    if start is not None:\n        kw_args[\"start\"] = start\n\n    for index in np.ndindex(shape):\n        if name is not None:\n            suffix = str(index)\n            kw_args[\"name\"] = f\"{name}{suffix}\"\n        variables[index] = model.add_variable(**kw_args)\n\n    return variables\n\n\ndef make_variable_tupledict(\n    model,\n    *coords: Collection,\n    domain: Optional[VariableDomain] = None,\n    lb: Optional[float] = None,\n    ub: Optional[float] = None,\n    name: Optional[str] = None,\n    start: Optional[float] = None,\n):\n    kw_args = dict()\n    if domain is not None:\n        kw_args[\"domain\"] = domain\n    if lb is not None:\n        kw_args[\"lb\"] = lb\n    if ub is not None:\n        kw_args[\"ub\"] = ub\n    if start is not None:\n        kw_args[\"start\"] = start\n\n    def f(*args):\n        if name is not None:\n            suffix = str(args)\n            kw_args[\"name\"] = f\"{name}{suffix}\"\n        return model.add_variable(**kw_args)\n\n    td = make_tupledict(*coords, rule=f)\n    return td\n\n\n# def make_nd_variable_batch(\n#     model,\n#     *coords: Collection,\n#     domain=None,\n#     lb=None,\n#     ub=None,\n#     name=None,\n# ):\n#     assert model.supports_batch_add_variables()\n#\n#     kw_args = dict()\n#     if domain is not None:\n#         kw_args[\"domain\"] = domain\n#     if lb is not None:\n#         kw_args[\"lb\"] = lb\n#     if ub is not None:\n#         kw_args[\"ub\"] = ub\n#\n#     N = math.prod(len(c) for c in coords)\n#\n#     start_vi = model.add_variables(N, **kw_args)\n#     start_index = start_vi.index\n#\n#     kvs = []\n#     assert len(coords) > 0\n#     for i, coord in enumerate(product(*coords)):\n#         coord = tuple(flatten_tuple(coord))\n#         value = VariableIndex(start_index + i)\n#         if len(coord) == 1:\n#             coord = coord[0]\n#         if value is not None:\n#             kvs.append((coord, value))\n#\n#         suffix = str(coord)\n#         if name is not None:\n#             model.set_variable_name(value, f\"{name}{suffix}\")\n#     return tupledict(kvs)\n\n\ndef quicksum_(expr: ExprBuilder, terms, f=None):\n    import numpy as np\n\n    if isinstance(terms, dict):\n        iter = terms.values()\n    elif isinstance(terms, np.ndarray):\n        iter = terms.flat\n    else:\n        iter = terms\n    if f:\n        iter = map(f, iter)\n    for v in iter:\n        expr += v\n\n\ndef quicksum(terms, f=None):\n    expr = ExprBuilder()\n    quicksum_(expr, terms, f)\n    return expr\n"
  },
  {
    "path": "src/pyoptinterface/_src/attributes.py",
    "content": "from enum import Enum, auto\nfrom .core_ext import VariableDomain, ObjectiveSense\n\n\nclass VariableAttribute(Enum):\n    Value = auto()\n    LowerBound = auto()\n    UpperBound = auto()\n    Domain = auto()\n    PrimalStart = auto()\n    Name = auto()\n    IISLowerBound = auto()\n    IISUpperBound = auto()\n    ReducedCost = auto()\n\n\nvar_attr_type_map = {\n    VariableAttribute.Value: float,\n    VariableAttribute.LowerBound: float,\n    VariableAttribute.UpperBound: float,\n    VariableAttribute.PrimalStart: float,\n    VariableAttribute.Domain: VariableDomain,\n    VariableAttribute.Name: str,\n    VariableAttribute.IISLowerBound: bool,\n    VariableAttribute.IISUpperBound: bool,\n    VariableAttribute.ReducedCost: float,\n}\n\n\nclass ModelAttribute(Enum):\n    # ModelLike API\n    # NumberOfConstraints = auto()\n    # NumberOfVariables = auto()\n    Name = auto()\n    ObjectiveSense = auto()\n\n    # AbstractOptimizer API\n    DualStatus = auto()\n    PrimalStatus = auto()\n    RawStatusString = auto()\n    TerminationStatus = auto()\n    BarrierIterations = auto()\n    DualObjectiveValue = auto()\n    NodeCount = auto()\n    NumberOfThreads = auto()\n    ObjectiveBound = auto()\n    ObjectiveValue = auto()\n    RelativeGap = auto()\n    Silent = auto()\n    SimplexIterations = auto()\n    SolverName = auto()\n    SolverVersion = auto()\n    SolveTimeSec = auto()\n    TimeLimitSec = auto()\n    # ObjectiveLimit = auto()\n\n\nclass ResultStatusCode(Enum):\n    NO_SOLUTION = auto()\n    FEASIBLE_POINT = auto()\n    NEARLY_FEASIBLE_POINT = auto()\n    INFEASIBLE_POINT = auto()\n    INFEASIBILITY_CERTIFICATE = auto()\n    NEARLY_INFEASIBILITY_CERTIFICATE = auto()\n    REDUCTION_CERTIFICATE = auto()\n    NEARLY_REDUCTION_CERTIFICATE = auto()\n    UNKNOWN_RESULT_STATUS = auto()\n    OTHER_RESULT_STATUS = auto()\n\n\nclass TerminationStatusCode(Enum):\n    OPTIMIZE_NOT_CALLED = auto()\n    OPTIMAL = auto()\n    INFEASIBLE = auto()\n    DUAL_INFEASIBLE = auto()\n    LOCALLY_SOLVED = auto()\n    LOCALLY_INFEASIBLE = auto()\n    INFEASIBLE_OR_UNBOUNDED = auto()\n    ALMOST_OPTIMAL = auto()\n    ALMOST_INFEASIBLE = auto()\n    ALMOST_DUAL_INFEASIBLE = auto()\n    ALMOST_LOCALLY_SOLVED = auto()\n    ITERATION_LIMIT = auto()\n    TIME_LIMIT = auto()\n    NODE_LIMIT = auto()\n    SOLUTION_LIMIT = auto()\n    MEMORY_LIMIT = auto()\n    OBJECTIVE_LIMIT = auto()\n    NORM_LIMIT = auto()\n    OTHER_LIMIT = auto()\n    SLOW_PROGRESS = auto()\n    NUMERICAL_ERROR = auto()\n    INVALID_MODEL = auto()\n    INVALID_OPTION = auto()\n    INTERRUPTED = auto()\n    OTHER_ERROR = auto()\n\n\nmodel_attr_type_map = {\n    ModelAttribute.Name: str,\n    ModelAttribute.ObjectiveSense: ObjectiveSense,\n    ModelAttribute.DualStatus: ResultStatusCode,\n    ModelAttribute.PrimalStatus: ResultStatusCode,\n    ModelAttribute.RawStatusString: str,\n    ModelAttribute.TerminationStatus: TerminationStatusCode,\n    ModelAttribute.BarrierIterations: int,\n    ModelAttribute.DualObjectiveValue: float,\n    ModelAttribute.NodeCount: int,\n    ModelAttribute.NumberOfThreads: int,\n    ModelAttribute.ObjectiveBound: float,\n    ModelAttribute.ObjectiveValue: float,\n    ModelAttribute.RelativeGap: float,\n    ModelAttribute.Silent: bool,\n    ModelAttribute.SimplexIterations: int,\n    ModelAttribute.SolverName: str,\n    ModelAttribute.SolverVersion: str,\n    ModelAttribute.SolveTimeSec: float,\n    ModelAttribute.TimeLimitSec: float,\n}\n\n\nclass ConstraintAttribute(Enum):\n    Name = auto()\n    # PrimalStart = auto()\n    # DualStart = auto()\n    Primal = auto()\n    Dual = auto()\n    # BasisStatus = auto()\n    IIS = auto()\n\n\nconstraint_attr_type_map = {\n    ConstraintAttribute.Name: str,\n    ConstraintAttribute.Primal: float,\n    ConstraintAttribute.Dual: float,\n    ConstraintAttribute.IIS: bool,\n}\n"
  },
  {
    "path": "src/pyoptinterface/_src/codegen_c.py",
    "content": "from .cppad_interface_ext import (\n    graph_op,\n)\nfrom .cpp_graph_iter import cpp_graph_iterator\n\nfrom typing import IO\n\nop2name = {\n    graph_op.abs: \"fabs\",\n    graph_op.acos: \"acos\",\n    graph_op.asin: \"asin\",\n    graph_op.atan: \"atan\",\n    graph_op.cos: \"cos\",\n    graph_op.exp: \"exp\",\n    graph_op.log: \"log\",\n    graph_op.pow: \"pow\",\n    graph_op.sign: \"sign\",\n    graph_op.sin: \"sin\",\n    graph_op.sqrt: \"sqrt\",\n    graph_op.tan: \"tan\",\n    graph_op.add: \"+\",\n    graph_op.sub: \"-\",\n    graph_op.mul: \"*\",\n    graph_op.div: \"/\",\n    graph_op.azmul: \"*\",\n    graph_op.neg: \"-\",\n}\n\ncompare_ops = set([graph_op.cexp_eq, graph_op.cexp_le, graph_op.cexp_lt])\n\ncompare_ops_string = {\n    graph_op.cexp_eq: \"==\",\n    graph_op.cexp_le: \"<=\",\n    graph_op.cexp_lt: \"<\",\n}\n\n\ndef generate_csrc_prelude(io: IO[str]):\n    io.write(\"\"\"// includes\n#include <stddef.h>\n\n// typedefs\ntypedef double float_point_t;\n\n// declare mathematical functions\n#define UNARY(f) extern float_point_t f(float_point_t x)\n#define BINARY(f) extern float_point_t f(float_point_t x, float_point_t y)\n\n// unary functions\nUNARY(fabs);\nUNARY(acos);\nUNARY(asin);\nUNARY(atan);\nUNARY(cos);\nUNARY(exp);\nUNARY(log);\nUNARY(sin);\nUNARY(sqrt);\nUNARY(tan);\n\n// binary functions\nBINARY(pow);\n\n// externals\n// azmul\nfloat_point_t azmul(float_point_t x, float_point_t y)\n{\n    if( x == 0.0 ) return 0.0;\n    return x * y;\n}\n\n// sign\nfloat_point_t sign(float_point_t x)\n{\t\n    if( x > 0.0 ) return 1.0;\n    if( x == 0.0 ) return 0.0;\n    return -1.0;\n}\n\"\"\")\n\n\ndef generate_csrc_from_graph(\n    io: IO[str],\n    graph_obj,\n    name: str,\n    np: int = 0,\n    hessian_lagrange: bool = False,\n    nw: int = 0,\n    indirect_x: bool = False,\n    indirect_p: bool = False,\n    indirect_w: bool = False,\n    indirect_y: bool = False,\n    add_y: bool = False,\n):\n    n_dynamic_ind = graph_obj.n_dynamic_ind\n    n_variable_ind = graph_obj.n_variable_ind\n    n_constant = graph_obj.n_constant\n    n_dependent = graph_obj.n_dependent\n\n    # Simple case\n    # 0 -> dummy\n    # [1, 1 + np) -> *p\n    # [1 + np, 1 + n_dynamic_ind + n_variable_ind) -> *x\n    # [1 + n_dynamic_ind + n_variable_ind, 1 + n_dynamic_ind + n_variable_ind + n_constant) -> c[...]\n    # [1 + n_dynamic_ind + n_variable_ind + n_constant, ...) -> v[...]\n\n    # Hessian lagragian case\n    # 0 -> dummy\n    # [1, 1 + np) -> *p\n    # [1 + np, 1 + np + nw) -> *w\n    # [1 + np + nw, 1 + n_dynamic_ind + n_variable_ind) -> *x\n    # [1 + n_dynamic_ind + n_variable_ind, 1 + n_dynamic_ind + n_variable_ind + n_constant) -> c[...]\n    # [1 + n_dynamic_ind + n_variable_ind + n_constant, ...) -> v[...]\n\n    n_node = 0\n    for graph_iter in cpp_graph_iterator(graph_obj):\n        n_node += graph_iter.n_result\n\n    has_parameter = np > 0\n\n    function_args_signature = [\"const float_point_t* x\"]\n    if has_parameter:\n        function_args_signature.append(\"const float_point_t* p\")\n    if hessian_lagrange:\n        function_args_signature.append(\"const float_point_t* w\")\n    function_args_signature.append(\"float_point_t* y\")\n    if indirect_x:\n        function_args_signature.append(\"const int* xi\")\n    if has_parameter and indirect_p:\n        function_args_signature.append(\"const int* pi\")\n    if hessian_lagrange and indirect_w:\n        function_args_signature.append(\"const int* wi\")\n    if indirect_y:\n        function_args_signature.append(\"const int* yi\")\n\n    function_args = \", \".join(function_args_signature)\n\n    function_prototype = f\"\"\"\nvoid {name}(\n    {function_args}\n)\n\"\"\"\n    io.write(function_prototype)\n\n    if not hessian_lagrange:\n        nx = n_dynamic_ind + n_variable_ind - np\n    else:\n        nx = n_dynamic_ind + n_variable_ind - np - nw\n    ny = n_dependent\n    io.write(f\"\"\"{{\n    // begin function body\n\n    // size checks\n    // const size_t nx = {nx};\n    // const size_t np = {np};\n    // const size_t ny = {ny};\n\"\"\")\n    if hessian_lagrange:\n        io.write(f\"    // const size_t nw = {nw};\\n\")\n\n    io.write(f\"\"\"\n    // declare variables\n    float_point_t v[{n_node}];\n    \"\"\")\n\n    nc = n_constant\n    if nc > 0:\n        cs = (graph_obj.constant_vec_get(i) for i in range(nc))\n        cs_str = \", \".join(f\"{c}\" for c in cs)\n        io.write(f\"\"\"\n    // constants\n    // set c[i] for i = 0, ..., nc-1\n    // nc = {nc}\n    static const float_point_t c[{nc}] = {{\n        {cs_str}\n    }};\n\"\"\")\n\n    n_result_node = n_node\n    io.write(f\"\"\"\n    // result nodes\n    // set v[i] for i = 0, ..., n_result_node-1\n    // n_result_node = {n_result_node}\n\"\"\")\n\n    def get_node_name(node: int) -> str:\n        if node < 1:\n            raise ValueError(f\"Invalid node: {node}\")\n        if node < 1 + np:\n            index = node - 1\n            if indirect_p:\n                return f\"p[pi[{index}]]\"\n            else:\n                return f\"p[{index}]\"\n        elif node < 1 + n_dynamic_ind + n_variable_ind:\n            if hessian_lagrange:\n                if node < 1 + np + nw:\n                    index = node - 1 - np\n                    if indirect_w:\n                        return f\"w[wi[{index}]]\"\n                    else:\n                        return f\"w[{index}]\"\n                else:\n                    index = node - 1 - np - nw\n                    if indirect_x:\n                        return f\"x[xi[{index}]]\"\n                    else:\n                        return f\"x[{index}]\"\n            else:\n                index = node - 1 - np\n                if indirect_x:\n                    return f\"x[xi[{index}]]\"\n                else:\n                    return f\"x[{index}]\"\n        elif node < 1 + n_dynamic_ind + n_variable_ind + n_constant:\n            index = node - 1 - n_dynamic_ind - n_variable_ind\n            return f\"c[{index}]\"\n        else:\n            node = node - 1 - n_dynamic_ind - n_variable_ind - n_constant\n            assert node < n_node\n            return f\"v[{node}]\"\n\n    result_node = 0\n\n    infix_operators = set([\"+\", \"-\", \"*\", \"/\"])\n\n    for iter in cpp_graph_iterator(graph_obj):\n        op = iter.op\n        n_result = iter.n_result\n        args = iter.args\n\n        assert n_result == 1\n\n        n_arg = len(args)\n\n        op_name = op2name.get(op, None)\n        if op_name is not None:\n            if n_arg == 1:\n                arg1 = get_node_name(args[0])\n                io.write(f\"    v[{result_node}] = {op_name}({arg1});\\n\")\n            elif n_arg == 2:\n                arg1 = get_node_name(args[0])\n                arg2 = get_node_name(args[1])\n                if op_name in infix_operators:\n                    io.write(f\"    v[{result_node}] = {arg1} {op_name} {arg2};\\n\")\n                else:\n                    io.write(f\"    v[{result_node}] = {op_name}({arg1}, {arg2});\\n\")\n            else:\n                message = f\"Unknown n_arg: {n_arg} for op_enum: {op}\\n\"\n                raise ValueError(message)\n        elif op in compare_ops:\n            cmp_op = compare_ops_string[op]\n            assert n_arg == 4\n            predicate = get_node_name(args[0])\n            target = get_node_name(args[1])\n            then_value = get_node_name(args[2])\n            else_value = get_node_name(args[3])\n            io.write(\n                f\"    v[{result_node}] = {predicate} {cmp_op} {target} ? {then_value} : {else_value};\\n\"\n            )\n        else:\n            message = f\"Unknown name for op_enum: {op}\\n\"\n            debug_context = f\"name: {name}\\nfull graph:\\n{str(graph_obj)}\"\n            raise ValueError(message + debug_context)\n\n        result_node += n_result\n\n    io.write(\"\"\"\n    // dependent variables\n    // set y[i] for i = 0, ny-1\n\"\"\")\n\n    op = \"=\"\n    if add_y:\n        op = \"+=\"\n    for i in range(ny):\n        node = graph_obj.dependent_vec_get(i)\n        node_name = get_node_name(node)\n        if indirect_y:\n            assignment = f\"    y[yi[{i}]] {op} {node_name};\\n\"\n        else:\n            assignment = f\"    y[{i}] {op} {node_name};\\n\"\n        io.write(assignment)\n\n    io.write(\"\"\"\n    // end function body\n}\n\"\"\")\n"
  },
  {
    "path": "src/pyoptinterface/_src/codegen_llvm.py",
    "content": "from .cppad_interface_ext import (\n    graph_op,\n)\nfrom .cpp_graph_iter import cpp_graph_iterator\nfrom llvmlite import ir\n\nD = ir.DoubleType()\nD_PTR = ir.PointerType(D)\nI = ir.IntType(32)\nI_PTR = ir.PointerType(I)\n\n\ndef create_azmul(module: ir.Module):\n    # Define and create the azmul function\n    azmul_func_type = ir.FunctionType(D, [D, D])\n    azmul_func = ir.Function(module, azmul_func_type, name=\"azmul\")\n    azmul_func.attributes.add(\"alwaysinline\")\n    x, y = azmul_func.args\n    x.name = \"x\"\n    y.name = \"y\"\n\n    block = azmul_func.append_basic_block(name=\"entry\")\n    builder = ir.IRBuilder(block)\n\n    # Implement the azmul logic\n    with builder.if_else(builder.fcmp_unordered(\"==\", x, D(0.0))) as (\n        then,\n        otherwise,\n    ):\n        with then:\n            builder.ret(D(0.0))\n        with otherwise:\n            result = builder.fmul(x, y)\n            builder.ret(result)\n    builder.unreachable()\n\n\ndef create_sign(module: ir.Module):\n    # Define and create the sign function\n    sign_func_type = ir.FunctionType(D, [D])\n    sign_func = ir.Function(module, sign_func_type, name=\"sign\")\n    sign_func.attributes.add(\"alwaysinline\")\n    x = sign_func.args[0]\n    x.name = \"x\"\n\n    block = sign_func.append_basic_block(name=\"entry\")\n    builder = ir.IRBuilder(block)\n\n    # Implement the sign logic\n    with builder.if_else(builder.fcmp_ordered(\">\", x, D(0.0))) as (\n        then_positive,\n        otherwise,\n    ):\n        with then_positive:\n            builder.ret(D(1.0))\n        with otherwise:\n            with builder.if_else(builder.fcmp_ordered(\"==\", x, D(0.0))) as (\n                then_zero,\n                otherwise_negative,\n            ):\n                with then_zero:\n                    builder.ret(D(0.0))\n                with otherwise_negative:\n                    builder.ret(D(-1.0))\n    builder.unreachable()\n\n\ndef create_direct_load_store(module: ir.Module):\n    # Define and create the load_direct function\n    # D load_directly(D_PTR, I)\n    # returns ptr[idx_ptr[idx]]\n    load_direct_func_type = ir.FunctionType(D, [D_PTR, I])\n    load_direct_func = ir.Function(module, load_direct_func_type, name=\"load_direct\")\n    load_direct_func.attributes.add(\"alwaysinline\")\n    ptr, idx = load_direct_func.args\n    ptr.name = \"ptr\"\n    idx.name = \"idx\"\n\n    block = load_direct_func.append_basic_block(name=\"entry\")\n    builder = ir.IRBuilder(block)\n\n    # Implement the load_direct logic\n    ptr = builder.gep(ptr, [idx], name=\"gep_ptr\")\n    val = builder.load(ptr, name=\"val\")\n    builder.ret(val)\n\n    # Define and create the store_direct function\n    # void store_directly(D_PTR, I, D)\n    # ptr[idx] = val\n    store_direct_func_type = ir.FunctionType(ir.VoidType(), [D_PTR, I, D])\n    store_direct_func = ir.Function(module, store_direct_func_type, name=\"store_direct\")\n    store_direct_func.attributes.add(\"alwaysinline\")\n    ptr, idx, val = store_direct_func.args\n    ptr.name = \"ptr\"\n    idx.name = \"idx\"\n    val.name = \"val\"\n\n    block = store_direct_func.append_basic_block(name=\"entry\")\n    builder = ir.IRBuilder(block)\n\n    # Implement the store_direct logic\n    ptr = builder.gep(ptr, [idx], name=\"gep_ptr\")\n    builder.store(val, ptr)\n    builder.ret_void()\n\n    # Define and create the add_store_direct function\n    # void add_store_directly(D_PTR, I, D)\n    # ptr[idx] += val\n    add_store_direct_func_type = ir.FunctionType(ir.VoidType(), [D_PTR, I, D])\n    add_store_direct_func = ir.Function(\n        module, add_store_direct_func_type, name=\"add_store_direct\"\n    )\n    add_store_direct_func.attributes.add(\"alwaysinline\")\n    ptr, idx, val = add_store_direct_func.args\n    ptr.name = \"ptr\"\n    idx.name = \"idx\"\n    val.name = \"val\"\n\n    block = add_store_direct_func.append_basic_block(name=\"entry\")\n    builder = ir.IRBuilder(block)\n\n    # Implement the add_store_direct logic\n    ptr = builder.gep(ptr, [idx], name=\"gep_ptr\")\n    old_val = builder.load(ptr, name=\"old_val\")\n    new_val = builder.fadd(old_val, val, name=\"new_val\")\n    builder.store(new_val, ptr)\n    builder.ret_void()\n\n\ndef create_indirect_load_store(module: ir.Module):\n    # Define and create the load_indirect function\n    # D load_indirectly(D_PTR, I_PTR, I)\n    # returns ptr[idx_ptr[idx]]\n    load_indirect_func_type = ir.FunctionType(D, [D_PTR, I_PTR, I])\n    load_indirect_func = ir.Function(\n        module, load_indirect_func_type, name=\"load_indirect\"\n    )\n    load_indirect_func.attributes.add(\"alwaysinline\")\n    ptr, idx_ptr, idx = load_indirect_func.args\n    ptr.name = \"ptr\"\n    idx_ptr.name = \"idx_ptr\"\n    idx.name = \"idx\"\n\n    block = load_indirect_func.append_basic_block(name=\"entry\")\n    builder = ir.IRBuilder(block)\n\n    # Implement the load_indirect logic\n    idx = builder.gep(idx_ptr, [idx], name=\"gep_idx\")\n    idx = builder.load(idx, name=\"real_idx\")\n    ptr = builder.gep(ptr, [idx], name=\"gep_ptr\")\n    val = builder.load(ptr, name=\"val\")\n    builder.ret(val)\n\n    # Define and create the store_indirect function\n    # void store_indirectly(D_PTR, I_PTR, I, D)\n    # ptr[idx_ptr[idx]] = val\n    store_indirect_func_type = ir.FunctionType(ir.VoidType(), [D_PTR, I_PTR, I, D])\n    store_indirect_func = ir.Function(\n        module, store_indirect_func_type, name=\"store_indirect\"\n    )\n    store_indirect_func.attributes.add(\"alwaysinline\")\n    ptr, idx_ptr, idx, val = store_indirect_func.args\n    ptr.name = \"ptr\"\n    idx_ptr.name = \"idx_ptr\"\n    idx.name = \"idx\"\n    val.name = \"val\"\n\n    block = store_indirect_func.append_basic_block(name=\"entry\")\n    builder = ir.IRBuilder(block)\n\n    # Implement the store_indirect logic\n    idx = builder.gep(idx_ptr, [idx], name=\"gep_idx\")\n    idx = builder.load(idx, name=\"real_idx\")\n    ptr = builder.gep(ptr, [idx], name=\"gep_ptr\")\n    builder.store(val, ptr)\n    builder.ret_void()\n\n    # Define and create the add_store_indirect function\n    # void add_store_indirectly(D_PTR, I_PTR, I, D)\n    # ptr[idx_ptr[idx]] += val\n    add_store_indirect_func_type = ir.FunctionType(ir.VoidType(), [D_PTR, I_PTR, I, D])\n    add_store_indirect_func = ir.Function(\n        module, add_store_indirect_func_type, name=\"add_store_indirect\"\n    )\n    add_store_indirect_func.attributes.add(\"alwaysinline\")\n    ptr, idx_ptr, idx, val = add_store_indirect_func.args\n    ptr.name = \"ptr\"\n    idx_ptr.name = \"idx_ptr\"\n    idx.name = \"idx\"\n    val.name = \"val\"\n\n    block = add_store_indirect_func.append_basic_block(name=\"entry\")\n    builder = ir.IRBuilder(block)\n\n    # Implement the add_store_indirect logic\n    idx = builder.gep(idx_ptr, [idx], name=\"gep_idx\")\n    idx = builder.load(idx, name=\"real_idx\")\n    ptr = builder.gep(ptr, [idx], name=\"gep_ptr\")\n    old_val = builder.load(ptr, name=\"old_val\")\n    new_val = builder.fadd(old_val, val, name=\"new_val\")\n    builder.store(new_val, ptr)\n    builder.ret_void()\n\n\nop2name = {\n    graph_op.abs: \"fabs\",\n    graph_op.acos: \"acos\",\n    graph_op.asin: \"asin\",\n    graph_op.atan: \"atan\",\n    graph_op.cos: \"cos\",\n    graph_op.exp: \"exp\",\n    graph_op.log: \"log\",\n    graph_op.pow: \"pow\",\n    graph_op.sin: \"sin\",\n    graph_op.sqrt: \"sqrt\",\n    graph_op.tan: \"tan\",\n}\n\nmath_ops = set(op2name.keys())\n\nbinary_ops = set([graph_op.pow])\n\ncompare_ops = set([graph_op.cexp_eq, graph_op.cexp_le, graph_op.cexp_lt])\n\ncompare_ops_string = {\n    graph_op.cexp_eq: \"==\",\n    graph_op.cexp_le: \"<=\",\n    graph_op.cexp_lt: \"<\",\n}\n\n\ndef create_llvmir_basic_functions(module: ir.Module):\n    create_azmul(module)\n    create_sign(module)\n    create_direct_load_store(module)\n    create_indirect_load_store(module)\n\n    for op, op_name in op2name.items():\n        if op in binary_ops:\n            func_type = ir.FunctionType(D, [D, D])\n        else:\n            func_type = ir.FunctionType(D, [D])\n        ir.Function(module, func_type, name=op_name)\n\n    # sin = module.declare_intrinsic('llvm.sin', [D])\n    # cos = module.declare_intrinsic('llvm.cos', [D])\n\n\n# Define graph to LLVM IR translation function\ndef generate_llvmir_from_graph(\n    module: ir.Module,\n    graph_obj,\n    name: str,\n    np: int = 0,\n    hessian_lagrange: bool = False,\n    nw: int = 0,\n    indirect_x: bool = False,\n    indirect_p: bool = False,\n    indirect_w: bool = False,\n    indirect_y: bool = False,\n    add_y: bool = False,\n):\n    n_dynamic_ind = graph_obj.n_dynamic_ind\n    n_variable_ind = graph_obj.n_variable_ind\n    n_constant = graph_obj.n_constant\n    n_dependent = graph_obj.n_dependent\n\n    n_node = 0\n    for graph_iter in cpp_graph_iterator(graph_obj):\n        n_node += graph_iter.n_result\n\n    has_parameter = np > 0\n\n    # Define function signature\n    func_args = [D_PTR]\n    arg_names = [\"x\"]\n    if has_parameter:\n        func_args.append(D_PTR)\n        arg_names.append(\"p\")\n    if hessian_lagrange:\n        func_args.append(D_PTR)\n        arg_names.append(\"w\")\n    func_args.append(D_PTR)\n    arg_names.append(\"y\")\n    if indirect_x:\n        func_args.append(I_PTR)\n        arg_names.append(\"xi\")\n    if has_parameter and indirect_p:\n        func_args.append(I_PTR)\n        arg_names.append(\"pi\")\n    if hessian_lagrange and indirect_w:\n        func_args.append(I_PTR)\n        arg_names.append(\"wi\")\n    if indirect_y:\n        func_args.append(I_PTR)\n        arg_names.append(\"yi\")\n\n    func_type = ir.FunctionType(ir.VoidType(), func_args)\n    func = ir.Function(module, func_type, name=name)\n\n    # set argument names\n    args_dict = {}\n    args = func.args\n    for i, arg in enumerate(args):\n        arg.name = arg_names[i]\n        args_dict[arg.name] = arg\n    # Destructure the args\n    x = args_dict.get(\"x\", None)\n    p = args_dict.get(\"p\", None)\n    w = args_dict.get(\"w\", None)\n    y = args_dict.get(\"y\", None)\n    xi = args_dict.get(\"xi\", None)\n    pi = args_dict.get(\"pi\", None)\n    wi = args_dict.get(\"wi\", None)\n    yi = args_dict.get(\"yi\", None)\n    # add noalias attribute\n    for arg in [x, p, w, y, xi, pi, wi, yi]:\n        if arg is not None:\n            arg.add_attribute(\"noalias\")\n\n    # Define entry block\n    block = func.append_basic_block(name=\"entry\")\n    builder = ir.IRBuilder(block)\n\n    comment = \"\"\n    if not hessian_lagrange:\n        nx = n_dynamic_ind + n_variable_ind - np\n        comment += f\"nx = {nx}, np = {np}, \"\n    else:\n        nx = n_dynamic_ind + n_variable_ind - np - nw\n        comment += f\"nx = {nx}, np = {np}, nw = {nw}, \"\n    ny = n_dependent\n    comment += f\"ny = {ny}\"\n    builder.comment(comment)\n\n    # Constants and initial setup (if any)\n    nc = n_constant\n    constants = [graph_obj.constant_vec_get(i) for i in range(nc)]\n    c_array = ir.Constant(ir.ArrayType(D, len(constants)), constants)\n    c_global = ir.GlobalVariable(module, c_array.type, name=f\"{name}_constants\")\n    c_global.linkage = \"internal\"\n    c_global.initializer = c_array\n    c_global_ptr = builder.bitcast(c_global, D_PTR)\n\n    # sin = module.get_global(\"llvm.sin.f64\")\n    # cos = module.get_global(\"llvm.cos.f64\")\n    math_functions = dict()\n    for op_name in op2name.values():\n        op_function = module.get_global(op_name)\n        if op_function is None:\n            raise ValueError(f\"Math function {op_name} not found in module\")\n        math_functions[op_name] = op_function\n\n    azmul = module.get_global(\"azmul\")\n    sign = module.get_global(\"sign\")\n    load_direct = module.get_global(\"load_direct\")\n    store_direct = module.get_global(\"store_direct\")\n    add_store_direct = module.get_global(\"add_store_direct\")\n    load_indirect = module.get_global(\"load_indirect\")\n    store_indirect = module.get_global(\"store_indirect\")\n    add_store_indirect = module.get_global(\"add_store_indirect\")\n\n    result_node = 0\n\n    p_dict = {}\n    w_dict = {}\n    x_dict = {}\n    c_dict = {}\n    v_dict = {}\n\n    def get_node_value(node: int):\n        if node < 1:\n            raise ValueError(f\"Invalid node: {node}\")\n        if node < 1 + np:\n            p_index = node - 1\n            val = p_dict.get(p_index, None)\n            if val is None:\n                if indirect_p:\n                    val = builder.call(load_indirect, [p, pi, I(p_index)])\n                else:\n                    val = builder.call(load_direct, [p, I(p_index)])\n                val.name = f\"p[{p_index}]\"\n                p_dict[p_index] = val\n        elif node < 1 + n_dynamic_ind + n_variable_ind:\n            if hessian_lagrange:\n                if node < 1 + np + nw:\n                    w_index = node - 1 - np\n                    val = w_dict.get(w_index, None)\n                    if val is None:\n                        if indirect_w:\n                            val = builder.call(load_indirect, [w, wi, I(w_index)])\n                        else:\n                            val = builder.call(load_direct, [w, I(w_index)])\n                        val.name = f\"w[{w_index}]\"\n                        w_dict[w_index] = val\n                else:\n                    x_index = node - 1 - np - nw\n                    val = x_dict.get(x_index, None)\n                    if val is None:\n                        if indirect_x:\n                            val = builder.call(load_indirect, [x, xi, I(x_index)])\n                        else:\n                            val = builder.call(load_direct, [x, I(x_index)])\n                        val.name = f\"x[{x_index}]\"\n                        x_dict[x_index] = val\n            else:\n                x_index = node - 1 - np\n                val = x_dict.get(x_index, None)\n                if val is None:\n                    if indirect_x:\n                        val = builder.call(load_indirect, [x, xi, I(x_index)])\n                    else:\n                        val = builder.call(load_direct, [x, I(x_index)])\n                    val.name = f\"x[{x_index}]\"\n                    x_dict[x_index] = val\n        elif node < 1 + n_dynamic_ind + n_variable_ind + n_constant:\n            c_index = node - 1 - n_dynamic_ind - n_variable_ind\n            val = c_dict.get(c_index, None)\n            if val is None:\n                val = builder.call(load_direct, [c_global_ptr, I(c_index)])\n                val.name = f\"c[{c_index}]\"\n                c_dict[c_index] = val\n        else:\n            v_index = node - 1 - n_dynamic_ind - n_variable_ind - n_constant\n            assert v_index < n_node\n            v_val = v_dict.get(v_index, None)\n            if v_val is None:\n                raise ValueError(f\"Node value not found: {v_index}\")\n            val = v_val\n        return val\n\n    arithmetic_flags = (\"fast\",)\n\n    for iter in cpp_graph_iterator(graph_obj):\n        op = iter.op\n        n_result = iter.n_result\n        args = iter.args\n\n        assert n_result == 1\n\n        arg1 = get_node_value(args[0])\n        if len(args) >= 2:\n            arg2 = get_node_value(args[1])\n\n        if op == graph_op.add:\n            ret_val = builder.fadd(arg1, arg2, flags=arithmetic_flags)\n        elif op == graph_op.sub:\n            ret_val = builder.fsub(arg1, arg2, flags=arithmetic_flags)\n        elif op == graph_op.mul:\n            ret_val = builder.fmul(arg1, arg2, flags=arithmetic_flags)\n        elif op == graph_op.div:\n            ret_val = builder.fdiv(arg1, arg2, flags=arithmetic_flags)\n        elif op == graph_op.azmul:\n            ret_val = builder.fmul(arg1, arg2, flags=arithmetic_flags)\n            # ret_val = builder.call(azmul, [arg1, arg2])\n        elif op == graph_op.neg:\n            ret_val = builder.fneg(arg1, flags=arithmetic_flags)\n        elif op == graph_op.sign:\n            ret_val = builder.call(sign, [arg1])\n        elif op in math_ops:\n            op_name = op2name[op]\n            op_function = math_functions[op_name]\n            if op in binary_ops:\n                ret_val = builder.call(op_function, [arg1, arg2])\n            else:\n                ret_val = builder.call(op_function, [arg1])\n        elif op in compare_ops:\n            assert len(args) == 4\n            predicate = arg1\n            target = arg2\n            then_value = get_node_value(args[2])\n            else_value = get_node_value(args[3])\n\n            cmp_string = compare_ops_string[op]\n            cond = builder.fcmp_ordered(cmp_string, predicate, target)\n\n            ret_val = builder.select(cond, then_value, else_value)\n        else:\n            raise ValueError(f\"Unknown CppAD graph op_enum: {op}\")\n\n        ret_val.name = f\"v[{result_node}]\"\n        v_dict[result_node] = ret_val\n\n        result_node += n_result\n\n    store_f_dict = {\n        (True, True): add_store_indirect,\n        (True, False): store_indirect,\n        (False, True): add_store_direct,\n        (False, False): store_direct,\n    }\n    store_f = store_f_dict[(indirect_y, add_y)]\n    for i in range(ny):\n        node = graph_obj.dependent_vec_get(i)\n        val = get_node_value(node)\n        builder.comment(f\"write y[{i}]\")\n        if indirect_y:\n            builder.call(store_f, [y, yi, I(i), val])\n        else:\n            builder.call(store_f, [y, I(i), val])\n\n    # Return from the function\n    builder.ret_void()\n"
  },
  {
    "path": "src/pyoptinterface/_src/comparison_constraint.py",
    "content": "from dataclasses import dataclass\nfrom typing import Any\n\nfrom .core_ext import ConstraintSense\n\n\n@dataclass\nclass ComparisonConstraint:\n    sense: ConstraintSense\n    lhs: Any\n    rhs: Any\n"
  },
  {
    "path": "src/pyoptinterface/_src/constraint_bridge.py",
    "content": "from .core_ext import ScalarQuadraticFunction, ConstraintSense\n\n\ndef bridge_soc_quadratic_constraint(model, cone_variables, name=\"\", rotated=False):\n    \"\"\"\n    Convert a second order cone constraint to a quadratic constraint.\n    x[0] >= sqrt(x[1]^2 + ... + x[n]^2)\n    to\n    x[0]^2 - x[1]^2 - ... - x[n]^2 >= 0\n    or\n    convert a rotated second order cone constraint to a quadratic constraint.\n    2 * x[0] * x[1] >= x[2]^2 + ... + x[n]^2\n    to\n    2 * x[0] * x[1] - x[2]^2 - ... - x[n]^2 >= 0\n    \"\"\"\n    N = len(cone_variables)\n    if N < 2:\n        raise ValueError(\n            \"Second order cone constraint must have at least two variables\"\n        )\n\n    expr = ScalarQuadraticFunction()\n    expr.reserve_quadratic(N)\n\n    if not rotated:\n        x0 = cone_variables[0]\n        expr.add_quadratic_term(x0, x0, 1.0)\n\n        for i in range(1, N):\n            xi = cone_variables[i]\n            expr.add_quadratic_term(xi, xi, -1.0)\n\n        con = model.add_quadratic_constraint(\n            expr, ConstraintSense.GreaterEqual, 0.0, name\n        )\n    else:\n        x0 = cone_variables[0]\n        x1 = cone_variables[1]\n        expr.add_quadratic_term(x0, x1, 2.0)\n\n        for i in range(2, N):\n            xi = cone_variables[i]\n            expr.add_quadratic_term(xi, xi, -1.0)\n\n        con = model.add_quadratic_constraint(\n            expr, ConstraintSense.GreaterEqual, 0.0, name\n        )\n\n    return con\n"
  },
  {
    "path": "src/pyoptinterface/_src/copt.py",
    "content": "import os\nimport platform\nfrom pathlib import Path\nimport logging\nfrom typing import Dict, Tuple, Union, overload\n\nfrom .copt_model_ext import RawModel, Env, COPT, load_library\nfrom .attributes import (\n    VariableAttribute,\n    ConstraintAttribute,\n    ModelAttribute,\n    ResultStatusCode,\n    TerminationStatusCode,\n)\nfrom .core_ext import (\n    VariableIndex,\n    ScalarAffineFunction,\n    ScalarQuadraticFunction,\n    ExprBuilder,\n    ConstraintType,\n    ConstraintSense,\n    ObjectiveSense,\n)\nfrom .nlexpr_ext import ExpressionHandle\nfrom .nlfunc import ExpressionGraphContext, convert_to_expressionhandle\nfrom .comparison_constraint import ComparisonConstraint\nfrom .solver_common import (\n    _direct_get_model_attribute,\n    _direct_set_model_attribute,\n    _direct_get_entity_attribute,\n    _direct_set_entity_attribute,\n)\nfrom .aml import make_variable_tupledict, make_variable_ndarray\nfrom .matrix import add_matrix_constraints\n\n\ndef detected_libraries():\n    libs = []\n\n    subdir = {\n        \"Linux\": \"lib\",\n        \"Darwin\": \"lib\",\n        \"Windows\": \"bin\",\n    }[platform.system()]\n    libname = {\n        \"Linux\": \"libcopt.so\",\n        \"Darwin\": \"libcopt.dylib\",\n        \"Windows\": \"copt.dll\",\n    }[platform.system()]\n\n    # Environment\n    home = os.environ.get(\"COPT_HOME\", None)\n    if home and os.path.exists(home):\n        lib = Path(home) / subdir / libname\n        if lib.exists():\n            libs.append(str(lib))\n\n    # default names\n    default_libname = libname\n    libs.append(default_libname)\n\n    return libs\n\n\ndef autoload_library():\n    libs = detected_libraries()\n    for lib in libs:\n        ret = load_library(lib)\n        if ret:\n            logging.info(f\"Loaded COPT library: {lib}\")\n            return True\n    return False\n\n\nautoload_library()\n\nDEFAULT_ENV = None\n\n\ndef init_default_env():\n    global DEFAULT_ENV\n    if DEFAULT_ENV is None:\n        DEFAULT_ENV = Env()\n\n\nvariable_attribute_get_func_map = {\n    VariableAttribute.Value: lambda model, v: model.get_variable_info(v, \"Value\"),\n    VariableAttribute.LowerBound: lambda model, v: model.get_variable_info(v, \"LB\"),\n    VariableAttribute.UpperBound: lambda model, v: model.get_variable_info(v, \"UB\"),\n    VariableAttribute.PrimalStart: lambda model, v: model.variable_start_values.get(\n        v, None\n    ),\n    VariableAttribute.Domain: lambda model, v: model.get_variable_type(v),\n    VariableAttribute.Name: lambda model, v: model.get_variable_name(v),\n    VariableAttribute.IISLowerBound: lambda model, v: model._get_variable_lowerbound_IIS(\n        v\n    )\n    > 0,\n    VariableAttribute.IISUpperBound: lambda model, v: model._get_variable_upperbound_IIS(\n        v\n    )\n    > 0,\n    VariableAttribute.ReducedCost: lambda model, v: model.get_variable_info(\n        v, \"RedCost\"\n    ),\n}\n\n\ndef set_variable_start(model, v, val):\n    model.variable_start_values[v] = val\n\n\nvariable_attribute_set_func_map = {\n    VariableAttribute.LowerBound: lambda model, v, val: model.set_variable_lower_bound(\n        v, val\n    ),\n    VariableAttribute.UpperBound: lambda model, v, val: model.set_variable_upper_bound(\n        v, val\n    ),\n    VariableAttribute.PrimalStart: set_variable_start,\n    VariableAttribute.Domain: lambda model, v, val: model.set_variable_type(v, val),\n    VariableAttribute.Name: lambda model, v, val: model.set_variable_name(v, val),\n}\n\nconstraint_type_attribute_name_map = {\n    ConstraintType.Linear: \"Rows\",\n    ConstraintType.Quadratic: \"QConstrs\",\n}\n\ncopt_parameter_raw_type_map = {\n    0: float,\n    1: int,\n}\n\ncopt_attribute_raw_type_map = {\n    2: float,\n    3: int,\n}\n\n\ndef get_objsense(model):\n    raw_sense = model.get_raw_attribute_int(\"ObjSense\")\n    if raw_sense == COPT.MINIMIZE:\n        return ObjectiveSense.Minimize\n    elif raw_sense == COPT.MAXIMIZE:\n        return ObjectiveSense.Maximize\n    else:\n        raise ValueError(f\"Unknown objective sense: {raw_sense}\")\n\n\ndef get_objval(model):\n    if model._is_mip():\n        attr_name = \"BestObj\"\n    else:\n        attr_name = \"LpObjval\"\n    obj = model.get_raw_attribute_double(attr_name)\n    return obj\n\n\ndef get_primalstatus(model):\n    if model._is_mip():\n        attr_name = \"HasMipSol\"\n    else:\n        attr_name = \"HasLpSol\"\n    has_sol = model.get_raw_attribute_int(attr_name)\n    if has_sol != 0:\n        return ResultStatusCode.FEASIBLE_POINT\n    else:\n        return ResultStatusCode.NO_SOLUTION\n\n\ndef get_dualstatus(model):\n    if not model._is_mip():\n        has_sol = model.get_raw_attribute_int(\"HasLpSol\")\n        if has_sol != 0:\n            return ResultStatusCode.FEASIBLE_POINT\n    return ResultStatusCode.NO_SOLUTION\n\n\n# LP status codes. Descriptions taken from COPT user guide.\n# Code : (TerminationStatus, RawStatusString)\n_RAW_LPSTATUS_STRINGS = {\n    COPT.UNSTARTED: (\n        TerminationStatusCode.OPTIMIZE_NOT_CALLED,\n        \"The LP optimization is not started yet.\",\n    ),\n    COPT.OPTIMAL: (\n        TerminationStatusCode.OPTIMAL,\n        \"The LP problem is solved to optimality.\",\n    ),\n    COPT.INFEASIBLE: (\n        TerminationStatusCode.INFEASIBLE,\n        \"The LP problem is infeasible.\",\n    ),\n    COPT.UNBOUNDED: (\n        TerminationStatusCode.DUAL_INFEASIBLE,\n        \"The LP problem is unbounded.\",\n    ),\n    COPT.NUMERICAL: (\n        TerminationStatusCode.NUMERICAL_ERROR,\n        \"Numerical trouble encountered.\",\n    ),\n    COPT.IMPRECISE: (\n        TerminationStatusCode.ALMOST_OPTIMAL,\n        \"The LP problem is solved to optimality with relaxed tolerances.\",\n    ),\n    COPT.TIMEOUT: (\n        TerminationStatusCode.TIME_LIMIT,\n        \"The LP optimization is stopped because of time limit.\",\n    ),\n    COPT.UNFINISHED: (\n        TerminationStatusCode.NUMERICAL_ERROR,\n        \"The LP optimization is stopped but the solver cannot provide a solution because of numerical difficulties.\",\n    ),\n    COPT.INTERRUPTED: (\n        TerminationStatusCode.INTERRUPTED,\n        \"The LP optimization is stopped by user interrupt.\",\n    ),\n}\n\n# MIP status codes. Descriptions taken from COPT user guide.\n# Code : (TerminationStatus, RawStatusString)\n_RAW_MIPSTATUS_STRINGS = {\n    COPT.UNSTARTED: (\n        TerminationStatusCode.OPTIMIZE_NOT_CALLED,\n        \"The MIP optimization is not started yet.\",\n    ),\n    COPT.OPTIMAL: (\n        TerminationStatusCode.OPTIMAL,\n        \"The MIP problem is solved to optimality.\",\n    ),\n    COPT.INFEASIBLE: (\n        TerminationStatusCode.INFEASIBLE,\n        \"The MIP problem is infeasible.\",\n    ),\n    COPT.UNBOUNDED: (\n        TerminationStatusCode.DUAL_INFEASIBLE,\n        \"The MIP problem is unbounded.\",\n    ),\n    COPT.INF_OR_UNB: (\n        TerminationStatusCode.INFEASIBLE_OR_UNBOUNDED,\n        \"The MIP problem is infeasible or unbounded.\",\n    ),\n    COPT.NODELIMIT: (\n        TerminationStatusCode.NODE_LIMIT,\n        \"The MIP optimization is stopped because of node limit.\",\n    ),\n    COPT.TIMEOUT: (\n        TerminationStatusCode.TIME_LIMIT,\n        \"The MIP optimization is stopped because of time limit.\",\n    ),\n    COPT.UNFINISHED: (\n        TerminationStatusCode.NUMERICAL_ERROR,\n        \"The MIP optimization is stopped but the solver cannot provide a solution because of numerical difficulties.\",\n    ),\n    COPT.INTERRUPTED: (\n        TerminationStatusCode.INTERRUPTED,\n        \"The MIP optimization is stopped by user interrupt.\",\n    ),\n}\n\n\ndef get_terminationstatus(model):\n    if model._is_mip():\n        raw_status = model.get_raw_attribute_int(\"MipStatus\")\n        status_string_pair = _RAW_MIPSTATUS_STRINGS.get(raw_status, None)\n    else:\n        raw_status = model.get_raw_attribute_int(\"LpStatus\")\n        status_string_pair = _RAW_LPSTATUS_STRINGS.get(raw_status, None)\n    if not status_string_pair:\n        raise ValueError(f\"Unknown termination status: {raw_status}\")\n    return status_string_pair[0]\n\n\ndef get_rawstatusstring(model):\n    if model._is_mip():\n        raw_status = model.get_raw_attribute_int(\"MipStatus\")\n        status_string_pair = _RAW_MIPSTATUS_STRINGS.get(raw_status, None)\n    else:\n        raw_status = model.get_raw_attribute_int(\"LpStatus\")\n        status_string_pair = _RAW_LPSTATUS_STRINGS.get(raw_status, None)\n    if not status_string_pair:\n        raise ValueError(f\"Unknown termination status: {raw_status}\")\n    return status_string_pair[1]\n\n\ndef get_silent(model):\n    return model.get_raw_parameter_int(\"LogToConsole\") == 0\n\n\nmodel_attribute_get_func_map = {\n    ModelAttribute.ObjectiveSense: get_objsense,\n    ModelAttribute.BarrierIterations: lambda model: model.get_model_raw_attribute_int(\n        \"BarrierIter\"\n    ),\n    ModelAttribute.DualObjectiveValue: get_objval,\n    ModelAttribute.NodeCount: lambda model: model.get_model_raw_attribute_int(\n        \"NodeCnt\"\n    ),\n    ModelAttribute.ObjectiveBound: get_objval,\n    ModelAttribute.ObjectiveValue: get_objval,\n    ModelAttribute.SimplexIterations: lambda model: model.get_model_raw_attribute_int(\n        \"SimplexIter\"\n    ),\n    ModelAttribute.SolveTimeSec: lambda model: model.get_raw_attribute_double(\n        \"SolvingTime\"\n    ),\n    ModelAttribute.NumberOfThreads: lambda model: model.get_raw_parameter_int(\n        \"Threads\"\n    ),\n    ModelAttribute.RelativeGap: lambda model: model.get_raw_parameter_double(\"RelGap\"),\n    ModelAttribute.TimeLimitSec: lambda model: model.get_raw_parameter_double(\n        \"TimeLimit\"\n    ),\n    ModelAttribute.DualStatus: get_dualstatus,\n    ModelAttribute.PrimalStatus: get_primalstatus,\n    ModelAttribute.RawStatusString: get_rawstatusstring,\n    ModelAttribute.TerminationStatus: get_terminationstatus,\n    ModelAttribute.Silent: get_silent,\n    ModelAttribute.SolverName: lambda _: \"COPT\",\n    ModelAttribute.SolverVersion: lambda model: model.version_string(),\n}\n\n\ndef set_silent(model, value: bool):\n    if value:\n        model.set_raw_parameter_int(\"LogToConsole\", 0)\n    else:\n        model.set_raw_parameter_int(\"LogToConsole\", 1)\n\n\nmodel_attribute_set_func_map = {\n    ModelAttribute.ObjectiveSense: lambda model, v: model.set_obj_sense(v),\n    ModelAttribute.NumberOfThreads: lambda model, v: model.set_raw_parameter_int(\n        \"Threads\", v\n    ),\n    ModelAttribute.RelativeGap: lambda model, v: model.set_raw_parameter_double(\n        \"RelGap\", v\n    ),\n    ModelAttribute.TimeLimitSec: lambda model, v: model.set_raw_parameter_double(\n        \"TimeLimit\", v\n    ),\n    ModelAttribute.Silent: set_silent,\n}\n\nconstraint_attribute_get_func_map = {\n    ConstraintAttribute.Name: lambda model, constraint: model.get_constraint_name(\n        constraint\n    ),\n    ConstraintAttribute.Primal: lambda model, constraint: model.get_constraint_info(\n        constraint, \"Slack\"\n    ),\n    ConstraintAttribute.Dual: lambda model, constraint: model.get_constraint_info(\n        constraint, \"Dual\"\n    ),\n    ConstraintAttribute.IIS: lambda model, constraint: model._get_constraint_IIS(\n        constraint\n    )\n    > 0,\n}\n\nconstraint_attribute_set_func_map = {\n    ConstraintAttribute.Name: lambda model, constraint, value: model.set_constraint_name(\n        constraint, value\n    ),\n}\n\ncallback_info_typemap = {\n    \"BestObj\": float,\n    \"BestBnd\": float,\n    \"HasIncumbent\": int,\n    \"MipCandObj\": float,\n    \"RelaxSolObj\": float,\n    \"NodeStatus\": int,\n}\n\n\nclass Model(RawModel):\n    def __init__(self, env=None):\n        if env is None:\n            init_default_env()\n            env = DEFAULT_ENV\n        super().__init__(env)\n\n        # We must keep a reference to the environment to prevent it from being garbage collected\n        self._env = env\n        self.variable_start_values: Dict[VariableIndex, float] = dict()\n        self.nl_start_values: Dict[VariableIndex, float] = dict()\n\n        # override logging\n        self.set_raw_parameter(\"LogToConsole\", 0)\n        self.set_logging(print)\n\n    def add_variables(self, *args, **kwargs):\n        return make_variable_tupledict(self, *args, **kwargs)\n\n    @staticmethod\n    def supports_variable_attribute(attribute: VariableAttribute, settable=False):\n        if settable:\n            return attribute in variable_attribute_set_func_map\n        else:\n            return attribute in variable_attribute_get_func_map\n\n    @staticmethod\n    def supports_model_attribute(attribute: ModelAttribute, settable=False):\n        if settable:\n            return attribute in model_attribute_set_func_map\n        else:\n            return attribute in model_attribute_get_func_map\n\n    @staticmethod\n    def supports_constraint_attribute(attribute: ConstraintAttribute, settable=False):\n        if settable:\n            return attribute in constraint_attribute_set_func_map\n        else:\n            return attribute in constraint_attribute_get_func_map\n\n    def get_variable_attribute(self, variable, attribute: VariableAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown variable attribute to get: {attribute}\")\n\n        value = _direct_get_entity_attribute(\n            self,\n            variable,\n            attribute,\n            variable_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_variable_attribute(self, variable, attribute: VariableAttribute, value):\n        def e(attribute):\n            raise ValueError(f\"Unknown variable attribute to set: {attribute}\")\n\n        _direct_set_entity_attribute(\n            self,\n            variable,\n            attribute,\n            value,\n            variable_attribute_set_func_map,\n            e,\n        )\n\n    def number_of_constraints(self, type: ConstraintType):\n        attr_name = constraint_type_attribute_name_map.get(type, None)\n        if not attr_name:\n            raise ValueError(f\"Unknown constraint type: {type}\")\n        return self.get_raw_attribute_int(attr_name)\n\n    def number_of_variables(self):\n        return self.get_raw_attribute_int(\"Cols\")\n\n    def _is_mip(self):\n        ismip = self.get_raw_attribute_int(\"IsMIP\")\n        return ismip > 0\n\n    def _has_nl(self):\n        nlconstrs = self.get_raw_attribute_int(\"NLConstrs\")\n        hasnlobj = self.get_raw_attribute_int(\"HasNLObj\")\n        return nlconstrs > 0 or hasnlobj > 0\n\n    def get_model_attribute(self, attribute: ModelAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown model attribute to get: {attribute}\")\n\n        value = _direct_get_model_attribute(\n            self,\n            attribute,\n            model_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_model_attribute(self, attribute: ModelAttribute, value):\n        def e(attribute):\n            raise ValueError(f\"Unknown model attribute to set: {attribute}\")\n\n        _direct_set_model_attribute(\n            self,\n            attribute,\n            value,\n            model_attribute_set_func_map,\n            e,\n        )\n\n    def get_constraint_attribute(self, constraint, attribute: ConstraintAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown constraint attribute to get: {attribute}\")\n\n        value = _direct_get_entity_attribute(\n            self,\n            constraint,\n            attribute,\n            constraint_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_constraint_attribute(\n        self, constraint, attribute: ConstraintAttribute, value\n    ):\n        def e(attribute):\n            raise ValueError(f\"Unknown constraint attribute to set: {attribute}\")\n\n        _direct_set_entity_attribute(\n            self,\n            constraint,\n            attribute,\n            value,\n            constraint_attribute_set_func_map,\n            e,\n        )\n\n    def get_raw_parameter(self, param_name: str):\n        param_type = copt_parameter_raw_type_map[\n            self.raw_parameter_attribute_type(param_name)\n        ]\n        get_function_map = {\n            int: self.get_raw_parameter_int,\n            float: self.get_raw_parameter_double,\n        }\n        get_function = get_function_map[param_type]\n        return get_function(param_name)\n\n    def set_raw_parameter(self, param_name: str, value):\n        param_type = copt_parameter_raw_type_map[\n            self.raw_parameter_attribute_type(param_name)\n        ]\n        set_function_map = {\n            int: self.set_raw_parameter_int,\n            float: self.set_raw_parameter_double,\n        }\n        set_function = set_function_map[param_type]\n        set_function(param_name, value)\n\n    def get_raw_attribute(self, param_name: str):\n        param_type = copt_attribute_raw_type_map[\n            self.raw_parameter_attribute_type(param_name)\n        ]\n        get_function_map = {\n            int: self.get_raw_attribute_int,\n            float: self.get_raw_attribute_double,\n        }\n        get_function = get_function_map[param_type]\n        return get_function(param_name)\n\n    def optimize(self):\n        is_mip = self._is_mip()\n        is_nl = self._has_nl()\n\n        if is_mip or is_nl:\n            variable_start_values = self.variable_start_values\n            if len(variable_start_values) != 0:\n                variables = list(variable_start_values.keys())\n                values = list(variable_start_values.values())\n                variable_start_values.clear()\n\n                if is_mip:\n                    self.add_mip_start(variables, values)\n                if is_nl:\n                    self.add_nl_start(variables, values)\n\n        super().optimize()\n\n    def cb_get_info(self, what):\n        cb_info_type = callback_info_typemap.get(what, None)\n        if cb_info_type is None:\n            raise ValueError(f\"Unknown callback info type: {what}\")\n        if cb_info_type is int:\n            return self.cb_get_info_int(what)\n        elif cb_info_type is float:\n            return self.cb_get_info_double(what)\n        else:\n            raise ValueError(f\"Unknown callback info type: {what}\")\n\n    @overload\n    def add_linear_constraint(\n        self,\n        expr: Union[VariableIndex, ScalarAffineFunction, ExprBuilder],\n        sense: ConstraintSense,\n        rhs: float,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_linear_constraint(\n        self,\n        expr: Union[VariableIndex, ScalarAffineFunction, ExprBuilder],\n        interval: Tuple[float, float],\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_linear_constraint(\n        self,\n        con: ComparisonConstraint,\n        name: str = \"\",\n    ): ...\n\n    def add_linear_constraint(self, arg, *args, **kwargs):\n        if isinstance(arg, ComparisonConstraint):\n            return self._add_linear_constraint(\n                arg.lhs, arg.sense, arg.rhs, *args, **kwargs\n            )\n        else:\n            return self._add_linear_constraint(arg, *args, **kwargs)\n\n    @overload\n    def add_quadratic_constraint(\n        self,\n        expr: Union[ScalarQuadraticFunction, ExprBuilder],\n        sense: ConstraintSense,\n        rhs: float,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_quadratic_constraint(\n        self,\n        con: ComparisonConstraint,\n        name: str = \"\",\n    ): ...\n\n    def add_quadratic_constraint(self, arg, *args, **kwargs):\n        if isinstance(arg, ComparisonConstraint):\n            return self._add_quadratic_constraint(\n                arg.lhs, arg.sense, arg.rhs, *args, **kwargs\n            )\n        else:\n            return self._add_quadratic_constraint(arg, *args, **kwargs)\n\n    @overload\n    def add_nl_constraint(\n        self,\n        expr,\n        sense: ConstraintSense,\n        rhs: float,\n        /,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_nl_constraint(\n        self,\n        expr,\n        interval: Tuple[float, float],\n        /,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_nl_constraint(\n        self,\n        con,\n        /,\n        name: str = \"\",\n    ): ...\n\n    def add_nl_constraint(self, expr, *args, **kwargs):\n        graph = ExpressionGraphContext.current_graph()\n        expr = convert_to_expressionhandle(graph, expr)\n        if not isinstance(expr, ExpressionHandle):\n            raise ValueError(\n                \"Expression should be able to be converted to ExpressionHandle\"\n            )\n\n        con = self._add_single_nl_constraint(graph, expr, *args, **kwargs)\n\n        return con\n\n    def add_nl_objective(self, expr):\n        graph = ExpressionGraphContext.current_graph()\n        expr = convert_to_expressionhandle(graph, expr)\n        if not isinstance(expr, ExpressionHandle):\n            raise ValueError(\n                \"Expression should be able to be converted to ExpressionHandle\"\n            )\n        self._add_single_nl_objective(graph, expr)\n\n    add_variables = make_variable_tupledict\n    add_m_variables = make_variable_ndarray\n    add_m_linear_constraints = add_matrix_constraints\n"
  },
  {
    "path": "src/pyoptinterface/_src/cpp_graph_iter.py",
    "content": "from collections import namedtuple\nfrom .cppad_interface_ext import cpp_graph_cursor\n\ncpp_graph_instruction = namedtuple(\"cpp_graph_instruction\", [\"op\", \"args\", \"n_result\"])\n\n\nclass cpp_graph_iterator:\n    def __init__(self, graph):\n        self.graph = graph\n        self.init = False\n        self.cursor = None\n        self.N = graph.n_operator\n\n    def __iter__(self):\n        return self\n\n    def __next__(self):\n        if self.N == 0:\n            raise StopIteration\n\n        graph = self.graph\n        if not self.init:\n            self.init = True\n            self.cursor = cpp_graph_cursor()\n        else:\n            if self.cursor.op_index >= self.N:\n                raise StopIteration\n\n        cursor = self.cursor\n\n        op = graph.get_cursor_op(cursor)\n        args = graph.get_cursor_args(cursor)\n        n_result = 1\n\n        instruction = cpp_graph_instruction(op, args, n_result)\n\n        graph.next_cursor(self.cursor)\n\n        return instruction\n"
  },
  {
    "path": "src/pyoptinterface/_src/dylib.py",
    "content": "import platform\n\n\ndef dylib_suffix():\n    system = platform.system()\n    if system == \"Linux\":\n        return \"so\"\n    elif system == \"Darwin\":\n        return \"dylib\"\n    elif system == \"Windows\":\n        return \"dll\"\n    else:\n        raise RuntimeError(\"Unknown platform: %s\" % system)\n"
  },
  {
    "path": "src/pyoptinterface/_src/gurobi.py",
    "content": "import os\nimport platform\nfrom pathlib import Path\nimport re\nimport sys\nimport logging\nfrom typing import Tuple, Union, overload\n\nfrom .gurobi_model_ext import RawModel, RawEnv, GRB, load_library\nfrom .attributes import (\n    VariableAttribute,\n    ConstraintAttribute,\n    ModelAttribute,\n    ResultStatusCode,\n    TerminationStatusCode,\n)\nfrom .core_ext import (\n    VariableIndex,\n    ScalarAffineFunction,\n    ScalarQuadraticFunction,\n    ExprBuilder,\n    VariableDomain,\n    ConstraintType,\n    ConstraintSense,\n    ObjectiveSense,\n)\nfrom .nlexpr_ext import ExpressionHandle\nfrom .nlfunc import ExpressionGraphContext, convert_to_expressionhandle\nfrom .comparison_constraint import ComparisonConstraint\nfrom .solver_common import (\n    _get_model_attribute,\n    _set_model_attribute,\n    _get_entity_attribute,\n    _direct_get_entity_attribute,\n    _set_entity_attribute,\n    _direct_set_entity_attribute,\n)\nfrom .constraint_bridge import bridge_soc_quadratic_constraint\nfrom .aml import make_variable_tupledict, make_variable_ndarray\nfrom .matrix import add_matrix_constraints\n\n\ndef detected_libraries():\n    libs = []\n\n    subdir = {\n        \"Linux\": \"lib\",\n        \"Darwin\": \"lib\",\n        \"Windows\": \"bin\",\n    }[platform.system()]\n    libname_pattern = {\n        \"Linux\": r\"libgurobi(\\d+)\\.so\",\n        \"Darwin\": r\"libgurobi(\\d+)\\.dylib\",\n        \"Windows\": r\"gurobi(\\d+)\\.dll\",\n    }[platform.system()]\n    suffix_pattern = {\n        \"Linux\": \"*.so\",\n        \"Darwin\": \"*.dylib\",\n        \"Windows\": \"*.dll\",\n    }[platform.system()]\n\n    # Environment\n    home = os.environ.get(\"GUROBI_HOME\", None)\n    if home and os.path.exists(home):\n        dir = Path(home) / subdir\n        for path in dir.glob(suffix_pattern):\n            match = re.match(libname_pattern, path.name)\n            if match:\n                libs.append(str(path))\n\n    # gurobipy installation\n    try:\n        import gurobipy\n\n        dir = Path(gurobipy.__path__[0])\n        if platform.system() != \"Windows\":\n            dir = dir / \".libs\"\n        for path in dir.glob(suffix_pattern):\n            match = re.match(libname_pattern, path.name)\n            if match:\n                libs.append(str(path))\n    except Exception:\n        pass\n\n    # conda/pixi environment\n    prefix = Path(sys.prefix)\n    dir = prefix / subdir\n    for path in dir.glob(suffix_pattern):\n        match = re.match(libname_pattern, path.name)\n        if match:\n            libs.append(str(path))\n\n    # default names\n    gurobi_names = [\n        \"gurobi130\",\n        \"gurobi120\",\n        \"gurobi110\",\n    ]\n    default_libname = {\n        \"Linux\": [\"lib\" + name + \".so\" for name in gurobi_names],\n        \"Darwin\": [\"lib\" + name + \".dylib\" for name in gurobi_names],\n        \"Windows\": [name + \".dll\" for name in gurobi_names],\n    }[platform.system()]\n    libs.extend(default_libname)\n\n    return libs\n\n\ndef autoload_library():\n    libs = detected_libraries()\n    for lib in libs:\n        ret = load_library(lib)\n        if ret:\n            logging.info(f\"Loaded Gurobi library: {lib}\")\n            return True\n    return False\n\n\nautoload_library()\n\nDEFAULT_ENV = None\n\n\ndef init_default_env():\n    global DEFAULT_ENV\n    if DEFAULT_ENV is None:\n        DEFAULT_ENV = RawEnv()\n\n\n# Variable Attribute\nvariable_attribute_get_func_map = {\n    VariableAttribute.Value: lambda model, v: model.get_variable_raw_attribute_double(\n        v, \"X\"\n    ),\n    VariableAttribute.LowerBound: lambda model, v: model.get_variable_raw_attribute_double(\n        v, \"LB\"\n    ),\n    VariableAttribute.UpperBound: lambda model, v: model.get_variable_raw_attribute_double(\n        v, \"UB\"\n    ),\n    VariableAttribute.PrimalStart: lambda model, v: model.get_variable_raw_attribute_double(\n        v, \"Start\"\n    ),\n    VariableAttribute.Domain: lambda model, v: model.get_variable_raw_attribute_char(\n        v, \"VType\"\n    ),\n    VariableAttribute.Name: lambda model, v: model.get_variable_raw_attribute_string(\n        v, \"VarName\"\n    ),\n    VariableAttribute.IISLowerBound: lambda model, v: model.get_variable_raw_attribute_int(\n        v, \"IISLB\"\n    )\n    > 0,\n    VariableAttribute.IISUpperBound: lambda model, v: model.get_variable_raw_attribute_int(\n        v, \"IISUB\"\n    )\n    > 0,\n    VariableAttribute.ReducedCost: lambda model, v: model.get_variable_raw_attribute_double(\n        v, \"RC\"\n    ),\n}\n\nvariable_attribute_get_translate_func_map = {\n    VariableAttribute.Domain: lambda v: {\n        GRB.BINARY: VariableDomain.Binary,\n        GRB.INTEGER: VariableDomain.Integer,\n        GRB.CONTINUOUS: VariableDomain.Continuous,\n        GRB.SEMICONT: VariableDomain.SemiContinuous,\n    }[v],\n}\n\nvariable_attribute_set_translate_func_map = {\n    VariableAttribute.Domain: lambda v: {\n        VariableDomain.Binary: GRB.BINARY,\n        VariableDomain.Integer: GRB.INTEGER,\n        VariableDomain.Continuous: GRB.CONTINUOUS,\n        VariableDomain.SemiContinuous: GRB.SEMICONT,\n    }[v],\n}\n\nvariable_attribute_set_func_map = {\n    VariableAttribute.LowerBound: lambda model, v, x: model.set_variable_raw_attribute_double(\n        v, \"LB\", x\n    ),\n    VariableAttribute.UpperBound: lambda model, v, x: model.set_variable_raw_attribute_double(\n        v, \"UB\", x\n    ),\n    VariableAttribute.PrimalStart: lambda model, v, x: model.set_variable_raw_attribute_double(\n        v, \"Start\", x\n    ),\n    VariableAttribute.Domain: lambda model, v, x: model.set_variable_raw_attribute_char(\n        v, \"VType\", x\n    ),\n    VariableAttribute.Name: lambda model, v, x: model.set_variable_raw_attribute_string(\n        v, \"VarName\", x\n    ),\n}\n\n# Model Attribute\n\nconstraint_type_attribute_name_map = {\n    ConstraintType.Linear: \"NumConstrs\",\n    ConstraintType.Quadratic: \"NumQConstrs\",\n}\n\n_RAW_STATUS_STRINGS = [  # TerminationStatus, RawStatusString\n    (\n        TerminationStatusCode.OPTIMIZE_NOT_CALLED,\n        \"Model is loaded, but no solution information is available.\",\n    ),\n    (\n        TerminationStatusCode.OPTIMAL,\n        \"Model was solved to optimality (subject to tolerances), and an optimal solution is available.\",\n    ),\n    (TerminationStatusCode.INFEASIBLE, \"Model was proven to be infeasible.\"),\n    (\n        TerminationStatusCode.INFEASIBLE_OR_UNBOUNDED,\n        \"Model was proven to be either infeasible or unbounded. To obtain a more definitive conclusion, set the DualReductions parameter to 0 and reoptimize.\",\n    ),\n    (\n        TerminationStatusCode.DUAL_INFEASIBLE,\n        \"Model was proven to be unbounded. Important note: an unbounded status indicates the presence of an unbounded ray that allows the objective to improve without limit. It says nothing about whether the model has a feasible solution. If you require information on feasibility, you should set the objective to zero and reoptimize.\",\n    ),\n    (\n        TerminationStatusCode.OBJECTIVE_LIMIT,\n        \"Optimal objective for model was proven to be worse than the value specified in the Cutoff parameter. No solution information is available.\",\n    ),\n    (\n        TerminationStatusCode.ITERATION_LIMIT,\n        \"Optimization terminated because the total number of simplex iterations performed exceeded the value specified in the IterationLimit parameter, or because the total number of barrier iterations exceeded the value specified in the BarIterLimit parameter.\",\n    ),\n    (\n        TerminationStatusCode.NODE_LIMIT,\n        \"Optimization terminated because the total number of branch-and-cut nodes explored exceeded the value specified in the NodeLimit parameter.\",\n    ),\n    (\n        TerminationStatusCode.TIME_LIMIT,\n        \"Optimization terminated because the time expended exceeded the value specified in the TimeLimit parameter.\",\n    ),\n    (\n        TerminationStatusCode.SOLUTION_LIMIT,\n        \"Optimization terminated because the number of solutions found reached the value specified in the SolutionLimit parameter.\",\n    ),\n    (TerminationStatusCode.INTERRUPTED, \"Optimization was terminated by the user.\"),\n    (\n        TerminationStatusCode.NUMERICAL_ERROR,\n        \"Optimization was terminated due to unrecoverable numerical difficulties.\",\n    ),\n    (\n        TerminationStatusCode.LOCALLY_SOLVED,\n        \"Unable to satisfy optimality tolerances; a sub-optimal solution is available.\",\n    ),\n    (\n        TerminationStatusCode.OTHER_ERROR,\n        \"An asynchronous optimization call was made, but the associated optimization run is not yet complete.\",\n    ),\n    (\n        TerminationStatusCode.OBJECTIVE_LIMIT,\n        \"User specified an objective limit (a bound on either the best objective or the best bound), and that limit has been reached.\",\n    ),\n    (\n        TerminationStatusCode.OTHER_LIMIT,\n        \"Optimization terminated because the work expended exceeded the value specified in the WorkLimit parameter.\",\n    ),\n    (\n        TerminationStatusCode.MEMORY_LIMIT,\n        \"Optimization terminated because the total amount of allocated memory exceeded the value specified in the SoftMemLimit parameter.\",\n    ),\n    (\n        TerminationStatusCode.LOCALLY_SOLVED,\n        \"Model solved to local optimality. A solution satisfying the first-order optimality conditions (subject to tolerances) was found and is available.\",\n    ),\n    (\n        TerminationStatusCode.LOCALLY_INFEASIBLE,\n        \"Model appears to be locally infeasible. A first-order minimizer of a measure for the constraint violations was found.\",\n    ),\n]\n\ngurobi_raw_type_map = {\n    0: \"char\",\n    1: int,\n    2: float,\n    3: str,\n}\n\n\ndef get_terminationstatus(model):\n    status = model.get_model_raw_attribute_int(\"Status\")\n    assert status >= 1 and status <= 19, f\"Unknown status code: {status}\"\n    return _RAW_STATUS_STRINGS[status - 1][0]\n\n\ndef get_primalstatus(model):\n    termination_status = get_terminationstatus(model)\n    if termination_status in (\n        TerminationStatusCode.DUAL_INFEASIBLE,\n        TerminationStatusCode.INFEASIBLE_OR_UNBOUNDED,\n    ):\n        try:\n            model.get_model_raw_attribute_list_double(\"UnbdRay\", [0])\n            return ResultStatusCode.INFEASIBILITY_CERTIFICATE\n        except:\n            return ResultStatusCode.NO_SOLUTION\n    solcount = model.get_model_raw_attribute_int(\"SolCount\")\n    if solcount == 0:\n        return ResultStatusCode.NO_SOLUTION\n    else:\n        return ResultStatusCode.FEASIBLE_POINT\n\n\ndef get_dualstatus(model):\n    if model.get_model_raw_attribute_int(\"IsMIP\") != 0:\n        return ResultStatusCode.NO_SOLUTION\n    elif (\n        model.get_model_raw_attribute_int(\"IsQCP\") != 0\n        and model.get_model_raw_attribute(\"QCPDual\") != 1\n    ):\n        return ResultStatusCode.NO_SOLUTION\n    termination_status = get_terminationstatus(model)\n    if termination_status in (\n        TerminationStatusCode.DUAL_INFEASIBLE,\n        TerminationStatusCode.INFEASIBLE_OR_UNBOUNDED,\n    ):\n        try:\n            model.get_model_raw_attribute_list_double(\"FarkasDual\", [0])\n            return ResultStatusCode.INFEASIBILITY_CERTIFICATE\n        except:\n            return ResultStatusCode.NO_SOLUTION\n    solcount = model.get_model_raw_attribute_int(\"SolCount\")\n    if solcount == 0:\n        return ResultStatusCode.NO_SOLUTION\n    try:\n        model.get_model_raw_attribute_list_double(\"RC\", [0])\n        return ResultStatusCode.FEASIBLE_POINT\n    except:\n        return ResultStatusCode.NO_SOLUTION\n\n\ndef get_rawstatusstring(model):\n    status = model.get_model_raw_attribute_int(\"Status\")\n    assert status >= 1 and status <= 15, f\"Unknown status code: {status}\"\n    return _RAW_STATUS_STRINGS[status - 1][1]\n\n\ndef get_silent(model):\n    return model.get_model_raw_parameter_int(\"OutputFlag\") == 0\n\n\nmodel_attribute_get_func_map = {\n    ModelAttribute.Name: lambda model: model.get_model_raw_attribute_string(\n        \"ModelName\"\n    ),\n    ModelAttribute.ObjectiveSense: lambda model: model.get_model_raw_attribute_int(\n        \"ModelSense\"\n    ),\n    ModelAttribute.BarrierIterations: lambda model: model.get_model_raw_attribute_int(\n        \"BarIterCount\"\n    ),\n    ModelAttribute.DualObjectiveValue: lambda model: model.get_model_raw_attribute_double(\n        \"ObjBound\"\n    ),\n    ModelAttribute.NodeCount: lambda model: model.get_model_raw_attribute_int(\n        \"NodeCount\"\n    ),\n    ModelAttribute.ObjectiveBound: lambda model: model.get_model_raw_attribute_double(\n        \"ObjBound\"\n    ),\n    ModelAttribute.ObjectiveValue: lambda model: model.get_model_raw_attribute_double(\n        \"ObjVal\"\n    ),\n    ModelAttribute.SimplexIterations: lambda model: model.get_model_raw_attribute_int(\n        \"IterCount\"\n    ),\n    ModelAttribute.SolveTimeSec: lambda model: model.get_model_raw_attribute_double(\n        \"RunTime\"\n    ),\n    ModelAttribute.NumberOfThreads: lambda model: model.get_raw_parameter_int(\n        \"Threads\"\n    ),\n    ModelAttribute.RelativeGap: lambda model: model.get_raw_parameter_double(\"MIPGap\"),\n    ModelAttribute.TimeLimitSec: lambda model: model.get_raw_parameter_double(\n        \"TimeLimit\"\n    ),\n    ModelAttribute.DualStatus: get_dualstatus,\n    ModelAttribute.PrimalStatus: get_primalstatus,\n    ModelAttribute.RawStatusString: get_rawstatusstring,\n    ModelAttribute.TerminationStatus: get_terminationstatus,\n    ModelAttribute.Silent: get_silent,\n    ModelAttribute.SolverName: lambda _: \"Gurobi\",\n    ModelAttribute.SolverVersion: lambda model: model.version_string(),\n}\n\nmodel_attribute_get_translate_func_map = {\n    ModelAttribute.ObjectiveSense: lambda v: {\n        GRB.MINIMIZE: ObjectiveSense.Minimize,\n        GRB.MAXIMIZE: ObjectiveSense.Maximize,\n    }[v],\n}\n\nmodel_attribute_set_translate_func_map = {\n    ModelAttribute.ObjectiveSense: lambda v: {\n        ObjectiveSense.Minimize: GRB.MINIMIZE,\n        ObjectiveSense.Maximize: GRB.MAXIMIZE,\n    }[v],\n}\n\n\ndef set_silent(model, value: bool):\n    if value:\n        model.set_raw_parameter_int(\"OutputFlag\", 0)\n    else:\n        model.set_raw_parameter_int(\"OutputFlag\", 1)\n\n\nmodel_attribute_set_func_map = {\n    ModelAttribute.Name: lambda model, v: model.set_model_raw_attribute_string(\n        \"ModelName\", v\n    ),\n    ModelAttribute.ObjectiveSense: lambda model, v: model.set_model_raw_attribute_int(\n        \"ModelSense\", v\n    ),\n    ModelAttribute.NumberOfThreads: lambda model, v: model.set_raw_parameter_int(\n        \"Threads\", v\n    ),\n    ModelAttribute.RelativeGap: lambda model, v: model.set_raw_parameter_double(\n        \"MIPGap\", v\n    ),\n    ModelAttribute.TimeLimitSec: lambda model, v: model.set_raw_parameter_double(\n        \"TimeLimit\", v\n    ),\n    ModelAttribute.Silent: set_silent,\n}\n\n# Constraint Attribute\n\n\ndef get_constraint_name(model, constraint):\n    type = constraint.type\n    attr_name_dict = {\n        ConstraintType.Linear: \"ConstrName\",\n        ConstraintType.Quadratic: \"QConstrName\",\n    }\n    attr_name = attr_name_dict.get(type, None)\n    if not attr_name:\n        raise ValueError(f\"Unknown constraint type: {type}\")\n    return model.get_constraint_raw_attribute_string(constraint, attr_name)\n\n\ndef get_constraint_primal(model, constraint):\n    # Linear : RHS - Slack\n    # Quadratic : QCRHS - QCSlack\n    type = constraint.type\n    attr_name_dict = {\n        ConstraintType.Linear: (\"RHS\", \"Slack\"),\n        ConstraintType.Quadratic: (\"QCRHS\", \"QCSlack\"),\n    }\n    attr_name = attr_name_dict.get(type, None)\n    if not attr_name:\n        raise ValueError(f\"Unknown constraint type: {type}\")\n    rhs = model.get_constraint_raw_attribute_double(constraint, attr_name[0])\n    slack = model.get_constraint_raw_attribute_double(constraint, attr_name[1])\n    return rhs - slack\n\n\ndef get_constraint_dual(model, constraint):\n    type = constraint.type\n    attr_name_dict = {\n        ConstraintType.Linear: \"Pi\",\n        ConstraintType.Quadratic: \"QCPi\",\n    }\n    attr_name = attr_name_dict.get(type, None)\n    if not attr_name:\n        raise ValueError(f\"Unknown constraint type: {type}\")\n    return model.get_constraint_raw_attribute_double(constraint, attr_name)\n\n\ndef get_constraint_IIS(model, constraint):\n    type = constraint.type\n    attr_name_dict = {\n        ConstraintType.Linear: \"IISConstr\",\n        ConstraintType.SOS: \"IISSOS\",\n        ConstraintType.Quadratic: \"IISQConstr\",\n    }\n    attr_name = attr_name_dict.get(type, None)\n    if not attr_name:\n        raise ValueError(f\"Unknown constraint type: {type}\")\n    return model.get_constraint_raw_attribute_int(constraint, attr_name) > 0\n\n\nconstraint_attribute_get_func_map = {\n    ConstraintAttribute.Name: get_constraint_name,\n    ConstraintAttribute.Primal: get_constraint_primal,\n    ConstraintAttribute.Dual: get_constraint_dual,\n    ConstraintAttribute.IIS: get_constraint_IIS,\n}\n\nconstraint_attribute_set_func_map = {\n    ConstraintAttribute.Name: lambda model, constraint, value: model.set_constraint_name(\n        constraint, value\n    ),\n}\n\ncallback_info_typemap = {\n    GRB.Callback.RUNTIME: float,\n    GRB.Callback.WORK: float,\n    GRB.Callback.PRE_COLDEL: int,\n    GRB.Callback.PRE_ROWDEL: int,\n    GRB.Callback.PRE_SENCHG: int,\n    GRB.Callback.PRE_BNDCHG: int,\n    GRB.Callback.PRE_COECHG: int,\n    GRB.Callback.SPX_ITRCNT: float,\n    GRB.Callback.SPX_OBJVAL: float,\n    GRB.Callback.SPX_PRIMINF: float,\n    GRB.Callback.SPX_DUALINF: float,\n    GRB.Callback.SPX_ISPERT: int,\n    GRB.Callback.MIP_OBJBST: float,\n    GRB.Callback.MIP_OBJBND: float,\n    GRB.Callback.MIP_NODCNT: float,\n    GRB.Callback.MIP_SOLCNT: int,\n    GRB.Callback.MIP_CUTCNT: int,\n    GRB.Callback.MIP_NODLFT: float,\n    GRB.Callback.MIP_ITRCNT: float,\n    GRB.Callback.MIP_OPENSCENARIOS: int,\n    GRB.Callback.MIP_PHASE: int,\n    GRB.Callback.MIPSOL_OBJ: float,\n    GRB.Callback.MIPSOL_OBJBST: float,\n    GRB.Callback.MIPSOL_OBJBND: float,\n    GRB.Callback.MIPSOL_NODCNT: float,\n    GRB.Callback.MIPSOL_SOLCNT: int,\n    GRB.Callback.MIPSOL_OPENSCENARIOS: int,\n    GRB.Callback.MIPSOL_PHASE: int,\n    GRB.Callback.MIPNODE_STATUS: int,\n    GRB.Callback.MIPNODE_OBJBST: float,\n    GRB.Callback.MIPNODE_OBJBND: float,\n    GRB.Callback.MIPNODE_NODCNT: float,\n    GRB.Callback.MIPNODE_SOLCNT: int,\n    GRB.Callback.MIPNODE_OPENSCENARIOS: int,\n    GRB.Callback.MIPNODE_PHASE: int,\n    GRB.Callback.MIPNODE_REL: float,\n    GRB.Callback.BARRIER_ITRCNT: int,\n    GRB.Callback.BARRIER_PRIMOBJ: float,\n    GRB.Callback.BARRIER_DUALOBJ: float,\n    GRB.Callback.BARRIER_PRIMINF: float,\n    GRB.Callback.BARRIER_DUALINF: float,\n    GRB.Callback.BARRIER_COMPL: float,\n}\n\n\nclass Env(RawEnv):\n    def set_raw_parameter(self, param_name: str, value):\n        param_type = gurobi_raw_type_map[self.raw_parameter_type(param_name)]\n        set_function_map = {\n            int: self.set_raw_parameter_int,\n            float: self.set_raw_parameter_double,\n            str: self.set_raw_parameter_string,\n        }\n        set_function = set_function_map[param_type]\n        set_function(param_name, value)\n\n\nclass Model(RawModel):\n    def __init__(self, env=None):\n        if env is None:\n            init_default_env()\n            env = DEFAULT_ENV\n        super().__init__(env)\n\n        # We must keep a reference to the environment to prevent it from being garbage collected\n        self._env = env\n\n        # Replace default logging behavior to use Python print\n        # otherwise it prints directly to stdout/stderr bypassing Python and causing issues in Jupyter notebooks\n        self.set_raw_parameter(\"LogToConsole\", 0)\n        self.set_logging(lambda msg: print(msg, end=\"\"))\n\n    @staticmethod\n    def supports_variable_attribute(attribute: VariableAttribute, settable=False):\n        if settable:\n            return attribute in variable_attribute_set_func_map\n        else:\n            return attribute in variable_attribute_get_func_map\n\n    @staticmethod\n    def supports_model_attribute(attribute: ModelAttribute, settable=False):\n        if settable:\n            return attribute in model_attribute_set_func_map\n        else:\n            return attribute in model_attribute_get_func_map\n\n    @staticmethod\n    def supports_constraint_attribute(attribute: ConstraintAttribute, settable=False):\n        if settable:\n            return attribute in constraint_attribute_set_func_map\n        else:\n            return attribute in constraint_attribute_get_func_map\n\n    def get_variable_attribute(self, variable, attribute: VariableAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown variable attribute to get: {attribute}\")\n\n        value = _get_entity_attribute(\n            self,\n            variable,\n            attribute,\n            variable_attribute_get_func_map,\n            variable_attribute_get_translate_func_map,\n            e,\n        )\n        return value\n\n    def set_variable_attribute(self, variable, attribute: VariableAttribute, value):\n        def e(attribute):\n            raise ValueError(f\"Unknown variable attribute to set: {attribute}\")\n\n        _set_entity_attribute(\n            self,\n            variable,\n            attribute,\n            value,\n            variable_attribute_set_func_map,\n            variable_attribute_set_translate_func_map,\n            e,\n        )\n\n    def number_of_constraints(self, type: ConstraintType):\n        attr_name = constraint_type_attribute_name_map.get(type, None)\n        if not attr_name:\n            raise ValueError(f\"Unknown constraint type: {type}\")\n        return self.get_model_raw_attribute_int(attr_name)\n\n    def number_of_variables(self):\n        return self.get_model_raw_attribute_int(\"NumVars\")\n\n    def get_model_attribute(self, attribute: ModelAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown model attribute to get: {attribute}\")\n\n        value = _get_model_attribute(\n            self,\n            attribute,\n            model_attribute_get_func_map,\n            model_attribute_get_translate_func_map,\n            e,\n        )\n        return value\n\n    def set_model_attribute(self, attribute: ModelAttribute, value):\n        def e(attribute):\n            raise ValueError(f\"Unknown model attribute to set: {attribute}\")\n\n        _set_model_attribute(\n            self,\n            attribute,\n            value,\n            model_attribute_set_func_map,\n            model_attribute_set_translate_func_map,\n            e,\n        )\n\n    def get_constraint_attribute(self, constraint, attribute: ConstraintAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown constraint attribute to get: {attribute}\")\n\n        value = _direct_get_entity_attribute(\n            self,\n            constraint,\n            attribute,\n            constraint_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_constraint_attribute(\n        self, constraint, attribute: ConstraintAttribute, value\n    ):\n        def e(attribute):\n            raise ValueError(f\"Unknown constraint attribute to set: {attribute}\")\n\n        _direct_set_entity_attribute(\n            self,\n            constraint,\n            attribute,\n            value,\n            constraint_attribute_set_func_map,\n            e,\n        )\n\n    def get_raw_parameter(self, param_name: str):\n        param_type = gurobi_raw_type_map[self.raw_parameter_type(param_name)]\n        get_function_map = {\n            int: self.get_raw_parameter_int,\n            float: self.get_raw_parameter_double,\n            str: self.get_raw_parameter_string,\n        }\n        get_function = get_function_map[param_type]\n        return get_function(param_name)\n\n    def set_raw_parameter(self, param_name: str, value):\n        param_type = gurobi_raw_type_map[self.raw_parameter_type(param_name)]\n        set_function_map = {\n            int: self.set_raw_parameter_int,\n            float: self.set_raw_parameter_double,\n            str: self.set_raw_parameter_string,\n        }\n        set_function = set_function_map[param_type]\n        set_function(param_name, value)\n\n    def get_model_raw_attribute(self, name: str):\n        param_type = gurobi_raw_type_map[self.raw_attribute_type(name)]\n        get_function_map = {\n            int: self.get_model_raw_attribute_int,\n            float: self.get_model_raw_attribute_double,\n            str: self.get_model_raw_attribute_string,\n        }\n        get_function = get_function_map[param_type]\n        return get_function(name)\n\n    def set_model_raw_attribute(self, name: str, value):\n        param_type = gurobi_raw_type_map[self.raw_attribute_type(name)]\n        set_function_map = {\n            int: self.set_model_raw_attribute_int,\n            float: self.set_model_raw_attribute_double,\n            str: self.set_model_raw_attribute_string,\n        }\n        set_function = set_function_map[param_type]\n        set_function(name, value)\n\n    def get_variable_raw_attribute(self, variable, name: str):\n        param_type = gurobi_raw_type_map[self.raw_attribute_type(name)]\n        get_function_map = {\n            \"char\": self.get_variable_raw_attribute_char,\n            int: self.get_variable_raw_attribute_int,\n            float: self.get_variable_raw_attribute_double,\n            str: self.get_variable_raw_attribute_string,\n        }\n        get_function = get_function_map[param_type]\n        return get_function(variable, name)\n\n    def set_variable_raw_attribute(self, variable, name: str, value):\n        param_type = gurobi_raw_type_map[self.raw_attribute_type(name)]\n        set_function_map = {\n            \"char\": self.set_variable_raw_attribute_char,\n            int: self.set_variable_raw_attribute_int,\n            float: self.set_variable_raw_attribute_double,\n            str: self.set_variable_raw_attribute_string,\n        }\n        set_function = set_function_map[param_type]\n        set_function(variable, name, value)\n\n    def get_constraint_raw_attribute(self, constraint, name: str):\n        param_type = gurobi_raw_type_map[self.raw_attribute_type(name)]\n        get_function_map = {\n            \"char\": self.get_constraint_raw_attribute_char,\n            int: self.get_constraint_raw_attribute_int,\n            float: self.get_constraint_raw_attribute_double,\n            str: self.get_constraint_raw_attribute_string,\n        }\n        get_function = get_function_map[param_type]\n        return get_function(constraint, name)\n\n    def set_constraint_raw_attribute(self, constraint, name: str, value):\n        param_type = gurobi_raw_type_map[self.raw_attribute_type(name)]\n        set_function_map = {\n            \"char\": self.set_constraint_raw_attribute_char,\n            int: self.set_constraint_raw_attribute_int,\n            float: self.set_constraint_raw_attribute_double,\n            str: self.set_constraint_raw_attribute_string,\n        }\n        set_function = set_function_map[param_type]\n        set_function(constraint, name, value)\n\n    def cb_get_info(self, what):\n        cb_info_type = callback_info_typemap.get(what, None)\n        if cb_info_type is None:\n            raise ValueError(f\"Unknown callback info type: {what}\")\n        if cb_info_type is int:\n            return self.cb_get_info_int(what)\n        elif cb_info_type is float:\n            return self.cb_get_info_double(what)\n        else:\n            raise ValueError(f\"Unknown callback info type: {what}\")\n\n    @overload\n    def add_linear_constraint(\n        self,\n        expr: Union[VariableIndex, ScalarAffineFunction, ExprBuilder],\n        sense: ConstraintSense,\n        rhs: float,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_linear_constraint(\n        self,\n        con: ComparisonConstraint,\n        name: str = \"\",\n    ): ...\n\n    def add_linear_constraint(self, arg, *args, **kwargs):\n        if isinstance(arg, ComparisonConstraint):\n            return self._add_linear_constraint(\n                arg.lhs, arg.sense, arg.rhs, *args, **kwargs\n            )\n        else:\n            return self._add_linear_constraint(arg, *args, **kwargs)\n\n    @overload\n    def add_quadratic_constraint(\n        self,\n        expr: Union[ScalarQuadraticFunction, ExprBuilder],\n        sense: ConstraintSense,\n        rhs: float,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_quadratic_constraint(\n        self,\n        con: ComparisonConstraint,\n        name: str = \"\",\n    ): ...\n\n    def add_quadratic_constraint(self, arg, *args, **kwargs):\n        if isinstance(arg, ComparisonConstraint):\n            return self._add_quadratic_constraint(\n                arg.lhs, arg.sense, arg.rhs, *args, **kwargs\n            )\n        else:\n            return self._add_quadratic_constraint(arg, *args, **kwargs)\n\n    @overload\n    def add_nl_constraint(\n        self,\n        expr,\n        sense: ConstraintSense,\n        rhs: float,\n        /,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_nl_constraint(\n        self,\n        expr,\n        interval: Tuple[float, float],\n        /,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_nl_constraint(\n        self,\n        con,\n        /,\n        name: str = \"\",\n    ): ...\n\n    def add_nl_constraint(self, expr, *args, **kwargs):\n        graph = ExpressionGraphContext.current_graph()\n        expr = convert_to_expressionhandle(graph, expr)\n        if not isinstance(expr, ExpressionHandle):\n            raise ValueError(\n                \"Expression should be able to be converted to ExpressionHandle\"\n            )\n\n        con = self._add_single_nl_constraint(graph, expr, *args, **kwargs)\n\n        return con\n\n    def add_nl_objective(self, expr):\n        graph = ExpressionGraphContext.current_graph()\n        expr = convert_to_expressionhandle(graph, expr)\n        if not isinstance(expr, ExpressionHandle):\n            raise ValueError(\n                \"Expression should be able to be converted to ExpressionHandle\"\n            )\n        self._add_single_nl_objective(graph, expr)\n\n    add_variables = make_variable_tupledict\n    add_m_variables = make_variable_ndarray\n    add_m_linear_constraints = add_matrix_constraints\n    add_second_order_cone_constraint = bridge_soc_quadratic_constraint\n"
  },
  {
    "path": "src/pyoptinterface/_src/highs.py",
    "content": "import logging\nimport os\nimport platform\nfrom pathlib import Path\nfrom typing import Dict, Union, overload\n\nfrom .highs_model_ext import (\n    RawModel,\n    HighsSolutionStatus,\n    Enum,\n    load_library,\n)\nfrom .attributes import (\n    VariableAttribute,\n    ConstraintAttribute,\n    ModelAttribute,\n    ResultStatusCode,\n    TerminationStatusCode,\n)\nfrom .core_ext import (\n    VariableIndex,\n    ScalarAffineFunction,\n    ExprBuilder,\n    ConstraintType,\n    ConstraintSense,\n)\nfrom .comparison_constraint import ComparisonConstraint\nfrom .solver_common import (\n    _direct_get_model_attribute,\n    _direct_set_model_attribute,\n    _direct_get_entity_attribute,\n    _direct_set_entity_attribute,\n)\nfrom .aml import make_variable_tupledict, make_variable_ndarray\nfrom .matrix import add_matrix_constraints\n\n\ndef detected_libraries():\n    libs = []\n\n    subdir = {\n        \"Linux\": \"lib\",\n        \"Darwin\": \"lib\",\n        \"Windows\": \"bin\",\n    }[platform.system()]\n    libname = {\n        \"Linux\": \"libhighs.so\",\n        \"Darwin\": \"libhighs.dylib\",\n        \"Windows\": \"highs.dll\",\n    }[platform.system()]\n\n    # Environment\n    home = os.environ.get(\"HiGHS_HOME\", None)\n    if home and os.path.exists(home):\n        lib = Path(home) / subdir / libname\n        if lib.exists():\n            libs.append(str(lib))\n\n    # HiGHS pypi installation\n    try:\n        import highsbox\n\n        home = highsbox.highs_dist_dir()\n\n        if os.path.exists(home):\n            lib = Path(home) / subdir / libname\n            if lib.exists():\n                libs.append(str(lib))\n    except Exception:\n        pass\n\n    # default names\n    default_libname = libname\n    libs.append(default_libname)\n\n    return libs\n\n\ndef autoload_library():\n    libs = detected_libraries()\n    for lib in libs:\n        ret = load_library(lib)\n        if ret:\n            logging.info(f\"Loaded HiGHS library: {lib}\")\n            return True\n    return False\n\n\nautoload_library()\n\n\nvariable_attribute_get_func_map = {\n    VariableAttribute.Value: lambda model, v: model.get_value(v),\n    VariableAttribute.LowerBound: lambda model, v: model.get_variable_lower_bound(v),\n    VariableAttribute.UpperBound: lambda model, v: model.get_variable_upper_bound(v),\n    VariableAttribute.PrimalStart: lambda model, v: model.mip_start_values.get(v, None),\n    VariableAttribute.Domain: lambda model, v: model.get_variable_type(v),\n    VariableAttribute.Name: lambda model, v: model.get_variable_name(v),\n    VariableAttribute.ReducedCost: lambda model, v: model.get_variable_dual(v),\n}\n\nvariable_attribute_set_func_map = {\n    VariableAttribute.LowerBound: lambda model, v, val: model.set_variable_lower_bound(\n        v, val\n    ),\n    VariableAttribute.UpperBound: lambda model, v, val: model.set_variable_upper_bound(\n        v, val\n    ),\n    VariableAttribute.PrimalStart: lambda model, v, val: model.mip_start_values.__setitem__(\n        v, val\n    ),\n    VariableAttribute.Domain: lambda model, v, val: model.set_variable_type(v, val),\n    VariableAttribute.Name: lambda model, v, val: model.set_variable_name(v, val),\n}\n\n\ndef get_dualstatus(model):\n    sol = model.solution\n    if sol.dual_solution_status == Enum.kHighsSolutionStatusFeasible:\n        return ResultStatusCode.FEASIBLE_POINT\n    elif sol.dual_solution_status == Enum.kHighsSolutionStatusInfeasible:\n        return ResultStatusCode.INFEASIBLE_POINT\n    elif model.solution.has_dual_ray:\n        return ResultStatusCode.INFEASIBILITY_CERTIFICATE\n    else:\n        return ResultStatusCode.NO_SOLUTION\n\n\ndef get_primalstatus(model):\n    sol = model.solution\n    if sol.primal_solution_status == Enum.kHighsSolutionStatusFeasible:\n        return ResultStatusCode.FEASIBLE_POINT\n    elif sol.primal_solution_status == Enum.kHighsSolutionStatusInfeasible:\n        return ResultStatusCode.INFEASIBLE_POINT\n    elif sol.has_primal_ray:\n        return ResultStatusCode.INFEASIBILITY_CERTIFICATE\n    return ResultStatusCode.NO_SOLUTION\n\n\ndef get_rawstatusstring(model):\n    status = model.solution.status\n    model_status = model.solution.model_status\n    if status == HighsSolutionStatus.OPTIMIZE_NOT_CALLED:\n        return \"OPTIMIZE_NOT_CALLED\"\n    elif status == HighsSolutionStatus.OPTIMIZE_ERROR:\n        return \"There was an error calling optimize!\"\n    elif model_status == Enum.kHighsModelStatusNotset:\n        return \"kHighsModelStatusNotset\"\n    elif model_status == Enum.kHighsModelStatusLoadError:\n        return \"kHighsModelStatusLoadError\"\n    elif model_status == Enum.kHighsModelStatusModelError:\n        return \"kHighsModelStatusModelError\"\n    elif model_status == Enum.kHighsModelStatusPresolveError:\n        return \"kHighsModelStatusPresolveError\"\n    elif model_status == Enum.kHighsModelStatusSolveError:\n        return \"kHighsModelStatusSolveError\"\n    elif model_status == Enum.kHighsModelStatusPostsolveError:\n        return \"kHighsModelStatusPostsolveError\"\n    elif model_status == Enum.kHighsModelStatusModelEmpty:\n        return \"kHighsModelStatusModelEmpty\"\n    elif model_status == Enum.kHighsModelStatusOptimal:\n        return \"kHighsModelStatusOptimal\"\n    elif model_status == Enum.kHighsModelStatusInfeasible:\n        return \"kHighsModelStatusInfeasible\"\n    elif model_status == Enum.kHighsModelStatusUnboundedOrInfeasible:\n        return \"kHighsModelStatusUnboundedOrInfeasible\"\n    elif model_status == Enum.kHighsModelStatusUnbounded:\n        return \"kHighsModelStatusUnbounded\"\n    elif model_status == Enum.kHighsModelStatusObjectiveBound:\n        return \"kHighsModelStatusObjectiveBound\"\n    elif model_status == Enum.kHighsModelStatusObjectiveTarget:\n        return \"kHighsModelStatusObjectiveTarget\"\n    elif model_status == Enum.kHighsModelStatusTimeLimit:\n        return \"kHighsModelStatusTimeLimit\"\n    elif model_status == Enum.kHighsModelStatusIterationLimit:\n        return \"kHighsModelStatusIterationLimit\"\n    else:\n        assert model_status == Enum.kHighsModelStatusUnknown\n        return \"kHighsModelStatusUnknown\"\n\n\ndef get_terminationstatus(model):\n    status = model.solution.status\n    model_status = model.solution.model_status\n    if status == HighsSolutionStatus.OPTIMIZE_NOT_CALLED:\n        return TerminationStatusCode.OPTIMIZE_NOT_CALLED\n    elif status == HighsSolutionStatus.OPTIMIZE_ERROR:\n        return TerminationStatusCode.OTHER_ERROR\n    elif model_status == Enum.kHighsModelStatusNotset:\n        return TerminationStatusCode.OTHER_ERROR\n    elif model_status == Enum.kHighsModelStatusLoadError:\n        return TerminationStatusCode.OTHER_ERROR\n    elif model_status == Enum.kHighsModelStatusModelError:\n        return TerminationStatusCode.INVALID_MODEL\n    elif model_status == Enum.kHighsModelStatusPresolveError:\n        return TerminationStatusCode.OTHER_ERROR\n    elif model_status == Enum.kHighsModelStatusSolveError:\n        return TerminationStatusCode.OTHER_ERROR\n    elif model_status == Enum.kHighsModelStatusPostsolveError:\n        return TerminationStatusCode.OTHER_ERROR\n    elif model_status == Enum.kHighsModelStatusModelEmpty:\n        return TerminationStatusCode.INVALID_MODEL\n    elif model_status == Enum.kHighsModelStatusOptimal:\n        return TerminationStatusCode.OPTIMAL\n    elif model_status == Enum.kHighsModelStatusInfeasible:\n        return TerminationStatusCode.INFEASIBLE\n    elif model_status == Enum.kHighsModelStatusUnboundedOrInfeasible:\n        return TerminationStatusCode.INFEASIBLE_OR_UNBOUNDED\n    elif model_status == Enum.kHighsModelStatusUnbounded:\n        return TerminationStatusCode.DUAL_INFEASIBLE\n    elif model_status == Enum.kHighsModelStatusObjectiveBound:\n        return TerminationStatusCode.OBJECTIVE_LIMIT\n    elif model_status == Enum.kHighsModelStatusObjectiveTarget:\n        return TerminationStatusCode.OBJECTIVE_LIMIT\n    elif model_status == Enum.kHighsModelStatusTimeLimit:\n        return TerminationStatusCode.TIME_LIMIT\n    elif model_status == Enum.kHighsModelStatusIterationLimit:\n        return TerminationStatusCode.ITERATION_LIMIT\n    elif model_status == Enum.kHighsModelStatusUnknown:\n        return TerminationStatusCode.OTHER_ERROR\n    else:\n        assert model_status == Enum.kHighsModelStatusSolutionLimit\n        return TerminationStatusCode.SOLUTION_LIMIT\n\n\nmodel_attribute_get_func_map = {\n    ModelAttribute.ObjectiveSense: lambda model: model.get_obj_sense(),\n    # ModelAttribute.DualObjectiveValue: lambda model: model.getdualobj(),\n    ModelAttribute.ObjectiveValue: lambda model: model.get_obj_value(),\n    ModelAttribute.SolveTimeSec: lambda model: model.getruntime(),\n    ModelAttribute.NumberOfThreads: lambda model: model.get_raw_option_int(\"threads\"),\n    ModelAttribute.RelativeGap: lambda model: model.get_raw_option_double(\n        \"mip_rel_gap\"\n    ),\n    ModelAttribute.TimeLimitSec: lambda model: model.get_raw_option_double(\n        \"time_limit\"\n    ),\n    ModelAttribute.DualStatus: get_dualstatus,\n    ModelAttribute.PrimalStatus: get_primalstatus,\n    ModelAttribute.RawStatusString: get_rawstatusstring,\n    ModelAttribute.TerminationStatus: get_terminationstatus,\n    ModelAttribute.Silent: lambda model: not model.get_raw_option_bool(\"output_flag\"),\n    ModelAttribute.SolverName: lambda _: \"HiGHS\",\n    ModelAttribute.SolverVersion: lambda model: model.version_string(),\n}\n\nmodel_attribute_set_func_map = {\n    ModelAttribute.ObjectiveSense: lambda model, v: model.set_obj_sense(v),\n    ModelAttribute.NumberOfThreads: lambda model, v: model.set_raw_option_int(\n        \"threads\", v\n    ),\n    ModelAttribute.RelativeGap: lambda model, v: model.set_raw_option_double(\n        \"mip_rel_gap\", v\n    ),\n    ModelAttribute.TimeLimitSec: lambda model, v: model.set_raw_option_double(\n        \"time_limit\", v\n    ),\n    ModelAttribute.Silent: lambda model, v: model.set_raw_option_bool(\n        \"output_flag\", not v\n    ),\n}\n\nconstraint_attribute_get_func_map = {\n    ConstraintAttribute.Name: lambda model, constraint: model.get_constraint_name(\n        constraint\n    ),\n    ConstraintAttribute.Primal: lambda model, constraint: model.get_constraint_primal(\n        constraint\n    ),\n    ConstraintAttribute.Dual: lambda model, constraint: model.get_constraint_dual(\n        constraint\n    ),\n}\n\nconstraint_attribute_set_func_map = {\n    ConstraintAttribute.Name: lambda model, constraint, value: model.set_constraint_name(\n        constraint, value\n    ),\n}\n\nhighs_option_raw_type_map = {\n    Enum.kHighsOptionTypeBool: bool,\n    Enum.kHighsOptionTypeInt: int,\n    Enum.kHighsOptionTypeDouble: float,\n    Enum.kHighsOptionTypeString: str,\n}\n\nhighs_info_raw_type_map = {\n    Enum.kHighsInfoTypeInt: int,\n    Enum.kHighsInfoTypeInt64: \"int64\",\n    Enum.kHighsInfoTypeDouble: float,\n}\n\n\nclass Model(RawModel):\n    def __init__(self):\n        super().__init__()\n\n        self.mip_start_values: Dict[VariableIndex, float] = dict()\n\n    @staticmethod\n    def supports_variable_attribute(attribute: VariableAttribute, settable=False):\n        if settable:\n            return attribute in variable_attribute_set_func_map\n        else:\n            return attribute in variable_attribute_get_func_map\n\n    @staticmethod\n    def supports_model_attribute(attribute: ModelAttribute, settable=False):\n        if settable:\n            return attribute in model_attribute_set_func_map\n        else:\n            return attribute in model_attribute_get_func_map\n\n    @staticmethod\n    def supports_constraint_attribute(attribute: ConstraintAttribute, settable=False):\n        if settable:\n            return attribute in constraint_attribute_set_func_map\n        else:\n            return attribute in constraint_attribute_get_func_map\n\n    def get_variable_attribute(self, variable, attribute: VariableAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown variable attribute to get: {attribute}\")\n\n        value = _direct_get_entity_attribute(\n            self,\n            variable,\n            attribute,\n            variable_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_variable_attribute(self, variable, attribute: VariableAttribute, value):\n        def e(attribute):\n            raise ValueError(f\"Unknown variable attribute to set: {attribute}\")\n\n        _direct_set_entity_attribute(\n            self,\n            variable,\n            attribute,\n            value,\n            variable_attribute_set_func_map,\n            e,\n        )\n\n    def number_of_constraints(self, type: ConstraintType):\n        if type not in {ConstraintType.Linear}:\n            raise ValueError(f\"Unknown constraint type: {type}\")\n        return self.m_n_constraints\n\n    def number_of_variables(self):\n        return self.m_n_variables\n\n    def get_model_attribute(self, attribute: ModelAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown model attribute to get: {attribute}\")\n\n        value = _direct_get_model_attribute(\n            self,\n            attribute,\n            model_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_model_attribute(self, attribute: ModelAttribute, value):\n        def e(attribute):\n            raise ValueError(f\"Unknown model attribute to set: {attribute}\")\n\n        _direct_set_model_attribute(\n            self,\n            attribute,\n            value,\n            model_attribute_set_func_map,\n            e,\n        )\n\n    def get_constraint_attribute(self, constraint, attribute: ConstraintAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown constraint attribute to get: {attribute}\")\n\n        value = _direct_get_entity_attribute(\n            self,\n            constraint,\n            attribute,\n            constraint_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_constraint_attribute(\n        self, constraint, attribute: ConstraintAttribute, value\n    ):\n        def e(attribute):\n            raise ValueError(f\"Unknown constraint attribute to set: {attribute}\")\n\n        _direct_set_entity_attribute(\n            self,\n            constraint,\n            attribute,\n            value,\n            constraint_attribute_set_func_map,\n            e,\n        )\n\n    def get_raw_parameter(self, param_name: str):\n        param_type = highs_option_raw_type_map[self.raw_option_type(param_name)]\n        get_function_map = {\n            bool: self.get_raw_option_bool,\n            int: self.get_raw_option_int,\n            float: self.get_raw_option_double,\n            str: self.get_raw_option_string,\n        }\n        get_function = get_function_map[param_type]\n        return get_function(param_name)\n\n    def set_raw_parameter(self, param_name: str, value):\n        param_type = highs_option_raw_type_map[self.raw_option_type(param_name)]\n        set_function_map = {\n            bool: self.set_raw_option_bool,\n            int: self.set_raw_option_int,\n            float: self.set_raw_option_double,\n            str: self.set_raw_option_string,\n        }\n        set_function = set_function_map[param_type]\n        set_function(param_name, value)\n\n    def get_raw_information(self, param_name: str):\n        param_type = highs_info_raw_type_map[self.raw_info_type(param_name)]\n        get_function_map = {\n            int: self.get_raw_attribute_int,\n            \"int64\": self.get_raw_attribute_int64,\n            float: self.get_raw_attribute_double,\n        }\n        get_function = get_function_map[param_type]\n        return get_function(param_name)\n\n    def optimize(self):\n        mip_start = self.mip_start_values\n        if len(mip_start) != 0:\n            variables = list(mip_start.keys())\n            values = list(mip_start.values())\n            self.set_primal_start(variables, values)\n            mip_start.clear()\n        super().optimize()\n\n    @overload\n    def add_linear_constraint(\n        self,\n        expr: Union[VariableIndex, ScalarAffineFunction, ExprBuilder],\n        sense: ConstraintSense,\n        rhs: float,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_linear_constraint(\n        self,\n        con: ComparisonConstraint,\n        name: str = \"\",\n    ): ...\n\n    def add_linear_constraint(self, arg, *args, **kwargs):\n        if isinstance(arg, ComparisonConstraint):\n            return self._add_linear_constraint(\n                arg.lhs, arg.sense, arg.rhs, *args, **kwargs\n            )\n        else:\n            return self._add_linear_constraint(arg, *args, **kwargs)\n\n    add_variables = make_variable_tupledict\n    add_m_variables = make_variable_ndarray\n    add_m_linear_constraints = add_matrix_constraints\n"
  },
  {
    "path": "src/pyoptinterface/_src/ipopt.py",
    "content": "from io import StringIO\nimport logging\nimport platform\nfrom typing import Optional, List, Dict, Set, Union, Tuple, overload\n\nfrom llvmlite import ir\n\nfrom .ipopt_model_ext import RawModel, ApplicationReturnStatus, load_library\nfrom .codegen_c import generate_csrc_prelude, generate_csrc_from_graph\nfrom .jit_c import TCCJITCompiler\nfrom .codegen_llvm import create_llvmir_basic_functions, generate_llvmir_from_graph\nfrom .jit_llvm import LLJITCompiler\nfrom .nlexpr_ext import ExpressionHandle, ExpressionGraph, unpack_comparison_expression\nfrom .nlfunc import (\n    ExpressionGraphContext,\n    convert_to_expressionhandle,\n)\n\nfrom .core_ext import (\n    VariableIndex,\n    ScalarAffineFunction,\n    ScalarQuadraticFunction,\n    ExprBuilder,\n    ConstraintSense,\n)\nfrom .comparison_constraint import ComparisonConstraint\nfrom .nleval_ext import (\n    AutodiffSymbolicStructure,\n    ConstraintAutodiffEvaluator,\n    ObjectiveAutodiffEvaluator,\n)\nfrom .cppad_interface_ext import (\n    CppADAutodiffGraph,\n    cppad_trace_graph_constraints,\n    cppad_trace_graph_objective,\n    cppad_autodiff,\n)\n\nfrom .attributes import (\n    VariableAttribute,\n    ConstraintAttribute,\n    ModelAttribute,\n    ResultStatusCode,\n    TerminationStatusCode,\n)\nfrom .solver_common import (\n    _direct_get_model_attribute,\n    _direct_set_model_attribute,\n    _direct_get_entity_attribute,\n    _direct_set_entity_attribute,\n)\nfrom .constraint_bridge import bridge_soc_quadratic_constraint\nfrom .aml import make_variable_tupledict, make_variable_ndarray\nfrom .matrix import add_matrix_constraints\n\n\ndef detected_libraries():\n    libs = []\n\n    # default names\n    default_libnames = {\n        \"Linux\": [\"libipopt.so\"],\n        \"Darwin\": [\"libipopt.dylib\"],\n        \"Windows\": [\"ipopt-3.dll\", \"ipopt.dll\", \"libipopt-3.dll\", \"libipopt.dll\"],\n    }[platform.system()]\n    libs.extend(default_libnames)\n\n    return libs\n\n\ndef autoload_library():\n    libs = detected_libraries()\n    for lib in libs:\n        ret = load_library(lib)\n        if ret:\n            logging.info(f\"Loaded IPOPT library: {lib}\")\n            return True\n    return False\n\n\nautoload_library()\n\nvariable_attribute_get_func_map = {\n    VariableAttribute.Value: lambda model, v: model.get_value(v),\n    VariableAttribute.LowerBound: lambda model, v: model.get_variable_lb(v),\n    VariableAttribute.UpperBound: lambda model, v: model.get_variable_ub(v),\n    VariableAttribute.PrimalStart: lambda model, v: model.get_variable_start(v),\n    VariableAttribute.Name: lambda model, v: model.get_variable_name(v),\n}\n\nvariable_attribute_set_func_map = {\n    VariableAttribute.LowerBound: lambda model, v, val: model.set_variable_lb(v, val),\n    VariableAttribute.UpperBound: lambda model, v, val: model.set_variable_ub(v, val),\n    VariableAttribute.PrimalStart: lambda model, v, val: model.set_variable_start(\n        v, val\n    ),\n    VariableAttribute.Name: lambda model, v, val: model.set_variable_name(v, val),\n}\n\n\ndef get_dualstatus(model):\n    status = model.m_status\n    if status == ApplicationReturnStatus.Solve_Succeeded:\n        return ResultStatusCode.FEASIBLE_POINT\n    elif status == ApplicationReturnStatus.Feasible_Point_Found:\n        return ResultStatusCode.FEASIBLE_POINT\n    elif status == ApplicationReturnStatus.Solved_To_Acceptable_Level:\n        return ResultStatusCode.NEARLY_FEASIBLE_POINT\n    else:\n        return ResultStatusCode.UNKNOWN_RESULT_STATUS\n\n\ndef get_primalstatus(model):\n    status = model.m_status\n    if status == ApplicationReturnStatus.Solve_Succeeded:\n        return ResultStatusCode.FEASIBLE_POINT\n    elif status == ApplicationReturnStatus.Feasible_Point_Found:\n        return ResultStatusCode.FEASIBLE_POINT\n    elif status == ApplicationReturnStatus.Solved_To_Acceptable_Level:\n        return ResultStatusCode.NEARLY_FEASIBLE_POINT\n    elif status == ApplicationReturnStatus.Infeasible_Problem_Detected:\n        return ResultStatusCode.INFEASIBLE_POINT\n    else:\n        return ResultStatusCode.UNKNOWN_RESULT_STATUS\n\n\ndef get_rawstatusstring(model):\n    status = model.m_status\n    return status.name\n\n\ndef get_terminationstatus(model):\n    is_dirty = model.m_is_dirty\n    if is_dirty:\n        return TerminationStatusCode.OPTIMIZE_NOT_CALLED\n    status = model.m_status\n    if (\n        status == ApplicationReturnStatus.Solve_Succeeded\n        or status == ApplicationReturnStatus.Feasible_Point_Found\n    ):\n        return TerminationStatusCode.LOCALLY_SOLVED\n    elif status == ApplicationReturnStatus.Infeasible_Problem_Detected:\n        return TerminationStatusCode.LOCALLY_INFEASIBLE\n    elif status == ApplicationReturnStatus.Solved_To_Acceptable_Level:\n        return TerminationStatusCode.ALMOST_LOCALLY_SOLVED\n    elif status == ApplicationReturnStatus.Search_Direction_Becomes_Too_Small:\n        return TerminationStatusCode.NUMERICAL_ERROR\n    elif status == ApplicationReturnStatus.Diverging_Iterates:\n        return TerminationStatusCode.NORM_LIMIT\n    elif status == ApplicationReturnStatus.User_Requested_Stop:\n        return TerminationStatusCode.INTERRUPTED\n    elif status == ApplicationReturnStatus.Maximum_Iterations_Exceeded:\n        return TerminationStatusCode.ITERATION_LIMIT\n    elif status == ApplicationReturnStatus.Maximum_CpuTime_Exceeded:\n        return TerminationStatusCode.TIME_LIMIT\n    elif status == ApplicationReturnStatus.Maximum_WallTime_Exceeded:\n        return TerminationStatusCode.TIME_LIMIT\n    elif status == ApplicationReturnStatus.Restoration_Failed:\n        return TerminationStatusCode.NUMERICAL_ERROR\n    elif status == ApplicationReturnStatus.Error_In_Step_Computation:\n        return TerminationStatusCode.NUMERICAL_ERROR\n    elif status == ApplicationReturnStatus.Invalid_Option:\n        return TerminationStatusCode.INVALID_OPTION\n    elif status == ApplicationReturnStatus.Not_Enough_Degrees_Of_Freedom:\n        return TerminationStatusCode.INVALID_MODEL\n    elif status == ApplicationReturnStatus.Invalid_Problem_Definition:\n        return TerminationStatusCode.INVALID_MODEL\n    elif status == ApplicationReturnStatus.Invalid_Number_Detected:\n        return TerminationStatusCode.INVALID_MODEL\n    elif status == ApplicationReturnStatus.Unrecoverable_Exception:\n        return TerminationStatusCode.OTHER_ERROR\n    elif status == ApplicationReturnStatus.NonIpopt_Exception_Thrown:\n        return TerminationStatusCode.OTHER_ERROR\n    else:\n        assert status == ApplicationReturnStatus.Insufficient_Memory\n        return TerminationStatusCode.MEMORY_LIMIT\n\n\nmodel_attribute_get_func_map = {\n    ModelAttribute.ObjectiveValue: lambda model: model.get_obj_value(),\n    ModelAttribute.DualStatus: get_dualstatus,\n    ModelAttribute.PrimalStatus: get_primalstatus,\n    ModelAttribute.RawStatusString: get_rawstatusstring,\n    ModelAttribute.TerminationStatus: get_terminationstatus,\n    ModelAttribute.SolverName: lambda _: \"IPOPT\",\n}\n\nmodel_attribute_set_func_map = {\n    ModelAttribute.TimeLimitSec: lambda model, v: model.set_raw_parameter(\n        \"max_wall_time\", v\n    ),\n    ModelAttribute.Silent: lambda model, v: model.set_raw_parameter(\n        \"print_level\", 0 if v else 5\n    ),\n}\n\n\ndef get_constraint_primal(model, constraint):\n    return model.get_constraint_primal(constraint)\n\n\ndef get_constraint_dual(model, constraint):\n    return model.get_constraint_dual(constraint)\n\n\nconstraint_attribute_get_func_map = {\n    ConstraintAttribute.Primal: get_constraint_primal,\n    ConstraintAttribute.Dual: get_constraint_dual,\n}\n\nconstraint_attribute_set_func_map = {}\n\n\nclass Model(RawModel):\n    def __init__(self, jit: str = \"LLVM\"):\n        super().__init__()\n\n        if jit == \"C\":\n            self.jit_compiler = TCCJITCompiler()\n        elif jit == \"LLVM\":\n            self.jit_compiler = LLJITCompiler()\n        else:\n            raise ValueError(f\"JIT engine can only be 'C' or 'LLVM', got {jit}\")\n        self.jit = jit\n\n        # store graph_instance to graph_index\n        self.graph_instance_to_index: Dict[ExpressionGraph, int] = {}\n        self.graph_instances: List[ExpressionGraph] = []\n\n        self.nl_constraint_group_num = 0\n        self.nl_constraint_group_representatives: List[int] = []\n        self.nl_constraint_cppad_autodiff_graphs: List[CppADAutodiffGraph] = []\n        self.nl_constraint_autodiff_structures: List[AutodiffSymbolicStructure] = []\n        self.nl_constraint_evaluators: List[ConstraintAutodiffEvaluator] = []\n\n        self.nl_objective_group_num = 0\n        self.nl_objective_group_representatives: List[int] = []\n        self.nl_objective_cppad_autodiff_graphs: List[CppADAutodiffGraph] = []\n        self.nl_objective_autodiff_structures: List[AutodiffSymbolicStructure] = []\n        self.nl_objective_evaluators: List[ObjectiveAutodiffEvaluator] = []\n\n        # record the analyzed part of the problem\n        self.n_graph_instances_since_last_optimize = 0\n        self.nl_constraint_group_num_since_last_optimize = 0\n        self.nl_objective_group_num_since_last_optimize = 0\n\n    @staticmethod\n    def supports_variable_attribute(attribute: VariableAttribute, settable=False):\n        if settable:\n            return attribute in variable_attribute_set_func_map\n        else:\n            return attribute in variable_attribute_get_func_map\n\n    @staticmethod\n    def supports_model_attribute(attribute: ModelAttribute, settable=False):\n        if settable:\n            return attribute in model_attribute_set_func_map\n        else:\n            return attribute in model_attribute_get_func_map\n\n    @staticmethod\n    def supports_constraint_attribute(attribute: ConstraintAttribute, settable=False):\n        if settable:\n            return attribute in constraint_attribute_set_func_map\n        else:\n            return attribute in constraint_attribute_get_func_map\n\n    def get_variable_attribute(self, variable, attribute: VariableAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown variable attribute to get: {attribute}\")\n\n        value = _direct_get_entity_attribute(\n            self,\n            variable,\n            attribute,\n            variable_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_variable_attribute(self, variable, attribute: VariableAttribute, value):\n        def e(attribute):\n            raise ValueError(f\"Unknown variable attribute to set: {attribute}\")\n\n        _direct_set_entity_attribute(\n            self,\n            variable,\n            attribute,\n            value,\n            variable_attribute_set_func_map,\n            e,\n        )\n\n    def get_model_attribute(self, attribute: ModelAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown model attribute to get: {attribute}\")\n\n        value = _direct_get_model_attribute(\n            self,\n            attribute,\n            model_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_model_attribute(self, attribute: ModelAttribute, value):\n        def e(attribute):\n            raise ValueError(f\"Unknown model attribute to set: {attribute}\")\n\n        _direct_set_model_attribute(\n            self,\n            attribute,\n            value,\n            model_attribute_set_func_map,\n            e,\n        )\n\n    def get_constraint_attribute(self, constraint, attribute: ConstraintAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown constraint attribute to get: {attribute}\")\n\n        value = _direct_get_entity_attribute(\n            self,\n            constraint,\n            attribute,\n            constraint_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_constraint_attribute(\n        self, constraint, attribute: ConstraintAttribute, value\n    ):\n        def e(attribute):\n            raise ValueError(f\"Unknown constraint attribute to set: {attribute}\")\n\n        _direct_set_entity_attribute(\n            self,\n            constraint,\n            attribute,\n            value,\n            constraint_attribute_set_func_map,\n            e,\n        )\n\n    def set_raw_parameter(self, param_name: str, value):\n        ty = type(value)\n        if ty is int:\n            self.set_raw_option_int(param_name, value)\n        elif ty is float:\n            self.set_raw_option_double(param_name, value)\n        elif ty is str:\n            self.set_raw_option_string(param_name, value)\n        else:\n            raise ValueError(f\"Unsupported parameter type: {ty}\")\n\n    @overload\n    def add_linear_constraint(\n        self,\n        expr: Union[VariableIndex, ScalarAffineFunction, ExprBuilder],\n        sense: ConstraintSense,\n        rhs: float,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_linear_constraint(\n        self,\n        expr: Union[VariableIndex, ScalarAffineFunction, ExprBuilder],\n        interval: Tuple[float, float],\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_linear_constraint(\n        self,\n        con: ComparisonConstraint,\n        name: str = \"\",\n    ): ...\n\n    def add_linear_constraint(self, arg, *args, **kwargs):\n        if isinstance(arg, ComparisonConstraint):\n            return self._add_linear_constraint(\n                arg.lhs, arg.sense, arg.rhs, *args, **kwargs\n            )\n        else:\n            return self._add_linear_constraint(arg, *args, **kwargs)\n\n    @overload\n    def add_quadratic_constraint(\n        self,\n        expr: Union[ScalarQuadraticFunction, ExprBuilder],\n        sense: ConstraintSense,\n        rhs: float,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_quadratic_constraint(\n        self,\n        expr: Union[ScalarQuadraticFunction, ExprBuilder],\n        interval: Tuple[float, float],\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_quadratic_constraint(\n        self,\n        con: ComparisonConstraint,\n        name: str = \"\",\n    ): ...\n\n    def add_quadratic_constraint(self, arg, *args, **kwargs):\n        if isinstance(arg, ComparisonConstraint):\n            return self._add_quadratic_constraint(\n                arg.lhs, arg.sense, arg.rhs, *args, **kwargs\n            )\n        else:\n            return self._add_quadratic_constraint(arg, *args, **kwargs)\n\n    @overload\n    def add_nl_constraint(\n        self,\n        expr,\n        sense: ConstraintSense,\n        rhs: float,\n        /,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_nl_constraint(\n        self,\n        expr,\n        interval: Tuple[float, float],\n        /,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_nl_constraint(\n        self,\n        con,\n        /,\n        name: str = \"\",\n    ): ...\n\n    def add_nl_constraint(self, expr, *args, **kwargs):\n        graph = ExpressionGraphContext.current_graph()\n        expr = convert_to_expressionhandle(graph, expr)\n        if not isinstance(expr, ExpressionHandle):\n            raise ValueError(\n                \"Expression should be able to be converted to ExpressionHandle\"\n            )\n\n        n_args = len(args)\n\n        if n_args == 0:\n            is_comparison = graph.is_compare_expression(expr)\n            if is_comparison:\n                expr, lb, ub = unpack_comparison_expression(graph, expr, float(\"inf\"))\n            else:\n                raise ValueError(\"Must specify either equality or inequality bounds\")\n        elif n_args == 1:\n            arg = args[0]\n            if isinstance(arg, tuple):\n                lb, ub = arg\n            else:\n                raise ValueError(\"Must specify either equality or inequality bounds\")\n        elif n_args == 2:\n            sense = args[0]\n            rhs = args[1]\n            if isinstance(sense, ConstraintSense) and isinstance(rhs, float):\n                if sense == ConstraintSense.Equal:\n                    lb = ub = rhs\n                elif sense == ConstraintSense.LessEqual:\n                    lb = -float(\"inf\")\n                    ub = rhs\n                elif sense == ConstraintSense.GreaterEqual:\n                    lb = rhs\n                    ub = float(\"inf\")\n                else:\n                    raise ValueError(f\"Unknown constraint sense: {sense}\")\n            else:\n                raise ValueError(\"Must specify either equality or inequality bounds\")\n        else:\n            raise ValueError(\"Must specify either equality or inequality bounds\")\n\n        graph.add_constraint_output(expr)\n\n        graph_index = self.graph_instance_to_index.get(graph, None)\n        if graph_index is None:\n            graph_index = self._add_graph_index()\n            self.graph_instance_to_index[graph] = graph_index\n            self.graph_instances.append(graph)\n\n        con = self._add_single_nl_constraint(graph_index, graph, lb, ub)\n\n        return con\n\n    def add_nl_objective(self, expr):\n        graph = ExpressionGraphContext.current_graph()\n        expr = convert_to_expressionhandle(graph, expr)\n        if not isinstance(expr, ExpressionHandle):\n            raise ValueError(\n                \"Expression should be able to be converted to ExpressionHandle\"\n            )\n\n        graph.add_objective_output(expr)\n\n        graph_index = self.graph_instance_to_index.get(graph, None)\n        if graph_index is None:\n            graph_index = self._add_graph_index()\n            self.graph_instance_to_index[graph] = graph_index\n            self.graph_instances.append(graph)\n\n        self.m_is_dirty = True\n\n    def optimize(self):\n        self._find_similar_graphs()\n        self._compile_evaluators()\n        # print(\"Compiling evaluators successfully\")\n        # print(self.jit_compiler.source_codes[0])\n\n        self.n_graph_instances_since_last_optimize = len(self.graph_instances)\n        self.nl_constraint_group_num_since_last_optimize = self.nl_constraint_group_num\n        self.nl_objective_group_num_since_last_optimize = self.nl_objective_group_num\n\n        super()._optimize()\n\n    def _find_similar_graphs(self):\n        for i in range(\n            self.n_graph_instances_since_last_optimize, len(self.graph_instances)\n        ):\n            graph = self.graph_instances[i]\n            self._finalize_graph_instance(i, graph)\n\n        # constraint part\n\n        n_groups = self._aggregate_nl_constraint_groups()\n        # print(f\"Found {n_groups} nonlinear constraint groups of similar graphs\")\n        self.nl_constraint_group_num = n_groups\n\n        rep_instances = self.nl_constraint_group_representatives\n\n        for i in range(self.nl_constraint_group_num_since_last_optimize, n_groups):\n            graph_index = self._get_nl_constraint_group_representative(i)\n            rep_instances.append(graph_index)\n\n        # objective part\n        n_groups = self._aggregate_nl_objective_groups()\n        # print(f\"Found {n_groups} nonlinear objective groups of similar graphs\")\n        self.nl_objective_group_num = n_groups\n\n        rep_instances = self.nl_objective_group_representatives\n\n        for i in range(self.nl_objective_group_num_since_last_optimize, n_groups):\n            graph_index = self._get_nl_objective_group_representative(i)\n            rep_instances.append(graph_index)\n\n    def _compile_evaluators(self):\n        # for each group of nonlinear constraint and objective, we construct a cppad_autodiff graph\n        # and then compile them to get the function pointers\n\n        # constraint\n        # self.nl_constraint_cppad_autodiff_graphs.clear()\n        # self.nl_constraint_autodiff_structures.clear()\n        for i in range(\n            self.nl_constraint_group_num_since_last_optimize,\n            self.nl_constraint_group_num,\n        ):\n            graph_index = self.nl_constraint_group_representatives[i]\n            graph = self.graph_instances[graph_index]\n\n            # print(graph)\n\n            cppad_function = cppad_trace_graph_constraints(graph)\n\n            nx = cppad_function.nx\n            var_values = [(i + 1) / (nx + 1) for i in range(nx)]\n            np = cppad_function.np\n            param_values = [(i + 1) / (np + 1) for i in range(np)]\n\n            # print(f\"nx = {nx}, np = {np}\")\n            # print(f\"var_values = {var_values}\")\n            # print(f\"param_values = {param_values}\")\n\n            autodiff_structure = AutodiffSymbolicStructure()\n            cppad_graph = CppADAutodiffGraph()\n\n            cppad_autodiff(\n                cppad_function,\n                autodiff_structure,\n                cppad_graph,\n                var_values,\n                param_values,\n            )\n\n            # print(cppad_graph.f)\n\n            self._assign_nl_constraint_group_autodiff_structure(i, autodiff_structure)\n\n            self.nl_constraint_cppad_autodiff_graphs.append(cppad_graph)\n            self.nl_constraint_autodiff_structures.append(autodiff_structure)\n\n        # objective\n        # self.nl_objective_cppad_autodiff_graphs.clear()\n        # self.nl_objective_autodiff_structures.clear()\n        for i in range(\n            self.nl_objective_group_num_since_last_optimize, self.nl_objective_group_num\n        ):\n            graph_index = self.nl_objective_group_representatives[i]\n            graph = self.graph_instances[graph_index]\n\n            cppad_function = cppad_trace_graph_objective(graph)\n\n            nx = cppad_function.nx\n            var_values = [(i + 1) / (nx + 1) for i in range(nx)]\n            np = cppad_function.np\n            param_values = [(i + 1) / (np + 1) for i in range(np)]\n\n            autodiff_structure = AutodiffSymbolicStructure()\n            cppad_graph = CppADAutodiffGraph()\n\n            cppad_autodiff(\n                cppad_function,\n                autodiff_structure,\n                cppad_graph,\n                var_values,\n                param_values,\n            )\n\n            self._assign_nl_objective_group_autodiff_structure(i, autodiff_structure)\n\n            self.nl_objective_cppad_autodiff_graphs.append(cppad_graph)\n            self.nl_objective_autodiff_structures.append(autodiff_structure)\n\n        # compile the evaluators\n        jit_compiler = self.jit_compiler\n        if isinstance(jit_compiler, TCCJITCompiler):\n            self._codegen_c()\n        elif isinstance(jit_compiler, LLJITCompiler):\n            self._codegen_llvm()\n\n    def _codegen_c(self):\n        jit_compiler: TCCJITCompiler = self.jit_compiler\n        io = StringIO()\n\n        generate_csrc_prelude(io)\n\n        for group_index in range(\n            self.nl_constraint_group_num_since_last_optimize,\n            self.nl_constraint_group_num,\n        ):\n            cppad_autodiff_graph = self.nl_constraint_cppad_autodiff_graphs[group_index]\n            autodiff_structure = self.nl_constraint_autodiff_structures[group_index]\n\n            np = autodiff_structure.np\n            ny = autodiff_structure.ny\n\n            name = f\"nlconstraint_{group_index}\"\n\n            f_name = name\n            generate_csrc_from_graph(\n                io,\n                cppad_autodiff_graph.f,\n                f_name,\n                np=np,\n                indirect_x=True,\n            )\n            if autodiff_structure.has_jacobian:\n                jacobian_name = name + \"_jacobian\"\n                generate_csrc_from_graph(\n                    io,\n                    cppad_autodiff_graph.jacobian,\n                    jacobian_name,\n                    np=np,\n                    indirect_x=True,\n                )\n            if autodiff_structure.has_hessian:\n                hessian_name = name + \"_hessian\"\n                generate_csrc_from_graph(\n                    io,\n                    cppad_autodiff_graph.hessian,\n                    hessian_name,\n                    np=np,\n                    hessian_lagrange=True,\n                    nw=ny,\n                    indirect_x=True,\n                    indirect_y=True,\n                    add_y=True,\n                )\n\n        for group_index in range(\n            self.nl_objective_group_num_since_last_optimize, self.nl_objective_group_num\n        ):\n            cppad_autodiff_graph = self.nl_objective_cppad_autodiff_graphs[group_index]\n            autodiff_structure = self.nl_objective_autodiff_structures[group_index]\n\n            np = autodiff_structure.np\n            ny = autodiff_structure.ny\n\n            name = f\"nlobjective_{group_index}\"\n\n            f_name = name\n            generate_csrc_from_graph(\n                io, cppad_autodiff_graph.f, f_name, np=np, indirect_x=True, add_y=True\n            )\n            if autodiff_structure.has_jacobian:\n                jacobian_name = name + \"_jacobian\"\n                generate_csrc_from_graph(\n                    io,\n                    cppad_autodiff_graph.jacobian,\n                    jacobian_name,\n                    np=np,\n                    indirect_x=True,\n                    indirect_y=True,\n                    add_y=True,\n                )\n            if autodiff_structure.has_hessian:\n                hessian_name = name + \"_hessian\"\n                generate_csrc_from_graph(\n                    io,\n                    cppad_autodiff_graph.hessian,\n                    hessian_name,\n                    np=np,\n                    hessian_lagrange=True,\n                    nw=ny,\n                    indirect_x=True,\n                    indirect_y=True,\n                    add_y=True,\n                )\n\n        csrc = io.getvalue()\n\n        inst = jit_compiler.create_instance()\n        jit_compiler.compile_string(inst, csrc)\n\n        for group_index in range(\n            self.nl_constraint_group_num_since_last_optimize,\n            self.nl_constraint_group_num,\n        ):\n            name = f\"nlconstraint_{group_index}\"\n            autodiff_structure = self.nl_constraint_autodiff_structures[group_index]\n            has_parameter = autodiff_structure.has_parameter\n\n            f_name = name\n            jacobian_name = name + \"_jacobian\"\n            hessian_name = name + \"_hessian\"\n\n            f_ptr = inst.get_symbol(f_name)\n            jacobian_ptr = hessian_ptr = 0\n            if autodiff_structure.has_jacobian:\n                jacobian_ptr = inst.get_symbol(jacobian_name)\n            if autodiff_structure.has_hessian:\n                hessian_ptr = inst.get_symbol(hessian_name)\n\n            evaluator = ConstraintAutodiffEvaluator(\n                has_parameter, f_ptr, jacobian_ptr, hessian_ptr\n            )\n            self._assign_nl_constraint_group_autodiff_evaluator(group_index, evaluator)\n\n        for group_index in range(\n            self.nl_objective_group_num_since_last_optimize, self.nl_objective_group_num\n        ):\n            name = f\"nlobjective_{group_index}\"\n            autodiff_structure = self.nl_objective_autodiff_structures[group_index]\n            has_parameter = autodiff_structure.has_parameter\n\n            f_name = name\n            jacobian_name = name + \"_jacobian\"\n            hessian_name = name + \"_hessian\"\n\n            f_ptr = inst.get_symbol(f_name)\n            jacobian_ptr = hessian_ptr = 0\n            if autodiff_structure.has_jacobian:\n                jacobian_ptr = inst.get_symbol(jacobian_name)\n            if autodiff_structure.has_hessian:\n                hessian_ptr = inst.get_symbol(hessian_name)\n\n            evaluator = ObjectiveAutodiffEvaluator(\n                has_parameter, f_ptr, jacobian_ptr, hessian_ptr\n            )\n            self._assign_nl_objective_group_autodiff_evaluator(group_index, evaluator)\n\n    def _codegen_llvm(self):\n        jit_compiler: LLJITCompiler = self.jit_compiler\n        module = ir.Module(name=\"my_module\")\n        create_llvmir_basic_functions(module)\n\n        export_functions = []\n\n        for group_index in range(\n            self.nl_constraint_group_num_since_last_optimize,\n            self.nl_constraint_group_num,\n        ):\n            cppad_autodiff_graph = self.nl_constraint_cppad_autodiff_graphs[group_index]\n            autodiff_structure = self.nl_constraint_autodiff_structures[group_index]\n\n            np = autodiff_structure.np\n            ny = autodiff_structure.ny\n\n            name = f\"nlconstraint_{group_index}\"\n\n            f_name = name\n            generate_llvmir_from_graph(\n                module,\n                cppad_autodiff_graph.f,\n                f_name,\n                np=np,\n                indirect_x=True,\n            )\n            export_functions.append(f_name)\n            if autodiff_structure.has_jacobian:\n                jacobian_name = name + \"_jacobian\"\n                generate_llvmir_from_graph(\n                    module,\n                    cppad_autodiff_graph.jacobian,\n                    jacobian_name,\n                    np=np,\n                    indirect_x=True,\n                )\n                export_functions.append(jacobian_name)\n            if autodiff_structure.has_hessian:\n                hessian_name = name + \"_hessian\"\n                generate_llvmir_from_graph(\n                    module,\n                    cppad_autodiff_graph.hessian,\n                    hessian_name,\n                    np=np,\n                    hessian_lagrange=True,\n                    nw=ny,\n                    indirect_x=True,\n                    indirect_y=True,\n                    add_y=True,\n                )\n                export_functions.append(hessian_name)\n\n        for group_index in range(\n            self.nl_objective_group_num_since_last_optimize, self.nl_objective_group_num\n        ):\n            cppad_autodiff_graph = self.nl_objective_cppad_autodiff_graphs[group_index]\n            autodiff_structure = self.nl_objective_autodiff_structures[group_index]\n\n            np = autodiff_structure.np\n            ny = autodiff_structure.ny\n\n            name = f\"nlobjective_{group_index}\"\n\n            f_name = name\n            generate_llvmir_from_graph(\n                module,\n                cppad_autodiff_graph.f,\n                f_name,\n                np=np,\n                indirect_x=True,\n                add_y=True,\n            )\n            export_functions.append(f_name)\n            if autodiff_structure.has_jacobian:\n                jacobian_name = name + \"_jacobian\"\n                generate_llvmir_from_graph(\n                    module,\n                    cppad_autodiff_graph.jacobian,\n                    jacobian_name,\n                    np=np,\n                    indirect_x=True,\n                    indirect_y=True,\n                    add_y=True,\n                )\n                export_functions.append(jacobian_name)\n            if autodiff_structure.has_hessian:\n                hessian_name = name + \"_hessian\"\n                generate_llvmir_from_graph(\n                    module,\n                    cppad_autodiff_graph.hessian,\n                    hessian_name,\n                    np=np,\n                    hessian_lagrange=True,\n                    nw=ny,\n                    indirect_x=True,\n                    indirect_y=True,\n                    add_y=True,\n                )\n                export_functions.append(hessian_name)\n\n        rt = jit_compiler.compile_module(module, export_functions)\n\n        for group_index in range(\n            self.nl_constraint_group_num_since_last_optimize,\n            self.nl_constraint_group_num,\n        ):\n            name = f\"nlconstraint_{group_index}\"\n            autodiff_structure = self.nl_constraint_autodiff_structures[group_index]\n            has_parameter = autodiff_structure.has_parameter\n\n            f_name = name\n            jacobian_name = name + \"_jacobian\"\n            hessian_name = name + \"_hessian\"\n\n            f_ptr = rt[f_name]\n            jacobian_ptr = hessian_ptr = 0\n            if autodiff_structure.has_jacobian:\n                jacobian_ptr = rt[jacobian_name]\n            if autodiff_structure.has_hessian:\n                hessian_ptr = rt[hessian_name]\n\n            evaluator = ConstraintAutodiffEvaluator(\n                has_parameter, f_ptr, jacobian_ptr, hessian_ptr\n            )\n            self._assign_nl_constraint_group_autodiff_evaluator(group_index, evaluator)\n\n        for group_index in range(\n            self.nl_objective_group_num_since_last_optimize, self.nl_objective_group_num\n        ):\n            name = f\"nlobjective_{group_index}\"\n            autodiff_structure = self.nl_objective_autodiff_structures[group_index]\n            has_parameter = autodiff_structure.has_parameter\n\n            f_name = name\n            jacobian_name = name + \"_jacobian\"\n            hessian_name = name + \"_hessian\"\n\n            f_ptr = rt[f_name]\n            jacobian_ptr = hessian_ptr = 0\n            if autodiff_structure.has_jacobian:\n                jacobian_ptr = rt[jacobian_name]\n            if autodiff_structure.has_hessian:\n                hessian_ptr = rt[hessian_name]\n\n            evaluator = ObjectiveAutodiffEvaluator(\n                has_parameter, f_ptr, jacobian_ptr, hessian_ptr\n            )\n            self._assign_nl_objective_group_autodiff_evaluator(group_index, evaluator)\n\n    add_variables = make_variable_tupledict\n    add_m_variables = make_variable_ndarray\n    add_m_linear_constraints = add_matrix_constraints\n    add_second_order_cone_constraint = bridge_soc_quadratic_constraint\n"
  },
  {
    "path": "src/pyoptinterface/_src/jit_c.py",
    "content": "import platform\nimport os\n\nimport tccbox\n\nfrom .tcc_interface_ext import load_library, TCCInstance\n\nsystem = platform.system()\n\nlibtcc_dir = tccbox.tcc_lib_dir()\n# windows: libtcc.dll\n# linux: libtcc.so\n# macos: libtcc.dylib\nsharedlib_suffix = {\n    \"Windows\": \"dll\",\n    \"Linux\": \"so\",\n    \"Darwin\": \"dylib\",\n}[system]\nlibtcc_path = os.path.join(libtcc_dir, f\"libtcc.{sharedlib_suffix}\")\n\nret = load_library(libtcc_path)\nif not ret:\n    raise Exception(\"Failed to load libtcc from tccbox\")\n\n# On Linux/Mac, tcc has lib/tcc/include/ and lib/tcc/libtcc1.a which must be included in compilation\nlibtcc_extra_include_paths = []\nlibtcc_extra_lib_paths = []\nlibtcc_extra_lib_names = []\nif system in [\"Linux\", \"Darwin\"]:\n    libtcc_extra_include_paths.append(os.path.join(libtcc_dir, \"tcc\", \"include\"))\n    libtcc_extra_lib_paths.append(os.path.join(libtcc_dir, \"tcc\"))\n    libtcc_extra_lib_names.append(\"m\")\nif system == \"Linux\":\n    libtcc_extra_include_paths.extend(\n        [\n            \"/usr/include\",\n            \"/usr/local/include\",\n            \"/usr/include/x86_64-linux-gnu\",\n            # arm\n            \"/usr/include/aarch64-linux-gnu\",\n        ]\n    )\n    libtcc_extra_lib_paths.extend(\n        [\n            \"/usr/lib\",\n            \"/usr/local/lib\",\n            \"/usr/lib/x86_64-linux-gnu\",\n            # arm\n            \"/usr/lib/aarch64-linux-gnu\",\n        ]\n    )\n\n\nclass TCCJITCompiler:\n    def __init__(self):\n        self.instances = []\n        self.source_codes = []\n\n    def create_instance(self):\n        inst = TCCInstance()\n        inst.init()\n\n        # Add extra include path and library path\n        for path in libtcc_extra_include_paths:\n            inst.add_include_path(path)\n            inst.add_sysinclude_path(path)\n        for path in libtcc_extra_lib_paths:\n            inst.add_library_path(path)\n        for name in libtcc_extra_lib_names:\n            inst.add_library(name)\n\n        self.instances.append(inst)\n\n        return inst\n\n    def compile_string(self, inst, c_code: str):\n        inst.compile_string(c_code)\n\n        self.source_codes.append(c_code)\n"
  },
  {
    "path": "src/pyoptinterface/_src/jit_llvm.py",
    "content": "from llvmlite import ir, binding\n\nfrom typing import List\n\n# Initialize LLVM\ntry:\n    # llvmlite older than 0.45.0 still requires this\n    binding.initialize()\nexcept Exception:\n    pass\n\nbinding.initialize_native_target()\nbinding.initialize_native_asmprinter()\n\n\nclass LLJITCompiler:\n    def __init__(self):\n        target = binding.Target.from_default_triple()\n        target_machine = target.create_target_machine(jit=True, opt=3)\n        self.lljit = binding.create_lljit_compiler(target_machine)\n\n        self.rts = []\n        self.source_codes = []\n\n    def compile_module(self, module: ir.Module, export_functions: List[str] = []):\n        ir_str = str(module)\n        self.source_codes.append(ir_str)\n        builder = binding.JITLibraryBuilder().add_ir(ir_str).add_current_process()\n        for f in export_functions:\n            builder.export_symbol(f)\n        n = len(self.rts)\n        libname = f\"lib{n}\"\n        rt = builder.link(self.lljit, libname)\n        self.rts.append(rt)\n\n        return rt\n"
  },
  {
    "path": "src/pyoptinterface/_src/knitro.py",
    "content": "import logging\nimport os\nimport platform\nimport re\nfrom pathlib import Path\nfrom typing import Tuple, Union, overload\n\nfrom .aml import make_variable_ndarray, make_variable_tupledict\nfrom .attributes import (\n    ConstraintAttribute,\n    ModelAttribute,\n    ResultStatusCode,\n    TerminationStatusCode,\n    VariableAttribute,\n)\nfrom .comparison_constraint import ComparisonConstraint\nfrom .core_ext import (\n    ConstraintIndex,\n    ConstraintSense,\n    ExprBuilder,\n    ScalarAffineFunction,\n    ScalarQuadraticFunction,\n    VariableIndex,\n)\nfrom .knitro_model_ext import KN, RawEnv, RawModel, load_library\nfrom .matrix import add_matrix_constraints\nfrom .nlexpr_ext import ExpressionGraph, ExpressionHandle\nfrom .nlfunc import ExpressionGraphContext, convert_to_expressionhandle\nfrom .solver_common import (\n    _get_entity_attribute,\n    _get_model_attribute,\n    _set_entity_attribute,\n    _set_model_attribute,\n)\n\n\ndef detected_libraries():\n    libs = []\n\n    subdir = {\n        \"Linux\": \"lib\",\n        \"Darwin\": \"lib\",\n        \"Windows\": \"bin\",\n    }[platform.system()]\n    libname_pattern = {\n        \"Linux\": r\"libknitro\\.so.*\",\n        \"Darwin\": r\"libknitro\\.dylib.*\",\n        \"Windows\": r\"knitro\\d*\\.dll\",\n    }[platform.system()]\n    suffix_pattern = {\n        \"Linux\": \"*.so*\",\n        \"Darwin\": \"*.dylib*\",\n        \"Windows\": \"*.dll\",\n    }[platform.system()]\n\n    # Environment variable\n    knitro_dir = os.environ.get(\"KNITRODIR\", None)\n    if knitro_dir and os.path.exists(knitro_dir):\n        dir = Path(knitro_dir) / subdir\n        if dir.exists():\n            for path in dir.glob(suffix_pattern):\n                match = re.match(libname_pattern, path.name)\n                if match:\n                    libs.append(str(path))\n\n    try:\n        import knitro\n\n        dir = Path(knitro.__path__[0])\n        dir = dir / \"lib\"\n        for path in dir.glob(suffix_pattern):\n            match = re.match(libname_pattern, path.name)\n            if match:\n                libs.append(str(path))\n    except ImportError:\n        pass\n\n    # Default library names\n    default_libname = {\n        \"Linux\": [\"libknitro.so\"],\n        \"Darwin\": [\"libknitro.dylib\"],\n        \"Windows\": [\"knitro.dll\"],\n    }[platform.system()]\n    libs.extend(default_libname)\n\n    return libs\n\n\ndef autoload_library():\n    libs = detected_libraries()\n    for lib in libs:\n        ret = load_library(lib)\n        if ret:\n            logging.info(f\"Loaded KNITRO library: {lib}\")\n            return True\n    return False\n\n\nautoload_library()\n\n\n# Variable Attribute\nvariable_attribute_get_func_map = {\n    VariableAttribute.Value: lambda model, v: model.get_value(v),\n    VariableAttribute.LowerBound: lambda model, v: model.get_variable_lb(v),\n    VariableAttribute.UpperBound: lambda model, v: model.get_variable_ub(v),\n    VariableAttribute.Name: lambda model, v: model.get_variable_name(v),\n    VariableAttribute.Domain: lambda model, v: model.get_variable_domain(v),\n    VariableAttribute.ReducedCost: lambda model, v: model.get_variable_rc(v),\n}\n\nvariable_attribute_set_func_map = {\n    VariableAttribute.LowerBound: lambda model, v, x: model.set_variable_lb(v, x),\n    VariableAttribute.UpperBound: lambda model, v, x: model.set_variable_ub(v, x),\n    VariableAttribute.PrimalStart: lambda model, v, x: model.set_variable_start(v, x),\n    VariableAttribute.Name: lambda model, v, x: model.set_variable_name(v, x),\n    VariableAttribute.Domain: lambda model, v, x: model.set_variable_domain(v, x),\n}\n\n# Constraint Attribute\nconstraint_attribute_get_func_map = {\n    ConstraintAttribute.Primal: lambda model, c: model.get_constraint_primal(c),\n    ConstraintAttribute.Dual: lambda model, c: model.get_constraint_dual(c),\n    ConstraintAttribute.Name: lambda model, c: model.get_constraint_name(c),\n}\n\nconstraint_attribute_set_func_map = {\n    ConstraintAttribute.Name: lambda model, c, x: model.set_constraint_name(c, x),\n}\n\n_RAW_STATUS_STRINGS = [\n    (TerminationStatusCode.OPTIMAL, KN.RC_OPTIMAL),\n    (TerminationStatusCode.OPTIMAL, KN.RC_OPTIMAL_OR_SATISFACTORY),\n    (TerminationStatusCode.ALMOST_OPTIMAL, KN.RC_NEAR_OPT),\n    (TerminationStatusCode.ALMOST_OPTIMAL, KN.RC_FEAS_XTOL),\n    (TerminationStatusCode.ALMOST_OPTIMAL, KN.RC_FEAS_NO_IMPROVE),\n    (TerminationStatusCode.ALMOST_OPTIMAL, KN.RC_FEAS_FTOL),\n    (TerminationStatusCode.LOCALLY_SOLVED, KN.RC_FEAS_BEST),\n    (TerminationStatusCode.LOCALLY_SOLVED, KN.RC_FEAS_MULTISTART),\n    (TerminationStatusCode.INFEASIBLE, KN.RC_INFEASIBLE),\n    (TerminationStatusCode.LOCALLY_INFEASIBLE, KN.RC_INFEAS_XTOL),\n    (TerminationStatusCode.LOCALLY_INFEASIBLE, KN.RC_INFEAS_NO_IMPROVE),\n    (TerminationStatusCode.LOCALLY_INFEASIBLE, KN.RC_INFEAS_MULTISTART),\n    (TerminationStatusCode.INFEASIBLE, KN.RC_INFEAS_CON_BOUNDS),\n    (TerminationStatusCode.INFEASIBLE, KN.RC_INFEAS_VAR_BOUNDS),\n    (TerminationStatusCode.DUAL_INFEASIBLE, KN.RC_UNBOUNDED),\n    (TerminationStatusCode.INFEASIBLE_OR_UNBOUNDED, KN.RC_UNBOUNDED_OR_INFEAS),\n    (TerminationStatusCode.ITERATION_LIMIT, KN.RC_ITER_LIMIT_FEAS),\n    (TerminationStatusCode.ITERATION_LIMIT, KN.RC_ITER_LIMIT_INFEAS),\n    (TerminationStatusCode.TIME_LIMIT, KN.RC_TIME_LIMIT_FEAS),\n    (TerminationStatusCode.TIME_LIMIT, KN.RC_TIME_LIMIT_INFEAS),\n    (TerminationStatusCode.OTHER_LIMIT, KN.RC_FEVAL_LIMIT_FEAS),\n    (TerminationStatusCode.OTHER_LIMIT, KN.RC_FEVAL_LIMIT_INFEAS),\n    (TerminationStatusCode.OTHER_LIMIT, KN.RC_MIP_EXH_FEAS),\n    (TerminationStatusCode.OTHER_LIMIT, KN.RC_MIP_EXH_INFEAS),\n    (TerminationStatusCode.NODE_LIMIT, KN.RC_MIP_NODE_LIMIT_FEAS),\n    (TerminationStatusCode.NODE_LIMIT, KN.RC_MIP_NODE_LIMIT_INFEAS),\n    (TerminationStatusCode.INTERRUPTED, KN.RC_USER_TERMINATION),\n    (TerminationStatusCode.NUMERICAL_ERROR, KN.RC_EVAL_ERR),\n    (TerminationStatusCode.MEMORY_LIMIT, KN.RC_OUT_OF_MEMORY),\n    (TerminationStatusCode.OTHER_ERROR, KN.RC_CALLBACK_ERR),\n    (TerminationStatusCode.OTHER_ERROR, KN.RC_LP_SOLVER_ERR),\n    (TerminationStatusCode.OTHER_ERROR, KN.RC_LINEAR_SOLVER_ERR),\n    (TerminationStatusCode.OTHER_ERROR, KN.RC_INTERNAL_ERROR),\n]\n\n\ndef _termination_status_knitro(model: \"Model\"):\n    if model.is_dirty:\n        return TerminationStatusCode.OPTIMIZE_NOT_CALLED\n\n    code = model.solve_status\n    for ts, rs in _RAW_STATUS_STRINGS:\n        if code == rs:\n            return ts\n    return TerminationStatusCode.OTHER_ERROR\n\n\ndef _result_status_knitro(model: \"Model\"):\n    if model.is_dirty:\n        return ResultStatusCode.NO_SOLUTION\n\n    code = model.solve_status\n\n    feasible = {\n        KN.RC_OPTIMAL,\n        KN.RC_OPTIMAL_OR_SATISFACTORY,\n        KN.RC_NEAR_OPT,\n        KN.RC_FEAS_XTOL,\n        KN.RC_FEAS_NO_IMPROVE,\n        KN.RC_FEAS_FTOL,\n        KN.RC_FEAS_BEST,\n        KN.RC_FEAS_MULTISTART,\n        KN.RC_ITER_LIMIT_FEAS,\n        KN.RC_TIME_LIMIT_FEAS,\n        KN.RC_FEVAL_LIMIT_FEAS,\n        KN.RC_MIP_EXH_FEAS,\n        KN.RC_MIP_TERM_FEAS,\n        KN.RC_MIP_SOLVE_LIMIT_FEAS,\n        KN.RC_MIP_NODE_LIMIT_FEAS,\n    }\n\n    infeasible = {\n        KN.RC_INFEASIBLE,\n        KN.RC_INFEAS_XTOL,\n        KN.RC_INFEAS_NO_IMPROVE,\n        KN.RC_INFEAS_MULTISTART,\n        KN.RC_INFEAS_CON_BOUNDS,\n        KN.RC_INFEAS_VAR_BOUNDS,\n        KN.RC_ITER_LIMIT_INFEAS,\n        KN.RC_TIME_LIMIT_INFEAS,\n        KN.RC_FEVAL_LIMIT_INFEAS,\n        KN.RC_MIP_EXH_INFEAS,\n        KN.RC_MIP_SOLVE_LIMIT_INFEAS,\n        KN.RC_MIP_NODE_LIMIT_INFEAS,\n    }\n\n    if code in feasible:\n        return ResultStatusCode.FEASIBLE_POINT\n    if code in infeasible:\n        return ResultStatusCode.INFEASIBLE_POINT\n    return ResultStatusCode.NO_SOLUTION\n\n\n# Model Attribute\nmodel_attribute_get_func_map = {\n    ModelAttribute.ObjectiveValue: lambda model: model.get_obj_value(),\n    ModelAttribute.ObjectiveSense: lambda model: model.get_obj_sense(),\n    ModelAttribute.TerminationStatus: _termination_status_knitro,\n    ModelAttribute.RawStatusString: lambda model: (\n        f\"KNITRO status code: {model.solve_status}\"\n    ),\n    ModelAttribute.PrimalStatus: _result_status_knitro,\n    ModelAttribute.NumberOfThreads: lambda model: model.get_raw_parameter(\n        KN.PARAM_NUMTHREADS\n    ),\n    ModelAttribute.TimeLimitSec: lambda model: model.get_raw_parameter(\n        KN.PARAM_MAXTIME\n    ),\n    ModelAttribute.BarrierIterations: lambda model: model.get_number_iterations(),\n    ModelAttribute.NodeCount: lambda model: model.get_mip_node_count(),\n    ModelAttribute.ObjectiveBound: lambda model: model.get_obj_bound(),\n    ModelAttribute.RelativeGap: lambda model: model.get_mip_relative_gap(),\n    ModelAttribute.SolverName: lambda model: model.get_solver_name(),\n    ModelAttribute.SolverVersion: lambda model: model.get_release(),\n    ModelAttribute.SolveTimeSec: lambda model: model.get_solve_time(),\n}\n\nmodel_attribute_set_func_map = {\n    ModelAttribute.ObjectiveSense: lambda model, x: model.set_obj_sense(x),\n    ModelAttribute.NumberOfThreads: lambda model, x: model.set_raw_parameter(\n        KN.PARAM_NUMTHREADS, x\n    ),\n    ModelAttribute.Silent: lambda model, x: model.set_raw_parameter(\n        KN.PARAM_OUTLEV, KN.OUTLEV_NONE if x else KN.OUTLEV_ITER_10\n    ),\n    ModelAttribute.TimeLimitSec: lambda model, x: model.set_raw_parameter(\n        KN.PARAM_MAXTIME, x\n    ),\n}\n\n\nclass Env(RawEnv):\n    \"\"\"\n    KNITRO license manager environment.\n    \"\"\"\n\n    @property\n    def is_empty(self):\n        return self.empty()\n\n\nclass Model(RawModel):\n    \"\"\"\n    KNITRO model class for PyOptInterface.\n    \"\"\"\n\n    def __init__(self, env: Env = None) -> None:\n        if env is not None:\n            super().__init__(env)\n        else:\n            super().__init__()\n        self.graph_map: dict[ExpressionGraph, int] = {}\n\n    def _reset_graph_map(self) -> None:\n        self.graph_map.clear()\n\n    def _add_graph_expr(\n        self, expr: ExpressionHandle\n    ) -> tuple[ExpressionGraph, ExpressionHandle]:\n        graph = ExpressionGraphContext.current_graph()\n        expr = convert_to_expressionhandle(graph, expr)\n        if not isinstance(expr, ExpressionHandle):\n            raise ValueError(\"Expression should be convertible to ExpressionHandle\")\n        if graph not in self.graph_map:\n            self.graph_map[graph] = len(self.graph_map)\n        return graph, expr\n\n    def init(self, env: Env = None) -> None:\n        if env is not None:\n            super().init(env)\n        else:\n            super().init()\n        self._reset_graph_map()\n\n    def close(self) -> None:\n        super().close()\n        self._reset_graph_map()\n\n    @staticmethod\n    def supports_variable_attribute(\n        attribute: VariableAttribute, setable: bool = False\n    ) -> bool:\n        if setable:\n            return attribute in variable_attribute_set_func_map\n        else:\n            return attribute in variable_attribute_get_func_map\n\n    @staticmethod\n    def supports_constraint_attribute(\n        attribute: ConstraintAttribute, setable: bool = False\n    ) -> bool:\n        if setable:\n            return attribute in constraint_attribute_set_func_map\n        else:\n            return attribute in constraint_attribute_get_func_map\n\n    @staticmethod\n    def supports_model_attribute(\n        attribute: ModelAttribute, setable: bool = False\n    ) -> bool:\n        if setable:\n            return attribute in model_attribute_set_func_map\n        else:\n            return attribute in model_attribute_get_func_map\n\n    @overload\n    def add_linear_constraint(\n        self,\n        expr: Union[VariableIndex, ScalarAffineFunction, ExprBuilder],\n        sense: ConstraintSense,\n        rhs: float,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_linear_constraint(\n        self,\n        expr: Union[VariableIndex, ScalarAffineFunction, ExprBuilder],\n        interval: Tuple[float, float],\n        name: str = \"\",\n    ) -> ConstraintIndex: ...\n\n    @overload\n    def add_linear_constraint(\n        self,\n        con: ComparisonConstraint,\n        name: str = \"\",\n    ) -> ConstraintIndex: ...\n\n    def add_linear_constraint(self, arg, *args, **kwargs) -> ConstraintIndex:\n        if isinstance(arg, ComparisonConstraint):\n            return self._add_linear_constraint(\n                arg.lhs, arg.sense, arg.rhs, *args, **kwargs\n            )\n        else:\n            return self._add_linear_constraint(arg, *args, **kwargs)\n\n    @overload\n    def add_quadratic_constraint(\n        self,\n        expr: Union[ScalarQuadraticFunction, ExprBuilder],\n        sense: ConstraintSense,\n        rhs: float,\n        name: str = \"\",\n    ) -> ConstraintIndex: ...\n\n    @overload\n    def add_quadratic_constraint(\n        self,\n        con: ComparisonConstraint,\n        name: str = \"\",\n    ) -> ConstraintIndex: ...\n\n    def add_quadratic_constraint(self, arg, *args, **kwargs) -> ConstraintIndex:\n        if isinstance(arg, ComparisonConstraint):\n            return self._add_quadratic_constraint(\n                arg.lhs, arg.sense, arg.rhs, *args, **kwargs\n            )\n        else:\n            return self._add_quadratic_constraint(arg, *args, **kwargs)\n\n    @overload\n    def add_nl_constraint(\n        self,\n        expr,\n        sense: ConstraintSense,\n        rhs: float,\n        /,\n        name: str = \"\",\n    ) -> ConstraintIndex: ...\n\n    @overload\n    def add_nl_constraint(\n        self,\n        expr,\n        interval: Tuple[float, float],\n        /,\n        name: str = \"\",\n    ) -> ConstraintIndex: ...\n\n    @overload\n    def add_nl_constraint(\n        self,\n        con,\n        /,\n        name: str = \"\",\n    ) -> ConstraintIndex: ...\n\n    def add_nl_constraint(self, expr, *args, **kwargs) -> ConstraintIndex:\n        graph, expr = self._add_graph_expr(expr)\n        return self._add_single_nl_constraint(graph, expr, *args, **kwargs)\n\n    def add_nl_objective(self, expr) -> None:\n        graph, expr = self._add_graph_expr(expr)\n        self._add_single_nl_objective(graph, expr)\n\n    def get_model_attribute(self, attr: ModelAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown model attribute to get: {attribute}\")\n\n        return _get_model_attribute(self, attr, model_attribute_get_func_map, {}, e)\n\n    def set_model_attribute(self, attr: ModelAttribute, value):\n        def e(attribute):\n            raise ValueError(f\"Unknown model attribute to set: {attribute}\")\n\n        _set_model_attribute(self, attr, value, model_attribute_set_func_map, {}, e)\n\n    def get_variable_attribute(self, variable: VariableIndex, attr: VariableAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown variable attribute to get: {attribute}\")\n\n        return _get_entity_attribute(\n            self,\n            variable,\n            attr,\n            variable_attribute_get_func_map,\n            {},\n            e,\n        )\n\n    def set_variable_attribute(\n        self, variable: VariableIndex, attr: VariableAttribute, value\n    ):\n        def e(attribute):\n            raise ValueError(f\"Unknown variable attribute to set: {attribute}\")\n\n        _set_entity_attribute(\n            self,\n            variable,\n            attr,\n            value,\n            variable_attribute_set_func_map,\n            {},\n            e,\n        )\n\n    def get_constraint_attribute(\n        self, constraint: ConstraintIndex, attr: ConstraintAttribute\n    ):\n        def e(attribute):\n            raise ValueError(f\"Unknown constraint attribute to get: {attribute}\")\n\n        return _get_entity_attribute(\n            self,\n            constraint,\n            attr,\n            constraint_attribute_get_func_map,\n            {},\n            e,\n        )\n\n    def set_constraint_attribute(\n        self, constraint: ConstraintIndex, attr: ConstraintAttribute, value\n    ):\n        def e(attribute):\n            raise ValueError(f\"Unknown constraint attribute to set: {attribute}\")\n\n        _set_entity_attribute(\n            self,\n            constraint,\n            attr,\n            value,\n            constraint_attribute_set_func_map,\n            {},\n            e,\n        )\n\n    @property\n    def is_dirty(self) -> bool:\n        return self.dirty()\n\n    @property\n    def is_empty(self) -> bool:\n        return self.empty() and not self.graph_map\n\n    @property\n    def solve_status(self) -> int:\n        return self.get_solve_status()\n\n\nModel.add_variables = make_variable_tupledict\nModel.add_m_variables = make_variable_ndarray\nModel.add_m_linear_constraints = add_matrix_constraints\n"
  },
  {
    "path": "src/pyoptinterface/_src/matrix.py",
    "content": "from .tupledict import tupledict\nfrom .core_ext import ScalarAffineFunction\n\n\ndef iterate_sparse_matrix_rows(A):\n    \"\"\"\n    Iterate over rows of a sparse matrix and get non-zero elements for each row.\n\n    A is a 2-dimensional scipy sparse matrix\n    isinstance(A, scipy.sparse.sparray) = True and A.ndim = 2\n    \"\"\"\n    from scipy.sparse import csr_array\n\n    if not isinstance(A, csr_array):\n        A = csr_array(A)  # Convert to CSR format if not already\n\n    for i in range(A.shape[0]):\n        row_start = A.indptr[i]\n        row_end = A.indptr[i + 1]\n        row_indices = A.indices[row_start:row_end]\n        row_data = A.data[row_start:row_end]\n        yield row_indices, row_data\n\n\ndef add_matrix_constraints(model, A, x, sense, b):\n    \"\"\"\n    add constraints Ax <= / = / >= b\n\n    A is a 2-dimensional numpy array or scipy sparse matrix\n    x is an iterable of variables\n    sense is one of (poi.Leq, poi.Eq, poi.Geq)\n    b is an iterable of values or a single scalar\n    \"\"\"\n    import numpy as np\n    from scipy.sparse import sparray\n\n    is_ndarray = isinstance(A, np.ndarray)\n    is_sparse = isinstance(A, sparray)\n\n    if not is_ndarray and not is_sparse:\n        raise ValueError(\"A must be a numpy array or scipy.sparse array\")\n\n    ndim = A.ndim\n    if ndim != 2:\n        raise ValueError(\"A must be a 2-dimensional array\")\n\n    M, N = A.shape\n\n    # turn x into a list if x is an iterable\n    if isinstance(x, np.ndarray):\n        xdim = x.ndim\n        if xdim != 1:\n            raise ValueError(\"x must be a 1-dimensional array\")\n    elif isinstance(x, tupledict):\n        x = list(x.values())\n    else:\n        x = list(x)\n\n    if len(x) != N:\n        raise ValueError(\"x must have length equal to the number of columns of A\")\n\n    # check b\n    if np.isscalar(b):\n        b = np.full(M, b)\n    elif len(b) != M:\n        raise ValueError(\"b must have length equal to the number of rows of A\")\n\n    constraints = np.empty(M, dtype=object)\n\n    if is_ndarray:\n        for i in range(M):\n            expr = ScalarAffineFunction()\n            row = A[i]\n            for coef, var in zip(row, x):\n                expr.add_term(var, coef)\n            con = model.add_linear_constraint(expr, sense, b[i])\n            constraints[i] = con\n    elif is_sparse:\n        for i, (row_indices, row_data), rhs in zip(\n            range(M), iterate_sparse_matrix_rows(A), b\n        ):\n            expr = ScalarAffineFunction()\n            for j, coef in zip(row_indices, row_data):\n                expr.add_term(x[j], coef)\n            con = model.add_linear_constraint(expr, sense, rhs)\n            constraints[i] = con\n\n    return constraints\n"
  },
  {
    "path": "src/pyoptinterface/_src/monkeypatch.py",
    "content": "from .core_ext import (\n    VariableIndex,\n    ScalarAffineFunction,\n    ScalarQuadraticFunction,\n    ExprBuilder,\n    ConstraintSense,\n)\nfrom .comparison_constraint import ComparisonConstraint\nfrom .nlexpr_ext import (\n    ExpressionHandle,\n    BinaryOperator,\n    NaryOperator,\n    UnaryOperator,\n    ArrayType,\n)\nfrom .nlfunc import ExpressionGraphContext, convert_to_expressionhandle\n\n\ndef patch_core_compararison_operator(cls):\n    def _compare(self, other, op: ConstraintSense):\n        if isinstance(\n            other,\n            (VariableIndex, ScalarAffineFunction, ScalarQuadraticFunction, ExprBuilder),\n        ):\n            lhs = self - other\n            rhs = 0.0\n        elif isinstance(other, (int, float)):\n            lhs = self\n            rhs = other\n        else:\n            return NotImplemented\n\n        constraint = ComparisonConstraint(op, lhs, rhs)\n        return constraint\n\n    def __eq__(self, other):\n        return _compare(self, other, ConstraintSense.Equal)\n\n    def __le__(self, other):\n        return _compare(self, other, ConstraintSense.LessEqual)\n\n    def __ge__(self, other):\n        return _compare(self, other, ConstraintSense.GreaterEqual)\n\n    cls.__eq__ = __eq__\n    cls.__le__ = __le__\n    cls.__ge__ = __ge__\n\n\ndef patch_more_compararison_operator(cls):\n    def _compare(self, other, op: BinaryOperator):\n        graph = ExpressionGraphContext.current_graph_no_exception()\n        if graph is None:\n            return NotImplemented\n\n        converted_other = convert_to_expressionhandle(graph, other)\n        if isinstance(converted_other, ExpressionHandle):\n            converted_self = convert_to_expressionhandle(graph, self)\n            fallback_result = graph.add_binary(op, converted_self, converted_other)\n            return fallback_result\n        else:\n            return NotImplemented\n\n    def __lt__(self, other):\n        return _compare(self, other, BinaryOperator.LessThan)\n\n    def __gt__(self, other):\n        return _compare(self, other, BinaryOperator.GreaterThan)\n\n    def __ne__(self, other):\n        return _compare(self, other, BinaryOperator.NotEqual)\n\n    cls.__lt__ = __lt__\n    cls.__gt__ = __gt__\n    cls.__ne__ = __ne__\n\n\ndef patch_quadratic_mul(cls):\n    old_mul = getattr(cls, \"__mul__\", None)\n    old_rmul = getattr(cls, \"__rmul__\", None)\n\n    assert old_mul is not None, f\"{cls} does not have __mul__ method\"\n    assert old_rmul is not None, f\"{cls} does not have __rmul__ method\"\n\n    def __mul__(self, other):\n        original_result = NotImplemented\n\n        try:\n            original_result = old_mul(self, other)\n        except TypeError:\n            original_result = NotImplemented\n\n        if original_result is not NotImplemented:\n            return original_result\n\n        graph = ExpressionGraphContext.current_graph_no_exception()\n        if graph is None:\n            return NotImplemented\n\n        converted_other = convert_to_expressionhandle(graph, other)\n        if isinstance(converted_other, ExpressionHandle):\n            fallback_result = converted_other * self\n            return fallback_result\n        else:\n            return NotImplemented\n\n    def __rmul__(self, other):\n        original_result = NotImplemented\n\n        try:\n            original_result = old_rmul(self, other)\n        except TypeError:\n            original_result = NotImplemented\n\n        if original_result is not NotImplemented:\n            return original_result\n\n        graph = ExpressionGraphContext.current_graph_no_exception()\n        if graph is None:\n            return NotImplemented\n\n        converted_other = convert_to_expressionhandle(graph, other)\n        if isinstance(converted_other, ExpressionHandle):\n            fallback_result = converted_other * self\n            return fallback_result\n        else:\n            return NotImplemented\n\n    cls.__mul__ = __mul__\n    cls.__rmul__ = __rmul__\n\n\ndef patch_div(cls):\n    old_truediv = getattr(cls, \"__truediv__\", None)\n\n    assert old_truediv is not None, f\"{cls} does not have __truediv__ method\"\n\n    def __truediv__(self, other):\n        original_result = NotImplemented\n\n        try:\n            original_result = old_truediv(self, other)\n        except TypeError:\n            original_result = NotImplemented\n\n        if original_result is not NotImplemented:\n            return original_result\n\n        graph = ExpressionGraphContext.current_graph_no_exception()\n        if graph is None:\n            return NotImplemented\n\n        converted_other = convert_to_expressionhandle(graph, other)\n        if isinstance(converted_other, ExpressionHandle):\n            converted_self = convert_to_expressionhandle(graph, self)\n            fallback_result = graph.add_binary(\n                BinaryOperator.Div, converted_self, converted_other\n            )\n            return fallback_result\n        else:\n            return NotImplemented\n\n    def __rtruediv__(self, other):\n        graph = ExpressionGraphContext.current_graph_no_exception()\n        if graph is None:\n            return NotImplemented\n\n        converted_other = convert_to_expressionhandle(graph, other)\n        if isinstance(converted_other, ExpressionHandle):\n            converted_self = convert_to_expressionhandle(graph, self)\n            fallback_result = graph.add_binary(\n                BinaryOperator.Div, converted_other, converted_self\n            )\n            return fallback_result\n        else:\n            return NotImplemented\n\n    cls.__truediv__ = __truediv__\n    cls.__rtruediv__ = __rtruediv__\n\n\ndef pow_int(graph, expr, N):\n    if N == 0:\n        return 1\n    if N < 0:\n        return graph.add_binary(BinaryOperator.Div, 1, pow_int(graph, expr, -N))\n    if N == 1:\n        return expr\n\n    M, r = divmod(N, 2)\n\n    pow_2 = graph.add_nary(NaryOperator.Mul, [expr, expr])\n    pow_2M = pow_int(graph, pow_2, M)\n\n    if r == 0:\n        return pow_2M\n    else:\n        return graph.add_nary(NaryOperator.Mul, [pow_2M, expr])\n\n\ndef patch_expressionhandle(cls):\n    def _binary_operator(self, other, op: BinaryOperator, swap=False):\n        graph = ExpressionGraphContext.current_graph()\n        other = convert_to_expressionhandle(graph, other)\n        if not isinstance(other, ExpressionHandle):\n            return NotImplemented\n\n        if swap:\n            new_expression = graph.add_binary(op, other, self)\n        else:\n            new_expression = graph.add_binary(op, self, other)\n        return new_expression\n\n    def _nary_operator(self, other, op: NaryOperator):\n        graph = ExpressionGraphContext.current_graph()\n        other = convert_to_expressionhandle(graph, other)\n        if not isinstance(other, ExpressionHandle):\n            return NotImplemented\n\n        if self.array == ArrayType.Nary and graph.get_nary_operator(self) == op:\n            graph.append_nary(self, other)\n            return self\n        else:\n            new_expression = graph.add_nary(op, [self, other])\n            return new_expression\n\n    def __add__(self, other):\n        return self._nary_operator(other, NaryOperator.Add)\n\n    def __radd__(self, other):\n        return self._nary_operator(other, NaryOperator.Add)\n\n    def __sub__(self, other):\n        return self._binary_operator(other, BinaryOperator.Sub)\n\n    def __rsub__(self, other):\n        return self._binary_operator(other, BinaryOperator.Sub, swap=True)\n\n    def __mul__(self, other):\n        return self._nary_operator(other, NaryOperator.Mul)\n\n    def __rmul__(self, other):\n        return self._nary_operator(other, NaryOperator.Mul)\n\n    def __truediv__(self, other):\n        return self._binary_operator(other, BinaryOperator.Div)\n\n    def __rtruediv__(self, other):\n        return self._binary_operator(other, BinaryOperator.Div, swap=True)\n\n    def __neg__(self):\n        graph = ExpressionGraphContext.current_graph()\n        new_expression = graph.add_unary(UnaryOperator.Neg, self)\n        return new_expression\n\n    def __pow__(self, other):\n        # special case for integer powers, which can be implemented as a repeated multiplication\n        if isinstance(other, int):\n            graph = ExpressionGraphContext.current_graph()\n            new_expression = pow_int(graph, self, other)\n            return new_expression\n        else:\n            return self._binary_operator(other, BinaryOperator.Pow)\n\n    def __rpow__(self, other):\n        return self._binary_operator(other, BinaryOperator.Pow, swap=True)\n\n    # compare operators\n    def __eq__(self, other):\n        return self._binary_operator(other, BinaryOperator.Equal)\n\n    def __ne__(self, other):\n        return self._binary_operator(other, BinaryOperator.NotEqual)\n\n    def __lt__(self, other):\n        return self._binary_operator(other, BinaryOperator.LessThan)\n\n    def __le__(self, other):\n        return self._binary_operator(other, BinaryOperator.LessEqual)\n\n    def __gt__(self, other):\n        return self._binary_operator(other, BinaryOperator.GreaterThan)\n\n    def __ge__(self, other):\n        return self._binary_operator(other, BinaryOperator.GreaterEqual)\n\n    cls._binary_operator = _binary_operator\n    cls._nary_operator = _nary_operator\n    cls.__add__ = __add__\n    cls.__radd__ = __radd__\n    cls.__sub__ = __sub__\n    cls.__rsub__ = __rsub__\n    cls.__mul__ = __mul__\n    cls.__rmul__ = __rmul__\n    cls.__truediv__ = __truediv__\n    cls.__rtruediv__ = __rtruediv__\n    cls.__neg__ = __neg__\n    cls.__pow__ = __pow__\n    cls.__rpow__ = __rpow__\n    cls.__eq__ = __eq__\n    cls.__ne__ = __ne__\n    cls.__lt__ = __lt__\n    cls.__le__ = __le__\n    cls.__gt__ = __gt__\n    cls.__ge__ = __ge__\n\n\ndef patch_pow(cls):\n    def __pow__(self, other):\n        if other == 0:\n            return 1\n        elif other == 1:\n            return self\n        elif other == 2:\n            return self * self\n\n        graph = ExpressionGraphContext.current_graph_no_exception()\n        if graph is None:\n            return NotImplemented\n\n        self = convert_to_expressionhandle(graph, self)\n\n        if isinstance(other, int):\n            new_expression = pow_int(graph, self, other)\n            return new_expression\n\n        other = convert_to_expressionhandle(graph, other)\n        if isinstance(other, ExpressionHandle):\n            result = graph.add_binary(BinaryOperator.Pow, self, other)\n            return result\n        else:\n            return NotImplemented\n\n    def __rpow__(self, other):\n        if other == 0:\n            return 0\n        elif other == 1:\n            return 1\n\n        graph = ExpressionGraphContext.current_graph_no_exception()\n        if graph is None:\n            return NotImplemented\n\n        self = convert_to_expressionhandle(graph, self)\n        other = convert_to_expressionhandle(graph, other)\n        if isinstance(other, ExpressionHandle):\n            result = graph.add_binary(BinaryOperator.Pow, other, self)\n            return result\n        else:\n            return NotImplemented\n\n    cls.__pow__ = __pow__\n    cls.__rpow__ = __rpow__\n\n\ndef _monkeypatch_all():\n    patch_core_compararison_operator(VariableIndex)\n    patch_core_compararison_operator(ScalarAffineFunction)\n    patch_core_compararison_operator(ScalarQuadraticFunction)\n    patch_core_compararison_operator(ExprBuilder)\n\n    patch_more_compararison_operator(VariableIndex)\n    patch_more_compararison_operator(ScalarAffineFunction)\n    patch_more_compararison_operator(ScalarQuadraticFunction)\n    patch_more_compararison_operator(ExprBuilder)\n\n    patch_quadratic_mul(ScalarQuadraticFunction)\n    patch_quadratic_mul(ExprBuilder)\n\n    patch_div(VariableIndex)\n    patch_div(ScalarAffineFunction)\n    patch_div(ScalarQuadraticFunction)\n    patch_div(ExprBuilder)\n\n    patch_pow(VariableIndex)\n    patch_pow(ScalarAffineFunction)\n    patch_pow(ScalarQuadraticFunction)\n    patch_pow(ExprBuilder)\n\n    patch_expressionhandle(ExpressionHandle)\n"
  },
  {
    "path": "src/pyoptinterface/_src/mosek.py",
    "content": "import os\nimport platform\nfrom pathlib import Path\nimport re\nimport logging\nfrom typing import Optional, Union, overload\n\nfrom .mosek_model_ext import RawModel, Env, Enum, load_library\nfrom .attributes import (\n    VariableAttribute,\n    ConstraintAttribute,\n    ModelAttribute,\n    ResultStatusCode,\n    TerminationStatusCode,\n)\nfrom .core_ext import (\n    VariableIndex,\n    ScalarAffineFunction,\n    ScalarQuadraticFunction,\n    ExprBuilder,\n    ConstraintType,\n    ConstraintSense,\n)\nfrom .comparison_constraint import ComparisonConstraint\nfrom .solver_common import (\n    _direct_get_model_attribute,\n    _direct_set_model_attribute,\n    _direct_get_entity_attribute,\n    _direct_set_entity_attribute,\n)\nfrom .aml import make_variable_tupledict, make_variable_ndarray\nfrom .matrix import add_matrix_constraints\n\n\ndef detected_libraries():\n    libs = []\n\n    libname_pattern = {\n        \"Linux\": r\"libmosek64\\.so\",\n        \"Darwin\": r\"libmosek64\\.dylib\",\n        \"Windows\": r\"mosek64_(\\d+)_(\\d+)\\.dll\",\n    }[platform.system()]\n    suffix_pattern = {\n        \"Linux\": \"*.so\",\n        \"Darwin\": \"*.dylib\",\n        \"Windows\": \"*.dll\",\n    }[platform.system()]\n\n    # Environment\n    possible_envs = [\n        \"MOSEK_11_1_BINDIR\",\n        \"MOSEK_11_0_BINDIR\",\n        \"MOSEK_10_2_BINDIR\",\n        \"MOSEK_10_1_BINDIR\",\n    ]\n    for env in possible_envs:\n        home = os.environ.get(env, None)\n        if home and os.path.exists(home):\n            dir = Path(home)\n            for path in dir.glob(suffix_pattern):\n                match = re.match(libname_pattern, path.name)\n                if match:\n                    libs.append(str(path))\n            break\n\n    # mosekpy installation\n    try:\n        import mosek\n\n        dir = Path(mosek.__path__[0])\n\n        libname_pattern = {\n            \"Linux\": r\"libmosek64\\.so\\.*\",\n            \"Darwin\": r\"libmosek64\\.*\\.dylib\",\n            \"Windows\": r\"mosek64_(\\d+)_(\\d+)\\.dll\",\n        }[platform.system()]\n        suffix_pattern = {\n            \"Linux\": \"*.so.*\",\n            \"Darwin\": \"*.dylib\",\n            \"Windows\": \"*.dll\",\n        }[platform.system()]\n\n        for path in dir.glob(suffix_pattern):\n            match = re.match(libname_pattern, path.name)\n            if match:\n                libs.append(str(path))\n    except Exception:\n        pass\n\n    # default names\n    default_libname = {\n        \"Linux\": [\"libmosek64.so\"],\n        \"Darwin\": [\"libmosek64.dylib\"],\n        \"Windows\": [\n            \"mosek64_11_1.dll\",\n            \"mosek64_11_0.dll\",\n            \"mosek64_10_2.dll\",\n            \"mosek64_10_1.dll\",\n        ],\n    }[platform.system()]\n    libs.extend(default_libname)\n\n    return libs\n\n\ndef autoload_library():\n    libs = detected_libraries()\n    for lib in libs:\n        ret = load_library(lib)\n        if ret:\n            logging.info(f\"Loaded Mosek library: {lib}\")\n            return True\n    return False\n\n\nautoload_library()\n\nDEFAULT_ENV = None\n\n\ndef init_default_env():\n    global DEFAULT_ENV\n    if DEFAULT_ENV is None:\n        DEFAULT_ENV = Env()\n\n\nvariable_attribute_get_func_map = {\n    VariableAttribute.Value: lambda model, v: model.get_value(v),\n    VariableAttribute.LowerBound: lambda model, v: model.get_variable_lower_bound(v),\n    VariableAttribute.UpperBound: lambda model, v: model.get_variable_upper_bound(v),\n    # VariableAttribute.PrimalStart: lambda model, v: model.mip_start_values.get(v, None),\n    VariableAttribute.Domain: lambda model, v: model.get_variable_type(v),\n    VariableAttribute.Name: lambda model, v: model.get_variable_name(v),\n    VariableAttribute.ReducedCost: lambda model, v: model.get_variable_dual(v),\n}\n\nvariable_attribute_set_func_map = {\n    VariableAttribute.LowerBound: lambda model, v, val: model.set_variable_lower_bound(\n        v, val\n    ),\n    VariableAttribute.UpperBound: lambda model, v, val: model.set_variable_upper_bound(\n        v, val\n    ),\n    VariableAttribute.PrimalStart: lambda model, v, val: model.set_variable_primal(\n        v, val\n    ),\n    VariableAttribute.Domain: lambda model, v, val: model.set_variable_type(v, val),\n    VariableAttribute.Name: lambda model, v, val: model.set_variable_name(v, val),\n}\n\n\ndef get_primalstatus(model):\n    if model.m_is_dirty:\n        return ResultStatusCode.NO_SOLUTION\n    solsta = model.getsolsta()\n    if solsta == Enum.MSK_SOL_STA_UNKNOWN:\n        return ResultStatusCode.UNKNOWN_RESULT_STATUS\n    elif solsta == Enum.MSK_SOL_STA_OPTIMAL:\n        return ResultStatusCode.FEASIBLE_POINT\n    elif solsta == Enum.MSK_SOL_STA_PRIM_FEAS:\n        return ResultStatusCode.FEASIBLE_POINT\n    elif solsta == Enum.MSK_SOL_STA_DUAL_FEAS:\n        return ResultStatusCode.UNKNOWN_RESULT_STATUS\n    elif solsta == Enum.MSK_SOL_STA_PRIM_AND_DUAL_FEAS:\n        return ResultStatusCode.FEASIBLE_POINT\n    elif solsta == Enum.MSK_SOL_STA_PRIM_INFEAS_CER:\n        return ResultStatusCode.NO_SOLUTION\n    elif solsta == Enum.MSK_SOL_STA_DUAL_INFEAS_CER:\n        return ResultStatusCode.INFEASIBILITY_CERTIFICATE\n    elif solsta == Enum.MSK_SOL_STA_PRIM_ILLPOSED_CER:\n        return ResultStatusCode.NO_SOLUTION\n    elif solsta == Enum.MSK_SOL_STA_DUAL_ILLPOSED_CER:\n        return ResultStatusCode.REDUCTION_CERTIFICATE\n    elif solsta == Enum.MSK_SOL_STA_INTEGER_OPTIMAL:\n        return ResultStatusCode.FEASIBLE_POINT\n    else:\n        return ResultStatusCode.UNKNOWN_RESULT_STATUS\n\n\ndef get_dualstatus(model):\n    if model.m_is_dirty:\n        return ResultStatusCode.NO_SOLUTION\n    solsta = model.getsolsta()\n    if solsta == Enum.MSK_SOL_STA_UNKNOWN:\n        return ResultStatusCode.UNKNOWN_RESULT_STATUS\n    elif solsta == Enum.MSK_SOL_STA_OPTIMAL:\n        return ResultStatusCode.FEASIBLE_POINT\n    elif solsta == Enum.MSK_SOL_STA_PRIM_FEAS:\n        return ResultStatusCode.UNKNOWN_RESULT_STATUS\n    elif solsta == Enum.MSK_SOL_STA_DUAL_FEAS:\n        return ResultStatusCode.FEASIBLE_POINT\n    elif solsta == Enum.MSK_SOL_STA_PRIM_AND_DUAL_FEAS:\n        return ResultStatusCode.FEASIBLE_POINT\n    elif solsta == Enum.MSK_SOL_STA_PRIM_INFEAS_CER:\n        return ResultStatusCode.INFEASIBILITY_CERTIFICATE\n    elif solsta == Enum.MSK_SOL_STA_DUAL_INFEAS_CER:\n        return ResultStatusCode.NO_SOLUTION\n    elif solsta == Enum.MSK_SOL_STA_PRIM_ILLPOSED_CER:\n        return ResultStatusCode.REDUCTION_CERTIFICATE\n    elif solsta == Enum.MSK_SOL_STA_DUAL_ILLPOSED_CER:\n        return ResultStatusCode.NO_SOLUTION\n    elif solsta == Enum.MSK_SOL_STA_INTEGER_OPTIMAL:\n        return ResultStatusCode.NO_SOLUTION\n    else:\n        return ResultStatusCode.UNKNOWN_RESULT_STATUS\n\n\nsolsta_names = {\n    Enum.MSK_SOL_STA_UNKNOWN: \"MSK_SOL_STA_UNKNOWN\",\n    Enum.MSK_SOL_STA_OPTIMAL: \"MSK_SOL_STA_OPTIMAL\",\n    Enum.MSK_SOL_STA_PRIM_FEAS: \"MSK_SOL_STA_PRIM_FEAS\",\n    Enum.MSK_SOL_STA_DUAL_FEAS: \"MSK_SOL_STA_DUAL_FEAS\",\n    Enum.MSK_SOL_STA_PRIM_AND_DUAL_FEAS: \"MSK_SOL_STA_PRIM_AND_DUAL_FEAS\",\n    Enum.MSK_SOL_STA_PRIM_INFEAS_CER: \"MSK_SOL_STA_PRIM_INFEAS_CER\",\n    Enum.MSK_SOL_STA_DUAL_INFEAS_CER: \"MSK_SOL_STA_DUAL_INFEAS_CER\",\n    Enum.MSK_SOL_STA_PRIM_ILLPOSED_CER: \"MSK_SOL_STA_PRIM_ILLPOSED_CER\",\n    Enum.MSK_SOL_STA_DUAL_ILLPOSED_CER: \"MSK_SOL_STA_DUAL_ILLPOSED_CER\",\n    Enum.MSK_SOL_STA_INTEGER_OPTIMAL: \"MSK_SOL_STA_INTEGER_OPTIMAL\",\n}\n\ntermination_names = {\n    Enum.MSK_RES_OK: \"MSK_RES_OK\",\n    Enum.MSK_RES_TRM_MAX_ITERATIONS: \"MSK_RES_TRM_MAX_ITERATIONS\",\n    Enum.MSK_RES_TRM_MAX_TIME: \"MSK_RES_TRM_MAX_TIME\",\n    Enum.MSK_RES_TRM_OBJECTIVE_RANGE: \"MSK_RES_TRM_OBJECTIVE_RANGE\",\n    Enum.MSK_RES_TRM_STALL: \"MSK_RES_TRM_STALL\",\n    Enum.MSK_RES_TRM_USER_CALLBACK: \"MSK_RES_TRM_USER_CALLBACK\",\n    Enum.MSK_RES_TRM_MIO_NUM_RELAXS: \"MSK_RES_TRM_MIO_NUM_RELAXS\",\n    Enum.MSK_RES_TRM_MIO_NUM_BRANCHES: \"MSK_RES_TRM_MIO_NUM_BRANCHES\",\n    Enum.MSK_RES_TRM_NUM_MAX_NUM_INT_SOLUTIONS: \"MSK_RES_TRM_NUM_MAX_NUM_INT_SOLUTIONS\",\n    Enum.MSK_RES_TRM_MAX_NUM_SETBACKS: \"MSK_RES_TRM_MAX_NUM_SETBACKS\",\n    Enum.MSK_RES_TRM_NUMERICAL_PROBLEM: \"MSK_RES_TRM_NUMERICAL_PROBLEM\",\n    Enum.MSK_RES_TRM_LOST_RACE: \"MSK_RES_TRM_LOST_RACE\",\n    Enum.MSK_RES_TRM_INTERNAL: \"MSK_RES_TRM_INTERNAL\",\n    Enum.MSK_RES_TRM_INTERNAL_STOP: \"MSK_RES_TRM_INTERNAL_STOP\",\n}\n\n\ndef get_rawstatusstring(model):\n    if model.m_is_dirty:\n        return \"OPTIMIZE_NOT_CALLED\"\n    trm = model.last_solve_return_code\n    if trm is None:\n        return \"OPTIMIZE_NOT_CALLED\"\n    elif trm == Enum.MSK_RES_OK:\n        solsta = model.getsolsta()\n        return solsta_names[solsta]\n    else:\n        return termination_names[trm]\n\n\ndef get_terminationstatus(model):\n    if model.m_is_dirty:\n        return TerminationStatusCode.OPTIMIZE_NOT_CALLED\n    trm = model.last_solve_return_code\n    prosta = model.getprosta()\n    solsta = model.getsolsta()\n    if trm is None:\n        return TerminationStatusCode.OPTIMIZE_NOT_CALLED\n    elif trm == Enum.MSK_RES_OK:\n        if prosta in (Enum.MSK_PRO_STA_PRIM_INFEAS, Enum.MSK_PRO_STA_ILL_POSED):\n            return TerminationStatusCode.INFEASIBLE\n        elif prosta == Enum.MSK_PRO_STA_DUAL_INFEAS:\n            return TerminationStatusCode.DUAL_INFEASIBLE\n        elif prosta == Enum.MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED:\n            return TerminationStatusCode.INFEASIBLE_OR_UNBOUNDED\n        elif solsta in (Enum.MSK_SOL_STA_OPTIMAL, Enum.MSK_SOL_STA_INTEGER_OPTIMAL):\n            return TerminationStatusCode.OPTIMAL\n        else:\n            return TerminationStatusCode.OTHER_ERROR  # ??\n    elif trm == Enum.MSK_RES_TRM_MAX_ITERATIONS:\n        return TerminationStatusCode.ITERATION_LIMIT\n    elif trm == Enum.MSK_RES_TRM_MAX_TIME:\n        return TerminationStatusCode.TIME_LIMIT\n    elif trm == Enum.MSK_RES_TRM_OBJECTIVE_RANGE:\n        return TerminationStatusCode.OBJECTIVE_LIMIT\n    elif trm == Enum.MSK_RES_TRM_MIO_NUM_RELAXS:\n        return TerminationStatusCode.OTHER_LIMIT\n    elif trm == Enum.MSK_RES_TRM_MIO_NUM_BRANCHES:\n        return TerminationStatusCode.NODE_LIMIT\n    elif trm == Enum.MSK_RES_TRM_NUM_MAX_NUM_INT_SOLUTIONS:\n        return TerminationStatusCode.SOLUTION_LIMIT\n    elif trm == Enum.MSK_RES_TRM_STALL:\n        return TerminationStatusCode.SLOW_PROGRESS\n    elif trm == Enum.MSK_RES_TRM_USER_CALLBACK:\n        return TerminationStatusCode.INTERRUPTED\n    elif trm == Enum.MSK_RES_TRM_MAX_NUM_SETBACKS:\n        return TerminationStatusCode.OTHER_LIMIT\n    elif trm == Enum.MSK_RES_TRM_NUMERICAL_PROBLEM:\n        return TerminationStatusCode.SLOW_PROGRESS\n    elif trm == Enum.MSK_RES_TRM_INTERNAL:\n        return TerminationStatusCode.OTHER_ERROR\n    elif trm == Enum.MSK_RES_TRM_INTERNAL_STOP:\n        return TerminationStatusCode.OTHER_ERROR\n    else:\n        TerminationStatusCode.OTHER_ERROR\n\n\nmodel_attribute_get_func_map = {\n    ModelAttribute.ObjectiveSense: lambda model: model.get_obj_sense(),\n    ModelAttribute.DualObjectiveValue: lambda model: model.getdualobj(),\n    ModelAttribute.ObjectiveValue: lambda model: model.getprimalobj(),\n    ModelAttribute.SolveTimeSec: lambda model: model.get_raw_information_double(\n        \"MSK_DINF_OPTIMIZER_TIME\"\n    ),\n    ModelAttribute.NumberOfThreads: lambda model: model.get_raw_parameter_int(\n        \"MSK_IPAR_NUM_THREADS\"\n    ),\n    ModelAttribute.RelativeGap: lambda model: model.get_raw_parameter_double(\n        \"MSK_DPAR_MIO_REL_GAP_CONST\"\n    ),\n    ModelAttribute.TimeLimitSec: lambda model: model.get_raw_parameter_double(\n        \"MSK_DPAR_OPTIMIZER_MAX_TIME\"\n    ),\n    ModelAttribute.DualStatus: get_dualstatus,\n    ModelAttribute.PrimalStatus: get_primalstatus,\n    ModelAttribute.RawStatusString: get_rawstatusstring,\n    ModelAttribute.TerminationStatus: get_terminationstatus,\n    ModelAttribute.Silent: lambda model: model.silent,\n    ModelAttribute.SolverName: lambda _: \"MOSEK\",\n    ModelAttribute.SolverVersion: lambda model: model.version_string(),\n}\n\n\ndef set_silent(model, value: bool):\n    model.silent = value\n    if value:\n        model.disable_log()\n    else:\n        model.set_logging(lambda msg: print(msg, end=\"\"))\n\n\nmodel_attribute_set_func_map = {\n    ModelAttribute.ObjectiveSense: lambda model, v: model.set_obj_sense(v),\n    ModelAttribute.NumberOfThreads: lambda model, v: model.set_raw_parameter_int(\n        \"MSK_IPAR_NUM_THREADS\", v\n    ),\n    ModelAttribute.RelativeGap: lambda model, v: model.set_raw_parameter_double(\n        \"MSK_DPAR_MIO_REL_GAP_CONST\", v\n    ),\n    ModelAttribute.TimeLimitSec: lambda model, v: model.set_raw_parameter_double(\n        \"MSK_DPAR_OPTIMIZER_MAX_TIME\", v\n    ),\n    ModelAttribute.Silent: set_silent,\n}\n\nconstraint_attribute_get_func_map = {\n    ConstraintAttribute.Name: lambda model, constraint: model.get_constraint_name(\n        constraint\n    ),\n    ConstraintAttribute.Primal: lambda model, constraint: model.get_constraint_primal(\n        constraint\n    ),\n    ConstraintAttribute.Dual: lambda model, constraint: model.get_constraint_dual(\n        constraint\n    ),\n}\n\nconstraint_attribute_set_func_map = {\n    ConstraintAttribute.Name: lambda model, constraint, value: model.set_constraint_name(\n        constraint, value\n    ),\n}\n\n\ndef tell_enum_type(name: str):\n    if name.startswith(\"MSK_D\"):\n        return float\n    elif name.startswith(\"MSK_I\"):\n        return int\n    elif name.startswith(\"MSK_S\"):\n        return str\n    else:\n        raise ValueError(f\"Unknown parameter name: {name}\")\n\n\nclass Model(RawModel):\n    def __init__(self, env=None):\n        if env is None:\n            init_default_env()\n            env = DEFAULT_ENV\n        super().__init__(env)\n        # We must keep a reference to the environment to prevent it from being garbage collected\n        self._env = env\n        self.last_solve_return_code: Optional[int] = None\n        self.silent = False\n        self.set_logging(lambda msg: print(msg, end=\"\"))\n\n    @staticmethod\n    def supports_variable_attribute(attribute: VariableAttribute, settable=False):\n        if settable:\n            return attribute in variable_attribute_set_func_map\n        else:\n            return attribute in variable_attribute_get_func_map\n\n    @staticmethod\n    def supports_model_attribute(attribute: ModelAttribute, settable=False):\n        if settable:\n            return attribute in model_attribute_set_func_map\n        else:\n            return attribute in model_attribute_get_func_map\n\n    @staticmethod\n    def supports_constraint_attribute(attribute: ConstraintAttribute, settable=False):\n        if settable:\n            return attribute in constraint_attribute_set_func_map\n        else:\n            return attribute in constraint_attribute_get_func_map\n\n    def get_variable_attribute(self, variable, attribute: VariableAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown variable attribute to get: {attribute}\")\n\n        value = _direct_get_entity_attribute(\n            self,\n            variable,\n            attribute,\n            variable_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_variable_attribute(self, variable, attribute: VariableAttribute, value):\n        def e(attribute):\n            raise ValueError(f\"Unknown variable attribute to set: {attribute}\")\n\n        _direct_set_entity_attribute(\n            self,\n            variable,\n            attribute,\n            value,\n            variable_attribute_set_func_map,\n            e,\n        )\n\n    def number_of_constraints(self, type: ConstraintType):\n        if type not in {ConstraintType.Linear, ConstraintType.Quadratic}:\n            raise ValueError(f\"Unknown constraint type: {type}\")\n        return self.getnumcon()\n\n    def number_of_variables(self):\n        return self.getnumvar()\n\n    def get_model_attribute(self, attribute: ModelAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown model attribute to get: {attribute}\")\n\n        value = _direct_get_model_attribute(\n            self,\n            attribute,\n            model_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_model_attribute(self, attribute: ModelAttribute, value):\n        def e(attribute):\n            raise ValueError(f\"Unknown model attribute to set: {attribute}\")\n\n        _direct_set_model_attribute(\n            self,\n            attribute,\n            value,\n            model_attribute_set_func_map,\n            e,\n        )\n\n    def get_constraint_attribute(self, constraint, attribute: ConstraintAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown constraint attribute to get: {attribute}\")\n\n        value = _direct_get_entity_attribute(\n            self,\n            constraint,\n            attribute,\n            constraint_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_constraint_attribute(\n        self, constraint, attribute: ConstraintAttribute, value\n    ):\n        def e(attribute):\n            raise ValueError(f\"Unknown constraint attribute to set: {attribute}\")\n\n        _direct_set_entity_attribute(\n            self,\n            constraint,\n            attribute,\n            value,\n            constraint_attribute_set_func_map,\n            e,\n        )\n\n    def get_raw_parameter(self, param_name: str):\n        param_type = tell_enum_type(param_name)\n        get_function_map = {\n            int: self.get_raw_parameter_int,\n            float: self.get_raw_parameter_double,\n            str: self.get_raw_parameter_string,\n        }\n        get_function = get_function_map[param_type]\n        return get_function(param_name)\n\n    def set_raw_parameter(self, param_name: str, value):\n        param_type = tell_enum_type(param_name)\n        set_function_map = {\n            int: self.set_raw_parameter_int,\n            float: self.set_raw_parameter_double,\n            str: self.set_raw_parameter_string,\n        }\n        set_function = set_function_map[param_type]\n        set_function(param_name, value)\n\n    def get_raw_information(self, param_name: str):\n        param_type = tell_enum_type(param_name)\n        get_function_map = {\n            int: self.get_raw_information_int,\n            float: self.get_raw_information_double,\n        }\n        get_function = get_function_map[param_type]\n        return get_function(param_name)\n\n    def optimize(self):\n        ret = super().optimize()\n        self.last_solve_return_code = ret\n\n    @overload\n    def add_linear_constraint(\n        self,\n        expr: Union[VariableIndex, ScalarAffineFunction, ExprBuilder],\n        sense: ConstraintSense,\n        rhs: float,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_linear_constraint(\n        self,\n        con: ComparisonConstraint,\n        name: str = \"\",\n    ): ...\n\n    def add_linear_constraint(self, arg, *args, **kwargs):\n        if isinstance(arg, ComparisonConstraint):\n            return self._add_linear_constraint(\n                arg.lhs, arg.sense, arg.rhs, *args, **kwargs\n            )\n        else:\n            return self._add_linear_constraint(arg, *args, **kwargs)\n\n    @overload\n    def add_quadratic_constraint(\n        self,\n        expr: Union[ScalarQuadraticFunction, ExprBuilder],\n        sense: ConstraintSense,\n        rhs: float,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_quadratic_constraint(\n        self,\n        con: ComparisonConstraint,\n        name: str = \"\",\n    ): ...\n\n    def add_quadratic_constraint(self, arg, *args, **kwargs):\n        if isinstance(arg, ComparisonConstraint):\n            return self._add_quadratic_constraint(\n                arg.lhs, arg.sense, arg.rhs, *args, **kwargs\n            )\n        else:\n            return self._add_quadratic_constraint(arg, *args, **kwargs)\n\n    add_variables = make_variable_tupledict\n    add_m_variables = make_variable_ndarray\n    add_m_linear_constraints = add_matrix_constraints\n"
  },
  {
    "path": "src/pyoptinterface/_src/nlfunc.py",
    "content": "from .nlexpr_ext import (\n    ExpressionGraph,\n    ExpressionHandle,\n    UnaryOperator,\n    BinaryOperator,\n    TernaryOperator,\n)\nfrom .core_ext import (\n    VariableIndex,\n    ScalarAffineFunction,\n    ScalarQuadraticFunction,\n    ExprBuilder,\n    ConstraintSense,\n)\nfrom .comparison_constraint import ComparisonConstraint\nimport functools\nimport math\nimport threading\n\n\nclass ExpressionGraphContext:\n    _thread_local = threading.local()\n\n    def __enter__(self):\n        _thread_local = self._thread_local\n        graph = ExpressionGraph()\n        if not hasattr(_thread_local, \"_graph_stack\"):\n            _thread_local._graph_stack = [graph]\n        else:\n            _thread_local._graph_stack.append(graph)\n        return graph\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        self._thread_local._graph_stack.pop()\n\n    @classmethod\n    def current_graph_no_exception(cls):\n        _thread_local = cls._thread_local\n        if not hasattr(_thread_local, \"_graph_stack\"):\n            return None\n        stack = _thread_local._graph_stack\n        if not stack:\n            return None\n        return stack[-1]\n\n    @classmethod\n    def current_graph(cls):\n        _thread_local = cls._thread_local\n        if not hasattr(_thread_local, \"_graph_stack\"):\n            raise RuntimeError(\"No active expression graph context\")\n        stack = _thread_local._graph_stack\n        if not stack:\n            raise RuntimeError(\"No active expression graph context\")\n        return stack[-1]\n\n\ncompare_op_map = {\n    ConstraintSense.LessEqual: BinaryOperator.LessEqual,\n    ConstraintSense.GreaterEqual: BinaryOperator.GreaterEqual,\n    ConstraintSense.Equal: BinaryOperator.Equal,\n}\n\n\ndef convert_to_expressionhandle(graph, expr):\n    if isinstance(expr, ExpressionHandle):\n        return expr\n    elif isinstance(expr, (int, float)):\n        return graph.add_constant(expr)\n    elif isinstance(expr, VariableIndex):\n        return graph.merge_variableindex(expr)\n    elif isinstance(expr, ScalarAffineFunction):\n        return graph.merge_scalaraffinefunction(expr)\n    elif isinstance(expr, ScalarQuadraticFunction):\n        return graph.merge_scalarquadraticfunction(expr)\n    elif isinstance(expr, ExprBuilder):\n        return graph.merge_exprbuilder(expr)\n    elif isinstance(expr, ComparisonConstraint):\n        lhs = convert_to_expressionhandle(graph, expr.lhs)\n        rhs = convert_to_expressionhandle(graph, expr.rhs)\n        if isinstance(lhs, ExpressionHandle) and isinstance(rhs, ExpressionHandle):\n            compare_op = compare_op_map[expr.sense]\n            expr = graph.add_binary(compare_op, lhs, rhs)\n            return expr\n        else:\n            raise TypeError(f\"Unsupported expression type in comparison constraint\")\n    else:\n        return expr\n\n\ndef to_nlexpr(expr):\n    if isinstance(expr, ExpressionHandle):\n        return expr\n    graph = ExpressionGraphContext.current_graph()\n    if isinstance(expr, (int, float)):\n        return graph.add_constant(expr)\n    elif isinstance(expr, VariableIndex):\n        return graph.merge_variableindex(expr)\n    elif isinstance(expr, ScalarAffineFunction):\n        return graph.merge_scalaraffinefunction(expr)\n    elif isinstance(expr, ScalarQuadraticFunction):\n        return graph.merge_scalarquadraticfunction(expr)\n    elif isinstance(expr, ExprBuilder):\n        return graph.merge_exprbuilder(expr)\n    else:\n        raise TypeError(f\"Unsupported expression type: {type(expr)}\")\n\n\n# Implement unary mathematical functions\ndef unary_mathematical_function(math_function, op: UnaryOperator):\n    @functools.wraps(math_function)\n    def f(expr):\n        if isinstance(expr, (int, float)):\n            return math_function(expr)\n        graph = ExpressionGraphContext.current_graph()\n        expr = convert_to_expressionhandle(graph, expr)\n        if isinstance(expr, ExpressionHandle):\n            new_expression = graph.add_unary(op, expr)\n            return new_expression\n        else:\n            return NotImplemented\n\n    return f\n\n\nsin = unary_mathematical_function(math.sin, UnaryOperator.Sin)\ncos = unary_mathematical_function(math.cos, UnaryOperator.Cos)\ntan = unary_mathematical_function(math.tan, UnaryOperator.Tan)\nasin = unary_mathematical_function(math.asin, UnaryOperator.Asin)\nacos = unary_mathematical_function(math.acos, UnaryOperator.Acos)\natan = unary_mathematical_function(math.atan, UnaryOperator.Atan)\nabs = unary_mathematical_function(math.fabs, UnaryOperator.Abs)\nsqrt = unary_mathematical_function(math.sqrt, UnaryOperator.Sqrt)\nexp = unary_mathematical_function(math.exp, UnaryOperator.Exp)\nlog = unary_mathematical_function(math.log, UnaryOperator.Log)\nlog10 = unary_mathematical_function(math.log10, UnaryOperator.Log10)\n\n\n# Implement binary mathematical functions\ndef binary_mathematical_function(math_function, op: BinaryOperator):\n    @functools.wraps(math_function)\n    def f(expr1, expr2):\n        is_number1 = isinstance(expr1, (int, float))\n        is_number2 = isinstance(expr2, (int, float))\n        if is_number1 and is_number2:\n            return math_function(expr1, expr2)\n\n        graph = ExpressionGraphContext.current_graph()\n\n        expr1 = convert_to_expressionhandle(graph, expr1)\n        expr2 = convert_to_expressionhandle(graph, expr2)\n\n        if isinstance(expr1, ExpressionHandle) and isinstance(expr2, ExpressionHandle):\n            new_expression = graph.add_binary(op, expr1, expr2)\n            return new_expression\n        else:\n            return NotImplemented\n\n    return f\n\n\npow = binary_mathematical_function(math.pow, BinaryOperator.Pow)\n\n\ndef ifelse(condition, true_expr, false_expr):\n    graph = ExpressionGraphContext.current_graph()\n    if isinstance(condition, bool):\n        if condition:\n            return true_expr\n        else:\n            return false_expr\n\n    condition = convert_to_expressionhandle(graph, condition)\n    true_expr = convert_to_expressionhandle(graph, true_expr)\n    false_expr = convert_to_expressionhandle(graph, false_expr)\n\n    new_expression = graph.add_ternary(\n        TernaryOperator.IfThenElse, condition, true_expr, false_expr\n    )\n    return new_expression\n"
  },
  {
    "path": "src/pyoptinterface/_src/solver_common.py",
    "content": "# include some common methods for solver intergaces\n\n\ndef _get_model_attribute(\n    model, attribute, get_func_map, value_translate_map, error_callback\n):\n    get_function = get_func_map.get(attribute, None)\n    if not get_function:\n        raise error_callback(attribute)\n    value = get_function(model)\n    translate_function = value_translate_map.get(attribute, None)\n    if translate_function:\n        value = translate_function(value)\n    return value\n\n\ndef _direct_get_model_attribute(model, attribute, get_func_map, error_callback):\n    get_function = get_func_map.get(attribute, None)\n    if not get_function:\n        raise error_callback(attribute)\n    value = get_function(model)\n    return value\n\n\ndef _set_model_attribute(\n    model,\n    attribute,\n    value,\n    set_func_map,\n    value_translate_map,\n    error_callback,\n):\n    translate_function = value_translate_map.get(attribute, None)\n    if translate_function:\n        value = translate_function(value)\n    set_function = set_func_map.get(attribute, None)\n    if not set_function:\n        raise error_callback(attribute)\n    set_function(model, value)\n\n\ndef _direct_set_model_attribute(\n    model,\n    attribute,\n    value,\n    set_func_map,\n    error_callback,\n):\n    set_function = set_func_map.get(attribute, None)\n    if not set_function:\n        raise error_callback(attribute)\n    set_function(model, value)\n\n\ndef _get_entity_attribute(\n    model, entity, attribute, get_func_map, value_translate_map, error_callback\n):\n    get_function = get_func_map.get(attribute, None)\n    if not get_function:\n        raise error_callback(attribute)\n    value = get_function(model, entity)\n    translate_function = value_translate_map.get(attribute, None)\n    if translate_function:\n        value = translate_function(value)\n    return value\n\n\ndef _direct_get_entity_attribute(\n    model, entity, attribute, get_func_map, error_callback\n):\n    get_function = get_func_map.get(attribute, None)\n    if not get_function:\n        raise error_callback(attribute)\n    value = get_function(model, entity)\n    return value\n\n\ndef _set_entity_attribute(\n    model,\n    entity,\n    attribute,\n    value,\n    set_func_map,\n    value_translate_map,\n    error_callback,\n):\n    translate_function = value_translate_map.get(attribute, None)\n    if translate_function:\n        value = translate_function(value)\n    set_function = set_func_map.get(attribute, None)\n    if not set_function:\n        raise error_callback(attribute)\n    set_function(model, entity, value)\n\n\ndef _direct_set_entity_attribute(\n    model,\n    entity,\n    attribute,\n    value,\n    set_func_map,\n    error_callback,\n):\n    set_function = set_func_map.get(attribute, None)\n    if not set_function:\n        raise error_callback(attribute)\n    set_function(model, entity, value)\n"
  },
  {
    "path": "src/pyoptinterface/_src/tupledict.py",
    "content": "from typing import Iterable\nfrom itertools import product\n\nWILDCARD = \"*\"\n\n\nclass tupledict(dict):\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.__select_cache = None\n        self.__scalar = False\n\n    def __setitem__(self, key, value):\n        super().__setitem__(key, value)\n        self.__select_cache = None\n\n    def __delitem__(self, key):\n        super().__delitem__(key)\n        self.__select_cache = None\n\n    def __check_key_length(self):\n        if len(self) == 0:\n            return\n        first_key = next(iter(self.keys()))\n        if isinstance(first_key, tuple):\n            key_len = len(first_key)\n            for k in self.keys():\n                if len(k) != key_len:\n                    raise ValueError(\n                        \"The length of keys in tupledict is not consistent\"\n                    )\n            self.__key_len = key_len\n            self.__scalar = False\n        else:\n            key_len = 1\n            self.__key_len = key_len\n            self.__scalar = True\n\n    def select(self, *keys, with_key=False):\n        if len(keys) == 0:\n            yield from ()\n            return\n        if self.__scalar:\n            if len(keys) != 1:\n                raise ValueError(\n                    \"The length of keys is not consistent with the scalar tupledict\"\n                )\n            key = keys[0]\n            if key == WILDCARD:\n                if with_key:\n                    yield from self.items()\n                else:\n                    yield from self.values()\n            else:\n                if key in self:\n                    if with_key:\n                        yield key, self[key]\n                    else:\n                        yield self[key]\n                else:\n                    yield from ()\n        else:\n            if self.__select_cache is None:\n                self.__check_key_length()\n                self.__select_cache = dict()\n            key_len = self.__key_len\n            if len(keys) > key_len:\n                raise ValueError(\n                    f\"Too many keys for tupledict with {key_len}-tuple keys\"\n                )\n            no_wildcard_indices = tuple(\n                i for i, key in enumerate(keys) if key != WILDCARD\n            )\n            if len(no_wildcard_indices) == 0:\n                if with_key:\n                    yield from self.items()\n                else:\n                    yield from self.values()\n                return\n            no_wildcard_keys = tuple(keys[i] for i in no_wildcard_indices)\n            select_cache = self.__select_cache\n            indices_cache = select_cache.get(no_wildcard_indices, None)\n            if indices_cache is None:\n                indices_cache = dict()\n                for k, v in self.items():\n                    indices = tuple(k[i] for i in no_wildcard_indices)\n                    kv_cache = indices_cache.get(indices, None)\n                    if kv_cache is None:\n                        indices_cache[indices] = [(k, v)]\n                    else:\n                        kv_cache.append((k, v))\n                select_cache[no_wildcard_indices] = indices_cache\n            kv_cache = indices_cache.get(no_wildcard_keys, None)\n            if kv_cache is None:\n                yield from ()\n            else:\n                if with_key:\n                    yield from kv_cache\n                else:\n                    for k, v in kv_cache:\n                        yield v\n\n    def clean(self):\n        self.__select_cache = None\n\n    def map(self, func):\n        return tupledict((k, func(v)) for k, v in self.items())\n\n\ndef flatten_tuple(t):\n    # (1, (2, 3), (4, 5)) -> (1, 2, 3, 4, 5)\n    for it in t:\n        if isinstance(it, tuple) or isinstance(it, list):\n            for element in it:\n                yield element\n        else:\n            yield it\n\n\ndef make_tupledict(*coords: Iterable, rule):\n    d = {}\n    assert len(coords) > 0\n    for coord in product(*coords):\n        # (1, (2, 3), (4, 5)) -> (1, 2, 3, 4, 5)\n        coord = tuple(flatten_tuple(coord))\n        value = rule(*coord)\n        if len(coord) == 1:\n            coord = coord[0]\n        if value is not None:\n            d[coord] = value\n    return tupledict(d)\n"
  },
  {
    "path": "src/pyoptinterface/_src/xpress.py",
    "content": "import os\nimport platform\nfrom pathlib import Path\nimport logging\nfrom typing import Dict, Tuple, Union, overload\n\nfrom .xpress_model_ext import RawModel, Env, load_library, XPRS\nfrom .attributes import (\n    VariableAttribute,\n    ConstraintAttribute,\n    ModelAttribute,\n    ResultStatusCode,\n    TerminationStatusCode,\n)\nfrom .core_ext import (\n    VariableIndex,\n    ScalarAffineFunction,\n    ScalarQuadraticFunction,\n    ExprBuilder,\n    VariableDomain,\n    ConstraintType,\n    ConstraintSense,\n    ObjectiveSense,\n)\nfrom .nlexpr_ext import ExpressionHandle\nfrom .nlfunc import ExpressionGraphContext, convert_to_expressionhandle\nfrom .comparison_constraint import ComparisonConstraint\nfrom .solver_common import (\n    _get_model_attribute,\n    _set_model_attribute,\n    _get_entity_attribute,\n    _direct_get_entity_attribute,\n    _set_entity_attribute,\n    _direct_set_entity_attribute,\n)\n\nfrom .aml import make_variable_tupledict, make_variable_ndarray\nfrom .matrix import add_matrix_constraints\n\n\ndef detected_libraries():\n    libs = []\n\n    subdir = {\n        \"Linux\": \"lib\",\n        \"Darwin\": \"lib\",\n        \"Windows\": \"bin\",\n    }[platform.system()]\n    libname = {\n        \"Linux\": \"libxprs.so\",\n        \"Darwin\": \"libxprs.dylib\",\n        \"Windows\": \"xprs.dll\",\n    }[platform.system()]\n\n    # Environment\n    home = os.environ.get(\"XPRESSDIR\", None)\n    if home and os.path.exists(home):\n        lib = Path(home) / subdir / libname\n        if lib.exists():\n            libs.append(str(lib))\n\n    # default names\n    default_libname = libname\n    libs.append(default_libname)\n\n    return libs\n\n\ndef autoload_library():\n    libs = detected_libraries()\n    for lib in libs:\n        ret = load_library(lib)\n        if ret:\n            logging.info(f\"Loaded Xpress library: {lib}\")\n            return True\n    return False\n\n\nautoload_library()\n\n\n# LP status codes (TerminationStatus, RawStatusString)\n_RAW_LPSTATUS_STRINGS = {\n    XPRS.LPSTATUS.UNSTARTED: (\n        TerminationStatusCode.OPTIMIZE_NOT_CALLED,\n        \"LP problem optimization not started\",\n    ),\n    XPRS.LPSTATUS.OPTIMAL: (\n        TerminationStatusCode.OPTIMAL,\n        \"Optimal LP solution found\",\n    ),\n    XPRS.LPSTATUS.INFEAS: (\n        TerminationStatusCode.INFEASIBLE,\n        \"Infeasible LP problem\",\n    ),\n    XPRS.LPSTATUS.CUTOFF: (\n        TerminationStatusCode.OBJECTIVE_LIMIT,\n        \"LP problem objective worse than cutoff value\",\n    ),\n    XPRS.LPSTATUS.UNFINISHED: (\n        TerminationStatusCode.ITERATION_LIMIT,\n        \"LP problem optimization unfinished\",\n    ),\n    XPRS.LPSTATUS.UNBOUNDED: (\n        TerminationStatusCode.DUAL_INFEASIBLE,\n        \"LP problem is unbounded\",\n    ),\n    XPRS.LPSTATUS.CUTOFF_IN_DUAL: (\n        TerminationStatusCode.OBJECTIVE_LIMIT,\n        \"LP dual bound is worse than dual cutoff value\",\n    ),\n    XPRS.LPSTATUS.UNSOLVED: (\n        TerminationStatusCode.NUMERICAL_ERROR,\n        \"LP problem could not be solved due to numerical issues\",\n    ),\n    XPRS.LPSTATUS.NONCONVEX: (\n        TerminationStatusCode.INVALID_MODEL,\n        \"LP problem contains quadratic data which is not convex, consider using FICO Xpress Global\",\n    ),\n}\n\n# MIP status codes (TerminationStatus, RawStatusString)\n_RAW_MIPSTATUS_STRINGS = {\n    XPRS.MIPSTATUS.NOT_LOADED: (\n        TerminationStatusCode.OPTIMIZE_NOT_CALLED,\n        \"MIP problem has not been loaded\",\n    ),\n    XPRS.MIPSTATUS.LP_NOT_OPTIMAL: (\n        TerminationStatusCode.ITERATION_LIMIT,\n        \"MIP search incomplete, the initial continuous relaxation has not been solved and no integer solution has been found\",\n    ),\n    XPRS.MIPSTATUS.LP_OPTIMAL: (\n        TerminationStatusCode.ITERATION_LIMIT,\n        \"MIP search incomplete, the initial continuous relaxation has been solved and no integer solution has been found\",\n    ),\n    XPRS.MIPSTATUS.NO_SOL_FOUND: (\n        TerminationStatusCode.ITERATION_LIMIT,\n        \"MIP search incomplete, no integer solution found\",\n    ),\n    XPRS.MIPSTATUS.SOLUTION: (\n        TerminationStatusCode.ITERATION_LIMIT,\n        \"MIP search incomplete, an integer solution has been found\",\n    ),\n    XPRS.MIPSTATUS.INFEAS: (\n        TerminationStatusCode.INFEASIBLE,\n        \"MIP search complete, MIP is infeasible, no integer solution found\",\n    ),\n    XPRS.MIPSTATUS.OPTIMAL: (\n        TerminationStatusCode.OPTIMAL,\n        \"MIP search complete, optimal integer solution found\",\n    ),\n    XPRS.MIPSTATUS.UNBOUNDED: (\n        TerminationStatusCode.DUAL_INFEASIBLE,\n        \"MIP search incomplete, the initial continuous relaxation was found to be unbounded. A solution may have been found\",\n    ),\n}\n\n# NLP status codes (TerminationStatus, RawStatusString)\n_RAW_NLPSTATUS_STRINGS = {\n    XPRS.NLPSTATUS.UNSTARTED: (\n        TerminationStatusCode.OPTIMIZE_NOT_CALLED,\n        \"Optimization unstarted\",\n    ),\n    XPRS.NLPSTATUS.SOLUTION: (\n        TerminationStatusCode.LOCALLY_SOLVED,\n        \"Solution found\",\n    ),\n    XPRS.NLPSTATUS.OPTIMAL: (\n        TerminationStatusCode.OPTIMAL,\n        \"Globally optimal\",\n    ),\n    XPRS.NLPSTATUS.NOSOLUTION: (\n        TerminationStatusCode.ITERATION_LIMIT,\n        \"No solution found\",\n    ),\n    XPRS.NLPSTATUS.INFEASIBLE: (\n        TerminationStatusCode.INFEASIBLE,\n        \"Proven infeasible\",\n    ),\n    XPRS.NLPSTATUS.UNBOUNDED: (\n        TerminationStatusCode.DUAL_INFEASIBLE,\n        \"Locally unbounded\",\n    ),\n    XPRS.NLPSTATUS.UNFINISHED: (\n        TerminationStatusCode.ITERATION_LIMIT,\n        \"Not yet solved to completion\",\n    ),\n    XPRS.NLPSTATUS.UNSOLVED: (\n        TerminationStatusCode.NUMERICAL_ERROR,\n        \"Could not be solved due to numerical issues\",\n    ),\n}\n\n\ndef get_terminationstatus(model):\n    opt_type = model.get_optimize_type()\n\n    if opt_type == XPRS.OPTIMIZETYPE.LP:\n        raw_status = model.get_lp_status()\n        status_string_pair = _RAW_LPSTATUS_STRINGS.get(raw_status, None)\n    elif opt_type == XPRS.OPTIMIZETYPE.MIP:\n        raw_status = model.get_mip_status()\n        status_string_pair = _RAW_MIPSTATUS_STRINGS.get(raw_status, None)\n    else:  # NLP or LOCAL\n        raw_status = model.get_nlp_status()\n        status_string_pair = _RAW_NLPSTATUS_STRINGS.get(raw_status, None)\n\n    if not status_string_pair:\n        raise ValueError(f\"Unknown termination status: {raw_status}\")\n    return status_string_pair[0]\n\n\ndef get_primalstatus(model):\n    opt_type = model.get_optimize_type()\n\n    if opt_type == XPRS.OPTIMIZETYPE.LP:\n        status = model.get_lp_status()\n        if status == XPRS.LPSTATUS.OPTIMAL:\n            return ResultStatusCode.FEASIBLE_POINT\n        return ResultStatusCode.NO_SOLUTION\n\n    elif opt_type == XPRS.OPTIMIZETYPE.MIP:\n        status = model.get_mip_status()\n        if model.get_raw_attribute_int_by_id(XPRS.MIPSOLS) > 0:\n            return ResultStatusCode.FEASIBLE_POINT\n        return ResultStatusCode.NO_SOLUTION\n\n    else:  # NLP or LOCAL\n        status = model.get_nlp_status()\n        if status in (\n            XPRS.NLPSTATUS.OPTIMAL,\n            XPRS.NLPSTATUS.SOLUTION,\n            XPRS.NLPSTATUS.UNBOUNDED,\n        ):\n            return ResultStatusCode.FEASIBLE_POINT\n        return ResultStatusCode.NO_SOLUTION\n\n\ndef get_dualstatus(model):\n    opt_type = model.get_optimize_type()\n    if opt_type != XPRS.OPTIMIZETYPE.LP:\n        return ResultStatusCode.NO_SOLUTION\n\n    status = model.get_lp_status()\n    if status == XPRS.LPSTATUS.OPTIMAL:\n        return ResultStatusCode.FEASIBLE_POINT\n    return ResultStatusCode.NO_SOLUTION\n\n\ndef get_rawstatusstring(model):\n    opt_type = model.get_optimize_type()\n\n    if opt_type == XPRS.OPTIMIZETYPE.LP:\n        raw_status = model.get_lp_status()\n        status_string_pair = _RAW_LPSTATUS_STRINGS.get(raw_status, None)\n    elif opt_type == XPRS.OPTIMIZETYPE.MIP:\n        raw_status = model.get_mip_status()\n        status_string_pair = _RAW_MIPSTATUS_STRINGS.get(raw_status, None)\n    else:  # NLP or LOCAL\n        raw_status = model.get_nlp_status()\n        status_string_pair = _RAW_NLPSTATUS_STRINGS.get(raw_status, None)\n\n    if not status_string_pair:\n        raise ValueError(f\"Unknown termination status: {raw_status}\")\n    return status_string_pair[1]\n\n\n# Variable maps\nvariable_attribute_get_func_map = {  # UB, LB, Name, etc\n    VariableAttribute.Value: lambda model, v: model.get_variable_value(v),\n    VariableAttribute.LowerBound: lambda model, v: model.get_variable_lowerbound(v),\n    VariableAttribute.UpperBound: lambda model, v: model.get_variable_upperbound(v),\n    VariableAttribute.PrimalStart: lambda model, v: model.get_variable_mip_start(v),\n    VariableAttribute.Domain: lambda model, v: model.get_variable_type(v),\n    VariableAttribute.Name: lambda model, v: model.get_variable_name(v),\n    VariableAttribute.IISLowerBound: lambda model, v: model.get_variable_lowerbound_IIS(\n        v\n    ),\n    VariableAttribute.IISUpperBound: lambda model, v: model.get_variable_upperbound_IIS(\n        v\n    ),\n    VariableAttribute.ReducedCost: lambda model, v: model.get_variable_rc(v),\n}\n\nvariable_attribute_set_func_map = (\n    {  # Subset of the previous one about stuff that can be set\n        VariableAttribute.LowerBound: lambda model, v, x: model.set_variable_lowerbound(\n            v, x\n        ),\n        VariableAttribute.UpperBound: lambda model, v, x: model.set_variable_upperbound(\n            v, x\n        ),\n        VariableAttribute.PrimalStart: lambda model, v, x: model.set_variable_mip_start(\n            v, x\n        ),\n        VariableAttribute.Domain: lambda model, v, x: model.set_variable_type(v, x),\n        VariableAttribute.Name: lambda model, v, x: model.set_variable_name(v, x),\n    }\n)\n\nconstraint_attribute_get_func_map = {\n    ConstraintAttribute.Name: lambda model, c: model.get_constraint_name(c),\n    ConstraintAttribute.Primal: lambda model, c: model.get_normalized_rhs(c)\n    - model.get_constraint_slack(c),\n    ConstraintAttribute.Dual: lambda model, c: model.get_constraint_dual(c),\n    ConstraintAttribute.IIS: lambda model, c: model.is_constraint_in_IIS(c),\n}\n\nconstraint_attribute_set_func_map = {\n    ConstraintAttribute.Name: lambda model, constraint, value: model.set_constraint_name(\n        constraint, value\n    ),\n}\n\nmodel_attribute_get_func_map = {\n    ModelAttribute.Name: lambda model: model.get_problem_name(),\n    ModelAttribute.ObjectiveSense: lambda model: model.get_raw_attribute_dbl_by_id(\n        XPRS.OBJSENSE\n    ),\n    ModelAttribute.BarrierIterations: lambda model: model.get_raw_attribute_int_by_id(\n        XPRS.BARITER\n    ),\n    ModelAttribute.DualObjectiveValue: lambda model: model.get_raw_attribute_dbl_by_id(\n        XPRS.LPOBJVAL\n    ),\n    ModelAttribute.NodeCount: lambda model: model.get_raw_attribute_int_by_id(\n        XPRS.NODES\n    ),\n    ModelAttribute.ObjectiveBound: lambda model: model.get_raw_attribute_dbl_by_id(\n        XPRS.LPOBJVAL\n    ),\n    ModelAttribute.ObjectiveValue: lambda model: model.get_raw_attribute_dbl_by_id(\n        XPRS.OBJVAL\n    ),\n    ModelAttribute.SimplexIterations: lambda model: model.get_raw_attribute_int_by_id(\n        XPRS.SIMPLEXITER\n    ),\n    ModelAttribute.SolveTimeSec: lambda model: model.get_raw_attribute_dbl_by_id(\n        XPRS.TIME\n    ),\n    ModelAttribute.NumberOfThreads: lambda model: model.get_raw_control_int(\n        XPRS.THREADS\n    ),\n    ModelAttribute.RelativeGap: lambda model: model.get_raw_control_dbl_by_id(\n        XPRS.MIPRELSTOP\n    ),\n    ModelAttribute.TimeLimitSec: lambda model: model.get_raw_contorl_dbl_by_id(\n        XPRS.TIMELIMIT\n    ),\n    ModelAttribute.DualStatus: get_dualstatus,\n    ModelAttribute.PrimalStatus: get_primalstatus,\n    ModelAttribute.RawStatusString: get_rawstatusstring,\n    ModelAttribute.TerminationStatus: get_terminationstatus,\n    ModelAttribute.Silent: lambda model: model.get_raw_control_int_by_id(XPRS.OUTPUTLOG)\n    == 0,\n    ModelAttribute.SolverName: lambda _: \"FICO Xpress\",\n    ModelAttribute.SolverVersion: lambda model: model.version_string(),\n}\n\nmodel_control_set_func_map = {\n    ModelAttribute.Name: lambda model, value: model.set_problem_name(value),\n    ModelAttribute.ObjectiveSense: lambda model, value: model.set_raw_control_dbl_by_id(\n        XPRS.OBJSENSE, value\n    ),\n    ModelAttribute.NumberOfThreads: lambda model, value: model.set_raw_control_int_by_id(\n        XPRS.THREADS, value\n    ),\n    ModelAttribute.TimeLimitSec: lambda model, value: model.set_raw_control_dbl_by_id(\n        XPRS.TIMELIMIT, value\n    ),\n    ModelAttribute.Silent: lambda model, value: model.set_raw_control_int_by_id(\n        XPRS.OUTPUTLOG, 0 if value else 1\n    ),\n}\n\nmodel_attribute_get_translate_func_map = {\n    ModelAttribute.ObjectiveSense: lambda v: {\n        XPRS.OBJ_MINIMIZE: ObjectiveSense.Minimize,\n        XPRS.OBJ_MAXIMIZE: ObjectiveSense.Maximize,\n    }[v],\n}\n\nmodel_attribute_set_translate_func_map = {\n    ModelAttribute.ObjectiveSense: lambda v: {\n        ObjectiveSense.Minimize: XPRS.OBJ_MINIMIZE,\n        ObjectiveSense.Maximize: XPRS.OBJ_MAXIMIZE,\n    }[v],\n}\n\nDEFAULT_ENV = None\n\n\ndef init_default_env():\n    global DEFAULT_ENV\n    if DEFAULT_ENV is None:\n        DEFAULT_ENV = Env()\n\n\nclass Model(RawModel):\n    def __init__(self, env=None):\n        # Initializing with raw model object\n        if isinstance(env, RawModel):\n            super().__init__(env)\n            return\n\n        if env is None:\n            init_default_env()\n            env = DEFAULT_ENV\n        super().__init__(env)\n        self.mip_start_values: Dict[VariableIndex, float] = dict()\n\n    def optimize(self):\n        if self._is_mip():\n            mip_start = self.mip_start_values\n            if len(mip_start) != 0:\n                variables = list(mip_start.keys())\n                values = list(mip_start.values())\n                self.add_mip_start(variables, values)\n                mip_start.clear()\n        super().optimize()\n\n    @staticmethod\n    def supports_variable_attribute(attribute: VariableAttribute, settable=False):\n        if settable:\n            return attribute in variable_attribute_set_func_map\n        else:\n            return attribute in variable_attribute_get_func_map\n\n    @staticmethod\n    def supports_model_attribute(attribute: ModelAttribute, settable=False):\n        if settable:\n            return attribute in model_control_set_func_map\n        else:\n            return attribute in model_attribute_get_func_map\n\n    @staticmethod\n    def supports_constraint_attribute(attribute: ConstraintAttribute, settable=False):\n        if settable:\n            return attribute in constraint_attribute_set_func_map\n        else:\n            return attribute in constraint_attribute_get_func_map\n\n    def get_variable_attribute(self, variable, attribute: VariableAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown variable attribute to get: {attribute}\")\n\n        value = _direct_get_entity_attribute(\n            self,\n            variable,\n            attribute,\n            variable_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_variable_attribute(self, variable, attribute: VariableAttribute, value):\n        def e(attribute):\n            raise ValueError(f\"Unknown variable attribute to set: {attribute}\")\n\n        _direct_set_entity_attribute(\n            self,\n            variable,\n            attribute,\n            value,\n            variable_attribute_set_func_map,\n            e,\n        )\n\n    def number_of_constraints(self, type: ConstraintType):\n        if type in {ConstraintType.Linear, ConstraintType.Quadratic}:\n            return self.get_raw_attribute_int_by_id(XPRS.ROWS)\n        if type == ConstraintType.SOS:\n            return self.get_raw_attribute_int_by_id(XPRS.SETS)\n        raise ValueError(f\"Unknown constraint type: {type}\")\n\n    def number_of_variables(self):\n        return self.get_raw_attribute_int_by_id(XPRS.INPUTCOLS)\n\n    def get_model_attribute(self, attribute: ModelAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown model attribute to get: {attribute}\")\n\n        value = _get_model_attribute(\n            self,\n            attribute,\n            model_attribute_get_func_map,\n            model_attribute_get_translate_func_map,\n            e,\n        )\n        return value\n\n    def set_model_attribute(self, attribute: ModelAttribute, value):\n        def e(attribute):\n            raise ValueError(f\"Unknown model attribute to set: {attribute}\")\n\n        _set_model_attribute(\n            self,\n            attribute,\n            value,\n            model_control_set_func_map,\n            model_attribute_set_translate_func_map,\n            e,\n        )\n\n    def get_constraint_attribute(self, constraint, attribute: ConstraintAttribute):\n        def e(attribute):\n            raise ValueError(f\"Unknown constraint attribute to get: {attribute}\")\n\n        value = _direct_get_entity_attribute(\n            self,\n            constraint,\n            attribute,\n            constraint_attribute_get_func_map,\n            e,\n        )\n        return value\n\n    def set_constraint_attribute(\n        self, constraint, attribute: ConstraintAttribute, value\n    ):\n        def e(attribute):\n            raise ValueError(f\"Unknown constraint attribute to set: {attribute}\")\n\n        _direct_set_entity_attribute(\n            self,\n            constraint,\n            attribute,\n            value,\n            constraint_attribute_set_func_map,\n            e,\n        )\n\n    @overload\n    def add_linear_constraint(\n        self,\n        expr: Union[VariableIndex, ScalarAffineFunction, ExprBuilder],\n        sense: ConstraintSense,\n        rhs: float,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_linear_constraint(\n        self,\n        expr: Union[VariableIndex, ScalarAffineFunction, ExprBuilder],\n        interval: Tuple[float, float],\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_linear_constraint(\n        self,\n        con: ComparisonConstraint,\n        name: str = \"\",\n    ): ...\n\n    def add_linear_constraint(self, arg, *args, **kwargs):\n        if isinstance(arg, ComparisonConstraint):\n            return self._add_linear_constraint(\n                arg.lhs, arg.sense, arg.rhs, *args, **kwargs\n            )\n        else:\n            return self._add_linear_constraint(arg, *args, **kwargs)\n\n    @overload\n    def add_quadratic_constraint(\n        self,\n        expr: Union[ScalarQuadraticFunction, ExprBuilder],\n        sense: ConstraintSense,\n        rhs: float,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_quadratic_constraint(\n        self,\n        con: ComparisonConstraint,\n        name: str = \"\",\n    ): ...\n\n    def add_quadratic_constraint(self, arg, *args, **kwargs):\n        if isinstance(arg, ComparisonConstraint):\n            return self._add_quadratic_constraint(\n                arg.lhs, arg.sense, arg.rhs, *args, **kwargs\n            )\n        else:\n            return self._add_quadratic_constraint(arg, *args, **kwargs)\n\n    @overload\n    def add_nl_constraint(\n        self,\n        expr,\n        sense: ConstraintSense,\n        rhs: float,\n        /,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_nl_constraint(\n        self,\n        expr,\n        interval: Tuple[float, float],\n        /,\n        name: str = \"\",\n    ): ...\n\n    @overload\n    def add_nl_constraint(\n        self,\n        con,\n        /,\n        name: str = \"\",\n    ): ...\n\n    def add_nl_constraint(self, expr, *args, **kwargs):\n        graph = ExpressionGraphContext.current_graph()\n        expr = convert_to_expressionhandle(graph, expr)\n        if not isinstance(expr, ExpressionHandle):\n            raise ValueError(\"Expression should be convertible to ExpressionHandle\")\n\n        con = self._add_single_nl_constraint(graph, expr, *args, **kwargs)\n        return con\n\n    def add_nl_objective(self, expr):\n        graph = ExpressionGraphContext.current_graph()\n        expr = convert_to_expressionhandle(graph, expr)\n        if not isinstance(expr, ExpressionHandle):\n            raise ValueError(\"Expression should be convertible to ExpressionHandle\")\n        self._add_single_nl_objective(graph, expr)\n\n    def set_callback(self, cb, where):\n        def cb_wrapper(raw_model, ctx):\n            # Warning: This is super hacky. We need to provide a complete Model\n            # object to the callback (a RawModel is not enough). Xpress invokes\n            # callbacks with thread-local problem pointers, so we reuse the\n            # original object by swapping the pointers temporarily. This is\n            # okay because we've serialized access to the model anyway (GIL\n            # limitation). But all of this happens at the C++ level, here we\n            # only need to provide the user callback with the original complete\n            # Model object. So it looks like we're giving the original model to\n            # the callbacks, but in reality we pull a switcheroo behind the\n            # curtains.\n            cb(self, ctx)\n\n        super().set_callback(cb_wrapper, where)\n\n    add_variables = make_variable_tupledict\n    add_m_variables = make_variable_ndarray\n    add_m_linear_constraints = add_matrix_constraints\n"
  },
  {
    "path": "src/pyoptinterface/copt.py",
    "content": "from pyoptinterface._src.copt import Model, autoload_library\nfrom pyoptinterface._src.copt_model_ext import (\n    EnvConfig,\n    Env,\n    COPT,\n    load_library,\n    is_library_loaded,\n)\n\n__all__ = [\n    \"Model\",\n    \"EnvConfig\",\n    \"Env\",\n    \"COPT\",\n    \"autoload_library\",\n    \"load_library\",\n    \"is_library_loaded\",\n]\n"
  },
  {
    "path": "src/pyoptinterface/gurobi.py",
    "content": "from pyoptinterface._src.gurobi import Model, Env, autoload_library\nfrom pyoptinterface._src.gurobi_model_ext import (\n    GRB,\n    load_library,\n    is_library_loaded,\n)\n\n__all__ = [\n    \"Model\",\n    \"Env\",\n    \"GRB\",\n    \"autoload_library\",\n    \"load_library\",\n    \"is_library_loaded\",\n]\n"
  },
  {
    "path": "src/pyoptinterface/highs.py",
    "content": "from pyoptinterface._src.highs import Model, autoload_library\nfrom pyoptinterface._src.highs_model_ext import Enum, load_library, is_library_loaded\n\n__all__ = [\"Model\", \"Enum\", \"autoload_library\", \"load_library\", \"is_library_loaded\"]\n"
  },
  {
    "path": "src/pyoptinterface/ipopt.py",
    "content": "from pyoptinterface._src.ipopt import Model\nfrom pyoptinterface._src.ipopt_model_ext import (\n    ApplicationReturnStatus,\n    load_library,\n    is_library_loaded,\n)\n\n__all__ = [\"Model\", \"ApplicationReturnStatus\", \"load_library\", \"is_library_loaded\"]\n"
  },
  {
    "path": "src/pyoptinterface/knitro.py",
    "content": "from pyoptinterface._src.knitro import Env, Model, autoload_library\nfrom pyoptinterface._src.knitro_model_ext import (\n    KN,\n    load_library,\n    is_library_loaded,\n    has_valid_license,\n)\n\n__all__ = [\n    \"Env\",\n    \"Model\",\n    \"KN\",\n    \"autoload_library\",\n    \"load_library\",\n    \"is_library_loaded\",\n    \"has_valid_license\",\n]\n"
  },
  {
    "path": "src/pyoptinterface/mosek.py",
    "content": "from pyoptinterface._src.mosek import Model, autoload_library\nfrom pyoptinterface._src.mosek_model_ext import (\n    Env,\n    Enum,\n    load_library,\n    is_library_loaded,\n)\n\n__all__ = [\n    \"Model\",\n    \"Env\",\n    \"Enum\",\n    \"autoload_library\",\n    \"load_library\",\n    \"is_library_loaded\",\n]\n"
  },
  {
    "path": "src/pyoptinterface/nl.py",
    "content": "from pyoptinterface._src.nlfunc import (\n    ExpressionGraphContext as graph,\n    to_nlexpr,\n    sin,\n    cos,\n    tan,\n    asin,\n    acos,\n    atan,\n    abs,\n    sqrt,\n    exp,\n    log,\n    log10,\n    pow,\n    ifelse,\n)\n"
  },
  {
    "path": "src/pyoptinterface/xpress.py",
    "content": "from pyoptinterface._src.xpress import Model, autoload_library\nfrom pyoptinterface._src.xpress_model_ext import (\n    Env,\n    XPRS,\n    load_library,\n    is_library_loaded,\n    license,\n    beginlicensing,\n    endlicensing,\n)\n\n__all__ = [\n    \"Model\",\n    \"Env\",\n    \"XPRS\",\n    \"autoload_library\",\n    \"load_library\",\n    \"is_library_loaded\",\n    \"license\",\n    \"beginlicensing\",\n    \"endlicensing\",\n]\n"
  },
  {
    "path": "tests/conftest.py",
    "content": "import pytest\nimport platform\n\nfrom pyoptinterface import gurobi, xpress, copt, mosek, highs, ipopt, knitro\n\nnlp_model_dict = {}\n\nif ipopt.is_library_loaded():\n\n    def llvm():\n        return ipopt.Model(jit=\"LLVM\")\n\n    def c():\n        return ipopt.Model(jit=\"C\")\n\n    nlp_model_dict[\"ipopt_llvm\"] = llvm\n    system = platform.system()\n    if system != \"Darwin\":\n        # On macOS, loading dynamic library of Gurobi/Xpress/COPT/Mosek before loading libtcc will cause memory error\n        # The reason is still unclear\n        nlp_model_dict[\"ipopt_c\"] = c\n\nif copt.is_library_loaded():\n    nlp_model_dict[\"copt\"] = copt.Model\n\nif knitro.is_library_loaded() and knitro.has_valid_license():\n    nlp_model_dict[\"knitro\"] = knitro.Model\n\n\n@pytest.fixture(params=nlp_model_dict.keys())\ndef nlp_model_ctor(request):\n    name = request.param\n    ctor = nlp_model_dict[name]\n    return ctor\n\n\nmodel_interface_dict_full = {}\n\nif gurobi.is_library_loaded():\n    model_interface_dict_full[\"gurobi\"] = gurobi.Model\nif xpress.is_library_loaded():\n    model_interface_dict_full[\"xpress\"] = xpress.Model\nif copt.is_library_loaded():\n    model_interface_dict_full[\"copt\"] = copt.Model\nif mosek.is_library_loaded():\n    model_interface_dict_full[\"mosek\"] = mosek.Model\nif highs.is_library_loaded():\n    model_interface_dict_full[\"highs\"] = highs.Model\nif knitro.is_library_loaded() and knitro.has_valid_license():\n    model_interface_dict_full[\"knitro\"] = knitro.Model\n\n\n@pytest.fixture(params=model_interface_dict_full.keys())\ndef model_interface(request):\n    name = request.param\n    model_interface_class = model_interface_dict_full[name]\n    return model_interface_class()\n\n\nmodel_interface_dict_oneshot = model_interface_dict_full.copy()\nif ipopt.is_library_loaded():\n    model_interface_dict_oneshot[\"ipopt\"] = ipopt.Model\n\n\n@pytest.fixture(params=model_interface_dict_oneshot.keys())\ndef model_interface_oneshot(request):\n    name = request.param\n    model_interface_class = model_interface_dict_oneshot[name]\n    return model_interface_class()\n"
  },
  {
    "path": "tests/simple_cb.py",
    "content": "import pyoptinterface as poi\nfrom pyoptinterface import gurobi, xpress\n\nGRB = gurobi.GRB\nXPRS = xpress.XPRS\n\n\ndef simple_cb(f):\n    model = f()\n\n    x = model.add_variable(lb=0.0, ub=20.0)\n    y = model.add_variable(lb=8.0, ub=20.0)\n\n    model.set_variable_attribute(x, poi.VariableAttribute.Name, \"x\")\n    model.set_variable_attribute(y, poi.VariableAttribute.Name, \"y\")\n\n    obj = x * x + y * y\n    model.set_objective(obj, poi.ObjectiveSense.Minimize)\n\n    conexpr = x + y\n    model.add_linear_constraint(\n        conexpr, poi.ConstraintSense.GreaterEqual, 10.0, name=\"con1\"\n    )\n\n    def cb(model, where):\n        runtime = 0.0\n        coldel = 0\n        rowdel = 0\n        if isinstance(model, gurobi.Model) and where == GRB.Callback.PRESOLVE:\n            runtime = model.cb_get_info(GRB.Callback.RUNTIME)\n            coldel = model.cb_get_info(GRB.Callback.PRE_COLDEL)\n            rowdel = model.cb_get_info(GRB.Callback.PRE_ROWDEL)\n            print(f\"Runtime: {runtime}, Coldel: {coldel}, Rowdel: {rowdel}\")\n        if isinstance(model, xpress.Model) and where == XPRS.CB_CONTEXT.PRESOLVE:\n            runtime = model.get_raw_attribute_dbl_by_id(XPRS.TIME)\n            coldel = model.get_raw_attribute_int_by_id(\n                XPRS.ORIGINALCOLS\n            ) - model.get_raw_attribute_int_by_id(XPRS.COLS)\n            rowdel = model.get_raw_attribute_int_by_id(\n                XPRS.ORIGINALROWS\n            ) - model.get_raw_attribute_int_by_id(XPRS.ROWS)\n            print(\n                f\"CB[AFTER-PRESOLVE] >> Runtime: {runtime}, Coldel: {coldel}, Rowdel: {rowdel}\"\n            )\n        if isinstance(model, xpress.Model) and where == XPRS.CB_CONTEXT.MESSAGE:\n            args = model.cb_get_arguments()\n            print(f\"CB[MESSAGE-{args.msgtype}] >> {args.msg}\")\n\n    if isinstance(model, gurobi.Model):\n        model.set_callback(cb)\n    elif isinstance(model, xpress.Model):\n        model.set_callback(cb, XPRS.CB_CONTEXT.PRESOLVE | XPRS.CB_CONTEXT.MESSAGE)\n\n    model.set_model_attribute(poi.ModelAttribute.Silent, False)\n    model.optimize()\n\n\nif xpress.is_library_loaded():\n    simple_cb(xpress.Model)\nif gurobi.is_library_loaded():\n    simple_cb(gurobi.Model)\n"
  },
  {
    "path": "tests/test_basic.py",
    "content": "import pyoptinterface as poi\nimport numpy as np\nfrom pytest import approx\n\nfrom pyoptinterface._src.core_ext import IntMonotoneIndexer\n\n\ndef test_basic():\n    vars = [poi.VariableIndex(i) for i in range(10)]\n    v = vars[0]\n    assert v.index == 0\n\n    t = poi.ExprBuilder()\n    t += v\n    t += v * v\n    assert t.degree() == 2\n    assert t.empty() == False\n\n    t = poi.ExprBuilder(v)\n    t.add_affine_term(vars[1], 2.0)\n    t += 3.0 * vars[2]\n    t -= 4.0 * vars[3]\n    assert t.degree() == 1\n    assert t.empty() == False\n\n    saf = poi.ScalarAffineFunction(t)\n    saf.canonicalize()\n    assert list(saf.variables) == [0, 1, 2, 3]\n    assert np.allclose(saf.coefficients, [1.0, 2.0, 3.0, -4.0])\n\n    saf = 2.0 - 1.0 * saf * -4.0 / 2.0 + 1.0\n    saf.canonicalize()\n    assert list(saf.variables) == [0, 1, 2, 3]\n    assert np.allclose(saf.coefficients, [2.0, 4.0, 6.0, -8.0])\n    assert saf.constant == approx(3.0)\n\n    sqf = v * v + 2.0 * v + 1.0\n    sqf = 2.0 - 1.0 * sqf * -4.0 / 2.0 + 1.0\n    sqf.canonicalize()\n    assert list(sqf.variable_1s) == [0]\n    assert list(sqf.variable_2s) == [0]\n    assert np.allclose(sqf.coefficients, [2.0])\n    assert list(sqf.affine_part.variables) == [0]\n    assert np.allclose(sqf.affine_part.coefficients, [4.0])\n    assert sqf.affine_part.constant == approx(5.0)\n\n    t = poi.ExprBuilder(v)\n    t *= 2.0\n    assert t.degree() == 1\n\n    t *= vars[0]\n    assert t.degree() == 2\n\n    t /= 0.5\n    assert t.degree() == 2\n\n    t = poi.ExprBuilder(v * v + 2.0 * v + 1.0)\n    t += 2.0\n    t -= v\n    t *= 4.0\n    t /= 2.0\n    sqf = poi.ScalarQuadraticFunction(t)\n    sqf.canonicalize()\n    assert list(sqf.variable_1s) == [0]\n    assert list(sqf.variable_2s) == [0]\n    assert np.allclose(sqf.coefficients, [2.0])\n    assert list(sqf.affine_part.variables) == [0]\n    assert np.allclose(sqf.affine_part.coefficients, [2.0])\n    assert sqf.affine_part.constant == approx(6.0)\n\n\ndef test_affineexpr_from_numpy():\n    N = 25\n    coefs = np.arange(N, dtype=np.float64)\n    vars = np.arange(N, dtype=np.int_) * 2\n    coefs.flags.writeable = False\n    vars.flags.writeable = False\n\n    expr = poi.ScalarAffineFunction.from_numpy(coefs, vars)\n\n    assert list(expr.variables) == list(vars)\n    assert np.allclose(expr.coefficients, coefs)\n\n    constant = 3.0\n    expr = poi.ScalarAffineFunction.from_numpy(coefs, vars, constant)\n\n    assert list(expr.variables) == list(vars)\n    assert np.allclose(expr.coefficients, coefs)\n    assert expr.constant == approx(constant)\n\n\ndef test_monotoneindexer():\n    indexer = IntMonotoneIndexer()\n\n    N = 200\n    for i in range(N):\n        index = indexer.add_index()\n        assert index == i\n\n    for i in range(N - 1):\n        indexer.delete_index(i)\n        x = indexer.get_index(i + 1)\n        assert x == 0\n        x = indexer.get_index(N - 1)\n        assert x == N - 1 - (i + 1)\n        x = indexer.get_index(0)\n        assert x == -1\n"
  },
  {
    "path": "tests/test_close.py",
    "content": "from pyoptinterface import gurobi, xpress, copt, mosek\n\nenvs = []\nmodels = []\nif gurobi.is_library_loaded():\n    envs.append(gurobi.Env)\n    models.append(gurobi.Model)\nif xpress.is_library_loaded():\n    envs.append(xpress.Env)\n    models.append(xpress.Model)\nif copt.is_library_loaded():\n    envs.append(copt.Env)\n    models.append(copt.Model)\nif mosek.is_library_loaded():\n    envs.append(mosek.Env)\n    models.append(mosek.Model)\n\n\ndef test_close():\n    for env, model in zip(envs, models):\n        env_instance = env()\n        model_instance = model(env_instance)\n\n        model_instance.close()\n        env_instance.close()\n"
  },
  {
    "path": "tests/test_compare_constraint.py",
    "content": "import pyoptinterface as poi\n\nimport pytest\n\n\ndef test_compare_constraint(model_interface):\n    model = model_interface\n\n    x = model.add_variable(lb=0.0)\n    y = model.add_variable(lb=0.0)\n\n    def t_expr(expr):\n        con = model.add_linear_constraint(expr >= 1.0)\n        model.set_objective(expr)\n        model.optimize()\n        expr_value = model.get_value(expr)\n        assert expr_value == pytest.approx(1.0, abs=1e-6)\n        model.delete_constraint(con)\n\n        con = model.add_linear_constraint(expr <= 2.0)\n        model.set_objective(expr, poi.ObjectiveSense.Maximize)\n        model.optimize()\n        expr_value = model.get_value(expr)\n        assert expr_value == pytest.approx(2.0, abs=1e-6)\n        model.delete_constraint(con)\n\n        con = model.add_linear_constraint(expr == 3.0)\n        model.set_objective(expr, poi.ObjectiveSense.Maximize)\n        model.optimize()\n        expr_value = model.get_value(expr)\n        assert expr_value == pytest.approx(3.0, abs=1e-6)\n        model.delete_constraint(con)\n\n        con = model.add_linear_constraint(1.0 <= expr)\n        model.set_objective(expr)\n        model.optimize()\n        expr_value = model.get_value(expr)\n        assert expr_value == pytest.approx(1.0, abs=1e-6)\n        model.delete_constraint(con)\n\n        con = model.add_linear_constraint(2.0 >= expr)\n        model.set_objective(expr, poi.ObjectiveSense.Maximize)\n        model.optimize()\n        expr_value = model.get_value(expr)\n        assert expr_value == pytest.approx(2.0, abs=1e-6)\n        model.delete_constraint(con)\n\n        con = model.add_linear_constraint(3.0 == expr)\n        model.set_objective(expr, poi.ObjectiveSense.Maximize)\n        model.optimize()\n        expr_value = model.get_value(expr)\n        assert expr_value == pytest.approx(3.0, abs=1e-6)\n        model.delete_constraint(con)\n\n    def t_binary_expr(lhs, rhs):\n        expr = lhs - rhs\n\n        con = model.add_linear_constraint(lhs >= rhs + 1.0)\n        model.set_objective(expr)\n        model.optimize()\n        expr_value = model.get_value(expr)\n        assert expr_value == pytest.approx(1.0, abs=1e-6)\n        model.delete_constraint(con)\n\n        con = model.add_linear_constraint(lhs <= rhs + 2.0)\n        model.set_objective(expr, poi.ObjectiveSense.Maximize)\n        model.optimize()\n        expr_value = model.get_value(expr)\n        assert expr_value == pytest.approx(2.0, abs=1e-6)\n        model.delete_constraint(con)\n\n        con = model.add_linear_constraint(lhs == rhs + 3.0)\n        model.set_objective(expr, poi.ObjectiveSense.Maximize)\n        model.optimize()\n        expr_value = model.get_value(expr)\n        assert expr_value == pytest.approx(3.0, abs=1e-6)\n        model.delete_constraint(con)\n\n        con = model.add_linear_constraint(1.0 + rhs <= lhs)\n        model.set_objective(expr)\n        model.optimize()\n        expr_value = model.get_value(expr)\n        assert expr_value == pytest.approx(1.0, abs=1e-6)\n        model.delete_constraint(con)\n\n        con = model.add_linear_constraint(2.0 + rhs >= lhs)\n        model.set_objective(expr, poi.ObjectiveSense.Maximize)\n        model.optimize()\n        expr_value = model.get_value(expr)\n        assert expr_value == pytest.approx(2.0, abs=1e-6)\n        model.delete_constraint(con)\n\n        con = model.add_linear_constraint(3.0 + rhs == lhs)\n        model.set_objective(expr, poi.ObjectiveSense.Maximize)\n        model.optimize()\n        expr_value = model.get_value(expr)\n        assert expr_value == pytest.approx(3.0, abs=1e-6)\n        model.delete_constraint(con)\n\n    expr = x + y\n    t_expr(expr)\n\n    expr = poi.ExprBuilder(x + y)\n    t_expr(expr)\n\n    for lhs in [x, poi.ScalarAffineFunction(x), poi.ExprBuilder(x)]:\n        for rhs in [y, poi.ScalarAffineFunction(y), poi.ExprBuilder(y)]:\n            t_binary_expr(lhs, rhs)\n\n    if hasattr(model, \"add_quadratic_constraint\"):\n        con_expr = x * x + y * y\n        expr = x + y\n\n        con = model.add_quadratic_constraint(con_expr <= 18.0)\n        model.set_objective(expr, poi.ObjectiveSense.Maximize)\n        model.optimize()\n        expr_value = model.get_value(expr)\n        assert expr_value == pytest.approx(6.0, abs=1e-5)\n        model.delete_constraint(con)\n\n        con = model.add_quadratic_constraint(32.0 >= con_expr)\n        model.set_objective(expr, poi.ObjectiveSense.Maximize)\n        model.optimize()\n        expr_value = model.get_value(expr)\n        assert expr_value == pytest.approx(8.0, abs=1e-5)\n        model.delete_constraint(con)\n"
  },
  {
    "path": "tests/test_exp_cone.py",
    "content": "import pyoptinterface as poi\nfrom pytest import approx\nimport pytest\nimport math\n\n\ndef test_exp_cone(model_interface):\n    model = model_interface\n\n    if not hasattr(model, \"add_exp_cone_constraint\"):\n        pytest.skip(\"Model interface does not support exponential cone constraints\")\n\n    N = 4\n    x = model.add_variables(range(N), lb=1.0)\n    t = model.add_variables(range(N), lb=0.0)\n    one = model.add_variable(lb=1.0, ub=1.0, name=\"one\")\n\n    obj = poi.quicksum(t)\n    model.set_objective(obj, poi.ObjectiveSense.Minimize)\n\n    con = poi.make_tupledict(\n        range(N), rule=lambda i: model.add_exp_cone_constraint([t[i], one, x[i]])\n    )\n\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n\n    x_val = x.map(model.get_value)\n    t_val = t.map(model.get_value)\n    for i in range(N):\n        assert x_val[i] == approx(1.0)\n        assert t_val[i] == approx(math.e)\n\n    obj_val = model.get_value(obj)\n    assert obj_val == approx(N * math.e)\n\n    model.delete_constraint(con[0])\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n\n    x_val = x.map(model.get_value)\n    t_val = t.map(model.get_value)\n    for i in range(1, N):\n        assert x_val[i] == approx(1.0)\n        assert t_val[i] == approx(math.e)\n\n    obj_val = model.get_value(obj)\n    assert obj_val == approx((N - 1) * math.e)\n"
  },
  {
    "path": "tests/test_iis.py",
    "content": "import pyoptinterface as poi\nimport pytest\n\n\ndef test_constraint_iis(model_interface):\n    model = model_interface\n\n    if not hasattr(model, \"computeIIS\"):\n        pytest.skip(\"Model interface does not support IIS computation\")\n\n    x = model.add_variable(lb=0.0, name=\"x\")\n    y = model.add_variable(lb=0.0, name=\"y\")\n\n    con1 = model.add_linear_constraint(x + y, poi.Geq, 5.0)\n    con2 = model.add_linear_constraint(x + 2 * y, poi.Leq, 1.0)\n\n    model.set_objective(x)\n\n    model.computeIIS()\n\n    con1_iis = model.get_constraint_attribute(con1, poi.ConstraintAttribute.IIS)\n    con2_iis = model.get_constraint_attribute(con2, poi.ConstraintAttribute.IIS)\n\n    assert con1_iis\n    assert con2_iis\n\n\ndef test_variable_iis(model_interface):\n    model = model_interface\n\n    if not hasattr(model, \"computeIIS\"):\n        pytest.skip(\"Model interface does not support IIS computation\")\n\n    x = model.add_variable(lb=0.0, ub=2.0, name=\"x\")\n    y = model.add_variable(lb=0.0, ub=3.0, name=\"y\")\n\n    con1 = model.add_linear_constraint(x + y, poi.Geq, 6.0)\n\n    model.set_objective(x)\n\n    model.computeIIS()\n\n    con1_iis = model.get_constraint_attribute(con1, poi.ConstraintAttribute.IIS)\n    x_lb_iis = model.get_variable_attribute(x, poi.VariableAttribute.IISLowerBound)\n    x_ub_iis = model.get_variable_attribute(x, poi.VariableAttribute.IISUpperBound)\n    y_lb_iis = model.get_variable_attribute(y, poi.VariableAttribute.IISLowerBound)\n    y_ub_iis = model.get_variable_attribute(y, poi.VariableAttribute.IISUpperBound)\n\n    assert con1_iis\n    assert not x_lb_iis\n    assert x_ub_iis\n    assert not y_lb_iis\n    assert y_ub_iis\n"
  },
  {
    "path": "tests/test_in_constraint.py",
    "content": "import pyoptinterface as poi\nfrom pyoptinterface import nl, gurobi\n\nimport pytest\n\n\ndef test_linear_in_constraint(model_interface_oneshot):\n    model = model_interface_oneshot\n\n    if isinstance(model, gurobi.Model):\n        pytest.skip(\"Gurobi does not support range linear constraints\")\n\n    x = model.add_variable(lb=0.0)\n    y = model.add_variable(lb=0.0)\n\n    expr = x + y\n    model.add_linear_constraint(expr, (0, 1.0))\n    model.set_objective(expr)\n    model.optimize()\n\n    expr_value = model.get_value(expr)\n    assert expr_value == pytest.approx(0.0, abs=1e-6)\n\n    model.set_objective(-expr)\n    model.optimize()\n\n    expr_value = model.get_value(expr)\n    assert expr_value == pytest.approx(1.0, rel=1e-6)\n\n\ndef test_nl_in_constraint(nlp_model_ctor):\n    model = nlp_model_ctor()\n\n    x = model.add_variable(lb=0.0)\n    y = model.add_variable(lb=0.0)\n\n    with nl.graph():\n        expr = nl.exp(x) + nl.exp(y)\n        model.add_nl_constraint(expr, (5.0, 10.0))\n        model.add_nl_objective(expr)\n\n    model.optimize()\n    objective_value = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n    assert objective_value == pytest.approx(5.0, abs=1e-6)\n"
  },
  {
    "path": "tests/test_ipopt.py",
    "content": "import pytest\nimport pyoptinterface as poi\nfrom pyoptinterface import ipopt, nl\n\npytestmark = pytest.mark.skipif(\n    not ipopt.is_library_loaded(), reason=\"IPOPT library not available\"\n)\n\nOPTIMIZE_RE = r\"optimize\\(\\)\"\n\n\ndef _build_simple_model():\n    \"\"\"Build a simple model: min x^2 s.t. x >= 0.5\"\"\"\n    model = ipopt.Model()\n    x = model.add_variable(lb=0.0, ub=10.0)\n    model.set_objective(x**2)\n    con = model.add_linear_constraint(x, poi.Geq, 0.5)\n    return model, x, con\n\n\nclass TestUnoptimizedModelRaises:\n    \"\"\"Accessing variable/constraint/objective values before calling optimize() should raise.\"\"\"\n\n    def test_get_variable_value_before_optimize(self):\n        model, x, _con = _build_simple_model()\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_value(x)\n\n    def test_get_objective_value_before_optimize(self):\n        model, _x, _con = _build_simple_model()\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n\n    def test_get_constraint_primal_before_optimize(self):\n        model, _x, con = _build_simple_model()\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_constraint_attribute(con, poi.ConstraintAttribute.Primal)\n\n    def test_get_constraint_dual_before_optimize(self):\n        model, _x, con = _build_simple_model()\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_constraint_attribute(con, poi.ConstraintAttribute.Dual)\n\n\nclass TestDirtyAfterModificationRaises:\n    \"\"\"After a successful optimize(), modifying the model (adding variables/constraints)\n    should make it dirty and re-querying values should raise.\"\"\"\n\n    def test_dirty_after_add_variable(self):\n        model, x, con = _build_simple_model()\n        model.optimize()\n        # Values should be accessible now\n        model.get_value(x)\n        model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n\n        # Add a new variable to make the model dirty\n        model.add_variable(lb=0.0, ub=10.0)\n\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_value(x)\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_constraint_attribute(con, poi.ConstraintAttribute.Primal)\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_constraint_attribute(con, poi.ConstraintAttribute.Dual)\n\n    def test_dirty_after_add_linear_constraint(self):\n        model, x, _con = _build_simple_model()\n        model.optimize()\n        model.get_value(x)\n\n        # Add a linear constraint to make the model dirty\n        model.add_linear_constraint(x, poi.Leq, 5.0)\n\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_value(x)\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n\n    def test_dirty_after_add_quadratic_constraint(self):\n        model, x, _con = _build_simple_model()\n        model.optimize()\n        model.get_value(x)\n\n        # Add a quadratic constraint to make the model dirty\n        model.add_quadratic_constraint(x**2, poi.Leq, 25.0)\n\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_value(x)\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n\n    def test_dirty_after_add_nl_constraint(self):\n        model, x, _con = _build_simple_model()\n        model.optimize()\n        model.get_value(x)\n\n        # Add a nonlinear constraint to make the model dirty\n        with nl.graph():\n            model.add_nl_constraint(nl.exp(x), poi.Leq, 100.0)\n\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_value(x)\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n\n    def test_reoptimize_clears_dirty(self):\n        \"\"\"After re-optimizing, values should be accessible again.\"\"\"\n        model, x, con = _build_simple_model()\n        model.optimize()\n\n        # Modify model\n        model.add_linear_constraint(x, poi.Leq, 5.0)\n\n        # Dirty – raises\n        with pytest.raises(RuntimeError, match=OPTIMIZE_RE):\n            model.get_value(x)\n\n        # Re-optimize – should clear the dirty flag\n        model.optimize()\n\n        val = model.get_value(x)\n        assert val == pytest.approx(0.5, abs=1e-6)\n        obj = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n        assert obj == pytest.approx(0.25, abs=1e-6)\n        primal = model.get_constraint_attribute(con, poi.ConstraintAttribute.Primal)\n        assert primal == pytest.approx(0.5, abs=1e-6)\n"
  },
  {
    "path": "tests/test_knitro.py",
    "content": "import pytest\nfrom pytest import approx\n\nfrom pyoptinterface import knitro\nimport pyoptinterface as poi\n\npytestmark = pytest.mark.skipif(\n    not knitro.is_library_loaded() or not knitro.has_valid_license(),\n    reason=\"KNITRO library is not loaded or license is not valid\",\n)\n\n\ndef test_new_model_without_env():\n    \"\"\"Test creating a model without an environment (default behavior).\"\"\"\n    model = knitro.Model()\n\n    x = model.add_variable(lb=0.0, ub=10.0)\n    y = model.add_variable(lb=0.0, ub=10.0)\n\n    model.set_objective(x + y, poi.ObjectiveSense.Minimize)\n    model.add_linear_constraint(x + y, poi.ConstraintSense.GreaterEqual, 5.0)\n\n    model.optimize()\n\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n\n    x_val = model.get_value(x)\n    y_val = model.get_value(y)\n    assert x_val + y_val == approx(5.0)\n\n\ndef test_new_model_with_env():\n    \"\"\"Test creating a model with an environment.\"\"\"\n    env = knitro.Env()\n    model = knitro.Model(env=env)\n\n    x = model.add_variable(lb=0.0, ub=10.0)\n    y = model.add_variable(lb=0.0, ub=10.0)\n\n    model.set_objective(x + y, poi.ObjectiveSense.Minimize)\n    model.add_linear_constraint(x + y, poi.ConstraintSense.GreaterEqual, 5.0)\n\n    model.optimize()\n\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n\n    x_val = model.get_value(x)\n    y_val = model.get_value(y)\n    assert x_val + y_val == approx(5.0)\n\n\ndef test_multiple_models_single_env():\n    \"\"\"Test creating multiple models sharing the same environment.\"\"\"\n    env = knitro.Env()\n\n    model1 = knitro.Model(env=env)\n    model2 = knitro.Model(env=env)\n\n    x1 = model1.add_variable(lb=0.0, ub=10.0)\n    model1.set_objective(x1, poi.ObjectiveSense.Minimize)\n    model1.add_linear_constraint(x1, poi.ConstraintSense.GreaterEqual, 3.0)\n    model1.optimize()\n\n    x2 = model2.add_variable(lb=0.0, ub=10.0)\n    model2.set_objective(x2, poi.ObjectiveSense.Minimize)\n    model2.add_linear_constraint(x2, poi.ConstraintSense.GreaterEqual, 5.0)\n    model2.optimize()\n\n    assert model1.get_value(x1) == approx(3.0)\n    assert model2.get_value(x2) == approx(5.0)\n\n\ndef test_multiple_models_multiple_envs():\n    \"\"\"Test creating multiple models each with its own environment.\"\"\"\n    env1 = knitro.Env()\n    env2 = knitro.Env()\n\n    model1 = knitro.Model(env=env1)\n    model2 = knitro.Model(env=env2)\n\n    x1 = model1.add_variable(lb=0.0, ub=10.0)\n    model1.set_objective(x1, poi.ObjectiveSense.Minimize)\n    model1.add_linear_constraint(x1, poi.ConstraintSense.GreaterEqual, 4.0)\n    model1.optimize()\n\n    x2 = model2.add_variable(lb=0.0, ub=10.0)\n    model2.set_objective(x2, poi.ObjectiveSense.Minimize)\n    model2.add_linear_constraint(x2, poi.ConstraintSense.GreaterEqual, 6.0)\n    model2.optimize()\n\n    assert model1.get_value(x1) == approx(4.0)\n    assert model2.get_value(x2) == approx(6.0)\n\n\ndef test_env_lifetime():\n    \"\"\"Test that environment properly manages its lifetime.\"\"\"\n    env = knitro.Env()\n    model = knitro.Model(env=env)\n\n    x = model.add_variable(lb=0.0, ub=10.0)\n    model.set_objective(x, poi.ObjectiveSense.Minimize)\n    model.add_linear_constraint(x, poi.ConstraintSense.GreaterEqual, 2.0)\n    model.optimize()\n\n    assert model.get_value(x) == approx(2.0)\n\n    model.close()\n\n    try:\n        del env\n    except Exception as e:\n        pytest.fail(f\"Deleting environment raised an error: {e}\")\n\n\ndef test_env_close():\n    \"\"\"Test that env.close() properly releases the license.\"\"\"\n    env = knitro.Env()\n\n    model = knitro.Model(env=env)\n    x = model.add_variable(lb=0.0, ub=10.0)\n    model.set_objective(x, poi.ObjectiveSense.Minimize)\n    model.add_linear_constraint(x, poi.ConstraintSense.GreaterEqual, 1.0)\n    model.optimize()\n    assert model.get_value(x) == approx(1.0)\n    model.close()\n\n    try:\n        env.close()\n    except Exception as e:\n        pytest.fail(f\"env.close() raised an error: {e}\")\n\n\ndef test_init_with_env():\n    \"\"\"Test using init method with an environment.\"\"\"\n    env = knitro.Env()\n    model = knitro.Model()\n    model.init(env)\n    x = model.add_variable(lb=0.0, ub=10.0)\n    model.set_objective(x, poi.ObjectiveSense.Minimize)\n    model.add_linear_constraint(x, poi.ConstraintSense.GreaterEqual, 1.0)\n    model.optimize()\n\n    assert model.get_value(x) == approx(1.0)\n\n    model.close()\n    del model\n    del env\n\n\ndef test_model_with_empty_env():\n    \"\"\"Test that creating a model with an empty environment raises an error.\"\"\"\n    env = knitro.Env(empty=True)\n    assert env.is_empty\n\n    with pytest.raises(RuntimeError, match=\"Empty environment\"):\n        knitro.Model(env=env)\n\n\ndef test_model_init_with_empty_env_after_start():\n    \"\"\"Test that initializing a model with an empty environment after starting raises an error.\"\"\"\n    env = knitro.Env(empty=True)\n    assert env.is_empty\n\n    env.start()\n    assert knitro.Model(env=env) is not None\n\n\ndef test_model_dirty():\n    \"\"\"Test the dirty method.\"\"\"\n    model = knitro.Model()\n\n    assert model.dirty() is True\n\n    x = model.add_variable(lb=0.0, ub=10.0)\n    assert model.dirty() is True\n\n    model.set_objective(x, poi.ObjectiveSense.Minimize)\n    model.add_linear_constraint(x, poi.ConstraintSense.GreaterEqual, 1.0)\n    model.optimize()\n\n    assert model.dirty() is False\n\n    model.add_variable(lb=0.0, ub=5.0)\n    assert model.dirty() is True\n\n\ndef test_model_is_dirty():\n    \"\"\"Test the is_dirty property.\"\"\"\n    model = knitro.Model()\n\n    assert model.is_dirty is True\n\n    x = model.add_variable(lb=0.0, ub=10.0)\n    assert model.is_dirty is True\n\n    model.set_objective(x, poi.ObjectiveSense.Minimize)\n    model.add_linear_constraint(x, poi.ConstraintSense.GreaterEqual, 1.0)\n    model.optimize()\n\n    assert model.is_dirty is False\n\n    model.add_variable(lb=0.0, ub=5.0)\n    assert model.is_dirty is True\n\n\ndef test_model_empty():\n    \"\"\"Test the empty() method.\"\"\"\n    model = knitro.Model()\n    assert model.empty() is False\n    model.close()\n    assert model.empty() is True\n\n\ndef test_model_is_empty_property():\n    \"\"\"Test the is_empty property.\"\"\"\n    model = knitro.Model()\n    assert model.is_empty is False\n    model.close()\n    assert model.is_empty is True\n\n\ndef test_number_of_variables():\n    \"\"\"Test number_of_variables() method.\"\"\"\n    model = knitro.Model()\n\n    assert model.number_of_variables() == 0\n\n    model.add_variable()\n    assert model.number_of_variables() == 1\n\n    model.add_variable()\n    model.add_variable()\n    assert model.number_of_variables() == 3\n\n\ndef test_number_of_constraints():\n    \"\"\"Test number_of_constraints() method.\"\"\"\n    model = knitro.Model()\n    x = model.add_variable(lb=-10.0, ub=10.0)\n    y = model.add_variable(lb=-10.0, ub=10.0)\n\n    assert model.number_of_constraints() == 0\n    assert model.number_of_constraints(poi.ConstraintType.Linear) == 0\n    assert model.number_of_constraints(poi.ConstraintType.Quadratic) == 0\n\n    model.add_linear_constraint(x + y, poi.ConstraintSense.LessEqual, 5.0)\n    assert model.number_of_constraints() == 1\n    assert model.number_of_constraints(poi.ConstraintType.Linear) == 1\n\n    model.add_quadratic_constraint(x * x + y, poi.ConstraintSense.LessEqual, 10.0)\n    assert model.number_of_constraints() == 2\n    assert model.number_of_constraints(poi.ConstraintType.Quadratic) == 1\n\n\ndef test_supports_attribute_methods():\n    \"\"\"Test supports_*_attribute() static methods.\"\"\"\n    assert knitro.Model.supports_variable_attribute(poi.VariableAttribute.Value) is True\n    assert (\n        knitro.Model.supports_variable_attribute(poi.VariableAttribute.LowerBound)\n        is True\n    )\n    assert (\n        knitro.Model.supports_variable_attribute(\n            poi.VariableAttribute.LowerBound, setable=True\n        )\n        is True\n    )\n    assert (\n        knitro.Model.supports_variable_attribute(\n            poi.VariableAttribute.Value, setable=True\n        )\n        is False\n    )\n\n    assert (\n        knitro.Model.supports_constraint_attribute(poi.ConstraintAttribute.Primal)\n        is True\n    )\n    assert (\n        knitro.Model.supports_constraint_attribute(poi.ConstraintAttribute.Name) is True\n    )\n    assert (\n        knitro.Model.supports_constraint_attribute(\n            poi.ConstraintAttribute.Name, setable=True\n        )\n        is True\n    )\n\n    assert (\n        knitro.Model.supports_model_attribute(poi.ModelAttribute.ObjectiveValue) is True\n    )\n    assert knitro.Model.supports_model_attribute(poi.ModelAttribute.SolverName) is True\n    assert (\n        knitro.Model.supports_model_attribute(poi.ModelAttribute.Silent, setable=True)\n        is True\n    )\n    assert (\n        knitro.Model.supports_model_attribute(\n            poi.ModelAttribute.ObjectiveValue, setable=True\n        )\n        is False\n    )\n    assert (\n        knitro.Model.supports_model_attribute(\n            poi.ModelAttribute.NumberOfThreads, setable=True\n        )\n        is True\n    )\n    assert (\n        knitro.Model.supports_model_attribute(\n            poi.ModelAttribute.TimeLimitSec, setable=True\n        )\n        is True\n    )\n\n\ndef test_model_attribute_solver_info():\n    \"\"\"Test getting solver info model attributes.\"\"\"\n    model = knitro.Model()\n\n    solver_name = model.get_model_attribute(poi.ModelAttribute.SolverName)\n    assert solver_name == \"KNITRO\"\n\n    solver_version = model.get_model_attribute(poi.ModelAttribute.SolverVersion)\n    assert isinstance(solver_version, str)\n    assert len(solver_version) > 0\n\n\ndef test_model_attribute_after_solve():\n    \"\"\"Test model attributes after solving.\"\"\"\n    model = knitro.Model()\n    x = model.add_variable(lb=0.0, ub=10.0)\n    y = model.add_variable(lb=0.0, ub=10.0)\n\n    model.set_objective(x + 2 * y, poi.ObjectiveSense.Minimize)\n    model.add_linear_constraint(x + y, poi.ConstraintSense.GreaterEqual, 5.0)\n    model.optimize()\n\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n\n    primal_status = model.get_model_attribute(poi.ModelAttribute.PrimalStatus)\n    assert primal_status == poi.ResultStatusCode.FEASIBLE_POINT\n\n    raw_status = model.get_model_attribute(poi.ModelAttribute.RawStatusString)\n    assert isinstance(raw_status, str)\n    assert \"KNITRO\" in raw_status\n\n    obj_value = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n    assert obj_value == approx(5.0)\n\n    obj_sense = model.get_model_attribute(poi.ModelAttribute.ObjectiveSense)\n    assert obj_sense == poi.ObjectiveSense.Minimize\n\n    solve_time = model.get_model_attribute(poi.ModelAttribute.SolveTimeSec)\n    assert isinstance(solve_time, float)\n    assert solve_time >= 0.0\n\n    iterations = model.get_model_attribute(poi.ModelAttribute.BarrierIterations)\n    assert isinstance(iterations, int)\n    assert iterations >= 0\n\n\ndef test_set_model_attribute_objective_sense():\n    \"\"\"Test setting objective sense.\"\"\"\n    model = knitro.Model()\n    model.add_variable(lb=0.0, ub=10.0)\n\n    model.set_model_attribute(\n        poi.ModelAttribute.ObjectiveSense, poi.ObjectiveSense.Maximize\n    )\n    assert (\n        model.get_model_attribute(poi.ModelAttribute.ObjectiveSense)\n        == poi.ObjectiveSense.Maximize\n    )\n\n    model.set_model_attribute(\n        poi.ModelAttribute.ObjectiveSense, poi.ObjectiveSense.Minimize\n    )\n    assert (\n        model.get_model_attribute(poi.ModelAttribute.ObjectiveSense)\n        == poi.ObjectiveSense.Minimize\n    )\n\n\ndef test_set_model_attribute_silent():\n    \"\"\"Test setting silent mode (should not raise error).\"\"\"\n    model = knitro.Model()\n    x = model.add_variable(lb=0.0, ub=10.0)\n    model.set_objective(x, poi.ObjectiveSense.Minimize)\n    model.add_linear_constraint(x, poi.ConstraintSense.GreaterEqual, 1.0)\n\n    model.set_model_attribute(poi.ModelAttribute.Silent, True)\n    model.optimize()\n\n    assert model.get_value(x) == approx(1.0)\n\n\ndef test_set_model_attribute_threads():\n    \"\"\"Test setting number of threads.\"\"\"\n    model = knitro.Model()\n\n    model.set_model_attribute(poi.ModelAttribute.NumberOfThreads, 2)\n    threads = model.get_model_attribute(poi.ModelAttribute.NumberOfThreads)\n    assert threads == 2\n\n\ndef test_set_model_attribute_time_limit():\n    \"\"\"Test setting time limit (set only, get may not work due to param type mismatch).\"\"\"\n    model = knitro.Model()\n\n    model.set_model_attribute(poi.ModelAttribute.TimeLimitSec, 100.0)\n\n\ndef test_variable_attribute_bounds():\n    \"\"\"Test getting and setting variable bounds.\"\"\"\n    model = knitro.Model()\n    x = model.add_variable(lb=0.0, ub=10.0)\n\n    lb = model.get_variable_attribute(x, poi.VariableAttribute.LowerBound)\n    ub = model.get_variable_attribute(x, poi.VariableAttribute.UpperBound)\n    assert lb == approx(0.0)\n    assert ub == approx(10.0)\n\n    model.set_variable_attribute(x, poi.VariableAttribute.LowerBound, 1.0)\n    model.set_variable_attribute(x, poi.VariableAttribute.UpperBound, 5.0)\n\n    lb = model.get_variable_attribute(x, poi.VariableAttribute.LowerBound)\n    ub = model.get_variable_attribute(x, poi.VariableAttribute.UpperBound)\n    assert lb == approx(1.0)\n    assert ub == approx(5.0)\n\n\ndef test_variable_attribute_name():\n    \"\"\"Test getting and setting variable name.\"\"\"\n    model = knitro.Model()\n    x = model.add_variable(name=\"my_var\")\n\n    name = model.get_variable_attribute(x, poi.VariableAttribute.Name)\n    assert name == \"my_var\"\n\n    model.set_variable_attribute(x, poi.VariableAttribute.Name, \"new_name\")\n    name = model.get_variable_attribute(x, poi.VariableAttribute.Name)\n    assert name == \"new_name\"\n\n\ndef test_variable_attribute_value():\n    \"\"\"Test getting variable value after solve.\"\"\"\n    model = knitro.Model()\n    x = model.add_variable(lb=0.0, ub=10.0)\n\n    model.set_objective(x, poi.ObjectiveSense.Minimize)\n    model.add_linear_constraint(x, poi.ConstraintSense.GreaterEqual, 3.0)\n    model.optimize()\n\n    value = model.get_variable_attribute(x, poi.VariableAttribute.Value)\n    assert value == approx(3.0)\n\n\ndef test_variable_attribute_primal_start():\n    \"\"\"Test setting primal start value.\"\"\"\n    model = knitro.Model()\n    x = model.add_variable(lb=0.0, ub=10.0)\n\n    model.set_variable_attribute(x, poi.VariableAttribute.PrimalStart, 5.0)\n\n    model.set_objective(x, poi.ObjectiveSense.Minimize)\n    model.add_linear_constraint(x, poi.ConstraintSense.GreaterEqual, 2.0)\n    model.optimize()\n\n    assert model.get_value(x) == approx(2.0)\n\n\ndef test_variable_attribute_domain():\n    \"\"\"Test getting and setting variable domain.\"\"\"\n    model = knitro.Model()\n    x = model.add_variable(lb=0.0, ub=10.0)\n\n    # Default domain should be Continuous\n    domain = model.get_variable_attribute(x, poi.VariableAttribute.Domain)\n    assert domain == poi.VariableDomain.Continuous\n\n    # Set to Integer and verify\n    model.set_variable_attribute(\n        x, poi.VariableAttribute.Domain, poi.VariableDomain.Integer\n    )\n    domain = model.get_variable_attribute(x, poi.VariableAttribute.Domain)\n    assert domain == poi.VariableDomain.Integer\n\n    model.set_objective(x, poi.ObjectiveSense.Minimize)\n    model.add_linear_constraint(x, poi.ConstraintSense.GreaterEqual, 2.5)\n    model.optimize()\n\n    assert model.get_value(x) == approx(3.0)\n\n    # Test Binary domain\n    y = model.add_variable(domain=poi.VariableDomain.Binary)\n    domain = model.get_variable_attribute(y, poi.VariableAttribute.Domain)\n    assert domain == poi.VariableDomain.Binary\n\n\ndef test_constraint_attribute_name():\n    \"\"\"Test getting and setting constraint name.\"\"\"\n    model = knitro.Model()\n    x = model.add_variable(lb=0.0, ub=10.0)\n\n    con = model.add_linear_constraint(\n        x, poi.ConstraintSense.LessEqual, 5.0, name=\"my_con\"\n    )\n\n    name = model.get_constraint_attribute(con, poi.ConstraintAttribute.Name)\n    assert name == \"my_con\"\n\n    model.set_constraint_attribute(con, poi.ConstraintAttribute.Name, \"new_con\")\n    name = model.get_constraint_attribute(con, poi.ConstraintAttribute.Name)\n    assert name == \"new_con\"\n\n\ndef test_constraint_attribute_primal_dual():\n    \"\"\"Test getting constraint primal and dual values after solve.\"\"\"\n    model = knitro.Model()\n    x = model.add_variable(lb=0.0, ub=10.0)\n    y = model.add_variable(lb=0.0, ub=10.0)\n\n    model.set_objective(x + y, poi.ObjectiveSense.Minimize)\n    con = model.add_linear_constraint(x + y, poi.ConstraintSense.GreaterEqual, 5.0)\n    model.optimize()\n\n    primal = model.get_constraint_attribute(con, poi.ConstraintAttribute.Primal)\n    assert primal == approx(5.0)\n\n    dual = model.get_constraint_attribute(con, poi.ConstraintAttribute.Dual)\n    assert isinstance(dual, float)\n"
  },
  {
    "path": "tests/test_lukvle10.py",
    "content": "import pytest\n\nimport pyoptinterface as poi\nfrom pyoptinterface import ipopt, nl, copt\n\n\ndef test_nlp_lukvle10(nlp_model_ctor):\n    # LUKSAN-VLCEK Problem 10\n    #\n    # min  sum[i=1..n] (x[2i]^2)^(x[2i+1]^2 + 1) + (x[2i+1]^2)^(x[2i]^2 + 1)\n    # s.t. (3 - 2*x[i+1])*x[i+1] + 1 - x[i] - 2*x[i+2] = 0,  i = 1,...,2n-2\n    #\n    # Starting point: x[2i] = -1, x[2i+1] = 1\n    model = nlp_model_ctor()\n    if isinstance(model, ipopt.Model):\n        # LUKVLE10 is too large and IPOPT raises a bad_alloc error.\n        pytest.skip(\"lukvle10 is too large to be supported with IPOPT\")\n    if isinstance(model, copt.Model):\n        # LUKVLE10 is too large the current license of COpt supports up\n        # to 2000 variables.\n        pytest.skip(\"lukvle10 is too large to be supported with COpt\")\n\n    n = 1250\n    x = model.add_m_variables(2 * n, name=\"x\")\n\n    for i in range(2 * n - 2):\n        model.add_quadratic_constraint(\n            (3 - 2 * x[i + 1]) * x[i + 1] + 1 - x[i] - 2 * x[i + 2],\n            poi.ConstraintSense.Equal,\n            0.0,\n            name=f\"c{i}\",\n        )\n\n    with nl.graph():\n        for i in range(n):\n            model.add_nl_objective(\n                nl.pow(x[2 * i] ** 2, (x[2 * i + 1] ** 2) + 1)\n                + nl.pow(x[2 * i + 1] ** 2, (x[2 * i] ** 2) + 1)\n            )\n\n    for i in range(n):\n        model.set_variable_attribute(x[2 * i], poi.VariableAttribute.PrimalStart, -1.0)\n        model.set_variable_attribute(\n            x[2 * i + 1], poi.VariableAttribute.PrimalStart, 1.0\n        )\n\n    model.optimize()\n    model.set_model_attribute(poi.ModelAttribute.Silent, False)\n\n    termination_status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert termination_status == poi.TerminationStatusCode.OPTIMAL\n"
  },
  {
    "path": "tests/test_matrix_api.py",
    "content": "import pyoptinterface as poi\nimport numpy as np\nfrom scipy.sparse import coo_array\nfrom pytest import approx\n\n\ndef test_matrix_api(model_interface_oneshot):\n    model = model_interface_oneshot\n\n    N = 10\n    x = model.add_m_variables(N, lb=0.0)\n    A = np.eye(N)\n    ub = 3.0\n    lb = 1.0\n    A_sparse = coo_array(np.eye(N))\n    model.add_m_linear_constraints(A, x, poi.Leq, ub)\n    model.add_m_linear_constraints(A_sparse, x, poi.Geq, lb)\n\n    obj = poi.quicksum(x)\n\n    model.set_objective(obj)\n    model.optimize()\n    obj_value = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n    assert obj_value == approx(N * lb)\n\n    model.set_objective(-obj)\n    model.optimize()\n    obj_value = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n    assert obj_value == approx(-N * ub)\n\n\ndef test_quicksum_ndarray(model_interface_oneshot):\n    model = model_interface_oneshot\n\n    N = 10\n    x = model.add_m_variables((N, 2 * N), lb=1.0, ub=3.0)\n    obj = poi.quicksum(x)\n    model.set_objective(obj)\n    model.optimize()\n    obj_value = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n    assert obj_value == approx(2 * N**2)\n"
  },
  {
    "path": "tests/test_nlp.py",
    "content": "import math\nimport pytest\n\nimport pyoptinterface as poi\nfrom pyoptinterface import ipopt, nl\n\n\ndef test_easy_nlp(nlp_model_ctor):\n    model = nlp_model_ctor()\n\n    x = model.add_variable(lb=0.1, ub=10.0)\n    y = model.add_variable(lb=0.1, ub=10.0)\n\n    model.add_linear_constraint(x + y, poi.Eq, 1.0)\n\n    with nl.graph():\n        model.add_nl_objective(nl.exp(x) + nl.exp(y))\n\n    with nl.graph():\n        z = x * x\n        s = y * y\n        model.add_nl_constraint(z, (0.36, 4.0))\n        model.add_nl_constraint(s, (0.04, 4.0))\n\n    nl_funcs = [\n        nl.abs,\n        nl.acos,\n        nl.asin,\n        nl.atan,\n        nl.cos,\n        nl.exp,\n        nl.log,\n        nl.log10,\n        nl.pow,\n        nl.sin,\n        nl.sqrt,\n        nl.tan,\n    ]\n\n    B = 1e10\n    all_nlfuncs_con = []\n    with nl.graph():\n        for f in nl_funcs:\n            if f == nl.pow:\n                v = f(x, 2)\n            else:\n                v = f(x)\n            con = model.add_nl_constraint(v, (-B, B))\n            all_nlfuncs_con.append(con)\n\n    model.optimize()\n\n    termination_status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert (\n        termination_status == poi.TerminationStatusCode.LOCALLY_SOLVED\n        or termination_status == poi.TerminationStatusCode.OPTIMAL\n    )\n\n    x_value = model.get_value(x)\n    y_value = model.get_value(y)\n    assert x_value == pytest.approx(0.6)\n    assert y_value == pytest.approx(0.4)\n\n    obj_value = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n    assert obj_value == pytest.approx(math.exp(x_value) + math.exp(y_value))\n\n    con_values = [\n        model.get_constraint_attribute(con, poi.ConstraintAttribute.Primal)\n        for con in all_nlfuncs_con\n    ]\n\n    correct_con_values = []\n    for f in nl_funcs:\n        if f == nl.pow:\n            correct_con_values.append(f(x_value, 2))\n        else:\n            correct_con_values.append(f(x_value))\n\n    assert con_values == pytest.approx(correct_con_values)\n\n\ndef test_nlfunc_ifelse(nlp_model_ctor):\n    model = nlp_model_ctor()\n    if not isinstance(model, ipopt.Model):\n        pytest.skip(\"ifelse is only supported in IPOPT\")\n\n    for x_, fx in zip([0.2, 0.5, 1.0, 2.0, 3.0], [0.2, 0.5, 1.0, 4.0, 9.0]):\n        model = nlp_model_ctor()\n\n        x = model.add_variable(lb=0.0, ub=10.0)\n\n        with nl.graph():\n            y = nl.ifelse(x > 1.0, x**2, x)\n            model.add_nl_constraint(y, poi.Geq, fx)\n\n        model.set_objective(x)\n\n        model.optimize()\n\n        x_value = model.get_value(x)\n        assert x_value == pytest.approx(x_)\n\n\n@pytest.mark.skipif(not ipopt.is_library_loaded(), reason=\"IPOPT library not available\")\ndef test_ipopt_optimizer_not_called():\n    model = ipopt.Model()\n\n    x = model.add_variable(lb=0.0, ub=10.0)\n    termination_status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert termination_status == poi.TerminationStatusCode.OPTIMIZE_NOT_CALLED\n\n    model.set_objective(x**2)\n    model.optimize()\n    termination_status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert termination_status == poi.TerminationStatusCode.LOCALLY_SOLVED\n\n    model.add_linear_constraint(x >= 0.5)\n    termination_status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert termination_status == poi.TerminationStatusCode.OPTIMIZE_NOT_CALLED\n\n    model.optimize()\n    termination_status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert termination_status == poi.TerminationStatusCode.LOCALLY_SOLVED\n\n    model.add_quadratic_constraint(x**2 >= 0.36)\n    termination_status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert termination_status == poi.TerminationStatusCode.OPTIMIZE_NOT_CALLED\n\n    model.optimize()\n    termination_status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert termination_status == poi.TerminationStatusCode.LOCALLY_SOLVED\n\n    with nl.graph():\n        model.add_nl_constraint(nl.exp(x) <= 100.0)\n    termination_status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert termination_status == poi.TerminationStatusCode.OPTIMIZE_NOT_CALLED\n\n    model.optimize()\n    termination_status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert termination_status == poi.TerminationStatusCode.LOCALLY_SOLVED\n\n    with nl.graph():\n        model.add_nl_objective(nl.log(x))\n    termination_status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert termination_status == poi.TerminationStatusCode.OPTIMIZE_NOT_CALLED\n\n    model.optimize()\n    termination_status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert termination_status == poi.TerminationStatusCode.LOCALLY_SOLVED\n\n\nif __name__ == \"__main__\":\n\n    def c():\n        return ipopt.Model(jit=\"C\")\n\n    test_easy_nlp(c)\n    test_nlfunc_ifelse(c)\n\n    def llvm():\n        return ipopt.Model(jit=\"LLVM\")\n\n    test_easy_nlp(llvm)\n    test_nlfunc_ifelse(llvm)\n"
  },
  {
    "path": "tests/test_nlp_bilinear.py",
    "content": "import pyoptinterface as poi\n\nimport pytest\n\n\ndef test_bilinear(nlp_model_ctor):\n    model = nlp_model_ctor()\n\n    x = model.add_m_variables(3, lb=0.0)\n\n    obj = -(x[0] + x[1]) * (x[0] + x[2])\n\n    expr = (x[0] + x[1]) * (x[0] + x[1]) + (x[0] + x[2]) * (x[0] + x[2])\n    model.add_quadratic_constraint(expr == 4.0)\n\n    model.set_objective(obj)\n    model.optimize()\n\n    objective_value = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n    assert objective_value == pytest.approx(-2.0, abs=1e-8)\n"
  },
  {
    "path": "tests/test_nlp_clnlbeam.py",
    "content": "import pyoptinterface as poi\nfrom pyoptinterface import nl\n\nimport pytest\n\nimport numpy as np\n\n\ndef test_clnlbeam(nlp_model_ctor):\n    model = nlp_model_ctor()\n\n    N = 100\n    h = 1 / N\n    alpha = 350\n\n    t = model.add_m_variables(N + 1, lb=-1.0, ub=1.0)\n    x = model.add_m_variables(N + 1, lb=-0.05, ub=0.05)\n    u = model.add_m_variables(N + 1)\n\n    for i in range(N):\n        with nl.graph():\n            model.add_nl_objective(\n                0.5 * h * (u[i] * u[i] + u[i + 1] * u[i + 1])\n                + 0.5 * alpha * h * (nl.cos(t[i]) + nl.cos(t[i + 1]))\n            )\n            model.add_nl_constraint(\n                x[i + 1] - x[i] - 0.5 * h * (nl.sin(t[i]) + nl.sin(t[i + 1])) == 0.0\n            )\n            model.add_linear_constraint(\n                t[i + 1] - t[i] - 0.5 * h * u[i + 1] - 0.5 * h * u[i] == 0.0\n            )\n\n    model.optimize()\n\n    tv = np.zeros(N + 1)\n    xv = np.zeros(N + 1)\n    uv = np.zeros(N + 1)\n    for i in range(N + 1):\n        tv[i] = model.get_value(t[i])\n        xv[i] = model.get_value(x[i])\n        uv[i] = model.get_value(u[i])\n\n    con_expr_val = np.zeros(N)\n    for i in range(N):\n        con_expr_val[i] = (\n            xv[i + 1] - xv[i] - 0.5 * h * (np.sin(tv[i]) + np.sin(tv[i + 1]))\n        )\n\n    assert np.allclose(con_expr_val, 0.0, atol=1e-8)\n\n    lin_con_expr_val = np.zeros(N)\n    for i in range(N):\n        lin_con_expr_val[i] = tv[i + 1] - tv[i] - 0.5 * h * uv[i + 1] - 0.5 * h * uv[i]\n\n    assert np.allclose(lin_con_expr_val, 0.0, atol=1e-8)\n\n    obj_expr_val = 0.0\n    for i in range(N):\n        obj_expr_val += 0.5 * h * (uv[i] * uv[i] + uv[i + 1] * uv[i + 1])\n        obj_expr_val += 0.5 * alpha * h * (np.cos(tv[i]) + np.cos(tv[i + 1]))\n\n    objective_value = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n\n    assert np.isclose(obj_expr_val, objective_value, atol=1e-8)\n    assert objective_value == pytest.approx(\n        328.0967, abs=1e-4\n    ) or objective_value == pytest.approx(350.0, abs=1e-8)\n"
  },
  {
    "path": "tests/test_nlp_expression.py",
    "content": "import pyoptinterface as poi\nfrom pyoptinterface import nl\nimport math\nimport pytest\nfrom pytest import approx\n\n\ndef test_nlp_expressiontree(model_interface):\n    model = model_interface\n\n    if not hasattr(model, \"add_nl_constraint\"):\n        pytest.skip(\"Model interface does not support nonlinear constraint\")\n\n    x = model.add_variable(lb=0.0, ub=2.0)\n    y = model.add_variable(lb=0.0, ub=2.0)\n\n    with nl.graph():\n        z = nl.exp(x) + nl.exp(2 * y)\n        model.add_nl_constraint(z <= 2 * math.exp(1.0))\n\n        z = x * x * x\n        model.add_nl_constraint(z >= 0.8**3)\n\n    model.set_objective(x + 2 * y, poi.ObjectiveSense.Maximize)\n    model.optimize()\n\n    x_value = model.get_value(x)\n    y_value = model.get_value(y)\n\n    # Note: with a feasibility tolerance defaulted to 1e-6 + the\n    # effect of the internal solver scaling, x and y can assume\n    # values relatively far away from the expected ones.\n    # E.g.: x = 1.0005, y = 0.49975\n    assert x_value == approx(1.0, rel=1e-2)\n    assert y_value == approx(0.5, rel=1e-2)\n\n\ndef test_nlp_expressiontree_obj(model_interface):\n    model = model_interface\n\n    if not hasattr(model, \"add_nl_constraint\"):\n        pytest.skip(\"Model interface does not support nonlinear constraint\")\n    if not hasattr(model, \"add_nl_objective\"):\n        pytest.skip(\"Model interface does not support nonlinear objective\")\n\n    x = model.add_variable(lb=-2.0, ub=2.0)\n    y = model.add_variable(lb=-2.0, ub=2.0)\n\n    with nl.graph():\n        z = x**2 + y**2\n        model.add_nl_constraint(z, (-1.0, 1.0))\n\n    with nl.graph():\n        z = nl.exp(x**2) + nl.exp(y**2)\n        model.add_nl_objective(z)\n\n    model.optimize()\n\n    x_value = model.get_value(x)\n    y_value = model.get_value(y)\n\n    assert x_value == approx(0.0, abs=1e-4)\n    assert y_value == approx(0.0, abs=1e-4)\n"
  },
  {
    "path": "tests/test_nlp_hs071.py",
    "content": "import pyoptinterface as poi\nfrom pyoptinterface import nl\nimport pytest\n\n\ndef test_hs071(nlp_model_ctor):\n    model = nlp_model_ctor()\n\n    x = model.add_m_variables(4, lb=1.0, ub=5.0, name=\"x\")\n\n    model.set_variable_attribute(x[0], poi.VariableAttribute.PrimalStart, 1.0)\n    model.set_variable_attribute(x[1], poi.VariableAttribute.PrimalStart, 5.0)\n    model.set_variable_attribute(x[2], poi.VariableAttribute.PrimalStart, 5.0)\n    model.set_variable_attribute(x[3], poi.VariableAttribute.PrimalStart, 1.0)\n\n    with nl.graph():\n        model.add_nl_objective(x[0] * x[3] * (x[0] + x[1] + x[2]) + x[2])\n\n    with nl.graph():\n        model.add_nl_constraint(x[0] * x[1] * x[2] * x[3] >= 25.0)\n        model.add_quadratic_constraint(\n            x[0] ** 2 + x[1] ** 2 + x[2] ** 2 + x[3] ** 2 == 40.0\n        )\n\n    model.optimize()\n\n    x1_val = model.get_value(x[0])\n    x2_val = model.get_value(x[1])\n    x3_val = model.get_value(x[2])\n    x4_val = model.get_value(x[3])\n\n    sum_sq = x1_val**2 + x2_val**2 + x3_val**2 + x4_val**2\n    product = x1_val * x2_val * x3_val * x4_val\n    assert sum_sq == pytest.approx(40.0, rel=1e-6)\n    assert 25.0 - 1e-6 <= product <= 100.0 + 1e-6\n\n    objective_value = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n    assert objective_value == pytest.approx(17.014, rel=1e-3)\n"
  },
  {
    "path": "tests/test_nlp_multiple_run.py",
    "content": "from pyoptinterface import copt, ipopt, knitro, nl\nimport pytest\nimport math\n\n\ndef test_nlp_reopt(nlp_model_ctor):\n    model = nlp_model_ctor()\n\n    x = model.add_variable(lb=0.1)\n    y = model.add_variable(lb=0.1)\n\n    with nl.graph():\n        model.add_nl_objective(x**2 + y**2)\n\n    with nl.graph():\n        model.add_nl_constraint(x**2 <= 1.0)\n        model.add_nl_constraint(y**2 <= 1.0)\n\n    model.optimize()\n\n    assert model.get_value(x) == pytest.approx(0.1, rel=1e-5)\n    assert model.get_value(y) == pytest.approx(0.1, rel=1e-5)\n\n    z = model.add_variable(lb=0.2)\n    with nl.graph():\n        model.add_nl_objective(z**4)\n\n    model.optimize()\n\n    assert model.get_value(z) == pytest.approx(0.2)\n\n    with nl.graph():\n        model.add_nl_constraint(nl.log(z) >= math.log(4.0))\n\n    model.optimize()\n\n    print(model.get_value(z))\n\n    assert model.get_value(z) == pytest.approx(4.0, rel=1e-5)\n\n\nif __name__ == \"__main__\":\n\n    def c():\n        return ipopt.Model(jit=\"C\")\n\n    test_nlp_reopt(c)\n\n    def llvm():\n        return ipopt.Model(jit=\"LLVM\")\n\n    test_nlp_reopt(llvm)\n\n    test_nlp_reopt(copt.Model)\n    test_nlp_reopt(knitro.Model)\n"
  },
  {
    "path": "tests/test_nlp_opf.py",
    "content": "import math\nimport pyoptinterface as poi\nfrom pyoptinterface import nl\n\nimport pytest\n\n\ndef test_acopf(nlp_model_ctor):\n    model = nlp_model_ctor()\n\n    branches = [\n        # (from, to, R, X, B, angmin, angmax, Smax)\n        (0, 1, 0.00281, 0.0281, 0.00712, -30.0, 30.0, 4.00),\n        (0, 3, 0.00304, 0.0304, 0.00658, -30.0, 30.0, 4.26),\n        (0, 4, 0.00064, 0.0064, 0.03126, -30.0, 30.0, 4.26),\n        (1, 2, 0.00108, 0.0108, 0.01852, -30.0, 30.0, 4.26),\n        (2, 3, 0.00297, 0.0297, 0.00674, -30.0, 30.0, 4.26),\n        (3, 4, 0.00297, 0.0297, 0.00674, -30.0, 30.0, 2.40),\n    ]\n\n    buses = [\n        # (Pd, Qd, Gs, Bs, Vmin, Vmax)\n        (0.0, 0.0000, 0.0, 0.0, 0.9, 1.1),\n        (3.0, 0.9861, 0.0, 0.0, 0.9, 1.1),\n        (3.0, 0.9861, 0.0, 0.0, 0.9, 1.1),\n        (4.0, 1.3147, 0.0, 0.0, 0.9, 1.1),\n        (0.0, 0.0000, 0.0, 0.0, 0.9, 1.1),\n    ]\n\n    generators = [\n        # (bus, Pmin, Pmax, Qmin, Qmax, a, b, c)\n        (0, 0.0, 0.4, -0.300, 0.300, 0.0, 1400, 0.0),\n        (0, 0.0, 1.7, -1.275, 1.275, 0.0, 1500, 0.0),\n        (2, 0.0, 5.2, -3.900, 3.900, 0.0, 3000, 0.0),\n        (3, 0.0, 2.0, -1.500, 1.500, 0.0, 4000, 0.0),\n        (4, 0.0, 6.0, -4.500, 4.500, 0.0, 1000, 0.0),\n    ]\n\n    slack_bus = 3\n\n    N_branch = len(branches)\n    N_bus = len(buses)\n    N_gen = len(generators)\n\n    Pbr_from = model.add_m_variables(N_branch)\n    Qbr_from = model.add_m_variables(N_branch)\n    Pbr_to = model.add_m_variables(N_branch)\n    Qbr_to = model.add_m_variables(N_branch)\n\n    V = model.add_m_variables(N_bus, name=\"V\")\n    theta = model.add_m_variables(N_bus, name=\"theta\")\n\n    for i in range(N_bus):\n        Vmin, Vmax = buses[i][4], buses[i][5]\n        model.set_variable_bounds(V[i], Vmin, Vmax)\n\n    model.set_variable_bounds(theta[slack_bus], 0.0, 0.0)\n\n    P = model.add_variables(range(N_gen), name=\"P\")\n    Q = model.add_variables(range(N_gen), name=\"Q\")\n\n    for i in range(N_gen):\n        model.set_variable_bounds(P[i], generators[i][1], generators[i][2])\n        model.set_variable_bounds(Q[i], generators[i][3], generators[i][4])\n\n    # nonlinear constraints\n    for k in range(N_branch):\n        with nl.graph():\n            branch = branches[k]\n            R, X, Bc2 = branch[2], branch[3], branch[4]\n\n            G = R / (R**2 + X**2)\n            B = -X / (R**2 + X**2)\n            Bc = Bc2 / 2\n\n            i = branch[0]\n            j = branch[1]\n\n            Vi = V[i]\n            Vj = V[j]\n            theta_i = theta[i]\n            theta_j = theta[j]\n\n            Pij = Pbr_from[k]\n            Qij = Qbr_from[k]\n            Pji = Pbr_to[k]\n            Qji = Qbr_to[k]\n\n            sin_ij = nl.sin(theta_i - theta_j)\n            cos_ij = nl.cos(theta_i - theta_j)\n\n            Pij_eq = G * Vi**2 - Vi * Vj * (G * cos_ij + B * sin_ij) - Pij\n            Qij_eq = -(B + Bc) * Vi**2 - Vi * Vj * (G * sin_ij - B * cos_ij) - Qij\n            Pji_eq = G * Vj**2 - Vi * Vj * (G * cos_ij - B * sin_ij) - Pji\n            Qji_eq = -(B + Bc) * Vj**2 - Vi * Vj * (-G * sin_ij - B * cos_ij) - Qji\n\n            model.add_nl_constraint(\n                Pij_eq == 0.0,\n            )\n            model.add_nl_constraint(\n                Qij_eq == 0.0,\n            )\n            model.add_nl_constraint(\n                Pji_eq == 0.0,\n            )\n            model.add_nl_constraint(\n                Qji_eq == 0.0,\n            )\n\n    # power balance constraints\n    P_balance_eq = [poi.ExprBuilder() for i in range(N_bus)]\n    Q_balance_eq = [poi.ExprBuilder() for i in range(N_bus)]\n\n    for b in range(N_bus):\n        Pd, Qd = buses[b][0], buses[b][1]\n        Gs, Bs = buses[b][2], buses[b][3]\n        Vb = V[b]\n\n        P_balance_eq[b] -= poi.quicksum(\n            Pbr_from[k] for k in range(N_branch) if branches[k][0] == b\n        )\n        P_balance_eq[b] -= poi.quicksum(\n            Pbr_to[k] for k in range(N_branch) if branches[k][1] == b\n        )\n        P_balance_eq[b] += poi.quicksum(\n            P[i] for i in range(N_gen) if generators[i][0] == b\n        )\n        P_balance_eq[b] -= Pd\n        P_balance_eq[b] -= Gs * Vb * Vb\n\n        Q_balance_eq[b] -= poi.quicksum(\n            Qbr_from[k] for k in range(N_branch) if branches[k][0] == b\n        )\n        Q_balance_eq[b] -= poi.quicksum(\n            Qbr_to[k] for k in range(N_branch) if branches[k][1] == b\n        )\n        Q_balance_eq[b] += poi.quicksum(\n            Q[i] for i in range(N_gen) if generators[i][0] == b\n        )\n        Q_balance_eq[b] -= Qd\n        Q_balance_eq[b] += Bs * Vb * Vb\n\n        model.add_quadratic_constraint(P_balance_eq[b], poi.Eq, 0.0)\n        model.add_quadratic_constraint(Q_balance_eq[b], poi.Eq, 0.0)\n\n    for k in range(N_branch):\n        branch = branches[k]\n\n        i = branch[0]\n        j = branch[1]\n\n        theta_i = theta[i]\n        theta_j = theta[j]\n\n        angmin = branch[5] / 180 * math.pi\n        angmax = branch[6] / 180 * math.pi\n\n        model.add_linear_constraint(theta_i - theta_j, (angmin, angmax))\n\n        Smax = branch[7]\n        Pij = Pbr_from[k]\n        Qij = Qbr_from[k]\n        Pji = Pbr_to[k]\n        Qji = Qbr_to[k]\n        model.add_quadratic_constraint(Pij * Pij + Qij * Qij, poi.Leq, Smax * Smax)\n        model.add_quadratic_constraint(Pji * Pji + Qji * Qji, poi.Leq, Smax * Smax)\n\n    cost = poi.ExprBuilder()\n    for i in range(N_gen):\n        a, b, c = generators[i][5], generators[i][6], generators[i][7]\n        cost += a * P[i] * P[i] + b * P[i] + c\n    model.set_objective(cost)\n\n    model.optimize()\n\n    terminattion_status = model.get_model_attribute(\n        poi.ModelAttribute.TerminationStatus\n    )\n    assert (terminattion_status == poi.TerminationStatusCode.LOCALLY_SOLVED) or (\n        terminattion_status == poi.TerminationStatusCode.OPTIMAL\n    )\n\n    P_value = P.map(model.get_value)\n    P_value_sum = sum(P_value.values())\n\n    total_load_p = sum(b[0] for b in buses)\n\n    assert P_value_sum > total_load_p\n\n    objective_value = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n    assert objective_value == pytest.approx(1.7552e4, rel=1e-3)\n\n\nif __name__ == \"__main__\":\n    from pyoptinterface import ipopt, copt, knitro\n\n    test_acopf(ipopt.Model)\n    test_acopf(copt.Model)\n    test_acopf(knitro.Model)\n"
  },
  {
    "path": "tests/test_nlp_rocket.py",
    "content": "from pyoptinterface import nl\n\nimport math\nimport pytest\n\n\ndef rocket_model(model, nh: int):\n    h_0 = 1.0\n    v_0 = 0.0\n    m_0 = 1.0\n    g_0 = 1.0\n    T_c = 3.5\n    h_c = 500.0\n    v_c = 620.0\n    m_c = 0.6\n\n    c = 0.5 * math.sqrt(g_0 * h_0)\n    m_f = m_c * m_0\n    D_c = 0.5 * v_c * (m_0 / g_0)\n    T_max = T_c * m_0 * g_0\n\n    h = model.add_m_variables(nh, lb=1.0)\n    v = model.add_m_variables(nh, lb=0.0)\n    m = model.add_m_variables(nh, lb=m_f, ub=m_0)\n    T = model.add_m_variables(nh, lb=0.0, ub=T_max)\n    step = model.add_variable(lb=0.0)\n\n    model.set_objective(-1.0 * h[-1])\n\n    for i in range(nh - 1):\n        with nl.graph():\n            h1 = h[i]\n            h2 = h[i + 1]\n            v1 = v[i]\n            v2 = v[i + 1]\n            m1 = m[i]\n            m2 = m[i + 1]\n            T1 = T[i]\n            T2 = T[i + 1]\n\n            model.add_nl_constraint(h2 - h1 - 0.5 * step * (v1 + v2) == 0)\n\n            D1 = D_c * v1 * v1 * nl.exp(-h_c * (h1 - h_0)) / h_0\n            D2 = D_c * v2 * v2 * nl.exp(-h_c * (h2 - h_0)) / h_0\n            g1 = g_0 * h_0 * h_0 / (h1 * h1)\n            g2 = g_0 * h_0 * h_0 / (h2 * h2)\n            dv1 = (T1 - D1) / m1 - g1\n            dv2 = (T2 - D2) / m2 - g2\n\n            model.add_nl_constraint(v2 - v1 - 0.5 * step * (dv1 + dv2) == 0)\n            model.add_nl_constraint(m2 - m1 + 0.5 * step * (T1 + T2) / c == 0)\n\n    # Boundary conditions\n    model.set_variable_bounds(h[0], h_0, h_0)\n    model.set_variable_bounds(v[0], v_0, v_0)\n    model.set_variable_bounds(m[0], m_0, m_0)\n    model.set_variable_bounds(m[-1], m_f, m_f)\n\n    model.h = h\n\n\ndef test_rocket(nlp_model_ctor):\n    nh = 400\n    model = nlp_model_ctor()\n    rocket_model(model, nh)\n    model.optimize()\n\n    obj = model.get_value(model.h[-1])\n\n    assert obj == pytest.approx(1.01283, rel=1e-4)\n\n\nif __name__ == \"__main__\":\n    from pyoptinterface import copt, ipopt, knitro\n\n    def c():\n        return ipopt.Model(jit=\"C\")\n\n    test_rocket(c)\n\n    def llvm():\n        return ipopt.Model(jit=\"LLVM\")\n\n    test_rocket(llvm)\n\n    test_rocket(copt.Model)\n\n    test_rocket(knitro.Model)\n"
  },
  {
    "path": "tests/test_operator.py",
    "content": "from operator import add, sub, mul, truediv\n\nfrom pyoptinterface import (\n    VariableIndex,\n    ExprBuilder,\n    ScalarAffineFunction,\n    ScalarQuadraticFunction,\n    quicksum,\n    quicksum_,\n)\nfrom pytest import approx\n\n\ndef evaluate(expr, var_value_map=None):\n    if isinstance(expr, VariableIndex):\n        return var_value_map[expr.index]\n    elif isinstance(expr, ScalarAffineFunction):\n        s = 0.0\n        if expr.constant is not None:\n            s = expr.constant\n        for index, coef in zip(expr.variables, expr.coefficients):\n            val = var_value_map[index]\n            s += coef * val\n        return s\n    elif isinstance(expr, ScalarQuadraticFunction):\n        s = 0.0\n        if expr.affine_part is not None:\n            s = evaluate(expr.affine_part, var_value_map)\n        for index1, index2, coef in zip(\n            expr.variable_1s, expr.variable_2s, expr.coefficients\n        ):\n            val1 = var_value_map[index1]\n            val2 = var_value_map[index2]\n            s += coef * val1 * val2\n        return s\n    elif isinstance(expr, ExprBuilder):\n        degree = expr.degree()\n        if degree < 2:\n            return evaluate(ScalarAffineFunction(expr), var_value_map)\n        elif degree == 2:\n            return evaluate(ScalarQuadraticFunction(expr), var_value_map)\n        else:\n            raise ValueError(\"Unsupported degree\")\n    elif isinstance(expr, (int, float)):\n        return expr\n    else:\n        raise ValueError(\"Unsupported type\")\n\n\ndef degree(expr):\n    if isinstance(expr, VariableIndex):\n        return 1\n    elif isinstance(expr, ScalarAffineFunction):\n        return 1\n    elif isinstance(expr, ScalarQuadraticFunction):\n        return 2\n    elif isinstance(expr, ExprBuilder):\n        return expr.degree()\n    elif isinstance(expr, (int, float)):\n        return 0\n    else:\n        raise ValueError(\"Unsupported type\")\n\n\ndef test_evaluate():\n    assert evaluate(1.0) == approx(1.0)\n    assert evaluate(2) == 2\n\n    N = 6\n    vars = [VariableIndex(i) for i in range(N)]\n    var_value_map = {v.index: float(v.index) for v in vars}\n\n    for i in range(N):\n        assert evaluate(vars[i], var_value_map) == approx(i)\n\n    expr = vars[0] + 1 * vars[1] + 2 * vars[2]\n    assert evaluate(expr, var_value_map) == approx(5.0)\n\n    expr = ExprBuilder(expr)\n    assert evaluate(expr, var_value_map) == approx(5.0)\n\n    expr = vars[0] + 2 * vars[1] + 5 * vars[3] * vars[2] + 6 * vars[4] * vars[4]\n    answer = 2 + 5 * 3 * 2 + 6 * 4 * 4\n    assert evaluate(expr, var_value_map) == approx(answer)\n\n    expr = ExprBuilder(expr)\n    assert evaluate(expr, var_value_map) == approx(answer)\n\n\ndef test_operator():\n    N = 6\n    vars = [VariableIndex(i) for i in range(N)]\n\n    exprs = [\n        1,\n        2.0,\n        vars[4],\n        3 * vars[2],\n        2 * vars[1] + vars[3],\n        2 * vars[2] + vars[3] + 5.0,\n        13 * vars[4] * vars[4],\n        17 * vars[3] * vars[3] + 1.0,\n        17 * vars[3] * vars[5] + 3 * vars[1],\n        11 * vars[5] * vars[5] + 7 * vars[1] + 3.0,\n    ]\n    exprs += [ExprBuilder(e) for e in exprs]\n\n    # For two quadratic polynomials, if their values equal on more than 3 points, then thir coefficients are the same.\n    for i in (1, 2, 3, 4):\n        var_value_map = {v.index: i * float(v.index) for v in vars}\n\n        expr_values = [evaluate(e, var_value_map) for e in exprs]\n\n        for op in [add, sub]:\n            for i, ei in enumerate(exprs):\n                for j, ej in enumerate(exprs):\n                    expr = op(ei, ej)\n                    value = evaluate(expr, var_value_map)\n                    assert value == approx(op(expr_values[i], expr_values[j]))\n\n        op = mul\n        for i, ei in enumerate(exprs):\n            for j, ej in enumerate(exprs):\n                total_degree = degree(ei) + degree(ej)\n                if total_degree > 2:\n                    continue\n                expr = op(ei, ej)\n                value = evaluate(expr, var_value_map)\n                # flag = value == approx(op(expr_values[i], expr_values[j]))\n                # if not flag:\n                #     k = 1\n                assert value == approx(op(expr_values[i], expr_values[j]))\n\n        op = truediv\n        for i, ei in enumerate(exprs):\n            for j, ej in enumerate(exprs):\n                if not isinstance(ej, (int, float)):\n                    continue\n                expr = op(ei, ej)\n                value = evaluate(expr, var_value_map)\n                assert value == approx(op(expr_values[i], expr_values[j]))\n\n\ndef test_quicksum():\n    N = 6\n    vars = [VariableIndex(i) for i in range(N)]\n    var_value_map = {v.index: float(v.index) for v in vars}\n    vars_dict = {i: v for i, v in enumerate(vars)}\n\n    expr = ExprBuilder()\n    for v in vars:\n        expr += v\n    expr_sum = quicksum(vars_dict)\n    assert evaluate(expr_sum, var_value_map) == approx(evaluate(expr, var_value_map))\n\n    f = lambda x: x * x\n    expr = ExprBuilder()\n    for v in vars:\n        expr += f(v)\n    expr_sum = quicksum(vars, f)\n    assert evaluate(expr_sum, var_value_map) == approx(evaluate(expr, var_value_map))\n\n    c = 3.0\n    expr = ExprBuilder(c)\n    for v in vars:\n        expr += v\n    expr_sum = ExprBuilder(c)\n    quicksum_(expr_sum, vars)\n    assert evaluate(expr_sum, var_value_map) == approx(evaluate(expr, var_value_map))\n\n    f = lambda x: x * x\n    expr = ExprBuilder(c)\n    for v in vars:\n        expr += f(v)\n    expr_sum = ExprBuilder(c)\n    quicksum_(expr_sum, vars_dict, f)\n    assert evaluate(expr_sum, var_value_map) == approx(evaluate(expr, var_value_map))\n"
  },
  {
    "path": "tests/test_preopt.py",
    "content": "import pyoptinterface as poi\n\n\ndef test_model_attribute_termination_before_solve(model_interface_oneshot):\n    \"\"\"Test termination status before solving.\"\"\"\n    model = model_interface_oneshot\n    x = model.add_variable(lb=0.0, ub=10.0)\n    model.set_objective(x, poi.ObjectiveSense.Minimize)\n\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMIZE_NOT_CALLED\n"
  },
  {
    "path": "tests/test_qp.py",
    "content": "import pyoptinterface as poi\nfrom pytest import approx\n\nimport numpy as np\n\n\ndef test_simple_qp(model_interface_oneshot):\n    model = model_interface_oneshot\n\n    N = 6\n\n    x = model.add_variables(range(N), lb=0.0)\n\n    model.add_linear_constraint(poi.quicksum(x), poi.Geq, N)\n\n    s = poi.quicksum(x)\n    s *= s\n    model.set_objective(s, poi.ObjectiveSense.Minimize)\n\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert (\n        status == poi.TerminationStatusCode.OPTIMAL\n        or status == poi.TerminationStatusCode.LOCALLY_SOLVED\n    )\n\n    obj_val = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n    assert obj_val == approx(N**2, rel=1e-5)\n\n\n# reported by https://github.com/metab0t/PyOptInterface/issues/59\ndef test_shuffle_qp_objective(model_interface_oneshot):\n    model = model_interface_oneshot\n\n    N = 3\n    weights = model.add_m_variables(N, lb=0)\n\n    expected_returns = [0.05, 0.07, 0.12]\n    min_return = 0.06\n    cov = [\n        (0, 0, 0.1),\n        (0, 1, 0.1),\n        (0, 2, 0.04),\n        (1, 1, 0.4),\n        (1, 2, 0.2),\n        (2, 2, 0.9),\n    ]\n    cov_objs = [weights[i] * weights[j] * v for i, j, v in cov]\n\n    model.add_linear_constraint(poi.quicksum(weights) == 1)\n    model.add_linear_constraint(\n        poi.quicksum(expected_returns[i] * weights[i] for i in range(N)) >= min_return\n    )\n\n    trial = 120\n    obj_values = []\n    for _ in range(trial):\n        import random\n\n        random.shuffle(cov_objs)\n        obj = poi.quicksum(cov_objs)\n        model.set_objective(obj, poi.ObjectiveSense.Minimize)\n\n        model.optimize()\n\n        obj_value = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n        obj_values.append(obj_value)\n\n    obj_values = np.array(obj_values)\n    # test all values are the same\n    assert np.all(np.abs(obj_values - obj_values[0]) < 1e-8)\n\n\ndef test_duplicated_quadratic_terms(model_interface_oneshot):\n    model = model_interface_oneshot\n\n    x = model.add_m_variables(2, lb=1.0)\n\n    obj = (\n        x[0] * x[0]\n        + x[0] * x[0]\n        + x[1] * x[1]\n        + 2 * x[1] * x[1]\n        + 0.5 * x[0] * x[1]\n        + 0.1 * x[1] * x[0]\n    )\n\n    model.set_objective(obj)\n\n    model.optimize()\n    obj_value = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n    assert obj_value == approx(5.6)\n"
  },
  {
    "path": "tests/test_reducedcost.py",
    "content": "import pyoptinterface as poi\nimport pytest\nfrom pytest import approx\n\n\ndef test_simple_redcost(model_interface):\n    model = model_interface\n\n    if not model.supports_variable_attribute(poi.VariableAttribute.ReducedCost):\n        pytest.skip(\"Model interface does not support ReducedCost attribute\")\n\n    x = model.add_variable(lb=0.0, ub=2.0)\n    y = model.add_variable(lb=0.0, ub=2.5)\n    model.add_linear_constraint(x + 2 * y >= 6.0)\n\n    model.set_objective(x + y)\n\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n\n    x_redcost = model.get_variable_attribute(x, poi.VariableAttribute.ReducedCost)\n    y_redcost = model.get_variable_attribute(y, poi.VariableAttribute.ReducedCost)\n\n    assert x_redcost == approx(0.0, abs=1e-5)\n    assert y_redcost == approx(-1.0, abs=1e-5)\n"
  },
  {
    "path": "tests/test_simple_opt.py",
    "content": "import pyoptinterface as poi\nfrom pytest import approx\nimport pytest\n\n\ndef test_simple_opt(model_interface):\n    model = model_interface\n\n    x = model.add_variable(lb=0.0, ub=20.0)\n    y = model.add_variable()\n    model.set_variable_bounds(y, 8.0, 20.0)\n\n    model.set_variable_attribute(x, poi.VariableAttribute.Name, \"x\")\n    model.set_variable_attribute(y, poi.VariableAttribute.Name, \"y\")\n\n    obj = x * x + y * y\n    model.set_objective(obj, poi.ObjectiveSense.Minimize)\n\n    conexpr = x + y\n    con1 = model.add_linear_constraint(\n        conexpr - 10.0, poi.ConstraintSense.GreaterEqual, 0.0, name=\"con1\"\n    )\n\n    assert model.number_of_variables() == 2\n    assert model.number_of_constraints(poi.ConstraintType.Linear) == 1\n\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n    x_val = model.get_variable_attribute(x, poi.VariableAttribute.Value)\n    y_val = model.get_variable_attribute(y, poi.VariableAttribute.Value)\n    assert x_val == approx(2.0)\n    assert y_val == approx(8.0)\n    obj_val = model.get_value(obj)\n    assert obj_val == approx(68.0)\n    obj_val_attr = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n    assert obj_val_attr == approx(obj_val)\n    conexpr_val = model.get_value(conexpr)\n    assert conexpr_val == approx(10.0)\n\n    assert model.pprint(x) == \"x\"\n    assert model.pprint(y) == \"y\"\n    assert model.pprint(obj) == \"1*x*x+1*y*y\"\n    assert model.pprint(conexpr) == \"1*x+1*y\"\n\n    model.delete_constraint(con1)\n    assert model.number_of_constraints(poi.ConstraintType.Linear) == 0\n    con2 = model.add_linear_constraint(conexpr, poi.ConstraintSense.GreaterEqual, 20.0)\n    assert model.number_of_constraints(poi.ConstraintType.Linear) == 1\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n    x_val = model.get_variable_attribute(x, poi.VariableAttribute.Value)\n    y_val = model.get_variable_attribute(y, poi.VariableAttribute.Value)\n    assert x_val == approx(10.0, abs=1e-3)\n    assert y_val == approx(10.0, abs=1e-3)\n\n    model.delete_constraint(con2)\n    con3 = model.add_linear_constraint(conexpr, poi.ConstraintSense.GreaterEqual, 20.05)\n    model.set_variable_attribute(\n        x, poi.VariableAttribute.Domain, poi.VariableDomain.Integer\n    )\n    model.set_objective(x + 2 * y, poi.ObjectiveSense.Minimize)\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n    x_val = model.get_variable_attribute(x, poi.VariableAttribute.Value)\n    y_val = model.get_variable_attribute(y, poi.VariableAttribute.Value)\n    assert x_val == approx(12.0)\n    assert y_val == approx(8.05)\n\n    model.delete_constraint(con3)\n    con4 = model.add_linear_constraint(conexpr, poi.ConstraintSense.GreaterEqual, 10.0)\n    model.set_variable_attribute(\n        x, poi.VariableAttribute.Domain, poi.VariableDomain.Continuous\n    )\n    model.set_variable_attribute(y, poi.VariableAttribute.LowerBound, 0.0)\n    model.set_objective(obj, poi.ObjectiveSense.Minimize)\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n    x_val = model.get_variable_attribute(x, poi.VariableAttribute.Value)\n    y_val = model.get_variable_attribute(y, poi.VariableAttribute.Value)\n    assert x_val == approx(5.0)\n    assert y_val == approx(5.0)\n\n    model.set_normalized_rhs(con4, 16.0)\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n    x_val = model.get_variable_attribute(x, poi.VariableAttribute.Value)\n    y_val = model.get_variable_attribute(y, poi.VariableAttribute.Value)\n    assert x_val == approx(8.0)\n    assert y_val == approx(8.0)\n\n\ndef test_constant_objective(model_interface_oneshot):\n    model = model_interface_oneshot\n\n    x = model.add_variable(lb=0.0, ub=1.0)\n    obj = 1.0\n    model.set_objective(obj, poi.ObjectiveSense.Minimize)\n    model.optimize()\n    obj_val = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n    assert obj_val == approx(1.0)\n    model.set_objective(obj, poi.ObjectiveSense.Maximize)\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert (\n        status == poi.TerminationStatusCode.OPTIMAL\n        or status == poi.TerminationStatusCode.LOCALLY_SOLVED\n    )\n    obj_val = model.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n    assert obj_val == approx(1.0)\n\n\ndef test_constraint_primal_dual(model_interface_oneshot):\n    model = model_interface_oneshot\n\n    x = model.add_variable(lb=0.0, ub=1.0)\n    y = model.add_variable(lb=0.0, ub=1.0)\n\n    model.set_variable_attribute(x, poi.VariableAttribute.Name, \"x\")\n    model.set_variable_attribute(y, poi.VariableAttribute.Name, \"y\")\n\n    obj = x + y\n    model.set_objective(obj, poi.ObjectiveSense.Minimize)\n\n    conexpr = x + 2 * y\n    con1 = model.add_linear_constraint(conexpr, poi.Geq, 1.0, name=\"con1\")\n\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert (\n        status == poi.TerminationStatusCode.OPTIMAL\n        or status == poi.TerminationStatusCode.LOCALLY_SOLVED\n    )\n\n    primal_val = model.get_constraint_attribute(con1, poi.ConstraintAttribute.Primal)\n    assert primal_val == approx(1.0)\n\n    dual_val = model.get_constraint_attribute(con1, poi.ConstraintAttribute.Dual)\n    assert dual_val == approx(0.5)\n\n\ndef test_add_quadratic_expr_as_linear_throws_error(model_interface_oneshot):\n    model = model_interface_oneshot\n\n    xs = model.add_m_variables(10)\n    x2_sum = poi.quicksum(x * x for x in xs.flat)\n\n    with pytest.raises(RuntimeError, match=\"add_linear_constraint\"):\n        model.add_linear_constraint(x2_sum <= 1.0)\n\n\ndef test_exprbuilder_self_operation(model_interface_oneshot):\n    model = model_interface_oneshot\n\n    x = model.add_m_variables(2, lb=1.0, ub=4.0)\n\n    expr = poi.ExprBuilder(x[0] + 2.0 * x[1] + 3.0)\n    expr += expr\n    model.set_objective(expr)\n    model.optimize()\n    obj_value = model.get_value(expr)\n    assert obj_value == approx(12.0)\n\n    expr = poi.ExprBuilder(x[0] + 2.0 * x[1] + 3.0)\n    expr -= expr\n    model.set_objective(expr)\n    model.optimize()\n    obj_value = model.get_value(expr)\n    assert obj_value == approx(0.0)\n\n    expr = poi.ExprBuilder(x[0] + 2.0 * x[1] + 3.0)\n    expr *= expr\n    model.set_objective(expr)\n    model.optimize()\n    obj_value = model.get_value(expr)\n    assert obj_value == approx(36.0)\n"
  },
  {
    "path": "tests/test_soc.py",
    "content": "import pyoptinterface as poi\nfrom pytest import approx\nimport pytest\n\n\ndef test_soc(model_interface):\n    model = model_interface\n\n    if not hasattr(model, \"add_second_order_cone_constraint\"):\n        pytest.skip(\"Model interface does not support second order cone constraints\")\n\n    x = model.add_variable(lb=0.0, name=\"x\")\n    y = model.add_variable(lb=3.0, name=\"y\")\n    z = model.add_variable(lb=4.0, name=\"z\")\n\n    obj = x + y + z\n    model.set_objective(obj, poi.ObjectiveSense.Minimize)\n\n    con1 = model.add_second_order_cone_constraint([x, y, z])\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n    x_val = model.get_value(x)\n    y_val = model.get_value(y)\n    z_val = model.get_value(z)\n    assert x_val == approx(5.0, rel=1e-5)\n    assert y_val == approx(3.0, rel=1e-5)\n    assert z_val == approx(4.0, rel=1e-5)\n    obj_val = model.get_value(obj)\n    assert obj_val == approx(12.0, rel=1e-5)\n\n    model.delete_constraint(con1)\n    xx = model.add_variable(lb=0.0, name=\"xx\")\n    model.add_linear_constraint(xx - 2 * x, poi.ConstraintSense.Equal, 0.0)\n\n    model.add_second_order_cone_constraint([xx, y, z])\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n    x_val = model.get_value(x)\n    y_val = model.get_value(y)\n    z_val = model.get_value(z)\n    assert x_val == approx(2.5, rel=1e-5)\n    assert y_val == approx(3.0, rel=1e-5)\n    assert z_val == approx(4.0, rel=1e-5)\n    obj_val = model.get_value(obj)\n    assert obj_val == approx(9.5, rel=1e-5)\n\n\ndef test_rotated_soc(model_interface):\n    model = model_interface\n\n    if not hasattr(model, \"add_second_order_cone_constraint\"):\n        pytest.skip(\"Model interface does not support second order cone constraints\")\n\n    x = model.add_variable(lb=0.0, name=\"x\")\n    y = model.add_variable(lb=0.0, name=\"y\")\n    z = model.add_variable(lb=4.0, ub=4.0, name=\"z\")\n\n    obj = x + 2 * y\n    model.set_objective(obj, poi.ObjectiveSense.Minimize)\n\n    con1 = model.add_second_order_cone_constraint([x, y, z], rotated=True)\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n    x_val = model.get_value(x)\n    y_val = model.get_value(y)\n    assert x_val == approx(4.0, rel=1e-3)\n    assert y_val == approx(2.0, rel=1e-3)\n    obj_val = model.get_value(obj)\n    assert obj_val == approx(8.0, rel=1e-3)\n\n    model.delete_constraint(con1)\n    xx = model.add_variable(lb=0.0, name=\"xx\")\n    model.add_linear_constraint(xx - 4 * x, poi.ConstraintSense.Equal, 0.0)\n\n    model.add_second_order_cone_constraint([xx, y, z], rotated=True)\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n    x_val = model.get_value(x)\n    y_val = model.get_value(y)\n    assert x_val == approx(2.0, rel=1e-3)\n    assert y_val == approx(1.0, rel=1e-3)\n    obj_val = model.get_value(obj)\n    assert obj_val == approx(4.0, rel=1e-3)\n"
  },
  {
    "path": "tests/test_sos.py",
    "content": "import pyoptinterface as poi\nfrom pytest import approx\nimport pytest\n\n\n# write a test to test if SOS1 and SOS2 constraint are functional\ndef test_sos(model_interface):\n    model = model_interface\n\n    if not hasattr(model, \"add_sos_constraint\"):\n        pytest.skip(\"Model interface does not support SOS constraints\")\n\n    N = 10\n    vars = [model.add_variable(lb=0.0, ub=1.0) for _ in range(N)]\n\n    obj = poi.quicksum(vars)\n    model.set_objective(obj, poi.ObjectiveSense.Maximize)\n\n    con1 = model.add_sos_constraint(vars, poi.SOSType.SOS1)\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n    obj_val = model.get_value(obj)\n    assert obj_val == approx(1.0)\n\n    nz_indices = [i for i in range(N) if model.get_value(vars[i]) > 1e-3]\n    assert len(nz_indices) == 1\n\n    model.delete_constraint(con1)\n    con2 = model.add_sos_constraint(vars, poi.SOSType.SOS2)\n    model.optimize()\n    status = model.get_model_attribute(poi.ModelAttribute.TerminationStatus)\n    assert status == poi.TerminationStatusCode.OPTIMAL\n    obj_val = model.get_value(obj)\n    assert obj_val == approx(2.0)\n\n    nz_indices = [i for i in range(N) if model.get_value(vars[i]) > 1e-3]\n    assert len(nz_indices) == 2\n    v1, v2 = nz_indices\n    assert v1 + 1 == v2\n"
  },
  {
    "path": "tests/test_tupledict.py",
    "content": "from pyoptinterface._src.tupledict import (\n    flatten_tuple,\n    make_tupledict,\n    tupledict,\n    WILDCARD,\n)\n\n\ndef test_flatten_tuple():\n    assert list(flatten_tuple((1, (2, 3), (4, 5)))) == [1, 2, 3, 4, 5]\n    assert list(flatten_tuple((1, 2, 3))) == [1, 2, 3]\n    assert list(flatten_tuple(((1, 2), 3))) == [1, 2, 3]\n\n\ndef test_make_tupledict():\n    assert make_tupledict([1, 2], [3, 4], rule=lambda x, y: x * y) == {\n        (1, 3): 3,\n        (1, 4): 4,\n        (2, 3): 6,\n        (2, 4): 8,\n    }\n    assert make_tupledict([1, 2], [3, 4], rule=lambda x, y: None) == {}\n    assert make_tupledict([1, 2], rule=lambda x: x) == {1: 1, 2: 2}\n    assert make_tupledict([1, 2], [(3, 3), (4, 4)], rule=lambda x, y, z: x) == {\n        (1, 3, 3): 1,\n        (1, 4, 4): 1,\n        (2, 3, 3): 2,\n        (2, 4, 4): 2,\n    }\n\n\ndef test_tupledict_select():\n    # Create a tupledict instance\n    td = tupledict(\n        {\n            (1, 2): \"a\",\n            (1, 3): \"b\",\n            (2, 2): \"c\",\n            (2, 3): \"d\",\n        }\n    )\n\n    # Test select with specific keys\n    assert list(td.select(1, 2)) == [\"a\"]\n    assert list(td.select(2, WILDCARD)) == [\"c\", \"d\"]\n\n    # Test select with wildcard\n    assert list(td.select(WILDCARD, 2)) == [\"a\", \"c\"]\n\n    # Test select with all wildcards\n    assert list(td.select(WILDCARD, WILDCARD)) == [\"a\", \"b\", \"c\", \"d\"]\n\n    # Test select with non-existing key\n    assert list(td.select(3, 2)) == []\n\n    # Test select with key and value\n    assert list(td.select(1, 2, with_key=True)) == [((1, 2), \"a\")]\n    assert list(td.select(2, WILDCARD, with_key=True)) == [((2, 2), \"c\"), ((2, 3), \"d\")]\n\n\ndef test_tupledict_map():\n    td = tupledict([((i, i + 1), i) for i in range(10)])\n\n    td_m = td.map(lambda x: x**2)\n\n    assert isinstance(td_m, tupledict)\n\n    assert list(td_m.values()) == [i**2 for i in range(10)]\n\n    assert list(td_m.keys()) == list(td.keys())\n"
  },
  {
    "path": "tests/test_update.py",
    "content": "import pyoptinterface as poi\nfrom pytest import approx\n\n\ndef test_update(model_interface):\n    model = model_interface\n\n    x = model.add_variables(range(3), lb=1.0, ub=2.0)\n\n    model.delete_variable(x[1])\n\n    expr = x[0] - x[2]\n    con = model.add_linear_constraint(expr, poi.Eq, 0.0)\n\n    obj = x[0] - x[2]\n    model.set_objective(obj)\n\n    model.optimize()\n\n    assert model.get_value(obj) == approx(0.0)\n\n    model.delete_constraint(con)\n    model.set_variable_attribute(x[0], poi.VariableAttribute.LowerBound, 2.0)\n    assert model.get_variable_attribute(\n        x[0], poi.VariableAttribute.LowerBound\n    ) == approx(2.0)\n\n    model.optimize()\n\n    assert model.get_value(x[0]) == approx(2.0)\n    assert model.get_value(x[2]) == approx(2.0)\n\n    con = model.add_linear_constraint(expr, poi.Eq, 0.0)\n    model.set_normalized_coefficient(con, x[2], -2.0)\n\n    model.optimize()\n\n    assert model.get_value(x[0]) == approx(2.0)\n    assert model.get_value(x[2]) == approx(1.0)\n\n    model.set_variable_attribute(x[0], poi.VariableAttribute.LowerBound, 1.5)\n    model.set_variable_attribute(x[2], poi.VariableAttribute.LowerBound, 0.5)\n    model.set_objective_coefficient(x[0], 2.0)\n    model.set_objective_coefficient(x[2], 1.0)\n    model.optimize()\n\n    assert model.get_value(x[0]) == approx(1.5)\n    assert model.get_value(x[2]) == approx(0.75)\n"
  },
  {
    "path": "tests/tsp_cb.py",
    "content": "# This file is adapted from the examples/python/tsp.py in Gurobi installation.\n# We use this file to ensure our callback implementation is correct and the result is compared with gurobipy/coptpy/xpress\n# this test is currently run manually\n\n# Copyright 2024, Gurobi Optimization, LLC\n\nfrom typing import List, Tuple\nimport math\nimport random\nimport time\nfrom collections import defaultdict\nfrom itertools import combinations\n\n# Test what is available in the current system\nGUROBIPY_AVAILABLE = False\nCOPTPY_AVAILABLE = False\nXPRESS_AVAILABLE = False\n\ntry:\n    import gurobipy as gp\n\n    GUROBIPY_AVAILABLE = True\nexcept ImportError:\n    print(\"Gurobipy not found.\")\n\ntry:\n    import coptpy as cp\n\n    COPTPY_AVAILABLE = True\nexcept ImportError:\n    print(\"Coptpy not found.\")\n\ntry:\n    import xpress as xp\n\n    XPRESS_AVAILABLE = True\nexcept ImportError:\n    print(\"Xpress Python Interface not found.\")\n\nimport pyoptinterface as poi\nfrom pyoptinterface import gurobi, copt, xpress\n\nGRB = gurobi.GRB\nCOPT = copt.COPT\nXPRS = xpress.XPRS\n\n\ndef shortest_subtour(edges: List[Tuple[int, int]]) -> List[int]:\n    node_neighbors = defaultdict(list)\n    for i, j in edges:\n        node_neighbors[i].append(j)\n    assert all(len(neighbors) == 2 for neighbors in node_neighbors.values())\n\n    # Follow edges to find cycles. Each time a new cycle is found, keep track\n    # of the shortest cycle found so far and restart from an unvisited node.\n    unvisited = set(node_neighbors)\n    shortest = None\n    while unvisited:\n        cycle = []\n        neighbors = list(unvisited)\n        while neighbors:\n            current = neighbors.pop()\n            cycle.append(current)\n            unvisited.remove(current)\n            neighbors = [j for j in node_neighbors[current] if j in unvisited]\n        if shortest is None or len(cycle) < len(shortest):\n            shortest = cycle\n\n    assert shortest is not None\n    return shortest\n\n\nif GUROBIPY_AVAILABLE:\n\n    class GurobiTSPCallback:\n        def __init__(self, nodes, x):\n            self.nodes = nodes\n            self.x = x\n\n        def __call__(self, model, where):\n            if where == GRB.Callback.MIPSOL:\n                self.eliminate_subtours_gurobipy(model)\n\n        def eliminate_subtours_gurobipy(self, model):\n            values = model.cbGetSolution(self.x)\n            edges = [(i, j) for (i, j), v in values.items() if v > 0.5]\n            tour = shortest_subtour(edges)\n            if len(tour) < len(self.nodes):\n                # add subtour elimination constraint for every pair of cities in tour\n                model.cbLazy(\n                    gp.quicksum(self.x[i, j] for i, j in combinations(tour, 2))\n                    <= len(tour) - 1\n                )\n\n    def solve_tsp_gurobipy(nodes, distances):\n        \"\"\"\n        Solve a dense symmetric TSP using the following base formulation:\n\n        min  sum_ij d_ij x_ij\n        s.t. sum_j x_ij == 2   forall i in V\n             x_ij binary       forall (i,j) in E\n\n        and subtours eliminated using lazy constraints.\n        \"\"\"\n\n        m = gp.Model()\n\n        x = m.addVars(distances.keys(), obj=distances, vtype=GRB.BINARY, name=\"e\")\n        x.update({(j, i): v for (i, j), v in x.items()})\n\n        # Create degree 2 constraints\n        for i in nodes:\n            m.addConstr(gp.quicksum(x[i, j] for j in nodes if i != j) == 2)\n\n        m.Params.OutputFlag = 0\n        m.Params.LazyConstraints = 1\n        cb = GurobiTSPCallback(nodes, x)\n        m.optimize(cb)\n\n        edges = [(i, j) for (i, j), v in x.items() if v.X > 0.5]\n        tour = shortest_subtour(edges)\n        assert set(tour) == set(nodes)\n\n        return tour, m.ObjVal\n\n\nif COPTPY_AVAILABLE:\n\n    class COPTTSPCallback(cp.CallbackBase):\n        def __init__(self, nodes, x):\n            super().__init__()\n            self.nodes = nodes\n            self.x = x\n\n        def callback(self):\n            if self.where() == COPT.CBCONTEXT_MIPSOL:\n                self.eliminate_subtours_coptpy()\n\n        def eliminate_subtours_coptpy(self):\n            values = self.getSolution(self.x)\n            edges = [(i, j) for (i, j), v in values.items() if v > 0.5]\n            tour = shortest_subtour(edges)\n            if len(tour) < len(self.nodes):\n                # add subtour elimination constraint for every pair of cities in tour\n                self.addLazyConstr(\n                    cp.quicksum(self.x[i, j] for i, j in combinations(tour, 2))\n                    <= len(tour) - 1\n                )\n\n    def solve_tsp_coptpy(nodes, distances):\n        env = cp.Envr()\n        m = env.createModel(\"TSP Callback Example\")\n\n        x = m.addVars(distances.keys(), vtype=COPT.BINARY, nameprefix=\"e\")\n        for (i, j), v in x.items():\n            v.setInfo(COPT.Info.Obj, distances[i, j])\n        for i, j in distances.keys():\n            x[j, i] = x[i, j]\n\n        # Create degree 2 constraints\n        for i in nodes:\n            m.addConstr(cp.quicksum(x[i, j] for j in nodes if i != j) == 2)\n\n        m.Param.Logging = 0\n        cb = COPTTSPCallback(nodes, x)\n        m.setCallback(cb, COPT.CBCONTEXT_MIPSOL)\n        m.solve()\n\n        edges = [(i, j) for (i, j), v in x.items() if v.x > 0.5]\n        tour = shortest_subtour(edges)\n        assert set(tour) == set(nodes)\n\n        return tour, m.objval\n\n\nif XPRESS_AVAILABLE:\n\n    class XpressTSPCallback:\n        def __init__(self, nodes, x):\n            self.nodes = nodes\n            self.x = x\n\n        def __call__(self, prob, data, soltype, cutoff):\n            \"\"\"\n            Pre-integer solution callback: checks candidate solution and adds\n            subtour elimination cuts.\n\n            Args:\n                soltype: Solution origin (0=B&B node, 1=heuristic, 2=user)\n                cutoff: Current cutoff value\n\n            Returns:\n                (reject, new_cutoff): reject=1 to discard solution, new_cutoff\n                to update solution cutoff value\n            \"\"\"\n\n            # Extract solution and identify active edges\n            sol = prob.getCallbackSolution()\n            edges = [(i, j) for i, j in self.x if sol[self.x[i, j].index] > 0.5]\n\n            tour = shortest_subtour(edges)\n            if len(tour) == len(self.nodes):  # Complete tour\n                return (0, None)\n\n            if soltype != 0:  # Can only add cuts at B&B nodes\n                return (1, None)\n\n            # Build and presolve SEC\n            idxs = [self.x[i, j].index for i, j in combinations(tour, 2)]\n            coeffs = [1.0] * len(idxs)\n            rhs = len(tour) - 1\n\n            idxs, coeffs, rhs, status = prob.presolveRow(\"L\", idxs, coeffs, rhs)\n            if status < 0:  # Presolve failed (dual reductions on?)\n                return (1, None)\n\n            # Add cut\n            prob.addCuts([0], [\"L\"], [rhs], [0, len(idxs)], idxs, coeffs)\n            return (0, None)  # reject=1 would drop the node as well!\n\n    def solve_tsp_xpress(nodes, distances):\n        prob = xp.problem()\n\n        x = prob.addVariables(distances.keys(), vartype=xp.binary, name=\"e\")\n        prob.setObjective(xp.Sum(dist * x[i, j] for (i, j), dist in distances.items()))\n        x.update({(j, i): v for (i, j), v in x.items()})\n\n        # Create degree 2 constraints\n        for i in nodes:\n            prob.addConstraint(xp.Sum(x[i, j] for j in nodes if i != j) == 2)\n\n        prob.controls.outputlog = 0\n        prob.controls.mipdualreductions = 0\n        cb = XpressTSPCallback(nodes, x)\n        prob.addPreIntsolCallback(cb, None, 0)\n\n        prob.optimize()\n\n        edges = [(i, j) for (i, j), v in x.items() if prob.getSolution(v) > 0.5]\n        tour = shortest_subtour(edges)\n        assert set(tour) == set(nodes)\n        return tour, prob.attributes.objval\n\n\nclass POITSPCallback:\n    def __init__(self, nodes, x):\n        self.nodes = nodes\n        self.x = x\n\n    def run_gurobi(self, model, where):\n        if where == GRB.Callback.MIPSOL:\n            self.eliminate_subtours_poi(model)\n\n    def run_copt(self, model, where):\n        if where == COPT.CBCONTEXT_MIPSOL:\n            self.eliminate_subtours_poi(model)\n\n    def run_xpress(self, model, where):\n        if where == XPRS.CB_CONTEXT.PREINTSOL:\n            self.eliminate_subtours_poi(model)\n\n    def eliminate_subtours_poi(self, model):\n        edges = []\n        for (i, j), xij in self.x.items():\n            v = model.cb_get_solution(xij)\n            if v > 0.5:\n                edges.append((i, j))\n        tour = shortest_subtour(edges)\n        if len(tour) < len(self.nodes):\n            # add subtour elimination constraint for every pair of cities in tour\n            model.cb_add_lazy_constraint(\n                poi.quicksum(self.x[i, j] for i, j in combinations(tour, 2)),\n                poi.Leq,\n                len(tour) - 1,\n            )\n\n\ndef solve_tsp_poi(f, nodes, distances):\n    m = f()\n    x = m.add_variables(distances.keys(), domain=poi.VariableDomain.Binary, name=\"e\")\n    m.set_objective(poi.quicksum(distances[k] * x[k] for k in distances))\n    for i, j in distances.keys():\n        x[j, i] = x[i, j]\n\n    for i in nodes:\n        m.add_linear_constraint(\n            poi.quicksum(x[i, j] for j in nodes if i != j), poi.Eq, 2\n        )\n\n    m.set_model_attribute(poi.ModelAttribute.Silent, True)\n    cb = POITSPCallback(nodes, x)\n    if isinstance(m, gurobi.Model):\n        m.set_raw_parameter(\"LazyConstraints\", 1)\n        m.set_callback(cb.run_gurobi)\n    elif isinstance(m, copt.Model):\n        m.set_callback(cb.run_copt, COPT.CBCONTEXT_MIPSOL)\n    elif isinstance(m, xpress.Model):\n        m.set_raw_control(\"XPRS_MIPDUALREDUCTIONS\", 0)\n        m.set_callback(cb.run_xpress, XPRS.CB_CONTEXT.PREINTSOL)\n    m.optimize()\n\n    # Extract the solution as a tour\n    edges = [(i, j) for (i, j), v in x.items() if m.get_value(v) > 0.5]\n    tour = shortest_subtour(edges)\n    assert set(tour) == set(nodes)\n\n    objval = m.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n\n    return tour, objval\n\n\ndef create_map(npoints, seed):\n    # Create n random points in 2D\n    random.seed(seed)\n    nodes = list(range(npoints))\n    points = [(random.randint(0, 100), random.randint(0, 100)) for i in nodes]\n\n    # Dictionary of Euclidean distance between each pair of points\n    distances = {\n        (i, j): math.sqrt(sum((points[i][k] - points[j][k]) ** 2 for k in range(2)))\n        for i, j in combinations(nodes, 2)\n    }\n\n    return nodes, distances\n\n\ndef test_gurobi(npoints_series, seed):\n    for npoints in npoints_series:\n        nodes, distances = create_map(npoints, seed)\n\n        print(f\"npoints = {npoints}\")\n\n        t0 = time.time()\n        tour1, cost1 = solve_tsp_gurobipy(nodes, distances)\n        t1 = time.time()\n        print(f\"\\t gurobipy time: {t1 - t0:g} seconds\")\n\n        t0 = time.time()\n        f = gurobi.Model\n        tour2, cost2 = solve_tsp_poi(f, nodes, distances)\n        t1 = time.time()\n        print(f\"\\t poi time: {t1 - t0:g} seconds\")\n\n        assert tour1 == tour2\n        assert abs(cost1 - cost2) < 1e-6\n\n\ndef test_copt(npoints_series, seed):\n    for npoints in npoints_series:\n        nodes, distances = create_map(npoints, seed)\n\n        print(f\"npoints = {npoints}\")\n\n        t0 = time.time()\n        tour1, cost1 = solve_tsp_coptpy(nodes, distances)\n        t1 = time.time()\n        print(f\"\\t coptpy time: {t1 - t0:g} seconds\")\n\n        t0 = time.time()\n        f = copt.Model\n        tour2, cost2 = solve_tsp_poi(f, nodes, distances)\n        t1 = time.time()\n        print(f\"\\t poi time: {t1 - t0:g} seconds\")\n\n        assert tour1 == tour2\n        assert abs(cost1 - cost2) < 1e-6\n\n\ndef test_xpress(npoints_series, seed):\n    for npoints in npoints_series:\n        nodes, distances = create_map(npoints, seed)\n\n        print(f\"npoints = {npoints}\")\n\n        t0 = time.time()\n        tour1, cost1 = solve_tsp_xpress(nodes, distances)\n        t1 = time.time()\n        print(f\"\\t Xpress-Python cost: {cost1}, time: {t1 - t0:g} seconds\")\n\n        t0 = time.time()\n        f = xpress.Model\n        tour2, cost2 = solve_tsp_poi(f, nodes, distances)\n        t1 = time.time()\n        print(f\"\\t PyOptInterface cost: {cost2}, time: {t1 - t0:g} seconds\")\n\n        assert tour1 == tour2\n        assert abs(cost1 - cost2) < 1e-6\n\n\nif __name__ == \"__main__\":\n    seed = 987651234\n\n    X = range(10, 90, 10)\n\n    if copt.is_library_loaded():\n        test_copt(X, seed)\n    else:\n        print(\"PyOptInterface did not find COPT.\")\n\n    if gurobi.is_library_loaded():\n        test_gurobi(X, seed)\n    else:\n        print(\"PyOptInterface did not find Gurobi.\")\n\n    if xpress.is_library_loaded():\n        test_xpress(X, seed)\n    else:\n        print(\"PyOptInterface did not find Xpress.\")\n"
  },
  {
    "path": "tests/tsp_xpress.py",
    "content": "# TSP example using numpy functions (for efficiency)\n#\n# (C) Fair Isaac Corp., 1983-2025\n\nfrom typing import List, Tuple\nimport math\nimport random\nimport time\nfrom collections import defaultdict\nfrom itertools import combinations\n\nimport pyoptinterface as poi\nfrom pyoptinterface import xpress\n\nimport xpress as xp\nimport numpy as np\n\nXPRS = xpress.XPRS\n\n\ndef cb_preintsol(prob, data, soltype, cutoff):\n    \"\"\"Callback for checking if solution is acceptable\"\"\"\n\n    n = data\n    xsol = prob.getCallbackSolution()\n    xsolf = np.array(xsol)\n    xsol = xsolf.reshape(n, n)\n    nextc = np.argmax(xsol, axis=1)\n\n    i = 0\n    ncities = 1\n\n    while nextc[i] != 0 and ncities < n:\n        ncities += 1\n        i = nextc[i]\n\n    reject = False\n    if ncities < n:\n        if soltype != 0:\n            reject = True\n        else:\n            unchecked = np.zeros(n)\n            ngroup = 0\n\n            cut_mstart = [0]\n            cut_ind = []\n            cut_coe = []\n            cut_rhs = []\n\n            nnz = 0\n            ncuts = 0\n\n            while np.min(unchecked) == 0 and ngroup <= n:\n                \"\"\"Seek a tour\"\"\"\n\n                ngroup += 1\n                firstcity = np.argmin(unchecked)\n                i = firstcity\n                ncities = 0\n                while True:\n                    unchecked[i] = ngroup\n                    ncities += 1\n                    i = nextc[i]\n\n                    if i == firstcity or ncities > n + 1:\n                        break\n\n                S = np.where(unchecked == ngroup)[0].tolist()\n                compS = np.where(unchecked != ngroup)[0].tolist()\n\n                indices = [i * n + j for i in S for j in compS]\n\n                if sum(xsolf[i] for i in indices) < 1 - 1e-3:\n                    mcolsp, dvalp = [], []\n\n                    drhsp, status = prob.presolverow(\n                        rowtype=\"G\",\n                        origcolind=indices,\n                        origrowcoef=np.ones(len(indices)),\n                        origrhs=1,\n                        maxcoefs=prob.attributes.cols,\n                        colind=mcolsp,\n                        rowcoef=dvalp,\n                    )\n                    assert status == 0\n\n                    nnz += len(mcolsp)\n                    ncuts += 1\n\n                    cut_ind.extend(mcolsp)\n                    cut_coe.extend(dvalp)\n                    cut_rhs.append(drhsp)\n                    cut_mstart.append(nnz)\n\n                if ncuts > 0:\n                    prob.addcuts(\n                        cuttype=[0] * ncuts,\n                        rowtype=[\"G\"] * ncuts,\n                        rhs=cut_rhs,\n                        start=cut_mstart,\n                        colind=cut_ind,\n                        cutcoef=cut_coe,\n                    )\n\n    return (reject, None)\n\n\ndef print_sol(p, n):\n    \"\"\"Print the solution: order of nodes and cost\"\"\"\n\n    xsol = np.array(p.getSolution()).reshape(n, n)\n    nextc = np.argmax(xsol, axis=1)\n\n    i = 0\n\n    tour = []\n    while i != 0 or len(tour) == 0:\n        tour.append(str(i))\n        i = nextc[i]\n    print(\"->\".join(tour), \"->0; cost: \", p.attributes.objval, sep=\"\")\n\n\ndef create_initial_tour(n):\n    \"\"\"Returns a permuted trivial solution 0->1->2->...->(n-1)->0\"\"\"\n    sol = np.zeros((n, n))\n    p = np.random.permutation(n)\n    for i in range(n):\n        sol[p[i], p[(i + 1) % n]] = 1\n    return sol.flatten()\n\n\ndef solve_xpress(nodes, distances):\n    n = len(nodes)\n    nodes = range(n)\n    p = xp.problem()\n    p.controls.outputlog = 0\n\n    fly = np.array(\n        [\n            p.addVariable(vartype=xp.binary, name=f\"x_{i}_{j}\")\n            for i in nodes\n            for j in nodes\n        ],\n        dtype=xp.npvar,\n    ).reshape(n, n)\n\n    # Outgoing constraints: sum of outgoing arcs from i equals 1\n    for i in nodes:\n        p.addConstraint(xp.Sum(fly[i, :]) - fly[i, i] == 1)\n\n    # Incoming constraints: sum of incoming arcs to i equals 1\n    for i in nodes:\n        p.addConstraint(xp.Sum(fly[:, i]) - fly[i, i] == 1)\n\n    # No self-loops\n    for i in nodes:\n        p.addConstraint(fly[i, i] == 0)\n\n    p.setObjective(xp.Sum(fly[i, j] * distances[i, j] for i in nodes for j in nodes))\n    p.addcbpreintsol(cb_preintsol, n)\n    p.controls.mipdualreductions = 0\n\n    for k in range(10):\n        InitTour = create_initial_tour(n)\n        p.addmipsol(solval=InitTour, name=f\"InitTour_{k}\")\n\n    p.optimize()\n\n    if p.attributes.solstatus not in [xp.SolStatus.OPTIMAL, xp.SolStatus.FEASIBLE]:\n        print(\"Solve status:\", p.attributes.solvestatus.name)\n        print(\"Solution status:\", p.attributes.solstatus.name)\n    else:\n        print_sol(p, n)\n\n    xvals = np.array(p.getSolution()).reshape(n, n)\n    edges = [(i, j) for i in nodes for j in nodes if xvals[i, j] > 0.5]\n    print(edges)\n\n    tour = shortest_subtour(edges)\n    objval = p.attributes.objval\n\n    return tour, objval\n\n\ndef shortest_subtour(edges: List[Tuple[int, int]]) -> List[int]:\n    node_neighbors = defaultdict(list)\n    for i, j in edges:\n        node_neighbors[i].append(j)\n\n    # Follow edges to find cycles. Each time a new cycle is found, keep track\n    # of the shortest cycle found so far and restart from an unvisited node.\n    unvisited = set(node_neighbors)\n    shortest = None\n    while unvisited:\n        cycle = []\n        neighbors = list(unvisited)\n        while neighbors:\n            current = neighbors.pop()\n            cycle.append(current)\n            unvisited.remove(current)\n            neighbors = [j for j in node_neighbors[current] if j in unvisited]\n        if shortest is None or len(cycle) < len(shortest):\n            shortest = cycle\n\n    assert shortest is not None\n    return shortest\n\n\ndef solve_poi(f, nodes, distances):\n    n = len(nodes)\n    m = f()\n\n    fly = np.array(\n        [\n            m.add_variable(name=f\"x_{i}_{j}\", domain=poi.VariableDomain.Binary)\n            for i in nodes\n            for j in nodes\n        ],\n        dtype=object,  # Changed from xp.npvar\n    ).reshape(n, n)\n\n    # Outgoing constraints: sum of outgoing arcs from i equals 1\n    for i in nodes:\n        m.add_linear_constraint(poi.quicksum(fly[i, :]) - fly[i, i], poi.Eq, 1)\n\n    # Incoming constraints: sum of incoming arcs to i equals 1\n    for i in nodes:\n        m.add_linear_constraint(poi.quicksum(fly[:, i]) - fly[i, i], poi.Eq, 1)\n\n    # No self-loops\n    for i in nodes:\n        m.add_linear_constraint(fly[i, i], poi.Eq, 0)\n\n    m.set_objective(\n        poi.quicksum(fly[i, j] * distances[i, j] for i in nodes for j in nodes)\n    )\n\n    def eliminate_subtours_poi(model):\n        edges = [\n            (i, j)\n            for (i, j), v in np.ndenumerate(fly)\n            if model.cb_get_solution(v) > 0.5\n        ]\n        tour = shortest_subtour(edges)\n        if len(tour) < len(nodes):\n            print(\"                    Shortest subtour:\", tour)\n            print(\n                f\"                    Adding new cut with {len(tour)**2 - len(tour)} nonzeros.\"\n            )\n            model.cb_add_lazy_constraint(\n                poi.quicksum(fly[i, j] + fly[j, i] for i, j in combinations(tour, 2)),\n                poi.Leq,\n                len(tour) - 1,\n            )\n\n    def cb(model, ctx):\n        args = model.cb_get_arguments()\n        if ctx == XPRS.CB_CONTEXT.MESSAGE and args.msgtype > 0:\n            print(f\"{ctx.name:>16}: {args.msg}\")\n        if ctx == XPRS.CB_CONTEXT.BARITERATION:\n            print(\n                f\"{ctx.name:>16}: Barrier iter {model.get_raw_attribute(\"XPRS_BARITER\")}, primal {model.get_raw_attribute(\"XPRS_BARPRIMALOBJ\")}, dual {model.get_raw_attribute(\"XPRS_BARDUALOBJ\")}, primal inf {model.get_raw_attribute(\"XPRS_BARPRIMALINF\")}, dual inf{model.get_raw_attribute(\"XPRS_BARDUALINF\")}, gap {model.get_raw_attribute(\"XPRS_BARCGAP\")}\"\n            )\n        if ctx == XPRS.CB_CONTEXT.BARLOG:\n            print(\n                f\"{ctx.name:>16}: Barrier iter {model.get_raw_attribute(\"XPRS_BARITER\")}, primal {model.get_raw_attribute(\"XPRS_BARPRIMALOBJ\")}, dual {model.get_raw_attribute(\"XPRS_BARDUALOBJ\")}, primal inf {model.get_raw_attribute(\"XPRS_BARPRIMALINF\")}, dual inf{model.get_raw_attribute(\"XPRS_BARDUALINF\")}, gap {model.get_raw_attribute(\"XPRS_BARCGAP\")}\"\n            )\n        if ctx == XPRS.CB_CONTEXT.AFTEROBJECTIVE:\n            print(\n                f\"{ctx.name:>16}: Completed obj solve {model.get_raw_attribute(\"XPRS_SOLVEDOBJS\")}\"\n            )\n        if ctx == XPRS.CB_CONTEXT.BEFOREOBJECTIVE:\n            print(\n                f\"{ctx.name:>16}: Starting obj solve {model.get_raw_attribute(\"XPRS_SOLVEDOBJS\")}\"\n            )\n        if ctx == XPRS.CB_CONTEXT.PRESOLVE:\n            runtime = model.get_raw_attribute_dbl_by_id(XPRS.TIME)\n            coldel = model.get_raw_attribute_int_by_id(\n                XPRS.ORIGINALCOLS\n            ) - model.get_raw_attribute_int_by_id(XPRS.COLS)\n            rowdel = model.get_raw_attribute_int_by_id(\n                XPRS.ORIGINALROWS\n            ) - model.get_raw_attribute_int_by_id(XPRS.ROWS)\n            print(\n                f\"{ctx.name:>16}: Runtime: {runtime}, Coldel: {coldel}, Rowdel: {rowdel}\"\n            )\n        if ctx == XPRS.CB_CONTEXT.CHECKTIME:\n            print(\n                f\"{ctx.name:>16}: {model.get_raw_attribute(\"XPRS_TIME\")} seconds have passed.\"\n            )\n        if ctx == XPRS.CB_CONTEXT.CHGBRANCHOBJECT:\n            print(f\"{ctx.name:>16}: Not a lot to print here at the moment\")\n        if ctx == XPRS.CB_CONTEXT.CUTLOG:\n            print(\n                f\"{ctx.name:>16}: You should see the cutlog somewhere near this message.\"\n            )\n        if ctx == XPRS.CB_CONTEXT.CUTROUND:\n            print(\n                f\"{ctx.name:>16}: The optimizer would have done another cut round? {args.ifxpresscuts} - Forcing it.\"\n            )\n            args.p_action = 1\n        if ctx == XPRS.CB_CONTEXT.DESTROYMT:\n            print(f\"{ctx.name:>16}: Somewhere someone is killing a MIP Thread. RIP :(\")\n        if ctx == XPRS.CB_CONTEXT.GAPNOTIFY:\n            obj = model.get_raw_attribute_dbl_by_id(XPRS.MIPOBJVAL)\n            bound = model.get_raw_attribute_dbl_by_id(XPRS.BESTBOUND)\n            gap = 0\n            if obj != 0 or bound != 0:\n                gap = abs(obj - bound) / max(abs(obj), abs(bound))\n            print(f\"{ctx.name:>16}: Current gap {gap}, next target set to {gap/2}\")\n        if ctx == XPRS.CB_CONTEXT.MIPLOG:\n            print(\n                f\"{ctx.name:>16}: Node {model.get_raw_attribute(\"XPRS_CURRENTNODE\")} with depth {model.get_raw_attribute(\"XPRS_NODEDEPTH\")} has just been processed\"\n            )\n        if ctx == XPRS.CB_CONTEXT.INFNODE:\n            print(\n                f\"{ctx.name:>16}: Infeasible node id {model.get_raw_attribute(\"XPRS_CURRENTNODE\")}\"\n            )\n        if ctx == XPRS.CB_CONTEXT.INTSOL:\n            print(\n                f\"{ctx.name:>16}: Integer solution value: {model.get_raw_attribute(\"XPRS_MIPOBJVAL\")}\"\n            )\n        if ctx == XPRS.CB_CONTEXT.LPLOG:\n            print(\n                f\"{ctx.name:>16}: At iteration {model.get_raw_attribute(\"XPRS_SIMPLEXITER\")} objval is {model.get_raw_attribute(\"XPRS_LPOBJVAL\")}\"\n            )\n        if ctx == XPRS.CB_CONTEXT.NEWNODE:\n            print(\n                f\"{ctx.name:>16}: New node id {args.node}, parent node {args.parentnode}, branch {args.branch}\"\n            )\n        # if ctx == XPRS.CB_CONTEXT.MIPTHREAD:\n        #    print(f\"{ctx.name:>16}: Not a lot to print here at the moment\")\n        if ctx == XPRS.CB_CONTEXT.NODECUTOFF:\n            print(f\"{ctx.name:>16}: Node {args.node} cut off.\")\n        if ctx == XPRS.CB_CONTEXT.NODELPSOLVED:\n            obj = model.get_raw_attribute_dbl_by_id(XPRS.LPOBJVAL)\n            print(\n                f\"{ctx.name:>16}: Solved relaxation at node {model.get_raw_attribute(\"XPRS_CURRENTNODE\")}, lp obj {obj}\"\n            )\n        if ctx == XPRS.CB_CONTEXT.OPTNODE:\n            obj = model.get_raw_attribute_dbl_by_id(XPRS.LPOBJVAL)\n            print(\n                f\"{ctx.name:>16}: Finished processing node {model.get_raw_attribute(\"XPRS_CURRENTNODE\")}, lp obj {obj}\"\n            )\n        if ctx == XPRS.CB_CONTEXT.PREINTSOL:\n            print(\n                f\"{ctx.name:>16}: Candidate integer solution objective {model.get_raw_attribute(\"LPOBJVAL\")}, soltype: {args.soltype}, p_reject: {args.p_reject}, p_cutoff: {args.p_cutoff}\"\n            )\n            eliminate_subtours_poi(model)\n        if ctx == XPRS.CB_CONTEXT.PRENODE:\n            print(f\"{ctx.name:>16}: Node optimization is about to start...\")\n        if ctx == XPRS.CB_CONTEXT.USERSOLNOTIFY:\n            print(\n                f\"{ctx.name:>16}: Solution {args.solname} was processed resulting in status {args.status}.\"\n            )\n\n    m.set_callback(\n        cb,\n        XPRS.CB_CONTEXT.MESSAGE\n        | XPRS.CB_CONTEXT.BARITERATION\n        | XPRS.CB_CONTEXT.BARLOG\n        | XPRS.CB_CONTEXT.AFTEROBJECTIVE\n        | XPRS.CB_CONTEXT.BEFOREOBJECTIVE\n        | XPRS.CB_CONTEXT.PRESOLVE\n        | XPRS.CB_CONTEXT.CHECKTIME\n        | XPRS.CB_CONTEXT.CHGBRANCHOBJECT\n        | XPRS.CB_CONTEXT.CUTLOG\n        | XPRS.CB_CONTEXT.CUTROUND\n        | XPRS.CB_CONTEXT.DESTROYMT\n        | XPRS.CB_CONTEXT.GAPNOTIFY\n        | XPRS.CB_CONTEXT.MIPLOG\n        | XPRS.CB_CONTEXT.INFNODE\n        | XPRS.CB_CONTEXT.INTSOL\n        | XPRS.CB_CONTEXT.LPLOG\n        # |XPRS.CB_CONTEXT.MIPTHREAD\n        | XPRS.CB_CONTEXT.NEWNODE\n        | XPRS.CB_CONTEXT.NODECUTOFF\n        | XPRS.CB_CONTEXT.NODELPSOLVED\n        | XPRS.CB_CONTEXT.OPTNODE\n        | XPRS.CB_CONTEXT.PREINTSOL\n        | XPRS.CB_CONTEXT.PRENODE\n        | XPRS.CB_CONTEXT.USERSOLNOTIFY,\n    )\n    m.set_raw_control_int_by_id(XPRS.CALLBACKCHECKTIMEDELAY, 10)\n    m.set_raw_control_dbl_by_id(XPRS.MIPRELGAPNOTIFY, 1.0)\n    m.set_raw_control(\"XPRS_MIPDUALREDUCTIONS\", 0)\n    m.optimize()\n\n    # Extract the solution as a tour\n    edges = [(i, j) for (i, j), v in np.ndenumerate(fly) if m.get_value(v) > 0.5]\n    tour = shortest_subtour(edges)\n\n    objval = m.get_model_attribute(poi.ModelAttribute.ObjectiveValue)\n\n    return tour, objval\n\n\ndef create_map(npoints, seed):\n    # Create n random points in 2D\n    random.seed(seed)\n    nodes = list(range(npoints))\n    points = [(random.randint(0, 100), random.randint(0, 100)) for _ in nodes]\n\n    # Dictionary of Euclidean distance between each pair of points\n    distances = {\n        (i, j): math.sqrt(sum((points[i][k] - points[j][k]) ** 2 for k in range(2)))\n        for i in nodes\n        for j in nodes\n    }\n    return nodes, distances\n\n\ndef test_xpress(npoints_series, seed):\n    for npoints in npoints_series:\n        nodes, distances = create_map(npoints, seed)\n\n        print(f\"npoints = {npoints}\")\n\n        t0 = time.time()\n        f = xpress.Model\n        _, cost2 = solve_poi(f, nodes, distances)\n        t1 = time.time()\n        print(f\"\\t poi time: {t1 - t0:g} seconds\")\n        print(f\"POI solution value: {cost2}\")\n\n        t0 = time.time()\n        _, cost1 = solve_xpress(nodes, distances)\n        t1 = time.time()\n        print(f\"\\t xpress time: {t1 - t0:g} seconds\")\n        print(f\"Xpress solution value: {cost1}\")\n\n\nif __name__ == \"__main__\":\n    seed = 987651234\n\n    X = range(20, 10000, 10000)\n    test_xpress(X, seed)\n"
  },
  {
    "path": "thirdparty/ankerl/stl.h",
    "content": "///////////////////////// ankerl::unordered_dense::{map, set} /////////////////////////\n\n// A fast & densely stored hashmap and hashset based on robin-hood backward shift deletion.\n// Version 4.8.1\n// https://github.com/martinus/unordered_dense\n//\n// Licensed under the MIT License <http://opensource.org/licenses/MIT>.\n// SPDX-License-Identifier: MIT\n// Copyright (c) 2022 Martin Leitner-Ankerl <martin.ankerl@gmail.com>\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n#ifndef ANKERL_STL_H\n#define ANKERL_STL_H\n\n#include <array>            // for array\n#include <cstdint>          // for uint64_t, uint32_t, std::uint8_t, UINT64_C\n#include <cstring>          // for size_t, memcpy, memset\n#include <functional>       // for equal_to, hash\n#include <initializer_list> // for initializer_list\n#include <iterator>         // for pair, distance\n#include <limits>           // for numeric_limits\n#include <memory>           // for allocator, allocator_traits, shared_ptr\n#include <optional>         // for optional\n#include <stdexcept>        // for out_of_range\n#include <string>           // for basic_string\n#include <string_view>      // for basic_string_view, hash\n#include <tuple>            // for forward_as_tuple\n#include <type_traits>      // for enable_if_t, declval, conditional_t, ena...\n#include <utility>          // for forward, exchange, pair, as_const, piece...\n#include <vector>           // for vector\n\n// <memory_resource> includes <mutex>, which fails to compile if\n// targeting GCC >= 13 with the (rewritten) win32 thread model, and\n// targeting Windows earlier than Vista (0x600).  GCC predefines\n// _REENTRANT when using the 'posix' model, and doesn't when using the\n// 'win32' model.\n#if defined __MINGW64__ && defined __GNUC__ && __GNUC__ >= 13 && !defined _REENTRANT\n// _WIN32_WINNT is guaranteed to be defined here because of the\n// <cstdint> inclusion above.\n#    ifndef _WIN32_WINNT\n#        error \"_WIN32_WINNT not defined\"\n#    endif\n#    if _WIN32_WINNT < 0x600\n#        define ANKERL_MEMORY_RESOURCE_IS_BAD() 1 // NOLINT(cppcoreguidelines-macro-usage)\n#    endif\n#endif\n#ifndef ANKERL_MEMORY_RESOURCE_IS_BAD\n#    define ANKERL_MEMORY_RESOURCE_IS_BAD() 0 // NOLINT(cppcoreguidelines-macro-usage)\n#endif\n\n#if defined(__has_include) && !defined(ANKERL_UNORDERED_DENSE_DISABLE_PMR)\n#    if __has_include(<memory_resource>) && !ANKERL_MEMORY_RESOURCE_IS_BAD()\n#        define ANKERL_UNORDERED_DENSE_PMR std::pmr // NOLINT(cppcoreguidelines-macro-usage)\n#        include <memory_resource>                  // for polymorphic_allocator\n#    elif __has_include(<experimental/memory_resource>)\n#        define ANKERL_UNORDERED_DENSE_PMR std::experimental::pmr // NOLINT(cppcoreguidelines-macro-usage)\n#        include <experimental/memory_resource>                   // for polymorphic_allocator\n#    endif\n#endif\n\n#if defined(_MSC_VER) && defined(_M_X64)\n#    include <intrin.h>\n#    pragma intrinsic(_umul128)\n#endif\n\n#endif\n"
  },
  {
    "path": "thirdparty/ankerl/unordered_dense.h",
    "content": "///////////////////////// ankerl::unordered_dense::{map, set} /////////////////////////\n\n// A fast & densely stored hashmap and hashset based on robin-hood backward shift deletion.\n// Version 4.8.1\n// https://github.com/martinus/unordered_dense\n//\n// Licensed under the MIT License <http://opensource.org/licenses/MIT>.\n// SPDX-License-Identifier: MIT\n// Copyright (c) 2022 Martin Leitner-Ankerl <martin.ankerl@gmail.com>\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\n#ifndef ANKERL_UNORDERED_DENSE_H\n#define ANKERL_UNORDERED_DENSE_H\n\n// see https://semver.org/spec/v2.0.0.html\n#define ANKERL_UNORDERED_DENSE_VERSION_MAJOR 4 // NOLINT(cppcoreguidelines-macro-usage) incompatible API changes\n#define ANKERL_UNORDERED_DENSE_VERSION_MINOR 8 // NOLINT(cppcoreguidelines-macro-usage) backwards compatible functionality\n#define ANKERL_UNORDERED_DENSE_VERSION_PATCH 1 // NOLINT(cppcoreguidelines-macro-usage) backwards compatible bug fixes\n\n// API versioning with inline namespace, see https://www.foonathan.net/2018/11/inline-namespaces/\n\n// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)\n#define ANKERL_UNORDERED_DENSE_VERSION_CONCAT1(major, minor, patch) v##major##_##minor##_##patch\n// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)\n#define ANKERL_UNORDERED_DENSE_VERSION_CONCAT(major, minor, patch) ANKERL_UNORDERED_DENSE_VERSION_CONCAT1(major, minor, patch)\n#define ANKERL_UNORDERED_DENSE_NAMESPACE   \\\n    ANKERL_UNORDERED_DENSE_VERSION_CONCAT( \\\n        ANKERL_UNORDERED_DENSE_VERSION_MAJOR, ANKERL_UNORDERED_DENSE_VERSION_MINOR, ANKERL_UNORDERED_DENSE_VERSION_PATCH)\n\n#if defined(_MSVC_LANG)\n#    define ANKERL_UNORDERED_DENSE_CPP_VERSION _MSVC_LANG\n#else\n#    define ANKERL_UNORDERED_DENSE_CPP_VERSION __cplusplus\n#endif\n\n#if defined(__GNUC__)\n// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)\n#    define ANKERL_UNORDERED_DENSE_PACK(decl) decl __attribute__((__packed__))\n#elif defined(_MSC_VER)\n// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)\n#    define ANKERL_UNORDERED_DENSE_PACK(decl) __pragma(pack(push, 1)) decl __pragma(pack(pop))\n#endif\n\n// exceptions\n#if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)\n#    define ANKERL_UNORDERED_DENSE_HAS_EXCEPTIONS() 1 // NOLINT(cppcoreguidelines-macro-usage)\n#else\n#    define ANKERL_UNORDERED_DENSE_HAS_EXCEPTIONS() 0 // NOLINT(cppcoreguidelines-macro-usage)\n#endif\n#ifdef _MSC_VER\n#    define ANKERL_UNORDERED_DENSE_NOINLINE __declspec(noinline)\n#else\n#    define ANKERL_UNORDERED_DENSE_NOINLINE __attribute__((noinline))\n#endif\n\n#if defined(__clang__) && defined(__has_attribute)\n#    if __has_attribute(__no_sanitize__)\n#        define ANKERL_UNORDERED_DENSE_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK \\\n            __attribute__((__no_sanitize__(\"unsigned-integer-overflow\")))\n#    endif\n#endif\n\n#if !defined(ANKERL_UNORDERED_DENSE_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK)\n#    define ANKERL_UNORDERED_DENSE_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK\n#endif\n\n#if ANKERL_UNORDERED_DENSE_CPP_VERSION < 201703L\n#    error ankerl::unordered_dense requires C++17 or higher\n#else\n\n#    if !defined(ANKERL_UNORDERED_DENSE_STD_MODULE)\n// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)\n#        define ANKERL_UNORDERED_DENSE_STD_MODULE 0\n#    endif\n\n#    if !ANKERL_UNORDERED_DENSE_STD_MODULE\n#        include \"stl.h\"\n#    endif\n\n#    if __has_cpp_attribute(likely) && __has_cpp_attribute(unlikely) && ANKERL_UNORDERED_DENSE_CPP_VERSION >= 202002L\n#        define ANKERL_UNORDERED_DENSE_LIKELY_ATTR [[likely]]     // NOLINT(cppcoreguidelines-macro-usage)\n#        define ANKERL_UNORDERED_DENSE_UNLIKELY_ATTR [[unlikely]] // NOLINT(cppcoreguidelines-macro-usage)\n#        define ANKERL_UNORDERED_DENSE_LIKELY(x) (x)              // NOLINT(cppcoreguidelines-macro-usage)\n#        define ANKERL_UNORDERED_DENSE_UNLIKELY(x) (x)            // NOLINT(cppcoreguidelines-macro-usage)\n#    else\n#        define ANKERL_UNORDERED_DENSE_LIKELY_ATTR   // NOLINT(cppcoreguidelines-macro-usage)\n#        define ANKERL_UNORDERED_DENSE_UNLIKELY_ATTR // NOLINT(cppcoreguidelines-macro-usage)\n\n#        if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__)\n#            define ANKERL_UNORDERED_DENSE_LIKELY(x) __builtin_expect(x, 1)   // NOLINT(cppcoreguidelines-macro-usage)\n#            define ANKERL_UNORDERED_DENSE_UNLIKELY(x) __builtin_expect(x, 0) // NOLINT(cppcoreguidelines-macro-usage)\n#        else\n#            define ANKERL_UNORDERED_DENSE_LIKELY(x) (x)   // NOLINT(cppcoreguidelines-macro-usage)\n#            define ANKERL_UNORDERED_DENSE_UNLIKELY(x) (x) // NOLINT(cppcoreguidelines-macro-usage)\n#        endif\n\n#    endif\n\nnamespace ankerl::unordered_dense {\ninline namespace ANKERL_UNORDERED_DENSE_NAMESPACE {\n\nnamespace detail {\n\n#    if ANKERL_UNORDERED_DENSE_HAS_EXCEPTIONS()\n\n// make sure this is not inlined as it is slow and dramatically enlarges code, thus making other\n// inlinings more difficult. Throws are also generally the slow path.\n[[noreturn]] inline ANKERL_UNORDERED_DENSE_NOINLINE void on_error_key_not_found() {\n    throw std::out_of_range(\"ankerl::unordered_dense::map::at(): key not found\");\n}\n[[noreturn]] inline ANKERL_UNORDERED_DENSE_NOINLINE void on_error_bucket_overflow() {\n    throw std::overflow_error(\"ankerl::unordered_dense: reached max bucket size, cannot increase size\");\n}\n[[noreturn]] inline ANKERL_UNORDERED_DENSE_NOINLINE void on_error_too_many_elements() {\n    throw std::out_of_range(\"ankerl::unordered_dense::map::replace(): too many elements\");\n}\n\n#    else\n\n[[noreturn]] inline void on_error_key_not_found() {\n    abort();\n}\n[[noreturn]] inline void on_error_bucket_overflow() {\n    abort();\n}\n[[noreturn]] inline void on_error_too_many_elements() {\n    abort();\n}\n\n#    endif\n\n} // namespace detail\n\n// hash ///////////////////////////////////////////////////////////////////////\n\n// This is a stripped-down implementation of wyhash: https://github.com/wangyi-fudan/wyhash\n// No big-endian support (because different values on different machines don't matter),\n// hardcodes seed and the secret, reformats the code, and clang-tidy fixes.\nnamespace detail::wyhash {\n\ninline void mum(std::uint64_t* a, std::uint64_t* b) {\n#    if defined(__SIZEOF_INT128__)\n    __uint128_t r = *a;\n    r *= *b;\n    *a = static_cast<std::uint64_t>(r);\n    *b = static_cast<std::uint64_t>(r >> 64U);\n#    elif defined(_MSC_VER) && defined(_M_X64)\n    *a = _umul128(*a, *b, b);\n#    else\n    std::uint64_t ha = *a >> 32U;\n    std::uint64_t hb = *b >> 32U;\n    std::uint64_t la = static_cast<std::uint32_t>(*a);\n    std::uint64_t lb = static_cast<std::uint32_t>(*b);\n    std::uint64_t hi{};\n    std::uint64_t lo{};\n    std::uint64_t rh = ha * hb;\n    std::uint64_t rm0 = ha * lb;\n    std::uint64_t rm1 = hb * la;\n    std::uint64_t rl = la * lb;\n    std::uint64_t t = rl + (rm0 << 32U);\n    auto c = static_cast<std::uint64_t>(t < rl);\n    lo = t + (rm1 << 32U);\n    c += static_cast<std::uint64_t>(lo < t);\n    hi = rh + (rm0 >> 32U) + (rm1 >> 32U) + c;\n    *a = lo;\n    *b = hi;\n#    endif\n}\n\n// multiply and xor mix function, aka MUM\n[[nodiscard]] inline auto mix(std::uint64_t a, std::uint64_t b) -> std::uint64_t {\n    mum(&a, &b);\n    return a ^ b;\n}\n\n// read functions. WARNING: we don't care about endianness, so results are different on big endian!\n[[nodiscard]] inline auto r8(const std::uint8_t* p) -> std::uint64_t {\n    std::uint64_t v{};\n    std::memcpy(&v, p, 8U);\n    return v;\n}\n\n[[nodiscard]] inline auto r4(const std::uint8_t* p) -> std::uint64_t {\n    std::uint32_t v{};\n    std::memcpy(&v, p, 4);\n    return v;\n}\n\n// reads 1, 2, or 3 bytes\n[[nodiscard]] inline auto r3(const std::uint8_t* p, std::size_t k) -> std::uint64_t {\n    return (static_cast<std::uint64_t>(p[0]) << 16U) | (static_cast<std::uint64_t>(p[k >> 1U]) << 8U) | p[k - 1];\n}\n\n[[maybe_unused]] [[nodiscard]] inline auto hash(void const* key, std::size_t len) -> std::uint64_t {\n    static constexpr auto secret = std::array{UINT64_C(0xa0761d6478bd642f),\n                                              UINT64_C(0xe7037ed1a0b428db),\n                                              UINT64_C(0x8ebc6af09c88c6e3),\n                                              UINT64_C(0x589965cc75374cc3)};\n\n    auto const* p = static_cast<std::uint8_t const*>(key);\n    std::uint64_t seed = secret[0];\n    std::uint64_t a{};\n    std::uint64_t b{};\n    if (ANKERL_UNORDERED_DENSE_LIKELY(len <= 16))\n        ANKERL_UNORDERED_DENSE_LIKELY_ATTR {\n            if (ANKERL_UNORDERED_DENSE_LIKELY(len >= 4))\n                ANKERL_UNORDERED_DENSE_LIKELY_ATTR {\n                    a = (r4(p) << 32U) | r4(p + ((len >> 3U) << 2U));\n                    b = (r4(p + len - 4) << 32U) | r4(p + len - 4 - ((len >> 3U) << 2U));\n                }\n            else if (ANKERL_UNORDERED_DENSE_LIKELY(len > 0))\n                ANKERL_UNORDERED_DENSE_LIKELY_ATTR {\n                    a = r3(p, len);\n                    b = 0;\n                }\n            else {\n                a = 0;\n                b = 0;\n            }\n        }\n    else {\n        std::size_t i = len;\n        if (ANKERL_UNORDERED_DENSE_UNLIKELY(i > 48))\n            ANKERL_UNORDERED_DENSE_UNLIKELY_ATTR {\n                std::uint64_t see1 = seed;\n                std::uint64_t see2 = seed;\n                do {\n                    seed = mix(r8(p) ^ secret[1], r8(p + 8) ^ seed);\n                    see1 = mix(r8(p + 16) ^ secret[2], r8(p + 24) ^ see1);\n                    see2 = mix(r8(p + 32) ^ secret[3], r8(p + 40) ^ see2);\n                    p += 48;\n                    i -= 48;\n                } while (ANKERL_UNORDERED_DENSE_LIKELY(i > 48));\n                seed ^= see1 ^ see2;\n            }\n        while (ANKERL_UNORDERED_DENSE_UNLIKELY(i > 16))\n            ANKERL_UNORDERED_DENSE_UNLIKELY_ATTR {\n                seed = mix(r8(p) ^ secret[1], r8(p + 8) ^ seed);\n                i -= 16;\n                p += 16;\n            }\n        a = r8(p + i - 16);\n        b = r8(p + i - 8);\n    }\n\n    return mix(secret[1] ^ len, mix(a ^ secret[1], b ^ seed));\n}\n\n[[nodiscard]] inline auto hash(std::uint64_t x) -> std::uint64_t {\n    return detail::wyhash::mix(x, UINT64_C(0x9E3779B97F4A7C15));\n}\n\n} // namespace detail::wyhash\n\ntemplate <typename T, typename Enable = void>\nstruct hash {\n    auto operator()(T const& obj) const noexcept(noexcept(std::declval<std::hash<T>>().operator()(std::declval<T const&>())))\n        -> std::uint64_t {\n        return std::hash<T>{}(obj);\n    }\n};\n\ntemplate <typename T>\nstruct hash<T, typename std::hash<T>::is_avalanching> {\n    using is_avalanching = void;\n    auto operator()(T const& obj) const noexcept(noexcept(std::declval<std::hash<T>>().operator()(std::declval<T const&>())))\n        -> std::uint64_t {\n        return std::hash<T>{}(obj);\n    }\n};\n\ntemplate <typename CharT>\nstruct hash<std::basic_string<CharT>> {\n    using is_avalanching = void;\n    auto operator()(std::basic_string<CharT> const& str) const noexcept -> std::uint64_t {\n        return detail::wyhash::hash(str.data(), sizeof(CharT) * str.size());\n    }\n};\n\ntemplate <typename CharT>\nstruct hash<std::basic_string_view<CharT>> {\n    using is_avalanching = void;\n    auto operator()(std::basic_string_view<CharT> const& sv) const noexcept -> std::uint64_t {\n        return detail::wyhash::hash(sv.data(), sizeof(CharT) * sv.size());\n    }\n};\n\ntemplate <class T>\nstruct hash<T*> {\n    using is_avalanching = void;\n    auto operator()(T* ptr) const noexcept -> std::uint64_t {\n        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)\n        return detail::wyhash::hash(reinterpret_cast<std::uintptr_t>(ptr));\n    }\n};\n\ntemplate <class T>\nstruct hash<std::unique_ptr<T>> {\n    using is_avalanching = void;\n    auto operator()(std::unique_ptr<T> const& ptr) const noexcept -> std::uint64_t {\n        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)\n        return detail::wyhash::hash(reinterpret_cast<std::uintptr_t>(ptr.get()));\n    }\n};\n\ntemplate <class T>\nstruct hash<std::shared_ptr<T>> {\n    using is_avalanching = void;\n    auto operator()(std::shared_ptr<T> const& ptr) const noexcept -> std::uint64_t {\n        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)\n        return detail::wyhash::hash(reinterpret_cast<std::uintptr_t>(ptr.get()));\n    }\n};\n\ntemplate <typename Enum>\nstruct hash<Enum, typename std::enable_if_t<std::is_enum_v<Enum>>> {\n    using is_avalanching = void;\n    auto operator()(Enum e) const noexcept -> std::uint64_t {\n        using underlying = std::underlying_type_t<Enum>;\n        return detail::wyhash::hash(static_cast<underlying>(e));\n    }\n};\n\ntemplate <typename... Args>\nstruct tuple_hash_helper {\n    // Converts the value into 64bit. If it is an integral type, just cast it. Mixing is doing the rest.\n    // If it isn't an integral we need to hash it.\n    template <typename Arg>\n    [[nodiscard]] constexpr static auto to64(Arg const& arg) -> std::uint64_t {\n        if constexpr (std::is_integral_v<Arg> || std::is_enum_v<Arg>) {\n            return static_cast<std::uint64_t>(arg);\n        } else {\n            return hash<Arg>{}(arg);\n        }\n    }\n\n    [[nodiscard]] ANKERL_UNORDERED_DENSE_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK static auto mix64(std::uint64_t state,\n                                                                                                std::uint64_t v)\n        -> std::uint64_t {\n        return detail::wyhash::mix(state + v, std::uint64_t{0x9ddfea08eb382d69});\n    }\n\n    // Creates a buffer that holds all the data from each element of the tuple. If possible we memcpy the data directly. If\n    // not, we hash the object and use this for the array. Size of the array is known at compile time, and memcpy is optimized\n    // away, so filling the buffer is highly efficient. Finally, call wyhash with this buffer.\n    template <typename T, std::size_t... Idx>\n    [[nodiscard]] static auto calc_hash(T const& t, std::index_sequence<Idx...> /*unused*/) noexcept -> std::uint64_t {\n        auto h = std::uint64_t{};\n        ((h = mix64(h, to64(std::get<Idx>(t)))), ...);\n        return h;\n    }\n};\n\ntemplate <typename... Args>\nstruct hash<std::tuple<Args...>> : tuple_hash_helper<Args...> {\n    using is_avalanching = void;\n    auto operator()(std::tuple<Args...> const& t) const noexcept -> std::uint64_t {\n        return tuple_hash_helper<Args...>::calc_hash(t, std::index_sequence_for<Args...>{});\n    }\n};\n\ntemplate <typename A, typename B>\nstruct hash<std::pair<A, B>> : tuple_hash_helper<A, B> {\n    using is_avalanching = void;\n    auto operator()(std::pair<A, B> const& t) const noexcept -> std::uint64_t {\n        return tuple_hash_helper<A, B>::calc_hash(t, std::index_sequence_for<A, B>{});\n    }\n};\n\n// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)\n#    define ANKERL_UNORDERED_DENSE_HASH_STATICCAST(T)                         \\\n        template <>                                                           \\\n        struct hash<T> {                                                      \\\n            using is_avalanching = void;                                      \\\n            auto operator()(T const& obj) const noexcept -> std::uint64_t {   \\\n                return detail::wyhash::hash(static_cast<std::uint64_t>(obj)); \\\n            }                                                                 \\\n        }\n\n#    if defined(__GNUC__) && !defined(__clang__)\n#        pragma GCC diagnostic push\n#        pragma GCC diagnostic ignored \"-Wuseless-cast\"\n#    endif\n// see https://en.cppreference.com/w/cpp/utility/hash\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(bool);\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(char);\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(signed char);\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(unsigned char);\n#    if ANKERL_UNORDERED_DENSE_CPP_VERSION >= 202002L && defined(__cpp_char8_t)\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(char8_t);\n#    endif\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(char16_t);\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(char32_t);\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(wchar_t);\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(short);\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(unsigned short);\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(int);\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(unsigned int);\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(long);\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(long long);\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(unsigned long);\nANKERL_UNORDERED_DENSE_HASH_STATICCAST(unsigned long long);\n\n#    if defined(__GNUC__) && !defined(__clang__)\n#        pragma GCC diagnostic pop\n#    endif\n\n// bucket_type //////////////////////////////////////////////////////////\n\nnamespace bucket_type {\n\nstruct standard {\n    static constexpr std::uint32_t dist_inc = 1U << 8U;             // skip 1 byte fingerprint\n    static constexpr std::uint32_t fingerprint_mask = dist_inc - 1; // mask for 1 byte of fingerprint\n\n    std::uint32_t m_dist_and_fingerprint; // upper 3 byte: distance to original bucket. lower byte: fingerprint from hash\n    std::uint32_t m_value_idx;            // index into the m_values vector.\n};\n\nANKERL_UNORDERED_DENSE_PACK(struct big {\n    static constexpr std::uint32_t dist_inc = 1U << 8U;             // skip 1 byte fingerprint\n    static constexpr std::uint32_t fingerprint_mask = dist_inc - 1; // mask for 1 byte of fingerprint\n\n    std::uint32_t m_dist_and_fingerprint; // upper 3 byte: distance to original bucket. lower byte: fingerprint from hash\n    std::size_t m_value_idx;              // index into the m_values vector.\n});\n\n} // namespace bucket_type\n\nnamespace detail {\n\nstruct nonesuch {};\nstruct default_container_t {};\n\ntemplate <class Default, class AlwaysVoid, template <class...> class Op, class... Args>\nstruct detector {\n    using value_t = std::false_type;\n    using type = Default;\n};\n\ntemplate <class Default, template <class...> class Op, class... Args>\nstruct detector<Default, std::void_t<Op<Args...>>, Op, Args...> {\n    using value_t = std::true_type;\n    using type = Op<Args...>;\n};\n\ntemplate <template <class...> class Op, class... Args>\nusing is_detected = typename detail::detector<detail::nonesuch, void, Op, Args...>::value_t;\n\ntemplate <template <class...> class Op, class... Args>\nconstexpr bool is_detected_v = is_detected<Op, Args...>::value;\n\ntemplate <typename T>\nusing detect_avalanching = typename T::is_avalanching;\n\ntemplate <typename T>\nusing detect_is_transparent = typename T::is_transparent;\n\ntemplate <typename T>\nusing detect_iterator = typename T::iterator;\n\ntemplate <typename T>\nusing detect_reserve = decltype(std::declval<T&>().reserve(std::size_t{}));\n\n// enable_if helpers\n\ntemplate <typename Mapped>\nconstexpr bool is_map_v = !std::is_void_v<Mapped>;\n\n// clang-format off\ntemplate <typename Hash, typename KeyEqual>\nconstexpr bool is_transparent_v = is_detected_v<detect_is_transparent, Hash> && is_detected_v<detect_is_transparent, KeyEqual>;\n// clang-format on\n\ntemplate <typename From, typename To1, typename To2>\nconstexpr bool is_neither_convertible_v = !std::is_convertible_v<From, To1> && !std::is_convertible_v<From, To2>;\n\ntemplate <typename T>\nconstexpr bool has_reserve = is_detected_v<detect_reserve, T>;\n\n// base type for map has mapped_type\ntemplate <class T>\nstruct base_table_type_map {\n    using mapped_type = T;\n};\n\n// base type for set doesn't have mapped_type\nstruct base_table_type_set {};\n\n} // namespace detail\n\n// Very much like std::deque, but faster for indexing (in most cases). As of now this doesn't implement the full std::vector\n// API, but merely what's necessary to work as an underlying container for ankerl::unordered_dense::{map, set}.\n// It allocates blocks of equal size and puts them into the m_blocks vector. That means it can grow simply by adding a new\n// block to the back of m_blocks, and doesn't double its size like an std::vector. The disadvantage is that memory is not\n// linear and thus there is one more indirection necessary for indexing.\ntemplate <typename T, typename Allocator = std::allocator<T>, std::size_t MaxSegmentSizeBytes = 4096>\nclass segmented_vector {\n    template <bool IsConst>\n    class iter_t;\n\npublic:\n    using allocator_type = Allocator;\n    using pointer = typename std::allocator_traits<allocator_type>::pointer;\n    using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;\n    using difference_type = typename std::allocator_traits<allocator_type>::difference_type;\n    using value_type = T;\n    using size_type = std::size_t;\n    using reference = T&;\n    using const_reference = T const&;\n    using iterator = iter_t<false>;\n    using const_iterator = iter_t<true>;\n\nprivate:\n    using vec_alloc = typename std::allocator_traits<Allocator>::template rebind_alloc<pointer>;\n    std::vector<pointer, vec_alloc> m_blocks{};\n    std::size_t m_size{};\n\n    // Calculates the maximum number for x in  (s << x) <= max_val\n    static constexpr auto num_bits_closest(std::size_t max_val, std::size_t s) -> std::size_t {\n        auto f = std::size_t{0};\n        while (s << (f + 1) <= max_val) {\n            ++f;\n        }\n        return f;\n    }\n\n    using self_t = segmented_vector<T, Allocator, MaxSegmentSizeBytes>;\n    static constexpr auto num_bits = num_bits_closest(MaxSegmentSizeBytes, sizeof(T));\n    static constexpr auto num_elements_in_block = 1U << num_bits;\n    static constexpr auto mask = num_elements_in_block - 1U;\n\n    /**\n     * Iterator class doubles as const_iterator and iterator\n     */\n    template <bool IsConst>\n    class iter_t {\n        using ptr_t = std::conditional_t<IsConst, segmented_vector::const_pointer const*, segmented_vector::pointer*>;\n        ptr_t m_data{};\n        std::size_t m_idx{};\n\n        template <bool B>\n        friend class iter_t;\n\n    public:\n        using difference_type = segmented_vector::difference_type;\n        using value_type = segmented_vector::value_type;\n        using reference = std::conditional_t<IsConst, value_type const&, value_type&>;\n        using pointer = std::conditional_t<IsConst, segmented_vector::const_pointer, segmented_vector::pointer>;\n        using iterator_category = std::forward_iterator_tag;\n\n        iter_t() noexcept = default;\n\n        template <bool OtherIsConst, typename = std::enable_if_t<IsConst && !OtherIsConst>>\n        // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)\n        constexpr iter_t(iter_t<OtherIsConst> const& other) noexcept\n            : m_data(other.m_data)\n            , m_idx(other.m_idx) {}\n\n        constexpr iter_t(ptr_t data, std::size_t idx) noexcept\n            : m_data(data)\n            , m_idx(idx) {}\n\n        template <bool OtherIsConst, typename = std::enable_if_t<IsConst && !OtherIsConst>>\n        constexpr auto operator=(iter_t<OtherIsConst> const& other) noexcept -> iter_t& {\n            m_data = other.m_data;\n            m_idx = other.m_idx;\n            return *this;\n        }\n\n        constexpr auto operator++() noexcept -> iter_t& {\n            ++m_idx;\n            return *this;\n        }\n\n        constexpr auto operator++(int) noexcept -> iter_t {\n            iter_t prev(*this);\n            this->operator++();\n            return prev;\n        }\n\n        constexpr auto operator--() noexcept -> iter_t& {\n            --m_idx;\n            return *this;\n        }\n\n        constexpr auto operator--(int) noexcept -> iter_t {\n            iter_t prev(*this);\n            this->operator--();\n            return prev;\n        }\n\n        [[nodiscard]] constexpr auto operator+(difference_type diff) const noexcept -> iter_t {\n            return {m_data, static_cast<std::size_t>(static_cast<difference_type>(m_idx) + diff)};\n        }\n\n        constexpr auto operator+=(difference_type diff) noexcept -> iter_t& {\n            m_idx += diff;\n            return *this;\n        }\n\n        [[nodiscard]] constexpr auto operator-(difference_type diff) const noexcept -> iter_t {\n            return {m_data, static_cast<std::size_t>(static_cast<difference_type>(m_idx) - diff)};\n        }\n\n        constexpr auto operator-=(difference_type diff) noexcept -> iter_t& {\n            m_idx -= diff;\n            return *this;\n        }\n\n        template <bool OtherIsConst>\n        [[nodiscard]] constexpr auto operator-(iter_t<OtherIsConst> const& other) const noexcept -> difference_type {\n            return static_cast<difference_type>(m_idx) - static_cast<difference_type>(other.m_idx);\n        }\n\n        constexpr auto operator*() const noexcept -> reference {\n            return m_data[m_idx >> num_bits][m_idx & mask];\n        }\n\n        constexpr auto operator->() const noexcept -> pointer {\n            return &m_data[m_idx >> num_bits][m_idx & mask];\n        }\n\n        template <bool O>\n        [[nodiscard]] constexpr auto operator==(iter_t<O> const& o) const noexcept -> bool {\n            return m_idx == o.m_idx;\n        }\n\n        template <bool O>\n        [[nodiscard]] constexpr auto operator!=(iter_t<O> const& o) const noexcept -> bool {\n            return !(*this == o);\n        }\n\n        template <bool O>\n        [[nodiscard]] constexpr auto operator<(iter_t<O> const& o) const noexcept -> bool {\n            return m_idx < o.m_idx;\n        }\n\n        template <bool O>\n        [[nodiscard]] constexpr auto operator>(iter_t<O> const& o) const noexcept -> bool {\n            return o < *this;\n        }\n\n        template <bool O>\n        [[nodiscard]] constexpr auto operator<=(iter_t<O> const& o) const noexcept -> bool {\n            return !(o < *this);\n        }\n\n        template <bool O>\n        [[nodiscard]] constexpr auto operator>=(iter_t<O> const& o) const noexcept -> bool {\n            return !(*this < o);\n        }\n    };\n\n    // slow path: need to allocate a new segment every once in a while\n    void increase_capacity() {\n        auto ba = Allocator(m_blocks.get_allocator());\n        pointer block = std::allocator_traits<Allocator>::allocate(ba, num_elements_in_block);\n        m_blocks.push_back(block);\n    }\n\n    // Moves everything from other\n    void append_everything_from(segmented_vector&& other) { // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)\n        reserve(size() + other.size());\n        for (auto&& o : other) {\n            emplace_back(std::move(o));\n        }\n    }\n\n    // Copies everything from other\n    void append_everything_from(segmented_vector const& other) {\n        reserve(size() + other.size());\n        for (auto const& o : other) {\n            emplace_back(o);\n        }\n    }\n\n    void dealloc() {\n        auto ba = Allocator(m_blocks.get_allocator());\n        for (auto ptr : m_blocks) {\n            std::allocator_traits<Allocator>::deallocate(ba, ptr, num_elements_in_block);\n        }\n    }\n\n    [[nodiscard]] static constexpr auto calc_num_blocks_for_capacity(std::size_t capacity) {\n        return (capacity + num_elements_in_block - 1U) / num_elements_in_block;\n    }\n\n    void resize_shrink(std::size_t new_size) {\n        if constexpr (!std::is_trivially_destructible_v<T>) {\n            for (std::size_t ix = new_size; ix < m_size; ++ix) {\n                operator[](ix).~T();\n            }\n        }\n        m_size = new_size;\n    }\n\npublic:\n    segmented_vector() = default;\n\n    // NOLINTNEXTLINE(google-explicit-constructor,hicpp-explicit-conversions)\n    segmented_vector(Allocator alloc)\n        : m_blocks(vec_alloc(alloc)) {}\n\n    segmented_vector(segmented_vector&& other, Allocator alloc)\n        : segmented_vector(alloc) {\n        *this = std::move(other);\n    }\n\n    segmented_vector(segmented_vector const& other, Allocator alloc)\n        : m_blocks(vec_alloc(alloc)) {\n        append_everything_from(other);\n    }\n\n    segmented_vector(segmented_vector&& other) noexcept\n        : segmented_vector(std::move(other), other.get_allocator()) {}\n\n    segmented_vector(segmented_vector const& other) {\n        append_everything_from(other);\n    }\n\n    auto operator=(segmented_vector const& other) -> segmented_vector& {\n        if (this == &other) {\n            return *this;\n        }\n        clear();\n        append_everything_from(other);\n        return *this;\n    }\n\n    auto operator=(segmented_vector&& other) noexcept -> segmented_vector& {\n        clear();\n        dealloc();\n        if (other.get_allocator() == get_allocator()) {\n            m_blocks = std::move(other.m_blocks);\n            m_size = std::exchange(other.m_size, {});\n        } else {\n            // make sure to construct with other's allocator!\n            m_blocks = std::vector<pointer, vec_alloc>(vec_alloc(other.get_allocator()));\n            append_everything_from(std::move(other));\n        }\n        return *this;\n    }\n\n    ~segmented_vector() {\n        clear();\n        dealloc();\n    }\n\n    [[nodiscard]] constexpr auto size() const -> std::size_t {\n        return m_size;\n    }\n\n    [[nodiscard]] constexpr auto capacity() const -> std::size_t {\n        return m_blocks.size() * num_elements_in_block;\n    }\n\n    // Indexing is highly performance critical\n    [[nodiscard]] constexpr auto operator[](std::size_t i) const noexcept -> T const& {\n        return m_blocks[i >> num_bits][i & mask];\n    }\n\n    [[nodiscard]] constexpr auto operator[](std::size_t i) noexcept -> T& {\n        return m_blocks[i >> num_bits][i & mask];\n    }\n\n    [[nodiscard]] constexpr auto begin() -> iterator {\n        return {m_blocks.data(), 0U};\n    }\n    [[nodiscard]] constexpr auto begin() const -> const_iterator {\n        return {m_blocks.data(), 0U};\n    }\n    [[nodiscard]] constexpr auto cbegin() const -> const_iterator {\n        return {m_blocks.data(), 0U};\n    }\n\n    [[nodiscard]] constexpr auto end() -> iterator {\n        return {m_blocks.data(), m_size};\n    }\n    [[nodiscard]] constexpr auto end() const -> const_iterator {\n        return {m_blocks.data(), m_size};\n    }\n    [[nodiscard]] constexpr auto cend() const -> const_iterator {\n        return {m_blocks.data(), m_size};\n    }\n\n    [[nodiscard]] constexpr auto back() -> reference {\n        return operator[](m_size - 1);\n    }\n    [[nodiscard]] constexpr auto back() const -> const_reference {\n        return operator[](m_size - 1);\n    }\n\n    void pop_back() {\n        back().~T();\n        --m_size;\n    }\n\n    [[nodiscard]] auto empty() const {\n        return 0 == m_size;\n    }\n\n    void reserve(std::size_t new_capacity) {\n        m_blocks.reserve(calc_num_blocks_for_capacity(new_capacity));\n        while (new_capacity > capacity()) {\n            increase_capacity();\n        }\n    }\n\n    void resize(std::size_t const count) {\n        if (count < m_size) {\n            resize_shrink(count);\n        } else if (count > m_size) {\n            std::size_t const new_elems = count - m_size;\n            reserve(count);\n            for (std::size_t ix = 0; ix < new_elems; ++ix) {\n                emplace_back();\n            }\n        }\n    }\n\n    void resize(std::size_t const count, value_type const& value) {\n        if (count < m_size) {\n            resize_shrink(count);\n        } else if (count > m_size) {\n            std::size_t const new_elems = count - m_size;\n            reserve(count);\n            for (std::size_t ix = 0; ix < new_elems; ++ix) {\n                emplace_back(value);\n            }\n        }\n    }\n\n    [[nodiscard]] auto get_allocator() const -> allocator_type {\n        return allocator_type{m_blocks.get_allocator()};\n    }\n\n    template <class... Args>\n    auto emplace_back(Args&&... args) -> reference {\n        if (m_size == capacity()) {\n            increase_capacity();\n        }\n        auto* ptr = static_cast<void*>(&operator[](m_size));\n        auto& ref = *new (ptr) T(std::forward<Args>(args)...);\n        ++m_size;\n        return ref;\n    }\n\n    void clear() {\n        if constexpr (!std::is_trivially_destructible_v<T>) {\n            for (std::size_t i = 0, s = size(); i < s; ++i) {\n                operator[](i).~T();\n            }\n        }\n        m_size = 0;\n    }\n\n    void shrink_to_fit() {\n        auto ba = Allocator(m_blocks.get_allocator());\n        auto num_blocks_required = calc_num_blocks_for_capacity(m_size);\n        while (m_blocks.size() > num_blocks_required) {\n            std::allocator_traits<Allocator>::deallocate(ba, m_blocks.back(), num_elements_in_block);\n            m_blocks.pop_back();\n        }\n        m_blocks.shrink_to_fit();\n    }\n};\n\nnamespace detail {\n\n// This is it, the table. Doubles as map and set, and uses `void` for T when its used as a set.\ntemplate <class Key,\n          class T, // when void, treat it as a set.\n          class Hash,\n          class KeyEqual,\n          class AllocatorOrContainer,\n          class Bucket,\n          class BucketContainer,\n          bool IsSegmented>\nclass table : public std::conditional_t<is_map_v<T>, base_table_type_map<T>, base_table_type_set> {\n    using underlying_value_type = std::conditional_t<is_map_v<T>, std::pair<Key, T>, Key>;\n    using underlying_container_type = std::conditional_t<IsSegmented,\n                                                         segmented_vector<underlying_value_type, AllocatorOrContainer>,\n                                                         std::vector<underlying_value_type, AllocatorOrContainer>>;\n\npublic:\n    using value_container_type = std::\n        conditional_t<is_detected_v<detect_iterator, AllocatorOrContainer>, AllocatorOrContainer, underlying_container_type>;\n\nprivate:\n    using bucket_alloc =\n        typename std::allocator_traits<typename value_container_type::allocator_type>::template rebind_alloc<Bucket>;\n    using default_bucket_container_type =\n        std::conditional_t<IsSegmented, segmented_vector<Bucket, bucket_alloc>, std::vector<Bucket, bucket_alloc>>;\n\n    using bucket_container_type = std::conditional_t<std::is_same_v<BucketContainer, detail::default_container_t>,\n                                                     default_bucket_container_type,\n                                                     BucketContainer>;\n\n    static constexpr std::uint8_t initial_shifts = 64 - 2; // 2^(64-m_shift) number of buckets\n    static constexpr float default_max_load_factor = 0.8F;\n\npublic:\n    using key_type = Key;\n    using value_type = typename value_container_type::value_type;\n    using size_type = typename value_container_type::size_type;\n    using difference_type = typename value_container_type::difference_type;\n    using hasher = Hash;\n    using key_equal = KeyEqual;\n    using allocator_type = typename value_container_type::allocator_type;\n    using reference = typename value_container_type::reference;\n    using const_reference = typename value_container_type::const_reference;\n    using pointer = typename value_container_type::pointer;\n    using const_pointer = typename value_container_type::const_pointer;\n    using const_iterator = typename value_container_type::const_iterator;\n    using iterator = std::conditional_t<is_map_v<T>, typename value_container_type::iterator, const_iterator>;\n    using bucket_type = Bucket;\n\nprivate:\n    using value_idx_type = decltype(Bucket::m_value_idx);\n    using dist_and_fingerprint_type = decltype(Bucket::m_dist_and_fingerprint);\n\n    static_assert(std::is_trivially_destructible_v<Bucket>, \"assert there's no need to call destructor / std::destroy\");\n    static_assert(std::is_trivially_copyable_v<Bucket>, \"assert we can just memset / memcpy\");\n\n    value_container_type m_values{}; // Contains all the key-value pairs in one densely stored container. No holes.\n    bucket_container_type m_buckets{};\n    std::size_t m_max_bucket_capacity = 0;\n    float m_max_load_factor = default_max_load_factor;\n    Hash m_hash{};\n    KeyEqual m_equal{};\n    std::uint8_t m_shifts = initial_shifts;\n\n    [[nodiscard]] auto next(value_idx_type bucket_idx) const -> value_idx_type {\n        if (ANKERL_UNORDERED_DENSE_UNLIKELY(bucket_idx + 1U == bucket_count()))\n            ANKERL_UNORDERED_DENSE_UNLIKELY_ATTR {\n                return 0;\n            }\n\n        return static_cast<value_idx_type>(bucket_idx + 1U);\n    }\n\n    // Helper to access bucket through pointer types\n    [[nodiscard]] static constexpr auto at(bucket_container_type& bucket, std::size_t offset) -> Bucket& {\n        return bucket[offset];\n    }\n\n    [[nodiscard]] static constexpr auto at(const bucket_container_type& bucket, std::size_t offset) -> const Bucket& {\n        return bucket[offset];\n    }\n\n    // use the dist_inc and dist_dec functions so that std::uint16_t types work without warning\n    [[nodiscard]] static constexpr auto dist_inc(dist_and_fingerprint_type x) -> dist_and_fingerprint_type {\n        return static_cast<dist_and_fingerprint_type>(x + Bucket::dist_inc);\n    }\n\n    [[nodiscard]] static constexpr auto dist_dec(dist_and_fingerprint_type x) -> dist_and_fingerprint_type {\n        return static_cast<dist_and_fingerprint_type>(x - Bucket::dist_inc);\n    }\n\n    // The goal of mixed_hash is to always produce a high quality 64bit hash.\n    template <typename K>\n    [[nodiscard]] constexpr auto mixed_hash(K const& key) const -> std::uint64_t {\n        if constexpr (is_detected_v<detect_avalanching, Hash>) {\n            // we know that the hash is good because is_avalanching.\n            if constexpr (sizeof(decltype(m_hash(key))) < sizeof(std::uint64_t)) {\n                // 32bit hash and is_avalanching => multiply with a constant to avalanche bits upwards\n                return m_hash(key) * UINT64_C(0x9ddfea08eb382d69);\n            } else {\n                // 64bit and is_avalanching => only use the hash itself.\n                return m_hash(key);\n            }\n        } else {\n            // not is_avalanching => apply wyhash\n            return wyhash::hash(m_hash(key));\n        }\n    }\n\n    [[nodiscard]] constexpr auto dist_and_fingerprint_from_hash(std::uint64_t hash) const -> dist_and_fingerprint_type {\n        return Bucket::dist_inc | (static_cast<dist_and_fingerprint_type>(hash) & Bucket::fingerprint_mask);\n    }\n\n    [[nodiscard]] constexpr auto bucket_idx_from_hash(std::uint64_t hash) const -> value_idx_type {\n        return static_cast<value_idx_type>(hash >> m_shifts);\n    }\n\n    [[nodiscard]] static constexpr auto get_key(value_type const& vt) -> key_type const& {\n        if constexpr (is_map_v<T>) {\n            return vt.first;\n        } else {\n            return vt;\n        }\n    }\n\n    template <typename K>\n    [[nodiscard]] auto next_while_less(K const& key) const -> Bucket {\n        auto hash = mixed_hash(key);\n        auto dist_and_fingerprint = dist_and_fingerprint_from_hash(hash);\n        auto bucket_idx = bucket_idx_from_hash(hash);\n\n        while (dist_and_fingerprint < at(m_buckets, bucket_idx).m_dist_and_fingerprint) {\n            dist_and_fingerprint = dist_inc(dist_and_fingerprint);\n            bucket_idx = next(bucket_idx);\n        }\n        return {dist_and_fingerprint, bucket_idx};\n    }\n\n    void place_and_shift_up(Bucket bucket, value_idx_type place) {\n        while (0 != at(m_buckets, place).m_dist_and_fingerprint) {\n            bucket = std::exchange(at(m_buckets, place), bucket);\n            bucket.m_dist_and_fingerprint = dist_inc(bucket.m_dist_and_fingerprint);\n            place = next(place);\n        }\n        at(m_buckets, place) = bucket;\n    }\n\n    void erase_and_shift_down(value_idx_type bucket_idx) {\n        // shift down until either empty or an element with correct spot is found\n        auto next_bucket_idx = next(bucket_idx);\n        while (at(m_buckets, next_bucket_idx).m_dist_and_fingerprint >= Bucket::dist_inc * 2) {\n            auto& next_bucket = at(m_buckets, next_bucket_idx);\n            at(m_buckets, bucket_idx) = {dist_dec(next_bucket.m_dist_and_fingerprint), next_bucket.m_value_idx};\n            bucket_idx = std::exchange(next_bucket_idx, next(next_bucket_idx));\n        }\n        at(m_buckets, bucket_idx) = {};\n    }\n\n    [[nodiscard]] static constexpr auto calc_num_buckets(std::uint8_t shifts) -> std::size_t {\n        return (std::min)(max_bucket_count(), std::size_t{1} << (64U - shifts));\n    }\n\n    [[nodiscard]] constexpr auto calc_shifts_for_size(std::size_t s) const -> std::uint8_t {\n        auto shifts = initial_shifts;\n        while (shifts > 0 && static_cast<std::size_t>(static_cast<float>(calc_num_buckets(shifts)) * max_load_factor()) < s) {\n            --shifts;\n        }\n        return shifts;\n    }\n\n    // assumes m_values has data, m_buckets=m_buckets_end=nullptr, m_shifts is INITIAL_SHIFTS\n    void copy_buckets(table const& other) {\n        // assumes m_values has already the correct data copied over.\n        if (empty()) {\n            // when empty, at least allocate an initial buckets and clear them.\n            allocate_buckets_from_shift();\n            clear_buckets();\n        } else {\n            m_shifts = other.m_shifts;\n            allocate_buckets_from_shift();\n            if constexpr (IsSegmented || !std::is_same_v<BucketContainer, default_container_t>) {\n                for (auto i = 0UL; i < bucket_count(); ++i) {\n                    at(m_buckets, i) = at(other.m_buckets, i);\n                }\n            } else {\n                std::memcpy(m_buckets.data(), other.m_buckets.data(), sizeof(Bucket) * bucket_count());\n            }\n        }\n    }\n\n    /**\n     * True when no element can be added any more without increasing the size\n     */\n    [[nodiscard]] auto is_full() const -> bool {\n        return size() > m_max_bucket_capacity;\n    }\n\n    void deallocate_buckets() {\n        m_buckets.clear();\n        m_buckets.shrink_to_fit();\n        m_max_bucket_capacity = 0;\n    }\n\n    void allocate_buckets_from_shift() {\n        auto num_buckets = calc_num_buckets(m_shifts);\n        if constexpr (IsSegmented || !std::is_same_v<BucketContainer, default_container_t>) {\n            if constexpr (has_reserve<bucket_container_type>) {\n                m_buckets.reserve(num_buckets);\n            }\n            for (std::size_t i = m_buckets.size(); i < num_buckets; ++i) {\n                m_buckets.emplace_back();\n            }\n        } else {\n            m_buckets.resize(num_buckets);\n        }\n        if (num_buckets == max_bucket_count()) {\n            // reached the maximum, make sure we can use each bucket\n            m_max_bucket_capacity = max_bucket_count();\n        } else {\n            m_max_bucket_capacity = static_cast<value_idx_type>(static_cast<float>(num_buckets) * max_load_factor());\n        }\n    }\n\n    void clear_buckets() {\n        if constexpr (IsSegmented || !std::is_same_v<BucketContainer, default_container_t>) {\n            for (auto&& e : m_buckets) {\n                std::memset(&e, 0, sizeof(e));\n            }\n        } else {\n            std::memset(m_buckets.data(), 0, sizeof(Bucket) * bucket_count());\n        }\n    }\n\n    void clear_and_fill_buckets_from_values() {\n        clear_buckets();\n        for (value_idx_type value_idx = 0, end_idx = static_cast<value_idx_type>(m_values.size()); value_idx < end_idx;\n             ++value_idx) {\n            auto const& key = get_key(m_values[value_idx]);\n            auto [dist_and_fingerprint, bucket] = next_while_less(key);\n\n            // we know for certain that key has not yet been inserted, so no need to check it.\n            place_and_shift_up({dist_and_fingerprint, value_idx}, bucket);\n        }\n    }\n\n    void increase_size() {\n        if (m_max_bucket_capacity == max_bucket_count()) {\n            // remove the value again, we can't add it!\n            m_values.pop_back();\n            on_error_bucket_overflow();\n        }\n        --m_shifts;\n        if constexpr (!IsSegmented || std::is_same_v<BucketContainer, default_container_t>) {\n            deallocate_buckets();\n        }\n        allocate_buckets_from_shift();\n        clear_and_fill_buckets_from_values();\n    }\n\n    template <typename Op>\n    void do_erase(value_idx_type bucket_idx, Op handle_erased_value) {\n        auto const value_idx_to_remove = at(m_buckets, bucket_idx).m_value_idx;\n        erase_and_shift_down(bucket_idx);\n        handle_erased_value(std::move(m_values[value_idx_to_remove]));\n\n        // update m_values\n        if (value_idx_to_remove != m_values.size() - 1) {\n            // no luck, we'll have to replace the value with the last one and update the index accordingly\n            auto& val = m_values[value_idx_to_remove];\n            val = std::move(m_values.back());\n\n            // update the values_idx of the moved entry. No need to play the info game, just look until we find the values_idx\n            bucket_idx = bucket_idx_from_hash(mixed_hash(get_key(val)));\n            auto const values_idx_back = static_cast<value_idx_type>(m_values.size() - 1);\n            while (values_idx_back != at(m_buckets, bucket_idx).m_value_idx) {\n                bucket_idx = next(bucket_idx);\n            }\n            at(m_buckets, bucket_idx).m_value_idx = value_idx_to_remove;\n        }\n        m_values.pop_back();\n    }\n\n    template <typename K, typename Op>\n    auto do_erase_key(K&& key, Op handle_erased_value) -> std::size_t { // NOLINT(cppcoreguidelines-missing-std-forward)\n        if (empty()) {\n            return 0;\n        }\n\n        auto [dist_and_fingerprint, bucket_idx] = next_while_less(key);\n\n        while (dist_and_fingerprint == at(m_buckets, bucket_idx).m_dist_and_fingerprint &&\n               !m_equal(key, get_key(m_values[at(m_buckets, bucket_idx).m_value_idx]))) {\n            dist_and_fingerprint = dist_inc(dist_and_fingerprint);\n            bucket_idx = next(bucket_idx);\n        }\n\n        if (dist_and_fingerprint != at(m_buckets, bucket_idx).m_dist_and_fingerprint) {\n            return 0;\n        }\n        do_erase(bucket_idx, handle_erased_value);\n        return 1;\n    }\n\n    template <class K, class M>\n    auto do_insert_or_assign(K&& key, M&& mapped) -> std::pair<iterator, bool> {\n        auto it_isinserted = try_emplace(std::forward<K>(key), std::forward<M>(mapped));\n        if (!it_isinserted.second) {\n            it_isinserted.first->second = std::forward<M>(mapped);\n        }\n        return it_isinserted;\n    }\n\n    template <typename... Args>\n    auto do_place_element(dist_and_fingerprint_type dist_and_fingerprint, value_idx_type bucket_idx, Args&&... args)\n        -> std::pair<iterator, bool> {\n\n        // emplace the new value. If that throws an exception, no harm done; index is still in a valid state\n        m_values.emplace_back(std::forward<Args>(args)...);\n\n        auto value_idx = static_cast<value_idx_type>(m_values.size() - 1);\n        if (ANKERL_UNORDERED_DENSE_UNLIKELY(is_full()))\n            ANKERL_UNORDERED_DENSE_UNLIKELY_ATTR {\n                increase_size();\n            }\n        else {\n            place_and_shift_up({dist_and_fingerprint, value_idx}, bucket_idx);\n        }\n\n        // place element and shift up until we find an empty spot\n        return {begin() + static_cast<difference_type>(value_idx), true};\n    }\n\n    template <typename K, typename... Args>\n    auto do_try_emplace(K&& key, Args&&... args) -> std::pair<iterator, bool> {\n        auto hash = mixed_hash(key);\n        auto dist_and_fingerprint = dist_and_fingerprint_from_hash(hash);\n        auto bucket_idx = bucket_idx_from_hash(hash);\n\n        while (true) {\n            auto* bucket = &at(m_buckets, bucket_idx);\n            if (dist_and_fingerprint == bucket->m_dist_and_fingerprint) {\n                if (m_equal(key, get_key(m_values[bucket->m_value_idx]))) {\n                    return {begin() + static_cast<difference_type>(bucket->m_value_idx), false};\n                }\n            } else if (dist_and_fingerprint > bucket->m_dist_and_fingerprint) {\n                return do_place_element(dist_and_fingerprint,\n                                        bucket_idx,\n                                        std::piecewise_construct,\n                                        std::forward_as_tuple(std::forward<K>(key)),\n                                        std::forward_as_tuple(std::forward<Args>(args)...));\n            }\n            dist_and_fingerprint = dist_inc(dist_and_fingerprint);\n            bucket_idx = next(bucket_idx);\n        }\n    }\n\n    template <typename K>\n    auto do_find(K const& key) -> iterator {\n        if (ANKERL_UNORDERED_DENSE_UNLIKELY(empty()))\n            ANKERL_UNORDERED_DENSE_UNLIKELY_ATTR {\n                return end();\n            }\n\n        auto mh = mixed_hash(key);\n        auto dist_and_fingerprint = dist_and_fingerprint_from_hash(mh);\n        auto bucket_idx = bucket_idx_from_hash(mh);\n        auto* bucket = &at(m_buckets, bucket_idx);\n\n        // unrolled loop. *Always* check a few directly, then enter the loop. This is faster.\n        if (dist_and_fingerprint == bucket->m_dist_and_fingerprint && m_equal(key, get_key(m_values[bucket->m_value_idx]))) {\n            return begin() + static_cast<difference_type>(bucket->m_value_idx);\n        }\n        dist_and_fingerprint = dist_inc(dist_and_fingerprint);\n        bucket_idx = next(bucket_idx);\n        bucket = &at(m_buckets, bucket_idx);\n\n        if (dist_and_fingerprint == bucket->m_dist_and_fingerprint && m_equal(key, get_key(m_values[bucket->m_value_idx]))) {\n            return begin() + static_cast<difference_type>(bucket->m_value_idx);\n        }\n        dist_and_fingerprint = dist_inc(dist_and_fingerprint);\n        bucket_idx = next(bucket_idx);\n        bucket = &at(m_buckets, bucket_idx);\n\n        while (true) {\n            if (dist_and_fingerprint == bucket->m_dist_and_fingerprint) {\n                if (m_equal(key, get_key(m_values[bucket->m_value_idx]))) {\n                    return begin() + static_cast<difference_type>(bucket->m_value_idx);\n                }\n            } else if (dist_and_fingerprint > bucket->m_dist_and_fingerprint) {\n                return end();\n            }\n            dist_and_fingerprint = dist_inc(dist_and_fingerprint);\n            bucket_idx = next(bucket_idx);\n            bucket = &at(m_buckets, bucket_idx);\n        }\n    }\n\n    template <typename K>\n    auto do_find(K const& key) const -> const_iterator {\n        return const_cast<table*>(this)->do_find(key); // NOLINT(cppcoreguidelines-pro-type-const-cast)\n    }\n\n    template <typename K, typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto do_at(K const& key) -> Q& {\n        if (auto it = find(key); ANKERL_UNORDERED_DENSE_LIKELY(end() != it))\n            ANKERL_UNORDERED_DENSE_LIKELY_ATTR {\n                return it->second;\n            }\n        on_error_key_not_found();\n    }\n\n    template <typename K, typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto do_at(K const& key) const -> Q const& {\n        return const_cast<table*>(this)->at(key); // NOLINT(cppcoreguidelines-pro-type-const-cast)\n    }\n\npublic:\n    explicit table(std::size_t bucket_count,\n                   Hash const& hash = Hash(),\n                   KeyEqual const& equal = KeyEqual(),\n                   allocator_type const& alloc_or_container = allocator_type())\n        : m_values(alloc_or_container)\n        , m_buckets(alloc_or_container)\n        , m_hash(hash)\n        , m_equal(equal) {\n        if (0 != bucket_count) {\n            reserve(bucket_count);\n        } else {\n            allocate_buckets_from_shift();\n            clear_buckets();\n        }\n    }\n\n    table()\n        : table(0) {}\n\n    table(std::size_t bucket_count, allocator_type const& alloc)\n        : table(bucket_count, Hash(), KeyEqual(), alloc) {}\n\n    table(std::size_t bucket_count, Hash const& hash, allocator_type const& alloc)\n        : table(bucket_count, hash, KeyEqual(), alloc) {}\n\n    explicit table(allocator_type const& alloc)\n        : table(0, Hash(), KeyEqual(), alloc) {}\n\n    template <class InputIt>\n    table(InputIt first,\n          InputIt last,\n          size_type bucket_count = 0,\n          Hash const& hash = Hash(),\n          KeyEqual const& equal = KeyEqual(),\n          allocator_type const& alloc = allocator_type())\n        : table(bucket_count, hash, equal, alloc) {\n        insert(first, last);\n    }\n\n    template <class InputIt>\n    table(InputIt first, InputIt last, size_type bucket_count, allocator_type const& alloc)\n        : table(first, last, bucket_count, Hash(), KeyEqual(), alloc) {}\n\n    template <class InputIt>\n    table(InputIt first, InputIt last, size_type bucket_count, Hash const& hash, allocator_type const& alloc)\n        : table(first, last, bucket_count, hash, KeyEqual(), alloc) {}\n\n    table(table const& other)\n        : table(other, other.m_values.get_allocator()) {}\n\n    table(table const& other, allocator_type const& alloc)\n        : m_values(other.m_values, alloc)\n        , m_max_load_factor(other.m_max_load_factor)\n        , m_hash(other.m_hash)\n        , m_equal(other.m_equal) {\n        copy_buckets(other);\n    }\n\n    table(table&& other) noexcept\n        : table(std::move(other), other.m_values.get_allocator()) {}\n\n    table(table&& other, allocator_type const& alloc) noexcept\n        : m_values(alloc) {\n        *this = std::move(other);\n    }\n\n    table(std::initializer_list<value_type> ilist,\n          std::size_t bucket_count = 0,\n          Hash const& hash = Hash(),\n          KeyEqual const& equal = KeyEqual(),\n          allocator_type const& alloc = allocator_type())\n        : table(bucket_count, hash, equal, alloc) {\n        insert(ilist);\n    }\n\n    table(std::initializer_list<value_type> ilist, size_type bucket_count, allocator_type const& alloc)\n        : table(ilist, bucket_count, Hash(), KeyEqual(), alloc) {}\n\n    table(std::initializer_list<value_type> init, size_type bucket_count, Hash const& hash, allocator_type const& alloc)\n        : table(init, bucket_count, hash, KeyEqual(), alloc) {}\n\n    ~table() = default;\n\n    auto operator=(table const& other) -> table& {\n        if (&other != this) {\n            deallocate_buckets(); // deallocate before m_values is set (might have another allocator)\n            m_values = other.m_values;\n            m_max_load_factor = other.m_max_load_factor;\n            m_hash = other.m_hash;\n            m_equal = other.m_equal;\n            m_shifts = initial_shifts;\n            copy_buckets(other);\n        }\n        return *this;\n    }\n\n    auto operator=(table&& other) noexcept(noexcept(std::is_nothrow_move_assignable_v<value_container_type> &&\n                                                    std::is_nothrow_move_assignable_v<Hash> &&\n                                                    std::is_nothrow_move_assignable_v<KeyEqual>)) -> table& {\n        if (&other != this) {\n            deallocate_buckets(); // deallocate before m_values is set (might have another allocator)\n            m_values = std::move(other.m_values);\n            other.m_values.clear();\n\n            // we can only reuse m_buckets when both maps have the same allocator!\n            if (get_allocator() == other.get_allocator()) {\n                m_buckets = std::move(other.m_buckets);\n                other.m_buckets.clear();\n                m_max_bucket_capacity = std::exchange(other.m_max_bucket_capacity, 0);\n                m_shifts = std::exchange(other.m_shifts, initial_shifts);\n                m_max_load_factor = std::exchange(other.m_max_load_factor, default_max_load_factor);\n                m_hash = std::exchange(other.m_hash, {});\n                m_equal = std::exchange(other.m_equal, {});\n                other.allocate_buckets_from_shift();\n                other.clear_buckets();\n            } else {\n                // set max_load_factor *before* copying the other's buckets, so we have the same\n                // behavior\n                m_max_load_factor = other.m_max_load_factor;\n\n                // copy_buckets sets m_buckets, m_num_buckets, m_max_bucket_capacity, m_shifts\n                copy_buckets(other);\n                // clear's the other's buckets so other is now already usable.\n                other.clear_buckets();\n                m_hash = other.m_hash;\n                m_equal = other.m_equal;\n            }\n            // map \"other\" is now already usable, it's empty.\n        }\n        return *this;\n    }\n\n    auto operator=(std::initializer_list<value_type> ilist) -> table& {\n        clear();\n        insert(ilist);\n        return *this;\n    }\n\n    auto get_allocator() const noexcept -> allocator_type {\n        return m_values.get_allocator();\n    }\n\n    // iterators //////////////////////////////////////////////////////////////\n\n    auto begin() noexcept -> iterator {\n        return m_values.begin();\n    }\n\n    auto begin() const noexcept -> const_iterator {\n        return m_values.begin();\n    }\n\n    auto cbegin() const noexcept -> const_iterator {\n        return m_values.cbegin();\n    }\n\n    auto end() noexcept -> iterator {\n        return m_values.end();\n    }\n\n    auto cend() const noexcept -> const_iterator {\n        return m_values.cend();\n    }\n\n    auto end() const noexcept -> const_iterator {\n        return m_values.end();\n    }\n\n    // capacity ///////////////////////////////////////////////////////////////\n\n    [[nodiscard]] auto empty() const noexcept -> bool {\n        return m_values.empty();\n    }\n\n    [[nodiscard]] auto size() const noexcept -> std::size_t {\n        return m_values.size();\n    }\n\n    [[nodiscard]] static constexpr auto max_size() noexcept -> std::size_t {\n        if constexpr ((std::numeric_limits<value_idx_type>::max)() == (std::numeric_limits<std::size_t>::max)()) {\n            return std::size_t{1} << (sizeof(value_idx_type) * 8 - 1);\n        } else {\n            return std::size_t{1} << (sizeof(value_idx_type) * 8);\n        }\n    }\n\n    // modifiers //////////////////////////////////////////////////////////////\n\n    void clear() {\n        m_values.clear();\n        clear_buckets();\n    }\n\n    auto insert(value_type const& value) -> std::pair<iterator, bool> {\n        return emplace(value);\n    }\n\n    auto insert(value_type&& value) -> std::pair<iterator, bool> {\n        return emplace(std::move(value));\n    }\n\n    template <class P, std::enable_if_t<std::is_constructible_v<value_type, P&&>, bool> = true>\n    auto insert(P&& value) -> std::pair<iterator, bool> {\n        return emplace(std::forward<P>(value));\n    }\n\n    auto insert(const_iterator /*hint*/, value_type const& value) -> iterator {\n        return insert(value).first;\n    }\n\n    auto insert(const_iterator /*hint*/, value_type&& value) -> iterator {\n        return insert(std::move(value)).first;\n    }\n\n    template <class P, std::enable_if_t<std::is_constructible_v<value_type, P&&>, bool> = true>\n    auto insert(const_iterator /*hint*/, P&& value) -> iterator {\n        return insert(std::forward<P>(value)).first;\n    }\n\n    template <class InputIt>\n    void insert(InputIt first, InputIt last) {\n        while (first != last) {\n            insert(*first);\n            ++first;\n        }\n    }\n\n    void insert(std::initializer_list<value_type> ilist) {\n        insert(ilist.begin(), ilist.end());\n    }\n\n    // nonstandard API: *this is emptied.\n    // Also see \"A Standard flat_map\" https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p0429r9.pdf\n    auto extract() && -> value_container_type {\n        return std::move(m_values);\n    }\n\n    // nonstandard API:\n    // Discards the internally held container and replaces it with the one passed. Erases non-unique elements.\n    auto replace(value_container_type&& container) {\n        if (ANKERL_UNORDERED_DENSE_UNLIKELY(container.size() > max_size()))\n            ANKERL_UNORDERED_DENSE_UNLIKELY_ATTR {\n                on_error_too_many_elements();\n            }\n        auto shifts = calc_shifts_for_size(container.size());\n        if (0 == bucket_count() || shifts < m_shifts || container.get_allocator() != m_values.get_allocator()) {\n            m_shifts = shifts;\n            deallocate_buckets();\n            allocate_buckets_from_shift();\n        }\n        clear_buckets();\n\n        m_values = std::move(container);\n\n        // can't use clear_and_fill_buckets_from_values() because container elements might not be unique\n        auto value_idx = value_idx_type{};\n\n        // loop until we reach the end of the container. duplicated entries will be replaced with back().\n        while (value_idx != static_cast<value_idx_type>(m_values.size())) {\n            auto const& key = get_key(m_values[value_idx]);\n\n            auto hash = mixed_hash(key);\n            auto dist_and_fingerprint = dist_and_fingerprint_from_hash(hash);\n            auto bucket_idx = bucket_idx_from_hash(hash);\n\n            bool key_found = false;\n            while (true) {\n                auto const& bucket = at(m_buckets, bucket_idx);\n                if (dist_and_fingerprint > bucket.m_dist_and_fingerprint) {\n                    break;\n                }\n                if (dist_and_fingerprint == bucket.m_dist_and_fingerprint &&\n                    m_equal(key, get_key(m_values[bucket.m_value_idx]))) {\n                    key_found = true;\n                    break;\n                }\n                dist_and_fingerprint = dist_inc(dist_and_fingerprint);\n                bucket_idx = next(bucket_idx);\n            }\n\n            if (key_found) {\n                if (value_idx != static_cast<value_idx_type>(m_values.size() - 1)) {\n                    m_values[value_idx] = std::move(m_values.back());\n                }\n                m_values.pop_back();\n            } else {\n                place_and_shift_up({dist_and_fingerprint, value_idx}, bucket_idx);\n                ++value_idx;\n            }\n        }\n    }\n\n    template <class M, typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto insert_or_assign(Key const& key, M&& mapped) -> std::pair<iterator, bool> {\n        return do_insert_or_assign(key, std::forward<M>(mapped));\n    }\n\n    template <class M, typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto insert_or_assign(Key&& key, M&& mapped) -> std::pair<iterator, bool> {\n        return do_insert_or_assign(std::move(key), std::forward<M>(mapped));\n    }\n\n    template <typename K,\n              typename M,\n              typename Q = T,\n              typename H = Hash,\n              typename KE = KeyEqual,\n              std::enable_if_t<is_map_v<Q> && is_transparent_v<H, KE>, bool> = true>\n    auto insert_or_assign(K&& key, M&& mapped) -> std::pair<iterator, bool> {\n        return do_insert_or_assign(std::forward<K>(key), std::forward<M>(mapped));\n    }\n\n    template <class M, typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto insert_or_assign(const_iterator /*hint*/, Key const& key, M&& mapped) -> iterator {\n        return do_insert_or_assign(key, std::forward<M>(mapped)).first;\n    }\n\n    template <class M, typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto insert_or_assign(const_iterator /*hint*/, Key&& key, M&& mapped) -> iterator {\n        return do_insert_or_assign(std::move(key), std::forward<M>(mapped)).first;\n    }\n\n    template <typename K,\n              typename M,\n              typename Q = T,\n              typename H = Hash,\n              typename KE = KeyEqual,\n              std::enable_if_t<is_map_v<Q> && is_transparent_v<H, KE>, bool> = true>\n    auto insert_or_assign(const_iterator /*hint*/, K&& key, M&& mapped) -> iterator {\n        return do_insert_or_assign(std::forward<K>(key), std::forward<M>(mapped)).first;\n    }\n\n    // Single arguments for unordered_set can be used without having to construct the value_type\n    template <class K,\n              typename Q = T,\n              typename H = Hash,\n              typename KE = KeyEqual,\n              std::enable_if_t<!is_map_v<Q> && is_transparent_v<H, KE>, bool> = true>\n    auto emplace(K&& key) -> std::pair<iterator, bool> {\n        auto hash = mixed_hash(key);\n        auto dist_and_fingerprint = dist_and_fingerprint_from_hash(hash);\n        auto bucket_idx = bucket_idx_from_hash(hash);\n\n        while (dist_and_fingerprint <= at(m_buckets, bucket_idx).m_dist_and_fingerprint) {\n            if (dist_and_fingerprint == at(m_buckets, bucket_idx).m_dist_and_fingerprint &&\n                m_equal(key, m_values[at(m_buckets, bucket_idx).m_value_idx])) {\n                // found it, return without ever actually creating anything\n                return {begin() + static_cast<difference_type>(at(m_buckets, bucket_idx).m_value_idx), false};\n            }\n            dist_and_fingerprint = dist_inc(dist_and_fingerprint);\n            bucket_idx = next(bucket_idx);\n        }\n\n        // value is new, insert element first, so when exception happens we are in a valid state\n        return do_place_element(dist_and_fingerprint, bucket_idx, std::forward<K>(key));\n    }\n\n    template <class... Args>\n    auto emplace(Args&&... args) -> std::pair<iterator, bool> {\n        // we have to instantiate the value_type to be able to access the key.\n        // 1. emplace_back the object so it is constructed. 2. If the key is already there, pop it later in the loop.\n        auto& key = get_key(m_values.emplace_back(std::forward<Args>(args)...));\n        auto hash = mixed_hash(key);\n        auto dist_and_fingerprint = dist_and_fingerprint_from_hash(hash);\n        auto bucket_idx = bucket_idx_from_hash(hash);\n\n        while (dist_and_fingerprint <= at(m_buckets, bucket_idx).m_dist_and_fingerprint) {\n            if (dist_and_fingerprint == at(m_buckets, bucket_idx).m_dist_and_fingerprint &&\n                m_equal(key, get_key(m_values[at(m_buckets, bucket_idx).m_value_idx]))) {\n                m_values.pop_back(); // value was already there, so get rid of it\n                return {begin() + static_cast<difference_type>(at(m_buckets, bucket_idx).m_value_idx), false};\n            }\n            dist_and_fingerprint = dist_inc(dist_and_fingerprint);\n            bucket_idx = next(bucket_idx);\n        }\n\n        // value is new, place the bucket and shift up until we find an empty spot\n        auto value_idx = static_cast<value_idx_type>(m_values.size() - 1);\n        if (ANKERL_UNORDERED_DENSE_UNLIKELY(is_full()))\n            ANKERL_UNORDERED_DENSE_UNLIKELY_ATTR {\n                // increase_size just rehashes all the data we have in m_values\n                increase_size();\n            }\n        else {\n            // place element and shift up until we find an empty spot\n            place_and_shift_up({dist_and_fingerprint, value_idx}, bucket_idx);\n        }\n        return {begin() + static_cast<difference_type>(value_idx), true};\n    }\n\n    template <class... Args>\n    auto emplace_hint(const_iterator /*hint*/, Args&&... args) -> iterator {\n        return emplace(std::forward<Args>(args)...).first;\n    }\n\n    template <class... Args, typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto try_emplace(Key const& key, Args&&... args) -> std::pair<iterator, bool> {\n        return do_try_emplace(key, std::forward<Args>(args)...);\n    }\n\n    template <class... Args, typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto try_emplace(Key&& key, Args&&... args) -> std::pair<iterator, bool> {\n        return do_try_emplace(std::move(key), std::forward<Args>(args)...);\n    }\n\n    template <class... Args, typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto try_emplace(const_iterator /*hint*/, Key const& key, Args&&... args) -> iterator {\n        return do_try_emplace(key, std::forward<Args>(args)...).first;\n    }\n\n    template <class... Args, typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto try_emplace(const_iterator /*hint*/, Key&& key, Args&&... args) -> iterator {\n        return do_try_emplace(std::move(key), std::forward<Args>(args)...).first;\n    }\n\n    template <\n        typename K,\n        typename... Args,\n        typename Q = T,\n        typename H = Hash,\n        typename KE = KeyEqual,\n        std::enable_if_t<is_map_v<Q> && is_transparent_v<H, KE> && is_neither_convertible_v<K&&, iterator, const_iterator>,\n                         bool> = true>\n    auto try_emplace(K&& key, Args&&... args) -> std::pair<iterator, bool> {\n        return do_try_emplace(std::forward<K>(key), std::forward<Args>(args)...);\n    }\n\n    template <\n        typename K,\n        typename... Args,\n        typename Q = T,\n        typename H = Hash,\n        typename KE = KeyEqual,\n        std::enable_if_t<is_map_v<Q> && is_transparent_v<H, KE> && is_neither_convertible_v<K&&, iterator, const_iterator>,\n                         bool> = true>\n    auto try_emplace(const_iterator /*hint*/, K&& key, Args&&... args) -> iterator {\n        return do_try_emplace(std::forward<K>(key), std::forward<Args>(args)...).first;\n    }\n\n    // Replaces the key at the given iterator with new_key. This does not change any other data in the underlying table, so\n    // all iterators and references remain valid. However, this operation can fail if new_key already exists in the table.\n    // In that case, returns {iterator to the already existing new_key, false} and no change is made.\n    //\n    // In the case of a set, this effectively removes the old key and inserts the new key at the same spot, which is more\n    // efficient than removing the old key and inserting the new key because it avoids repositioning the last element.\n    template <typename K>\n    auto replace_key(iterator it, K&& new_key) -> std::pair<iterator, bool> {\n        auto const new_key_hash = mixed_hash(new_key);\n\n        // first, check if new_key already exists and return if so\n        auto dist_and_fingerprint = dist_and_fingerprint_from_hash(new_key_hash);\n        auto bucket_idx = bucket_idx_from_hash(new_key_hash);\n        while (dist_and_fingerprint <= at(m_buckets, bucket_idx).m_dist_and_fingerprint) {\n            auto const& bucket = at(m_buckets, bucket_idx);\n            if (dist_and_fingerprint == bucket.m_dist_and_fingerprint &&\n                m_equal(new_key, get_key(m_values[bucket.m_value_idx]))) {\n                return {begin() + static_cast<difference_type>(bucket.m_value_idx), false};\n            }\n            dist_and_fingerprint = dist_inc(dist_and_fingerprint);\n            bucket_idx = next(bucket_idx);\n        }\n\n        // const_cast is needed because iterator for the set is always const, so adding another get_key overload is not\n        // feasible.\n        auto& target_key = const_cast<key_type&>(get_key(*it));\n        auto const old_key_bucket_idx = bucket_idx_from_hash(mixed_hash(target_key));\n\n        // Replace the key before doing any bucket changes. If it throws, no harm done, we are still in a valid state as we\n        // have not modified any buckets yet.\n        target_key = std::forward<K>(new_key);\n\n        auto const value_idx = static_cast<value_idx_type>(it - begin());\n\n        // Find the bucket containing our value_idx. It's guaranteed we find it, so no other stopping condition needed.\n        bucket_idx = old_key_bucket_idx;\n        while (value_idx != at(m_buckets, bucket_idx).m_value_idx) {\n            bucket_idx = next(bucket_idx);\n        }\n        erase_and_shift_down(bucket_idx);\n\n        // place the new bucket\n        dist_and_fingerprint = dist_and_fingerprint_from_hash(new_key_hash);\n        bucket_idx = bucket_idx_from_hash(new_key_hash);\n        while (dist_and_fingerprint < at(m_buckets, bucket_idx).m_dist_and_fingerprint) {\n            dist_and_fingerprint = dist_inc(dist_and_fingerprint);\n            bucket_idx = next(bucket_idx);\n        }\n        place_and_shift_up({dist_and_fingerprint, value_idx}, bucket_idx);\n\n        return {it, true};\n    }\n\n    auto erase(iterator it) -> iterator {\n        auto hash = mixed_hash(get_key(*it));\n        auto bucket_idx = bucket_idx_from_hash(hash);\n\n        auto const value_idx_to_remove = static_cast<value_idx_type>(it - cbegin());\n        while (at(m_buckets, bucket_idx).m_value_idx != value_idx_to_remove) {\n            bucket_idx = next(bucket_idx);\n        }\n\n        do_erase(bucket_idx, [](value_type const& /*unused*/) -> void {\n        });\n        return begin() + static_cast<difference_type>(value_idx_to_remove);\n    }\n\n    auto extract(iterator it) -> value_type {\n        auto hash = mixed_hash(get_key(*it));\n        auto bucket_idx = bucket_idx_from_hash(hash);\n\n        auto const value_idx_to_remove = static_cast<value_idx_type>(it - cbegin());\n        while (at(m_buckets, bucket_idx).m_value_idx != value_idx_to_remove) {\n            bucket_idx = next(bucket_idx);\n        }\n\n        auto tmp = std::optional<value_type>{};\n        do_erase(bucket_idx, [&tmp](value_type&& val) -> void {\n            tmp = std::move(val);\n        });\n        return std::move(tmp).value();\n    }\n\n    template <typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto erase(const_iterator it) -> iterator {\n        return erase(begin() + (it - cbegin()));\n    }\n\n    template <typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto extract(const_iterator it) -> value_type {\n        return extract(begin() + (it - cbegin()));\n    }\n\n    auto erase(const_iterator first, const_iterator last) -> iterator {\n        auto const idx_first = first - cbegin();\n        auto const idx_last = last - cbegin();\n        auto const first_to_last = std::distance(first, last);\n        auto const last_to_end = std::distance(last, cend());\n\n        // remove elements from left to right which moves elements from the end back\n        auto const mid = idx_first + (std::min)(first_to_last, last_to_end);\n        auto idx = idx_first;\n        while (idx != mid) {\n            erase(begin() + idx);\n            ++idx;\n        }\n\n        // all elements from the right are moved, now remove the last element until all done\n        idx = idx_last;\n        while (idx != mid) {\n            --idx;\n            erase(begin() + idx);\n        }\n\n        return begin() + idx_first;\n    }\n\n    auto erase(Key const& key) -> std::size_t {\n        return do_erase_key(key, [](value_type const& /*unused*/) -> void {\n        });\n    }\n\n    auto extract(Key const& key) -> std::optional<value_type> {\n        auto tmp = std::optional<value_type>{};\n        do_erase_key(key, [&tmp](value_type&& val) -> void {\n            tmp = std::move(val);\n        });\n        return tmp;\n    }\n\n    template <class K, class H = Hash, class KE = KeyEqual, std::enable_if_t<is_transparent_v<H, KE>, bool> = true>\n    auto erase(K&& key) -> std::size_t {\n        return do_erase_key(std::forward<K>(key), [](value_type const& /*unused*/) -> void {\n        });\n    }\n\n    template <class K, class H = Hash, class KE = KeyEqual, std::enable_if_t<is_transparent_v<H, KE>, bool> = true>\n    auto extract(K&& key) -> std::optional<value_type> {\n        auto tmp = std::optional<value_type>{};\n        do_erase_key(std::forward<K>(key), [&tmp](value_type&& val) -> void {\n            tmp = std::move(val);\n        });\n        return tmp;\n    }\n\n    void swap(table& other) noexcept(noexcept(std::is_nothrow_swappable_v<value_container_type> &&\n                                              std::is_nothrow_swappable_v<Hash> && std::is_nothrow_swappable_v<KeyEqual>)) {\n        using std::swap;\n        swap(other, *this);\n    }\n\n    // lookup /////////////////////////////////////////////////////////////////\n\n    template <typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto at(key_type const& key) -> Q& {\n        return do_at(key);\n    }\n\n    template <typename K,\n              typename Q = T,\n              typename H = Hash,\n              typename KE = KeyEqual,\n              std::enable_if_t<is_map_v<Q> && is_transparent_v<H, KE>, bool> = true>\n    auto at(K const& key) -> Q& {\n        return do_at(key);\n    }\n\n    template <typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto at(key_type const& key) const -> Q const& {\n        return do_at(key);\n    }\n\n    template <typename K,\n              typename Q = T,\n              typename H = Hash,\n              typename KE = KeyEqual,\n              std::enable_if_t<is_map_v<Q> && is_transparent_v<H, KE>, bool> = true>\n    auto at(K const& key) const -> Q const& {\n        return do_at(key);\n    }\n\n    template <typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto operator[](Key const& key) -> Q& {\n        return try_emplace(key).first->second;\n    }\n\n    template <typename Q = T, std::enable_if_t<is_map_v<Q>, bool> = true>\n    auto operator[](Key&& key) -> Q& {\n        return try_emplace(std::move(key)).first->second;\n    }\n\n    template <typename K,\n              typename Q = T,\n              typename H = Hash,\n              typename KE = KeyEqual,\n              std::enable_if_t<is_map_v<Q> && is_transparent_v<H, KE>, bool> = true>\n    auto operator[](K&& key) -> Q& {\n        return try_emplace(std::forward<K>(key)).first->second;\n    }\n\n    auto count(Key const& key) const -> std::size_t {\n        return find(key) == end() ? 0 : 1;\n    }\n\n    template <class K, class H = Hash, class KE = KeyEqual, std::enable_if_t<is_transparent_v<H, KE>, bool> = true>\n    auto count(K const& key) const -> std::size_t {\n        return find(key) == end() ? 0 : 1;\n    }\n\n    auto find(Key const& key) -> iterator {\n        return do_find(key);\n    }\n\n    auto find(Key const& key) const -> const_iterator {\n        return do_find(key);\n    }\n\n    template <class K, class H = Hash, class KE = KeyEqual, std::enable_if_t<is_transparent_v<H, KE>, bool> = true>\n    auto find(K const& key) -> iterator {\n        return do_find(key);\n    }\n\n    template <class K, class H = Hash, class KE = KeyEqual, std::enable_if_t<is_transparent_v<H, KE>, bool> = true>\n    auto find(K const& key) const -> const_iterator {\n        return do_find(key);\n    }\n\n    auto contains(Key const& key) const -> bool {\n        return find(key) != end();\n    }\n\n    template <class K, class H = Hash, class KE = KeyEqual, std::enable_if_t<is_transparent_v<H, KE>, bool> = true>\n    auto contains(K const& key) const -> bool {\n        return find(key) != end();\n    }\n\n    auto equal_range(Key const& key) -> std::pair<iterator, iterator> {\n        auto it = do_find(key);\n        return {it, it == end() ? end() : it + 1};\n    }\n\n    auto equal_range(const Key& key) const -> std::pair<const_iterator, const_iterator> {\n        auto it = do_find(key);\n        return {it, it == end() ? end() : it + 1};\n    }\n\n    template <class K, class H = Hash, class KE = KeyEqual, std::enable_if_t<is_transparent_v<H, KE>, bool> = true>\n    auto equal_range(K const& key) -> std::pair<iterator, iterator> {\n        auto it = do_find(key);\n        return {it, it == end() ? end() : it + 1};\n    }\n\n    template <class K, class H = Hash, class KE = KeyEqual, std::enable_if_t<is_transparent_v<H, KE>, bool> = true>\n    auto equal_range(K const& key) const -> std::pair<const_iterator, const_iterator> {\n        auto it = do_find(key);\n        return {it, it == end() ? end() : it + 1};\n    }\n\n    // bucket interface ///////////////////////////////////////////////////////\n\n    auto bucket_count() const noexcept -> std::size_t { // NOLINT(modernize-use-nodiscard)\n        return m_buckets.size();\n    }\n\n    static constexpr auto max_bucket_count() noexcept -> std::size_t { // NOLINT(modernize-use-nodiscard)\n        return max_size();\n    }\n\n    // hash policy ////////////////////////////////////////////////////////////\n\n    [[nodiscard]] auto load_factor() const -> float {\n        return bucket_count() ? static_cast<float>(size()) / static_cast<float>(bucket_count()) : 0.0F;\n    }\n\n    [[nodiscard]] auto max_load_factor() const -> float {\n        return m_max_load_factor;\n    }\n\n    void max_load_factor(float ml) {\n        m_max_load_factor = ml;\n        if (bucket_count() != max_bucket_count()) {\n            m_max_bucket_capacity = static_cast<value_idx_type>(static_cast<float>(bucket_count()) * max_load_factor());\n        }\n    }\n\n    void rehash(std::size_t count) {\n        count = (std::min)(count, max_size());\n        auto shifts = calc_shifts_for_size((std::max)(count, size()));\n        if (shifts != m_shifts) {\n            m_shifts = shifts;\n            deallocate_buckets();\n            m_values.shrink_to_fit();\n            allocate_buckets_from_shift();\n            clear_and_fill_buckets_from_values();\n        }\n    }\n\n    void reserve(std::size_t capa) {\n        capa = (std::min)(capa, max_size());\n        if constexpr (has_reserve<value_container_type>) {\n            // std::deque doesn't have reserve(). Make sure we only call when available\n            m_values.reserve(capa);\n        }\n        auto shifts = calc_shifts_for_size((std::max)(capa, size()));\n        if (0 == bucket_count() || shifts < m_shifts) {\n            m_shifts = shifts;\n            deallocate_buckets();\n            allocate_buckets_from_shift();\n            clear_and_fill_buckets_from_values();\n        }\n    }\n\n    // observers //////////////////////////////////////////////////////////////\n\n    auto hash_function() const -> hasher {\n        return m_hash;\n    }\n\n    auto key_eq() const -> key_equal {\n        return m_equal;\n    }\n\n    // nonstandard API: expose the underlying values container\n    [[nodiscard]] auto values() const noexcept -> value_container_type const& {\n        return m_values;\n    }\n\n    // non-member functions ///////////////////////////////////////////////////\n\n    friend auto operator==(table const& a, table const& b) -> bool {\n        if (&a == &b) {\n            return true;\n        }\n        if (a.size() != b.size()) {\n            return false;\n        }\n        for (auto const& b_entry : b) {\n            auto it = a.find(get_key(b_entry));\n            if constexpr (is_map_v<T>) {\n                // map: check that key is here, then also check that value is the same\n                if (a.end() == it || !(b_entry.second == it->second)) {\n                    return false;\n                }\n            } else {\n                // set: only check that the key is here\n                if (a.end() == it) {\n                    return false;\n                }\n            }\n        }\n        return true;\n    }\n\n    friend auto operator!=(table const& a, table const& b) -> bool {\n        return !(a == b);\n    }\n};\n\n} // namespace detail\n\ntemplate <class Key,\n          class T,\n          class Hash = hash<Key>,\n          class KeyEqual = std::equal_to<Key>,\n          class AllocatorOrContainer = std::allocator<std::pair<Key, T>>,\n          class Bucket = bucket_type::standard,\n          class BucketContainer = detail::default_container_t>\nusing map = detail::table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket, BucketContainer, false>;\n\ntemplate <class Key,\n          class T,\n          class Hash = hash<Key>,\n          class KeyEqual = std::equal_to<Key>,\n          class AllocatorOrContainer = std::allocator<std::pair<Key, T>>,\n          class Bucket = bucket_type::standard,\n          class BucketContainer = detail::default_container_t>\nusing segmented_map = detail::table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket, BucketContainer, true>;\n\ntemplate <class Key,\n          class Hash = hash<Key>,\n          class KeyEqual = std::equal_to<Key>,\n          class AllocatorOrContainer = std::allocator<Key>,\n          class Bucket = bucket_type::standard,\n          class BucketContainer = detail::default_container_t>\nusing set = detail::table<Key, void, Hash, KeyEqual, AllocatorOrContainer, Bucket, BucketContainer, false>;\n\ntemplate <class Key,\n          class Hash = hash<Key>,\n          class KeyEqual = std::equal_to<Key>,\n          class AllocatorOrContainer = std::allocator<Key>,\n          class Bucket = bucket_type::standard,\n          class BucketContainer = detail::default_container_t>\nusing segmented_set = detail::table<Key, void, Hash, KeyEqual, AllocatorOrContainer, Bucket, BucketContainer, true>;\n\n#    if defined(ANKERL_UNORDERED_DENSE_PMR)\n\nnamespace pmr {\n\ntemplate <class Key,\n          class T,\n          class Hash = hash<Key>,\n          class KeyEqual = std::equal_to<Key>,\n          class Bucket = bucket_type::standard>\nusing map = detail::table<Key,\n                          T,\n                          Hash,\n                          KeyEqual,\n                          ANKERL_UNORDERED_DENSE_PMR::polymorphic_allocator<std::pair<Key, T>>,\n                          Bucket,\n                          detail::default_container_t,\n                          false>;\n\ntemplate <class Key,\n          class T,\n          class Hash = hash<Key>,\n          class KeyEqual = std::equal_to<Key>,\n          class Bucket = bucket_type::standard>\nusing segmented_map = detail::table<Key,\n                                    T,\n                                    Hash,\n                                    KeyEqual,\n                                    ANKERL_UNORDERED_DENSE_PMR::polymorphic_allocator<std::pair<Key, T>>,\n                                    Bucket,\n                                    detail::default_container_t,\n                                    true>;\n\ntemplate <class Key, class Hash = hash<Key>, class KeyEqual = std::equal_to<Key>, class Bucket = bucket_type::standard>\nusing set = detail::table<Key,\n                          void,\n                          Hash,\n                          KeyEqual,\n                          ANKERL_UNORDERED_DENSE_PMR::polymorphic_allocator<Key>,\n                          Bucket,\n                          detail::default_container_t,\n                          false>;\n\ntemplate <class Key, class Hash = hash<Key>, class KeyEqual = std::equal_to<Key>, class Bucket = bucket_type::standard>\nusing segmented_set = detail::table<Key,\n                                    void,\n                                    Hash,\n                                    KeyEqual,\n                                    ANKERL_UNORDERED_DENSE_PMR::polymorphic_allocator<Key>,\n                                    Bucket,\n                                    detail::default_container_t,\n                                    true>;\n\n} // namespace pmr\n\n#    endif\n\n// deduction guides ///////////////////////////////////////////////////////////\n\n// deduction guides for alias templates are only possible since C++20\n// see https://en.cppreference.com/w/cpp/language/class_template_argument_deduction\n\n} // namespace ANKERL_UNORDERED_DENSE_NAMESPACE\n} // namespace ankerl::unordered_dense\n\n// std extensions /////////////////////////////////////////////////////////////\n\nnamespace std { // NOLINT(cert-dcl58-cpp)\n\ntemplate <class Key,\n          class T,\n          class Hash,\n          class KeyEqual,\n          class AllocatorOrContainer,\n          class Bucket,\n          class Pred,\n          class BucketContainer,\n          bool IsSegmented>\n// NOLINTNEXTLINE(cert-dcl58-cpp)\nauto erase_if(\n    ankerl::unordered_dense::detail::table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket, BucketContainer, IsSegmented>&\n        map,\n    Pred pred) -> std::size_t {\n    using map_t = ankerl::unordered_dense::detail::\n        table<Key, T, Hash, KeyEqual, AllocatorOrContainer, Bucket, BucketContainer, IsSegmented>;\n\n    // going back to front because erase() invalidates the end iterator\n    auto const old_size = map.size();\n    auto idx = old_size;\n    while (idx) {\n        --idx;\n        auto it = map.begin() + static_cast<typename map_t::difference_type>(idx);\n        if (pred(*it)) {\n            map.erase(it);\n        }\n    }\n\n    return old_size - map.size();\n}\n\n} // namespace std\n\n#endif\n#endif\n"
  },
  {
    "path": "thirdparty/cppad/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.8...3.26)\n\nproject(CPPAD CXX)\n\nfile(GLOB CPPAD_HEADERS include/cppad/*.hpp)\nset(CPPAD_SOURCES\nsrc/cpp_graph_op.cpp\nsrc/temp_file.cpp\n)\n\nadd_library(cppad STATIC)\ntarget_sources(cppad PRIVATE\n  ${CPPAD_HEADERS}\n  ${CPPAD_SOURCES}\n)\ntarget_include_directories(cppad PUBLIC include)"
  },
  {
    "path": "thirdparty/cppad/include/cppad/base_require.hpp",
    "content": "# ifndef CPPAD_BASE_REQUIRE_HPP\n# define CPPAD_BASE_REQUIRE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin base_require}\n{xrst_spell\n   ostream\n}\n\nAD<Base> Requirements for a CppAD Base Type\n###########################################\n\nSyntax\n******\n| ``# include <cppad/base_require.hpp>``\n\nPurpose\n*******\nThis section lists the requirements for the type\n*Base* so that the type ``AD`` < *Base* > can be used.\n\nAPI Warning\n***********\nDefining a CppAD *Base* type is an advanced use of CppAD.\nThis part of the CppAD API changes with time. The most common change\nis adding more requirements.\nSearch for ``base_require`` in the\ncurrent :ref:`whats_new-name` section for these changes.\n\nStandard Base Types\n*******************\nIn the case where *Base* is\n``float`` ,\n``double`` ,\n``std::complex<float>`` ,\n``std::complex<double>`` ,\nor ``AD`` < *Other* > ,\nthese requirements are provided by including the file\n``cppad/cppad.hpp`` .\nIn the documentation, The notation :math:`\\B{R}` denotes\nthe field corresponding to the base type.\nMultiplication must be commutative for this field,\nbut it need not be the reals; e.g., the complex numbers.\n\nInclude Order\n*************\nIf you are linking a non-standard base type to CppAD,\nyou must first include the file ``cppad/base_require.hpp`` ,\nthen provide the specifications below,\nand then include the file ``cppad/cppad.hpp`` .\n\nNumeric Type\n************\nThe type *Base* must support all the operations for a\n:ref:`NumericType-name` .\n\nOutput Operator\n***************\nThe type *Base* must support the syntax\n\n   *os* << *x*\n\nwhere *os* is an ``std::ostream&``\nand *x* is a ``const base_alloc&`` .\nFor example, see\n:ref:`base_alloc<base_alloc.hpp@Output Operator>` .\n\nInteger\n*******\nThe type *Base* must support the syntax\n\n   *i* = ``CppAD::Integer`` ( *x* )\n\nwhich converts *x* to an ``int`` .\nThe argument *x* has prototype\n\n   ``const`` *Base* & *x*\n\nand the return value *i* has prototype\n\n   ``int`` *i*\n\nSuggestion\n==========\nIn many cases, the *Base* version of the ``Integer`` function\ncan be defined by\n\n| ``namespace CppAD`` {\n| |tab| ``inline int Integer`` ( ``const`` *Base* & ``x`` )\n| |tab| { ``return static_cast<int>`` ( ``x`` ); }\n| }\n\nFor example, see\n:ref:`base_float<base_float.hpp@Integer>` and\n:ref:`base_alloc<base_alloc.hpp@Integer>` .\n\nAbsolute Zero, azmul\n********************\nThe type *Base* must support the syntax\n\n   *z* = ``azmul`` ( *x* , *y* )\n\nsee; :ref:`azmul-name` .\nThe following preprocessor macro invocation suffices\n(for most *Base* types):\n\n| ``namespace CppAD`` {\n| |tab| ``CPPAD_AZMUL`` ( *Base* )\n| }\n\nwhere the macro is defined by\n{xrst_spell_off}\n{xrst_code cpp} */\n# define CPPAD_AZMUL(Base) \\\n   inline Base azmul(const Base& x, const Base& y) \\\n   {  Base zero(0.0);   \\\n      if( x == zero ) \\\n         return zero;  \\\n      return x * y;     \\\n   }\n/* {xrst_code}\n{xrst_spell_on}\n\nContents\n********\n{xrst_toc_table\n   xrst/base_require/base_member.xrst\n   include/cppad/core/base_cond_exp.hpp\n   xrst/base_require/base_identical.xrst\n   xrst/base_require/base_ordered.xrst\n   include/cppad/core/base_std_math.hpp\n   include/cppad/core/base_limits.hpp\n   include/cppad/core/base_to_string.hpp\n   include/cppad/core/base_hash.hpp\n   xrst/base_require/base_example.xrst\n}\n\n{xrst_end base_require}\n*/\n\n// definitions that must come before base implementations\n# include <cppad/utility/error_handler.hpp>\n# include <cppad/local/define.hpp>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/local/declare_ad.hpp>\n\n// grouping documentation by feature\n# include <cppad/core/base_cond_exp.hpp>\n# include <cppad/core/base_std_math.hpp>\n# include <cppad/core/base_limits.hpp>\n# include <cppad/core/base_to_string.hpp>\n# include <cppad/core/base_hash.hpp>\n\n// must define template class numeric_limits before the base cases\n# include <cppad/core/numeric_limits.hpp>\n# include <cppad/core/epsilon.hpp> // deprecated\n\n// base cases that come with CppAD\n# include <cppad/core/base_float.hpp>\n# include <cppad/core/base_double.hpp>\n# include <cppad/core/base_complex.hpp>\n\n// deprecated base type\n# include <cppad/core/zdouble.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/configure.hpp",
    "content": "# ifndef CPPAD_CONFIGURE_HPP\n# define CPPAD_CONFIGURE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*!\n{xrst_begin configure.hpp dev}\n{xrst_spell\n   adolc\n   cmd\n   colpack\n   gettimeofday\n   ipopt\n   mkstemp\n   noexcept\n   nullptr\n   pragmas\n   tmpnam\n   unreferenced\n   yyyy\n   yyyymmdd\n}\n\nPreprocessor Symbols Set By CMake Command\n#########################################\n\nCPPAD_COMPILER_HAS_CONVERSION_WARN\n**********************************\nis the compiler a variant of g++ and has conversion warnings\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_COMPILER_HAS_CONVERSION_WARN 0\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_DISABLE_SOME_MICROSOFT_COMPILER_WARNINGS\n**********************************************\nThis macro is only used to document the pragmas that disables the\nfollow warnings:\n\nC4100\n=====\nunreferenced formal parameter.\n\nC4127\n=====\nconditional expression is constant.\n\nC4723\n=====\nThe second operand in a divide operation evaluated to zero at compile time.\n\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_DISABLE_SOME_MICROSOFT_COMPILER_WARNINGS 1\n# if _MSC_VER\n# pragma warning( disable : 4100 )\n# pragma warning( disable : 4127 )\n# pragma warning( disable : 4723 )\n# endif\n# undef CPPAD_DISABLE_SOME_MICROSOFT_COMPILER_WARNINGS\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_DEBUG_AND_RELEASE\n***********************\nStarting with 2023-12-24,\nthis flag is set by the cmake command; see\n:ref:`cmake@cppad_debug_and_release` .\nBefore then, one would add -D CPPAD_DEBUG_AND_RELEASE\nwhen compiling CppAD code.\n{xrst_code hpp} */\n# define CPPAD_DEBUG_AND_RELEASE 1\n/* {xrst_code}\n\nCPPAD_USE_CPLUSPLUS_2011\n************************\nDeprecated 2020-12-03:\nIs it OK to use C++11 features. This is always 1 (for true).\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_USE_CPLUSPLUS_2011 1\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_USE_CPLUSPLUS_2017\n************************\nDeprecated 2020-12-03:\nIs it OK for CppAD use C++17 features.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_USE_CPLUSPLUS_2017 1\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_PACKAGE_STRING\n********************\ncppad-yyyymmdd as a C string where yyyy is year, mm is month, and dd is day.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_PACKAGE_STRING \"cppad-20260000\"\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_HAS_ADOLC\n***************\nWas include_adolc=true on the cmake command line.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_HAS_ADOLC 0\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_HAS_COLPACK\n*****************\nWas a colpack_prefix specified on the cmake command line.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_HAS_COLPACK 0\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_HAS_EIGEN\n***************\nWas include_eigen=true on the cmake command line.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_HAS_EIGEN 0\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_HAS_IPOPT\n***************\nWas include_ipopt=true on the cmake command line.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_HAS_IPOPT 0\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_DEPRECATED\n****************\nThis symbol is not currently being used.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_DEPRECATED \n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_BOOSTVECTOR\n*****************\nIf this symbol is one, and _MSC_VER is not defined,\nwe are using boost vector for CPPAD_TESTVECTOR.\nIt this symbol is zero,\nwe are not using boost vector for CPPAD_TESTVECTOR.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_BOOSTVECTOR 0\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_CPPADVECTOR\n*****************\nIf this symbol is one,\nwe are using CppAD vector for CPPAD_TESTVECTOR.\nIt this symbol is zero,\nwe are not using CppAD vector for CPPAD_TESTVECTOR.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_CPPADVECTOR 1\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_STDVECTOR\n***************\nIf this symbol is one,\nwe are using standard vector for CPPAD_TESTVECTOR.\nIt this symbol is zero,\nwe are not using standard vector for CPPAD_TESTVECTOR.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_STDVECTOR 0\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_EIGENVECTOR\n*****************\nIf this symbol is one,\nwe are using Eigen vector for CPPAD_TESTVECTOR.\nIf this symbol is zero,\nwe are not using Eigen vector for CPPAD_TESTVECTOR.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_EIGENVECTOR 0\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_HAS_GETTIMEOFDAY\n**********************\nIf this symbol is one, and _MSC_VER is not defined,\nthis system supports the gettimeofday function.\nOtherwise, this symbol should be zero.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_HAS_GETTIMEOFDAY 0\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_TAPE_ADDR_TYPE\n********************\nIs the type used to store address on the tape.\nIf it is not size_t, then\n{xrst_code cpp}\n   sizeof(CPPAD_TAPE_ADDR_TYPE) < sizeof( size_t )\n{xrst_code}\ncan be used to conserve memory.\nThis type must support std::numeric_limits,\nthe <= operator,\nand conversion to size_t.\nMake sure that the type chosen returns true for is_pod<CPPAD_TAPE_ADDR_TYPE>\nin pod_vector.hpp.\nThis type is later defined as addr_t in the CppAD namespace.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_TAPE_ADDR_TYPE unsigned int\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_IS_SAME_TAPE_ADDR_TYPE_SIZE_T\n***********************************\nIs size_t the type the same as CPPAD_TAPE_ADDR_TYPE.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_IS_SAME_TAPE_ADDR_TYPE_SIZE_T \\\n   0\n/* {xrst_code}\n{xrst_spell_off}\n\n\nCPPAD_TAPE_ID_TYPE\n******************\nIs the type used to store tape identifiers.\nIf it is not size_t, then\n{xrst_code cpp}\n   sizeof(CPPAD_TAPE_ID_TYPE) < sizeof( size_t )\n{xrst_code}\ncan be used to conserve memory.\nThis type must support std::numeric_limits,\nthe <= operator,\nand conversion to size_t.\nMake sure that the type chosen returns true for is_pod<CPPAD_TAPE_ID_TYPE>\nin pod_vector.hpp.\nThis type is later defined as tape_id_t in the CppAD namespace.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_TAPE_ID_TYPE unsigned int\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_MAX_NUM_THREADS\n*********************\nSpecifies the maximum number of threads that CppAD can support\n(must be greater than or equal four).\n\nThe user may define CPPAD_MAX_NUM_THREADS before including any of the CppAD\nheader files.  If it is not yet defined,\n{xrst_spell_off}\n{xrst_code hpp} */\n# ifndef CPPAD_MAX_NUM_THREADS\n# define CPPAD_MAX_NUM_THREADS 48\n# endif\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_HAS_MKSTEMP\n*****************\nif true, mkstemp works in C++ on this system.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_HAS_MKSTEMP 0\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_HAS_TMPNAM_S\n******************\nIf true, tmpnam_s works in C++ on this system.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_HAS_TMPNAM_S 0\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_NULL\n**********\nDeprecated 2020-12-03:\nThis preprocessor symbol was used for a null pointer before c++11.\nReplace it by ``nullptr`` .\n\nCPPAD_NOEXCEPT\n**************\nDeprecated 2020-12-03:\nThis preprocessor symbol was used for no exception before c++11,\nreplace it by ``noexcept`` .\n\nCPPAD_NDEBUG_NOEXCEPT\n=====================\nThis preprocessor symbol is\n``noexcept`` when ``NDEBUG`` is defined.\nOtherwise it is empty.\n\nCPPAD_C_COMPILER_CMD\n********************\nThis is the command that runs the C compiler as a C string;\ni.e., surrounded by double quotes.\nIt can be used to run the C compiler; e.g. see for :ref:`create_dll_lib-name` .\n{xrst_code hpp} */\n# define CPPAD_C_COMPILER_CMD \"cl.exe\"\n/* {xrst_code}\n\nCPPAD_C_COMPILER_GNU_FLAGS\n**************************\nIf true, the C complier uses the same flags as ``gcc``\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_C_COMPILER_GNU_FLAGS 0\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_C_COMPILER_MSVC_FLAGS\n***************************\nIf true, the C complier uses the same flags as ``cl``\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_C_COMPILER_MSVC_FLAGS 0\n/* {xrst_code}\n{xrst_spell_on}\n\nCPPAD_IS_SAME_UNSIGNED_INT_SIZE_T\n*********************************\nIf true, ``unsigned int`` and ``size_t`` are the same type\n{xrst_code hpp} */\n# define CPPAD_IS_SAME_UNSIGNED_INT_SIZE_T 0\n/* {xrst_code}\n\nCPPAD_PADDING_BLOCK_T\n*********************\nIs a string used to define an object that pads the block_t structure\nso that its size is a multiple of the size of a double.\n{xrst_code hpp} */\n# define CPPAD_PADDING_BLOCK_T \n/* {xrst_code}\n\n{xrst_end configure.hpp}\n*/\n// -------------------------------------------------\n# define CPPAD_NULL                nullptr\n# define CPPAD_NOEXCEPT            noexcept\n//\n# ifdef NDEBUG\n# define CPPAD_NDEBUG_NOEXCEPT     noexcept\n# else\n# define CPPAD_NDEBUG_NOEXCEPT\n# endif\n// -------------------------------------------------\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/abort_recording.hpp",
    "content": "# ifndef CPPAD_CORE_ABORT_RECORDING_HPP\n# define CPPAD_CORE_ABORT_RECORDING_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin abort_recording}\n\nAbort Recording of an Operation Sequence\n########################################\n\nSyntax\n******\n| ``AD`` < *Base* >:: ``abort_recording`` ()\n\nPurpose\n*******\nSometimes it is necessary to abort the recording of an operation sequence\nthat started with a call of the form\n\n   ``Independent`` ( *x* )\n\nIf such a recording is currently in progress,\n``abort_recording`` will stop the recording and delete the\ncorresponding information.\nOtherwise, ``abort_recording`` has no effect.\n{xrst_toc_hidden\n   example/general/abort_recording.cpp\n}\nExample\n*******\nThe file\n:ref:`abort_recording.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end abort_recording}\n----------------------------------------------------------------------------\n*/\n\n\nnamespace CppAD {\n   template <class Base>\n   void AD<Base>::abort_recording(void)\n   {  local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n      if( tape != nullptr )\n         AD<Base>::tape_manage(delete_tape_manage);\n   }\n}\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/abs.hpp",
    "content": "# ifndef CPPAD_CORE_ABS_HPP\n# define CPPAD_CORE_ABS_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n-------------------------------------------------------------------------------\n{xrst_begin abs}\n{xrst_spell\n   faq\n   rl\n}\n\nAD Absolute Value Functions: abs, fabs\n######################################\n\nSyntax\n******\n| *y* = ``abs`` ( *x* )\n| *y* = ``fabs`` ( *x* )\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nIn the case where *x* is an AD type,\nthis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nComplex Types\n*************\nThe functions ``abs`` and *fabs*\nare not defined for the base types\n``std::complex<float>`` or ``std::complex<double>``\nbecause the complex ``abs`` function is not complex differentiable\n(see :ref:`complex types faq<Faq@Complex Types>` ).\n\nDerivative\n**********\nCppAD defines the derivative of the ``abs`` function is\nthe :ref:`sign-name` function; i.e.,\n\n.. math::\n\n   {\\rm abs}^{(1)} ( x ) = {\\rm sign} (x ) =\n   \\left\\{ \\begin{array}{rl}\n      +1 & {\\rm if} \\; x > 0 \\\\\n      0  & {\\rm if} \\; x = 0 \\\\\n      -1 & {\\rm if} \\; x < 0\n   \\end{array} \\right.\n\nThe result for *x*  == 0 used to be a directional derivative.\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/fabs.cpp\n}\nThe file\n:ref:`fabs.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end abs}\n-------------------------------------------------------------------------------\n*/\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nAD<Base> AD<Base>::abs_me (void) const\n{\n   AD<Base> result;\n   result.value_ = abs(value_);\n   CPPAD_ASSERT_UNKNOWN( Parameter(result) );\n\n   // check if there is a recording in progress\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n\n   // check if operand is a constant parameter\n   if( tape_id_ != tape->id_ )\n      return result;\n\n   if(ad_type_ == dynamic_enum)\n   {  // dynamic parameter argument\n      result.taddr_   = tape->Rec_.put_dyn_par(\n         result.value_, local::abs_dyn, taddr_\n      );\n      result.tape_id_  = tape_id_;\n      result.ad_type_  = dynamic_enum;\n   }\n   else\n   {  // variable argument\n      CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AbsOp) == 1 );\n      CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AbsOp) == 1 );\n\n      // corresponding operand address\n      tape->Rec_.PutArg(taddr_);\n\n      // put operator in the tape\n      result.taddr_    = tape->Rec_.PutOp(local::AbsOp);\n\n      // make result a variable\n      result.tape_id_  = tape_id_;\n      result.ad_type_  = variable_enum;\n   }\n   return result;\n}\n\ntemplate <class Base>\nAD<Base> abs(const AD<Base> &x)\n{  return x.abs_me(); }\n\ntemplate <class Base>\nAD<Base> abs(const VecAD_reference<Base> &x)\n{  return x.ADBase().abs_me(); }\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/abs_normal_fun.hpp",
    "content": "# ifndef CPPAD_CORE_ABS_NORMAL_FUN_HPP\n# define CPPAD_CORE_ABS_NORMAL_FUN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin abs_normal_fun}\n\nCreate An Abs-normal Representation of a Function\n#################################################\n\nSyntax\n******\n| *f* . ``abs_normal_fun`` ( *g* , *a* )\n\nf\n*\nThe object *f* has prototype\n\n   ``const ADFun`` < *Base* >& *f*\n\nIt represents a function :math:`f : \\B{R}^n \\rightarrow \\B{R}^m`.\nWe assume that the only non-smooth terms in the representation are\nabsolute value functions and use :math:`s \\in \\B{Z}_+`\nto represent the number of these terms.\n\nn\n=\nWe use *n* to denote the dimension of the domain space for *f* .\n\nm\n=\nWe use *m* to denote the dimension of the range space for *f* .\n\ns\n=\nWe use *s* to denote the number of absolute value terms in *f* .\n\na\n*\nThe object *a* has prototype\n\n   ``ADFun`` < *Base* > *a*\n\nThe initial function representation in *a* is lost.\nUpon return it represents the result of the absolute terms\n:math:`a : \\B{R}^n \\rightarrow \\B{R}^s`; see :math:`a(x)` defined below.\nNote that *a* is constructed by copying *f*\nand then changing the dependent variables. There may\nbe many calculations in this representation that are not necessary\nand can be removed using\n\n   *a* . ``optimize`` ()\n\nThis optimization is not done automatically by ``abs_normal_fun``\nbecause it may take a significant amount of time.\n\nzeta\n====\nLet :math:`\\zeta_0 ( x )`\ndenote the argument for the first absolute value term in :math:`f(x)`,\n:math:`\\zeta_1 ( x , |\\zeta_0 (x)| )` for the second term, and so on.\n\na(x)\n====\nFor :math:`i = 0 , \\ldots , {s-1}` define\n\n.. math::\n\n   a_i (x)\n   =\n   | \\zeta_i ( x , a_0 (x) , \\ldots , a_{i-1} (x ) ) |\n\nThis defines :math:`a : \\B{R}^n \\rightarrow \\B{R}^s`.\n\ng\n*\nThe object *g* has prototype\n\n   ``ADFun`` < *Base* > *g*\n\nThe initial function representation in *g* is lost.\nUpon return it represents the smooth function\n:math:`g : \\B{R}^{n + s} \\rightarrow  \\B{R}^{m + s}` is defined by\n\n.. math::\n\n   g( x , u )\n   =\n   \\left[ \\begin{array}{c} y(x, u) \\\\ z(x, u) \\end{array} \\right]\n\nwere :math:`y(x, u)` and :math:`z(x, u)` are defined below.\n\nz(x, u)\n=======\nDefine the smooth function\n:math:`z : \\B{R}^{n + s} \\rightarrow  \\B{R}^s` by\n\n.. math::\n\n   z_i ( x , u ) = \\zeta_i ( x , u_0 , \\ldots , u_{i-1} )\n\nNote that the partial of :math:`z_i` with respect to :math:`u_j` is zero\nfor :math:`j \\geq i`.\n\ny(x, u)\n=======\nThere is a smooth function\n:math:`y : \\B{R}^{n + s} \\rightarrow  \\B{R}^m`\nsuch that :math:`y( x , u ) = f(x)` whenever :math:`u = a(x)`.\n\nAffine Approximation\n********************\nWe define the affine approximations\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   y[ \\hat{x} ]( x , u )\n   & = &\n   y ( \\hat{x}, a( \\hat{x} ) )\n      + \\partial_x y ( \\hat{x}, a( \\hat{x} ) ) ( x - \\hat{x} )\n      + \\partial_u y ( \\hat{x}, a( \\hat{x} ) ) ( u - a( \\hat{x} ) )\n   \\\\\n   z[ \\hat{x} ]( x , u )\n   & = &\n   z ( \\hat{x}, a( \\hat{x} ) )\n      + \\partial_x z ( \\hat{x}, a( \\hat{x} ) ) ( x - \\hat{x} )\n      + \\partial_u z ( \\hat{x}, a( \\hat{x} ) ) ( u - a( \\hat{x} ) )\n   \\end{eqnarray}\n\nIt follows that\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   y( x , u )\n   & = &\n   y[ \\hat{x} ]( x , u ) + o ( x - \\hat{x}, u - a( \\hat{x} ) )\n   \\\\\n   z( x , u )\n   & = &\n   z[ \\hat{x} ]( x , u ) + o ( x - \\hat{x}, u - a( \\hat{x} ) )\n   \\end{eqnarray}\n\nAbs-normal Approximation\n************************\n\nApproximating a(x)\n==================\nThe function :math:`a(x)` is not smooth, but it is equal to\n:math:`| z(x, u) |` when :math:`u = a(x)`.\nFurthermore\n\n.. math::\n\n   z[ \\hat{x} ]( x , u )\n   =\n   z ( \\hat{x}, a( \\hat{x} ) )\n      + \\partial_x z ( \\hat{x}, a( \\hat{x} ) ) ( x - \\hat{x} )\n      + \\partial_u z ( \\hat{x}, a( \\hat{x} ) ) ( u - a( \\hat{x} ) )\n\nThe partial of :math:`z_i` with respect to :math:`u_j` is zero\nfor :math:`j \\geq i`. It follows that\n\n.. math::\n\n   z_i [ \\hat{x} ]( x , u )\n   =\n   z_i ( \\hat{x}, a( \\hat{x} ) )\n      + \\partial_x z_i ( \\hat{x}, a( \\hat{x} ) ) ( x - \\hat{x} )\n      + \\sum_{j < i} \\partial_{u(j)}\n         z_i ( \\hat{x}, a( \\hat{x} ) ) ( u_j - a_j ( \\hat{x} ) )\n\nConsidering the case :math:`i = 0` we define\n\n.. math::\n\n   a_0 [ \\hat{x} ]( x )\n   =\n   | z_0 [ \\hat{x} ]( x , u ) |\n   =\n   \\left|\n      z_0 ( \\hat{x}, a( \\hat{x} ) )\n      + \\partial_x z_0 ( \\hat{x}, a( \\hat{x} ) ) ( x - \\hat{x} )\n   \\right|\n\nIt follows that\n\n.. math::\n\n   a_0 (x) = a_0 [ \\hat{x} ]( x ) + o ( x - \\hat{x} )\n\nIn general, we define :math:`a_i [ \\hat{x} ]` using\n:math:`a_j [ \\hat{x} ]` for :math:`j < i` as follows:\n\n.. math::\n\n   a_i [ \\hat{x} ]( x )\n   =\n   \\left |\n      z_i ( \\hat{x}, a( \\hat{x} ) )\n      + \\partial_x z_i ( \\hat{x}, a( \\hat{x} ) ) ( x - \\hat{x} )\n      + \\sum_{j < i} \\partial_{u(j)}\n         z_i ( \\hat{x}, a( \\hat{x} ) )\n            ( a_j [ \\hat{x} ] ( x )  - a_j ( \\hat{x} ) )\n   \\right|\n\nIt follows that\n\n.. math::\n\n   a (x) = a[ \\hat{x} ]( x ) + o ( x - \\hat{x} )\n\nNote that in the case where :math:`z(x, u)` and :math:`y(x, u)` are\naffine,\n\n.. math::\n\n   a[ \\hat{x} ]( x ) = a( x )\n\nApproximating f(x)\n==================\n\n.. math::\n\n   f(x)\n   =\n   y ( x , a(x ) )\n   =\n   y [ \\hat{x} ] ( x , a[ \\hat{x} ] ( x ) )\n   + o( x - \\hat{x} )\n\nCorrespondence to Literature\n****************************\nUsing the notation\n:math:`Z = \\partial_x z(\\hat{x}, \\hat{u})`,\n:math:`L = \\partial_u z(\\hat{x}, \\hat{u})`,\n:math:`J = \\partial_x y(\\hat{x}, \\hat{u})`,\n:math:`Y = \\partial_u y(\\hat{x}, \\hat{u})`,\nthe approximation for :math:`z` and :math:`y` are\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   z[ \\hat{x} ]( x , u )\n   & = &\n   z ( \\hat{x}, a( \\hat{x} ) ) + Z ( x - \\hat{x} ) + L ( u - a( \\hat{x} ) )\n   \\\\\n   y[ \\hat{x} ]( x , u )\n   & = &\n   y ( \\hat{x}, a( \\hat{x} ) ) + J ( x - \\hat{x} ) + Y ( u - a( \\hat{x} ) )\n   \\end{eqnarray}\n\nMoving the terms with :math:`\\hat{x}` together, we have\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   z[ \\hat{x} ]( x , u )\n   & = &\n   z ( \\hat{x}, a( \\hat{x} ) ) - Z \\hat{x} - L a( \\hat{x} )  + Z x + L u\n   \\\\\n   y[ \\hat{x} ]( x , u )\n   & = &\n   y ( \\hat{x}, a( \\hat{x} ) ) - J \\hat{x} - Y a( \\hat{x} )  + J x + Y u\n   \\end{eqnarray}\n\nUsing the notation\n:math:`c = z ( \\hat{x}, \\hat{u} ) - Z \\hat{x} - L \\hat{u}`,\n:math:`b = y ( \\hat{x}, \\hat{u} ) - J \\hat{x} - Y \\hat{u}`,\nwe have\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   z[ \\hat{x} ]( x , u ) & = & c + Z x + L u\n   \\\\\n   y[ \\hat{x} ]( x , u ) & = & b + J x + Y u\n   \\end{eqnarray}\n\nConsidering the affine case, where the approximations are exact,\nand choosing :math:`u = a(x) = |z(x, u)|`, we obtain\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   z( x , a(x ) ) & = & c + Z x + L |z( x , a(x ) )|\n   \\\\\n   y( x , a(x ) ) & = & b + J x + Y |z( x , a(x ) )|\n   \\end{eqnarray}\n\nThis is Equation (2) of the\n:ref:`example_abs_normal@Reference` .\n{xrst_toc_hidden\n   example/abs_normal/abs_normal.xrst\n}\nExample\n*******\nThe file :ref:`abs_get_started.cpp-name` contains\nan example and test using this operation.\nThe section :ref:`example_abs_normal-name`\nhas a links to all the abs normal examples.\n\n{xrst_end abs_normal_fun}\n-------------------------------------------------------------------------------\n*/\n/*!\nfile abs_normal_fun.hpp\nCreate an abs-normal representation of a function\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\nCreate an abs-normal representation of an ADFun object.\n\n\\tparam Base\nbase type for this abs-normal form and for the function being represented;\ni.e., f.\n\n\\param f\nis the function that this object will represent in abs-normal form.\nThis is effectively const except that the play back state play_\nis used.\n*/\n\n# ifndef NDEBUG\n# define CPPAD_J_PAR_EQUAL_REC j_par = (size_t) rec\n# else\n# define CPPAD_J_PAR_EQUAL_REC rec\n# endif\n\ntemplate <class Base, class RecBase>\nvoid ADFun<Base,RecBase>::abs_normal_fun(ADFun& g, ADFun& a) const\n{  using namespace local;\n\n   // -----------------------------------------------------------------------\n   // Forward sweep to determine number of absolute value operations in f\n   // -----------------------------------------------------------------------\n   // The argument and result index in f for each absolute value operator\n   CppAD::vector<addr_t> f_abs_arg;\n   CppAD::vector<size_t> f_abs_res;\n   //\n   op_code_var   op;                 // this operator\n   const addr_t* arg = nullptr;   // arguments for this operator\n   size_t        i_var;              // variable index for this operator\n   local::play::const_sequential_iterator itr = play_.begin();\n   itr.op_info(op, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op == BeginOp );\n   //\n   bool    more_operators = true;\n   while( op != EndOp )\n   {\n      // next op\n      (++itr).op_info(op, arg, i_var);\n      switch( op )\n      {  // absolute value operator\n         case AbsOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1);\n         f_abs_arg.push_back( arg[0] );\n         f_abs_res.push_back( i_var );\n         break;\n\n         default:\n         break;\n      }\n   }\n   // ------------------------------------------------------------------------\n   // Forward sweep to create new recording\n   // ------------------------------------------------------------------------\n   // dynamic parameter information in player\n   const pod_vector<bool>&     par_is_dyn( play_.par_is_dyn() );\n   const pod_vector<opcode_t>& dyn_par_op( play_.dyn_par_op() );\n   const pod_vector<addr_t>&   dyn_par_arg( play_.dyn_par_arg() );\n   //\n   // recorder for new operation sequence\n   recorder<Base> rec;\n   //\n   // number of parameters in both operation sequences\n   size_t num_par = play_.num_par_all();\n   //\n   // number of independent dynamic parameters\n   size_t n_dyn_independent = play_.num_dynamic_par();\n   rec.set_n_dyn_independent(n_dyn_independent);\n   //\n   // set all parameter to be exactly the same in rec as in play\n   size_t i_dyn = 0; // dynamic parameter index\n   size_t i_arg = 0; // dynamic parameter operator argument index\n   for(size_t i_par = 0; i_par < num_par; ++i_par)\n   {\n# ifndef NDEBUG\n      size_t j_par = 0;\n# endif\n      // value of this parameter\n      Base par = play_.par_one(i_par);\n      if( ! par_is_dyn[i_par] )\n         CPPAD_J_PAR_EQUAL_REC.put_con_par(par);\n      else\n      {  // operator for this dynamic parameter\n         op_code_dyn op_dyn = op_code_dyn( dyn_par_op[i_dyn] );\n         CPPAD_ASSERT_KNOWN(\n            op_dyn != local::atom_dyn,\n            \"abs_normal_fun: not yet implemented for \"\n            \"atomic dynamic parameter functions\"\n         );\n         //\n         // number of arguments for this dynamic parameter\n         size_t n_arg = num_arg_dyn(op_dyn);\n         //\n         switch(n_arg)\n         {  case 0:\n            CPPAD_J_PAR_EQUAL_REC.put_dyn_par(par, op_dyn);\n            break;\n\n            case 1:\n            CPPAD_J_PAR_EQUAL_REC.put_dyn_par(par, op_dyn,\n               dyn_par_arg[i_arg + 0]\n            );\n            break;\n\n            case 2:\n            CPPAD_J_PAR_EQUAL_REC.put_dyn_par(par, op_dyn,\n               dyn_par_arg[i_arg + 0] ,\n               dyn_par_arg[i_arg + 1]\n            );\n            break;\n\n            case 5:\n            CPPAD_J_PAR_EQUAL_REC.put_dyn_cond_exp(par,\n               CompareOp( dyn_par_arg[i_arg + 0] )  ,\n               dyn_par_arg[i_arg + 1]               ,\n               dyn_par_arg[i_arg + 2]               ,\n               dyn_par_arg[i_arg + 3]               ,\n               dyn_par_arg[i_arg + 4]\n            );\n            break;\n\n            default:\n            CPPAD_ASSERT_UNKNOWN(false);\n         }\n         ++i_dyn;\n         i_arg += n_arg;\n      }\n      CPPAD_ASSERT_UNKNOWN( j_par == i_par );\n   }\n   //\n   // number of variables in both operation sequences\n   // (the AbsOp operators are replace by InvOp operators)\n   const size_t num_var = play_.num_var();\n   //\n   // mapping from old variable index to new variable index\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( (std::numeric_limits<addr_t>::max)() ) >= num_var\n   );\n   CppAD::vector<addr_t> f2g_var(num_var);\n   for(i_var = 0; i_var < num_var; i_var++)\n      f2g_var[i_var] = addr_t( num_var ); // invalid (should not be used)\n   //\n   // record the independent variables in f\n   itr = play_.begin();\n   itr.op_info(op, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op == BeginOp );\n   more_operators   = true;\n   while( more_operators )\n   {  switch( op )\n      {\n         // phantom variable\n         case BeginOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1);\n         CPPAD_ASSERT_UNKNOWN( arg[0] == 0 );\n         rec.PutArg(0);\n         f2g_var[i_var] = rec.PutOp(op);\n         break;\n\n         // independent variables\n         case InvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         f2g_var[i_var] = rec.PutOp(op);\n         break;\n\n         // end of independent variables\n         default:\n         more_operators = false;\n         break;\n      }\n      if( more_operators )\n         (++itr).op_info(op, arg, i_var);\n   }\n   // add one for the phantom variable\n   CPPAD_ASSERT_UNKNOWN( 1 + Domain() == i_var );\n   //\n   // record the independent variables corresponding AbsOp results\n   size_t index_abs;\n   for(index_abs = 0; index_abs < f_abs_res.size(); index_abs++)\n      f2g_var[ f_abs_res[index_abs] ] = rec.PutOp(InvOp);\n   //\n   // used to hold new argument vector\n   addr_t new_arg[6];\n   //\n   // now loop through the rest of the\n   more_operators = true;\n   index_abs      = 0;\n   while( more_operators )\n   {  addr_t mask; // temporary used in some switch cases\n      switch( op )\n      {\n         // check setting of f_abs_arg and f_abs_res;\n         case AbsOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1);\n         CPPAD_ASSERT_UNKNOWN( f_abs_arg[index_abs] ==  arg[0] );\n         CPPAD_ASSERT_UNKNOWN( f_abs_res[index_abs] ==  i_var );\n         CPPAD_ASSERT_UNKNOWN( f2g_var[i_var] > 0 );\n         ++index_abs;\n         break;\n\n         // These operators come at beginning of take and are handled above\n         case InvOp:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n\n         // ---------------------------------------------------------------\n         // Unary operators, argument a parameter, one result\n         case ParOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1);\n         new_arg[0] = arg[0]; // parameter\n         rec.PutArg( new_arg[0] );\n         f2g_var[i_var] = rec.PutOp(op);\n         break;\n\n         // --------------------------------------------------------------\n         // Unary operators, argument a variable, one result\n         // (excluding the absolute value operator AbsOp)\n         case AcosOp:\n         case AcoshOp:\n         case AsinOp:\n         case AsinhOp:\n         case AtanOp:\n         case AtanhOp:\n         case CosOp:\n         case CoshOp:\n         case ExpOp:\n         case Expm1Op:\n         case LogOp:\n         case Log1pOp:\n         case NegOp:\n         case SignOp:\n         case SinOp:\n         case SinhOp:\n         case SqrtOp:\n         case TanOp:\n         case TanhOp:\n         // some of these operators have an auxiliary result; e.g.,\n         // sine and cosine are computed togeather.\n         CPPAD_ASSERT_UNKNOWN( NumArg(op) ==  1 );\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 || NumRes(op) == 2 );\n         CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[0] ] ) < num_var );\n         new_arg[0] = f2g_var[ arg[0] ];\n         rec.PutArg( new_arg[0] );\n         f2g_var[i_var] = rec.PutOp( op );\n         break;\n\n         case ErfOp:\n         case ErfcOp:\n         CPPAD_ASSERT_NARG_NRES(op, 3, 5);\n         CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[0] ] ) < num_var );\n         // Error function is a special case\n         // second argument is always the parameter 0\n         // third argument is always the parameter 2 / sqrt(pi)\n         rec.PutArg( arg[1] ); // parameter\n         rec.PutArg( arg[2] ); // parameter\n         f2g_var[i_var] = rec.PutOp(op);\n         break;\n         // --------------------------------------------------------------\n         // Binary operators, left variable, right parameter, one result\n         case SubvpOp:\n         case DivvpOp:\n         case PowvpOp:\n         case ZmulvpOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[0] ] ) < num_var );\n         new_arg[0] = f2g_var[ arg[0] ];\n         new_arg[1] = arg[1]; // parameter\n         rec.PutArg( new_arg[0], new_arg[1] );\n         f2g_var[i_var] = rec.PutOp(op);\n         break;\n         // ---------------------------------------------------\n         // Binary operators, left index, right variable, one result\n         case DisOp:\n         CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] ) < num_var );\n         new_arg[0] = arg[0];\n         new_arg[1] = f2g_var[ arg[1] ];\n         rec.PutArg( new_arg[0], new_arg[1] );\n         f2g_var[i_var] = rec.PutOp(op);\n         break;\n\n         // --------------------------------------------------------------\n         // Binary operators, left parameter, right variable, one result\n         case AddpvOp:\n         case SubpvOp:\n         case MulpvOp:\n         case DivpvOp:\n         case PowpvOp:\n         case ZmulpvOp:\n# ifndef NDEBUG\n         if( op == PowpvOp )\n         {  CPPAD_ASSERT_NARG_NRES(op, 2, 3);\n         }\n         else\n         {  CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         }\n# endif\n         CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] ) < num_var );\n         new_arg[0] = arg[0]; // parameter\n         new_arg[1] = f2g_var[ arg[1] ];\n         rec.PutArg( new_arg[0], new_arg[1] );\n         f2g_var[i_var] = rec.PutOp(op);\n         break;\n         // --------------------------------------------------------------\n         // Binary operators, left and right variables, one result\n         case AddvvOp:\n         case SubvvOp:\n         case MulvvOp:\n         case DivvvOp:\n         case PowvvOp:\n         case ZmulvvOp:\n# ifndef NDEBUG\n         if( op == PowvvOp )\n         {  CPPAD_ASSERT_NARG_NRES(op, 2, 3);\n         }\n         else\n         {  CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         }\n# endif\n         CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[0] ] ) < num_var );\n         CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] ) < num_var );\n         new_arg[0] = f2g_var[ arg[0] ];\n         new_arg[1] = f2g_var[ arg[1] ];\n         rec.PutArg( new_arg[0], new_arg[1] );\n         f2g_var[i_var] = rec.PutOp(op);\n         break;\n         // ---------------------------------------------------\n         // Conditional expression operators\n         case CExpOp:\n         CPPAD_ASSERT_NARG_NRES(op, 6, 1);\n         new_arg[0] = arg[0];\n         new_arg[1] = arg[1];\n         mask = 1;\n         for(size_t i = 2; i < 6; i++)\n         {  if( arg[1] & mask )\n            {  CPPAD_ASSERT_UNKNOWN( size_t(f2g_var[arg[i]]) < num_var );\n               new_arg[i] = f2g_var[ arg[i] ];\n            }\n            else\n               new_arg[i] = arg[i]; // parameter\n            mask = mask << 1;\n         }\n         rec.PutArg(\n            new_arg[0] ,\n            new_arg[1] ,\n            new_arg[2] ,\n            new_arg[3] ,\n            new_arg[4] ,\n            new_arg[5]\n         );\n         f2g_var[i_var] = rec.PutOp(op);\n         break;\n\n         // --------------------------------------------------\n         // Operators with no arguments and no results\n         case EndOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 0);\n         rec.PutOp(op);\n         more_operators = false;\n         break;\n\n         // ---------------------------------------------------\n         // Operations with two arguments and no results\n         case LepvOp:\n         case LtpvOp:\n         case EqpvOp:\n         case NepvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 0);\n         new_arg[0] = arg[0]; // parameter\n         new_arg[1] = f2g_var[ arg[1] ];\n         rec.PutArg(new_arg[0], new_arg[1]);\n         rec.PutOp(op);\n         break;\n         //\n         case LevpOp:\n         case LtvpOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 0);\n         new_arg[0] = f2g_var[ arg[0] ];\n         new_arg[1] = arg[1]; // parameter\n         rec.PutArg(new_arg[0], new_arg[1]);\n         rec.PutOp(op);\n         break;\n         //\n         case LevvOp:\n         case LtvvOp:\n         case EqvvOp:\n         case NevvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 0);\n         new_arg[0] = f2g_var[ arg[0] ];\n         new_arg[1] = f2g_var[ arg[1] ];\n         rec.PutArg(new_arg[0], new_arg[1]);\n         rec.PutOp(op);\n         break;\n\n         // ---------------------------------------------------\n         // print forward operator\n         case PriOp:\n         CPPAD_ASSERT_NARG_NRES(op, 5, 0);\n         //\n         // arg[0]\n         new_arg[0] = arg[0];\n         //\n         // arg[1]\n         if( arg[0] & 1 )\n         {\n            CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] )  < num_var );\n            new_arg[1] = f2g_var[ arg[1] ];\n         }\n         else\n         {  new_arg[1] = arg[1]; // parameter\n         }\n         //\n         // arg[3]\n         if( arg[0] & 2 )\n         {\n            CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[3] ] )  < num_var );\n            new_arg[3] = f2g_var[ arg[3] ];\n         }\n         else\n         {  new_arg[3] = arg[3]; // parameter\n         }\n         new_arg[2] = rec.PutTxt( play_.GetTxt(size_t(arg[2])) );\n         new_arg[4] = rec.PutTxt( play_.GetTxt(size_t(arg[4])) );\n         //\n         rec.PutArg(\n            new_arg[0] ,\n            new_arg[1] ,\n            new_arg[2] ,\n            new_arg[3] ,\n            new_arg[4]\n         );\n         // no result\n         rec.PutOp(op);\n         break;\n\n         // ---------------------------------------------------\n         // VecAD operators\n\n         // Load using a parameter index\n         case LdpOp:\n         CPPAD_ASSERT_NARG_NRES(op, 3, 1);\n         new_arg[0] = arg[0];\n         new_arg[1] = arg[1]; // parameter\n         new_arg[2] = arg[2];\n         rec.PutArg(\n            new_arg[0],\n            new_arg[1],\n            new_arg[2]\n         );\n         f2g_var[i_var] = rec.PutLoadOp(op);\n         break;\n\n         // Load using a variable index\n         case LdvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 3, 1);\n         CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] ) < num_var );\n         new_arg[0] = arg[0];\n         new_arg[1] = f2g_var[ arg[1] ];\n         new_arg[2] = arg[2];\n         rec.PutArg(\n            new_arg[0],\n            new_arg[1],\n            new_arg[2]\n         );\n         f2g_var[i_var] = rec.PutLoadOp(op);\n         break;\n\n         // Store a parameter using a parameter index\n         case StppOp:\n         CPPAD_ASSERT_NARG_NRES(op, 3, 0);\n         new_arg[0] = arg[0];\n         new_arg[1] = arg[1]; // parameter\n         new_arg[2] = arg[2]; // parameter\n         rec.PutArg(\n            new_arg[0],\n            new_arg[1],\n            new_arg[2]\n         );\n         rec.PutOp(op);\n         break;\n\n         // Store a parameter using a variable index\n         case StvpOp:\n         CPPAD_ASSERT_NARG_NRES(op, 3, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] ) < num_var );\n         new_arg[0] = arg[0];\n         new_arg[1] = f2g_var[ arg[1] ];\n         new_arg[2] = arg[2]; // parameter\n         rec.PutArg(\n            new_arg[0],\n            new_arg[1],\n            new_arg[2]\n         );\n         rec.PutOp(op);\n         break;\n\n         // Store a variable using a parameter index\n         case StpvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 3, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[2] ] ) < num_var );\n         new_arg[0] = arg[0];\n         new_arg[1] = arg[1]; // parameter\n         new_arg[2] = f2g_var[ arg[2] ];\n         rec.PutArg(\n            new_arg[0],\n            new_arg[1],\n            new_arg[2]\n         );\n         rec.PutOp(op);\n         break;\n\n         // Store a variable using a variable index\n         case StvvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 3, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[1] ] ) < num_var );\n         CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[ arg[2] ] ) < num_var );\n         new_arg[0] = arg[0];\n         new_arg[1] = f2g_var[ arg[1] ];\n         new_arg[2] = f2g_var[ arg[2] ];\n         rec.PutArg(\n            new_arg[0],\n            new_arg[1],\n            new_arg[2]\n         );\n         break;\n\n         // -----------------------------------------------------------\n         // atomic function call operators\n\n         case AFunOp:\n         CPPAD_ASSERT_NARG_NRES(op, 4, 0);\n         // atom_index, atom_old, atom_n, atom_m\n         rec.PutArg(arg[0], arg[1], arg[2], arg[3]);\n         rec.PutOp(AFunOp);\n         break;\n\n         case FunapOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 0);\n         new_arg[0] = arg[0]; // parameter\n         rec.PutArg(new_arg[0]);\n         rec.PutOp(FunapOp);\n         break;\n\n         case FunavOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t( f2g_var[arg[0]] ) < num_var );\n         new_arg[0] = f2g_var[ arg[0] ];\n         rec.PutArg(new_arg[0]);\n         rec.PutOp(FunavOp);\n         break;\n\n         case FunrpOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 0);\n         new_arg[0] = arg[0]; // parameter\n         rec.PutArg(new_arg[0]);\n         rec.PutOp(FunrpOp);\n         break;\n\n         case FunrvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         f2g_var[i_var] = rec.PutOp(FunrvOp);\n         break;\n         // ---------------------------------------------------\n\n         // all cases should be handled above\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n      }\n      if( more_operators )\n         (++itr).op_info(op, arg, i_var);\n   }\n   // Check a few expected results\n   CPPAD_ASSERT_UNKNOWN( rec.num_var_op() == play_.num_var_op() );\n   CPPAD_ASSERT_UNKNOWN( rec.num_var() == play_.num_var() );\n   CPPAD_ASSERT_UNKNOWN( rec.num_var_load() == play_.num_var_load() );\n\n   // -----------------------------------------------------------------------\n   // Use rec to create the function g\n   // -----------------------------------------------------------------------\n\n   // number of variables in the recording\n   g.num_var_tape_ = rec.num_var();\n\n   // dimension cskip_op vector to number of operators\n   g.cskip_op_.resize( rec.num_var_op() );\n\n   // independent variables in g: (x, u)\n   size_t s = f_abs_res.size();\n   size_t n = Domain();\n   g.ind_taddr_.resize(n + s);\n   // (x, u)\n   for(size_t j = 0; j < n; j++)\n   {  g.ind_taddr_[j] = size_t( f2g_var[ ind_taddr_[j] ] );\n      CPPAD_ASSERT_UNKNOWN( g.ind_taddr_[j] == j + 1 );\n   }\n   for(size_t j = 0; j < s; j++)\n   {  g.ind_taddr_[n + j] = size_t( f2g_var[ f_abs_res[j] ] );\n      CPPAD_ASSERT_UNKNOWN( g.ind_taddr_[n + j] == n + j + 1 );\n   }\n\n   // dependent variable in g: (y, z)\n   CPPAD_ASSERT_UNKNOWN( s == f_abs_arg.size() );\n   size_t m = Range();\n   g.dep_taddr_.resize(m + s);\n   for(size_t i = 0; i < m; i++)\n   {  g.dep_taddr_[i] = size_t( f2g_var[ dep_taddr_[i] ] );\n      CPPAD_ASSERT_UNKNOWN( g.dep_taddr_[i] < num_var );\n   }\n   for(size_t i = 0; i < s; i++)\n   {  g.dep_taddr_[m + i] = size_t( f2g_var[ f_abs_arg[i] ] );\n      CPPAD_ASSERT_UNKNOWN( g.dep_taddr_[m + i] < num_var );\n   }\n\n   // which  dependent variables are parameters\n   g.dep_parameter_.resize(m + s);\n   for(size_t i = 0; i < m; i++)\n      g.dep_parameter_[i] = dep_parameter_[i];\n   for(size_t i = 0; i < s; i++)\n      g.dep_parameter_[m + i] = false;\n\n   // free memory allocated for sparse Jacobian calculation\n   // (the results are no longer valid)\n   g.for_jac_sparse_pack_.resize(0, 0);\n   g.for_jac_sparse_set_.resize(0, 0);\n\n   // free taylor coefficient memory\n   g.taylor_.clear();\n   g.num_order_taylor_ = 0;\n   g.cap_order_taylor_ = 0;\n\n   // Transferring the recording swaps its vectors so do this last\n   // replace the recording in g (this ADFun object)\n   g.play_.get_recording(rec, n + s);\n\n   // resize subgraph_info_\n   g.subgraph_info_.resize(\n      g.ind_taddr_.size(),   // n_ind\n      g.dep_taddr_.size(),   // n_dep\n      g.play_.num_var_op(),  // n_op\n      g.play_.num_var()      // n_var\n   );\n\n   // ------------------------------------------------------------------------\n   // Create the function a\n   // ------------------------------------------------------------------------\n\n   // start with a copy of f\n   a = *this;\n\n   // dependent variables in a(x)\n   CPPAD_ASSERT_UNKNOWN( s == f_abs_arg.size() );\n   a.dep_taddr_.resize(s);\n   for(size_t i = 0; i < s; i++)\n   {  a.dep_taddr_[i] = f_abs_res[i];\n      CPPAD_ASSERT_UNKNOWN( a.dep_taddr_[i] < num_var );\n   }\n\n   // free memory allocated for sparse Jacobian calculation\n   // (the results are no longer valid)\n   a.for_jac_sparse_pack_.resize(0, 0);\n   a.for_jac_sparse_set_.resize(0, 0);\n\n   // free taylor coefficient memory\n   a.taylor_.clear();\n   a.num_order_taylor_ = 0;\n   a.cap_order_taylor_ = 0;\n}\n\n// preprocessor symbols that are local to this file\n# undef CPPAD_J_PAR_EQUAL_REC\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/ad.hpp",
    "content": "# ifndef CPPAD_CORE_AD_HPP\n# define CPPAD_CORE_AD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// simple AD operations that must be defined for AD as well as base class\n# include <cppad/core/ordered.hpp>\n# include <cppad/core/identical.hpp>\n\n// define the template classes that are used by the AD template class\n# include <cppad/local/op_code_dyn.hpp>\n# include <cppad/local/op_code_var.hpp>\n# include <cppad/core/ad_type.hpp>\n# include <cppad/local/record/recorder.hpp>\n# include <cppad/local/play/player.hpp>\n# include <cppad/local/ad_tape.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n// tape_manage_enum\ntypedef enum {\n   new_tape_manage,\n   delete_tape_manage\n}\ntape_manage_enum;\n\ntemplate <class Base>\nclass AD {\nprivate :\n   // -----------------------------------------------------------------------\n   // Base type value for this object\n   Base value_;\n   //\n   // tape for this object\n   tape_id_t tape_id_;\n   //\n   // tape address for this object\n   // (when tape_id is current tape for AD<Base>)\n   addr_t taddr_;\n   //\n   // sub-type for this object\n   // (when tape_id is current tape for AD<Base>)\n   ad_type_enum ad_type_;\n   // -----------------------------------------------------------------------\n\n   // enable use of AD<Base> in parallel mode\n   template <class Type>\n   friend void parallel_ad(void);\n\n   // template friend functions where template parameter is not bound\n   template <class ADVector>\n   friend void Independent(\n      ADVector&  x              ,\n      size_t     abort_op_index ,\n      bool       record_compare ,\n      ADVector&  dynamic\n   );\n\n   // one argument functions\n   friend bool Constant  <Base> (const AD<Base>    &u);\n   friend bool Constant  <Base> (const VecAD<Base> &u);\n   //\n   friend bool Dynamic   <Base> (const AD<Base>    &u);\n   friend bool Dynamic   <Base> (const VecAD<Base> &u);\n   //\n   friend bool Parameter <Base> (const AD<Base>    &u);\n   friend bool Parameter <Base> (const VecAD<Base> &u);\n   //\n   friend bool Variable  <Base> (const AD<Base>    &u);\n   friend bool Variable  <Base> (const VecAD<Base> &u);\n   //\n   friend int  Integer   <Base> (const AD<Base>    &u);\n   friend AD   Var2Par   <Base> (const AD<Base>    &u);\n   //\n   friend unsigned short hash_code <Base> (const AD<Base> &u);\n   //\n   // power function\n   friend AD pow <Base>\n      (const AD<Base> &x, const AD<Base> &y);\n\n   // azmul function\n   friend AD azmul <Base>\n      (const AD<Base> &x, const AD<Base> &y);\n\n   // order determining functions, see ordered.hpp\n   friend bool GreaterThanZero   <Base> (const AD<Base> &x);\n   friend bool GreaterThanOrZero <Base> (const AD<Base> &x);\n   friend bool LessThanZero      <Base> (const AD<Base> &x);\n   friend bool LessThanOrZero    <Base> (const AD<Base> &x);\n   friend bool abs_geq           <Base>\n      (const AD<Base>& x, const AD<Base>& y);\n\n   // The identical property functions, see identical.hpp\n   friend bool IdenticalCon      <Base> (const AD<Base> &x);\n   friend bool IdenticalZero     <Base> (const AD<Base> &x);\n   friend bool IdenticalOne      <Base> (const AD<Base> &x);\n   friend bool IdenticalEqualCon <Base>\n      (const AD<Base> &x, const AD<Base> &y);\n\n   // EqualOpSeq function\n   friend bool EqualOpSeq <Base>\n      (const AD<Base> &u, const AD<Base> &v);\n\n   // NearEqual function\n   friend bool NearEqual <Base> (\n   const AD<Base> &x, const AD<Base> &y, const Base &r, const Base &a);\n\n   friend bool NearEqual <Base> (\n   const Base &x, const AD<Base> &y, const Base &r, const Base &a);\n\n   friend bool NearEqual <Base> (\n   const AD<Base> &x, const Base &y, const Base &r, const Base &a);\n\n   // CondExp function\n   friend AD<Base> CondExpOp  <Base> (\n      enum CompareOp  cop       ,\n      const AD<Base> &left      ,\n      const AD<Base> &right     ,\n      const AD<Base> &trueCase  ,\n      const AD<Base> &falseCase\n   );\n\n   // classes\n   friend class local::ADTape<Base>;\n   friend class local::dyn_recorder<Base>;\n   friend class local::recorder<Base>;\n   friend class ADFun<Base>;\n   friend class atomic_base<Base>;\n   friend class atomic_three<Base>;\n   friend class atomic_four<Base>;\n   friend class discrete<Base>;\n   friend class VecAD<Base>;\n   friend class VecAD_reference<Base>;\n\n   // arithematic binary operators\n   friend AD<Base> operator + <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   friend AD<Base> operator - <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   friend AD<Base> operator * <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   friend AD<Base> operator / <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n\n   // comparison operators\n   friend bool operator < <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   friend bool operator <= <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   friend bool operator > <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   friend bool operator >= <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   friend bool operator == <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   friend bool operator != <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n\n   // input operator\n   friend std::istream& operator >> <Base>\n      (std::istream &is, AD<Base> &x);\n\n   // output operations\n   friend std::ostream& operator << <Base>\n      (std::ostream &os, const AD<Base> &x);\n   friend void PrintFor <Base> (\n      const AD<Base>&    flag   ,\n      const char*        before ,\n      const AD<Base>&    var    ,\n      const char*        after\n   );\npublic:\n   // type of value\n   typedef Base value_type;\n\n   // implicit default constructor\n   AD(void);\n\n   // destructor\n   ~AD(void) { }\n\n   // use default implicit copy constructor\n   // AD(const AD &x);\n\n# ifdef CPPAD_FOR_TMB\n   // TMB would rather have implicit construction from double,\n   // CppAD uses default constructor and assignment to double instead.\n   AD(const double &d);\n# else\n   // implicit construction from base type\n   AD(const Base &b);\n# endif\n\n   // implicit constructor from VecAD<Base>::reference\n   AD(const VecAD_reference<Base> &x);\n\n   // explicit construction from some other type (deprecated)\n   template <class T> explicit AD(const T &t);\n\n   // conversion from AD to Base type\n   friend Base Value <Base> (const AD<Base> &x);\n\n   // use default assignment operator\n   // AD& operator=(const AD &x);\n\n   // assignment from base type\n   AD& operator=(const Base &b);\n\n   // assignment from VecAD<Base>::reference\n   AD& operator=(const VecAD_reference<Base> &x);\n\n   // assignment from some other type\n   template <class T> AD& operator=(const T &right);\n\n   // compound assignment operators\n   AD& operator += (const AD &right);\n   AD& operator -= (const AD &right);\n   AD& operator *= (const AD &right);\n   AD& operator /= (const AD &right);\n\n   // unary operators\n   AD operator +(void) const;\n   AD operator -(void) const;\n\n   // interface so these functions need not be friends\n   AD abs_me(void) const;\n   AD acos_me(void) const;\n   AD asin_me(void) const;\n   AD atan_me(void) const;\n   AD cos_me(void) const;\n   AD cosh_me(void) const;\n   AD exp_me(void) const;\n   AD fabs_me(void) const;\n   AD log_me(void) const;\n   AD sin_me(void) const;\n   AD sign_me(void) const;\n   AD sinh_me(void) const;\n   AD sqrt_me(void) const;\n   AD tan_me(void) const;\n   AD tanh_me(void) const;\n   AD asinh_me(void) const;\n   AD acosh_me(void) const;\n   AD atanh_me(void) const;\n   AD erf_me(bool complemnet) const;\n   AD expm1_me(void) const;\n   AD log1p_me(void) const;\n\n   // ----------------------------------------------------------\n   // static public member functions\n\n   // abort current AD<Base> recording\n   static void        abort_recording(void);\n\n   // set the maximum number of OpenMP threads (deprecated)\n   static void        omp_max_thread(size_t number);\n\n   // These functions declared public so can be accessed by user through\n   // a macro interface and are not intended for direct use.\n   // The macro interface is documented in bool_fun.hpp.\n   // Developer documentation for these functions is in  bool_fun.hpp\n   static bool UnaryBool(\n      bool FunName(const Base &x),\n      const AD<Base> &x\n   );\n   static bool BinaryBool(\n      bool FunName(const Base &x, const Base &y),\n      const AD<Base> &x , const AD<Base> &y\n   );\n\nprivate:\n   // -----------------------------------------------------------------\n   // Make this parameter a new variable\n   void make_variable(tape_id_t id,  addr_t taddr)\n   {  CPPAD_ASSERT_UNKNOWN( Parameter(*this) ); // currently a par\n      CPPAD_ASSERT_UNKNOWN( taddr > 0 );        // sure valid taddr\n\n      tape_id_ = id;\n      taddr_   = taddr;\n      ad_type_ = variable_enum;\n   }\n   // -----------------------------------------------------------------\n   // Make this parameter a new dynamic\n   void make_dynamic(tape_id_t id,  addr_t taddr)\n   {   CPPAD_ASSERT_UNKNOWN( Parameter(*this) ); // currently a par\n       CPPAD_ASSERT_UNKNOWN( taddr > 0 );        // sure valid taddr\n\n       tape_id_ = id;\n       taddr_   = taddr;\n       ad_type_ = dynamic_enum;\n   }\n   // ---------------------------------------------------------------\n   // tape linking functions\n   //\n   // not static\n   local::ADTape<Base>* tape_this(void) const;\n   //\n   // static\n   static tape_id_t*            tape_id_ptr(size_t thread);\n   static local::ADTape<Base>** tape_handle(size_t thread);\n   static local::ADTape<Base>*         tape_manage(tape_manage_enum job);\n   static local::ADTape<Base>*  tape_ptr(void);\n   static local::ADTape<Base>*  tape_ptr(tape_id_t tape_id);\n};\n// ---------------------------------------------------------------------------\n\n} // END_CPPAD_NAMESPACE\n\n// tape linking private functions\n# include <cppad/core/tape_link.hpp>\n\n// operations that expect the AD template class to be defined\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/ad_assign.hpp",
    "content": "# ifndef CPPAD_CORE_AD_ASSIGN_HPP\n# define CPPAD_CORE_AD_ASSIGN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n------------------------------------------------------------------------------\n\n{xrst_begin ad_assign}\n\nAD Assignment Operator\n######################\n\nSyntax\n******\n| *y* = *x*\n\nPurpose\n*******\nAssigns the value in *x* to the object *y* .\nIn either case,\n\nx\n*\nThe argument *x* has prototype\n\n   ``const`` *Type* & *x*\n\nwhere *Type* is\n``VecAD`` < *Base* >:: ``reference`` ,\n``AD`` < *Base* > ,\n*Base* ,\nor any type that has an implicit constructor of the form\n*Base* ( *x* ) .\n\ny\n*\nThe target *y* has prototype\n\n   ``AD`` < *Base* > *y*\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/ad_assign.cpp\n}\nThe file :ref:`ad_assign.cpp-name` contain examples and tests of these operations.\nIt test returns true if it succeeds and false otherwise.\n\n{xrst_end ad_assign}\n------------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*!\n\\file ad_assign.hpp\nAD<Base> constructors and and copy operations.\n*/\n\n/*!\n\\page AD_default_assign\nUse default assignment operator\nbecause they may be optimized better than the code below:\n\\code\ntemplate <class Base>\nAD<Base>& AD<Base>::operator=(const AD<Base> &right)\n{  value_    = right.value_;\n   tape_id_  = right.tape_id_;\n   taddr_    = right.taddr_;\n   ad_type_  = right.ad_type_;\n\n   return *this;\n}\n\\endcode\n*/\n\n/*!\nAssignment to Base type value.\n\n\\tparam Base\nBase type for this AD object.\n\n\\param b\nis the Base type value being assignment to this AD object.\nThe tape identifier will be an invalid tape identifier,\nso this object is initially a parameter.\n*/\ntemplate <class Base>\nAD<Base>& AD<Base>::operator=(const Base &b)\n{  value_   = b;\n   tape_id_ = 0;\n   //\n   CPPAD_ASSERT_UNKNOWN( ! ( Variable(*this) || Dynamic(*this) ) );\n   return *this;\n}\n\n/*!\nAssignment to an ADVec<Base> element drops the vector information.\n\n\\tparam Base\nBase type for this AD object.\n*/\ntemplate <class Base>\nAD<Base>& AD<Base>::operator=(const VecAD_reference<Base> &x)\n{  *this = x.ADBase();\n   CPPAD_ASSERT_UNKNOWN( ! Dynamic(*this) );\n   return *this;\n}\n\n/*!\nAssignment from any other type, converts to Base type, and then uses assignment\nfrom Base type.\n\n\\tparam Base\nBase type for this AD object.\n\n\\tparam T\nis the the type that is being assigned to AD<Base>.\nThere must be an assignment for Base from Type.\n\n\\param t\nis the object that is being assigned to an AD<Base> object.\n*/\ntemplate <class Base>\ntemplate <class T>\nAD<Base>& AD<Base>::operator=(const T &t)\n{  *this = Base(t);\n   CPPAD_ASSERT_UNKNOWN( ! ( Variable(*this) || Dynamic(*this) ) );\n   return *this;\n}\n\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/ad_binary.hpp",
    "content": "# ifndef CPPAD_CORE_AD_BINARY_HPP\n# define CPPAD_CORE_AD_BINARY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n-------------------------------------------------------------------------------\n{xrst_begin ad_binary}\n{xrst_spell\n   div\n}\n\nAD Binary Arithmetic Operators\n##############################\n\nSyntax\n******\n| *z* = *x* *Op* *y*\n\nPurpose\n*******\nPerforms arithmetic operations where either *x* or *y*\nhas type\n``AD`` < *Base* > or\n:ref:`VecAD@VecAD\\<Base>::reference` .\n\nOp\n**\nThe operator *Op* is one of the following\n\n.. csv-table::\n   :widths: auto\n\n   **Op**,**Meaning**\n   ``+``,*z* is *x* plus *y*\n   ``-``,*z* is *x* minus *y*\n   ``*``,*z* is *x* times *y*\n   ``/``,*z* is *x* divided by *y*\n\nBase\n****\nThe type *Base* is determined by the operand that\nhas type ``AD`` < *Base* > or ``VecAD`` < *Base* >:: ``reference`` .\n\nx\n*\nThe operand *x* has the following prototype\n\n   ``const`` *Type* & *x*\n\nwhere *Type* is\n``VecAD`` < *Base* >:: ``reference`` ,\n``AD`` < *Base* > ,\n*Base* , or\n``double`` .\n\ny\n*\nThe operand *y* has the following prototype\n\n   ``const`` *Type* & *y*\n\nwhere *Type* is\n``VecAD`` < *Base* >:: ``reference`` ,\n``AD`` < *Base* > ,\n*Base* , or\n``double`` .\n\nz\n*\nThe result *z* has the following prototype\n\n   *Type* *z*\n\nwhere *Type* is\n``AD`` < *Base* > .\n\nOperation Sequence\n******************\nThis is an :ref:`atomic_base<glossary@Operation@Atomic>`\n:ref:`glossary@AD of Base` operation\nand hence it is part of the current\nAD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n{xrst_toc_hidden\n   example/general/add.cpp\n   example/general/sub.cpp\n   example/general/mul.cpp\n   example/general/div.cpp\n}\n\nZero Special Cases\n******************\nSuppose that an AD *value* is\n:ref:`identically zero <base_identical@Identical@Identical Functions>` .\nThen the following results will be identically zero no matter\nwhat *other* is:\nvalue * other, other * value, value / other.\nThis may be unexpected when *other* is nan\n(or when it is zero in the division case).\nThis is closely related to the :ref:`azmul-name` function.\n\nExample\n*******\nThe following files contain examples and tests of these functions.\nEach test returns true if it succeeds and false otherwise.\n\n.. csv-table::\n   :widths: auto\n\n   add.cpp,:ref:`add.cpp-title`\n   sub.cpp,:ref:`sub.cpp-title`\n   mul.cpp,:ref:`mul.cpp-title`\n   div.cpp,:ref:`div.cpp-title`\n\nDerivative\n**********\nIf :math:`f` and :math:`g` are\n:ref:`Base functions<glossary@Base Function>`\n\nAddition\n========\n\n.. math::\n\n   \\D{[ f(x) + g(x) ]}{x} = \\D{f(x)}{x} + \\D{g(x)}{x}\n\nSubtraction\n===========\n\n.. math::\n\n   \\D{[ f(x) - g(x) ]}{x} = \\D{f(x)}{x} - \\D{g(x)}{x}\n\nMultiplication\n==============\n\n.. math::\n\n   \\D{[ f(x) * g(x) ]}{x} = g(x) * \\D{f(x)}{x} + f(x) * \\D{g(x)}{x}\n\nDivision\n========\n\n.. math::\n\n   \\D{[ f(x) / g(x) ]}{x} =\n      [1/g(x)] * \\D{f(x)}{x} - [f(x)/g(x)^2] * \\D{g(x)}{x}\n\n{xrst_end ad_binary}\n-----------------------------------------------------------------------------\n*/\n# include <cppad/core/add.hpp>\n# include <cppad/core/sub.hpp>\n# include <cppad/core/mul.hpp>\n# include <cppad/core/div.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/ad_ctor.hpp",
    "content": "# ifndef CPPAD_CORE_AD_CTOR_HPP\n# define CPPAD_CORE_AD_CTOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n------------------------------------------------------------------------------\n\n{xrst_begin ad_ctor}\n\nAD Constructors\n###############\n\nSyntax\n******\n| ``AD`` < *Base* > *ay* ()\n| ``AD`` < *Base* > *ay* ( *x* )\n\nPurpose\n*******\ncreates a new ``AD`` < *Base* > object *ay*\nand initializes it as a\nequal to *x* .\n\nx\n*\n\nimplicit\n========\nThere is an implicit constructor where *x* has prototype\n\n   ``const VecAD`` < *Base* >& *x*\n\nThere also is an implicit constructor where *x* has prototype\n\n   ``const`` *Base* & *x*\n\nIn this case, *ay* is a\n:ref:`constant parameter<glossary@Parameter@Constant>`\n\nexplicit\n========\nThere is an explicit constructor where *x* has prototype\n\n   ``const`` *Type* & *x*\n\nfor any type that has an explicit constructor of the form\n*Base* ( *x* ) .\nIn this case, *ay* is a\n:ref:`constant parameter<glossary@Parameter@Constant>`\n\nay\n**\nThe target *ay* has prototype\n\n   ``AD`` < *Base* > *ay*\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/ad_ctor.cpp\n}\nThe files :ref:`ad_ctor.cpp-name` contain examples and tests of these operations.\nIt test returns true if it succeeds and false otherwise.\n\n{xrst_end ad_ctor}\n------------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*!\n\\file ad_ctor.hpp\nAD<Base> constructors and and copy operations.\n*/\n\n/*!\n\\page AD_default_ctor\nUse default copy constructor\nbecause they may be optimized better than the code below:\n\\code\ntemplate <class Base>\nAD<Base>::AD(const AD &x)\n{\n   value_    = x.value_;\n   tape_id_  = x.tape_id_;\n   taddr_    = x.taddr_;\n   ad_type_  = x.ad_type_;\n\n   return;\n}\n\\endcode\n*/\n\n/*!\nDefault Constructor.\n\n\\tparam Base\nBase type for this AD object.\n*/\ntemplate <class Base>\nAD<Base>::AD(void)\n: value_()\n, tape_id_(0)\n, taddr_(0)\n, ad_type_(constant_enum)\n{ }\n\n// --------------------------------------------------------------------------\n# ifdef CPPAD_FOR_TMB\n/*!\nConstructor from double.\n\n\\param d\nis value corresponding to this AD object.\nThe tape identifier will be an invalid tape identifier,\nso this object is initially a parameter.\n\n\\par CPPAD_FOR_TMB\nThis constructor is defined when CPPAD_FOR_TMB is defined.\n*/\ntemplate <class Base>\nAD<Base>::AD(const double &d)\n: value_( Base(d) )\n, tape_id_(0)\n, taddr_(0)\n, ad_type_(constant_enum)\n{  // check that this is a parameter\n   CPPAD_ASSERT_UNKNOWN( Parameter(*this) );\n}\n// --------------------------------------------------------------------------\n# else\n// --------------------------------------------------------------------------\n/*!\nConstructor from Base type.\n\n\\tparam Base\nBase type for this AD object.\n\n\\param b\nis the Base type value corresponding to this AD object.\nThe tape identifier will be an invalid tape identifier,\nso this object is initially a parameter.\n\n\\par CPPAD_FOR_TMB\nThis constructor is defined when CPPAD_FOR_TMB is not defined.\n*/\ntemplate <class Base>\nAD<Base>::AD(const Base &b)\n: value_(b)\n, tape_id_(0)\n, taddr_(0)\n, ad_type_(constant_enum)\n{  // check that this is a parameter\n   CPPAD_ASSERT_UNKNOWN( Parameter(*this) );\n}\n# endif\n// --------------------------------------------------------------------------\n\n/*!\nConstructor from an ADVec<Base> element drops the vector information.\n\n\\tparam Base\nBase type for this AD object.\n*/\ntemplate <class Base>\nAD<Base>::AD(const VecAD_reference<Base> &x)\n{  *this = x.ADBase(); }\n\n/*!\nConstructor from any other type, converts to Base type, and uses constructor\nfrom Base type.\n\n\\tparam Base\nBase type for this AD object.\n\n\\tparam T\nis the the type that is being converted to AD<Base>.\nThere must be a constructor for Base from Type.\n\n\\param t\nis the object that is being converted from T to AD<Base>.\n*/\ntemplate <class Base>\ntemplate <class T>\nAD<Base>::AD(const T &t)\n: value_( Base(t) )\n, tape_id_(0)\n, taddr_(0)\n, ad_type_(constant_enum)\n{ }\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/ad_fun.hpp",
    "content": "# ifndef CPPAD_CORE_AD_FUN_HPP\n# define CPPAD_CORE_AD_FUN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin ADFun}\n\nADFun Objects\n#############\n\nPurpose\n*******\nAn AD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>`\nis stored in an ``ADFun`` object by its :ref:`fun_construct-name` .\nThe ``ADFun`` object can then be used to calculate function values,\nderivative values, and other values related to the corresponding function.\n\nContents\n********\n{xrst_toc_table\n   include/cppad/core/ad_fun.xrst\n   include/cppad/core/optimize.hpp\n   include/cppad/core/fun_check.hpp\n   include/cppad/core/check_for_nan.hpp\n   include/cppad/core/to_csrc.hpp\n}\n\n{xrst_end ADFun}\n*/\n# include <cppad/core/graph/cpp_graph.hpp>\n# include <cppad/local/subgraph/info.hpp>\n# include <cppad/local/graph/cpp_graph_op.hpp>\n# include <cppad/local/val_graph/val_type.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file ad_fun.hpp\nFile used to define the ADFun<Base> class.\n*/\n\n/*!\nClass used to hold function objects\n\n\\tparam Base\nA function object has a recording of <tt>AD<Base></tt> operations.\nIt does it calculations using Base operations.\n*/\n\n\ntemplate <class Base, class RecBase>\nclass ADFun {\n   // ADFun<Base> must be a friend of ADFun< AD<Base> > for base2ad to work.\n   template <class Base2, class RecBase2> friend class ADFun;\nprivate:\n   // ------------------------------------------------------------\n   // Private member variables\n   // ------------------------------------------------------------\n\n   /// name of this function (so far only json operations use this value)\n   std::string function_name_;\n\n   /// Did the previous optimization exceed the collision limit\n   bool exceed_collision_limit_;\n\n   /// Has this ADFun object been optimized\n   bool has_been_optimized_;\n\n   /// Check for nan's and report message to user (default value is true).\n   bool check_for_nan_;\n\n   /// If zero, ignoring comparison operators. Otherwise is the\n   /// compare change count at which to store the operator index.\n   size_t compare_change_count_;\n\n   /// If compare_change_count_ is zero, compare_change_number_ is also zero.\n   /// Otherwise, it is set to the number of comparison operations that had a\n   /// different result during the subsequent zero order forward.\n   size_t compare_change_number_;\n\n   /// If compare_change_count is zero, compare_change_op_index_ is also\n   /// zero. Otherwise it is the operator index for the comparison operator\n   //// that corresponded to the number changing from count-1 to count.\n   size_t compare_change_op_index_;\n\n   /// number of orders stored in taylor_\n   size_t num_order_taylor_;\n\n   /// maximum number of orders that will fit in taylor_\n   size_t cap_order_taylor_;\n\n   /// number of directions stored in taylor_\n   size_t num_direction_taylor_;\n\n   /// number of variables in the recording (play_)\n   size_t num_var_tape_;\n\n   /// tape address for the independent variables\n   local::pod_vector<size_t> ind_taddr_;\n\n   /// tape address and parameter flag for the dependent variables\n   local::pod_vector<size_t> dep_taddr_;\n\n   /// which dependent variables are actually parameters\n   local::pod_vector<bool> dep_parameter_;\n\n   /// which operations can be conditionally skipped\n   /// Set during forward pass of order zero\n   local::pod_vector<bool> cskip_op_;\n\n   /// Variable on the tape corresponding to each vecad load operation\n   /// (if zero, the operation corresponds to a parameter).\n   local::pod_vector<addr_t> load_op2var_;\n\n   /// results of the forward mode calculations\n   local::pod_vector_maybe<Base> taylor_;\n\n   /// used for subgraph reverse mode calculations.\n   /// Declared here to avoid reallocation for each call to subgraph_reverse.\n   /// Not in subgraph_info_ because it depends on Base.\n   local::pod_vector_maybe<Base> subgraph_partial_;\n\n   /// the operation sequence corresponding to this object\n   local::player<Base> play_;\n\n   /// subgraph information for this object\n   local::subgraph::subgraph_info subgraph_info_;\n\n   /// Packed results of the forward mode Jacobian sparsity calculations.\n   /// for_jac_sparse_pack_.n_set() != 0  implies other sparsity results\n   /// are empty\n   local::sparse::pack_setvec for_jac_sparse_pack_;\n\n   /// Set results of the forward mode Jacobian sparsity calculations\n   /// for_jac_sparse_set_.n_set() != 0  implies for_sparse_pack_ is empty.\n   local::sparse::list_setvec for_jac_sparse_set_;\n\n\n   // ------------------------------------------------------------\n   // Private member functions\n   // ------------------------------------------------------------\n\n   /// change the operation sequence corresponding to this object\n   template <class ADvector>\n   void Dependent(local::ADTape<Base> *tape, const ADvector &y);\n\n   // vector of bool version of ForSparseJac\n   // (doxygen in cppad/core/for_sparse_jac.hpp)\n   template <class SetVector>\n   void ForSparseJacCase(\n      bool               set_type  ,\n      bool               transpose ,\n      bool               dependency,\n      size_t             q         ,\n      const SetVector&   r         ,\n      SetVector&         s\n   );\n\n   // vector of std::set<size_t> version of ForSparseJac\n   // (doxygen in cppad/core/for_sparse_jac.hpp)\n   template <class SetVector>\n   void ForSparseJacCase(\n      const std::set<size_t>&  set_type  ,\n      bool                     transpose ,\n      bool                     dependency,\n      size_t                   q         ,\n      const SetVector&         r         ,\n      SetVector&               s\n   );\n\n   // vector of bool version of RevSparseJac\n   // (doxygen in cppad/core/rev_sparse_jac.hpp)\n   template <class SetVector>\n   void RevSparseJacCase(\n      bool               set_type  ,\n      bool               transpose ,\n      bool               dependency,\n      size_t             p         ,\n      const SetVector&   s         ,\n      SetVector&         r\n   );\n\n   // vector of std::set<size_t> version of RevSparseJac\n   // (doxygen in cppad/core/rev_sparse_jac.hpp)\n   template <class SetVector>\n   void RevSparseJacCase(\n      const std::set<size_t>&  set_type  ,\n      bool                     transpose ,\n      bool                     dependency,\n      size_t                   p         ,\n      const SetVector&         s         ,\n      SetVector&               r\n   );\n\n   // vector of bool version of ForSparseHes\n   // (doxygen in cppad/core/for_sparse_hes.hpp)\n   template <class SetVector>\n   void ForSparseHesCase(\n      bool               set_type  ,\n      const SetVector&   r         ,\n      const SetVector&   s         ,\n      SetVector&         h\n   );\n\n   // vector of std::set<size_t> version of ForSparseHes\n   // (doxygen in cppad/core/for_sparse_hes.hpp)\n   template <class SetVector>\n   void ForSparseHesCase(\n      const std::set<size_t>&  set_type  ,\n      const SetVector&         r         ,\n      const SetVector&         s         ,\n      SetVector&               h\n   );\n\n   // vector of bool version of RevSparseHes\n   // (doxygen in cppad/core/rev_sparse_hes.hpp)\n   template <class SetVector>\n   void RevSparseHesCase(\n      bool               set_type  ,\n      bool               transpose ,\n      size_t             q         ,\n      const SetVector&   s         ,\n      SetVector&         h\n   );\n\n   // vector of std::set<size_t> version of RevSparseHes\n   // (doxygen in cppad/core/rev_sparse_hes.hpp)\n   template <class SetVector>\n   void RevSparseHesCase(\n      const std::set<size_t>&  set_type  ,\n      bool                     transpose ,\n      size_t                   q         ,\n      const SetVector&         s         ,\n      SetVector&               h\n   );\n\n   // Forward mode version of SparseJacobian\n   // (doxygen in cppad/core/sparse_jacobian.hpp)\n   template <class BaseVector, class SetVector, class SizeVector>\n   size_t SparseJacobianFor(\n      const BaseVector&           x               ,\n              SetVector&            p_transpose     ,\n      const SizeVector&           row             ,\n      const SizeVector&           col             ,\n              BaseVector&           jac             ,\n              sparse_jacobian_work& work\n   );\n\n   // Reverse mode version of SparseJacobian\n   // (doxygen in cppad/core/sparse_jacobian.hpp)\n   template <class BaseVector, class SetVector, class SizeVector>\n   size_t SparseJacobianRev(\n      const BaseVector&           x               ,\n              SetVector&            p               ,\n      const SizeVector&           row             ,\n      const SizeVector&           col             ,\n              BaseVector&           jac             ,\n              sparse_jacobian_work& work\n   );\n\n   // combined sparse_list and sparse_pack version of SparseHessian\n   // (doxygen in cppad/core/sparse_hessian.hpp)\n   template <class BaseVector, class SetVector, class SizeVector>\n   size_t SparseHessianCompute(\n      const BaseVector&              x           ,\n      const BaseVector&              w           ,\n              SetVector&               sparsity    ,\n      const SizeVector&              row         ,\n      const SizeVector&              col         ,\n              BaseVector&              hes         ,\n              sparse_hessian_work&     work\n   );\n\npublic:\n   /// default constructor\n   ADFun(void);\n\n   /// copy constructor\n   ADFun(const ADFun& g) = delete;\n\n   // assignment operator\n   // (doxygen in cppad/core/fun_construct.hpp)\n   void operator=(const ADFun& f);\n\n   // swap\n   void swap(ADFun& f);\n\n   // move semenatics copy\n   ADFun(ADFun&& f);\n\n   // move semantics assignment\n   void operator=(ADFun&& f);\n\n   // create from Json or C++ AD graph\n   void from_json(const std::string& json);\n   void from_graph(const cpp_graph& graph_obj);\n   void from_graph(\n      const cpp_graph&    graph_obj  ,\n      const vector<bool>& dyn2var    ,\n      const vector<bool>& var2dyn\n   );\n\n   // convert function to  a\n   // C++ graph, Json graph, C source code\n   void to_graph(cpp_graph& graph_obj);\n   std::string to_json(void);\n   void to_csrc(std::ostream& os, const std::string& type);\n   //\n   // value graph routines\n   void fun2val( local::val_graph::tape_t<Base>& val_tape );\n   void val2fun(\n      const local::val_graph::tape_t<Base>&                   val_tape  ,\n      const CppAD::local::val_graph::Vector<size_t>&          dyn_ind   ,\n      const CppAD::local::val_graph::Vector<size_t>&          var_ind   ,\n      const CppAD::vectorBool&                                use_val\n   );\n   void val2fun(\n      const local::val_graph::tape_t<Base>&                   val_tape  ,\n      const CppAD::local::val_graph::Vector<size_t>&          dyn_ind   ,\n      const CppAD::local::val_graph::Vector<size_t>&          var_ind\n   );\n   void val_optimize(const std::string& options);\n\n   // create ADFun< AD<Base> > from this ADFun<Base>\n   // (doxygen in cppad/core/base2ad.hpp)\n   ADFun< AD<Base>, RecBase > base2ad(void) const;\n\n   /// sequence constructor\n   template <class ADvector>\n   ADFun(const ADvector &x, const ADvector &y);\n\n   /// destructor\n   ~ADFun(void);\n\n   /// set check_for_nan\n   void check_for_nan(bool value);\n\n   /// get check_for_nan\n   bool check_for_nan(void) const;\n\n   /// assign a new operation sequence\n   template <class ADvector>\n   void Dependent(const ADvector &x, const ADvector &y);\n\n   /// new_dynamic user API\n   template <class BaseVector>\n   void new_dynamic(const BaseVector& dynamic);\n\n   /// forward mode user API, one order multiple directions.\n   template <class BaseVector>\n   BaseVector Forward(size_t q, size_t r, const BaseVector& x);\n\n   /// forward mode user API, multiple orders one direction.\n   template <class BaseVector>\n   BaseVector Forward(\n      size_t q, const BaseVector& xq, std::ostream& s = std::cout\n   );\n\n   /// reverse mode sweep\n   template <class BaseVector>\n   BaseVector Reverse(size_t p, const BaseVector &v);\n\n   // forward Jacobian sparsity pattern\n   // (doxygen in cppad/core/for_sparse_jac.hpp)\n   template <class SetVector>\n   SetVector ForSparseJac(\n      size_t q, const SetVector &r, bool transpose = false,\n      bool dependency = false\n   );\n\n   // reverse Jacobian sparsity pattern\n   // (doxygen in cppad/core/rev_sparse_jac.hpp)\n   template <class SetVector>\n   SetVector RevSparseJac(\n      size_t q, const SetVector &s, bool transpose = false,\n      bool dependency = false\n   );\n\n   // subgraph_reverse: select domain\n   // (doxygen in cppad/core/subgraph_reverse.hpp)\n   template <class BoolVector>\n   void subgraph_reverse(\n      const BoolVector&                   select_domain\n   );\n\n   // subgraph_reverse: compute derivative\n   // (doxygen in cppad/core/subgraph_reverse.hpp)\n   template <class Addr, class BaseVector, class SizeVector>\n   void subgraph_reverse_helper(\n      size_t                               q         ,\n      size_t                               ell       ,\n      SizeVector&                          col       ,\n      BaseVector&                          dw\n   );\n\n   // subgraph_reverse: compute derivative\n   // (doxygen in cppad/core/subgraph_reverse.hpp)\n   template <class BaseVector, class SizeVector>\n   void subgraph_reverse(\n      size_t                               q         ,\n      size_t                               ell       ,\n      SizeVector&                          col       ,\n      BaseVector&                          dw\n   );\n\n   // subgraph_jac_rev: compute Jacobian\n   // (doxygen in cppad/core/subgraph_jac_rev.hpp)\n   template <class SizeVector, class BaseVector>\n   void subgraph_jac_rev(\n      const BaseVector&                    x         ,\n      sparse_rcv<SizeVector, BaseVector>&  subset\n   );\n\n   // subgraph_jac_rev: compute Jacobian\n   // (doxygen missing in cppad/core/subgraph_jac_rev.hpp)\n   template <class BoolVector, class SizeVector, class BaseVector>\n   void subgraph_jac_rev(\n      const BoolVector&                    select_domain ,\n      const BoolVector&                    select_range  ,\n      const BaseVector&                    x             ,\n      sparse_rcv<SizeVector, BaseVector>&  matrix_out\n   );\n\n\n   // compute sparse Jacobian using forward mode\n   // (doxygen in cppad/core/sparse_jac.hpp)\n   template <class SizeVector, class BaseVector>\n   size_t sparse_jac_for(\n      size_t                               group_max ,\n      const BaseVector&                    x         ,\n      sparse_rcv<SizeVector, BaseVector>&  subset    ,\n      const sparse_rc<SizeVector>&         pattern   ,\n      const std::string&                   coloring  ,\n      sparse_jac_work&                     work\n   );\n\n   // compute sparse Jacobian using reverse mode\n   // (doxygen in cppad/core/sparse_jac.hpp)\n   template <class SizeVector, class BaseVector>\n   size_t sparse_jac_rev(\n      const BaseVector&                    x        ,\n      sparse_rcv<SizeVector, BaseVector>&  subset   ,\n      const sparse_rc<SizeVector>&         pattern  ,\n      const std::string&                   coloring ,\n      sparse_jac_work&                     work\n   );\n\n   // compute sparse Hessian\n   // (doxygen in cppad/core/sparse_hes.hpp)\n   template <class SizeVector, class BaseVector>\n   size_t sparse_hes(\n      const BaseVector&                    x        ,\n      const BaseVector&                    w        ,\n      sparse_rcv<SizeVector, BaseVector>&  subset   ,\n      const sparse_rc<SizeVector>&         pattern  ,\n      const std::string&                   coloring ,\n      sparse_hes_work&                     work\n   );\n\n   // compute sparsity pattern using subgraphs\n   // (doxygen in cppad/core/subgraph_sparsity.hpp)\n   template <class BoolVector, class SizeVector>\n   void subgraph_sparsity(\n      const BoolVector&            select_domain    ,\n      const BoolVector&            select_range     ,\n      bool                         transpose        ,\n      sparse_rc<SizeVector>&       pattern_out\n   );\n\n\n   // forward mode Jacobian sparsity pattern\n   // (doxygen in cppad/core/for_jac_sparsity.hpp)\n   template <class SizeVector>\n   void for_jac_sparsity(\n      const sparse_rc<SizeVector>& pattern_in       ,\n      bool                         transpose        ,\n      bool                         dependency       ,\n      bool                         internal_bool    ,\n      sparse_rc<SizeVector>&       pattern_out\n   );\n\n   // reverse mode Jacobian sparsity pattern\n   // (doxygen in cppad/core/for_jac_sparsity.hpp)\n   template <class SizeVector>\n   void rev_jac_sparsity(\n      const sparse_rc<SizeVector>& pattern_in       ,\n      bool                         transpose        ,\n      bool                         dependency       ,\n      bool                         internal_bool    ,\n      sparse_rc<SizeVector>&       pattern_out\n   );\n\n   // reverse mode Hessian sparsity pattern\n   // (doxygen in cppad/core/rev_hes_sparsity.hpp)\n   template <class BoolVector, class SizeVector>\n   void rev_hes_sparsity(\n      const BoolVector&            select_range     ,\n      bool                         transpose        ,\n      bool                         internal_bool    ,\n      sparse_rc<SizeVector>&       pattern_out\n   );\n\n   // forward mode Hessian sparsity pattern\n   // (doxygen in cppad/core/for_hes_sparsity.hpp)\n   template <class BoolVector, class SizeVector>\n   void for_hes_sparsity(\n      const BoolVector&            select_domain    ,\n      const BoolVector&            select_range     ,\n      bool                         internal_bool    ,\n      sparse_rc<SizeVector>&       pattern_out\n   );\n\n   // forward mode Hessian sparsity pattern\n   // (see doxygen in cppad/core/for_sparse_hes.hpp)\n   template <class SetVector>\n   SetVector ForSparseHes(\n      const SetVector &r, const SetVector &s\n   );\n\n   // internal set sparsity version of ForSparseHes\n   // (used by checkpoint functions only)\n   void ForSparseHesCheckpoint(\n      vector<bool>&                 r         ,\n      vector<bool>&                 s         ,\n      local::sparse::list_setvec&   h\n   );\n\n   // reverse mode Hessian sparsity pattern\n   // (see doxygen in cppad/core/rev_sparse_hes.hpp)\n   template <class SetVector>\n   SetVector RevSparseHes(\n      size_t q, const SetVector &s, bool transpose = false\n   );\n\n   // internal set sparsity version of RevSparseHes\n   // (doxygen in cppad/core/rev_sparse_hes.hpp)\n   // (used by checkpoint functions only)\n   void RevSparseHesCheckpoint(\n      size_t                        q         ,\n      vector<bool>&                 s         ,\n      bool                          transpose ,\n      local::sparse::list_setvec&   h\n   );\n\n   // internal set sparsity version of RevSparseJac\n   // (doxygen in cppad/core/rev_sparse_jac.hpp)\n   // (used by checkpoint functions only)\n   void RevSparseJacCheckpoint(\n      size_t                        q          ,\n      const local::sparse::list_setvec&     r          ,\n      bool                          transpose  ,\n      bool                          dependency ,\n      local::sparse::list_setvec&   s\n   );\n\n   // internal set sparsity version of RevSparseJac\n   // (doxygen in cppad/core/for_sparse_jac.hpp)\n   // (used by checkpoint functions only)\n   void ForSparseJacCheckpoint(\n   size_t                             q          ,\n   const local::sparse::list_setvec&  r          ,\n   bool                               transpose  ,\n   bool                               dependency ,\n   local::sparse::list_setvec&        s\n   );\n\n   /// did previous optimization exceed the collision limit\n   bool exceed_collision_limit(void) const\n   {  return exceed_collision_limit_; }\n\n   /// amount of memory used for boolean Jacobain sparsity pattern\n   size_t size_forward_bool(void) const\n   {  return for_jac_sparse_pack_.memory(); }\n\n   /// free memory used for Jacobain sparsity pattern\n   void size_forward_bool(size_t zero)\n   {  CPPAD_ASSERT_KNOWN(\n         zero == 0,\n         \"size_forward_bool: argument not equal to zero\"\n      );\n      for_jac_sparse_pack_.resize(0, 0);\n   }\n\n   /// amount of memory used for vector of set Jacobain sparsity pattern\n   size_t size_forward_set(void) const\n   {  return for_jac_sparse_set_.memory(); }\n\n   /// free memory used for Jacobain sparsity pattern\n   void size_forward_set(size_t zero)\n   {  CPPAD_ASSERT_KNOWN(\n         zero == 0,\n         \"size_forward_bool: argument not equal to zero\"\n      );\n      for_jac_sparse_set_.resize(0, 0);\n   }\n\n   /// number of operators in the operation sequence\n   size_t size_op(void) const\n   {  return play_.num_var_op(); }\n\n   /// number of operator arguments in the operation sequence\n   size_t size_op_arg(void) const\n   {  return play_.num_var_arg(); }\n\n   /// amount of memory required for the operation sequence\n   size_t size_op_seq(void) const\n   {  return play_.size_op_seq(); }\n\n   /// amount of memory currently allocated for random access\n   /// of the operation sequence\n   size_t size_random(void) const\n   {  return play_.size_random(); }\n\n   /// number of parameters in the operation sequence\n   size_t size_par(void) const\n   {  return play_.num_par_all(); }\n\n   /// number of independent dynamic parameters\n   size_t size_dyn_ind(void) const\n   {  return play_.n_dyn_independent(); }\n\n   /// number of dynamic parameters\n   size_t size_dyn_par(void) const\n   {  return play_.num_dynamic_par(); }\n\n   /// number of dynamic parameters arguments\n   size_t size_dyn_arg(void) const\n   {  return play_.num_dynamic_arg(); }\n\n   /// number taylor coefficient orders calculated\n   size_t size_order(void) const\n   {  return num_order_taylor_; }\n\n   /// number taylor coefficient directions calculated\n   size_t size_direction(void) const\n   {  return num_direction_taylor_; }\n\n   /// number of characters in the operation sequence\n   size_t size_text(void) const\n   {  return play_.num_var_text(); }\n\n   /// number of variables in operation sequence\n   size_t size_var(void) const\n   {  return num_var_tape_; }\n\n   /// number of VecAD indices in the operation sequence\n   size_t size_VecAD(void) const\n   {  return play_.num_var_vec_ind(); }\n\n   /// set number of orders currently allocated (user API)\n   void capacity_order(size_t c);\n\n   /// set number of orders and directions currently allocated\n   void capacity_order(size_t c, size_t r);\n\n   /// number of variables in conditional expressions that can be skipped\n   size_t number_skip(void);\n\n   /// number of independent variables\n   size_t Domain(void) const\n   {  return ind_taddr_.size(); }\n\n   /// number of dependent variables\n   size_t Range(void) const\n   {  return dep_taddr_.size(); }\n\n   /// set and get function name\n   void function_name_set(const std::string& function_name)\n   {  function_name_ = function_name; }\n   std::string function_name_get(void)\n   {  return function_name_; }\n\n   /// is variable a parameter\n   bool Parameter(size_t i)\n   {  CPPAD_ASSERT_KNOWN(\n         i < dep_taddr_.size(),\n         \"Argument to Parameter is >= dimension of range space\"\n      );\n      return dep_parameter_[i];\n   }\n\n   /// Deprecated: number of comparison operations that changed\n   /// for the previous zero order forward (than when function was recorded)\n   size_t CompareChange(void) const\n   {  return compare_change_number_; }\n\n   /// count as which to store operator index\n   void compare_change_count(size_t count)\n   {  compare_change_count_    = count;\n      compare_change_number_   = 0;\n      compare_change_op_index_ = 0;\n   }\n\n   /// number of comparison operations that changed\n   size_t compare_change_number(void) const\n   {  return compare_change_number_; }\n\n   /// operator index for the count-th  comparison change\n   size_t compare_change_op_index(void) const\n   {  if( has_been_optimized_ )\n         return 0;\n      return compare_change_op_index_;\n   }\n\n   /// calculate entire Jacobian\n   template <class BaseVector>\n   BaseVector Jacobian(const BaseVector &x);\n\n   /// calculate Hessian for one component of f\n   template <class BaseVector>\n   BaseVector Hessian(const BaseVector &x, const BaseVector &w);\n   template <class BaseVector>\n   BaseVector Hessian(const BaseVector &x, size_t i);\n\n   /// forward mode calculation of partial w.r.t one domain component\n   template <class BaseVector>\n   BaseVector ForOne(\n      const BaseVector   &x ,\n      size_t              j );\n\n   /// reverse mode calculation of derivative of one range component\n   template <class BaseVector>\n   BaseVector RevOne(\n      const BaseVector   &x ,\n      size_t              i );\n\n   /// forward mode calculation of a subset of second order partials\n   template <class BaseVector, class SizeVector_t>\n   BaseVector ForTwo(\n      const BaseVector   &x ,\n      const SizeVector_t &J ,\n      const SizeVector_t &K );\n\n   /// reverse mode calculation of a subset of second order partials\n   template <class BaseVector, class SizeVector_t>\n   BaseVector RevTwo(\n      const BaseVector   &x ,\n      const SizeVector_t &I ,\n      const SizeVector_t &J );\n\n   /// calculate sparse Jacobians\n   template <class BaseVector>\n   BaseVector SparseJacobian(\n      const BaseVector &x\n   );\n   template <class BaseVector, class SetVector>\n   BaseVector SparseJacobian(\n      const BaseVector &x ,\n      const SetVector  &p\n   );\n   template <class BaseVector, class SetVector, class SizeVector>\n   size_t SparseJacobianForward(\n      const BaseVector&     x     ,\n      const SetVector&      p     ,\n      const SizeVector&     r     ,\n      const SizeVector&     c     ,\n      BaseVector&           jac   ,\n      sparse_jacobian_work& work\n   );\n   template <class BaseVector, class SetVector, class SizeVector>\n   size_t SparseJacobianReverse(\n      const BaseVector&     x    ,\n      const SetVector&      p    ,\n      const SizeVector&     r    ,\n      const SizeVector&     c    ,\n      BaseVector&           jac  ,\n      sparse_jacobian_work& work\n   );\n\n   /// calculate sparse Hessians\n   template <class BaseVector>\n   BaseVector SparseHessian(\n      const BaseVector&    x  ,\n      const BaseVector&    w\n   );\n   template <class BaseVector, class BoolVector>\n   BaseVector SparseHessian(\n      const BaseVector&    x  ,\n      const BaseVector&    w  ,\n      const BoolVector&    p\n   );\n   template <class BaseVector, class SetVector, class SizeVector>\n   size_t SparseHessian(\n      const BaseVector&    x   ,\n      const BaseVector&    w   ,\n      const SetVector&     p   ,\n      const SizeVector&    r   ,\n      const SizeVector&    c   ,\n      BaseVector&          hes ,\n      sparse_hessian_work& work\n   );\n\n   // Optimize the tape\n   // (see doxygen documentation in optimize.hpp)\n   void optimize( const std::string& options = \"\" );\n\n   // create abs-normal representation of the function f(x)\n   void abs_normal_fun( ADFun& g, ADFun& a ) const;\n\n   // clear all subgraph information\n   void clear_subgraph(void);\n   // ------------------- Deprecated -----------------------------\n\n   /// deprecated: assign a new operation sequence\n   template <class ADvector>\n   void Dependent(const ADvector &y);\n\n   /// Deprecated: number of variables in operation sequence\n   size_t Size(void) const\n   {  return num_var_tape_; }\n\n   /// Deprecated: # taylor_ coefficients currently stored\n   /// (per variable,direction)\n   size_t Order(void) const\n   {  return num_order_taylor_ - 1; }\n\n   /// Deprecated: amount of memory for this object\n   /// Note that an approximation is used for the std::set<size_t> memory\n   size_t Memory(void) const\n   {  size_t pervar  = cap_order_taylor_ * sizeof(Base)\n      + for_jac_sparse_pack_.memory()\n      + for_jac_sparse_set_.memory();\n      size_t total   = num_var_tape_  * pervar;\n      total         += play_.size_op_seq();\n      total         += play_.size_random();\n      total         += subgraph_info_.memory();\n      return total;\n   }\n\n   /// Deprecated: # taylor_ coefficient orderss stored\n   /// (per variable,direction)\n   size_t taylor_size(void) const\n   {  return num_order_taylor_; }\n\n   /// Deprecated: Does this AD operation sequence use\n   /// VecAD<Base>::reference operands\n   bool use_VecAD(void) const\n   {  return play_.num_var_vec_ind() > 0; }\n\n   /// Deprecated: # taylor_ coefficient orders calculated\n   /// (per variable,direction)\n   size_t size_taylor(void) const\n   {  return num_order_taylor_; }\n\n   /// Deprecated: set number of orders currently allocated\n   /// (per variable,direction)\n   void capacity_taylor(size_t per_var);\n};\n// ---------------------------------------------------------------------------\n\n} // END_CPPAD_NAMESPACE\n\n// non-user interfaces\n# include <cppad/local/sweep/forward_0.hpp>\n# include <cppad/local/sweep/forward_any.hpp>\n# include <cppad/local/sweep/forward_dir.hpp>\n# include <cppad/local/sweep/reverse.hpp>\n# include <cppad/local/sweep/for_jac.hpp>\n# include <cppad/local/sweep/rev_jac.hpp>\n# include <cppad/local/sweep/rev_hes.hpp>\n# include <cppad/local/sweep/for_hes.hpp>\n# include <cppad/core/graph/from_graph.hpp>\n# include <cppad/core/graph/to_graph.hpp>\n\n// user interfaces\n# include <cppad/core/parallel_ad.hpp>\n# include <cppad/core/independent/independent.hpp>\n# include <cppad/core/dependent.hpp>\n# include <cppad/core/fun_construct.hpp>\n# include <cppad/core/base2ad.hpp>\n# include <cppad/core/abort_recording.hpp>\n# include <cppad/core/fun_eval.hpp>\n# include <cppad/core/drivers.hpp>\n# include <cppad/core/fun_check.hpp>\n# include <cppad/core/omp_max_thread.hpp>\n# include <cppad/core/optimize.hpp>\n# include <cppad/core/abs_normal_fun.hpp>\n# include <cppad/core/graph/from_json.hpp>\n# include <cppad/core/graph/to_json.hpp>\n# include <cppad/core/to_csrc.hpp>\n\n// 2DO: move to core directory\n# include <cppad/local/val_graph/val_optimize.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/ad_io.hpp",
    "content": "# ifndef CPPAD_CORE_AD_IO_HPP\n# define CPPAD_CORE_AD_IO_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin ad_input}\n{xrst_spell\n   istream\n}\n\nAD Input Stream Operator\n########################\n\nSyntax\n******\n| *is* >> *x*\n\nPurpose\n*******\nSets *x* to a :ref:`glossary@Parameter`\nwith value *b* corresponding to\n\n   *is* >> *b*\n\nwhere *b* is a *Base* object.\nIt is assumed that this *Base* input operation returns\na reference to *is* .\n\nis\n**\nThe operand *is* has prototype\n\n   ``std::istream&`` *is*\n\nx\n*\nThe operand *x* has one of the following prototypes\n\n   ``AD`` < *Base* >& *x*\n\nResult\n******\nThe result of this operation can be used as a reference to *is* .\nFor example, if the operand *y* has prototype\n\n   ``AD`` < *Base* > *y*\n\nthen the syntax\n\n   *is* >> *x* >> *y*\n\nwill first read the *Base* value of *x* from *is* ,\nand then read the *Base* value to *y* .\n\nOperation Sequence\n******************\nThe result of this operation is not an\n:ref:`glossary@AD of Base` object.\nThus it will not be recorded as part of an\nAD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/ad_input.cpp\n}\nThe file\n:ref:`ad_input.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end ad_input}\n------------------------------------------------------------------------------\n{xrst_begin ad_output}\n{xrst_spell\n   ostream\n}\n\nAD Output Stream Operator\n#########################\n\nSyntax\n******\n*os* << *x*\n\nSee Also\n********\n:ref:`PrintFor-name`\n\nPurpose\n*******\nWrites the *Base* value, corresponding to *x* ,\nto the output stream *os* .\n\nAssumption\n**********\nIf *b* is a *Base* object,\n\n   *os* << *b*\n\nreturns a reference to *os* .\n\nos\n**\nThe operand *os* has prototype\n\n   ``std::ostream&`` *os*\n\nx\n*\nThe operand *x* has one of the following prototypes\n\n| |tab| ``const AD`` < *Base* >& *x*\n| |tab| ``const VecAD`` < *Base* >:: ``reference&`` *x*\n\nResult\n******\nThe result of this operation can be used as a reference to *os* .\nFor example, if the operand *y* has prototype\n\n   ``AD`` < *Base* > *y*\n\nthen the syntax\n\n   *os* << *x* << *y*\n\nwill output the value corresponding to *x*\nfollowed by the value corresponding to *y* .\n\nOperation Sequence\n******************\nThe result of this operation is not an\n:ref:`glossary@AD of Base` object.\nThus it will not be recorded as part of an\nAD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/ad_output.cpp\n}\nThe file\n:ref:`ad_output.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end ad_output}\n------------------------------------------------------------------------------\n*/\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file ad_io.hpp\nAD<Base> input and output stream operators.\n*/\n// ---------------------------------------------------------------------------\n/*!\nRead an AD<Base> object from an input stream.\n\n\\tparam Base\nBase type for the AD object.\n\n\\param is [in,out]\nIs the input stream from which that value is read.\n\n\\param x [out]\nis the object that is being set to a value.\nUpone return, x.value_ is read from the input stream\nand x.tape_is_ is zero; i.e., x is a parameter.\n*/\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nstd::istream& operator >> (std::istream& is, AD<Base>& x)\n{  // like assignment to a base type value\n   x.tape_id_ = 0;\n   CPPAD_ASSERT_UNKNOWN( Parameter(x) );\n   return (is >> x.value_);\n}\n// ---------------------------------------------------------------------------\n/*!\nWrite an AD<Base> object to an output stream.\n\n\\tparam Base\nBase type for the AD object.\n\n\\param os [in,out]\nIs the output stream to which that value is written.\n\n\\param x\nis the object that is being written to the output stream.\nThis is equivalent to writing x.value_ to the output stream.\n*/\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nstd::ostream& operator << (std::ostream &os, const AD<Base> &x)\n{  return (os << x.value_); }\n// ---------------------------------------------------------------------------\n/*!\nWrite a VecAD_reference<Base> object to an output stream.\n\n\\tparam Base\nBase type for the VecAD_reference object.\n\n\\param os [in,out]\nIs the output stream to which that value is written.\n\n\\param x\nis the element of the VecAD object that is being written to the output stream.\nThis is equivalent to writing the corresponding Base value to the stream.\n*/\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nstd::ostream& operator << (std::ostream &os, const VecAD_reference<Base> &x)\n{  return (os << x.ADBase()); }\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/ad_to_string.hpp",
    "content": "# ifndef CPPAD_CORE_AD_TO_STRING_HPP\n# define CPPAD_CORE_AD_TO_STRING_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin ad_to_string}\n\nConvert An AD or Base Type to String\n####################################\n\nSyntax\n******\n| *s* = ``to_string`` ( *value* ) .\n\nSee Also\n********\n:ref:`to_string-name` , :ref:`base_to_string-name`\n\nvalue\n*****\nThe argument *value* has prototype\n\n| |tab| ``const AD`` < *Base* >& *value*\n| |tab| ``const`` *Base* & *value*\n\nwhere *Base* is a type that supports the\n:ref:`base_to_string-name` type requirement.\n\ns\n*\nThe return value has prototype\n\n   ``std::string`` *s*\n\nand contains a representation of the specified *value* .\nIf *value* is an AD type,\nthe result has the same precision as for the *Base* type.\n\nExample\n*******\nThe file :ref:`to_string.cpp-name`\nincludes an example and test of ``to_string`` with AD types.\n\n{xrst_end ad_to_string}\n*/\n# include <cppad/utility/to_string.hpp>\n# include <cppad/core/ad.hpp>\n\nnamespace CppAD {\n\n   // Template definition is in cppad/utility/to_string.hpp.\n   // Partial specialzation for AD<Base> types\n   template<class Base>\n   struct to_string_struct< CppAD::AD<Base> >\n   {  std::string operator()(const CppAD::AD<Base>& value)\n      {  to_string_struct<Base> ts;\n         return ts( Value( Var2Par( value ) ) ); }\n   };\n\n}\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/ad_type.hpp",
    "content": "# ifndef CPPAD_CORE_AD_TYPE_HPP\n# define CPPAD_CORE_AD_TYPE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/is_pod.hpp>\n\n# ifdef NDEBUG\n# define CPPAD_ASSERT_AD_TYPE(ad_obj)\n# else\n# define CPPAD_ASSERT_AD_TYPE(ad_obj)               \\\n   switch(ad_obj.ad_type_)                          \\\n   {  case constant_enum:                           \\\n      CPPAD_ASSERT_UNKNOWN( ad_obj.tape_id_ == 0 ); \\\n      break;                                        \\\n                                                    \\\n      case dynamic_enum:                            \\\n      case variable_enum:                           \\\n      break;                                        \\\n                                                    \\\n      default:                                      \\\n      CPPAD_ASSERT_UNKNOWN(false);                  \\\n   }                                                \\\n   CPPAD_ASSERT_UNKNOWN(                            \\\n      ad_obj.tape_id_ == 0 ||                       \\\n      ad_obj.ad_type_ == dynamic_enum ||            \\\n      ad_obj.ad_type_ == variable_enum              \\\n   );\n# endif\n\n\nnamespace CppAD {\n   // BEGIN TYPEDEF\n   typedef enum {\n      identical_zero_enum,      // identically zero\n      constant_enum,            // constant parameter\n      dynamic_enum,             // dynamic parameter\n      variable_enum,            // variable\n      number_ad_type_enum       // number of valid values for type_ad_enum\n   } ad_type_enum;\n   // END TYPEDEF\n\n   // BEGIN IS_POD\n   namespace local {\n      template <> inline bool\n      is_pod<ad_type_enum>(void) { return true; }\n   }\n   // END IS_POD\n}\n\n\n/*\n{xrst_begin ad_type_enum dev}\n{xrst_spell\n   typedef\n}\n\nType of AD an Object\n####################\n\ntypedef\n*******\nThis typedef is in the ``CppAD`` namespace:\n{xrst_literal\n   // BEGIN TYPEDEF\n   // END TYPEDEF\n}\n\nis_pod\n******\nThe following informs :ref:`is_pod-name` that this is plain old data.\n{xrst_literal\n   // BEGIN IS_POD\n   // END IS_POD\n}\n\nAtomic Function\n***************\nOnly some of the values are valid for the user atomic function API; see\n:ref:`atomic_three<atomic_three_define@ad_type>` and\n:ref:`atomic_four<atomic_four_for_type@ad_type>` .\n\nASSERT_AD_TYPE\n**************\nIf *ad_obj* is an ``AD`` < *Base* > object, the syntax\n\n   ``CPPAD_ASSERT_AD_TYPE`` ( *ad_obj* )\n\ncheck that *ad_obj* satisfies the following conditions:\n\n#. *ad_obj* . ``ad_type_`` is one of the following:\n   ``constant_enum`` , ``dynamic_enum`` , ``variable_enum`` .\n#. *ad_obj* . ``ad_type_`` is ``constant_enum`` , then\n   *ad_obj* . ``tape_id_`` == 0 .\n\n{xrst_end ad_type_enum}\n*/\n\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/ad_valued.hpp",
    "content": "# ifndef CPPAD_CORE_AD_VALUED_HPP\n# define CPPAD_CORE_AD_VALUED_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin ADValued}\n\nAD Valued Operations and Functions\n##################################\n\n{xrst_comment atomic.omh includes atomic_two.hpp}\n\nContents\n********\n{xrst_toc_table\n   include/cppad/core/arithmetic.hpp\n   include/cppad/core/standard_math.hpp\n   include/cppad/core/cond_exp.hpp\n   include/cppad/core/discrete/user.xrst\n   include/cppad/core/numeric_limits.hpp\n   include/cppad/core/atomic/atomic.xrst\n}\n\n{xrst_end ADValued}\n*/\n\n// include MathOther.h after CondExp.h because some MathOther.h routines use\n// CondExp.h and CondExp.h is not sufficiently declared in Declare.h\n\n# include <cppad/core/arithmetic.hpp>\n# include <cppad/core/standard_math.hpp>\n# include <cppad/core/azmul.hpp>\n# include <cppad/core/cond_exp.hpp>\n# include <cppad/core/discrete/discrete.hpp>\n# include <cppad/core/atomic/four/atomic.hpp>\n# include <cppad/core/atomic/three/atomic.hpp>\n# include <cppad/core/atomic/four/atomic.hpp>\n# include <cppad/core/chkpoint_two/chkpoint_two.hpp>\n# include <cppad/core/atomic/two/atomic.hpp>\n# include <cppad/core/atomic/one/atomic.hpp>\n# include <cppad/core/chkpoint_one/chkpoint_one.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/add.hpp",
    "content": "# ifndef CPPAD_CORE_ADD_HPP\n# define CPPAD_CORE_ADD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nAD<Base> operator + (const AD<Base> &left , const AD<Base> &right)\n{\n   // compute the Base part of this AD object\n   AD<Base> result;\n   result.value_  = left.value_ + right.value_;\n   CPPAD_ASSERT_UNKNOWN( Parameter(result) );\n\n   // check if there is a recording in progress\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if left and right tapes match\n   bool match_left  = left.tape_id_  == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n\n   // check if left and right are dynamic parameters\n   bool dyn_left  = match_left  & (left.ad_type_ == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if left and right are variables\n   bool var_left  = match_left  & (left.ad_type_ != dynamic_enum);\n   bool var_right = match_right & (right.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      left.tape_id_ == right.tape_id_ || ! match_left || ! match_right ,\n      \"Add: AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_left )\n   {  if( var_right )\n      {  // result = variable + variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AddvvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AddvvOp) == 2 );\n\n         // put operand addresses in tape\n         tape->Rec_.PutArg(left.taddr_, right.taddr_);\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::AddvvOp);\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n      else if( (! dyn_right) && IdenticalZero(right.value_) )\n      {  // result = variable + 0\n         result.make_variable(left.tape_id_, left.taddr_);\n      }\n      else\n      {  // result = variable  + parameter\n         //        = parameter + variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AddpvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AddpvOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = right.taddr_;\n         if( ! dyn_right )\n            p = tape->Rec_.put_con_par(right.value_);\n         tape->Rec_.PutArg(p, left.taddr_);\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::AddpvOp);\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n   }\n   else if( var_right )\n   {  if( (! dyn_left) && IdenticalZero(left.value_) )\n      {  // result = 0 + variable\n         result.make_variable(right.tape_id_, right.taddr_);\n      }\n      else\n      {  // result = parameter + variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AddpvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AddpvOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = left.taddr_;\n         if( ! dyn_left )\n            p = tape->Rec_.put_con_par(left.value_);\n         tape->Rec_.PutArg(p, right.taddr_);\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::AddpvOp);\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n   }\n   else if( dyn_left | dyn_right )\n   {  if( (! dyn_left) && IdenticalZero(left.value_) )\n      {\n         result.make_dynamic(right.tape_id_, right.taddr_);\n      }\n      else if( (! dyn_right) && IdenticalZero(right.value_) )\n      {\n         result.make_dynamic(left.tape_id_, left.taddr_);\n      }\n      else \n      {  \n         addr_t arg0 = left.taddr_;\n         addr_t arg1 = right.taddr_;\n         if( ! dyn_left )\n         arg0 = tape->Rec_.put_con_par(left.value_);\n         if( ! dyn_right )\n         arg1 = tape->Rec_.put_con_par(right.value_);\n         //\n         // parameters with a dynamic parameter result\n         result.taddr_   = tape->Rec_.put_dyn_par(\n            result.value_, local::add_dyn,   arg0, arg1\n         );\n         result.tape_id_ = tape_id;\n         result.ad_type_ = dynamic_enum;\n      }\n   }\n   return result;\n}\n\n// convert other cases into the case above\nCPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(+)\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/add_eq.hpp",
    "content": "# ifndef CPPAD_CORE_ADD_EQ_HPP\n# define CPPAD_CORE_ADD_EQ_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nAD<Base>& AD<Base>::operator += (const AD<Base> &right)\n{\n   // compute the Base part\n   Base left;\n   left    = value_;\n   value_ += right.value_;\n\n   // check if there is a recording in progress\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return *this;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if left and right tapes match\n   bool match_left  = tape_id_       == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n\n   // check if left and right are dynamic parameters\n   bool dyn_left  = match_left  & (ad_type_ == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if left and right are variables\n   bool var_left  = match_left  & (ad_type_ != dynamic_enum);\n   bool var_right = match_right & (right.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      tape_id_ == right.tape_id_ || ! match_left || ! match_right ,\n      \"+= : AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_left )\n   {  if( var_right )\n      {  // this = variable + variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AddvvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AddvvOp) == 2 );\n\n         // put operand addresses in tape\n         tape->Rec_.PutArg(taddr_, right.taddr_);\n         // put operator in the tape\n         taddr_ = tape->Rec_.PutOp(local::AddvvOp);\n         // check that this is a variable\n         CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id );\n         CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum);\n      }\n      else if( dyn_right | (! IdenticalZero(right.value_) ) )\n      {  // this = variable  + parameter\n         //      = parameter + variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AddpvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AddpvOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = right.taddr_;\n         if( ! dyn_right )\n            p = tape->Rec_.put_con_par(right.value_);\n         tape->Rec_.PutArg(p, taddr_);\n         // put operator in the tape\n         taddr_ = tape->Rec_.PutOp(local::AddpvOp);\n         // check that this is a variable\n         CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id );\n         CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum);\n      }\n   }\n   else if( var_right  )\n   {  if( (! dyn_left) && IdenticalZero(left) )\n      {  // this = 0 + right\n         make_variable(right.tape_id_, right.taddr_);\n      }\n      else\n      {  // this = parameter + variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AddpvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AddpvOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = taddr_;\n         if( ! dyn_left )\n            p = tape->Rec_.put_con_par(left);\n         tape->Rec_.PutArg(p, right.taddr_);\n\n         // put operator in the tape\n         taddr_ = tape->Rec_.PutOp(local::AddpvOp);\n\n         // make this a variable\n         tape_id_ = tape_id;\n         ad_type_ = variable_enum;\n      }\n   }\n   else if( dyn_left | dyn_right )\n   {  if( (! dyn_right) && IdenticalZero(right.value_) )\n      {   // this is left += 0, so do nothing\n      }\n      else if( (! dyn_left) && IdenticalZero(left))\n      {   // this is 0 += right\n         make_dynamic(right.tape_id_, right.taddr_);\n      } \n      else\n      {\n         addr_t arg0 = taddr_;\n         addr_t arg1 = right.taddr_;\n         if( ! dyn_left )\n         arg0 = tape->Rec_.put_con_par(left);\n         if( ! dyn_right )\n         arg1 = tape->Rec_.put_con_par(right.value_);\n         //\n         // parameters with a dynamic parameter results\n         taddr_ = tape->Rec_.put_dyn_par(\n            value_, local::add_dyn, arg0, arg1\n         );\n         tape_id_ = tape_id;\n         ad_type_ = dynamic_enum;\n      }\n   }\n   return *this;\n}\n\nCPPAD_FOLD_ASSIGNMENT_OPERATOR(+=)\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/arithmetic.hpp",
    "content": "# ifndef CPPAD_CORE_ARITHMETIC_HPP\n# define CPPAD_CORE_ARITHMETIC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n-------------------------------------------------------------------------------\n{xrst_begin Arithmetic}\n\nAD Arithmetic Operators and Compound Assignments\n################################################\n\nContents\n********\n{xrst_toc_table\n   include/cppad/core/unary_plus.hpp\n   include/cppad/core/unary_minus.hpp\n   include/cppad/core/ad_binary.hpp\n   include/cppad/core/compound_assign.hpp\n}\n\n{xrst_end Arithmetic}\n-------------------------------------------------------------------------------\n*/\n# include <cppad/core/unary_plus.hpp>\n# include <cppad/core/unary_minus.hpp>\n# include <cppad/core/ad_binary.hpp>\n# include <cppad/core/compound_assign.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atan2.hpp",
    "content": "# ifndef CPPAD_CORE_ATAN2_HPP\n# define CPPAD_CORE_ATAN2_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n-------------------------------------------------------------------------------\n{xrst_begin atan2}\n\nAD Two Argument Inverse Tangent Function\n########################################\n\nSyntax\n******\n| *theta* = ``atan2`` ( *y* , *x* )\n\nPurpose\n*******\nDetermines an angle :math:`\\theta \\in [ - \\pi , + \\pi ]`\nsuch that\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      \\sin ( \\theta )  & = & y / \\sqrt{ x^2 + y^2 }  \\\\\n      \\cos ( \\theta )  & = & x / \\sqrt{ x^2 + y^2 }\n   \\end{eqnarray}\n\ny\n*\nThe argument *y* has one of the following prototypes\n\n| |tab| ``const AD`` < *Base* >               & *y*\n| |tab| ``const VecAD`` < *Base* >:: ``reference &`` *y*\n\nx\n*\nThe argument *x* has one of the following prototypes\n\n| |tab| ``const AD`` < *Base* >               & *x*\n| |tab| ``const VecAD`` < *Base* >:: ``reference &`` *x*\n\ntheta\n*****\nThe result *theta* has prototype\n\n   ``AD`` < *Base* > *theta*\n\nOperation Sequence\n******************\nThe AD of *Base*\noperation sequence used to calculate *theta* is\n:ref:`glossary@Operation@Independent`\nof *x* and *y* .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/atan2.cpp\n}\nThe file\n:ref:`atan2.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end atan2}\n-------------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN CppAD namespace\n\ninline float atan2(float x, float y)\n{  return std::atan2(x, y); }\n\ninline double atan2(double x, double y)\n{  return std::atan2(x, y); }\n\n// The code below is used as an example by the CondExp documentation.\n// BEGIN CondExp\ntemplate <class Base>\nAD<Base> atan2 (const AD<Base> &y, const AD<Base> &x)\n{  //\n   // zero, pi2, pi\n   AD<Base> zero(0.);\n   AD<Base> pi2(2. * atan(1.));\n   AD<Base> pi(2. * pi2);\n   //\n   // abs_x, abs_y\n   // Not using fabs because its derivative is zero at zero\n   AD<Base> abs_x = CondExpGe(x, zero, x, -x);\n   AD<Base> abs_y = CondExpGe(y, zero, y, -y);\n   //\n   // first\n   // This is the result for first quadrant: x >= 0 , y >= 0\n   AD<Base> alpha = atan(abs_y / abs_x);\n   AD<Base> beta  = pi2 - atan(abs_x / abs_y);\n   AD<Base> first = CondExpGt(abs_x, abs_y, alpha, beta);\n   //\n   // second\n   // This is the result for second quadrant: x <= 0 , y >= 0\n   AD<Base> second = pi - first;\n   //\n   // third\n   // This is the result for third quadrant: x <= 0 , y <= 0\n   AD<Base> third = - pi + first;\n   //\n   // fourth\n   // This is the result for fourth quadrant: x >= 0 , y <= 0\n   AD<Base> fourth = - first;\n   //\n   // alpha\n   // This is the result for x >= 0\n   alpha = CondExpGe(y, zero, first, fourth);\n   //\n   // beta\n   // This is the result for x <= 0\n   beta = CondExpGe(y, zero, second, third);\n   //\n   //\n   AD<Base> result = CondExpGe(x, zero, alpha, beta);\n   return result;\n}\n// END CondExp\n\ntemplate <class Base>\nAD<Base> atan2 (const VecAD_reference<Base> &y, const AD<Base> &x)\n{  return atan2( y.ADBase() , x ); }\n\ntemplate <class Base>\nAD<Base> atan2 (const AD<Base> &y, const VecAD_reference<Base> &x)\n{  return atan2( y , x.ADBase() ); }\n\ntemplate <class Base>\nAD<Base> atan2\n(const VecAD_reference<Base> &y, const VecAD_reference<Base> &x)\n{  return atan2( y.ADBase() , x.ADBase() ); }\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/four/atomic.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_FOUR_ATOMIC_HPP\n# define CPPAD_CORE_ATOMIC_FOUR_ATOMIC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_four_define}\n{xrst_spell\n   ctor\n}\n\nDefining Atomic Functions: Fourth Generation\n############################################\n\nSyntax\n******\n\nDefine Class\n============\n\n| ``class`` *atomic_user* : ``public CppAD::atomic_four<`` *Base* > {\n| |tab| ...\n| };\n\nConstructor\n===========\n*atomic_user* *afun* ( *ctor_arg_list* )\n\nCall\n====\n\n| *afun* ( *ax* , *ay* )\n| *afun* ( *call_id* , *ax* , *ay* )\n\nCallbacks\n=========\n\n| *ok* = *afun* . ``for_type`` ( *call_id* ,\n| |tab| *type_x* , *type_y*\n| )\n| *ok* = *afun* . ``forward`` ( *call_id* ,\n| |tab| *select_y* , *order_low* , *order_up* , *taylor_x* , *taylor_y*\n| )\n| *ok* = *afun* . ``reverse`` ( *call_id* ,\n| |tab| *select_x* , *order_up* , *taylor_x* , *taylor_y* , *partial_x* , *partial_y*\n| )\n| *ok* = *afun* . ``jac_sparsity`` ( *call_id* ,\n| |tab| *dependency* , *ident_zero_x* , *select_x* *select_y* , *pattern_out*\n| )\n| *ok* = *afun* . ``hes_sparsity`` ( *call_id* ,\n| |tab| *ident_zero_x* , *select_x* , *select_y* , *pattern_out*\n| )\n| *ok* = *afun* . ``rev_depend`` ( *call_id* ,\n| |tab| *ident_zero_x* , *depend_x* , *depend_y*\n| )\n\nSee Also\n********\n:ref:`chkpoint_two-name` , :ref:`atomic_three-name`\n\nPurpose\n*******\n\nSpeed\n=====\nIn some cases, it is possible to compute derivatives of a function\n\n.. math::\n\n   y = g(x) \\; {\\rm where} \\; g : \\B{R}^n \\rightarrow \\B{R}^m\n\nmore efficiently than by coding it using ``AD`` < *Base* >\n:ref:`glossary@Operation@Atomic` operations\nand letting CppAD do the rest.\nThe class ``atomic_four`` < ``Base`` > is used to\ncreate a new atomic operation corresponding to a function :math:`g(x)`\nwhere the user specifies how to compute the derivatives\nand sparsity patterns for :math:`g(x)`.\n\nReduce Memory\n=============\nIf the function :math:`g(x)` is used many times during the recording\nof an :ref:`ADFun-name` object,\nan atomic version of :math:`g(x)` removes the need for repeated\ncopies of the corresponding ``AD`` < *Base* > operations and variables\nin the recording.\n\nVirtual Functions\n*****************\nThe :ref:`callback functions<atomic_four_define@Syntax@Callbacks>`\nare implemented by defining the virtual functions in the\n*atomic_user* class.\nThese functions compute derivatives,\nsparsity patterns, and dependency relations.\nEach virtual function has a default implementation\nthat returns *ok* == ``false`` .\nThe :ref:`for_type<atomic_four_for_type-name>`\nand :ref:`forward<atomic_four_forward-name>` function\n(for the case *order_up*  == 0 ) are used by an atomic function\n:ref:`atomic_four_define@Syntax@Call` .\nHence, they are required for one to use an atomic function.\nOther functions and orders are only required if they are used\nfor your calculations.\nFor example,\n*forward* for the case *order_up*  == 2 can just return\n*ok* == ``false`` unless you require\nforward mode calculation of second derivatives.\n\nContents\n********\n{xrst_toc_table\n   include/cppad/core/atomic/four/ctor.hpp\n   include/cppad/core/atomic/four/call.hpp\n   include/cppad/core/atomic/four/for_type.hpp\n   include/cppad/core/atomic/four/forward.hpp\n   include/cppad/core/atomic/four/reverse.hpp\n   include/cppad/core/atomic/four/jac_sparsity.hpp\n   include/cppad/core/atomic/four/hes_sparsity.hpp\n   include/cppad/core/atomic/four/rev_depend.hpp\n}\n\n{xrst_end atomic_four_define}\n-------------------------------------------------------------------------------\n*/\n\n# include <set>\n# include <map>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/local/atomic_index.hpp>\n# include <cppad/core/ad_type.hpp>\n# include <cppad/utility/sparse_rc.hpp>\n# include <cppad/local/pod_vector.hpp>\n# include <cppad/local/op_code_var.hpp>\n\n// needed before one can use in_parallel\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic_four.hpp\nBase class for atomic function operations.\n*/\n\ntemplate <class Base>\nclass atomic_four {\n// ===================================================================\nprivate:\n   // ------------------------------------------------------\n   // constants\n   //\n   /// index of this object in local::atomic_index\n   /// (set by constructor and not changed; i.e., effectively const)\n   size_t index_;\n   //\n   // -----------------------------------------------------\n   //\n   /// temporary work space used by call member functions, declared here\n   // to avoid memory allocation/deallocation for each call\n   struct work_struct {\n      vector<ad_type_enum>        type_x;\n      vector<ad_type_enum>        type_y;\n      //\n      vector<Base>                taylor_x;\n      vector<Base>                taylor_y;\n      //\n      vector< AD<Base> >          ataylor_x;\n      vector< AD<Base> >          ataylor_y;\n      //\n      vector<bool>                select_y;\n   };\n   // Use pointers, to avoid false sharing between threads.\n   // Not using: vector<work_struct*> work_;\n   // so that deprecated atomic examples do not result in a memory leak.\n   work_struct* work_[CPPAD_MAX_NUM_THREADS];\n   // -----------------------------------------------------\npublic:\n   //\n   // atomic_index\n   // Needed by val_graph and not documented. Perhaps should be in\n   // include/cppad/core/atomic/four/devel/devel.xrst\n   size_t atomic_index(void) const\n   { return index_; }\n   // =====================================================================\n   // In User API\n   // =====================================================================\n   //\n   // ---------------------------------------------------------------------\n   // constructors\n   atomic_four(void);\n   atomic_four(const std::string& name);\n\n   // ------------------------------------------------------------------------\n   template <class ADVector> void operator()(\n      size_t           call_id ,\n      const ADVector&  ax      ,\n              ADVector&  ay\n   );\n   template <class ADVector> void operator()(\n      const ADVector&  ax      ,\n              ADVector&  ay\n   );\n   // ------------------------------------------------------------------------\n   // for_type\n   virtual bool for_type(\n      size_t                       call_id     ,\n      const vector<ad_type_enum>&  type_x      ,\n      vector<ad_type_enum>&        type_y\n   );\n   // ------------------------------------------------------------------------\n   // forward\n   virtual bool forward(\n      size_t                       call_id     ,\n      const vector<bool>&          select_y    ,\n      size_t                       order_low   ,\n      size_t                       order_up    ,\n      const vector<Base>&          taylor_x    ,\n      vector<Base>&                taylor_y\n   );\n   virtual bool forward(\n      size_t                       call_id      ,\n      const vector<bool>&          select_y    ,\n      size_t                       order_low    ,\n      size_t                       order_up     ,\n      const vector< AD<Base> >&    ataylor_x    ,\n      vector< AD<Base> >&          ataylor_y\n   );\n   // ------------------------------------------------------------------------\n   // reverse\n   virtual bool reverse(\n      size_t                       call_id     ,\n      const vector<bool>&          select_x    ,\n      size_t                       order_up    ,\n      const vector<Base>&          taylor_x    ,\n      const vector<Base>&          taylor_y    ,\n      vector<Base>&                partial_x   ,\n      const vector<Base>&          partial_y\n   );\n   virtual bool reverse(\n      size_t                       call_id     ,\n      const vector<bool>&          select_x    ,\n      size_t                       order_up    ,\n      const vector< AD<Base> >&    ataylor_x   ,\n      const vector< AD<Base> >&    ataylor_y   ,\n      vector< AD<Base> >&          apartial_x  ,\n      const vector< AD<Base> >&    apartial_y\n   );\n   // ------------------------------------------------------------\n   // jac_sparsity\n   virtual bool jac_sparsity(\n      size_t                       call_id      ,\n      bool                         dependency   ,\n      const vector<bool>&          ident_zero_x ,\n      const vector<bool>&          select_x     ,\n      const vector<bool>&          select_y     ,\n      sparse_rc< vector<size_t> >& pattern_out\n   );\n   template <class InternalSparsity>\n   bool for_jac_sparsity(\n      size_t                           call_id      ,\n      bool                             dependency   ,\n      const vector<bool>&              ident_zero_x ,\n      const vector<size_t>&            x_index      ,\n      const vector<size_t>&            y_index      ,\n      InternalSparsity&                var_sparsity\n   );\n   template <class InternalSparsity>\n   bool rev_jac_sparsity(\n      size_t                           call_id      ,\n      bool                             dependency   ,\n      const vector<bool>&              ident_zero_x ,\n      const vector<size_t>&            x_index      ,\n      const vector<size_t>&            y_index      ,\n      InternalSparsity&                var_sparsity\n   );\n   // deprecated version of this callback\n   virtual bool jac_sparsity(\n      size_t                       call_id      ,\n      bool                         dependency   ,\n      const vector<bool>&          select_x     ,\n      const vector<bool>&          select_y     ,\n      sparse_rc< vector<size_t> >& pattern_out\n   );\n   // ------------------------------------------------------------\n   // hes_sparsity\n   virtual bool hes_sparsity(\n      size_t                                  call_id      ,\n      const vector<bool>&                     ident_zero_x ,\n      const vector<bool>&                     select_x     ,\n      const vector<bool>&                     select_y     ,\n      sparse_rc< vector<size_t> >&            pattern_out\n   );\n   template <class InternalSparsity>\n   bool for_hes_sparsity(\n      size_t                           call_id          ,\n      const vector<bool>&              ident_zero_x     ,\n      const vector<size_t>&            x_index          ,\n      const vector<size_t>&            y_index          ,\n      size_t                           np1              ,\n      size_t                           numvar           ,\n      const InternalSparsity&          rev_jac_sparsity ,\n      InternalSparsity&                for_sparsity\n   );\n   template <class InternalSparsity>\n   bool rev_hes_sparsity(\n      size_t                           call_id          ,\n      const vector<bool>&              ident_zero_x     ,\n      const vector<size_t>&            x_index          ,\n      const vector<size_t>&            y_index          ,\n      const InternalSparsity&          for_jac_pattern  ,\n      bool*                            rev_jac_flag     ,\n      InternalSparsity&                hes_sparsity\n   );\n   // deprecated version of this callback\n   virtual bool hes_sparsity(\n      size_t                                  call_id      ,\n      const vector<bool>&                     select_x     ,\n      const vector<bool>&                     select_y     ,\n      sparse_rc< vector<size_t> >&            pattern_out\n   );\n   // ------------------------------------------------------------------------\n   // rev_depend\n   virtual bool rev_depend(\n      size_t                       call_id      ,\n      const vector<bool>&          ident_zero_x ,\n      vector<bool>&                depend_x     ,\n      const vector<bool>&          depend_y\n   );\n   // deprecated version of this callback\n   virtual bool rev_depend(\n      size_t                       call_id     ,\n      vector<bool>&                depend_x    ,\n      const vector<bool>&          depend_y\n   );\n   // =====================================================================\n   // Not in User API\n   // =====================================================================\n\n   /// Name corresponding to a atomic_four object\n   const std::string atomic_name(void) const\n   {  bool        set_null = false;\n      size_t      type  = 0;          // set to avoid warning\n      std::string name;\n      void*       v_ptr = nullptr; // set to avoid warning\n      local::atomic_index<Base>(set_null, index_, type, &name, v_ptr);\n      CPPAD_ASSERT_UNKNOWN( type == 4 );\n      return name;\n   }\n   /// destructor informs CppAD that this atomic function with this index\n   /// has dropped out of scope by setting its pointer to null\n   virtual ~atomic_four(void)\n   {  // change object pointer to null, but leave name for error reporting\n      bool         set_null = true;\n      size_t       type  = 0;          // set to avoid warning\n      std::string* name  = nullptr;\n      void*        v_ptr = nullptr; // set to avoid warning\n      local::atomic_index<Base>(set_null, index_, type, name, v_ptr);\n      CPPAD_ASSERT_UNKNOWN( type == 4 );\n      //\n      // free temporary work memory\n      for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++)\n         free_work(thread);\n   }\n   /// allocates work_ for a specified thread\n   void allocate_work(size_t thread)\n   {  if( work_[thread] == nullptr )\n      {  // allocate the raw memory\n         size_t min_bytes = sizeof(work_struct);\n         size_t num_bytes;\n         void*  v_ptr     = thread_alloc::get_memory(min_bytes, num_bytes);\n         // save in work_\n         work_[thread]    = reinterpret_cast<work_struct*>( v_ptr );\n         // call constructor\n         new( work_[thread] ) work_struct;\n      }\n      return;\n   }\n   /// frees work_ for a specified thread\n   void free_work(size_t thread)\n   {  if( work_[thread] != nullptr )\n      {  // call destructor\n         work_[thread]->~work_struct();\n         // return memory to available pool for this thread\n         thread_alloc::return_memory(\n            reinterpret_cast<void*>(work_[thread])\n         );\n         // mark this thread as not allocated\n         work_[thread] = nullptr;\n      }\n      return;\n   }\n   /// atomic_four function object corresponding to a certain index\n   static atomic_four* class_object(size_t index)\n   {  bool         set_null = false;\n      size_t       type  = 0;          // set to avoid warning\n      std::string* name  = nullptr;\n      void*        v_ptr = nullptr; // set to avoid warning\n      local::atomic_index<Base>(set_null, index, type, name, v_ptr);\n      CPPAD_ASSERT_UNKNOWN( type == 4 );\n      return reinterpret_cast<atomic_four*>( v_ptr );\n   }\n   /// atomic_four function name corresponding to a certain index\n   static const std::string class_name(size_t index)\n   {  bool        set_null = false;\n      size_t      type  = 0;          // set to avoid warning\n      std::string name;\n      void*       v_ptr = nullptr; // set to avoid warning\n      local::atomic_index<Base>(set_null, index, type, &name, v_ptr);\n      CPPAD_ASSERT_UNKNOWN( type == 4 );\n      return name;\n   }\n\n   /*!\n   Set value of id (used by deprecated atomic_one class)\n\n   This function is called just before calling any of the virtual function\n   and has the corresponding id of the corresponding virtual call.\n   */\n   virtual void set_old(size_t id)\n   { }\n// ---------------------------------------------------------------------------\n};\n} // END_CPPAD_NAMESPACE\n\n// member functions\n# include <cppad/core/atomic/four/ctor.hpp>\n# include <cppad/core/atomic/four/call.hpp>\n# include <cppad/core/atomic/four/for_type.hpp>\n# include <cppad/core/atomic/four/rev_depend.hpp>\n# include <cppad/core/atomic/four/forward.hpp>\n# include <cppad/core/atomic/four/reverse.hpp>\n# include <cppad/core/atomic/four/jac_sparsity.hpp>\n# include <cppad/core/atomic/four/hes_sparsity.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/four/call.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_FOUR_CALL_HPP\n# define CPPAD_CORE_ATOMIC_FOUR_CALL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_four_call}\n\nCalling an Atomic Function\n##########################\n\nSyntax\n******\n| *afun* ( *ax* , *ay* )\n| *ay* = *afun* ( *call_id* , *ax* , *ay* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nPurpose\n*******\nGiven *ax* , this call computes the corresponding value of *ay* .\nIf ``AD`` < *Base* > operations are being recorded,\nit enters the computation as an atomic operation in the recording;\nsee :ref:`Independent@Start Recording` .\n\nBase\n****\nThis is the :ref:`atomic_four_ctor@atomic_four@Base`\nin the *afun* constructor.\nIt is also the *Base* type of the elements of\n*ax* and *ay* in the atomic function call.\nTo be specific, the elements of *ax* and *ay* have type\n``AD`` < ``Base`` > .\n\nADVector\n********\nThe type *ADVector* must be a\n:ref:`simple vector class<SimpleVector-name>` with elements of type\n``AD`` < *Base* > .\n\nafun\n****\nis a :ref:`atomic_four_ctor@atomic_user` object\nand this *afun* function call is implemented by the\n:ref:`atomic_four_ctor@atomic_four` class.\n\nax\n**\nThis vector is ``const`` and passed by reference and\nits size determines *n* .\nIt specifies vector :math:`x \\in \\B{R}^n`\nat which an ``AD`` < *Base* > version of\n:math:`y = g(x)` is to be evaluated.\n\nay\n**\nThis vector is passed by reference and its size determines *m* .\nThe input values of its elements\nare not specified (must not matter).\nUpon return, it is an ``AD`` < *Base* > version of\n:math:`y = g(x)`.\n\ncall_id\n*******\nThis optional argument has default value zero.\nIt can be used to specify additional information about this call to\n*afun* . For example, it could specify the index in vector of structures\nin the *afun* object where the actual information is placed.\n\nfor_type\n********\nThe :ref:`for_type<atomic_four_for_type-name>` routine will be called once,\nfor each call to an atomic function,\nbefore any other callbacks corresponding to the atomic function call.\nThis enables you to store, during the ``for_type`` routine,\nthe values in\n:ref:`atomic_four_for_type@type_x` and or\n:ref:`atomic_four_for_type@type_y` corresponding\nto this atomic function call.\n\nRestriction\n===========\nThe value of *call_id* must be less than or equal\n\n   ``std::numeric_limits<`` *cppad_tape_id_type* >:: ``max`` ()\n\nsee :ref:`cmake@cppad_tape_id_type` .\n\n{xrst_end atomic_four_call}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n// BEGIN_PROTOTYPE\ntemplate <class Base> template <class ADVector>\nvoid atomic_four<Base>::operator()(\n   size_t           call_id ,\n   const ADVector&  ax      ,\n   ADVector&        ay      )\n// END_PROTOTYPE\n{\n   size_t n = ax.size();\n   size_t m = ay.size();\n# ifndef NDEBUG\n   bool ok = true;\n   std::string msg = \"atomic_four: call \" + atomic_name() + \" \";\n   if( (n == 0) || (m == 0) )\n   {  msg += \"ax.size() or ay.size() is zero\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# endif\n   //\n   // type_x, type_y, taylor_x, taylor_y, select_y\n   size_t thread = thread_alloc::thread_num();\n   allocate_work(thread);\n   vector<ad_type_enum>& type_x   = work_[thread]->type_x;\n   vector<ad_type_enum>& type_y   = work_[thread]->type_y;\n   vector<Base>&         taylor_x = work_[thread]->taylor_x;\n   vector<Base>&         taylor_y = work_[thread]->taylor_y;\n   vector<bool>&         select_y = work_[thread]->select_y;\n   type_x.resize(n);\n   taylor_x.resize(n);\n   type_y.resize(m);\n   taylor_y.resize(m);\n   select_y.resize(m);\n   //\n   // tape_id, tape, taylor_x, type_x\n   tape_id_t            tape_id  = 0;\n   local::ADTape<Base>* tape     = nullptr;\n   for(size_t j = 0; j < n; j++)\n   {  taylor_x[j]  = ax[j].value_;\n      if( IdenticalZero( ax[j] ) )\n         type_x[j] = identical_zero_enum;\n      else if( Constant( ax[j] ) )\n         type_x[j] = constant_enum;\n      else\n      {  type_x[j] = ax[j].ad_type_;\n         if( tape_id == 0 )\n         {  tape    = ax[j].tape_this();\n            tape_id = ax[j].tape_id_;\n            CPPAD_ASSERT_UNKNOWN( tape != nullptr );\n         }\n# ifndef NDEBUG\n         if( Dynamic( ax[j] ) )\n         {    CPPAD_ASSERT_UNKNOWN( type_x[j] == dynamic_enum );\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( Variable( ax[j] ) );\n            CPPAD_ASSERT_UNKNOWN( type_x[j] == variable_enum );\n         }\n         if( tape_id != ax[j].tape_id_ )\n         {  msg += atomic_name() +\n            \": ax contains non-constant values from different threads.\";\n            CPPAD_ASSERT_KNOWN(false, msg.c_str());\n         }\n# endif\n      }\n   }\n   // Use zero order forward mode to compute all the components of y\n   for(size_t i = 0; i < m; ++i)\n      select_y[i] = true;\n   size_t order_low   = 0;\n   size_t order_up    = 0;\n# ifdef NDEBUG\n   for_type(\n      call_id, type_x, type_y\n   );\n   forward(\n      call_id, select_y, order_low, order_up, taylor_x, taylor_y\n   );\n# else\n   ok &= for_type(\n      call_id, type_x, type_y\n   );\n   ok &= forward(\n      call_id, select_y, order_low, order_up, taylor_x, taylor_y\n   );\n   if( ! ok )\n   {  msg += atomic_name() + \": ok is false for \"\n         \"type or zero order forward mode calculation.\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str());\n   }\n# endif\n   bool record_dynamic = false;\n   bool record_variable = false;\n   //\n   // set ay to be vector of constant parameters with correct value\n   for(size_t i = 0; i < m; i++)\n   {  // pass back values\n      ay[i].value_ = taylor_y[i];\n\n      // initialize entire vector as constants\n      ay[i].tape_id_ = 0;\n      ay[i].taddr_   = 0;\n\n      // we need to record this operation if\n      // any of the elements of ay are dynamics or variables,\n      record_dynamic  |= type_y[i] == dynamic_enum;\n      record_variable |= type_y[i] == variable_enum;\n   }\n# ifndef NDEBUG\n   if( (record_dynamic || record_variable) && tape == nullptr )\n   {  msg +=\n      \"all elements of x are constants but y contains a non-constant\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# endif\n   if( record_dynamic)\n   {  tape->Rec_.put_dyn_atomic(\n         tape_id, index_, call_id, type_x, type_y, ax, ay\n      );\n   }\n   // case where result contains a variable\n   if( record_variable )\n   {  tape->Rec_.put_var_atomic(\n         tape_id, index_, call_id, type_x, type_y, ax, ay\n      );\n   }\n# ifndef NDEBUG\n   for(size_t i = 0; i < m; ++i) switch( type_y[i] )\n   {  //\n      case identical_zero_enum:\n      case constant_enum:\n      CPPAD_ASSERT_UNKNOWN( Constant( ay[i] ) );\n      break;\n      //\n      case dynamic_enum:\n      CPPAD_ASSERT_UNKNOWN( Dynamic( ay[i] ) );\n      break;\n      //\n      case variable_enum:\n      CPPAD_ASSERT_UNKNOWN( Variable( ay[i] ) );\n      break;\n      //\n      default:\n      CPPAD_ASSERT_KNOWN( false,\n         \"atomic_four: for_type: type_y[i]: is not a valid type\"\n      );\n      break;\n   }\n# endif\n   return;\n}\ntemplate <class Base> template <class ADVector>\nvoid atomic_four<Base>::operator()(\n   const ADVector&  ax      ,\n   ADVector&        ay      )\n{  size_t call_id = 0;\n   (*this)(call_id, ax, ay);\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/four/ctor.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_FOUR_CTOR_HPP\n# define CPPAD_CORE_ATOMIC_FOUR_CTOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_four_ctor}\n\nAtomic Function Constructor\n###########################\n\nSyntax\n******\n| ``class`` *atomic_user* : ``public CppAD::atomic_four<`` *Base* > {\n| ``public:``\n| |tab| *atomic_user* ( *ctor_arg_list* ) : ``CppAD::atomic_four<`` *Base* >( *name* )\n| |tab| ...\n| };\n| *atomic_user afun* ( *ctor_arg_list* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\natomic_user\n***********\n\nctor_arg_list\n=============\nIs a list of arguments for the *atomic_user* constructor.\n\nafun\n====\nThe object *afun* must stay in scope for as long\nas the corresponding atomic function is used.\nThis includes use by any :ref:`ADFun\\<Base><ADFun-name>` object that\nhas this *atomic_user* operation in its\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nImplementation\n==============\nThe user defined *atomic_user* class is a publicly derived class of\n``atomic_four`` < *Base* > .\nIt should be declared as follows:\n\n| |tab| ``class`` *atomic_user* : ``public CppAD::atomic_four<`` *Base* > {\n| |tab| ``public:``\n| |tab| |tab| *atomic_user* ( *ctor_arg_list* ) : ``atomic_four`` < *Base* >( *name* )\n| |tab| ...\n| |tab| };\n\nwhere ...\ndenotes the rest of the implementation of the derived class.\nThis includes completing the constructor and\nall the virtual functions that have their\n``atomic_four`` implementations replaced by\n*atomic_user* implementations.\n\natomic_four\n***********\n\nRestrictions\n============\nThe ``atomic_four`` constructor and destructor cannot be called in\n:ref:`parallel<ta_in_parallel-name>` mode.\n\nBase\n====\nThe template parameter determines the\n:ref:`atomic_four_call@Base`\ntype for this ``AD`` < *Base* > atomic operation.\n\nname\n====\nThis ``atomic_four`` constructor argument has the following prototype\n\n   ``const std::string&`` *name*\n\nIt is the name for this atomic function and is used for error reporting.\nThe suggested value for *name* is *afun* or *atomic_user* ,\ni.e., the name of the corresponding atomic object or class.\n\nExample\n*******\nThe following is an example constructor definition taken from\n:ref:`atomic_four_norm_sq.cpp-name` :\n{xrst_literal\n   example/atomic_four/norm_sq.cpp\n   // BEGIN CONSTRUCTOR\n   // END CONSTRUCTOR\n}\n\n{xrst_end atomic_four_ctor}\n-------------------------------------------------------------------------------\n*/\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n// atomic_four()\ntemplate <class Base>\natomic_four<Base>::atomic_four(void)\n{  CPPAD_ASSERT_KNOWN(false,\n      \"Attempt to use the atomic_four default constructor\"\n   );\n}\n\n// atomic_four(name)\n// BEGIN_PROTOTYPE\ntemplate <class Base>\natomic_four<Base>::atomic_four(const std::string& name )\n// END_PROTOTYPE\n{  CPPAD_ASSERT_KNOWN(\n      ! thread_alloc::in_parallel() ,\n      \"atomic_four: constructor cannot be called in parallel mode.\"\n   );\n   //\n   // index_\n   bool        set_null  = false;\n   size_t      index     = 0;\n   size_t      type      = 4;\n   std::string copy_name = name;\n   void*       copy_this = reinterpret_cast<void*>( this );\n   index_  = local::atomic_index<Base>(\n      set_null, index, type, &copy_name, copy_this\n   );\n   //\n   // work_\n   for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++)\n      work_[thread] = nullptr;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/four/devel/hes_sparsity.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_FOUR_DEVEL_HES_SPARSITY_HPP\n# define CPPAD_CORE_ATOMIC_FOUR_DEVEL_HES_SPARSITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*\n-----------------------------------------------------------------------------\n{xrst_begin atomic_four_for_hes_sparsity dev}\n{xrst_spell\n   numvar\n}\n\nLink from Forward Hessian Sparsity Sweep to atomic_four Callback\n################################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_FOR_HES_SPARSITY\n   // END_FOR_HES_SPARSITY\n}\n\nInternalSparsity\n****************\nIs the used internally for sparsity calculations; i.e.,\nsparse_pack or sparse_list.\n\ncall_id [in]\n************\nsee :ref:`atomic_four_call@call_id` .\n\nident_zero_x\n************\nThis argument has size equal to the number of arguments to this\natomic function; i.e. the size of *ax* .\nIf *ident_zero_x* [ *j* ] is true, the argument *ax* [ *j* ]\nis a constant parameter that is identically zero.\n\nx_index\n*******\nis the variable index, on the tape, for the arguments to this function.\nThis size of x_index is n, the number of arguments to this function.\nThe index zero is used for parameters.\n\ny_index\n*******\nis the variable index, on the tape, for the results for this function.\nThis size of y_index is m, the number of results for this function.\nThe index zero is used for parameters.\n\nnp1\n***\nis the number of components of x plus one; i.e. *n*  + 1 .\n\nnumvar\n******\nis the total number of variables in the tape; i.e.,\n*play* ``->num_var`` () .\n\nfor_sparsity\n************\nThe sparsity patterns with index zero and index *np1* are empty\n(because they correspond to parameters).\n\nOn Input\n========\nOn input, for j = 0, ... , n-1,\nthe forward Jacobian sparsity for the *j*-th argument to the atomic function\nis the sparsity pattern with index *np1* + *x_index* [ *j* ] .\nIn addition, the sparsity pattern with index *j+1*-th contains\nthe non-zero cross partial indices where *j+1*-th is the other index.\nThis Hessian does not include the atomic operation.\n\nOn Output\n=========\nOn output, for i = 0, ... , m-1,\nthe forward Jacobian sparsity for the *i*-th result of the atomic function\nis the sparsity pattern with index *np1* + *y_index* [ *i* ] .\nIn addition, the sparsity pattern with index *j+1*-th contains\nthe non-zero cross partial indices where *j+1*-th is the other index.\nThis Hessian includes the atomic operation.\n\nrev_jac_pattern\n***************\nOn input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i],\nis the reverse Jacobian sparsity for the i-th result to this atomic function.\nThis shows which components of the result affect the function we are\ncomputing the Hessian of.\n\nhes_sparsity_for\n****************\nThis is the sparsity pattern for the Hessian. On input, the non-linear\nterms in the atomic function have not been included. Upon return, they\nhave been included.\n\n{xrst_end atomic_four_for_hes_sparsity}\n*/\n// BEGIN_FOR_HES_SPARSITY\ntemplate <class Base>\ntemplate <class InternalSparsity>\nbool atomic_four<Base>::for_hes_sparsity(\n   size_t                           call_id          ,\n   const vector<bool>&              ident_zero_x     ,\n   const vector<size_t>&            x_index          ,\n   const vector<size_t>&            y_index          ,\n   size_t                           np1              ,\n   size_t                           numvar           ,\n   const InternalSparsity&          rev_jac_pattern  ,\n   InternalSparsity&                for_sparsity     )\n// END_FOR_HES_SPARSITY\n{  typedef typename InternalSparsity::const_iterator const_iterator;\n   //\n   CPPAD_ASSERT_UNKNOWN( rev_jac_pattern.end() == 1 );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + numvar );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.number_elements(0) == 0 );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.number_elements(np1) == 0 );\n   //\n   size_t n      = x_index.size();\n   size_t m      = y_index.size();\n   //\n   // select_x\n   vector<bool> select_x(n);\n   for(size_t j = 0; j < n; j++)\n   {  // check if should compute pattern w.r.t x[j]\n      select_x[j] = for_sparsity.number_elements(np1 + x_index[j]) > 0;\n   }\n   //\n   // bool select_y\n   vector<bool> select_y(m);\n   for(size_t i = 0; i < m; i++)\n   {  // check if we should include y[i]\n      select_y[i] = rev_jac_pattern.number_elements(y_index[i]) > 0;\n   }\n   // ------------------------------------------------------------------------\n   // call user's version of atomic function for Jacobian\n   sparse_rc< vector<size_t> > pattern_out;\n   bool dependency = false;\n   bool ok = jac_sparsity( call_id,\n      dependency, ident_zero_x, select_x, select_y, pattern_out\n   );\n   if(! ok) ok = jac_sparsity(\n      call_id, dependency, select_x, select_y, pattern_out\n   );\n   if( ! ok )\n      return false;\n   //\n   // transfer sparsity patterns from pattern_out to var_sparsity\n   size_t                nnz = pattern_out.nnz();\n   const vector<size_t>& row( pattern_out.row() );\n   const vector<size_t>& col( pattern_out.col() );\n   for(size_t k = 0; k < nnz; ++k)\n   {  size_t i = row[k];\n      size_t j = col[k];\n      CPPAD_ASSERT_KNOWN(\n         select_y[i] && select_x[j],\n         \"atomic: jac_sparsity: pattern_out not in \"\n         \"select_x or select_y range\"\n      );\n      const_iterator itr(for_sparsity, np1 + x_index[j]);\n      size_t ell = *itr;\n      while( ell < np1 )\n      {  for_sparsity.post_element(np1 + y_index[i], ell );\n         ell = *(++itr);\n      }\n   }\n   for(size_t i = 0; i < m; ++i)\n      for_sparsity.process_post( np1 + y_index[i] );\n   // ------------------------------------------------------------------------\n   // call user's version of atomic function for Hessian\n   ok = hes_sparsity(\n      call_id, ident_zero_x, select_x, select_y, pattern_out\n   );\n   if(! ok ) ok = hes_sparsity(\n      call_id, select_x, select_y, pattern_out\n   );\n   if( ! ok )\n      return ok;\n   //\n   // add new elements to Hessian sparisty in calling routine\n   nnz = pattern_out.nnz();\n   for(size_t k = 0; k < nnz; ++k)\n   {  size_t r = row[k];\n      size_t c = col[k];\n      CPPAD_ASSERT_KNOWN(\n         select_x[r] && select_x[c],\n         \"atomic: hes_sparsity: pattern_out not in select_x range\"\n      );\n      const_iterator itr_1(for_sparsity, np1 + x_index[r]);\n      size_t v1 = *itr_1;\n      while( v1 < np1 )\n      {  for_sparsity.binary_union(\n            v1, v1, np1 + x_index[c], for_sparsity\n             );\n             v1 = *(++itr_1);\n      }\n      // no need to add same elements twice\n      if( c != r )\n      {  const_iterator itr_2(for_sparsity, np1 + x_index[c]);\n         size_t v2 = *itr_2;\n         while( v2 < np1 )\n         {  for_sparsity.binary_union(\n               v2, v2, np1 + x_index[r], for_sparsity\n            );\n            v2 = *(++itr_2);\n         }\n      }\n   }\n   return ok;\n}\n/*\n{xrst_begin atomic_four_rev_hes_sparsity dev}\n\nLink from Reverse Hessian Sparsity Sweep to atomic_four Callback\n################################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_REV_HES_SPARSITY\n   // END_REV_HES_SPARSITY\n}\n\nInternalSparsity\n****************\nIs the used internally for sparsity calculations; i.e.,\nsparse_pack or sparse_list.\n\ncall_id [in]\n************\nsee :ref:`atomic_four_call@call_id` .\n\nident_zero_x\n************\nThis argument has size equal to the number of arguments to this\natomic function; i.e. the size of *ax* .\nIf *ident_zero_x* [ *j* ] is true, the argument *ax* [ *j* ]\nis a constant parameter that is identically zero.\n\nx_index\n*******\nis the variable index, on the tape, for the arguments to this function.\nThis size of x_index is n, the number of arguments to this function.\nThe index zero is used for parameters.\n\ny_index\n*******\nis the variable index, on the tape, for the results for this function.\nThis size of y_index is m, the number of results for this function.\nThe index zero is used for parameters.\n\nfor_jac_pattern\n***************\nOn input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nis the forward Jacobian pattern for the j-th argument to this atomic function.\n\nrev_jac_flag\n************\nOn input, for i = 0, ... , m-1, rev_jac_flag[ y_index[i] ] is true\nif the function we are computing the Hessian of has possibly non-zero Jacobian\nw.r.t variable y_index[i].\nOn output, for j = 0, ... , n, rev_jac_flag[ x_index[j] ] is set to true\nif the variable with index x_index[j] has possible non-zero Jacobian\nwith respect to one of the true y_index[i] cases.\nOtherwise, rev_jac_flag [ x_index[j] ] is not changed.\n\nhes_sparsity_rev\n****************\nIs the reverse mode sparsity pattern for the Hessian. On input, the non-linear\nterms in the atomic function have not been included. Upon return, they\nhave been included.\n\n{xrst_end atomic_four_rev_hes_sparsity}\n*/\n// BEGIN_REV_HES_SPARSITY\ntemplate <class Base>\ntemplate <class InternalSparsity>\nbool atomic_four<Base>::rev_hes_sparsity(\n   size_t                           call_id          ,\n   const vector<bool>&              ident_zero_x     ,\n   const vector<size_t>&            x_index          ,\n   const vector<size_t>&            y_index          ,\n   const InternalSparsity&          for_jac_pattern  ,\n   bool*                            rev_jac_flag     ,\n   InternalSparsity&                hes_sparsity_rev )\n// END_REV_HES_SPARSITY\n{  CPPAD_ASSERT_UNKNOWN( for_jac_pattern.number_elements(0) == 0 );\n   CPPAD_ASSERT_UNKNOWN( ! rev_jac_flag[0] );\n   //\n   size_t n      = x_index.size();\n   size_t m      = y_index.size();\n   //\n   // select_x\n   vector<bool> select_x(n);\n   for(size_t j = 0; j < n; j++)\n      select_x[j] = for_jac_pattern.number_elements( x_index[j] ) > 0;\n   //\n   // select_y\n   vector<bool> select_y(m);\n   for(size_t i = 0; i < m; i++)\n      select_y[i] = rev_jac_flag[ y_index[i] ];\n   //\n   // call atomic function for Jacobain sparsity\n   bool dependency = false;\n   sparse_rc< vector<size_t> > pattern_jac;\n   bool ok = jac_sparsity( call_id,\n      dependency, ident_zero_x, select_x, select_y, pattern_jac\n   );\n   if(! ok) ok = jac_sparsity(\n      call_id, dependency, select_x, select_y, pattern_jac\n   );\n   const vector<size_t>& row_jac( pattern_jac.row() );\n   const vector<size_t>& col_jac( pattern_jac.col() );\n   size_t nnz_jac = pattern_jac.nnz();\n   if( ! ok )\n      return ok;\n   //\n   // call atomic function for Hessian sparsity\n   sparse_rc< vector<size_t> > pattern_hes;\n   ok = hes_sparsity(\n      call_id, ident_zero_x, select_x, select_y, pattern_hes\n   );\n   if( ! ok ) ok = hes_sparsity(\n      call_id, select_x, select_y, pattern_hes\n   );\n   if( ! ok )\n      return ok;\n   //\n   // row_hes, col_hes, nnz_hes\n   const vector<size_t>& row_hes( pattern_hes.row() );\n   const vector<size_t>& col_hes( pattern_hes.col() );\n   size_t nnz_hes = pattern_hes.nnz();\n   //\n   // propagate Hessian sparsity through the Jacobian\n   for(size_t k = 0; k < nnz_jac; ++k)\n   {  size_t i = row_jac[k];\n      size_t j = col_jac[k];\n      CPPAD_ASSERT_KNOWN(\n         select_y[i] && select_x[j] ,\n         \"atomic: jac_sparsity: pattern_out not in \"\n         \"select_x or select_y range\"\n      );\n      // from y_index[i] to x_index[j]\n      hes_sparsity_rev.binary_union(\n         x_index[j], x_index[j], y_index[i], hes_sparsity_rev\n      );\n   }\n   //\n   // propagate rev_jac_flag through the Jacobian\n   // (seems OK to exclude variables with zero forward jacobian)\n   for(size_t k = 0; k < nnz_jac; ++k)\n   {  size_t j = col_jac[k];\n      rev_jac_flag[ x_index[j] ] = true;\n   }\n   //\n   // new hessian sparsity terms between y and x\n   for(size_t k = 0; k < nnz_hes; ++k)\n   {  size_t r = row_hes[k];\n      size_t c = col_hes[k];\n      CPPAD_ASSERT_KNOWN(\n         select_x[r] && select_x[c] ,\n         \"atomic: hes_sparsity: pattern_out not in select_x range\"\n      );\n      hes_sparsity_rev.binary_union(\n         x_index[r], x_index[r], x_index[c], for_jac_pattern\n      );\n      hes_sparsity_rev.binary_union(\n         x_index[c], x_index[c], x_index[r], for_jac_pattern\n      );\n   }\n   return ok;\n}\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/four/devel/jac_sparsity.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_FOUR_DEVEL_JAC_SPARSITY_HPP\n# define CPPAD_CORE_ATOMIC_FOUR_DEVEL_JAC_SPARSITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*\n------------------------------------------------------------------------------\n{xrst_begin atomic_four_for_jac_sparsity dev}\n\nLink from Forward Jacobian Sparsity Sweep to atomic_four Callback\n#################################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_FOR_JAC_SPARSITY\n   // END_FOR_JAC_SPARSITY\n}\n\nInternalSparsity\n****************\nis the type used for internal sparsity calculations; i.e.,\nsparse_pack or sparse_list.\n\ncall_id\n*******\nsee :ref:`atomic_four_call@call_id` .\n\ndependency\n**********\nif true, calculate dependency pattern,\notherwise calculate sparsity pattern.\n\nident_zero_x\n************\nThis argument has size equal to the number of arguments to this\natomic function; i.e. the size of *ax* .\nIf *ident_zero_x* [ *j* ] is true, the argument *ax* [ *j* ]\nis a constant parameter that is identically zero.\n\nx_index\n*******\nis the variable index, on the tape, for the arguments to this atomic function.\nThis size of x_index is, the number of arguments to this atomic function.\nThe index zero is used for parameters.\n\ny_index\n*******\nis the variable index, on the tape, for the results for this atomic function.\nThis size of y_index is m, the number of results for this atomic function.\nThe index zero is used for parameters.\n\nvar_sparsity\n************\nOn input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nis the sparsity for the j-th argument to this atomic function.\nOn output, for i = 0, ... , m-1, the sparsity pattern with index y_index[i],\nis the sparsity for the i-th result for this atomic function.\n\nReturn Value\n************\nis true if the computation succeeds.\n\n{xrst_end atomic_four_for_jac_sparsity}\n*/\n// BEGIN_FOR_JAC_SPARSITY\ntemplate <class Base>\ntemplate <class InternalSparsity>\nbool atomic_four<Base>::for_jac_sparsity(\n   size_t                           call_id      ,\n   bool                             dependency   ,\n   const vector<bool>&              ident_zero_x ,\n   const vector<size_t>&            x_index      ,\n   const vector<size_t>&            y_index      ,\n   InternalSparsity&                var_sparsity )\n// END_FOR_JAC_SPARSITY\n{  typedef typename InternalSparsity::const_iterator iterator;\n\n   // number of arguments and results for this atomic function\n   size_t n = x_index.size();\n   size_t m = y_index.size();\n\n   // select_y\n   vector<bool> select_y(m);\n   for(size_t i = 0; i < m; ++i)\n      select_y[i] = y_index[i] != 0;\n\n   // determine select_x\n   vector<bool> select_x(n);\n   for(size_t j = 0; j < n; ++j)\n   {  if( x_index[j] == 0 )\n         select_x[j] = false;\n      else\n      {  // check if x_j depends on any previous variable\n         iterator itr(var_sparsity, x_index[j]);\n         size_t ell = *itr;\n         select_x[j] = ell < var_sparsity.end();\n      }\n   }\n   sparse_rc< vector<size_t> > pattern_out;\n   bool ok = jac_sparsity( call_id,\n      dependency, ident_zero_x, select_x, select_y, pattern_out\n   );\n   if( ! ok ) ok = jac_sparsity(\n      call_id, dependency, select_x, select_y, pattern_out\n   );\n   if( ! ok )\n      return false;\n   //\n   // transfer sparsity patterns from pattern_out to var_sparsity\n   size_t                nnz = pattern_out.nnz();\n   const vector<size_t>& row( pattern_out.row() );\n   const vector<size_t>& col( pattern_out.col() );\n   for(size_t k = 0; k < nnz; ++k)\n   {  size_t i = row[k];\n      size_t j = col[k];\n      CPPAD_ASSERT_KNOWN(\n         select_y[i] && select_x[j],\n         \"atomic: jac_sparsity: pattern_out not in \"\n         \"select_x or select_y range\"\n      );\n      iterator itr(var_sparsity, x_index[j]);\n      size_t ell = *itr;\n      while( ell < var_sparsity.end() )\n      {  var_sparsity.post_element( y_index[i], ell );\n         ell = *(++itr);\n      }\n   }\n   for(size_t i = 0; i < m; ++i)\n      var_sparsity.process_post( y_index[i] );\n   //\n   return true;\n}\n\n/*\n------------------------------------------------------------------------------\n{xrst_begin atomic_four_rev_jac_sparsity dev}\n\nLink from Reverse Jacobian Sparsity Sweep to atomic_four Callback\n#################################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_REV_JAC_SPARSITY\n   // END_REV_JAC_SPARSITY\n}\n\nInternalSparsity\n****************\nIs the type used for internal sparsity calculations; i.e.,\nsparse_pack or sparse_list.\n\ncall_id\n*******\nsee :ref:`atomic_four_call@call_id`\n\ndependency\n**********\nif true, calculate dependency pattern,\notherwise calculate sparsity pattern.\n\nident_zero_x\n************\nThis argument has size equal to the number of arguments to this\natomic function; i.e. the size of *ax* .\nIf *ident_zero_x* [ *j* ] is true, the argument *ax* [ *j* ]\nis a constant parameter that is identically zero.\n\nx_index\n*******\nis the variable index, on the tape, for the arguments to this atomic function.\nThis size of x_index is n, the number of arguments to this atomic function.\nThe index zero is used for parameters.\n\ny_index\n*******\nis the variable index, on the tape, for the results for this atomic function.\nThis size of y_index is m, the number of results for this atomic function.\nThe index zero is used for parameters.\n\nvar_sparsity\n************\nWe are given a sparsity pattern an outer function G(y, x) and compute\nthe pattern for an inner function H(x), which is the outer functions\nwith the components of y treated as functions of x; i.e.\nH(x) = G( Y(x), x).\n\ny_index\n=======\nOn input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i],\nis the sparsity of the outer function with respect to the i-th\nresult for this atomic function.\n\nx_index\n=======\nOn input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nis the sparsity for the outer function with respect to the j-th\nargument to this atomic function.\nOn output, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nis the sparsity for the inner function with respect to the j-th\nargument to this atomic function.\n\nReturn Value\n************\nis true if the computation succeeds.\n\n{xrst_end atomic_four_rev_jac_sparsity}\n*/\n// BEGIN_REV_JAC_SPARSITY\ntemplate <class Base>\ntemplate <class InternalSparsity>\nbool atomic_four<Base>::rev_jac_sparsity(\n   size_t                           call_id      ,\n   bool                             dependency   ,\n   const vector<bool>&              ident_zero_x ,\n   const vector<size_t>&            x_index      ,\n   const vector<size_t>&            y_index      ,\n   InternalSparsity&                var_sparsity )\n// END_REV_JAC_SPARSITY\n{  typedef typename InternalSparsity::const_iterator iterator;\n\n   // number of arguments and results for this atomic function\n   size_t n = x_index.size();\n   size_t m = y_index.size();\n\n   // selection vectors\n   vector<bool> select_x(n), select_y(m);\n\n   // select_x\n   for(size_t j = 0; j < n; ++j)\n      select_x[j] = x_index[j] != 0;\n\n   // determine select_y\n   for(size_t i = 0; i < m; ++i)\n   {  if( y_index[i] == 0 )\n         select_y[i] = false;\n      else\n      {  // check if y_i has sparsity is non-empty\n         iterator itr(var_sparsity, y_index[i]);\n         size_t ell = *itr;\n         select_y[i] = ell < var_sparsity.end();\n      }\n   }\n   sparse_rc< vector<size_t> > pattern_out;\n   bool ok = jac_sparsity( call_id,\n      dependency, ident_zero_x, select_x, select_y, pattern_out\n   );\n   if( ! ok ) ok = jac_sparsity(\n      call_id, dependency, select_x, select_y, pattern_out\n   );\n   if( ! ok )\n      return false;\n   //\n   // transfer sparsity patterns from pattern_out to var_sparsity\n   size_t                nnz = pattern_out.nnz();\n   const vector<size_t>& row( pattern_out.row() );\n   const vector<size_t>& col( pattern_out.col() );\n   for(size_t k = 0; k < nnz; ++k)\n   {  size_t i = row[k];\n      size_t j = col[k];\n      CPPAD_ASSERT_KNOWN(\n         select_y[i] && select_x[j],\n         \"atomic: jac_sparsity: pattern_out not in \"\n         \"select_x or select_y range\"\n      );\n      iterator itr(var_sparsity, y_index[i]);\n      size_t ell = *itr;\n      while( ell < var_sparsity.end() )\n      {  var_sparsity.post_element( x_index[j], ell );\n         ell = *(++itr);\n      }\n   }\n   for(size_t j = 0; j < n; ++j)\n      var_sparsity.process_post( x_index[j] );\n   //\n   return true;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/four/for_type.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_FOUR_FOR_TYPE_HPP\n# define CPPAD_CORE_ATOMIC_FOUR_FOR_TYPE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_four_for_type}\n\nAtomic Function Forward Type Calculation\n########################################\n\nSyntax\n******\n| *ok* = *afun* . ``for_type`` ( *call_id* , *type_x* , *type_y* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nDependency Analysis\n*******************\nThis calculation is sometimes referred to as a forward dependency analysis.\n\nUsage\n*****\nThis syntax and prototype are used a\n:ref:`call<atomic_four_call-name>` to an atomic function.\n\nImplementation\n**************\nThis virtual function must be defined by the\n:ref:`atomic_four_ctor@atomic_user` derived class.\n\nvector\n******\nis the :ref:`CppAD_vector-name` template class.\n\nBase\n****\nSee :ref:`atomic_four_call@Base` .\n\ncall_id\n*******\nSee :ref:`atomic_four_call@call_id` .\n\nad_type\n*******\nThe type ``CppAD::ad_type_enum``\nis used to specify if an AD object is a\n:ref:`constant parameter<glossary@Parameter@Constant>`\n:ref:`dynamic parameter<glossary@Parameter@Dynamic>`\nor :ref:`glossary@Variable` .\nIt has the following possible values:\n\n.. csv-table::\n   :widths: auto\n\n   *ad_type_enum*,Meaning\n   ``identical_zero_enum``,identically zero\n   ``constant_enum``,constant parameter\n   ``dynamic_enum``,dynamic parameter\n   ``variable_enum``,variable\n\nIn addition,\n\n   ``identical_zero_enum < constant_enum < dynamic_enum < variable_enum``\n\nA value that is identically zero is also a constant parameter.\nIn CppAD, multiplication of a variable by a value that is identically zero\nis sometimes treated like :ref:`azmul-title`.\nThis avoids having to record the operation.\n\ntype_x\n******\nThis vector has size equal to the number of arguments in the\natomic function call; i.e., the size of\n:ref:`atomic_four_call@ax` which we denote by *n* .\nFor *j* =0,..., *n* ``-1`` , *type_x* [ *j* ]\nis the type of *ax* [ *j* ] .\n\ntype_y\n******\nThis vector has size equal to the number of results in the\natomic function call; i.e., the size of\n:ref:`atomic_four_call@ay` which we denote by *m* .\nThe input values of the elements of *type_y*\nare not specified (must not matter).\nUpon return, for :math:`i = 0 , \\ldots , m-1`,\n*type_y* [ *i* ] is set to one of the following values:\n\n#. It is ``identical_zero_enum`` if *ay* [ *i* ] is\n   :ref:`identically zero<base_identical@Identical>` .\n#. It is ``constant_enum`` if *ay* [ *i* ] only depends on\n   the arguments that are constants.\n#. It is ``dynamic_enum`` if *ay* [ *i* ] depends on\n   a dynamic parameter and does not depend on any variables.\n#. It is ``variable_enum`` if *ay* [ *i* ] depends on\n   a variable.\n\nok\n**\nIf this calculation succeeded, *ok* is true.\nOtherwise, it is false.\n\nExample\n*******\nThe following is an example ``for_type`` definition taken from\n:ref:`atomic_four_norm_sq.cpp-name` :\n{xrst_literal\n   example/atomic_four/norm_sq.cpp\n   // BEGIN FOR_TYPE\n   // END FOR_TYPE\n}\n\n{xrst_end atomic_four_for_type}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n// BEGIN_PROTOTYPE\ntemplate <class Base>\nbool atomic_four<Base>::for_type(\n   size_t                       call_id     ,\n   const vector<ad_type_enum>&  type_x      ,\n   vector<ad_type_enum>&        type_y      )\n// END_PROTOTYPE\n{  return false; }\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/four/forward.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_FOUR_FORWARD_HPP\n# define CPPAD_CORE_ATOMIC_FOUR_FORWARD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_four_forward}\n{xrst_spell\n   ataylor\n}\n\nAtomic Function Forward Mode\n############################\n\nSyntax\n******\n\nBase\n====\n\n| *ok* = *afun* . ``forward`` (\n| |tab| *call_id* , *select_y* ,\n| |tab| *order_low* , *order_up* , *type_x* , *taylor_x* , *taylor_y*\n| )\n\nAD<Base>\n========\n\n| *ok* = *afun* . ``forward`` (\n| |tab| *call_id* , *select_y* ,\n| |tab| *order_low* , *order_up* , *type_x* , *ataylor_x* , *ataylor_y*\n| )\n\nPrototype\n*********\n\nBase\n====\n{xrst_literal\n   // BEGIN_PROTOTYPE_BASE\n   // END_PROTOTYPE_BASE\n}\n\nAD<Base>\n========\n{xrst_literal\n   // BEGIN_PROTOTYPE_AD_BASE\n   // END_PROTOTYPE_AD_BASE\n}\n\nBase\n****\nsee :ref:`atomic_four_call@Base` .\n\nvector\n******\nis the :ref:`CppAD_vector-name` template class.\n\nUsage\n*****\n\nBase\n====\nThe *Base* syntax and prototype are used by a\n:ref:`call<atomic_four_call-name>` to the atomic function *afun* .\nThey are also used by\n*f* . ``Forward`` and *f* . ``new_dynamic``\nwhere *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nand *afun* is used during the recording of *f* .\n\nAD<Base>\n========\nThe ``AD`` < *Base* > syntax and prototype are used by\n*af* . ``Forward`` and *af* . ``new_dynamic``\nwhere *af* has prototype\n\n   ``ADFun< AD<`` *Base* > , *Base* > *af*\n\nand *afun* is used in a function *af* ,\ncreated from *f* using :ref:`base2ad-name` .\n\nImplementation\n**************\nThe *taylor_x* , *taylor_y* version of this function\nmust be defined by the\n:ref:`atomic_four_ctor@atomic_user` class.\nIt can return *ok* == ``false``\n(and not compute anything) for values\nof *order_up* that are greater than those used by your\n:ref:`Forward-name` mode calculations.\nOrder zero must be implemented.\n\ncall_id\n*******\nSee :ref:`atomic_four_call@call_id` .\n\nselect_y\n********\nThis argument has size equal to the number of results to this\natomic function; i.e. the size of :ref:`atomic_four_call@ay` .\nIt specifies which components of *y* the corresponding\nTaylor coefficients must be computed.\n\norder_low\n*********\nThis argument\nspecifies the lowest order Taylor coefficient that we are computing.\n\np\n=\nWe sometimes use the notation *p* = *order_low* below.\n\norder_up\n********\nThis argument is the highest order Taylor coefficient that we\nare computing ( *order_low* <= *order_up* ).\n\nq\n=\nWe use the notation *q* = *order_up*  + 1 below.\nThis is the number of Taylor coefficients for each\ncomponent of *x* and *y* .\n\ntaylor_x\n********\nThe size of *taylor_x* is *q* * *n* .\nFor :math:`j = 0 , \\ldots , n-1` and :math:`k = 0 , \\ldots , q-1`,\nwe use the Taylor coefficient notation\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      x_j^k    & = & \\R{taylor\\_x} [ j * q + k ]\n      \\\\\n      X_j (t)  & = & x_j^0 + x_j^1 t^1 + \\cdots + x_j^{q-1} t^{q-1}\n   \\end{eqnarray}\n\nNote that superscripts represent an index for :math:`x_j^k`\nand an exponent for :math:`t^k`.\nAlso note that the Taylor coefficients for :math:`X(t)` correspond\nto the derivatives of :math:`X(t)` at :math:`t = 0` in the following way:\n\n.. math::\n\n   x_j^k = \\frac{1}{ k ! } X_j^{(k)} (0)\n\nparameters\n==========\nIf the *j*-th component of *x* is a parameter,\n\n   *type_x* [ *j* ] < ``CppAD::variable_enum``\n\nIn this case, for *k*  > 0 ,\n\n   *taylor_x* [ *j* * *q* + *k*  ] == 0\n\nataylor_x\n*********\nThe specifications for *ataylor_x* is the same as for *taylor_x*\n(only the type of *ataylor_x* is different).\n\ntaylor_y\n********\nThe size of *taylor_y* is *q* * *m* .\nUpon return,\nFor :math:`i = 0 , \\ldots , m-1` and :math:`k = 0 , \\ldots , q-1`,\nif *select_y* [ *i* ] is true,\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      Y_i (t)  & = & g_i [ X(t) ]\n      \\\\\n      Y_i (t)  & = & y_i^0 + y_i^1 t^1 + \\cdots + y_i^{q-1} t^{q-1} + o( t^{q-1} )\n      \\\\\n      \\R{taylor\\_y}  [ i * q + k ] & = & y_i^k\n   \\end{eqnarray}\n\nwhere :math:`o( t^{q-1} ) / t^{q-1} \\rightarrow 0`\nas :math:`t \\rightarrow 0`.\nNote that superscripts represent an index for :math:`y_j^k`\nand an exponent for :math:`t^k`.\nAlso note that the Taylor coefficients for :math:`Y(t)` correspond\nto the derivatives of :math:`Y(t)` at :math:`t = 0` in the following way:\n\n.. math::\n\n   y_j^k = \\frac{1}{ k ! } Y_j^{(k)} (0)\n\nIf :math:`p > 0`,\nfor :math:`i = 0 , \\ldots , m-1` and :math:`k = 0 , \\ldots , p-1`,\nthe input of *taylor_y* satisfies\n\n.. math::\n\n   \\R{taylor\\_y}  [ i * q + k ] = y_i^k\n\nThese values do not need to be recalculated\nand can be used during the computation of the higher order coefficients.\n\nataylor_y\n*********\nThe specifications for *ataylor_y* is the same as for *taylor_y*\n(only the type of *ataylor_y* is different).\n\nok\n**\nIf this calculation succeeded, *ok* is true.\nOtherwise, it is false.\n\nDiscussion\n**********\nFor example, suppose that *order_up*  == 2 ,\nand you know how to compute the function :math:`g(x)`,\nits first derivative :math:`g^{(1)} (x)`,\nand it component wise Hessian :math:`g_i^{(2)} (x)`.\nThen you can compute *taylor_x* using the following formulas:\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   y_i^0 & = & Y(0)\n         = g_i ( x^0 )\n   \\\\\n   y_i^1 & = & Y^{(1)} ( 0 )\n         = g_i^{(1)} ( x^0 ) X^{(1)} ( 0 )\n         = g_i^{(1)} ( x^0 ) x^1\n   \\\\\n   y_i^2\n   & = & \\frac{1}{2 !} Y^{(2)} (0)\n   \\\\\n   & = & \\frac{1}{2} X^{(1)} (0)^\\R{T} g_i^{(2)} ( x^0 ) X^{(1)} ( 0 )\n     +   \\frac{1}{2} g_i^{(1)} ( x^0 ) X^{(2)} ( 0 )\n   \\\\\n   & = & \\frac{1}{2} (x^1)^\\R{T} g_i^{(2)} ( x^0 ) x^1\n     +    g_i^{(1)} ( x^0 ) x^2\n   \\end{eqnarray}\n\nFor :math:`i = 0 , \\ldots , m-1`, and :math:`k = 0 , 1 , 2`,\n\n.. math::\n\n   \\R{taylor\\_y} [ i * q + k ] = y_i^k\n\nExample\n*******\nThe following is an example ``forward`` definition taken from\n:ref:`atomic_four_norm_sq.cpp-name` :\n{xrst_literal\n   example/atomic_four/norm_sq.cpp\n   // BEGIN FORWARD\n   // END FORWARD\n}\n\n{xrst_end atomic_four_forward}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n// BEGIN_PROTOTYPE_BASE\ntemplate <class Base>\nbool atomic_four<Base>::forward(\n   size_t                       call_id     ,\n   const vector<bool>&          select_y    ,\n   size_t                       order_low   ,\n   size_t                       order_up    ,\n   const vector<Base>&          taylor_x    ,\n   vector<Base>&                taylor_y    )\n// END_PROTOTYPE_BASE\n{  return false; }\n\n// BEGIN_PROTOTYPE_AD_BASE\ntemplate <class Base>\nbool atomic_four<Base>::forward(\n   size_t                       call_id      ,\n   const vector<bool>&          select_y    ,\n   size_t                       order_low    ,\n   size_t                       order_up     ,\n   const vector< AD<Base> >&    ataylor_x    ,\n   vector< AD<Base> >&          ataylor_y    )\n// END_PROTOTYPE_AD_BASE\n{  return false; }\n\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/four/hes_sparsity.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_FOUR_HES_SPARSITY_HPP\n# define CPPAD_CORE_ATOMIC_FOUR_HES_SPARSITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/core/atomic/four/devel/hes_sparsity.hpp>\n/*\n{xrst_begin atomic_four_hes_sparsity}\n\nAtomic Function Hessian Sparsity Patterns\n#########################################\n\nSyntax\n******\n\nPreferred\n=========\n\n| *ok* = *afun* . ``hes_sparsity`` ( *call_id* ,\n| |tab| *ident_zero_x* , *select_x* , *select_y* , *pattern_out*\n| )\n\nDeprecated 2022-05-16\n=====================\n\n| *ok* = *afun* . ``hes_sparsity`` ( *call_id* ,\n| |tab| *select_x* , *select_y* , *pattern_out*\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nImplementation\n**************\nThis function must be defined if\n:ref:`atomic_four_ctor@atomic_user@afun` is\nused to define an :ref:`ADFun-name` object *f* ,\nand Hessian sparsity patterns are computed for *f* .\n\nBase\n****\nSee :ref:`atomic_four_call@Base` .\n\nvector\n******\nis the :ref:`CppAD_vector-name` template class.\n\ncall_id\n*******\nSee :ref:`atomic_four_call@call_id` .\n\nident_zero_x\n************\nThis can sometimes be used to create more efficient sparsity patterns.\nIf you do not see a way to do this, you can just ignore it.\nThis argument has size equal to the number of arguments to this\natomic function; i.e. the size of *ax* .\nIf *ident_zero_x* [ *j* ] is true, the argument *ax* [ *j* ]\nis a constant parameter that is identically zero.\nAn identically zero value times any other value can be treated\nas being identically zero.\n\nselect_x\n********\nThis argument has size equal to the number of arguments to this\natomic function; i.e. the size of *ax* .\nIt specifies which domain components are included in\nthe calculation of *pattern_out* .\nIf *select_x* [ *j* ] is false, then there will be no indices\n*k* such that either of the following hold:\n\n| |tab| *pattern_out* . ``row`` ()[ *k* ] == *j*\n| |tab| *pattern_out* . ``col`` ()[ *k* ] == *j*\n\n.\n\nselect_y\n********\nThis argument has size equal to the number of results to this\natomic function; i.e. the size of *ay* .\nIt specifies which range component functions :math:`g_i (x)` are included in\nof *pattern_out* .\n\npattern_out\n***********\nThis input value of *pattern_out* does not matter.\nUpon return it is the union,\nwith respect to *i* such that *select_y* [ *i* ] is true,\nof the sparsity pattern for Hessian of :math:`g_i (x)`.\nTo be specific, there are non-negative indices\n*r* , *c* , and *k* such that\n\n| |tab| *pattern_out* . ``row`` ()[ *k* ] == *r*\n| |tab| *pattern_out* . ``col`` ()[ *k* ] == *c*\n\nif and only if\nthere exists an index *i* such that,\n*select_y* [ *i* ] is true,\n*select_x* [ *r* ] is true,\n*select_x* [ *c* ] is true,\nand\n\n.. math::\n\n   \\partial_{x(r)} \\partial_{x(c)} g_i(x)\n\nis possibly non-zero.\nNote that the sparsity pattern should be symmetric.\n\nok\n**\nIf this calculation succeeded, *ok* is true.\nOtherwise it is false.\n\nExample\n*******\nThe following is an example ``hes_sparsity`` definition taken from\n:ref:`atomic_four_norm_sq.cpp-name` :\n{xrst_literal\n   example/atomic_four/norm_sq.cpp\n   // BEGIN HES_SPARSITY\n   // END HES_SPARSITY\n}\n\n{xrst_end atomic_four_hes_sparsity}\n-----------------------------------------------------------------------------\n*/\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n// BEGIN_PROTOTYPE\ntemplate <class Base>\nbool atomic_four<Base>::hes_sparsity(\n   size_t                                  call_id      ,\n   const vector<bool>&                     ident_zero_x ,\n   const vector<bool>&                     select_x     ,\n   const vector<bool>&                     select_y     ,\n   sparse_rc< vector<size_t> >&            pattern_out  )\n// END_PROTOTYPE\n{  return false; }\n//\n// deprecated version\ntemplate <class Base>\nbool atomic_four<Base>::hes_sparsity(\n   size_t                                  call_id      ,\n   const vector<bool>&                     select_x     ,\n   const vector<bool>&                     select_y     ,\n   sparse_rc< vector<size_t> >&            pattern_out  )\n{  return false; }\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/four/jac_sparsity.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_FOUR_JAC_SPARSITY_HPP\n# define CPPAD_CORE_ATOMIC_FOUR_JAC_SPARSITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/core/atomic/four/devel/jac_sparsity.hpp>\n\n/*\n{xrst_begin atomic_four_jac_sparsity}\n\nAtomic Function Jacobian Sparsity Patterns\n##########################################\n\nSyntax\n******\n| You can define one or the other of the following callbacks,\n| but you should not define both.\n\nPreferred\n=========\n\n| *ok* = *afun* . ``jac_sparsity`` ( *call_id* ,\n| |tab| *dependency* , *ident_zero_x* , *select_x* , *select_y* , *pattern_out*\n| )\n\nDeprecated 2022-05-10\n=====================\n\n| *ok* = *afun* . ``jac_sparsity`` (\n| |tab| *dependency* , *call_id* , *select_x* , *select_y* , *pattern_out*\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nImplementation\n**************\nThis function must be defined if\n:ref:`atomic_four_ctor@atomic_user@afun` is\nused to define an :ref:`ADFun-name` object *f* ,\nand Jacobian sparsity patterns are computed for *f* .\n(Computing Hessian sparsity patterns\nrequires Jacobian sparsity patterns.)\n\nBase\n****\nSee :ref:`atomic_four_call@Base` .\n\nvector\n******\nis the :ref:`CppAD_vector-name` template class.\n\ncall_id\n*******\nSee :ref:`atomic_four_call@call_id` .\n\ndependency\n**********\nIf *dependency* is true,\nthen *pattern_out* is a\n:ref:`dependency.cpp@Dependency Pattern`\nfor this atomic function.\nOtherwise it is a\n:ref:`glossary@Sparsity Pattern` for the\nderivative of the atomic function.\n\nident_zero_x\n************\nThis can sometimes be used to create more efficient sparsity patterns.\nIf you do not see a way to do this, you can just ignore it.\nThis argument has size equal to the number of arguments to this\natomic function; i.e. the size of *ax* .\nIf *ident_zero_x* [ *j* ] is true, the argument *ax* [ *j* ]\nis a constant parameter that is identically zero.\nAn identically zero value times any other value can be treated\nas being identically zero.\n\nselect_x\n********\nThis argument has size equal to the number of arguments to this\natomic function; i.e. the size of *ax* .\nIt specifies which domain components are included in\nthe calculation of *pattern_out* .\nIf *select_x* [ *j* ] is false, then there will be no indices\n*k* such that\n\n   *pattern_out* . ``col`` ()[ *k* ] == *j*\n\n.\nIf *select_x* [ *j* ] is true, the argument *ax* [ *j* ]\nis a variable and *ident_zero_x* [ *j* ] will be false.\n\nselect_y\n********\nThis argument has size equal to the number of results to this\natomic function; i.e. the size of *ay* .\nIt specifies which range components are included in\nthe calculation of *pattern_out* .\nIf *select_y* [ *i* ] is false, then there will be no indices\n*k* such that\n\n   *pattern_out* . ``row`` ()[ *k* ] == *i*\n\n.\n\npattern_out\n***********\nThis input value of *pattern_out* does not matter.\nUpon return it is a\ndependency or sparsity pattern for the Jacobian of :math:`g(x)`,\nthe function corresponding to\n:ref:`atomic_four_ctor@atomic_user@afun` .\nTo be specific, there are non-negative indices\n*i* , *j* , *k* such that\n\n| |tab| *pattern_out* . ``row`` ()[ *k* ] == *i*\n| |tab| *pattern_out* . ``col`` ()[ *k* ] == *j*\n\nif and only if\n*select_x* [ *j* ] is true,\n*select_y* [ *j* ] is true,\nand :math:`g_i(x)` depends on the value of :math:`x_j`\n(and the partial of :math:`g_i(x)` with respect to\n:math:`x_j` is possibly non-zero).\n\nok\n**\nIf this calculation succeeded, *ok* is true.\nOtherwise it is false.\n\nExample\n*******\nThe following is an example ``jac_sparsity`` definition taken from\n:ref:`atomic_four_norm_sq.cpp-name` :\n{xrst_literal\n   example/atomic_four/norm_sq.cpp\n   // BEGIN JAC_SPARSITY\n   // END JAC_SPARSITY\n}\n\n{xrst_end atomic_four_jac_sparsity}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n//\n// BEGIN_PROTOTYPE\ntemplate <class Base>\nbool atomic_four<Base>::jac_sparsity(\n   size_t                                  call_id      ,\n   bool                                    dependency   ,\n   const vector<bool>&                     ident_zero_x ,\n   const vector<bool>&                     select_x     ,\n   const vector<bool>&                     select_y     ,\n   sparse_rc< vector<size_t> >&            pattern_out  )\n// END_PROTOTYPE\n{  return false; }\n//\n// deprecated version of jac_sparsity callback\ntemplate <class Base>\nbool atomic_four<Base>::jac_sparsity(\n   size_t                                  call_id      ,\n   bool                                    dependency   ,\n   const vector<bool>&                     select_x     ,\n   const vector<bool>&                     select_y     ,\n   sparse_rc< vector<size_t> >&            pattern_out  )\n{  return false; }\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/four/rev_depend.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_FOUR_REV_DEPEND_HPP\n# define CPPAD_CORE_ATOMIC_FOUR_REV_DEPEND_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-23 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_four_rev_depend}\n\nAtomic Function Reverse Dependency\n##################################\n\nSyntax\n******\nYou can define one or the other of the following callbacks,\nbut you should not define both.\n\nPreferred\n=========\n\n| *ok* = *afun* . ``rev_depend`` ( *call_id* ,\n| |tab| *ident_zero_x* , *depend_x* , *depend_y*\n| )\n\nDeprecated 2022-05-10\n=====================\n\n| *ok* = *afun* . ``rev_depend`` ( *call_id* ,\n| |tab| *depend_x* , *depend_y*\n| )\n\nPrototype\n=========\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nDependency Analysis\n*******************\nThis calculation is sometimes referred to as a reverse dependency analysis.\n\nImplementation\n**************\nThis function must be defined if\n:ref:`atomic_four_ctor@atomic_user@afun` is\nused to define an :ref:`ADFun-name` object *f* ,\nand :ref:`f.optimize()<optimize-name>` is used.\n\nBase\n****\nSee :ref:`atomic_four_call@Base` .\n\nvector\n******\nis the :ref:`CppAD_vector-name` template class.\n\ncall_id\n*******\nSee :ref:`atomic_four_call@call_id` .\n\nident_zero_x\n************\nThis can sometimes be used to create more efficient dependency\n(fewer true values in *depend_x* ).\nIf you do not see a way to do this, you can just ignore it.\nThis argument has size equal to the number of arguments to this\natomic function; i.e. the size of *ax* .\nIf *ident_zero_x* [ *j* ] is true, the argument *ax* [ *j* ]\nis a constant parameter that is identically zero.\nAn identically zero value times any other value can be treated\nas being identically zero.\n\ndepend_x\n********\nThis vector has size equal to the number of arguments for this atomic function;\ni.e. *n* = *ax* . ``size`` () (see :ref:`atomic_four_call@ax` ).\nThe input values of the elements of *depend_x*\nare not specified (must not matter).\nUpon return, for :math:`j = 0 , \\ldots , n-1`,\n*depend_x* [ *j* ] is true if the values of interest depend\non the value of *ax* [ *j* ] in the corresponding atomic function call.\n\nOptimize\n========\nParameters and variables,\nthat the values of interest do not depend on,\nmay get removed by :ref:`optimization<optimize-name>` .\nThe corresponding values in\n:ref:`atomic_four_forward@taylor_x`\n(after optimization has removed them) are currently zero,\nbut perhaps these should be changed back to nan.\n\ndepend_y\n********\nThis vector has size equal to the number of results for this atomic function;\ni.e. *m* = *ay* . ``size`` () (see :ref:`atomic_four_call@ay` ).\nFor :math:`i = 0 , \\ldots , m-1`,\n*depend_y* [ *i* ] is true if the values of interest depend\non the value of *ay* [ *i* ] in the corresponding atomic function call.\n\nok\n**\nIf this calculation succeeded, *ok* is true.\nOtherwise, it is false.\n\nExample\n*******\nThe following is an example ``rev_depend`` definition taken from\n:ref:`atomic_four_norm_sq.cpp-name` :\n{xrst_literal\n   example/atomic_four/norm_sq.cpp\n   // BEGIN REV_DEPEND\n   // END REV_DEPEND\n}\n\n{xrst_end atomic_four_rev_depend}\n-----------------------------------------------------------------------------\n*/\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n// BEGIN_PROTOTYPE\ntemplate <class Base>\nbool atomic_four<Base>::rev_depend(\n   size_t                      call_id      ,\n   const vector<bool>&         ident_zero_x ,\n   vector<bool>&               depend_x     ,\n   const vector<bool>&         depend_y     )\n// END_PROTOTYPE\n{  return false; }\n\n// deprecated version\ntemplate <class Base>\nbool atomic_four<Base>::rev_depend(\n   size_t                      call_id     ,\n   vector<bool>&               depend_x    ,\n   const vector<bool>&         depend_y    )\n// end deprecated version\n{  return false; }\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/four/reverse.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_FOUR_REVERSE_HPP\n# define CPPAD_CORE_ATOMIC_FOUR_REVERSE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_four_reverse}\n{xrst_spell\n   apartial\n   ataylor\n}\n\nAtomic Function Reverse Mode\n############################\n\nSyntax\n******\n\nBase\n====\n\n| *ok* = *afun* . ``reverse`` (\n| |tab| *call_id* , *select_x* ,\n| |tab| *order_up* , *taylor_x* , *taylor_y* , *partial_x* , *partial_y*\n| )\n\nAD<Base>\n========\n\n| *ok* = *afun* . ``reverse`` (\n| |tab| *call_id* , *select_x* ,\n| |tab| *order_up* , *ataylor_x* , *ataylor_y* , *apartial_x* , *apartial_y*\n| )\n\nPrototype\n*********\n\nBase\n====\n{xrst_literal\n   // BEGIN_PROTOTYPE_BASE\n   // END_PROTOTYPE_BASE\n}\n\nAD<Base>\n========\n{xrst_literal\n   // BEGIN_PROTOTYPE_AD_BASE\n   // END_PROTOTYPE_AD_BASE\n}\n\nBase\n****\nsee :ref:`atomic_four_call@Base` .\n\nvector\n******\nis the :ref:`CppAD_vector-name` template class.\n\nUsage\n*****\n\nBase\n====\nThis syntax is used by *f* . ``Reverse`` where *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nand atomic function *afun* is used in *f* ;\nsee :ref:`atomic_four_call@Base` .\n\nAD<Base>\n========\nThis syntax is used by *af* . ``Reverse`` where *af* has prototype\n\n   ``ADFun< AD<`` *Base* > , *Base* > *af*\n\nand the atomic function *afun* is used in\n*af* ; see :ref:`base2ad-name` .\n\nImplementation\n**************\nThis function must be defined if\n:ref:`atomic_four_ctor@atomic_user@afun` is\nused during the recording of an :ref:`ADFun-name` object *f* ,\nand reverse mode derivatives are computed for *f* .\nIt can return *ok* == ``false``\n(and not compute anything) for values\nof *order_up* that are greater than those used by your\n:ref:`Reverse-name` mode calculations.\n\ncall_id\n*******\nSee :ref:`atomic_four_call@call_id` .\n\nselect_x\n********\nThis argument has size equal to the number of arguments to this\natomic function; i.e. the size of :ref:`atomic_four_call@ax` .\nIt specifies which components of *x* the corresponding\npartial derivatives *partial_x* must be computed.\n\norder_up\n********\nThis argument is one greater than highest order Taylor coefficient that\ncomputing the derivative of.\n\nq\n*\nWe use the notation *q* = *order_up*  + 1 below.\nThis is one less than the number of Taylor coefficients for each component\nof *x* and *y* .\n\ntaylor_x\n********\nThe size of *taylor_x* is *q* * *n* .\nFor :math:`j = 0 , \\ldots , n-1` and :math:`k = 0 , \\ldots , q-1`,\nwe use the Taylor coefficient notation\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      x_j^k    & = & \\R{taylor\\_x} [ j * q + k ]\n      \\\\\n      X_j (t)  & = & x_j^0 + x_j^1 t^1 + \\cdots + x_j^{q-1} t^{q-1}\n   \\end{eqnarray}\n\nNote that superscripts represent an index for :math:`x_j^k`\nand an exponent for :math:`t^k`.\nAlso note that the Taylor coefficients for :math:`X(t)` correspond\nto the derivatives of :math:`X(t)` at :math:`t = 0` in the following way:\n\n.. math::\n\n   x_j^k = \\frac{1}{ k ! } X_j^{(k)} (0)\n\nparameters\n==========\nIf the *j*-th component of *x* is a parameter,\n\n   *type_x* [ *j* ] < ``CppAD::variable_enum``\n\nIn this case, for *k*  > 0 ,\n\n   *taylor_x* [ *j* * *q* + *k*  ] == 0\n\nataylor_x\n*********\nThe specifications for *ataylor_x* is the same as for *taylor_x*\n(only the type of *ataylor_x* is different).\n\ntaylor_y\n********\nThe size of *taylor_y* is *q* * *m* .\nFor :math:`i = 0 , \\ldots , m-1` and :math:`k = 0 , \\ldots , q-1`,\nwe use the Taylor coefficient notation\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      Y_i (t)  & = & g_i [ X(t) ]\n      \\\\\n      Y_i (t)  & = &\n         y_i^0 + y_i^1 t^1 + \\cdots + y_i^{q-1} t^{q-1} + o ( t^{q-1} )\n      \\\\\n      y_i^k    & = & \\R{taylor\\_y} [ i * q + k ]\n   \\end{eqnarray}\n\nwhere :math:`o( t^{q-1} ) / t^{q-1} \\rightarrow 0` as :math:`t \\rightarrow 0`.\nNote that superscripts represent an index for :math:`y_j^k`\nand an exponent for :math:`t^k`.\nAlso note that the Taylor coefficients for :math:`Y(t)` correspond\nto the derivatives of :math:`Y(t)` at :math:`t = 0` in the following way:\n\n.. math::\n\n   y_j^k = \\frac{1}{ k ! } Y_j^{(k)} (0)\n\nataylor_y\n*********\nThe specifications for *ataylor_y* is the same as for *taylor_y*\n(only the type of *ataylor_y* is different).\n\nF\n*\nWe use the notation :math:`\\{ x_j^k \\} \\in \\B{R}^{n \\times q}` for\n\n.. math::\n\n   \\{ x_j^k \\W{:} j = 0 , \\ldots , n-1, k = 0 , \\ldots , q-1 \\}\n\nWe use the notation :math:`\\{ y_i^k \\} \\in \\B{R}^{m \\times q}` for\n\n.. math::\n\n   \\{ y_i^k \\W{:} i = 0 , \\ldots , m-1, k = 0 , \\ldots , q-1 \\}\n\nWe use\n:math:`F : \\B{R}^{n \\times q} \\rightarrow \\B{R}^{m \\times q}` by\nto denote the function corresponding to the forward mode calculations\n\n.. math::\n\n   y_i^k = F_i^k [ \\{ x_j^k \\} ]\n\nNote that\n\n.. math::\n\n   F_i^0 ( \\{ x_j^k \\} ) = g_i ( X(0) )  = g_i ( x^0 )\n\nWe also note that\n:math:`F_i^\\ell ( \\{ x_j^k \\} )` is a function of\n:math:`x^0 , \\ldots , x^\\ell`; i.e.,\nit is determined by the derivatives of :math:`g_i (x)`\nup to order :math:`\\ell`.\n\nG, H\n****\nWe use :math:`G : \\B{R}^{m \\times q} \\rightarrow \\B{R}`\nto denote an arbitrary scalar valued function of :math:`\\{ y_i^k \\}`.\nWe use :math:`H : \\B{R}^{n \\times q} \\rightarrow \\B{R}`\ndefined by\n\n.. math::\n\n   H ( \\{ x_j^k \\} ) = G[ F( \\{ x_j^k \\} ) ]\n\npartial_y\n*********\nThe size of *partial_y* is *q* * *m* .\nFor :math:`i = 0 , \\ldots , m-1`, :math:`k = 0 , \\ldots , q-1`,\n\n.. math::\n\n   \\R{partial\\_y} [ i * q + k ] = \\partial G / \\partial y_i^k\n\napartial_y\n**********\nThe specifications for *apartial_y* is the same as for\n*partial_y* (only the type of *apartial_y* is different).\n\npartial_x\n*********\nThe size of *partial_x* is *q* * *n* .\nThe input values of the elements of *partial_x*\nare not specified (must not matter).\nUpon return,\nfor :math:`j = 0 , \\ldots , n-1` and :math:`\\ell = 0 , \\ldots , q-1`,\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   \\R{partial\\_x} [ j * q + \\ell ] & = & \\partial H / \\partial x_j^\\ell\n   \\\\\n   & = &\n   ( \\partial G / \\partial \\{ y_i^k \\} ) \\cdot\n      ( \\partial \\{ y_i^k \\} / \\partial x_j^\\ell )\n   \\\\\n   & = &\n   \\sum_{k=0}^{q-1}\n   \\sum_{i=0}^{m-1}\n   ( \\partial G / \\partial y_i^k ) ( \\partial y_i^k / \\partial x_j^\\ell )\n   \\\\\n   & = &\n   \\sum_{k=\\ell}^{q-1}\n   \\sum_{i=0}^{m-1}\n   \\R{partial\\_y}[ i * q + k ] ( \\partial F_i^k / \\partial x_j^\\ell )\n   \\end{eqnarray}\n\nNote that we have used the fact that for :math:`k < \\ell`,\n:math:`\\partial F_i^k / \\partial x_j^\\ell = 0`.\n\nazmul\n=====\nAn :ref:`optimized<optimize-name>` function will use zero\nfor values in *taylor_x* and *taylor_y* that are\nnot necessary in the current context.\nIf you divide by these values when computing\n:math:`( \\partial F_i^k / \\partial x_j^\\ell )` you could get an nan\nif the corresponding value in *partial_y* is zero.\nTo be careful, if you do divide by\n*taylor_x* or *taylor_y* , use :ref:`azmul-name`\nfor to avoid zero over zero calculations.\n\napartial_x\n**********\nThe specifications for *apartial_x* is the same as for\n*partial_x* (only the type of *apartial_x* is different).\n\nok\n**\nIf this calculation succeeded, *ok* is true.\nOtherwise it is false.\n\nExample\n*******\nThe following is an example ``reverse`` definition taken from\n:ref:`atomic_four_norm_sq.cpp-name` :\n{xrst_literal\n   example/atomic_four/norm_sq.cpp\n   // BEGIN REVERSE\n   // END REVERSE\n}\n\nExamples\n********\nThe file :ref:`atomic_four_norm_sq.cpp-name`\ncontains an example that defines this routine.\n\n{xrst_end atomic_four_reverse}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n// BEGIN_PROTOTYPE_BASE\ntemplate <class Base>\nbool atomic_four<Base>::reverse(\n   size_t                      call_id     ,\n   const vector<bool>&         select_x    ,\n   size_t                      order_up    ,\n   const vector<Base>&         taylor_x    ,\n   const vector<Base>&         taylor_y    ,\n   vector<Base>&               partial_x   ,\n   const vector<Base>&         partial_y   )\n// END_PROTOTYPE_BASE\n{  return false; }\n\n// BEGIN_PROTOTYPE_AD_BASE\ntemplate <class Base>\nbool atomic_four<Base>::reverse(\n   size_t                          call_id      ,\n   const vector<bool>&             select_x     ,\n   size_t                          order_up     ,\n   const vector< AD<Base> >&       ataylor_x    ,\n   const vector< AD<Base> >&       ataylor_y    ,\n   vector< AD<Base> >&             apartial_x   ,\n   const vector< AD<Base> >&       apartial_y   )\n// END_PROTOTYPE_AD_BASE\n{  return false; }\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/one/atomic.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_ONE_ATOMIC_HPP\n# define CPPAD_CORE_ATOMIC_ONE_ATOMIC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_one app}\n{xrst_spell\n   px\n   py\n   tvector\n   tx\n   vx\n   vy\n}\n\nDefining Atomic Functions: First Generation\n###########################################\n\nDeprecated 2013-05-27\n*********************\nUsing ``CPPAD_USER_ATOMIC`` has been deprecated.\nUse :ref:`atomic_three-name` instead.\n\nSyntax Function\n***************\n\n| ``CPPAD_USER_ATOMIC`` ( *afun* , *Tvector* , *Base* ,\n| |tab| *forward* , *reverse* , *for_jac_sparse* , *rev_jac_sparse* , *rev_hes_sparse*\n| )\n\nUse Function\n============\n\n   *afun* ( *id* , *ax* , *ay* )\n\nCallback Routines\n=================\n\n| *ok* = *forward* ( *id* , *k* , *n* , *m* , *vx* , *vy* , *tx* , *ty* )\n| *ok* = *reverse* ( *id* , *k* , *n* , *m* , *tx* , *ty* , *px* , *py* )\n| *ok* = *for_jac_sparse* ( *id* , *n* , *m* , *q* , *r* , *s* )\n| *ok* = *rev_jac_sparse* ( *id* , *n* , *m* , *q* , *r* , *s* )\n| *ok* = *rev_hes_sparse* ( *id* , *n* , *m* , *q* , *r* , *s* , *t* , *u* , *v* )\n\nFree Static Memory\n==================\n``user_atomic`` < *Base* >:: ``clear`` ()\n\nPurpose\n*******\nIn some cases, the user knows how to compute the derivative\nof a function\n\n.. math::\n\n   y = f(x) \\; {\\rm where} \\; f : \\B{R}^n \\rightarrow \\B{R}^m\n\nmore efficiently than by coding it using ``AD`` < *Base* >\n:ref:`atomic_base<glossary@Operation@Atomic>` operations\nand letting CppAD do the rest.\nIn this case, ``CPPAD_USER_ATOMIC`` can be used\nadd the user code for :math:`f(x)`, and its derivatives,\nto the set of ``AD`` < *Base* > atomic operations.\n\nAnother possible purpose is to reduce the size of the tape.\n\nPartial Implementation\n**********************\nThe routines\n:ref:`atomic_one@forward` ,\n:ref:`atomic_one@reverse` ,\n:ref:`atomic_one@for_jac_sparse` ,\n:ref:`atomic_one@rev_jac_sparse` , and\n:ref:`atomic_one@rev_hes_sparse` ,\nmust be defined by the user.\nThe *forward* the routine,\nfor the case *k*  = 0 , must be implemented.\nFunctions with the correct prototype,\nthat just return ``false`` ,\ncan be used for the other cases\n(unless they are required by your calculations).\nFor example, you need not implement\n*forward* for the case *k*  == 2 until you require\nforward mode calculation of second derivatives.\n\nCPPAD_USER_ATOMIC\n*****************\nThe macro\n\n| ``CPPAD_USER_ATOMIC`` ( *afun* , *Tvector* , *Base* ,\n| |tab| *forward* , *reverse* , *for_jac_sparse* , *rev_jac_sparse* , *rev_hes_sparse*\n| )\n\ndefines the ``AD`` < *Base* > routine *afun* .\nThis macro can be placed within a namespace\n(not the ``CppAD`` namespace)\nbut must be outside of any routine.\n\nTvector\n=======\nThe macro argument *Tvector* must be a\n:ref:`simple vector template class<SimpleVector-name>` .\nIt determines the type of vectors used as arguments to the routine\n*afun* .\n\nBase\n====\nThe macro argument *Base* specifies the\n:ref:`base type<base_require-name>`\ncorresponding to ``AD`` < *Base>* operation sequences.\nCalling the routine *afun* will add the operator defined\nby this macro to an ``AD`` < *Base>* operation sequence.\n\nok\n**\nFor all routines documented below,\nthe return value *ok* has prototype\n\n   ``bool`` *ok*\n\nIf it is ``true`` , the corresponding evaluation succeeded,\notherwise it failed.\n\nid\n**\nFor all routines documented below,\nthe argument *id* has prototype\n\n   ``size_t`` *id*\n\nIts value in all other calls is the same as in the corresponding\ncall to *afun* .\nIt can be used to store and retrieve extra information about\na specific call to *afun* .\n\nk\n*\nFor all routines documented below, the argument *k* has prototype\n\n   ``size_t`` *k*\n\nThe value *k* is the order of the Taylor coefficient that\nwe are evaluating (:ref:`atomic_one@forward` )\nor taking the derivative of (:ref:`atomic_one@reverse` ).\n\nn\n*\nFor all routines documented below,\nthe argument *n* has prototype\n\n   ``size_t`` *n*\n\nIt is the size of the vector *ax* in the corresponding call to\n*afun* ( *id* , *ax* , *ay* ) ; i.e.,\nthe dimension of the domain space for :math:`y = f(x)`.\n\nm\n*\nFor all routines documented below, the argument *m* has prototype\n\n   ``size_t`` *m*\n\nIt is the size of the vector *ay* in the corresponding call to\n*afun* ( *id* , *ax* , *ay* ) ; i.e.,\nthe dimension of the range space for :math:`y = f(x)`.\n\ntx\n**\nFor all routines documented below,\nthe argument *tx* has prototype\n\n   ``const CppAD::vector<`` *Base* >& *tx*\n\nand *tx* . ``size`` () >= ( *k* + 1) * *n* .\nFor :math:`j = 0 , \\ldots , n-1` and :math:`\\ell = 0 , \\ldots , k`,\nwe use the Taylor coefficient notation\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      x_j^\\ell & = & tx [ j * ( k + 1 ) + \\ell ]\n      \\\\\n      X_j (t) & = & x_j^0 + x_j^1 t^1 + \\cdots + x_j^k t^k\n   \\end{eqnarray}\n\nIf *tx* . ``size`` () > ( *k* + 1) * *n* ,\nthe other components of *tx* are not specified and should not be used.\nNote that superscripts represent an index for :math:`x_j^\\ell`\nand an exponent for :math:`t^\\ell`.\nAlso note that the Taylor coefficients for :math:`X(t)` correspond\nto the derivatives of :math:`X(t)` at :math:`t = 0` in the following way:\n\n.. math::\n\n   x_j^\\ell = \\frac{1}{ \\ell ! } X_j^{(\\ell)} (0)\n\nty\n**\nIn calls to :ref:`atomic_one@forward` ,\nthe argument *ty* has prototype\n\n   ``CppAD::vector<`` *Base* >& *ty*\n\nwhile in calls to :ref:`atomic_one@reverse` it has prototype\n\n   ``const CppAD::vector<`` *Base* >& *ty*\n\nFor all calls, *tx* . ``size`` () >= ( *k* + 1) * *m* .\nFor :math:`i = 0 , \\ldots , m-1` and :math:`\\ell = 0 , \\ldots , k`,\nwe use the Taylor coefficient notation\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      y_i^\\ell & = & ty [ i * ( k + 1 ) + \\ell ]\n      \\\\\n      Y_i (t)  & = & y_i^0 + y_i^1 t^1 + \\cdots + y_i^k t^k + o ( t^k )\n   \\end{eqnarray}\n\nwhere :math:`o( t^k ) / t^k \\rightarrow 0` as :math:`t \\rightarrow 0`.\nIf *ty* . ``size`` () > ( *k* + 1) * *m* ,\nthe other components of *ty* are not specified and should not be used.\nNote that superscripts represent an index for :math:`y_j^\\ell`\nand an exponent for :math:`t^\\ell`.\nAlso note that the Taylor coefficients for :math:`Y(t)` correspond\nto the derivatives of :math:`Y(t)` at :math:`t = 0` in the following way:\n\n.. math::\n\n   y_j^\\ell = \\frac{1}{ \\ell ! } Y_j^{(\\ell)} (0)\n\nforward\n=======\nIn the case of *forward* ,\nfor :math:`i = 0 , \\ldots , m-1`, :math:`ty[ i *( k  + 1) + k ]` is an output\nand all the other components of *ty* are inputs.\n\nreverse\n=======\nIn the case of *reverse* ,\nall the components of *ty* are inputs.\n\nafun\n****\nThe macro argument *afun* ,\nis the name of the AD function corresponding to this atomic\noperation (as it is used in the source code).\nCppAD uses the other functions,\nwhere the arguments are vectors with elements of type *Base* ,\nto implement the function\n\n   *afun* ( *id* , *ax* , *ay* )\n\nwhere the argument are vectors with elements of type ``AD`` < *Base* > .\n\nax\n==\nThe *afun* argument *ax* has prototype\n\n   ``const`` *Tvector* < ``AD`` < *Base* > >& *ax*\n\nIt is the argument vector :math:`x \\in \\B{R}^n`\nat which the ``AD`` < *Base* > version of\n:math:`y = f(x)` is to be evaluated.\nThe dimension of the domain space for :math:`y = f (x)`\nis specified by :ref:`atomic_one@n` = *ax* . ``size`` () ,\nwhich must be greater than zero.\n\nay\n==\nThe *afun* result *ay* has prototype\n\n   *Tvector* < ``AD`` < *Base* > >& *ay*\n\nThe input values of its elements\nare not specified (must not matter).\nUpon return, it is the ``AD`` < *Base* > version of the\nresult vector :math:`y = f(x)`.\nThe dimension of the range space for :math:`y = f (x)`\nis specified by :ref:`atomic_one@m` = *ay* . ``size`` () ,\nwhich must be greater than zero.\n\nParallel Mode\n=============\nThe first call to\n\n   *afun* ( *id* , *ax* , *ay* )\n\nmust not be in :ref:`parallel<ta_in_parallel-name>` mode.\nIn addition, the\n:ref:`atomic_one clear<atomic_one@clear>`\nroutine cannot be called while in parallel mode.\n\nforward\n*******\nThe macro argument *forward* is a\nuser defined function\n\n   *ok* = *forward* ( *id* , *k* , *n* , *m* , *vx* , *vy* , *tx* , *ty* )\n\nthat computes results during a :ref:`Forward-name` mode sweep.\nFor this call, we are given the Taylor coefficients in *tx*\nform order zero through *k* ,\nand the Taylor coefficients in  *ty* with order less than *k* .\nThe *forward* routine computes the\n*k* order Taylor coefficients for :math:`y` using the definition\n:math:`Y(t) = f[ X(t) ]`.\nFor example, for :math:`i = 0 , \\ldots , m-1`,\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   y_i^0 & = & Y(0)\n         = f_i ( x^0 )\n   \\\\\n   y_i^1 & = & Y^{(1)} ( 0 )\n         = f_i^{(1)} ( x^0 ) X^{(1)} ( 0 )\n         = f_i^{(1)} ( x^0 ) x^1\n   \\\\\n   y_i^2\n   & = & \\frac{1}{2 !} Y^{(2)} (0)\n   \\\\\n   & = & \\frac{1}{2} X^{(1)} (0)^\\R{T} f_i^{(2)} ( x^0 ) X^{(1)} ( 0 )\n     +   \\frac{1}{2} f_i^{(1)} ( x^0 ) X^{(2)} ( 0 )\n   \\\\\n   & = & \\frac{1}{2} (x^1)^\\R{T} f_i^{(2)} ( x^0 ) x^1\n     +    f_i^{(1)} ( x^0 ) x^2\n   \\end{eqnarray}\n\nThen, for :math:`i = 0 , \\ldots , m-1`, it sets\n\n.. math::\n\n   ty [ i * (k + 1) + k ] = y_i^k\n\nThe other components of *ty* must be left unchanged.\n\nUsage\n=====\nThis routine is used,\nwith *vx* . ``size`` () > 0 and *k*  == 0 ,\nby calls to *afun* .\nIt is used,\nwith *vx* . ``size`` () = 0 and\n*k* equal to the order of the derivative begin computed,\nby calls to :ref:`forward<forward_order-name>` .\n\nvx\n==\nThe *forward* argument *vx* has prototype\n\n   ``const CppAD::vector<bool>&`` *vx*\n\nThe case *vx* . ``size`` () > 0 occurs\nonce for each call to *afun* ,\nduring the call,\nand before any of the other callbacks corresponding to that call.\nHence such a call can be used to cache information attached to\nthe corresponding *id*\n(such as the elements of *vx* ).\nIf *vx* . ``size`` () > 0 then\n*k*  == 0 ,\n*vx* . ``size`` () >= *n* , and\nfor :math:`j = 0 , \\ldots , n-1`,\n*vx* [ *j* ] is true if and only if\n*ax* [ *j* ] is a :ref:`glossary@Variable` .\n\nIf *vx* . ``size`` () == 0 ,\nthen *vy* . ``size`` () == 0 and neither of these vectors\nshould be used.\n\nvy\n==\nThe *forward* argument *vy* has prototype\n\n   ``CppAD::vector<bool>&`` *vy*\n\nIf *vy* . ``size`` () == 0 , it should not be used.\nOtherwise,\n*k*  == 0 and *vy* . ``size`` () >= *m* .\nThe input values of the elements of *vy*\nare not specified (must not matter).\nUpon return, for :math:`j = 0 , \\ldots , m-1`,\n*vy* [ *i* ] is true if and only if\n*ay* [ *j* ] is a variable.\n(CppAD uses *vy* to reduce the necessary computations.)\n\nreverse\n*******\nThe macro argument *reverse*\nis a user defined function\n\n   *ok* = *reverse* ( *id* , *k* , *n* , *m* , *tx* , *ty* , *px* , *py* )\n\nthat computes results during a :ref:`Reverse-name` mode sweep.\nThe input value of the vectors *tx* and *ty*\ncontain Taylor coefficient, up to order *k* ,\nfor :math:`X(t)` and :math:`Y(t)` respectively.\nWe use the :math:`\\{ x_j^\\ell \\}` and :math:`\\{ y_i^\\ell \\}`\nto denote these Taylor coefficients where the implicit range indices are\n:math:`i = 0 , \\ldots , m-1`,\n:math:`j = 0 , \\ldots , n-1`,\n:math:`\\ell = 0 , \\ldots , k`.\nUsing the calculations done by :ref:`atomic_one@forward` ,\nthe Taylor coefficients :math:`\\{ y_i^\\ell \\}` are a function of the Taylor\ncoefficients for :math:`\\{ x_j^\\ell \\}`; i.e., given :math:`y = f(x)`\nwe define the function\n:math:`F : \\B{R}^{n \\times (k+1)} \\rightarrow \\B{R}^{m \\times (k+1)}` by\n\n.. math::\n\n   y_i^\\ell =  F_i^\\ell ( \\{ x_j^\\ell \\} )\n\nWe use :math:`G : \\B{R}^{m \\times (k+1)} \\rightarrow \\B{R}`\nto denote an arbitrary scalar valued function of the Taylor coefficients for\n:math:`Y(t)` and write  :math:`z = G( \\{ y_i^\\ell \\} )`.\nThe ``reverse`` routine\nis given the derivative of :math:`z` with respect to\n:math:`\\{ y_i^\\ell \\}` and computes its derivative with respect\nto :math:`\\{ x_j^\\ell \\}`.\n\nUsage\n=====\nThis routine is used,\nwith *k*  + 1 equal to the order of the derivative being calculated,\nby calls to :ref:`reverse<reverse_any-name>` .\n\npy\n==\nThe *reverse* argument *py* has prototype\n\n   ``const CppAD::vector<`` *Base* >& *py*\n\nand *py* . ``size`` () >= ( *k* + 1) * *m* .\nFor :math:`i = 0 , \\ldots , m-1` and :math:`\\ell = 0 , \\ldots , k`,\n\n.. math::\n\n   py[ i * (k + 1 ) + \\ell ] = \\partial G / \\partial y_i^\\ell\n\nIf *py* . ``size`` () > ( *k* + 1) * *m* ,\nthe other components of *py* are not specified and should not be used.\n\npx\n==\nWe define the function\n\n.. math::\n\n   H ( \\{ x_j^\\ell \\} ) = G[ F( \\{ x_j^\\ell \\} ) ]\n\nThe *reverse* argument *px* has prototype\n\n   ``CppAD::vector<`` *Base* >& *px*\n\nand *px* . ``size`` () >= ( *k* + 1) * *n* .\nThe input values of the elements of *px*\nare not specified (must not matter).\nUpon return,\nfor :math:`j = 0 , \\ldots , n-1` and :math:`p = 0 , \\ldots , k`,\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   px [ j * (k + 1) + p ] & = & \\partial H / \\partial x_j^p\n   \\\\\n   & = &\n   ( \\partial G / \\partial \\{ y_i^\\ell \\} )\n      ( \\partial \\{ y_i^\\ell \\} / \\partial x_j^p )\n   \\\\\n   & = &\n   \\sum_{i=0}^{m-1} \\sum_{\\ell=0}^k\n   ( \\partial G / \\partial y_i^\\ell ) ( \\partial y_i^\\ell / \\partial x_j^p )\n   \\\\\n   & = &\n   \\sum_{i=0}^{m-1} \\sum_{\\ell=p}^k\n   py[ i * (k + 1 ) + \\ell ] ( \\partial F_i^\\ell / \\partial x_j^p )\n   \\end{eqnarray}\n\nNote that we have used the fact that for :math:`\\ell < p`,\n:math:`\\partial F_i^\\ell / \\partial x_j^p = 0`.\nIf *px* . ``size`` () > ( *k* + 1) * *n* ,\nthe other components of *px* are not specified and should not be used.\n\nfor_jac_sparse\n**************\nThe macro argument *for_jac_sparse*\nis a user defined function\n\n   *ok* = *for_jac_sparse* ( *id* , *n* , *m* , *q* , *r* , *s* )\n\nthat is used to compute results during a forward Jacobian sparsity sweep.\nFor a fixed :math:`n \\times q` matrix :math:`R`,\nthe Jacobian of :math:`f( x + R * u)` with respect to :math:`u \\in \\B{R}^q` is\n\n.. math::\n\n   S(x) = f^{(1)} (x) * R\n\nGiven a :ref:`glossary@Sparsity Pattern` for :math:`R`,\n*for_jac_sparse* computes a sparsity pattern for :math:`S(x)`.\n\nUsage\n=====\nThis routine is used by calls to :ref:`ForSparseJac-name` .\n\nq\n=\nThe *for_jac_sparse* argument *q* has prototype\n\n   ``size_t`` *q*\n\nIt specifies the number of columns in\n:math:`R \\in \\B{R}^{n \\times q}` and the Jacobian\n:math:`S(x) \\in \\B{R}^{m \\times q}`.\n\nr\n=\nThe *for_jac_sparse* argument *r* has prototype\n\n   ``const CppAD::vector< std::set<size_t> >&`` *r*\n\nand *r* . ``size`` () >= *n* .\nFor :math:`j = 0 , \\ldots , n-1`,\nall the elements of *r* [ *j* ] are between\nzero and *q* ``-1`` inclusive.\nThis specifies a sparsity pattern for the matrix :math:`R`.\n\ns\n=\nThe *for_jac_sparse* return value *s* has prototype\n\n   ``CppAD::vector< std::set<size_t> >&`` *s*\n\nand *s* . ``size`` () >= *m* .\nThe input values of its sets\nare not specified (must not matter). Upon return\nfor :math:`i = 0 , \\ldots , m-1`,\nall the elements of *s* [ *i* ] are between\nzero and *q* ``-1`` inclusive.\nThis represents a sparsity pattern for the matrix :math:`S(x)`.\n\nrev_jac_sparse\n**************\nThe macro argument *rev_jac_sparse*\nis a user defined function\n\n   *ok* = *rev_jac_sparse* ( *id* , *n* , *m* , *q* , *r* , *s* )\n\nthat is used to compute results during a reverse Jacobian sparsity sweep.\nFor a fixed :math:`q \\times m` matrix :math:`S`,\nthe Jacobian of :math:`S * f( x )` with respect to :math:`x \\in \\B{R}^n` is\n\n.. math::\n\n   R(x) = S * f^{(1)} (x)\n\nGiven a :ref:`glossary@Sparsity Pattern` for :math:`S`,\n*rev_jac_sparse* computes a sparsity pattern for :math:`R(x)`.\n\nUsage\n=====\nThis routine is used by calls to :ref:`RevSparseJac-name`\nand to :ref:`optimize-name` .\n\nq\n=\nThe *rev_jac_sparse* argument *q* has prototype\n\n   ``size_t`` *q*\n\nIt specifies the number of rows in\n:math:`S \\in \\B{R}^{q \\times m}` and the Jacobian\n:math:`R(x) \\in \\B{R}^{q \\times n}`.\n\ns\n=\nThe *rev_jac_sparse* argument *s* has prototype\n\n   ``const CppAD::vector< std::set<size_t> >&`` *s*\n\nand *s* . ``size`` () >= *m* .\nFor :math:`i = 0 , \\ldots , m-1`,\nall the elements of *s* [ *i* ]\nare between zero and *q* ``-1`` inclusive.\nThis specifies a sparsity pattern for the matrix :math:`S^\\R{T}`.\n\nr\n=\nThe *rev_jac_sparse* return value *r* has prototype\n\n   ``CppAD::vector< std::set<size_t> >&`` *r*\n\nand *r* . ``size`` () >= *n* .\nThe input values of its sets\nare not specified (must not matter).\nUpon return for :math:`j = 0 , \\ldots , n-1`,\nall the elements of *r* [ *j* ]\nare between zero and *q* ``-1`` inclusive.\nThis represents a sparsity pattern for the matrix :math:`R(x)^\\R{T}`.\n\nrev_hes_sparse\n**************\nThe macro argument *rev_hes_sparse*\nis a user defined function\n\n   *ok* = *rev_hes_sparse* ( *id* , *n* , *m* , *q* , *r* , *s* , *t* , *u* , *v* )\n\nThere is an unspecified scalar valued function\n:math:`g : \\B{R}^m \\rightarrow \\B{R}`.\nGiven a sparsity pattern for :math:`R`\nand information about the function :math:`z = g(y)`,\nthis routine computes the sparsity pattern for\n\n.. math::\n\n   V(x) = (g \\circ f)^{(2)}( x ) R\n\nUsage\n=====\nThis routine is used by calls to :ref:`RevSparseHes-name` .\n\nq\n=\nThe *rev_hes_sparse* argument *q* has prototype\n\n   ``size_t`` *q*\n\nIt specifies the number of columns in the sparsity patterns.\n\nr\n=\nThe *rev_hes_sparse* argument *r* has prototype\n\n   ``const CppAD::vector< std::set<size_t> >&`` *r*\n\nand *r* . ``size`` () >= *n* .\nFor :math:`j = 0 , \\ldots , n-1`,\nall the elements of *r* [ *j* ] are between\nzero and *q* ``-1`` inclusive.\nThis specifies a sparsity pattern for the matrix :math:`R \\in \\B{R}^{n \\times q}`.\n\ns\n=\nThe *rev_hes_sparse* argument *s* has prototype\n\n   ``const CppAD::vector<bool>&`` *s*\n\nand *s* . ``size`` () >= *m* .\nThis specifies a sparsity pattern for the matrix\n:math:`S(x) = g^{(1)} (y) \\in \\B{R}^{1 \\times m}`.\n\nt\n=\nThe *rev_hes_sparse* argument *t* has prototype\n\n   ``CppAD::vector<bool>&`` *t*\n\nand *t* . ``size`` () >= *n* .\nThe input values of its elements\nare not specified (must not matter).\nUpon return it represents a sparsity pattern for the matrix\n:math:`T(x) \\in \\B{R}^{1 \\times n}` defined by\n\n.. math::\n\n   T(x)  =  (g \\circ f)^{(1)} (x) =  S(x) * f^{(1)} (x)\n\nu\n=\nThe *rev_hes_sparse* argument *u* has prototype\n\n   ``const CppAD::vector< std::set<size_t> >&`` *u*\n\nand *u* . ``size`` () >= *m* .\nFor :math:`i = 0 , \\ldots , m-1`,\nall the elements of *u* [ *i* ]\nare between zero and *q* ``-1`` inclusive.\nThis specifies a sparsity pattern\nfor the matrix :math:`U(x) \\in \\B{R}^{m \\times q}` defined by\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   U(x)\n   & = &\n   \\partial_u \\{ \\partial_y g[ y + f^{(1)} (x) R u ] \\}_{u=0}\n   \\\\\n   & = &\n   \\partial_u \\{ g^{(1)} [ y + f^{(1)} (x) R u ] \\}_{u=0}\n   \\\\\n   & = &\n   g^{(2)} (y) f^{(1)} (x) R\n   \\end{eqnarray}\n\nv\n=\nThe *rev_hes_sparse* argument *v* has prototype\n\n   ``CppAD::vector< std::set<size_t> >&`` *v*\n\nand *v* . ``size`` () >= *n* .\nThe input values of its elements\nare not specified (must not matter).\nUpon return, for :math:`j = 0, \\ldots , n-1`,\nall the elements of *v* [ *j* ]\nare between zero and *q* ``-1`` inclusive.\nThis represents a sparsity pattern for the matrix\n:math:`V(x) \\in \\B{R}^{n \\times q}` defined by\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   V(x)\n   & = &\n   \\partial_u [ \\partial_x (g \\circ f) ( x + R u )  ]_{u=0}\n   \\\\\n   & = &\n   \\partial_u [ (g \\circ f)^{(1)}( x + R u )  ]_{u=0}\n   \\\\\n   & = &\n   (g \\circ f)^{(2)}( x ) R\n   \\\\\n   & = &\n   f^{(1)} (x)^\\R{T} g^{(2)} ( y ) f^{(1)} (x)  R\n   +\n   \\sum_{i=1}^m [ g^{(1)} (y) ]_i \\; f_i^{(2)} (x) R\n   \\\\\n   & = &\n   f^{(1)} (x)^\\R{T} U(x)\n   +\n   \\sum_{i=1}^m S(x)_i \\; f_i^{(2)} (x) R\n   \\end{eqnarray}\n\nclear\n*****\nUser atomic functions hold onto static work space in order to\nincrease speed by avoiding system memory allocation calls.\nThe function call\n\n   ``user_atomic`` < *Base* >:: ``clear`` ()\n\nmakes to work space :ref:`available<ta_available-name>` to\nfor other uses by the same thread.\nThis should be called when you are done using the\natomic functions for a specific value of *Base* .\n\nRestriction\n===========\nThe atomic function ``clear`` routine cannot be called\nwhile in :ref:`parallel<ta_in_parallel-name>` execution mode.\n\n{xrst_end atomic_one}\n------------------------------------------------------------------------------\n*/\n# include <set>\n# include <cppad/core/cppad_assert.hpp>\n\n// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic_one.hpp\nuser defined atomic operations.\n*/\n\n/*!\n\\def CPPAD_USER_ATOMIC(afun, Tvector,\n   forward, reverse, for_jac_sparse, rev_jac_sparse, rev_hes_sparse\n)\nDefines the function <tt>afun(id, ax, ay)</tt>\nwhere id is ax and ay are vectors with <tt>AD<Base></tt> elements.\n\n\\par Tvector\nthe Simple Vector template class for this function.\n\n\\par Base\nthe base type for the atomic operation.\n\n\\par afun\nname of the CppAD defined function that corresponding to this operation.\nNote that afun, preceded` by a pound sign,\nis a version of afun with quotes around it.\n\n\\par forward\nname of the user defined function that computes corresponding\nresults during forward mode.\n\n\\par reverse\nname of the user defined function that computes corresponding\nresults during reverse mode.\n\n\\par for_jac_sparse\nname of the user defined routine that computes corresponding\nresults during forward mode jacobian sparsity sweeps.\n\n\\par rev_jac_sparse\nname of the user defined routine that computes corresponding\nresults during reverse mode jacobian sparsity sweeps.\n\n\\par rev_hes_sparse\nname of the user defined routine that computes corresponding\nresults during reverse mode Hessian sparsity sweeps.\n\n\\par memory allocation\nNote that atomic_one is used as a static object, so its objects\ndo note get deallocated until the program terminates.\n*/\n# define CPPAD_USER_ATOMIC(                                           \\\n     afun            ,                                                \\\n     Tvector         ,                                                \\\n     Base            ,                                                \\\n   forward         ,                                                \\\n     reverse         ,                                                \\\n     for_jac_sparse  ,                                                \\\n     rev_jac_sparse  ,                                                \\\n     rev_hes_sparse                                                   \\\n)                                                                     \\\ninline void afun (                                                    \\\n     size_t                               id ,                        \\\n     const Tvector< CppAD::AD<Base> >&    ax ,                        \\\n     Tvector< CppAD::AD<Base> >&          ay                          \\\n)                                                                     \\\n{  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;                            \\\n   static CppAD::atomic_one<Base> fun(                              \\\n          #afun          ,                                            \\\n          forward        ,                                            \\\n          reverse        ,                                            \\\n          for_jac_sparse ,                                            \\\n          rev_jac_sparse ,                                            \\\n          rev_hes_sparse                                              \\\n     );                                                               \\\n     fun(id, ax, ay);                                                 \\\n}\n\n/// link so that user_atomic<Base>::clear() still works\ntemplate <class Base> class user_atomic : public atomic_base<Base> {\n};\n\n/*!\nClass that actually implements the <tt>afun(id, ax, ay)</tt> calls.\n\nA new atomic_one object is generated each time the user invokes\nthe CPPAD_USER_ATOMIC macro; see static object in that macro.\n*/\ntemplate <class Base>\nclass atomic_one : public atomic_base<Base> {\npublic:\n   /// disable atomic_one<Base>::clear(void)\n   static void clear(void)\n   {  CPPAD_ASSERT_KNOWN(\n         false,\n         \"Deprecated API uses user_atomic<Base>::clear()\"\n      );\n   }\n   /// type for user routine that computes forward mode results\n   typedef bool (*F) (\n      size_t                  id ,\n      size_t                   k ,\n      size_t                   n ,\n      size_t                   m ,\n      const vector<bool>&     vx ,\n      vector<bool>&           vy ,\n      const vector<Base>&     tx ,\n      vector<Base>&           ty\n   );\n   /// type for user routine that computes reverse mode results\n   typedef bool (*R) (\n      size_t                  id ,\n      size_t                   k ,\n      size_t                   n ,\n      size_t                   m ,\n      const vector<Base>&     tx ,\n      const vector<Base>&     ty ,\n      vector<Base>&           px ,\n      const vector<Base>&     py\n   );\n   /// type for user routine that computes forward mode Jacobian sparsity\n   typedef bool (*FJS) (\n      size_t                           id ,\n      size_t                            n ,\n      size_t                            m ,\n      size_t                            q ,\n      const vector< std::set<size_t> >& r ,\n      vector< std::set<size_t>  >&      s\n   );\n   /// type for user routine that computes reverse mode Jacobian sparsity\n   typedef bool (*RJS) (\n      size_t                           id ,\n      size_t                            n ,\n      size_t                            m ,\n      size_t                            q ,\n      vector< std::set<size_t> >&       r ,\n      const vector< std::set<size_t> >& s\n   );\n   /// type for user routine that computes reverse mode Hessian sparsity\n   typedef bool (*RHS) (\n      size_t                           id ,\n      size_t                            n ,\n      size_t                            m ,\n      size_t                            q ,\n      const vector< std::set<size_t> >& r ,\n      const vector<bool>&               s ,\n      vector<bool>&                     t ,\n      const vector< std::set<size_t> >& u ,\n      vector< std::set<size_t> >&       v\n   );\nprivate:\n   /// id value corresponding to next virtual callback\n   size_t                  id_;\n   /// user's implementation of forward mode\n   const F                  f_;\n   /// user's implementation of reverse mode\n   const R                  r_;\n   /// user's implementation of forward jacobian sparsity calculations\n   const FJS              fjs_;\n   /// user's implementation of reverse jacobian sparsity calculations\n   const RJS              rjs_;\n   /// user's implementation of reverse Hessian sparsity calculations\n   const RHS              rhs_;\n\npublic:\n   /*!\n   Constructor called for each invocation of CPPAD_USER_ATOMIC.\n\n   Put this object in the list of all objects for this class and set\n   the constant private data f_, r_, fjs_, rjs_, rhs_.\n\n   \\param afun\n   is the user's name for the AD version of this atomic operation.\n\n   \\param f\n   user routine that does forward mode calculations for this operation.\n\n   \\param r\n   user routine that does reverse mode calculations for this operation.\n\n   \\param fjs\n   user routine that does forward Jacobian sparsity calculations.\n\n   \\param rjs\n   user routine that does reverse Jacobian sparsity calculations.\n\n   \\param rhs\n   user routine that does reverse Hessian sparsity calculations.\n\n   \\par\n   This constructor can not be used in parallel mode because\n   atomic_base has this restriction.\n   */\n   atomic_one(const char* afun, F f, R r, FJS fjs, RJS rjs, RHS rhs) :\n   atomic_base<Base>(afun) // name = afun\n   , f_(f)\n   , r_(r)\n   , fjs_(fjs)\n   , rjs_(rjs)\n   , rhs_(rhs)\n   {  this->option( atomic_base<Base>::set_sparsity_enum );\n   }\n   /*!\n   Implement the user call to <tt>afun(id, ax, ay)</tt>.\n\n   \\tparam ADVector\n   A simple vector class with elements of type <code>AD<Base></code>.\n\n   \\param id\n   extra information vector that is just passed through by CppAD,\n   and possibly used by user's routines.\n\n   \\param ax\n   is the argument vector for this call,\n   <tt>ax.size()</tt> determines the number of arguments.\n\n   \\param ay\n   is the result vector for this call,\n   <tt>ay.size()</tt> determines the number of results.\n   */\n   template <class ADVector>\n   void operator()(size_t id, const ADVector& ax, ADVector& ay)\n   {  // call atomic_base function object\n      this->atomic_base<Base>::operator()(ax, ay, id);\n      return;\n   }\n   /*!\n   Store id for next virtual function callback\n\n   \\param id\n   id value corresponding to next virtual callback\n   */\n   virtual void set_old(size_t id)\n   {  id_ = id; }\n   /*!\n   Link from atomic_one to forward mode\n\n   \\copydetails atomic_base::forward\n   */\n   virtual bool forward(\n      size_t                    p ,\n      size_t                    q ,\n      const vector<bool>&      vx ,\n              vector<bool>&      vy ,\n      const vector<Base>&      tx ,\n              vector<Base>&      ty )\n   {  CPPAD_ASSERT_UNKNOWN( tx.size() % (q+1) == 0 );\n      CPPAD_ASSERT_UNKNOWN( ty.size() % (q+1) == 0 );\n      size_t n = tx.size() / (q+1);\n      size_t m = ty.size() / (q+1);\n      size_t i, j, k, ell;\n\n      vector<Base> x(n * (q+1));\n      vector<Base> y(m * (q+1));\n      vector<bool> empty;\n\n      // atomic_one interface can only handle one order at a time\n      // so must just through hoops to get multiple orders at one time.\n      bool ok = true;\n      for(k = p; k <= q; k++)\n      {  for(j = 0; j < n; j++)\n            for(ell = 0; ell <= k; ell++)\n               x[ j * (k+1) + ell ] = tx[ j * (q+1) + ell ];\n         for(i = 0; i < m; i++)\n            for(ell = 0; ell < k; ell++)\n               y[ i * (k+1) + ell ] = ty[ i * (q+1) + ell ];\n         if( k == 0 )\n            ok &= f_(id_, k, n, m, vx, vy, x, y);\n         else\n            ok &= f_(id_, k, n, m, empty, empty, x, y);\n         for(i = 0; i < m; i++)\n            ty[ i * (q+1) + k ] = y[ i * (k+1) + k];\n      }\n      return ok;\n   }\n   /*!\n   Link from atomic_one to reverse mode\n\n   \\copydetails atomic_base::reverse\n   */\n   virtual bool reverse(\n      size_t                   q ,\n      const vector<Base>&     tx ,\n      const vector<Base>&     ty ,\n              vector<Base>&     px ,\n      const vector<Base>&     py )\n   {  CPPAD_ASSERT_UNKNOWN( tx.size() % (q+1) == 0 );\n      CPPAD_ASSERT_UNKNOWN( ty.size() % (q+1) == 0 );\n      size_t n = tx.size() / (q+1);\n      size_t m = ty.size() / (q+1);\n      bool   ok = r_(id_, q, n, m, tx, ty, px, py);\n      return ok;\n   }\n   /*!\n   Link from forward Jacobian sparsity sweep to atomic_one\n\n   \\copydetails atomic_base::for_sparse_jac\n   */\n   virtual bool for_sparse_jac(\n      size_t                                q ,\n      const vector< std::set<size_t> >&     r ,\n              vector< std::set<size_t> >&     s ,\n      const vector<Base>&                   x )\n   {  size_t n = r.size();\n      size_t m = s.size();\n      bool ok  = fjs_(id_, n, m, q, r, s);\n      return ok;\n   }\n\n   /*!\n   Link from reverse Jacobian sparsity sweep to atomic_one.\n\n   \\copydetails atomic_base::rev_sparse_jac\n   */\n   virtual bool rev_sparse_jac(\n      size_t                               q  ,\n      const vector< std::set<size_t> >&    rt ,\n              vector< std::set<size_t> >&    st ,\n      const vector<Base>&                   x )\n   {  size_t n = st.size();\n      size_t m = rt.size();\n      bool ok  = rjs_(id_, n, m, q, st, rt);\n      return ok;\n   }\n   /*!\n   Link from reverse Hessian sparsity sweep to atomic_one\n\n   \\copydetails atomic_base::rev_sparse_hes\n   */\n   virtual bool rev_sparse_hes(\n      const vector<bool>&                   vx,\n      const vector<bool>&                   s ,\n              vector<bool>&                   t ,\n      size_t                                q ,\n      const vector< std::set<size_t> >&     r ,\n      const vector< std::set<size_t> >&     u ,\n              vector< std::set<size_t> >&     v ,\n      const vector<Base>&                   x )\n   {  size_t m = u.size();\n      size_t n = v.size();\n      CPPAD_ASSERT_UNKNOWN( r.size() == n );\n      CPPAD_ASSERT_UNKNOWN( s.size() == m );\n      CPPAD_ASSERT_UNKNOWN( t.size() == n );\n      //\n      // old interface used id instead of vx\n      bool ok = rhs_(id_, n, m, q, r, s, t, u, v);\n      return ok;\n   }\n};\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/three/afun.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_THREE_AFUN_HPP\n# define CPPAD_CORE_ATOMIC_THREE_AFUN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_three_afun}\n\nUsing AD Version of an Atomic Function\n######################################\n\nSyntax\n******\n| *afun* ( *ax* , *ay* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nPurpose\n*******\nGiven *ax* , this call computes the corresponding value of *ay* .\nIf ``AD`` < *Base* > operations are being recorded,\nit enters the computation as an atomic operation in the recording;\nsee :ref:`Independent@Start Recording` .\n\nBase\n****\nThis is the *Base* type of the elements of *ax* and *ay*\nin the call to the *afun* atomic operation.\nTo be specific, the elements of *ax* and *ay* have type\n``AD`` < ``Base`` > .\n\nADVector\n********\nThe type *ADVector* must be a\n:ref:`simple vector class<SimpleVector-name>` with elements of type\n``AD`` < *Base* > .\n\nafun\n****\nis a :ref:`atomic_three_ctor@atomic_user` object\nand this *afun* function call is implemented by the\n:ref:`atomic_three_ctor@atomic_three` class.\n\nax\n**\nThis argument has prototype\n\n   ``const`` *ADVector* & *ax*\n\nand size must be equal to *n* .\nIt specifies vector :math:`x \\in \\B{R}^n`\nat which an ``AD`` < *Base* > version of\n:math:`y = g(x)` is to be evaluated; see\n:ref:`atomic_three_ctor@atomic_three@Base` .\n\nay\n**\nThis argument has prototype\n\n   *ADVector* & *ay*\n\nand size must be equal to *m* .\nThe input values of its elements\nare not specified (must not matter).\nUpon return, it is an ``AD`` < *Base* > version of\n:math:`y = g(x)`.\n\n{xrst_end atomic_three_afun}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/three_afun.hpp\nImplement user call to an atomic_three function.\n*/\n\n/*!\nImplement the user call to afun(ax, ay)\n\n\\tparam ADVector\nA simple vector class with elements of type AD<Base>.\n\n\\param ax\nis the argument vector for this call,\nax.size() determines the number of arguments.\n\n\\param ay\nis the result vector for this call,\nay.size() determines the number of results.\n*/\n// BEGIN_PROTOTYPE\ntemplate <class Base>\ntemplate <class ADVector>\nvoid atomic_three<Base>::operator()(\n   const ADVector&  ax     ,\n   ADVector&        ay     )\n// END_PROTOTYPE\n{\n\n   size_t n = ax.size();\n   size_t m = ay.size();\n# ifndef NDEBUG\n   bool ok = true;\n   std::string msg = \"atomic_three: \" + atomic_name() + \".eval: \";\n   if( (n == 0) || (m == 0) )\n   {  msg += \"ax.size() or ay.size() is zero\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# endif\n   size_t thread = thread_alloc::thread_num();\n   allocate_work(thread);\n   vector<Base>& taylor_x        = work_[thread]->taylor_x;\n   vector<Base>& taylor_y        = work_[thread]->taylor_y;\n   vector<ad_type_enum>& type_x  = work_[thread]->type_x;\n   vector<ad_type_enum>& type_y  = work_[thread]->type_y;\n   //\n   type_x.resize(n);\n   taylor_x.resize(n);\n   //\n   type_y.resize(m);\n   taylor_y.resize(m);\n   //\n   // Determine tape corresponding to variables in ax\n   tape_id_t            tape_id  = 0;\n   local::ADTape<Base>* tape     = nullptr;\n   for(size_t j = 0; j < n; j++)\n   {  taylor_x[j]  = ax[j].value_;\n      if( Constant( ax[j] ) )\n         type_x[j] = constant_enum;\n      else\n      {  type_x[j] = ax[j].ad_type_;\n         if( tape_id == 0 )\n         {  tape    = ax[j].tape_this();\n            tape_id = ax[j].tape_id_;\n            CPPAD_ASSERT_UNKNOWN( tape != nullptr );\n         }\n# ifndef NDEBUG\n         if( Dynamic( ax[j] ) )\n         {    CPPAD_ASSERT_UNKNOWN( type_x[j] == dynamic_enum );\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( Variable( ax[j] ) );\n            CPPAD_ASSERT_UNKNOWN( type_x[j] == variable_enum );\n         }\n         if( tape_id != ax[j].tape_id_ )\n         {  msg += atomic_name() +\n            \": ax contains non-constant values from different threads.\";\n            CPPAD_ASSERT_KNOWN(false, msg.c_str());\n         }\n# endif\n      }\n   }\n   // Use zero order forward mode to compute all the components of y\n   size_t need_y    = size_t(variable_enum) + 1;\n   size_t order_low = 0;\n   size_t order_up  = 0;\n   CPPAD_ASSERT_UNKNOWN( need_y > size_t(variable_enum) );\n# ifdef NDEBUG\n   forward(taylor_x, type_x, need_y, order_low, order_up, taylor_x, taylor_y);\n   for(size_t j = 0; j < n; ++j)\n      if( type_x[j] == variable_enum )\n         taylor_x[j] = CppAD::numeric_limits<Base>::quiet_NaN();\n   for_type(taylor_x, type_x, type_y);\n# else\n   ok &= forward(\n      taylor_x, type_x, need_y, order_low, order_up, taylor_x, taylor_y\n   );\n   for(size_t j = 0; j < n; ++j)\n      if( type_x[j] == variable_enum )\n         taylor_x[j] = CppAD::numeric_limits<Base>::quiet_NaN();\n   ok &= for_type(taylor_x, type_x, type_y);\n   if( ! ok )\n   {  msg += atomic_name() + \": ok is false for \"\n         \"type or zero order forward mode calculation.\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str());\n   }\n# endif\n   bool record_dynamic = false;\n   bool record_variable = false;\n   //\n   // set ay to be vector of constant parameters with correct value\n   for(size_t i = 0; i < m; i++)\n   {  // pass back values\n      ay[i].value_ = taylor_y[i];\n\n      // initialize entire vector as constants\n      ay[i].tape_id_ = 0;\n      ay[i].taddr_   = 0;\n\n      // we need to record this operation if\n      // any of the elements of ay are dynamics or variables,\n      record_dynamic  |= type_y[i] == dynamic_enum;\n      record_variable |= type_y[i] == variable_enum;\n   }\n# ifndef NDEBUG\n   if( (record_dynamic || record_variable) && tape == nullptr )\n   {  msg +=\n      \"all elements of x are constants but y contains a non-constant\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# endif\n   if( record_dynamic)\n   {  size_t call_id = 0;\n      tape->Rec_.put_dyn_atomic(\n         tape_id, index_, call_id, type_x, type_y, ax, ay\n      );\n   }\n   // case where result contains a variable\n   if( record_variable )\n   {  size_t call_id = 0; // atomic_three does not user call_id\n      tape->Rec_.put_var_atomic(\n         tape_id, index_, call_id, type_x, type_y, ax, ay);\n   }\n# ifndef NDEBUG\n   for(size_t i = 0; i < m; ++i) switch( type_y[i] )\n   {  //\n      case constant_enum:\n      CPPAD_ASSERT_UNKNOWN( Constant( ay[i] ) );\n      break;\n      //\n      case dynamic_enum:\n      CPPAD_ASSERT_UNKNOWN( Dynamic( ay[i] ) );\n      break;\n      //\n      case variable_enum:\n      CPPAD_ASSERT_UNKNOWN( Variable( ay[i] ) );\n      break;\n      //\n      default:\n      CPPAD_ASSERT_KNOWN( false,\n         \"atomic_three: for_type: type_y[i]: is not a valid type\"\n      );\n      break;\n   }\n# endif\n   return;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/three/atomic.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_THREE_ATOMIC_HPP\n# define CPPAD_CORE_ATOMIC_THREE_ATOMIC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_three_define}\n{xrst_spell\n   ctor\n}\n\nDefining Atomic Functions: Third Generation\n###########################################\n\nSyntax\n******\n\nDefine Class\n============\n\n| ``class`` *atomic_user* : ``public CppAD::atomic_three<`` *Base* > {\n| |tab| ...\n| };\n\nConstruct Atomic Function\n=========================\n*atomic_user* *afun* ( *ctor_arg_list* )\n\nUse Atomic Function\n===================\n*afun* ( *ax* , *ay* )\n\nClass Member Callbacks\n======================\n\n| *ok* = *afun* . ``for_type`` (\n| |tab| *parameter_x* , *type_x* , *type_y*\n| )\n| *ok* = *afun* . ``forward`` (\n| |tab| *parameter_x* , *type_x* ,\n| |tab| *need_y* , *order_low* , *order_up* , *taylor_x* , *taylor_y*\n| )\n| *ok* = *afun* . ``reverse`` (\n| |tab| *parameter_x* , *type_x* ,\n| |tab| *order_up* , *taylor_x* , *taylor_y* , *partial_x* , *partial_y*\n| )\n| *ok* = *afun* . ``jac_sparsity`` (\n| |tab| *parameter_x* , *type_x* , *dependency* , *select_x* *select_y* , *pattern_out*\n| )\n| *ok* = *afun* . ``hes_sparsity`` (\n| |tab| *parameter_x* , *type_x* , *select_x* *select_y* , *pattern_out*\n| )\n| *ok* = *afun* . ``rev_depend`` (\n| |tab| *parameter_x* , *type_x* , *depend_x* , *depend_y*\n| )\n\nSee Also\n********\n:ref:`chkpoint_two-name` , :ref:`atomic_two-name`\n\nPurpose\n*******\n\nSpeed\n=====\nIn some cases, it is possible to compute derivatives of a function\n\n.. math::\n\n   y = g(x) \\; {\\rm where} \\; g : \\B{R}^n \\rightarrow \\B{R}^m\n\nmore efficiently than by coding it using ``AD`` < *Base* >\n:ref:`glossary@Operation@Atomic` operations\nand letting CppAD do the rest.\nThe class ``atomic_three`` < ``Base`` > is used to\ncreate a new atomic operation corresponding to a function :math:`g(x)`\nwhere the user specifies how to compute the derivatives\nand sparsity patterns for :math:`g(x)`.\n\nReduce Memory\n=============\nIf the function :math:`g(x)` is used many times during the recording\nof an :ref:`ADFun-name` object,\nusing an atomic version of :math:`g(x)` removes the need for repeated\ncopies of the corresponding ``AD`` < *Base* > operations and variables\nin the recording.\n\nad_type\n*******\nThe type ``CppAD::ad_type_enum``\nis used to specify if an AD object is a\n:ref:`constant parameter<glossary@Parameter@Constant>`\n:ref:`dynamic parameter<glossary@Parameter@Dynamic>`\nor :ref:`glossary@Variable` .\nIt has the following possible values:\n\n.. csv-table::\n   :widths: auto\n\n   *ad_type_enum*,Meaning\n   ``constant_enum``,constant parameter\n   ``dynamic_enum``,dynamic parameter\n   ``variable_enum``,variable\n\nIn addition,\n``constant_enum < dynamic_enum < variable_enum`` .\n\nVirtual Functions\n*****************\nThe\n:ref:`callback functions<atomic_three_define@Syntax@Class Member Callbacks>`\nare implemented by defining the virtual functions in the\n*atomic_user* class.\nThese functions compute derivatives,\nsparsity patterns, and dependency relations.\nEach virtual function has a default implementation\nthat returns *ok* == ``false`` .\nThe :ref:`for_type<atomic_three_for_type-name>`\nand :ref:`forward<atomic_three_forward-name>` function\n(for the case *order_up*  == 0 ) must be implemented.\nOtherwise, only those functions and orders\nrequired by the your calculations need to be implemented.\nFor example,\n*forward* for the case *order_up*  == 2 can just return\n*ok* == ``false`` unless you require\nforward mode calculation of second derivatives.\n\nBase\n****\nThis is the base type of the elements of\n:ref:`atomic_three_afun@ax` and :ref:`atomic_three_afun@ay`\nin the corresponding *afun* ( *ax* , *ay* ) call; i.e.,\nthe elements of *ax* and *ay* have type\n``AD`` < *Base* > .\n\nparameter_x\n***********\nAll the virtual functions include this argument which has prototype\n\n   ``const CppAD::vector<`` *Base* > *parameter_x*\n\nIts size is equal to *n* = *ax* . ``size`` ()\nin corresponding *afun* ( *ax* , *ay* ) call.\n\nConstant\n========\nFor *j* =0,..., *n* ``-1`` ,\nif *ax* [ *j* ] is a :ref:`con_dyn_var@Constant` parameter,\n\n   *parameter_x* [ *j* ] == *ax* [ *j* ]\n\nDynamic\n=======\nIf *ax* [ *j* ] is a :ref:`con_dyn_var@Dynamic` parameter,\n*parameter_x* [ *j* ] value of *ax* [ *j* ] corresponding to the\nprevious call to :ref:`new_dynamic-name` for the corresponding function object.\n\nVariable\n========\nIf *ax* [ *j* ] is a variable,\nthe value of *parameter_x* [ *j* ] is not specified.\nSee the\n:ref:`atomic_three_mat_mul.hpp<atomic_three_mat_mul.hpp@Purpose@parameter_x>`\nfor an example using *parameter_x* .\n\ntype_x\n******\nAll the virtual functions include this argument.\nIts size is equal to *n* = *ax* . ``size`` ()\nin corresponding *afun* ( *ax* , *ay* ) call.\nFor *j* =0,..., *n* ``-1`` ,\nif *ax* [ *j* ] is a constant parameter,\n\n   *type_x* [ *j* ] == ``CppAD::constant_enum``\n\nif *ax* [ *j* ] is a dynamic parameter,\n\n   *type_x* [ *j* ] == ``CppAD::dynamic_enum``\n\nif *ax* [ *j* ] is a variable,\n\n   *type_x* [ *j* ] == ``CppAD::variable_enum``\n\nSee the\n:ref:`atomic_three_mat_mul.hpp<atomic_three_mat_mul.hpp@Purpose@type_x>`\nfor an example using *type_x* .\n\nContents\n********\n{xrst_toc_table\n   include/cppad/core/atomic/three/ctor.hpp\n   include/cppad/core/atomic/three/afun.hpp\n   include/cppad/core/atomic/three/for_type.hpp\n   include/cppad/core/atomic/three/forward.hpp\n   include/cppad/core/atomic/three/reverse.hpp\n   include/cppad/core/atomic/three/jac_sparsity.hpp\n   include/cppad/core/atomic/three/hes_sparsity.hpp\n   include/cppad/core/atomic/three/rev_depend.hpp\n}\n\n{xrst_end atomic_three_define}\n-------------------------------------------------------------------------------\n*/\n\n# include <set>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/local/atomic_index.hpp>\n\n// needed before one can use in_parallel\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic_three.hpp\nBase class for atomic function operations.\n*/\n\ntemplate <class Base>\nclass atomic_three {\n// ===================================================================\nprivate:\n   // ------------------------------------------------------\n   // constants\n   //\n   /// index of this object in local::atomic_index\n   /// (set by constructor and not changed; i.e., effectively const)\n   size_t index_;\n   //\n   // -----------------------------------------------------\n   //\n   /// temporary work space used by member functions, declared here to avoid\n   // memory allocation/deallocation for each usage\n   struct work_struct {\n      vector<ad_type_enum>        type_x;\n      vector<ad_type_enum>        type_y;\n      //\n      vector<Base>                taylor_x;\n      vector<Base>                taylor_y;\n      //\n      vector< AD<Base> >          ataylor_x;\n      vector< AD<Base> >          ataylor_y;\n      //\n      sparse_rc< vector<size_t> > pattern;\n   };\n   // Use pointers, to avoid false sharing between threads.\n   // Not using: vector<work_struct*> work_;\n   // so that deprecated atomic examples do not result in a memory leak.\n   work_struct* work_[CPPAD_MAX_NUM_THREADS];\n   // -----------------------------------------------------\npublic:\n   //\n   // atomic_index\n   size_t atomic_index(void) const\n   { return index_; }\n   // =====================================================================\n   // In User API\n   // =====================================================================\n   //\n   // ---------------------------------------------------------------------\n   // ctor: doxygen in atomic/three_ctor.hpp\n   atomic_three(void);\n   atomic_three(const std::string& name);\n\n   // ------------------------------------------------------------------------\n   // operator(): see doxygen in atomic_three/afun.hpp\n   template <class ADVector>\n   void operator()(\n      const ADVector&  ax     ,\n              ADVector&  ay\n   );\n   // ------------------------------------------------------------------------\n   // type: doxygen in atomic/three_for_type.hpp\n   virtual bool for_type(\n      const vector<Base>&          parameter_x ,\n      const vector<ad_type_enum>&  type_x      ,\n      vector<ad_type_enum>&        type_y\n   );\n   // ------------------------------------------------------------------------\n   // type: doxygen in atomic/three_rev_depend.hpp\n   virtual bool rev_depend(\n      const vector<Base>&          parameter_x ,\n      const vector<ad_type_enum>&  type_x      ,\n      vector<bool>&                depend_x    ,\n      const vector<bool>&          depend_y\n   );\n   // ------------------------------------------------------------------------\n   // forward: see docygen in atomic/three_forward.hpp\n   virtual bool forward(\n      const vector<Base>&          parameter_x ,\n      const vector<ad_type_enum>&  type_x      ,\n      size_t                       need_y      ,\n      size_t                       order_low   ,\n      size_t                       order_up    ,\n      const vector<Base>&          taylor_x    ,\n      vector<Base>&                taylor_y\n   );\n   virtual bool forward(\n      const vector< AD<Base> >&    aparameter_x ,\n      const vector<ad_type_enum>&  type_x       ,\n      size_t                       need_y       ,\n      size_t                       order_low    ,\n      size_t                       order_up     ,\n      const vector< AD<Base> >&    ataylor_x    ,\n      vector< AD<Base> >&          ataylor_y\n   );\n   // ------------------------------------------------------------------------\n   // reverse: see docygen in atomic/three_reverse.hpp\n   virtual bool reverse(\n      const vector<Base>&          parameter_x ,\n      const vector<ad_type_enum>&  type_x      ,\n      size_t                       order_up    ,\n      const vector<Base>&          taylor_x    ,\n      const vector<Base>&          taylor_y    ,\n      vector<Base>&                partial_x   ,\n      const vector<Base>&          partial_y\n   );\n   virtual bool reverse(\n      const vector< AD<Base> >&    aparameter_x ,\n      const vector<ad_type_enum>&  type_x       ,\n      size_t                       order_up    ,\n      const vector< AD<Base> >&    ataylor_x   ,\n      const vector< AD<Base> >&    ataylor_y   ,\n      vector< AD<Base> >&          apartial_x  ,\n      const vector< AD<Base> >&    apartial_y\n   );\n   // ------------------------------------------------------------\n   // jac_sparsity: see doxygen in atomic/three_jac_sparsity.hpp\n   virtual bool jac_sparsity(\n      const vector<Base>&          parameter_x ,\n      const vector<ad_type_enum>&  type_x      ,\n      bool                         dependency  ,\n      const vector<bool>&          select_x    ,\n      const vector<bool>&          select_y    ,\n      sparse_rc< vector<size_t> >& pattern_out\n   );\n   template <class InternalSparsity>\n   bool for_jac_sparsity(\n      bool                             dependency   ,\n      const vector<Base>&              parameter_x  ,\n      const vector<ad_type_enum>&      type_x       ,\n      const vector<size_t>&            x_index      ,\n      const vector<size_t>&            y_index      ,\n      InternalSparsity&                var_sparsity\n   );\n   template <class InternalSparsity>\n   bool rev_jac_sparsity(\n      bool                             dependency   ,\n      const vector<Base>&              parameter_x  ,\n      const vector<ad_type_enum>&      type_x       ,\n      const vector<size_t>&            x_index      ,\n      const vector<size_t>&            y_index      ,\n      InternalSparsity&                var_sparsity\n   );\n   // ------------------------------------------------------------\n   // hes_sparsity: see doxygen in atomic/three_jac_sparsity.hpp\n   virtual bool hes_sparsity(\n      const vector<Base>&                     parameter_x  ,\n      const vector<ad_type_enum>&             type_x       ,\n      const vector<bool>&                     select_x     ,\n      const vector<bool>&                     select_y     ,\n      sparse_rc< vector<size_t> >&            pattern_out\n   );\n   template <class InternalSparsity>\n   bool for_hes_sparsity(\n      const vector<Base>&              parameter_x      ,\n      const vector<ad_type_enum>&      type_x           ,\n      const vector<size_t>&            x_index          ,\n      const vector<size_t>&            y_index          ,\n      size_t                           np1              ,\n      size_t                           numvar           ,\n      const InternalSparsity&          rev_jac_sparsity ,\n      InternalSparsity&                for_sparsity\n   );\n   template <class InternalSparsity>\n   bool rev_hes_sparsity(\n      const vector<Base>&              parameter_x      ,\n      const vector<ad_type_enum>&      type_x           ,\n      const vector<size_t>&            x_index          ,\n      const vector<size_t>&            y_index          ,\n      const InternalSparsity&          for_jac_pattern  ,\n      bool*                            rev_jac_flag     ,\n      InternalSparsity&                hes_sparsity\n   );\n\n   // =====================================================================\n   // Not in User API\n   // =====================================================================\n\n   /// Name corresponding to a atomic_three object\n   const std::string atomic_name(void) const\n   {  bool        set_null = false;\n      size_t      type  = 0;          // set to avoid warning\n      std::string name;\n      void*       v_ptr = nullptr; // set to avoid warning\n      local::atomic_index<Base>(set_null, index_, type, &name, v_ptr);\n      CPPAD_ASSERT_UNKNOWN( type == 3 );\n      return name;\n   }\n   /// destructor informs CppAD that this atomic function with this index\n   /// has dropped out of scope by setting its pointer to null\n   virtual ~atomic_three(void)\n   {  // change object pointer to null, but leave name for error reporting\n      bool         set_null = true;\n      size_t       type  = 0;          // set to avoid warning\n      std::string* name  = nullptr;\n      void*        v_ptr = nullptr; // set to avoid warning\n      local::atomic_index<Base>(set_null, index_, type, name, v_ptr);\n      CPPAD_ASSERT_UNKNOWN( type == 3 );\n      //\n      // free temporary work memory\n      for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++)\n         free_work(thread);\n   }\n   /// allocates work_ for a specified thread\n   void allocate_work(size_t thread)\n   {  if( work_[thread] == nullptr )\n      {  // allocate the raw memory\n         size_t min_bytes = sizeof(work_struct);\n         size_t num_bytes;\n         void*  v_ptr     = thread_alloc::get_memory(min_bytes, num_bytes);\n         // save in work_\n         work_[thread]    = reinterpret_cast<work_struct*>( v_ptr );\n         // call constructor\n         new( work_[thread] ) work_struct;\n      }\n      return;\n   }\n   /// frees work_ for a specified thread\n   void free_work(size_t thread)\n   {  if( work_[thread] != nullptr )\n      {  // call destructor\n         work_[thread]->~work_struct();\n         // return memory to available pool for this thread\n         thread_alloc::return_memory(\n            reinterpret_cast<void*>(work_[thread])\n         );\n         // mark this thread as not allocated\n         work_[thread] = nullptr;\n      }\n      return;\n   }\n   /// atomic_three function object corresponding to a certain index\n   static atomic_three* class_object(size_t index)\n   {  bool         set_null = false;\n      size_t       type  = 0;          // set to avoid warning\n      std::string* name  = nullptr;\n      void*        v_ptr = nullptr; // set to avoid warning\n      local::atomic_index<Base>(set_null, index, type, name, v_ptr);\n      CPPAD_ASSERT_UNKNOWN( type == 3 );\n      return reinterpret_cast<atomic_three*>( v_ptr );\n   }\n   /// atomic_three function name corresponding to a certain index\n   static const std::string class_name(size_t index)\n   {  bool        set_null = false;\n      size_t      type  = 0;          // set to avoid warning\n      std::string name;\n      void*       v_ptr = nullptr; // set to avoid warning\n      local::atomic_index<Base>(set_null, index, type, &name, v_ptr);\n      CPPAD_ASSERT_UNKNOWN( type == 3 );\n      return name;\n   }\n\n   /*!\n   Set value of id (used by deprecated atomic_one class)\n\n   This function is called just before calling any of the virtual function\n   and has the corresponding id of the corresponding virtual call.\n   */\n   virtual void set_old(size_t id)\n   { }\n// ---------------------------------------------------------------------------\n};\n} // END_CPPAD_NAMESPACE\n\n// member functions\n# include <cppad/core/atomic/three/ctor.hpp>\n# include <cppad/core/atomic/three/afun.hpp>\n# include <cppad/core/atomic/three/for_type.hpp>\n# include <cppad/core/atomic/three/rev_depend.hpp>\n# include <cppad/core/atomic/three/forward.hpp>\n# include <cppad/core/atomic/three/reverse.hpp>\n# include <cppad/core/atomic/three/jac_sparsity.hpp>\n# include <cppad/core/atomic/three/hes_sparsity.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/three/ctor.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_THREE_CTOR_HPP\n# define CPPAD_CORE_ATOMIC_THREE_CTOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_three_ctor}\n\nAtomic Function Constructor\n###########################\n\nSyntax\n******\n| ``class`` *atomic_user* : ``public CppAD::atomic_three<`` *Base* > {\n| ``public:``\n| |tab| *atomic_user* ( *ctor_arg_list* ) : ``CppAD::atomic_three<`` *Base* >( *name* )\n| |tab| ...\n| };\n| *atomic_user afun* ( *ctor_arg_list* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\natomic_user\n***********\n\nctor_arg_list\n=============\nIs a list of arguments for the *atomic_user* constructor.\n\nafun\n====\nThe object *afun* must stay in scope for as long\nas the corresponding atomic function is used.\nThis includes use by any :ref:`ADFun\\<Base><ADFun-name>` that\nhas this *atomic_user* operation in its\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nImplementation\n==============\nThe user defined *atomic_user* class is a publicly derived class of\n``atomic_three`` < *Base* > .\nIt should be declared as follows:\n\n| |tab| ``class`` *atomic_user* : ``public CppAD::atomic_three<`` *Base* > {\n| |tab| ``public:``\n| |tab| |tab| *atomic_user* ( *ctor_arg_list* ) : ``atomic_three`` < *Base* >( *name* )\n| |tab| ...\n| |tab| };\n\nwhere ...\ndenotes the rest of the implementation of the derived class.\nThis includes completing the constructor and\nall the virtual functions that have their\n``atomic_three`` implementations replaced by\n*atomic_user* implementations.\n\natomic_three\n************\n\nRestrictions\n============\nThe ``atomic_three`` constructor and destructor cannot be called in\n:ref:`parallel<ta_in_parallel-name>` mode.\n\nBase\n====\nThe template parameter determines the\n:ref:`atomic_three_afun@Base`\ntype for this ``AD`` < *Base* > atomic operation.\n\nname\n====\nThis ``atomic_three`` constructor argument has the following prototype\n\n   ``const std::string&`` *name*\n\nIt is the name for this atomic function and is used for error reporting.\nThe suggested value for *name* is *afun* or *atomic_user* ,\ni.e., the name of the corresponding atomic object or class.\n\nExample\n*******\n\nDefine Constructor\n==================\nThe following is an example of a atomic function constructor definition:\n:ref:`get_started.cpp<atomic_three_get_started.cpp@Constructor>` .\n\nUse Constructor\n===============\nThe following is an example using a atomic function constructor:\n:ref:`get_started.cpp<atomic_three_get_started.cpp@Use Atomic Function@Constructor>` .\n\n{xrst_end atomic_three_ctor}\n-------------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/three_ctor.hpp\nConstructors for atomic_three class.\n*/\n\n/*!\nBase class for atomic_atomic functions.\n\n\\tparam Base\nThis class is used for defining an AD<Base> atomic operation y = g(x).\n\n\\par\nmake sure user does not invoke the default constructor\n*/\ntemplate <class Base>\natomic_three<Base>::atomic_three(void)\n{  CPPAD_ASSERT_KNOWN(false,\n      \"Attempt to use the atomic_three default constructor\"\n   );\n}\n/*!\nConstructor\n\n\\param name\nname used for error reporting\n*/\n// BEGIN_PROTOTYPE\ntemplate <class Base>\natomic_three<Base>::atomic_three(const std::string& name )\n// END_PROTOTYPE\n{  CPPAD_ASSERT_KNOWN(\n      ! thread_alloc::in_parallel() ,\n      \"atomic_three: constructor cannot be called in parallel mode.\"\n   );\n   //\n   // atomic_index\n   bool        set_null  = false;\n   size_t      index     = 0;\n   size_t      type      = 3;\n   std::string copy_name = name;\n   void*       copy_this = reinterpret_cast<void*>( this );\n   index_  = local::atomic_index<Base>(\n      set_null, index, type, &copy_name, copy_this\n   );\n   // initialize work pointers as null;\n   for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++)\n      work_[thread] = nullptr;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/three/for_type.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_THREE_FOR_TYPE_HPP\n# define CPPAD_CORE_ATOMIC_THREE_FOR_TYPE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_three_for_type}\n\nAtomic Function Forward Type Calculation\n########################################\n\nSyntax\n******\n| *ok* = *afun* . ``for_type`` ( *parameter_x* , *type_x* , *type_y* )\n\nPrototype\n=========\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nDependency Analysis\n*******************\nThis calculation is sometimes referred to as a forward dependency analysis.\n\nUsage\n*****\nThis syntax and prototype are used by\n\n   *afun* ( *ax* , *ay* )\n\nwhere :ref:`atomic_three_ctor@atomic_user@afun`\nis a user defined atomic function.\n\nImplementation\n**************\nThis virtual function must be defined by the\n:ref:`atomic_three_ctor@atomic_user` class.\n\nBase\n****\nSee :ref:`atomic_three_define@Base` .\n\nparameter_x\n***********\nSee :ref:`atomic_three_define@parameter_x` .\n\ntype_x\n******\nSee :ref:`atomic_three_define@type_x` .\n\ntype_y\n******\nThis vector has size equal to the number of results for this atomic function;\ni.e. *m* = *ay* . ``size`` () .\nThe input values of the elements of *type_y*\nare not specified (must not matter).\nUpon return, for :math:`i = 0 , \\ldots , m-1`,\n*type_y* [ *i* ] is set to one of the following values:\n\n#. It is ``constant_enum`` if *ay* [ *i* ] only depends on\n   the arguments that are constants.\n#. It is ``dynamic_enum`` if *ay* [ *i* ] depends on\n   a dynamic parameter and does not depend on any variables.\n#. It is ``variable_enum`` if *ay* [ *i* ] depends on\n   a variable.\n\nok\n**\nIf this calculation succeeded, *ok* is true.\nOtherwise, it is false.\n\nExample\n*******\nThe following is an example of a atomic function ``for_type`` definition:\n:ref:`get_started.cpp<atomic_three_get_started.cpp@for_type>` .\n\n{xrst_end atomic_three_for_type}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/three_for_type.hpp\nThird generation atomic type computation.\n*/\n/*!\nLink from atomic_three to type calculation\n\n\\param parameter_x [in]\nis the value of the parameters in the corresponding function call\nafun(ax, ay).\n\n\\param type_x [in]\nspecifies which components of x are\nconstants, dynamics, and variables\n\n\\param type_y [out]\nspecifies which components of y are\nconstants, dynamics, and variables\n*/\n// BEGIN_PROTOTYPE\ntemplate <class Base>\nbool atomic_three<Base>::for_type(\n   const vector<Base>&          parameter_x ,\n   const vector<ad_type_enum>&  type_x      ,\n   vector<ad_type_enum>&        type_y      )\n// END_PROTOTYPE\n{  return false; }\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/three/forward.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_THREE_FORWARD_HPP\n# define CPPAD_CORE_ATOMIC_THREE_FORWARD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_three_forward}\n{xrst_spell\n   aparameter\n   ataylor\n}\n\nAtomic Function Forward Mode\n############################\n\nBase\n****\nThis syntax and prototype are used by\n:ref:`afun(ax, ay)<atomic_three_afun-name>` ; see\n:ref:`atomic_three_afun@Base` .\nThey are also used by\n*f* . ``Forward`` and *f* . ``new_dynamic``\nwhere *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nand *afun* is used during the recording of *f* .\n\nSyntax\n======\n\n| *ok* = *afun* . ``forward`` (\n| |tab| *parameter_x* , *type_x* ,\n| |tab| *need_y* , *order_low* , *order_up* , *type_x* , *taylor_x* , *taylor_y*\n| )\n\nPrototype\n=========\n{xrst_literal\n   // BEGIN_PROTOTYPE_BASE\n   // END_PROTOTYPE_BASE\n}\n\nAD<Base>\n********\nThis syntax and prototype are used by\n*af* . ``Forward`` and *af* . ``new_dynamic``\nwhere *af* has prototype\n\n   ``ADFun< AD<`` *Base* > , *Base* > *af*\n\nand *afun* is used in *af* (see :ref:`base2ad-name` ).\n\nSyntax\n======\n\n| *ok* = *afun* . ``forward`` (\n| |tab| *parameter_x* , *type_x* ,\n| |tab| *need_y* , *order_low* , *order_up* , *type_x* , *ataylor_x* , *ataylor_y*\n| )\n\nPrototype\n=========\n{xrst_literal\n   // BEGIN_PROTOTYPE_AD_BASE\n   // END_PROTOTYPE_AD_BASE\n}\n\nImplementation\n**************\nThe *taylor_x* , *taylor_y* version of this function\nmust be defined by the\n:ref:`atomic_three_ctor@atomic_user` class.\nIt can just return *ok* == ``false``\n(and not compute anything) for values\nof *order_up* that are greater than those used by your\n:ref:`Forward-name` mode calculations\n(order zero must be implemented).\n\nparameter_x\n***********\nSee :ref:`atomic_three_define@parameter_x` .\n\naparameter_x\n************\nThe specifications for *aparameter_x*\nis the same as for :ref:`atomic_three_define@parameter_x`\n(only the type of *ataylor_x* is different).\n\ntype_x\n******\nSee :ref:`atomic_three_define@type_x` .\n\nneed_y\n******\nOne can ignore this argument and compute all the *taylor_y*\nTaylor coefficient.\nOften, this is not necessary and *need_y* is used to specify this.\nThe value :ref:`atomic_three_for_type@type_y` is used\nto determine which coefficients are necessary as follows:\n\nConstant Parameters\n===================\nIf *need_y* == ``size_t`` ( ``constant_enum`` ) ,\nthen only the taylor coefficients\nfor :math:`Y_i (t)` where *type_y* [ *i* ] == ``constant_enum``\nare necessary.\nThis is the case during a :ref:`from_json-name` operation.\n\nDynamic Parameters\n==================\nIf *need_y* == ``size_t`` ( ``dynamic_enum`` ) ,\nthen only the taylor coefficients\nfor :math:`Y_i (t)` where *type_y* [ *i* ] == ``dynamic_enum``\nare necessary.\nThis is the case during an :ref:`new_dynamic-name` operation.\n\nVariables\n=========\nIf *need_y* == ``size_t`` ( ``variable_enum`` ) ,\nIf ``ad_type_enum`` ( *need_y* ) == *variable_enum* ,\nthen only the taylor coefficients\nfor :math:`Y_i (t)` where *type_y* [ *i* ] == ``variable_enum``\nare necessary.\nThis is the case during a :ref:`f.Forward<Forward-name>` operation.\nT\n\nAll\n===\nIf *need_y > size_t* ( *variable_enum* ) ,\nthen the taylor coefficients for all :math:`Y_i (t)` are necessary.\nThis is the case during an *afun* ( *ax* , *ay* ) operation.\n\norder_low\n*********\nThis argument\nspecifies the lowest order Taylor coefficient that we are computing.\n\np\n=\nWe sometimes use the notation *p* = *order_low* below.\n\norder_up\n********\nThis argument\nspecifies the highest order Taylor coefficient that we are computing\n( *order_low* <= *order_up* ).\n\nq\n=\nWe sometimes use the notation *q* = *order_up* below.\n\ntaylor_x\n********\nThe size of *taylor_x* is ( *q* +1)* *n* .\nFor :math:`j = 0 , \\ldots , n-1` and :math:`k = 0 , \\ldots , q`,\nwe use the Taylor coefficient notation\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      x_j^k    & = & \\R{taylor\\_x} [ j * ( q + 1 ) + k ]\n      \\\\\n      X_j (t)  & = & x_j^0 + x_j^1 t^1 + \\cdots + x_j^q t^q\n   \\end{eqnarray}\n\nNote that superscripts represent an index for :math:`x_j^k`\nand an exponent for :math:`t^k`.\nAlso note that the Taylor coefficients for :math:`X(t)` correspond\nto the derivatives of :math:`X(t)` at :math:`t = 0` in the following way:\n\n.. math::\n\n   x_j^k = \\frac{1}{ k ! } X_j^{(k)} (0)\n\nparameters\n==========\nIf the *j*-th component of *x* corresponds to a parameter,\n\n   *type_x* [ *j* ] < ``CppAD::variable_enum``\n\nIn this case,\nthe *j*-th component of *parameter_x* is equal to :math:`x_j^0`;\ni.e.,\n\n   *parameter_x* [ *j* ] == *taylor_x* [ *j* * ( *q*  + 1 ) + 0 ]\n\nFurthermore, for *k*  > 0 ,\n\n   *taylor_x* [ *j* * ( *q* + 1 ) + *k*  ] == 0\n\nataylor_x\n*********\nThe specifications for *ataylor_x* is the same as for *taylor_x*\n(only the type of *ataylor_x* is different).\n\ntaylor_y\n********\nThe size of *taylor_y* is ( *q* +1)* *m* .\nUpon return,\nFor :math:`i = 0 , \\ldots , m-1` and :math:`k = 0 , \\ldots , q`,\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      Y_i (t)  & = & g_i [ X(t) ]\n      \\\\\n      Y_i (t)  & = & y_i^0 + y_i^1 t^1 + \\cdots + y_i^q t^q + o ( t^q )\n      \\\\\n      \\R{taylor\\_y}  [ i * ( q + 1 ) + k ] & = & y_i^k\n   \\end{eqnarray}\n\nwhere :math:`o( t^q ) / t^q \\rightarrow 0` as :math:`t \\rightarrow 0`.\nNote that superscripts represent an index for :math:`y_j^k`\nand an exponent for :math:`t^k`.\nAlso note that the Taylor coefficients for :math:`Y(t)` correspond\nto the derivatives of :math:`Y(t)` at :math:`t = 0` in the following way:\n\n.. math::\n\n   y_j^k = \\frac{1}{ k ! } Y_j^{(k)} (0)\n\nIf :math:`p > 0`,\nfor :math:`i = 0 , \\ldots , m-1` and :math:`k = 0 , \\ldots , p-1`,\nthe input of *taylor_y* satisfies\n\n.. math::\n\n   \\R{taylor\\_y}  [ i * ( q + 1 ) + k ] = y_i^k\n\nThese values do not need to be recalculated\nand can be used during the computation of the higher order coefficients.\n\nataylor_y\n*********\nThe specifications for *ataylor_y* is the same as for *taylor_y*\n(only the type of *ataylor_y* is different).\n\nok\n**\nIf this calculation succeeded, *ok* is true.\nOtherwise, it is false.\n\nDiscussion\n**********\nFor example, suppose that *order_up*  == 2 ,\nand you know how to compute the function :math:`g(x)`,\nits first derivative :math:`g^{(1)} (x)`,\nand it component wise Hessian :math:`g_i^{(2)} (x)`.\nThen you can compute *taylor_x* using the following formulas:\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   y_i^0 & = & Y(0)\n         = g_i ( x^0 )\n   \\\\\n   y_i^1 & = & Y^{(1)} ( 0 )\n         = g_i^{(1)} ( x^0 ) X^{(1)} ( 0 )\n         = g_i^{(1)} ( x^0 ) x^1\n   \\\\\n   y_i^2\n   & = & \\frac{1}{2 !} Y^{(2)} (0)\n   \\\\\n   & = & \\frac{1}{2} X^{(1)} (0)^\\R{T} g_i^{(2)} ( x^0 ) X^{(1)} ( 0 )\n     +   \\frac{1}{2} g_i^{(1)} ( x^0 ) X^{(2)} ( 0 )\n   \\\\\n   & = & \\frac{1}{2} (x^1)^\\R{T} g_i^{(2)} ( x^0 ) x^1\n     +    g_i^{(1)} ( x^0 ) x^2\n   \\end{eqnarray}\n\nFor :math:`i = 0 , \\ldots , m-1`, and :math:`k = 0 , 1 , 2`,\n\n.. math::\n\n   \\R{taylor\\_y} [ i * (q + 1) + k ] = y_i^k\n\n{xrst_toc_hidden\n   example/atomic_three/forward.cpp\n   example/atomic_three/dynamic.cpp\n}\nExamples\n********\nThe files\n:ref:`atomic_three_forward.cpp-name` and :ref:`atomic_three_dynamic.cpp-name`\ncontain examples and tests that uses this routine.\n\n{xrst_end atomic_three_forward}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/three_forward.hpp\nThird generation atomic forward mode.\n*/\n/*!\nLink from atomic_three to forward mode\n\n\\param parameter_x [in]\ncontains the values, in afun(ax, ay), for arguments that are parameters.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param need_y [in]\nspecifies which components of taylor_y are needed,\n\n\\param order_low [in]\nlowerest order for this forward mode calculation.\n\n\\param order_up [in]\nhighest order for this forward mode calculation.\n\n\\param taylor_x [in]\nTaylor coefficients corresponding to x for this calculation.\n\n\\param taylor_y [out]\nTaylor coefficient corresponding to y for this calculation\n\nSee the forward mode in user's documentation for atomic_three\n*/\n// BEGIN_PROTOTYPE_BASE\ntemplate <class Base>\nbool atomic_three<Base>::forward(\n   const vector<Base>&          parameter_x ,\n   const vector<ad_type_enum>&  type_x      ,\n   size_t                       need_y      ,\n   size_t                       order_low   ,\n   size_t                       order_up    ,\n   const vector<Base>&          taylor_x    ,\n   vector<Base>&                taylor_y    )\n// END_PROTOTYPE_BASE\n{  return false; }\n\n/*!\nLink from atomic_three to forward mode\n\n\\param aparameter_x [in]\ncontains the values, in afun(ax, ay), for arguments that are parameters.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param need_y [in]\nspecifies which components of taylor_y are needed,\n\n\\param order_low [in]\nlowerest order for this forward mode calculation.\n\n\\param order_up [in]\nhighest order for this forward mode calculation.\n\n\\param ataylor_x [in]\nTaylor coefficients corresponding to x for this calculation.\n\n\\param ataylor_y [out]\nTaylor coefficient corresponding to y for this calculation\n\nSee the forward mode in user's documentation for base_three\n*/\n// BEGIN_PROTOTYPE_AD_BASE\ntemplate <class Base>\nbool atomic_three<Base>::forward(\n   const vector< AD<Base> >&    aparameter_x ,\n   const vector<ad_type_enum>&  type_x       ,\n   size_t                       need_y       ,\n   size_t                       order_low    ,\n   size_t                       order_up     ,\n   const vector< AD<Base> >&    ataylor_x    ,\n   vector< AD<Base> >&          ataylor_y    )\n// END_PROTOTYPE_AD_BASE\n{  return false; }\n\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/three/hes_sparsity.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_THREE_HES_SPARSITY_HPP\n# define CPPAD_CORE_ATOMIC_THREE_HES_SPARSITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_three_hes_sparsity}\n\nAtomic Function Hessian Sparsity Patterns\n#########################################\n\nSyntax\n******\n| *ok* = *afun* . ``hes_sparsity`` (\n| |tab| *parameter_x* , *type_x* , *select_x* , *select_y* , *pattern_out*\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nImplementation\n**************\nThis function must be defined if\n:ref:`atomic_three_ctor@atomic_user@afun` is\nused to define an :ref:`ADFun-name` object *f* ,\nand Hessian sparsity patterns are computed for *f* .\n\nBase\n****\nSee :ref:`atomic_three_afun@Base` .\n\nparameter_x\n***********\nSee :ref:`atomic_three_define@parameter_x` .\n\ntype_x\n******\nSee :ref:`atomic_three_define@type_x` .\n\nselect_x\n********\nThis argument has size equal to the number of arguments to this\natomic function; i.e. the size of *ax* .\nIt specifies which domain components are included in\nthe calculation of *pattern_out* .\nIf *select_x* [ *j* ] is false, then there will be no indices\n*k* such that either of the following hold:\n\n| |tab| *pattern_out* . ``row`` ()[ *k* ] == *j*\n| |tab| *pattern_out* . ``col`` ()[ *k* ] == *j*\n\n.\n\nselect_y\n********\nThis argument has size equal to the number of results to this\natomic function; i.e. the size of *ay* .\nIt specifies which range component functions :math:`g_i (x)` are included in\nof *pattern_out* .\n\npattern_out\n***********\nThis input value of *pattern_out* does not matter.\nUpon return it is the union,\nwith respect to *i* such that *select_y* [ *i* ] is true,\nof the sparsity pattern for Hessian of :math:`g_i (x)`.\nTo be specific, there are non-negative indices\n*i* , *r* , *c* , and *k* such that\n\n| |tab| *pattern_out* . ``row`` ()[ *k* ] == *r*\n| |tab| *pattern_out* . ``col`` ()[ *k* ] == *c*\n\nif and only if\n*select_y* [ *i* ] is true,\n*select_x* [ *r* ] is true,\n*select_x* [ *c* ] is true,\nand\n\n.. math::\n\n   \\partial_{x(r)} \\partial_{x(c)} g_i(x)\n\nis possibly non-zero.\nNote that the sparsity pattern should be symmetric.\n\nok\n**\nIf this calculation succeeded, *ok* is true.\nOtherwise it is false.\n{xrst_toc_hidden\n   example/atomic_three/hes_sparsity.cpp\n}\nExamples\n********\nThe file :ref:`atomic_three_hes_sparsity.cpp-name` contains an example and test\nthat uses this routine.\n\n{xrst_end atomic_three_hes_sparsity}\n-----------------------------------------------------------------------------\n*/\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/three_hes_sparsity.hpp\nThird generation atomic Hessian dependency and sparsity patterns.\n*/\n/*!\natomic_three to Hessian dependency and sparsity calculations.\n\n\\param parameter_x [in]\ncontains the values for arguments that are parameters.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param select_x [in]\nwhich domain components to include in the dependency or sparsity pattern.\n\n\\param select_y [in]\nwhich range components to include in the dependency or sparsity pattern.\n\n\\param pattern_out [out]\nis the sparsity pattern for Hessian.\n*/\n// BEGIN_PROTOTYPE\ntemplate <class Base>\nbool atomic_three<Base>::hes_sparsity(\n   const vector<Base>&                     parameter_x  ,\n   const vector<ad_type_enum>&             type_x       ,\n   const vector<bool>&                     select_x     ,\n   const vector<bool>&                     select_y     ,\n   sparse_rc< vector<size_t> >&            pattern_out  )\n// END_PROTOTYPE\n{  return false; }\n/*!\nLink from forward Hessian sweep to atomic_three.\n2DO: move this function outside this file so can change\ndeveloper documentation to omhelp formatting.\n\n\\tparam InternalSparsity\nIs the used internally for sparsity calculations; i.e.,\nsparse_pack or sparse_list.\n\n\\param parameter_x\nis parameter arguments to the function, other components are nan.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param x_index\nis the variable index, on the tape, for the arguments to this function.\nThis size of x_index is n, the number of arguments to this function.\nThe index zero is used for parameters.\n\n\\param y_index\nis the variable index, on the tape, for the results for this function.\nThis size of y_index is m, the number of results for this function.\nThe index zero is used for parameters.\n\n\\param for_jac_sparsity\nOn input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nis the forward Jacobian sparsity for the j-th argument to this atomic function.\n\n\\param rev_jac_pattern\nOn input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i],\nis the reverse Jacobian sparsity for the i-th result to this atomic function.\nThis shows which components of the result affect the function we are\ncomputing the Hessian of.\n\n\\param hes_sparsity_for\nThis is the sparsity pattern for the Hessian. On input, the non-linear\nterms in the atomic function have not been included. Upon return, they\nhave been included.\n*/\ntemplate <class Base>\ntemplate <class InternalSparsity>\nbool atomic_three<Base>::for_hes_sparsity(\n   const vector<Base>&              parameter_x      ,\n   const vector<ad_type_enum>&      type_x           ,\n   const vector<size_t>&            x_index          ,\n   const vector<size_t>&            y_index          ,\n   size_t                           np1              ,\n   size_t                           numvar           ,\n   const InternalSparsity&          rev_jac_pattern  ,\n   InternalSparsity&                for_sparsity     )\n{  typedef typename InternalSparsity::const_iterator const_iterator;\n   //\n   CPPAD_ASSERT_UNKNOWN( rev_jac_pattern.end() == 1 );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + numvar );\n   size_t n      = x_index.size();\n   size_t m      = y_index.size();\n   //\n   // select_x\n   vector<bool> select_x(n);\n   for(size_t j = 0; j < n; j++)\n   {  // check if should compute pattern w.r.t x[j]\n      select_x[j] = for_sparsity.number_elements(np1 + x_index[j]) > 0;\n   }\n   //\n   // bool select_y\n   vector<bool> select_y(m);\n   for(size_t i = 0; i < m; i++)\n   {  // check if we should include y[i]\n      select_y[i] = rev_jac_pattern.number_elements(y_index[i]) > 0;\n   }\n   // ------------------------------------------------------------------------\n   // call user's version of atomic function for Jacobian\n   sparse_rc< vector<size_t> > pattern_out;\n   bool dependency = false;\n   bool ok = jac_sparsity(\n      parameter_x, type_x, dependency, select_x, select_y, pattern_out\n   );\n   if( ! ok )\n      return false;\n   //\n   // transfer sparsity patterns from pattern_out to var_sparsity\n   size_t                nnz = pattern_out.nnz();\n   const vector<size_t>& row( pattern_out.row() );\n   const vector<size_t>& col( pattern_out.col() );\n   for(size_t k = 0; k < nnz; ++k)\n   {  size_t i = row[k];\n      size_t j = col[k];\n      CPPAD_ASSERT_KNOWN(\n         select_y[i] && select_x[j],\n         \"atomic: jac_sparsity: pattern_out not in \"\n         \"select_x or select_y range\"\n      );\n      const_iterator itr(for_sparsity, np1 + x_index[j]);\n      size_t ell = *itr;\n      while( ell < np1 )\n      {  for_sparsity.post_element(np1 + y_index[i], ell );\n         ell = *(++itr);\n      }\n   }\n   for(size_t i = 0; i < m; ++i)\n      for_sparsity.process_post( np1 + y_index[i] );\n   // ------------------------------------------------------------------------\n   // call user's version of atomic function for Hessian\n   ok = hes_sparsity(\n      parameter_x, type_x, select_x, select_y, pattern_out\n   );\n   if( ! ok )\n      return ok;\n   //\n   // add new elements to Hessian sparisty in calling routine\n   nnz = pattern_out.nnz();\n   for(size_t k = 0; k < nnz; ++k)\n   {  size_t r = row[k];\n      size_t c = col[k];\n      CPPAD_ASSERT_KNOWN(\n         select_x[r] && select_x[c],\n         \"atomic: hes_sparsity: pattern_out not in select_x range\"\n      );\n      const_iterator itr_1(for_sparsity, np1 + x_index[r]);\n      size_t v1 = *itr_1;\n      while( v1 < np1 )\n      {  for_sparsity.binary_union(\n            v1, v1, np1 + x_index[c], for_sparsity\n             );\n             v1 = *(++itr_1);\n      }\n      // no need to add same elements twice\n      if( c != r )\n      {  const_iterator itr_2(for_sparsity, np1 + x_index[c]);\n         size_t v2 = *itr_2;\n         while( v2 < np1 )\n         {  for_sparsity.binary_union(\n               v2, v2, np1 + x_index[r], for_sparsity\n            );\n            v2 = *(++itr_2);\n         }\n      }\n   }\n   return ok;\n}\n/*!\nLink from for_reverse Hessian sweep to atomic_three.\n\n\\tparam InternalSparsity\nIs the used internally for sparsity calculations; i.e.,\nsparse_pack or sparse_list.\n\n\\param parameter_x\nis parameter arguments to the function, other components are nan.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param x_index\nis the variable index, on the tape, for the arguments to this function.\nThis size of x_index is n, the number of arguments to this function.\nThe index zero is used for parameters.\n\n\\param y_index\nis the variable index, on the tape, for the results for this function.\nThis size of y_index is m, the number of results for this function.\nThe index zero is used for parameters.\n\n\\param for_jac_pattern\nOn input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nis the forward Jacobian pattern for the j-th argument to this atomic function.\n\n\\param rev_jac_flag\nOn input, for i = 0, ... , m-1, rev_jac_flag[ y_index[i] ] is true\nif the function we are computing the Hessian of has possibly non-zero Jacobian\nw.r.t variable y_index[i].\nOn output, for j = 0, ... , n, rev_jac_flag[ x_index[j] ] is set to true\nif the variable with index x_index[j] has possible non-zero Jacobian\nwith respect to one of the true y_index[i] cases.\nOtherwise, rev_jac_flag [ x_inde[j] ] is not changed.\n\n\\param hes_sparsity_rev\nIs the reverse mode sparsity pattern for the Hessian. On input, the non-linear\nterms in the atomic function have not been included. Upon return, they\nhave been included.\n*/\ntemplate <class Base>\ntemplate <class InternalSparsity>\nbool atomic_three<Base>::rev_hes_sparsity(\n   const vector<Base>&              parameter_x      ,\n   const vector<ad_type_enum>&      type_x           ,\n   const vector<size_t>&            x_index          ,\n   const vector<size_t>&            y_index          ,\n   const InternalSparsity&          for_jac_pattern  ,\n   bool*                            rev_jac_flag     ,\n   InternalSparsity&                hes_sparsity_rev )\n{  typedef typename InternalSparsity::const_iterator const_iterator;\n   size_t n      = x_index.size();\n   size_t m      = y_index.size();\n   //\n   // select_x\n   vector<bool> select_x(n);\n   for(size_t j = 0; j < n; j++)\n   {  // check if should compute pattern w.r.t x[j]\n      const_iterator itr(for_jac_pattern, x_index[j]);\n      size_t i = *itr;\n      select_x[j] = i < for_jac_pattern.end();\n      CPPAD_ASSERT_UNKNOWN( x_index[j] > 0 || ! select_x[j] );\n   }\n   //\n   // bool select_y\n   vector<bool> select_y(m);\n   for(size_t i = 0; i < m; i++)\n   {  // check if we should include y[i]\n      select_y[i] = rev_jac_flag[ y_index[i] ];\n      CPPAD_ASSERT_UNKNOWN( y_index[i] > 0 || ! select_y[i] );\n   }\n   //\n   // call atomic function for Jacobain sparsity\n   bool dependency = false;\n   sparse_rc< vector<size_t> > pattern_jac;\n   bool ok = jac_sparsity(\n      parameter_x, type_x, dependency, select_x, select_y, pattern_jac\n   );\n   const vector<size_t>& row_jac( pattern_jac.row() );\n   const vector<size_t>& col_jac( pattern_jac.col() );\n   size_t nnz_jac = pattern_jac.nnz();\n   if( ! ok )\n      return ok;\n   //\n   // call atomic function for Hessian sparsity\n   sparse_rc< vector<size_t> > pattern_hes;\n   ok = hes_sparsity(parameter_x, type_x, select_x, select_y, pattern_hes);\n   const vector<size_t>& row_hes( pattern_hes.row() );\n   const vector<size_t>& col_hes( pattern_hes.col() );\n   size_t nnz_hes = pattern_hes.nnz();\n   if( ! ok )\n      return ok;\n   //\n   // propagate Hessian sparsity through the Jacobian\n   for(size_t k = 0; k < nnz_jac; ++k)\n   {  size_t i = row_jac[k];\n      size_t j = col_jac[k];\n      CPPAD_ASSERT_KNOWN(\n         select_y[i] && select_x[j] ,\n         \"atomic: jac_sparsity: pattern_out not in \"\n         \"select_x or select_y range\"\n      );\n      // from y_index[i] to x_index[j]\n      hes_sparsity_rev.binary_union(\n         x_index[j], x_index[j], y_index[i], hes_sparsity_rev\n      );\n   }\n   //\n   // propagate rev_jac_flag through the Jacobian\n   // (seems OK to exclude variables with zero forward jacobian)\n   for(size_t k = 0; k < nnz_jac; ++k)\n   {  size_t j = col_jac[k];\n      rev_jac_flag[ x_index[j] ] = true;\n   }\n   //\n   // new hessian sparsity terms between y and x\n   for(size_t k = 0; k < nnz_hes; ++k)\n   {  size_t r = row_hes[k];\n      size_t c = col_hes[k];\n      CPPAD_ASSERT_KNOWN(\n         select_x[r] && select_x[c] ,\n         \"atomic: hes_sparsity: pattern_out not in select_x range\"\n      );\n      hes_sparsity_rev.binary_union(\n         x_index[r], x_index[r], x_index[c], for_jac_pattern\n      );\n      hes_sparsity_rev.binary_union(\n         x_index[c], x_index[c], x_index[r], for_jac_pattern\n      );\n   }\n   return ok;\n}\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/three/jac_sparsity.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_THREE_JAC_SPARSITY_HPP\n# define CPPAD_CORE_ATOMIC_THREE_JAC_SPARSITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_three_jac_sparsity}\n\nAtomic Function Jacobian Sparsity Patterns\n##########################################\n\nSyntax\n******\n| *ok* = *afun* . ``jac_sparsity`` (\n| |tab| *parameter_x* , *type_x* , *dependency* , *select_x* , *select_y* , *pattern_out*\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nImplementation\n**************\nThis function must be defined if\n:ref:`atomic_three_ctor@atomic_user@afun` is\nused to define an :ref:`ADFun-name` object *f* ,\nand Jacobian sparsity patterns are computed for *f* .\n(Computing Hessian sparsity patterns and optimizing\nrequires Jacobian sparsity patterns.)\n\nBase\n****\nSee :ref:`atomic_three_afun@Base` .\n\nparameter_x\n***********\nSee :ref:`atomic_three_define@parameter_x` .\n\ntype_x\n******\nSee :ref:`atomic_three_define@type_x` .\n\ndependency\n**********\nIf *dependency* is true,\nthen *pattern_out* is a\n:ref:`dependency.cpp@Dependency Pattern`\nfor this atomic function.\nOtherwise it is a\n:ref:`glossary@Sparsity Pattern` for the\nderivative of the atomic function.\n\nselect_x\n********\nThis argument has size equal to the number of arguments to this\natomic function; i.e. the size of *ax* .\nIt specifies which domain components are included in\nthe calculation of *pattern_out* .\nIf *select_x* [ *j* ] is false, then there will be no indices\n*k* such that\n\n   *pattern_out* . ``col`` ()[ *k* ] == *j*\n\n.\n\nselect_y\n********\nThis argument has size equal to the number of results to this\natomic function; i.e. the size of *ay* .\nIt specifies which range components are included in\nthe calculation of *pattern_out* .\nIf *select_y* [ *i* ] is false, then there will be no indices\n*k* such that\n\n   *pattern_out* . ``row`` ()[ *k* ] == *i*\n\n.\n\npattern_out\n***********\nThis input value of *pattern_out* does not matter.\nUpon return it is a\ndependency or sparsity pattern for the Jacobian of :math:`g(x)`,\nthe function corresponding to\n:ref:`atomic_three_ctor@atomic_user@afun` ;\n*dependency* above.\nTo be specific, there are non-negative indices\n*i* , *j* , *k* such that\n\n| |tab| *pattern_out* . ``row`` ()[ *k* ] == *i*\n| |tab| *pattern_out* . ``col`` ()[ *k* ] == *j*\n\nif and only if\n*select_x* [ *j* ] is true,\n*select_y* [ *j* ] is true,\nand :math:`g_i(x)` depends on the value of :math:`x_j`\n(and the partial of :math:`g_i(x)` with respect to\n:math:`x_j` is possibly non-zero).\n\nok\n**\nIf this calculation succeeded, *ok* is true.\nOtherwise it is false.\n{xrst_toc_hidden\n   example/atomic_three/jac_sparsity.cpp\n}\nExamples\n********\nThe file :ref:`atomic_three_jac_sparsity.cpp-name` contains an example and test\nthat uses this routine.\n\n{xrst_end atomic_three_jac_sparsity}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/three_jac_sparsity.hpp\nThird generation atomic Jacobian dependency and sparsity patterns.\n*/\n/*!\natomic_three to Jacobian dependency and sparsity calculations.\n\n\\param parameter_x [in]\ncontains the values for arguments that are parameters.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param dependency [in]\nif true, calculate dependency pattern,\notherwise calculate sparsity pattern.\n\n\\param select_x [in]\nwhich domain components to include in the dependency or sparsity pattern.\nThe index zero is used for parameters.\n\n\\param select_y [in]\nwhich range components to include in the dependency or sparsity pattern.\nThe index zero is used for parameters.\n\n\\param pattern_out [out]\nis the dependency or sparsity pattern.\n*/\n// BEGIN_PROTOTYPE\ntemplate <class Base>\nbool atomic_three<Base>::jac_sparsity(\n   const vector<Base>&                     parameter_x  ,\n   const vector<ad_type_enum>&             type_x       ,\n   bool                                    dependency   ,\n   const vector<bool>&                     select_x     ,\n   const vector<bool>&                     select_y     ,\n   sparse_rc< vector<size_t> >&            pattern_out  )\n// END_PROTOTYPE\n{  return false; }\n/*!\nLink from forward Jacobian sparsity calculations to atomic_three\n\n\\tparam InternalSparsity\nIs the type used for internal sparsity calculations; i.e.,\nsparse_pack or sparse_list.\n\n\\param dependency\nif true, calculate dependency pattern,\notherwise calculate sparsity pattern.\n\n\\param parameter_x\nis parameter arguments to the function, other components are nan.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param x_index\nis the variable index, on the tape, for the arguments to this atomic function.\nThis size of x_index is n, the number of arguments to this atomic function.\nThe index zero is used for parameters.\n\n\\param y_index\nis the variable index, on the tape, for the results for this atomic function.\nThis size of y_index is m, the number of results for this atomic function.\nThe index zero is used for parameters.\n\n\\param var_sparsity\nOn input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nis the sparsity for the j-th argument to this atomic function.\nOn output, for i = 0, ... , m-1, the sparsity pattern with index y_index[i],\nis the sparsity for the i-th result for this atomic function.\n\n\\return\nis true if the computation succeeds.\n*/\ntemplate <class Base>\ntemplate <class InternalSparsity>\nbool atomic_three<Base>::for_jac_sparsity(\n   bool                             dependency   ,\n   const vector<Base>&              parameter_x  ,\n   const vector<ad_type_enum>&      type_x       ,\n   const vector<size_t>&            x_index      ,\n   const vector<size_t>&            y_index      ,\n   InternalSparsity&                var_sparsity )\n{  typedef typename InternalSparsity::const_iterator iterator;\n\n   // number of arguments and results for this atomic function\n   size_t n = x_index.size();\n   size_t m = y_index.size();\n\n   // select_y\n   vector<bool> select_y(m);\n   for(size_t i = 0; i < m; ++i)\n      select_y[i] = y_index[i] != 0;\n\n   // determine select_x\n   vector<bool> select_x(n);\n   for(size_t j = 0; j < n; ++j)\n   {  // check if x_j depends on any previous variable\n      iterator itr(var_sparsity, x_index[j]);\n      size_t ell = *itr;\n      select_x[j] = ell < var_sparsity.end();\n      CPPAD_ASSERT_UNKNOWN( x_index[j] > 0 || ! select_x[j] );\n   }\n   sparse_rc< vector<size_t> > pattern_out;\n   bool ok = jac_sparsity(\n      parameter_x, type_x, dependency, select_x, select_y, pattern_out\n   );\n   if( ! ok )\n      return false;\n   //\n   // transfer sparsity patterns from pattern_out to var_sparsity\n   size_t                nnz = pattern_out.nnz();\n   const vector<size_t>& row( pattern_out.row() );\n   const vector<size_t>& col( pattern_out.col() );\n   for(size_t k = 0; k < nnz; ++k)\n   {  size_t i = row[k];\n      size_t j = col[k];\n      CPPAD_ASSERT_KNOWN(\n         select_y[i] && select_x[j],\n         \"atomic: jac_sparsity: pattern_out not in \"\n         \"select_x or select_y range\"\n      );\n      iterator itr(var_sparsity, x_index[j]);\n      size_t ell = *itr;\n      while( ell < var_sparsity.end() )\n      {  var_sparsity.post_element( y_index[i], ell );\n         ell = *(++itr);\n      }\n   }\n   for(size_t i = 0; i < m; ++i)\n      var_sparsity.process_post( y_index[i] );\n   //\n   return true;\n}\n/*!\nLink from reverse Jacobian sparsity calculations to atomic_three\n\n\\tparam InternalSparsity\nIs the type used for internal sparsity calculations; i.e.,\nsparse_pack or sparse_list.\n\n\\param dependency\nif true, calculate dependency pattern,\notherwise calculate sparsity pattern.\n\n\\param parameter_x\nis parameter arguments to the function, other components are nan.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param x_index\nis the variable index, on the tape, for the arguments to this atomic function.\nThis size of x_index is n, the number of arguments to this atomic function.\n\n\\param y_index\nis the variable index, on the tape, for the results for this atomic function.\nThis size of y_index is m, the number of results for this atomic function.\n\n\\param var_sparsity\nOn input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i],\nis the sparsity of the outer function with respect to the i-th\nresult for this atomic function.\nOn input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nis the sparsity for the outer function with respect to the j-th\nargument to this atomic function.\nOn output, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nis the sparsity for the outer function with respect to the j-th\nargument to this atomic function with the atomic function results\nremoved as arguments to the outer function.\n\n\\return\nis true if the computation succeeds.\n*/\ntemplate <class Base>\ntemplate <class InternalSparsity>\nbool atomic_three<Base>::rev_jac_sparsity(\n   bool                             dependency   ,\n   const vector<Base>&              parameter_x  ,\n   const vector<ad_type_enum>&      type_x       ,\n   const vector<size_t>&            x_index      ,\n   const vector<size_t>&            y_index      ,\n   InternalSparsity&                var_sparsity )\n{  typedef typename InternalSparsity::const_iterator iterator;\n\n   // number of arguments and results for this atomic function\n   size_t n = x_index.size();\n   size_t m = y_index.size();\n\n   // selection vectors\n   vector<bool> select_x(n), select_y(m);\n\n   // 2DO: perhaps we could use for_type(type_x, type_y)\n   // to reduce the true components in select_x\n   for(size_t j = 0; j < n; ++j)\n      select_x[j] = true;\n\n   // determine select_y\n   for(size_t i = 0; i < m; ++i)\n   {  // check if y_i has sparsity is non-empty\n      iterator itr(var_sparsity, y_index[i]);\n      size_t ell = *itr;\n      select_y[i] = ell < var_sparsity.end();\n   }\n   sparse_rc< vector<size_t> > pattern_out;\n   bool ok = jac_sparsity(\n      parameter_x, type_x, dependency, select_x, select_y, pattern_out\n   );\n   if( ! ok )\n      return false;\n   //\n   // transfer sparsity patterns from pattern_out to var_sparsity\n   size_t                nnz = pattern_out.nnz();\n   const vector<size_t>& row( pattern_out.row() );\n   const vector<size_t>& col( pattern_out.col() );\n   for(size_t k = 0; k < nnz; ++k)\n   {  size_t i = row[k];\n      size_t j = col[k];\n      CPPAD_ASSERT_KNOWN(\n         select_y[i] && select_x[j],\n         \"atomic: jac_sparsity: pattern_out not in \"\n         \"select_x or select_y range\"\n      );\n      iterator itr(var_sparsity, y_index[i]);\n      size_t ell = *itr;\n      while( ell < var_sparsity.end() )\n      {  var_sparsity.post_element( x_index[j], ell );\n         ell = *(++itr);\n      }\n   }\n   for(size_t j = 0; j < n; ++j)\n      var_sparsity.process_post( x_index[j] );\n   //\n   return true;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/three/rev_depend.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_THREE_REV_DEPEND_HPP\n# define CPPAD_CORE_ATOMIC_THREE_REV_DEPEND_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_three_rev_depend}\n\nAtomic Function Reverse Dependency Calculation\n##############################################\n\nSyntax\n******\n| *ok* = *afun* . ``rev_depend`` (\n| |tab| *parameter_x* , *type_x* , *depend_x* , *depend_y*\n| )\n\nPrototype\n=========\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nDependency Analysis\n*******************\nThis calculation is sometimes referred to as a reverse dependency analysis.\n\nImplementation\n**************\nThis function must be defined if\n:ref:`atomic_three_ctor@atomic_user@afun` is\nused to define an :ref:`ADFun-name` object *f* ,\nand :ref:`f.optimize()<optimize-name>` is used.\n\nBase\n****\nSee :ref:`atomic_three_afun@Base` .\n\nparameter_x\n***********\nSee :ref:`atomic_three_define@parameter_x` .\n\ntype_x\n******\nSee :ref:`atomic_three_define@type_x` .\n\ndepend_x\n********\nThis vector has size equal to the number of arguments for this atomic function;\ni.e. *n* = *ax* . ``size`` () .\nThe input values of the elements of *depend_x*\nare not specified (must not matter).\nUpon return, for :math:`j = 0 , \\ldots , n-1`,\n*depend_x* [ *j* ] is true if the values of interest depend\non the value of :ref:`ax[j]<atomic_three_afun@ax>` in the corresponding\n*afun* ( *ax* , *ay* ) call.\n\nOptimize\n========\nParameters and variables,\nthat the values of interest do not depend on,\nmay get removed by :ref:`optimization<optimize-name>` .\nThe corresponding values in :ref:`atomic_three_define@parameter_x` ,\nand :ref:`atomic_three_forward@taylor_x`\n(after optimization has removed them) are not specified.\n\ndepend_y\n********\nThis vector has size equal to the number of results for this atomic function;\ni.e. *m* = *ay* . ``size`` () .\nFor :math:`i = 0 , \\ldots , m-1`,\n*depend_y* [ *i* ] is true if the values of interest depend\non the value of :ref:`ay[i]<atomic_three_afun@ay>` in the corresponding\n*afun* ( *ax* , *ay* ) call.\n\nok\n**\nIf this calculation succeeded, *ok* is true.\nOtherwise, it is false.\n\nContents\n********\n{xrst_toc_table\n   example/atomic_three/rev_depend.cpp\n}\nExample\n*******\nThe following is an example of a atomic function ``rev_depend`` definition:\n:ref:`atomic_three_rev_depend.cpp-name` .\n\n{xrst_end atomic_three_rev_depend}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/three_rev_depend.hpp\nThird generation atomic type computation.\n*/\n/*!\nLink from atomic_three to reverse dependency calculation\n\n\\param parameter_x [in]\nis the value of the parameters in the corresponding function call\nafun(ax, ay).\n\n\\param type_x [in]\nis the value for each of the components of x.\n\n\\param depend_x [out]\nspecifies which components of x affect values of interest.\n\n\\param depend_y [in]\nspecifies which components of y affect values of interest.\n*/\n// BEGIN_PROTOTYPE\ntemplate <class Base>\nbool atomic_three<Base>::rev_depend(\n   const vector<Base>&         parameter_x ,\n   const vector<ad_type_enum>& type_x      ,\n   vector<bool>&               depend_x    ,\n   const vector<bool>&         depend_y    )\n// END_PROTOTYPE\n{  return false; }\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/three/reverse.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_THREE_REVERSE_HPP\n# define CPPAD_CORE_ATOMIC_THREE_REVERSE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_three_reverse}\n{xrst_spell\n   aparameter\n   apartial\n   ataylor\n}\n\nAtomic Function Reverse Mode\n############################\n\nBase\n****\nThis syntax is used by *f* . ``Reverse`` where *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nand *afun* is used in *f* ;\nsee :ref:`atomic_three_afun@Base` .\n\nSyntax\n======\n\n| *ok* = *afun* . ``reverse`` (\n| |tab| *parameter_x* , *type_x* ,\n| |tab| *order_up* , *taylor_x* , *taylor_y* , *partial_x* , *partial_y*\n| )\n\nPrototype\n=========\n{xrst_literal\n   // BEGIN_PROTOTYPE_BASE\n   // END_PROTOTYPE_BASE\n}\n\nAD<Base>\n********\nThis syntax is used by *af* . ``Reverse`` where *af* has prototype\n\n   ``ADFun< AD<`` *Base* > , *Base* > *af*\n\nand *afun* is used in *af* (see :ref:`base2ad-name` ).\n\nSyntax\n======\n\n| *ok* = *afun* . ``reverse`` (\n| |tab| *aparameter_x* , *type_x* ,\n| |tab| *order_up* , *ataylor_x* , *ataylor_y* , *apartial_x* , *apartial_y*\n| )\n\nPrototype\n=========\n{xrst_literal\n   // BEGIN_PROTOTYPE_AD_BASE\n   // END_PROTOTYPE_AD_BASE\n}\n\nImplementation\n**************\nThis function must be defined if\n:ref:`atomic_three_ctor@atomic_user@afun` is\nused to define an :ref:`ADFun-name` object *f* ,\nand reverse mode derivatives are computed for *f* .\nIt can return *ok* == ``false``\n(and not compute anything) for values\nof *order_up* that are greater than those used by your\n:ref:`Reverse-name` mode calculations.\n\nparameter_x\n***********\nSee :ref:`atomic_three_define@parameter_x` .\n\naparameter_x\n************\nThe specifications for *aparameter_x*\nis the same as for :ref:`atomic_three_define@parameter_x`\n(only the type of *ataylor_x* is different).\n\ntype_x\n******\nSee :ref:`atomic_three_define@type_x` .\n\norder_up\n********\nThis argument specifies the highest order Taylor coefficient that\ncomputing the derivative of.\n\ntaylor_x\n********\nThe size of *taylor_x* is ( *q* +1)* *n* .\nFor :math:`j = 0 , \\ldots , n-1` and :math:`k = 0 , \\ldots , q`,\nwe use the Taylor coefficient notation\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      x_j^k    & = & \\R{taylor\\_x} [ j * ( q + 1 ) + k ]\n      \\\\\n      X_j (t)  & = & x_j^0 + x_j^1 t^1 + \\cdots + x_j^q t^q\n   \\end{eqnarray}\n\nNote that superscripts represent an index for :math:`x_j^k`\nand an exponent for :math:`t^k`.\nAlso note that the Taylor coefficients for :math:`X(t)` correspond\nto the derivatives of :math:`X(t)` at :math:`t = 0` in the following way:\n\n.. math::\n\n   x_j^k = \\frac{1}{ k ! } X_j^{(k)} (0)\n\nparameters\n==========\nIf the *j*-th component of *x* corresponds to a parameter,\n\n   *type_x* [ *j* ] < ``CppAD::variable_enum``\n\nIn this case,\nthe *j*-th component of *parameter_x* is equal to :math:`x_j^0`;\ni.e.,\n\n   *parameter_x* [ *j* ] == *taylor_x* [ *j* * ( *q*  + 1 ) + 0 ]\n\nFurthermore, for *k*  > 0 ,\n\n   *taylor_x* [ *j* * ( *q* + 1 ) + *k*  ] == 0\n\nataylor_x\n*********\nThe specifications for *ataylor_x* is the same as for *taylor_x*\n(only the type of *ataylor_x* is different).\n\ntaylor_y\n********\nThe size of *taylor_y* is ( *q* +1)* *m* .\nFor :math:`i = 0 , \\ldots , m-1` and :math:`k = 0 , \\ldots , q`,\nwe use the Taylor coefficient notation\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      Y_i (t)  & = & g_i [ X(t) ]\n      \\\\\n      Y_i (t)  & = & y_i^0 + y_i^1 t^1 + \\cdots + y_i^q t^q + o ( t^q )\n      \\\\\n      y_i^k    & = & \\R{taylor\\_y} [ i * ( q + 1 ) + k ]\n   \\end{eqnarray}\n\nwhere :math:`o( t^q ) / t^q \\rightarrow 0` as :math:`t \\rightarrow 0`.\nNote that superscripts represent an index for :math:`y_j^k`\nand an exponent for :math:`t^k`.\nAlso note that the Taylor coefficients for :math:`Y(t)` correspond\nto the derivatives of :math:`Y(t)` at :math:`t = 0` in the following way:\n\n.. math::\n\n   y_j^k = \\frac{1}{ k ! } Y_j^{(k)} (0)\n\nataylor_y\n*********\nThe specifications for *ataylor_y* is the same as for *taylor_y*\n(only the type of *ataylor_y* is different).\n\nF\n*\nWe use the notation :math:`\\{ x_j^k \\} \\in \\B{R}^{n \\times (q+1)}` for\n\n.. math::\n\n   \\{ x_j^k \\W{:} j = 0 , \\ldots , n-1, k = 0 , \\ldots , q \\}\n\nWe use the notation :math:`\\{ y_i^k \\} \\in \\B{R}^{m \\times (q+1)}` for\n\n.. math::\n\n   \\{ y_i^k \\W{:} i = 0 , \\ldots , m-1, k = 0 , \\ldots , q \\}\n\nWe define the function\n:math:`F : \\B{R}^{n \\times (q+1)} \\rightarrow \\B{R}^{m \\times (q+1)}` by\n\n.. math::\n\n   y_i^k = F_i^k [ \\{ x_j^k \\} ]\n\nNote that\n\n.. math::\n\n   F_i^0 ( \\{ x_j^k \\} ) = g_i ( X(0) )  = g_i ( x^0 )\n\nWe also note that\n:math:`F_i^\\ell ( \\{ x_j^k \\} )` is a function of\n:math:`x^0 , \\ldots , x^\\ell`\nand is determined by the derivatives of :math:`g_i (x)`\nup to order :math:`\\ell`.\n\nG, H\n****\nWe use :math:`G : \\B{R}^{m \\times (q+1)} \\rightarrow \\B{R}`\nto denote an arbitrary scalar valued function of :math:`\\{ y_i^k \\}`.\nWe use :math:`H : \\B{R}^{n \\times (q+1)} \\rightarrow \\B{R}`\ndefined by\n\n.. math::\n\n   H ( \\{ x_j^k \\} ) = G[ F( \\{ x_j^k \\} ) ]\n\npartial_y\n*********\nThe size of *partial_y* is ( *q* +1)* *m* .\nFor :math:`i = 0 , \\ldots , m-1`, :math:`k = 0 , \\ldots , q`,\n\n.. math::\n\n   \\R{partial\\_y} [ i * (q + 1 ) + k ] = \\partial G / \\partial y_i^k\n\napartial_y\n**********\nThe specifications for *apartial_y* is the same as for\n*partial_y* (only the type of *apartial_y* is different).\n\npartial_x\n*********\nThe size of *partial_x* is ( *q* +1)* *n* .\nThe input values of the elements of *partial_x*\nare not specified (must not matter).\nUpon return,\nfor :math:`j = 0 , \\ldots , n-1` and :math:`\\ell = 0 , \\ldots , q`,\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   \\R{partial\\_x} [ j * (q + 1) + \\ell ] & = & \\partial H / \\partial x_j^\\ell\n   \\\\\n   & = &\n   ( \\partial G / \\partial \\{ y_i^k \\} ) \\cdot\n      ( \\partial \\{ y_i^k \\} / \\partial x_j^\\ell )\n   \\\\\n   & = &\n   \\sum_{k=0}^q\n   \\sum_{i=0}^{m-1}\n   ( \\partial G / \\partial y_i^k ) ( \\partial y_i^k / \\partial x_j^\\ell )\n   \\\\\n   & = &\n   \\sum_{k=\\ell}^q\n   \\sum_{i=0}^{m-1}\n   \\R{partial\\_y}[ i * (q + 1 ) + k ] ( \\partial F_i^k / \\partial x_j^\\ell )\n   \\end{eqnarray}\n\nNote that we have used the fact that for :math:`k < \\ell`,\n:math:`\\partial F_i^k / \\partial x_j^\\ell = 0`.\n\nShort Circuit Operations\n========================\nFor the :ref:`atomic_three_reverse@Base` prototype, if\n``IdenticalZero`` ( *partial_y* [ *i* * ( *q* +1)+ *k* ]) is true,\none does not need to compute :math:`( \\partial F_i^k / \\partial x_j^\\ell )`;\nsee :ref:`base_identical-name` .\nThis can be used,\nin a similar way to :ref:`atomic_three_forward@need_y` ,\nto avoid unnecessary operations.\n\nazmul\n=====\nAn :ref:`optimized<optimize-name>` function will use zero\nfor values in *taylor_x* and *taylor_y* that are\nnot necessary in the current context.\nIf you divide by these values when computing\n:math:`( \\partial F_i^k / \\partial x_j^\\ell )` you could get an nan\nif the corresponding value in *partial_y* is zero.\nTo be careful, if you do divide by\n*taylor_x* or *taylor_y* , use :ref:`azmul-name`\nfor to avoid zero over zero calculations.\n\napartial_x\n**********\nThe specifications for *apartial_x* is the same as for\n*partial_x* (only the type of *apartial_x* is different).\n\nok\n**\nIf this calculation succeeded, *ok* is true.\nOtherwise it is false.\n{xrst_toc_hidden\n   example/atomic_three/reverse.cpp\n}\nExamples\n********\nThe file :ref:`atomic_three_reverse.cpp-name` contains an example and test\nthat uses this routine.\n\n{xrst_end atomic_three_reverse}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/three_reverse.hpp\nThird Generation Atomic reverse mode.\n*/\n/*!\nLink from reverse mode sweep to users routine.\n\n\\param parameter_x [in]\ncontains the values, in afun(ax, ay), for arguments that are parameters.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param order_up [in]\nhighest order for this reverse mode calculation.\n\n\\param taylor_x [in]\nTaylor coefficients corresponding to x for this calculation.\n\n\\param taylor_y [in]\nTaylor coefficient corresponding to y for this calculation\n\n\\param partial_x [out]\nPartials w.r.t. the x Taylor coefficients.\n\n\\param partial_y [in]\nPartials w.r.t. the y Taylor coefficients.\n\nSee atomic_three_reverse mode use documentation\n*/\n// BEGIN_PROTOTYPE_BASE\ntemplate <class Base>\nbool atomic_three<Base>::reverse(\n   const vector<Base>&         parameter_x ,\n   const vector<ad_type_enum>& type_x      ,\n   size_t                      order_up    ,\n   const vector<Base>&         taylor_x    ,\n   const vector<Base>&         taylor_y    ,\n   vector<Base>&               partial_x   ,\n   const vector<Base>&         partial_y   )\n// END_PROTOTYPE_BASE\n{  return false; }\n\n/*!\nLink from reverse mode sweep to users routine.\n\n\\param aparameter_x [in]\ncontains the values, in afun(ax, ay), for arguments that are parameters.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\n\\param order_up [in]\nhighest order for this reverse mode calculation.\n\n\\param ataylor_x [in]\nTaylor coefficients corresponding to x for this calculation.\n\n\\param ataylor_y [in]\nTaylor coefficient corresponding to y for this calculation\n\n\\param apartial_x [out]\nPartials w.r.t. the x Taylor coefficients.\n\n\\param apartial_y [in]\nPartials w.r.t. the y Taylor coefficients.\n\nSee atomic_three_reverse mode use documentation\n*/\n// BEGIN_PROTOTYPE_AD_BASE\ntemplate <class Base>\nbool atomic_three<Base>::reverse(\n   const vector< AD<Base> >&       aparameter_x ,\n   const vector<ad_type_enum>&     type_x       ,\n   size_t                          order_up     ,\n   const vector< AD<Base> >&       ataylor_x    ,\n   const vector< AD<Base> >&       ataylor_y    ,\n   vector< AD<Base> >&             apartial_x   ,\n   const vector< AD<Base> >&       apartial_y   )\n// END_PROTOTYPE_AD_BASE\n{  return false; }\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/two/afun.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_TWO_AFUN_HPP\n# define CPPAD_CORE_ATOMIC_TWO_AFUN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_two_afun app}\n\nUsing AD Version of Atomic Function\n###################################\n\nSyntax\n******\n| *afun* ( *ax* , *ay* )\n\nPurpose\n*******\nGiven *ax* ,\nthis call computes the corresponding value of *ay* .\nIf ``AD`` < *Base* > operations are being recorded,\nit enters the computation as an atomic operation in the recording;\nsee :ref:`Independent@Start Recording` .\n\nADVector\n********\nThe type *ADVector* must be a\n:ref:`simple vector class<SimpleVector-name>` with elements of type\n``AD`` < *Base* > ; see :ref:`atomic_two_ctor@atomic_base@Base` .\n\nafun\n****\nis a :ref:`atomic_two_ctor@atomic_user` object\nand this *afun* function call is implemented by the\n:ref:`atomic<atomic_two_ctor@atomic_base>` class.\n\nax\n**\nThis argument has prototype\n\n   ``const`` *ADVector* & *ax*\n\nand size must be equal to *n* .\nIt specifies vector :math:`x \\in \\B{R}^n`\nat which an ``AD`` < *Base* > version of\n:math:`y = f(x)` is to be evaluated; see\n:ref:`atomic_two_ctor@atomic_base@Base` .\n\nay\n**\nThis argument has prototype\n\n   *ADVector* & *ay*\n\nand size must be equal to *m* .\nThe input values of its elements\nare not specified (must not matter).\nUpon return, it is an ``AD`` < *Base* > version of\n:math:`y = f(x)`.\n\n{xrst_end atomic_two_afun}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/two_afun.hpp\nImplement user call to an atomic_two function.\n*/\n\n/*!\nImplement the user call to afun(ax, ay) and atomic_one call to\nafun(ax, ay, id).\n\n\\tparam ADVector\nA simple vector class with elements of type <code>AD<Base></code>.\n\n\\param id\noptional extra information vector that is just passed through by CppAD,\nand used by atomic_one derived class (not other derived classes).\nThis is an extra parameter to the virtual callbacks for atomic_one;\nsee the set_old member function.\n\n\\param ax\nis the argument vector for this call,\n<tt>ax.size()</tt> determines the number of arguments.\n\n\\param ay\nis the result vector for this call,\n<tt>ay.size()</tt> determines the number of results.\n*/\ntemplate <class Base>\ntemplate <class ADVector>\nvoid atomic_base<Base>::operator()(\n   const ADVector&  ax     ,\n          ADVector&  ay     ,\n   size_t           id     )\n{  size_t i, j;\n   size_t n = ax.size();\n   size_t m = ay.size();\n# ifndef NDEBUG\n   bool ok;\n   std::string msg = \"atomic_base: \" + atomic_name() + \".eval: \";\n   if( (n == 0) || (m == 0) )\n   {  msg += \"ax.size() or ay.size() is zero\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# endif\n   size_t thread = thread_alloc::thread_num();\n   allocate_work(thread);\n   vector <Base>& tx  = work_[thread]->tx;\n   vector <Base>& ty  = work_[thread]->ty;\n   vector <bool>& vx  = work_[thread]->vx;\n   vector <bool>& vy  = work_[thread]->vy;\n   //\n   if( vx.size() != n )\n   {  vx.resize(n);\n      tx.resize(n);\n   }\n   if( vy.size() != m )\n   {  vy.resize(m);\n      ty.resize(m);\n   }\n   //\n   // Determine tape corresponding to variables in ax\n   tape_id_t            tape_id  = 0;\n   local::ADTape<Base>* tape     = nullptr;\n   for(j = 0; j < n; j++)\n   {  tx[j]  = ax[j].value_;\n      vx[j]  = ! Constant( ax[j] );\n      if( vx[j] )\n      {\n         if( tape_id == 0 )\n         {  tape    = ax[j].tape_this();\n            tape_id = ax[j].tape_id_;\n            CPPAD_ASSERT_UNKNOWN( tape != nullptr );\n         }\n# ifndef NDEBUG\n         if( tape_id != ax[j].tape_id_ )\n         {  msg += atomic_name() +\n            \": ax contains variables from different threads.\";\n            CPPAD_ASSERT_KNOWN(false, msg.c_str());\n         }\n# endif\n      }\n   }\n   // Use zero order forward mode to compute values\n   size_t p = 0, q = 0;\n   set_old(id);\n# ifdef NDEBUG\n   forward(p, q, vx, vy, tx, ty);\n# else\n   ok = forward(p, q, vx, vy, tx, ty);\n   if( ! ok )\n   {  msg += atomic_name() + \": ok is false for \"\n         \"zero order forward mode calculation.\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str());\n   }\n# endif\n   bool record_operation = false;\n   for(i = 0; i < m; i++)\n   {\n      // pass back values\n      ay[i].value_ = ty[i];\n\n      // initialize entire vector parameters (not in tape)\n      ay[i].tape_id_ = 0;\n      ay[i].taddr_   = 0;\n\n      // we need to record this operation if\n      // any of the elements of ay are variables,\n      record_operation |= vy[i];\n   }\n# ifndef NDEBUG\n   if( record_operation & (tape == nullptr) )\n   {  msg +=\n      \"all elements of vx are false but vy contains a true element\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# endif\n   // if tape is not null, ay is on the tape\n   if( record_operation )\n   {\n      // Operator that marks beginning of this atomic operation\n      CPPAD_ASSERT_UNKNOWN( local::NumRes(local::AFunOp) == 0 );\n      CPPAD_ASSERT_UNKNOWN( local::NumArg(local::AFunOp) == 4 );\n      CPPAD_ASSERT_KNOWN(\n         size_t( std::numeric_limits<addr_t>::max() ) >=\n         std::max( std::max( std::max(index_, id), n), m ),\n         \"atomic_base: cppad_tape_addr_type maximum not large enough\"\n      );\n      tape->Rec_.PutArg(addr_t(index_), addr_t(id), addr_t(n), addr_t(m));\n      tape->Rec_.PutOp(local::AFunOp);\n\n      // Now put n operators, one for each element of argument vector\n      CPPAD_ASSERT_UNKNOWN( local::NumRes(local::FunavOp) == 0 );\n      CPPAD_ASSERT_UNKNOWN( local::NumRes(local::FunapOp) == 0 );\n      CPPAD_ASSERT_UNKNOWN( local::NumArg(local::FunavOp) == 1 );\n      CPPAD_ASSERT_UNKNOWN( local::NumArg(local::FunapOp) == 1 );\n      for(j = 0; j < n; j++)\n      {  if( Variable(ax[j]) )\n         {  // information for an argument that is a variable\n            tape->Rec_.PutArg(ax[j].taddr_);\n            tape->Rec_.PutOp(local::FunavOp);\n         }\n         else\n         {  // information for an argument that is parameter\n            addr_t par = ax[j].taddr_;\n            if( ! Dynamic( ax[j] ) )\n               par = tape->Rec_.put_con_par(ax[j].value_);\n            tape->Rec_.PutArg(par);\n            tape->Rec_.PutOp(local::FunapOp);\n         }\n      }\n\n      // Now put m operators, one for each element of result vector\n      CPPAD_ASSERT_UNKNOWN( local::NumArg(local::FunrpOp) == 1 );\n      CPPAD_ASSERT_UNKNOWN( local::NumRes(local::FunrpOp) == 0 );\n      CPPAD_ASSERT_UNKNOWN( local::NumArg(local::FunrvOp) == 0 );\n      CPPAD_ASSERT_UNKNOWN( local::NumRes(local::FunrvOp) == 1 );\n      for(i = 0; i < m; i++)\n      {  if( vy[i] )\n         {  ay[i].taddr_    = tape->Rec_.PutOp(local::FunrvOp);\n            ay[i].tape_id_  = tape_id;\n            ay[i].ad_type_  = variable_enum;\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( ! Dynamic( ay[i] ) );\n            addr_t par = tape->Rec_.put_con_par(ay[i].value_);\n            tape->Rec_.PutArg(par);\n            tape->Rec_.PutOp(local::FunrpOp);\n         }\n      }\n\n      // Put a duplicate AFunOp at end of AFunOp sequence\n      CPPAD_ASSERT_KNOWN(\n         size_t( std::numeric_limits<addr_t>::max() ) >=\n         std::max( std::max( std::max(index_, id), n), m ),\n         \"atomic_base: cppad_tape_addr_type maximum not large enough\"\n      );\n      tape->Rec_.PutArg(addr_t(index_), addr_t(id), addr_t(n), addr_t(m));\n      tape->Rec_.PutOp(local::AFunOp);\n   }\n   return;\n}\n\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/two/atomic.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_TWO_ATOMIC_HPP\n# define CPPAD_CORE_ATOMIC_TWO_ATOMIC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_two app}\n{xrst_spell\n   ctor\n   px\n   py\n   tx\n   vx\n   vy\n}\n\nDefining Atomic Functions: Second Generation\n############################################\n\nDeprecated 2019-01-01\n*********************\nUsing the ``atomic_base`` class has been deprecated.\nUse :ref:`atomic_three-name` instead.\n\nSyntax\n******\n| *atomic_user* *afun* ( *ctor_arg_list* )\n| *afun* ( *ax* , *ay* )\n| *ok* = *afun* . ``forward`` ( *p* , *q* , *vx* , *vy* , *tx* , *ty* )\n| *ok* = *afun* . ``reverse`` ( *q* , *tx* , *ty* , *px* , *py* )\n| *ok* = *afun* . ``for_sparse_jac`` ( *q* , *r* , *s* , *x* )\n| *ok* = *afun* . ``rev_sparse_jac`` ( *q* , *r* , *s* , *x* )\n| *ok* = *afun* . ``for_sparse_hes`` ( *vx* , *r* , *s* , *h* , *x* )\n| *ok* = *afun* . ``rev_sparse_hes`` ( *vx* , *s* , *t* , *q* , *r* , *u* , *v* , *x* )\n| *atomic_base* < ``Base`` >:: *clear* ()\n\nSee Also\n********\n:ref:`checkpoint<chkpoint_one-name>`\n\nPurpose\n*******\n\nSpeed\n=====\nIn some cases, the user knows how to compute derivatives of a function\n\n.. math::\n\n   y = f(x) \\; {\\rm where} \\; f : \\B{R}^n \\rightarrow \\B{R}^m\n\nmore efficiently than by coding it using ``AD`` < *Base* >\n:ref:`atomic_base<glossary@Operation@Atomic>` operations\nand letting CppAD do the rest.\nIn this case ``atomic_base`` < ``Base`` > can use\nthe user code for :math:`f(x)`, and its derivatives,\nas ``AD`` < *Base* > atomic operations.\n\nReduce Memory\n=============\nIf the function :math:`f(x)` is used often,\nusing an atomic version of :math:`f(x)` remove the need for repeated\ncopies of the corresponding ``AD`` < *Base* > operations.\n\nVirtual Functions\n*****************\nUser defined derivatives are implemented by defining the\nfollowing virtual functions in the *atomic_base* class:\n:ref:`forward<atomic_two_forward-name>` ,\n:ref:`reverse<atomic_two_reverse-name>` ,\n:ref:`for_sparse_jac<atomic_two_for_sparse_jac-name>` ,\n:ref:`rev_sparse_jac<atomic_two_rev_sparse_jac-name>` , and\n:ref:`rev_sparse_hes<atomic_two_rev_sparse_hes-name>` .\nThese virtual functions have a default implementation\nthat returns *ok* == ``false`` .\nThe ``forward`` function,\nfor the case *q*  == 0 , must be implemented.\nOtherwise, only those functions\nrequired by the your calculations need to be implemented.\nFor example,\n*forward* for the case *q*  == 2 can just return\n*ok* == ``false`` unless you require\nforward mode calculation of second derivatives.\n\nExamples\n********\nSee :ref:`atomic_two_example-name` .\n\nContents\n********\n{xrst_toc_table\n   include/cppad/core/atomic/two/ctor.hpp\n   include/cppad/core/atomic/two/option.hpp\n   include/cppad/core/atomic/two/afun.hpp\n   include/cppad/core/atomic/two/forward.hpp\n   include/cppad/core/atomic/two/reverse.hpp\n   include/cppad/core/atomic/two/for_sparse_jac.hpp\n   include/cppad/core/atomic/two/rev_sparse_jac.hpp\n   include/cppad/core/atomic/two/for_sparse_hes.hpp\n   include/cppad/core/atomic/two/rev_sparse_hes.hpp\n   include/cppad/core/atomic/two/clear.hpp\n}\n\n{xrst_end atomic_two}\n-------------------------------------------------------------------------------\n{xrst_begin atomic_two_example app}\n\nExample Defining Atomic Functions: Second Generation\n####################################################\n\nGetting Started\n***************\nthat shows the minimal amount of information required to create\na user defined atomic operation.\n\nScalar Function\n***************\nwhere the user provides the code for computing derivatives.\nThis example is simple because the domain and range are scalars.\n\nVector Range\n************\nwhere the user provides the code for computing derivatives.\nThis example is more complex because the range has two components.\n\nHessian Sparsity Patterns\n*************************\nwhere the user provides the code for computing Hessian sparsity patterns.\n\nContents\n********\n{xrst_toc_table\n   example/atomic_two/eigen_mat_mul.cpp\n   example/atomic_two/eigen_mat_inv.cpp\n   example/atomic_two/eigen_cholesky.cpp\n}\n\n{xrst_end atomic_two_example}\n-------------------------------------------------------------------------------\n*/\n\n# include <set>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/local/sparse/internal.hpp>\n# include <cppad/local/atomic_index.hpp>\n# include <cppad/core/ad.hpp>\n\n// needed before one can use in_parallel\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic_two.hpp\nBase class for atomic function operations.\n*/\n\ntemplate <class Base>\nclass atomic_base {\n// ===================================================================\npublic:\n   enum option_enum {\n      pack_sparsity_enum   ,\n      bool_sparsity_enum   ,\n      set_sparsity_enum\n   };\n   //\n   // atomic_index\n   size_t atomic_index(void) const\n   { return index_; }\nprivate:\n   // ------------------------------------------------------\n   // constants\n   //\n   /// index of this object in local::atomic_index\n   /// (set by constructor and not changed; i.e., effectively const)\n   size_t index_;\n   //\n   // -----------------------------------------------------\n   // variables\n   //\n   /// sparsity pattern this object is currently using\n   /// (set by constructor and option member functions)\n   option_enum sparsity_;\n   //\n   /// temporary work space used by member functions, declared here to avoid\n   // memory allocation/deallocation for each usage\n   struct work_struct {\n      vector<bool>               vx;\n      vector<bool>               vy;\n      //\n      vector<Base>               tx;\n      vector<Base>               ty;\n      //\n      vector< AD<Base> >         atx;\n      vector< AD<Base> >         aty;\n      //\n      vector<bool>               bool_t;\n      //\n      vectorBool                 pack_h;\n      vectorBool                 pack_r;\n      vectorBool                 pack_s;\n      vectorBool                 pack_u;\n      //\n      vector<bool>               bool_h;\n      vector<bool>               bool_r;\n      vector<bool>               bool_s;\n      vector<bool>               bool_u;\n      //\n      vector< std::set<size_t> > set_h;\n      vector< std::set<size_t> > set_r;\n      vector< std::set<size_t> > set_s;\n      vector< std::set<size_t> > set_u;\n   };\n   // Use pointers, to avoid false sharing between threads.\n   // Not using: vector<work_struct*> work_;\n   // so that deprecated atomic examples do not result in a memory leak.\n   work_struct* work_[CPPAD_MAX_NUM_THREADS];\npublic:\n   // =====================================================================\n   // In User API\n   // =====================================================================\n   //\n   // ---------------------------------------------------------------------\n   // ctor: doxygen in atomic_base/ctor.hpp\n   atomic_base(void);\n   atomic_base(\n      const std::string&     name,\n      option_enum            sparsity = bool_sparsity_enum\n   );\n\n   // option: see doxygen in atomic_base/option.hpp\n   void option(enum option_enum option_value);\n\n   // operator(): see doxygen in atomic_base/afun.hpp\n   template <class ADVector>\n   void operator()(\n      const ADVector&  ax     ,\n              ADVector&  ay     ,\n      size_t           id = 0\n   );\n\n   // ------------------------------------------------------------------------\n   // base_two version of forward\n   virtual bool forward(\n      size_t                    p  ,\n      size_t                    q  ,\n      const vector<bool>&       vx ,\n      vector<bool>&             vy ,\n      const vector<Base>&       tx ,\n      vector<Base>&             ty\n   );\n   virtual bool forward(\n      size_t                    p  ,\n      size_t                    q  ,\n      const vector<bool>&       vx ,\n      vector<bool>&             vy ,\n      const vector< AD<Base> >& atx ,\n      vector< AD<Base> >&       aty\n   );\n   // base_three version of forward\n   bool forward(\n      size_t                       order_low  ,\n      size_t                       order_up   ,\n      const vector<ad_type_enum>&  type_x     ,\n      vector<ad_type_enum>&        type_y     ,\n      const vector<Base>&          taylor_x   ,\n      vector<Base>&                taylor_y\n   );\n   bool forward(\n      size_t                       order_low  ,\n      size_t                       order_up   ,\n      const vector<ad_type_enum>&  type_x     ,\n      vector<ad_type_enum>&        type_y     ,\n      const vector< AD<Base> >&    ataylor_x  ,\n      vector< AD<Base> >&          ataylor_y\n   );\n   // ------------------------------------------------------------------------\n   // reverse: see doxygen in atomic_base/reverse.hpp\n   virtual bool reverse(\n      size_t                    q  ,\n      const vector<Base>&       tx ,\n      const vector<Base>&       ty ,\n              vector<Base>&       px ,\n      const vector<Base>&       py\n   );\n   virtual bool reverse(\n      size_t                    q   ,\n      const vector< AD<Base> >& atx ,\n      const vector< AD<Base> >& aty ,\n              vector< AD<Base> >& apx ,\n      const vector< AD<Base> >& apy\n   );\n\n   // ------------------------------------------------------------\n   // for_sparse_jac: see doxygen in atomic_base/for_sparse_jac.hpp\n   virtual bool for_sparse_jac(\n      size_t                                  q  ,\n      const vector< std::set<size_t> >&       r  ,\n              vector< std::set<size_t> >&       s  ,\n      const vector<Base>&                     x\n   );\n   virtual bool for_sparse_jac(\n      size_t                                  q  ,\n      const vector<bool>&                     r  ,\n              vector<bool>&                     s  ,\n      const vector<Base>&                     x\n   );\n   virtual bool for_sparse_jac(\n      size_t                                  q  ,\n      const vectorBool&                       r  ,\n              vectorBool&                       s  ,\n      const vector<Base>&                     x\n   );\n   template <class InternalSparsity>\n   bool for_sparse_jac(\n      const vector<Base>&              x            ,\n      const vector<size_t>&            x_index      ,\n      const vector<size_t>&            y_index      ,\n      InternalSparsity&                var_sparsity\n   );\n   // deprecated versions\n   virtual bool for_sparse_jac(\n      size_t                                  q  ,\n      const vector< std::set<size_t> >&       r  ,\n              vector< std::set<size_t> >&       s\n   );\n   virtual bool for_sparse_jac(\n      size_t                                  q  ,\n      const vector<bool>&                     r  ,\n              vector<bool>&                     s\n   );\n   virtual bool for_sparse_jac(\n      size_t                                  q  ,\n      const vectorBool&                       r  ,\n              vectorBool&                       s\n   );\n   // ------------------------------------------------------------\n   // rev_sparse_jac: see doxygen in atomic_base/rev_sparse_jac.hpp\n   virtual bool rev_sparse_jac(\n      size_t                                  q  ,\n      const vector< std::set<size_t> >&       rt ,\n              vector< std::set<size_t> >&       st ,\n      const vector<Base>&                     x\n   );\n   virtual bool rev_sparse_jac(\n      size_t                                  q  ,\n      const vector<bool>&                     rt ,\n              vector<bool>&                     st ,\n      const vector<Base>&                     x\n   );\n   virtual bool rev_sparse_jac(\n      size_t                                  q  ,\n      const vectorBool&                       rt ,\n              vectorBool&                       st ,\n      const vector<Base>&                     x\n   );\n   template <class InternalSparsity>\n   bool rev_sparse_jac(\n      const vector<Base>&        x            ,\n      const vector<size_t>&            x_index ,\n      const vector<size_t>&            y_index ,\n      InternalSparsity&          var_sparsity\n   );\n   // deprecated versions\n   virtual bool rev_sparse_jac(\n      size_t                                  q  ,\n      const vector< std::set<size_t> >&       rt ,\n              vector< std::set<size_t> >&       st\n   );\n   virtual bool rev_sparse_jac(\n      size_t                                  q  ,\n      const vector<bool>&                     rt ,\n              vector<bool>&                     st\n   );\n   virtual bool rev_sparse_jac(\n      size_t                                  q  ,\n      const vectorBool&                       rt ,\n              vectorBool&                       st\n   );\n   // ------------------------------------------------------------\n   // for_sparse_hes: see doxygen in atomic_base/for_sparse_hes.hpp\n   virtual bool for_sparse_hes(\n      const vector<bool>&             vx ,\n      const vector<bool>&             r  ,\n      const vector<bool>&             s  ,\n      vector< std::set<size_t> >&     h  ,\n      const vector<Base>&             x\n   );\n   virtual bool for_sparse_hes(\n      const vector<bool>&             vx ,\n      const vector<bool>&             r  ,\n      const vector<bool>&             s  ,\n      vector<bool>&                   h  ,\n      const vector<Base>&             x\n   );\n   virtual bool for_sparse_hes(\n      const vector<bool>&             vx ,\n      const vector<bool>&             r  ,\n      const vector<bool>&             s  ,\n      vectorBool&                     h  ,\n      const vector<Base>&             x\n   );\n   template <class InternalSparsity>\n   bool for_sparse_hes(\n      const vector<Base>&              x                ,\n      const vector<size_t>&            x_index          ,\n      const vector<size_t>&            y_index          ,\n      size_t                           np1              ,\n      size_t                           numvar           ,\n      const InternalSparsity&          rev_jac_sparsity ,\n      InternalSparsity&                for_sparsity\n   );\n   // deprecated versions\n   virtual bool for_sparse_hes(\n      const vector<bool>&             vx ,\n      const vector<bool>&             r  ,\n      const vector<bool>&             s  ,\n      vector< std::set<size_t> >&     h\n   );\n   virtual bool for_sparse_hes(\n      const vector<bool>&             vx ,\n      const vector<bool>&             r  ,\n      const vector<bool>&             s  ,\n      vector<bool>&                   h\n   );\n   virtual bool for_sparse_hes(\n      const vector<bool>&             vx ,\n      const vector<bool>&             r  ,\n      const vector<bool>&             s  ,\n      vectorBool&                     h\n   );\n   // ------------------------------------------------------------\n   // rev_sparse_hes: see doxygen in atomic_base/rev_sparse_hes.hpp\n   virtual bool rev_sparse_hes(\n      const vector<bool>&                     vx ,\n      const vector<bool>&                     s  ,\n              vector<bool>&                     t  ,\n      size_t                                  q  ,\n      const vector< std::set<size_t> >&       r  ,\n      const vector< std::set<size_t> >&       u  ,\n              vector< std::set<size_t> >&       v  ,\n      const vector<Base>&                     x\n   );\n   virtual bool rev_sparse_hes(\n      const vector<bool>&                     vx ,\n      const vector<bool>&                     s  ,\n              vector<bool>&                     t  ,\n      size_t                                  q  ,\n      const vector<bool>&                     r  ,\n      const vector<bool>&                     u  ,\n              vector<bool>&                     v  ,\n      const vector<Base>&                     x\n   );\n   virtual bool rev_sparse_hes(\n      const vector<bool>&                     vx ,\n      const vector<bool>&                     s  ,\n              vector<bool>&                     t  ,\n      size_t                                  q  ,\n      const vectorBool&                       r  ,\n      const vectorBool&                       u  ,\n              vectorBool&                       v  ,\n      const vector<Base>&                     x\n   );\n   template <class InternalSparsity>\n   bool rev_sparse_hes(\n      const vector<Base>&              x                ,\n      const vector<size_t>&            x_index          ,\n      const vector<size_t>&            y_index          ,\n      const InternalSparsity&          for_jac_sparsity ,\n      bool*                            rev_jac_flag     ,\n      InternalSparsity&                rev_hes_sparsity\n   );\n   // deprecated\n   virtual bool rev_sparse_hes(\n      const vector<bool>&                     vx ,\n      const vector<bool>&                     s  ,\n              vector<bool>&                     t  ,\n      size_t                                  q  ,\n      const vector< std::set<size_t> >&       r  ,\n      const vector< std::set<size_t> >&       u  ,\n              vector< std::set<size_t> >&       v\n   );\n   virtual bool rev_sparse_hes(\n      const vector<bool>&                     vx ,\n      const vector<bool>&                     s  ,\n              vector<bool>&                     t  ,\n      size_t                                  q  ,\n      const vector<bool>&                     r  ,\n      const vector<bool>&                     u  ,\n              vector<bool>&                     v\n   );\n   virtual bool rev_sparse_hes(\n      const vector<bool>&                     vx ,\n      const vector<bool>&                     s  ,\n              vector<bool>&                     t  ,\n      size_t                                  q  ,\n      const vectorBool&                       r  ,\n      const vectorBool&                       u  ,\n              vectorBool&                       v\n   );\n   // ------------------------------------------------------------\n   // atomic_three like interface for reverse dependency analysis\n   bool rev_depend(\n      const vector<Base>&         parameter_x ,\n      const vector<ad_type_enum>& type_x      ,\n      vector<bool>&               depend_x    ,\n      const vector<bool>&         depend_y\n   );\n   // ------------------------------------------------------------\n   // clear: see doxygen in atomic_base/clear.hpp\n   static void clear(void);\n\n   // =====================================================================\n   // Not in User API\n   // =====================================================================\n\n   /// current sparsity setting\n   option_enum sparsity(void) const\n   {  return sparsity_; }\n\n   /// Name corresponding to a atomic_base object\n   const std::string atomic_name(void) const\n   {  bool        set_null = false;\n      size_t      type  = 0;          // set to avoid warning\n      std::string name;\n      void*       v_ptr = nullptr; // set to avoid warning\n      local::atomic_index<Base>(set_null, index_, type, &name, v_ptr);\n      CPPAD_ASSERT_UNKNOWN( type == 2 );\n      return name;\n   }\n   /// destructor informs CppAD that this atomic function with this index\n   /// has dropped out of scope by setting its pointer to null\n   virtual ~atomic_base(void)\n   {  // change object pointer to null, but leave name for error reporting\n      bool         set_null = true;\n      size_t       type  = 0;          // set to avoid warning\n      std::string* name  = nullptr;\n      void*        v_ptr = nullptr; // set to avoid warning\n      local::atomic_index<Base>(set_null, index_, type, name, v_ptr);\n      CPPAD_ASSERT_UNKNOWN( type == 2 );\n      //\n      // free temporary work memory\n      for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++)\n         free_work(thread);\n   }\n   /// allocates work_ for a specified thread\n   void allocate_work(size_t thread)\n   {  if( work_[thread] == nullptr )\n      {  // allocate the raw memory\n         size_t min_bytes = sizeof(work_struct);\n         size_t num_bytes;\n         void*  v_ptr     = thread_alloc::get_memory(min_bytes, num_bytes);\n         // save in work_\n         work_[thread]    = reinterpret_cast<work_struct*>( v_ptr );\n         // call constructor\n         new( work_[thread] ) work_struct;\n      }\n      return;\n   }\n   /// frees work_ for a specified thread\n   void free_work(size_t thread)\n   {  if( work_[thread] != nullptr )\n      {  // call destructor\n         work_[thread]->~work_struct();\n         // return memory to available pool for this thread\n         thread_alloc::return_memory(\n            reinterpret_cast<void*>(work_[thread])\n         );\n         // mark this thread as not allocated\n         work_[thread] = nullptr;\n      }\n      return;\n   }\n   /// atomic_base function object corresponding to a certain index\n   static atomic_base* class_object(size_t index)\n   {  bool         set_null = false;\n      size_t       type  = 0;          // set to avoid warning\n      std::string* name  = nullptr;\n      void*        v_ptr = nullptr; // set to avoid warning\n      local::atomic_index<Base>(set_null, index, type, name, v_ptr);\n      CPPAD_ASSERT_UNKNOWN( type == 2 );\n      return reinterpret_cast<atomic_base*>( v_ptr );\n   }\n   /// atomic_base function name corresponding to a certain index\n   static const std::string class_name(size_t index)\n   {  bool        set_null = false;\n      size_t      type  = 0;          // set to avoid warning\n      std::string name;\n      void*       v_ptr = nullptr; // set to avoid warning\n      local::atomic_index<Base>(set_null, index, type, &name, v_ptr);\n      CPPAD_ASSERT_UNKNOWN( type == 2 );\n      return name;\n   }\n\n   /*!\n   Set value of id (used by deprecated atomic_one class)\n\n   This function is called just before calling any of the virtual function\n   and has the corresponding id of the corresponding virtual call.\n   */\n   virtual void set_old(size_t id)\n   { }\n// ---------------------------------------------------------------------------\n};\n} // END_CPPAD_NAMESPACE\n\n// functions implemented in cppad/core/atomic_base files\n# include <cppad/core/atomic/two/ctor.hpp>\n# include <cppad/core/atomic/two/option.hpp>\n# include <cppad/core/atomic/two/afun.hpp>\n# include <cppad/core/atomic/two/forward.hpp>\n# include <cppad/core/atomic/two/reverse.hpp>\n# include <cppad/core/atomic/two/for_sparse_jac.hpp>\n# include <cppad/core/atomic/two/rev_sparse_jac.hpp>\n# include <cppad/core/atomic/two/for_sparse_hes.hpp>\n# include <cppad/core/atomic/two/rev_sparse_hes.hpp>\n# include <cppad/core/atomic/two/rev_depend.hpp>\n# include <cppad/core/atomic/two/clear.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/two/clear.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_TWO_CLEAR_HPP\n# define CPPAD_CORE_ATOMIC_TWO_CLEAR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_two_clear app}\n\nFree Static Variables\n#####################\n\nSyntax\n******\n| ``atomic_base`` < *Base* >:: ``clear`` ()\n\nPurpose\n*******\nEach ``atomic_base`` objects holds onto work space in order to\navoid repeated memory allocation calls and thereby increase speed\n(until it is deleted).\nIf an the ``atomic_base`` object is global or static because,\nthe it does not get deleted.\nThis is a problem when using\n``thread_alloc`` :ref:`free_all<ta_free_all-name>`\nto check that all allocated memory has been freed.\nCalling this ``clear`` function will free all the\nmemory currently being held onto by the\n``atomic_base`` < *Base* > class.\n\nFuture Use\n**********\nIf there is future use of an ``atomic_base`` object,\nafter a call to ``clear`` ,\nthe work space will be reallocated and held onto.\n\nRestriction\n***********\nThis routine cannot be called\nwhile in :ref:`parallel<ta_in_parallel-name>` execution mode.\n\n{xrst_end atomic_two_clear}\n------------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/two_clear.hpp\nFree static variables in atomic_base class.\n*/\n/*!\nFree all thread_alloc static memory held by atomic_base (avoids reallocations).\n(This does not include class_object() which is an std::vector.)\n*/\ntemplate <class Base>\nvoid atomic_base<Base>::clear(void)\n{  CPPAD_ASSERT_KNOWN(\n      ! thread_alloc::in_parallel() ,\n      \"cannot use atomic_base clear during parallel execution\"\n   );\n   bool         set_null = true;\n   size_t       index  = 0;\n   size_t       type  = 0;          // set to avoid warning\n   std::string* name  = nullptr;\n   void*        v_ptr = nullptr; // set to avoid warning\n   size_t       n_atomic = local::atomic_index<Base>(\n      set_null, index, type, name, v_ptr\n   );\n   //\n   set_null = false;\n   for(index = 1; index <= n_atomic; ++index)\n   {  local::atomic_index<Base>(set_null, index, type, name, v_ptr);\n      if( type == 2 )\n      {  atomic_base* op = reinterpret_cast<atomic_base*>(v_ptr);\n         if( op != nullptr )\n         {  for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++)\n               op->free_work(thread);\n         }\n      }\n   }\n   return;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/two/ctor.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_TWO_CTOR_HPP\n# define CPPAD_CORE_ATOMIC_TWO_CTOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_two_ctor app}\n\nAtomic Function Constructor\n###########################\n\nSyntax\n******\n| *atomic_user afun* ( *ctor_arg_list* )\n| ``atomic_base`` < *Base* >( *name* , *sparsity* )\n\natomic_user\n***********\n\nctor_arg_list\n=============\nIs a list of arguments for the *atomic_user* constructor.\n\nafun\n====\nThe object *afun* must stay in scope for as long\nas the corresponding atomic function is used.\nThis includes use by any :ref:`ADFun\\<Base><ADFun-name>` that\nhas this *atomic_user* operation in its\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nImplementation\n==============\nThe user defined *atomic_user* class is a publicly derived class of\n``atomic_base`` < *Base* > .\nIt should be declared as follows:\n\n| |tab| ``class`` *atomic_user* : ``public CppAD::atomic_base<`` *Base* > {\n| |tab| ``public:``\n| |tab| |tab| *atomic_user* ( *ctor_arg_list* ) : ``atomic_base`` < *Base* >( *name* , *sparsity* )\n| |tab| ...\n| |tab| };\n\nwhere ...\ndenotes the rest of the implementation of the derived class.\nThis includes completing the constructor and\nall the virtual functions that have their\n``atomic_base`` implementations replaced by\n*atomic_user* implementations.\n\natomic_base\n***********\n\nRestrictions\n============\nThe ``atomic_base`` constructor and destructor cannot be called in\n:ref:`parallel<ta_in_parallel-name>` mode.\n\nBase\n====\nThe template parameter determines the\n*Base* type for this ``AD`` < *Base* > atomic operation.\n\nname\n====\nThis ``atomic_base`` constructor argument has the following prototype\n\n   ``const std::string&`` *name*\n\nIt is the name for this atomic function and is used for error reporting.\nThe suggested value for *name* is *afun* or *atomic_user* ,\ni.e., the name of the corresponding atomic object or class.\n\nsparsity\n========\nThis ``atomic_base`` constructor argument has prototype\n\n   ``atomic_base`` < *Base* >:: ``option_enum`` *sparsity*\n\nThe current *sparsity* for an ``atomic_base`` object\ndetermines which type of sparsity patterns it uses\nand its value is one of the following:\n\n.. list-table::\n   :widths: auto\n\n   * - *sparsity*\n     - sparsity patterns\n   * - ``atomic_base`` < *Base* >:: ``pack_sparsity_enum``\n     - :ref:`CppAD_vector@vectorBool`\n   * - ``atomic_base`` < *Base* >:: ``bool_sparsity_enum``\n     - :ref:`vector<CppAD_vector-name>` ``<bool>``\n   * - ``atomic_base`` < *Base* >:: ``set_sparsity_enum``\n     - :ref:`vector<CppAD_vector-name>` ``<std::set<std::size_t> >``\n\nThere is a default value for *sparsity* if it is not\nincluded in the constructor (which may be either the bool or set option).\n\n{xrst_end atomic_two_ctor}\n-------------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/two_ctor.hpp\nConstructors for atomic_base class.\n*/\n\n/*!\nBase class for atomic_atomic functions.\n\n\\tparam Base\nThis class is used for defining an AD<Base> atomic operation y = f(x).\n\n\\par\nmake sure user does not invoke the default constructor\n*/\ntemplate <class Base>\natomic_base<Base>::atomic_base(void)\n{  CPPAD_ASSERT_KNOWN(false,\n      \"Attempt to use the atomic_base default constructor\"\n   );\n}\n/*!\nConstructor\n\n\\param name\nname used for error reporting\n\n\\param sparsity [in]\nwhat type of sparsity patterns are computed by this function,\nbool_sparsity_enum or set_sparsity_enum. Default value is\nbool sparsity patterns.\n*/\ntemplate <class Base>\natomic_base<Base>::atomic_base(\n      const std::string&     name,\n      option_enum            sparsity\n) :\nsparsity_( sparsity               )\n{  CPPAD_ASSERT_KNOWN(\n      ! thread_alloc::in_parallel() ,\n      \"atomic_base: constructor cannot be called in parallel mode.\"\n   );\n   CPPAD_ASSERT_UNKNOWN( constant_enum < dynamic_enum );\n   CPPAD_ASSERT_UNKNOWN( dynamic_enum < variable_enum );\n   //\n   // atomic_index\n   bool        set_null  = false;\n   size_t      index     = 0;\n   size_t      type      = 2;\n   std::string copy_name = name;\n   void*       copy_this = reinterpret_cast<void*>( this );\n   index_  = local::atomic_index<Base>(\n      set_null, index, type, &copy_name, copy_this\n   );\n   // initialize work pointers as null;\n   for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++)\n      work_[thread] = nullptr;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/two/for_sparse_hes.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_TWO_FOR_SPARSE_HES_HPP\n# define CPPAD_CORE_ATOMIC_TWO_FOR_SPARSE_HES_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_two_for_sparse_hes app}\n{xrst_spell\n   vx\n}\n\nAtomic Forward Hessian Sparsity Patterns\n########################################\n\nSyntax\n******\n| *ok* = *afun* . ``for_sparse_hes`` ( *vx* , *r* , *s* , *h* , *x* )\n\nDeprecated 2016-06-27\n*********************\n*ok* = *afun* . ``for_sparse_hes`` ( *vx* , *r* , *s* , *h* )\n\nPurpose\n*******\nThis function is used by :ref:`ForSparseHes-name` to compute\nHessian sparsity patterns.\nIf you are using :ref:`ForSparseHes-name` ,\none of the versions of this\nvirtual function must be defined by the\n:ref:`atomic_two_ctor@atomic_user` class.\n\nGiven a :ref:`glossary@Sparsity Pattern` for\na diagonal matrix :math:`R \\in \\B{R}^{n \\times n}`, and\na row vector :math:`S \\in \\B{R}^{1 \\times m}`,\nthis routine computes the sparsity pattern for\n\n.. math::\n\n   H(x) = R^\\R{T} \\cdot (S \\cdot f)^{(2)}( x ) \\cdot R\n\nImplementation\n**************\nIf you are using and :ref:`ForSparseHes-name` ,\nthis virtual function must be defined by the\n:ref:`atomic_two_ctor@atomic_user` class.\n\nvx\n==\nThe argument *vx* has prototype\n\n   ``const CppAD:vector<bool>&`` *vx*\n\n*vx* . ``size`` () == *n* , and\nfor :math:`j = 0 , \\ldots , n-1`,\n*vx* [ *j* ] is true if and only if\n*ax* [ *j* ] is a :ref:`glossary@Variable`\nor :ref:`dynamic parameter<glossary@Parameter@Dynamic>`\nin the corresponding call to\n\n   *afun* ( *ax* , *ay* )\n\nr\n=\nThis argument has prototype\n\n   ``const CppAD:vector<bool>&`` *r*\n\nand is a :ref:`atomic_two_option@atomic_sparsity` pattern for\nthe diagonal of :math:`R \\in \\B{R}^{n \\times n}`.\n\ns\n=\nThe argument *s* has prototype\n\n   ``const CppAD:vector<bool>&`` *s*\n\nand its size is *m* .\nIt is a sparsity pattern for :math:`S \\in \\B{R}^{1 \\times m}`.\n\nh\n=\nThis argument has prototype\n\n   *atomic_sparsity* & *h*\n\nThe input value of its elements\nare not specified (must not matter).\nUpon return, *h* is a\n:ref:`atomic_two_option@atomic_sparsity` pattern for\n:math:`H(x) \\in \\B{R}^{n \\times n}` which is defined above.\n\nx\n=\nThe argument has prototype\n\n   ``const CppAD::vector<`` *Base* >& *x*\n\nand size is equal to the *n* .\nThis is the :ref:`Value-name`  corresponding to the parameters in the\nvector :ref:`atomic_two_afun@ax` (when the atomic function was called).\nTo be specific, if\n\n| |tab| ``if`` ( ``Parameter`` ( *ax* [ *i* ]) == ``true`` )\n| |tab| |tab| *x* [ *i* ] = ``Value`` ( *ax* [ *i* ] );\n| |tab| ``else``\n| |tab| |tab| *x* [ *i* ] = ``CppAD::numeric_limits<`` *Base* >:: ``quiet_NaN`` ();\n\nThe version of this function with out the *x* argument is deprecated;\ni.e., you should include the argument even if you do not use it.\n\n{xrst_end atomic_two_for_sparse_hes}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/two_for_sparse_hes.hpp\nAtomic forward mode Hessian sparsity patterns.\n*/\n/*!\nLink, after case split, from for_hes_sweep to atomic_base.\n\n\\param vx [in]\nwhich components of x are variables.\n\n\\param r [in]\nis the forward Jacobian sparsity pattern w.r.t the argument vector x.\n\n\\param s [in]\nis the reverse Jacobian sparsity pattern w.r.t the result vector y.\n\n\\param h [out]\nis the Hessian sparsity pattern w.r.t the argument vector x.\n\n\\param x\nis the integer value of the x arguments that are parameters.\n*/\ntemplate <class Base>\nbool atomic_base<Base>::for_sparse_hes(\n   const vector<bool>&             vx ,\n   const vector<bool>&             r  ,\n   const vector<bool>&             s  ,\n   vector< std::set<size_t> >&     h  ,\n   const vector<Base>&             x  )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::for_sparse_hes(\n   const vector<bool>&             vx ,\n   const vector<bool>&             r  ,\n   const vector<bool>&             s  ,\n   vector<bool>&                   h  ,\n   const vector<Base>&             x  )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::for_sparse_hes(\n   const vector<bool>&             vx ,\n   const vector<bool>&             r  ,\n   const vector<bool>&             s  ,\n   vectorBool&                     h  ,\n   const vector<Base>&             x  )\n// deprecated versions\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::for_sparse_hes(\n   const vector<bool>&             vx ,\n   const vector<bool>&             r  ,\n   const vector<bool>&             s  ,\n   vector< std::set<size_t> >&     h  )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::for_sparse_hes(\n   const vector<bool>&             vx ,\n   const vector<bool>&             r  ,\n   const vector<bool>&             s  ,\n   vector<bool>&                   h  )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::for_sparse_hes(\n   const vector<bool>&             vx ,\n   const vector<bool>&             r  ,\n   const vector<bool>&             s  ,\n   vectorBool&                     h  )\n{  return false; }\n/*!\nLink, before case split, from for_hes_sweep to atomic_base.\n2DO: move this function outside this file so can change\ndeveloper documentation to omhelp formatting.\n\n\\tparam InternalSparsity\nIs the used internally for sparsity calculations; i.e.,\nsparse_pack or sparse_list.\n\n\\param x\nis parameter arguments to the function, other components are nan.\n\n\\param x_index\nis the variable index, on the tape, for the arguments to this function.\nThis size of x_index is n, the number of arguments to this function.\n\n\\param y_index\nis the variable index, on the tape, for the results for this function.\nThis size of y_index is m, the number of results for this function.\n\n\\param for_jac_sparsity\nOn input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nis the forward Jacobian sparsity for the j-th argument to this atomic function.\n\n\\param rev_jac_sparsity\nOn input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i],\nis the reverse Jacobian sparsity for the i-th result to this atomic function.\nThis shows which components of the result affect the function we are\ncomputing the Hessian of.\n\n\\param for_hes_sparsity\nThis is the sparsity pattern for the Hessian. On input, the non-linear\nterms in the atomic function have not been included. Upon return, they\nhave been included.\n*/\ntemplate <class Base>\ntemplate <class InternalSparsity>\nbool atomic_base<Base>::for_sparse_hes(\n   const vector<Base>&              x                ,\n   const vector<size_t>&            x_index          ,\n   const vector<size_t>&            y_index          ,\n   size_t                           np1              ,\n   size_t                           numvar           ,\n   const InternalSparsity&          rev_jac_sparsity ,\n   InternalSparsity&                for_sparsity     )\n{  typedef typename InternalSparsity::const_iterator const_iterator;\n   CPPAD_ASSERT_UNKNOWN( rev_jac_sparsity.end() == 1 );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + numvar );\n   size_t n      = x_index.size();\n   size_t m      = y_index.size();\n   bool   ok     = false;\n   size_t thread = thread_alloc::thread_num();\n   allocate_work(thread);\n   //\n   // vx\n   vector<bool> vx(n);\n   for(size_t j = 0; j < n; j++)\n      vx[j] = x_index[j] != 0;\n   //\n   // bool_r\n   vector<bool>& bool_r( work_[thread]->bool_r );\n   bool_r.resize(n);\n   for(size_t j = 0; j < n; j++)\n   {  // check if we must compute row and column j of h\n      const_iterator itr(for_sparsity, np1 + x_index[j]);\n      size_t i = *itr;\n      bool_r[j] = i < np1;\n   }\n   //\n   // bool s\n   vector<bool>& bool_s( work_[thread]->bool_s );\n   bool_s.resize(m);\n   for(size_t i = 0; i < m; i++)\n   {  // check if row i of result is included in h\n      bool_s[i] = rev_jac_sparsity.is_element(y_index[i], 0);\n   }\n   //\n   // h\n   vectorBool&                 pack_h( work_[thread]->pack_h );\n   vector<bool>&               bool_h( work_[thread]->bool_h );\n   vector< std::set<size_t> >& set_h(  work_[thread]->set_h );\n   //\n   // call user's version of atomic function\n   std::string msg    = \": atomic_base.for_sparse_hes: returned false\";\n   if( sparsity_ == pack_sparsity_enum )\n   {  pack_h.resize(n * n);\n      ok = for_sparse_hes(vx, bool_r, bool_s, pack_h, x);\n      if( ! ok )\n         ok = for_sparse_hes(vx, bool_r, bool_s, pack_h);\n      if( ! ok )\n      {  msg = atomic_name() + msg + \" sparsity = pack_sparsity_enum\";\n         CPPAD_ASSERT_KNOWN(false, msg.c_str());\n      }\n   }\n   else if( sparsity_ == bool_sparsity_enum )\n   {  bool_h.resize(n * n);\n      ok = for_sparse_hes(vx, bool_r, bool_s, bool_h, x);\n      if( ! ok )\n         ok = for_sparse_hes(vx, bool_r, bool_s, bool_h);\n      if( ! ok )\n      {  msg = atomic_name() + msg + \" sparsity = bool_sparsity_enum\";\n         CPPAD_ASSERT_KNOWN(false, msg.c_str());\n      }\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( sparsity_ == set_sparsity_enum )\n      set_h.resize(n);\n      ok = for_sparse_hes(vx, bool_r, bool_s, set_h, x);\n      if( ! ok )\n         ok = for_sparse_hes(vx, bool_r, bool_s, set_h);\n      if( ! ok )\n      {  msg = atomic_name() + msg + \" sparsity = set_sparsity_enum\";\n         CPPAD_ASSERT_KNOWN(false, msg.c_str());\n      }\n   }\n   CPPAD_ASSERT_UNKNOWN( ok );\n   //\n   // modify hessian in calling routine\n   for(size_t i = 0; i < n; i++)\n   {  for(size_t j = 0; j < n; j++)\n      {  if( (x_index[i] > 0) && (x_index[j] > 0) )\n         {  bool flag = false;\n            switch( sparsity_ )\n            {  case pack_sparsity_enum:\n               flag = pack_h[i * n + j];\n               break;\n               //\n               case bool_sparsity_enum:\n               flag = bool_h[i * n + j];\n               break;\n               //\n               case set_sparsity_enum:\n               flag = set_h[i].find(j) != set_h[i].end();\n               break;\n            }\n            if( flag )\n            {  const_iterator itr_i(for_sparsity, np1 + x_index[i]);\n               size_t i_x = *itr_i;\n               while( i_x < np1 )\n               {  for_sparsity.binary_union(\n                     i_x, i_x, np1 + x_index[j], for_sparsity\n                  );\n                  i_x = *(++itr_i);\n               }\n               const_iterator itr_j(for_sparsity, np1 + x_index[j]);\n               size_t j_x = *itr_j;\n               while( j_x < np1 )\n               {  for_sparsity.binary_union(\n                     j_x, j_x, np1 + x_index[i], for_sparsity\n                  );\n                  j_x = *(++itr_j);\n               }\n            }\n         }\n      }\n   }\n   return ok;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/two/for_sparse_jac.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_TWO_FOR_SPARSE_JAC_HPP\n# define CPPAD_CORE_ATOMIC_TWO_FOR_SPARSE_JAC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_two_for_sparse_jac app}\n\nAtomic Forward Jacobian Sparsity Patterns\n#########################################\n\nSyntax\n******\n| *ok* = *afun* . ``for_sparse_jac`` ( *q* , *r* , *s* , *x* )\n\nDeprecated 2016-06-27\n*********************\n\n   *ok* = *afun* . ``for_sparse_jac`` ( *q* , *r* , *s* )\n\nPurpose\n*******\nThis function is used by :ref:`ForSparseJac-name` to compute\nJacobian sparsity patterns.\nFor a fixed matrix :math:`R \\in \\B{R}^{n \\times q}`,\nthe Jacobian of :math:`f( x + R * u)` with respect to :math:`u \\in \\B{R}^q` is\n\n.. math::\n\n   S(x) = f^{(1)} (x) * R\n\nGiven a :ref:`glossary@Sparsity Pattern` for :math:`R`,\n``for_sparse_jac`` computes a sparsity pattern for :math:`S(x)`.\n\nImplementation\n**************\nIf you are using\n:ref:`ForSparseJac-name` ,\n:ref:`ForSparseHes-name` , or\n:ref:`RevSparseHes-name` ,\none of the versions of this\nvirtual function must be defined by the\n:ref:`atomic_two_ctor@atomic_user` class.\n\nq\n=\nThe argument *q* has prototype\n\n   ``size_t`` *q*\n\nIt specifies the number of columns in\n:math:`R \\in \\B{R}^{n \\times q}` and the Jacobian\n:math:`S(x) \\in \\B{R}^{m \\times q}`.\n\nr\n=\nThis argument has prototype\n\n   ``const`` *atomic_sparsity* & *r*\n\nand is a :ref:`atomic_two_option@atomic_sparsity` pattern for\n:math:`R \\in \\B{R}^{n \\times q}`.\n\ns\n=\nThis argument has prototype\n\n   *atomic_sparsity* & *s*\n\nThe input values of its elements\nare not specified (must not matter).\nUpon return, *s* is a\n:ref:`atomic_two_option@atomic_sparsity` pattern for\n:math:`S(x) \\in \\B{R}^{m \\times q}`.\n\nx\n=\nThe argument has prototype\n\n   ``const CppAD::vector<`` *Base* >& *x*\n\nand size is equal to the *n* .\nThis is the :ref:`Value-name`  corresponding to the parameters in the\nvector :ref:`atomic_two_afun@ax` (when the atomic function was called).\nTo be specific, if\n\n| |tab| ``if`` ( ``Parameter`` ( *ax* [ *i* ]) == ``true`` )\n| |tab| |tab| *x* [ *i* ] = ``Value`` ( *ax* [ *i* ] );\n| |tab| ``else``\n| |tab| |tab| *x* [ *i* ] = ``CppAD::numeric_limits<`` *Base* >:: ``quiet_NaN`` ();\n\nThe version of this function with out the *x* argument is deprecated;\ni.e., you should include the argument even if you do not use it.\n\nok\n**\nThe return value *ok* has prototype\n\n   ``bool`` *ok*\n\nIf it is ``true`` , the corresponding evaluation succeeded,\notherwise it failed.\n\n{xrst_end atomic_two_for_sparse_jac}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/two_for_sparse_jac.hpp\nAtomic forward Jacobian sparsity pattern.\n*/\n/*!\nLink, after case split, from for_jac_sweep to atomic_base.\n\n\\param q\nis the column dimension for the Jacobian sparsity patterns.\n\n\\param r\nis the Jacobian sparsity pattern for the argument vector x\n\n\\param s\nis the Jacobian sparsity pattern for the result vector y\n\n\\param x\nis the integer value for x arguments that are parameters.\n*/\ntemplate <class Base>\nbool atomic_base<Base>::for_sparse_jac(\n   size_t                                  q  ,\n   const vector< std::set<size_t> >&       r  ,\n          vector< std::set<size_t> >&       s  ,\n   const vector<Base>&                     x  )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::for_sparse_jac(\n   size_t                                  q  ,\n   const vector<bool>&                     r  ,\n          vector<bool>&                     s  ,\n   const vector<Base>&                     x  )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::for_sparse_jac(\n   size_t                                  q  ,\n   const vectorBool&                       r  ,\n          vectorBool&                       s  ,\n   const vector<Base>&                     x  )\n{  return false; }\n// deprecated versions\ntemplate <class Base>\nbool atomic_base<Base>::for_sparse_jac(\n   size_t                                  q  ,\n   const vector< std::set<size_t> >&       r  ,\n          vector< std::set<size_t> >&       s  )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::for_sparse_jac(\n   size_t                                  q  ,\n   const vector<bool>&                     r  ,\n          vector<bool>&                     s  )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::for_sparse_jac(\n   size_t                                  q  ,\n   const vectorBool&                       r  ,\n          vectorBool&                       s  )\n{  return false; }\n\n/*!\nLink, before case split, from for_jac_sweep to atomic_base.\n\n\\tparam InternalSparsity\nIs the type used for internal sparsity calculations; i.e.,\nsparse_pack or sparse_list.\n\n\\param x\nis parameter arguments to the function, other components are nan.\n\n\\param x_index\nis the variable index, on the tape, for the arguments to this function.\nThis size of x_index is n, the number of arguments to this function.\n\n\\param y_index\nis the variable index, on the tape, for the results for this function.\nThis size of y_index is m, the number of results for this function.\n\n\\param var_sparsity\nOn input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nis the sparsity for the j-th argument to this atomic function.\nOn output, for i = 0, ... , m-1, the sparsity pattern with index y_index[i],\nis the sparsity for the i-th result for this atomic function.\n*/\ntemplate <class Base>\ntemplate <class InternalSparsity>\nbool atomic_base<Base>::for_sparse_jac(\n   const vector<Base>&              x            ,\n   const vector<size_t>&            x_index      ,\n   const vector<size_t>&            y_index      ,\n   InternalSparsity&                var_sparsity )\n{  //\n   // pod_x_index, pod_y_index\n   local::pod_vector<size_t> pod_x_index( x_index.size() );\n   local::pod_vector<size_t> pod_y_index( y_index.size() );\n   for(size_t j = 0; j < x_index.size(); ++j)\n      pod_x_index[j] = x_index[j];\n   for(size_t i = 0; i < y_index.size(); ++i)\n      pod_y_index[i] = y_index[i];\n   //\n   // initial results are empty during forward mode\n   size_t q           = var_sparsity.end();\n   bool   input_empty = true;\n   bool   zero_empty  = true;\n   bool   transpose   = false;\n   size_t m           = pod_y_index.size();\n   bool   ok          = false;\n   size_t thread      = thread_alloc::thread_num();\n   allocate_work(thread);\n   //\n   std::string msg    = \": atomic_base.for_sparse_jac: returned false\";\n   if( sparsity_ == pack_sparsity_enum )\n   {  vectorBool& pack_r ( work_[thread]->pack_r );\n      vectorBool& pack_s ( work_[thread]->pack_s );\n      local::sparse::get_internal_pattern(\n         transpose, pod_x_index, var_sparsity, pack_r\n      );\n      //\n      pack_s.resize(m * q );\n      ok = for_sparse_jac(q, pack_r, pack_s, x);\n      if( ! ok )\n         ok = for_sparse_jac(q, pack_r, pack_s);\n      if( ! ok )\n      {  msg = atomic_name() + msg + \" sparsity = pack_sparsity_enum\";\n         CPPAD_ASSERT_KNOWN(false, msg.c_str());\n      }\n      local::sparse::set_internal_pattern(zero_empty, input_empty,\n         transpose, pod_y_index, var_sparsity, pack_s\n      );\n   }\n   else if( sparsity_ == bool_sparsity_enum )\n   {  vector<bool>& bool_r ( work_[thread]->bool_r );\n      vector<bool>& bool_s ( work_[thread]->bool_s );\n      local::sparse::get_internal_pattern(\n         transpose, pod_x_index, var_sparsity, bool_r\n      );\n      bool_s.resize(m * q );\n      ok = for_sparse_jac(q, bool_r, bool_s, x);\n      if( ! ok )\n         ok = for_sparse_jac(q, bool_r, bool_s);\n      if( ! ok )\n      {  msg = atomic_name() + msg + \" sparsity = bool_sparsity_enum\";\n         CPPAD_ASSERT_KNOWN(false, msg.c_str());\n      }\n      local::sparse::set_internal_pattern(zero_empty, input_empty,\n         transpose, pod_y_index, var_sparsity, bool_s\n      );\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( sparsity_ == set_sparsity_enum );\n      vector< std::set<size_t> >& set_r ( work_[thread]->set_r );\n      vector< std::set<size_t> >& set_s ( work_[thread]->set_s );\n      local::sparse::get_internal_pattern(\n         transpose, pod_x_index, var_sparsity, set_r\n      );\n      //\n      set_s.resize(m);\n      ok = for_sparse_jac(q, set_r, set_s, x);\n      if( ! ok )\n         ok = for_sparse_jac(q, set_r, set_s);\n      if( ! ok )\n      {  msg = atomic_name() + msg + \" sparsity = set_sparsity_enum\";\n         CPPAD_ASSERT_KNOWN(false, msg.c_str());\n      }\n      local::sparse::set_internal_pattern(zero_empty, input_empty,\n         transpose, pod_y_index, var_sparsity, set_s\n      );\n   }\n   return ok;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/two/forward.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_TWO_FORWARD_HPP\n# define CPPAD_CORE_ATOMIC_TWO_FORWARD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_two_forward app}\n{xrst_spell\n   atx\n   aty\n   tx\n   vx\n   vy\n}\n\nAtomic Forward Mode\n###################\n\nSyntax\n******\n\nBase\n====\n\n   *ok* = *afun* . ``forward`` ( *p* , *q* , *vx* , *vy* , *tx* , *ty* )\n\nThis syntax is used by *f* . ``Forward`` where *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nand *afun* is used in *f* .\n\nAD<Base>\n========\n\n   *ok* = *afun* . ``forward`` ( *p* , *q* , *vx* , *vy* , *atx* , *aty* )\n\nThis syntax is used by *af* . ``Forward`` where *af* has prototype\n\n   ``ADFun< AD<`` *Base* > , *Base* > *af*\n\nand *afun* is used in *af* (see :ref:`base2ad-name` ).\n\nPurpose\n*******\nThis virtual function is used by :ref:`atomic_two_afun-name`\nto evaluate function values.\nIt is also used buy\n:ref:`f.Forward<Forward-name>` (and *af* . ``Forward`` )\nto compute function vales and derivatives.\n\nImplementation\n**************\nThis virtual function must be defined by the\n:ref:`atomic_two_ctor@atomic_user` class.\nIt can just return *ok* == ``false``\n(and not compute anything) for values\nof *q*  > 0 that are greater than those used by your\n:ref:`Forward-name` mode calculations.\n\np\n*\nThe argument *p* has prototype\n\n   ``size_t`` *p*\n\nIt specifies the lowest order Taylor coefficient that we are evaluating.\nDuring calls to :ref:`atomic_two_afun-name` , *p*  == 0 .\n\nq\n*\nThe argument *q* has prototype\n\n   ``size_t`` *q*\n\nIt specifies the highest order Taylor coefficient that we are evaluating.\nDuring calls to :ref:`atomic_two_afun-name` , *q*  == 0 .\n\nvx\n**\nThe ``forward`` argument *vx* has prototype\n\n   ``const CppAD::vector<bool>&`` *vx*\n\nThe case *vx* . ``size`` () > 0 only occurs while evaluating a call to\n:ref:`atomic_two_afun-name` .\nIn this case,\n*p* == *q*  == 0 ,\n*vx* . ``size`` () == *n* , and\nfor :math:`j = 0 , \\ldots , n-1`,\n*vx* [ *j* ] is true if and only if\n*ax* [ *j* ] is a :ref:`glossary@Variable`\nor :ref:`dynamic parameter<glossary@Parameter@Dynamic>`\nin the corresponding call to\n\n   *afun* ( *ax* , *ay* )\n\nIf *vx* . ``size`` () == 0 ,\nthen *vy* . ``size`` () == 0 and neither of these vectors\nshould be used.\n\nvy\n**\nThe ``forward`` argument *vy* has prototype\n\n   ``CppAD::vector<bool>&`` *vy*\n\nIf *vy* . ``size`` () == 0 , it should not be used.\nOtherwise,\n*q*  == 0 and *vy* . ``size`` () == *m* .\nThe input values of the elements of *vy*\nare not specified (must not matter).\nUpon return, for :math:`j = 0 , \\ldots , m-1`,\n*vy* [ *i* ] is true if and only if\n*ay* [ *i* ] is a variable\nor dynamic parameter\n(CppAD uses *vy* to reduce the necessary computations).\n\ntx\n**\nThe argument *tx* has prototype\n\n   ``const CppAD::vector<`` *Base* >& *tx*\n\nand *tx* . ``size`` () == ( *q* +1)* *n* .\nIt is used by *f* . ``Forward`` where *f* has type\n``ADFun`` < *Base* > *f* and *afun* is used in *f* .\nFor :math:`j = 0 , \\ldots , n-1` and :math:`k = 0 , \\ldots , q`,\nwe use the Taylor coefficient notation\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      x_j^k    & = & tx [ j * ( q + 1 ) + k ]\n      \\\\\n      X_j (t)  & = & x_j^0 + x_j^1 t^1 + \\cdots + x_j^q t^q\n   \\end{eqnarray}\n\nNote that superscripts represent an index for :math:`x_j^k`\nand an exponent for :math:`t^k`.\nAlso note that the Taylor coefficients for :math:`X(t)` correspond\nto the derivatives of :math:`X(t)` at :math:`t = 0` in the following way:\n\n.. math::\n\n   x_j^k = \\frac{1}{ k ! } X_j^{(k)} (0)\n\natx\n***\nThe argument *atx* has prototype\n\n   ``const CppAD::vector< AD<`` *Base* > >& *atx*\n\nOtherwise, *atx* specifications are the same as for *tx* .\n\nty\n**\nThe argument *ty* has prototype\n\n   ``CppAD::vector<`` *Base* >& *ty*\n\nand *tx* . ``size`` () == ( *q* +1)* *m* .\nIt is set by *f* . ``Forward`` where *f* has type\n``ADFun`` < *Base* > *f* and *afun* is used in *f* .\nUpon return,\nFor :math:`i = 0 , \\ldots , m-1` and :math:`k = 0 , \\ldots , q`,\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      Y_i (t)  & = & f_i [ X(t) ]\n      \\\\\n      Y_i (t)  & = & y_i^0 + y_i^1 t^1 + \\cdots + y_i^q t^q + o ( t^q )\n      \\\\\n      ty [ i * ( q + 1 ) + k ] & = & y_i^k\n   \\end{eqnarray}\n\nwhere :math:`o( t^q ) / t^q \\rightarrow 0` as :math:`t \\rightarrow 0`.\nNote that superscripts represent an index for :math:`y_j^k`\nand an exponent for :math:`t^k`.\nAlso note that the Taylor coefficients for :math:`Y(t)` correspond\nto the derivatives of :math:`Y(t)` at :math:`t = 0` in the following way:\n\n.. math::\n\n   y_j^k = \\frac{1}{ k ! } Y_j^{(k)} (0)\n\nIf :math:`p > 0`,\nfor :math:`i = 0 , \\ldots , m-1` and :math:`k = 0 , \\ldots , p-1`,\nthe input of *ty* satisfies\n\n.. math::\n\n   ty [ i * ( q + 1 ) + k ] = y_i^k\n\nand hence the corresponding elements need not be recalculated.\n\naty\n***\nThe argument *aty* has prototype\n\n   ``const CppAD::vector< AD<`` *Base* > >& *aty*\n\nOtherwise, *aty* specifications are the same as for *ty* .\n\nok\n**\nIf the required results are calculated, *ok* should be true.\nOtherwise, it should be false.\n\nDiscussion\n**********\nFor example, suppose that *q*  == 2 ,\nand you know how to compute the function :math:`f(x)`,\nits first derivative :math:`f^{(1)} (x)`,\nand it component wise Hessian :math:`f_i^{(2)} (x)`.\nThen you can compute *ty* using the following formulas:\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   y_i^0 & = & Y(0)\n         = f_i ( x^0 )\n   \\\\\n   y_i^1 & = & Y^{(1)} ( 0 )\n         = f_i^{(1)} ( x^0 ) X^{(1)} ( 0 )\n         = f_i^{(1)} ( x^0 ) x^1\n   \\\\\n   y_i^2\n   & = & \\frac{1}{2 !} Y^{(2)} (0)\n   \\\\\n   & = & \\frac{1}{2} X^{(1)} (0)^\\R{T} f_i^{(2)} ( x^0 ) X^{(1)} ( 0 )\n     +   \\frac{1}{2} f_i^{(1)} ( x^0 ) X^{(2)} ( 0 )\n   \\\\\n   & = & \\frac{1}{2} (x^1)^\\R{T} f_i^{(2)} ( x^0 ) x^1\n     +    f_i^{(1)} ( x^0 ) x^2\n   \\end{eqnarray}\n\nFor :math:`i = 0 , \\ldots , m-1`, and :math:`k = 0 , 1 , 2`,\n\n.. math::\n\n   ty [ i * (q + 1) + k ] = y_i^k\n\n{xrst_end atomic_two_forward}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/two_forward.hpp\nAtomic forward mode\n*/\n/*!\nLink from atomic_base to forward mode (for replacement by derived class)\n\n\\param p [in]\nlowerest order for this forward mode calculation.\n\n\\param q [in]\nhighest order for this forward mode calculation.\n\n\\param vx [in]\nif size not zero, which components of x are variables\n\n\\param vy [out]\nif size not zero, which components of y are variables\n\n\\param tx [in]\nTaylor coefficients corresponding to x for this calculation.\n\n\\param ty [out]\nTaylor coefficient corresponding to y for this calculation\n\nSee the forward mode in user's documentation for atomic_two\n*/\ntemplate <class Base>\nbool atomic_base<Base>::forward(\n   size_t                    p  ,\n   size_t                    q  ,\n   const vector<bool>&       vx ,\n          vector<bool>&       vy ,\n   const vector<Base>&       tx ,\n          vector<Base>&       ty )\n{  return false; }\n/*!\nLink from atomic_base to forward mode (for replacement by derived class)\n\n\\param p [in]\nlowerest order for this forward mode calculation.\n\n\\param q [in]\nhighest order for this forward mode calculation.\n\n\\param vx [in]\nif size not zero, which components of x are variables\n\n\\param vy [out]\nif size not zero, which components of y are variables\n\n\\param atx [in]\nTaylor coefficients corresponding to x for this calculation.\n\n\\param aty [out]\nTaylor coefficient corresponding to y for this calculation\n\nSee the forward mode in user's documentation for atomic_two\n*/\ntemplate <class Base>\nbool atomic_base<Base>::forward(\n   size_t                    p   ,\n   size_t                    q   ,\n   const vector<bool>&       vx  ,\n          vector<bool>&       vy  ,\n   const vector< AD<Base> >& atx ,\n          vector< AD<Base> >& aty )\n{  return false; }\n/*!\nConvert atomic_three interface to atomic_two interface\n\n\\param order_low [in]\nlowerest order for this forward mode calculation.\n\n\\param order_up [in]\nhighest order for this forward mode calculation.\n\n\\param  type_x [in]\nif size not zero, which components of x are variables\n\n\\param type_y [out]\nif size not zero, which components of y are variables\n\n\\param taylor_x [in]\nTaylor coefficients corresponding to x for this calculation.\n\n\\param taylor_y [out]\nTaylor coefficient corresponding to y for this calculation\n\nSee the forward mode in user's documentation for atomic_three\n*/\n# define CPPAD_ATOMIC_BASE_MUSTDO 0\ntemplate <class Base>\nbool atomic_base<Base>::forward(\n   size_t                       order_low  ,\n   size_t                       order_up   ,\n   const vector<ad_type_enum>&  type_x     ,\n   vector<ad_type_enum>&        type_y     ,\n   const vector<Base>&          taylor_x   ,\n   vector<Base>&                taylor_y   )\n{  //\n   // atomic_base::afun(ax, ay) calls bool version directly\n   CPPAD_ASSERT_UNKNOWN( type_x.size() == 0 );\n   CPPAD_ASSERT_UNKNOWN( type_y.size() == 0 );\n   //\n# if CPPAD_ATOMIC_BASE_MUSTDO\n   size_t thread = thread_alloc::thread_num();\n   allocate_work(thread);\n   vector <bool>& vx  = work_[thread]->vx;\n   vector <bool>& vy  = work_[thread]->vy;\n   vx.resize(type_x.size());\n   vy.resize(type_y.size());\n# else\n   vector<bool> vx, vy;\n# endif\n   //\n   bool ok = forward(order_low, order_up, vx, vy, taylor_x, taylor_y);\n   //\n   return ok;\n}\n# undef CPPAD_ATOMIC_BASE_MUSTDO\n/*!\nConvert atomic_three interface to atomic_two interface\n\n\\param order_low [in]\nlowerest order for this forward mode calculation.\n\n\\param order_up [in]\nhighest order for this forward mode calculation.\n\n\\param  type_x [in]\nif size not zero, which components of x are variables\n\n\\param type_y [out]\nif size not zero, which components of y are variables\n\n\\param ataylor_x [in]\nTaylor coefficients corresponding to x for this calculation.\n\n\\param ataylor_y [out]\nTaylor coefficient corresponding to y for this calculation\n\nSee the forward mode in user's documentation for atomic_three\n*/\ntemplate <class Base>\nbool atomic_base<Base>::forward(\n   size_t                       order_low  ,\n   size_t                       order_up   ,\n   const vector<ad_type_enum>&  type_x     ,\n   vector<ad_type_enum>&        type_y     ,\n   const vector< AD<Base> >&    ataylor_x  ,\n   vector< AD<Base> >&          ataylor_y  )\n{  //\n   // atomic_base::afun(ax, ay) calls bool version directly\n   CPPAD_ASSERT_UNKNOWN( type_x.size() == 0 );\n   CPPAD_ASSERT_UNKNOWN( type_y.size() == 0 );\n   //\n   vector<bool> vx, vy;\n   bool ok = forward(order_low, order_up, vx, vy, ataylor_x, ataylor_y);\n   //\n   return ok;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/two/option.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_TWO_OPTION_HPP\n# define CPPAD_CORE_ATOMIC_TWO_OPTION_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_two_option app}\n{xrst_spell\n   typedef\n}\n\nSet Atomic Function Options\n###########################\n\nSyntax\n******\n| *afun* . ``option`` ( *option_value* )\n\nScope\n*****\nThese settings do not apply to individual *afun* calls,\nbut rather all subsequent uses of the corresponding atomic operation\nin an :ref:`ADFun-name` object.\n\natomic_sparsity\n***************\nNote that, if you use :ref:`optimize-name` , these sparsity patterns are used\nto determine the :ref:`dependency<dependency.cpp-name>` relationship between\nargument and result variables.\n\npack_sparsity_enum\n==================\nIf *option_value* is ``atomic_base`` < *Base* >:: ``pack_sparsity_enum`` ,\nthen the type used by *afun* for\n:ref:`sparsity patterns<glossary@Sparsity Pattern>` ,\n(after the option is set) will be\n\n   ``typedef CppAD::vectorBool`` *atomic_sparsity*\n\nIf *r* is a sparsity pattern\nfor a matrix :math:`R \\in \\B{R}^{p \\times q}`:\n*r* . ``size`` () == *p* * *q* .\n\nbool_sparsity_enum\n==================\nIf *option_value* is ``atomic_base`` < *Base* >:: ``bool_sparsity_enum`` ,\nthen the type used by *afun* for\n:ref:`sparsity patterns<glossary@Sparsity Pattern>` ,\n(after the option is set) will be\n\n   ``typedef CppAD::vector<bool>`` *atomic_sparsity*\n\nIf *r* is a sparsity pattern\nfor a matrix :math:`R \\in \\B{R}^{p \\times q}`:\n*r* . ``size`` () == *p* * *q* .\n\nset_sparsity_enum\n=================\nIf *option_value* is *atomic_base* < ``Base`` >:: *set_sparsity_enum* ,\nthen the type used by *afun* for\n:ref:`sparsity patterns<glossary@Sparsity Pattern>` ,\n(after the option is set) will be\n\n   ``typedef CppAD::vector< std::set<size_t> >`` *atomic_sparsity*\n\nIf *r* is a sparsity pattern\nfor a matrix :math:`R \\in \\B{R}^{p \\times q}`:\n*r* . ``size`` () == *p* , and for :math:`i = 0 , \\ldots , p-1`,\nthe elements of *r* [ *i* ] are between zero and :math:`q-1` inclusive.\n\n{xrst_end atomic_two_option}\n------------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/two_option.hpp\nSetting atomic_base options.\n*/\n\n/*!\nSetting atomic_base options.\n\n\\param option_value\nnew option value.\n*/\ntemplate <class Base>\nvoid atomic_base<Base>::option(enum option_enum option_value)\n{  switch( option_value )\n   {  case pack_sparsity_enum:\n      case bool_sparsity_enum:\n      case set_sparsity_enum:\n      sparsity_ = option_value;\n      break;\n\n      default:\n      CPPAD_ASSERT_KNOWN(\n         false,\n         \"atoic_base::option: option_value is not valid\"\n      );\n   }\n   return;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/two/rev_depend.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_TWO_REV_DEPEND_HPP\n# define CPPAD_CORE_ATOMIC_TWO_REV_DEPEND_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/two_rev_depend.hpp\nThird generation atomic type computation.\n*/\n/*!\nLink from atomic_two to reverse dependency calculation\n\n\\param parameter_x [in]\nis the value of the parameters in the corresponding function call\nafun(ax, ay).\n\n\\param type_x [in]\nis the type for each component of ax in the corresponding function call\nafun(ax, ay).\n\n\\param depend_x [out]\nspecifies which components of x affect values of interest.\n\n\\param depend_y [in]\nspecifies which components of y affect values of interest.\n*/\n// BEGIN_PROTOTYPE\ntemplate <class Base>\nbool atomic_base<Base>::rev_depend(\n   const vector<Base>&         parameter_x ,\n   const vector<ad_type_enum>& type_x      ,\n   vector<bool>&               depend_x    ,\n   const vector<bool>&         depend_y    )\n// END_PROTOTYPE\n{  bool ok = true;\n   CPPAD_ASSERT_UNKNOWN( depend_x.size() == parameter_x.size() );\n   size_t n = depend_x.size();\n   size_t m = depend_y.size();\n   //\n   size_t thread = thread_alloc::thread_num();\n   allocate_work(thread);\n   //\n   if( sparsity_ == pack_sparsity_enum )\n   {  vectorBool& rt ( work_[thread]->pack_r );\n      vectorBool& st ( work_[thread]->pack_s );\n      //\n      st.resize(n * 1 );\n      rt.resize(m * 1 );\n      for(size_t i = 0; i < m; ++i)\n         rt[i] = depend_y[i];\n      ok = rev_sparse_jac(1, rt, st, parameter_x);\n      if( ! ok )\n         ok = rev_sparse_jac(1, rt, st);\n      if( ! ok )\n         return false;\n      for(size_t j = 0; j < n; ++j)\n         depend_x[j] = st[j];\n   }\n   else if( sparsity_ == bool_sparsity_enum )\n   {\n      ok = rev_sparse_jac(1, depend_y, depend_x, parameter_x);\n      if( ! ok )\n         ok = rev_sparse_jac(m, depend_y, depend_x);\n      if( ! ok )\n         return false;\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( sparsity_ == set_sparsity_enum );\n      vector< std::set<size_t> >& rt ( work_[thread]->set_r );\n      vector< std::set<size_t> >& st ( work_[thread]->set_s );\n      rt.resize(m);\n      st.resize(n);\n      for(size_t i = 0; i < m; ++i)\n      {  if( depend_y[i] )\n            rt[i].insert(0);\n      }\n      ok = rev_sparse_jac(m, rt, st, parameter_x);\n      if( ! ok )\n         ok = rev_sparse_jac(m, rt, st);\n      if( ! ok )\n         return false;\n      for(size_t j = 0; j < n; ++j)\n         depend_x[j] = ! st[j].empty();\n   }\n   return ok;\n}\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/two/rev_sparse_hes.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_TWO_REV_SPARSE_HES_HPP\n# define CPPAD_CORE_ATOMIC_TWO_REV_SPARSE_HES_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_two_rev_sparse_hes app}\n{xrst_spell\n   vx\n}\n\nAtomic Reverse Hessian Sparsity Patterns\n########################################\n\nSyntax\n******\n| *ok* = *afun* . ``rev_sparse_hes`` ( *vx* , *s* , *t* , *q* , *r* , *u* , *v* , *x* )\n\nDeprecated 2016-06-27\n*********************\n*ok* = *afun* . ``rev_sparse_hes`` ( *vx* , *s* , *t* , *q* , *r* , *u* , *v* )\n\nPurpose\n*******\nThis function is used by :ref:`RevSparseHes-name` to compute\nHessian sparsity patterns.\nIf you are using :ref:`RevSparseHes-name` to compute\none of the versions of this\nvirtual function muse be defined by the\n:ref:`atomic_two_ctor@atomic_user` class.\n\nThere is an unspecified scalar valued function\n:math:`g : \\B{R}^m \\rightarrow \\B{R}`.\nGiven a :ref:`glossary@Sparsity Pattern` for\n:math:`R \\in \\B{R}^{n \\times q}`,\nand information about the function :math:`z = g(y)`,\nthis routine computes the sparsity pattern for\n\n.. math::\n\n   V(x) = (g \\circ f)^{(2)}( x ) R\n\nImplementation\n**************\nIf you are using and :ref:`RevSparseHes-name` ,\nthis virtual function must be defined by the\n:ref:`atomic_two_ctor@atomic_user` class.\n\nvx\n==\nThe argument *vx* has prototype\n\n   ``const CppAD:vector<bool>&`` *vx*\n\n*vx* . ``size`` () == *n* , and\nfor :math:`j = 0 , \\ldots , n-1`,\n*vx* [ *j* ] is true if and only if\n*ax* [ *j* ] is a :ref:`glossary@Variable`\nor :ref:`dynamic parameter<glossary@Parameter@Dynamic>`\nin the corresponding call to\n\n   *afun* ( *ax* , *ay* )\n\ns\n=\nThe argument *s* has prototype\n\n   ``const CppAD:vector<bool>&`` *s*\n\nand its size is *m* .\nIt is a sparsity pattern for\n:math:`S(x) = g^{(1)} [ f(x) ] \\in \\B{R}^{1 \\times m}`.\n\nt\n=\nThis argument has prototype\n\n   ``CppAD:vector<bool>&`` *t*\n\nand its size is *m* .\nThe input values of its elements\nare not specified (must not matter).\nUpon return, *t* is a\nsparsity pattern for\n:math:`T(x) \\in \\B{R}^{1 \\times n}` where\n\n.. math::\n\n   T(x) = (g \\circ f)^{(1)} (x) = S(x) * f^{(1)} (x)\n\nq\n=\nThe argument *q* has prototype\n\n   ``size_t`` *q*\n\nIt specifies the number of columns in\n:math:`R \\in \\B{R}^{n \\times q}`,\n:math:`U(x) \\in \\B{R}^{m \\times q}`, and\n:math:`V(x) \\in \\B{R}^{n \\times q}`.\n\nr\n=\nThis argument has prototype\n\n   ``const`` *atomic_sparsity* & *r*\n\nand is a :ref:`atomic_two_option@atomic_sparsity` pattern for\n:math:`R \\in \\B{R}^{n \\times q}`.\n\nu\n*\nThis argument has prototype\n\n   ``const`` *atomic_sparsity* & *u*\n\nand is a :ref:`atomic_two_option@atomic_sparsity` pattern for\n:math:`U(x) \\in \\B{R}^{m \\times q}` which is defined by\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   U(x)\n   & = &\n   \\{ \\partial_u \\{ \\partial_y g[ y + f^{(1)} (x) R u ] \\}_{y=f(x)} \\}_{u=0}\n   \\\\\n   & = &\n   \\partial_u \\{ g^{(1)} [ f(x) + f^{(1)} (x) R u ] \\}_{u=0}\n   \\\\\n   & = &\n   g^{(2)} [ f(x) ] f^{(1)} (x) R\n   \\end{eqnarray}\n\nv\n=\nThis argument has prototype\n\n   *atomic_sparsity* & *v*\n\nThe input value of its elements\nare not specified (must not matter).\nUpon return, *v* is a\n:ref:`atomic_two_option@atomic_sparsity` pattern for\n:math:`V(x) \\in \\B{R}^{n \\times q}` which is defined by\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   V(x)\n   & = &\n   \\partial_u [ \\partial_x (g \\circ f) ( x + R u )  ]_{u=0}\n   \\\\\n   & = &\n   \\partial_u [ (g \\circ f)^{(1)}( x + R u )  ]_{u=0}\n   \\\\\n   & = &\n   (g \\circ f)^{(2)}( x ) R\n   \\\\\n   & = &\n   f^{(1)} (x)^\\R{T} g^{(2)} [ f(x) ] f^{(1)} (x)  R\n   +\n   \\sum_{i=1}^m g_i^{(1)} [ f(x) ] \\; f_i^{(2)} (x) R\n   \\\\\n   & = &\n   f^{(1)} (x)^\\R{T} U(x)\n   +\n   \\sum_{i=1}^m S_i (x) \\; f_i^{(2)} (x) R\n   \\end{eqnarray}\n\nx\n=\nThe argument has prototype\n\n   ``const CppAD::vector<`` *Base* >& *x*\n\nand size is equal to the *n* .\nThis is the :ref:`Value-name`  corresponding to the parameters in the\nvector :ref:`atomic_two_afun@ax` (when the atomic function was called).\nTo be specific, if\n\n| |tab| ``if`` ( ``Parameter`` ( *ax* [ *i* ]) == ``true`` )\n| |tab| |tab| *x* [ *i* ] = ``Value`` ( *ax* [ *i* ] );\n| |tab| ``else``\n| |tab| |tab| *x* [ *i* ] = ``CppAD::numeric_limits<`` *Base* >:: ``quiet_NaN`` ();\n\nThe version of this function with out the *x* argument is deprecated;\ni.e., you should include the argument even if you do not use it.\n\n{xrst_end atomic_two_rev_sparse_hes}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/two_rev_sparse_hes.hpp\nAtomic reverse mode Hessian sparsity patterns.\n*/\n/*!\nLink from reverse Hessian sparsity sweep to atomic_base\n\n\\param vx [in]\nwhich components of x are variables.\n\n\\param s [in]\nis the reverse Jacobian sparsity pattern w.r.t the result vector y.\n\n\\param t [out]\nis the reverse Jacobian sparsity pattern w.r.t the argument vector x.\n\n\\param q [in]\nis the column dimension for the sparsity patterns.\n\n\\param r [in]\nis the forward Jacobian sparsity pattern w.r.t the argument vector x\n\n\\param u [in]\nis the Hessian sparsity pattern w.r.t the result vector y.\n\n\\param v [out]\nis the Hessian sparsity pattern w.r.t the argument vector x.\n\n\\param x [in]\nis the integer value of the x arguments that are parameters.\n*/\ntemplate <class Base>\nbool atomic_base<Base>::rev_sparse_hes(\n   const vector<bool>&                     vx ,\n   const vector<bool>&                     s  ,\n          vector<bool>&                     t  ,\n   size_t                                  q  ,\n   const vector< std::set<size_t> >&       r  ,\n   const vector< std::set<size_t> >&       u  ,\n          vector< std::set<size_t> >&       v  ,\n   const vector<Base>&                     x  )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::rev_sparse_hes(\n   const vector<bool>&                     vx ,\n   const vector<bool>&                     s  ,\n          vector<bool>&                     t  ,\n   size_t                                  q  ,\n   const vector<bool>&                     r  ,\n   const vector<bool>&                     u  ,\n          vector<bool>&                     v  ,\n   const vector<Base>&                     x  )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::rev_sparse_hes(\n   const vector<bool>&                     vx ,\n   const vector<bool>&                     s  ,\n          vector<bool>&                     t  ,\n   size_t                                  q  ,\n   const vectorBool&                       r  ,\n   const vectorBool&                       u  ,\n          vectorBool&                       v  ,\n   const vector<Base>&                     x  )\n{  return false; }\n// deprecated\ntemplate <class Base>\nbool atomic_base<Base>::rev_sparse_hes(\n   const vector<bool>&                     vx ,\n   const vector<bool>&                     s  ,\n          vector<bool>&                     t  ,\n   size_t                                  q  ,\n   const vector< std::set<size_t> >&       r  ,\n   const vector< std::set<size_t> >&       u  ,\n          vector< std::set<size_t> >&       v  )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::rev_sparse_hes(\n   const vector<bool>&                     vx ,\n   const vector<bool>&                     s  ,\n          vector<bool>&                     t  ,\n   size_t                                  q  ,\n   const vector<bool>&                     r  ,\n   const vector<bool>&                     u  ,\n          vector<bool>&                     v  )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::rev_sparse_hes(\n   const vector<bool>&                     vx ,\n   const vector<bool>&                     s  ,\n          vector<bool>&                     t  ,\n   size_t                                  q  ,\n   const vectorBool&                       r  ,\n   const vectorBool&                       u  ,\n          vectorBool&                       v  )\n{  return false; }\n/*!\nLink, before case split, from rev_hes_sweep to atomic_base.\n\n\\tparam InternalSparsity\nIs the used internally for sparsity calculations; i.e.,\nsparse_pack or sparse_list.\n\n\\param x\nis parameter arguments to the function, other components are nan.\n\n\\param x_index\nis the variable index, on the tape, for the arguments to this function.\nThis size of x_index is n, the number of arguments to this function.\n\n\\param y_index\nis the variable index, on the tape, for the results for this function.\nThis size of y_index is m, the number of results for this function.\n\n\\param for_jac_sparsity\nOn input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nis the forward Jacobian sparsity for the j-th argument to this atomic function.\n\n\\param rev_jac_flag\nThis shows which variables affect the function we are\ncomputing the Hessian of.\nOn input, for i = 0, ... , m-1, the rev_jac_flag[ y_index[i] ] is true\nif the Jacobian of function (we are computing sparsity for) is no-zero.\nUpon return, for j = 0, ... , n-1, rev_jac_flag [ x_index[j] ]\nas been adjusted to account removing this atomic function.\n\n\\param rev_hes_sparsity\nThis is the sparsity pattern for the Hessian.\nOn input, for i = 0, ... , m-1, row y_index[i] is the reverse Hessian sparsity\nwith one of the partials with respect to to y_index[i].\n*/\ntemplate <class Base>\ntemplate <class InternalSparsity>\nbool atomic_base<Base>::rev_sparse_hes(\n   const vector<Base>&              x                ,\n   const vector<size_t>&            x_index          ,\n   const vector<size_t>&            y_index          ,\n   const InternalSparsity&          for_jac_sparsity ,\n   bool*                            rev_jac_flag     ,\n   InternalSparsity&                rev_hes_sparsity )\n{  CPPAD_ASSERT_UNKNOWN( for_jac_sparsity.end() == rev_hes_sparsity.end() );\n   //\n   // pod_x_index, pod_y_index\n   local::pod_vector<size_t> pod_x_index( x_index.size() );\n   local::pod_vector<size_t> pod_y_index( y_index.size() );\n   for(size_t j = 0; j < x_index.size(); ++j)\n      pod_x_index[j] = x_index[j];\n   for(size_t i = 0; i < y_index.size(); ++i)\n      pod_y_index[i] = y_index[i];\n   //\n   size_t q           = rev_hes_sparsity.end();\n   size_t n           = pod_x_index.size();\n   size_t m           = pod_y_index.size();\n   bool   ok          = false;\n   size_t thread      = thread_alloc::thread_num();\n   allocate_work(thread);\n   bool   zero_empty  = true;\n   bool   input_empty = false;\n   bool   transpose   = false;\n   //\n   // vx\n   vector<bool> vx(n);\n   for(size_t j = 0; j < n; j++)\n      vx[j] = pod_x_index[j] != 0;\n   //\n   // note that s and t are vectors so transpose does not matter for bool case\n   vector<bool> bool_s( work_[thread]->bool_s );\n   vector<bool> bool_t( work_[thread]->bool_t );\n   //\n   bool_s.resize(m);\n   bool_t.resize(n);\n   //\n   for(size_t i = 0; i < m; i++)\n   {  if( pod_y_index[i] > 0  )\n         bool_s[i] = rev_jac_flag[ pod_y_index[i] ];\n   }\n   //\n   std::string msg = \": atomic_base.rev_sparse_hes: returned false\";\n   if( sparsity_ == pack_sparsity_enum )\n   {  vectorBool&  pack_r( work_[thread]->pack_r );\n      vectorBool&  pack_u( work_[thread]->pack_u );\n      vectorBool&  pack_v( work_[thread]->pack_h );\n      //\n      pack_v.resize(n * q);\n      //\n      local::sparse::get_internal_pattern(\n         transpose, pod_x_index, for_jac_sparsity, pack_r\n      );\n      local::sparse::get_internal_pattern(\n         transpose, pod_y_index, rev_hes_sparsity, pack_u\n      );\n      //\n      ok = rev_sparse_hes(vx, bool_s, bool_t, q, pack_r, pack_u, pack_v, x);\n      if( ! ok )\n         ok = rev_sparse_hes(vx, bool_s, bool_t, q, pack_r, pack_u, pack_v);\n      if( ! ok )\n      {  msg = atomic_name() + msg + \" sparsity = pack_sparsity_enum\";\n         CPPAD_ASSERT_KNOWN(false, msg.c_str());\n      }\n      local::sparse::set_internal_pattern(zero_empty, input_empty,\n         transpose, pod_x_index, rev_hes_sparsity, pack_v\n      );\n   }\n   else if( sparsity_ == bool_sparsity_enum )\n   {  vector<bool>&  bool_r( work_[thread]->bool_r );\n      vector<bool>&  bool_u( work_[thread]->bool_u );\n      vector<bool>&  bool_v( work_[thread]->bool_h );\n      //\n      bool_v.resize(n * q);\n      //\n      local::sparse::get_internal_pattern(\n         transpose, pod_x_index, for_jac_sparsity, bool_r\n      );\n      local::sparse::get_internal_pattern(\n         transpose, pod_y_index, rev_hes_sparsity, bool_u\n      );\n      //\n      ok = rev_sparse_hes(vx, bool_s, bool_t, q, bool_r, bool_u, bool_v, x);\n      if( ! ok )\n         ok = rev_sparse_hes(vx, bool_s, bool_t, q, bool_r, bool_u, bool_v);\n      if( ! ok )\n      {  msg = atomic_name() + msg + \" sparsity = bool_sparsity_enum\";\n         CPPAD_ASSERT_KNOWN(false, msg.c_str());\n      }\n      local::sparse::set_internal_pattern(zero_empty, input_empty,\n         transpose, pod_x_index, rev_hes_sparsity, bool_v\n      );\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( sparsity_ == set_sparsity_enum );\n      vector< std::set<size_t> >&  set_r( work_[thread]->set_r );\n      vector< std::set<size_t> >&  set_u( work_[thread]->set_u );\n      vector< std::set<size_t> >&  set_v( work_[thread]->set_h );\n      //\n      set_v.resize(n);\n      //\n      local::sparse::get_internal_pattern(\n         transpose, pod_x_index, for_jac_sparsity, set_r\n      );\n      local::sparse::get_internal_pattern(\n         transpose, pod_y_index, rev_hes_sparsity, set_u\n      );\n      //\n      ok = rev_sparse_hes(vx, bool_s, bool_t, q, set_r, set_u, set_v, x);\n      if( ! ok )\n         ok = rev_sparse_hes(vx, bool_s, bool_t, q, set_r, set_u, set_v);\n      if( ! ok )\n      {  msg = atomic_name() + msg + \" sparsity = set_sparsity_enum\";\n         CPPAD_ASSERT_KNOWN(false, msg.c_str());\n      }\n      local::sparse::set_internal_pattern(zero_empty, input_empty,\n         transpose, pod_x_index, rev_hes_sparsity, set_v\n      );\n   }\n   for(size_t j = 0; j < n; j++)\n   {  if( pod_x_index[j] > 0  )\n         rev_jac_flag[ pod_x_index[j] ] |= bool_t[j];\n   }\n   return ok;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/two/rev_sparse_jac.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_TWO_REV_SPARSE_JAC_HPP\n# define CPPAD_CORE_ATOMIC_TWO_REV_SPARSE_JAC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_two_rev_sparse_jac app}\n{xrst_spell\n   rt\n}\n\nAtomic Reverse Jacobian Sparsity Patterns\n#########################################\n\nSyntax\n******\n| *ok* = *afun* . ``rev_sparse_jac`` ( *q* , *rt* , *st* , *x* )\n\nDeprecated 2016-06-27\n*********************\n\n   *ok* = *afun* . ``rev_sparse_jac`` ( *q* , *rt* , *st* )\n\nPurpose\n*******\nThis function is used by\n:ref:`RevSparseJac-name` to compute\nJacobian sparsity patterns.\nIf you are using :ref:`RevSparseJac-name` ,\none of the versions of this\nvirtual function must be defined by the\n:ref:`atomic_two_ctor@atomic_user` class.\n\nFor a fixed matrix :math:`R \\in \\B{R}^{q \\times m}`,\nthe Jacobian of :math:`R * f( x )` with respect to :math:`x \\in \\B{R}^n` is\n\n.. math::\n\n   S(x) = R * f^{(1)} (x)\n\nGiven a :ref:`glossary@Sparsity Pattern` for :math:`R`,\n``rev_sparse_jac`` computes a sparsity pattern for :math:`S(x)`.\n\nImplementation\n**************\nIf you are using\n:ref:`RevSparseJac-name` or :ref:`ForSparseHes-name` ,\nthis virtual function must be defined by the\n:ref:`atomic_two_ctor@atomic_user` class.\n\nq\n=\nThe argument *q* has prototype\n\n   ``size_t`` *q*\n\nIt specifies the number of rows in\n:math:`R \\in \\B{R}^{q \\times m}` and the Jacobian\n:math:`S(x) \\in \\B{R}^{q \\times n}`.\n\nrt\n==\nThis argument has prototype\n\n   ``const`` *atomic_sparsity* & *rt*\n\nand is a\n:ref:`atomic_two_option@atomic_sparsity` pattern for\n:math:`R^\\R{T} \\in \\B{R}^{m \\times q}`.\n\nst\n==\nThis argument has prototype\n\n   *atomic_sparsity* & *st*\n\nThe input value of its elements\nare not specified (must not matter).\nUpon return, *s* is a\n:ref:`atomic_two_option@atomic_sparsity` pattern for\n:math:`S(x)^\\R{T} \\in \\B{R}^{n \\times q}`.\n\nx\n=\nThe argument has prototype\n\n   ``const CppAD::vector<`` *Base* >& *x*\n\nand size is equal to the *n* .\nThis is the :ref:`Value-name` corresponding to the parameters in the\nvector :ref:`atomic_two_afun@ax` (when the atomic function was called).\nTo be specific, if\n\n| |tab| ``if`` ( ``Parameter`` ( *ax* [ *i* ]) == ``true`` )\n| |tab| |tab| *x* [ *i* ] = ``Value`` ( *ax* [ *i* ] );\n| |tab| ``else``\n| |tab| |tab| *x* [ *i* ] = ``CppAD::numeric_limits<`` *Base* >:: ``quiet_NaN`` ();\n\nThe version of this function with out the *x* argument is deprecated;\ni.e., you should include the argument even if you do not use it.\n\nok\n**\nThe return value *ok* has prototype\n\n   ``bool`` *ok*\n\nIf it is ``true`` , the corresponding evaluation succeeded,\notherwise it failed.\n\n{xrst_end atomic_two_rev_sparse_jac}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/two_rev_sparse_jac.hpp\nAtomic reverse mode Jacobian sparsity patterns.\n*/\n/*!\nLink, after case split, from rev_jac_sweep to atomic_base\n\n\\param q [in]\nis the row dimension for the Jacobian sparsity patterns\n\n\\param rt [out]\nis the tansposed Jacobian sparsity pattern w.r.t to range variables y\n\n\\param st [in]\nis the tansposed Jacobian sparsity pattern for the argument variables x\n\n\\param x\nis the integer value for x arguments that are parameters.\n*/\ntemplate <class Base>\nbool atomic_base<Base>::rev_sparse_jac(\n   size_t                                  q  ,\n   const vector< std::set<size_t> >&       rt ,\n          vector< std::set<size_t> >&       st ,\n   const vector<Base>&                     x  )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::rev_sparse_jac(\n   size_t                                  q  ,\n   const vector<bool>&                     rt ,\n          vector<bool>&                     st ,\n   const vector<Base>&                     x  )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::rev_sparse_jac(\n   size_t                                  q  ,\n   const vectorBool&                       rt ,\n          vectorBool&                       st ,\n   const vector<Base>&                     x  )\n{  return false; }\n// deprecated versions\ntemplate <class Base>\nbool atomic_base<Base>::rev_sparse_jac(\n   size_t                                  q  ,\n   const vector< std::set<size_t> >&       rt ,\n          vector< std::set<size_t> >&       st )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::rev_sparse_jac(\n   size_t                                  q  ,\n   const vector<bool>&                     rt ,\n          vector<bool>&                     st )\n{  return false; }\ntemplate <class Base>\nbool atomic_base<Base>::rev_sparse_jac(\n   size_t                                  q  ,\n   const vectorBool&                       rt ,\n          vectorBool&                       st )\n{  return false; }\n\n/*!\nLink, before case split, from rev_jac_sweep to atomic_base.\n\n\\tparam InternalSparsity\nIs the used internally for sparsity calculations; i.e.,\nsparse_pack or sparse_list.\n\n\\param x\nis parameter arguments to the function, other components are nan.\n\n\\param x_index\nis the variable index, on the tape, for the arguments to this function.\nThis size of x_index is n, the number of arguments to this function.\n\n\\param y_index\nis the variable index, on the tape, for the results for this function.\nThis size of y_index is m, the number of results for this function.\n\n\\param var_sparsity\nOn input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i],\nis the sparsity for the i-th argument to this atomic function.\nOn output, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nthe sparsity has been updated to remove y as a function of x.\n*/\ntemplate <class Base>\ntemplate <class InternalSparsity>\nbool atomic_base<Base>::rev_sparse_jac(\n   const vector<Base>&              x            ,\n   const vector<size_t>&            x_index      ,\n   const vector<size_t>&            y_index      ,\n   InternalSparsity&                var_sparsity )\n{  //\n   // pod_x_index, pod_y_index\n   local::pod_vector<size_t> pod_x_index( x_index.size() );\n   local::pod_vector<size_t> pod_y_index( y_index.size() );\n   for(size_t j = 0; j < x_index.size(); ++j)\n      pod_x_index[j] = x_index[j];\n   for(size_t i = 0; i < y_index.size(); ++i)\n      pod_y_index[i] = y_index[i];\n   //\n   // initial results may be non-empty during reverse mode\n   size_t q           = var_sparsity.end();\n   bool   input_empty = false;\n   bool   zero_empty  = true;\n   bool   transpose   = false;\n   size_t n           = pod_x_index.size();\n   bool   ok          = false;\n   size_t thread      = thread_alloc::thread_num();\n   allocate_work(thread);\n   //\n   std::string msg    = \": atomic_base.rev_sparse_jac: returned false\";\n   if( sparsity_ == pack_sparsity_enum )\n   {  vectorBool& pack_rt ( work_[thread]->pack_r );\n      vectorBool& pack_st ( work_[thread]->pack_s );\n      local::sparse::get_internal_pattern(\n         transpose, pod_y_index, var_sparsity, pack_rt\n      );\n      //\n      pack_st.resize(n * q );\n      ok = rev_sparse_jac(q, pack_rt, pack_st, x);\n      if( ! ok )\n         ok = rev_sparse_jac(q, pack_rt, pack_st);\n      if( ! ok )\n      {  msg = atomic_name() + msg + \" sparsity = pack_sparsity_enum\";\n         CPPAD_ASSERT_KNOWN(false, msg.c_str());\n      }\n      local::sparse::set_internal_pattern(zero_empty, input_empty,\n         transpose, pod_x_index, var_sparsity, pack_st\n      );\n   }\n   else if( sparsity_ == bool_sparsity_enum )\n   {  vector<bool>& bool_rt ( work_[thread]->bool_r );\n      vector<bool>& bool_st ( work_[thread]->bool_s );\n      local::sparse::get_internal_pattern(\n         transpose, pod_y_index, var_sparsity, bool_rt\n      );\n      bool_st.resize(n * q );\n      ok = rev_sparse_jac(q, bool_rt, bool_st, x);\n      if( ! ok )\n         ok = rev_sparse_jac(q, bool_rt, bool_st);\n      if( ! ok )\n      {  msg = atomic_name() + msg + \" sparsity = bool_sparsity_enum\";\n         CPPAD_ASSERT_KNOWN(false, msg.c_str());\n      }\n      local::sparse::set_internal_pattern(zero_empty, input_empty,\n         transpose, pod_x_index, var_sparsity, bool_st\n      );\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( sparsity_ == set_sparsity_enum );\n      vector< std::set<size_t> >& set_rt ( work_[thread]->set_r );\n      vector< std::set<size_t> >& set_st ( work_[thread]->set_s );\n      local::sparse::get_internal_pattern(\n         transpose, pod_y_index, var_sparsity, set_rt\n      );\n      set_st.resize(n);\n      ok = rev_sparse_jac(q, set_rt, set_st, x);\n      if( ! ok )\n         ok = rev_sparse_jac(q, set_rt, set_st);\n      if( ! ok )\n      {  msg = atomic_name() + msg + \" sparsity = set_sparsity_enum\";\n         CPPAD_ASSERT_KNOWN(false, msg.c_str());\n      }\n      local::sparse::set_internal_pattern(zero_empty, input_empty,\n         transpose, pod_x_index, var_sparsity, set_st\n      );\n   }\n   return ok;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/atomic/two/reverse.hpp",
    "content": "# ifndef CPPAD_CORE_ATOMIC_TWO_REVERSE_HPP\n# define CPPAD_CORE_ATOMIC_TWO_REVERSE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_two_reverse app}\n{xrst_spell\n   apx\n   apy\n   atx\n   aty\n   px\n   py\n   tx\n}\n\nAtomic Reverse Mode\n###################\n\nSyntax\n******\n\nBase\n====\n\n   *ok* = *afun* . ``reverse`` ( *q* , *tx* , *ty* , *px* , *py* )\n\nThis syntax is used by *f* . ``Forward`` where *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nand *afun* is used in *f* .\n\nAD<Base>\n========\n\n   *ok* = *afun* . ``reverse`` ( *q* , *atx* , *aty* , *apx* , *apy* )\n\nThis syntax is used by *af* . ``Forward`` where *af* has prototype\n\n   ``ADFun< AD<`` *Base* > , *Base* > *af*\n\nand *afun* is used in *af* (see :ref:`base2ad-name` ).\n\nPurpose\n*******\nThis function is used by :ref:`Reverse-name`\nto compute derivatives.\n\nImplementation\n**************\nIf you are using\n:ref:`Reverse-name` mode,\nthis virtual function must be defined by the\n:ref:`atomic_two_ctor@atomic_user` class.\nIt can just return *ok* == ``false``\n(and not compute anything) for values\nof *q* that are greater than those used by your\n:ref:`Reverse-name` mode calculations.\n\nq\n*\nThe argument *q* has prototype\n\n   ``size_t`` *q*\n\nIt specifies the highest order Taylor coefficient that\ncomputing the derivative of.\n\ntx\n**\nThe argument *tx* has prototype\n\n   ``const CppAD::vector<`` *Base* >& *tx*\n\nand *tx* . ``size`` () == ( *q* +1)* *n* .\nFor :math:`j = 0 , \\ldots , n-1` and :math:`k = 0 , \\ldots , q`,\nwe use the Taylor coefficient notation\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      x_j^k    & = & tx [ j * ( q + 1 ) + k ]\n      \\\\\n      X_j (t)  & = & x_j^0 + x_j^1 t^1 + \\cdots + x_j^q t^q\n   \\end{eqnarray}\n\nNote that superscripts represent an index for :math:`x_j^k`\nand an exponent for :math:`t^k`.\nAlso note that the Taylor coefficients for :math:`X(t)` correspond\nto the derivatives of :math:`X(t)` at :math:`t = 0` in the following way:\n\n.. math::\n\n   x_j^k = \\frac{1}{ k ! } X_j^{(k)} (0)\n\natx\n***\nThe argument *atx* has prototype\n\n   ``const CppAD::vector< AD<`` *Base* > >& *atx*\n\nOtherwise, *atx* specifications are the same as for *tx* .\n\nty\n**\nThe argument *ty* has prototype\n\n   ``const CppAD::vector<`` *Base* >& *ty*\n\nand *tx* . ``size`` () == ( *q* +1)* *m* .\nFor :math:`i = 0 , \\ldots , m-1` and :math:`k = 0 , \\ldots , q`,\nwe use the Taylor coefficient notation\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      Y_i (t)  & = & f_i [ X(t) ]\n      \\\\\n      Y_i (t)  & = & y_i^0 + y_i^1 t^1 + \\cdots + y_i^q t^q + o ( t^q )\n      \\\\\n      y_i^k    & = & ty [ i * ( q + 1 ) + k ]\n   \\end{eqnarray}\n\nwhere :math:`o( t^q ) / t^q \\rightarrow 0` as :math:`t \\rightarrow 0`.\nNote that superscripts represent an index for :math:`y_j^k`\nand an exponent for :math:`t^k`.\nAlso note that the Taylor coefficients for :math:`Y(t)` correspond\nto the derivatives of :math:`Y(t)` at :math:`t = 0` in the following way:\n\n.. math::\n\n   y_j^k = \\frac{1}{ k ! } Y_j^{(k)} (0)\n\naty\n***\nThe argument *aty* has prototype\n\n   ``const CppAD::vector< AD<`` *Base* > >& *aty*\n\nOtherwise, *aty* specifications are the same as for *ty* .\n\nF\n*\nWe use the notation :math:`\\{ x_j^k \\} \\in \\B{R}^{n \\times (q+1)}` for\n\n.. math::\n\n   \\{ x_j^k \\W{:} j = 0 , \\ldots , n-1, k = 0 , \\ldots , q \\}\n\nWe use the notation :math:`\\{ y_i^k \\} \\in \\B{R}^{m \\times (q+1)}` for\n\n.. math::\n\n   \\{ y_i^k \\W{:} i = 0 , \\ldots , m-1, k = 0 , \\ldots , q \\}\n\nWe define the function\n:math:`F : \\B{R}^{n \\times (q+1)} \\rightarrow \\B{R}^{m \\times (q+1)}` by\n\n.. math::\n\n   y_i^k = F_i^k [ \\{ x_j^k \\} ]\n\nNote that\n\n.. math::\n\n   F_i^0 ( \\{ x_j^k \\} ) = f_i ( X(0) )  = f_i ( x^0 )\n\nWe also note that\n:math:`F_i^\\ell ( \\{ x_j^k \\} )` is a function of\n:math:`x^0 , \\ldots , x^\\ell`\nand is determined by the derivatives of :math:`f_i (x)`\nup to order :math:`\\ell`.\n\nG, H\n****\nWe use :math:`G : \\B{R}^{m \\times (q+1)} \\rightarrow \\B{R}`\nto denote an arbitrary scalar valued function of :math:`\\{ y_i^k \\}`.\nWe use :math:`H : \\B{R}^{n \\times (q+1)} \\rightarrow \\B{R}`\ndefined by\n\n.. math::\n\n   H ( \\{ x_j^k \\} ) = G[ F( \\{ x_j^k \\} ) ]\n\npy\n**\nThe argument *py* has prototype\n\n   ``const CppAD::vector<`` *Base* >& *py*\n\nand *py* . ``size`` () == ``m`` * ( *q* +1) .\nFor :math:`i = 0 , \\ldots , m-1`, :math:`k = 0 , \\ldots , q`,\n\n.. math::\n\n   py[ i * (q + 1 ) + k ] = \\partial G / \\partial y_i^k\n\napy\n***\nThe argument *apy* has prototype\n\n   ``const CppAD::vector< AD<`` *Base* > >& *apy*\n\nOtherwise, *apy* specifications are the same as for *py* .\n\npx\n==\nThe *px* has prototype\n\n   ``CppAD::vector<`` *Base* >& *px*\n\nand *px* . ``size`` () == ``n`` * ( *q* +1) .\nThe input values of the elements of *px*\nare not specified (must not matter).\nUpon return,\nfor :math:`j = 0 , \\ldots , n-1` and :math:`\\ell = 0 , \\ldots , q`,\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   px [ j * (q + 1) + \\ell ] & = & \\partial H / \\partial x_j^\\ell\n   \\\\\n   & = &\n   ( \\partial G / \\partial \\{ y_i^k \\} ) \\cdot\n      ( \\partial \\{ y_i^k \\} / \\partial x_j^\\ell )\n   \\\\\n   & = &\n   \\sum_{k=0}^q\n   \\sum_{i=0}^{m-1}\n   ( \\partial G / \\partial y_i^k ) ( \\partial y_i^k / \\partial x_j^\\ell )\n   \\\\\n   & = &\n   \\sum_{k=\\ell}^q\n   \\sum_{i=0}^{m-1}\n   py[ i * (q + 1 ) + k ] ( \\partial F_i^k / \\partial x_j^\\ell )\n   \\end{eqnarray}\n\nNote that we have used the fact that for :math:`k < \\ell`,\n:math:`\\partial F_i^k / \\partial x_j^\\ell = 0`.\n\napx\n***\nThe argument *apx* has prototype\n\n   ``CppAD::vector< AD<`` *Base* > >& *apx*\n\nOtherwise, *apx* specifications are the same as for *px* .\n\nok\n**\nThe return value *ok* has prototype\n\n   ``bool`` *ok*\n\nIf it is ``true`` , the corresponding evaluation succeeded,\notherwise it failed.\n\n{xrst_end atomic_two_reverse}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file atomic/two_reverse.hpp\nAtomic reverse mode.\n*/\n/*!\nLink from reverse mode sweep to users routine.\n\n\\param q [in]\nhighest order for this reverse mode calculation.\n\n\\param tx [in]\nTaylor coefficients corresponding to x for this calculation.\n\n\\param ty [in]\nTaylor coefficient corresponding to y for this calculation\n\n\\param px [out]\nPartials w.r.t. the x Taylor coefficients.\n\n\\param py [in]\nPartials w.r.t. the y Taylor coefficients.\n\nSee atomic_reverse mode use documentation\n*/\ntemplate <class Base>\nbool atomic_base<Base>::reverse(\n   size_t                    q  ,\n   const vector<Base>&       tx ,\n   const vector<Base>&       ty ,\n          vector<Base>&       px ,\n   const vector<Base>&       py )\n{  return false; }\n\ntemplate <class Base>\nbool atomic_base<Base>::reverse(\n   size_t                    q  ,\n   const vector< AD<Base> >& atx ,\n   const vector< AD<Base> >& aty ,\n          vector< AD<Base> >& apx ,\n   const vector< AD<Base> >& apy )\n{  return false; }\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/azmul.hpp",
    "content": "# ifndef CPPAD_CORE_AZMUL_HPP\n# define CPPAD_CORE_AZMUL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin azmul}\n{xrst_spell\n   ieee\n}\n\nAbsolute Zero Multiplication\n############################\n\nSyntax\n******\n| *z* = ``azmul`` ( *x* , *y* )\n\nPurpose\n*******\nEvaluates multiplication with an absolute zero\nfor any of the possible types listed below.\nThe result is given by\n\n.. math::\n\n   z = \\left\\{ \\begin{array}{ll}\n      0          & {\\rm if} \\; x = 0 \\\\\n      x \\cdot y  & {\\rm otherwise}\n   \\end{array} \\right.\n\nNote if *x* is zero and *y* is infinity,\nieee multiplication would result in not a number whereas\n*z* would be zero.\n\nBase\n****\nIf *Base* satisfies the\n:ref:`base type requirements<base_require-name>`\nand arguments *x* , *y* have prototypes\n\n| |tab| ``const`` *Base* & *x*\n| |tab| ``const`` *Base* & *y*\n\nthen the result *z* has prototype\n\n   *Base* *z*\n\nAD<Base>\n********\nIf the arguments *x* , *y* have prototype\n\n| |tab| ``const AD`` < *Base* >& *x*\n| |tab| ``const AD`` < *Base* >& *y*\n\nthen the result *z* has prototype\n\n   ``AD`` < *Base* > *z*\n\nVecAD<Base>\n***********\nIf the arguments *x* , *y* have prototype\n\n| |tab| ``const VecAD`` < *Base* >:: ``reference&`` *x*\n| |tab| ``const VecAD`` < *Base* >:: ``reference&`` *y*\n\nthen the result *z* has prototype\n\n   ``AD`` < *Base* > *z*\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/azmul.cpp\n}\nThe file\n:ref:`azmul.cpp-name`\nis an examples and tests of this function.\n\n{xrst_end azmul}\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n// ==========================================================================\n\n// case where x and y are AD<Base> -------------------------------------------\ntemplate <class Base> AD<Base>\nazmul(const AD<Base>& x, const AD<Base>& y)\n{\n   // compute the Base part\n   AD<Base> result;\n   result.value_ = azmul(x.value_, y.value_);\n\n   // check if there is a recording in progress\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if x and y tapes match\n   bool match_x  = x.tape_id_  == tape_id;\n   bool match_y  = y.tape_id_  == tape_id;\n\n   // check if x and y are dynamic parameters\n   bool dyn_x  = match_x  & (x.ad_type_ == dynamic_enum);\n   bool dyn_y  = match_y  & (y.ad_type_ == dynamic_enum);\n\n   // check if x and y are variables\n   bool var_x  = match_x  & (x.ad_type_ != dynamic_enum);\n   bool var_y  = match_y  & (y.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      x.tape_id_ == y.tape_id_ || ! match_x || ! match_y ,\n      \"azmul: AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_x )\n   {  if( var_y )\n      {  // result = azmul(variable, variable)\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::ZmulvvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::ZmulvvOp) == 2 );\n\n         // put operand addresses in tape\n         tape->Rec_.PutArg(x.taddr_, y.taddr_);\n\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::ZmulvvOp);\n\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n      else if( ( ! dyn_y ) && IdenticalZero( y.value_ ) )\n      {  // result = variable * 0\n      }\n      else if( ( ! dyn_y ) && IdenticalOne( y.value_ ) )\n      {  // result = variable * 1\n         result.make_variable(x.tape_id_, x.taddr_);\n      }\n      else\n      {  // result = zmul(variable, parameter)\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::ZmulvpOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::ZmulvpOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = y.taddr_;\n         if( ! dyn_y )\n            p = tape->Rec_.put_con_par(y.value_);\n         tape->Rec_.PutArg(x.taddr_, p);\n\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::ZmulvpOp);\n\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n   }\n   else if( var_y )\n   {  if( ( ! dyn_x ) && IdenticalZero(x.value_) )\n      {  // result = 0 * variable\n      }\n      else if( ( ! dyn_x ) && IdenticalOne( x.value_ ) )\n      {  // result = 1 * variable\n         result.make_variable(y.tape_id_, y.taddr_);\n      }\n      else\n      {  // result = zmul(parameter, variable)\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::ZmulpvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::ZmulpvOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = x.taddr_;\n         if( ! dyn_x )\n            p = tape->Rec_.put_con_par(x.value_);\n         tape->Rec_.PutArg(p, y.taddr_);\n\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::ZmulpvOp);\n\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n   }\n   else if( dyn_x | dyn_y )\n   {  if( (! dyn_x) && IdenticalZero(x.value_) )\n      {   // result = 0 * dynamic\n      }\n      else if ( ( ! dyn_y ) && IdenticalZero(y.value_) )\n      {   // result = dynamic * 0\n      }\n      else if( ( ! dyn_x ) && IdenticalOne(x.value_) )\n      {   // result = 1 * dynamic\n         result.make_dynamic(y.tape_id_, y.taddr_);\n      }\n      else if( ( ! dyn_y ) && IdenticalOne(y.value_) )\n      {   // result = dynamic * 1\n         result.make_dynamic(x.tape_id_, x.taddr_ );\n      }\n      else\n      {\n         addr_t arg0 = x.taddr_;\n         addr_t arg1 = y.taddr_;\n         if( ! dyn_x )\n         arg0 = tape->Rec_.put_con_par(x.value_);\n         if( ! dyn_y )\n         arg1 = tape->Rec_.put_con_par(y.value_);\n         //\n         // parameters with a dynamic parameter result\n         result.taddr_   = tape->Rec_.put_dyn_par(\n            result.value_, local::zmul_dyn,   arg0, arg1\n         );\n         result.tape_id_ = tape_id;\n         result.ad_type_ = dynamic_enum;\n      }\n   }\n   return result;\n}\n// =========================================================================\n// Fold operations into case above\n// -------------------------------------------------------------------------\n// Operations with VecAD_reference<Base> and AD<Base> only\n\ntemplate <class Base> AD<Base>\nazmul(const AD<Base>& x, const VecAD_reference<Base>& y)\n{  return azmul(x, y.ADBase()); }\n\ntemplate <class Base> AD<Base>\nazmul(const VecAD_reference<Base>& x, const VecAD_reference<Base>& y)\n{  return azmul(x.ADBase(), y.ADBase()); }\n\ntemplate <class Base> AD<Base>\nazmul(const VecAD_reference<Base>& x, const AD<Base>& y)\n{  return azmul(x.ADBase(), y); }\n// -------------------------------------------------------------------------\n// Operations with Base\n\ntemplate <class Base> AD<Base>\nazmul(const Base& x, const AD<Base>& y)\n{  return azmul(AD<Base>(x), y); }\n\ntemplate <class Base> AD<Base>\nazmul(const Base& x, const VecAD_reference<Base>& y)\n{  return azmul(AD<Base>(x), y.ADBase()); }\n\ntemplate <class Base> AD<Base>\nazmul(const AD<Base>& x, const Base& y)\n{  return azmul(x, AD<Base>(y)); }\n\ntemplate <class Base> AD<Base>\nazmul(const VecAD_reference<Base>& x, const Base& y)\n{  return azmul(x.ADBase(), AD<Base>(y)); }\n\n// ==========================================================================\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/base2ad.hpp",
    "content": "# ifndef CPPAD_CORE_BASE2AD_HPP\n# define CPPAD_CORE_BASE2AD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin base2ad}\n\nCreate an AD<Base> Function From a Base Function\n################################################\n\nSyntax\n******\n| *af* = *f* . ``base2ad`` ()\n\nSee Also\n********\n:ref:`mul_level-name`\n\nBase\n****\nThis is the base type used to recorded the operation sequence in *f*\nand *af* ; i.e., the type ``AD`` < *Base* > was used to record\nthe operation sequence.\n\nf\n*\nThis object has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nIt does it's derivative calculations using the type *Base* .\n\naf\n**\nThis object has prototype\n\n   ``ADFun< AD<`` *Base* > , *Base* > *af*\n\nIt has the same operation sequence as *f* ,\nbut it does it's derivative calculations using the type\n``AD`` < *Base>* .\nThis enables one to record new functions that are defined\nusing derivatives of the function *f* .\nInitially, there are no Taylor coefficients stored in *af* and\n:ref:`af.size_order()<size_order-name>` is zero.\n{xrst_toc_hidden\n   example/general/base2ad.cpp\n   example/general/base2vec_ad.cpp\n}\nExample\n*******\nThe file :ref:`base2ad.cpp-name`\ncontains an example and test of this operation.\n\nVecAD\n*****\nForward mode on a ``base2ad`` function does not preserve\n:ref:`VecAD-name` operations (which might be expected); see the\n:ref:`base2vec_ad.cpp-name` example.\n\n{xrst_end base2ad}\n----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file base2ad.hpp\n*/\n/// Create an ADFun< AD<Base>, Base > from this ADFun<Base>\ntemplate <class Base, class RecBase>\nADFun< AD<Base>, RecBase > ADFun<Base,RecBase>::base2ad(void) const\n{  ADFun< AD<Base>, RecBase > fun;\n   //\n   // bool values\n   fun.has_been_optimized_        = has_been_optimized_;\n   fun.check_for_nan_             = check_for_nan_;\n   //\n   // size_t values\n   fun.compare_change_count_      = compare_change_count_;\n   fun.compare_change_number_     = compare_change_number_;\n   fun.compare_change_op_index_   = compare_change_op_index_;\n   CPPAD_ASSERT_UNKNOWN( fun.num_order_taylor_ == 0 ) ;\n   CPPAD_ASSERT_UNKNOWN( fun.cap_order_taylor_ == 0 );\n   CPPAD_ASSERT_UNKNOWN( fun.num_direction_taylor_ == 0 );\n   fun.num_var_tape_              = num_var_tape_;\n   //\n   // pod_vector objects\n   fun.ind_taddr_                 = ind_taddr_;\n   fun.dep_taddr_                 = dep_taddr_;\n   fun.dep_parameter_             = dep_parameter_;\n   fun.cskip_op_                  = cskip_op_;\n   fun.load_op2var_               = load_op2var_;\n   //\n   // pod_maybe_vector< AD<Base> > = pod_maybe_vector<Base>\n   CPPAD_ASSERT_UNKNOWN( fun.taylor_.size() == 0 );\n   //\n   // player\n   // (uses move semantics)\n   fun.play_ = play_.base2ad();\n   //\n   // subgraph\n   fun.subgraph_info_ = subgraph_info_;\n   //\n   // sparse_pack\n   fun.for_jac_sparse_pack_ = for_jac_sparse_pack_;\n   //\n   // sparse_list\n   fun.for_jac_sparse_set_  = for_jac_sparse_set_;\n   //\n   return fun;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/base_complex.hpp",
    "content": "# ifndef CPPAD_CORE_BASE_COMPLEX_HPP\n# define CPPAD_CORE_BASE_COMPLEX_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/configure.hpp>\n# include <limits>\n# include <complex>\n\n/*\n{xrst_begin base_complex.hpp}\n{xrst_spell\n   azmul\n   isnan\n}\n\nEnable use of AD<Base> where Base is std::complex<double>\n#########################################################\n{xrst_toc_hidden\n   example/general/complex_poly.cpp\n}\nExample\n*******\nThe file :ref:`complex_poly.cpp-name` contains an example use of\n``std::complex<double>`` type for a CppAD *Base* type.\n\nInclude Order\n*************\nThis file is included before ``<cppad/cppad.hpp>``\nso it is necessary to define the error handler\nin addition to including\n:ref:`base_require.hpp<base_require@Include Order>`\n{xrst_spell_off}\n{xrst_code cpp} */\n# include <limits>\n# include <complex>\n# include <cppad/base_require.hpp>\n# include <cppad/core/cppad_assert.hpp>\n\n/* {xrst_code}\n{xrst_spell_on}\n\nCondExpOp\n*********\nThe type ``std::complex<double>`` does not support the\n``<`` , ``<=`` , ``>=`` , and ``>`` operators; see\n:ref:`base_cond_exp@CondExpTemplate@Not Ordered` .\nHence these operators and ``CondExpOp`` function are defined by\n{xrst_spell_off}\n{xrst_code cpp} */\n# define CPPAD_TEMP(op)                                          \\\n   inline bool operator op(                                      \\\n      const std::complex<double>& left   ,                       \\\n      const std::complex<double>& right  )                       \\\n   {  CppAD::ErrorHandler::Call(                                 \\\n         true     , __LINE__ , __FILE__ ,                        \\\n         \"std::complex<double> \" #op \" std::complex<double>\" ,   \\\n         \"Error: std::complex is not an ordered type\"            \\\n      );                                                         \\\n      return false;                                              \\\n   }\nnamespace CppAD {\n   CPPAD_TEMP(<)\n   CPPAD_TEMP(<=)\n   CPPAD_TEMP(>=)\n   CPPAD_TEMP(>)\n   inline std::complex<double> CondExpOp(\n      enum CppAD::CompareOp      cop        ,\n      const std::complex<double> &left      ,\n      const std::complex<double> &right     ,\n      const std::complex<double> &trueCase  ,\n      const std::complex<double> &falseCase )\n   {  CppAD::ErrorHandler::Call(\n         true     , __LINE__ , __FILE__ ,\n         \"std::complex<float> CondExpOp(...)\",\n         \"Error: cannot use CondExp with a complex type\"\n      );\n      return std::complex<double>(0);\n   }\n}\n# undef CPPAD_TEMP\n/* {xrst_code}\n{xrst_spell_on}\n\n\nCondExpRel\n**********\nThe :ref:`CPPAD_COND_EXP_REL<base_cond_exp@CondExpRel>` macro invocation\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   CPPAD_COND_EXP_REL( std::complex<double> )\n}\n/* {xrst_code}\n{xrst_spell_on}\nused ``CondExpOp`` above to\ndefine ``CondExp`` *Rel* for ``std::complex<double>`` arguments\nand *Rel* equal to\n``Lt`` , ``Le`` , ``Eq`` , ``Ge`` , and ``Gt`` .\n\nEqualOpSeq\n**********\nComplex numbers do not carry operation sequence information.\nThus they are equal in this sense if and only if there values are equal.\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline bool EqualOpSeq(\n      const std::complex<double> &x ,\n      const std::complex<double> &y )\n   {  return x == y;\n   }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nIdentical\n*********\nComplex numbers do not carry operation sequence information.\nThus they are all parameters so the identical functions just check values.\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline bool IdenticalCon(const std::complex<double> &x)\n   {  return true; }\n   inline bool IdenticalZero(const std::complex<double> &x)\n   {  return (x == std::complex<double>(0., 0.) ); }\n   inline bool IdenticalOne(const std::complex<double> &x)\n   {  return (x == std::complex<double>(1., 0.) ); }\n   inline bool IdenticalEqualCon(\n      const std::complex<double> &x, const std::complex<double> &y)\n   {  return (x == y); }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nOrdered\n*******\nComplex types do not support comparison operators,\n{xrst_spell_off}\n{xrst_code cpp} */\n# undef  CPPAD_USER_MACRO\n# define CPPAD_USER_MACRO(Fun)                                     \\\ninline bool Fun(const std::complex<double>& x)                     \\\n{      CppAD::ErrorHandler::Call(                                  \\\n               true     , __LINE__ , __FILE__ ,                    \\\n               #Fun\"(x)\",                                          \\\n               \"Error: cannot use \" #Fun \" with x complex<double> \" \\\n       );                                                          \\\n       return false;                                               \\\n}\nnamespace CppAD {\n   CPPAD_USER_MACRO(LessThanZero)\n   CPPAD_USER_MACRO(LessThanOrZero)\n   CPPAD_USER_MACRO(GreaterThanOrZero)\n   CPPAD_USER_MACRO(GreaterThanZero)\n   inline bool abs_geq(\n      const std::complex<double>& x ,\n      const std::complex<double>& y )\n   {  return std::abs(x) >= std::abs(y); }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nInteger\n*******\nThe implementation of this function must agree\nwith the CppAD user specifications for complex arguments to the\n:ref:`Integer<Integer@x@Complex Types>` function:\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline int Integer(const std::complex<double> &x)\n   {  return static_cast<int>( x.real() ); }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nazmul\n*****\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   CPPAD_AZMUL( std::complex<double> )\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nisnan\n*****\nThe gcc 4.1.1 compiler defines the function\n\n   ``int std::complex<double>::isnan`` ( ``std::complex<double>`` *z*  )\n\n(which is not specified in the C++ 1998 standard ISO/IEC 14882).\nThis causes an ambiguity between the function above and the CppAD\n:ref:`isnan<nan-name>` template function.\nWe avoid this ambiguity by defining a non-template version of\nthis function in the CppAD namespace.\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline bool isnan(const std::complex<double>& z)\n   {  return (z != z);\n   }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nValid Unary Math\n****************\nThe following macro invocations define the standard unary\nmath functions that are valid with complex arguments and are\nrequired to use ``AD< std::complex<double> >`` .\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   CPPAD_STANDARD_MATH_UNARY(std::complex<double>, cos)\n   CPPAD_STANDARD_MATH_UNARY(std::complex<double>, cosh)\n   CPPAD_STANDARD_MATH_UNARY(std::complex<double>, exp)\n   CPPAD_STANDARD_MATH_UNARY(std::complex<double>, log)\n   CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sin)\n   CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sinh)\n   CPPAD_STANDARD_MATH_UNARY(std::complex<double>, sqrt)\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nInvalid Unary Math\n******************\nThe following macro definition and invocations define the standard unary\nmath functions that are invalid with complex arguments and are\nrequired to use ``AD< std::complex<double> >`` .\n{xrst_spell_off}\n{xrst_code cpp} */\n# undef  CPPAD_USER_MACRO\n# define CPPAD_USER_MACRO(Fun)                                     \\\ninline std::complex<double> Fun(const std::complex<double>& x)     \\\n{      CppAD::ErrorHandler::Call(                                  \\\n               true     , __LINE__ , __FILE__ ,                    \\\n               #Fun\"(x)\",                                          \\\n               \"Error: cannot use \" #Fun \" with x complex<double> \" \\\n       );                                                          \\\n       return std::complex<double>(0);                             \\\n}\nnamespace CppAD {\n   CPPAD_USER_MACRO(abs)\n   CPPAD_USER_MACRO(fabs)\n   CPPAD_USER_MACRO(acos)\n   CPPAD_USER_MACRO(asin)\n   CPPAD_USER_MACRO(atan)\n   CPPAD_USER_MACRO(sign)\n   CPPAD_USER_MACRO(asinh)\n   CPPAD_USER_MACRO(acosh)\n   CPPAD_USER_MACRO(atanh)\n   CPPAD_USER_MACRO(erf)\n   CPPAD_USER_MACRO(erfc)\n   CPPAD_USER_MACRO(expm1)\n   CPPAD_USER_MACRO(log1p)\n}\n/* {xrst_code}\n{xrst_spell_on}\n\npow\n***\nThe following defines a ``CppAD::pow`` function that\nis required to use ``AD< std::complex<double> >`` :\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline std::complex<double> pow(\n      const std::complex<double> &x ,\n      const std::complex<double> &y )\n   {  return std::pow(x, y); }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nnumeric_limits\n**************\nThe following defines the CppAD :ref:`numeric_limits-name`\nfor the type ``std::complex<double>`` :\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   CPPAD_NUMERIC_LIMITS(double, std::complex<double>)\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nto_string\n*********\nThe following defines the function CppAD :ref:`to_string-name`\nfor the type ``std::complex<double>`` :\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   CPPAD_TO_STRING(std::complex<double>)\n}\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end base_complex.hpp}\n*/\n# undef  CPPAD_USER_MACRO_ONE\n# define CPPAD_USER_MACRO_ONE(Fun)                                 \\\ninline bool Fun(const std::complex<float>& x)                      \\\n{      CppAD::ErrorHandler::Call(                                  \\\n               true     , __LINE__ , __FILE__ ,                    \\\n               #Fun\"(x)\",                                          \\\n               \"Error: cannot use \" #Fun \" with x complex<float> \" \\\n       );                                                          \\\n       return false;                                               \\\n}\n# undef  CPPAD_USER_MACRO_TWO\n# define CPPAD_USER_MACRO_TWO(Fun)                                 \\\ninline std::complex<float> Fun(const std::complex<float>& x)       \\\n{      CppAD::ErrorHandler::Call(                                  \\\n               true     , __LINE__ , __FILE__ ,                    \\\n               #Fun\"(x)\",                                          \\\n               \"Error: cannot use \" #Fun \" with x complex<float> \" \\\n       );                                                          \\\n       return std::complex<float>(0);                              \\\n}\nnamespace CppAD {\n   // CondExpOp ------------------------------------------------------\n   inline std::complex<float> CondExpOp(\n      enum CppAD::CompareOp      cop       ,\n      const std::complex<float> &left      ,\n      const std::complex<float> &right     ,\n      const std::complex<float> &trueCase  ,\n      const std::complex<float> &falseCase )\n   {  CppAD::ErrorHandler::Call(\n         true     , __LINE__ , __FILE__ ,\n         \"std::complex<float> CondExpOp(...)\",\n         \"Error: cannot use CondExp with a complex type\"\n      );\n      return std::complex<float>(0);\n   }\n   // CondExpRel --------------------------------------------------------\n   CPPAD_COND_EXP_REL( std::complex<float> )\n   // EqualOpSeq -----------------------------------------------------\n   inline bool EqualOpSeq(\n      const std::complex<float> &x ,\n      const std::complex<float> &y )\n   {  return x == y;\n   }\n   // Identical ------------------------------------------------------\n   inline bool IdenticalCon(const std::complex<float> &x)\n   {  return true; }\n   inline bool IdenticalZero(const std::complex<float> &x)\n   {  return (x == std::complex<float>(0., 0.) ); }\n   inline bool IdenticalOne(const std::complex<float> &x)\n   {  return (x == std::complex<float>(1., 0.) ); }\n   inline bool IdenticalEqualCon(\n      const std::complex<float> &x, const std::complex<float> &y)\n   {  return (x == y); }\n   // Ordered --------------------------------------------------------\n   CPPAD_USER_MACRO_ONE(LessThanZero)\n   CPPAD_USER_MACRO_ONE(LessThanOrZero)\n   CPPAD_USER_MACRO_ONE(GreaterThanOrZero)\n   CPPAD_USER_MACRO_ONE(GreaterThanZero)\n   inline bool abs_geq(\n      const std::complex<float>& x ,\n      const std::complex<float>& y )\n   {  return std::abs(x) >= std::abs(y); }\n   // Integer ------------------------------------------------------\n   inline int Integer(const std::complex<float> &x)\n   {  return static_cast<int>( x.real() ); }\n   // isnan -------------------------------------------------------------\n   inline bool isnan(const std::complex<float>& z)\n   {  return (z != z);\n   }\n   // Valid standard math functions --------------------------------\n   CPPAD_STANDARD_MATH_UNARY(std::complex<float>, cos)\n   CPPAD_STANDARD_MATH_UNARY(std::complex<float>, cosh)\n   CPPAD_STANDARD_MATH_UNARY(std::complex<float>, exp)\n   CPPAD_STANDARD_MATH_UNARY(std::complex<float>, log)\n   CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sin)\n   CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sinh)\n   CPPAD_STANDARD_MATH_UNARY(std::complex<float>, sqrt)\n   // Invalid standard math functions -------------------------------\n   CPPAD_USER_MACRO_TWO(abs)\n   CPPAD_USER_MACRO_TWO(acos)\n   CPPAD_USER_MACRO_TWO(asin)\n   CPPAD_USER_MACRO_TWO(atan)\n   CPPAD_USER_MACRO_TWO(sign)\n   // The pow function\n   inline std::complex<float> pow(\n      const std::complex<float> &x ,\n      const std::complex<float> &y )\n   {  return std::pow(x, y); }\n   // numeric_limits -------------------------------------------------\n   CPPAD_NUMERIC_LIMITS(float, std::complex<float>)\n   // to_string -------------------------------------------------\n   CPPAD_TO_STRING(std::complex<float>)\n}\n\n// undefine macros only used by this file\n# undef CPPAD_USER_MACRO\n# undef CPPAD_USER_MACRO_ONE\n# undef CPPAD_USER_MACRO_TWO\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/base_cond_exp.hpp",
    "content": "# ifndef CPPAD_CORE_BASE_COND_EXP_HPP\n# define CPPAD_CORE_BASE_COND_EXP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin base_cond_exp}\n{xrst_spell\n   adolc\n}\n\nBase Type Requirements for Conditional Expressions\n##################################################\n\nPurpose\n*******\nThese definitions are required by the user's code to support the\n``AD`` < *Base* > type for :ref:`CondExp-name` operations:\n\nCompareOp\n*********\nThe following ``enum`` type is used in the specifications below:\n::\n\n   namespace CppAD {\n   // The conditional expression operator enum type\n   enum CompareOp\n   {  CompareLt, // less than\n   CompareLe, // less than or equal\n   CompareEq, // equal\n   CompareGe, // greater than or equal\n   CompareGt, // greater than\n   CompareNe  // not equal\n   };\n   }\n\nCondExpTemplate\n***************\nThe type *Base* must support the syntax\n\n| |tab| *result* = ``CppAD::CondExpOp`` (\n| |tab| |tab| *cop* , *left* , *right* , *exp_if_true* , *exp_if_false*\n| |tab| )\n\nwhich computes implements the corresponding :ref:`CondExp-name`\nfunction when the result has prototype\n\n   *Base* *result*\n\nThe argument *cop* has prototype\n\n   ``enum CppAD::CompareOp`` *cop*\n\nThe other arguments have the prototype\n\n| |tab| ``const`` *Base* & *left*\n| |tab| ``const`` *Base* & *right*\n| |tab| ``const`` *Base* & *exp_if_true*\n| |tab| ``const`` *Base* & *exp_if_false*\n\nOrdered Type\n============\nIf *Base* is a relatively simple type\nthat supports\n``<`` , ``<=`` , ``==`` , ``>=`` , and ``>`` operators\nits ``CondExpOp`` function can be defined by\n\n| ``namespace CppAD`` {\n| |tab| ``inline`` *Base* ``CondExpOp`` (\n| |tab| ``enum CppAD::CompareOp`` *cop*             ,\n| |tab| ``const`` *Base* & *left*           ,\n| |tab| ``const`` *Base* & *right*          ,\n| |tab| ``const`` *Base* & *exp_if_true*    ,\n| |tab| ``const`` *Base* & *exp_if_false*   )\n| |tab| { ``return CondExpTemplate`` (\n| |tab| |tab| |tab| ``cop`` , ``left`` , ``right`` , ``trueCase`` , ``falseCase`` );\n| |tab| }\n| }\n\nFor example, see\n:ref:`double CondExpOp<base_alloc.hpp@CondExpOp>` .\nFor an example of and implementation of ``CondExpOp`` with\na more involved *Base* type see\n:ref:`adolc CondExpOp<base_adolc.hpp@CondExpOp>` .\n\nNot Ordered\n===========\nIf the type *Base* does not support ordering; i.e., does not support\nthe ``<`` , ``<=`` , ``>=`` , or ``>`` operator they should be defined\nas resulting in error when used; e.g.\n\n| ``namespace CppAD`` {\n| |tab| ``inline bool operator<`` (\n| |tab| ``const`` *Base* & *left*          ,\n| |tab| ``const`` *Base* & *right*         )\n| |tab| {  // ``attempt to use < operator with`` *Base* ``arguments``\n| |tab| |tab| ``assert`` (0);\n| |tab| |tab| ``return`` false;\n| |tab| }\n| }\n\nUsing the ``CondExpOp`` function does should also be defined a an error; e.g.,\n\n| ``namespace CppAD`` {\n| |tab| ``inline`` *Base* ``CondExpOp`` (\n| |tab| ``enum CompareOp`` *cop*            ,\n| |tab| ``const`` *Base* & *left*          ,\n| |tab| ``const`` *Base* & *right*         ,\n| |tab| ``const`` *Base* & *exp_if_true*   ,\n| |tab| ``const`` *Base* & *exp_if_false*  )\n| |tab| {  // ``attempt to use CondExp with a`` *Base* ``argument``\n| |tab| |tab| ``assert`` (0);\n| |tab| |tab| ``return`` *Base* (0);\n| |tab| }\n| }\n\nFor example, see\n:ref:`complex CondExpOp<base_complex.hpp@CondExpOp>` .\n\nCondExpRel\n**********\nThe macro invocation\n\n   ``CPPAD_COND_EXP_REL`` ( *Base* )\n\nuses ``CondExpOp`` above to define the following functions\n\n| |tab| ``CondExpLt`` ( *left* , *right* , *exp_if_true* , *exp_if_false* )\n| |tab| ``CondExpLe`` ( *left* , *right* , *exp_if_true* , *exp_if_false* )\n| |tab| ``CondExpEq`` ( *left* , *right* , *exp_if_true* , *exp_if_false* )\n| |tab| ``CondExpGe`` ( *left* , *right* , *exp_if_true* , *exp_if_false* )\n| |tab| ``CondExpGt`` ( *left* , *right* , *exp_if_true* , *exp_if_false* )\n\nwhere the arguments have type *Base* .\nThis should be done inside of the CppAD namespace.\nFor example, see\n:ref:`base_alloc<base_alloc.hpp@CondExpRel>` .\n\n{xrst_end base_cond_exp}\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*!\n\\file base_cond_exp.hpp\nCondExp operations that aid in meeting Base type requirements.\n*/\n\n/*!\n\\def CPPAD_COND_EXP_BASE_REL(Type, Rel, Op)\nThis macro defines the operation\n\\verbatim\n   CondExpRel(left, right, exp_if_true, exp_if_false)\n\\endverbatim\nThe argument Type is the Base type for this base require operation.\nThe argument Rel is one of Lt, Le, Eq, Ge, Gt.\nThe argument Op is the corresponding CompareOp value.\n*/\n# define CPPAD_COND_EXP_BASE_REL(Type, Rel, Op)       \\\n   inline Type CondExp##Rel(                        \\\n      const Type& left      ,                     \\\n      const Type& right     ,                     \\\n      const Type& exp_if_true  ,                  \\\n      const Type& exp_if_false )                  \\\n   {  return CondExpOp(Op, left, right, exp_if_true, exp_if_false); \\\n   }\n\n/*!\n\\def CPPAD_COND_EXP_REL(Type)\nThe macro defines the operations\n\\verbatim\n   CondExpLt(left, right, exp_if_true, exp_if_false)\n   CondExpLe(left, right, exp_if_true, exp_if_false)\n   CondExpEq(left, right, exp_if_true, exp_if_false)\n   CondExpGe(left, right, exp_if_true, exp_if_false)\n   CondExpGt(left, right, exp_if_true, exp_if_false)\n\\endverbatim\nThe argument Type is the Base type for this base require operation.\n*/\n# define CPPAD_COND_EXP_REL(Type)                     \\\n   CPPAD_COND_EXP_BASE_REL(Type, Lt, CompareLt)     \\\n   CPPAD_COND_EXP_BASE_REL(Type, Le, CompareLe)     \\\n   CPPAD_COND_EXP_BASE_REL(Type, Eq, CompareEq)     \\\n   CPPAD_COND_EXP_BASE_REL(Type, Ge, CompareGe)     \\\n   CPPAD_COND_EXP_BASE_REL(Type, Gt, CompareGt)\n\n/*!\nTemplate function to implement Conditional Expressions for simple types\nthat have comparison operators.\n\n\\tparam CompareType\nis the type of the left and right operands to the comparison operator.\n\n\\tparam ResultType\nis the type of the result, which is the same as CompareType except\nduring forward and reverse mode sparese calculations.\n\n\\param cop\nspedifies which comparison to use; i.e.,\n$code <$$,\n$code <=$$,\n$code ==$$,\n$code >=$$,\n$code >$$, or\n$code !=$$.\n\n\\param left\nis the left operand to the comparison operator.\n\n\\param right\nis the right operand to the comparison operator.\n\n\\param exp_if_true\nis the return value is the comparison results in true.\n\n\\param exp_if_false\nis the return value is the comparison results in false.\n\n\\return\nsee exp_if_true and exp_if_false above.\n*/\ntemplate <class CompareType, class ResultType>\nResultType CondExpTemplate(\n   enum  CompareOp            cop          ,\n   const CompareType&         left         ,\n   const CompareType&         right        ,\n   const ResultType&          exp_if_true  ,\n   const ResultType&          exp_if_false )\n{  ResultType returnValue;\n   switch( cop )\n   {\n      case CompareLt:\n      if( left < right )\n         returnValue = exp_if_true;\n      else\n         returnValue = exp_if_false;\n      break;\n\n      case CompareLe:\n      if( left <= right )\n         returnValue = exp_if_true;\n      else\n         returnValue = exp_if_false;\n      break;\n\n      case CompareEq:\n      if( left == right )\n         returnValue = exp_if_true;\n      else\n         returnValue = exp_if_false;\n      break;\n\n      case CompareGe:\n      if( left >= right )\n         returnValue = exp_if_true;\n      else\n         returnValue = exp_if_false;\n      break;\n\n      case CompareGt:\n      if( left > right )\n         returnValue = exp_if_true;\n      else\n         returnValue = exp_if_false;\n      break;\n\n      default:\n      CPPAD_ASSERT_UNKNOWN(0);\n      returnValue = exp_if_true;\n   }\n   return returnValue;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/base_double.hpp",
    "content": "# ifndef CPPAD_CORE_BASE_DOUBLE_HPP\n# define CPPAD_CORE_BASE_DOUBLE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/configure.hpp>\n# include <limits>\n\n/*\n{xrst_begin base_double.hpp}\n{xrst_spell\n   azmul\n   namespaces\n}\n\nEnable use of AD<Base> where Base is double\n###########################################\n\nCondExpOp\n*********\nThe type ``double`` is a relatively simple type that supports\n``<`` , ``<=`` , ``==`` , ``>=`` , and ``>`` operators; see\n:ref:`base_cond_exp@CondExpTemplate@Ordered Type` .\nHence its ``CondExpOp`` function is defined by\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline double CondExpOp(\n      enum CompareOp      cop          ,\n      const double&       left         ,\n      const double&       right        ,\n      const double&       exp_if_true  ,\n      const double&       exp_if_false )\n   {  return CondExpTemplate(cop, left, right, exp_if_true, exp_if_false);\n   }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nCondExpRel\n**********\nThe :ref:`CPPAD_COND_EXP_REL<base_cond_exp@CondExpRel>` macro invocation\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   CPPAD_COND_EXP_REL(double)\n}\n/* {xrst_code}\n{xrst_spell_on}\nuses ``CondExpOp`` above to\ndefine ``CondExp`` *Rel* for ``double`` arguments\nand *Rel* equal to\n``Lt`` , ``Le`` , ``Eq`` , ``Ge`` , and ``Gt`` .\n\nEqualOpSeq\n**********\nThe type ``double`` is simple (in this respect) and so we define\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline bool EqualOpSeq(const double& x, const double& y)\n   {  return x == y; }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nIdentical\n*********\nThe type ``double`` is simple (in this respect) and so we define\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline bool IdenticalCon(const double& x)\n   {  return true; }\n   inline bool IdenticalZero(const double& x)\n   {  return (x == 0.); }\n   inline bool IdenticalOne(const double& x)\n   {  return (x == 1.); }\n   inline bool IdenticalEqualCon(const double& x, const double& y)\n   {  return (x == y); }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nInteger\n*******\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline int Integer(const double& x)\n   {  return static_cast<int>(x); }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nazmul\n*****\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   CPPAD_AZMUL( double )\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nOrdered\n*******\nThe ``double`` type supports ordered comparisons\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline bool GreaterThanZero(const double& x)\n   {  return x > 0.; }\n   inline bool GreaterThanOrZero(const double& x)\n   {  return x >= 0.; }\n   inline bool LessThanZero(const double& x)\n   {  return x < 0.; }\n   inline bool LessThanOrZero(const double& x)\n   {  return x <= 0.; }\n   inline bool abs_geq(const double& x, const double& y)\n   {  return std::fabs(x) >= std::fabs(y); }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nUnary Standard Math\n*******************\nThe following macro invocations import the ``double`` versions of\nthe unary standard math functions into the ``CppAD`` namespace.\nImporting avoids ambiguity errors when using both the\n``CppAD`` and ``std`` namespaces.\nNote this also defines the :ref:`float<base_float.hpp@Unary Standard Math>`\nversions of these functions.\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   using std::acos;\n   using std::asin;\n   using std::atan;\n   using std::cos;\n   using std::cosh;\n   using std::exp;\n   using std::fabs;\n   using std::log;\n   using std::log10;\n   using std::sin;\n   using std::sinh;\n   using std::sqrt;\n   using std::tan;\n   using std::tanh;\n   using std::asinh;\n   using std::acosh;\n   using std::atanh;\n   using std::erf;\n   using std::erfc;\n   using std::expm1;\n   using std::log1p;\n}\n/* {xrst_code}\n{xrst_spell_on}\nThe absolute value function is special because its ``std`` name is\n``fabs``\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline double abs(const double& x)\n   {  return std::fabs(x); }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nsign\n****\nThe following defines the ``CppAD::sign`` function that\nis required to use ``AD<double>`` :\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline double sign(const double& x)\n   {  if( x > 0. )\n         return 1.;\n      if( x == 0. )\n         return 0.;\n      return -1.;\n   }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\npow\n***\nThe following defines a ``CppAD::pow`` function that\nis required to use ``AD<double>`` .\nAs with the unary standard math functions,\nthis has the exact same signature as ``std::pow`` ,\nso use it instead of defining another function.\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   using std::pow;\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nnumeric_limits\n**************\nThe following defines the CppAD :ref:`numeric_limits-name`\nfor the type ``double`` :\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   CPPAD_NUMERIC_LIMITS(double, double)\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nto_string\n*********\nThere is no need to define ``to_string`` for ``double``\nbecause it is defined by including ``cppad/utility/to_string.hpp`` ;\nsee :ref:`to_string-name` .\nSee :ref:`base_complex.hpp<base_complex.hpp@to_string>` for an example where\nit is necessary to define ``to_string`` for a *Base* type.\n\n{xrst_end base_double.hpp}\n*/\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/base_float.hpp",
    "content": "# ifndef CPPAD_CORE_BASE_FLOAT_HPP\n# define CPPAD_CORE_BASE_FLOAT_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/configure.hpp>\n# include <limits>\n\n/*\n{xrst_begin base_float.hpp}\n{xrst_spell\n   azmul\n   namespaces\n}\n\nEnable use of AD<Base> where Base is float\n##########################################\n\nCondExpOp\n*********\nThe type ``float`` is a relatively simple type that supports\n``<`` , ``<=`` , ``==`` , ``>=`` , and ``>`` operators; see\n:ref:`base_cond_exp@CondExpTemplate@Ordered Type` .\nHence its ``CondExpOp`` function is defined by\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline float CondExpOp(\n      enum CompareOp     cop          ,\n      const float&       left         ,\n      const float&       right        ,\n      const float&       exp_if_true  ,\n      const float&       exp_if_false )\n   {  return CondExpTemplate(cop, left, right, exp_if_true, exp_if_false);\n   }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nCondExpRel\n**********\nThe :ref:`CPPAD_COND_EXP_REL<base_cond_exp@CondExpRel>` macro invocation\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   CPPAD_COND_EXP_REL(float)\n}\n/* {xrst_code}\n{xrst_spell_on}\nuses ``CondExpOp`` above to\ndefine ``CondExp`` *Rel* for ``float`` arguments\nand *Rel* equal to\n``Lt`` , ``Le`` , ``Eq`` , ``Ge`` , and ``Gt`` .\n\nEqualOpSeq\n**********\nThe type ``float`` is simple (in this respect) and so we define\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline bool EqualOpSeq(const float& x, const float& y)\n   {  return x == y; }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nIdentical\n*********\nThe type ``float`` is simple (in this respect) and so we define\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline bool IdenticalCon(const float& x)\n   {  return true; }\n   inline bool IdenticalZero(const float& x)\n   {  return (x == 0.f); }\n   inline bool IdenticalOne(const float& x)\n   {  return (x == 1.f); }\n   inline bool IdenticalEqualCon(const float& x, const float& y)\n   {  return (x == y); }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nInteger\n*******\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline int Integer(const float& x)\n   {  return static_cast<int>(x); }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nazmul\n*****\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   CPPAD_AZMUL( float )\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nOrdered\n*******\nThe ``float`` type supports ordered comparisons\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline bool GreaterThanZero(const float& x)\n   {  return x > 0.f; }\n   inline bool GreaterThanOrZero(const float& x)\n   {  return x >= 0.f; }\n   inline bool LessThanZero(const float& x)\n   {  return x < 0.f; }\n   inline bool LessThanOrZero(const float& x)\n   {  return x <= 0.f; }\n   inline bool abs_geq(const float& x, const float& y)\n   {  return std::fabs(x) >= std::fabs(y); }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nUnary Standard Math\n*******************\nThe following macro invocations import the ``float`` versions of\nthe unary standard math functions into the ``CppAD`` namespace.\nImporting avoids ambiguity errors when using both the\n``CppAD`` and ``std`` namespaces.\nNote this also defines the :ref:`double<base_double.hpp@Unary Standard Math>`\nversions of these functions.\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   using std::acos;\n   using std::asin;\n   using std::atan;\n   using std::cos;\n   using std::cosh;\n   using std::exp;\n   using std::fabs;\n   using std::log;\n   using std::log10;\n   using std::sin;\n   using std::sinh;\n   using std::sqrt;\n   using std::tan;\n   using std::tanh;\n   using std::asinh;\n   using std::acosh;\n   using std::atanh;\n   using std::erf;\n   using std::erfc;\n   using std::expm1;\n   using std::log1p;\n}\n\n/* {xrst_code}\n{xrst_spell_on}\nThe absolute value function is special because its ``std`` name is\n``fabs``\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline float abs(const float& x)\n   {  return std::fabs(x); }\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nsign\n****\nThe following defines the ``CppAD::sign`` function that\nis required to use ``AD<float>`` :\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   inline float sign(const float& x)\n   {  if( x > 0.f )\n         return 1.f;\n      if( x == 0.f )\n         return 0.f;\n      return -1.f;\n   }\n}\n/* {xrst_code}\n{xrst_spell_on}\npow\n***\nThe following defines a ``CppAD::pow`` function that\nis required to use ``AD<float>`` .\nAs with the unary standard math functions,\nthis has the exact same signature as ``std::pow`` ,\nso use it instead of defining another function.\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   using std::pow;\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nnumeric_limits\n**************\nThe following defines the CppAD :ref:`numeric_limits-name`\nfor the type ``float`` :\n{xrst_spell_off}\n{xrst_code cpp} */\nnamespace CppAD {\n   CPPAD_NUMERIC_LIMITS(float, float)\n}\n/* {xrst_code}\n{xrst_spell_on}\n\nto_string\n*********\nThere is no need to define ``to_string`` for ``float``\nbecause it is defined by including ``cppad/utility/to_string.hpp`` ;\nsee :ref:`to_string-name` .\nSee :ref:`base_complex.hpp<base_complex.hpp@to_string>` for an example where\nit is necessary to define ``to_string`` for a *Base* type.\n\n{xrst_end base_float.hpp}\n*/\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/base_hash.hpp",
    "content": "# ifndef CPPAD_CORE_BASE_HASH_HPP\n# define CPPAD_CORE_BASE_HASH_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin base_hash}\n{xrst_spell\n   adouble\n   valgrind\n}\n\nBase Type Requirements for Hash Coding Values\n#############################################\n\nSyntax\n******\n| *code* = ``hash_code`` ( *x* )\n\nPurpose\n*******\nCppAD uses a table of *Base* type values when recording\n``AD`` < *Base* > operations.\nA hashing function is used to reduce number of values stored in this table;\nfor example, it is not necessary to store the value 3.0 every\ntime it is used as a :ref:`con_dyn_var@Parameter` .\n\nDefault\n*******\nThe default hashing function works with the set of bits that correspond\nto a *Base* value.\nIn most cases this works well, but in some cases\nit does not. For example, in the\n:ref:`base_adolc.hpp-name` case, an ``adouble`` value can have\nfields that are not initialized and ``valgrind`` reported an error\nwhen these are used to form the hash code.\n\nx\n*\nThis argument has prototype\n\n   *const* ``Base`` & ``x``\n\nIt is the value we are forming a hash code for.\n\ncode\n****\nThe return value *code* has prototype\n\n   ``unsigned short`` *code*\n\nIt is the hash code corresponding to *x* . This intention is the\ncommonly used values will have different hash codes.\nThe hash code must satisfy\n\n   *code* < ``CPPAD_HASH_TABLE_SIZE``\n\nso that it is a valid index into the hash code table.\n\ninline\n******\nIf you define this function, it should declare it to be ``inline`` ,\nso that you do not get multiple definitions from different compilation units.\n\nExample\n*******\nSee the ``base_alloc`` :ref:`base_alloc.hpp@hash_code`\nand the ``adouble`` :ref:`base_adolc.hpp@hash_code` .\n\n{xrst_end base_hash}\n*/\n\n/*!\n\\def CPPAD_HASH_TABLE_SIZE\nthe codes returned by hash_code are between zero and CPPAD_HASH_TABLE_SIZE\nminus one.\n*/\n# define CPPAD_HASH_TABLE_SIZE 10000\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/base_limits.hpp",
    "content": "# ifndef CPPAD_CORE_BASE_LIMITS_HPP\n# define CPPAD_CORE_BASE_LIMITS_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-23 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin base_limits}\n\nBase Type Requirements for Numeric Limits\n#########################################\n\nnumeric_limits\n**************\nA specialization for\n:ref:`CppAD::numeric_limits<numeric_limits-name>`\nmust be defined in order to use the type ``AD`` < *Base* > .\nCppAD does not use a specialization of\n``std::numeric_limits<`` *Base* > .\nSince C++11, using a specialization of\n``std::numeric_limits<`` *Base* >\nwould require that *Base* be a literal type.\n\nCPPAD_NUMERIC_LIMITS\n********************\nIn most cases, this macro can be used to define the specialization where\nthe numeric limits for the type *Base*\nare the same as the standard numeric limits for the type *Other* .\nFor most *Base* types,\nthere is a choice of *Other* ,\nfor which the following preprocessor macro invocation suffices:\n\n| |tab| ``namespace CppAD`` {\n| |tab| |tab| ``CPPAD_NUMERIC_LIMITS`` ( *Other* , *Base* )\n| |tab| }\n\ne.g., see :ref:`base_double.hpp@numeric_limits` for the type ``double`` .\nThe macro ``CPPAD_NUMERIC_LIMITS`` is defined by\n{xrst_spell_off}\n{xrst_code cpp} */\n# define CPPAD_NUMERIC_LIMITS(Other, Base) \\\ntemplate <> class numeric_limits<Base>\\\n{\\\n   public:\\\n   static Base min(void) \\\n   {  return static_cast<Base>( std::numeric_limits<Other>::min() ); }\\\n   static Base max(void) \\\n   {  return static_cast<Base>( std::numeric_limits<Other>::max() ); }\\\n   static Base epsilon(void) \\\n   {  return static_cast<Base>( std::numeric_limits<Other>::epsilon() ); }\\\n   static Base quiet_NaN(void) \\\n   {  return static_cast<Base>( std::numeric_limits<Other>::quiet_NaN() ); }\\\n   static Base infinity(void) \\\n   {  return static_cast<Base>( std::numeric_limits<Other>::infinity() ); }\\\n   static const int digits10 = std::numeric_limits<Other>::digits10;\\\n   static const int max_digits10 = std::numeric_limits<Other>::max_digits10;\\\n};\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end base_limits}\n*/\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/base_std_math.hpp",
    "content": "# ifndef CPPAD_CORE_BASE_STD_MATH_HPP\n# define CPPAD_CORE_BASE_STD_MATH_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin base_std_math}\n{xrst_spell\n   acosh\n   asinh\n   erfc\n   expm\n   isnan\n}\n\nBase Type Requirements for Standard Math Functions\n##################################################\n\nPurpose\n*******\nThese definitions are required for the user's code to use the type\n``AD`` < *Base* > :\n\nUnary Standard Math\n*******************\nThe type *Base* must support the following functions\nunary standard math functions (in the CppAD namespace):\n\n.. csv-table::\n   :widths: auto\n\n   **Syntax**,**Result**\n   *y* = ``abs`` ( *x* ),absolute value\n   *y* = ``acos`` ( *x* ),inverse cosine\n   *y* = ``acosh`` ( *x* ),inverse hyperbolic cosine\n   *y* = ``asin`` ( *x* ),inverse sine\n   *y* = ``asinh`` ( *x* ),inverse hyperbolic sin\n   *y* = ``atan`` ( *x* ),inverse tangent\n   *y* = ``atanh`` ( *x* ),inverse hyperbolic tangent\n   *y* = ``cos`` ( *x* ),cosine\n   *y* = ``cosh`` ( *x* ),hyperbolic cosine\n   *y* = ``erf`` ( *x* ),error function\n   *y* = ``erfc`` ( *x* ),complementary error function\n   *y* = ``exp`` ( *x* ),exponential\n   *y* = ``expm1`` ( *x* ),exponential of x minus one\n   *y* = ``fabs`` ( *x* ),absolute value\n   *y* = ``log`` ( *x* ),natural logarithm\n   *y* = ``log1p`` ( *x* ),logarithm of one plus x\n   *y* = ``sin`` ( *x* ),sine\n   *y* = ``sinh`` ( *x* ),hyperbolic sine\n   *y* = ``sqrt`` ( *x* ),square root\n   *y* = ``tan`` ( *x* ),tangent\n\nwhere the arguments and return value have the prototypes\n\n| |tab| ``const`` *Base* & *x*\n| |tab| *Base* *y*\n\nFor example,\n:ref:`base_alloc<base_alloc.hpp@Unary Standard Math>` ,\n\nCPPAD_STANDARD_MATH_UNARY\n*************************\nThe macro invocation, within the CppAD namespace,\n\n   ``CPPAD_STANDARD_MATH_UNARY`` ( *Base* , *Fun* )\n\ndefines the syntax\n\n   *y* = ``CppAD::`` *Fun* ( *x* )\n\nThis macro uses the functions ``std::`` *Fun* which\nmust be defined and have the same prototype as ``CppAD::`` *Fun* .\nFor example,\n:ref:`float<base_float.hpp@Unary Standard Math>` .\n\nsign\n****\nThe type *Base* must support the syntax\n\n   *y* = ``CppAD::sign`` ( *x* )\n\nwhich computes\n\n.. math::\n\n   y = \\left\\{ \\begin{array}{ll}\n      +1 & {\\rm if} \\; x > 0 \\\\\n        0 & {\\rm if} \\; x = 0 \\\\\n      -1 & {\\rm if} \\; x < 0\n   \\end{array} \\right.\n\nwhere *x* and *y* have the same prototype as above.\nFor example, see\n:ref:`base_alloc<base_alloc.hpp@sign>` .\nNote that, if ordered comparisons are not defined for the type *Base* ,\nthe ``code sign`` function should generate an assert if it is used; see\n:ref:`complex invalid unary math<base_complex.hpp@Invalid Unary Math>` .\n\npow\n***\nThe type *Base* must support the syntax\n\n   *z* = ``CppAD::pow`` ( *x* , *y* )\n\nwhich computes :math:`z = x^y`.\nThe arguments *x* and *y* have prototypes\n\n| |tab| ``const`` *Base* & *x*\n| |tab| ``const`` *Base* & *y*\n\nand the return value *z* has prototype\n\n   *Base* *z*\n\nFor example, see\n:ref:`base_alloc<base_alloc.hpp@pow>` .\n\nisnan\n*****\nIf *Base* defines the ``isnan`` function,\nyou may also have to provide a definition in the CppAD namespace\n(to avoid a function ambiguity).\nFor example, see\n:ref:`base_complex<base_complex.hpp@isnan>` .\n\n{xrst_end base_std_math}\n-------------------------------------------------------------------------------\n*/\n\n# include <cmath>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*!\n\\file base_std_math.hpp\nDefinitions that aid meeting Base type requirements for standard math functions.\n*/\n\n/*!\n\\def CPPAD_STANDARD_MATH_UNARY(Type, Fun)\nThis macro defines the function\n\\verbatim\n   y = CppAD:Fun(x)\n\\endverbatim\nwhere the argument x and return value y have type Type\nusing the corresponding function <code>std::Fun</code>.\n*/\n# define CPPAD_STANDARD_MATH_UNARY(Type, Fun) \\\n   inline Type Fun(const Type& x)            \\\n   {  return std::Fun(x); }\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/base_to_string.hpp",
    "content": "# ifndef CPPAD_CORE_BASE_TO_STRING_HPP\n# define CPPAD_CORE_BASE_TO_STRING_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin base_to_string}\n{xrst_spell\n   struct\n}\n\nExtending to_string To Another Floating Point Type\n##################################################\n\nBase Requirement\n****************\nIf the function :ref:`to_string-name` is used by an\n:ref:`glossary@AD Type Above Base` ,\nA specialization for the template structure\n``CppAD::to_string_struct`` must be defined.\n\nCPPAD_TO_STRING\n***************\nFor most *Base* types,\nthe following can be used to define the specialization:\n\n| |tab| ``namespace CppAD`` {\n| |tab| |tab| ``CPPAD_TO_STRING`` ( *Base* )\n| |tab| }\n\nNote that the ``CPPAD_TO_STRING`` macro assumes that the\n:ref:`base_limits-name` and :ref:`base_std_math-name` have already been defined\nfor this type.\nThis macro is defined as follows:\n{xrst_spell_off}\n{xrst_code cpp} */\n# define CPPAD_TO_STRING(Base) \\\ntemplate <> struct to_string_struct<Base>\\\n{  std::string operator()(const Base& value) \\\n   {  std::stringstream os;\\\n      int n_digits = 1 + CppAD::numeric_limits<Base>::digits10; \\\n      os << std::setprecision(n_digits);\\\n      os << value;\\\n      return os.str();\\\n   }\\\n};\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end base_to_string}\n------------------------------------------------------------------------------\n*/\n// make sure to_string has been included\n# include <cppad/utility/to_string.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/bender_quad.hpp",
    "content": "# ifndef CPPAD_CORE_BENDER_QUAD_HPP\n# define CPPAD_CORE_BENDER_QUAD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin BenderQuad app}\n{xrst_spell\n   avector\n   gx\n   gxx\n}\n\nComputing Jacobian and Hessian of Bender's Reduced Objective\n############################################################\n\nSyntax\n******\n| # ``include <cppad/cppad.hpp>``\n| *BenderQuad* ( ``x`` , ``y`` , ``fun`` , ``g`` , ``gx`` , ``gxx`` )\n\nSee Also\n********\n:ref:`opt_val_hes-name`\n\nProblem\n*******\nThe type :ref:`BenderQuad@ADvector` cannot be determined\nform the arguments above\n(currently the type *ADvector* must be\n``CPPAD_TESTVECTOR`` ( *Base* ) .)\nThis will be corrected in the future by requiring *Fun*\nto define *Fun* :: ``vector_type`` which will specify the\ntype *ADvector* .\n\nPurpose\n*******\nWe are given the optimization problem\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   {\\rm minimize} & F(x, y) & {\\rm w.r.t.} \\; (x, y) \\in \\B{R}^n \\times \\B{R}^m\n   \\end{eqnarray}\n\nthat is convex with respect to :math:`y`.\nIn addition, we are given a set of equations :math:`H(x, y)`\nsuch that\n\n.. math::\n\n   H[ x , Y(x) ] = 0 \\;\\; \\Rightarrow \\;\\; F_y [ x , Y(x) ] = 0\n\n(In fact, it is often the case that :math:`H(x, y) = F_y (x, y)`.)\nFurthermore, it is easy to calculate a Newton step for these equations; i.e.,\n\n.. math::\n\n   dy = - [ \\partial_y H(x, y)]^{-1} H(x, y)\n\nThe purpose of this routine is to compute the\nvalue, Jacobian, and Hessian of the reduced objective function\n\n.. math::\n\n   G(x) = F[ x , Y(x) ]\n\nNote that if only the value and Jacobian are needed, they can be\ncomputed more quickly using the relations\n\n.. math::\n\n   G^{(1)} (x) = \\partial_x F [x, Y(x) ]\n\nx\n*\nThe ``BenderQuad`` argument *x* has prototype\n\n   ``const`` *BAvector* & *x*\n\n(see :ref:`BenderQuad@BAvector` below)\nand its size must be equal to *n* .\nIt specifies the point at which we evaluating\nthe reduced objective function and its derivatives.\n\ny\n*\nThe ``BenderQuad`` argument *y* has prototype\n\n   ``const`` *BAvector* & *y*\n\nand its size must be equal to *m* .\nIt must be equal to :math:`Y(x)`; i.e.,\nit must solve the problem in :math:`y` for this given value of :math:`x`\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      {\\rm minimize} & F(x, y) & {\\rm w.r.t.} \\; y \\in \\B{R}^m\n   \\end{eqnarray}\n\nfun\n***\nThe ``BenderQuad`` object *fun*\nmust support the member functions listed below.\nThe ``AD`` < *Base* > arguments will be variables for\na tape created by a call to :ref:`Independent-name` from ``BenderQuad``\n(hence they can not be combined with variables corresponding to a\ndifferent tape).\n\nfun.f\n=====\nThe ``BenderQuad`` argument *fun* supports the syntax\n\n   *f* = *fun* . ``f`` ( *x* , *y* )\n\nThe *fun* . ``f`` argument *x* has prototype\n\n   ``const`` *ADvector* & *x*\n\n(see :ref:`BenderQuad@ADvector` below)\nand its size must be equal to *n* .\nThe *fun* . ``f`` argument *y* has prototype\n\n   ``const`` *ADvector* & *y*\n\nand its size must be equal to *m* .\nThe *fun* . ``f`` result *f* has prototype\n\n   *ADvector* *f*\n\nand its size must be equal to one.\nThe value of *f* is\n\n.. math::\n\n   f = F(x, y)\n\nfun.h\n=====\nThe ``BenderQuad`` argument *fun* supports the syntax\n\n   *h* = *fun* . ``h`` ( *x* , *y* )\n\nThe *fun* . ``h`` argument *x* has prototype\n\n   ``const`` *ADvector* & *x*\n\nand its size must be equal to *n* .\nThe *fun* . ``h`` argument *y* has prototype\n\n   ``const`` *BAvector* & *y*\n\nand its size must be equal to *m* .\nThe *fun* . ``h`` result *h* has prototype\n\n   *ADvector* *h*\n\nand its size must be equal to *m* .\nThe value of *h* is\n\n.. math::\n\n   h = H(x, y)\n\nfun.dy\n======\nThe ``BenderQuad`` argument *fun* supports the syntax\n\n| |tab| *dy* = *fun* . ``dy`` ( *x* , *y* , *h* )\n|\n| *x*\n\nThe *fun* . ``dy`` argument *x* has prototype\n\n   ``const`` *BAvector* & *x*\n\nand its size must be equal to *n* .\nIts value will be exactly equal to the ``BenderQuad`` argument\n*x* and values depending on it can be stored as private objects\nin *f* and need not be recalculated.\n\n   *y*\n\nThe *fun* . ``dy`` argument *y* has prototype\n\n   ``const`` *BAvector* & *y*\n\nand its size must be equal to *m* .\nIts value will be exactly equal to the ``BenderQuad`` argument\n*y* and values depending on it can be stored as private objects\nin *f* and need not be recalculated.\n\n   *h*\n\nThe *fun* . ``dy`` argument *h* has prototype\n\n   ``const`` *ADvector* & *h*\n\nand its size must be equal to *m* .\n\n   *dy*\n\nThe *fun* . ``dy`` result *dy* has prototype\n\n   *ADvector* *dy*\n\nand its size must be equal to *m* .\nThe return value *dy* is given by\n\n.. math::\n\n   dy = - [ \\partial_y H (x , y) ]^{-1} h\n\nNote that if *h* is equal to :math:`H(x, y)`,\n:math:`dy` is the Newton step for finding a zero\nof :math:`H(x, y)` with respect to :math:`y`;\ni.e.,\n:math:`y + dy` is an approximate solution for the equation\n:math:`H (x, y + dy) = 0`.\n\ng\n*\nThe argument *g* has prototype\n\n   *BAvector* & *g*\n\nand has size one.\nThe input value of its element does not matter.\nOn output,\nit contains the value of :math:`G (x)`; i.e.,\n\n.. math::\n\n   g[0] = G (x)\n\ngx\n**\nThe argument *gx* has prototype\n\n   *BAvector* & *gx*\n\nand has size :math:`n`.\nThe input values of its elements do not matter.\nOn output,\nit contains the Jacobian of :math:`G (x)`; i.e.,\nfor :math:`j = 0 , \\ldots , n-1`,\n\n.. math::\n\n   gx[ j ] = G^{(1)} (x)_j\n\ngxx\n***\nThe argument *gx* has prototype\n\n   *BAvector* & *gxx*\n\nand has size :math:`n \\times n`.\nThe input values of its elements do not matter.\nOn output,\nit contains the Hessian of :math:`G (x)`; i.e.,\nfor :math:`i = 0 , \\ldots , n-1`, and\n:math:`j = 0 , \\ldots , n-1`,\n\n.. math::\n\n   gxx[ i * n + j ] = G^{(2)} (x)_{i,j}\n\nBAvector\n********\nThe type *BAvector* must be a\n:ref:`SimpleVector-name` class.\nWe use *Base* to refer to the type of the elements of\n*BAvector* ; i.e.,\n\n   *BAvector* :: ``value_type``\n\nADvector\n********\nThe type *ADvector* must be a\n:ref:`SimpleVector-name` class with elements of type\n``AD`` < *Base* > ; i.e.,\n\n   *ADvector* :: ``value_type``\n\nmust be the same type as\n\n   ``AD`` < *BAvector* :: ``value_type >``\n\n.\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/bender_quad.cpp\n}\nThe file\n:ref:`bender_quad.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end BenderQuad}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN CppAD namespace\n\ntemplate <class BAvector, class Fun>\nvoid BenderQuad(\n   const BAvector   &x     ,\n   const BAvector   &y     ,\n   Fun               fun   ,\n   BAvector         &g     ,\n   BAvector         &gx    ,\n   BAvector         &gxx   )\n{  // determine the base type\n   typedef typename BAvector::value_type Base;\n\n   // check that BAvector is a SimpleVector class\n   CheckSimpleVector<Base, BAvector>();\n\n   // declare the ADvector type\n   typedef CPPAD_TESTVECTOR(AD<Base>) ADvector;\n\n   // size of the x and y spaces\n   size_t n = size_t(x.size());\n   size_t m = size_t(y.size());\n\n   // check the size of gx and gxx\n   CPPAD_ASSERT_KNOWN(\n      g.size() == 1,\n      \"BenderQuad: size of the vector g is not equal to 1\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(gx.size()) == n,\n      \"BenderQuad: size of the vector gx is not equal to n\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(gxx.size()) == n * n,\n      \"BenderQuad: size of the vector gxx is not equal to n * n\"\n   );\n\n   // some temporary indices\n   size_t i, j;\n\n   // variable versions x\n   ADvector vx(n);\n   for(j = 0; j < n; j++)\n      vx[j] = x[j];\n\n   // declare the independent variables\n   Independent(vx);\n\n   // evaluate h = H(x, y)\n   ADvector h(m);\n   h = fun.h(vx, y);\n\n   // evaluate dy (x) = Newton step as a function of x through h only\n   ADvector dy(m);\n   dy = fun.dy(x, y, h);\n\n   // variable version of y\n   ADvector vy(m);\n   for(j = 0; j < m; j++)\n      vy[j] = y[j] + dy[j];\n\n   // evaluate G~ (x) = F [ x , y + dy(x) ]\n   ADvector gtilde(1);\n   gtilde = fun.f(vx, vy);\n\n   // AD function object that corresponds to G~ (x)\n   // We will make heavy use of this tape, so optimize it\n   ADFun<Base> Gtilde;\n   Gtilde.Dependent(vx, gtilde);\n   Gtilde.optimize();\n\n   // value of G(x)\n   g = Gtilde.Forward(0, x);\n\n   // initial forward direction vector as zero\n   BAvector dx(n);\n   for(j = 0; j < n; j++)\n      dx[j] = Base(0.0);\n\n   // weight, first and second order derivative values\n   BAvector dg(1), w(1), ddw(2 * n);\n   w[0] = 1.;\n\n\n   // Jacobian and Hessian of G(x) is equal Jacobian and Hessian of Gtilde\n   for(j = 0; j < n; j++)\n   {  // compute partials in x[j] direction\n      dx[j] = Base(1.0);\n      dg    = Gtilde.Forward(1, dx);\n      gx[j] = dg[0];\n\n      // restore the dx vector to zero\n      dx[j] = Base(0.0);\n\n      // compute second partials w.r.t x[j] and x[l]  for l = 1, n\n      ddw = Gtilde.Reverse(2, w);\n      for(i = 0; i < n; i++)\n         gxx[ i * n + j ] = ddw[ i * 2 + 1 ];\n   }\n\n   return;\n}\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/bool_fun.hpp",
    "content": "# ifndef CPPAD_CORE_BOOL_FUN_HPP\n# define CPPAD_CORE_BOOL_FUN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin bool_fun}\n\nAD Boolean Functions\n####################\n\nSyntax\n******\n| ``CPPAD_BOOL_UNARY`` ( *Base* , *unary_name* )\n| *b* = *unary_name* ( *u* )\n| *b* = *unary_name* ( *x* )\n| ``CPPAD_BOOL_BINARY`` ( *Base* , *binary_name* )\n| *b* = *binary_name* ( *u* , *v* )\n| *b* = *binary_name* ( *x* , *y* )\n\nPurpose\n*******\nCreate a ``bool`` valued function that has ``AD`` < *Base* > arguments.\n\nunary_name\n**********\nThis is the name of the ``bool`` valued function with one argument\n(as it is used in the source code).\nThe user must provide a version of *unary_name* where\nthe argument has type *Base* .\nCppAD uses this to create a version of *unary_name* where the\nargument has type ``AD`` < *Base* > .\n\nu\n*\nThe argument *u* has prototype\n\n   ``const`` *Base* & *u*\n\nIt is the value at which the user provided version of *unary_name*\nis to be evaluated.\nIt is also used for the first argument to the\nuser provided version of *binary_name* .\n\nx\n*\nThe argument *x* has prototype\n\n   ``const AD`` < *Base* > & *x*\n\nIt is the value at which the CppAD provided version of *unary_name*\nis to be evaluated.\nIt is also used for the first argument to the\nCppAD provided version of *binary_name* .\n\nb\n*\nThe result *b* has prototype\n\n   ``bool`` *b*\n\nCreate Unary\n************\nThe preprocessor macro invocation\n\n   ``CPPAD_BOOL_UNARY`` ( *Base* , *unary_name* )\n\ndefines the version of *unary_name* with a ``AD`` < *Base* >\nargument.\nThis can with in a namespace\n(not the ``CppAD`` namespace)\nbut must be outside of any routine.\n\nbinary_name\n***********\nThis is the name of the ``bool`` valued function with two arguments\n(as it is used in the source code).\nThe user must provide a version of *binary_name* where\nthe arguments have type *Base* .\nCppAD uses this to create a version of *binary_name* where the\narguments have type ``AD`` < *Base* > .\n\nv\n*\nThe argument *v* has prototype\n\n   ``const`` *Base* & *v*\n\nIt is the second argument to\nthe user provided version of *binary_name* .\n\ny\n*\nThe argument *x* has prototype\n\n   ``const AD`` < *Base* > & *y*\n\nIt is the second argument to\nthe CppAD provided version of *binary_name* .\n\nCreate Binary\n*************\nThe preprocessor macro invocation\n\n   ``CPPAD_BOOL_BINARY`` ( *Base* , *binary_name* )\n\ndefines the version of *binary_name* with ``AD`` < *Base* >\narguments.\nThis can with in a namespace\n(not the ``CppAD`` namespace)\nbut must be outside of any routine.\n\nOperation Sequence\n******************\nThe result of this operation is not an\n:ref:`glossary@AD of Base` object.\nThus it will not be recorded as part of an\nAD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/bool_fun.cpp\n}\nThe file\n:ref:`bool_fun.cpp-name`\ncontains an example and test of these operations.\n\nDeprecated 2007-07-31\n*********************\nThe preprocessor symbols ``CppADCreateUnaryBool``\nand ``CppADCreateBinaryBool`` are defined to be the same as\n``CPPAD_BOOL_UNARY`` and ``CPPAD_BOOL_BINARY`` respectively\n(but their use is deprecated).\n\n{xrst_end bool_fun}\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file bool_fun.hpp\nRoutines and macros that implement functions from AD<Base> to bool.\n*/\n\n/*!\nMacro that defines a unary function <tt>bool F(AD<Base> x)</tt>\nusing <tt>bool F(Base x)</tt>.\n\n\\param Base\nbase for the AD type of arguments to this unary bool valued function.\n\n\\param unary_name\nname of this unary function; i.e., F.\n*/\n# define CPPAD_BOOL_UNARY(Base, unary_name)                        \\\n     inline bool unary_name (const CppAD::AD<Base> &x)             \\\n     {                                                             \\\n          return CppAD::AD<Base>::UnaryBool(unary_name, x);        \\\n     }\n\n/*!\nDeprecated name for CPPAD_BOOL_UNARY\n*/\n# define CppADCreateUnaryBool  CPPAD_BOOL_UNARY\n\n/*!\nLink a function name, and AD value pair to function call with base argument\nand bool return value.\n\n\\param FunName\nis the name of the function that we are linking.\n\n\\param x\nis the argument where we are evaluating the function.\n*/\ntemplate <class Base>\nbool AD<Base>::UnaryBool(\n   bool FunName(const Base &x),\n   const AD<Base> &x\n)\n{\n   return FunName(x.value_);\n}\n\n/*!\nMacro that defines a binary function <tt>bool F(AD<Base> x, AD<Base> y)</tt>\nusing <tt>bool F(Base x, Base y)</tt>.\n\n\\param Base\nbase for the AD type of arguments to this binary bool valued function.\n\n\\param binary_name\nname of this binary function; i.e., F.\n*/\n\n# define CPPAD_BOOL_BINARY(Base, binary_name)                      \\\n     inline bool binary_name (                                     \\\n          const CppAD::AD<Base> &x, const CppAD::AD<Base> &y)      \\\n     {                                                             \\\n          return CppAD::AD<Base>::BinaryBool(binary_name, x, y);   \\\n     }\n/*!\nDeprecated name for CPPAD_BOOL_BINARY\n*/\n# define CppADCreateBinaryBool CPPAD_BOOL_BINARY\n\n\n/*!\nLink a function name, and two AD values to function call with base arguments\nand bool return value.\n\n\\param FunName\nis the name of the function that we are linking.\n\n\\param x\nis the first argument where we are evaluating the function at.\n\n\\param y\nis the second argument where we are evaluating the function at.\n*/\ntemplate <class Base>\nbool AD<Base>::BinaryBool(\n   bool FunName(const Base &x, const Base &y),\n   const AD<Base> &x, const AD<Base> &y\n)\n{\n   return FunName(x.value_, y.value_);\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/bool_valued.hpp",
    "content": "# ifndef CPPAD_CORE_BOOL_VALUED_HPP\n# define CPPAD_CORE_BOOL_VALUED_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin bool_valued}\n{xrst_spell\n   dyn\n   ext\n}\n\nBool Valued Operations and Functions with AD Arguments\n######################################################\n{xrst_toc_hidden\n   include/cppad/core/compare.hpp\n   include/cppad/core/near_equal_ext.hpp\n   include/cppad/core/bool_fun.hpp\n   include/cppad/core/con_dyn_var.hpp\n   include/cppad/core/equal_op_seq.hpp\n}\n\n.. csv-table::\n   :widths: auto\n\n   Compare,:ref:`Compare-title`\n   near_equal_ext,:ref:`near_equal_ext-title`\n   bool_fun,:ref:`bool_fun-title`\n   con_dyn_var,:ref:`con_dyn_var-title`\n   EqualOpSeq,:ref:`EqualOpSeq-title`\n\n{xrst_end bool_valued}\n*/\n\n# include <cppad/core/compare.hpp>\n# include <cppad/core/near_equal_ext.hpp>\n# include <cppad/core/bool_fun.hpp>\n# include <cppad/core/con_dyn_var.hpp>\n# include <cppad/core/equal_op_seq.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/capacity_order.hpp",
    "content": "# ifndef CPPAD_CORE_CAPACITY_ORDER_HPP\n# define CPPAD_CORE_CAPACITY_ORDER_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin capacity_order}\n{xrst_spell\n   pre\n   xq\n   yq\n}\n\nControlling Taylor Coefficients Memory Allocation\n#################################################\n\nSyntax\n******\n| *f* . ``capacity_order`` ( *c* )\n\nSee Also\n========\n:ref:`fun_property-name`\n\nPurpose\n*******\nThe Taylor coefficients calculated by :ref:`Forward-name` mode calculations\nare retained in an :ref:`ADFun-name` object for subsequent use during\n:ref:`Reverse-name` mode and higher order Forward mode calculations.\nFor example, a call to :ref:`Forward<forward_order-name>` with the syntax\n\n   *yq* = *f* . ``Forward`` ( *q* , *xq* )\n\nwhere *q*  > 0 and  *xq* . ``size`` () == *f* . ``Domain`` () ,\nuses the lower order Taylor coefficients and\ncomputes the *q*-th order Taylor coefficients for all\nthe variables in the operation sequence corresponding to *f* .\nThe ``capacity_order`` operation allows you to control that\namount of memory that is retained by an AD function object\n(to hold ``Forward`` results for subsequent calculations).\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nc\n*\nThe argument *c* has prototype\n\n   ``size_t`` *c*\n\nIt specifies the number of Taylor coefficient orders that are allocated\nin the AD operation sequence corresponding to *f* .\n\nPre-Allocating Memory\n=====================\nIf you plan to make calls to ``Forward`` with the maximum value of\n*q* equal to *Q* ,\nit should be faster to pre-allocate memory for these calls using\n\n   *f* . ``capacity_order`` ( *c* )\n\nwith *c* equal to :math:`Q + 1`.\nIf you do no do this, ``Forward`` will automatically allocate memory\nand will copy the results to a larger buffer, when necessary.\n\nNote that each call to :ref:`Dependent-name` frees the old memory\nconnected to the function object and sets the corresponding\ntaylor capacity to zero.\n\nFreeing Memory\n==============\nIf you no longer need the Taylor coefficients of order *q*\nand higher (that are stored in *f* ),\nyou can reduce the memory allocated to *f* using\n\n   *f* . ``capacity_order`` ( *c* )\n\nwith *c* equal to *q* .\nNote that, if :ref:`ta_hold_memory-name` is true, this memory is not actually\nreturned to the system, but rather held for future use by the same thread.\n\nOriginal State\n**************\nIf *f* is :ref:`constructed<fun_construct-name>` with the syntax\n\n   ``ADFun`` < *Base* > *f* ( *x* , *y* )\n\n,\nthere is an implicit call to :ref:`forward_zero-name` with *xq* equal to\nthe value of the\n:ref:`independent variables<glossary@Tape@Independent Variable>`\nwhen the AD operation sequence was recorded.\nThis corresponds to *c*  == 1 .\n{xrst_toc_hidden\n   example/general/capacity_order.cpp\n}\nExample\n*******\nThe file\n:ref:`capacity_order.cpp-name`\ncontains an example and test of these operations.\n\n{xrst_end capacity_order}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file capacity_order.hpp\nControl of number of orders allocated.\n\\}\n*/\n\n/*!\nControl of number of orders and directions allocated.\n\n\\tparam Base\nThe type used during the forward mode computations; i.e., the corresponding\nrecording of operations used the type AD<Base>.\n\n\\param c\nis the number of orders to allocate memory for.\nIf <code>c == 0</code> then r must also be zero.\nIn this case num_order_taylor_, cap_order_taylor_, and num_direction_taylor_\nare all set to zero.\nIn addition, taylor_.clear() is called.\n\n\\param r\nis the number of directions to allocate memory for.\nIf <code>c == 1</code> then r must also be one.\nIn all cases, it must hold that\n<code>\n   r == num_direction_taylor_ || num_order_taylor <= 1\n</code>\nUpon return, num_direction_taylor_ is equal to r.\n\n\\par num_order_taylor_\nThe output value of num_order_taylor_ is the mininumum of its input\nvalue and c. This minimum is the number of orders that are copied to the\nnew taylor coefficient buffer.\n\n\\par num_direction_taylor_\nThe output value of num_direction_taylor_ is equal to r.\n*/\n\ntemplate <class Base, class RecBase>\nvoid ADFun<Base,RecBase>::capacity_order(size_t c, size_t r)\n{  // temporary indices\n   size_t i, k, ell;\n\n   if( (c == cap_order_taylor_) && (r == num_direction_taylor_) )\n      return;\n\n   if( c == 0 )\n   {  CPPAD_ASSERT_UNKNOWN( r == 0 );\n      taylor_.clear();\n      num_order_taylor_     = 0;\n      cap_order_taylor_     = 0;\n      num_direction_taylor_ = r;\n      return;\n   }\n   CPPAD_ASSERT_UNKNOWN(r==num_direction_taylor_ || num_order_taylor_<=1);\n\n   // Allocate new taylor with requested number of orders and directions\n   size_t new_len   = ( (c-1)*r + 1 ) * num_var_tape_;\n   local::pod_vector_maybe<Base> new_taylor(new_len);\n\n   // number of orders to copy\n   size_t p = std::min(num_order_taylor_, c);\n   if( p > 0 )\n   {\n      // old order capacity\n      size_t C = cap_order_taylor_;\n\n      // old number of directions\n      size_t R = num_direction_taylor_;\n\n      // copy the old data into the new matrix\n      CPPAD_ASSERT_UNKNOWN( p == 1 || r == R );\n      for(i = 0; i < num_var_tape_; i++)\n      {  // copy zero order\n         size_t old_index = ((C-1) * R + 1) * i + 0;\n         size_t new_index = ((c-1) * r + 1) * i + 0;\n         new_taylor[ new_index ] = taylor_[ old_index ];\n         // copy higher orders\n         for(k = 1; k < p; k++)\n         {  for(ell = 0; ell < R; ell++)\n            {  old_index = ((C-1) * R + 1) * i + (k-1) * R + ell + 1;\n               new_index = ((c-1) * r + 1) * i + (k-1) * r + ell + 1;\n               new_taylor[ new_index ] = taylor_[ old_index ];\n            }\n         }\n      }\n   }\n\n   // replace taylor_ by new_taylor\n   taylor_.swap(new_taylor);\n   cap_order_taylor_     = c;\n   num_order_taylor_     = p;\n   num_direction_taylor_ = r;\n\n   // note that the destructor for new_taylor will free the old taylor memory\n   return;\n}\n\n/*!\nUser API control of number of orders allocated.\n\n\\tparam Base\nThe type used during the forward mode computations; i.e., the corresponding\nrecording of operations used the type AD<Base>.\n\n\\param c\nis the number of orders to allocate memory for.\nIf <code>c == 0</code>,\nnum_order_taylor_, cap_order_taylor_, and num_direction_taylor_\nare all set to zero.\nIn addition, taylor_.clear() is called.\n\n\\par num_order_taylor_\nThe output value of num_order_taylor_ is the mininumum of its input\nvalue and c. This minimum is the number of orders that are copied to the\nnew taylor coefficient buffer.\n\n\\par num_direction_taylor_\nIf is zero (one), num_direction_taylor_ is set to zero (one).\nOtherwise, if num_direction_taylor_ is zero, it is set to one.\nOtherwise, num_direction_taylor_ is not modified.\n*/\n\ntemplate <class Base, class RecBase>\nvoid ADFun<Base,RecBase>::capacity_order(size_t c)\n{  size_t r;\n   if( (c == 0) || (c == 1) )\n   {  r = c;\n      capacity_order(c, r);\n      return;\n   }\n   r = num_direction_taylor_;\n   if( r == 0 )\n      r = 1;\n   capacity_order(c, r);\n   return;\n}\n\n} // END CppAD namespace\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/check_for_nan.hpp",
    "content": "# ifndef CPPAD_CORE_CHECK_FOR_NAN_HPP\n# define CPPAD_CORE_CHECK_FOR_NAN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin check_for_nan}\n{xrst_spell\n   newline\n}\nCheck an ADFun Object For Nan Results\n#####################################\n\nSyntax\n******\n| *f* . ``check_for_nan`` ( *b* )\n| *b* = *f* . ``check_for_nan`` ()\n| ``get_check_for_nan`` ( *vec* , *file* )\n\nDebugging\n*********\nIf ``NDEBUG`` is not defined, and\nthe result of a :ref:`forward<forward_order-name>` or :ref:`reverse<reverse_any-name>`\ncalculation contains a  :ref:`nan-name` ,\nCppAD can halt with an error message.\n\nf\n*\nFor the syntax where *b* is an argument,\n*f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\n(see ``ADFun`` < *Base* > :ref:`constructor<fun_construct-name>` ).\nFor the syntax where *b* is the result,\n*f* has prototype\n\n   ``const ADFun`` < *Base* > *f*\n\nb\n*\nThis argument or result has prototype\n\n   ``bool`` *b*\n\nIf *b* is true (false),\nfuture calls to *f* . ``Forward`` will (will not) check for ``nan`` .\n\nDefault\n*******\nThe value for this setting after construction of *f* is true.\nThe value of this setting is not affected by calling\n:ref:`Dependent-name` for this function object.\n\nError Message\n*************\nIf this error is detected during zero order forward mode,\nthe values of the independent variables that resulted in the ``nan``\nare written to a temporary binary file.\nThis is so that you can run the original source code with those values\nto see what is causing the ``nan`` .\n\nvector_size\n===========\nThe error message with contain the text\n``vector_size`` = *vector_size* followed the newline character\n``'\\n'`` .\nThe value of *vector_size* is the number of elements\nin the independent vector.\n\nfile_name\n=========\nThe error message with contain the text\n``file_name`` = *file_name* followed the newline character\n``'\\n'`` .\nThe value of *file_name* is the name of the temporary file\nthat contains the dependent variable values.\n\nindex\n=====\nThe error message will contain the text\n``index`` = *index* followed by the newline character ``'\\n'`` .\nThe value of *index* is the lowest dependent variable index\nthat has the value ``nan`` .\n\nget_check_for_nan\n*****************\nThis routine can be used to get the independent variable\nvalues that result in a ``nan`` .\n\nvec\n===\nThis argument has prototype\n\n   ``CppAD::vector<`` *Base* >& *vec*\n\nIt size must be equal to the corresponding value of\n:ref:`check_for_nan@Error Message@vector_size`\nin the corresponding error message.\nThe input value of its elements does not matter.\nUpon return, it will contain the values for the independent variables,\nin the corresponding call to :ref:`Independent-name` ,\nthat resulted in the ``nan`` .\n(Note that the call to ``Independent`` uses an vector with elements\nof type ``AD`` < *Base* > and *vec* has elements of type\n*Base* .)\n\nfile\n====\nThis argument has prototype\n\n   ``const std::string&`` *file*\n\nIt must be the value of\n:ref:`check_for_nan@Error Message@file_name`\nin the corresponding error message.\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/check_for_nan.cpp\n}\nThe file\n:ref:`check_for_nan.cpp-name`\ncontains an example and test of these operations.\n\n{xrst_end check_for_nan}\n*/\n\n# include <fstream>\n# include <cppad/utility/vector.hpp>\n# include <cppad/local/temp_file.hpp>\n\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*!\nSet check_for_nan\n\n\\param value\nnew value for this flag.\n*/\ntemplate <class Base, class RecBase>\nvoid ADFun<Base,RecBase>::check_for_nan(bool value)\n{  check_for_nan_ = value; }\n\n/*!\nGet check_for_nan\n\n\\return\ncurrent value of check_for_nan_.\n*/\ntemplate <class Base, class RecBase>\nbool ADFun<Base,RecBase>::check_for_nan(void) const\n{  return check_for_nan_; }\n\n/*!\nStores a vector in a file when nans occur.\n\n\\param vec [in]\nis the vector that is stored.\n\n\\param [out] file_name\nis the file where the vector is stored\n*/\ntemplate <class Base>\nvoid put_check_for_nan(const CppAD::vector<Base>& vec, std::string& file_name)\n{\n   // char_size\n   std::streamsize char_size = std::streamsize( sizeof(Base) * vec.size() );\n   //\n   // char_ptr\n   const char* char_ptr   = reinterpret_cast<const char*>( vec.data() );\n   //\n   // file_name\n   file_name = local::temp_file();\n   //\n   // write data to file_name\n   std::fstream file_out(file_name.c_str(), std::ios::out|std::ios::binary );\n   file_out.write(char_ptr, char_size);\n   file_out.close();\n   //\n   return;\n}\n/*!\nGets a vector that was stored by put_check_for_nan.\n\n\\param vec [out]\nis the vector that is stored.\n\n\\param file_name [in]\nis the file where the vector is stored\n*/\ntemplate <class Base>\nvoid get_check_for_nan(CppAD::vector<Base>& vec, const std::string& file_name)\n{  //\n   std::streamsize char_size = std::streamsize( sizeof(Base) * vec.size() );\n   char* char_ptr   = reinterpret_cast<char*>( vec.data() );\n   //\n   std::fstream file_in(file_name.c_str(), std::ios::in|std::ios::binary );\n   file_in.read(char_ptr, char_size);\n   //\n   return;\n}\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_one/chkpoint_one.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_ONE_CHKPOINT_ONE_HPP\n# define CPPAD_CORE_CHKPOINT_ONE_CHKPOINT_ONE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/sparse/list_setvec.hpp>\n# include <cppad/local/sparse/pack_setvec.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file chkpoint_one.hpp\nFirst generation checkpoint functions.\n*/\n\n/*\n{xrst_begin chkpoint_one app}\n{xrst_spell\n   algo\n   sv\n}\n\nCheckpoint Functions: First Generation\n######################################\n\nDeprecated 2019-01-14\n*********************\nUsing the ``checkpoint`` class has been deprecated.\nUse :ref:`chkpoint_two-name` instead.\n\nSyntax\n******\n| ``checkpoint`` < *Base* > *atom_fun* (\n| |tab| *name* , *algo* , *ax* , *ay* , *sparsity* , *optimize*\n| )\n| *sv* = *atom_fun* . ``size_var`` ()\n| *atom_fun* . ``option`` ( *option_value* )\n| *algo* ( *ax* , *ay* )\n| *atom_fun* ( *ax* , *ay* )\n| *checkpoint* < ``Base`` >:: *clear* ()\n\nSee Also\n********\n:ref:`atomic_two-name` , :ref:`rev_checkpoint.cpp-name`\n\nPurpose\n*******\n\nReduce Memory\n=============\nYou can reduce the size of the tape and memory required for AD by\ncheckpointing functions of the form :math:`y = f(x)` where\n:math:`f : \\B{R}^n \\rightarrow \\B{R}^m`.\n\nFaster Recording\n================\nIt may also reduce the time to make a recording the same function\nfor different values of the independent variable.\nNote that the operation sequence for a recording that uses :math:`f(x)`\nmay depend on its independent variables.\n\nRepeating Forward\n=================\nNormally, CppAD store :ref:`forward-name` mode results until they freed\nusing :ref:`capacity_order-name` or the corresponding :ref:`ADFun-name` object is\ndeleted. This is not true for checkpoint functions because a checkpoint\nfunction may be used repeatedly with different arguments in the same tape.\nThus, forward mode results are recomputed each time a checkpoint function\nis used during a forward or reverse mode sweep.\n\nRestriction\n===========\nThe :ref:`operation sequence<glossary@Operation@Sequence>`\nrepresenting :math:`f(x)` cannot depend on the value of :math:`x`.\nThe approach in the :ref:`rev_checkpoint.cpp-name` example case be applied\nwhen the operation sequence depends on :math:`x`.\n\nMultiple Level AD\n=================\nIf *Base* is an AD type, it is possible to record *Base*\noperations.\nNote that *atom_fun* will treat *algo* as an atomic\noperation while recording ``AD`` < ``Base`` > operations, but not while\nrecording *Base* operations.\nSee the ``chkpoint_one_mul_level.cpp`` example.\n\nMethod\n******\nThe ``checkpoint`` class is derived from ``atomic_base``\nand makes this easy.\nIt implements all the ``atomic_base``\n:ref:`atomic_two@Virtual Functions`\nand hence its source code ``cppad/core/chkpoint_one/chkpoint_one.hpp``\nprovides an example implementation of :ref:`atomic_two-name` .\nThe difference is that ``chkpoint_one.hpp`` uses AD\ninstead of user provided derivatives.\n\nconstructor\n***********\nThe syntax for the checkpoint constructor is\n\n   ``checkpoint`` < *Base* > *atom_fun* ( *name* , *algo* , *ax* , *ay* )\n\n#. This constructor cannot be called in :ref:`parallel<ta_in_parallel-name>` mode.\n#. You cannot currently be recording\n   ``AD`` < *Base* > operations when the constructor is called.\n#. This object *atom_fun* must not be destructed for as long\n   as any ``ADFun`` < *Base* > object uses its atomic operation.\n#. This class is implemented as a derived class of\n   :ref:`atomic<atomic_two_ctor@atomic_base>` and hence\n   some of its error message will refer to ``atomic_base`` .\n\nBase\n****\nThe type *Base* specifies the base type for AD operations.\n\nADVector\n********\nThe type *ADVector* must be a\n:ref:`simple vector class<SimpleVector-name>` with elements of type\n``AD`` < *Base* > .\n\nname\n****\nThis *checkpoint* constructor argument has prototype\n\n   ``const char`` * *name*\n\nIt is the name used for error reporting.\nThe suggested value for *name* is *atom_fun* ; i.e.,\nthe same name as used for the object being constructed.\n\nax\n**\nThis argument has prototype\n\n   ``const`` *ADVector* & *ax*\n\nand size must be equal to *n* .\nIt specifies vector :math:`x \\in \\B{R}^n`\nat which an ``AD`` < *Base* > version of\n:math:`y = f(x)` is to be evaluated.\n\nay\n**\nThis argument has prototype\n\n   *ADVector* & *ay*\n\nIts input size must be equal to *m* and does not change.\nThe input values of its elements do not matter.\nUpon return, it is an ``AD`` < *Base* > version of\n:math:`y = f(x)`.\n\nsparsity\n********\nThis argument has prototype\n\n   ``atomic_base`` < *Base* >:: ``option_enum`` *sparsity*\n\nIt specifies :ref:`atomic_two_ctor@atomic_base@sparsity`\nin the ``atomic_base`` constructor and must be either\n``atomic_base`` < *Base* >:: ``pack_sparsity_enum`` ,\n``atomic_base`` < *Base* >:: ``bool_sparsity_enum`` , or\n``atomic_base`` < *Base* >:: ``set_sparsity_enum`` .\nThis argument is optional and its default value is unspecified.\n\noptimize\n********\nThis argument has prototype\n\n   ``bool`` *optimize*\n\nIt specifies if the recording corresponding to the atomic function\nshould be :ref:`optimized<optimize-name>` .\nOne expects to use a checkpoint function many times, so it should\nbe worth the time to optimize its operation sequence.\nFor debugging purposes, it may be useful to use the\noriginal operation sequence (before optimization)\nbecause it corresponds more closely to *algo* .\nThis argument is optional and its default value is true.\n\nsize_var\n********\nThis ``size_var`` member function return value has prototype\n\n   ``size_t`` *sv*\n\nIt is the :ref:`fun_property@size_var` for the\n``ADFun`` < *Base* > object is used to store the operation sequence\ncorresponding to *algo* .\n\noption\n******\nThe ``option`` syntax can be used to set the type of sparsity\npattern used by *atom_fun* .\nThis is an ``atomic_base`` < *Base* > function and its documentation\ncan be found at :ref:`atomic_two_option-name` .\n\nalgo\n****\nThe type of *algo* is arbitrary, except for the fact that\nthe syntax\n\n   *algo* ( *ax* , *ay* )\n\nmust evaluate the function :math:`y = f(x)` using\n``AD`` < *Base* > operations.\nIn addition, we assume that the\n:ref:`operation sequence<glossary@Operation@Sequence>`\ndoes not depend on the value of *ax* .\n\natom_fun\n********\nGiven *ax* it computes the corresponding value of *ay*\nusing the operation sequence corresponding to *algo* .\nIf ``AD`` < *Base* > operations are being recorded,\nit enters the computation as single operation in the recording\nsee :ref:`Independent@Start Recording` .\n(Currently each use of *atom_fun* actually corresponds to\n*m* + *n* +2 operations and creates *m* new variables,\nbut this is not part of the CppAD specifications and my change.)\n\nMemory\n******\n\nRestriction\n===========\nThe ``clear`` routine cannot be called\nwhile in :ref:`parallel<ta_in_parallel-name>` execution mode.\n\nParallel Mode\n*************\nThe CppAD checkpoint function delays the caching of certain calculations\nuntil they are needed.\nIn :ref:`parallel model<ta_parallel_setup-name>` ,\nthis may result in :ref:`thread_alloc::inuse(thread)<ta_inuse-name>`\nbeing non-zero even though the specified thread is no longer active.\nThis memory will be freed when the checkpoint object is deleted.\n\nclear\n=====\nThe ``atomic_base`` class holds onto static work space\nthat is not connected to a particular object\n(in order to increase speed by avoiding system memory allocation calls).\nThis call makes to work space :ref:`available<ta_available-name>` to\nfor other uses by the same thread.\nThis should be called when you are done using the\natomic functions for a specific value of *Base* .\n\n{xrst_end chkpoint_one}\n*/\n\ntemplate <class Base>\nclass checkpoint : public atomic_base<Base> {\n// ---------------------------------------------------------------------------\nprivate:\n   /// same as option_enum in base class\n   typedef typename atomic_base<Base>::option_enum option_enum;\n   //\n   // ------------------------------------------------------------------------\n   // member_\n   // ------------------------------------------------------------------------\n   // same checkpoint object can be used by multiple threads\n   struct member_struct {\n      //\n      /// AD function corresponding to this checkpoint object\n      ADFun<Base>             f_;\n      ADFun< AD<Base>, Base > af_;\n      //\n      /// sparsity for entire Jacobian f(x)^{(1)}\n      /// does not change so can cache it\n      local::sparse::list_setvec jac_sparse_set_;\n      vectorBool                 jac_sparse_bool_;\n      //\n      /// sparsity for sum_i f_i(x)^{(2)} does not change so can cache it\n      local::sparse::list_setvec hes_sparse_set_;\n      vectorBool                 hes_sparse_bool_;\n   };\n   /// This version of work is const except during constructor\n   member_struct const_member_;\n\n   /// use pointers and allocate memory to avoid false sharing\n   member_struct* member_[CPPAD_MAX_NUM_THREADS];\n   //\n   /// allocate member_ for this thread\n   void allocate_member(size_t thread)\n   {  if( member_[thread] == nullptr )\n      {  member_[thread] = new member_struct;\n         // The function is recorded in sequential mode and placed in\n         // const_member_.f_, other threads have copy.\n         member_[thread]->f_ = const_member_.f_;\n      }\n      return;\n   }\n   //\n   /// free member_ for this thread\n   void free_member(size_t thread)\n   {  if( member_[thread] != nullptr )\n      {  delete member_[thread];\n         member_[thread] = nullptr;\n      }\n      return;\n   }\n   // ------------------------------------------------------------------------\n   option_enum sparsity(void)\n   {  return static_cast< atomic_base<Base>* >(this)->sparsity(); }\n   // ------------------------------------------------------------------------\n   /// set jac_sparse_set_\n   void set_jac_sparse_set(void);\n   /// set jac_sparse_bool_\n   void set_jac_sparse_bool(void);\n   // ------------------------------------------------------------------------\n   /// set hes_sparse_set_\n   void set_hes_sparse_set(void);\n   /// set hes_sparse_bool_\n   void set_hes_sparse_bool(void);\n   // ------------------------------------------------------------------------\n   /*!\n   Link from user_atomic to forward sparse Jacobian pack and bool\n\n   \\copydetails atomic_base::for_sparse_jac\n   */\n   template <class sparsity_type>\n   bool for_sparse_jac_sparsity_type(\n      size_t                                  q  ,\n      const sparsity_type&                    r  ,\n              sparsity_type&                    s  ,\n      const vector<Base>&                     x\n   );\n   // ------------------------------------------------------------------------\n   /*!\n   Link from user_atomic to reverse sparse Jacobian pack and bool\n\n   \\copydetails atomic_base::rev_sparse_jac\n   */\n   template <class sparsity_type>\n   bool rev_sparse_jac_sparsity_type(\n      size_t                                  q  ,\n      const sparsity_type&                    rt ,\n              sparsity_type&                    st ,\n      const vector<Base>&                     x\n   );\n   /*!\n   Link from user_atomic to reverse sparse Hessian  bools\n\n   \\copydetails atomic_base::rev_sparse_hes\n   */\n   template <class sparsity_type>\n   bool rev_sparse_hes_sparsity_type(\n      const vector<bool>&                     vx ,\n      const vector<bool>&                     s  ,\n              vector<bool>&                     t  ,\n      size_t                                  q  ,\n      const sparsity_type&                    r  ,\n      const sparsity_type&                    u  ,\n              sparsity_type&                    v  ,\n      const vector<Base>&                     x\n   );\npublic:\n   // ------------------------------------------------------------------------\n   /*!\n   Constructor of a checkpoint object\n\n   \\param name [in]\n   is the user's name for the AD version of this atomic operation.\n\n   \\param algo [in/out]\n   user routine that compute AD function values\n   (not const because state may change during evaluation).\n\n   \\param ax [in]\n   argument value where algo operation sequence is taped.\n\n   \\param ay [out]\n   function value at specified argument value.\n\n   \\param sparsity [in]\n   what type of sparsity patterns are computed by this function,\n   pack_sparsity_enum bool_sparsity_enum, or set_sparsity_enum.\n   The default value is unspecified.\n\n   \\param optimize [in]\n   should the operation sequence corresponding to the algo be optimized.\n   The default value is true, but it is\n   sometimes useful to use false for debugging purposes.\n   */\n   template <class Algo, class ADVector>\n   checkpoint(\n      const char*                    name            ,\n      Algo&                          algo            ,\n      const ADVector&                ax              ,\n      ADVector&                      ay              ,\n      option_enum                    sparsity =\n            atomic_base<Base>::pack_sparsity_enum  ,\n      bool                           optimize = true\n   );\n   /// destructor\n   ~checkpoint(void)\n   {\n# ifndef NDEBUG\n      if( thread_alloc::in_parallel() )\n      {  std::string msg = atomic_base<Base>::atomic_name();\n         msg += \": checkpoint destructor called in parallel mode.\";\n         CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n      }\n# endif\n      for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; ++thread)\n         free_member(thread);\n   }\n   // ------------------------------------------------------------------------\n   /*!\n   Implement the user call to atom_fun.size_var().\n   */\n   size_t size_var(void)\n   {  // make sure member_ is allocated for this thread\n      size_t thread = thread_alloc::thread_num();\n      allocate_member(thread);\n      //\n      return member_[thread]->f_.size_var();\n   }\n   // ------------------------------------------------------------------------\n   /*!\n   Implement the user call to atom_fun(ax, ay).\n\n   \\tparam ADVector\n   A simple vector class with elements of type AD<Base>.\n\n   \\param id\n   optional parameter which must be zero if present.\n\n   \\param ax\n   is the argument vector for this call,\n   ax.size() determines the number of arguments.\n\n   \\param ay\n   is the result vector for this call,\n   ay.size() determines the number of results.\n   */\n   template <class ADVector>\n   void operator()(const ADVector& ax, ADVector& ay, size_t id = 0)\n   {  CPPAD_ASSERT_KNOWN(\n         id == 0,\n         \"checkpoint: id is non-zero in atom_fun(ax, ay, id)\"\n      );\n      this->atomic_base<Base>::operator()(ax, ay, id);\n   }\n   // ------------------------------------------------------------------------\n   /*!\n   Link from user_atomic to forward mode\n\n   \\copydetails atomic_base::forward\n   */\n   virtual bool forward(\n      size_t                      p  ,\n      size_t                      q  ,\n      const vector<bool>&         vx ,\n              vector<bool>&         vy ,\n      const vector<Base>&         tx ,\n              vector<Base>&         ty\n   );\n   virtual bool forward(\n      size_t                      p   ,\n      size_t                      q   ,\n      const vector<bool>&         vx  ,\n              vector<bool>&         vy  ,\n      const vector< AD<Base> >&   atx ,\n              vector< AD<Base> >&   aty\n   );\n   // ------------------------------------------------------------------------\n   /*!\n   Link from user_atomic to reverse mode\n\n   \\copydetails atomic_base::reverse\n   */\n   virtual bool reverse(\n      size_t                          q  ,\n      const vector<Base>&             tx ,\n      const vector<Base>&             ty ,\n              vector<Base>&             px ,\n      const vector<Base>&             py\n   );\n   virtual bool reverse(\n      size_t                          q  ,\n      const vector< AD<Base> >&       atx ,\n      const vector< AD<Base> >&       aty ,\n              vector< AD<Base> >&       apx ,\n      const vector< AD<Base> >&       apy\n   );\n   // ------------------------------------------------------------------------\n   /*!\n   Link from user_atomic to forward sparse Jacobian pack\n\n   \\copydetails atomic_base::for_sparse_jac\n   */\n   virtual bool for_sparse_jac(\n      size_t                                  q  ,\n      const vectorBool&                       r  ,\n              vectorBool&                       s  ,\n      const vector<Base>&                     x\n   );\n   /*!\n   Link from user_atomic to forward sparse Jacobian bool\n\n   \\copydetails atomic_base::for_sparse_jac\n   */\n   virtual bool for_sparse_jac(\n      size_t                                  q  ,\n      const vector<bool>&                     r  ,\n              vector<bool>&                     s  ,\n      const vector<Base>&                     x\n   );\n   /*!\n   Link from user_atomic to forward sparse Jacobian sets\n\n   \\copydetails atomic_base::for_sparse_jac\n   */\n   virtual bool for_sparse_jac(\n      size_t                                  q  ,\n      const vector< std::set<size_t> >&       r  ,\n              vector< std::set<size_t> >&       s  ,\n      const vector<Base>&                     x\n   );\n   // ------------------------------------------------------------------------\n   /*!\n   Link from user_atomic to reverse sparse Jacobian pack\n\n   \\copydetails atomic_base::rev_sparse_jac\n   */\n   virtual bool rev_sparse_jac(\n      size_t                                  q  ,\n      const vectorBool&                       rt ,\n              vectorBool&                       st ,\n      const vector<Base>&                     x\n   );\n   /*!\n   Link from user_atomic to reverse sparse Jacobian bool\n\n   \\copydetails atomic_base::rev_sparse_jac\n   */\n   virtual bool rev_sparse_jac(\n      size_t                                  q  ,\n      const vector<bool>&                     rt ,\n              vector<bool>&                     st ,\n      const vector<Base>&                     x\n   );\n   /*!\n   Link from user_atomic to reverse Jacobian sets\n\n   \\copydetails atomic_base::rev_sparse_jac\n   */\n   virtual bool rev_sparse_jac(\n      size_t                                  q  ,\n      const vector< std::set<size_t> >&       rt ,\n              vector< std::set<size_t> >&       st ,\n      const vector<Base>&                     x\n   );\n   // ------------------------------------------------------------------------\n   /*!\n   Link from user_atomic to reverse sparse Hessian pack\n\n   \\copydetails atomic_base::rev_sparse_hes\n   */\n   virtual bool rev_sparse_hes(\n      const vector<bool>&                     vx ,\n      const vector<bool>&                     s  ,\n              vector<bool>&                     t  ,\n      size_t                                  q  ,\n      const vectorBool&                       r  ,\n      const vectorBool&                       u  ,\n              vectorBool&                       v  ,\n      const vector<Base>&                     x\n   );\n   /*!\n   Link from user_atomic to reverse sparse Hessian bool\n\n   \\copydetails atomic_base::rev_sparse_hes\n   */\n   virtual bool rev_sparse_hes(\n      const vector<bool>&                     vx ,\n      const vector<bool>&                     s  ,\n              vector<bool>&                     t  ,\n      size_t                                  q  ,\n      const vector<bool>&                     r  ,\n      const vector<bool>&                     u  ,\n              vector<bool>&                     v  ,\n      const vector<Base>&                     x\n   );\n   /*!\n   Link from user_atomic to reverse sparse Hessian sets\n\n   \\copydetails atomic_base::rev_sparse_hes\n   */\n   virtual bool rev_sparse_hes(\n      const vector<bool>&                     vx ,\n      const vector<bool>&                     s  ,\n              vector<bool>&                     t  ,\n      size_t                                  q  ,\n      const vector< std::set<size_t> >&       r  ,\n      const vector< std::set<size_t> >&       u  ,\n              vector< std::set<size_t> >&       v  ,\n      const vector<Base>&                     x\n   );\n};\n\n} // END_CPPAD_NAMESPACE\n\n// functions implemented in cppad/core/checkpoint files\n# include <cppad/core/chkpoint_one/ctor.hpp>\n# include <cppad/core/chkpoint_one/reverse.hpp>\n# include <cppad/core/chkpoint_one/forward.hpp>\n# include <cppad/core/chkpoint_one/rev_sparse_hes.hpp>\n# include <cppad/core/chkpoint_one/rev_sparse_jac.hpp>\n# include <cppad/core/chkpoint_one/for_sparse_jac.hpp>\n# include <cppad/core/chkpoint_one/set_hes_sparse_bool.hpp>\n# include <cppad/core/chkpoint_one/set_hes_sparse_set.hpp>\n# include <cppad/core/chkpoint_one/set_jac_sparse_bool.hpp>\n# include <cppad/core/chkpoint_one/set_jac_sparse_set.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_one/ctor.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_ONE_CTOR_HPP\n# define CPPAD_CORE_CHKPOINT_ONE_CTOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\ntemplate <class Base>\ntemplate <class Algo, class ADVector>\ncheckpoint<Base>::checkpoint(\n   const char*                    name            ,\n   Algo&                          algo            ,\n   const ADVector&                ax              ,\n   ADVector&                      ay              ,\n   option_enum                    sparsity        ,\n   bool                           optimize\n) : atomic_base<Base>(name, sparsity)\n{\n# ifndef NDEBUG\n   if( thread_alloc::in_parallel() )\n   {  std::string msg = name;\n      msg += \": checkpoint constructor called in parallel mode.\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# endif\n   for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; ++thread)\n      member_[thread] = nullptr;\n   //\n   CheckSimpleVector< CppAD::AD<Base> , ADVector>();\n   //\n   // make a copy of ax because Independent modifies AD information\n   ADVector x_tmp(ax);\n   // declare x_tmp as the independent variables\n   Independent(x_tmp);\n   // record mapping from x_tmp to ay\n   algo(x_tmp, ay);\n   // create function f_ : x -> y\n   const_member_.f_.Dependent(ay);\n   if( optimize )\n   {  // suppress checking for nan in f_ results\n      // (see optimize documentation for atomic functions)\n      const_member_.f_.check_for_nan(false);\n      //\n      // now optimize\n      const_member_.f_.optimize();\n   }\n   // now disable checking of comparison operations\n   // 2DO: add a debugging mode that checks for changes and aborts\n   const_member_.f_.compare_change_count(0);\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_one/for_sparse_jac.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_ONE_FOR_SPARSE_JAC_HPP\n# define CPPAD_CORE_CHKPOINT_ONE_FOR_SPARSE_JAC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\ntemplate <class Base>\ntemplate <class sparsity_type>\nbool checkpoint<Base>::for_sparse_jac_sparsity_type(\n   size_t                                  q  ,\n   const sparsity_type&                    r  ,\n          sparsity_type&                    s  ,\n   const vector<Base>&                     x  )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   // during user sparsity calculations\n   size_t m = member_[thread]->f_.Range();\n   size_t n = member_[thread]->f_.Domain();\n   if( member_[thread]->jac_sparse_bool_.size() == 0 )\n      set_jac_sparse_bool();\n   if( member_[thread]->jac_sparse_set_.n_set() != 0 )\n      member_[thread]->jac_sparse_set_.resize(0, 0);\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_bool_.size() == m * n );\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_set_.n_set() == 0 );\n   CPPAD_ASSERT_UNKNOWN( r.size() == n * q );\n   CPPAD_ASSERT_UNKNOWN( s.size() == m * q );\n   //\n   bool ok = true;\n   for(size_t i = 0; i < m; i++)\n   {  for(size_t k = 0; k < q; k++)\n         s[i * q + k] = false;\n   }\n   // sparsity for  s = jac_sparse_bool_ * r\n   for(size_t i = 0; i < m; i++)\n   {  for(size_t k = 0; k < q; k++)\n      {  // initialize sparsity for S(i,k)\n         bool s_ik = false;\n         // S(i,k) = sum_j J(i,j) * R(j,k)\n         for(size_t j = 0; j < n; j++)\n         {  bool J_ij = member_[thread]->jac_sparse_bool_[ i * n + j];\n            bool R_jk = r[j * q + k ];\n            s_ik |= ( J_ij & R_jk );\n         }\n         s[i * q + k] = s_ik;\n      }\n   }\n   return ok;\n}\ntemplate <class Base>\nbool checkpoint<Base>::for_sparse_jac(\n   size_t                                  q  ,\n   const vectorBool&                       r  ,\n          vectorBool&                       s  ,\n   const vector<Base>&                     x  )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   return for_sparse_jac_sparsity_type< vectorBool >(q, r, s, x);\n}\ntemplate <class Base>\nbool checkpoint<Base>::for_sparse_jac(\n   size_t                                  q  ,\n   const vector<bool>&                     r  ,\n          vector<bool>&                     s  ,\n   const vector<Base>&                     x  )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   return for_sparse_jac_sparsity_type< vector<bool> >(q, r, s, x);\n}\ntemplate <class Base>\nbool checkpoint<Base>::for_sparse_jac(\n   size_t                                  q  ,\n   const vector< std::set<size_t> >&       r  ,\n          vector< std::set<size_t> >&       s  ,\n   const vector<Base>&                     x  )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   // during user sparsity calculations\n   size_t m = member_[thread]->f_.Range();\n   size_t n = member_[thread]->f_.Domain();\n   if( member_[thread]->jac_sparse_bool_.size() != 0 )\n      member_[thread]->jac_sparse_bool_.clear();\n   if( member_[thread]->jac_sparse_set_.n_set() == 0 )\n      set_jac_sparse_set();\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_bool_.size() == 0 );\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_set_.n_set() == m );\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_set_.end()   == n );\n   CPPAD_ASSERT_UNKNOWN( r.size() == n );\n   CPPAD_ASSERT_UNKNOWN( s.size() == m );\n\n   bool ok = true;\n   for(size_t i = 0; i < m; i++)\n      s[i].clear();\n\n   // sparsity for  s = jac_sparse_set_ * r\n   for(size_t i = 0; i < m; i++)\n   {  // compute row i of the return pattern\n      local::sparse::list_setvec::const_iterator set_itr(\n         member_[thread]->jac_sparse_set_, i\n      );\n      size_t j = *set_itr;\n      while(j < n )\n      {  std::set<size_t>::const_iterator itr_j;\n         const std::set<size_t>& r_j( r[j] );\n         for(itr_j = r_j.begin(); itr_j != r_j.end(); itr_j++)\n         {  size_t k = *itr_j;\n            CPPAD_ASSERT_UNKNOWN( k < q );\n            s[i].insert(k);\n         }\n         j = *(++set_itr);\n      }\n   }\n\n   return ok;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_one/forward.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_ONE_FORWARD_HPP\n# define CPPAD_CORE_CHKPOINT_ONE_FORWARD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n// ---------------------------------------------------------------------------\ntemplate <class Base>\nbool checkpoint<Base>::forward(\n   size_t                   p  ,\n   size_t                   q  ,\n   const vector<bool>&      vx ,\n          vector<bool>&      vy ,\n   const vector<Base>&      tx ,\n          vector<Base>&      ty )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   size_t n = member_[thread]->f_.Domain();\n   size_t m = member_[thread]->f_.Range();\n   //\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_var() > 0 );\n   CPPAD_ASSERT_UNKNOWN( tx.size() % (q+1) == 0 );\n   CPPAD_ASSERT_UNKNOWN( ty.size() % (q+1) == 0 );\n   CPPAD_ASSERT_UNKNOWN( n == tx.size() / (q+1) );\n   CPPAD_ASSERT_UNKNOWN( m == ty.size() / (q+1) );\n   bool ok  = true;\n   //\n   if( vx.size() == 0 )\n   {  // during user forward mode\n      if( member_[thread]->jac_sparse_set_.n_set() != 0 )\n         member_[thread]->jac_sparse_set_.resize(0,0);\n      if( member_[thread]->jac_sparse_bool_.size() != 0 )\n         member_[thread]->jac_sparse_bool_.clear();\n      //\n      if( member_[thread]->hes_sparse_set_.n_set() != 0 )\n         member_[thread]->hes_sparse_set_.resize(0,0);\n      if( member_[thread]->hes_sparse_bool_.size() != 0 )\n         member_[thread]->hes_sparse_bool_.clear();\n   }\n   if( vx.size() > 0 )\n   {  // need Jacobian sparsity pattern to determine variable relation\n      // during user recording using checkpoint functions\n      if( sparsity() == atomic_base<Base>::set_sparsity_enum )\n      {  if( member_[thread]->jac_sparse_set_.n_set() == 0 )\n            set_jac_sparse_set();\n         CPPAD_ASSERT_UNKNOWN(\n            member_[thread]->jac_sparse_set_.n_set() == m\n         );\n         CPPAD_ASSERT_UNKNOWN(\n            member_[thread]->jac_sparse_set_.end()   == n\n         );\n         //\n         for(size_t i = 0; i < m; i++)\n         {  vy[i] = false;\n            local::sparse::list_setvec::const_iterator set_itr(\n               member_[thread]->jac_sparse_set_, i\n            );\n            size_t j = *set_itr;\n            while(j < n )\n            {  // y[i] depends on the value of x[j]\n               // cast avoid Microsoft warning (should not be needed)\n               vy[i] |= static_cast<bool>( vx[j] );\n               j = *(++set_itr);\n            }\n         }\n      }\n      else\n      {  if( member_[thread]->jac_sparse_set_.n_set() != 0 )\n            member_[thread]->jac_sparse_set_.resize(0, 0);\n         if( member_[thread]->jac_sparse_bool_.size() == 0 )\n            set_jac_sparse_bool();\n         CPPAD_ASSERT_UNKNOWN(\n            member_[thread]->jac_sparse_set_.n_set() == 0\n         );\n         CPPAD_ASSERT_UNKNOWN(\n            member_[thread]->jac_sparse_bool_.size() == m * n\n         );\n         //\n         for(size_t i = 0; i < m; i++)\n         {  vy[i] = false;\n            for(size_t j = 0; j < n; j++)\n            {  if( member_[thread]->jac_sparse_bool_[ i * n + j ] )\n               {  // y[i] depends on the value of x[j]\n                  // cast avoid Microsoft warning\n                  vy[i] |= static_cast<bool>( vx[j] );\n               }\n            }\n         }\n      }\n   }\n   // compute forward results for orders zero through q\n   ty = member_[thread]->f_.Forward(q, tx);\n\n   // no longer need the Taylor coefficients in f_\n   // (have to reconstruct them every time)\n   // Hold onto sparsity pattern because it is always good.\n   size_t c = 0;\n   size_t r = 0;\n   member_[thread]->f_.capacity_order(c, r);\n   return ok;\n}\n\n// ---------------------------------------------------------------------------\ntemplate <class Base>\nbool checkpoint<Base>::forward(\n   size_t                     p   ,\n   size_t                     q   ,\n   const vector<bool>&        vx  ,\n          vector<bool>&        vy  ,\n   const vector< AD<Base> >&  atx ,\n          vector< AD<Base> >&  aty )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   // make sure af_ is defined\n   if( member_[thread]->af_.size_var() == 0 )\n      member_[thread]->af_ = member_[thread]->f_.base2ad();\n   //\n# ifndef NDEBUG\n   size_t n = member_[thread]->f_.Domain();\n   size_t m = member_[thread]->f_.Range();\n# endif\n   //\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_var() > 0 );\n   CPPAD_ASSERT_UNKNOWN( atx.size() % (q+1) == 0 );\n   CPPAD_ASSERT_UNKNOWN( aty.size() % (q+1) == 0 );\n   CPPAD_ASSERT_UNKNOWN( n == atx.size() / (q+1) );\n   CPPAD_ASSERT_UNKNOWN( m == aty.size() / (q+1) );\n   CPPAD_ASSERT_UNKNOWN( vx.size() == 0 )\n   bool ok  = true;\n   //\n   // during user forward mode\n   if( member_[thread]->jac_sparse_set_.n_set() != 0 )\n      member_[thread]->jac_sparse_set_.resize(0,0);\n   if( member_[thread]->jac_sparse_bool_.size() != 0 )\n      member_[thread]->jac_sparse_bool_.clear();\n   //\n   if( member_[thread]->hes_sparse_set_.n_set() != 0 )\n      member_[thread]->hes_sparse_set_.resize(0,0);\n   if( member_[thread]->hes_sparse_bool_.size() != 0 )\n      member_[thread]->hes_sparse_bool_.clear();\n   //\n   // compute forward results for orders zero through q\n   aty = member_[thread]->af_.Forward(q, atx);\n\n   // no longer need the Taylor coefficients in af_\n   // (have to reconstruct them every time)\n   // Hold onto sparsity pattern because it is always good.\n   size_t c = 0;\n   size_t r = 0;\n   member_[thread]->af_.capacity_order(c, r);\n   //\n   return ok;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_one/rev_sparse_hes.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_ONE_REV_SPARSE_HES_HPP\n# define CPPAD_CORE_CHKPOINT_ONE_REV_SPARSE_HES_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\ntemplate <class Base>\ntemplate <class sparsity_type>\nbool checkpoint<Base>::rev_sparse_hes_sparsity_type(\n   const vector<bool>&                     vx ,\n   const vector<bool>&                     s  ,\n          vector<bool>&                     t  ,\n   size_t                                  q  ,\n   const sparsity_type&                    r  ,\n   const sparsity_type&                    u  ,\n          sparsity_type&                    v  ,\n   const vector<Base>&                     x  )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   size_t n = member_[thread]->f_.Domain();\n# ifndef NDEBUG\n   size_t m = member_[thread]->f_.Range();\n# endif\n   CPPAD_ASSERT_UNKNOWN( vx.size() == n );\n   CPPAD_ASSERT_UNKNOWN(  s.size() == m );\n   CPPAD_ASSERT_UNKNOWN(  t.size() == n );\n   CPPAD_ASSERT_UNKNOWN(  r.size() == n * q );\n   CPPAD_ASSERT_UNKNOWN(  u.size() == m * q );\n   CPPAD_ASSERT_UNKNOWN(  v.size() == n * q );\n   //\n   bool ok        = true;\n\n   // make sure hes_sparse_bool_ has been set\n   if( member_[thread]->hes_sparse_bool_.size() == 0 )\n      set_hes_sparse_bool();\n   if( member_[thread]->hes_sparse_set_.n_set() != 0 )\n      member_[thread]->hes_sparse_set_.resize(0, 0);\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_bool_.size() == n * n );\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_set_.n_set() == 0 );\n\n\n   // compute sparsity pattern for T(x) = S(x) * f'(x)\n   t = member_[thread]->f_.RevSparseJac(1, s);\n# ifndef NDEBUG\n   for(size_t j = 0; j < n; j++)\n      CPPAD_ASSERT_UNKNOWN( vx[j] || ! t[j] )\n# endif\n\n   // V(x) = f'(x)^T * g''(y) * f'(x) * R  +  g'(y) * f''(x) * R\n   // U(x) = g''(y) * f'(x) * R\n   // S(x) = g'(y)\n\n   // compute sparsity pattern for A(x) = f'(x)^T * U(x)\n   bool transpose = true;\n   sparsity_type a(n * q);\n   a = member_[thread]->f_.RevSparseJac(q, u, transpose);\n\n   // Need sparsity pattern for H(x) = (S(x) * f(x))''(x) * R,\n   // but use less efficient sparsity for  f(x)''(x) * R so that\n   // hes_sparse_set_ can be used every time this is needed.\n   for(size_t i = 0; i < n; i++)\n   {  for(size_t k = 0; k < q; k++)\n      {  // initialize sparsity pattern for H(i,k)\n         bool h_ik = false;\n         // H(i,k) = sum_j f''(i,j) * R(j,k)\n         for(size_t j = 0; j < n; j++)\n         {  bool f_ij = member_[thread]->hes_sparse_bool_[i * n + j];\n            bool r_jk = r[j * q + k];\n            h_ik     |= ( f_ij & r_jk );\n         }\n         // sparsity for H(i,k)\n         v[i * q + k] = h_ik;\n      }\n   }\n\n   // compute sparsity pattern for V(x) = A(x) + H(x)\n   for(size_t i = 0; i < n; i++)\n   {  for(size_t k = 0; k < q; k++)\n         // v[ i * q + k ] |= a[ i * q + k];\n         v[ i * q + k ] = bool(v[ i * q + k]) || bool(a[ i * q + k]);\n   }\n   return ok;\n}\ntemplate <class Base>\nbool checkpoint<Base>::rev_sparse_hes(\n   const vector<bool>&                     vx ,\n   const vector<bool>&                     s  ,\n          vector<bool>&                     t  ,\n   size_t                                  q  ,\n   const vectorBool&                       r  ,\n   const vectorBool&                       u  ,\n          vectorBool&                       v  ,\n   const vector<Base>&                     x  )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   return rev_sparse_hes_sparsity_type< vectorBool >(vx, s, t, q, r, u, v, x);\n}\ntemplate <class Base>\nbool checkpoint<Base>::rev_sparse_hes(\n   const vector<bool>&                     vx ,\n   const vector<bool>&                     s  ,\n          vector<bool>&                     t  ,\n   size_t                                  q  ,\n   const vector<bool>&                     r  ,\n   const vector<bool>&                     u  ,\n          vector<bool>&                     v  ,\n   const vector<Base>&                     x  )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   return rev_sparse_hes_sparsity_type< vector<bool> >(vx, s, t, q, r, u, v, x);\n}\ntemplate <class Base>\nbool checkpoint<Base>::rev_sparse_hes(\n   const vector<bool>&                     vx ,\n   const vector<bool>&                     s  ,\n          vector<bool>&                     t  ,\n   size_t                                  q  ,\n   const vector< std::set<size_t> >&       r  ,\n   const vector< std::set<size_t> >&       u  ,\n          vector< std::set<size_t> >&       v  ,\n   const vector<Base>&                     x  )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   size_t n = member_[thread]->f_.Domain();\n# ifndef NDEBUG\n   size_t m = member_[thread]->f_.Range();\n# endif\n   CPPAD_ASSERT_UNKNOWN( vx.size() == n );\n   CPPAD_ASSERT_UNKNOWN(  s.size() == m );\n   CPPAD_ASSERT_UNKNOWN(  t.size() == n );\n   CPPAD_ASSERT_UNKNOWN(  r.size() == n );\n   CPPAD_ASSERT_UNKNOWN(  u.size() == m );\n   CPPAD_ASSERT_UNKNOWN(  v.size() == n );\n   //\n   bool ok        = true;\n\n   // make sure hes_sparse_set_ has been set\n   if( member_[thread]->hes_sparse_bool_.size() != 0 )\n      member_[thread]->hes_sparse_bool_.clear();\n   if( member_[thread]->hes_sparse_set_.n_set() == 0 )\n      set_hes_sparse_set();\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_bool_.size() == 0 );\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_set_.n_set() == n );\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_set_.end()   == n );\n\n   // compute sparsity pattern for T(x) = S(x) * f'(x)\n   t = member_[thread]->f_.RevSparseJac(1, s);\n# ifndef NDEBUG\n   for(size_t j = 0; j < n; j++)\n      CPPAD_ASSERT_UNKNOWN( vx[j] || ! t[j] )\n# endif\n\n   // V(x) = f'(x)^T * g''(y) * f'(x) * R  +  g'(y) * f''(x) * R\n   // U(x) = g''(y) * f'(x) * R\n   // S(x) = g'(y)\n\n   // compute sparsity pattern for A(x) = f'(x)^T * U(x)\n   // 2DO: change a to use INTERNAL_SPARSE_SET\n   bool transpose = true;\n   vector< std::set<size_t> > a(n);\n   a = member_[thread]->f_.RevSparseJac(q, u, transpose);\n\n   // Need sparsity pattern for H(x) = (S(x) * f(x))''(x) * R,\n   // but use less efficient sparsity for  f(x)''(x) * R so that\n   // hes_sparse_set_ can be used every time this is needed.\n   for(size_t i = 0; i < n; i++)\n   {  v[i].clear();\n      local::sparse::list_setvec::const_iterator set_itr(\n         member_[thread]->hes_sparse_set_, i\n      );\n      size_t j = *set_itr;\n      while( j < n )\n      {  std::set<size_t>::const_iterator itr_j;\n         const std::set<size_t>& r_j( r[j] );\n         for(itr_j = r_j.begin(); itr_j != r_j.end(); itr_j++)\n         {  size_t k = *itr_j;\n            v[i].insert(k);\n         }\n         j = *(++set_itr);\n      }\n   }\n   // compute sparsity pattern for V(x) = A(x) + H(x)\n   std::set<size_t>::const_iterator itr;\n   for(size_t i = 0; i < n; i++)\n   {  for(itr = a[i].begin(); itr != a[i].end(); itr++)\n      {  size_t j = *itr;\n         CPPAD_ASSERT_UNKNOWN( j < q );\n         v[i].insert(j);\n      }\n   }\n\n   return ok;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_one/rev_sparse_jac.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_ONE_REV_SPARSE_JAC_HPP\n# define CPPAD_CORE_CHKPOINT_ONE_REV_SPARSE_JAC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\ntemplate <class Base>\ntemplate <class sparsity_type>\nbool checkpoint<Base>::rev_sparse_jac_sparsity_type(\n   size_t                                  q  ,\n   const sparsity_type&                    rt ,\n          sparsity_type&                    st ,\n   const vector<Base>&                     x  )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   // during user sparsity calculations\n   size_t m = member_[thread]->f_.Range();\n   size_t n = member_[thread]->f_.Domain();\n   if( member_[thread]->jac_sparse_bool_.size() == 0 )\n      set_jac_sparse_bool();\n   if( member_[thread]->jac_sparse_set_.n_set() != 0 )\n      member_[thread]->jac_sparse_set_.resize(0, 0);\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_bool_.size() == m * n );\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_set_.n_set() == 0 );\n   CPPAD_ASSERT_UNKNOWN( rt.size() == m * q );\n   CPPAD_ASSERT_UNKNOWN( st.size() == n * q );\n   bool ok  = true;\n   //\n   // S = R * J where J is jacobian\n   for(size_t i = 0; i < q; i++)\n   {  for(size_t j = 0; j < n; j++)\n      {  // initialize sparsity for S(i,j)\n         bool s_ij = false;\n         // S(i,j) = sum_k R(i,k) * J(k,j)\n         for(size_t k = 0; k < m; k++)\n         {  // sparsity for R(i, k)\n            bool R_ik = rt[ k * q + i ];\n            bool J_kj = member_[thread]->jac_sparse_bool_[ k * n + j ];\n            s_ij     |= (R_ik & J_kj);\n         }\n         // set sparsity for S^T\n         st[ j * q + i ] = s_ij;\n      }\n   }\n   return ok;\n}\ntemplate <class Base>\nbool checkpoint<Base>::rev_sparse_jac(\n   size_t                                  q  ,\n   const vectorBool&                       rt ,\n          vectorBool&                       st ,\n   const vector<Base>&                     x  )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   return rev_sparse_jac_sparsity_type< vectorBool >(q, rt, st, x);\n}\ntemplate <class Base>\nbool checkpoint<Base>::rev_sparse_jac(\n   size_t                                  q  ,\n   const vector<bool>&                     rt ,\n          vector<bool>&                     st ,\n   const vector<Base>&                     x  )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   return rev_sparse_jac_sparsity_type< vector<bool> >(q, rt, st, x);\n}\ntemplate <class Base>\nbool checkpoint<Base>::rev_sparse_jac(\n   size_t                                  q  ,\n   const vector< std::set<size_t> >&       rt ,\n          vector< std::set<size_t> >&       st ,\n   const vector<Base>&                     x  )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   // during user sparsity calculations\n   size_t m = member_[thread]->f_.Range();\n   size_t n = member_[thread]->f_.Domain();\n   if( member_[thread]->jac_sparse_bool_.size() != 0 )\n      member_[thread]->jac_sparse_bool_.clear();\n   if( member_[thread]->jac_sparse_set_.n_set() == 0 )\n      set_jac_sparse_set();\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_bool_.size() == 0 );\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_set_.n_set() == m );\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_set_.end()   == n );\n   CPPAD_ASSERT_UNKNOWN( rt.size() == m );\n   CPPAD_ASSERT_UNKNOWN( st.size() == n );\n   //\n   bool ok  = true;\n   //\n   for(size_t j = 0; j < n; j++)\n      st[j].clear();\n   //\n   // sparsity for  s = r * jac_sparse_set_\n   // s^T = jac_sparse_set_^T * r^T\n   for(size_t i = 0; i < m; i++)\n   {  // i is the row index in r^T\n      std::set<size_t>::const_iterator itr_i;\n      const std::set<size_t>& r_i( rt[i] );\n      for(itr_i = r_i.begin(); itr_i != r_i.end(); itr_i++)\n      {  // k is the column index in r^T\n         size_t k = *itr_i;\n         CPPAD_ASSERT_UNKNOWN( k < q );\n         //\n         // i is column index in jac_sparse_set^T\n         local::sparse::list_setvec::const_iterator set_itr(\n            member_[thread]->jac_sparse_set_, i\n         );\n         size_t j = *set_itr;\n         while( j < n )\n         {  // j is row index in jac_sparse_set^T\n            st[j].insert(k);\n            j = *(++set_itr);\n         }\n      }\n   }\n\n   return ok;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_one/reverse.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_ONE_REVERSE_HPP\n# define CPPAD_CORE_CHKPOINT_ONE_REVERSE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n// ---------------------------------------------------------------------------\ntemplate <class Base>\nbool checkpoint<Base>::reverse(\n   size_t                    q  ,\n   const vector<Base>&       tx ,\n   const vector<Base>&       ty ,\n          vector<Base>&       px ,\n   const vector<Base>&       py )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n\n# ifndef NDEBUG\n   size_t n = member_[thread]->f_.Domain();\n   size_t m = member_[thread]->f_.Range();\n# endif\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_var() > 0 );\n   CPPAD_ASSERT_UNKNOWN( n == tx.size() / (q+1) );\n   CPPAD_ASSERT_UNKNOWN( m == ty.size() / (q+1) );\n   CPPAD_ASSERT_UNKNOWN( tx.size() % (q+1) == 0 );\n   CPPAD_ASSERT_UNKNOWN( ty.size() % (q+1) == 0 );\n   CPPAD_ASSERT_UNKNOWN( px.size() == n * (q+1) );\n   CPPAD_ASSERT_UNKNOWN( py.size() == m * (q+1) );\n   bool ok  = true;\n\n   // put proper forward mode coefficients in f_\n# ifdef NDEBUG\n   // compute forward results for orders zero through q\n   member_[thread]->f_.Forward(q, tx);\n# else\n   size_t i, j, k;\n   //\n   // compute forward results for orders zero through q\n   vector<Base> check_ty = member_[thread]->f_.Forward(q, tx);\n   for(i = 0; i < m; i++)\n   {  for(k = 0; k <= q; k++)\n      {  j = i * (q+1) + k;\n         CPPAD_ASSERT_UNKNOWN( check_ty[j] == ty[j] );\n      }\n   }\n# endif\n   // now can run reverse mode\n   px = member_[thread]->f_.Reverse(q+1, py);\n\n   // no longer need the Taylor coefficients in f_\n   // (have to reconstruct them every time)\n   size_t c = 0;\n   size_t r = 0;\n   member_[thread]->f_.capacity_order(c, r);\n   return ok;\n}\n// ---------------------------------------------------------------------------\ntemplate <class Base>\nbool checkpoint<Base>::reverse(\n   size_t                          q   ,\n   const vector< AD<Base> >&       atx ,\n   const vector< AD<Base> >&       aty ,\n          vector< AD<Base> >&       apx ,\n   const vector< AD<Base> >&       apy )\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   // make sure af_ is defined\n   if( member_[thread]->af_.size_var() == 0 )\n      member_[thread]->af_ = member_[thread]->f_.base2ad();\n# ifndef NDEBUG\n   size_t n = member_[thread]->f_.Domain();\n   size_t m = member_[thread]->f_.Range();\n# endif\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_var() > 0 );\n   CPPAD_ASSERT_UNKNOWN( n == atx.size() / (q+1) );\n   CPPAD_ASSERT_UNKNOWN( m == aty.size() / (q+1) );\n   CPPAD_ASSERT_UNKNOWN( atx.size() % (q+1) == 0 );\n   CPPAD_ASSERT_UNKNOWN( aty.size() % (q+1) == 0 );\n   CPPAD_ASSERT_UNKNOWN( apx.size() == n * (q+1) );\n   CPPAD_ASSERT_UNKNOWN( apy.size() == m * (q+1) );\n   bool ok  = true;\n\n   // put proper forward mode coefficients in f_\n# ifdef NDEBUG\n   // compute forward results for orders zero through q\n   member_[thread]->af_.Forward(q, atx);\n# else\n   size_t i, j, k;\n   //\n   // compute forward results for orders zero through q\n   vector< AD<Base> > check_aty = member_[thread]->af_.Forward(q, atx);\n   for(i = 0; i < m; i++)\n   {  for(k = 0; k <= q; k++)\n      {  j = i * (q+1) + k;\n         CPPAD_ASSERT_UNKNOWN( check_aty[j] == aty[j] );\n      }\n   }\n# endif\n   // now can run reverse mode\n   apx = member_[thread]->af_.Reverse(q+1, apy);\n\n   // no longer need the Taylor coefficients in f_\n   // (have to reconstruct them every time)\n   size_t c = 0;\n   size_t r = 0;\n   member_[thread]->af_.capacity_order(c, r);\n   return ok;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_one/set_hes_sparse_bool.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_ONE_SET_HES_SPARSE_BOOL_HPP\n# define CPPAD_CORE_CHKPOINT_ONE_SET_HES_SPARSE_BOOL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\ntemplate <class Base>\nvoid checkpoint<Base>::set_hes_sparse_bool(void)\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_bool_.size() == 0 );\n   size_t n = member_[thread]->f_.Domain();\n   size_t m = member_[thread]->f_.Range();\n   //\n   // set version of sparsity for vector of all ones\n   vectorBool all_one(m);\n   for(size_t i = 0; i < m; i++)\n      all_one[i] = true;\n\n   // set version of sparsity for n by n identity matrix\n   vectorBool identity(n * n);\n   for(size_t j = 0; j < n; j++)\n   {  for(size_t i = 0; i < n; i++)\n         identity[ i * n + j ] = (i == j);\n   }\n\n   // compute sparsity pattern for H(x) = sum_i f_i(x)^{(2)}\n   bool transpose  = false;\n   bool dependency = false;\n   member_[thread]->f_.ForSparseJac(n, identity, transpose, dependency);\n   member_[thread]->hes_sparse_bool_ = member_[thread]->f_.RevSparseHes(n, all_one, transpose);\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_bool_.size() == n * n );\n   //\n   // drop the forward sparsity results from f_\n   member_[thread]->f_.size_forward_bool(0);\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_forward_bool() == 0 );\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_forward_set() == 0 );\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_one/set_hes_sparse_set.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_ONE_SET_HES_SPARSE_SET_HPP\n# define CPPAD_CORE_CHKPOINT_ONE_SET_HES_SPARSE_SET_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\ntemplate <class Base>\nvoid checkpoint<Base>::set_hes_sparse_set(void)\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_set_.n_set() == 0 );\n   size_t n = member_[thread]->f_.Domain();\n   size_t m = member_[thread]->f_.Range();\n   //\n   // set version of sparsity for vector of all ones\n   vector<bool> all_one(m);\n   for(size_t i = 0; i < m; i++)\n      all_one[i] = true;\n\n   // set version of sparsity for n by n identity matrix\n   local::sparse::list_setvec identity;\n   identity.resize(n, n);\n   for(size_t j = 0; j < n; j++)\n   {  // Not using post_element because only adding one element per set\n      identity.add_element(j, j);\n   }\n\n   // compute sparsity pattern for H(x) = sum_i f_i(x)^{(2)}\n   bool transpose  = false;\n   bool dependency = false;\n   member_[thread]->f_.ForSparseJacCheckpoint(\n      n, identity, transpose, dependency, member_[thread]->jac_sparse_set_\n   );\n   member_[thread]->f_.RevSparseHesCheckpoint(\n      n, all_one, transpose, member_[thread]->hes_sparse_set_\n   );\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_set_.n_set() == n );\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->hes_sparse_set_.end()   == n );\n   //\n   // drop the forward sparsity results from f_\n   member_[thread]->f_.size_forward_set(0);\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_one/set_jac_sparse_bool.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_ONE_SET_JAC_SPARSE_BOOL_HPP\n# define CPPAD_CORE_CHKPOINT_ONE_SET_JAC_SPARSE_BOOL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\ntemplate <class Base>\nvoid checkpoint<Base>::set_jac_sparse_bool(void)\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_bool_.size() == 0 );\n   bool transpose  = false;\n   bool dependency = true;\n   size_t n = member_[thread]->f_.Domain();\n   size_t m = member_[thread]->f_.Range();\n   // Use the choice for forward / reverse that results in smaller\n   // size for the sparsity pattern of all variables in the tape.\n   if( n <= m )\n   {  vectorBool identity(n * n);\n      for(size_t j = 0; j < n; j++)\n      {  for(size_t i = 0; i < n; i++)\n            identity[ i * n + j ] = (i == j);\n      }\n      member_[thread]->jac_sparse_bool_ = member_[thread]->f_.ForSparseJac(\n         n, identity, transpose, dependency\n      );\n      member_[thread]->f_.size_forward_bool(0);\n   }\n   else\n   {  vectorBool identity(m * m);\n      for(size_t j = 0; j < m; j++)\n      {  for(size_t i = 0; i < m; i++)\n            identity[ i * m + j ] = (i == j);\n      }\n      member_[thread]->jac_sparse_bool_ = member_[thread]->f_.RevSparseJac(\n         m, identity, transpose, dependency\n      );\n   }\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_forward_bool() == 0 );\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_forward_set() == 0 );\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_one/set_jac_sparse_set.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_ONE_SET_JAC_SPARSE_SET_HPP\n# define CPPAD_CORE_CHKPOINT_ONE_SET_JAC_SPARSE_SET_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\ntemplate <class Base>\nvoid checkpoint<Base>::set_jac_sparse_set(void)\n{  // make sure member_ is allocated for this thread\n   size_t thread = thread_alloc::thread_num();\n   allocate_member(thread);\n   //\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->jac_sparse_set_.n_set() == 0 );\n   bool transpose  = false;\n   bool dependency = true;\n   size_t n = member_[thread]->f_.Domain();\n   size_t m = member_[thread]->f_.Range();\n   // Use the choice for forward / reverse that results in smaller\n   // size for the sparsity pattern of all variables in the tape.\n   if( n <= m )\n   {  local::sparse::list_setvec identity;\n      identity.resize(n, n);\n      for(size_t j = 0; j < n; j++)\n      {  // Not using post_element because only adding one element per set\n         identity.add_element(j, j);\n      }\n      member_[thread]->f_.ForSparseJacCheckpoint(\n         n, identity, transpose, dependency, member_[thread]->jac_sparse_set_\n      );\n      member_[thread]->f_.size_forward_set(0);\n   }\n   else\n   {  local::sparse::list_setvec identity;\n      identity.resize(m, m);\n      for(size_t i = 0; i < m; i++)\n      {  // Not using post_element because only adding one element per set\n         identity.add_element(i, i);\n      }\n      member_[thread]->f_.RevSparseJacCheckpoint(\n         m, identity, transpose, dependency, member_[thread]->jac_sparse_set_\n      );\n   }\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_forward_set() == 0 );\n   CPPAD_ASSERT_UNKNOWN( member_[thread]->f_.size_forward_bool() == 0 );\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_two/chkpoint_two.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_TWO_CHKPOINT_TWO_HPP\n# define CPPAD_CORE_CHKPOINT_TWO_CHKPOINT_TWO_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file chkpoint_two.hpp\nSecond generation checkpoint functions.\n*/\n\n/*\n{xrst_begin chkpoint_two}\n{xrst_spell\n   chk\n}\n\nCheckpoint Functions: Second Generation\n#######################################\n\nSyntax\n******\n\nConstructor\n===========\n\n| ``chkpoint_two`` < *Base* > *chk_fun* ( *fun* , *name* ,\n| |tab| *internal_bool* , *use_hes_sparsity* , *use_base2ad* , *use_in_parallel*\n| )\n\nUse Checkpoint Function\n=======================\n*chk_fun* ( *ax* , *ay* )\n\nnew_dynamic\n===========\n*chk_fun* . ``new_dynamic`` ( *dynamic* )\n\nReduce Memory\n*************\nYou can reduce the size of the tape and memory required for AD\nusing a checkpoint representation of a function\n:math:`g : \\B{R}^n \\rightarrow \\B{R}^m`.\n\nFaster Recording\n****************\nIt may also reduce the time to make a recording if the same :math:`g(x)`\nis used many times (with different values) during the\nrecording of an ``ADFun`` < *Base* > object.\n\nRepeating Forward\n*****************\nNormally, CppAD stores :ref:`forward-name` mode results,\nuntil they freed using :ref:`capacity_order-name` ,\nor the corresponding :ref:`ADFun-name` object is deleted.\nThis is not true for ``chkpoint_two`` functions\nbecause the same checkpoint function may be used repeatedly\nwith different arguments during a single forward mode operation.\nThus, forward mode results are computed for each use of *chk_fun*\nin a forward mode sweep.\n\nOperation Sequence\n******************\nThe :ref:`operation sequence<glossary@Operation@Sequence>`\nrepresenting :math:`g(x)` is fixed; i.e.,\nit cannot depend on the value of :math:`x`.\n\natomic_three\n************\nThe ``chkpoint_two`` class is derived from ``atomic_three`` ,\nhence some of its error message will refer to atomic operations.\nThe ``chkpoint_two`` class implements all the\n:ref:`atomic_three_define@Virtual Functions`\nand hence its source code,\n\n   ``include/cppad/core/chkpoint_two/chkpoint_two.hpp``\n\nprovides an example for :ref:`atomic_three-name` operations.\nThe difference is that ``chkpoint_two.hpp`` uses AD\ninstead of user provided derivatives.\n\nBase\n****\nThe type *Base* specifies the base type for AD operations;\ni.e., *chk_fun* can be used during the recording of\n``AD`` < *Base* > operations.\n\nContents\n********\n{xrst_toc_table\n   include/cppad/core/chkpoint_two/ctor.hpp\n   include/cppad/core/chkpoint_two/chk_fun.xrst\n   include/cppad/core/chkpoint_two/dynamic.hpp\n   example/chkpoint_two/get_started.cpp\n   example/chkpoint_two/compare.cpp\n   example/chkpoint_two/base2ad.cpp\n   example/chkpoint_two/dynamic.cpp\n   example/chkpoint_two/ode.cpp\n}\n\n{xrst_end chkpoint_two}\n*/\n\ntemplate <class Base>\nclass chkpoint_two : public atomic_three<Base> {\n// ---------------------------------------------------------------------------\nprivate:\n   /// are sparsity calculations using bools or sets of integers\n   const bool internal_bool_;\n   //\n   /// can this checkpoint function calculate Hessian sparsity patterns\n   const bool use_hes_sparsity_;\n   //\n   /// can this checkpoint function be used in base2ad recordings\n   const bool use_base2ad_;\n   //\n   /// can this checkpoint function be used in parallel mode\n   const bool use_in_parallel_;\n   //\n   /// Jacobian sparsity for g(x) with dependency true.\n   /// This is set by the constructor and constant after that.\n   sparse_rc< vector<size_t> > jac_sparsity_;\n   //\n   /// Hessian sparsity for g(x). If use_hes_sparsity_ is true,\n   /// This is set by the constructor and constant after that.\n   sparse_rc< vector<size_t> > hes_sparsity_;\n   //\n   /// Function corresponding to this checkpoint object.\n   /// If use_in_parallel_, this is constant after the constructor.\n   ADFun<Base>    g_;\n   //\n   /// AD version of function corresponding to this checkpoint object\n   /// If use_in_parallel_, this is constant after the constructor.\n   ADFun< AD<Base>, Base>  ag_;\n   // ------------------------------------------------------------------------\n   // member_\n   // ------------------------------------------------------------------------\n   /// If use_in_parallel_ is true, must have a separate copy member data\n   /// that is not constant.\n   struct member_struct {\n      //\n      /// function corresponding to this checkpoint object\n      ADFun<Base>                 g_;\n      //\n      /// AD version of this function object\n      ADFun< AD<Base>, Base >     ag_;\n      //\n   };\n   /// use pointers and allocate memory to avoid false sharing\n   /// (initialized to null by constructor)\n   member_struct* member_[CPPAD_MAX_NUM_THREADS];\n   //\n   // ------------------------------------------------------------------------\n   /// allocate member_ for this thread\n   void allocate_member(size_t thread)\n   {  CPPAD_ASSERT_UNKNOWN( use_in_parallel_ );\n      if( member_[thread] == nullptr )\n      {  // allocaate raw memory\n         size_t min_bytes = sizeof(member_struct);\n         size_t num_bytes;\n         void* v_ptr = thread_alloc::get_memory(min_bytes, num_bytes);\n         // convert to member_struct*\n         member_[thread] = reinterpret_cast<member_struct*>(v_ptr);\n         // call member_struct constructor\n         new( member_[thread] ) member_struct;\n         //\n         // The thread has a copy of corresponding information.\n         member_[thread]->g_  = g_;\n         member_[thread]->ag_ = ag_;\n      }\n      return;\n   }\n   //\n   // ------------------------------------------------------------------------\n   /// free member_ for this thread\n   void free_member(size_t thread)\n   {  if( member_[thread] != nullptr )\n      {  // call destructor\n         member_[thread]->~member_struct();\n         // return raw m,emory to available pool for this thread\n         void* v_ptr = reinterpret_cast<void*>(member_[thread]);\n         thread_alloc::return_memory(v_ptr);\n         // mark member for this thread as not allocated\n         member_[thread] = nullptr;\n      }\n      return;\n   }\n   // -----------------------------------------------------------------------\n   // atomic_three virtual functions\n   // ------------------------------------------------------------------------\n   // type\n   virtual bool for_type(\n      const vector<Base>&          parameter_x ,\n      const vector<ad_type_enum>&  type_x      ,\n      vector<ad_type_enum>&        type_y\n   );\n   // forward\n   virtual bool forward(\n      const vector<Base>&          parameter_x ,\n      const vector<ad_type_enum>&  type_x      ,\n      size_t                       need_y      ,\n      size_t                       order_low   ,\n      size_t                       order_up    ,\n      const vector<Base>&          taylor_x    ,\n      vector<Base>&                taylor_y\n   );\n   // AD forward\n   virtual bool forward(\n      const vector< AD<Base> >&    aparameter_x ,\n      const vector<ad_type_enum>&  type_x       ,\n      size_t                       need_y       ,\n      size_t                       order_low    ,\n      size_t                       order_up     ,\n      const vector< AD<Base> >&    ataylor_x    ,\n      vector< AD<Base> >&          ataylor_y\n   );\n   // reverse\n   virtual bool reverse(\n      const vector<Base>&          parameter_x ,\n      const vector<ad_type_enum>&  type_x      ,\n      size_t                       order_up    ,\n      const vector<Base>&          taylor_x    ,\n      const vector<Base>&          taylor_y    ,\n      vector<Base>&                partial_x   ,\n      const vector<Base>&          partial_y\n   );\n   // AD reverse\n   virtual bool reverse(\n      const vector< AD<Base> >&    aparameter_x ,\n      const vector<ad_type_enum>&  type_x       ,\n      size_t                       order_up     ,\n      const vector< AD<Base> >&    ataylor_x    ,\n      const vector< AD<Base> >&    ataylor_y    ,\n      vector< AD<Base> >&          apartial_x   ,\n      const vector< AD<Base> >&    apartial_y\n   );\n   // jac_sparsity\n   virtual bool jac_sparsity(\n      const vector<Base>&            parameter_x  ,\n      const vector<ad_type_enum>&    type_x       ,\n      bool                           dependency   ,\n      const vector<bool>&            select_x     ,\n      const vector<bool>&            select_y     ,\n      sparse_rc< vector<size_t> >&   pattern_out\n   );\n   // hes_sparsity\n   virtual bool hes_sparsity(\n      const vector<Base>&            parameter_x  ,\n      const vector<ad_type_enum>&    type_x       ,\n      const vector<bool>&            select_x     ,\n      const vector<bool>&            select_y     ,\n      sparse_rc< vector<size_t> >&   pattern_out\n   );\n   // rev_depend\n   virtual bool rev_depend(\n      const vector<Base>&            parameter_x ,\n      const vector<ad_type_enum>&    type_x      ,\n      vector<bool>&                  depend_x    ,\n      const vector<bool>&            depend_y\n   );\npublic:\n   // ctor\n   chkpoint_two(\n      const ADFun<Base>& fun    ,\n      const std::string& name   ,\n      bool  internal_bool       ,\n      bool  use_hes_sparsity    ,\n      bool  use_base2ad         ,\n      bool  use_in_parallel\n   );\n   //\n   // destructor\n   ~chkpoint_two(void);\n   //\n   // assignment operator\n   void operator=(const chkpoint_two& other)\n   {  CPPAD_ASSERT_KNOWN(false,\n         \"cannot use chkpoint_two assignment operator\"\n      );\n   }\n   // copy constructor\n   chkpoint_two(const chkpoint_two& other)\n   :\n   internal_bool_    ( other.internal_bool_ ) ,\n   use_hes_sparsity_ ( other.use_hes_sparsity_ ) ,\n   use_base2ad_      ( other.use_base2ad_ ) ,\n   use_in_parallel_  ( other.use_in_parallel_ ) ,\n   jac_sparsity_     ( other.jac_sparsity_ ) ,\n   hes_sparsity_     ( other.hes_sparsity_ )\n   {  g_  = other.g_;\n      ag_ = other.ag_;\n   }\n   //\n   // new_dynamic\n   template <class BaseVector>\n   void new_dynamic(const BaseVector& dynamic);\n};\n\n} // END_CPPAD_NAMESPACE\n\n# include <cppad/core/chkpoint_two/ctor.hpp>\n# include <cppad/core/chkpoint_two/dynamic.hpp>\n# include <cppad/core/chkpoint_two/for_type.hpp>\n# include <cppad/core/chkpoint_two/forward.hpp>\n# include <cppad/core/chkpoint_two/reverse.hpp>\n# include <cppad/core/chkpoint_two/jac_sparsity.hpp>\n# include <cppad/core/chkpoint_two/hes_sparsity.hpp>\n# include <cppad/core/chkpoint_two/rev_depend.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_two/ctor.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_TWO_CTOR_HPP\n# define CPPAD_CORE_CHKPOINT_TWO_CTOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin chkpoint_two_ctor}\n{xrst_spell\n   chk\n}\n\nCheckpoint Function Constructor\n###############################\n\nSyntax\n******\n| ``chkpoint_two`` < *Base* > *chk_fun* ( *fun* , *name* ,\n| |tab| *internal_bool* , *use_hes_sparsity* , *use_base2ad* , *use_in_parallel*\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nParallel\n********\nThis constructor, and its corresponding destructor, must not be called in\n:ref:`parallel<ta_in_parallel-name>` mode.\nThe object *chk_fun* should not be destructed for as long as there is\nan ``ADFun`` < *Base* > object the has *chk_fun* in its recording.\n\nBase\n****\nThe type *Base* specifies the base type for AD operations.\n\nfun\n***\nThis specifies the function :math:`g(x)`.\nNote that *fun* may or may not have been\n:ref:`optimized<optimize-name>` before calling the constructor.\nThis will determine if the internal representation for *g* ( *x* )\nis optimized.\n\nname\n****\nis the name used for reporting errors using this checkpoint function.\n\ninternal_bool\n*************\nIf true, sparsity calculations are done with sets represented\nby vectors of boolean values.\nOtherwise, vectors of sets are used for sparsity patterns.\n\nuse_hes_sparsity\n****************\nIf true, Hessian sparsity patterns can be calculated for\n``ADFun`` < *Base* > objects that have uses of *chk_fun*\nin their recording.\nThis requires some extra memory and extra computation during the constructor.\n\nuse_base2ad\n***********\nIf this is true, *chk_fun* can be used during the recording\nof ``ADFun`` < *Base* > objects that get converted to\n``ADFun< AD<`` *Base* > > objects using :ref:`base2ad-name` .\nThis requires some extra memory and extra computation during the constructor.\n\nuse_in_parallel\n***************\nIf this is true, *chk_fun* can be used\n:ref:`ta_parallel_setup@in_parallel` .\nThis requires some extra memory for a constant copy of the *fun*\ninformation and a separate copy (that changes) for each thread.\n\nchk_fun\n*******\nThis is a checkpoint function representation of :math:`g(x)`\nthat can be used during the recording of ``AD`` < *Base* > operations.\n\n{xrst_end chkpoint_two_ctor}\n*/\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file chkpoint_two/ctor.hpp\nConstructor for chkpoint_two class.\n*/\n\n/*!\nConstructor\n\n\\tparam Base\nbase class for recording AD<Base> operations using this checkpoint object.\n\n\\param fun\nis the function g(x) corresponding to this checkpoint object.\n\n\\param name\nis the name used for error reporting.\n\n\\param internal_bool\nshould sparisity calculations be done using bools (or sets).\n\n\\param use_hes_sparsity\nwill this checkpoint function be used with Hessian sparsity calculations.\n\n\\param use_base2ad\nwill this checkpoint function be used with base2ad.\n\n\\param use_in_parallel\nwill this checkpoint function be used in parallel mode.\n*/\n\n// BEGIN_PROTOTYPE\ntemplate <class Base>\nchkpoint_two<Base>::chkpoint_two(\n      const ADFun<Base>& fun    ,\n      const std::string& name   ,\n      bool  internal_bool       ,\n      bool  use_hes_sparsity    ,\n      bool  use_base2ad         ,\n      bool  use_in_parallel     )\n// END_PROTOTYPE\n:\natomic_three<Base>(name)              ,\ninternal_bool_( internal_bool )       ,\nuse_hes_sparsity_( use_hes_sparsity ) ,\nuse_base2ad_ ( use_base2ad )          ,\nuse_in_parallel_ ( use_in_parallel )\n{  CPPAD_ASSERT_KNOWN(\n      ! thread_alloc::in_parallel() ,\n      \"chkpoint_two: constructor cannot be called in parallel mode.\"\n   );\n   // initialize member pointers as null;\n   for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; thread++)\n      member_[thread] = nullptr;\n   //\n   // g_\n   g_ = fun;\n   //\n   // suppress check for nan because chkpoint_two object can be used in a\n   // function that gets optimized and some checkpoint results may not matter.\n   g_.check_for_nan(false);\n   //\n   // ag_\n   if( use_base2ad )\n      ag_ = g_.base2ad();\n   //\n   // jac_sparsity__\n   size_t n = g_.Domain();\n   size_t m = g_.Range();\n   sparse_rc< vector<size_t> > pattern_in;\n   bool transpose     = false;\n   bool dependency    = true;\n   if( n <= m || use_hes_sparsity )\n   {  // use forward mode\n      pattern_in.resize(n, n, n);\n      for(size_t k = 0; k < n; ++k)\n         pattern_in.set(k, k, k);\n      g_.for_jac_sparsity(\n         pattern_in,\n         transpose,\n         dependency,\n         internal_bool,\n         jac_sparsity_\n      );\n   }\n   else\n   {  // use reverse mode\n      pattern_in.resize(m, m, m);\n      for(size_t k = 0; k < m; ++k)\n         pattern_in.set(k, k, k);\n      g_.rev_jac_sparsity(\n         pattern_in,\n         transpose,\n         dependency,\n         internal_bool,\n         jac_sparsity_\n      );\n   }\n   //\n   // hes_sparsity_\n   if( use_hes_sparsity )\n   {  vector<bool> select_y(m), select_x(n);\n      for(size_t i = 0; i < m; ++i)\n         select_y[i] = true;\n      if( n <= m )\n      {  for(size_t j = 0; j < n; ++j)\n            select_x[j] = true;\n         g_.for_hes_sparsity(\n            select_x, select_y, internal_bool, hes_sparsity_\n         );\n      }\n      else\n      {  // forward jacobian sparsity is stored in g_\n         g_.rev_hes_sparsity(\n            select_y, transpose, internal_bool, hes_sparsity_\n         );\n      }\n   }\n   // free memory holding forward Jacobian sparsity\n   if( internal_bool )\n      g_.size_forward_bool(0);\n   else\n      g_.size_forward_set(0);\n}\n/// destructor\ntemplate <class Base>\nchkpoint_two<Base>::~chkpoint_two(void)\n{\n# ifndef NDEBUG\n   if( thread_alloc::in_parallel() )\n   {  std::string msg = atomic_three<Base>::atomic_name();\n      msg += \": chkpoint_two destructor called in parallel mode.\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# endif\n   for(size_t thread = 0; thread < CPPAD_MAX_NUM_THREADS; ++thread)\n      free_member(thread);\n   }\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_two/dynamic.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_TWO_DYNAMIC_HPP\n# define CPPAD_CORE_CHKPOINT_TWO_DYNAMIC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin chkpoint_two_dynamic}\n{xrst_spell\n   chk\n   dyn\n}\n\nDynamic Parameters in Checkpoint Functions\n##########################################\n\nSyntax\n******\n| *chk_fun* . ``new_dynamic`` ( *dynamic* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nchk_fun\n*******\nThis object must have been created using the\n:ref:`chkpoint_two<chkpoint_two_ctor@chk_fun>` constructor.\n\nBase\n====\nThis is the :ref:`chkpoint_two_ctor@Base` type\nin the *chk_fun* constructor.\n\nfun\n===\nThis is the function :ref:`chkpoint_two_ctor@fun`\nin the *chk_fun* constructor.\n\nBaseVector\n**********\nThis must be a :ref:`SimpleVector-name` with elements of type *Base* .\n\ndynamic\n*******\nThis is a vector with new values for the dynamic parameters\nin the function *fun* .\nIs size must be equal to\n:ref:`fun.size_dyn_ind()<fun_property@size_dyn_par>` .\nThis only affects the copy of *fun* used by *chk_fun* .\n\nMulti-Threading\n***************\nIf one is using :ref:`in_parallel<ta_in_parallel-name>` ,\nthere is a separate copy of *fun* for each thread.\nIn this case, only the dynamic parameters in the copy for the current\n:ref:`thread number<ta_thread_num-name>` are changed.\n\n{xrst_end chkpoint_two_dynamic}\n*/\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file chkpoint_two/dynamic.hpp\nChange the dynnamic parameter in a checkpoint function.\n*/\n\n/*!\nConstructor\n\n\\tparam Base\nbase class for recording AD<Base> operations using this checkpoint object.\n\n\\param dynamic\nis the new values for the dynamic parameters in the function\ndefining this checkpoint object.\n*/\n\n// BEGIN_PROTOTYPE\ntemplate <class Base>\ntemplate <class BaseVector>\nvoid chkpoint_two<Base>::new_dynamic(const BaseVector& dynamic)\n// END_PROTOTYPE\n{  ADFun<Base>* g_ptr = &g_;\n   if( use_in_parallel_ )\n   {  size_t thread = thread_alloc::thread_num();\n      allocate_member(thread);\n      g_ptr = &(member_[thread]->g_);\n   }\n# ifndef NDEBUG\n   else if( thread_alloc::in_parallel() )\n   {  std::string msg = atomic_three<Base>::atomic_name();\n      msg += \": use_in_parallel is false and in_parallel() is true\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# endif\n   g_ptr->new_dynamic(dynamic);\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_two/for_type.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_TWO_FOR_TYPE_HPP\n# define CPPAD_CORE_CHKPOINT_TWO_FOR_TYPE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file chkpoint_two/for_type.hpp\nSecond generation checkpoint type computation.\n*/\n/*!\nLink from atomic_three to type calculation\n\n\\param parameter_x [in]\nis the value of the parameters in the corresponding function call\nafun(ax, ay).\n\n\\param type_x [in]\nspecifies which components of x are\nconstants, dynamics, and variables\n\n\\param type_y [out]\nspecifies which components of y are\nconstants, dynamics, and variables\n*/\ntemplate <class Base>\nbool chkpoint_two<Base>::for_type(\n   const vector<Base>&          parameter_x ,\n   const vector<ad_type_enum>&  type_x      ,\n   vector<ad_type_enum>&        type_y      )\n{  size_t nr  = jac_sparsity_.nr();\n   size_t nnz = jac_sparsity_.nnz();\n   const vector<size_t>& row( jac_sparsity_.row() );\n   const vector<size_t>& col( jac_sparsity_.col() );\n   //\n   CPPAD_ASSERT_UNKNOWN( jac_sparsity_.nr() == type_y.size() );\n   CPPAD_ASSERT_UNKNOWN( jac_sparsity_.nc() == type_x.size() );\n   //\n   // initialize type_y as constant_enum\n   for(size_t i = 0; i < nr; ++i)\n      type_y[i] = constant_enum;\n   //\n   // loop over entries in Dependency pattern\n   for(size_t k = 0; k < nnz; ++k)\n   {  size_t i  = row[k];\n      size_t j  = col[k];\n      type_y[i] = std::max(type_y[i], type_x[j]);\n   }\n   return true;\n}\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_two/forward.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_TWO_FORWARD_HPP\n# define CPPAD_CORE_CHKPOINT_TWO_FORWARD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file chkpoint_two/forward.hpp\nSecond generation checkpoint forward mode.\n*/\n/*!\nLink from chkpoint_two to forward mode\n\n\\param parameter_x [in]\ncontains the values, in afun(ax, ay), for arguments that are parameters.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param need_y [in]\nspecifies which components of taylor_y are needed,\n\n\\param order_low [in]\nlowerest order for this forward mode calculation.\n\n\\param order_up [in]\nhighest order for this forward mode calculation.\n\n\\param taylor_x [in]\nTaylor coefficients corresponding to x for this calculation.\n\n\\param taylor_y [out]\nTaylor coefficient corresponding to y for this calculation\n\nSee the forward mode in user's documentation for atomic_three\n*/\ntemplate <class Base>\nbool chkpoint_two<Base>::forward(\n   const vector<Base>&          parameter_x ,\n   const vector<ad_type_enum>&  type_x      ,\n   size_t                       need_y      ,\n   size_t                       order_low   ,\n   size_t                       order_up    ,\n   const vector<Base>&          taylor_x    ,\n   vector<Base>&                taylor_y    )\n{  ADFun<Base>* g_ptr = &g_;\n   if( use_in_parallel_ )\n   {  size_t thread = thread_alloc::thread_num();\n      allocate_member(thread);\n      g_ptr = &(member_[thread]->g_);\n   }\n# ifndef NDEBUG\n   else if( thread_alloc::in_parallel() )\n   {  std::string msg = atomic_three<Base>::atomic_name();\n      msg += \": use_in_parallel is false and in_parallel() is true\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# endif\n   // compute forward mode results for all values and orders\n   taylor_y = g_ptr->Forward(order_up, taylor_x);\n   //\n   return true;\n}\n/*!\nLink from chkpoint_two to AD forward mode\n\n\\param aparameter_x [in]\ncontains the values, in afun(ax, ay), for arguments that are parameters.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param need_y [in]\nspecifies which components of taylor_y are needed,\n\n\\param order_low [in]\nlowerest order for this forward mode calculation.\n\n\\param order_up [in]\nhighest order for this forward mode calculation.\n\n\\param ataylor_x [in]\nTaylor coefficients corresponding to x for this calculation.\n\n\\param ataylor_y [out]\nTaylor coefficient corresponding to y for this calculation\n\nSee the forward mode in user's documentation for atomic_three\n*/\ntemplate <class Base>\nbool chkpoint_two<Base>::forward(\n   const vector< AD<Base> >&    aparameter_x ,\n   const vector<ad_type_enum>&  type_x       ,\n   size_t                       need_y       ,\n   size_t                       order_low    ,\n   size_t                       order_up     ,\n   const vector< AD<Base> >&    ataylor_x    ,\n   vector< AD<Base> >&          ataylor_y    )\n{  if( ! use_base2ad_ )\n      return false;\n   //\n   ADFun< AD<Base>, Base >* ag_ptr = &ag_;\n   if( use_in_parallel_ )\n   {  size_t thread = thread_alloc::thread_num();\n      allocate_member(thread);\n      ag_ptr = &(member_[thread]->ag_);\n   }\n# ifndef NDEBUG\n   else if( thread_alloc::in_parallel() )\n   {  std::string msg = atomic_three<Base>::atomic_name();\n      msg += \": use_in_parallel is false and in_parallel() is true\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# endif\n   // compute forward mode results for all values and orders\n   ataylor_y = ag_ptr->Forward(order_up, ataylor_x);\n   //\n   return true;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_two/hes_sparsity.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_TWO_HES_SPARSITY_HPP\n# define CPPAD_CORE_CHKPOINT_TWO_HES_SPARSITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file chkpoint_two/hes_sparsity.hpp\nSecond generation checkpoint Jacobian sparsity patterns.\n*/\n/*!\nchkpoint_two to Hessian sparsity calculations.\n\n\\param parameter_x [in]\ncontains the values for arguments that are parameters.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param select_x [in]\nwhich domain components to include in the dependency or sparsity pattern.\nThe index zero is used for parameters.\n\n\\param select_y [in]\nwhich range components to include in the dependency or sparsity pattern.\nThe index zero is used for parameters.\nThis argument is ignored because the sparsity pattern corresponding to\nall components true is computed during the construction and used for all cases.\nThis errors on the side of caution for the sake of speed.\n\n\n\\param pattern_out [out]\nis the dependency or sparsity pattern.\n*/\n// BEGIN_PROTOTYPE\ntemplate <class Base>\nbool chkpoint_two<Base>::hes_sparsity(\n   const vector<Base>&                     parameter_x  ,\n   const vector<ad_type_enum>&             type_x       ,\n   const vector<bool>&                     select_x     ,\n   const vector<bool>&                     select_y     ,\n   sparse_rc< vector<size_t> >&            pattern_out  )\n// END_PROTOTYPE\n{  CPPAD_ASSERT_UNKNOWN( hes_sparsity_.nr() == select_x.size() );\n   CPPAD_ASSERT_UNKNOWN( hes_sparsity_.nc() == select_x.size() );\n   if( ! use_hes_sparsity_ )\n      return false;\n\n   // count number of non-zeros\n   size_t nnz = hes_sparsity_.nnz();\n   size_t nr  = hes_sparsity_.nr();\n   size_t nc  = hes_sparsity_.nc();\n   const vector<size_t>& row = hes_sparsity_.row();\n   const vector<size_t>& col = hes_sparsity_.col();\n   size_t nnz_out = 0;\n   for(size_t k = 0; k < nnz; ++k)\n   {  size_t i = row[k];\n      size_t j = col[k];\n      if( select_x[j] && select_x[i] )\n         ++nnz_out;\n   }\n\n   // set the output sparsity pattern\n   pattern_out.resize(nr, nc, nnz_out);\n   size_t ell = 0;\n   for(size_t k = 0; k < nnz; ++k)\n   {  size_t i = row[k];\n      size_t j = col[k];\n      if( select_x[j] && select_x[i] )\n         pattern_out.set(ell++, i, j);\n   }\n   CPPAD_ASSERT_UNKNOWN( ell == nnz_out );\n   //\n   return true;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_two/jac_sparsity.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_TWO_JAC_SPARSITY_HPP\n# define CPPAD_CORE_CHKPOINT_TWO_JAC_SPARSITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file chkpoint_two/jac_sparsity.hpp\nSecond generation checkpoint Jacobian sparsity patterns.\n*/\n/*!\nchkpoint_two to Jacobian sparsity calculations.\n\n\\param dependency [in]\nThis argument is ignored.\nThe return pattern is always a dependency pattern which is a correct,\nbut possibly not efficient, sparsity pattern.\n\n\\param parameter_x [in]\ncontains the values for arguments that are parameters.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param select_x [in]\nwhich domain components to include in the dependency or sparsity pattern.\nThe index zero is used for parameters.\n\n\\param select_y [in]\nwhich range components to include in the dependency or sparsity pattern.\nThe index zero is used for parameters.\n\n\\param pattern_out [out]\nis the dependency or sparsity pattern.\n*/\n// BEGIN_PROTOTYPE\ntemplate <class Base>\nbool chkpoint_two<Base>::jac_sparsity(\n   const vector<Base>&                     parameter_x  ,\n   const vector<ad_type_enum>&             type_x       ,\n   bool                                    dependency   ,\n   const vector<bool>&                     select_x     ,\n   const vector<bool>&                     select_y     ,\n   sparse_rc< vector<size_t> >&            pattern_out  )\n// END_PROTOTYPE\n{  CPPAD_ASSERT_UNKNOWN( jac_sparsity_.nr() == select_y.size() );\n   CPPAD_ASSERT_UNKNOWN( jac_sparsity_.nc() == select_x.size() );\n\n   // count number of non-zeros\n   size_t nnz = jac_sparsity_.nnz();\n   size_t nr  = jac_sparsity_.nr();\n   size_t nc  = jac_sparsity_.nc();\n   const vector<size_t>& row = jac_sparsity_.row();\n   const vector<size_t>& col = jac_sparsity_.col();\n   size_t nnz_out = 0;\n   for(size_t k = 0; k < nnz; ++k)\n   {  size_t i = row[k];\n      size_t j = col[k];\n      if( select_x[j] && select_y[i] )\n         ++nnz_out;\n   }\n\n   // set the output sparsity pattern\n   pattern_out.resize(nr, nc, nnz_out);\n   size_t ell = 0;\n   for(size_t k = 0; k < nnz; ++k)\n   {  size_t i = row[k];\n      size_t j = col[k];\n      if( select_x[j] && select_y[i] )\n         pattern_out.set(ell++, i, j);\n   }\n   CPPAD_ASSERT_UNKNOWN( ell == nnz_out );\n   //\n   return true;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_two/rev_depend.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_TWO_REV_DEPEND_HPP\n# define CPPAD_CORE_CHKPOINT_TWO_REV_DEPEND_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file chkpoint_two/rev_depend.hpp\nSecond generation checkpoint type computation.\n*/\n/*!\nLink from atomic_three to dependency calculation\n\n\\param parameter_x [in]\nis the value of the parameters in the corresponding function call\nafun(ax, ay).\n\n\\param type_x [in]\nis the AD type for ax in the corresponding afun(ax, ay) call.\n\n\\param depend_x [out]\nspecifies which components of x affect the values of interest\n\n\\param depend_y [in]\nspecifies which components of y affect the values of interest\n*/\ntemplate <class Base>\nbool chkpoint_two<Base>::rev_depend(\n   const vector<Base>&         parameter_x ,\n   const vector<ad_type_enum>& type_x      ,\n   vector<bool>&               depend_x    ,\n   const vector<bool>&         depend_y    )\n{  size_t nc  = jac_sparsity_.nc();\n   size_t nnz = jac_sparsity_.nnz();\n   const vector<size_t>& row( jac_sparsity_.row() );\n   const vector<size_t>& col( jac_sparsity_.col() );\n   //\n   CPPAD_ASSERT_UNKNOWN( jac_sparsity_.nr() == depend_y.size() );\n   CPPAD_ASSERT_UNKNOWN( jac_sparsity_.nc() == depend_x.size() );\n   //\n   // initialize depend_x as false\n   for(size_t j = 0; j < nc; ++j)\n      depend_x[j] = false;\n   //\n   // loop over entries in Dependency pattern\n   for(size_t k = 0; k < nnz; ++k)\n   {  size_t i  = row[k];\n      size_t j  = col[k];\n      if( depend_y[i] )\n         depend_x[j] = true;\n   }\n   return true;\n}\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/chkpoint_two/reverse.hpp",
    "content": "# ifndef CPPAD_CORE_CHKPOINT_TWO_REVERSE_HPP\n# define CPPAD_CORE_CHKPOINT_TWO_REVERSE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file chkpoint_two/reverse.hpp\nSecond generation checkpoint reverse mode.\n*/\n/*!\nLink from chkpoint_two to reverse mode\n\n\\param parameter_x [in]\ncontains the values, in afun(ax, ay), for arguments that are parameters.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param order_up [in]\nhighest order Taylor coefficient aht we are computing derivative of\n\n\\param taylor_x [in]\nTaylor coefficients corresponding to x for this calculation.\n\n\\param taylor_y [in]\nTaylor coefficient corresponding to y for this calculation\n\n\\param partial_x [out]\nPartials w.r.t. the x Taylor coefficients.\n\n\\param partial_y [in]\nPartials w.r.t. the y Taylor coefficients.\n\nSee the reverse mode in user's documentation for atomic_three\n*/\ntemplate <class Base>\nbool chkpoint_two<Base>::reverse(\n   const vector<Base>&         parameter_x   ,\n   const vector<ad_type_enum>& type_x        ,\n   size_t                      order_up      ,\n   const vector<Base>&         taylor_x      ,\n   const vector<Base>&         taylor_y      ,\n   vector<Base>&               partial_x     ,\n   const vector<Base>&         partial_y     )\n\n{  ADFun<Base>* g_ptr = &g_;\n   if( use_in_parallel_ )\n   {  size_t thread = thread_alloc::thread_num();\n      allocate_member(thread);\n      g_ptr = &(member_[thread]->g_);\n   }\n# ifndef NDEBUG\n   else if( thread_alloc::in_parallel() )\n   {  std::string msg = atomic_three<Base>::atomic_name();\n      msg += \": use_in_parallel is false and in_parallel() is true\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# endif\n   // compute forward mode Taylor coefficient orders 0 through order_up\n# ifdef NDEBUG\n   g_ptr->Forward(order_up, taylor_x);\n# else\n   vector<Base> check = g_ptr->Forward(order_up, taylor_x);\n   CPPAD_ASSERT_UNKNOWN( taylor_y.size() == check.size() )\n   for(size_t i = 0; i < taylor_y.size(); ++i)\n      CPPAD_ASSERT_UNKNOWN( taylor_y[i] == check[i] );\n# endif\n   // now can run reverse mode\n   partial_x = g_ptr->Reverse(order_up+1, partial_y);\n   //\n   return true;\n}\n/*!\nLink from chkpoint_two to AD reverse mode\n\n\\param aparameter_x [in]\ncontains the values, in afun(ax, ay), for arguments that are parameters.\n\n\\param type_x [in]\nwhat is the type, in afun(ax, ay), for each component of x.\n\n\\param order_up [in]\nhighest order Taylor coefficient aht we are computing derivative of\n\n\\param ataylor_x [in]\nTaylor coefficients corresponding to x for this calculation.\n\n\\param ataylor_y [in]\nTaylor coefficient corresponding to y for this calculation\n\n\\param apartial_x [out]\nPartials w.r.t. the x Taylor coefficients.\n\n\\param apartial_y [in]\nPartials w.r.t. the y Taylor coefficients.\n\nSee the reverse mode in user's documentation for atomic_three\n*/\ntemplate <class Base>\nbool chkpoint_two<Base>::reverse(\n   const vector< AD<Base> >&   aparameter_x ,\n   const vector<ad_type_enum>& type_x       ,\n   size_t                      order_up     ,\n   const vector< AD<Base> >&   ataylor_x    ,\n   const vector< AD<Base> >&   ataylor_y    ,\n   vector< AD<Base> >&         apartial_x   ,\n   const vector< AD<Base> >&   apartial_y   )\n{  ADFun< AD<Base>, Base >* ag_ptr = &ag_;\n   if( use_in_parallel_ )\n   {  size_t thread = thread_alloc::thread_num();\n      allocate_member(thread);\n      ag_ptr = &(member_[thread]->ag_);\n   }\n   // compute forward mode Taylor coefficient orders 0 through order_up\n# ifdef NDEBUG\n   ag_ptr->Forward(order_up, ataylor_x);\n# else\n   vector< AD<Base> > acheck = ag_ptr->Forward(order_up, ataylor_x);\n   CPPAD_ASSERT_UNKNOWN( ataylor_y.size() == acheck.size() )\n   for(size_t i = 0; i < ataylor_y.size(); ++i)\n      CPPAD_ASSERT_UNKNOWN( ataylor_y[i] == acheck[i] );\n# endif\n   // now can run reverse mode\n   apartial_x = ag_ptr->Reverse(order_up+1, apartial_y);\n   //\n   return true;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/compare.hpp",
    "content": "# ifndef CPPAD_CORE_COMPARE_HPP\n# define CPPAD_CORE_COMPARE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n-------------------------------------------------------------------------------\n{xrst_begin Compare}\n\nAD Binary Comparison Operators\n##############################\n\nSyntax\n******\n| *b* = *x* *Op* *y*\n\nPurpose\n*******\nCompares two operands where one of the operands is an\n``AD`` < *Base* > object.\nThe comparison has the same interpretation as for\nthe *Base* type.\n\nOp\n**\nThe operator *Op* is one of the following:\n\n.. csv-table::\n   :widths: auto\n\n   **Op**,**Meaning**\n   ``<``,is *x* less than *y*\n   ``<=``,is *x* less than or equal *y*\n   ``>``,is *x* greater than *y*\n   ``>=``,is *x* greater than or equal *y*\n   ``==``,is *x* equal to *y*\n   ``!=``,is *x* not equal to *y*\n\nx\n*\nThe operand *x* has prototype\n\n   ``const`` *Type* & *x*\n\nwhere *Type* is ``AD`` < *Base* > , *Base* , or ``int`` .\n\ny\n*\nThe operand *y* has prototype\n\n   ``const`` *Type* & *y*\n\nwhere *Type* is ``AD`` < *Base* > , *Base* , or ``int`` .\n\nb\n*\nThe result *b* has type\n\n   ``bool`` *b*\n\nOperation Sequence\n******************\nThe result of this operation is a ``bool`` value\n(not an :ref:`glossary@AD of Base` object).\nThus it will not be recorded as part of an\nAD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nFor example, suppose\n*x* and *y* are ``AD`` < *Base* > objects,\nthe tape corresponding to ``AD`` < *Base* > is recording,\n*b* is true,\nand the subsequent code is\n\n| |tab| ``if`` ( *b*  )\n| |tab| |tab| *y* = ``cos`` ( *x* );\n| |tab| ``else``\n| |tab| |tab| *y* = ``sin`` ( *x* );\n\nonly the assignment *y* = ``cos`` ( *x* ) is recorded on the tape\n(if *x* is a :ref:`glossary@Parameter` ,\nnothing is recorded).\nThe :ref:`CompareChange-name` function can yield\nsome information about changes in comparison operation results.\nYou can use :ref:`CondExp-name` to obtain comparison operations\nthat depends on the\n:ref:`glossary@Tape@Independent Variable`\nvalues with out re-taping the AD sequence of operations.\n\nAssumptions\n***********\nIf one of the *Op* operators listed above\nis used with an ``AD`` < *Base* > object,\nit is assumed that the same operator is supported by the base type\n*Base* .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/compare.cpp\n}\nThe file\n:ref:`compare.cpp-name`\ncontains an example and test of these operations.\n\n{xrst_end Compare}\n-------------------------------------------------------------------------------\n*/\n//  BEGIN CppAD namespace\nnamespace CppAD {\n// -------------------------------- < --------------------------\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool operator < (const AD<Base> &left , const AD<Base> &right)\n{  bool result    =  (left.value_ < right.value_);\n   //\n   // check if we are recording compare operators\n   local::ADTape<Base> *tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n   if( ! tape->Rec_.get_record_compare() )\n      return result;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if left and right tapes match\n   bool match_left  = left.tape_id_  == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n\n   // check if left and right are dynamic parameters\n   bool dyn_left  = match_left  & (left.ad_type_ == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if left and right are variables\n   bool var_left  = match_left  & (left.ad_type_ != dynamic_enum);\n   bool var_right = match_right & (right.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      left.tape_id_ == right.tape_id_ || ! match_left || ! match_right ,\n      \"< : AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_left )\n   {  if( var_right )\n      {  // variable < variable\n         if( result )\n         {  tape->Rec_.PutOp(local::LtvvOp);\n            tape->Rec_.PutArg(left.taddr_, right.taddr_);\n         }\n         else\n         {  tape->Rec_.PutOp(local::LevvOp);\n            tape->Rec_.PutArg(right.taddr_, left.taddr_);\n         }\n      }\n      else\n      {  // variable < parameter\n         addr_t p = right.taddr_;\n         if( ! dyn_right )\n            p = tape->Rec_.put_con_par(right.value_);\n         if( result )\n         {  tape->Rec_.PutOp(local::LtvpOp);\n            tape->Rec_.PutArg(left.taddr_, p);\n         }\n         else\n         {  tape->Rec_.PutOp(local::LepvOp);\n            tape->Rec_.PutArg(p, left.taddr_);\n         }\n      }\n   }\n   else if ( var_right )\n   {  // parameter < variable\n      addr_t p = left.taddr_;\n      if( ! dyn_left )\n         p = tape->Rec_.put_con_par(left.value_);\n      if( result )\n      {  tape->Rec_.PutOp(local::LtpvOp);\n         tape->Rec_.PutArg(p, right.taddr_);\n      }\n      else\n      {  tape->Rec_.PutOp(local::LevpOp);\n         tape->Rec_.PutArg(right.taddr_, p);\n      }\n   }\n   else if( dyn_left | dyn_right )\n   {  // parameter < parameter\n      addr_t arg0 = left.taddr_;\n      addr_t arg1 = right.taddr_;\n      if( ! dyn_left )\n         arg0 = tape->Rec_.put_con_par(left.value_);\n      if( ! dyn_right )\n         arg1 = tape->Rec_.put_con_par(right.value_);\n      //\n      if( result )\n      {  tape->Rec_.PutOp(local::LtppOp);\n         tape->Rec_.PutArg(arg0, arg1);\n      }\n      else\n      {  tape->Rec_.PutOp(local::LeppOp);\n         tape->Rec_.PutArg(arg1, arg0);\n      }\n   }\n   return result;\n}\n// convert other cases into the case above\nCPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(<)\n\n// -------------------------------- <= --------------------------\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool operator <= (const AD<Base> &left , const AD<Base> &right)\n{  bool result    =  (left.value_ <= right.value_);\n   //\n   // check if we are recording compare operators\n   local::ADTape<Base> *tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n   if( ! tape->Rec_.get_record_compare() )\n      return result;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if left and right tapes match\n   bool match_left  = left.tape_id_  == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n\n   // check if left and right are dynamic parameters\n   bool dyn_left  = match_left  & (left.ad_type_ == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if left and right are variables\n   bool var_left  = match_left  & (left.ad_type_ != dynamic_enum);\n   bool var_right = match_right & (right.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      left.tape_id_ == right.tape_id_ || ! match_left || ! match_right ,\n      \"<= : AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_left )\n   {  if( var_right )\n      {  // variable <= variable\n         if( result )\n         {  tape->Rec_.PutOp(local::LevvOp);\n            tape->Rec_.PutArg(left.taddr_, right.taddr_);\n         }\n         else\n         {  tape->Rec_.PutOp(local::LtvvOp);\n            tape->Rec_.PutArg(right.taddr_, left.taddr_);\n         }\n      }\n      else\n      {  // variable <= parameter\n         addr_t p = right.taddr_;\n         if( ! dyn_right )\n            p = tape->Rec_.put_con_par(right.value_);\n         if( result )\n         {  tape->Rec_.PutOp(local::LevpOp);\n            tape->Rec_.PutArg(left.taddr_, p);\n         }\n         else\n         {  tape->Rec_.PutOp(local::LtpvOp);\n            tape->Rec_.PutArg(p, left.taddr_);\n         }\n      }\n   }\n   else if ( var_right )\n   {  // parameter <= variable\n      addr_t p = left.taddr_;\n      if( ! dyn_left )\n         p = tape->Rec_.put_con_par(left.value_);\n      if( result )\n      {  tape->Rec_.PutOp(local::LepvOp);\n         tape->Rec_.PutArg(p, right.taddr_);\n      }\n      else\n      {  tape->Rec_.PutOp(local::LtvpOp);\n         tape->Rec_.PutArg(right.taddr_, p);\n      }\n   }\n   else if( dyn_left | dyn_right )\n   {  // parameter <= parameter\n      addr_t arg0 = left.taddr_;\n      addr_t arg1 = right.taddr_;\n      if( ! dyn_left )\n         arg0 = tape->Rec_.put_con_par(left.value_);\n      if( ! dyn_right )\n         arg1 = tape->Rec_.put_con_par(right.value_);\n      //\n      if( result )\n      {  tape->Rec_.PutOp(local::LeppOp);\n         tape->Rec_.PutArg(arg0, arg1);\n      }\n      else\n      {  tape->Rec_.PutOp(local::LtppOp);\n         tape->Rec_.PutArg(arg1, arg0);\n      }\n   }\n   return result;\n}\n// convert other cases into the case above\nCPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(<=)\n\n// -------------------------------- > --------------------------\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool operator > (const AD<Base> &left , const AD<Base> &right)\n{  bool result    =  (left.value_ > right.value_);\n   //\n   // check if we are recording compare operators\n   local::ADTape<Base> *tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n   if( ! tape->Rec_.get_record_compare() )\n      return result;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if left and right tapes match\n   bool match_left  = left.tape_id_  == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n\n   // check if left and right are dynamic parameters\n   bool dyn_left  = match_left  & (left.ad_type_ == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if left and right are variables\n   bool var_left  = match_left  & (left.ad_type_ != dynamic_enum);\n   bool var_right = match_right & (right.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      left.tape_id_ == right.tape_id_ || ! match_left || ! match_right ,\n      \"> : AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_left )\n   {  if( var_right )\n      {  // variable > variable\n         if( result )\n         {  tape->Rec_.PutOp(local::LtvvOp);\n            tape->Rec_.PutArg(right.taddr_, left.taddr_);\n         }\n         else\n         {  tape->Rec_.PutOp(local::LevvOp);\n            tape->Rec_.PutArg(left.taddr_, right.taddr_);\n         }\n      }\n      else\n      {  // variable > parameter\n         addr_t p = right.taddr_;\n         if( ! dyn_right )\n            p = tape->Rec_.put_con_par(right.value_);\n         if( result )\n         {  tape->Rec_.PutOp(local::LtpvOp);\n            tape->Rec_.PutArg(p, left.taddr_);\n         }\n         else\n         {  tape->Rec_.PutOp(local::LevpOp);\n            tape->Rec_.PutArg(left.taddr_, p);\n         }\n      }\n   }\n   else if ( var_right )\n   {  // parameter > variable\n      addr_t p = left.taddr_;\n      if( ! dyn_left )\n         p = tape->Rec_.put_con_par(left.value_);\n      if( result )\n      {  tape->Rec_.PutOp(local::LtvpOp);\n         tape->Rec_.PutArg(right.taddr_, p);\n      }\n      else\n      {  tape->Rec_.PutOp(local::LepvOp);\n         tape->Rec_.PutArg(p, right.taddr_);\n      }\n   }\n   else if( dyn_left | dyn_right )\n   {  // parameter > parameter\n      addr_t arg0 = left.taddr_;\n      addr_t arg1 = right.taddr_;\n      if( ! dyn_left )\n         arg0 = tape->Rec_.put_con_par(left.value_);\n      if( ! dyn_right )\n         arg1 = tape->Rec_.put_con_par(right.value_);\n      //\n      if( result )\n      {  tape->Rec_.PutOp(local::LtppOp);\n         tape->Rec_.PutArg(arg1, arg0);\n      }\n      else\n      {  tape->Rec_.PutOp(local::LeppOp);\n         tape->Rec_.PutArg(arg0, arg1);\n      }\n   }\n   return result;\n}\n// convert other cases into the case above\nCPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(>)\n\n// -------------------------------- >= --------------------------\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool operator >= (const AD<Base> &left , const AD<Base> &right)\n{  bool result    =  (left.value_ >= right.value_);\n   //\n   // check if we are recording compare operators\n   local::ADTape<Base> *tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n   if( ! tape->Rec_.get_record_compare() )\n      return result;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if left and right tapes match\n   bool match_left  = left.tape_id_  == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n\n   // check if left and right are dynamic parameters\n   bool dyn_left  = match_left  & (left.ad_type_ == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if left and right are variables\n   bool var_left  = match_left  & (left.ad_type_ != dynamic_enum);\n   bool var_right = match_right & (right.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      left.tape_id_ == right.tape_id_ || ! match_left || ! match_right ,\n      \">= : AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_left )\n   {  if( var_right )\n      {  // variable >= variable\n         if( result )\n         {  tape->Rec_.PutOp(local::LevvOp);\n            tape->Rec_.PutArg(right.taddr_, left.taddr_);\n         }\n         else\n         {  tape->Rec_.PutOp(local::LtvvOp);\n            tape->Rec_.PutArg(left.taddr_, right.taddr_);\n         }\n      }\n      else\n      {  // variable >= parameter\n         addr_t p = right.taddr_;\n         if( ! dyn_right )\n            p = tape->Rec_.put_con_par(right.value_);\n         if( result )\n         {  tape->Rec_.PutOp(local::LepvOp);\n            tape->Rec_.PutArg(p, left.taddr_);\n         }\n         else\n         {  tape->Rec_.PutOp(local::LtvpOp);\n            tape->Rec_.PutArg(left.taddr_, p);\n         }\n      }\n   }\n   else if ( var_right )\n   {  // parameter >= variable\n      addr_t p = left.taddr_;\n      if( ! dyn_left )\n         p = tape->Rec_.put_con_par(left.value_);\n      if( result )\n      {  tape->Rec_.PutOp(local::LevpOp);\n         tape->Rec_.PutArg(right.taddr_, p);\n      }\n      else\n      {  tape->Rec_.PutOp(local::LtpvOp);\n         tape->Rec_.PutArg(p, right.taddr_);\n      }\n   }\n   else if( dyn_left | dyn_right )\n   {  // parameter >= parameter\n      addr_t arg0 = left.taddr_;\n      addr_t arg1 = right.taddr_;\n      if( ! dyn_left )\n         arg0 = tape->Rec_.put_con_par(left.value_);\n      if( ! dyn_right )\n         arg1 = tape->Rec_.put_con_par(right.value_);\n      //\n      if( result )\n      {  tape->Rec_.PutOp(local::LeppOp);\n         tape->Rec_.PutArg(arg1, arg0);\n      }\n      else\n      {  tape->Rec_.PutOp(local::LtppOp);\n         tape->Rec_.PutArg(arg0, arg1);\n      }\n   }\n   return result;\n}\n// convert other cases into the case above\nCPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(>=)\n\n// -------------------------------- == -------------------------\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool operator == (const AD<Base> &left , const AD<Base> &right)\n{  bool result    =  (left.value_ == right.value_);\n   //\n   // check if we are recording compare operators\n   local::ADTape<Base> *tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n   if( ! tape->Rec_.get_record_compare() )\n      return result;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if left and right tapes match\n   bool match_left  = left.tape_id_  == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n\n   // check if left and right are dynamic parameters\n   bool dyn_left  = match_left  & (left.ad_type_ == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if left and right are variables\n   bool var_left  = match_left  & (left.ad_type_ != dynamic_enum);\n   bool var_right = match_right & (right.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      left.tape_id_ == right.tape_id_ || ! match_left || ! match_right ,\n      \"==: AD variables or dynamic parameters on different threads.\"\n   );\n   //\n   tape->Rec_.comp_eq(\n      var_left, var_right, dyn_left, dyn_right, left, right, result\n   );\n   //\n   return result;\n}\n// convert other cases into the case above\nCPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(==)\n\n// -------------------------------- != -------------------------\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool operator != (const AD<Base> &left , const AD<Base> &right)\n{  bool result    =  (left.value_ != right.value_);\n   //\n   // check if we are recording compare operators\n   local::ADTape<Base> *tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n   if( ! tape->Rec_.get_record_compare() )\n      return result;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if left and right tapes match\n   bool match_left  = left.tape_id_  == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n\n   // check if left and right are dynamic parameters\n   bool dyn_left  = match_left  & (left.ad_type_ == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if left and right are variables\n   bool var_left  = match_left  & (left.ad_type_ != dynamic_enum);\n   bool var_right = match_right & (right.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      left.tape_id_ == right.tape_id_ || ! match_left || ! match_right ,\n      \"!=: AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_left )\n   {  if( var_right )\n      {  // variable == variable\n         tape->Rec_.PutArg(left.taddr_, right.taddr_);\n         if( result )\n            tape->Rec_.PutOp(local::NevvOp);\n         else\n            tape->Rec_.PutOp(local::EqvvOp);\n      }\n      else\n      {  // variable == parameter\n         addr_t p = right.taddr_;\n         if( ! dyn_right )\n            p = tape->Rec_.put_con_par(right.value_);\n         tape->Rec_.PutArg(p, left.taddr_);\n         if( result )\n            tape->Rec_.PutOp(local::NepvOp);\n         else\n            tape->Rec_.PutOp(local::EqpvOp);\n      }\n   }\n   else if ( var_right )\n   {  // parameter == variable\n      addr_t p = left.taddr_;\n      if( ! dyn_left )\n         p = tape->Rec_.put_con_par(left.value_);\n      tape->Rec_.PutArg(p, right.taddr_);\n      if( result )\n         tape->Rec_.PutOp(local::NepvOp);\n      else\n         tape->Rec_.PutOp(local::EqpvOp);\n   }\n   else if( dyn_left | dyn_right )\n   {  // parameter == parameter\n      addr_t arg0 = left.taddr_;\n      addr_t arg1 = right.taddr_;\n      if( ! dyn_left )\n         arg0 = tape->Rec_.put_con_par(left.value_);\n      if( ! dyn_right )\n         arg1 = tape->Rec_.put_con_par(right.value_);\n      //\n      tape->Rec_.PutArg(arg0, arg1);\n      if( result )\n         tape->Rec_.PutOp(local::NeppOp);\n      else\n         tape->Rec_.PutOp(local::EqppOp);\n   }\n   return result;\n}\n// convert other cases into the case above\nCPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(!=)\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/compound_assign.hpp",
    "content": "# ifndef CPPAD_CORE_COMPOUND_ASSIGN_HPP\n# define CPPAD_CORE_COMPOUND_ASSIGN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n-------------------------------------------------------------------------------\n{xrst_begin compound_assign}\n{xrst_spell\n   div\n}\n\nAD Compound Assignment Operators\n################################\n\nSyntax\n******\n| *x* *Op* *y*\n\nPurpose\n*******\nPerforms compound assignment operations\nwhere either *x* has type\n``AD`` < *Base* > .\n\nOp\n**\nThe operator *Op* is one of the following\n\n.. csv-table::\n   :widths: auto\n\n   **Op**,**Meaning**\n   ``+=``,*x* is assigned *x* plus *y*\n   ``-=``,*x* is assigned *x* minus *y*\n   ``*=``,*x* is assigned *x* times *y*\n   ``/=``,*x* is assigned *x* divided by *y*\n\nBase\n****\nThe type *Base* is determined by the operand *x* .\n\nx\n*\nThe operand *x* has the following prototype\n\n   ``AD`` < *Base* > & *x*\n\ny\n*\nThe operand *y* has the following prototype\n\n   ``const`` *Type* & *y*\n\nwhere *Type* is\n``VecAD`` < *Base* >:: ``reference`` ,\n``AD`` < *Base* > ,\n*Base* , or\n``double`` .\n\nResult\n******\nThe result of this assignment\ncan be used as a reference to *x* .\nFor example, if *z* has the following type\n\n   ``AD`` < *Base* > *z*\n\nthen the syntax\n\n   *z* = *x* += *y*\n\nwill compute *x* plus *y*\nand then assign this value to both *x* and *z* .\n\nOperation Sequence\n******************\nThis is an :ref:`atomic_base<glossary@Operation@Atomic>`\n:ref:`glossary@AD of Base` operation\nand hence it is part of the current\nAD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n{xrst_toc_hidden\n   example/general/add_eq.cpp\n   example/general/sub_eq.cpp\n   example/general/mul_eq.cpp\n   example/general/div_eq.cpp\n}\n\nExample\n*******\nThe following files contain examples and tests of these functions.\nEach test returns true if it succeeds and false otherwise.\n\n.. csv-table::\n   :widths: auto\n\n   add_eq.cpp,:ref:`add_eq.cpp-title`\n   sub_eq.cpp,:ref:`sub_eq.cpp-title`\n   mul_eq.cpp,:ref:`mul_eq.cpp-title`\n   div_eq.cpp,:ref:`div_eq.cpp-title`\n\nDerivative\n**********\nIf :math:`f` and :math:`g` are\n:ref:`Base functions<glossary@Base Function>`\n\nAddition\n========\n\n.. math::\n\n   \\D{[ f(x) + g(x) ]}{x} = \\D{f(x)}{x} + \\D{g(x)}{x}\n\nSubtraction\n===========\n\n.. math::\n\n   \\D{[ f(x) - g(x) ]}{x} = \\D{f(x)}{x} - \\D{g(x)}{x}\n\nMultiplication\n==============\n\n.. math::\n\n   \\D{[ f(x) * g(x) ]}{x} = g(x) * \\D{f(x)}{x} + f(x) * \\D{g(x)}{x}\n\nDivision\n========\n\n.. math::\n\n   \\D{[ f(x) / g(x) ]}{x} =\n      [1/g(x)] * \\D{f(x)}{x} - [f(x)/g(x)^2] * \\D{g(x)}{x}\n\n{xrst_end compound_assign}\n-----------------------------------------------------------------------------\n*/\n# include <cppad/core/add_eq.hpp>\n# include <cppad/core/sub_eq.hpp>\n# include <cppad/core/mul_eq.hpp>\n# include <cppad/core/div_eq.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/con_dyn_var.hpp",
    "content": "# ifndef CPPAD_CORE_CON_DYN_VAR_HPP\n# define CPPAD_CORE_CON_DYN_VAR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n---------------------------------------------------------------------------\n\n{xrst_begin con_dyn_var}\n\nConstant, Dynamic, Parameter, and Variable\n##########################################\n\nSyntax\n******\n| *b* = ``Constant`` ( *x* )\n| *b* = ``Dynamic`` ( *x* )\n| *b* = ``Parameter`` ( *x* )\n| *b* = ``Variable`` ( *x* )\n\nx\n*\nThe argument *x* has prototype\n\n| |tab| ``const AD`` < *Base* >    & *x*\n| |tab| ``const VecAD`` < *Base* > & *x*\n\nb\n*\nThe return value *b* has prototype\n\n   ``bool`` *b*\n\nConstant\n********\nThe return value for ``Constant`` is true\nis true if and only if *x* is\na :ref:`glossary@Parameter@Constant` parameter.\nA :ref:`VecAD\\<Base><VecAD-name>` object is a constant parameter\nif no element of the vector depends on the independent variables.\n\nDynamic\n*******\nThe return value for ``Dynamic`` is true\nis true if and only if *x* is\na :ref:`glossary@Parameter@Dynamic` parameter.\nNo element of a :ref:`VecAD\\<Base><VecAD-name>` object\ncan depend on the dynamic parameters and this function returns false\nfor these objects.\n\nParameter\n*********\nThe return value for ``Parameter`` is true\nis true if and only if *x* is\na :ref:`glossary@Parameter` .\nA :ref:`VecAD\\<Base><VecAD-name>` object is a parameter\nif no element of the vector depends on the independent variables.\n\nVariable\n********\nThe return value for ``Variable`` is true\nis true if and only if *x* is\na :ref:`glossary@Variable` .\nA :ref:`VecAD\\<Base><VecAD-name>` object is a variable\nif any element of the vector depends on the independent variables.\n\nOperation Sequence\n******************\nThe result of this operation is not an\n:ref:`glossary@AD of Base` object.\nThus it will not be recorded as part of an\nAD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/con_dyn_var.cpp\n}\nThe file\n:ref:`con_dyn_var.cpp-name`\ncontains an example and test of these functions.\n\n{xrst_end con_dyn_var}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD {\n   // -----------------------------------------------------------------------\n   // Constant\n   template <class Base>\n   bool Constant(const AD<Base> &x)\n   {  CPPAD_ASSERT_AD_TYPE( x );\n      if( x.tape_id_ == 0 )\n         return true;\n      //\n      size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS);\n      return x.tape_id_ != *AD<Base>::tape_id_ptr(thread);\n   }\n   //\n   template <class Base>\n   bool Constant(const VecAD<Base> &x)\n   {  CPPAD_ASSERT_AD_TYPE( x );\n      if( x.tape_id_ == 0 )\n         return true;\n      //\n      size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS);\n      return x.tape_id_ != *AD<Base>::tape_id_ptr(thread);\n   }\n   // -----------------------------------------------------------------------\n   // Dynamic\n   template <class Base>\n   bool Dynamic(const AD<Base> &x)\n   {  CPPAD_ASSERT_AD_TYPE( x );\n      if( (x.tape_id_ == 0) || (x.ad_type_ != dynamic_enum) )\n         return false;\n      //\n      size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS);\n      return x.tape_id_ == *AD<Base>::tape_id_ptr(thread);\n   }\n   //\n   template <class Base>\n   bool Dynamic(const VecAD<Base> &x)\n   {  CPPAD_ASSERT_AD_TYPE( x );\n      if( (x.tape_id_ == 0) || (x.ad_type_ != dynamic_enum) )\n         return false;\n      //\n      size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS);\n      return x.tape_id_ == *AD<Base>::tape_id_ptr(thread);\n   }\n   // -----------------------------------------------------------------------\n   // Parameter\n   template <class Base>\n   bool Parameter(const AD<Base> &x)\n   {  CPPAD_ASSERT_AD_TYPE( x );\n      if( (x.tape_id_ == 0) || (x.ad_type_ == dynamic_enum) )\n         return true;\n      //\n      size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS);\n      return x.tape_id_ != *AD<Base>::tape_id_ptr(thread);\n   }\n   //\n   template <class Base>\n   bool Parameter(const VecAD<Base> &x)\n   {  CPPAD_ASSERT_AD_TYPE( x );\n      if( (x.tape_id_ == 0) || (x.ad_type_ == dynamic_enum) )\n         return true;\n      //\n      size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS);\n      return x.tape_id_ != *AD<Base>::tape_id_ptr(thread);\n   }\n   // -----------------------------------------------------------------------\n   // Variable\n   template <class Base>\n   bool Variable(const AD<Base> &x)\n   {  CPPAD_ASSERT_AD_TYPE( x );\n      if( (x.tape_id_ == 0) || (x.ad_type_ != variable_enum) )\n         return false;\n      //\n      size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS);\n      return x.tape_id_ == *AD<Base>::tape_id_ptr(thread);\n   }\n   //\n   template <class Base>\n   bool Variable(const VecAD<Base> &x)\n   {  CPPAD_ASSERT_AD_TYPE( x );\n      if( (x.tape_id_ == 0) || (x.ad_type_ != variable_enum) )\n         return false;\n      //\n      size_t thread = size_t(x.tape_id_ % CPPAD_MAX_NUM_THREADS);\n      return x.tape_id_ == *AD<Base>::tape_id_ptr(thread);\n   }\n}\n// END CppAD namespace\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/cond_exp.hpp",
    "content": "# ifndef CPPAD_CORE_COND_EXP_HPP\n# define CPPAD_CORE_COND_EXP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n-------------------------------------------------------------------------------\n{xrst_begin CondExp}\n\nAD Conditional Expressions\n##########################\n\nSyntax\n******\n| *result* = ``CondExp`` *Rel* ( *left* , *right* , *if_true* , *if_false* )\n\nPurpose\n*******\nRecord,\nas part of an AD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` ,\nthe conditional result\n\n| |tab| ``if`` ( *left* *Cop* *right*  )\n| |tab| |tab| *result* = *if_true*\n| |tab| ``else``\n| |tab| |tab| *result* = *if_false*\n\nThe relational *Rel* and comparison operator *Cop*\nabove have the following correspondence:\n\n.. csv-table::\n\n   *Rel* , ``Lt`` , ``Le`` , ``Eq`` , ``Ge`` , ``Gt``\n   *Cop* ,  <     , <=     , ==     , >=     , >\n\nIf *f* is the :ref:`ADFun-name` object corresponding to the\nAD operation sequence,\nthe assignment choice for *result*\nin an AD conditional expression is made each time\n:ref:`f.Forward<Forward-name>` is used to evaluate the zero order Taylor\ncoefficients with new values for the\n:ref:`independent variables<glossary@Tape@Independent Variable>` .\nThis is in contrast to the :ref:`AD comparison operators<Compare-name>`\nwhich are boolean valued and not included in the AD operation sequence.\n\nRel\n***\nIn the syntax above, the relation *Rel* represents one of the following\ntwo characters: ``Lt`` , ``Le`` , ``Eq`` , ``Ge`` , ``Gt`` .\nAs in the table above,\n*Rel* determines which comparison operator *Cop* is used\nwhen comparing *left* and *right* .\n\nType\n****\nThese functions are defined in the CppAD namespace for arguments of\n*Type* is *Base* or ``AD`` < *Base* > .\nNote that all four arguments,\n*left* , *right*, *if_true* , *if_false* ,  must have the same type.\n\nleft\n****\nThe argument *left* has prototype\n\n   ``const`` *Type* & *left*\n\nIt specifies the value for the left side of the comparison operator.\n\nright\n*****\nThe argument *right* has prototype\n\n   ``const`` *Type* & *right*\n\nIt specifies the value for the right side of the comparison operator.\n\nif_true\n*******\nThe argument *if_true* has prototype\n\n   ``const`` *Type* & *if_true*\n\nIt specifies the return value if the result of the comparison is true.\n\nif_false\n********\nThe argument *if_false* has prototype\n\n   ``const`` *Type* & *if_false*\n\nIt specifies the return value if the result of the comparison is false.\n\nresult\n******\nThe *result* has prototype\n\n   *Type* & *if_false*\n\nOptimize\n********\nThe :ref:`optimize-name` method will optimize conditional expressions\nin the following way:\nDuring :ref:`zero order forward mode<forward_zero-name>` ,\nonce the value of the *left* and *right* have been determined,\nit is known if the true or false case is required.\nFrom this point on, values corresponding to the case that is not required\nare not computed.\nThis optimization is done for the rest of zero order forward mode\nas well as forward and reverse derivatives calculations.\n\nDeprecate 2005-08-07\n********************\nPrevious versions of CppAD used\n\n   ``CondExp`` ( *flag* , *if_true* , *if_false* )\n\nfor the same meaning as\n\n   ``CondExpGt`` ( *flag* , *Type* (0), *if_true* , *if_false* )\n\nUse of ``CondExp`` is deprecated, but continues to be supported.\n\nOperation Sequence\n******************\nThis is an AD of *Base*\n:ref:`atomic operation<glossary@Operation@Atomic>`\nand hence is part of the current\nAD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nExample\n*******\n\nTest\n****\n{xrst_toc_hidden\n   example/general/cond_exp.cpp\n}\nThe file\n:ref:`cond_exp.cpp-name`\ncontains an example and test of this function.\n\nAtan2\n*****\nThe following implementation of the\nAD :ref:`atan2-name` function is a more complex\nexample of using conditional expressions:\n{xrst_literal\n   include/cppad/core/atan2.hpp\n   BEGIN CondExp\n   // END CondExp\n}\n\n{xrst_end CondExp}\n-------------------------------------------------------------------------------\n*/\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nAD<Base> CondExpOp(\n   enum  CompareOp cop       ,\n   const AD<Base> &left      ,\n   const AD<Base> &right     ,\n   const AD<Base> &if_true   ,\n   const AD<Base> &if_false  )\n{\n   AD<Base> result;\n   CPPAD_ASSERT_UNKNOWN( Parameter(result) );\n\n   // check first case where do not need to tape\n   if( IdenticalCon(left) && IdenticalCon(right) )\n   {  result = CondExpOp(\n         cop, left.value_, right.value_, if_true.value_, if_false.value_\n      );\n      return result;\n   }\n\n   // must use CondExp in case Base is an AD type and recording\n   result.value_ = CondExpOp(cop,\n      left.value_, right.value_, if_true.value_, if_false.value_);\n\n   local::ADTape<Base> *tape = AD<Base>::tape_ptr();\n\n   // add this operation to the tape\n   if( tape != nullptr ) tape->Rec_.cond_exp(\n         tape->id_, cop, result, left, right, if_true, if_false\n   );\n\n   return result;\n}\n\n// ------------ CondExpOp(left, right, if_true, if_false) ----------------\n\n# define CPPAD_COND_EXP(Name)                                        \\\n   template <class Base>                                           \\\n   CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION                           \\\n   AD<Base> CondExp##Name(                                         \\\n      const AD<Base> &left      ,                                \\\n      const AD<Base> &right     ,                                \\\n      const AD<Base> &if_true   ,                                \\\n      const AD<Base> &if_false  )                                \\\n   {                                                               \\\n      return CondExpOp(Compare##Name,                            \\\n         left, right, if_true, if_false);                      \\\n   }\n\n// AD<Base>\nCPPAD_COND_EXP(Lt)\nCPPAD_COND_EXP(Le)\nCPPAD_COND_EXP(Eq)\nCPPAD_COND_EXP(Ge)\nCPPAD_COND_EXP(Gt)\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nAD<Base> CondExp(\n   const AD<Base> &flag      ,\n   const AD<Base> &if_true   ,\n   const AD<Base> &if_false  )\n{\n   return CondExpOp(CompareGt, flag, AD<Base>(0), if_true, if_false);\n}\n\n# undef CPPAD_COND_EXP\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/convert.hpp",
    "content": "# ifndef CPPAD_CORE_CONVERT_HPP\n# define CPPAD_CORE_CONVERT_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin Convert}\n\nConversion and I/O of AD Objects\n################################\n{xrst_toc_hidden\n   include/cppad/core/value.hpp\n   include/cppad/core/integer.hpp\n   include/cppad/core/ad_to_string.hpp\n   include/cppad/core/ad_io.hpp\n   include/cppad/core/print_for.hpp\n   include/cppad/core/var2par.hpp\n}\n\n.. csv-table::\n   :widths: auto\n\n   Value,:ref:`Value-title`\n   Integer,:ref:`Integer-title`\n   ad_output,:ref:`ad_output-title`\n   PrintFor,:ref:`PrintFor-title`\n   Var2Par,:ref:`Var2Par-title`\n\n{xrst_end Convert}\n*/\n\n# include <cppad/core/value.hpp>\n# include <cppad/core/integer.hpp>\n# include <cppad/core/ad_to_string.hpp>\n# include <cppad/core/ad_io.hpp>\n# include <cppad/core/print_for.hpp>\n# include <cppad/core/var2par.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/cppad_assert.hpp",
    "content": "# ifndef CPPAD_CORE_CPPAD_ASSERT_HPP\n# define CPPAD_CORE_CPPAD_ASSERT_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*!\n\\file cppad_assert.hpp\nDefine the CppAD error checking macros (all of which begin with CPPAD_ASSERT_)\n*/\n\n/*\n-------------------------------------------------------------------------------\n{xrst_begin cppad_assert}\n{xrst_spell\n   msg\n}\n\nCppAD Assertions During Execution\n#################################\n\nSyntax\n******\n| ``CPPAD_ASSERT_KNOWN`` ( *exp* , *msg* )\n| ``CPPAD_ASSERT_UNKNOWN`` ( *exp* )\n\nPurpose\n*******\nThese CppAD macros are used to detect and report errors.\nThey are documented here because they correspond to the C++\nsource code that the error is reported at.\n\nNDEBUG\n******\nIf the preprocessor symbol\n:ref:`Faq@Speed@NDEBUG` is defined,\nthese macros do nothing; i.e., they are optimized out.\n\nRestriction\n***********\nThe CppAD user should not uses these macros.\nYou can however write your own macros that do not begin with ``CPPAD``\nand that call the :ref:`CppAD error handler<ErrorHandler-name>` .\n\nKnown\n*****\nThe ``CPPAD_ASSERT_KNOWN`` macro is used to check for an error\nwith a known cause.\nFor example, many CppAD routines uses these macros\nto make sure their arguments conform to their specifications.\n\nUnknown\n*******\nThe ``CPPAD_ASSERT_UNKNOWN`` macro is used to check that the\nCppAD internal data structures conform as expected.\nIf this is not the case, CppAD does not know why the error has\noccurred; for example, the user may have written past the end\nof an allocated array.\n\nExp\n***\nThe argument *exp* is a C++ source code expression\nthat results in a ``bool`` value that should be true.\nIf it is false, an error has occurred.\nThis expression may be execute any number of times\n(including zero times) so it must have not side effects.\n\nMsg\n***\nThe argument *msg* has prototype\n\n   ``const char`` * *msg*\n\nand contains a ``'\\0'`` terminated character string.\nThis string is a description of the error\ncorresponding to *exp* being false.\n\nError Handler\n*************\nThese macros use the\n:ref:`CppAD error handler<ErrorHandler-name>` to report errors.\nThis error handler can be replaced by the user.\n\n{xrst_end cppad_assert}\n------------------------------------------------------------------------------\n*/\n\n# include <cassert>\n# include <iostream>\n# include <cppad/utility/error_handler.hpp>\n\n/*!\n\\def CPPAD_ASSERT_KNOWN(exp, msg)\nCheck that exp is true, if not print msg and terminate execution.\n\nThe C++ expression exp is expected to be true.\nIf it is false,\nthe CppAD use has made an error that is described by msg.\nIf the preprocessor symbol NDEBUG is not defined,\nand exp is false,\nthis macro will report the source code line number at\nwhich this expected result occurred.\nIn addition, it will print the specified error message msg.\n*/\n# ifdef NDEBUG\n# define CPPAD_ASSERT_KNOWN(exp, msg)  // do nothing\n# else\n# define CPPAD_ASSERT_KNOWN(exp, msg)           \\\n{  if( ! ( exp ) )                         \\\n   CppAD::ErrorHandler::Call(              \\\n      true       ,                    \\\n      __LINE__   ,                    \\\n      __FILE__   ,                    \\\n      #exp       ,                    \\\n      msg        );                   \\\n}\n# endif\n\n/*!\n\\def CPPAD_ASSERT_UNKNOWN(exp)\nCheck that exp is true, if not terminate execution.\n\nThe C++ expression exp is expected to be true.\nIf it is false,\nCppAD has detected an error but does not know the cause of the error.\nIf the preprocessor symbol NDEBUG is not defined,\nand exp is false,\nthis macro will report the source code line number at\nwhich this expected result occurred.\n*/\n# ifdef NDEBUG\n# define CPPAD_ASSERT_UNKNOWN(exp)      // do nothing\n# else\n# define CPPAD_ASSERT_UNKNOWN(exp)              \\\n{  if( ! ( exp ) )                         \\\n   CppAD::ErrorHandler::Call(              \\\n      false      ,                    \\\n      __LINE__   ,                    \\\n      __FILE__   ,                    \\\n      #exp       ,                    \\\n      \"\"         );                   \\\n}\n# endif\n\n/*!\n\\def CPPAD_ASSERT_NARG_NRES(op, n_arg, n_res)\nCheck that operator op has the specified number of of arguments and results.\n\nIf NDEBUG is not defined and either the number of arguments\nor the number of results are not as expected,\nexecution is terminated and the source code line number is reported.\n*/\n# define CPPAD_ASSERT_NARG_NRES(op, n_arg, n_res)   \\\n   CPPAD_ASSERT_UNKNOWN( NumArg(op) == n_arg ) \\\n   CPPAD_ASSERT_UNKNOWN( NumRes(op) == n_res )\n\n/*!\n\\def CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\nCheck that the first call to a routine is not during parallel execution mode.\n\nIf NDEBUG is defined, this macro has no effect\n(not even the definition of (assert_first_call).\nOtherwise, the variable\n\\code\n   static bool assert_first_call\n\\endcode\nis defined and if the first call is executed in parallel mode,\nexecution is terminated and the source code line number is reported.\n*/\n# ifdef NDEBUG\n# define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# else\n# define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL                           \\\n   static bool assert_first_call = true;                              \\\n   if( assert_first_call )                                            \\\n   {  CPPAD_ASSERT_KNOWN(                                           \\\n      ! (CppAD::thread_alloc::in_parallel() ),                      \\\n      \"In parallel mode and parallel_setup has not been called.\"    \\\n      );                                                            \\\n      assert_first_call = false;                                    \\\n   }\n# endif\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/dependent.hpp",
    "content": "# ifndef CPPAD_CORE_DEPENDENT_HPP\n# define CPPAD_CORE_DEPENDENT_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin Dependent}\n\nStop Recording and Store Operation Sequence\n###########################################\n\nSyntax\n******\n| *f* . ``Dependent`` ( *x* , *y* )\n\nStop Recording\n**************\nThe call stops the recording and the AD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>`\nthat started with the call\n\n   ``Independent`` ( *x* )\n\nStore Operation Sequence\n************************\nThis call also stores the operation sequence in *f* .\nThe operation sequence defines an\n:ref:`glossary@AD Function`\n\n.. math::\n\n   F : \\B{R}^n \\rightarrow \\B{R}^m\n\nwhere :math:`B` is the space corresponding to objects of type *Base* .\nThe value :math:`n` is the dimension of the\n:ref:`fun_property@Domain` space for the operation sequence.\nThe value :math:`m` is the dimension of the\n:ref:`fun_property@Range` space for the operation sequence\n(which is determined by the size of *y* ).\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nThe AD of *Base* operation sequence is stored in *f* ; i.e.,\nit becomes the operation sequence corresponding to *f* .\nIf a previous operation sequence was stored in *f* ,\nit is deleted.\n\nx\n*\nThe argument *x*\nmust be the vector argument in a previous call to\n:ref:`Independent-name` .\nNeither its size, or any of its values, are allowed to change\nbetween calling\n\n   ``Independent`` ( *x* )\n\nand\n\n   *f* . ``Dependent`` ( *x* , *y* )\n\n.\n\ny\n*\nThe vector *y* has prototype\n\n   ``const`` *ADvector* & *y*\n\n(see :ref:`ADvector<fun_construct-name>` below).\nThe length of *y* must be greater than zero\nand is the dimension of the range space for *f* .\n\nADvector\n********\nThe type *ADvector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``AD`` < *Base* > .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nTaping\n******\nThe tape,\nthat was created when ``Independent`` ( *x* ) was called,\nwill stop recording.\nThe AD operation sequence will be transferred from\nthe tape to the object *f* and the tape will then be deleted.\n\nForward\n*******\nNo :ref:`Forward-name` calculation is preformed during this operation.\nThus, directly after this operation,\n\n   *f* . ``size_order`` ()\n\nis zero (see :ref:`size_order-name` ).\n\nParallel Mode\n*************\nThe call to ``Independent`` ,\nand the corresponding call to\n\n   ``ADFun`` < *Base* > *f* ( *x* , *y* )\n\nor\n\n   *f* . ``Dependent`` ( *x* , *y* )\n\nor :ref:`abort_recording-name` ,\nmust be preformed by the same thread; i.e.,\n:ref:`thread_alloc::thread_num<ta_thread_num-name>` must be the same.\n\nExample\n*******\nThe file\n:ref:`fun_check.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end Dependent}\n----------------------------------------------------------------------------\n*/\n\n\n// BEGIN CppAD namespace\nnamespace CppAD {\n\n/*!\n\\file dependent.hpp\nDifferent versions of Dependent function.\n*/\n\n/*!\nDetermine the tape corresponding to this execution thread and then use\n<code>Dependent(tape, y)</code> to store this tapes recording in a function.\n\n\\param y [in]\nThe dependent variable vector for the corresponding function.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class ADvector>\nvoid ADFun<Base,RecBase>::Dependent(const ADvector &y)\n{  local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   CPPAD_ASSERT_KNOWN(\n      tape != nullptr,\n      \"Can't store current operation sequence in this ADFun object\"\n      \"\\nbecause there is no active tape (for this thread).\"\n   );\n\n   // code above just determines the tape and checks for errors\n   Dependent(tape, y);\n}\n\n\n/*!\nDetermine the tape corresponding to this execution thread and then use\n<code>Dependent(tape, y)</code> to store this tapes recording in a function.\n\n\\param x [in]\nThe independent variable vector for this tape. This information is\nalso stored in the tape so a check is done to make sure it is correct\n(if NDEBUG is not defined).\n\n\\param y [in]\nThe dependent variable vector for the corresponding function.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class ADvector>\nvoid ADFun<Base,RecBase>::Dependent(const ADvector &x, const ADvector &y)\n{\n   CPPAD_ASSERT_KNOWN(\n      x.size() > 0,\n      \"Dependent: independent variable vector has size zero.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      Variable(x[0]),\n      \"Dependent: independent variable vector has been changed.\"\n   );\n   local::ADTape<Base> *tape = AD<Base>::tape_ptr(x[0].tape_id_);\n   CPPAD_ASSERT_KNOWN(\n      tape->size_independent_ == size_t( x.size() ),\n      \"Dependent: independent variable vector has been changed.\"\n   );\n# ifndef NDEBUG\n   size_t i, j;\n   for(j = 0; j < size_t(x.size()); j++)\n   {  CPPAD_ASSERT_KNOWN(\n      size_t(x[j].taddr_) == (j+1),\n      \"ADFun<Base>: independent variable vector has been changed.\"\n      );\n      CPPAD_ASSERT_KNOWN(\n      x[j].tape_id_ == x[0].tape_id_,\n      \"ADFun<Base>: independent variable vector has been changed.\"\n      );\n   }\n   for(i = 0; i < size_t(y.size()); i++)\n   {  CPPAD_ASSERT_KNOWN(\n      CppAD::Parameter( y[i] ) || (y[i].tape_id_ == x[0].tape_id_) ,\n      \"ADFun<Base>: dependent vector contains a variable for\"\n      \"\\na different tape (thread) than the independent variables.\"\n      );\n   }\n# endif\n\n   // code above just determines the tape and checks for errors\n   Dependent(tape, y);\n}\n\n/*!\nReplace the floationg point operations sequence for this function object.\n\n\\param tape\nis a tape that contains the new floating point operation sequence\nfor this function.\nAfter this operation, all memory allocated for this tape is deleted.\n\n\\param y\nThe dependent variable vector for the function being stored in this object.\n\n\\par\nAll of the private member data in ad_fun.hpp is set to correspond to the\nnew tape except for check_for_nan_.\n*/\n\ntemplate <class Base, class RecBase>\ntemplate <class ADvector>\nvoid ADFun<Base,RecBase>::Dependent(local::ADTape<Base> *tape, const ADvector &y)\n{\n   size_t   m = y.size();\n   size_t   n = tape->size_independent_;\n\n   // check ADvector is Simple Vector class with AD<Base> elements\n   CheckSimpleVector< AD<Base>, ADvector>();\n\n   CPPAD_ASSERT_KNOWN(\n      y.size() > 0,\n      \"ADFun operation sequence dependent variable size is zero size\"\n   );\n   // ---------------------------------------------------------------------\n   // Begin setting ad_fun.hpp private member data\n   // ---------------------------------------------------------------------\n   // dep_parameter_, dep_taddr_\n   CPPAD_ASSERT_UNKNOWN( local::NumRes(local::ParOp) == 1 );\n   dep_parameter_.resize(m);\n   dep_taddr_.resize(m);\n   for(size_t i = 0; i < m; i++)\n   {  dep_parameter_[i] = CppAD::Parameter(y[i]);\n      addr_t y_taddr;\n      if( dep_parameter_[i] )\n      {  // make a tape copy of dependent variables that are parameters,\n         y_taddr = tape->RecordParOp( y[i] );\n      }\n      else\n         y_taddr = y[i].taddr_;\n\n      CPPAD_ASSERT_UNKNOWN( y_taddr > 0 );\n      dep_taddr_[i] = size_t( y_taddr );\n   }\n\n   // put an EndOp at the end of the tape\n   tape->Rec_.PutOp(local::EndOp);\n\n   // bool values in this object except check_for_nan_\n   has_been_optimized_        = false;\n   //\n   // size_t values in this object\n   compare_change_count_      = 1;\n   compare_change_number_     = 0;\n   compare_change_op_index_   = 0;\n   num_order_taylor_          = 0;\n   cap_order_taylor_          = 0;\n   num_direction_taylor_      = 0;\n   num_var_tape_              = tape->Rec_.num_var();\n\n   // taylor_\n   taylor_.resize(0);\n\n   // cskip_op_\n   cskip_op_.resize( tape->Rec_.num_var_op() );\n\n   // load_op2var_\n   load_op2var_.resize( tape->Rec_.num_var_load() );\n\n   // play_\n   // Now that each dependent variable has a place in the tape,\n   // and there is a EndOp at the end of the tape, we can transfer the\n   // recording to the player and and erase the recording; i.e. ERASE Rec_.\n   play_.get_recording(tape->Rec_, n);\n\n   // ind_taddr_\n   // Note that play_ has been set, we can use it to check operators\n   ind_taddr_.resize(n);\n   CPPAD_ASSERT_UNKNOWN( n < num_var_tape_);\n   for(size_t j = 0; j < n; j++)\n   {  CPPAD_ASSERT_UNKNOWN( play_.GetOp(j+1) == local::InvOp );\n      ind_taddr_[j] = j+1;\n   }\n\n   // for_jac_sparse_pack_, for_jac_sparse_set_\n   for_jac_sparse_pack_.resize(0, 0);\n   for_jac_sparse_set_.resize(0,0);\n\n   // resize subgraph_info_\n   subgraph_info_.resize(\n      ind_taddr_.size(),   // n_dep\n      dep_taddr_.size(),   // n_ind\n      play_.num_var_op(),  // n_op\n      play_.num_var()      // n_var\n   );\n   // ---------------------------------------------------------------------\n   // End set ad_fun.hpp private member data\n   // ---------------------------------------------------------------------\n\n   // now we can delete the tape\n   AD<Base>::tape_manage(delete_tape_manage);\n\n   // total number of variables in this recording\n   CPPAD_ASSERT_UNKNOWN( num_var_tape_  == play_.num_var() );\n\n   // used to determine if there is an operation sequence in *this\n   CPPAD_ASSERT_UNKNOWN( num_var_tape_  > 0 );\n\n}\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/discrete/discrete.hpp",
    "content": "# ifndef CPPAD_CORE_DISCRETE_DISCRETE_HPP\n# define CPPAD_CORE_DISCRETE_DISCRETE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <vector>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/local/op_code_dyn.hpp>\n\n// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*\n ------------------------------------------------------------------------------\n{xrst_begin discrete_create dev}\nCreate a Discrete AD Function\n#############################\n\nSyntax\n******\n| ``CPPAD_DISCRETE_FUNCTION`` ( *Base* , *name* )\n| ``name`` ( *ax* , *ay* )\n\nBase\n****\nis the base type for the discrete function.\n\nname\n****\nis the name of the user defined function that corresponding to this operation.\n\nax\n**\nIs a ``AD`` < *Base* > corresponding to the argument for the function.\n\nay\n**\nIs a ``AD`` < *Base* > corresponding to the result for the function.\n\nfun\n***\nThe local object ``fun`` is a member of the ``discrete`` class.\n\nSource Code\n***********\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_DISCRETE_FUNCTION(Base, name)            \\\ninline CppAD::AD<Base> name (const CppAD::AD<Base>& ax) \\\n{    static CppAD::discrete<Base> fun(#name, name);     \\\n     return fun.ad(ax);                                 \\\n}                                                       \\\nCppAD::AD<Base> this_variable_name_used_to_initialize_discrete_ ##name =  \\\nname( CppAD::AD<Base>(0.0) );\n//\n# define CppADCreateDiscrete CPPAD_DISCRETE_FUNCTION\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end discrete_create}\n-----------------------------------------------------------------------------\n{xrst_begin discrete_class dev}\n\nDeclare discrete Class and Member Data\n######################################\n\nparallel_ad\n***********\nis a friend of this class so it can call List to initialize\nits static data.\n\nFun\n***\nis the type for the user routine that computes *Base* function values.\n\nname\\_\n******\nname of this user defined discrete function.\n\nf\\_\n***\nuser routine that computes *Base* function values.\n\nindex\\_\n*******\nindex of this object in :ref:`discrete_list-name` for this *Base* .\n\nSource Code\n***********\n{xrst_spell_off}\n{xrst_code hpp} */\ntemplate <class Base>\nclass discrete {\nprivate:\n   template <class Type> friend void parallel_ad(void);\n   typedef Base (*Fun) (const Base& x);\n   const std::string    name_;\n   const Fun            f_;\n   const size_t         index_;\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end discrete_class}\n------------------------------------------------------------------------------\n{xrst_begin discrete_list dev}\nList of all objects in the discrete class\n#########################################\n\nSyntax\n******\n*list* = ``discrete`` < *Base* >:: ``List`` ()\n\nBase\n****\nIs the :ref:`discrete_create@Base`\ntype for this list of discrete functions.\n\nlist\n****\nis a reference to the list of all the\n``discrete`` object currently defined.\n\nstd::vector\n===========\nWe use ``std::vector`` instead of ``CppAD::vector``\nso it does not appear that there is a :ref:`memory_leak-name`\nthis list is not destroyed before\n:ref:`thread_alloc::free_all<ta_free_all-name>` is called by testing routines.\n\nSource Code\n***********\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   static std::vector<discrete *>& List(void)\n   {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n      static std::vector<discrete *> list;\n      return list;\n   }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end discrete_list}\n ------------------------------------------------------------------------------\n{xrst_begin discrete_list_size dev}\nSize of the Discrete Function List\n##################################\n\nSyntax\n******\n*size* = ``discrete`` < *Base* >:: ``list_size`` ()\n\nBase\n****\nIs the :ref:`discrete_create@Base`\ntype for this list of discrete functions.\n\nsize\n****\nis the number of discrete functions for this *Base* type.\n\nSource Code\n***********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   static size_t list_size(void)\n   {  return List().size(); }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end discrete_list_size}\n ------------------------------------------------------------------------------\n{xrst_begin discrete_ctor dev}\nConstructor Called by each Use of CPPAD_DISCRETE_FUNCTION\n#########################################################\n\nSyntax\n******\n``discrete`` < *Base* > *fun* ( *name* , *f* )\n\nname\n****\nis the name of this function.\n\nf\n*\nuser routine that implements this function for Base class.\n\nfun\n***\nis the ``discrete`` object created by this call to the constructor.\n\nname\\_\n======\nis set equal to *name* .\n\nf\\_\n===\nis set equal to *f* .\n\nindex\\_\n=======\nThis object is put at the end of :ref:`discrete_list-name` and ``index_``\nis set to the index of this object in the discrete list.\n\nParallel\n********\nThis constructor cannot be used in parallel mode because it changes\nthe static object returned by :ref:`discrete_list-name` .\n\n{xrst_end discrete_ctor}\n*/\npublic:\n   discrete(const std::string& name, Fun f) :\n   name_(name), f_(f) , index_( List().size() )\n   {  std::string msg = \"discrete: first call to the discrete function \";\n      msg  += name;\n      msg  += \" is in parallel mode.\";\n      CPPAD_ASSERT_KNOWN(\n         ! thread_alloc::in_parallel() ,\n         msg.c_str()\n      );\n      List().push_back(this);\n   }\n/*\n ------------------------------------------------------------------------------\n{xrst_begin discrete_ad dev}\nImplement AD Version of a Discrete Function\n###########################################\n\nSyntax\n******\n*ay* = *fun* . ``ad`` ( *ax* )\n\nax\n**\nis the argument for the AD version of this function.\n\nay\n**\nis the return value for the AD version of this function.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\n   AD<Base> ad(const AD<Base> &ax) const\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end discrete_ad}\n*/\n   {\n      CPPAD_ASSERT_KNOWN(\n         size_t( std::numeric_limits<addr_t>::max() ) >= index_,\n         \"discrete: cppad_tape_addr_type maximum not large enough\"\n      );\n      //\n      AD<Base> ay;\n      ay.value_ = f_(ax.value_);\n      //\n      // check if there is a recording in progress\n      local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n      if( tape == nullptr )\n         return ay;\n      //\n      // check if argument is a constant parameter\n      if( ax.tape_id_ != tape->id_ )\n         return ay;\n      //\n      if( ax.ad_type_ == dynamic_enum )\n      {\n         // tape dynamic parameter operation\n         ay.taddr_   = tape->Rec_.put_dyn_par(\n            ay.value_, local::dis_dyn, addr_t(index_), ax.taddr_\n         );\n         ay.tape_id_  = ax.tape_id_;\n         ay.ad_type_  = dynamic_enum;\n\n         // make result a dynamic parameter\n         ay.tape_id_    = tape->id_;\n         ay.ad_type_    = dynamic_enum;\n\n         CPPAD_ASSERT_UNKNOWN( Dynamic(ay) );\n      }\n      else if( ax.ad_type_ == variable_enum )\n      {\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DisOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DisOp) == 2 );\n\n         // put operand addresses in the tape\n         CPPAD_ASSERT_KNOWN(\n            size_t( std::numeric_limits<addr_t>::max() ) >= index_,\n            \"discrete: cppad_tape_addr_type maximum not large enough\"\n         );\n         tape->Rec_.PutArg(addr_t(index_), ax.taddr_);\n         // put operator in the tape\n         ay.taddr_ = tape->Rec_.PutOp(local::DisOp);\n         // make result a variable\n         ay.tape_id_    = tape->id_;\n         ay.ad_type_    = variable_enum;\n\n         CPPAD_ASSERT_UNKNOWN( Variable(ay) );\n      }\n      else\n      {  // other types not yet being used and should have this tape id\n         CPPAD_ASSERT_UNKNOWN(false);\n      }\n      return ay;\n   }\n/*\n ------------------------------------------------------------------------------\n{xrst_begin discrete_index dev}\n{xrst_spell\n   msg\n   str\n}\n\nIndex That Identifies a Discrete Function\n#########################################\n{xrst_code hpp} */\nstatic size_t index(const std::string& name)\n{  size_t i = List().size();\n   while(i--)\n   {  if( List()[i]->name_ == name )\n         return i;\n   }\n   std::string msg = \"There is no discrete function named \" + name;\n   CPPAD_ASSERT_KNOWN(false, msg.c_str());\n   return List().size();\n}\n/* {xrst_code}\n\n{xrst_end discrete_index}\n*/\n/*\n------------------------------------------------------------------------------\n{xrst_begin discrete_name dev}\n\nName Corresponding to a discrete Function\n#########################################\n\nSyntax\n******\n``discrete`` < *Base* >:: ``name`` ( *index* )\n\nBase\n****\nIs the :ref:`discrete_create@Base`\ntype for this list of discrete functions.\n\nindex\n*****\nIs the index, in the list, for this discrete function.\n\nSource Code\n***********\n{xrst_spell_off}\n{xrst_code hpp} */\n   static const std::string& name(size_t index)\n   {  return List()[index]->name_; }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end discrete_name}\n------------------------------------------------------------------------------\n{xrst_begin discrete_eval dev}\nLink From Forward Mode Sweep to Users Routine\n#############################################\n\nSyntax\n******\n*y* = ``discrete`` < *Base* >:: ``eval`` ( *index* , *x* )\n\nBase\n****\nIs the :ref:`discrete_create@Base`\ntype for this list of discrete functions.\n\nindex\n*****\nindex for this function in :ref:`discrete_list-name` .\n\nx\n*\nargument at which to evaluate *Base* version of this function.\n\ny\n*\nresult for the *Base* version of this function.\n\nSource Code\n***********\n{xrst_spell_off}\n{xrst_code hpp} */\n   static Base eval(size_t index, const Base& x)\n   {  CPPAD_ASSERT_UNKNOWN(index < List().size() );\n      return List()[index]->f_(x);\n   }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end discrete_eval}\n------------------------------------------------------------------------------\n{xrst_begin discrete_ad_eval dev}\nLink From Forward Mode Sweep to AD Version of Discrete Function\n###############################################################\n\nSyntax\n******\n*ay* = ``discrete`` < *Base* >:: ``eval`` ( *index* , *ax* )\n\nBase\n****\nIs the :ref:`discrete_create@Base`\ntype for this list of discrete functions.\n\nindex\n*****\nindex for this function in :ref:`discrete_list-name` .\n\nax\n**\nargument at which to evaluate ``AD`` < *Base* > version of this function.\n\nay\n**\nresult for the ``AD`` < *Base* > version of this function.\n\nSource Code\n***********\n{xrst_spell_off}\n{xrst_code hpp} */\n   static AD<Base> ad_eval(size_t index, const AD<Base>& ax)\n   {  CPPAD_ASSERT_UNKNOWN(index < List().size() );\n      return List()[index]->ad(ax);\n   }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end discrete_ad_eval}\n*/\n};\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/div.hpp",
    "content": "# ifndef CPPAD_CORE_DIV_HPP\n# define CPPAD_CORE_DIV_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nAD<Base> operator / (const AD<Base> &left , const AD<Base> &right)\n{\n   // compute the Base part\n   AD<Base> result;\n   result.value_  = left.value_ / right.value_;\n   CPPAD_ASSERT_UNKNOWN( Parameter(result) );\n\n   // check if there is a recording in progress\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if left and right tapes match\n   bool match_left  = left.tape_id_  == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n\n   // check if left and right are dynamic parameters\n   bool dyn_left  = match_left  & (left.ad_type_ == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if left and right are variables\n   bool var_left  = match_left  & (left.ad_type_ != dynamic_enum);\n   bool var_right = match_right & (right.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      left.tape_id_ == right.tape_id_ || ! match_left || ! match_right ,\n      \"Divide: AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_left )\n   {  if( var_right )\n      {  // result = variable / variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivvvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivvvOp) == 2 );\n\n         // put operand addresses in tape\n         tape->Rec_.PutArg(left.taddr_, right.taddr_);\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::DivvvOp);\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n      else if( (! dyn_right) && IdenticalOne(right.value_) )\n      {  // result = variable / 1\n         result.make_variable(left.tape_id_, left.taddr_);\n      }\n      else\n      {  // result = variable / parameter\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivvpOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivvpOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = right.taddr_;\n         if( ! dyn_right )\n            p = tape->Rec_.put_con_par(right.value_);\n         tape->Rec_.PutArg(left.taddr_, p);\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::DivvpOp);\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n   }\n   else if( var_right )\n   {  if( (! dyn_left) && IdenticalZero(left.value_) )\n      {  // result = 0 / variable\n         result.value_ = Base(0.0); // incase right.value_ is zero or nan\n      }\n      else\n      {  // result = parameter / variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivpvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivpvOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = left.taddr_;\n         if( ! dyn_left )\n            p = tape->Rec_.put_con_par(left.value_);\n         tape->Rec_.PutArg(p, right.taddr_);\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::DivpvOp);\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n   }\n   else if( dyn_left | dyn_right )\n   {  if ( (!dyn_left) && IdenticalZero(left.value_))\n      {  // 0 / dynamic\n         result.value_ = Base(0.0);\n      } else if( (!dyn_right) && IdenticalOne(right.value_))\n      {  // dynamic / 1\n         result.make_dynamic(left.tape_id_, left.taddr_);\n      } else\n      {\n         addr_t arg0 = left.taddr_;\n         addr_t arg1 = right.taddr_;\n         if( ! dyn_left )\n         arg0 = tape->Rec_.put_con_par(left.value_);\n         if( ! dyn_right )\n         arg1 = tape->Rec_.put_con_par(right.value_);\n         //\n         // parameters with a dynamic parameter result\n         result.taddr_   = tape->Rec_.put_dyn_par(\n            result.value_, local::div_dyn,   arg0, arg1\n         );\n         result.tape_id_ = tape_id;\n         result.ad_type_ = dynamic_enum;\n      }\n   }\n   return result;\n}\n\n// convert other cases into the case above\nCPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(/)\n\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/div_eq.hpp",
    "content": "# ifndef CPPAD_CORE_DIV_EQ_HPP\n# define CPPAD_CORE_DIV_EQ_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nAD<Base>& AD<Base>::operator /= (const AD<Base> &right)\n{\n   // compute the Base part\n   Base left;\n   left    = value_;\n   value_ /= right.value_;\n\n   // check if there is a recording in progress\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return *this;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if left and right tapes match\n   bool match_left  = tape_id_       == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n\n   // check if left and right are dynamic parameters\n   bool dyn_left  = match_left  & (ad_type_ == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if left and right are variables\n   bool var_left  = match_left  & (ad_type_ != dynamic_enum);\n   bool var_right = match_right & (right.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      tape_id_ == right.tape_id_ || ! match_left || ! match_right ,\n      \"/= : AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_left )\n   {  if( var_right )\n      {  // this = variable / variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivvvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivvvOp) == 2 );\n\n         // put operand addresses in tape\n         tape->Rec_.PutArg(taddr_, right.taddr_);\n         // put operator in the tape\n         taddr_ = tape->Rec_.PutOp(local::DivvvOp);\n         // check that this is a variable\n         CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id );\n         CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum);\n      }\n      else if( (! dyn_right) && IdenticalOne(right.value_) )\n      {  // this = variable * 1\n      }\n      else\n      {  // this = variable / parameter\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivvpOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivvpOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = right.taddr_;\n         if( ! dyn_right )\n            p = tape->Rec_.put_con_par(right.value_);\n         tape->Rec_.PutArg(taddr_, p);\n         // put operator in the tape\n         taddr_ = tape->Rec_.PutOp(local::DivvpOp);\n         // check that this is a variable\n         CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id );\n         CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum);\n      }\n   }\n   else if( var_right  )\n   {  if( (! dyn_left) && IdenticalZero(left) )\n      {  // this = 0 / variable\n      }\n      else\n      {  // this = parameter / variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::DivpvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::DivpvOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = taddr_;\n         if( ! dyn_left )\n            p = tape->Rec_.put_con_par(left);\n         tape->Rec_.PutArg(p, right.taddr_);\n\n         // put operator in the tape\n         taddr_ = tape->Rec_.PutOp(local::DivpvOp);\n\n         // make this a variable\n         tape_id_ = tape_id;\n         ad_type_ = variable_enum;\n      }\n   }\n   else if( dyn_left | dyn_right )\n   {  if( (!dyn_right) && IdenticalOne(right.value_))\n      {  // dynamic /= 1, so do nothing\n      } else if( (!dyn_left) && IdenticalZero(left))\n      {  // 0 /= dynamic, so do nothing\n      } else\n      {     \n         addr_t arg0 = taddr_;\n         addr_t arg1 = right.taddr_;\n         if( ! dyn_left )\n         arg0 = tape->Rec_.put_con_par(left);\n         if( ! dyn_right )\n         arg1 = tape->Rec_.put_con_par(right.value_);\n         //\n         // parameters with a dynamic parameter results\n         taddr_ = tape->Rec_.put_dyn_par(\n            value_, local::div_dyn, arg0, arg1\n         );\n         tape_id_ = tape_id;\n         ad_type_ = dynamic_enum;\n      }\n   }\n   return *this;\n}\n\nCPPAD_FOLD_ASSIGNMENT_OPERATOR(/=)\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/drivers.hpp",
    "content": "# ifndef CPPAD_CORE_DRIVERS_HPP\n# define CPPAD_CORE_DRIVERS_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/core/jacobian.hpp>\n# include <cppad/core/hessian.hpp>\n# include <cppad/core/for_one.hpp>\n# include <cppad/core/rev_one.hpp>\n# include <cppad/core/for_two.hpp>\n# include <cppad/core/rev_two.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/epsilon.hpp",
    "content": "# ifndef CPPAD_CORE_EPSILON_HPP\n# define CPPAD_CORE_EPSILON_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n------------------------------------------------------------------------------\n{xrst_begin epsilon app}\n{xrst_spell\n   eps\n}\n\nMachine Epsilon For AD Types\n############################\n\nDeprecated 2012-06-17\n*********************\nThis routine has been deprecated.\nYou should use the :ref:`numeric_limits-name` ``epsilon`` instead.\n\nSyntax\n******\n| *eps* = ``epsilon`` < *Float* >()\n\nPurpose\n*******\nObtain the value of machine epsilon corresponding\nto the type *Float* .\n\nFloat\n*****\nthis type can either be ``AD`` < *Base* > ,\nor it can be *Base* for any ``AD`` < *Base* > type.\n\neps\n***\nThe result *eps* has prototype\n\n   *Float* ``eps``\n\n{xrst_end epsilon}\n------------------------------------------------------------------------------\n*/\n\nnamespace CppAD {\n\n   template <class Type>\n   inline Type epsilon(void)\n   {  return Type ( numeric_limits<Type>::epsilon() ); }\n\n}\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/equal_op_seq.hpp",
    "content": "# ifndef CPPAD_CORE_EQUAL_OP_SEQ_HPP\n# define CPPAD_CORE_EQUAL_OP_SEQ_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n------------------------------------------------------------------------------\n{xrst_begin EqualOpSeq}\n\nCheck if Two Value are Identically Equal\n########################################\n\nSyntax\n******\n| *b* = ``EqualOpSeq`` ( *x* , *y* )\n\nPurpose\n*******\nDetermine if two *x* and *y* are identically equal; i.e.,\nnot only is *x* == *y* true, but\nif they are :ref:`variables<glossary@Variable>` ,\nthey correspond have the same\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nMotivation\n**********\nSometimes it is useful to cache information\nand only recalculate when a function's arguments change.\nIn the case of AD variables,\nit may be important not only when the argument values are equal,\nbut when they are related to the\n:ref:`independent variables<glossary@Tape@Independent Variable>`\nby the same operation sequence.\nAfter the assignment\n\n   *y* = *x*\n\nthese two AD objects would not only have equal values,\nbut would also correspond to the same operation sequence.\n\nx\n*\nThe argument *x* has prototype\n\n   ``const AD`` < *Base* > & *x*\n\ny\n*\nThe argument *y* has prototype\n\n   ``const AD`` < *Base* > & *y*\n\nb\n*\nThe result *b* has prototype\n\n   ``bool`` *b*\n\nThe result is true if and only if one of the following cases holds:\n\n#. Both *x* and *y* are variables\n   and correspond to the same operation sequence.\n#. Both *x* and *y* are parameters,\n   *Base* is an AD type,\n   and ``EqualOpSeq`` ( ``Value`` ( *x* ) , ``Value`` ( *y* ) ) is true.\n#. Both *x* and *y* are parameters,\n   *Base* is not an AD type,\n   and *x* == *y* is true.\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/equal_op_seq.cpp\n}\nThe file\n:ref:`equal_op_seq.cpp-name`\ncontains an example and test of ``EqualOpSeq`` .\n\n{xrst_end EqualOpSeq}\n------------------------------------------------------------------------------\n*/\n\n\nnamespace CppAD {\n   template <class Base>\n   CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\n   bool EqualOpSeq(const AD<Base> &x, const AD<Base> &y)\n   {\n      if( Parameter(x) )\n      {  if( Parameter(y) )\n            return EqualOpSeq(x.value_, y.value_);\n         else\n            return false;\n      }\n      else if( Parameter(y) )\n         return false;\n\n      return (x.taddr_ == y.taddr_);\n   }\n\n}\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/for_hes_sparsity.hpp",
    "content": "# ifndef CPPAD_CORE_FOR_HES_SPARSITY_HPP\n# define CPPAD_CORE_FOR_HES_SPARSITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin for_hes_sparsity}\n{xrst_spell\n   rc\n   walther\n}\n\nForward Mode Hessian Sparsity Patterns\n######################################\n\nSyntax\n******\n| *f* . ``for_hes_sparsity`` (\n| |tab| *select_domain* , *select_range* , *internal_bool* , *pattern_out*\n| )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to\nthe operation sequence stored in *f* .\nFix a diagonal matrix :math:`D \\in \\B{R}^{n \\times n}`,\na vector :math:`s \\in \\B{R}^m` and define the function\n\n.. math::\n\n   H(x) = D ( s^\\R{T} F )^{(2)} ( x ) D\n\nGiven  the sparsity for :math:`D` and :math:`s`,\n``for_hes_sparsity`` computes a sparsity pattern for :math:`H(x)`.\n\nx\n*\nNote that the sparsity pattern :math:`H(x)` corresponds to the\noperation sequence stored in *f* and does not depend on\nthe argument *x* .\n\nBoolVector\n**********\nThe type *BoolVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``bool`` .\n\nSizeVector\n**********\nThe type *SizeVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``size_t`` .\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nselect_domain\n*************\nThe argument *select_domain* has prototype\n\n   ``const`` *BoolVector* & *select_domain*\n\nIt has size :math:`n` and specifies which components of the diagonal of\n:math:`D` are non-zero; i.e., *select_domain* [ *j* ] is true\nif and only if :math:`D_{j,j}` is possibly non-zero.\n\nselect_range\n************\nThe argument *select_range* has prototype\n\n   ``const`` *BoolVector* & *select_range*\n\nIt has size :math:`m` and specifies which components of the vector\n:math:`s` are non-zero; i.e., *select_range* [ *i* ] is true\nif and only if :math:`s_i` is possibly non-zero.\n\ninternal_bool\n*************\nIf this is true, calculations are done with sets represented by a vector\nof boolean values. Otherwise, a vector of sets of integers is used.\n\npattern_out\n***********\nThis argument has prototype\n\n   ``sparse_rc`` < *SizeVector* >& *pattern_out*\n\nThis input value of *pattern_out* does not matter.\nUpon return *pattern_out* is a sparsity pattern for :math:`H(x)`.\n\nSparsity for Entire Hessian\n***************************\nSuppose that :math:`D` is the :math:`n \\times n` identity matrix.\nIn this case, *pattern_out* is a sparsity pattern for\n:math:`(s^\\R{T} F) F^{(2)} ( x )`.\n\nAlgorithm\n*********\nSee Algorithm II in\n*Computing sparse Hessians with automatic differentiation*\nby Andrea Walther.\nNote that *s* provides the information so that\n'dead ends' are not included in the sparsity pattern.\n\nExample\n*******\n{xrst_toc_hidden\n   example/sparse/for_hes_sparsity.cpp\n}\nThe file :ref:`for_hes_sparsity.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end for_hes_sparsity}\n-----------------------------------------------------------------------------\n*/\n# include <cppad/core/ad_fun.hpp>\n# include <cppad/local/sparse/internal.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*!\nForward Hessian sparsity patterns.\n\n\\tparam Base\nis the base type for this recording.\n\n\\tparam BoolVector\nis the simple vector with elements of type bool that is used for\nsparsity for the vector s.\n\n\\tparam SizeVector\nis the simple vector with elements of type size_t that is used for\nrow, column index sparsity patterns.\n\n\\param select_domain\nis a sparsity pattern for for the diagonal of D.\n\n\\param select_range\nis a sparsity pattern for for s.\n\n\\param internal_bool\nIf this is true, calculations are done with sets represented by a vector\nof boolean values. Otherwise, a vector of standard sets is used.\n\n\\param pattern_out\nThe return value is a sparsity pattern for H(x) where\n\\f[\n   H(x) = D * F^{(1)} (x) * D\n\\f]\nHere F is the function corresponding to the operation sequence\nand x is any argument value.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BoolVector, class SizeVector>\nvoid ADFun<Base,RecBase>::for_hes_sparsity(\n   const BoolVector&            select_domain    ,\n   const BoolVector&            select_range     ,\n   bool                         internal_bool    ,\n   sparse_rc<SizeVector>&       pattern_out      )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   size_t n  = Domain();\n   size_t m  = Range();\n   //\n   CPPAD_ASSERT_KNOWN(\n      size_t( select_domain.size() ) == n,\n      \"for_hes_sparsity: size of select_domain is not equal to \"\n      \"number of independent variables\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t( select_range.size() ) == m,\n      \"for_hes_sparsity: size of select_range is not equal to \"\n      \"number of dependent variables\"\n   );\n   // do not need transpose or dependency\n   bool transpose  = false;\n   bool dependency = false;\n   //\n   local::pod_vector<bool> select_domain_pod_vector(n);\n   for(size_t j = 0; j < n; ++j)\n      select_domain_pod_vector[j] = select_domain[j];\n   //\n   sparse_rc<SizeVector> pattern_tmp;\n   if( internal_bool )\n   {\n      // reverse Jacobian sparsity pattern for select_range\n      local::sparse::pack_setvec internal_rev_jac;\n      internal_rev_jac.resize(num_var_tape_, 1);\n      for(size_t i = 0; i < m; i++) if( select_range[i] )\n      {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );\n         // Not using post_element because only adding one element per set\n         internal_rev_jac.add_element( dep_taddr_[i] , 0 );\n      }\n      // reverse Jacobian sparsity for all variables on tape\n      local::sweep::rev_jac(\n         &play_,\n         dependency,\n         n,\n         num_var_tape_,\n         internal_rev_jac,\n         not_used_rec_base\n      );\n      // internal vector of sets that will hold Hessian\n      local::sparse::pack_setvec internal_for_hes;\n      internal_for_hes.resize(n + 1 + num_var_tape_, n + 1);\n      //\n      // compute forward Hessian sparsity pattern\n      local::sweep::for_hes(\n         &play_,\n         n,\n         num_var_tape_,\n         select_domain_pod_vector,\n         internal_rev_jac,\n         internal_for_hes,\n         not_used_rec_base\n      );\n      //\n      // put the result in pattern_tmp\n      local::sparse::get_internal_pattern(\n         transpose, ind_taddr_, internal_for_hes, pattern_tmp\n      );\n   }\n   else\n   {\n      // reverse Jacobian sparsity pattern for select_range\n      // (corresponds to s)\n      local::sparse::list_setvec internal_rev_jac;\n      internal_rev_jac.resize(num_var_tape_, 1);\n      for(size_t i = 0; i < m; i++) if( select_range[i] )\n      {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );\n         // Not using post_element because only adding one element per set\n         internal_rev_jac.add_element( dep_taddr_[i] , 0 );\n      }\n      // reverse Jacobian sparsity for all variables on tape\n      local::sweep::rev_jac(\n         &play_,\n         dependency,\n         n,\n         num_var_tape_,\n         internal_rev_jac,\n         not_used_rec_base\n\n      );\n      // internal vector of sets that will hold Hessian\n      local::sparse::list_setvec internal_for_hes;\n      internal_for_hes.resize(n + 1 + num_var_tape_, n + 1);\n      //\n      // compute forward Hessian sparsity pattern\n      local::sweep::for_hes(\n         &play_,\n         n,\n         num_var_tape_,\n         select_domain_pod_vector,\n         internal_rev_jac,\n         internal_for_hes,\n         not_used_rec_base\n      );\n      //\n      // put the result in pattern_tmp\n      local::sparse::get_internal_pattern(\n         transpose, ind_taddr_, internal_for_hes, pattern_tmp\n      );\n   }\n   // subtract 1 from all column values\n   CPPAD_ASSERT_UNKNOWN( pattern_tmp.nr() == n );\n   CPPAD_ASSERT_UNKNOWN( pattern_tmp.nc() == n + 1 );\n   const SizeVector& row( pattern_tmp.row() );\n   const SizeVector& col( pattern_tmp.col() );\n   size_t nr   = n;\n   size_t nc   = n;\n   size_t nnz  = pattern_tmp.nnz();\n   pattern_out.resize(nr, nc, nnz);\n   for(size_t k = 0; k < nnz; k++)\n   {  CPPAD_ASSERT_UNKNOWN( 0 < col[k] );\n      pattern_out.set(k, row[k], col[k] - 1);\n   }\n   return;\n}\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/for_jac_sparsity.hpp",
    "content": "# ifndef CPPAD_CORE_FOR_JAC_SPARSITY_HPP\n# define CPPAD_CORE_FOR_JAC_SPARSITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin for_jac_sparsity}\n\nForward Mode Jacobian Sparsity Patterns\n#######################################\n\nSyntax\n******\n| *f* . ``for_jac_sparsity`` (\n| |tab| *pattern_in* , *transpose* , *dependency* , *internal_bool* , *pattern_out*\n| )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to\nthe operation sequence stored in *f* .\nFix :math:`R \\in \\B{R}^{n \\times \\ell}` and define the function\n\n.. math::\n\n   J(x) = F^{(1)} ( x ) * R\n\nGiven the :ref:`glossary@Sparsity Pattern` for :math:`R`,\n``for_jac_sparsity`` computes a sparsity pattern for :math:`J(x)`.\n\nx\n*\nNote that the sparsity pattern :math:`J(x)` corresponds to the\noperation sequence stored in *f* and does not depend on\nthe argument *x* .\n(The operation sequence may contain\n:ref:`CondExp-name` and  :ref:`VecAD-name` operations.)\n\nSizeVector\n**********\nThe type *SizeVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``size_t`` .\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nThe :ref:`ADFun-name` object *f* is not ``const`` .\nAfter a call to ``for_jac_sparsity`` , a sparsity pattern\nfor each of the variables in the operation sequence\nis held in *f* for possible later use during\nreverse Hessian sparsity calculations.\n\nsize_forward_bool\n=================\nAfter ``for_jac_sparsity`` , if *k* is a ``size_t`` object,\n\n   *k* = *f* . ``size_forward_bool`` ()\n\nsets *k* to the amount of memory (in unsigned character units)\nused to store the\n:ref:`glossary@Sparsity Pattern@Boolean Vector`\nsparsity patterns.\nIf *internal_bool* if false, *k* will be zero.\nOtherwise it will be non-zero.\nIf you do not need this information for :ref:`RevSparseHes-name`\ncalculations, it can be deleted\n(and the corresponding memory freed) using\n\n   *f* . ``size_forward_bool`` (0)\n\nafter which *f* . ``size_forward_bool`` () will return zero.\n\nsize_forward_set\n================\nAfter ``for_jac_sparsity`` , if *k* is a ``size_t`` object,\n\n   *k* = *f* . ``size_forward_set`` ()\n\nsets *k* to the amount of memory (in unsigned character units)\nused to store the\n:ref:`glossary@Sparsity Pattern@Vector of Sets`\nsparsity patterns.\nIf *internal_bool* if true, *k* will be zero.\nOtherwise it will be non-zero.\nIf you do not need this information for future :ref:`rev_hes_sparsity-name`\ncalculations, it can be deleted\n(and the corresponding memory freed) using\n\n   *f* . ``size_forward_set`` (0)\n\nafter which *f* . ``size_forward_set`` () will return zero.\n\npattern_in\n**********\nThe argument *pattern_in* has prototype\n\n   ``const sparse_rc`` < *SizeVector* >& *pattern_in*\n\nsee :ref:`sparse_rc-name` .\nIf *transpose* it is false (true),\n*pattern_in* is a sparsity pattern for :math:`R` (:math:`R^\\R{T}`).\n\ntranspose\n*********\nThis argument has prototype\n\n   ``bool`` *transpose*\n\nSee :ref:`for_jac_sparsity@pattern_in` above and\n:ref:`for_jac_sparsity@pattern_out` below.\n\ndependency\n**********\nThis argument has prototype\n\n   ``bool`` *dependency*\n\nsee :ref:`for_jac_sparsity@pattern_out` below.\n\ninternal_bool\n*************\nThis argument has prototype\n\n   ``bool`` *internal_bool*\n\nIf this is true, calculations are done with sets represented by a vector\nof boolean values. Otherwise, a vector of sets of integers is used.\n\npattern_out\n***********\nThis argument has prototype\n\n   ``sparse_rc`` < *SizeVector* >& *pattern_out*\n\nThis input value of *pattern_out* does not matter.\nIf *transpose* it is false (true),\nupon return *pattern_out* is a sparsity pattern for\n:math:`J(x)` (:math:`J(x)^\\R{T}`).\nIf *dependency* is true, *pattern_out* is a\n:ref:`dependency.cpp@Dependency Pattern`\ninstead of sparsity pattern.\n\nSparsity for Entire Jacobian\n****************************\nSuppose that\n:math:`R` is the :math:`n \\times n` identity matrix.\nIn this case, *pattern_out* is a sparsity pattern for\n:math:`F^{(1)} ( x )`  ( :math:`F^{(1)} (x)^\\R{T}` )\nif *transpose* is false (true).\n\nExample\n*******\n{xrst_toc_hidden\n   example/sparse/for_jac_sparsity.cpp\n}\nThe file\n:ref:`for_jac_sparsity.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end for_jac_sparsity}\n-----------------------------------------------------------------------------\n*/\n# include <cppad/core/ad_fun.hpp>\n# include <cppad/local/sparse/internal.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*!\nForward Jacobian sparsity patterns.\n\n\\tparam Base\nis the base type for this recording.\n\n\\tparam SizeVector\nis the simple vector with elements of type size_t that is used for\nrow, column index sparsity patterns.\n\n\\param pattern_in\nis the sparsity pattern for for R or R^T depending on transpose.\n\n\\param transpose\nIs the input and returned sparsity pattern transposed.\n\n\\param dependency\nAre the derivatives with respect to left and right of the expression below\nconsidered to be non-zero:\n\\code\n   CondExpRel(left, right, if_true, if_false)\n\\endcode\nThis is used by the optimizer to obtain the correct dependency relations.\n\n\\param internal_bool\nIf this is true, calculations are done with sets represented by a vector\nof boolean values. Otherwise, a vector of standard sets is used.\n\n\\param pattern_out\nThe value of transpose is false (true),\nthe return value is a sparsity pattern for J(x) ( J(x)^T ) where\n\\f[\n   J(x) = F^{(1)} (x) * R\n\\f]\nHere F is the function corresponding to the operation sequence\nand x is any argument value.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class SizeVector>\nvoid ADFun<Base,RecBase>::for_jac_sparsity(\n   const sparse_rc<SizeVector>& pattern_in       ,\n   bool                         transpose        ,\n   bool                         dependency       ,\n   bool                         internal_bool    ,\n   sparse_rc<SizeVector>&       pattern_out      )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   // number or rows, columns, and non-zeros in pattern_in\n   size_t nr_in  = pattern_in.nr();\n   size_t nc_in  = pattern_in.nc();\n   //\n   size_t n   = nr_in;\n   size_t ell = nc_in;\n   if( transpose )\n      std::swap(n, ell);\n   //\n   CPPAD_ASSERT_KNOWN(\n      n == Domain() ,\n      \"for_jac_sparsity: number rows in R \"\n      \"is not equal number of independent variables.\"\n   );\n   bool zero_empty  = true;\n   bool input_empty = true;\n   if( internal_bool )\n   {  // allocate memory for bool sparsity calculation\n      // (sparsity pattern is empty after a resize)\n      for_jac_sparse_pack_.resize(num_var_tape_, ell);\n      for_jac_sparse_set_.resize(0, 0);\n      //\n      // set sparsity pattern for independent variables\n      local::sparse::set_internal_pattern(\n         zero_empty            ,\n         input_empty           ,\n         transpose             ,\n         ind_taddr_            ,\n         for_jac_sparse_pack_  ,\n         pattern_in\n      );\n\n      // compute sparsity for other variables\n      local::sweep::for_jac(\n         &play_,\n         dependency,\n         n,\n         num_var_tape_,\n         for_jac_sparse_pack_,\n         not_used_rec_base\n\n      );\n      // set the output pattern\n      local::sparse::get_internal_pattern(\n         transpose, dep_taddr_, for_jac_sparse_pack_, pattern_out\n      );\n   }\n   else\n   {\n      // allocate memory for set sparsity calculation\n      // (sparsity pattern is empty after a resize)\n      for_jac_sparse_set_.resize(num_var_tape_, ell);\n      for_jac_sparse_pack_.resize(0, 0);\n      //\n      // set sparsity pattern for independent variables\n      local::sparse::set_internal_pattern(\n         zero_empty            ,\n         input_empty           ,\n         transpose             ,\n         ind_taddr_            ,\n         for_jac_sparse_set_   ,\n         pattern_in\n      );\n\n      // compute sparsity for other variables\n      local::sweep::for_jac(\n         &play_,\n         dependency,\n         n,\n         num_var_tape_,\n         for_jac_sparse_set_,\n         not_used_rec_base\n\n      );\n      // get the output pattern\n      local::sparse::get_internal_pattern(\n         transpose, dep_taddr_, for_jac_sparse_set_, pattern_out\n      );\n   }\n   return;\n}\n\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/for_one.hpp",
    "content": "# ifndef CPPAD_CORE_FOR_ONE_HPP\n# define CPPAD_CORE_FOR_ONE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin ForOne}\n\nFirst Order Partial Derivative: Driver Routine\n##############################################\n\nSyntax\n******\n| *dy* = *f* . ``ForOne`` ( *x* , *j* )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to *f* .\nThe syntax above sets *dy* to the\npartial of :math:`F` with respect to :math:`x_j`; i.e.,\n\n.. math::\n\n   dy\n   = \\D{F}{ x_j } (x)\n   = \\left[\n      \\D{ F_0 }{ x_j } (x) , \\cdots , \\D{ F_{m-1} }{ x_j } (x)\n   \\right]\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nNote that the :ref:`ADFun-name` object *f* is not ``const``\n(see :ref:`ForOne@ForOne Uses Forward` below).\n\nx\n*\nThe argument *x* has prototype\n\n   ``const`` *Vector* & *x*\n\n(see :ref:`ForOne@Vector` below)\nand its size\nmust be equal to *n* , the dimension of the\n:ref:`fun_property@Domain` space for *f* .\nIt specifies\nthat point at which to evaluate the partial derivative.\n\nj\n*\nThe argument *j* has prototype\n\n   ``size_t`` *j*\n\nan is less than *n* ,\n:ref:`fun_property@Domain` space for *f* .\nIt specifies the component of *F*\nfor which we are computing the partial derivative.\n\ndy\n**\nThe result *dy* has prototype\n\n   *Vector* *dy*\n\n(see :ref:`ForOne@Vector` below)\nand its size is :math:`m`, the dimension of the\n:ref:`fun_property@Range` space for *f* .\nThe value of *dy* is the partial of :math:`F` with respect to\n:math:`x_j` evaluated at *x* ; i.e.,\nfor :math:`i = 0 , \\ldots , m - 1`\n\n.. math::\n\n   dy[i] = \\D{ F_i }{ x_j } ( x )\n\nVector\n******\nThe type *Vector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n*Base* .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nForOne Uses Forward\n*******************\nAfter each call to :ref:`Forward-name` ,\nthe object *f* contains the corresponding\n:ref:`Taylor coefficients<glossary@Taylor Coefficient>` .\nAfter a call to ``ForOne`` ,\nthe zero order Taylor coefficients correspond to\n*f* . ``Forward`` (0, *x* )\nand the other coefficients are unspecified.\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/for_one.cpp\n}\nThe routine\n:ref:`ForOne<for_one.cpp-name>` is both an example and test.\nIt returns ``true`` , if it succeeds and ``false`` otherwise.\n\n{xrst_end ForOne}\n-----------------------------------------------------------------------------\n*/\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base, class RecBase>\ntemplate <class Vector>\nVector ADFun<Base,RecBase>::ForOne(const Vector &x, size_t j)\n{  size_t j1;\n\n   size_t n = Domain();\n   size_t m = Range();\n\n   // check Vector is Simple Vector class with Base type elements\n   CheckSimpleVector<Base, Vector>();\n\n   CPPAD_ASSERT_KNOWN(\n      x.size() == n,\n      \"ForOne: Length of x not equal domain dimension for f\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      j < n,\n      \"ForOne: the index j is not less than domain dimension for f\"\n   );\n\n   // point at which we are evaluating the second partials\n   Forward(0, x);\n\n   // direction in which are are taking the derivative\n   Vector dx(n);\n   for(j1 = 0; j1 < n; j1++)\n      dx[j1] = Base(0.0);\n   dx[j] = Base(1.0);\n\n   // dimension the return value\n   Vector dy(m);\n\n   // compute the return value\n   dy = Forward(1, dx);\n\n   return dy;\n}\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/for_sparse_hes.hpp",
    "content": "# ifndef CPPAD_CORE_FOR_SPARSE_HES_HPP\n# define CPPAD_CORE_FOR_SPARSE_HES_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin ForSparseHes}\n{xrst_spell\n   walther\n}\n\nHessian Sparsity Pattern: Forward Mode\n######################################\n\nSyntax\n******\n| *h* = *f* . ``ForSparseHes`` ( *r* , *s* )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to *f* .\nwe define\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   H(x)\n   & = & \\partial_x \\left[ \\partial_u S \\cdot F[ x + R \\cdot u ] \\right]_{u=0}\n   \\\\\n   & = & R^\\R{T} \\cdot (S \\cdot F)^{(2)} ( x ) \\cdot R\n   \\end{eqnarray}\n\nWhere :math:`R \\in \\B{R}^{n \\times n}` is a diagonal matrix\nand :math:`S \\in \\B{R}^{1 \\times m}` is a row vector.\nGiven a\n:ref:`glossary@Sparsity Pattern`\nfor the diagonal of :math:`R` and the vector :math:`S`,\n``ForSparseHes`` returns a sparsity pattern for the :math:`H(x)`.\n\nf\n*\nThe object *f* has prototype\n\n   ``const ADFun`` < *Base* > *f*\n\nx\n*\nIf the operation sequence in *f* is\n:ref:`glossary@Operation@Independent` of\nthe independent variables in :math:`x \\in \\B{R}^n`,\nthe sparsity pattern is valid for all values of\n(even if it has :ref:`CondExp-name` or :ref:`VecAD-name` operations).\n\nr\n*\nThe argument *r* has prototype\n\n   ``const`` *SetVector* & *r*\n\n(see :ref:`ForSparseHes@SetVector` below)\nIf it has elements of type ``bool`` ,\nits size is :math:`n`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is one and all the elements of *s* [0]\nare between zero and :math:`n - 1`.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the diagonal of :math:`R`.\nThe fewer non-zero elements in this sparsity pattern,\nthe faster the calculation should be and the more sparse\n:math:`H(x)` should be.\n\ns\n*\nThe argument *s* has prototype\n\n   ``const`` *SetVector* & *s*\n\n(see :ref:`ForSparseHes@SetVector` below)\nIf it has elements of type ``bool`` ,\nits size is :math:`m`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is one and all the elements of *s* [0]\nare between zero and :math:`m - 1`.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the vector *S* .\nThe fewer non-zero elements in this sparsity pattern,\nthe faster the calculation should be and the more sparse\n:math:`H(x)` should be.\n\nh\n*\nThe result *h* has prototype\n\n   *SetVector* & *h*\n\n(see :ref:`ForSparseHes@SetVector` below).\nIf *h* has elements of type ``bool`` ,\nits size is :math:`n * n`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is :math:`n` and all the set elements are between\nzero and *n* ``-1`` inclusive.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the matrix :math:`H(x)`.\n\nSetVector\n*********\nThe type *SetVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``bool`` or ``std::set<size_t>`` ;\nsee :ref:`glossary@Sparsity Pattern` for a discussion\nof the difference.\nThe type of the elements of\n:ref:`ForSparseHes@SetVector` must be the\nsame as the type of the elements of *r* .\n\nAlgorithm\n*********\nSee Algorithm II in\n*Computing sparse Hessians with automatic differentiation*\nby Andrea Walther.\nNote that *s* provides the information so that\n'dead ends' are not included in the sparsity pattern.\n\nExample\n*******\n{xrst_toc_hidden\n   example/sparse/for_sparse_hes.cpp\n}\nThe file\n:ref:`for_sparse_hes.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end ForSparseHes}\n-----------------------------------------------------------------------------\n*/\n# include <algorithm>\n# include <cppad/local/pod_vector.hpp>\n# include <cppad/local/std_set.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file core/for_sparse_hes.hpp\nForward mode Hessian sparsity patterns.\n*/\n// ===========================================================================\n// ForSparseHesCase\n/*!\nPrivate helper function for ForSparseHes(q, s) bool sparsity.\n\nAll of the description in the public member function ForSparseHes(q, s)\napplies.\n\n\\param set_type\nis a bool value. This argument is used to dispatch to the proper source\ncode depending on the value of SetVector::value_type.\n\n\\param r\nSee ForSparseHes(r, s).\n\n\\param s\nSee ForSparseHes(r, s).\n\n\\param h\nis the return value for the corresponding call to ForSparseJac(q, s).\n*/\ntemplate <class Base, class RecBase>\ntemplate <class SetVector>\nvoid ADFun<Base,RecBase>::ForSparseHesCase(\n   bool              set_type         ,\n   const SetVector&  r                ,\n   const SetVector&  s                ,\n   SetVector&        h                )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   size_t n = Domain();\n   size_t m = Range();\n   //\n   // check Vector is Simple SetVector class with bool elements\n   CheckSimpleVector<bool, SetVector>();\n   //\n   CPPAD_ASSERT_KNOWN(\n      size_t(r.size()) == n,\n      \"ForSparseHes: size of r is not equal to\\n\"\n      \"domain dimension for ADFun object.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(s.size()) == m,\n      \"ForSparseHes: size of s is not equal to\\n\"\n      \"range dimension for ADFun object.\"\n   );\n   //\n   // select_domain corresponding to r\n   local::pod_vector<bool> select_domain(n);\n   for(size_t j = 0; j < n; ++j)\n   {  select_domain[j] = r[j];\n      CPPAD_ASSERT_UNKNOWN( ind_taddr_[j]  == j + 1);\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp(j + 1) == local::InvOp );\n   }\n   // sparsity pattern corresponding to s\n   local::sparse::pack_setvec rev_jac_pattern;\n   rev_jac_pattern.resize(num_var_tape_, 1);\n   for(size_t i = 0; i < m; i++)\n   {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );\n      //\n      // Not using post_element because only adding one element per set\n      if( s[i] )\n         rev_jac_pattern.add_element( dep_taddr_[i], 0);\n   }\n   // compute reverse sparsity pattern for dependency analysis\n   // (note that we are only want non-zero derivatives not true dependency)\n   bool dependency = false;\n   local::sweep::rev_jac(\n      &play_,\n      dependency,\n      n,\n      num_var_tape_,\n      rev_jac_pattern,\n      not_used_rec_base\n   );\n   // vector of sets that will hold the forward Hessain values\n   local::sparse::pack_setvec for_hes_pattern;\n   for_hes_pattern.resize(n+1+num_var_tape_, n+1);\n   //\n   // compute the Hessian sparsity patterns\n   local::sweep::for_hes(\n      &play_,\n      n,\n      num_var_tape_,\n      select_domain,\n      rev_jac_pattern,\n      for_hes_pattern,\n      not_used_rec_base\n\n   );\n   // initialize return values corresponding to independent variables\n   h.resize(n * n);\n   for(size_t i = 0; i < n; i++)\n   {  for(size_t j = 0; j < n; j++)\n         h[ i * n + j ] = false;\n   }\n   // copy to result pattern\n   CPPAD_ASSERT_UNKNOWN( for_hes_pattern.end() == n+1 );\n   for(size_t i = 0; i < n; i++)\n   {  // ind_taddr_[i] is operator taddr for i-th independent variable\n      CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] == i + 1 );\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );\n\n      // extract the result from for_hes_pattern\n      local::sparse::pack_setvec::const_iterator itr(for_hes_pattern, ind_taddr_[i] );\n      size_t j = *itr;\n      while( j < for_hes_pattern.end() )\n      {  CPPAD_ASSERT_UNKNOWN( 0 < j )\n         h[ i * n + (j-1) ] = true;\n         j = *(++itr);\n      }\n   }\n}\n/*!\nPrivate helper function for ForSparseHes(q, s) set sparsity.\n\nAll of the description in the public member function ForSparseHes(q, s)\napplies.\n\n\\param set_type\nis a std::set<size_t> value.\nThis argument is used to dispatch to the proper source\ncode depending on the value of SetVector::value_type.\n\n\\param r\nSee ForSparseHes(r, s).\n\n\\param s\nSee ForSparseHes(q, s).\n\n\\param h\nis the return value for the corresponding call to ForSparseJac(q, s).\n*/\ntemplate <class Base, class RecBase>\ntemplate <class SetVector>\nvoid ADFun<Base,RecBase>::ForSparseHesCase(\n   const std::set<size_t>&   set_type         ,\n   const SetVector&          r                ,\n   const SetVector&          s                ,\n   SetVector&                h                )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   size_t n = Domain();\n# ifndef NDEBUG\n   size_t m = Range();\n# endif\n   std::set<size_t>::const_iterator itr_1;\n   //\n   // check SetVector is Simple Vector class with sets for elements\n   CheckSimpleVector<std::set<size_t>, SetVector>(\n      local::one_element_std_set<size_t>(), local::two_element_std_set<size_t>()\n   );\n   CPPAD_ASSERT_KNOWN(\n      r.size() == 1,\n      \"ForSparseHes: size of s is not equal to one.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      s.size() == 1,\n      \"ForSparseHes: size of s is not equal to one.\"\n   );\n   //\n   // select_domain corresponding to r\n   local::pod_vector<bool> select_domain(n);\n   for(size_t j = 0; j < n; ++j)\n   {  select_domain[j] = false;\n      CPPAD_ASSERT_UNKNOWN( ind_taddr_[j]  == j + 1);\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp(j + 1) == local::InvOp );\n   }\n   itr_1 = r[0].begin();\n   while( itr_1 != r[0].end() )\n   {  size_t j = *itr_1++;\n      select_domain[j] = true;\n   }\n   // sparsity pattern corresponding to s\n   local::sparse::list_setvec rev_jac_pattern;\n   rev_jac_pattern.resize(num_var_tape_, 1);\n   itr_1 = s[0].begin();\n   while( itr_1 != s[0].end() )\n   {  size_t i = *itr_1++;\n      CPPAD_ASSERT_KNOWN(\n         i < m,\n         \"ForSparseHes: an element of the set s[0] has value \"\n         \"greater than or equal m\"\n      );\n      CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );\n      //\n      // Not using post_element because only adding one element per set\n      rev_jac_pattern.add_element( dep_taddr_[i], 0);\n   }\n   //\n   // compute reverse sparsity pattern for dependency analysis\n   // (note that we are only want non-zero derivatives not true dependency)\n   bool dependency = false;\n   local::sweep::rev_jac(\n      &play_,\n      dependency,\n      n,\n      num_var_tape_,\n      rev_jac_pattern,\n      not_used_rec_base\n   );\n   //\n   // vector of sets that will hold reverse Hessain values\n   local::sparse::list_setvec for_hes_pattern;\n   for_hes_pattern.resize(n+1+num_var_tape_, n+1);\n   //\n   // compute the Hessian sparsity patterns\n   local::sweep::for_hes(\n      &play_,\n      n,\n      num_var_tape_,\n      select_domain,\n      rev_jac_pattern,\n      for_hes_pattern,\n      not_used_rec_base\n\n   );\n   // return values corresponding to independent variables\n   // j is index corresponding to reverse mode partial\n   h.resize(n);\n   CPPAD_ASSERT_UNKNOWN( for_hes_pattern.end() == n+1 );\n   for(size_t i = 0; i < n; i++)\n   {  CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] == i + 1 );\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );\n\n      // extract the result from for_hes_pattern\n      local::sparse::list_setvec::const_iterator itr_2(for_hes_pattern, ind_taddr_[i] );\n      size_t j = *itr_2;\n      while( j < for_hes_pattern.end() )\n      {  CPPAD_ASSERT_UNKNOWN( 0 < j )\n            h[i].insert(j-1);\n         j = *(++itr_2);\n      }\n   }\n}\n\n// ===========================================================================\n// ForSparseHes\n\n/*!\nUser API for Hessian sparsity patterns using reverse mode.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   h = f.ForSparseHes(q, r)\n\\endverbatim\n\n\\tparam Base\nis the base type for this recording.\n\n\\tparam SetVector\nis a simple vector with elements of type bool\nor std::set<size_t>.\n\n\\param r\nis a vector with size n that specifies the sparsity pattern\nfor the diagonal of the matrix \\f$ R \\f$,\nwhere n is the number of independent variables\ncorresponding to the operation sequence stored in play.\n\n\\param s\nis a vector with size m that specifies the sparsity pattern\nfor the vector \\f$ S \\f$,\nwhere m is the number of dependent variables\ncorresponding to the operation sequence stored in play.\n\n\\return\nThe return vector is a sparsity pattern for \\f$ H(x) \\f$\n\\f[\n   H(x) = R^T ( S * F)^{(2)} (x) R\n\\f]\nwhere \\f$ F \\f$ is the function corresponding to the operation sequence\nand x is any argument value.\n*/\n\ntemplate <class Base, class RecBase>\ntemplate <class SetVector>\nSetVector ADFun<Base,RecBase>::ForSparseHes(\n   const SetVector& r, const SetVector& s\n)\n{\n   SetVector h;\n   typedef typename SetVector::value_type Set_type;\n\n   // Should check to make sure q is same as in previous call to\n   // forward sparse Jacobian.\n   ForSparseHesCase(\n      Set_type()    ,\n      r             ,\n      s             ,\n      h\n   );\n\n   return h;\n}\n// ===========================================================================\n// ForSparseHesCheckpoint\n/*!\nHessian sparsity patterns calculation used by checkpoint functions.\n\n\\tparam Base\nis the base type for this recording.\n\n\\param r\nis a vector with size n that specifies the sparsity pattern\nfor the diagonal of \\f$ R \\f$,\nwhere n is the number of independent variables\ncorresponding to the operation sequence stored in play_.\n\n\\param s\nis a vector with size m that specifies the sparsity pattern\nfor the vector \\f$ S \\f$,\nwhere m is the number of dependent variables\ncorresponding to the operation sequence stored in play_.\n\n\\param h\nThe input size and elements of h do not matter.\nOn output, h is the sparsity pattern for the matrix \\f$ H(x) R \\f$.\n\n\\par Assumptions\nThe forward jacobian sparsity pattern must be currently stored\nin this ADFUN object.\n*/\n\n// The checkpoint class is not yet using forward sparse Hessians.\n# ifdef CPPAD_NOT_DEFINED\ntemplate <class Base, class RecBase>\nvoid ADFun<Base,RecBase>::ForSparseHesCheckpoint(\n   vector<bool>&                 r         ,\n   vector<bool>&                 s         ,\n   local::sparse::list_setvec&   h         )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n\n   size_t n = Domain();\n   size_t m = Range();\n\n   // checkpoint functions should get this right\n   CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.n_set() == 0 );\n   CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.n_set() == 0   );\n   CPPAD_ASSERT_UNKNOWN( s.size()                    == m );\n\n   // Array that holds the reverse Jacobiain dependency flags.\n   // Initialize as true for dependent variables, false for others.\n   local::pod_vector<bool> RevJac(num_var_tape_);\n   for(size_t i = 0; i < num_var_tape_; i++)\n      RevJac[i] = false;\n   for(size_t i = 0; i < m; i++)\n   {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ )\n      RevJac[ dep_taddr_[i] ] = s[i];\n   }\n\n   // holds forward Hessian sparsity pattern for all variables\n   local::sparse::list_setvec for_hes_pattern;\n   for_hes_pattern.resize(n+1+num_var_tape_, n+1);\n\n   // compute Hessian sparsity pattern for all variables\n   local::sweep::for_hes(\n      &play_,\n      n,\n      num_var_tape_,\n      for_jac_sparse_set_,\n      RevJac.data(),\n      for_hes_pattern,\n      not_used_rec_base\n\n   );\n\n   // dimension the return value\n   if( transpose )\n      h.resize(n, n);\n   else\n      h.resize(n, n);\n\n   // j is index corresponding to reverse mode partial\n   for(size_t j = 0; j < n; j++)\n   {  CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ );\n\n      // ind_taddr_[j] is operator taddr for j-th independent variable\n      CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j + 1 );\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );\n\n      // extract the result from for_hes_pattern\n      CPPAD_ASSERT_UNKNOWN( for_hes_pattern.end() == q );\n      local::sparse::list_setvec::const_iterator itr(for_hes_pattern, .j + 1);\n      size_t i = *itr;\n      while( i < q )\n      {  if( transpose )\n            h.post_element(j,  i);\n         else\n            h.post_element(i, j);\n         i = *(++itr);\n      }\n   }\n   // process posts\n   for(size_t i = 0; i < n; ++i)\n      h.process_post(i);\n}\n# endif\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/for_sparse_jac.hpp",
    "content": "# ifndef CPPAD_CORE_FOR_SPARSE_JAC_HPP\n# define CPPAD_CORE_FOR_SPARSE_JAC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin ForSparseJac}\n\nJacobian Sparsity Pattern: Forward Mode\n#######################################\n\nSyntax\n******\n| *s* = *f* . ``ForSparseJac`` ( *q* , *r* )\n| *s* = *f* . ``ForSparseJac`` ( *q* , *r* , *transpose* , *dependency* )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to *f* .\nFor a fixed :math:`n \\times q` matrix :math:`R`,\nthe Jacobian of :math:`F[ x + R * u ]`\nwith respect to :math:`u` at :math:`u = 0` is\n\n.. math::\n\n   S(x) = F^{(1)} ( x ) * R\n\nGiven a\n:ref:`glossary@Sparsity Pattern`\nfor :math:`R`,\n``ForSparseJac`` returns a sparsity pattern for the :math:`S(x)`.\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nNote that the :ref:`ADFun-name` object *f* is not ``const`` .\nAfter a call to ``ForSparseJac`` , the sparsity pattern\nfor each of the variables in the operation sequence\nis held in *f* (for possible later use by :ref:`RevSparseHes-name` ).\nThese sparsity patterns are stored with elements of type ``bool``\nor elements of type ``std::set<size_t>``\n(see :ref:`ForSparseJac@SetVector` below).\n\nsize_forward_bool\n=================\nAfter ``ForSparseJac`` , if *k* is a ``size_t`` object,\n\n   *k* = *f* . ``size_forward_bool`` ()\n\nsets *k* to the amount of memory (in unsigned character units)\nused to store the sparsity pattern with elements of type ``bool``\nin the function object *f* .\nIf the sparsity patterns for the previous ``ForSparseJac`` used\nelements of type ``bool`` ,\nthe return value for ``size_forward_bool`` will be non-zero.\nOtherwise, its return value will be zero.\nThis sparsity pattern is stored for use by :ref:`RevSparseHes-name` and\nwhen it is not longer needed, it can be deleted\n(and the corresponding memory freed) using\n\n   *f* . ``size_forward_bool`` (0)\n\nAfter this call, *f* . ``size_forward_bool`` () will return zero.\n\nsize_forward_set\n================\nAfter ``ForSparseJac`` , if *k* is a ``size_t`` object,\n\n   *k* = *f* . ``size_forward_set`` ()\n\nsets *k* to the amount of memory (in unsigned character units)\nused to store the\n:ref:`glossary@Sparsity Pattern@Vector of Sets`\nsparsity patterns.\nIf the sparsity patterns for this operation use elements of type ``bool`` ,\nthe return value for ``size_forward_set`` will be zero.\nOtherwise, its return value will be non-zero.\nThis sparsity pattern is stored for use by :ref:`RevSparseHes-name` and\nwhen it is not longer needed, it can be deleted\n(and the corresponding memory freed) using\n\n   *f* . ``size_forward_set`` (0)\n\nAfter this call, *f* . ``size_forward_set`` () will return zero.\n\nx\n*\nIf the operation sequence in *f* is\n:ref:`glossary@Operation@Independent` of\nthe independent variables in :math:`x \\in \\B{R}^n`,\nthe sparsity pattern is valid for all values of\n(even if it has :ref:`CondExp-name` or :ref:`VecAD-name` operations).\n\nq\n*\nThe argument *q* has prototype\n\n   ``size_t`` *q*\n\nIt specifies the number of columns in\n:math:`R \\in \\B{R}^{n \\times q}` and the Jacobian\n:math:`S(x) \\in \\B{R}^{m \\times q}`.\n\ntranspose\n*********\nThe argument *transpose* has prototype\n\n   ``bool`` *transpose*\n\nThe default value ``false`` is used when *transpose* is not present.\n\ndependency\n**********\nThe argument *dependency* has prototype\n\n   ``bool`` *dependency*\n\nIf *dependency* is true,\nthe :ref:`dependency.cpp@Dependency Pattern`\n(instead of sparsity pattern) is computed.\n\nr\n*\nThe argument *r* has prototype\n\n   ``const`` *SetVector* & *r*\n\nsee :ref:`ForSparseJac@SetVector` below.\n\ntranspose false\n===============\nIf *r* has elements of type ``bool`` ,\nits size is :math:`n * q`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is :math:`n` and all the set elements must be between\nzero and *q* ``-1`` inclusive.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the matrix :math:`R \\in \\B{R}^{n \\times q}`.\n\ntranspose true\n==============\nIf *r* has elements of type ``bool`` ,\nits size is :math:`q * n`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is :math:`q` and all the set elements must be between\nzero and *n* ``-1`` inclusive.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the matrix :math:`R^\\R{T} \\in \\B{R}^{q \\times n}`.\n\ns\n*\nThe return value *s* has prototype\n\n   *SetVector* *s*\n\nsee :ref:`ForSparseJac@SetVector` below.\n\ntranspose false\n===============\nIf *s* has elements of type ``bool`` ,\nits size is :math:`m * q`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is :math:`m` and all its set elements are between\nzero and *q* ``-1`` inclusive.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the matrix :math:`S(x) \\in \\B{R}^{m \\times q}`.\n\ntranspose true\n==============\nIf *s* has elements of type ``bool`` ,\nits size is :math:`q * m`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is :math:`q` and all its set elements are between\nzero and *m* ``-1`` inclusive.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the matrix :math:`S(x)^\\R{T} \\in \\B{R}^{q \\times m}`.\n\nSetVector\n*********\nThe type *SetVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``bool`` or ``std::set<size_t>`` ;\nsee :ref:`glossary@Sparsity Pattern` for a discussion\nof the difference.\n\nEntire Sparsity Pattern\n***********************\nSuppose that :math:`q = n` and\n:math:`R` is the :math:`n \\times n` identity matrix.\nIn this case,\nthe corresponding value for *s* is a\nsparsity pattern for the Jacobian :math:`S(x) = F^{(1)} ( x )`.\n\nExample\n*******\n{xrst_toc_hidden\n   example/sparse/for_sparse_jac.cpp\n}\nThe file\n:ref:`for_sparse_jac.cpp-name`\ncontains an example and test of this operation.\nThe file\n:ref:`sparsity_sub.cpp<sparsity_sub.cpp@ForSparseJac>`\ncontains an example and test of using ``ForSparseJac``\nto compute the sparsity pattern for a subset of the Jacobian.\n\n{xrst_end ForSparseJac}\n-----------------------------------------------------------------------------\n*/\n\n# include <cppad/local/std_set.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file core/for_sparse_jac.hpp\nForward mode Jacobian sparsity patterns.\n*/\n// ---------------------------------------------------------------------------\n/*!\nPrivate helper function for ForSparseJac(q, r) boolean sparsity patterns.\n\nAll of the description in the public member function ForSparseJac(q, r)\napplies.\n\n\\param set_type\nis a bool value. This argument is used to dispatch to the proper source\ncode depending on the value of SetVector::value_type.\n\n\\param transpose\nSee ForSparseJac(q, r, transpose, dependency).\n\n\\param dependency\nSee ForSparseJac(q, r, transpose, dependency).\n\n\\param q\nSee ForSparseJac(q, r, transpose, dependency).\n\n\\param r\nSee ForSparseJac(q, r, transpose, dependency).\n\n\\param s\nis the return value for the corresponding call to ForSparseJac(q, r).\n*/\n\ntemplate <class Base, class RecBase>\ntemplate <class SetVector>\nvoid ADFun<Base,RecBase>::ForSparseJacCase(\n   bool                set_type      ,\n   bool                transpose     ,\n   bool                dependency    ,\n   size_t              q             ,\n   const SetVector&    r             ,\n   SetVector&          s             )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   size_t m = Range();\n   size_t n = Domain();\n\n   // check SetVector is Simple Vector class with bool elements\n   CheckSimpleVector<bool, SetVector>();\n\n   // dimension size of result vector\n   s.resize( m * q );\n\n   CPPAD_ASSERT_KNOWN(\n      q > 0,\n      \"ForSparseJac: q is not greater than zero\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(r.size()) == n * q,\n      \"ForSparseJac: size of r is not equal to\\n\"\n      \"q times domain dimension for ADFun object.\"\n   );\n   //\n   // allocate memory for the requested sparsity calculation result\n   for_jac_sparse_pack_.resize(num_var_tape_, q);\n\n   // set values corresponding to independent variables\n   for(size_t i = 0; i < n; i++)\n   {  CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] < num_var_tape_ );\n      // ind_taddr_[i] is operator taddr for i-th independent variable\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );\n\n      // set bits that are true\n      if( transpose )\n      {  for(size_t j = 0; j < q; j++) if( r[ j * n + i ] )\n            for_jac_sparse_pack_.post_element( ind_taddr_[i], j);\n      }\n      else\n      {  for(size_t j = 0; j < q; j++) if( r[ i * q + j ] )\n            for_jac_sparse_pack_.post_element( ind_taddr_[i], j);\n      }\n   }\n   // process posts\n   for(size_t j = 0; j < n; j++)\n      for_jac_sparse_pack_.process_post( ind_taddr_[j] );\n\n   // evaluate the sparsity patterns\n   local::sweep::for_jac(\n      &play_,\n      dependency,\n      n,\n      num_var_tape_,\n      for_jac_sparse_pack_,\n      not_used_rec_base\n\n   );\n\n   // return values corresponding to dependent variables\n   CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == m * q );\n   for(size_t i = 0; i < m; i++)\n   {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );\n\n      // extract the result from for_jac_sparse_pack_\n      if( transpose )\n      {  for(size_t j = 0; j < q; j++)\n            s[ j * m + i ] = false;\n      }\n      else\n      {  for(size_t j = 0; j < q; j++)\n            s[ i * q + j ] = false;\n      }\n      CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.end() == q );\n      local::sparse::pack_setvec::const_iterator\n         itr(for_jac_sparse_pack_, dep_taddr_[i] );\n      size_t j = *itr;\n      while( j < q )\n      {  if( transpose )\n            s[j * m + i] = true;\n         else\n            s[i * q + j] = true;\n         j = *(++itr);\n      }\n   }\n}\n// ---------------------------------------------------------------------------\n/*!\nPrivate helper function for ForSparseJac(q, r) set sparsity.\n\nAll of the description in the public member function ForSparseJac(q, r)\napplies.\n\n\\param set_type\nis a std::set<size_t> object.\nThis argument is used to dispatch to the proper source\ncode depending on the value of SetVector::value_type.\n\n\\param transpose\nSee ForSparseJac(q, r, transpose, dependency).\n\n\\param dependency\nSee ForSparseJac(q, r, transpose, dependency).\n\n\\param q\nSee ForSparseJac(q, r, transpose, dependency).\n\n\\param r\nSee ForSparseJac(q, r, transpose, dependency).\n\n\\param s\nis the return value for the corresponding call to ForSparseJac(q, r).\n*/\ntemplate <class Base, class RecBase>\ntemplate <class SetVector>\nvoid ADFun<Base,RecBase>::ForSparseJacCase(\n   const std::set<size_t>&    set_type      ,\n   bool                       transpose     ,\n   bool                       dependency    ,\n   size_t                     q             ,\n   const SetVector&           r             ,\n   SetVector&                 s             )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   size_t m = Range();\n   size_t n = Domain();\n\n   // check SetVector is Simple Vector class with sets for elements\n   CheckSimpleVector<std::set<size_t>, SetVector>(\n      local::one_element_std_set<size_t>(), local::two_element_std_set<size_t>()\n   );\n\n   // dimension size of result vector\n   if( transpose )\n      s.resize(q);\n   else\n      s.resize( m );\n\n   // temporary iterator\n   std::set<size_t>::const_iterator itr_1;\n\n   CPPAD_ASSERT_KNOWN(\n      q > 0,\n      \"ForSparseJac: q is not greater than zero\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(r.size()) == n || transpose,\n      \"ForSparseJac: size of r is not equal to n and transpose is false.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(r.size()) == q || ! transpose,\n      \"ForSparseJac: size of r is not equal to q and transpose is true.\"\n   );\n   //\n   // allocate memory for the requested sparsity calculation\n   for_jac_sparse_set_.resize(num_var_tape_, q);\n\n   // set values corresponding to independent variables\n   if( transpose )\n   {  for(size_t i = 0; i < q; i++)\n      {  // add the elements that are present\n         itr_1 = r[i].begin();\n         while( itr_1 != r[i].end() )\n         {  size_t j = *itr_1++;\n            CPPAD_ASSERT_KNOWN(\n            j < n,\n            \"ForSparseJac: transpose is true and element of the set\\n\"\n            \"r[j] has value greater than or equal n.\"\n            );\n            CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ );\n            // operator for j-th independent variable\n            CPPAD_ASSERT_UNKNOWN(\n               play_.GetOp( ind_taddr_[j] ) == local::InvOp\n            );\n            for_jac_sparse_set_.post_element( ind_taddr_[j], i);\n         }\n      }\n   }\n   else\n   {  for(size_t i = 0; i < n; i++)\n      {  CPPAD_ASSERT_UNKNOWN( ind_taddr_[i] < num_var_tape_ );\n         // ind_taddr_[i] is operator taddr for i-th independent variable\n         CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[i] ) == local::InvOp );\n\n         // add the elements that are present\n         itr_1 = r[i].begin();\n         while( itr_1 != r[i].end() )\n         {  size_t j = *itr_1++;\n            CPPAD_ASSERT_KNOWN(\n               j < q,\n               \"ForSparseJac: an element of the set r[i] \"\n               \"has value greater than or equal q.\"\n            );\n            for_jac_sparse_set_.post_element( ind_taddr_[i], j);\n         }\n      }\n   }\n   // process posts\n   for(size_t j = 0; j < n; j++)\n      for_jac_sparse_set_.process_post( ind_taddr_[j] );\n\n   // evaluate the sparsity patterns\n   local::sweep::for_jac(\n      &play_,\n      dependency,\n      n,\n      num_var_tape_,\n      for_jac_sparse_set_,\n      not_used_rec_base\n\n   );\n\n   // return values corresponding to dependent variables\n   CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == m || transpose );\n   CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == q || ! transpose );\n   for(size_t i = 0; i < m; i++)\n   {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );\n\n      // extract results from for_jac_sparse_set_\n      // and add corresponding elements to sets in s\n      CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.end() == q );\n      local::sparse::list_setvec::const_iterator\n         itr_2(for_jac_sparse_set_, dep_taddr_[i] );\n      size_t j = *itr_2;\n      while( j < q )\n      {  if( transpose )\n            s[j].insert(i);\n         else\n            s[i].insert(j);\n         j = *(++itr_2);\n      }\n   }\n}\n// ---------------------------------------------------------------------------\n\n/*!\nUser API for Jacobian sparsity patterns using forward mode.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   s = f.ForSparseJac(q, r, transpose, dependency)\n\\endverbatim\n\n\\tparam Base\nis the base type for this recording.\n\n\\tparam SetVector\nis a simple vector with elements of type bool\nor std::set<size_t>.\n\n\\param q\nis the number of columns in the matrix \\f$ R \\f$.\n\n\\param r\nis a sparsity pattern for the matrix \\f$ R \\f$.\n\n\\param transpose\nare sparsity patterns for \\f$ R \\f$ and \\f$ S(x) \\f$ transposed.\n\n\\param dependency\nAre the derivatives with respect to left and right of the expression below\nconsidered to be non-zero:\n\\code\n   CondExpRel(left, right, if_true, if_false)\n\\endcode\nThis is used by the optimizer to obtain the correct dependency relations.\n\n\\return\nThe value of transpose is false (true),\nthe return value is a sparsity pattern for \\f$ S(x) \\f$ (\\f$ S(x)^T \\f$) where\n\\f[\n   S(x) = F^{(1)} (x) * R\n\\f]\nwhere \\f$ F \\f$ is the function corresponding to the operation sequence\nand x is any argument value.\nIf SetVector::value_type is bool,\nthe return value has size \\f$ m * q \\f$ (\\f$ q * m \\f$).\nwhere m is the number of dependent variables\ncorresponding to the operation sequence stored in f.\nIf SetVector::value_type is std::set<size_t>,\nthe return value has size \\f$ m \\f$ ( \\f$ q \\f$ )\nand with all its elements between zero and\n\\f$ q - 1 \\f$ ( \\f$ m - 1 \\f$).\n\n\\par Side Effects\nIf SetVector::value_type is bool,\nthe forward sparsity pattern for all of the variables on the\ntape is stored in for_jac_sparse_pack__.\nIn this case\n\\verbatim\n   for_jac_sparse_pack_.n_set() == num_var_tape_\n   for_jac_sparse_pack_.end() == q\n   for_jac_sparse_set_.n_set()  == 0\n   for_jac_sparse_set_.end()  == 0\n\\endverbatim\n\\n\n\\n\nIf SetVector::value_type is std::set<size_t>,\nthe forward sparsity pattern for all of the variables on the\ntape is stored in for_jac_sparse_set__.\nIn this case\n\\verbatim\n   for_jac_sparse_set_.n_set()   == num_var_tape_\n   for_jac_sparse_set_.end()   == q\n   for_jac_sparse_pack_.n_set()  == 0\n   for_jac_sparse_pack_.end()  == 0\n\\endverbatim\n*/\ntemplate <class Base, class RecBase>\ntemplate <class SetVector>\nSetVector ADFun<Base,RecBase>::ForSparseJac(\n   size_t             q             ,\n   const SetVector&   r             ,\n   bool               transpose     ,\n   bool               dependency    )\n{\n   SetVector s;\n   typedef typename SetVector::value_type Set_type;\n\n   // free all memory currently in sparsity patterns\n   for_jac_sparse_pack_.resize(0, 0);\n   for_jac_sparse_set_.resize(0, 0);\n\n   ForSparseJacCase(\n      Set_type()  ,\n      transpose   ,\n      dependency  ,\n      q           ,\n      r           ,\n      s\n   );\n\n   return s;\n}\n// ===========================================================================\n// ForSparseJacCheckpoint\n/*!\nForward mode Jacobian sparsity calculation used by checkpoint functions.\n\n\\tparam Base\nis the base type for this recording.\n\n\\param transpose\nis true (false) s is equal to \\f$ S(x) \\f$ (\\f$ S(x)^T \\f$)\nwhere\n\\f[\n   S(x) = F^{(1)} (x) * R\n\\f]\nwhere \\f$ F \\f$ is the function corresponding to the operation sequence\nand \\f$ x \\f$ is any argument value.\n\n\\param q\nis the number of columns in the matrix \\f$ R \\f$.\n\n\\param r\nis a sparsity pattern for the matrix \\f$ R \\f$.\n\n\\param transpose\nare the sparsity patterns for \\f$ R \\f$ and \\f$ S(x) \\f$ transposed.\n\n\\param dependency\nAre the derivatives with respect to left and right of the expression below\nconsidered to be non-zero:\n\\code\n   CondExpRel(left, right, if_true, if_false)\n\\endcode\nThis is used by the optimizer to obtain the correct dependency relations.\n\n\\param s\nThe input size and elements of s do not matter.\nOn output, s is the sparsity pattern for the matrix \\f$ S(x) \\f$\nor \\f$ S(x)^T \\f$ depending on transpose.\n\n\\par Side Effects\nIf SetVector::value_type is bool,\nthe forward sparsity pattern for all of the variables on the\ntape is stored in for_jac_sparse_pack__.\nIn this case\n\\verbatim\n   for_jac_sparse_pack_.n_set() == num_var_tape_\n   for_jac_sparse_pack_.end() == q\n   for_jac_sparse_set_.n_set()  == 0\n   for_jac_sparse_set_.end()  == 0\n\\endverbatim\n\\n\n\\n\nIf SetVector::value_type is std::set<size_t>,\nthe forward sparsity pattern for all of the variables on the\ntape is stored in for_jac_sparse_set__.\nIn this case\n\\verbatim\n   for_jac_sparse_set_.n_set()   == num_var_tape_\n   for_jac_sparse_set_.end()   == q\n   for_jac_sparse_pack_.n_set()  == 0\n   for_jac_sparse_pack_.end()  == 0\n\\endverbatim\n*/\ntemplate <class Base, class RecBase>\nvoid ADFun<Base,RecBase>::ForSparseJacCheckpoint(\n   size_t                             q          ,\n   const local::sparse::list_setvec&  r          ,\n   bool                               transpose  ,\n   bool                               dependency ,\n   local::sparse::list_setvec&        s          )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   size_t n = Domain();\n   size_t m = Range();\n\n# ifndef NDEBUG\n   if( transpose )\n   {  CPPAD_ASSERT_UNKNOWN( r.n_set() == q );\n      CPPAD_ASSERT_UNKNOWN( r.end()   == n );\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( r.n_set() == n );\n      CPPAD_ASSERT_UNKNOWN( r.end()   == q );\n   }\n   for(size_t j = 0; j < n; j++)\n   {  CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) );\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );\n   }\n# endif\n\n   // free all memory currently in sparsity patterns\n   for_jac_sparse_pack_.resize(0, 0);\n   for_jac_sparse_set_.resize(0, 0);\n\n   // allocate new sparsity pattern\n   for_jac_sparse_set_.resize(num_var_tape_, q);\n\n   // set sparsity pattern for dependent variables\n   if( transpose )\n   {  for(size_t i = 0; i < q; i++)\n      {  local::sparse::list_setvec::const_iterator itr(r, i);\n         size_t j = *itr;\n         while( j < n )\n         {  for_jac_sparse_set_.post_element( ind_taddr_[j], i );\n            j = *(++itr);\n         }\n      }\n   }\n   else\n   {  for(size_t j = 0; j < n; j++)\n      {  local::sparse::list_setvec::const_iterator itr(r, j);\n         size_t i = *itr;\n         while( i < q )\n         {  for_jac_sparse_set_.post_element( ind_taddr_[j], i );\n            i = *(++itr);\n         }\n      }\n   }\n   // process posts\n   for(size_t j = 0; j < n; j++)\n      for_jac_sparse_set_.process_post( ind_taddr_[j] );\n\n   // evaluate the sparsity pattern for all variables\n   local::sweep::for_jac(\n      &play_,\n      dependency,\n      n,\n      num_var_tape_,\n      for_jac_sparse_set_,\n      not_used_rec_base\n\n   );\n\n   // dimension the return value\n   if( transpose )\n      s.resize(q, m);\n   else\n      s.resize(m, q);\n\n   // return values corresponding to dependent variables\n   for(size_t i = 0; i < m; i++)\n   {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );\n\n      // extract the result from for_jac_sparse_set_\n      CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.end() == q );\n      local::sparse::list_setvec::const_iterator\n         itr(for_jac_sparse_set_, dep_taddr_[i] );\n      size_t j = *itr;\n      while( j < q )\n      {  if( transpose )\n            s.post_element(j, i);\n         else\n            s.post_element(i, j);\n         j  = *(++itr);\n      }\n   }\n   // process posts\n   for(size_t i = 0; i < s.n_set(); ++i)\n      s.process_post(i);\n\n}\n\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/for_two.hpp",
    "content": "# ifndef CPPAD_CORE_FOR_TWO_HPP\n# define CPPAD_CORE_FOR_TWO_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin ForTwo}\n{xrst_spell\n   ddy\n}\n\nForward Mode Second Partial Derivative Driver\n#############################################\n\nSyntax\n******\n| *ddy* = *f* . ``ForTwo`` ( *x* , *j* , *k* )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to *f* .\nThe syntax above sets\n\n.. math::\n\n   ddy [ i * p + \\ell ]\n   =\n   \\DD{ F_i }{ x_{j[ \\ell ]} }{ x_{k[ \\ell ]} } (x)\n\nfor :math:`i = 0 , \\ldots , m-1`\nand :math:`\\ell = 0 , \\ldots , p`,\nwhere :math:`p` is the size of the vectors *j* and *k* .\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nNote that the :ref:`ADFun-name` object *f* is not ``const``\n(see :ref:`ForTwo@ForTwo Uses Forward` below).\n\nx\n*\nThe argument *x* has prototype\n\n   ``const`` *BaseVector* & *x*\n\n(see :ref:`ForTwo@BaseVector` below)\nand its size\nmust be equal to *n* , the dimension of the\n:ref:`fun_property@Domain` space for *f* .\nIt specifies\nthat point at which to evaluate the partial derivatives listed above.\n\nj\n*\nThe argument *j* has prototype\n\n   ``const`` *SizeVector_t* & *j*\n\n(see :ref:`ForTwo@SizeVector_t` below)\nWe use *p* to denote the size of the vector *j* .\nAll of the indices in *j*\nmust be less than *n* ; i.e.,\nfor :math:`\\ell = 0 , \\ldots , p-1`, :math:`j[ \\ell ]  < n`.\n\nk\n*\nThe argument *k* has prototype\n\n   ``const`` *SizeVector_t* & *k*\n\n(see :ref:`ForTwo@SizeVector_t` below)\nand its size must be equal to *p* ,\nthe size of the vector *j* .\nAll of the indices in *k*\nmust be less than *n* ; i.e.,\nfor :math:`\\ell = 0 , \\ldots , p-1`, :math:`k[ \\ell ]  < n`.\n\nddy\n***\nThe result *ddy* has prototype\n\n   *BaseVector* *ddy*\n\n(see :ref:`ForTwo@BaseVector` below)\nand its size is :math:`m * p`.\nIt contains the requested partial derivatives; to be specific,\nfor :math:`i = 0 , \\ldots , m - 1`\nand :math:`\\ell = 0 , \\ldots , p - 1`\n\n.. math::\n\n   ddy [ i * p + \\ell ]\n   =\n   \\DD{ F_i }{ x_{j[ \\ell ]} }{ x_{k[ \\ell ]} } (x)\n\nBaseVector\n**********\nThe type *BaseVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type Base<SimpleVector@Elements of Specified Type>` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nSizeVector_t\n************\nThe type *SizeVector_t* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type size_t<SimpleVector@Elements of Specified Type>` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nForTwo Uses Forward\n*******************\nAfter each call to :ref:`Forward-name` ,\nthe object *f* contains the corresponding\n:ref:`Taylor coefficients<glossary@Taylor Coefficient>` .\nAfter a call to ``ForTwo`` ,\nthe zero order Taylor coefficients correspond to\n*f* . ``Forward`` (0, *x* )\nand the other coefficients are unspecified.\n\nExamples\n********\n{xrst_toc_hidden\n   example/general/for_two.cpp\n}\nThe routine\n:ref:`ForTwo<for_two.cpp-name>` is both an example and test.\nIt returns ``true`` , if it succeeds and ``false`` otherwise.\n\n{xrst_end ForTwo}\n-----------------------------------------------------------------------------\n*/\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector, class SizeVector_t>\nBaseVector ADFun<Base,RecBase>::ForTwo(\n   const BaseVector   &x,\n   const SizeVector_t &j,\n   const SizeVector_t &k)\n{  size_t i;\n   size_t j1;\n   size_t k1;\n   size_t l;\n\n   size_t n = Domain();\n   size_t m = Range();\n   size_t p = j.size();\n\n   // check BaseVector is Simple Vector class with Base type elements\n   CheckSimpleVector<Base, BaseVector>();\n\n   // check SizeVector_t is Simple Vector class with size_t elements\n   CheckSimpleVector<size_t, SizeVector_t>();\n\n   CPPAD_ASSERT_KNOWN(\n      x.size() == n,\n      \"ForTwo: Length of x not equal domain dimension for f.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      j.size() == k.size(),\n      \"ForTwo: Length of the j and k vectors are not equal.\"\n   );\n   // point at which we are evaluating the second partials\n   Forward(0, x);\n\n\n   // dimension the return value\n   BaseVector ddy(m * p);\n\n   // allocate memory to hold all possible diagonal Taylor coefficients\n   // (for large sparse cases, this is not efficient)\n   BaseVector D(m * n);\n\n   // boolean flag for which diagonal coefficients are computed\n   CppAD::vector<bool> c(n);\n   for(j1 = 0; j1 < n; j1++)\n      c[j1] = false;\n\n   // direction vector in argument space\n   BaseVector dx(n);\n   for(j1 = 0; j1 < n; j1++)\n      dx[j1] = Base(0.0);\n\n   // result vector in range space\n   BaseVector dy(m);\n\n   // compute the diagonal coefficients that are needed\n   for(l = 0; l < p; l++)\n   {  j1 = j[l];\n      k1 = k[l];\n      CPPAD_ASSERT_KNOWN(\n      j1 < n,\n      \"ForTwo: an element of j not less than domain dimension for f.\"\n      );\n      CPPAD_ASSERT_KNOWN(\n      k1 < n,\n      \"ForTwo: an element of k not less than domain dimension for f.\"\n      );\n      size_t count = 2;\n      while(count)\n      {  count--;\n         if( ! c[j1] )\n         {  // diagonal term in j1 direction\n            c[j1]  = true;\n            dx[j1] = Base(1.0);\n            Forward(1, dx);\n\n            dx[j1] = Base(0.0);\n            dy     = Forward(2, dx);\n            for(i = 0; i < m; i++)\n               D[i * n + j1 ] = dy[i];\n         }\n         j1 = k1;\n      }\n   }\n   // compute all the requested cross partials\n   for(l = 0; l < p; l++)\n   {  j1 = j[l];\n      k1 = k[l];\n      if( j1 == k1 )\n      {  for(i = 0; i < m; i++)\n            ddy[i * p + l] = Base(2.0) * D[i * n + j1];\n      }\n      else\n      {\n         // cross term in j1 and k1 directions\n         dx[j1] = Base(1.0);\n         dx[k1] = Base(1.0);\n         Forward(1, dx);\n\n         dx[j1] = Base(0.0);\n         dx[k1] = Base(0.0);\n         dy = Forward(2, dx);\n\n         // place result in return value\n         for(i = 0; i < m; i++)\n            ddy[i * p + l] = dy[i] - D[i*n+j1] - D[i*n+k1];\n\n      }\n   }\n   return ddy;\n}\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/forward/forward.hpp",
    "content": "# ifndef CPPAD_CORE_FORWARD_FORWARD_HPP\n# define CPPAD_CORE_FORWARD_FORWARD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// documented after Forward but included here so easy to see\n# include <cppad/core/capacity_order.hpp>\n# include <cppad/core/num_skip.hpp>\n# include <cppad/core/check_for_nan.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*\n--------------------------------------- ---------------------------------------\n{xrst_begin devel_forward_order dev}\n{xrst_spell\n   pri\n   xq\n   yq\n}\n\nMultiple orders, one direction, forward mode Taylor coefficients\n################################################################\n\nSyntax\n******\n| *yq* = *f* . ``Forward`` ( *q* , *xq* , *s*  )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_FORWARD_ORDER\n   // END_FORWARD_ORDER\n}\n\nBase\n****\nThe type used during the forward mode computations; i.e., the corresponding\nrecording of operations used the type AD<Base>.\n\nBaseVector\n**********\nis a Simple Vector class with elements of type Base.\n\nq\n*\nis the highest order for this forward mode computation; i.e.,\nafter this calculation there will be *q* +1\nTaylor coefficients per variable.\n\nxq\n**\ncontains Taylor coefficients for the independent variables.\nThe size of *xq* must either be *n* or ( *q* +1)* *n* ,\nWe define *p* = *q* + 1 *- xq.size* ()/ *n* .\nFor *j* = 0 , ... , *n-1* ,\n*k* = 0, ... , *q* ,\n*xq* [ ( *q* +1)* *j* + *k - p* ]\nis the k-th order coefficient for the j-th independent variable.\n\ns\n*\nIs the stream where output corresponding to PriOp operations will written.\n\nyq\n**\ncontains Taylor coefficients for the dependent variables.\nThe size of the return value *yq*\nhas size *m* * ( *q* +1 *-p* ) .\nFor *i* = 0, ... , *m-1* ,\n*k* = *p* , ..., *q* ,\n*yq* [( *q* +1 *-p* )* *i* + ( *k-p* )]\nis the k-th order coefficient for the i-th dependent variable.\n\ntaylor\\_\n********\nThe Taylor coefficients up to order *p-1* are inputs\nand the coefficients from order *p* through *q* are outputs.\nLet *N* = *num_var_tape_* , and\n*C* = *cap_order_taylor_* .\nNote that for\n*i* = 1 , ..., *N-1* ,\n*k* = 0 , ..., *q* ,\n*taylor_* [ *C* * *i* + *k* ]\nis the k-th order coefficient,\nfor the i-th variable on the tape.\n(The first independent variable has index one on the tape\nand there is no variable with index zero.)\n\n{xrst_end devel_forward_order}\n*/\n// BEGIN_FORWARD_ORDER\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector>\nBaseVector ADFun<Base,RecBase>::Forward(\n   size_t              q         ,\n   const BaseVector&   xq        ,\n          std::ostream& s         )\n// END_FORWARD_ORDER\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n\n   // temporary indices\n   size_t i, j, k;\n\n   // number of independent variables\n   size_t n = ind_taddr_.size();\n\n   // number of dependent variables\n   size_t m = dep_taddr_.size();\n\n   // check Vector is Simple Vector class with Base type elements\n   CheckSimpleVector<Base, BaseVector>();\n\n   // check size of xq\n   CPPAD_ASSERT_KNOWN(\n      size_t(xq.size()) == n || size_t(xq.size()) == n*(q+1),\n      \"Forward(q, xq): xq.size() is not equal n or n*(q+1)\"\n   );\n\n   // p = lowest order we are computing\n   size_t p = q + 1 - size_t(xq.size()) / n;\n   CPPAD_ASSERT_UNKNOWN( p == 0 || p == q );\n\n   // check one order case\n   CPPAD_ASSERT_KNOWN(\n      q <= num_order_taylor_ || p == 0,\n      \"Forward(q, xq): Number of Taylor coefficient orders stored in this\"\n      \" ADFun\\nis less than q and xq.size() != n*(q+1).\"\n   );\n\n   // if p > 1, the previous number of directions must be one\n   CPPAD_ASSERT_KNOWN(\n      p <= 1 || num_direction_taylor_ == 1,\n      \"Forward(q, xq): computing order q >= 2\"\n      \" and number of directions is not one.\"\n      \"\\nMust use Forward(q, r, xq) for this case\"\n   );\n\n   // does taylor_ need more orders or fewer directions\n   if( (cap_order_taylor_ <= q) || (num_direction_taylor_ != 1) )\n   {  if( p == 0 )\n      {  // no need to copy old values during capacity_order\n         num_order_taylor_ = 0;\n      }\n      else\n         num_order_taylor_ = q;\n      size_t c = std::max<size_t>(q + 1, cap_order_taylor_);\n      size_t r = 1;\n      capacity_order(c, r);\n   }\n   CPPAD_ASSERT_UNKNOWN( cap_order_taylor_ > q );\n   CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == 1 );\n\n   // short hand notation for order capacity\n   size_t C = cap_order_taylor_;\n\n   // The optimizer may skip a step that does not affect dependent variables.\n   // Initializing zero order coefficients avoids following valgrind warning:\n   // \"Conditional jump or move depends on uninitialised value(s)\".\n   for(j = 0; j < num_var_tape_; j++)\n   {  for(k = p; k <= q; k++)\n         taylor_[C * j + k] = CppAD::numeric_limits<Base>::quiet_NaN();\n   }\n\n   // set Taylor coefficients for independent variables\n# ifndef NDEBUG\n   for(j = 0; j < n; j++)\n   {  // ind_taddr_[j] is index of j-th independent variable\n      CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_  );\n      // ind_taddr_[j] is operator taddr for j-th independent variable\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );\n   }\n# endif\n   if( p == q )\n   {  CPPAD_ASSERT_UNKNOWN( xq.size() == n );\n      for(j = 0; j < n; ++j)\n         taylor_[ C * ind_taddr_[j] + q] = xq[j];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( xq.size() == (q + 1) * n );\n      for(j = 0; j < n; ++j)\n      {  for(k = 0; k <= q; k++)\n            taylor_[ C * ind_taddr_[j] + k] = xq[ (q+1)*j + k];\n      }\n   }\n   //\n   // evaluate the derivatives\n   CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_var_op() );\n   CPPAD_ASSERT_UNKNOWN( load_op2var_.size()  == play_.num_var_load() );\n   if( q == 0 )\n   {  bool print = true;\n      local::sweep::forward_0(\n         not_used_rec_base,\n         &play_,\n         num_var_tape_,\n         C,\n         cskip_op_.data(),\n         load_op2var_,\n         compare_change_count_,\n         compare_change_number_,\n         compare_change_op_index_,\n         s,\n         print,\n         taylor_.data()\n      );\n   }\n   else\n   {  bool print = true;\n      local::sweep::forward_any(\n         not_used_rec_base,\n         &play_,\n         num_var_tape_,\n         C,\n         cskip_op_.data(),\n         load_op2var_,\n         compare_change_count_,\n         compare_change_number_,\n         compare_change_op_index_,\n         s,\n         print,\n         p,\n         q,\n         taylor_.data()\n      );\n   }\n\n   // return Taylor coefficients for dependent variables\n   BaseVector yq;\n   if( p == q )\n   {  yq.resize(m);\n      for(i = 0; i < m; i++)\n      {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_  );\n         yq[i] = taylor_[ C * dep_taddr_[i] + q];\n      }\n   }\n   else\n   {  yq.resize(m * (q+1) );\n      for(i = 0; i < m; i++)\n      {  for(k = 0; k <= q; k++)\n            yq[ (q+1) * i + k] =\n               taylor_[ C * dep_taddr_[i] + k ];\n      }\n   }\n# ifndef NDEBUG\n   if( check_for_nan_ )\n   {  bool ok = true;\n      size_t index = m;\n      if( p == 0 )\n      {  for(i = 0; i < m; i++)\n         {  // Visual Studio 2012, CppAD required in front of isnan ?\n            if( CppAD::isnan( yq[ (q+1) * i + 0 ] ) )\n            {  ok    = false;\n               if( index == m )\n                  index = i;\n            }\n         }\n      }\n      if( ! ok )\n      {  CPPAD_ASSERT_UNKNOWN( index < m );\n         //\n         CppAD::vector<Base> x0(n);\n         for(j = 0; j < n; j++)\n            x0[j] = taylor_[ C * ind_taddr_[j] + 0 ];\n         std::string  file_name;\n         put_check_for_nan(x0, file_name);\n         std::stringstream ss;\n         ss <<\n         \"yq = f.Forward(q, xq): a zero order Taylor coefficient is nan.\\n\"\n         \"Corresponding independent variables vector was written \"\n         \"to binary a file.\\n\"\n         \"vector_size = \" << n << \"\\n\" <<\n         \"file_name = \" << file_name << \"\\n\" <<\n         \"index = \" << index << \"\\n\";\n         // ss.str() returns a string object with a copy of the current\n         // contents in the stream buffer.\n         std::string msg_str       = ss.str();\n         // msg_str.c_str() returns a pointer to the c-string\n         // representation of the string object's value.\n         const char* msg_char_star = msg_str.c_str();\n         ErrorHandler::Call(\n            true,\n            __LINE__,\n            __FILE__,\n            \"if( CppAD::isnan( yq[ (q+1) * index + 0 ] )\",\n            msg_char_star\n         );\n      }\n      CPPAD_ASSERT_KNOWN(ok,\n         \"with the value nan.\"\n      );\n      if( 0 < q )\n      {  for(i = 0; i < m; i++)\n         {  for(k = p; k <= q; k++)\n            {  // Studio 2012, CppAD required in front of isnan ?\n               ok &= ! CppAD::isnan( yq[ (q+1-p)*i + k-p ] );\n            }\n         }\n      }\n      CPPAD_ASSERT_KNOWN(ok,\n      \"yq = f.Forward(q, xq): has a non-zero order Taylor coefficient\\n\"\n      \"with the value nan (but zero order coefficients are not nan).\"\n      );\n   }\n# endif\n\n   // now we have q + 1  taylor_ coefficient orders per variable\n   num_order_taylor_ = q + 1;\n\n   return yq;\n}\n/*\n--------------------------------------- ---------------------------------------\n{xrst_begin devel_forward_dir dev}\n{xrst_spell\n   xq\n   yq\n}\n\nOne order, multiple directions, forward mode Taylor coefficients\n################################################################\n\nSyntax\n******\n\n   *yq* = *f* . ``Forward`` ( *q* , *r* , *xq* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_FORWARD_DIR\n   // END_FORWARD_DIR\n}\n\nBase\n****\nThe type used during the forward mode computations; i.e., the corresponding\nrecording of operations used the type AD<Base>.\n\nBaseVector\n**********\nis a Simple Vector class with elements of type Base.\n\nq\n*\nis the order for this forward mode computation,\n*q > 0* .\nThere must be at least *q* Taylor coefficients\nper variable before this call.\nAfter this call there will be *q* +1\nTaylor coefficients per variable.\n\nr\n*\nis the number of directions for this calculation.\nIf *q* != 1 , r must be the same as in the previous\ncall to Forward where q was equal to one.\n\nxq\n**\ncontains Taylor coefficients for the independent variables.\nThe size of xq must either be *r* * *n* ,\nFor *j* = 0 , ... , *n-1* ,\n*ell* = 0, ... , *r-1* ,\n*xq* [ ( *r* * *j* + *ell* ]\nis the q-th order coefficient for the j-th independent variable\nand the ell-th direction.\n\nyq\n**\ncontains Taylor coefficients for the dependent variables.\nThe size of *y* is *r* * *m* .\nFor *i* = 0, ... , *m-1* ,\n*ell* = 0, ... , *r-1* ,\n*yq* [ *r* * *i* + *ell* ]\nis the q-th order coefficient for the i-th dependent variable\nand the ell-th direction.\n\ntaylor\\_\n********\nThe Taylor coefficients up to order *q-1* are inputs\nand the coefficients of order q are outputs.\nLet *N* = *num_var_tape_* , and\n*C* = *cap_order_taylor_* .\nNote that for\n*i* = 1 , ..., *N-1* ,\n*taylor_* [ ( *C-1* )* *r* * *i* + *i* + 0 ]\nis the zero order coefficient,\nfor the i-th variable, and all directions.\nFor *i* = 1 , ..., *N-1* ,\n*k* = 1 , ..., *q* ,\n*ell* = 0 , ..., *r-1* ,\n*taylor_* [ ( *C-1* )* *r* * *i* + *i* + ( *k-1* )* *r* + *ell* + 1 ]\nis the k-th order coefficient,\nfor the i-th variable, and ell-th direction.\n(The first independent variable has index one on the tape\nand there is no variable with index zero.)\n\n{xrst_end devel_forward_dir}\n*/\n// BEGIN_FORWARD_DIR\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector>\nBaseVector ADFun<Base,RecBase>::Forward(\n   size_t              q         ,\n   size_t              r         ,\n   const BaseVector&   xq        )\n// END_FORWARD_DIR\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n\n   // temporary indices\n   size_t i, j, ell;\n\n   // number of independent variables\n   size_t n = ind_taddr_.size();\n\n   // number of dependent variables\n   size_t m = dep_taddr_.size();\n\n   // check Vector is Simple Vector class with Base type elements\n   CheckSimpleVector<Base, BaseVector>();\n\n   CPPAD_ASSERT_KNOWN( q > 0, \"Forward(q, r, xq): q == 0\" );\n   CPPAD_ASSERT_KNOWN(\n      size_t(xq.size()) == r * n,\n      \"Forward(q, r, xq): xq.size() is not equal r * n\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      q <= num_order_taylor_ ,\n      \"Forward(q, r, xq): Number of Taylor coefficient orders stored in\"\n      \" this ADFun is less than q\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      q == 1 || num_direction_taylor_ == r ,\n      \"Forward(q, r, xq): q > 1 and number of Taylor directions r\"\n      \" is not same as previous Forward(1, r, xq)\"\n   );\n\n   // does taylor_ need more orders or new number of directions\n   if( cap_order_taylor_ <= q || num_direction_taylor_ != r )\n   {  if( num_direction_taylor_ != r )\n         num_order_taylor_ = 1;\n\n      size_t c = std::max<size_t>(q + 1, cap_order_taylor_);\n      capacity_order(c, r);\n   }\n   CPPAD_ASSERT_UNKNOWN( cap_order_taylor_ > q );\n   CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == r )\n\n   // short hand notation for order capacity\n   size_t c = cap_order_taylor_;\n\n   // set Taylor coefficients for independent variables\n   for(j = 0; j < n; j++)\n   {  CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_  );\n\n      // ind_taddr_[j] is operator taddr for j-th independent variable\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );\n\n      for(ell = 0; ell < r; ell++)\n      {  size_t index = ((c-1)*r + 1)*ind_taddr_[j] + (q-1)*r + ell + 1;\n         taylor_[ index ] = xq[ r * j + ell ];\n      }\n   }\n\n   // evaluate the derivatives\n   CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_var_op() );\n   CPPAD_ASSERT_UNKNOWN( load_op2var_.size()  == play_.num_var_load() );\n   local::sweep::forward_dir(\n      not_used_rec_base,\n      &play_,\n      num_var_tape_,\n      c,\n      cskip_op_.data(),\n      load_op2var_,\n      q,\n      r,\n      taylor_.data()\n   );\n\n   // return Taylor coefficients for dependent variables\n   BaseVector yq;\n   yq.resize(r * m);\n   for(i = 0; i < m; i++)\n   {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_  );\n      for(ell = 0; ell < r; ell++)\n      {  size_t index = ((c-1)*r + 1)*dep_taddr_[i] + (q-1)*r + ell + 1;\n         yq[ r * i + ell ] = taylor_[ index ];\n      }\n   }\n# ifndef NDEBUG\n   if( check_for_nan_ )\n   {  bool ok = true;\n      for(i = 0; i < m; i++)\n      {  for(ell = 0; ell < r; ell++)\n         {  // Studio 2012, CppAD required in front of isnan ?\n            ok &= ! CppAD::isnan( yq[ r * i + ell ] );\n         }\n      }\n      CPPAD_ASSERT_KNOWN(ok,\n      \"yq = f.Forward(q, r, xq): has a non-zero order Taylor coefficient\\n\"\n      \"with the value nan (but zero order coefficients are not nan).\"\n      );\n   }\n# endif\n\n   // now we have q + 1  taylor_ coefficient orders per variable\n   num_order_taylor_ = q + 1;\n\n   return yq;\n}\n\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/fun_check.hpp",
    "content": "# ifndef CPPAD_CORE_FUN_CHECK_HPP\n# define CPPAD_CORE_FUN_CHECK_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin FunCheck}\n\nCheck an ADFun Sequence of Operations\n#####################################\n\nSyntax\n******\n| *ok* = ``FunCheck`` ( *f* , *g* , *x* , *r* , *a* )\n\nSee Also\n********\n:ref:`FunCheck-name`\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to *f* .\nWe use :math:`G : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\nfunction corresponding to the C++ function object *g* .\nThis routine check if\n\n.. math::\n\n   F(x) = G(x)\n\nIf :math:`F(x) \\neq G(x)`, the\n:ref:`operation sequence<glossary@Operation@Sequence>`\ncorresponding to *f* does not represents the algorithm used\nby *g* to calculate values for :math:`G`\n(see :ref:`FunCheck@Discussion` below).\n\nf\n*\nThe ``FunCheck`` argument *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nNote that the :ref:`ADFun-name` object *f* is not ``const``\n(see :ref:`Forward<FunCheck@FunCheck Uses Forward>` below).\n\ng\n*\nThe ``FunCheck`` argument *g* has prototype\n\n   *Fun* & *g*\n\n( *Fun* is defined the properties of *g* ).\nThe C++ function object *g* supports the syntax\n\n   *y* = *g* ( *x* )\n\nwhich computes :math:`y = G(x)`.\n\nx\n=\nThe *g* argument *x* has prototype\n\n   ``const`` *Vector* & *x*\n\n(see :ref:`FunCheck@Vector` below)\nand its size\nmust be equal to *n* , the dimension of the\n:ref:`fun_property@Domain` space for *f* .\n\ny\n*\nThe *g* result *y* has prototype\n\n   *Vector* *y*\n\nand its value is :math:`G(x)`.\nThe size of *y*\nis equal to *m* , the dimension of the\n:ref:`fun_property@Range` space for *f* .\n\nx\n*\nThe ``FunCheck`` argument *x* has prototype\n\n   ``const`` *Vector* & *x*\n\nand its size\nmust be equal to *n* , the dimension of the\n:ref:`fun_property@Domain` space for *f* .\nThis specifies that point at which to compare the values\ncalculated by *f* and *G* .\n\nr\n*\nThe ``FunCheck`` argument *r* has prototype\n\n   ``const`` *Base* & *r*\n\nIt specifies the relative error the element by element\ncomparison of the value of :math:`F(x)` and :math:`G(x)`.\n\na\n*\nThe ``FunCheck`` argument *a* has prototype\n\n   ``const`` *Base* & *a*\n\nIt specifies the absolute error the element by element\ncomparison of the value of :math:`F(x)` and :math:`G(x)`.\n\nok\n**\nThe ``FunCheck`` result *ok* has prototype\n\n   ``bool`` *ok*\n\nIt is true, if for :math:`i = 0 , \\ldots , m-1`\neither the relative error bound is satisfied\n\n.. math::\n\n   | F_i (x) - G_i (x) |\n   \\leq\n   r ( | F_i (x) | + | G_i (x) | )\n\nor the absolute error bound is satisfied\n\n.. math::\n\n   | F_i (x) - G_i (x) | \\leq a\n\nIt is false if for some :math:`(i, j)` neither\nof these bounds is satisfied.\n\nVector\n******\nThe type *Vector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n*Base* .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nFunCheck Uses Forward\n*********************\nAfter each call to :ref:`Forward-name` ,\nthe object *f* contains the corresponding\n:ref:`Taylor coefficients<glossary@Taylor Coefficient>` .\nAfter ``FunCheck`` ,\nthe previous calls to :ref:`Forward-name` are undefined.\n\nDiscussion\n**********\nSuppose that the algorithm corresponding to *g* contains\n\n| |tab| ``if`` ( *x*  >= 0 )\n| |tab| |tab| *y* = ``exp`` ( *x* )\n| |tab| ``else``\n| |tab| |tab| *y* = ``exp`` ( ``-`` *x* )\n\nwhere *x* and *y* are ``AD<double>`` objects.\nIt follows that the\nAD of ``double`` :ref:`operation sequence<glossary@Operation@Sequence>`\ndepends on the value of *x* .\nIf the sequence of operations stored in *f* corresponds to\n*g* with :math:`x \\geq 0`,\nthe function values computed using *f* when :math:`x < 0`\nwill not agree with the function values computed by :math:`g`.\nThis is because the operation sequence corresponding to *g* changed\n(and hence the object *f* does not represent the function\n:math:`G` for this value of *x* ).\nIn this case, you probably want to re-tape the calculations\nperformed by *g* with the\n:ref:`independent variables<glossary@Tape@Independent Variable>`\nequal to the values in *x*\n(so AD operation sequence properly represents the algorithm\nfor this value of independent variables).\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/fun_check.cpp\n}\nThe file\n:ref:`fun_check.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end FunCheck}\n---------------------------------------------------------------------------\n*/\n\nnamespace CppAD {\n   template <class Base, class RecBase, class Fun, class Vector>\n   bool FunCheck(\n      ADFun<Base, RecBase>  &f ,\n      Fun                   &g ,\n      const Vector          &x ,\n      const Base            &r ,\n      const Base            &a )\n   {  bool ok = true;\n\n      size_t m   = f.Range();\n      Vector yf  = f.Forward(0, x);\n      Vector yg  = g(x);\n\n      size_t i;\n      for(i = 0; i < m; i++)\n         ok  &= NearEqual(yf[i], yg[i], r, a);\n      return ok;\n   }\n}\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/fun_construct.hpp",
    "content": "# ifndef CPPAD_CORE_FUN_CONSTRUCT_HPP\n# define CPPAD_CORE_FUN_CONSTRUCT_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin fun_construct}\n{xrst_spell\n   versa\n}\n\nConstruct an ADFun Object and Stop Recording\n############################################\n\nSyntax\n******\n| ``ADFun`` < *Base* > *f* ( *ax* , *ay* );\n| ``ADFun`` < *Base* > *f*\n| *f* . ``swap`` ( *g* )\n| ``f`` = ``g``\n\nPurpose\n*******\nThe ``ADFun`` < *Base* > object *f*\nstores an AD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\nIt can then be used to calculate derivatives of the corresponding\n:ref:`glossary@AD Function`\n\n.. math::\n\n   F : \\B{R}^n \\rightarrow \\B{R}^m\n\nwhere :math:`B` is the space corresponding to objects of type *Base* .\n\nax\n**\nIf the argument *ax* is present, it has prototype\n\n   ``const`` *ADVector* & *ax*\n\nIt must be the vector argument in the previous call to\n:ref:`Independent-name` .\nNeither its size, or any of its values, are allowed to change\nbetween calling\n\n   ``Independent`` ( *ax* )\n\nand\n\n   ``ADFun`` < *Base* > *f* ( *ax* , *ay* )\n\nay\n**\nIf the argument *ay* is present, it has prototype\n\n   ``const`` *ADVector* & *ay*\n\nThe sequence of operations that map *ax*\nto *ay* are stored in the ADFun object *f* .\n\nADVector\n********\nThe type *ADVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``AD`` < *Base* > .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nDefault Constructor\n*******************\nThe default constructor\n\n   ``ADFun`` < *Base* > *g*\n\ncreates an\n``AD`` < *Base* > object with no corresponding operation sequence; i.e.,\n\n   *g* . ``size_var`` ()\n\nreturns the value zero (see :ref:`fun_property@size_var` ).\n\nSequence Constructor\n********************\nThe following constructor stores the current ``AD`` < *Base* > operation\nsequence in *f* :\n\n   ``ADFun`` < *Base* > *f* ( *ax* , *ay* )\n\nTo be specific, it is equivalent to the following\nsteps using the default constructor:\n\n#. Create *f* with the default constructor\n\n      ``ADFun`` < *Base* > *f* ;\n\n#. Stop the recording and store the operation sequence using\n\n      *f* . ``Dependent`` ( *ax* , *ay* );\n\n   see :ref:`Independent@Start Recording` ,\n   :ref:`Dependent@Stop Recording` , and\n   :ref:`Dependent@Store Operation Sequence` .\n\n#. Calculate the zero order Taylor coefficients for all\n   the variables in the operation sequence using\n\n      *y* = *f* . ``Forward`` ( 0 , *x* )\n\n   see :ref:`forward_zero-name`.\n   Here *x* and *y* are :ref:`simple vectors <SimpleVector-name>`\n   with elements of type *Base* and the elements of *x*\n   are equal to the corresponding elements in *ax*.\n\n#. If NDEBUG is not defined, *y* is checked to make sure it's elements are\n   nearly equal to the corresponding values in *ay* .\n\nCopy Constructor\n****************\nIt is an error to attempt to use the ``ADFun`` < *Base* > copy constructor;\ni.e., the following syntax is not allowed:\n\n   ``ADFun`` < *Base* > *g* ( *f* )\n\nwhere *f* is an ``ADFun`` < *Base* > object.\nUse its :ref:`fun_construct@Default Constructor` instead\nand its assignment operator.\n\nswap\n****\nThe swap operation *f* . ``swap`` ( *g* ) exchanges the contents of\nthe two ``ADFun`` < *Base* > functions; i.e.,\n*f* before the swap is identical to *g* after the swap and vise versa.\n\nAssignment Operator\n*******************\nThe ``ADFun`` < *Base* > assignment operation\n\n   *g* = *f*\n\nmakes a copy of the operation sequence currently stored in *f*\nin the object *g* .\nThe object *f* is not affected by this operation and\ncan be ``const`` .\nAll of information (state) stored in *f* is copied to *g*\nand any information originally in *g* is lost.\n\nMove Semantics\n==============\nIn the special case where *f* is a temporary object,\nthis assignment will use move semantics.\nThis avoids the overhead of the copying all the information from\n*f* to *g* .\n\nTaylor Coefficients\n===================\nThe Taylor coefficient information currently stored in *f*\n(computed by :ref:`f.Forward<Forward-name>` ) is\ncopied to *g* .\nHence, directly after this operation\n\n   *g* . ``size_order`` () == *f* . ``size_order`` ()\n\nSparsity Patterns\n=================\nThe forward Jacobian sparsity pattern currently stored in *f*\n(computed by :ref:`f.ForSparseJac<ForSparseJac-name>` ) is\ncopied to *g* .\nHence, directly after this operation\n\n| |tab| *g* . ``size_forward_bool`` () == *f* . ``size_forward_bool`` ()\n| |tab| *g* . ``size_forward_set`` ()  == *f* . ``size_forward_set`` ()\n\nParallel Mode\n*************\nThe call to ``Independent`` ,\nand the corresponding call to\n\n   ``ADFun`` < *Base* > *f* ( *ax* , *ay* )\n\nor\n\n   *f* . ``Dependent`` ( *ax* , *ay* )\n\nor :ref:`abort_recording-name` ,\nmust be preformed by the same thread; i.e.,\n:ref:`thread_alloc::thread_num<ta_thread_num-name>` must be the same.\n\nExample\n*******\n\nSequence Constructor\n====================\nThe file\n:ref:`independent.cpp-name`\ncontains an example and test of the sequence constructor.\n\nDefault Constructor\n===================\nThe files\n:ref:`fun_check.cpp-name`\nand\n:ref:`hes_lagrangian.cpp-name`\ncontain an examples and tests using the default constructor.\nThey return true if they succeed and false otherwise.\n{xrst_toc_hidden\n   example/general/fun_assign.cpp\n}\nAssignment Operator\n===================\nThe file\n:ref:`fun_assign.cpp-name`\ncontains an example and test of the ``ADFun`` < *Base* >\nassignment operator.\n\n{xrst_end fun_construct}\n----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file fun_construct.hpp\nADFun function constructors and assignment operator.\n*/\n\n/*!\nADFun default constructor\n\nThe C++ syntax for this operation is\n\\verbatim\n   ADFun<Base> f\n\\endverbatim\nAn empty ADFun object is created.\nThe Dependent member function,\nor the ADFun<Base> assignment operator,\ncan then be used to put an operation sequence in this ADFun object.\n\n\\tparam Base\nis the base for the recording that can be stored in this ADFun object;\ni.e., operation sequences that were recorded using the type AD<Base>.\n*/\ntemplate <class Base, class RecBase>\nADFun<Base,RecBase>::ADFun(void) :\nfunction_name_(\"\"),\nexceed_collision_limit_(false),\nhas_been_optimized_(false),\ncheck_for_nan_(true) ,\ncompare_change_count_(0),\ncompare_change_number_(0),\ncompare_change_op_index_(0),\nnum_order_taylor_(0),\ncap_order_taylor_(0),\nnum_direction_taylor_(0),\nnum_var_tape_(0)\n{ }\n//\n// move semantics version of constructor\n// (none of the default constructor values matter to the destructor)\ntemplate <class Base, class RecBase>\nADFun<Base,RecBase>::ADFun(ADFun&& f)\n{  swap(f); }\n//\n// destructor\ntemplate <class Base, class RecBase>\nADFun<Base,RecBase>::~ADFun(void)\n{ }\n/*!\nADFun assignment operator\n\nThe C++ syntax for this operation is\n\\verbatim\n   g = f\n\\endverbatim\nwhere g and f are ADFun<Base> ADFun objects.\nA copy of the the operation sequence currently stored in f\nis placed in this ADFun object (called g above).\nAny information currently stored in this ADFun object is lost.\n\n\\tparam Base\nis the base for the recording that can be stored in this ADFun object;\ni.e., operation sequences that were recorded using the type AD<Base>.\n\n\\param f\nADFun object containing the operation sequence to be copied.\n*/\ntemplate <class Base, class RecBase>\nvoid ADFun<Base,RecBase>::operator=(const ADFun& f)\n{\n   // go through member variables in ad_fun.hpp order\n   //\n   // string objects\n   function_name_             = f.function_name_;\n   //\n   // bool objects\n   exceed_collision_limit_    = f.exceed_collision_limit_;\n   has_been_optimized_        = f.has_been_optimized_;\n   check_for_nan_             = f.check_for_nan_;\n   //\n   // size_t objects\n   compare_change_count_      = f.compare_change_count_;\n   compare_change_number_     = f.compare_change_number_;\n   compare_change_op_index_   = f.compare_change_op_index_;\n   num_order_taylor_          = f.num_order_taylor_;\n   cap_order_taylor_          = f.cap_order_taylor_;\n   num_direction_taylor_      = f.num_direction_taylor_;\n   num_var_tape_              = f.num_var_tape_;\n   //\n   // pod_vector objects\n   ind_taddr_                 = f.ind_taddr_;\n   dep_taddr_                 = f.dep_taddr_;\n   dep_parameter_             = f.dep_parameter_;\n   cskip_op_                  = f.cskip_op_;\n   load_op2var_               = f.load_op2var_;\n   //\n   // pod_vector_maybe_vectors\n   taylor_                    = f.taylor_;\n   subgraph_partial_          = f.subgraph_partial_;\n   //\n   // player\n   play_                      = f.play_;\n   //\n   // subgraph\n   subgraph_info_             = f.subgraph_info_;\n   //\n   // sparse_pack\n   for_jac_sparse_pack_       = f.for_jac_sparse_pack_;\n   //\n   // sparse_list\n   for_jac_sparse_set_        = f.for_jac_sparse_set_;\n}\n/// swap\ntemplate <class Base, class RecBase>\nvoid ADFun<Base,RecBase>::swap(ADFun& f)\n{\n   // string objects\n   function_name_.swap( f.function_name_ );\n   //\n   // bool objects\n   std::swap( exceed_collision_limit_    , f.exceed_collision_limit_);\n   std::swap( has_been_optimized_        , f.has_been_optimized_);\n   std::swap( check_for_nan_             , f.check_for_nan_);\n   //\n   // size_t objects\n   std::swap( compare_change_count_      , f.compare_change_count_);\n   std::swap( compare_change_number_     , f.compare_change_number_);\n   std::swap( compare_change_op_index_   , f.compare_change_op_index_);\n   std::swap( num_order_taylor_          , f.num_order_taylor_);\n   std::swap( cap_order_taylor_          , f.cap_order_taylor_);\n   std::swap( num_direction_taylor_      , f.num_direction_taylor_);\n   std::swap( num_var_tape_              , f.num_var_tape_);\n   //\n   // pod_vector objects\n   ind_taddr_.swap(      f.ind_taddr_);\n   dep_taddr_.swap(      f.dep_taddr_);\n   dep_parameter_.swap(  f.dep_parameter_);\n   taylor_.swap(         f.taylor_);\n   cskip_op_.swap(       f.cskip_op_);\n   load_op2var_.swap(    f.load_op2var_);\n   //\n   // player\n   play_.swap(f.play_);\n   //\n   // subgraph_info\n   subgraph_info_.swap(f.subgraph_info_);\n   //\n   // sparse_pack\n   for_jac_sparse_pack_.swap( f.for_jac_sparse_pack_);\n   //\n   // sparse_list\n   for_jac_sparse_set_.swap( f.for_jac_sparse_set_);\n}\n/// Move semantics version of constructor and assignment\ntemplate <class Base, class RecBase>\nvoid ADFun<Base,RecBase>::operator=(ADFun&& f)\n{  swap(f); }\n\n\n/*!\nADFun constructor from an operation sequence.\n\nThe C++ syntax for this operation is\n\\verbatim\n   ADFun<Base> f(x, y)\n\\endverbatim\nThe operation sequence that started with the previous call\n Independent(x), and that ends with this operation, is stored\nin this ADFun<Base> object f.\n\n\\tparam Base\nis the base for the recording that will be stored in the object f;\ni.e., the operations were recorded using the type AD<Base>.\n\n\\tparam ADVector\nis a simple vector class with elements of typea AD<Base>.\n\n\\param x\nis the independent variable vector for this ADFun object.\nThe domain dimension of this object will be the size of x.\n\n\\param y\nis the dependent variable vector for this ADFun object.\nThe range dimension of this object will be the size of y.\n\n\\par Taylor Coefficients\nA zero order forward mode sweep is done,\nand if NDEBUG is not defined the resulting values for the\ndependent variables are checked against the values in y.\nThus, the zero order Taylor coefficients\ncorresponding to the value of the x vector\nare stored in this ADFun object.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class ADVector>\nADFun<Base,RecBase>::ADFun(const ADVector &x, const ADVector &y)\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n\n   CPPAD_ASSERT_KNOWN(\n      x.size() > 0,\n      \"ADFun<Base>: independent variable vector has size zero.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      Variable(x[0]),\n      \"ADFun<Base>: independent variable vector has been changed.\"\n   );\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr(x[0].tape_id_);\n   CPPAD_ASSERT_KNOWN(\n      tape->size_independent_ == size_t ( x.size() ),\n      \"ADFun<Base>: independent variable vector has been changed.\"\n   );\n   size_t j, n = x.size();\n# ifndef NDEBUG\n   size_t i, m = y.size();\n   for(j = 0; j < n; j++)\n   {  CPPAD_ASSERT_KNOWN(\n      size_t(x[j].taddr_) == (j+1),\n      \"ADFun<Base>: independent variable vector has been changed.\"\n      );\n      CPPAD_ASSERT_KNOWN(\n      x[j].tape_id_ == x[0].tape_id_,\n      \"ADFun<Base>: independent variable vector has been changed.\"\n      );\n   }\n   for(i = 0; i < m; i++)\n   {  CPPAD_ASSERT_KNOWN(\n      CppAD::Parameter( y[i] ) || (y[i].tape_id_ == x[0].tape_id_) ,\n      \"ADFun<Base>: dependent vector contains variables for\"\n      \"\\na different tape than the independent variables.\"\n      );\n   }\n# endif\n\n   // stop the tape and store the operation sequence\n   Dependent(tape, y);\n\n   // This function has not yet been optimized\n   exceed_collision_limit_    = false;\n\n   // ad_fun.hpp member values not set by dependent\n   check_for_nan_       = true;\n\n   // allocate memory for one zero order taylor_ coefficient\n   CPPAD_ASSERT_UNKNOWN( num_order_taylor_ == 0 );\n   CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == 0 );\n   size_t c = 1;\n   size_t r = 1;\n   capacity_order(c, r);\n   CPPAD_ASSERT_UNKNOWN( cap_order_taylor_     == c );\n   CPPAD_ASSERT_UNKNOWN( num_direction_taylor_ == r );\n\n   // set zero order coefficients corresponding to independent variables\n   CPPAD_ASSERT_UNKNOWN( n == ind_taddr_.size() );\n   for(j = 0; j < n; j++)\n   {  CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) );\n      CPPAD_ASSERT_UNKNOWN( size_t(x[j].taddr_) == (j+1) );\n      taylor_[ ind_taddr_[j] ]  = x[j].value_;\n   }\n\n   // use independent variable values to fill in values for others\n   CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_var_op() );\n   CPPAD_ASSERT_UNKNOWN( load_op2var_.size()  == play_.num_var_load() );\n   bool print = false;\n   local::sweep::forward_0(\n      not_used_rec_base,\n      &play_,\n      num_var_tape_,\n      cap_order_taylor_,\n      cskip_op_.data(),\n      load_op2var_,\n      compare_change_count_,\n      compare_change_number_,\n      compare_change_op_index_,\n      std::cout,\n      print,\n      taylor_.data()\n   );\n   CPPAD_ASSERT_UNKNOWN( compare_change_count_    == 1 );\n   CPPAD_ASSERT_UNKNOWN( compare_change_number_   == 0 );\n   CPPAD_ASSERT_UNKNOWN( compare_change_op_index_ == 0 );\n\n   // now set the number of orders stored\n   num_order_taylor_ = 1;\n\n# ifndef NDEBUG\n   // on MS Visual Studio 2012, CppAD required in front of isnan ?\n   for(i = 0; i < m; i++)\n   if( taylor_[dep_taddr_[i]] != y[i].value_ || CppAD::isnan( y[i].value_ ) )\n   {  using std::endl;\n      std::ostringstream buf;\n      buf << \"A dependent variable value is not equal to \"\n         << \"its tape evaluation value,\" << endl\n         << \"perhaps it is nan.\" << endl\n         << \"Dependent variable value = \"\n         <<  y[i].value_ << endl\n         << \"Tape evaluation value    = \"\n         <<  taylor_[dep_taddr_[i]]  << endl\n         << \"Difference               = \"\n         <<  y[i].value_ -  taylor_[dep_taddr_[i]]  << endl\n      ;\n      // buf.str() returns a string object with a copy of the current\n      // contents in the stream buffer.\n      std::string msg_str       = buf.str();\n      // msg_str.c_str() returns a pointer to the c-string\n      // representation of the string object's value.\n      const char* msg_char_star = msg_str.c_str();\n      CPPAD_ASSERT_KNOWN(\n         0,\n         msg_char_star\n      );\n   }\n# endif\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/fun_eval.hpp",
    "content": "# ifndef CPPAD_CORE_FUN_EVAL_HPP\n# define CPPAD_CORE_FUN_EVAL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/core/new_dynamic.hpp>\n# include <cppad/core/forward/forward.hpp>\n# include <cppad/core/reverse.hpp>\n# include <cppad/core/sparse.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/graph/cpp_graph.hpp",
    "content": "# ifndef CPPAD_CORE_GRAPH_CPP_GRAPH_HPP\n# define CPPAD_CORE_GRAPH_CPP_GRAPH_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <iomanip>\n# include <string>\n# include <cppad/utility/vector.hpp>\n# include <cppad/local/graph/cpp_graph_op.hpp>\n# include <cppad/local/graph/cpp_graph_itr.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\nclass cpp_graph { // BEGIN_CPP_GRAPH_CLASS\npublic:\n   typedef CppAD::graph::graph_op_enum graph_op_enum;\nprivate:\n   //\n   std::string                   function_name_;\n   vector<std::string>           discrete_name_vec_;\n   vector<std::string>           atomic_name_vec_;\n   vector<std::string>           print_text_vec_;\n   size_t                        n_dynamic_ind_;\n   size_t                        n_variable_ind_;\n   vector<double>                constant_vec_;\n   vector<graph_op_enum>         operator_vec_;\n   vector<size_t>                operator_arg_;\n   vector<size_t>                dependent_vec_;\npublic:\n   typedef local::graph::cpp_graph_itr const_iterator;\n   //\n   const_iterator begin(void) const\n   {  size_t op_index = 0;\n      return const_iterator(operator_vec_, operator_arg_, op_index);\n   }\n   const_iterator end(void)\n   {  size_t op_index = operator_vec_.size();\n      return const_iterator(operator_vec_, operator_arg_, op_index);\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin cpp_graph_ctor}\n\nC++ AD Graph Constructor\n########################\n\nSyntax\n******\n| ``cpp_graph`` *graph_obj*\n| *graph_obj* . ``initialize`` ()\n\nfunction_name\n*************\n:ref:`cpp_ad_graph@function_name`\nis initialized to the empty string.\n\nn_dynamic_ind\n*************\n:ref:`cpp_ad_graph@n_dynamic_ind` is initialized as zero.\n\nn_variable_ind\n**************\n:ref:`cpp_ad_graph@n_variable_ind` is initialized as zero.\n\nconstant_vec\n************\n:ref:`cpp_ad_graph@constant_vec` is initialized as empty.\n\noperator_vec\n************\n:ref:`cpp_ad_graph@operator_vec` is initialized as empty.\n\noperator_arg\n************\n:ref:`cpp_ad_graph@operator_arg` is initialized as empty.\n\ndependent_vec\n*************\n:ref:`cpp_ad_graph@dependent_vec` is initialized as empty.\n\nParallel Mode\n*************\nThe first use of the ``cpp_graph`` constructor\ncannot be in :ref:`parallel<ta_in_parallel-name>` execution mode.\n\n{xrst_end cpp_graph_ctor}\n--------------------------------------------------------------------------------\n*/\npublic:\n   void initialize(void)\n   {  function_name_  = \"\";\n      n_dynamic_ind_  = 0;\n      n_variable_ind_  = 0;\n      discrete_name_vec_.resize(0);\n      atomic_name_vec_.resize(0);\n      print_text_vec_.resize(0);\n      constant_vec_.resize(0);\n      operator_vec_.resize(0);\n      operator_arg_.resize(0);\n      dependent_vec_.resize(0);\n      return;\n   }\n   cpp_graph(void)\n   {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n      static bool first = true;\n      if( first )\n      {  first = false;\n         CPPAD_ASSERT_UNKNOWN( local::graph::op_name2enum.size() == 0 );\n         // initialize cpp_graph global variables in cpp_graph_op.cpp\n         local::graph::set_operator_info();\n      }\n      initialize();\n   }\n/*\n---------------------------------------------------------------------------------\n{xrst_begin cpp_graph_scalar}\n\nC++ AD Graph Scalar Values\n##########################\n\nSyntax\n******\n\nGet\n===\n\n| *function_name* = *graph_obj* . ``function_name_get`` ()\n| *n_dynamic_ind* = *graph_obj* . ``n_dynamic_ind_get`` ()\n| *n_variable_ind* = *graph_obj* . ``n_variable_ind_get`` ()\n\nSet\n===\n\n| *graph_obj* . ``function_name_set`` ( *function_name* )\n| *graph_obj* . ``n_dynamic_ind_set`` ( *n_dynamic_ind* )\n| *graph_obj* . ``n_variable_ind_set`` ( *n_variable_ind* )\n\nSet\n***\nThe argument for all the set operations is const.\n\ngraph_obj\n*********\nis an ``cpp_graph`` object.\nIt is const for all the get functions.\n\nfunction_name\n*************\nis a ``std::string&`` specifying the name of the function\nfor this graph.\n\nn_dynamic_ind\n*************\nis a ``size_t`` specifying the number of independent dynamic parameters.\n\nn_variable_ind\n**************\nis a ``size_t`` specifying the number of independent variables.\n\n{xrst_end cpp_graph_scalar}\n*/\n   // function_name\n   const std::string& function_name_get(void) const\n   {  return function_name_; }\n   void function_name_set(const std::string& function_name)\n   {  function_name_ = function_name; }\n   //\n   // n_dynamic_ind\n   const size_t& n_dynamic_ind_get(void) const\n   {  return n_dynamic_ind_; }\n   void n_dynamic_ind_set(const size_t n_dynamic_ind)\n   {  n_dynamic_ind_ = n_dynamic_ind; }\n   //\n   // n_variable_ind\n   const size_t& n_variable_ind_get(void) const\n   {  return n_variable_ind_; }\n   void n_variable_ind_set(const size_t n_variable_ind)\n   {  n_variable_ind_ = n_variable_ind; }\n/*\n---------------------------------------------------------------------------------\n{xrst_begin cpp_graph_vector}\n\nC++ AD Graph Vector Values\n##########################\n\nSyntax\n******\n\nSize\n====\n\n| *size* = *graph_obj* . ``discrete_name_vec_size`` ()\n| *size* = *graph_obj* . ``atomic_name_vec_size`` ()\n| *size* = *graph_obj* . ``print_text_vec_size`` ()\n| *size* = *graph_obj* . ``constant_vec_size`` ()\n| *size* = *graph_obj* . ``operator_vec_size`` ()\n| *size* = *graph_obj* . ``operator_arg_size`` ()\n| *size* = *graph_obj* . ``dependent_vec_size`` ()\n\nGet\n===\n\n| *discrete_name* = *graph_obj* . ``discrete_name_vec_get`` ( *index* )\n| *atomic_name* = *graph_obj* . ``atomic_name_vec_get`` ( *index* )\n| *print_text* = *graph_obj* . ``print_text_vec_get`` ( *index* )\n| *constant* = *graph_obj* . ``constant_vec_get`` ( *index* )\n| *op_enum* = *graph_obj* . ``operator_vec_get`` ( *index* )\n| *argument* = *graph_obj* . ``operator_arg_get`` ( *index* )\n| *node_index* = *graph_obj* . ``dependent_vec_get`` ( *index* )\n\nPush Back\n=========\n\n| *graph_obj* . ``discrete_name_vec_push_back`` ( *discrete_name* )\n| *graph_obj* . ``atomic_name_vec_push_back`` ( *atomic_name* )\n| *graph_obj* . ``print_text_vec_push_back`` ( *print_text* )\n| *graph_obj* . ``constant_vec_push_back`` ( *constant* )\n| *graph_obj* . ``operator_vec_push_back`` ( *op_enum* )\n| *graph_obj* . ``operator_arg_push_back`` ( *argument* )\n| *graph_obj* . ``dependent_vec_push_back`` ( *node_index* )\n\nFind\n====\n\n| *discrete_index* = *graph_obj* . ``discrete_name_vec_find`` ( *discrete_name* )\n| *atomic_index* = *graph_obj* . ``atomic_name_vec_find`` ( *atomic_name* )\n| *print_index* = *graph_obj* . ``print_text_vec_find`` ( *print_text* )\n\nArguments\n*********\nAll of the member function arguments are either call by value or const.\n\nsize\n****\nis a ``size_t`` value equal to the current size of the specified vector.\n\nindex\n*****\nis a ``size_t`` value that must be less than the current size\nof the specified vector.\n\npush_back\n*********\nThe arguments for all the push_back functions are const.\nThe size of the specified vector before a push_back,\nis the index in the vector corresponding to the argument value.\nThe size of the vector after the push_back is the size before plus one.\n\ngraph_obj\n*********\nis an ``cpp_graph`` object.\nIt is const for the size, get, and find functions and\nnot const for the push_back functions.\n\ndiscrete_name\n*************\nis a ``std::string`` equal to the name of a :ref:`discrete-name` function.\n\natomic_name\n***********\nis a ``std::string`` equal to the name of an :ref:`atomic_three-name` function.\n\nprint_text\n**********\nis a ``std::string`` equal to the text to be printed.\n\nconstant\n********\nis a ``double`` equal to the constant with the corresponding\nindex in ``constant_vec`` .\n\nop_enum\n*******\nis the :ref:`graph_op_enum-name` for corresponding operator.\n\nargument\n********\nis the ``size_t`` value for corresponding operator argument.\n\nnode_index\n**********\nis the node index for the corresponding dependent variable with\nthe corresponding index in\n:ref:`cpp_ad_graph@dependent_vec` .\n\ndiscrete_index\n**************\nis the index such that\n\n   *discrete_name* == *graph_obj* . ``discrete_name_vec_get`` ( *discrete_index* )\n\nIf there is no such index,\n\n   *discrete_index* == *graph_obj* . ``discrete_name_vec_size`` ()\n\natomic_index\n************\nis the index such that\n\n   *atomic_name* == *graph_obj* . ``atomic_name_vec_get`` ( *atomic_index* )\n\nIf there is no such index,\n\n   *atomic_index* == *graph_obj* . ``atomic_name_vec_size`` ()\n\nprint_index\n***********\nis the index such that\n\n   *print_text* == *graph_obj* . ``print_text_vec_get`` ( *print_index* )\n\nIf there is no such index,\n\n   *print_index* == *graph_obj* . ``print_text_vec_size`` ()\n\n{xrst_end cpp_graph_vector}\n*/\n   // discrete_name_vec\n   const std::string& discrete_name_vec_get(size_t index) const\n   {  return discrete_name_vec_[index]; }\n   size_t discrete_name_vec_size(void) const\n   {  return discrete_name_vec_.size(); }\n   void discrete_name_vec_push_back(const std::string& discrete_name)\n   {  discrete_name_vec_.push_back(discrete_name); }\n   size_t discrete_name_vec_find(const std::string& discrete_name) const\n   {  for(size_t i = 0; i < discrete_name_vec_.size(); ++i)\n         if( discrete_name == discrete_name_vec_[i] )\n            return i;\n      return discrete_name_vec_.size();\n   }\n   //\n   // atomic_name_vec\n   const std::string& atomic_name_vec_get(size_t index) const\n   {  return atomic_name_vec_[index]; }\n   size_t atomic_name_vec_size(void) const\n   {  return atomic_name_vec_.size(); }\n   void atomic_name_vec_push_back(const std::string& atomic_name)\n   {  atomic_name_vec_.push_back(atomic_name); }\n   size_t atomic_name_vec_find(const std::string& atomic_name) const\n   {  for(size_t i = 0; i < atomic_name_vec_.size(); ++i)\n         if( atomic_name == atomic_name_vec_[i] )\n            return i;\n      return atomic_name_vec_.size();\n   }\n   //\n   // print_text_vec\n   const std::string& print_text_vec_get(size_t index) const\n   {  return print_text_vec_[index]; }\n   size_t print_text_vec_size(void) const\n   {  return print_text_vec_.size(); }\n   void print_text_vec_push_back(const std::string& atomic_name)\n   {  print_text_vec_.push_back(atomic_name); }\n   size_t print_text_vec_find(const std::string& print_text) const\n   {  for(size_t i = 0; i < print_text_vec_.size(); ++i)\n         if( print_text == print_text_vec_[i] )\n            return i;\n      return print_text_vec_.size();\n   }\n   //\n   // constant_vec\n   const double& constant_vec_get(size_t index) const\n   {  return constant_vec_[index]; }\n   size_t constant_vec_size(void) const\n   {  return constant_vec_.size(); }\n   void constant_vec_push_back(const double& constant)\n   {  constant_vec_.push_back(constant); }\n   //\n   // oerator_vec\n   const graph_op_enum& operator_vec_get(size_t index) const\n   {  return operator_vec_[index]; }\n   size_t operator_vec_size(void) const\n   {  return operator_vec_.size(); }\n   void operator_vec_push_back(const graph_op_enum op_enum)\n   {  operator_vec_.push_back(op_enum); }\n   //\n   // operator_arg\n   const size_t& operator_arg_get(size_t index) const\n   {  return operator_arg_[index]; }\n   size_t operator_arg_size(void) const\n   {  return operator_arg_.size(); }\n   void operator_arg_push_back(const size_t argument)\n   {  operator_arg_.push_back(argument); }\n   //\n   // dependent_vec\n   const size_t& dependent_vec_get(size_t index) const\n   {  return dependent_vec_[index]; }\n   size_t dependent_vec_size(void) const\n   {  return dependent_vec_.size(); }\n   void dependent_vec_push_back(const size_t node_index)\n   {  dependent_vec_.push_back(node_index); }\n/*\n{xrst_begin cpp_graph_print}\n{xrst_spell\n   ostream\n}\n\nPrint A C++ AD Graph\n####################\n\nSyntax\n******\n\n   *graph_obj* . ``print`` ( *os* )\n\ngraph_obj\n*********\nis an const ``cpp_graph`` object.\n\nos\n**\nIs the ``std::ostream`` where the graph is printed.\n\nDiscussion\n**********\nThis function is included to help with using the ``cpp_graph`` class.\nThe formatting of it's output is not part of the API; i.e.,\nit may change in the future.\n{xrst_toc_hidden\n   example/graph/print_graph.cpp\n}\nExample\n*******\nThe file :ref:`print_graph.cpp-name` contains an example and test of this operation.\n\n{xrst_end cpp_graph_print}\n*/\n   void print(std::ostream& os) const\n   {  using std::setw;\n      using std::string;\n      //\n      // function name\n      if( function_name_ != \"\" )\n         os << function_name_ << \"\\n\";\n      //\n      // initialize node index\n      size_t node_index = 1;\n      //\n      // text vector\n      size_t n_text = print_text_vec_.size();\n      for(size_t i = 0; i < n_text; ++i)\n      {  string s_i = \"c[\" + std::to_string(i) + \"]\";\n         //\n         os << setw(11) << \"\";\n         os << setw(10) << s_i;\n         os << \"'\" << print_text_vec_[i] << \"'\";\n         os << \"\\n\";\n      }\n      //\n      //  parameter vector\n      for(size_t i = 0; i < n_dynamic_ind_; i++)\n      {  string p_i = \"p[\" + std::to_string(i) + \"]\";\n         //\n         os << setw(11)  << node_index;\n         os << setw(10) << p_i;\n         os << \"\\n\";\n         ++node_index;\n      }\n      //\n      //  variable vector\n      for(size_t i = 0; i < n_variable_ind_; i++)\n      {  string x_i = \"x[\" + std::to_string(i) + \"]\";\n         //\n         os << setw(11)  << node_index;\n         os << setw(10) << x_i;\n         os << \"\\n\";\n         ++node_index;\n      }\n      //\n      //  constant vector\n      size_t n_constant = constant_vec_.size();\n      for(size_t i = 0; i < n_constant; i++)\n      {  string c_i = \"c[\" + std::to_string(i) + \"]\";\n         //\n         os << setw(11) << node_index;\n         os << setw(10) << c_i;\n         os << setw(20) << constant_vec_[i];\n         os << \"\\n\";\n         ++node_index;\n      }\n\n      size_t                    n_op = operator_vec_.size();\n      cpp_graph::const_iterator itr;\n      for(size_t op_index = 0; op_index < n_op; ++op_index)\n      {  if( op_index == 0 )\n            itr = begin();\n         else\n            ++itr;\n         cpp_graph::const_iterator::value_type itr_value = *itr;\n         //\n         const vector<size_t>& str_index( *itr_value.str_index_ptr );\n         const vector<size_t>&       arg( *itr_value.arg_node_ptr );\n         graph_op_enum          op_enum  = itr_value.op_enum;\n         size_t                n_result  = itr_value.n_result;\n         size_t                   n_arg  = arg.size();\n         CPPAD_ASSERT_UNKNOWN( n_arg > 0 );\n         //\n         string op_name = local::graph::op_enum2name[ op_enum ];\n         //\n         if( n_result == 0 )\n            os << setw(11) << \"\";\n         else if( n_result == 1 )\n            os << setw(11)  << node_index;\n         else\n         {  string first = std::to_string(node_index);\n            string last  = std::to_string(node_index + n_result - 1);\n            os << setw(11) << first + \"-\" + last;\n         }\n         os << setw(10) << op_name;\n         for(size_t i = 0; i < n_arg; ++i)\n            os << setw(5) << arg[i];\n\n         switch( op_enum )\n         {\n            case graph::discrete_graph_op:\n            CPPAD_ASSERT_UNKNOWN( str_index.size() == 1 );\n            os << discrete_name_vec_get( str_index[0] );\n            break;\n\n            case graph::atom_graph_op:\n            CPPAD_ASSERT_UNKNOWN( str_index.size() == 1 );\n            os << atomic_name_vec_get( str_index[0] );\n            break;\n\n            case graph::print_graph_op:\n            CPPAD_ASSERT_UNKNOWN( str_index.size() == 2 );\n            os << print_text_vec_get( str_index[0] ) << \",\";\n            os << print_text_vec_get( str_index[1] );\n            break;\n\n            default:\n            CPPAD_ASSERT_UNKNOWN( str_index.size() == 0 );\n            break;\n         }\n         os << \"\\n\";\n         node_index += n_result;\n      }\n      //\n      //  dependent vector\n      size_t n_dependent = dependent_vec_.size();\n      os << \"y nodes = \";\n      for(size_t i = 0; i < n_dependent; i++)\n      {  os << dependent_vec_[i];\n         if( i + 1 < n_dependent )\n            os << \", \";\n      }\n      os << \"\\n\";\n   }\n\n}; // END CPP_GRAPH_CLASS\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/graph/from_graph.hpp",
    "content": "# ifndef CPPAD_CORE_GRAPH_FROM_GRAPH_HPP\n# define CPPAD_CORE_GRAPH_FROM_GRAPH_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/core/ad_fun.hpp>\n# include <cppad/core/ad_type.hpp>\n# include <cppad/core/discrete/discrete.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*\n{xrst_begin from_graph}\n\nADFun Object Corresponding to a CppAD Graph\n###########################################\n\nSyntax\n******\n| |tab| ``cpp_graph`` *graph_obj*\n| |tab| ``ADFun`` < *Base* > *fun*\n| |tab| *fun* . ``from_graph`` ( *graph_obj* )\n| |tab| *fun* . ``from_graph`` ( *graph_obj* , *dyn2var* , *var2dyn* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ONE_ARGUMENT\n   // END_ONE_ARGUMENT\n}\n{xrst_literal\n   // BEGIN_WITH_IS_DYNAMIC\n   // END_WITH_IS_DYNAMIC\n}\n\nBase\n****\nis the type corresponding to this :ref:`adfun-name` object;\ni.e., its calculations are done using the type *Base* .\n\nRecBase\n*******\nin the prototype above, *RecBase* is the same type as *Base* .\n\ngraph_obj\n*********\nis a :ref:`cpp_ad_graph-name` representation of this function.\n\ndyn2var\n*******\nis a vector with size equal to the number of independent dynamic parameters\nin the graph; i.e., the size of :ref:`cpp_ad_graph@Node Indices@p` .\nIt specifies which independent dynamic parameters in the graph are\nindependent variables in the function *fun* .\n\nvar2dyn\n*******\nis a vector with size equal to the number of independent variables\nin the graph; i.e., the size of :ref:`cpp_ad_graph@Node Indices@x` .\nIt specifies which independent variables in the graph are\nindependent dynamic parameters in the function *fun* .\n\nfun\n***\nIt *dyn2var* and *var2dyn* are not present,\nthe independent dynamic parameters and independent variables in *fun*\nare the same as for the graph.\nOtherwise, they are described below.\n\nm_true, m_false\n===============\nLet *m_true* ( *m_false* ) be the number of true (false)\nelements of *dyn2var* .\n\nn_true, n_false\n===============\nLet *n_true* ( *n_false* ) be the number of true (false)\nelements of *var2dyn* .\n\nIndependent Dynamic Parameters\n==============================\nThe first *m_false* independent dynamic parameters in *fun*\ncorrespond to the false components of *dyn2var*\nand have the same order as in the graph.\nThe next *n_true* independent dynamic parameters in *fun*\ncorrespond to the true components of *var2dyn*\nand have the same order as in the graph.\n\nIndependent Variables\n=====================\nThe first *m_true* independent variables in *fun*\ncorrespond to the true components of *dyn2var*\nand have the same order as in the graph.\nThe next *n_false* independent variables in *fun*\ncorrespond to the false components of *var2dyn*\nand have the same order as in the graph.\n{xrst_toc_hidden\n   example/graph/switch_var_dyn.cpp\n}\nExamples\n********\nThe file :ref:`switch_var_dyn.cpp-name` contains an example and test\nof this routine.\nFor simpler examples, that do not change the dynamic parameters and variables;\nsee :ref:`graph_op_enum examples<graph_op_enum@Examples>` .\n\n{xrst_end from_graph}\n*/\n// BEGIN_WITH_IS_DYNAMIC\ntemplate <class Base, class RecBase>\nvoid CppAD::ADFun<Base,RecBase>::from_graph(\n      const CppAD::cpp_graph& graph_obj     ,\n      const CppAD::vector<bool>& dyn2var    ,\n      const CppAD::vector<bool>& var2dyn    )\n// END_WITH_IS_DYNAMIC\n{  using CppAD::isnan;\n   using namespace CppAD::graph;\n   //\n   // some sizes\n   const std::string function_name  = graph_obj.function_name_get();\n   const size_t n_dynamic_ind       = graph_obj.n_dynamic_ind_get();\n   const size_t n_variable_ind      = graph_obj.n_variable_ind_get();\n   const size_t n_constant          = graph_obj.constant_vec_size();\n   const size_t n_usage             = graph_obj.operator_vec_size();\n   const size_t n_dependent         = graph_obj.dependent_vec_size();\n   //\n   // n_dynamic_ind_fun\n   // n_variable_ind_fun\n   CPPAD_ASSERT_KNOWN(\n      n_variable_ind == var2dyn.size(),\n      \"from_graph: size of var2dyn not equal \"\n      \"number of independent variables in graph\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      n_dynamic_ind == dyn2var.size(),\n      \"from_graph: size of dyn2val not equal \"\n      \"number of independent dynamic parameters in graph\"\n   );\n   size_t n_dynamic_ind_fun  = 0;\n   size_t n_variable_ind_fun = 0;\n   for(size_t i = 0; i < n_dynamic_ind; ++i)\n   {  if( dyn2var[i] )\n         ++n_variable_ind_fun;\n      else\n         ++n_dynamic_ind_fun;\n   }\n   for(size_t i = 0; i < n_variable_ind; ++i)\n   {  if( var2dyn[i] )\n         ++n_dynamic_ind_fun;\n      else\n         ++n_variable_ind_fun;\n   }\n   //\n   // Start of node indices\n# ifndef NDEBUG\n   size_t start_dynamic_ind = 1;\n   size_t start_independent = start_dynamic_ind + n_dynamic_ind;\n   size_t start_constant    = start_independent + n_variable_ind;\n   size_t start_operator    = start_constant    + n_constant;\n# endif\n   //\n   // initialize mappings from node index as empty\n   // (there is no node zero)\n   vector<ad_type_enum>        node_type( 1 );\n   local::pod_vector<addr_t>   node2fun( 1 );\n   node_type[0] = number_ad_type_enum; // invalid value\n   node2fun[0]  = 0;                   // invalid value\n   //\n   // discrete_index\n   // mapping from index in discrete_name_vec to discrete index\n   size_t n_list_discrete  = discrete<Base>::list_size();\n   size_t n_graph_discrete = graph_obj.discrete_name_vec_size();\n   vector<size_t> discrete_index( n_graph_discrete );\n   for(size_t i = 0; i < n_graph_discrete; ++i)\n      discrete_index[i] = n_list_discrete; // invalid discrete index\n   for(size_t index = 0; index < n_list_discrete; ++index)\n   {  const std::string& name( discrete<Base>::name(index) );\n      size_t graph_index = graph_obj.discrete_name_vec_find(name);\n      if( graph_index != n_graph_discrete )\n      {  if( discrete_index[graph_index] != n_list_discrete )\n         {  std::string msg = \"from_graph: error in call to \";\n            msg += name;\n            msg += \".\\nThere is more than one discrete \";\n            msg += \"function with this name\";\n            //\n            // use this source code as point of detection\n            bool known       = true;\n            int  line        = __LINE__;\n            const char* file = __FILE__;\n            const char* exp  = \"discrete_index[i] == n_list_discrete\";\n            //\n            // CppAD error handler\n            ErrorHandler::Call( known, line, file, exp, msg.c_str() );\n         }\n         discrete_index[graph_index] = index;\n      }\n   }\n   //\n   // atomic_name2index\n   // mapping from index in atomic_name_vec to atomic three index\n   size_t n_graph_atomic = graph_obj.atomic_name_vec_size();\n   vector<size_t> atomic_name2index( n_graph_atomic );\n   for(size_t index = 0; index < n_graph_atomic; ++index)\n      atomic_name2index[index] = 0; // invalid atomic index\n\n   {  bool        set_null = true;\n      size_t      index_in = 0;\n      size_t      type;\n      std::string name;\n      void*       ptr;\n      size_t n_atomic = CppAD::local::atomic_index<RecBase>(\n         set_null, index_in, type, &name, ptr\n      );\n      set_null = false;\n      for(index_in = 1; index_in <= n_atomic; ++index_in)\n      {  CppAD::local::atomic_index<RecBase>(\n            set_null, index_in, type, &name, ptr\n         );\n         size_t graph_index = graph_obj.atomic_name_vec_find(name);\n         if( graph_index != n_graph_atomic )\n         {  if( atomic_name2index[graph_index] != 0 )\n            {  std::string msg = \"from_graph: error in call to \";\n               msg += name + \".\\n\";\n               msg += \"There is more than one atomic \";\n               msg += \"function with this name\";\n               //\n               // use this source code as point of detection\n               bool known       = true;\n               int  line        = __LINE__;\n               const char* file = __FILE__;\n               const char* exp  = \"atomic_index[index] == 0\";\n               //\n               // CppAD error handler\n               ErrorHandler::Call(\n                  known, line, file, exp, msg.c_str()\n               );\n            }\n            atomic_name2index[graph_index] = index_in;\n         }\n      }\n   }\n   // ----------------------------------------------------------------------\n   // Create a recording for this function\n   // ----------------------------------------------------------------------\n\n   // start a recording\n   local::recorder<Base> rec;\n   CPPAD_ASSERT_UNKNOWN( rec.num_var_op() == 0 );\n   rec.set_n_dyn_independent(n_dynamic_ind_fun);\n   rec.set_abort_op_index(0);\n   rec.set_record_compare(false);\n\n   // rec_text_index\n   // mapping from print_text_vec index to recording index\n   vector<addr_t> rec_text_index( graph_obj.print_text_vec_size() );\n   for(size_t i = 0; i < graph_obj.print_text_vec_size(); ++i)\n   {  const std::string& text = graph_obj.print_text_vec_get(i);\n      rec_text_index[i]       = rec.PutTxt( text.c_str() );\n   }\n\n   // nan\n   Base nan = CppAD::numeric_limits<Base>::quiet_NaN();\n\n   // Place the parameter with index 0 in the tape\n   const local::pod_vector_maybe<Base>& parameter( rec.par_all());\n   CPPAD_ASSERT_UNKNOWN( parameter.size() == 0 );\n   addr_t i_par = rec.put_con_par(nan);\n   CPPAD_ASSERT_UNKNOWN( i_par == 0 );\n   CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_par] ) );\n   //\n   // Place the variable with index 0 in the tape\n   CPPAD_ASSERT_NARG_NRES(local::BeginOp, 1, 1);\n   rec.PutOp(local::BeginOp);\n   rec.PutArg(0);\n   //\n   // Next come the independent dynamic parameters in the graph\n   addr_t i_var = 0;\n   for(size_t i = 0; i < n_dynamic_ind; ++i)\n   {\n      if( dyn2var[i] )\n      {  i_var = rec.PutOp( local::InvOp );\n         node_type.push_back(variable_enum);;\n         node2fun.push_back(i_var);\n      }\n       else\n      {  i_par = rec.put_dyn_par(nan, local::ind_dyn );\n         CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_par] ) );\n         node_type.push_back(dynamic_enum);\n         node2fun.push_back(i_par);\n      }\n   }\n\n   // Next come the independent variables in the graph\n   CPPAD_ASSERT_NARG_NRES(local::InvOp, 0, 1);\n   for(size_t i = 0; i < n_variable_ind; ++i)\n   {  if( var2dyn[i] )\n      {  i_par = rec.put_dyn_par(nan, local::ind_dyn );\n         CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_par] ) );\n         node_type.push_back(dynamic_enum);\n         node2fun.push_back(i_par);\n      }\n      else\n      {  i_var = rec.PutOp( local::InvOp );\n         node_type.push_back(variable_enum);;\n         node2fun.push_back(i_var);\n      }\n   }\n   CPPAD_ASSERT_UNKNOWN( size_t( i_par ) == n_dynamic_ind_fun );\n   CPPAD_ASSERT_UNKNOWN( size_t( i_var ) == n_variable_ind_fun );\n\n   // Next come the constant parameters\n   for(size_t i = 0; i < n_constant; ++i)\n   {  Base par = Base( graph_obj.constant_vec_get(i) );\n      i_par = rec.put_con_par(par);\n      CPPAD_ASSERT_UNKNOWN( parameter[i_par] == par );\n      //\n      node_type.push_back(constant_enum);;\n      node2fun.push_back(i_par);\n   }\n\n   //\n   // local arrays used to avoid reallocating memory\n   local::pod_vector<addr_t>       temporary;\n   vector<ad_type_enum>            type_x;\n   vector<addr_t>                  arg;\n   vector<size_t>                  arg_node;\n   //\n   // arrays only used by atom_graph_op, atom4_graph_op\n   vector<Base>                    parameter_x, taylor_y;\n   vector<ad_type_enum>            type_y;\n   vector< AD<Base> >              ax, ay;\n   vector<bool>                    select_y;\n   //\n   // define here because not using as loop index\n   cpp_graph::const_iterator       graph_itr;\n   //\n   // loop over operators in the recording\n# ifndef NDEBUG\n   size_t start_result = start_operator;\n# endif\n   for(size_t op_index = 0; op_index < n_usage; ++op_index)\n   {  // op_enum, str_index, n_result, arg_node\n      if( op_index == 0 )\n         graph_itr = graph_obj.begin();\n      else\n         ++graph_itr;\n      cpp_graph::const_iterator::value_type itr_value = *graph_itr;\n      const vector<size_t>& str_index(*itr_value.str_index_ptr );\n      graph_op_enum op_enum    = itr_value.op_enum;\n      size_t        n_result   = itr_value.n_result;\n      size_t        call_id    = itr_value.call_id;\n      size_t        n_arg      = itr_value.arg_node_ptr->size();\n      arg.resize(n_arg);\n      //\n      // make sure type_x is large enough\n      type_x.resize(n_arg);\n# ifndef NDEBUG\n      addr_t n_con_arg      = 0;\n# endif\n      addr_t n_dyn_arg      = 0;\n      addr_t n_var_arg      = 0;\n      for(size_t j = 0; j < n_arg; ++j)\n      {  size_t node_index = (*itr_value.arg_node_ptr)[j];\n         //\n         // argument to graph operator\n         CPPAD_ASSERT_KNOWN( node_index < start_result,\n            \"from_graph op argument index is greater or equal\\n\"\n            \"the starting index for the next result\"\n         );\n         //\n         // type of argument\n         type_x[j] = node_type[ node_index ];\n         //\n         // argument to function operator\n         arg[j]  = node2fun[ node_index ];\n         CPPAD_ASSERT_UNKNOWN( arg[j] != 0 );\n         //\n         // count number of arguments of different types\n# ifndef NDEBUG\n         n_con_arg += addr_t( type_x[j] == constant_enum );\n# endif\n         n_dyn_arg += addr_t( type_x[j] == dynamic_enum  );\n         n_var_arg += addr_t( type_x[j] == variable_enum );\n      }\n      CPPAD_ASSERT_UNKNOWN(\n         n_arg == size_t(n_con_arg + n_dyn_arg + n_var_arg)\n      );\n      //\n      addr_t i_result = 0; // invalid value\n      // -------------------------------------------------------------------\n      // conditional expressions\n      // -------------------------------------------------------------------\n      if( op_enum == cexp_eq_graph_op ||\n         op_enum == cexp_le_graph_op ||\n         op_enum == cexp_lt_graph_op )\n      {  CPPAD_ASSERT_UNKNOWN( n_result == 1 && n_arg == 4 );\n         // cop\n         CompareOp cop;\n         if( op_enum == cexp_eq_graph_op )\n            cop = CompareEq;\n         else if ( op_enum == cexp_le_graph_op )\n            cop = CompareLe;\n         else\n            cop = CompareLt;\n         //\n         if( n_var_arg == 0 )\n         {  if( n_dyn_arg == 0 )\n            {  // result is a constant parameter\n               Base result = CondExpOp(cop,\n                  parameter[arg[0]],  // left\n                  parameter[arg[1]],  // right\n                  parameter[arg[2]],  // if_true\n                  parameter[arg[3]]   // if_false\n               );\n               i_result = rec.put_con_par(result);\n            }\n            else\n            {  i_result = rec.put_dyn_cond_exp(\n                  nan, cop, arg[0], arg[1], arg[2], arg[3]\n               );\n            }\n         }\n         else\n         {  // flag marking which arguments are variables\n            addr_t flag = 0;\n            addr_t bit  = 1;\n            for(size_t j = 0; j < 4; ++j)\n            {  if( type_x[j] == variable_enum )\n                  flag |= bit;\n               bit = 2 * bit;\n            }\n            CPPAD_ASSERT_UNKNOWN( flag != 0 );\n            rec.PutArg(addr_t(cop), flag, arg[0], arg[1], arg[2], arg[3]);\n            i_result = rec.PutOp(local::CExpOp);\n         }\n      }\n      // -------------------------------------------------------------------\n      // compare operators\n      // -------------------------------------------------------------------\n      else if(\n         op_enum == comp_eq_graph_op ||\n         op_enum == comp_le_graph_op ||\n         op_enum == comp_lt_graph_op ||\n         op_enum == comp_ne_graph_op )\n      {  CPPAD_ASSERT_UNKNOWN( n_result == 0 && n_arg == 2 );\n         //\n         bool var_left  = type_x[0] == variable_enum;\n         bool var_right = type_x[1] == variable_enum;\n         bool dyn_left  = type_x[0] == dynamic_enum;\n         bool dyn_right = type_x[1] == dynamic_enum;\n         //\n         ax.resize(n_arg);\n         // ax[0]\n         if( var_left | dyn_left )\n            ax[0].taddr_ = arg[0];\n         else\n            ax[0].value_ = parameter_x[0];\n         // ax[1]\n         if( var_right | dyn_right )\n            ax[1].taddr_ = arg[1];\n         else\n            ax[1].value_ = parameter_x[1];\n         //\n         bool result;\n         switch( op_enum )\n         {\n            case comp_eq_graph_op:\n            result = true;\n            rec.comp_eq(\n            var_left, var_right, dyn_left, dyn_right, ax[0], ax[1], result\n            );\n            break;\n\n            case comp_le_graph_op:\n            result = true;\n            rec.comp_le(\n            var_left, var_right, dyn_left, dyn_right, ax[0], ax[1], result\n            );\n            break;\n\n            case comp_lt_graph_op:\n            result = true;\n            rec.comp_lt(\n            var_left, var_right, dyn_left, dyn_right, ax[0], ax[1], result\n            );\n            break;\n\n            case comp_ne_graph_op:\n            result = false;\n            rec.comp_eq(\n            var_left, var_right, dyn_left, dyn_right, ax[0], ax[1], result\n            );\n            break;\n\n\n            default:\n            CPPAD_ASSERT_UNKNOWN(false);\n         }\n      }\n      // -------------------------------------------------------------------\n      // sum operator\n      // -------------------------------------------------------------------\n      else if( op_enum == sum_graph_op )\n      {\n         CPPAD_ASSERT_KNOWN( n_result == 1 ,\n            \"AD graph sum operator: n_result is not 1\"\n         );\n         if( n_var_arg == 0 )\n         {  // result of the sum is a parameter\n            Base sum_constant = 0.0;\n            temporary.resize(0);\n            for(size_t j = 0; j < n_arg; j++)\n            {  if( type_x[j] == constant_enum )\n                  sum_constant += parameter[ arg[j] ];\n               else\n               {  CPPAD_ASSERT_UNKNOWN( type_x[j] == dynamic_enum );\n                  temporary.push_back( arg[j] );\n               }\n            }\n            CPPAD_ASSERT_UNKNOWN( temporary.size() == size_t(n_dyn_arg) );\n            //\n            // start with constant parameter\n            i_result = rec.put_con_par(sum_constant);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == sum_constant );\n            //\n            // sum the dynamic parameters\n            for(addr_t j = 0; j < n_dyn_arg; ++j)\n            {  i_result = rec.put_dyn_par(\n                  nan, local::add_dyn, i_result, temporary[j]\n               );\n               CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            }\n         }\n         else\n         {  // result of the sum is a variable\n            size_t n_temporary = 6 + size_t(n_var_arg + n_dyn_arg);\n            if( temporary.size() < n_temporary )\n               temporary.resize( n_temporary );\n            Base sum_constant = 0.0;\n            addr_t j_variable = 5 ;\n            addr_t j_dynamic  = 5 + n_var_arg;\n            for(size_t j = 0; j < n_arg; j++)\n            {  if( type_x[j] == constant_enum )\n                  sum_constant += parameter[ arg[j] ];\n               if( type_x[j] == variable_enum )\n                  temporary[ j_variable++ ] = arg[j];\n               if( type_x[j] == dynamic_enum )\n                  temporary[ j_dynamic++ ]  = arg[j];\n            }\n            // number of arguments to this operator\n            temporary[j_dynamic] = j_dynamic + 1;\n            //\n            temporary[0] = rec.put_con_par(sum_constant);\n            CPPAD_ASSERT_UNKNOWN(parameter[temporary[0]] == sum_constant);\n            //\n            temporary[1] = 5 + n_var_arg;\n            temporary[2] = 5 + n_var_arg;\n            temporary[3] = temporary[2] + n_dyn_arg;\n            temporary[4] = temporary[2] + n_dyn_arg;\n            //\n            i_result = rec.PutOp(local::CSumOp);\n            for(size_t j = 0; j < n_temporary; ++j)\n               rec.PutArg( temporary[j] );\n            CPPAD_ASSERT_UNKNOWN( local::NumRes(local::CSumOp) == 1 );\n         }\n      }\n      // -------------------------------------------------------------------\n      // print operator\n      // -------------------------------------------------------------------\n      else if( op_enum == print_graph_op )\n      {  CPPAD_ASSERT_UNKNOWN( n_arg == 2 && n_result == 0 );\n         //\n         // before\n         size_t before_graph = str_index[0];\n         addr_t before_rec   = rec_text_index[before_graph];\n         //\n         // after\n         size_t after_graph  = str_index[1];\n         addr_t after_rec    = rec_text_index[after_graph];\n         //\n         // base 2 representation of [ Var(notpos), Var(value) ]\n         addr_t is_var = 0;\n         if( type_x[0] == variable_enum )\n            is_var += 1;\n         if( type_x[1] == variable_enum )\n            is_var += 2;\n         //\n         // record this print operator\n         addr_t notpos = arg[0];\n         addr_t value  = arg[1];\n         rec.PutOp(local::PriOp);\n         rec.PutArg(is_var, notpos, before_rec, value, after_rec);\n      }\n      // -------------------------------------------------------------------\n      // discrete operator\n      // -------------------------------------------------------------------\n      else if( op_enum == discrete_graph_op )\n      {  CPPAD_ASSERT_UNKNOWN( n_arg == 1 && n_result == 1 );\n         size_t name_index = str_index[0];\n         size_t function_index = discrete_index[name_index];\n         if( function_index == n_list_discrete )\n         {  std::string msg = \"from_graph: error in call to \";\n            msg += graph_obj.discrete_name_vec_get(name_index);\n            msg += \".\\nNo previously defined discrete function \";\n            msg += \"has this name\";\n            //\n            // use this source code as point of detection\n            bool known       = true;\n            int  line        = __LINE__;\n            const char* file = __FILE__;\n            const char* exp  =\n               \"discrete_index[name_index] != n_list_discrete\";\n            //\n            // CppAD error handler\n            ErrorHandler::Call(known, line, file, exp, msg.c_str());\n         }\n         if( type_x[0] == variable_enum )\n         {  CPPAD_ASSERT_NARG_NRES(local::DisOp, 2, 1);\n            i_result = rec.PutOp(local::DisOp);\n            rec.PutArg( addr_t(function_index) );\n            rec.PutArg( arg[0] );\n         }\n         else if( type_x[0] == dynamic_enum )\n         {  i_result = rec.put_dyn_par(\n               nan, local::dis_dyn, addr_t(function_index), arg[0]\n            );\n         }\n         else\n         {  Base result = discrete<Base>::eval(\n               function_index, parameter[ arg[0] ]\n            );\n            i_result = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n         }\n      }\n      // -------------------------------------------------------------------\n      // atomic operator\n      // -------------------------------------------------------------------\n      else if( op_enum == atom_graph_op || op_enum == atom4_graph_op )\n      {  size_t name_index = str_index[0];\n         //\n         // atomic_index\n         CPPAD_ASSERT_UNKNOWN( name_index < atomic_name2index.size() );\n         size_t atomic_index = atomic_name2index[name_index];\n         if( atomic_index == 0 )\n         {  std::string msg = \"from_graph: error in call to \";\n            msg += graph_obj.atomic_name_vec_get(name_index);\n            msg += \".\\n\";\n            msg += \"No previously defined atomic function \";\n            msg += \"has this name\";\n            //\n            // use this source code as point of detection\n            bool known       = true;\n            int  line        = __LINE__;\n            const char* file = __FILE__;\n            const char* exp  = \"atomic_index != 0\";\n            //\n            // CppAD error handler\n            ErrorHandler::Call(known, line, file, exp, msg.c_str());\n         }\n         //\n         // parameter_x\n         parameter_x.resize(n_arg);\n         for(size_t j = 0; j < n_arg; ++j)\n         {  if( type_x[j] == constant_enum )\n               parameter_x[j] = parameter[ arg[j] ];\n            else\n               parameter_x[j] = nan;\n         }\n         //\n         // type, name, v_ptr\n         bool         set_null = false;\n         size_t       type;\n         std::string* name = nullptr;\n         void*        v_ptr;\n         CppAD::local::atomic_index<RecBase>(\n            set_null, atomic_index, type, name, v_ptr\n         );\n         CPPAD_ASSERT_KNOWN( 2 < type,\n            \"from_graph: attempt to use an atomic function with < 3\"\n         );\n         //\n         // type_y, taylor_y\n         type_y.resize(n_result);\n         size_t order_low = 0;\n         size_t order_up  = 0;\n         if( type == 3 )\n         {  // afun\n            atomic_three<RecBase>* afun =\n               reinterpret_cast< atomic_three<RecBase>* >( v_ptr );\n            //\n            // type_y\n            afun->for_type(parameter_x, type_x, type_y);\n            //\n            // taylor_y\n            size_t need_y    = size_t(constant_enum);\n            taylor_y.resize(n_result);\n            afun->forward(\n               parameter_x ,\n               type_x      ,\n               need_y      ,\n               order_low   ,\n               order_up    ,\n               parameter_x ,\n               taylor_y\n            );\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( type == 4 );\n            // afun\n            atomic_four<RecBase>* afun =\n               reinterpret_cast< atomic_four<RecBase>* >( v_ptr );\n            //\n            // type_x\n            for(size_t j = 0; j < n_arg; ++j)\n            {  if( type_x[j] == constant_enum )\n                  if( parameter[ arg[j] ] == Base(0) )\n                     type_x[j] = identical_zero_enum;\n            }\n            //\n            // type_y\n            afun->for_type(call_id, type_x, type_y);\n            for(size_t i = 0; i < n_result; ++i)\n            {  if( type_y[i] == identical_zero_enum )\n                  type_y[i] = constant_enum;\n            }\n            //\n            // type_x\n            for(size_t j = 0; j < n_arg; ++j)\n               if( type_x[j] == identical_zero_enum )\n                  type_x[j] = constant_enum;\n            //\n            // select_y\n            select_y.resize(n_result);\n            for(size_t i = 0; i < n_result; ++i)\n               select_y[i] = type_y[i] == constant_enum;\n            //\n            // taylor_y\n            taylor_y.resize(n_result);\n            afun->forward(\n               call_id     ,\n               select_y    ,\n               order_low   ,\n               order_up    ,\n               parameter_x ,\n               taylor_y\n            );\n         }\n         //\n         // record_dynamic, record_variable\n         bool record_dynamic  = false;\n         bool record_variable = false;\n         for(size_t i = 0; i < n_result; ++i)\n         {  CPPAD_ASSERT_UNKNOWN( type_y[i] <= variable_enum );\n            record_dynamic  |= type_y[i] == dynamic_enum;\n            record_variable |= type_y[i] == variable_enum;\n         }\n         // tape_id is zero because not a true recording\n         tape_id_t tape_id = 0;\n         //\n         // ax, ay\n         if( record_dynamic || record_variable )\n         {  // tape_id (not a recording AD<Base> operations)\n            // ax\n            ax.resize(n_arg);\n            for(size_t j = 0; j < n_arg; ++j)\n            {  ax[j].value_ = parameter_x[j];\n               ax[j].taddr_ = arg[j];\n            }\n            // ay\n            ay.resize(n_result);\n            for(size_t i = 0; i < n_result; ++i)\n            {  ay[i].value_ = nan; // not_used\n               ay[i].taddr_ = 0;   // not used\n            }\n         }\n         if( record_dynamic ) rec.put_dyn_atomic(\n               tape_id, atomic_index, call_id, type_x, type_y, ax, ay\n         );\n         if( record_variable ) rec.put_var_atomic(\n               tape_id, atomic_index, call_id, type_x, type_y, ax, ay\n         );\n         //\n         // node_type, node2fun\n         for(size_t i = 0; i < n_result; ++i)\n         {  node_type.push_back(type_y[i]);\n                 switch( type_y[i] )\n            {  case constant_enum:\n               node2fun.push_back(rec.put_con_par(taylor_y[i]));\n               break;\n\n               case dynamic_enum:\n               case variable_enum:\n               node2fun.push_back(ay[i].taddr_);\n               break;\n\n               default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               break;\n            }\n         }\n      }\n      // -------------------------------------------------------------------\n      // unary operators\n      // -------------------------------------------------------------------\n      else if( n_arg == 1 )\n      {  CPPAD_ASSERT_UNKNOWN( n_arg == 1 && n_result == 1 );\n         Base result; // used in cases argument is a constant\n         if( type_x[0] == variable_enum ) switch( op_enum )\n         {\n            case abs_graph_op:\n            i_result = rec.PutOp(local::AbsOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::AbsOp) == 1 );\n            break;\n\n            case acosh_graph_op:\n            i_result = rec.PutOp(local::AcoshOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::AcoshOp) == 1 );\n            break;\n\n            case asinh_graph_op:\n            i_result = rec.PutOp(local::AsinhOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::AsinhOp) == 1 );\n            break;\n\n            case atanh_graph_op:\n            i_result = rec.PutOp(local::AtanhOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::AtanhOp) == 1 );\n            break;\n\n            case erf_graph_op:\n            i_result = rec.PutOp(local::ErfOp);\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::ErfOp) == 3 );\n            //\n            // arg[0] = variable index for function argument\n            rec.PutArg( arg[0] );\n            //\n            // parameter[ arg[1] ] = 0.0\n            i_par = rec.put_con_par( Base(0.0) );\n            rec.PutArg( i_par );\n            //\n            // parameter[ arg[2] ] = 2 / sqrt(pi)\n            i_par = rec.put_con_par(Base(\n               1.0 / std::sqrt( std::atan(1.0) )\n            ));\n            rec.PutArg( i_par );\n            //\n            break;\n\n            case erfc_graph_op:\n            i_result = rec.PutOp(local::ErfcOp);\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::ErfcOp) == 3 );\n            //\n            // arg[0] = variable index for function argument\n            rec.PutArg( arg[0] );\n            //\n            // parameter[ arg[1] ] = 0.0\n            i_par = rec.put_con_par( Base(0.0) );\n            rec.PutArg( i_par );\n            //\n            // parameter[ arg[2] ] = 2 / sqrt(pi)\n            i_par = rec.put_con_par(Base(\n               1.0 / std::sqrt( std::atan(1.0) )\n            ));\n            rec.PutArg( i_par );\n            //\n            break;\n\n            case expm1_graph_op:\n            i_result = rec.PutOp(local::Expm1Op);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::Expm1Op) == 1 );\n            break;\n\n            case log1p_graph_op:\n            i_result = rec.PutOp(local::Log1pOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::Log1pOp) == 1 );\n            break;\n\n            case acos_graph_op:\n            i_result = rec.PutOp(local::AcosOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::AcosOp) == 1 );\n            break;\n\n            case asin_graph_op:\n            i_result = rec.PutOp(local::AsinOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::AsinOp) == 1 );\n            break;\n\n            case atan_graph_op:\n            i_result = rec.PutOp(local::AtanOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::AtanOp) == 1 );\n            break;\n\n            case cosh_graph_op:\n            i_result = rec.PutOp(local::CoshOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::CoshOp) == 1 );\n            break;\n\n            case cos_graph_op:\n            i_result = rec.PutOp(local::CosOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::CosOp) == 1 );\n            break;\n\n            case exp_graph_op:\n            i_result = rec.PutOp(local::ExpOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::ExpOp) == 1 );\n            break;\n\n            case log_graph_op:\n            i_result = rec.PutOp(local::LogOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::LogOp) == 1 );\n            break;\n\n            case neg_graph_op:\n            i_result = rec.PutOp(local::NegOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::NegOp) == 1 );\n            break;\n\n            case sign_graph_op:\n            i_result = rec.PutOp(local::SignOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::SignOp) == 1 );\n            break;\n\n            case sinh_graph_op:\n            i_result = rec.PutOp(local::SinhOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::SinhOp) == 1 );\n            break;\n\n            case sin_graph_op:\n            i_result = rec.PutOp(local::SinOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::SinOp) == 1 );\n            break;\n\n            case sqrt_graph_op:\n            i_result = rec.PutOp(local::SqrtOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::SqrtOp) == 1 );\n            break;\n\n            case tanh_graph_op:\n            i_result = rec.PutOp(local::TanhOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::TanhOp) == 1 );\n            break;\n\n            case tan_graph_op:\n            i_result = rec.PutOp(local::TanOp);\n            rec.PutArg( arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::TanOp) == 1 );\n            break;\n\n            default:\n            CPPAD_ASSERT_UNKNOWN( false );\n            break;\n         }\n         else if( type_x[0] == dynamic_enum ) switch( op_enum )\n         {\n            case abs_graph_op:\n            i_result = rec.put_dyn_par(nan, local::abs_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case acosh_graph_op:\n            i_result = rec.put_dyn_par(nan, local::acosh_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case asinh_graph_op:\n            i_result = rec.put_dyn_par(nan, local::asinh_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case atanh_graph_op:\n            i_result = rec.put_dyn_par(nan, local::atanh_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case erf_graph_op:\n            i_result = rec.put_dyn_par(nan, local::erf_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case erfc_graph_op:\n            i_result = rec.put_dyn_par(nan, local::erfc_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case expm1_graph_op:\n            i_result = rec.put_dyn_par(nan, local::expm1_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case log1p_graph_op:\n            i_result = rec.put_dyn_par(nan, local::log1p_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case acos_graph_op:\n            i_result = rec.put_dyn_par(nan, local::acos_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case asin_graph_op:\n            i_result = rec.put_dyn_par(nan, local::asin_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case atan_graph_op:\n            i_result = rec.put_dyn_par(nan, local::atan_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case cosh_graph_op:\n            i_result = rec.put_dyn_par(nan, local::cosh_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case cos_graph_op:\n            i_result = rec.put_dyn_par(nan, local::cos_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case exp_graph_op:\n            i_result = rec.put_dyn_par(nan, local::exp_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case log_graph_op:\n            i_result = rec.put_dyn_par(nan, local::log_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case neg_graph_op:\n            i_result = rec.put_dyn_par(nan, local::neg_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case sign_graph_op:\n            i_result = rec.put_dyn_par(nan, local::sign_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case sinh_graph_op:\n            i_result = rec.put_dyn_par(nan, local::sinh_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case sin_graph_op:\n            i_result = rec.put_dyn_par(nan, local::sin_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case sqrt_graph_op:\n            i_result = rec.put_dyn_par(nan, local::sqrt_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case tanh_graph_op:\n            i_result = rec.put_dyn_par(nan, local::tanh_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case tan_graph_op:\n            i_result = rec.put_dyn_par(nan, local::tan_dyn, arg[0] );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            default:\n            CPPAD_ASSERT_UNKNOWN( false );\n            break;\n         }\n         else switch( op_enum )\n         {\n            case abs_graph_op:\n            result    = CppAD::abs( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case acosh_graph_op:\n            result    = CppAD::acosh( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case asinh_graph_op:\n            result    = CppAD::asinh( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case atanh_graph_op:\n            result    = CppAD::atanh( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case erf_graph_op:\n            result    = CppAD::erf( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case erfc_graph_op:\n            result    = CppAD::erfc( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case expm1_graph_op:\n            result    = CppAD::expm1( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case log1p_graph_op:\n            result    = CppAD::log1p( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case acos_graph_op:\n            result    = CppAD::acos( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case asin_graph_op:\n            result    = CppAD::asin( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case atan_graph_op:\n            result    = CppAD::atan( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case cosh_graph_op:\n            result    = CppAD::cosh( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case cos_graph_op:\n            result    = CppAD::cos( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case exp_graph_op:\n            result    = CppAD::exp( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case log_graph_op:\n            result    = CppAD::log( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case neg_graph_op:\n            result    = - parameter[ arg[0] ];\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case sign_graph_op:\n            result    = CppAD::sign( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case sinh_graph_op:\n            result    = CppAD::sinh( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case sin_graph_op:\n            result    = CppAD::sin( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case sqrt_graph_op:\n            result    = CppAD::sqrt( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case tanh_graph_op:\n            result    = CppAD::tanh( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case tan_graph_op:\n            result    = CppAD::tan( parameter[ arg[0] ] );\n            i_result  = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            default:\n            CPPAD_ASSERT_UNKNOWN( false );\n            break;\n         }\n      }\n      // -------------------------------------------------------------------\n      // binary operators\n      // -------------------------------------------------------------------\n      else\n      {  CPPAD_ASSERT_UNKNOWN( n_arg == 2 && n_result == 1 );\n         Base result; // used in cases where both arguments are constants\n         if( type_x[0] == variable_enum && type_x[1] == variable_enum )\n         switch( op_enum )\n         {\n            case add_graph_op:\n            i_result = rec.PutOp(local::AddvvOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::AddvvOp) == 2 );\n            break;\n\n            case azmul_graph_op:\n            i_result = rec.PutOp(local::ZmulvvOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::ZmulvvOp) == 2 );\n            break;\n\n            case div_graph_op:\n            i_result = rec.PutOp(local::DivvvOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::DivvvOp) == 2 );\n            break;\n\n            case mul_graph_op:\n            i_result = rec.PutOp(local::MulvvOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::MulvvOp) == 2 );\n            break;\n\n            case pow_graph_op:\n            i_result = rec.PutOp(local::PowvvOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::PowvvOp) == 2 );\n            break;\n\n            case sub_graph_op:\n            i_result = rec.PutOp(local::SubvvOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::SubvvOp) == 2 );\n            break;\n\n            default:\n            CPPAD_ASSERT_UNKNOWN( false );\n            break;\n         }\n         else if( type_x[0] == variable_enum ) switch( op_enum )\n         {\n            // addition is communitative, so use Addpv\n            case add_graph_op:\n            i_result = rec.PutOp(local::AddpvOp);\n            rec.PutArg( arg[1], arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::AddpvOp) == 2 );\n            break;\n\n            case azmul_graph_op:\n            i_result = rec.PutOp(local::ZmulvpOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::ZmulvpOp) == 2 );\n            break;\n\n            case div_graph_op:\n            i_result = rec.PutOp(local::DivvpOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::DivvpOp) == 2 );\n            break;\n\n            // multiplication is communitative, so use Mulpv\n            case mul_graph_op:\n            i_result = rec.PutOp(local::MulpvOp);\n            rec.PutArg( arg[1], arg[0] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::MulpvOp) == 2 );\n            break;\n\n            case pow_graph_op:\n            i_result = rec.PutOp(local::PowvpOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::PowvpOp) == 2 );\n            break;\n\n            case sub_graph_op:\n            i_result = rec.PutOp(local::SubvpOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::SubvpOp) == 2 );\n            break;\n\n            default:\n            CPPAD_ASSERT_UNKNOWN( false );\n            break;\n         }\n         else if( type_x[1] == variable_enum ) switch( op_enum )\n         {\n            case add_graph_op:\n            i_result = rec.PutOp(local::AddpvOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::AddpvOp) == 2 );\n            break;\n\n            case azmul_graph_op:\n            i_result = rec.PutOp(local::ZmulpvOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::ZmulpvOp) == 2 );\n            break;\n\n            case div_graph_op:\n            i_result = rec.PutOp(local::DivpvOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::DivpvOp) == 2 );\n            break;\n\n            case mul_graph_op:\n            i_result = rec.PutOp(local::MulpvOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::MulpvOp) == 2 );\n            break;\n\n            case pow_graph_op:\n            i_result = rec.PutOp(local::PowpvOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::PowpvOp) == 2 );\n            break;\n\n            case sub_graph_op:\n            i_result = rec.PutOp(local::SubpvOp);\n            rec.PutArg( arg[0], arg[1] );\n            CPPAD_ASSERT_UNKNOWN( NumArg(local::SubpvOp) == 2 );\n            break;\n\n            default:\n            CPPAD_ASSERT_UNKNOWN( false );\n            break;\n         }\n         else if( type_x[0] == dynamic_enum || type_x[1] == dynamic_enum )\n         switch( op_enum )\n         {\n            case add_graph_op:\n            i_result =\n               rec.put_dyn_par(nan, local::add_dyn, arg[0], arg[1]);\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case azmul_graph_op:\n            i_result =\n               rec.put_dyn_par(nan, local::zmul_dyn, arg[0], arg[1]);\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case div_graph_op:\n            i_result =\n               rec.put_dyn_par(nan, local::div_dyn, arg[0], arg[1]);\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case mul_graph_op:\n            i_result =\n               rec.put_dyn_par(nan, local::mul_dyn, arg[0], arg[1]);\n            break;\n\n            case pow_graph_op:\n            i_result =\n               rec.put_dyn_par(nan, local::pow_dyn, arg[0], arg[1]);\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            case sub_graph_op:\n            i_result =\n               rec.put_dyn_par(nan, local::sub_dyn, arg[0], arg[1]);\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[i_result] ) );\n            break;\n\n            default:\n            CPPAD_ASSERT_UNKNOWN( false );\n            break;\n         }\n         else switch( op_enum )\n         {\n            case add_graph_op:\n            result = parameter[ arg[0] ] + parameter[ arg[1] ];\n            i_result = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case azmul_graph_op:\n            result = azmul( parameter[ arg[0] ] , parameter[ arg[1] ] );\n            i_result = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case div_graph_op:\n            result = parameter[ arg[0] ] / parameter[ arg[1] ];\n            i_result = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case mul_graph_op:\n            result = parameter[ arg[0] ] * parameter[ arg[1] ];\n            i_result = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case pow_graph_op:\n            result = pow( parameter[ arg[0] ],  parameter[ arg[1] ] );\n            i_result = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            case sub_graph_op:\n            result = parameter[ arg[0] ] - parameter[ arg[1] ];\n            i_result = rec.put_con_par(result);\n            CPPAD_ASSERT_UNKNOWN( parameter[i_result] == result );\n            break;\n\n            default:\n            CPPAD_ASSERT_UNKNOWN( false );\n            break;\n\n         }\n      }\n      // Exclude cases where node_type and node2fun for the results\n      // have already been set\n      if( n_result != 0 )\n      if( op_enum != atom_graph_op && op_enum != atom4_graph_op )\n      {  // set node_type and node2fun for result\n         //\n         CPPAD_ASSERT_UNKNOWN( i_result != 0 );\n         CPPAD_ASSERT_UNKNOWN( n_result == 1 );\n         if( n_var_arg > 0 )\n            node_type.push_back(variable_enum);\n         else if( n_dyn_arg > 0 )\n            node_type.push_back(dynamic_enum);\n         else\n            node_type.push_back(constant_enum);\n         node2fun.push_back(i_result);\n      }\n      //\n# ifndef NDEBUG\n      start_result          += n_result;\n# endif\n      CPPAD_ASSERT_UNKNOWN( node2fun.size() == start_result );\n      CPPAD_ASSERT_UNKNOWN( node_type.size() == start_result );\n   }\n   // set this->dep_parameter_, set this->dep_taddr_\n   //\n   CPPAD_ASSERT_NARG_NRES(local::ParOp, 1, 1);\n   dep_parameter_.resize( n_dependent );\n   dep_taddr_.resize( n_dependent );\n   for(size_t i = 0; i < n_dependent; ++i)\n   {\n      CPPAD_ASSERT_UNKNOWN(\n         node_type[ graph_obj.dependent_vec_get(i) ] != number_ad_type_enum\n      );\n      if( node_type[ graph_obj.dependent_vec_get(i) ] == variable_enum )\n      {  dep_parameter_[i] = false;\n         dep_taddr_[i]     = size_t( node2fun[ graph_obj.dependent_vec_get(i) ] );\n      }\n      else\n      {  dep_parameter_[i] = true;\n         dep_taddr_[i]     = size_t( rec.PutOp(local::ParOp) );\n         rec.PutArg( node2fun[ graph_obj.dependent_vec_get(i) ] );\n      }\n   }\n   rec.PutOp(local::EndOp);\n   // ----------------------------------------------------------------------\n   // End recording, set private member data except for\n   // dep__parameter_ and dep_taddr_\n   // ----------------------------------------------------------------------\n   //\n   // bool values in this object except check_for_nan_\n   has_been_optimized_        = false;\n   //\n   // size_t values in this object\n   compare_change_count_      = 1;\n   compare_change_number_     = 0;\n   compare_change_op_index_   = 0;\n   num_order_taylor_          = 0;\n   cap_order_taylor_          = 0;\n   num_direction_taylor_      = 0;\n   num_var_tape_              = rec.num_var();\n   //\n   // taylor_\n   taylor_.resize(0);\n   //\n   // cskip_op_\n   cskip_op_.resize( rec.num_var_op() );\n   //\n   // load_op2var_\n   load_op2var_.resize( rec.num_var_load() );\n   //\n   // play_\n   // Now that each dependent variable has a place in the recording,\n   // and there is a EndOp at the end of the record, we can transfer the\n   // recording to the player and and erase the recording.\n   play_.get_recording(rec, n_variable_ind_fun);\n   //\n   // ind_taddr_\n   // Note that play_ has been set, we can use it to check operators\n   ind_taddr_.resize(n_variable_ind_fun);\n   CPPAD_ASSERT_UNKNOWN( n_variable_ind_fun < num_var_tape_);\n   for(size_t j = 0; j < n_variable_ind_fun; j++)\n   {  CPPAD_ASSERT_UNKNOWN( play_.GetOp(j+1) == local::InvOp );\n      ind_taddr_[j] = j+1;\n   }\n   //\n   // for_jac_sparse_pack_, for_jac_sparse_set_\n   for_jac_sparse_pack_.resize(0, 0);\n   for_jac_sparse_set_.resize(0,0);\n   //\n   // resize subgraph_info_\n   subgraph_info_.resize(\n      ind_taddr_.size(),   // n_dep\n      dep_taddr_.size(),   // n_ind\n      play_.num_var_op(),  // n_op\n      play_.num_var()      // n_var\n   );\n   //\n   // set the function name\n   function_name_ = function_name;\n   //\n   return;\n}\n// BEGIN_ONE_ARGUMENT\ntemplate <class Base, class RecBase>\nvoid CppAD::ADFun<Base,RecBase>::from_graph(\n   const CppAD::cpp_graph& graph_obj     )\n// END_ONE_ARGUMENT\n{  size_t n_variable_ind = graph_obj.n_variable_ind_get();\n   size_t n_dynamic_ind  = graph_obj.n_dynamic_ind_get();\n   CppAD::vector<bool> dyn2var(n_dynamic_ind), var2dyn(n_variable_ind);\n   for(size_t j = 0; j < n_dynamic_ind; ++j)\n      dyn2var[j] = false;\n   for(size_t j = 0; j < n_variable_ind; ++j)\n      var2dyn[j] = false;\n   //\n   from_graph(graph_obj, dyn2var, var2dyn);\n}\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/graph/from_json.hpp",
    "content": "# ifndef CPPAD_CORE_GRAPH_FROM_JSON_HPP\n# define CPPAD_CORE_GRAPH_FROM_JSON_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/core/ad_fun.hpp>\n# include <cppad/core/ad_type.hpp>\n# include <cppad/local/graph/json_parser.hpp>\n\n/*\n{xrst_begin from_json}\n\nADFun Object Corresponding to a Json AD Graph\n#############################################\n\nSyntax\n******\n| |tab| ``ADFun`` < *Base* > *fun*\n| |tab| *fun* . ``from_json`` ( *json* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\njson\n****\nis a :ref:`json_ad_graph-name` .\n\nBase\n****\nis the type corresponding to this :ref:`adfun-name` object;\ni.e., its calculations are done using the type *Base* .\n\nRecBase\n*******\nin the prototype above, *RecBase* is the same type as *Base* .\n{xrst_toc_hidden\n   example/json/from_json.cpp\n}\nExample\n*******\nThe file :ref:`from_json.cpp-name` is an example and test of this operation.\n\n{xrst_end from_json}\n*/\n// BEGIN_PROTOTYPE\ntemplate <class Base, class RecBase>\nvoid CppAD::ADFun<Base,RecBase>::from_json(const std::string& json)\n// END_PROTOTYPE\n{\n   using CppAD::isnan;\n   //\n   //\n   // C++ graph object\n   cpp_graph graph_obj;\n   //\n   // convert json to graph representation\n   local::graph::json_parser(json, graph_obj);\n   //\n   // convert the graph representation to a function\n   from_graph(graph_obj);\n   //\n   return;\n}\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/graph/graph_op_enum.hpp",
    "content": "# ifndef CPPAD_CORE_GRAPH_GRAPH_OP_ENUM_HPP\n# define CPPAD_CORE_GRAPH_GRAPH_OP_ENUM_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cstddef>\n# include <string>\n# include <map>\n\n# include <cppad/utility/vector.hpp>\n# include <cppad/configure.hpp>\n\n/*\n{xrst_begin graph_op_enum}\n\nC++ AD Graph Operator Enum Type\n###############################\n\n{xrst_comment\n   The following headings are referenced by comments in cpp_graph_op.cpp:\n   Atomic Function, Comparison, Discrete Function, Print, Summation\n}\n\nUnary\n*****\nThe unary operators have one argument and one result node.\nThe argument is a node index and the result is the next node.\n\nBinary\n******\nThe binary operators have two arguments and one result node.\nThe arguments are node indices and the result is the next node.\nThe first (second) argument is the left (right) operand node index.\n\nConditional Expression\n**********************\nThe conditional expression operators have four arguments and one result node.\nThe arguments are node indices and the result is the next node.\nThe first argument is :ref:`CondExp@left` ,\nthe second is :ref:`CondExp@right` ,\nthe third is :ref:`CondExp@if_true` ,\nthe fourth is :ref:`CondExp@if_false` ,\nthe result is given by\n\n| |tab| ``if`` ( *left* *cop* *right* )\n| |tab| |tab| *result* = *if_true* ;\n| |tab| ``else``\n| |tab| |tab| *result* = *if_false* ;\n\nwhere *cop* is given in the comment after the enum type values below.\n\nOther Comparisons\n=================\nNote that\n\n   ``CondExpGt`` ( *left* , *right* , *if_true* , *if_false* )\n\nis equivalent to\n\n   ``CondExpLe`` ( *left* , *right* , *if_false* , *if_true* )\n\nSimilar conversions can be used for all the possible\n:ref:`conditional expressions<CondExp-name>` .\n\nComparison\n**********\nThe comparison operators have two arguments and no result node.\nThe first (second) argument is the left (right) operand node index.\nThe comparison result was true for the value of the independent\ndynamic parameters and independent variables at which this graph was created.\n\nOther Comparisons\n=================\nThe comparison result true for *left* > *right*\nis equivalent to the comparison result true for *right* < *left* .\nThe comparison result false for *left* > *right*\nis equivalent to the comparison result true for *left* <= *right* .\nIn a similar fashion, all the possible comparisons results\ncan be converted to a true result for one of the comparisons above.\n\nSummation\n*********\nThe summation operator has one node result and a variable\nnumber of arguments.\nThe first argument is the number of nodes in the summation,\nand the other arguments are the indices of the nodes to be summed.\nThe total number of arguments for this operator\nis one plus the number of nodes in the summation.\n\nDiscrete Function\n*****************\nThe discrete function operator has two arguments and one node result.\nThe first argument is the index in\n:ref:`cpp_ad_graph@discrete_name_vec` for the\n:ref:`discrete@name` of the discrete function that is called.\nThe second argument is the index of the node that is the argument\nto the discrete function.\n\nAtomic Function\n***************\nThe atomic function operator has a variable number of arguments\nand a variable number of result nodes.\nThere are three extra arguments for :ref:`atomic_three-name` functions and\nfour extra arguments for :ref:`atomic_four-name` functions.\nThe total number of operator arguments is\nthe number of extra arguments\nplus the number of arguments for the function being called.\nThe extra arguments come before the function arguments.\n\n#. The first operator argument is function name represented by it's index in the\n   :ref:`cpp_ad_graph@atomic_name_vec` .\n#. If this is an atomic four function call,\n   the second operator argument is the :ref:`atomic_four_call@call_id` .\n#. In the atomic three (atomic four) case, second (third) operator argument\n   is the number of results for this function call.\n   The order of the function results is determined by the function being called.\n#. In the atomic three (atomic four) case, the third (fourth) operator argument\n   is the number of arguments for this function call.\n#. The rest of the operator arguments are the node indices for each of the\n   function arguments.\n   The order of the function arguments is determined by function being called.\n\nPrint\n*****\nThe print operator has four arguments.\n\n#. The first argument is the index in\n   :ref:`cpp_ad_graph@print_text_vec` for the\n   :ref:`PrintFor@before` text for this print operator.\n#. The second argument is the index in\n   :ref:`cpp_ad_graph@print_text_vec` for the\n   :ref:`PrintFor@after` text for this print operator.\n#. The third argument is the node corresponding to\n   :ref:`PrintFor@notpos` for this print operator.\n#. The fourth argument is the node corresponding to\n   :ref:`PrintFor@value` for this print operator.\n\nMissing Operators\n*****************\nAs of yet the following :ref:`ADFun-name` operators do not have a corresponding\ngraph operator:\n\n#. Operators to load and store :ref:`VecAD-name` elements.\n#. An operator for the :ref:`atomic_two-name` interface.\n\nEnum Values\n***********\n{xrst_literal\n   SORT_THIS_LINE_PLUS_3\n   SORT_THIS_LINE_MINUS_4\n}\n\nExamples\n********\n\nContents\n********\n{xrst_toc_table\n   example/graph/azmul_op.cpp\n   example/graph/add_op.cpp\n   example/graph/div_op.cpp\n   example/graph/mul_op.cpp\n   example/graph/pow_op.cpp\n   example/graph/sub_op.cpp\n   example/graph/unary_op.cpp\n   example/graph/sum_op.cpp\n   example/graph/comp_op.cpp\n   example/graph/cexp_op.cpp\n   example/graph/discrete_op.cpp\n   example/graph/atom_op.cpp\n   example/graph/atom4_op.cpp\n   example/graph/print_op.cpp\n}\n\n{xrst_end graph_op_enum}\n*/\n// BEGIN_SORT_THIS_LINE_PLUS_3\nnamespace CppAD { namespace graph {\n   enum graph_op_enum {\n      abs_graph_op,      // unary: absolute value\n      acos_graph_op,     // unary: inverse cosine\n      acosh_graph_op,    // unary: inverse hyperbolic cosine\n      add_graph_op,      // binary: addition\n      asin_graph_op,     // unary: inverse sine\n      asinh_graph_op,    // unary: inverse hyperbolic sine\n      atan_graph_op,     // unary: inverse tangent\n      atanh_graph_op,    // unary: inverse hyperbolic tangent\n      atom4_graph_op,    // atomic four function call\n      atom_graph_op,     // atomic three function call\n      azmul_graph_op,    // binary: absolute zero multiplication\n      cexp_eq_graph_op,  // conditional expression: ==\n      cexp_le_graph_op,  // conditional expression: <=\n      cexp_lt_graph_op,  // conditional expression: <\n      comp_eq_graph_op,  // comparison: ==\n      comp_le_graph_op,  // comparison: <=\n      comp_lt_graph_op,  // comparison: <\n      comp_ne_graph_op,  // comparison: !=\n      cos_graph_op,      // unary: cosine\n      cosh_graph_op,     // unary: hyperbolic cosine\n      discrete_graph_op, // discrete function\n      div_graph_op,      // binary: division\n      erf_graph_op,      // unary: error function\n      erfc_graph_op,     // unary: complementary error function\n      exp_graph_op,      // unary: exponential\n      expm1_graph_op,    // unary: exponential minus one\n      log1p_graph_op,    // unary: logarithm of one plus argument\n      log_graph_op,      // unary: logarithm\n      mul_graph_op,      // binary: multiplication\n      neg_graph_op,      // unary: minus\n      pow_graph_op,      // binary: first argument raised to second argument\n      print_graph_op,    // print during zero order forward\n      sign_graph_op,     // unary: sign of argument\n      sin_graph_op,      // unary: sine\n      sinh_graph_op,     // unary: hyperbolic sine\n      sqrt_graph_op,     // unary: square root\n      sub_graph_op,      // binary: subtraction\n      sum_graph_op,      // summation\n      tan_graph_op,      // unary: tangent\n      tanh_graph_op,     // unary: hyperbolic tangent\n      n_graph_op         // number of graph_op_enum operators\n   };\n} }\n// END_SORT_THIS_LINE_MINUS_4\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/graph/to_graph.hpp",
    "content": "# ifndef CPPAD_CORE_GRAPH_TO_GRAPH_HPP\n# define CPPAD_CORE_GRAPH_TO_GRAPH_HPP\n\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/core/ad_fun.hpp>\n# include <cppad/local/op_code_dyn.hpp>\n# include <cppad/local/graph/cpp_graph_op.hpp>\n\n/*\n------------------------------------------------------------------------------\n{xrst_begin to_graph}\n\nCreate a C++ AD Graph Corresponding to an ADFun Object\n######################################################\n\nSyntax\n******\n| |tab| ``cpp_graph`` *graph_obj*\n| |tab| ``ADFun`` < *Base* > *fun*\n| |tab| *fun* . ``to_graph`` ( *graph_obj* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nBase\n****\nis the type corresponding to this :ref:`adfun-name` object;\ni.e., its calculations are done using the type *Base* .\n\nRecBase\n*******\nin the prototype above, *RecBase* is the same type as *Base* .\n\ngraph_obj\n*********\nThis is a ``cpp_graph`` object.\nThe input value of the object does not matter.\nUpon return it is a :ref:`cpp_ad_graph-name` representation of this function.\n\nRestrictions\n************\nThe ``to_graph`` routine is not yet implement for some\npossible :ref:`ADFun-name` operators; see\n:ref:`graph_op_enum@Missing Operators` .\n\nExamples\n********\nSee :ref:`graph_op_enum examples<graph_op_enum@Examples>` .\n\n{xrst_end to_graph}\n*/\n// BEGIN_PROTOTYPE\ntemplate <class Base, class RecBase>\nvoid CppAD::ADFun<Base,RecBase>::to_graph(\n      CppAD::cpp_graph& graph_obj )\n// END_PROTOTYPE\n{  using local::pod_vector;\n   using local::opcode_t;\n   using namespace CppAD::graph;\n   //\n# ifndef NDEBUG\n# endif\n   graph_obj.initialize();\n   //\n   // --------------------------------------------------------------------\n   // some constants\n   // --------------------------------------------------------------------\n   //\n   // output: function_name\n   graph_obj.function_name_set(function_name_);\n   //\n   // dynamic parameter information\n   const pod_vector<opcode_t>& dyn_par_op ( play_.dyn_par_op()  );\n   const pod_vector<addr_t>&   dyn_par_arg( play_.dyn_par_arg() );\n   const pod_vector<addr_t>&   dyn2par_index ( play_.dyn2par_index() );\n   const pod_vector<bool>&     par_is_dyn( play_.par_is_dyn() );\n   //\n   // number of dynamic parameters\n   const size_t n_dynamic     = dyn2par_index.size();\n   //\n   // output: n_dynamic_ind\n   size_t n_dynamic_ind = play_.n_dyn_independent();\n   graph_obj.n_dynamic_ind_set(n_dynamic_ind);\n   //\n   // number of parameters\n   const size_t n_parameter = play_.num_par_all();\n   //\n   // number of constant parameters\n# ifndef NDEBUG\n   const size_t n_constant = n_parameter - n_dynamic - 1;\n# endif\n   //\n   // output: n_variable_ind\n   size_t n_variable_ind = ind_taddr_.size();\n   graph_obj.n_variable_ind_set(n_variable_ind);\n   //\n   // value of parameters\n   const Base* parameter = play_.par_ptr();\n   //\n   // number of variables\n   const size_t n_variable = play_.num_var();\n   //\n   // some checks\n   CPPAD_ASSERT_UNKNOWN( n_dynamic_ind <= n_dynamic );\n   CPPAD_ASSERT_UNKNOWN( par_is_dyn.size() == n_parameter );\n   CPPAD_ASSERT_UNKNOWN( n_parameter > 0 );\n   CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[0] ) );\n   CPPAD_ASSERT_UNKNOWN( ! par_is_dyn[0] );\n   // --------------------------------------------------------------------\n   // par2node\n   pod_vector<size_t> par2node(n_parameter);\n   par2node[0] = 0; // invalid value\n   for(size_t i = 1; i <= n_dynamic_ind; ++i)\n      par2node[i] = i; // independent dynamic parameters\n   for(size_t i = n_dynamic_ind + 1; i < n_parameter; ++i)\n      par2node[i] = 0; // will be set later\n   // ----------------------------------------------------------------------\n   //\n   // initialize index of previous node in the graph\n   size_t previous_node = 0;\n   //\n   // n_dynamic_ind\n   previous_node += n_dynamic_ind;\n   //\n   // n_variable_ind\n   previous_node += n_variable_ind;\n   // --------------------------------------------------------------------\n   //\n   // output: constant_vec\n   // constant_vec and par2node for constants\n   for(size_t i = 1; i < n_parameter; ++i)\n   {  if( ! par_is_dyn[i] )\n      {  // this is a constant node\n         graph_obj.constant_vec_push_back( parameter[i] );\n         par2node[i] = ++previous_node;\n      }\n   }\n   CPPAD_ASSERT_UNKNOWN( n_constant == graph_obj.constant_vec_size() );\n   // ----------------------------------------------------------------------\n   //  output: initialize atomic_name_vec, operator_vec, operator_arg\n   // temporary used for elements of operator_vec\n   //\n   // Json operators are dynamic operators plus variables operators.\n   // Skip BeginOp, EndOp, and independent variables.\n   //\n   // dynamic parameter operations and par2node\n   // for dynamic parameters that are not constants or independent\n   CPPAD_ASSERT_UNKNOWN( num_arg_dyn(local::ind_dyn) == 0 );\n   CPPAD_ASSERT_UNKNOWN( num_arg_dyn(local::atom_dyn) == 0 );\n   size_t i_arg = 0;\n   pod_vector<size_t> node_arg;\n\n   for(size_t i_dyn = n_dynamic_ind; i_dyn < n_dynamic; ++i_dyn)\n   {  // operator for this dynamic parameter\n      local::op_code_dyn dyn_op = local::op_code_dyn( dyn_par_op[i_dyn] );\n      //\n      // parameter index for this dynamic parameter\n      size_t i_par = size_t( dyn2par_index[i_dyn] );\n      CPPAD_ASSERT_UNKNOWN( par2node[i_par] == 0 );\n      par2node[i_par] = ++previous_node;\n      //\n      // number of arguments for operators with exception of atom_dyn\n      size_t n_arg = num_arg_dyn(dyn_op);\n      if( n_arg > node_arg.size() )\n         node_arg.resize(n_arg);\n      //\n      // parameter arguments in graph node space (except for atom_dyn)\n      if( dyn_op != local::atom_dyn )\n      {  size_t offset_par = num_non_par_arg_dyn(dyn_op);\n         for(size_t i = offset_par; i < n_arg; ++i)\n         {  node_arg[i] = par2node[ dyn_par_arg[i_arg + i] ];\n            CPPAD_ASSERT_UNKNOWN( node_arg[i] > 0 );\n         }\n      }\n      //\n      // invalid value\n      graph_op_enum graph_op = n_graph_op;\n      switch(dyn_op)\n      {\n         // ---------------------------------------------------------------\n         // unary operators\n\n         case local::abs_dyn:\n         case local::fabs_dyn:\n         graph_op = abs_graph_op;\n         break;\n\n         case local::acosh_dyn:\n         graph_op = acosh_graph_op;\n         break;\n\n         case local::asinh_dyn:\n         graph_op = asinh_graph_op;\n         break;\n\n         case local::atanh_dyn:\n         graph_op = atanh_graph_op;\n         break;\n\n         case local::erf_dyn:\n         graph_op = erf_graph_op;\n         break;\n\n         case local::erfc_dyn:\n         graph_op = erfc_graph_op;\n         break;\n\n         case local::expm1_dyn:\n         graph_op = expm1_graph_op;\n         break;\n\n         case local::log1p_dyn:\n         graph_op = log1p_graph_op;\n         break;\n\n         case local::acos_dyn:\n         graph_op = acos_graph_op;\n         break;\n\n         case local::asin_dyn:\n         graph_op = asin_graph_op;\n         break;\n\n         case local::atan_dyn:\n         graph_op = atan_graph_op;\n         break;\n\n         case local::cosh_dyn:\n         graph_op = cosh_graph_op;\n         break;\n\n         case local::cos_dyn:\n         graph_op = cos_graph_op;\n         break;\n\n         case local::exp_dyn:\n         graph_op = exp_graph_op;\n         break;\n\n         case local::log_dyn:\n         graph_op = log_graph_op;\n         break;\n\n         case local::neg_dyn:\n         graph_op = neg_graph_op;\n         break;\n\n         case local::sign_dyn:\n         graph_op = sign_graph_op;\n         break;\n\n         case local::sinh_dyn:\n         graph_op = sinh_graph_op;\n         break;\n\n         case local::sin_dyn:\n         graph_op = sin_graph_op;\n         break;\n\n         case local::sqrt_dyn:\n         graph_op = sqrt_graph_op;\n         break;\n\n         case local::tanh_dyn:\n         graph_op = tanh_graph_op;\n         break;\n\n         case local::tan_dyn:\n         graph_op = tan_graph_op;\n         break;\n\n         // ---------------------------------------------------------------\n         // binary operators\n\n         case local::add_dyn:\n         graph_op = add_graph_op;\n         break;\n\n         case local::div_dyn:\n         graph_op = div_graph_op;\n         break;\n\n         case local::mul_dyn:\n         graph_op = mul_graph_op;\n         break;\n\n         case local::pow_dyn:\n         graph_op = pow_graph_op;\n         break;\n\n         case local::sub_dyn:\n         graph_op = sub_graph_op;\n         break;\n\n         case local::zmul_dyn:\n         graph_op = azmul_graph_op;\n         break;\n\n         // ---------------------------------------------------------------\n         // graph_op determined later for these cases\n         case local::atom_dyn:\n         case local::cond_exp_dyn:\n         case local::dis_dyn:\n         case local::result_dyn:\n         break;\n\n         // ---------------------------------------------------------------\n         default:\n         // This error should have been reported above\n         CPPAD_ASSERT_UNKNOWN( false );\n         break;\n      }\n      switch( dyn_op )\n      {  // --------------------------------------------------------------\n         case local::result_dyn:\n         // setting par2node[i_dyn] above is all that is necessary\n         CPPAD_ASSERT_UNKNOWN( n_arg == 0 );\n         break;\n\n         // --------------------------------------------------------------\n         case local::dis_dyn:\n         {\n            // arg[0]: discrete function index\n            size_t discrete_index = size_t( dyn_par_arg[i_arg + 0] );\n            // get the name for this discrete function\n            std::string name = discrete<Base>::name( discrete_index );\n            //\n            // set graph index for this discrete function call\n            size_t name_index = graph_obj.discrete_name_vec_find(name);\n            if( name_index == graph_obj.discrete_name_vec_size() )\n               graph_obj.discrete_name_vec_push_back(name);\n            //\n            graph_op = discrete_graph_op;\n            graph_obj.operator_vec_push_back( graph_op );\n            graph_obj.operator_arg_push_back( name_index );\n            graph_obj.operator_arg_push_back( node_arg[1] );\n         }\n         break;\n\n         // --------------------------------------------------------------\n         case local::atom_dyn:\n         {\n            // arg[0]: atomic function index\n            size_t atom_index  = size_t( dyn_par_arg[i_arg + 0] );\n            //\n            // arg[1]: call_id\n            size_t call_id = size_t( dyn_par_arg[i_arg + 1] );\n            //\n            // arg[2]: number of arguments to function\n            n_arg              = size_t( dyn_par_arg[i_arg + 2] );\n            // arg[3]: number of results from function\n            size_t n_result    = size_t( dyn_par_arg[i_arg + 3] );\n            //\n            // get the name and type for this atomic function\n            std::string     name;\n            size_t          type;\n            {  bool        set_null = false;\n               void*       ptr;\n               CppAD::local::atomic_index<RecBase>(\n                  set_null, atom_index, type, &name, ptr\n               );\n            }\n            // set graph index for this atomic function call\n            size_t name_index = graph_obj.atomic_name_vec_find(name);\n            if( name_index == graph_obj.atomic_name_vec_size() )\n               graph_obj.atomic_name_vec_push_back(name);\n            //\n            // atom_graph_op:\n            // name_index, n_result, n_arg (before first_node)\n            //\n            // atom4_graph_op:\n            // name_index, call_id, n_result, n_arg (before first_node)\n            graph_obj.operator_arg_push_back(name_index);\n            if( type == 4 )\n               graph_obj.operator_arg_push_back(call_id);\n            graph_obj.operator_arg_push_back(n_result);\n            graph_obj.operator_arg_push_back(n_arg);\n            //\n            if( type == 3 )\n               graph_op = atom_graph_op;\n            else\n            {  CPPAD_ASSERT_UNKNOWN( type == 4 );\n               graph_op = atom4_graph_op;\n            }\n            //\n            graph_obj.operator_vec_push_back( graph_op );\n            //\n            for(size_t j  = 0; j < n_arg; ++j)\n            {  // arg[5 + j] is j-th argument to the function\n               size_t node_j = par2node[ dyn_par_arg[i_arg + 5 + j] ];\n               CPPAD_ASSERT_UNKNOWN( node_j < i_par );\n               graph_obj.operator_arg_push_back( node_j );\n            }\n         }\n         break;\n\n         // --------------------------------------------------------------\n         case local::cond_exp_dyn:\n         {\n            CompareOp cop = CompareOp( dyn_par_arg[i_arg + 0] );\n            size_t left     = node_arg[1];\n            size_t right    = node_arg[2];\n            size_t if_true  = node_arg[3];\n            size_t if_false = node_arg[4];\n            switch( cop )\n            {  case CompareLt:\n               graph_op = cexp_lt_graph_op;\n               break;\n\n               case CompareLe:\n               graph_op = cexp_le_graph_op;\n               break;\n\n               case CompareEq:\n               graph_op = cexp_eq_graph_op;\n               break;\n\n               case CompareGe:\n               graph_op = cexp_lt_graph_op;\n               std::swap(if_true, if_false);\n               break;\n\n               case CompareGt:\n               graph_op = cexp_le_graph_op;\n               std::swap(if_true, if_false);\n               break;\n\n               case CompareNe:\n               graph_op = cexp_eq_graph_op;\n               std::swap(if_true, if_false);\n               break;\n\n               default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               break;\n            }\n            graph_obj.operator_vec_push_back( graph_op );\n            graph_obj.operator_arg_push_back( left );\n            graph_obj.operator_arg_push_back( right );\n            graph_obj.operator_arg_push_back( if_true );\n            graph_obj.operator_arg_push_back( if_false );\n         }\n         break;\n\n         // --------------------------------------------------------------\n         // unary or binary\n         default:\n         CPPAD_ASSERT_UNKNOWN((n_arg == 1) || (n_arg == 2));\n         //\n         graph_obj.operator_vec_push_back( graph_op );\n         for(size_t i = 0; i < n_arg; ++i)\n            graph_obj.operator_arg_push_back( node_arg[i] );\n         break;\n      }\n      i_arg  += n_arg;\n   }\n   // ----------------------------------------------------------------------\n   // variable operators\n   pod_vector<size_t> var2node(n_variable);\n   var2node[0] = 0; // invalid node value\n   for(size_t i = 1; i <= n_variable_ind; ++i)\n      var2node[i] = n_dynamic_ind + i;\n   for(size_t i = n_variable_ind + 1; i < n_variable; ++i)\n      var2node[i] = 0; // invalid node value\n   //\n   local::play::const_sequential_iterator itr  = play_.begin();\n   local::op_code_var var_op;\n   const              addr_t* arg;\n   size_t             i_var;\n   pod_vector<bool>   is_var(2);\n   vector<size_t>     atom_node_arg;\n   bool in_atomic_call = false;\n   bool more_operators = true;\n   while(more_operators)\n   {  // if non-zero, this is a fixed size operator with this many arguments\n      // and implemented after the switch. In additionk, is_var is set for\n      // each of the at most 2 arguments.\n      size_t fixed_n_arg = 0;\n\n      // invalid value\n      graph_op_enum graph_op = n_graph_op;\n\n      // next op\n      (++itr).op_info(var_op, arg, i_var);\n\n\n      // -------------------------------------------------------------------\n      // Cases with fixed number of arguments, one or two arguments, and\n      // operator is not ignored.\n      // -------------------------------------------------------------------\n      switch( var_op )\n      {  // 2DO: some of these cases can be joined\n\n         // -------------------------------------------------------------\n         // unary operators\n         case local::AbsOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::AcoshOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::AsinhOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::AtanhOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::ErfOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::ErfcOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::Expm1Op:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::Log1pOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::AcosOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::AsinOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::AtanOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::CoshOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::CosOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::ExpOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::LogOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::NegOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::SignOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::SinhOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::SinOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::SqrtOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::TanhOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         case local::TanOp:\n         fixed_n_arg = 1;\n         is_var[0] = true;\n         break;\n\n         // ---------------------------------------------------------------\n         // binary operators\n         // ---------------------------------------------------------------\n\n         // first argument a parameter, second argument a variable\n         case local::AddpvOp:\n         case local::DivpvOp:\n         case local::MulpvOp:\n         case local::PowpvOp:\n         case local::SubpvOp:\n         case local::ZmulpvOp:\n         fixed_n_arg = 2;\n         is_var[0]   = false;\n         is_var[1]   = true;\n         break;\n\n         // first argument a variable, second argument a parameter\n         case local::DivvpOp:\n         case local::PowvpOp:\n         case local::SubvpOp:\n         case local::ZmulvpOp:\n         fixed_n_arg = 2;\n         is_var[0]   = true;\n         is_var[1]   = false;\n         break;\n\n         // first argument a variable, second argument a variable\n         case local::AddvvOp:\n         case local::DivvvOp:\n         case local::MulvvOp:\n         case local::PowvvOp:\n         case local::SubvvOp:\n         case local::ZmulvvOp:\n         fixed_n_arg = 2;\n         is_var[0]   = true;\n         is_var[1]   = true;\n         break;\n\n         // --------------------------------------------------------------\n         default:\n         break;\n      }\n      if( fixed_n_arg > 0 )\n      {  // Set graph_op\n         switch( var_op )\n         {\n            // ----------------------------------------------------------\n            // unary operators\n\n            case local::AbsOp:\n            graph_op = abs_graph_op;\n            break;\n\n            case local::AcoshOp:\n            graph_op = acosh_graph_op;\n            break;\n\n            case local::AsinhOp:\n            graph_op = asinh_graph_op;\n            break;\n\n            case local::AtanhOp:\n            graph_op = atanh_graph_op;\n            break;\n\n            case local::ErfOp:\n            graph_op = erf_graph_op;\n            break;\n\n            case local::ErfcOp:\n            graph_op = erfc_graph_op;\n            break;\n\n            case local::Expm1Op:\n            graph_op = expm1_graph_op;\n            break;\n\n            case local::Log1pOp:\n            graph_op = log1p_graph_op;\n            break;\n\n            case local::AcosOp:\n            graph_op = acos_graph_op;\n            break;\n\n            case local::AsinOp:\n            graph_op = asin_graph_op;\n            break;\n\n            case local::AtanOp:\n            graph_op = atan_graph_op;\n            break;\n\n            case local::CoshOp:\n            graph_op = cosh_graph_op;\n            break;\n\n            case local::CosOp:\n            graph_op = cos_graph_op;\n            break;\n\n            case local::ExpOp:\n            graph_op = exp_graph_op;\n            break;\n\n            case local::LogOp:\n            graph_op = log_graph_op;\n            break;\n\n            case local::NegOp:\n            graph_op = neg_graph_op;\n            break;\n\n            case local::SignOp:\n            graph_op = sign_graph_op;\n            break;\n\n            case local::SinhOp:\n            graph_op = sinh_graph_op;\n            break;\n\n            case local::SinOp:\n            graph_op = sin_graph_op;\n            break;\n\n            case local::SqrtOp:\n            graph_op = sqrt_graph_op;\n            break;\n\n            case local::TanhOp:\n            graph_op = tanh_graph_op;\n            break;\n\n            case local::TanOp:\n            graph_op = tan_graph_op;\n            break;\n\n            // -----------------------------------------------------------\n            // binary operators\n\n            case local::AddpvOp:\n            case local::AddvvOp:\n            graph_op = add_graph_op;\n            break;\n\n            case local::DivpvOp:\n            case local::DivvpOp:\n            case local::DivvvOp:\n            graph_op = div_graph_op;\n            break;\n\n            case local::MulpvOp:\n            case local::MulvvOp:\n            graph_op = mul_graph_op;\n            break;\n\n            case local::PowpvOp:\n            case local::PowvpOp:\n            case local::PowvvOp:\n            graph_op = pow_graph_op;\n            break;\n\n            case local::SubpvOp:\n            case local::SubvpOp:\n            case local::SubvvOp:\n            graph_op = sub_graph_op;\n            break;\n\n            case local::ZmulpvOp:\n            case local::ZmulvpOp:\n            case local::ZmulvvOp:\n            graph_op = azmul_graph_op;\n            break;\n\n            // -----------------------------------------------------------\n            default:\n            // This should be one of the cases above\n            CPPAD_ASSERT_UNKNOWN(false);\n            break;\n         }\n         //\n         // var2node and previous_node for this operator\n         var2node[i_var] = ++previous_node;\n         //\n         //\n         graph_obj.operator_vec_push_back( graph_op );\n         for(size_t i = 0; i < fixed_n_arg; ++i)\n         {  if( is_var[i] )\n               graph_obj.operator_arg_push_back( var2node[ arg[i] ] );\n            else\n               graph_obj.operator_arg_push_back( par2node[ arg[i] ] );\n         }\n      }\n      // -------------------------------------------------------------------\n      // Other cases\n      // -------------------------------------------------------------------\n      else switch( var_op )\n      {\n         // -------------------------------------------------------------\n         // comparison operators\n         case local::EqppOp:\n         case local::EqpvOp:\n         case local::EqvvOp:\n         case local::NeppOp:\n         case local::NepvOp:\n         case local::NevvOp:\n         case local::LtppOp:\n         case local::LtpvOp:\n         case local::LtvpOp:\n         case local::LtvvOp:\n         case local::LeppOp:\n         case local::LepvOp:\n         case local::LevpOp:\n         case local::LevvOp:\n         {  // node_0, node_1\n            size_t node_0, node_1;\n            switch( var_op )\n            {  // both nodes parameters\n               case local::EqppOp:\n               case local::NeppOp:\n               case local::LtppOp:\n               case local::LeppOp:\n               node_0 = par2node[arg[0]];\n               node_1 = par2node[arg[1]];\n               break;\n\n               // first node parameter, second variable\n               case local::EqpvOp:\n               case local::NepvOp:\n               case local::LtpvOp:\n               case local::LepvOp:\n               node_0 = par2node[arg[0]];\n               node_1 = var2node[arg[1]];\n               break;\n\n               // first node variable, second parameter\n               case local::LtvpOp:\n               case local::LevpOp:\n               node_0 = var2node[arg[0]];\n               node_1 = par2node[arg[1]];\n               break;\n\n               // both nodes variables\n               case local::EqvvOp:\n               case local::NevvOp:\n               case local::LtvvOp:\n               case local::LevvOp:\n               node_0 = var2node[arg[0]];\n               node_1 = var2node[arg[1]];\n               break;\n\n               // should never get here\n               default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               node_0 = 0; // to avoid compiler warning\n               node_1 = 0;\n               break;\n            }\n            // Set graph_op\n            switch( var_op )\n            {\n               case local::EqppOp:\n               case local::EqpvOp:\n               case local::EqvvOp:\n               graph_op = comp_eq_graph_op;\n               break;\n\n               case local::NeppOp:\n               case local::NepvOp:\n               case local::NevvOp:\n               graph_op = comp_ne_graph_op;\n               break;\n\n               case local::LtppOp:\n               case local::LtpvOp:\n               case local::LtvpOp:\n               case local::LtvvOp:\n               graph_op = comp_lt_graph_op;\n               break;\n\n               case local::LeppOp:\n               case local::LepvOp:\n               case local::LevpOp:\n               case local::LevvOp:\n               graph_op = comp_le_graph_op;\n               break;\n\n               // should never get here\n               default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               graph_op = n_graph_op; // invalid values\n               break;\n            }\n            graph_obj.operator_vec_push_back( graph_op );\n            graph_obj.operator_arg_push_back( node_0 );\n            graph_obj.operator_arg_push_back( node_1 );\n         }\n         break;\n\n         // --------------------------------------------------------------\n         // CSumOp\n         case local::CSumOp:\n         {  // does this case have subtraction terms\n            bool has_subtract = (arg[1] != arg[2]) || (arg[3] != arg[4]);\n            //\n            // var2node for this operator\n            if( has_subtract )\n            {  // two cumulative sum and one subtract operators\n               var2node[i_var] = previous_node + 3;\n            }\n            else\n            {  // one cumulative sum operator\n               var2node[i_var] = previous_node + 1;\n            }\n            //\n            // previous_node + 1 = sum corresponding to addition terms\n            //\n            graph_op = sum_graph_op;\n            CPPAD_ASSERT_UNKNOWN( 5 <= arg[1] );\n            CPPAD_ASSERT_UNKNOWN( arg[2] <= arg[3] );\n            size_t n_arg = size_t(1 + arg[1] - 5 + arg[3] - arg[2]);\n            //\n            // n_arg comes befrore first_node\n            graph_obj.operator_arg_push_back(n_arg);\n            //\n            // graph_op for addition terms\n            graph_obj.operator_vec_push_back( graph_op );\n            //\n            // argument nodes\n            size_t arg_node  = par2node[ arg[0] ];\n            graph_obj.operator_arg_push_back( arg_node );\n# ifndef NDEBUG\n            size_t j_arg = 1;\n# endif\n            for(addr_t i = 5; i < arg[1]; ++i)\n            {  arg_node    = var2node[ arg[i] ];\n               CPPAD_ASSERT_UNKNOWN( arg_node > 0 );\n               graph_obj.operator_arg_push_back( arg_node );\n# ifndef NDEBUG\n               ++j_arg;\n# endif\n            }\n            for(addr_t i = arg[2]; i < arg[3]; ++i)\n            {  arg_node  = par2node[ arg[i] ];\n               CPPAD_ASSERT_UNKNOWN( arg_node > 0 );\n               graph_obj.operator_arg_push_back( arg_node );\n# ifndef NDEBUG\n               ++j_arg;\n# endif\n            }\n            CPPAD_ASSERT_UNKNOWN( j_arg == n_arg );\n            if( has_subtract )\n            {  // previous_node + 2 = sum corresponding to subtract terms\n               CPPAD_ASSERT_UNKNOWN( arg[1] <= arg[2] );\n               CPPAD_ASSERT_UNKNOWN( arg[3] <= arg[4] );\n               n_arg = size_t(arg[2] - arg[1] + arg[4] - arg[3]);\n               //\n               // n_arg comes before first_node\n               graph_obj.operator_arg_push_back(n_arg);\n               //\n               // graph_op for subtraction terms\n               graph_op = sum_graph_op;\n               graph_obj.operator_vec_push_back( graph_op );\n               //\n               // argument nodes\n# ifndef NDEBUG\n               j_arg = 0;\n# endif\n               for(addr_t i = arg[1]; i < arg[2]; ++i)\n               {  arg_node    = var2node[ arg[i] ];\n                  CPPAD_ASSERT_UNKNOWN( arg_node > 0 );\n                  graph_obj.operator_arg_push_back( arg_node );\n# ifndef NDEBUG\n                  ++j_arg;\n# endif\n               }\n               for(addr_t i = arg[3]; i < arg[4]; ++i)\n               {  arg_node  = par2node[ arg[i] ];\n                  CPPAD_ASSERT_UNKNOWN( arg_node > 0 );\n                  graph_obj.operator_arg_push_back( arg_node );\n# ifndef NDEBUG\n                  ++j_arg;\n# endif\n               }\n               CPPAD_ASSERT_UNKNOWN( j_arg == n_arg );\n               //\n               // previous_node + 3 = first sum minus second sum\n               graph_op = sub_graph_op;\n               graph_obj.operator_vec_push_back( graph_op );\n               graph_obj.operator_arg_push_back( previous_node + 1 );\n               graph_obj.operator_arg_push_back( previous_node + 2 );\n            }\n            // previous node\n            if( has_subtract )\n               previous_node += 3;\n            else\n               previous_node += 1;\n         }\n         itr.correct_before_increment();\n         break;\n\n         // --------------------------------------------------------------\n         case local::DisOp:\n         {  // discrete function index\n            size_t discrete_index = size_t( arg[0] );\n            // name of this discrete function\n            std::string name  = discrete<Base>::name( discrete_index );\n            //\n            // set graph index for this discrete function call\n            size_t name_index = graph_obj.discrete_name_vec_find(name);\n            if( name_index == graph_obj.discrete_name_vec_size() )\n               graph_obj.discrete_name_vec_push_back(name);\n            //\n            graph_op = discrete_graph_op;\n            graph_obj.operator_vec_push_back( graph_op );\n            graph_obj.operator_arg_push_back( name_index );\n            graph_obj.operator_arg_push_back( var2node[arg[1]] );\n            //\n            var2node[i_var] = ++previous_node;\n         }\n         break;\n         // --------------------------------------------------------------\n         case local::PriOp:\n         {\n            // before\n            std::string before( play_.GetTxt( size_t(arg[2]) ) );\n            size_t before_index = graph_obj.print_text_vec_find(before);\n            if( before_index == graph_obj.print_text_vec_size() )\n               graph_obj.print_text_vec_push_back(before);\n            // after\n            std::string after( play_.GetTxt( size_t(arg[4]) ) );\n            size_t after_index = graph_obj.print_text_vec_find(after);\n            if( after_index == graph_obj.print_text_vec_size() )\n               graph_obj.print_text_vec_push_back(after);\n            // notpos\n            size_t notpos_node;\n            if( arg[0] & 1 )\n               notpos_node = var2node[ arg[1] ];\n            else\n               notpos_node = par2node[ arg[1] ];\n            // value\n            size_t value_node;\n            if( arg[0] & 1 )\n               value_node = var2node[ arg[3] ];\n            else\n               value_node = par2node[ arg[3] ];\n            //\n            graph_op = print_graph_op;\n            graph_obj.operator_vec_push_back( graph_op );\n            graph_obj.operator_arg_push_back( before_index );\n            graph_obj.operator_arg_push_back( after_index );\n            graph_obj.operator_arg_push_back( notpos_node );\n            graph_obj.operator_arg_push_back( value_node );\n         }\n         break;\n\n         // --------------------------------------------------------------\n         case local::FunapOp:\n         atom_node_arg.push_back( par2node[arg[0]] );\n         break;\n\n         case local::FunavOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );\n         atom_node_arg.push_back( var2node[arg[0]] );\n         break;\n\n         case local::FunrpOp:\n         par2node[arg[0]] = ++previous_node;\n         break;\n\n         case local::FunrvOp:\n         var2node[i_var] = ++previous_node;\n         break;\n\n         case local::AFunOp:\n         in_atomic_call = ! in_atomic_call;\n         if( in_atomic_call )\n         {  atom_node_arg.resize(0);\n         }\n         else\n         {  // This is the AFunOp at the end of the call\n            size_t atom_index   = size_t( arg[0] );\n            //\n            size_t call_id      = size_t( arg[1] );\n            size_t n_arg        = size_t( arg[2] );\n            size_t n_result     = size_t( arg[3] );\n            CPPAD_ASSERT_UNKNOWN( atom_node_arg.size() == n_arg );\n            //\n            // get the name and type for this atomic function\n            std::string     name;\n            size_t          type;\n            {  bool        set_null = false;\n               void*       ptr;\n               CppAD::local::atomic_index<RecBase>(\n                  set_null, atom_index, type, &name, ptr\n               );\n            }\n            // set graph index for this atomic function\n            size_t name_index = graph_obj.atomic_name_vec_find(name);\n            if( name_index == graph_obj.atomic_name_vec_size() )\n               graph_obj.atomic_name_vec_push_back(name);\n            //\n            // for atom_graph_op:\n            // name_index, n_result, n_arg (before first_node)\n            //\n            // for atom4_graph_op:\n            // name_index, call_id, n_result, n_arg (before first_node)\n            graph_obj.operator_arg_push_back(name_index);\n            if( type == 4 )\n               graph_obj.operator_arg_push_back(call_id);\n            graph_obj.operator_arg_push_back(n_result);\n            graph_obj.operator_arg_push_back(n_arg);\n            if( type == 3 )\n               graph_op = atom_graph_op;\n            else\n            {  CPPAD_ASSERT_UNKNOWN( type == 4 );\n               graph_op = atom4_graph_op;\n            }\n            graph_obj.operator_vec_push_back( graph_op );\n            for(size_t i = 0; i < n_arg; ++i)\n               graph_obj.operator_arg_push_back( atom_node_arg[i] );\n         }\n         break;\n         // --------------------------------------------------------------\n         // CExpOp:\n         case local::CExpOp:\n         {  CompareOp cop = CompareOp( arg[0] );\n            size_t left, right, if_true, if_false;\n            if( arg[1] & 1 )\n               left = var2node[ arg[2] ];\n            else\n               left = par2node[ arg[2] ];\n            if( arg[1] & 2 )\n               right = var2node[ arg[3] ];\n            else\n               right = par2node[ arg[3] ];\n            if( arg[1] & 4 )\n               if_true = var2node[ arg[4] ];\n            else\n               if_true = par2node[ arg[4] ];\n            if( arg[1] & 8 )\n               if_false = var2node[ arg[5] ];\n            else\n               if_false = par2node[ arg[5] ];\n            switch( cop )\n            {  case CompareLt:\n               graph_op = cexp_lt_graph_op;\n               break;\n\n               case CompareLe:\n               graph_op = cexp_le_graph_op;\n               break;\n\n               case CompareEq:\n               graph_op = cexp_eq_graph_op;\n               break;\n\n               case CompareGe:\n               graph_op = cexp_lt_graph_op;\n               std::swap(if_true, if_false);\n               break;\n\n               case CompareGt:\n               graph_op = cexp_le_graph_op;\n               std::swap(if_true, if_false);\n               break;\n\n               case CompareNe:\n               graph_op = cexp_eq_graph_op;\n               std::swap(if_true, if_false);\n               break;\n\n               default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               break;\n            }\n            // var2node and previous_node for this operator\n            var2node[i_var] = ++previous_node;\n            //\n            graph_obj.operator_vec_push_back( graph_op );\n            graph_obj.operator_arg_push_back( left );\n            graph_obj.operator_arg_push_back( right );\n            graph_obj.operator_arg_push_back( if_true );\n            graph_obj.operator_arg_push_back( if_false );\n         }\n         break;\n\n         // --------------------------------------------------------------\n         // EndOp:\n         case local::EndOp:\n         more_operators = false;\n         break;\n\n         // --------------------------------------------------------------\n         // InvOp: independent variables\n         case local::InvOp:\n         // no graph operators for independent variables\n         break;\n\n         // --------------------------------------------------------------\n         // ParOp:\n         case local::ParOp:\n         // no need for a graph operator, just map variable to parameter\n         var2node[i_var] = par2node[arg[0]];\n         break;\n\n         // --------------------------------------------------------------\n         default:\n         // This error should have been reported above\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n      }\n   }\n   // ----------------------------------------------------------------------\n   // output: dependent_vec\n   size_t n_dependent = dep_taddr_.size();\n   for(size_t i = 0; i < n_dependent; ++i)\n      graph_obj.dependent_vec_push_back( var2node[ dep_taddr_[i] ] );\n   //\n   return;\n}\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/graph/to_json.hpp",
    "content": "# ifndef CPPAD_CORE_GRAPH_TO_JSON_HPP\n# define CPPAD_CORE_GRAPH_TO_JSON_HPP\n\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/core/ad_fun.hpp>\n# include <cppad/local/op_code_dyn.hpp>\n# include <cppad/local/graph/cpp_graph_op.hpp>\n# include <cppad/core/graph/cpp_graph.hpp>\n# include <cppad/local/graph/json_writer.hpp>\n\n/*\n------------------------------------------------------------------------------\n{xrst_begin to_json}\n\nJson AD Graph Corresponding to an ADFun Object\n##############################################\n\nSyntax\n******\n| *json* = *fun* . ``to_json`` ()\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nfun\n***\nis the :ref:`adfun-name` object.\n\njson\n****\nThe return value of *json* is a\n:ref:`json_ad_graph-name` representation of the corresponding function.\n\nBase\n****\nis the type corresponding to this :ref:`adfun-name` object;\ni.e., its calculations are done using the type *Base* .\n\nRecBase\n*******\nin the prototype above, *RecBase* is the same type as *Base* .\n\nRestrictions\n************\nThe ``to_json`` routine is not yet implement for some\npossible :ref:`ADFun-name` operators; see\n:ref:`graph_op_enum@Missing Operators` .\n{xrst_toc_hidden\n   example/json/to_json.cpp\n}\nExample\n*******\nThe file :ref:`to_json.cpp-name` is an example and test of this operation.\n\n{xrst_end to_json}\n*/\n// BEGIN_PROTOTYPE\ntemplate <class Base, class RecBase>\nstd::string CppAD::ADFun<Base,RecBase>::to_json(void)\n// END_PROTOTYPE\n{  //\n   // to_graph return values\n   cpp_graph graph_obj;\n   //\n   // graph corresponding to this function\n   to_graph(graph_obj);\n   //\n   // convert to json\n   std::string json;\n   local::graph::json_writer(json, graph_obj);\n   //\n   return json;\n}\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/hash_code.hpp",
    "content": "# ifndef CPPAD_CORE_HASH_CODE_HPP\n# define CPPAD_CORE_HASH_CODE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*!\n\\file core/hash_code.hpp\nCppAD hashing utility.\n*/\n# include <cppad/local/hash_code.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\nGeneral purpose hash code for an arbitrary value.\n\n\\tparam Value\nis the type of the argument being hash coded.\nIt should be a plain old data class; i.e.,\nthe values included in the equality operator in the object and\nnot pointed to by the object.\n\n\\param value\nthe value that we are generating a hash code for.\nAll of the fields in value should have been set before the hash code\nis computed (otherwise undefined values are used).\n\n\\return\nis a hash code that is between zero and CPPAD_HASH_TABLE_SIZE - 1.\n\n\\par Checked Assertions\n\\li std::numeric_limits<unsigned short>::max() >= CPPAD_HASH_TABLE_SIZE\n\\li sizeof(value) is even\n\\li sizeof(unsigned short)  == 2\n*/\ntemplate <class Value>\nunsigned short hash_code(const Value& value)\n{  return local::local_hash_code(value); }\n\n/*!\nhash code for an AD<Base> object.\n\n\\tparam Base\nis the base type for this AD value.\n\n\\param u\nthe AD value that we are generating a hash code for.\n\n\\return\nis a hash code that is between zero and CPPAD_HASH_TABLE_SIZE - 1.\n*/\ntemplate <class Base>\nunsigned short hash_code(const AD<Base>& u)\n{  size_t code = hash_code(u.value_);\n   code       += size_t(u.taddr_);\n   code       += size_t(u.ad_type_ == dynamic_enum);\n   return (unsigned short)(code % CPPAD_HASH_TABLE_SIZE);\n}\n\n} // END_CPPAD_NAMESPACE\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/hessian.hpp",
    "content": "# ifndef CPPAD_CORE_HESSIAN_HPP\n# define CPPAD_CORE_HESSIAN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin Hessian}\n\nHessian: Easy Driver\n####################\n\nSyntax\n******\n| *hes* = *f* . ``Hessian`` ( *x* , *w* )\n| *hes* = *f* . ``Hessian`` ( *x* , *l* )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to *f* .\nThe syntax above sets *hes* to the Hessian\nThe syntax above sets *h* to the Hessian\n\n.. math::\n\n   hes = \\dpow{2}{x} \\sum_{i=1}^m w_i F_i (x)\n\nThe routine :ref:`sparse_hessian-name` may be faster in the case\nwhere the Hessian is sparse.\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nNote that the :ref:`ADFun-name` object *f* is not ``const``\n(see :ref:`Hessian@Hessian Uses Forward` below).\n\nx\n*\nThe argument *x* has prototype\n\n   ``const`` *Vector* & *x*\n\n(see :ref:`Hessian@Vector` below)\nand its size\nmust be equal to *n* , the dimension of the\n:ref:`fun_property@Domain` space for *f* .\nIt specifies\nthat point at which to evaluate the Hessian.\n\nl\n*\nIf the argument *l* is present, it has prototype\n\n   ``size_t`` *l*\n\nand is less than *m* , the dimension of the\n:ref:`fun_property@Range` space for *f* .\nIt specifies the component of *F*\nfor which we are evaluating the Hessian.\nTo be specific, in the case where the argument *l* is present,\n\n.. math::\n\n   w_i = \\left\\{ \\begin{array}{ll}\n      1 & i = l \\\\\n      0 & {\\rm otherwise}\n   \\end{array} \\right.\n\nw\n*\nIf the argument *w* is present, it has prototype\n\n   ``const`` *Vector* & *w*\n\nand size :math:`m`.\nIt specifies the value of :math:`w_i` in the expression\nfor *h* .\n\nhes\n***\nThe result *hes* has prototype\n\n   *Vector* *hes*\n\n(see :ref:`Hessian@Vector` below)\nand its size is :math:`n * n`.\nFor :math:`j = 0 , \\ldots , n - 1`\nand :math:`\\ell = 0 , \\ldots , n - 1`\n\n.. math::\n\n   hes [ j * n + \\ell ] = \\DD{ w^{\\rm T} F }{ x_j }{ x_\\ell } ( x )\n\nVector\n******\nThe type *Vector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n*Base* .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nHessian Uses Forward\n********************\nAfter each call to :ref:`Forward-name` ,\nthe object *f* contains the corresponding\n:ref:`Taylor coefficients<glossary@Taylor Coefficient>` .\nAfter a call to ``Hessian`` ,\nthe zero order Taylor coefficients correspond to\n*f* . ``Forward`` (0, *x* )\nand the other coefficients are unspecified.\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/hessian.cpp\n   example/general/hes_lagrangian.cpp\n}\nThe routines\n:ref:`hessian.cpp-name` and\n:ref:`hes_lagrangian.cpp-name`\nare examples and tests of ``Hessian`` .\nThey return ``true`` , if they succeed and ``false`` otherwise.\n\n{xrst_end Hessian}\n-----------------------------------------------------------------------------\n*/\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base, class RecBase>\ntemplate <class Vector>\nVector ADFun<Base,RecBase>::Hessian(const Vector &x, size_t l)\n{  size_t i, m = Range();\n   CPPAD_ASSERT_KNOWN(\n      l < m,\n      \"Hessian: index i is not less than range dimension for f\"\n   );\n\n   Vector w(m);\n   for(i = 0; i < m; i++)\n      w[i] = Base(0.0);\n   w[l] = Base(1.0);\n\n   return Hessian(x, w);\n}\n\n\ntemplate <class Base, class RecBase>\ntemplate <class Vector>\nVector ADFun<Base,RecBase>::Hessian(const Vector &x, const Vector &w)\n{  size_t j;\n   size_t k;\n\n   size_t n = Domain();\n\n   // check Vector is Simple Vector class with Base type elements\n   CheckSimpleVector<Base, Vector>();\n\n   CPPAD_ASSERT_KNOWN(\n      size_t(x.size()) == n,\n      \"Hessian: length of x not equal domain dimension for f\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(w.size()) == Range(),\n      \"Hessian: length of w not equal range dimension for f\"\n   );\n\n   // point at which we are evaluating the Hessian\n   Forward(0, x);\n\n   // define the return value\n   Vector hes(n * n);\n\n   // direction vector for calls to forward\n   Vector u(n);\n   for(j = 0; j < n; j++)\n      u[j] = Base(0.0);\n\n\n   // location for return values from Reverse\n   Vector ddw(n * 2);\n\n   // loop over forward directions\n   for(j = 0; j < n; j++)\n   {  // evaluate partials of entire function w.r.t. j-th coordinate\n      u[j] = Base(1.0);\n      Forward(1, u);\n      u[j] = Base(0.0);\n\n      // evaluate derivative of partial corresponding to F_i\n      ddw = Reverse(2, w);\n\n      // return desired components\n      for(k = 0; k < n; k++)\n         hes[k * n + j] = ddw[k * 2 + 1];\n   }\n\n   return hes;\n}\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/identical.hpp",
    "content": "# ifndef CPPAD_CORE_IDENTICAL_HPP\n# define CPPAD_CORE_IDENTICAL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/define.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file identical.hpp\nCheck if certain properties is true for any possible AD tape play back.\n*/\n\n// ---------------------------------------------------------------------------\n/*!\nDetermine if an AD<Base> object is a parameter, and could never have\na different value during any tape playback.\n\nAn AD<Base> object x is identically a parameter if and only if\nall of the objects in the following chain are parameters:\n\\code\n   x , x.value , x.value.value , ...\n\\endcode\nIn such a case, the value of the object will always be the same\nno matter what the independent variable values are at any level.\n\n\\param x\nvalues that we are checking for identically a pamameter.\n\n\\return\nreturns true iff x is identically a parameter.\n*/\ntemplate <class Base>\nbool IdenticalCon(const AD<Base> &x)\n{  return Constant(x) && IdenticalCon(x.value_); }\n// Zero ==============================================================\n/*!\nDetermine if an AD<Base> is equal to zero,\nand must be equal zero during any tape playback.\n\n\\param x\nobject that we are checking.\n\n\\return\nreturns true if and only if\n x is equals zero and is identically a parameter \\ref CppAD::IdenticalCon.\n*/\ntemplate <class Base>\nbool IdenticalZero(const AD<Base> &x)\n{  return Constant(x) && IdenticalZero(x.value_); }\n// One ==============================================================\n/*!\nDetermine if an AD<Base> is equal to one,\nand must be equal one during any tape playback.\n\n\\param x\nobject that we are checking.\n\n\\return\nreturns true if and only if\n x is equals one and is identically a parameter \\ref CppAD::IdenticalCon.\n*/\ntemplate <class Base>\nbool IdenticalOne(const AD<Base> &x)\n{  return Constant(x) && IdenticalOne(x.value_); }\n// Equal ===================================================================\n/*!\nDetermine if two AD<Base> objects are equal,\nand must be equal during any tape playback.\n\n\\param x\nfirst of two objects we are checking for equal.\n\n\\param y\nsecond of two objects we are checking for equal.\n\n\\return\nreturns true if and only if\nthe arguments are equal and both identically parameters \\ref CppAD::IdenticalCon.\n*/\ntemplate <class Base>\nbool IdenticalEqualCon\n(const AD<Base> &x, const AD<Base> &y)\n{  bool constant;\n   constant  = Constant(x) && Constant(y);\n   return constant  & IdenticalEqualCon(x.value_, y.value_);\n}\n// ==========================================================================\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/independent/independent.hpp",
    "content": "# ifndef CPPAD_CORE_INDEPENDENT_INDEPENDENT_HPP\n# define CPPAD_CORE_INDEPENDENT_INDEPENDENT_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/independent.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*\n{xrst_begin independent_all dev}\n\nIndependent: All Arguments Present\n##################################\n\nPurpose\n*******\nThis implements :ref:`Independent-name` with all the possible arguments present.\n\nSyntax\n******\n| ``Independent`` ( *x* , *abort_op_index* , *record_compare* , *dynamic* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ALL_ARGUMENT\n   // END_ALL_ARGUMENT\n}\n\nBase\n****\nThe base type the recording started by this operation.\n\nADVector\n********\nis simple vector type with elements of type ``AD`` < *Base* > .\n\nx\n*\nis the vector of the independent variables.\n\nabort_op_index\n**************\noperator index at which execution will be aborted (during  the recording\nof operations). The value zero corresponds to not aborting (will not match).\n\nrecord_compare\n**************\nshould comparison operators be recorded.\n\ndynamic\n*******\nis the independent dynamic parameter vector.\n\n{xrst_end independent_all}\n*/\n// BEGIN_ALL_ARGUMENT\ntemplate <class ADVector>\nvoid Independent(\n   ADVector&  x              ,\n   size_t     abort_op_index ,\n   bool       record_compare ,\n   ADVector&  dynamic        )\n// END_ALL_ARGUMENT\n{  CPPAD_ASSERT_KNOWN(\n      abort_op_index == 0 || record_compare,\n      \"Independent: abort_op_index is non-zero and record_compare is false.\"\n   );\n   typedef typename ADVector::value_type ADBase;\n   typedef typename ADBase::value_type   Base;\n   CPPAD_ASSERT_KNOWN(\n      ADBase::tape_ptr() == nullptr,\n      \"Independent: cannot create a new tape because\\n\"\n      \"a previous tape is still active (for this thread).\\n\"\n      \"AD<Base>::abort_recording() would abort this previous recording.\"\n   );\n   local::ADTape<Base>* tape = ADBase::tape_manage(new_tape_manage);\n   tape->Independent(x, abort_op_index, record_compare, dynamic);\n}\n/*\n----------------------------------------------------------------------------\n{xrst_begin independent_x_abort_record dev}\n\nIndependent: Default For dynamic\n################################\n\nPurpose\n*******\nThis implements :ref:`Independent-name` using\nthe default for the dynamic argument.\n\nSyntax\n******\n``Independent`` ( *x* , *abort_op_index* , *record_compare* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_THREE_ARGUMENT\n   // END_THREE_ARGUMENT\n}\n\nBase\n****\nThe base type the recording started by this operation.\n\nADVector\n********\nis simple vector type with elements of type ``AD`` < *Base* > .\n\nx\n*\nis the vector of the independent variables.\n\nabort_op_index\n**************\noperator index at which execution will be aborted (during  the recording\nof operations). The value zero corresponds to not aborting (will not match).\n\nrecord_compare\n**************\nshould comparison operators be recorded.\n\n{xrst_end independent_x_abort_record}\n*/\n// BEGIN_THREE_ARGUMENT\ntemplate <class ADVector>\nvoid Independent(ADVector &x, size_t abort_op_index, bool record_compare)\n// END_THREE_ARGUMENT\n{  ADVector dynamic(0); // empty vector\n   Independent(x, abort_op_index, record_compare, dynamic);\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin independent_x_abort_op_index dev}\n\nIndependent: Default For record_compare, dynamic\n################################################\n\nPurpose\n*******\nThis implements :ref:`Independent-name` using\nthe default for the record_compare and dynamic arguments.\n\nSyntax\n******\n``Independent`` ( *x* , *abort_op_index* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_X_ABORT_OP_INDEX\n   // END_X_ABORT_OP_INDEX\n}\n\nBase\n****\nThe base type the recording started by this operation.\n\nADVector\n********\nis simple vector type with elements of type ``AD`` < *Base* > .\n\nx\n*\nis the vector of the independent variables.\n\nabort_op_index\n**************\noperator index at which execution will be aborted (during  the recording\nof operations). The value zero corresponds to not aborting (will not match).\n\n{xrst_end independent_x_abort_op_index}\n*/\n// BEGIN_X_ABORT_OP_INDEX\ntemplate <class ADVector>\nvoid Independent(ADVector &x, size_t abort_op_index)\n// END_X_ABORT_OP_INDEX\n{  bool     record_compare = true;\n   ADVector dynamic(0); // empty vector\n   Independent(x, abort_op_index, record_compare, dynamic);\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin independent_x_dynamic dev}\n\nIndependent: Default For abort_op_index, record_compare\n#######################################################\n\nPurpose\n*******\nThis implements :ref:`Independent-name` using\nthe default for the abort_op_index and record_compare.\n\nSyntax\n******\n``Independent`` ( *x* , *dynamic* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_X_DYNAMIC\n   // END_X_DYNAMIC\n}\n\nBase\n****\nThe base type the recording started by this operation.\n\nADVector\n********\nis simple vector type with elements of type ``AD`` < *Base* > .\n\nx\n*\nis the vector of the independent variables.\n\ndynamic\n*******\nis the independent dynamic parameter vector.\n\n{xrst_end independent_x_dynamic}\n*/\n// BEGIN_X_DYNAMIC\ntemplate <class ADVector>\nvoid Independent(ADVector& x, ADVector& dynamic)\n// END_X_DYNAMIC\n{  size_t   abort_op_index = 0;\n   bool     record_compare = true;\n   Independent(x, abort_op_index, record_compare, dynamic);\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin independent_x dev}\n\nIndependent: Default For abort_op_index, record_compare, dynamic\n################################################################\n\nPurpose\n*******\nThis implements :ref:`Independent-name` using\nthe default for the abort_op_index, record_compare and dynamic arguments.\n\nSyntax\n******\n``Independent`` ( *x* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ONE_ARGUMENT\n   // END_ONE_ARGUMENT\n}\n\nBase\n****\nThe base type the recording started by this operation.\n\nADVector\n********\nis simple vector type with elements of type ``AD`` < *Base* > .\n\nx\n*\nis the vector of the independent variables.\n\n{xrst_end independent_x}\n*/\n// BEGIN_ONE_ARGUMENT\ntemplate <class ADVector>\nvoid Independent(ADVector &x)\n// END_ONE_ARGUMENT\n{  size_t   abort_op_index = 0;\n   bool     record_compare = true;\n   ADVector dynamic(0); // empty vector\n   Independent(x, abort_op_index, record_compare, dynamic);\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/integer.hpp",
    "content": "# ifndef CPPAD_CORE_INTEGER_HPP\n# define CPPAD_CORE_INTEGER_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n------------------------------------------------------------------------------\n{xrst_begin Integer}\n\nConvert From AD to Integer\n##########################\n\nSyntax\n******\n| *i* = ``Integer`` ( *x* )\n\nPurpose\n*******\nConverts from an AD type to the corresponding integer value.\n\ni\n*\nThe result *i* has prototype\n\n   ``int`` *i*\n\nx\n*\n\nReal Types\n==========\nIf the argument *x* has either of the following prototypes:\n\n| |tab| ``const float`` & *x*\n| |tab| ``const double`` & *x*\n\nthe fractional part is dropped to form the integer value.\nFor example, if *x* is 1.5, *i* is 1.\nIn general, if :math:`x \\geq 0`, *i* is the\ngreatest integer less than or equal *x* .\nIf :math:`x \\leq 0`, *i* is the\nsmallest integer greater than or equal *x* .\n\nComplex Types\n=============\nIf the argument *x* has either of the following prototypes:\n\n| |tab| ``const std::complex<float>`` & *x*\n| |tab| ``const std::complex<double>`` & *x*\n\nThe result *i* is given by\n\n   *i* = ``Integer`` ( *x* . ``real`` ())\n\nAD Types\n========\nIf the argument *x* has either of the following prototypes:\n\n| |tab| ``const AD`` < *Base* >               & *x*\n| |tab| ``const VecAD`` < *Base* >:: ``reference &`` *x*\n\n*Base* must support the ``Integer`` function and\nthe conversion has the same meaning as for *Base* .\n\nOperation Sequence\n******************\nThe result of this operation is not an\n:ref:`glossary@AD of Base` object.\nThus it will not be recorded as part of an\nAD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/integer.cpp\n}\nThe file\n:ref:`integer.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end Integer}\n------------------------------------------------------------------------------\n*/\n\n\nnamespace CppAD {\n\n   template <class Base>\n   CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\n   int Integer(const AD<Base> &x)\n   {  return Integer(x.value_); }\n\n   template <class Base>\n   CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\n   int Integer(const VecAD_reference<Base> &x)\n   {  return Integer( x.ADBase() ); }\n}\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/jacobian.hpp",
    "content": "# ifndef CPPAD_CORE_JACOBIAN_HPP\n# define CPPAD_CORE_JACOBIAN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin Jacobian}\n\nJacobian: Driver Routine\n########################\n\nSyntax\n******\n| *jac* = *f* . ``Jacobian`` ( *x* )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to *f* .\nThe syntax above sets *jac* to the\nJacobian of *F* evaluated at *x* ; i.e.,\n\n.. math::\n\n   jac = F^{(1)} (x)\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nNote that the :ref:`ADFun-name` object *f* is not ``const``\n(see :ref:`Jacobian@Forward or Reverse` below).\n\nx\n*\nThe argument *x* has prototype\n\n   ``const`` *Vector* & *x*\n\n(see :ref:`Jacobian@Vector` below)\nand its size\nmust be equal to *n* , the dimension of the\n:ref:`fun_property@Domain` space for *f* .\nIt specifies\nthat point at which to evaluate the Jacobian.\n\njac\n***\nThe result *jac* has prototype\n\n   *Vector* *jac*\n\n(see :ref:`Jacobian@Vector` below)\nand its size is :math:`m * n`; i.e., the product of the\n:ref:`fun_property@Domain`\nand\n:ref:`fun_property@Range`\ndimensions for *f* .\nFor :math:`i = 0 , \\ldots , m - 1`\nand :math:`j = 0 , \\ldots , n - 1`\n\n.. math::\n\n   jac[ i * n + j ] = \\D{ F_i }{ x_j } ( x )\n\nVector\n******\nThe type *Vector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n*Base* .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nForward or Reverse\n******************\nThis will use order zero Forward mode and either\norder one Forward or order one Reverse to compute the Jacobian\n(depending on which it estimates will require less work).\nAfter each call to :ref:`Forward-name` ,\nthe object *f* contains the corresponding\n:ref:`Taylor coefficients<glossary@Taylor Coefficient>` .\nAfter a call to ``Jacobian`` ,\nthe zero order Taylor coefficients correspond to\n*f* . ``Forward`` (0, *x* )\nand the other coefficients are unspecified.\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/jacobian.cpp\n}\nThe routine\n:ref:`Jacobian<jacobian.cpp-name>` is both an example and test.\nIt returns ``true`` , if it succeeds and ``false`` otherwise.\n\n{xrst_end Jacobian}\n-----------------------------------------------------------------------------\n*/\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base, class RecBase, class Vector>\nvoid JacobianFor(ADFun<Base, RecBase> &f, const Vector &x, Vector &jac)\n{  size_t i;\n   size_t j;\n\n   size_t n = f.Domain();\n   size_t m = f.Range();\n\n   // check Vector is Simple Vector class with Base type elements\n   CheckSimpleVector<Base, Vector>();\n\n   CPPAD_ASSERT_UNKNOWN( size_t(x.size())   == f.Domain() );\n   CPPAD_ASSERT_UNKNOWN( size_t(jac.size()) == f.Range() * f.Domain() );\n\n   // argument and result for forward mode calculations\n   Vector u(n);\n   Vector v(m);\n\n   // initialize all the components\n   for(j = 0; j < n; j++)\n      u[j] = Base(0.0);\n\n   // loop through the different coordinate directions\n   for(j = 0; j < n; j++)\n   {  // set u to the j-th coordinate direction\n      u[j] = Base(1.0);\n\n      // compute the partial of f w.r.t. this coordinate direction\n      v = f.Forward(1, u);\n\n      // reset u to vector of all zeros\n      u[j] = Base(0.0);\n\n      // return the result\n      for(i = 0; i < m; i++)\n         jac[ i * n + j ] = v[i];\n   }\n}\ntemplate <class Base, class RecBase, class Vector>\nvoid JacobianRev(ADFun<Base, RecBase> &f, const Vector &x, Vector &jac)\n{  size_t i;\n   size_t j;\n\n   size_t n = f.Domain();\n   size_t m = f.Range();\n\n   CPPAD_ASSERT_UNKNOWN( size_t(x.size())   == f.Domain() );\n   CPPAD_ASSERT_UNKNOWN( size_t(jac.size()) == f.Range() * f.Domain() );\n\n   // argument and result for reverse mode calculations\n   Vector u(n);\n   Vector v(m);\n\n   // initialize all the components\n   for(i = 0; i < m; i++)\n      v[i] = Base(0.0);\n\n   // loop through the different coordinate directions\n   for(i = 0; i < m; i++)\n   {  if( f.Parameter(i) )\n      {  // return zero for this component of f\n         for(j = 0; j < n; j++)\n            jac[ i * n + j ] = Base(0.0);\n      }\n      else\n      {\n         // set v to the i-th coordinate direction\n         v[i] = Base(1.0);\n\n         // compute the derivative of this component of f\n         u = f.Reverse(1, v);\n\n         // reset v to vector of all zeros\n         v[i] = Base(0.0);\n\n         // return the result\n         for(j = 0; j < n; j++)\n            jac[ i * n + j ] = u[j];\n      }\n   }\n}\n\ntemplate <class Base, class RecBase>\ntemplate <class Vector>\nVector ADFun<Base,RecBase>::Jacobian(const Vector &x)\n{  size_t i;\n   size_t n = Domain();\n   size_t m = Range();\n\n   CPPAD_ASSERT_KNOWN(\n      size_t(x.size()) == n,\n      \"Jacobian: length of x not equal domain dimension for F\"\n   );\n\n   // point at which we are evaluating the Jacobian\n   Forward(0, x);\n\n   // work factor for forward mode\n   size_t workForward = n;\n\n   // work factor for reverse mode\n   size_t workReverse = 0;\n   for(i = 0; i < m; i++)\n   {  if( ! Parameter(i) )\n         ++workReverse;\n   }\n\n   // choose the method with the least work\n   Vector jac( n * m );\n# ifdef CPPAD_FOR_TMB\n   if( workForward < workReverse )\n# else\n   if( workForward <= workReverse )\n# endif\n      JacobianFor(*this, x, jac);\n   else\n      JacobianRev(*this, x, jac);\n\n   return jac;\n}\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/lu_ratio.hpp",
    "content": "# ifndef CPPAD_CORE_LU_RATIO_HPP\n# define CPPAD_CORE_LU_RATIO_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin LuRatio app}\n{xrst_spell\n   ip\n   jp\n   xk\n}\n\nLU Factorization of A Square Matrix and Stability Calculation\n#############################################################\n\nSyntax\n******\n| ``# include <cppad/cppad.hpp>``\n| *sign* = ``LuRatio`` ( *ip* , *jp* , *LU* , *ratio* )\n\nDescription\n***********\nComputes an LU factorization of the matrix *A*\nwhere *A* is a square matrix.\nA measure of the numerical stability called *ratio* is calculated.\nThis ratio is useful when the results of ``LuRatio`` are\nused as part of an :ref:`ADFun-name` object.\n\nInclude\n*******\nThis routine is designed to be used with AD objects and\nrequires the ``cppad/cppad.hpp`` file to be included.\n\nMatrix Storage\n**************\nAll matrices are stored in row major order.\nTo be specific, if :math:`Y` is a vector\nthat contains a :math:`p` by :math:`q` matrix,\nthe size of :math:`Y` must be equal to :math:`p * q` and for\n:math:`i = 0 , \\ldots , p-1`,\n:math:`j = 0 , \\ldots , q-1`,\n\n.. math::\n\n   Y_{i,j} = Y[ i * q + j ]\n\nsign\n****\nThe return value *sign* has prototype\n\n   ``int`` *sign*\n\nIf *A* is invertible, *sign* is plus or minus one\nand is the sign of the permutation corresponding to the row ordering\n*ip* and column ordering *jp* .\nIf *A* is not invertible, *sign* is zero.\n\nip\n**\nThe argument *ip* has prototype\n\n   *SizeVector* & *ip*\n\n(see description of :ref:`LuFactor@SizeVector` below).\nThe size of *ip* is referred to as *n* in the\nspecifications below.\nThe input value of the elements of *ip* does not matter.\nThe output value of the elements of *ip* determine\nthe order of the rows in the permuted matrix.\n\njp\n**\nThe argument *jp* has prototype\n\n   *SizeVector* & *jp*\n\n(see description of :ref:`LuFactor@SizeVector` below).\nThe size of *jp* must be equal to *n* .\nThe input value of the elements of *jp* does not matter.\nThe output value of the elements of *jp* determine\nthe order of the columns in the permuted matrix.\n\nLU\n**\nThe argument *LU* has the prototype\n\n   *ADvector* & *LU*\n\nand the size of *LU* must equal :math:`n * n`\n(see description of :ref:`LuRatio@ADvector` below).\n\nA\n=\nWe define *A* as the matrix corresponding to the input\nvalue of *LU* .\n\nP\n=\nWe define the permuted matrix *P* in terms of *A* by\n\n   *P* ( *i* , *j* ) = *A* [ *ip* [ *i* ] * *n* + *jp* [ *j* ] ]\n\nL\n=\nWe define the lower triangular matrix *L* in terms of the\noutput value of *LU* .\nThe matrix *L* is zero above the diagonal\nand the rest of the elements are defined by\n\n   *L* ( *i* , *j* ) = *LU* [ *ip* [ *i* ] * *n* + *jp* [ *j* ] ]\n\nfor :math:`i = 0 , \\ldots , n-1` and :math:`j = 0 , \\ldots , i`.\n\nU\n=\nWe define the upper triangular matrix *U* in terms of the\noutput value of *LU* .\nThe matrix *U* is zero below the diagonal,\none on the diagonal,\nand the rest of the elements are defined by\n\n   *U* ( *i* , *j* ) = *LU* [ *ip* [ *i* ] * *n* + *jp* [ *j* ] ]\n\nfor :math:`i = 0 , \\ldots , n-2` and :math:`j = i+1 , \\ldots , n-1`.\n\nFactor\n======\nIf the return value *sign* is non-zero,\n\n   *L* * *U* = *P*\n\nIf the return value of *sign* is zero,\nthe contents of *L* and *U* are not defined.\n\nDeterminant\n===========\nIf the return value *sign* is zero,\nthe determinant of *A* is zero.\nIf *sign* is non-zero,\nusing the output value of *LU*\nthe determinant of the matrix *A* is equal to\n\n   *sign* * *LU* [ *ip* [0], *jp* [0]] * ... * *LU* [ *ip* [ *n* ``-1`` ], *jp* [ *n* ``-1`` ]]\n\nratio\n*****\nThe argument *ratio* has prototype\n\n   ``AD`` < *Base* > & *ratio*\n\nOn input, the value of *ratio* does not matter.\nOn output it is a measure of how good the choice of pivots is.\nFor :math:`p = 0 , \\ldots , n-1`,\nthe *p*-th pivot element is the element of maximum absolute value of a\n:math:`(n-p) \\times (n-p)` sub-matrix.\nThe ratio of each element of sub-matrix divided by the pivot element\nis computed.\nThe return value of *ratio* is the maximum absolute value of\nsuch ratios over with respect to all elements and all the pivots.\n\nPurpose\n=======\nSuppose that the execution of a call to ``LuRatio``\nis recorded in the ``ADFun`` < *Base* > object *F* .\nThen a call to :ref:`Forward-name` of the form\n\n   *F* . ``Forward`` ( *k* , *xk* )\n\nwith *k* equal to zero will revaluate this Lu factorization\nwith the same pivots and a new value for *A* .\nIn this case, the resulting *ratio* may not be one.\nIf *ratio* is too large (the meaning of too large is up to you),\nthe current pivots do not yield a stable LU factorization of *A* .\nA better choice for the pivots (for this value of *A* )\nwill be made if you recreate the ``ADFun`` object\nstarting with the :ref:`Independent-name` variable values\nthat correspond to the vector *xk* .\n\nSizeVector\n**********\nThe type *SizeVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type size_t<SimpleVector@Elements of Specified Type>` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nADvector\n********\nThe type *ADvector* must be a\n:ref:`simple vector class<SimpleVector-name>` with elements of type\n``AD`` < *Base* > .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/lu_ratio.cpp\n}\nThe file :ref:`lu_ratio.cpp-name`\ncontains an example and test of using ``LuRatio`` .\n\n{xrst_end LuRatio}\n--------------------------------------------------------------------------\n*/\nnamespace CppAD { // BEGIN CppAD namespace\n\n// Lines different from the code in cppad/lu_factor.hpp end with           //\ntemplate <class SizeVector, class ADvector, class Base>                    //\nint LuRatio(SizeVector &ip, SizeVector &jp, ADvector &LU, AD<Base> &ratio) //\n{\n   typedef ADvector FloatVector;                                       //\n   typedef AD<Base>       Float;                                       //\n\n   // check numeric type specifications\n   CheckNumericType<Float>();\n\n   // check simple vector class specifications\n   CheckSimpleVector<Float, FloatVector>();\n   CheckSimpleVector<size_t, SizeVector>();\n\n   size_t  i, j;          // some temporary indices\n   const Float zero( 0 ); // the value zero as a Float object\n   size_t  imax;          // row index of maximum element\n   size_t  jmax;          // column index of maximum element\n   Float    emax;         // maximum absolute value\n   size_t  p;             // count pivots\n   int     sign;          // sign of the permutation\n   Float   etmp;          // temporary element\n   Float   pivot;         // pivot element\n\n   // -------------------------------------------------------\n   size_t n = size_t(ip.size());\n   CPPAD_ASSERT_KNOWN(\n      size_t(jp.size()) == n,\n      \"Error in LuFactor: jp must have size equal to n\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(LU.size()) == n * n,\n      \"Error in LuFactor: LU must have size equal to n * m\"\n   );\n   // -------------------------------------------------------\n\n   // initialize row and column order in matrix not yet pivoted\n   for(i = 0; i < n; i++)\n   {  ip[i] = i;\n      jp[i] = i;\n   }\n   // initialize the sign of the permutation\n   sign = 1;\n   // initialize the ratio                                             //\n   ratio = Float(1);                                                   //\n   // ---------------------------------------------------------\n\n   // Reduce the matrix P to L * U using n pivots\n   for(p = 0; p < n; p++)\n   {  // determine row and column corresponding to element of\n      // maximum absolute value in remaining part of P\n      imax = jmax = n;\n      emax = zero;\n      for(i = p; i < n; i++)\n      {  for(j = p; j < n; j++)\n         {  CPPAD_ASSERT_UNKNOWN(\n               (ip[i] < n) && (jp[j] < n)\n            );\n            etmp = LU[ ip[i] * n + jp[j] ];\n\n            // check if maximum absolute value so far\n            if( AbsGeq (etmp, emax) )\n            {  imax = i;\n               jmax = j;\n               emax = etmp;\n            }\n         }\n      }\n      for(i = p; i < n; i++)                                       //\n      {  for(j = p; j < n; j++)                               //\n         {  etmp  = fabs(LU[ ip[i] * n + jp[j] ] / emax); //\n            ratio =                                      //\n            CondExpGt(etmp, ratio, etmp, ratio);         //\n         }                                                    //\n      }                                                            //\n      CPPAD_ASSERT_KNOWN(\n         (imax < n) && (jmax < n) ,\n         \"AbsGeq must return true when second argument is zero\"\n      );\n      if( imax != p )\n      {  // switch rows so max absolute element is in row p\n         i        = ip[p];\n         ip[p]    = ip[imax];\n         ip[imax] = i;\n         sign     = -sign;\n      }\n      if( jmax != p )\n      {  // switch columns so max absolute element is in column p\n         j        = jp[p];\n         jp[p]    = jp[jmax];\n         jp[jmax] = j;\n         sign     = -sign;\n      }\n      // pivot using the max absolute element\n      pivot   = LU[ ip[p] * n + jp[p] ];\n\n      // check for determinant equal to zero\n      if( pivot == zero )\n      {  // abort the mission\n         return   0;\n      }\n\n      // Reduce U by the elementary transformations that maps\n      // LU( ip[p], jp[p] ) to one.  Only need transform elements\n      // above the diagonal in U and LU( ip[p] , jp[p] ) is\n      // corresponding value below diagonal in L.\n      for(j = p+1; j < n; j++)\n         LU[ ip[p] * n + jp[j] ] /= pivot;\n\n      // Reduce U by the elementary transformations that maps\n      // LU( ip[i], jp[p] ) to zero. Only need transform elements\n      // above the diagonal in U and LU( ip[i], jp[p] ) is\n      // corresponding value below diagonal in L.\n      for(i = p+1; i < n; i++ )\n      {  etmp = LU[ ip[i] * n + jp[p] ];\n         for(j = p+1; j < n; j++)\n         {  LU[ ip[i] * n + jp[j] ] -=\n               etmp * LU[ ip[p] * n + jp[j] ];\n         }\n      }\n   }\n   return sign;\n}\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/mul.hpp",
    "content": "# ifndef CPPAD_CORE_MUL_HPP\n# define CPPAD_CORE_MUL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nAD<Base> operator * (const AD<Base> &left , const AD<Base> &right)\n{\n   // compute the Base part\n   AD<Base> result;\n   result.value_  = left.value_ * right.value_;\n   CPPAD_ASSERT_UNKNOWN( Parameter(result) );\n\n   // check if there is a recording in progress\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if left and right tapes match\n   bool match_left  = left.tape_id_  == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n\n   // check if left and right are dynamic parameters\n   bool dyn_left  = match_left  & (left.ad_type_ == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if left and right are variables\n   bool var_left  = match_left  & (left.ad_type_ != dynamic_enum);\n   bool var_right = match_right & (right.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      left.tape_id_ == right.tape_id_ || ! match_left || ! match_right ,\n      \"Multiply: AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_left )\n   {  if( var_right )\n      {  // result = variable * variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::MulvvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::MulvvOp) == 2 );\n\n         // put operand addresses in tape\n         tape->Rec_.PutArg(left.taddr_, right.taddr_);\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::MulvvOp);\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n      else if( (! dyn_right) && IdenticalZero(right.value_) )\n      {  // result = variable * 0\n         result.value_ = Base(0.0); // incase left.value_ is nan\n      }\n      else if( (! dyn_right) && IdenticalOne(right.value_) )\n      {  // result = variable * 1\n         result.make_variable(left.tape_id_, left.taddr_);\n      }\n      else\n      {  // result = variable * parameter\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::MulpvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::MulpvOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = right.taddr_;\n         if( ! dyn_right )\n            p = tape->Rec_.put_con_par(right.value_);\n         tape->Rec_.PutArg(p, left.taddr_);\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::MulpvOp);\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n   }\n   else if( var_right )\n   {  if( (! dyn_left) && IdenticalZero(left.value_) )\n      {  // result = 0 * variable\n         result.value_ = Base(0.0); // incase right.value_ is nan\n      }\n      else if( (! dyn_left) && IdenticalOne(left.value_) )\n      {  // result = 1 * variable\n         result.make_variable(right.tape_id_, right.taddr_);\n      }\n      else\n      {  // result = parameter * variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::MulpvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::MulpvOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = left.taddr_;\n         if( ! dyn_left )\n            p = tape->Rec_.put_con_par(left.value_);\n         tape->Rec_.PutArg(p, right.taddr_);\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::MulpvOp);\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n   }\n   else if( dyn_left | dyn_right )\n   {  if ( (!dyn_left) && IdenticalZero(left.value_))\n      {  // 0 * dynamic\n         result.value_ = Base(0.0);\n      } else if( (!dyn_right) && IdenticalZero(right.value_))\n      {  // dynamic * 0\n         result.value_ = Base(0.0);\n      } else if( (!dyn_left) && IdenticalOne(left.value_))\n      {  // 1 * dynamic\n         result.make_dynamic(right.tape_id_, right.taddr_);\n      } else if( (!dyn_right) && IdenticalOne(right.value_))\n      {  // dynamic * 1\n         result.make_dynamic(left.tape_id_, left.taddr_);\n      } else\n      {\n         addr_t arg0 = left.taddr_;\n         addr_t arg1 = right.taddr_;\n         if( ! dyn_left )\n         arg0 = tape->Rec_.put_con_par(left.value_);\n         if( ! dyn_right )\n         arg1 = tape->Rec_.put_con_par(right.value_);\n         //\n         // parameters with a dynamic parameter result\n         result.taddr_   = tape->Rec_.put_dyn_par(\n            result.value_, local::mul_dyn,   arg0, arg1\n         );\n         result.tape_id_ = tape_id;\n         result.ad_type_ = dynamic_enum;\n      }\n   }\n   return result;\n}\n\n// convert other cases into the case above\nCPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(*)\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/mul_eq.hpp",
    "content": "# ifndef CPPAD_CORE_MUL_EQ_HPP\n# define CPPAD_CORE_MUL_EQ_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nAD<Base>& AD<Base>::operator *= (const AD<Base> &right)\n{\n   // compute the Base part\n   Base left;\n   left    = value_;\n   value_ *= right.value_;\n\n   // check if there is a recording in progress\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return *this;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if left and right tapes match\n   bool match_left  = tape_id_       == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n\n   // check if left and right are dynamic parameters\n   bool dyn_left  = match_left  & (ad_type_ == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if left and right are variables\n   bool var_left  = match_left  & (ad_type_ != dynamic_enum);\n   bool var_right = match_right & (right.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      tape_id_ == right.tape_id_ || ! match_left || ! match_right ,\n      \"*= : AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_left )\n   {  if( var_right )\n      {  // this = variable * variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::MulvvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::MulvvOp) == 2 );\n\n         // put operand addresses in tape\n         tape->Rec_.PutArg(taddr_, right.taddr_);\n         // put operator in the tape\n         taddr_ = tape->Rec_.PutOp(local::MulvvOp);\n         // check that this is a variable\n         CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id );\n         CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum);\n      }\n      else if( (! dyn_right) && IdenticalOne(right.value_) )\n      {  // this = variable * 1\n      }\n      else if( (! dyn_right) && IdenticalZero(right.value_) )\n      {  // this = variable * 0\n         tape_id_ = 0; // not in current tape\n      }\n      else\n      {  // this = variable  * parameter\n         //      = parameter * variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::MulpvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::MulpvOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = right.taddr_;\n         if( ! dyn_right )\n            p = tape->Rec_.put_con_par(right.value_);\n         tape->Rec_.PutArg(p, taddr_);\n         // put operator in the tape\n         taddr_ = tape->Rec_.PutOp(local::MulpvOp);\n         // check that this is a variable\n         CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id );\n         CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum);\n      }\n   }\n   else if( var_right  )\n   {  if( (! dyn_left) && IdenticalZero(left) )\n      {  // this = 0 * right\n      }\n      else if( (! dyn_left) && IdenticalOne(left) )\n      {  // this = 1 * right\n         make_variable(right.tape_id_, right.taddr_);\n      }\n      else\n      {  // this = parameter * variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::MulpvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::MulpvOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = taddr_;\n         if( ! dyn_left )\n            p = tape->Rec_.put_con_par(left);\n         tape->Rec_.PutArg(p, right.taddr_);\n\n         // put operator in the tape\n         taddr_ = tape->Rec_.PutOp(local::MulpvOp);\n\n         // make this a variable\n         tape_id_ = tape_id;\n         ad_type_ = variable_enum;\n      }\n   }\n   else if( dyn_left | dyn_right )\n   {  if( (!dyn_right) && IdenticalOne(right.value_))\n      {  // dynamic *= 1, so do nothing\n      } else if( (!dyn_right) && IdenticalZero(right.value_))\n      {  // dynamic *= 0, so remove from tape\n         tape_id_ = 0;\n      } else if( (!dyn_left) && IdenticalOne(left))\n      {  // 1 *= dynamic\n         make_dynamic(right.tape_id_, right.taddr_);\n      } else if( (!dyn_left) && IdenticalZero(left))\n      {  // 0 *= dynamic, so do nothing\n      } else\n      {      \n         addr_t arg0 = taddr_;\n         addr_t arg1 = right.taddr_;\n         if( ! dyn_left )\n         arg0 = tape->Rec_.put_con_par(left);\n         if( ! dyn_right )\n         arg1 = tape->Rec_.put_con_par(right.value_);\n         //\n         // parameters with a dynamic parameter results\n         taddr_ = tape->Rec_.put_dyn_par(\n            value_, local::mul_dyn, arg0, arg1\n         );\n         tape_id_ = tape_id;\n         ad_type_ = dynamic_enum;\n      }\n   }\n   return *this;\n}\n\nCPPAD_FOLD_ASSIGNMENT_OPERATOR(*=)\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/near_equal_ext.hpp",
    "content": "# ifndef CPPAD_CORE_NEAR_EQUAL_EXT_HPP\n# define CPPAD_CORE_NEAR_EQUAL_EXT_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin near_equal_ext}\n\nCompare AD and Base Objects for Nearly Equal\n############################################\n\nSyntax\n******\n| *b* = ``NearEqual`` ( *x* , *y* , *r* , *a* )\n\nPurpose\n*******\nThe routine :ref:`NearEqual-name` determines if two objects of\nthe same type are nearly.\nThis routine is extended to the case where one object can have type\n*Type* while the other can have type\n``AD`` < *Type* > or\n``AD< std::complex<`` *Type* > > .\n\nx\n*\nThe arguments *x*\nhas one of the following possible prototypes:\n\n| |tab| ``const`` *Type* & *x*\n| |tab| ``const AD`` < *Type* >                 & *x*\n| |tab| ``const AD< std::complex<`` *Type* > > & *x*\n\ny\n*\nThe arguments *y*\nhas one of the following possible prototypes:\n\n| |tab| ``const`` *Type* & *y*\n| |tab| ``const AD`` < *Type* >                 & *y*\n| |tab| ``const AD< std::complex<`` *Type* > > & *x*\n\nr\n*\nThe relative error criteria *r* has prototype\n\n   ``const`` *Type* & *r*\n\nIt must be greater than or equal to zero.\nThe relative error condition is defined as:\n\n.. math::\n\n   \\frac{ | x - y | } { |x| + |y| } \\leq r\n\na\n*\nThe absolute error criteria *a* has prototype\n\n   ``const`` *Type* & *a*\n\nIt must be greater than or equal to zero.\nThe absolute error condition is defined as:\n\n.. math::\n\n   | x - y | \\leq a\n\nb\n*\nThe return value *b* has prototype\n\n   ``bool`` *b*\n\nIf either *x* or *y* is infinite or not a number,\nthe return value is false.\nOtherwise, if either the relative or absolute error\ncondition (defined above) is satisfied, the return value is true.\nOtherwise, the return value is false.\n\nType\n****\nThe type *Type* must be a\n:ref:`NumericType-name` .\nThe routine :ref:`CheckNumericType-name` will generate\nan error message if this is not the case.\nIf *a* and *b* have type *Type* ,\nthe following operation must be defined\n\n.. list-table::\n   :widths: auto\n\n   * - **Operation**\n     - **Description**\n   * - *a* <= *b*\n     - less that or equal operator (returns a ``bool`` object)\n\nOperation Sequence\n******************\nThe result of this operation is not an\n:ref:`glossary@AD of Base` object.\nThus it will not be recorded as part of an\nAD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/near_equal_ext.cpp\n}\nThe file :ref:`near_equal_ext.cpp-name` contains an example\nand test of this extension of :ref:`NearEqual-name` .\nIt return true if it succeeds and false otherwise.\n\n{xrst_end near_equal_ext}\n\n*/\n// BEGIN CppAD namespace\nnamespace CppAD {\n// ------------------------------------------------------------------------\n\n// fold into base type and then use <cppad/near_equal.hpp>\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool NearEqual(\nconst AD<Base> &x, const AD<Base> &y, const Base &r, const Base &a)\n{  return NearEqual(x.value_, y.value_, r, a);\n}\n\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool NearEqual(\nconst Base &x, const AD<Base> &y, const Base &r, const Base &a)\n{  return NearEqual(x, y.value_, r, a);\n}\n\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool NearEqual(\nconst AD<Base> &x, const Base &y, const Base &r, const Base &a)\n{  return NearEqual(x.value_, y, r, a);\n}\n\n// fold into AD type and then use cases above\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool NearEqual(\n   const VecAD_reference<Base> &x, const VecAD_reference<Base> &y,\n   const Base &r, const Base &a)\n{  return NearEqual(x.ADBase(), y.ADBase(), r, a);\n}\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool NearEqual(const VecAD_reference<Base> &x, const AD<Base> &y,\n   const Base &r, const Base &a)\n{  return NearEqual(x.ADBase(), y, r, a);\n}\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool NearEqual(const VecAD_reference<Base> &x, const Base &y,\n   const Base &r, const Base &a)\n{  return NearEqual(x.ADBase(), y, r, a);\n}\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool NearEqual(const AD<Base> &x, const VecAD_reference<Base> &y,\n   const Base &r, const Base &a)\n{  return NearEqual(x, y.ADBase(), r, a);\n}\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool NearEqual(const Base &x, const VecAD_reference<Base> &y,\n   const Base &r, const Base &a)\n{  return NearEqual(x, y.ADBase(), r, a);\n}\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/new_dynamic.hpp",
    "content": "# ifndef CPPAD_CORE_NEW_DYNAMIC_HPP\n# define CPPAD_CORE_NEW_DYNAMIC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin new_dynamic}\n\nChange the Dynamic Parameters\n#############################\n\nSyntax\n******\n| *f* . ``new_dynamic`` ( *dynamic* )\n\nPurpose\n*******\nOften one is only interested in computing derivatives with respect\nto a subset of arguments to a function.\nIn this case, it is easier to make all the arguments to the function\n:ref:`independent variables<glossary@Tape@Independent Variable>` .\nIt is more efficient,\nwill use less memory and be faster,\nif the only the argument were are computing derivatives with respect to\nare independent variables and the other arguments are\n:ref:`glossary@Parameter@Dynamic` parameters.\nThe ``new_dynamic`` method is used to change the value\nof the dynamic parameters in *f* .\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nNote that the :ref:`ADFun-name` object *f* is not ``const`` .\n\ndynamic\n*******\nThis argument has prototype\n\n   ``const`` *BaseVector* & *dynamic*\n\n(see *BaseVector* below).\nIt specifies a new value for the independent\n:ref:`glossary@Parameter@Dynamic` parameters.\nIt size must be the same as the size of the independent\n:ref:`Independent@dynamic` parameter vector\nin the call to ``Independent`` that started\nthe recording for *f* ; see\n:ref:`fun_property@size_dyn_ind` .\n\nBaseVector\n**********\nThe type *BaseVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n*Base* .\n\nTaylor Coefficients\n*******************\nThe Taylor coefficients computed by previous calls to\n:ref:`f.Forward<Forward-name>` are lost after this operation; including the\norder zero coefficients (because they may depend on the dynamic parameters).\nIn order words;\n:ref:`f.size_order<size_order-name>` returns zero directly after\n*f* . ``new_dynamic`` is called.\n{xrst_toc_hidden\n   example/general/new_dynamic.cpp\n}\nExample\n*******\nThe file :ref:`new_dynamic.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end new_dynamic}\n*/\n# include <cppad/local/sweep/dynamic.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file new_dynamic.hpp\nUser interface to ADFun dynamic_parameter member function.\n*/\n\n/*!\nChange the dynamic parameters in this ADFun object\n\n\\param dynamic\nis the vector of new values for the dynamic parameters.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector>\nvoid ADFun<Base,RecBase>::new_dynamic(const BaseVector& dynamic)\n{  using local::pod_vector;\n   CPPAD_ASSERT_KNOWN(\n      size_t( dynamic.size() ) == play_.n_dyn_independent() ,\n      \"f.new_dynamic: dynamic.size() different from corresponding \"\n      \"call to Independent\"\n   );\n   // check BaseVector is Simple Vector class with Base elements\n   CheckSimpleVector<Base, BaseVector>();\n\n   // retrieve player information about the dynamic parameters\n   local::pod_vector_maybe<Base>&     par_all( play_.par_all() );\n   const pod_vector<bool>&            par_is_dyn ( play_.par_is_dyn()  );\n   const pod_vector<local::opcode_t>& dyn_par_op ( play_.dyn_par_op()  );\n   const pod_vector<addr_t>&          dyn_par_arg( play_.dyn_par_arg() );\n   const pod_vector<addr_t>&     dyn2par_index ( play_.dyn2par_index() );\n\n   // set the dependent dynamic parameters\n   RecBase not_used_rec_base(0.0);\n   local::sweep::dynamic(\n      par_all             ,\n      dynamic             ,\n      par_is_dyn          ,\n      dyn2par_index       ,\n      dyn_par_op          ,\n      dyn_par_arg         ,\n      not_used_rec_base\n   );\n\n   // the existing Taylor coefficients are no longer valid\n   num_order_taylor_ = 0;\n\n   return;\n}\n\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/num_skip.hpp",
    "content": "# ifndef CPPAD_CORE_NUM_SKIP_HPP\n# define CPPAD_CORE_NUM_SKIP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin number_skip}\n\nNumber of Variables that Can be Skipped\n#######################################\n\nSyntax\n******\n| *n* = *f* . ``number_skip`` ()\n\nSee Also\n========\n:ref:`fun_property-name`\n\nPurpose\n*******\nThe :ref:`conditional expressions<CondExp-name>` use either the\n:ref:`if_true<CondExp-name>` or :ref:`if_false<CondExp-name>` .\nHence, some terms only need to be evaluated\ndepending on the value of the comparison in the conditional expression.\nThe :ref:`optimize-name` option is capable of detecting some of these\ncase and determining variables that can be skipped.\nThis routine returns the number such variables.\n\nn\n*\nThe return value *n* has type ``size_t``\nis the number of variables that the optimizer has determined can be skipped\n(given the independent variable values specified by the previous call to\n:ref:`f.Forward<Forward-name>` for order zero).\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\n{xrst_toc_hidden\n   example/general/number_skip.cpp\n}\nExample\n*******\nThe file :ref:`number_skip.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end number_skip}\n-----------------------------------------------------------------------------\n*/\n\n# include <cppad/local/play/atom_op_info.hpp>\n\n// BEGIN CppAD namespace\nnamespace CppAD {\n\n// This routine is not const because it runs through the operations sequence\n// 2DO: compute this value during zero order forward operations.\ntemplate <class Base, class RecBase>\nsize_t ADFun<Base,RecBase>::number_skip(void)\n{  // must pass through operation sequence to map operations to variables\n\n   // information defined by atomic forward\n   size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0;\n\n   // number of variables skipped\n   size_t num_var_skip = 0;\n\n   // start playback\n   local::play::const_sequential_iterator itr = play_.begin();\n   local::op_code_var op;\n   size_t        i_var;\n   const addr_t* arg;\n   itr.op_info(op, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN(op == local::BeginOp)\n   while(op != local::EndOp)\n   {  // next op\n      (++itr).op_info(op, arg, i_var);\n      //\n      if( op == local::AFunOp )\n      {  // skip only appears at front or back AFunOp of atomic function call\n         bool skip_call = cskip_op_[ itr.op_index() ];\n         local::play::atom_op_info<Base>(\n            op, arg, atom_index, atom_old, atom_m, atom_n\n         );\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 );\n         size_t num_op = atom_m + atom_n + 1;\n         for(size_t i = 0; i < num_op; i++)\n         {  CPPAD_ASSERT_UNKNOWN(\n               op != local::CSkipOp && op != local::CSumOp\n            );\n            (++itr).op_info(op, arg, i_var);\n            if( skip_call )\n               num_var_skip += NumRes(op);\n         }\n         CPPAD_ASSERT_UNKNOWN( op == local::AFunOp );\n      }\n      else\n      {  if( cskip_op_[ itr.op_index() ] )\n            num_var_skip += NumRes(op);\n         //\n         if( (op == local::CSkipOp) || (op == local::CSumOp) )\n            itr.correct_before_increment();\n      }\n   }\n   return num_var_skip;\n}\n\n} // END CppAD namespace\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/numeric_limits.hpp",
    "content": "# ifndef CPPAD_CORE_NUMERIC_LIMITS_HPP\n# define CPPAD_CORE_NUMERIC_LIMITS_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n------------------------------------------------------------------------------\n{xrst_begin numeric_limits}\n{xrst_spell\n   eps\n   isnan\n}\n\nNumeric Limits For an AD and Base Types\n#######################################\n\nSyntax\n******\n| *eps* = ``numeric_limits`` < *Float* >:: ``epsilon`` ()\n| *min* = ``numeric_limits`` < *Float* >:: ``min`` ()\n| *max* = ``numeric_limits`` < *Float* >:: ``max`` ()\n| *nan* = ``numeric_limits`` < *Float* >:: ``quiet_NaN`` ()\n| *inf* = ``numeric_limits`` < *Float* >:: ``infinity`` ()\n| ``numeric_limits`` < *Float* >:: ``digits10``\n| ``numeric_limits`` < *Float* >:: ``max_digits10``\n\nCppAD::numeric_limits\n*********************\nThe functions above and have the prototype\n\n   ``static`` *Float* ``CppAD::numeric_limits<`` *Float* >:: *fun* ( *void* )\n\nwhere *fun* is\n``epsilon`` , ``min`` , ``max`` , ``quiet_NaN`` , and ``infinity`` .\n\nThe values ``digits10`` and ``max_digits10`` are\nmember variable and not a functions.\n\nstd::numeric_limits\n*******************\nCppAD does not use a specialization of ``std::numeric_limits``\nbecause this would be to restrictive.\nThe C++ standard specifies that Non-fundamental standard\ntypes, such as\n:ref:`std::complex\\<double><base_complex.hpp-name>`\nshall not have specializations\nof ``std::numeric_limits`` ; see Section 18.2 of\nISO/IEC 14882:1998(E).\nIn addition, since C++11, a only literal types can have a specialization\nof ``std::numeric_limits`` .\n\nFloat\n*****\nThese functions are defined for all ``AD`` < *Base* > ,\nand for all corresponding *Base* types;\nsee *Base* type :ref:`base_limits-name` .\n\nepsilon\n*******\nThe result *eps* is equal to machine epsilon and has prototype\n\n   *Float* *eps*\n\nThe file :ref:`num_limits.cpp-name`\ntests the value *eps* by checking that the following are true\n\n| |tab| 1 != 1 + *eps*\n| |tab| 1 == 1 + *eps*  / 2\n\nwhere all the values, and calculations, are done with the precision\ncorresponding to *Float* .\n\nmin\n***\nThe result *min* is equal to\nthe minimum positive normalized value and has prototype\n\n   *Float* *min*\n\nThe file :ref:`num_limits.cpp-name`\ntests the value *min* by checking that the following are true\n\n| |tab| ``abs`` ( (( *min* / 100) * 100) / *min* ``- 1`` ) > 3 * *eps*\n| |tab| ``abs`` ( (( *min* * 100) / 100) / *min* ``- 1`` ) < 3 * *eps*\n\nwhere all the values, and calculations, are done with the precision\ncorresponding to *Float* .\n\nmax\n***\nThe result *max* is equal to\nthe maximum finite value and has prototype\n\n   *Float* *max*\n\nThe file :ref:`num_limits.cpp-name`\ntests the value *max* by checking that the following are true\n\n| |tab| ``abs`` ( (( *max* * 100) / 100) / *max* ``- 1`` ) > 3 * *eps*\n| |tab| ``abs`` ( (( *max* / 100) * 100) / *max* ``- 1`` ) < 3 * *eps*\n\nwhere all the values, and calculations, are done with the precision\ncorresponding to *Float* .\n\nquiet_NaN\n*********\nThe result *nan* is not a number and has prototype\n\n   *Float* *nan*\n\nThe file :ref:`num_limits.cpp-name`\ntests the value *nan* by checking that the following is true\n\n   *nan* != *nan*\n\ninfinity\n********\nThe result *inf* is equal to the\npositive infinite value and has prototype\n\n   *Float* *inf*\n\nThe file :ref:`num_limits.cpp-name`\ntests the value *inf* by checking that the following are true\n\n| |tab| *inf* + 100 == *inf*\n| |tab| ``isnan`` ( *inf* ``-`` *inf* )\n\ndigits10\n********\nThe member variable ``digits10`` has prototype\n\n   ``static const int numeric_limits`` < *Float* >:: ``digits10``\n\nIt is the number of decimal digits that can be represented by a\n*Float* value.  A number with this many decimal digits can be\nconverted to *Float* and back to a string,\nwithout change due to rounding or overflow.\n\nmax_digits10\n************\nThe member variable ``max_digits10`` has prototype\n\n   ``static const int numeric_limits`` < *Float* >:: ``max_digits10``\n\nis the number of decimal digits that are necessary to uniquely represent\nall distinct values of the type *Float* .\nFor example, the number of digits necessary to convert to text and back\nand get the exact same result.\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/num_limits.cpp\n}\nThe file\n:ref:`num_limits.cpp-name`\ncontains an example and test of these functions.\n\n{xrst_end numeric_limits}\n------------------------------------------------------------------------------\n*/\n# include <iostream>\n\n# include <cppad/configure.hpp>\n# include <cppad/local/define.hpp>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/local/declare_ad.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file numeric_limits.hpp\nFile that defines CppAD numeric_limits for AD types\n*/\n\n/// All these defaults correspond to errors\ntemplate <class Float>\nclass numeric_limits {\npublic:\n   /// machine epsilon\n   static Float epsilon(void)\n   {  CPPAD_ASSERT_KNOWN(\n      false,\n      \"numeric_limits<Float>::epsilon() is not specialized for this Float\"\n      );\n      return Float(0);\n   }\n   /// minimum positive normalized value\n   static Float min(void)\n   {  CPPAD_ASSERT_KNOWN(\n      false,\n      \"numeric_limits<Float>::min() is not specialized for this Float\"\n      );\n      return Float(0);\n   }\n   /// maximum finite value\n   static Float max(void)\n   {  CPPAD_ASSERT_KNOWN(\n      false,\n      \"numeric_limits<Float>::max() is not specialized for this Float\"\n      );\n      return Float(0);\n   }\n   /// not a number\n   static Float quiet_NaN(void)\n   {  CPPAD_ASSERT_KNOWN(\n      false,\n      \"numeric_limits<Float>::quiet_NaN() is not specialized for this Float\"\n      );\n      return Float(0);\n   }\n   /// positive infinite value\n   static Float infinity(void)\n   {  CPPAD_ASSERT_KNOWN(\n      false,\n      \"numeric_limits<Float>::infinity() is not specialized for this Float\"\n      );\n      return Float(0);\n   }\n   /// number of decimal digits\n   static const int digits10 = -1;\n};\n\n/// Partial specialization that defines limits for for all AD types\ntemplate <class Base>\nclass numeric_limits< AD<Base> > {\npublic:\n   /// machine epsilon\n   static AD<Base> epsilon(void)\n   {  return AD<Base>( numeric_limits<Base>::epsilon() ); }\n   /// minimum positive normalized value\n   static AD<Base> min(void)\n   {  return AD<Base>( numeric_limits<Base>::min() ); }\n   /// maximum finite value\n   static AD<Base> max(void)\n   {  return AD<Base>( numeric_limits<Base>::max() ); }\n   /// not a number\n   static AD<Base> quiet_NaN(void)\n   {  return AD<Base>( numeric_limits<Base>::quiet_NaN() ); }\n   /// positive infinite value\n   static AD<Base> infinity(void)\n   {  return AD<Base>( numeric_limits<Base>::infinity() ); }\n   /// number of decimal digits\n   static const int digits10     = numeric_limits<Base>::digits10;\n   static const int max_digits10 = numeric_limits<Base>::max_digits10;\n};\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/omp_max_thread.hpp",
    "content": "# ifndef CPPAD_CORE_OMP_MAX_THREAD_HPP\n# define CPPAD_CORE_OMP_MAX_THREAD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin omp_max_thread app}\n{xrst_spell\n   mp\n}\n\nOpenMP Parallel Setup\n#####################\n\nDeprecated 2011-06-23\n*********************\nUse :ref:`thread_alloc::parallel_setup<ta_parallel_setup-name>`\nto set the number of threads.\n\nSyntax\n******\n| ``AD`` < *Base* >:: ``omp_max_thread`` ( *number* )\n\nPurpose\n*******\nBy default, for each ``AD`` < *Base* > class there is only one\ntape that records :ref:`glossary@AD of Base` operations.\nThis tape is a global variable and hence it cannot be used\nby multiple OpenMP threads at the same time.\nThe ``omp_max_thread`` function is used to set the\nmaximum number of OpenMP threads that can be active.\nIn this case, there is a different tape corresponding to each\n``AD`` < *Base* > class and thread pair.\n\nnumber\n******\nThe argument *number* has prototype\n\n   ``size_t`` *number*\n\nIt must be greater than zero and specifies the maximum number of\nOpenMp threads that will be active at one time.\n\nIndependent\n***********\nEach call to :ref:`Independent(x)<Independent-name>`\ncreates a new :ref:`glossary@Tape@Active` tape.\nAll of the operations with the corresponding variables\nmust be preformed by the same OpenMP thread.\nThis includes the corresponding call to\n:ref:`f.Dependent(x,y)<Dependent-name>` or the\n:ref:`ADFun f(x, y)<fun_construct@Sequence Constructor>`\nduring which the tape stops recording and the variables\nbecome parameters.\n\nRestriction\n***********\nNo tapes can be\n:ref:`glossary@Tape@Active` when this function is called.\n\n{xrst_end omp_max_thread}\n-----------------------------------------------------------------------------\n*/\n\n// BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nvoid AD<Base>::omp_max_thread(size_t number)\n{\n# ifdef _OPENMP\n   thread_alloc::parallel_setup(\n      number, omp_alloc::in_parallel, omp_alloc::get_thread_num\n   );\n# else\n   CPPAD_ASSERT_KNOWN(\n      number == 1,\n      \"omp_max_thread: number > 1 and _OPENMP is not defined\"\n   );\n# endif\n   parallel_ad<Base>();\n}\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/opt_val_hes.hpp",
    "content": "# ifndef CPPAD_CORE_OPT_VAL_HES_HPP\n# define CPPAD_CORE_OPT_VAL_HES_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin opt_val_hes app}\n{xrst_spell\n   signdet\n   sy\n   yy\n}\n\nJacobian and Hessian of Optimal Values\n######################################\n\nSyntax\n******\n| *signdet* = ``opt_val_hes`` ( *x* , *y* , *fun* , *jac* , *hes* )\n\nSee Also\n********\n:ref:`BenderQuad-name`\n\nReference\n*********\nAlgorithmic differentiation of implicit functions and optimal values,\nBradley M. Bell and James V. Burke, Advances in Automatic Differentiation,\n2008, Springer.\n\nPurpose\n*******\nWe are given a function\n:math:`S : \\B{R}^n \\times \\B{R}^m \\rightarrow \\B{R}^\\ell`\nand we define :math:`F : \\B{R}^n \\times \\B{R}^m \\rightarrow \\B{R}`\nand :math:`V : \\B{R}^n \\rightarrow \\B{R}` by\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      F(x, y) & = & \\sum_{k=0}^{\\ell-1} S_k ( x , y)\n      \\\\\n      V(x)    & = & F [ x , Y(x) ]\n      \\\\\n      0       & = & \\partial_y F [x , Y(x) ]\n   \\end{eqnarray}\n\nWe wish to compute the Jacobian\nand possibly also the Hessian, of :math:`V (x)`.\n\nBaseVector\n**********\nThe type *BaseVector* must be a\n:ref:`SimpleVector-name` class.\nWe use *Base* to refer to the type of the elements of\n*BaseVector* ; i.e.,\n\n   *BaseVector* :: ``value_type``\n\nx\n*\nThe argument *x* has prototype\n\n   ``const`` *BaseVector* & *x*\n\nand its size must be equal to *n* .\nIt specifies the point at which we evaluating\nthe Jacobian :math:`V^{(1)} (x)`\n(and possibly the Hessian :math:`V^{(2)} (x)`).\n\ny\n*\nThe argument *y* has prototype\n\n   ``const`` *BaseVector* & *y*\n\nand its size must be equal to *m* .\nIt must be equal to :math:`Y(x)`; i.e.,\nit must solve the implicit equation\n\n.. math::\n\n   0 = \\partial_y F ( x , y)\n\nFun\n***\nThe argument *fun* is an object of type *Fun*\nwhich must support the member functions listed below.\nCppAD will may be recording operations of the type ``AD`` < *Base* >\nwhen these member functions are called.\nThese member functions must not stop such a recording; e.g.,\nthey must not call :ref:`AD\\<Base>::abort_recording<abort_recording-name>` .\n\nFun::ad_vector\n==============\nThe type *Fun* :: ``ad_vector`` must be a\n:ref:`SimpleVector-name` class with elements of type ``AD`` < *Base* > ; i.e.\n\n   *Fun* :: ``ad_vector::value_type``\n\nis equal to ``AD`` < *Base* > .\n\nfun.ell\n=======\nThe type *Fun* must support the syntax\n\n   *ell* = *fun* . ``ell`` ()\n\nwhere *ell* has prototype\n\n   ``size_t`` *ell*\n\nand is the value of :math:`\\ell`; i.e.,\nthe number of terms in the summation.\n\nOne can choose *ell* equal to one, and have\n:math:`S(x,y)` the same as :math:`F(x, y)`.\nEach of the functions :math:`S_k (x , y)`,\n(in the summation defining :math:`F(x, y)`)\nis differentiated separately using AD.\nFor very large problems, breaking :math:`F(x, y)` into the sum\nof separate simpler functions may reduce the amount of memory necessary for\nalgorithmic differentiation and there by speed up the process.\n\nfun.s\n=====\nThe type *Fun* must support the syntax\n\n   *s_k* = *fun* . ``s`` ( *k* , *x* , *y* )\n\nThe *fun* . ``s`` argument *k* has prototype\n\n   ``size_t`` *k*\n\nand is between zero and *ell* ``- 1`` .\nThe argument *x* to *fun* . ``s`` has prototype\n\n   ``const`` *Fun* :: ``ad_vector&`` *x*\n\nand its size must be equal to *n* .\nThe argument *y* to *fun* . ``s`` has prototype\n\n   ``const`` *Fun* :: ``ad_vector&`` *y*\n\nand its size must be equal to *m* .\nThe *fun* . ``s`` result *s_k* has prototype\n\n   ``AD`` < *Base* > *s_k*\n\nand its value must be given by :math:`s_k = S_k ( x , y )`.\n\nfun.sy\n======\nThe type *Fun* must support the syntax\n\n   *sy_k* = *fun* . ``sy`` ( *k* , *x* , *y* )\n\nThe  argument *k* to *fun* . ``sy`` has prototype\n\n   ``size_t`` *k*\n\nThe  argument *x* to *fun* . ``sy`` has prototype\n\n   ``const`` *Fun* :: ``ad_vector&`` *x*\n\nand its size must be equal to *n* .\nThe  argument *y* to *fun* . ``sy`` has prototype\n\n   ``const`` *Fun* :: ``ad_vector&`` *y*\n\nand its size must be equal to *m* .\nThe *fun* . ``sy`` result *sy_k* has prototype\n\n   *Fun* :: ``ad_vector`` *sy_k*\n\nits size must be equal to *m* ,\nand its value must be given by :math:`sy_k = \\partial_y S_k ( x , y )`.\n\njac\n***\nThe argument *jac* has prototype\n\n   *BaseVector* & *jac*\n\nand has size *n* or zero.\nThe input values of its elements do not matter.\nIf it has size zero, it is not affected. Otherwise, on output\nit contains the Jacobian of :math:`V (x)`; i.e.,\nfor :math:`j = 0 , \\ldots , n-1`,\n\n.. math::\n\n   jac[ j ] = V^{(1)} (x)_j\n\nwhere *x* is the first argument to ``opt_val_hes`` .\n\nhes\n***\nThe argument *hes* has prototype\n\n   *BaseVector* & *hes*\n\nand has size *n* * *n* or zero.\nThe input values of its elements do not matter.\nIf it has size zero, it is not affected. Otherwise, on output\nit contains the Hessian of :math:`V (x)`; i.e.,\nfor :math:`i = 0 , \\ldots , n-1`, and\n:math:`j = 0 , \\ldots , n-1`,\n\n.. math::\n\n   hes[ i * n + j ] = V^{(2)} (x)_{i,j}\n\nsigndet\n*******\nIf *hes* has size zero, *signdet* is not defined.\nOtherwise\nthe return value *signdet* is the sign of the determinant for\n:math:`\\partial_{yy}^2 F(x , y)`.\nIf it is zero, then the matrix is singular and\nthe Hessian is not computed ( *hes* is not changed).\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/opt_val_hes.cpp\n}\nThe file\n:ref:`opt_val_hes.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end opt_val_hes}\n-----------------------------------------------------------------------------\n*/\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file opt_val_hes.hpp\n\\brief Computing Jabobians and Hessians of Optimal Values\n*/\n\n/*!\nComputing Jabobians and Hessians of Optimal Values\n\nWe are given a function\n\\f$ S : {\\rm R}^n \\times {\\rm R}^m \\rightarrow {\\rm R}^\\ell \\f$\nand we define \\f$ F : {\\rm R}^n \\times {\\rm R}^m \\rightarrow {\\rm R} \\f$\nand \\f$ V : {\\rm R}^n \\rightarrow {\\rm R}  \\f$ by\n\\f[\n\\begin{array}{rcl}\n   F(x, y) & = & \\sum_{k=0}^{\\ell-1} S_k ( x , y)\n   \\\\\n   V(x)    & = & F [ x , Y(x) ]\n   \\\\\n   0       & = & \\partial_y F [x , Y(x) ]\n\\end{array}\n\\f]\nWe wish to compute the Jacobian\nand possibly also the Hessian, of \\f$ V (x) \\f$.\n\n\\tparam BaseVector\nThe type BaseVector must be a SimpleVector class.\nWe use Base to refer to the type of the elements of\n BaseVector; i.e.,\n<tt>BaseVector::value_type</tt>.\n\n\\param x\nis a vector with size n.\nIt specifies the point at which we evaluating\nthe Jacobian \\f$ V^{(1)} (x) \\f$\n(and possibly the Hessian \\f$ V^{(2)} (x) \\f$).\n\n\n\\param y\nis a vector with size m.\nIt must be equal to \\f$ Y(x) \\f$; i.e.,\nit must solve the implicit equation\n\\f[\n   0 = \\partial_y F ( x , y)\n\\f]\n\n\\param fun\nThe argument fun is an object of type Fun\nwhich must support the member functions listed below.\nCppAD will may be recording operations of the type  AD<Base>\nwhen these member functions are called.\nThese member functions must not stop such a recording; e.g.,\nthey must not call AD<Base>::abort_recording.\n\n\\par Fun::ad_vector</tt>\nThe type <tt>Fun::ad_vector</tt> must be a\nSimpleVector class with elements of type  AD<Base>; i.e.\n<tt>Fun::ad_vector::value_type</tt>\nis equal to  AD<Base>.\n\n\\par fun.ell\nthe type Fun must support the syntax\n\\verbatim\n   ell = fun.ell()\n\\endverbatim\nwhere ell is a size_t value that is set to \\f$ \\ell \\f$; i.e.,\nthe number of terms in the summation.\n\n\\par fun.s\nThe type Fun must support the syntax\n\\verbatim\n   s_k = fun.s(k, x, y)\n\\endverbatim\nThe argument k has prototype <tt>size_t k</tt>.\nThe argument x has prototype <tt>const Fun::ad_vector& x</tt>\nand its size must be equal to n.\nThe argument y has prototype <tt>const Fun::ad_vector& y</tt>\nand its size must be equal to m.\nThe return value s_k has prototype AD<Base> s_k\nand its value must be given by \\f$ s_k = S_k ( x , y ) \\f$.\n\n\\par fun.sy\nThe type Fun must support the syntax\n\\verbatim\n   sy_k = fun.sy(k, x, y)\n\\endverbatim\nThe argument k has prototype <tt>size_t k</tt>.\nThe argument x has prototype <tt>const Fun::ad_vector& x</tt>\nand its size must be equal to n.\nThe argument y has prototype <tt>const Fun::ad_vector& y</tt>\nand its size must be equal to m.\nThe return value sy_k has prototype <tt>Fun::ad_vector& sy_k</tt>,\nits size is m\nand its value must be given by \\f$ sy_k = \\partial_y S_k ( x , y ) \\f$.\n\n\\param jac\nis a vector with size n or zero.\nThe input values of its elements do not matter.\nIf it has size zero, it is not affected. Otherwise, on output\nit contains the Jacobian of \\f$ V (x) \\f$; i.e.,\nfor \\f$ j = 0 , \\ldots , n-1 \\f$,\n\\f[\n   jac[ j ] = V^{(1)} (x)_j\n\\f] $$\nwhere x is the first argument to opt_val_hes.\n\n\\param hes\nis a vector with size <tt>n * n</tt> or zero.\nThe input values of its elements do not matter.\nIf it has size zero, it is not affected. Otherwise, on output\nit contains the Hessian of \\f$ V (x) \\f$; i.e.,\nfor \\f$ i = 0 , \\ldots , n-1 \\f$, and\n\\f$ j = 0 , \\ldots , n-1 \\f$,\n\\f[\n   hes[ i * n + j ] = V^{(2)} (x)_{i,j}\n\\f]\n\n\\return\nIf <tt>hes.size() == 0</tt>, the return value is not defined.\nOtherwise,\nthe return value is the sign of the determinant for\n\\f$ \\partial_{yy}^2 F(x , y) \\f$$.\nIf it is zero, then the matrix is singular and hes is not set\nto its specified value.\n*/\n\n\ntemplate <class BaseVector, class Fun>\nint opt_val_hes(\n   const BaseVector&   x     ,\n   const BaseVector&   y     ,\n   Fun                 fun   ,\n   BaseVector&         jac   ,\n   BaseVector&         hes   )\n{  // determine the base type\n   typedef typename BaseVector::value_type Base;\n\n   // check that BaseVector is a SimpleVector class with Base elements\n   CheckSimpleVector<Base, BaseVector>();\n\n   // determine the AD vector type\n   typedef typename Fun::ad_vector ad_vector;\n\n   // check that ad_vector is a SimpleVector class with AD<Base> elements\n   CheckSimpleVector< AD<Base> , ad_vector >();\n\n   // size of the x and y spaces\n   size_t n = size_t(x.size());\n   size_t m = size_t(y.size());\n\n   // number of terms in the summation\n   size_t ell = fun.ell();\n\n   // check size of return values\n   CPPAD_ASSERT_KNOWN(\n      size_t(jac.size()) == n || jac.size() == 0,\n      \"opt_val_hes: size of the vector jac is not equal to n or zero\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(hes.size()) == n * n || hes.size() == 0,\n      \"opt_val_hes: size of the vector hes is not equal to n * n or zero\"\n   );\n\n   // some temporary indices\n   size_t i, j, k;\n\n   // AD version of S_k(x, y)\n   ad_vector s_k(1);\n\n   // ADFun version of S_k(x, y)\n   ADFun<Base> S_k;\n\n   // AD version of x\n   ad_vector a_x(n);\n\n   // AD version of y\n   ad_vector a_y(n);\n\n   if( jac.size() > 0  )\n   {  // this is the easy part, computing the V^{(1)} (x) which is equal\n      // to \\partial_x F (x, y) (see Theorem 2 of the reference).\n\n      // copy x and y to AD version\n      for(j = 0; j < n; j++)\n         a_x[j] = x[j];\n      for(j = 0; j < m; j++)\n         a_y[j] = y[j];\n\n      // initialize summation\n      for(j = 0; j < n; j++)\n         jac[j] = Base(0.);\n\n      // add in \\partial_x S_k (x, y)\n      for(k = 0; k < ell; k++)\n      {  // start recording\n         Independent(a_x);\n         // record\n         s_k[0] = fun.s(k, a_x, a_y);\n         // stop recording and store in S_k\n         S_k.Dependent(a_x, s_k);\n         // compute partial of S_k with respect to x\n         BaseVector jac_k = S_k.Jacobian(x);\n         // add \\partial_x S_k (x, y) to jac\n         for(j = 0; j < n; j++)\n            jac[j] += jac_k[j];\n      }\n   }\n   // check if we are done\n   if( hes.size() == 0 )\n      return 0;\n\n   /*\n   In this case, we need to compute the Hessian. Using Theorem 1 of the\n   reference:\n      Y^{(1)}(x) = - F_yy (x, y)^{-1} F_yx (x, y)\n   Using Theorem 2 of the reference:\n      V^{(2)}(x) = F_xx (x, y) + F_xy (x, y)  Y^{(1)}(x)\n   */\n   // Base and AD version of xy\n   BaseVector xy(n + m);\n   ad_vector a_xy(n + m);\n   for(j = 0; j < n; j++)\n      a_xy[j] = xy[j] = x[j];\n   for(j = 0; j < m; j++)\n      a_xy[n+j] = xy[n+j] = y[j];\n\n   // Initialization summation for Hessian of F\n   size_t nm_sq = (n + m) * (n + m);\n   BaseVector F_hes(nm_sq);\n   for(j = 0; j < nm_sq; j++)\n      F_hes[j] = Base(0.);\n   BaseVector hes_k(nm_sq);\n\n   // add in Hessian of S_k to hes\n   for(k = 0; k < ell; k++)\n   {  // start recording\n      Independent(a_xy);\n      // split out x\n      for(j = 0; j < n; j++)\n         a_x[j] = a_xy[j];\n      // split out y\n      for(j = 0; j < m; j++)\n         a_y[j] = a_xy[n+j];\n      // record\n      s_k[0] = fun.s(k, a_x, a_y);\n      // stop recording and store in S_k\n      S_k.Dependent(a_xy, s_k);\n      // when computing the Hessian it pays to optimize the tape\n      S_k.optimize();\n      // compute Hessian of S_k\n      hes_k = S_k.Hessian(xy, 0);\n      // add \\partial_x S_k (x, y) to jac\n      for(j = 0; j < nm_sq; j++)\n         F_hes[j] += hes_k[j];\n   }\n   // Extract F_yx\n   BaseVector F_yx(m * n);\n   for(i = 0; i < m; i++)\n   {  for(j = 0; j < n; j++)\n         F_yx[i * n + j] = F_hes[ (i+n)*(n+m) + j ];\n   }\n   // Extract F_yy\n   BaseVector F_yy(n * m);\n   for(i = 0; i < m; i++)\n   {  for(j = 0; j < m; j++)\n         F_yy[i * m + j] = F_hes[ (i+n)*(n+m) + j + n ];\n   }\n\n   // compute - Y^{(1)}(x) = F_yy (x, y)^{-1} F_yx (x, y)\n   BaseVector neg_Y_x(m * n);\n   Base logdet;\n   int signdet = CppAD::LuSolve(m, n, F_yy, F_yx, neg_Y_x, logdet);\n   if( signdet == 0 )\n      return signdet;\n\n   // compute hes = F_xx (x, y) + F_xy (x, y)  Y^{(1)}(x)\n   for(i = 0; i < n; i++)\n   {  for(j = 0; j < n; j++)\n      {  hes[i * n + j] = F_hes[ i*(n+m) + j ];\n         for(k = 0; k < m; k++)\n            hes[i*n+j] -= F_hes[i*(n+m) + k+n] * neg_Y_x[k*n+j];\n      }\n   }\n   return signdet;\n}\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/optimize.hpp",
    "content": "# ifndef CPPAD_CORE_OPTIMIZE_HPP\n# define CPPAD_CORE_OPTIMIZE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# define CPPAD_CORE_OPTIMIZE_PRINT_RESULT 0\n\n/*\n{xrst_begin optimize}\n{xrst_spell\n   onetape\n   substring\n}\n\nOptimize an ADFun Object Tape\n#############################\n\nSyntax\n******\n| *f* . ``optimize`` ()\n| *f* . ``optimize`` ( *options* )\n| *flag* = *f* . ``exceed_collision_limit`` ()\n\nPurpose\n*******\nThe operation sequence corresponding to an :ref:`ADFun-name` object can\nbe very large and involve many operations; see the\nsize functions in :ref:`fun_property-name` .\nThe *f* . ``optimize`` procedure reduces the number of operations,\nand thereby the time and the memory, required to\ncompute function and derivative values.\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\noptions\n*******\nThis argument has prototype\n\n   ``const std::string&`` *options*\n\nThe default for *options* is the empty string.\nIf it is present, it must consist of one or more of the options below\nseparated by a single space character.\n\nno_conditional_skip\n===================\nThe ``optimize`` function can create conditional skip operators\nto improve the speed of conditional expressions; see\n:ref:`CondExp@Optimize` .\nIf the sub-string ``no_conditional_skip`` appears in *options* ,\nconditional skip operations are not be generated.\nThis may make the optimize routine use significantly less memory\nand take less time to optimize *f* .\nIf conditional skip operations are generated,\nit may save a significant amount of time when\nusing *f* for :ref:`forward-name` or :ref:`reverse-name` mode calculations;\nsee :ref:`number_skip-name` .\n\nno_compare_op\n=============\nIf the sub-string ``no_compare_op`` appears in *options* ,\ncomparison operators will be removed from the optimized function.\nThese operators are necessary for the\n:ref:`compare_change-name` functions to be meaningful.\nOn the other hand, they are not necessary, and take extra time,\nwhen the compare_change functions are not used.\n\nno_print_for_op\n===============\nIf the sub-string ``no_compare_op`` appears in *options* ,\n:ref:`PrintFor-name` operations will be removed form the optimized function.\nThese operators are useful for reporting problems evaluating derivatives\nat independent variable values different from those used to record a function.\n\nno_cumulative_sum_op\n====================\nIf this sub-string appears,\nno cumulative sum operations will be generated during the optimization; see\n:ref:`optimize_cumulative_sum.cpp-name` .\n\ncollision_limit=value\n=====================\nIf this substring appears,\nwhere *value* is a sequence of decimal digits,\nthe optimizer's hash code collision limit will be set to *value* .\nWhen the collision limit is reached, the expressions with that hash code\nare removed and a new lists of expressions with that has code is started.\nThe larger *value* , the more identical expressions the optimizer\ncan recognize, but the slower the optimizer may run.\nThe default for *value* is ``10`` .\n\nval_graph\n=========\nIf the sub-string ``val_graph`` appears in *options* ,\nthe value graph optimizer is used.\nThis is a new (experimental) CppAD operation sequence optimizer.\n\n#. The val_graph optimizer has a much simpler implementation.\n#. It has better developer documentation\n#. It has examples and tests at the val_graph level.\n   This makes it easy to change the val_graph optimizer.\n#. The optimized tape has very similar speed to the old optimizer; i.e.,\n   when the :ref:`speed_main@Global Options@onetape` option is present.\n   For some of the :ref:`speed-name` test case\n   the val_graph optimized tape is significantly faster.\n#. The val_graph optimizer take much longer to run.\n   This is probably due to the conversion to and from a val_graph.\n\nno_conditional_skip\n-------------------\nIf the sub-string ``val_graph`` is present, the ``no_conditional_skip``\nsub-string must also appear.\n\ncollision_limit=value\n---------------------\nIf the sub-string ``val_graph`` is present, the ``collision_limit=value``\nsub-string must **not** appear.\nCurrently, there is no collision limit for the new optimizer.\n\nRe-Optimize\n***********\nBefore 2019-06-28, optimizing twice was not supported and would fail\nif cumulative sum operators were present after the first optimization.\nThis is now supported but it is not expected to have much benefit.\nIf you find a case where it does have a benefit, please inform the CppAD\ndevelopers of this.\n\nEfficiency\n**********\nIf a :ref:`zero order forward<forward_zero-name>` calculation is done during\nthe construction of *f* , it will require more memory\nand time than required after the optimization procedure.\nIn addition, it will need to be redone.\nFor this reason, it is more efficient to use\n\n| |tab| ``ADFun`` < *Base* > *f* ;\n| |tab| *f* . ``Dependent`` ( *x* , *y* );\n| |tab| *f* . ``optimize`` ();\n\ninstead of\n\n| |tab| ``ADFun`` < *Base* > *f* ( *x* , *y* )\n| |tab| *f* . ``optimize`` ();\n\nSee the discussion about\n:ref:`sequence constructors<fun_construct@Sequence Constructor>` .\n\nTaylor Coefficients\n*******************\nAny Taylor coefficients in the function object are lost; i.e.,\n:ref:`f.size_order()<size_order-name>` after the optimization is zero.\n(See the discussion about efficiency above.)\n\nSpeed Testing\n*************\nYou can run the CppAD :ref:`speed<speed_main-name>` tests and see\nthe corresponding changes in number of variables and execution time.\nNote that there is an interaction between using\n:ref:`speed_main@Global Options@optimize` and\n:ref:`speed_main@Global Options@onetape` .\nIf *onetape* is true and *optimize* is true,\nthe optimized tape will be reused many times.\nIf *onetape* is false and *optimize* is true,\nthe tape will be re-optimized for each test.\n\nAtomic Functions\n****************\nThere are some subtitle issue with optimized :ref:`atomic-name` functions\n:math:`v = g(u)`:\n\nrev_sparse_jac\n==============\nThe :ref:`atomic_two_rev_sparse_jac-name` function is be used to determine\nwhich components of *u* affect the dependent variables of *f* .\nFor each atomic operation, the current\n:ref:`atomic_two_option@atomic_sparsity` setting is used\nto determine if ``pack_sparsity_enum`` , ``bool_sparsity_enum`` ,\nor ``set_sparsity_enum`` is used to determine dependency relations\nbetween argument and result variables.\n\nnan\n===\nIf *u* [ *i* ] does not affect the value of\nthe dependent variables for *f* ,\nthe value of *u* [ *i* ] is set to :ref:`nan-name` .\n\nChecking Optimization\n*********************\nIf :ref:`Faq@Speed@NDEBUG` is not defined,\nand :ref:`f.size_order()<size_order-name>` is greater than zero,\na :ref:`forward_zero-name` calculation is done using the optimized version\nof *f* and the results are checked to see that they are\nthe same as before.\nIf they are not the same, the\n:ref:`ErrorHandler-name` is called with a known error message\nrelated to *f* . ``optimize`` () .\n\nexceed_collision_limit\n**********************\nIf the return value *flag* is true (false),\nthe previous call to *f* . ``optimize`` exceed the\n:ref:`collision_limit<optimize@options@collision_limit=value>` .\n\nExamples\n********\n{xrst_comment childtable without Example instead of Contents for header}\n{xrst_toc_hidden\n   example/optimize/optimize_twice.cpp\n   example/optimize/forward_active.cpp\n   example/optimize/reverse_active.cpp\n   example/optimize/compare_op.cpp\n   example/optimize/print_for.cpp\n   example/optimize/conditional_skip.cpp\n   example/optimize/nest_conditional.cpp\n   example/optimize/cumulative_sum.cpp\n}\n\n.. csv-table::\n   :widths: auto\n\n   optimize_twice.cpp,:ref:`optimize_twice.cpp-title`\n   optimize_forward_active.cpp,:ref:`optimize_forward_active.cpp-title`\n   optimize_reverse_active.cpp,:ref:`optimize_reverse_active.cpp-title`\n   optimize_compare_op.cpp,:ref:`optimize_compare_op.cpp-title`\n   optimize_print_for.cpp,:ref:`optimize_print_for.cpp-title`\n   optimize_conditional_skip.cpp,:ref:`optimize_conditional_skip.cpp-title`\n   optimize_nest_conditional.cpp,:ref:`optimize_nest_conditional.cpp-title`\n   optimize_cumulative_sum.cpp,:ref:`optimize_cumulative_sum.cpp-title`\n\n{xrst_end optimize}\n-----------------------------------------------------------------------------\n*/\n# include <cppad/local/optimize/optimize_run.hpp>\n/*!\n\\file optimize.hpp\nOptimize a player object operation sequence\n*/\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\nOptimize a player object operation sequence\n\nThe operation sequence for this object is replaced by one with fewer operations\nbut the same function and derivative values.\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD<Base> and computations by this routine are done using type\n Base.\n\n\\param options\n\\li\nIf the sub-string \"no_conditional_skip\" appears,\nconditional skip operations will not be generated.\nThis may make the optimize routine use significantly less memory\nand take significantly less time.\n\\li\nIf the sub-string \"no_compare_op\" appears,\nthen comparison operators will be removed from the optimized tape.\nThese operators are necessary for the compare_change function to be\nbe meaningful in the resulting recording.\nOn the other hand, they are not necessary and take extra time\nwhen compare_change is not used.\n*/\ntemplate <class Base, class RecBase>\nvoid ADFun<Base,RecBase>::optimize(const std::string& options)\n{\n# if CPPAD_CORE_OPTIMIZE_PRINT_RESULT\n   // size of operation sequence before optimizatiton\n   size_t size_op_before = size_op();\n# endif\n\n   // number of independent variables\n   size_t n_ind_var = ind_taddr_.size();\n\n# ifndef NDEBUG\n   // n_ind_dyn, ind_dynamic\n   size_t n_ind_dyn = play_.n_dyn_independent();\n   CppAD::vector<Base> ind_dynamic(n_ind_dyn);\n   //\n   // n_dep_var, x, y, check, max_taylor, check_zero_order\n   size_t n_dep_var = dep_taddr_.size();\n   CppAD::vector<Base> x(n_ind_var), y(n_dep_var), check(n_dep_var);\n   Base max_taylor(0);\n   bool check_zero_order = num_order_taylor_ > 0;\n   if( check_zero_order )\n   {  //\n      // ind_dynamic\n      for(size_t j = 0; j < n_ind_dyn; ++j)\n      {  const addr_t par_ind = play_.dyn2par_index()[j];\n         ind_dynamic[j]       = play_.par_all()[par_ind];\n      }\n      //\n      // x\n      // zero order coefficients for independent vars\n      for(size_t j = 0; j < n_ind_var; j++)\n      {  CPPAD_ASSERT_UNKNOWN( play_.GetOp(j+1) == local::InvOp );\n         CPPAD_ASSERT_UNKNOWN( ind_taddr_[j]    == j+1   );\n         x[j] = taylor_[ ind_taddr_[j] * cap_order_taylor_ + 0];\n      }\n      // y\n      // zero order coefficients for dependent vars\n      for(size_t i = 0; i < n_dep_var; i++)\n      {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_  );\n         y[i] = taylor_[ dep_taddr_[i] * cap_order_taylor_ + 0];\n      }\n      // max_taylor\n      // maximum zero order coefficient not counting BeginOp at beginning\n      // (which is corresponds to uninitialized memory).\n      for(size_t i = 1; i < num_var_tape_; i++)\n      {  if(  abs_geq(taylor_[i*cap_order_taylor_+0] , max_taylor) )\n            max_taylor = taylor_[i*cap_order_taylor_+0];\n      }\n   }\n# endif\n\n   //\n   // val_graph\n   bool val_graph = options.find(\"val_graph\") != std::string::npos;\n   //\n   if( val_graph )\n   {  val_optimize(options);\n      exceed_collision_limit_ = false;\n   }\n   else\n   {\n      // place to store the optimized version of the recording\n      local::recorder<Base> rec;\n\n      // create the optimized recording\n      size_t exceed = false;\n      switch( play_.address_type() )\n      {\n         case local::play::unsigned_short_enum:\n         exceed = local::optimize::optimize_run<unsigned short>(\n            options, n_ind_var, dep_taddr_, &play_, &rec\n         );\n         break;\n\n         case local::play::addr_t_enum:\n         exceed = local::optimize::optimize_run<addr_t>(\n            options, n_ind_var, dep_taddr_, &play_, &rec\n         );\n         break;\n\n         case local::play::size_t_enum:\n         exceed = local::optimize::optimize_run<size_t>(\n            options, n_ind_var, dep_taddr_, &play_, &rec\n         );\n         break;\n\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n      }\n      exceed_collision_limit_ = exceed;\n\n      // now replace the recording\n      play_.get_recording(rec, n_ind_var);\n   }\n\n   // number of variables in the recording\n   num_var_tape_  = play_.num_var();\n\n   // set flag so this function knows it has been optimized\n   has_been_optimized_ = true;\n\n   // free memory allocated for sparse Jacobian calculation\n   // (the results are no longer valid)\n   for_jac_sparse_pack_.resize(0, 0);\n   for_jac_sparse_set_.resize(0,0);\n\n   // free old Taylor coefficient memory\n   taylor_.clear();\n   num_order_taylor_     = 0;\n   cap_order_taylor_     = 0;\n\n   // resize and initialize conditional skip vector\n   // (must use player size because it now has the recoreder information)\n   cskip_op_.resize( play_.num_var_op() );\n\n   // resize subgraph_info_\n   subgraph_info_.resize(\n      ind_taddr_.size(),    // n_ind\n      dep_taddr_.size(),    // n_dep\n      play_.num_var_op(),   // n_op\n      play_.num_var()       // n_var\n   );\n\n# ifndef NDEBUG\n   if( check_zero_order )\n   {  std::stringstream s;\n      //\n      // zero order forward calculation using new operation sequence\n      new_dynamic(ind_dynamic);\n      check = Forward(0, x, s);\n\n      // check results\n      Base eps99 = Base(99) * CppAD::numeric_limits<Base>::epsilon();\n      for(size_t i = 0; i < n_dep_var; i++)\n      if( ! abs_geq( eps99 * max_taylor , check[i] - y[i] ) )\n      {  std::string msg = \"Error during check of f.optimize().\";\n         msg += \"\\neps99 * max_taylor = \" + to_string(eps99 * max_taylor);\n         msg += \"\\ncheck[i] = \" + to_string(check[i]);\n         msg += \"\\ny[i]     = \" + to_string(y[i]);\n         CPPAD_ASSERT_KNOWN(\n            abs_geq( eps99 * max_taylor , check[i] - y[i] ) ,\n            msg.c_str()\n         );\n      }\n\n      // Erase memory that this calculation was done so NDEBUG gives\n      // same final state for this object (from users perspective)\n      num_order_taylor_     = 0;\n   }\n# endif\n# if CPPAD_CORE_OPTIMIZE_PRINT_RESULT\n   // size of operation sequence after optimizatiton\n   size_t size_op_after = size_op();\n   std::cout << \"optimize: size_op:  before = \" <<\n   size_op_before << \", after = \" << size_op_after << \"\\n\";\n# endif\n}\n\n} // END_CPPAD_NAMESPACE\n\n# undef CPPAD_CORE_OPTIMIZE_PRINT_RESULT\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/ordered.hpp",
    "content": "# ifndef CPPAD_CORE_ORDERED_HPP\n# define CPPAD_CORE_ORDERED_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/define.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*!\n\\file ordered.hpp\nCheck and AD values ordering properties relative to zero.\n*/\n\n// GreaterThanZero ============================================================\n/*!\nCheck if an AD<Base> is greater than zero.\n\n\\param x\nvalue we are checking.\n\n\\return\nreturns true iff the x is greater than zero.\n*/\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool GreaterThanZero(const AD<Base> &x)\n{  return GreaterThanZero(x.value_); }\n// GreaterThanOrZero =========================================================\n/*!\nCheck if an AD<Base> is greater than or equal zero.\n\n\\param x\nvalue we are checking.\n\n\\return\nreturns true iff the x is greater than or equal zero.\n*/\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool GreaterThanOrZero(const AD<Base> &x)\n{  return GreaterThanOrZero(x.value_); }\n// LessThanZero ============================================================\n/*!\nCheck if an AD<Base> is less than zero.\n\n\\param x\nvalue we are checking.\n\n\\return\nreturns true iff the x is less than zero.\n*/\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool LessThanZero(const AD<Base> &x)\n{  return LessThanZero(x.value_); }\n// LessThanOrZero =========================================================\n/*!\nCheck if an AD<Base> is less than or equal zero.\n\n\\param x\nvalue we are checking.\n\n\\return\nreturns true iff the x is less than or equal zero.\n*/\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool LessThanOrZero(const AD<Base> &x)\n{  return LessThanOrZero(x.value_); }\n// abs_geq =========================================================\n/*!\nCheck if absolute value of one AD<Base> is greater or equal another.\n\n\\param x\nvalue we are checking if it is greater than or equal other.\n\n\\param y\nvalue we are checking if it is less than other.\n\n\\return\nreturns true iff the absolute value of x is greater than or equal\nabsolute value of y.\n*/\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nbool abs_geq(const AD<Base>& x, const AD<Base>& y)\n{  return abs_geq(x.value_, y.value_); }\n// ============================================================================\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/parallel_ad.hpp",
    "content": "# ifndef CPPAD_CORE_PARALLEL_AD_HPP\n# define CPPAD_CORE_PARALLEL_AD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin parallel_ad}\n{xrst_spell\n   rosen\n   runge\n   teardown\n}\n\nEnable AD Calculations During Parallel Mode\n###########################################\n\nSyntax\n******\n| ``parallel_ad`` < *Base* >()\n\nPurpose\n*******\nThe function\n``parallel_ad`` < *Base* >()\nmust be called before any ``AD`` < *Base>* objects are used\nin :ref:`parallel<ta_in_parallel-name>` mode.\nIn addition, if this routine is called after one is done using\nparallel mode, it will free extra memory used to keep track of\nthe multiple ``AD`` < *Base* > tapes required for parallel execution.\n\nDiscussion\n**********\nBy default, for each ``AD`` < *Base* > class there is only one\ntape that records :ref:`glossary@AD of Base` operations.\nThis tape is a global variable and hence it cannot be used\nby multiple threads at the same time.\nThe :ref:`parallel_setup<ta_parallel_setup-name>` function informs CppAD of the\nmaximum number of threads that can be active in parallel mode.\nThis routine does extra setup\n(and teardown) for the particular *Base* type.\n\nCheckSimpleVector\n*****************\nThis routine has the side effect of calling ``CheckSimpleVector`` for\nsome of the possible\n:ref:`CheckSimpleVector@Scalar` and :ref:`CheckSimpleVector@Vector` cases.\nThe set of these cases may increase in the future and currently includes\nthe following:\n\n.. csv-table::\n   :header: Scalar, Vector\n\n   ``bool``          , ``CppAD::vectorBool``\n   ``size_t``        , ``CppAD::vector<size_t>``\n   *Base*            , *vector* < *Base* >\n   ``AD`` < *Base* > , *vector* ``AD`` < *Base* >\n\nWhere *vector* above is\n``CppAD::vector`` ,\n``std::vector`` , and\nthe :ref:`cppad_testvector-name` .\n\n\nExample\n*******\nThe files\n:ref:`openmp_get_started.cpp-name` ,\n:ref:`bthread_get_started.cpp-name` , and\n:ref:`pthread_get_started.cpp-name` ,\ncontain examples and tests that implement this function.\n\nRestriction\n***********\nThis routine cannot be called in parallel mode or while\nthere is a tape recording ``AD`` < *Base* > operations.\n\nOther Initialization\n********************\nIf the following routines have static memory and must be called once\nbefore being used in parallel mode:\n\n#. :ref:`CheckSimpleVector <CheckSimpleVector@Parallel Mode>`\n#. :ref:`thread_alloc, memory_leak <ta_parallel_setup-name>`\n#. :ref:`Rosen34 <Rosen34@Parallel Mode>`\n#. :ref:`Runge45 <Runge45@Parallel Mode>`\n#. :ref:`discrete <Discrete@Parallel Mode>`\n#. :ref:`atomic_one <atomic_one@afun@Parallel Mode>`\n\n\n{xrst_end parallel_ad}\n-----------------------------------------------------------------------------\n*/\n\n# include <vector>\n# include <cppad/utility/vector.hpp>\n# include <cppad/local/std_set.hpp>\n# include <cppad/local/val_graph/enable_parallel.hpp>\n\n// BEGIN CppAD namespace\nnamespace CppAD {\n\n/*!\nEnable parallel execution mode with <code>AD<Base></code> by initializing\nstatic variables that my be used.\n*/\n\ntemplate <class Base>\nvoid parallel_ad(void)\n{  CPPAD_ASSERT_KNOWN(\n      ! thread_alloc::in_parallel() ,\n      \"parallel_ad must be called before entering parallel execution mode.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      AD<Base>::tape_ptr() == nullptr ,\n      \"parallel_ad cannot be called while a tape recording is in progress\"\n   );\n\n   // ensure statics in following functions are initialized\n   ErrorHandler::Current();                // error_handler.hpp\n   elapsed_seconds();                      // elapsed_seconds.hpp\n   local::num_arg_dyn(local::abs_dyn);     // op_code_dyn.hpp\n   local::op_name_dyn(local::abs_dyn);     // op_code_dyn.hpp\n   local::NumArg(local::BeginOp);          // op_code_var.hpp\n   local::NumRes(local::BeginOp);          // op_code_var.hpp\n   local::one_element_std_set<size_t>();   // std_set.hpp\n   local::two_element_std_set<size_t>();   // std_set.hpp\n\n   // the sparse_pack class has member functions with static data\n   local::sparse::pack_setvec sp;\n   sp.resize(1, 1);       // so can call add_element\n   sp.add_element(0, 0);  // has static data\n   sp.clear(0);           // has static data\n   sp.is_element(0, 0);   // has static data\n   local::sparse::pack_setvec::const_iterator itr(sp, 0); // has static data\n   ++itr;                                  // has static data\n\n   // statics that depend on the value of Base\n   AD<Base>::tape_id_ptr(0);                  // tape_link.hpp\n   AD<Base>::tape_handle(0);                  // tape_link.hpp\n   local::val_graph::enable_parallel<Base>(); // val_graph/*_op.hpp\n   discrete<Base>::List();                    // discrete.hpp\n\n   // Some check_simple_vector.hpp cases\n   //\n   CheckSimpleVector< bool, CppAD::vectorBool >();\n   CheckSimpleVector< size_t, CppAD::vector<size_t> >();\n   CheckSimpleVector< Base, CppAD::vector<Base> >();\n   CheckSimpleVector< AD<Base>, CppAD::vector< AD<Base> > >();\n   //\n   CheckSimpleVector< Base, std::vector<Base> >();\n   CheckSimpleVector< AD<Base>, std::vector< AD<Base> > >();\n   //\n# if CPPAD_BOOSTVECTOR\n   CheckSimpleVector< Base, boost::numeric::ublas::vector<Base> >();\n   CheckSimpleVector< AD<Base>, boost::numeric::ublas::vector< AD<Base> > >();\n# endif\n   //\n# if CPPAD_EIGENVECTOR\n   CheckSimpleVector< Base, CppAD::eigen_vector<Base> >();\n   CheckSimpleVector< AD<Base>, CppAD::eigen_vector< AD<Base> > > ();\n# endif\n\n}\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/pow.hpp",
    "content": "# ifndef CPPAD_CORE_POW_HPP\n# define CPPAD_CORE_POW_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin pow}\n\nThe AD Power Function\n#####################\n\nSyntax\n******\n| *z* = ``pow`` ( *x* , *y* )\n\nSee Also\n********\n:ref:`pow_int-name`\n\nPurpose\n*******\nDetermines the value of the power function which is defined by\n\n.. math::\n\n   {\\rm pow} (x, y) = x^y\n\nIf y is a Variable\n==================\nIf *y* is a variable,\nthe ``pow`` function may use\nlogarithms and exponentiation to compute derivatives.\nThis will not work if *x* is less than or equal zero.\n\nIf y is a Parameter\n===================\nIf *y* is a parameter, a different method is used to\ncompute the derivatives; see :ref:`pow_forward-name` .\nIn the special case where *x* is zero,\nzero is returned as the derivative.\nThis is correct when *y* minus the order of the derivative\nis greater than zero.\nIf *y* minus the order of the derivative is zero,\nthen *y* is an integer.\nIf *y* minus the order of the derivative is less than zero,\nthe actual derivative is infinite.\n\nIf y is an Integer\n==================\nIf the value of *y* is an integer,\nthe :ref:`pow_int-name` function can be used to compute this value\nusing only multiplication (and division if *y* is negative).\nThis will work even if *x* is less than or equal zero.\n\nx\n*\nThe argument *x* has one of the following prototypes\n\n| |tab| ``const`` *Base* & *x*\n| |tab| ``const AD`` < *Base* >& *x*\n| |tab| ``const VecAD`` < *Base* >:: ``reference&`` *x*\n\ny\n*\nThe argument *y* has one of the following prototypes\n\n| |tab| ``const`` *Base* & *y*\n| |tab| ``const AD`` < *Base* >& *y*\n| |tab| ``const VecAD`` < *Base* >:: ``reference&`` *y*\n\nz\n*\nIf both *x* and *y* are *Base* objects,\nthe result *z* is also a *Base* object.\nOtherwise, it has prototype\n\n   ``AD`` < *Base* > *z*\n\nOperation Sequence\n******************\nThis is an AD of *Base*\n:ref:`atomic operation<glossary@Operation@Atomic>`\nand hence is part of the current\nAD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/pow.cpp\n   example/general/pow_nan.cpp\n}\nThe files\n:ref:`pow.cpp-name` and :ref:`pow_nan.cpp-name`\nare examples tests of this function.\n\n{xrst_end pow}\n-------------------------------------------------------------------------------\n*/\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\n// case where x and y are AD<Base> -----------------------------------------\ntemplate <class Base> AD<Base>\npow(const AD<Base>& x, const AD<Base>& y)\n{\n   // compute the Base part\n   AD<Base> result;\n   result.value_  = pow(x.value_, y.value_);\n   CPPAD_ASSERT_UNKNOWN( Parameter(result) );\n\n   // check if there is a recording in progress\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if x and y tapes match\n   bool match_x  = x.tape_id_  == tape_id;\n   bool match_y  = y.tape_id_  == tape_id;\n\n   // check if x and y are dynamic parameters\n   bool dyn_x  = match_x  & (x.ad_type_ == dynamic_enum);\n   bool dyn_y  = match_y  & (y.ad_type_ == dynamic_enum);\n\n   // check if x and y are variables\n   bool var_x  = match_x  & (x.ad_type_ != dynamic_enum);\n   bool var_y  = match_y  & (y.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      x.tape_id_ == y.tape_id_ || ! match_x || ! match_y ,\n      \"pow: AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_x )\n   {  if( var_y )\n      {  // result = variable^variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::PowvvOp) == 3 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::PowvvOp) == 2 );\n\n         // put operand addresses in tape\n         tape->Rec_.PutArg(x.taddr_, y.taddr_);\n\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::PowvvOp);\n\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n      else if( (! dyn_y) && IdenticalZero( y.value_ ) )\n      {  // result = variable^0\n      }\n      else\n      {  // result = variable^parameter\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::PowvpOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::PowvpOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = y.taddr_;\n         if( ! dyn_y )\n            p = tape->Rec_.put_con_par(y.value_);\n         tape->Rec_.PutArg(x.taddr_, p);\n\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::PowvpOp);\n\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n   }\n   else if( var_y )\n   {  if( (! dyn_x) && IdenticalZero(x.value_) )\n      {  // result = 0^variable\n      }\n      else\n      {  // result = parameter^variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::PowpvOp) == 3 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::PowpvOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = x.taddr_;\n         if( ! dyn_x )\n            p = tape->Rec_.put_con_par(x.value_);\n         tape->Rec_.PutArg(p, y.taddr_);\n\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::PowpvOp);\n\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n   }\n   else if( dyn_x | dyn_y )\n   {  if( (!dyn_x) && IdenticalZero(x.value_) )\n      { // result = 0^dynamic\n      } else if( (! dyn_y) && IdenticalZero( y.value_ ) )\n      {  // result = dynamic^0\n      } else {\n         addr_t arg0 = x.taddr_;\n         addr_t arg1 = y.taddr_;\n         if( ! dyn_x )\n            arg0 = tape->Rec_.put_con_par(x.value_);\n         if( ! dyn_y )\n            arg1 = tape->Rec_.put_con_par(y.value_);\n         //\n         // parameters with a dynamic parameter result\n         result.taddr_   = tape->Rec_.put_dyn_par(\n            result.value_, local::pow_dyn,   arg0, arg1\n         );\n         result.tape_id_ = tape_id;\n         result.ad_type_ = dynamic_enum;\n      }\n   }\n   else\n   {  CPPAD_ASSERT_KNOWN( ! (dyn_x | dyn_y) ,\n      \"pow: one operand is a dynamic parameter and other not a variable\"\n      );\n   }\n   return result;\n}\n// =========================================================================\n// Fold operations in same way as CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(Op)\n// -------------------------------------------------------------------------\n// Operations with VecAD_reference<Base> and AD<Base> only\n\ntemplate <class Base> AD<Base>\npow(const AD<Base>& x, const VecAD_reference<Base>& y)\n{  return pow(x, y.ADBase()); }\n\ntemplate <class Base> AD<Base>\npow(const VecAD_reference<Base>& x, const VecAD_reference<Base>& y)\n{  return pow(x.ADBase(), y.ADBase()); }\n\ntemplate <class Base> AD<Base>\npow(const VecAD_reference<Base>& x, const AD<Base>& y)\n{  return pow(x.ADBase(), y); }\n// -------------------------------------------------------------------------\n// Operations with Base\n\ntemplate <class Base> AD<Base>\npow(const Base& x, const AD<Base>& y)\n{  return pow(AD<Base>(x), y); }\n\ntemplate <class Base> AD<Base>\npow(const Base& x, const VecAD_reference<Base>& y)\n{  return pow(AD<Base>(x), y.ADBase()); }\n\ntemplate <class Base> AD<Base>\npow(const AD<Base>& x, const Base& y)\n{  return pow(x, AD<Base>(y)); }\n\ntemplate <class Base> AD<Base>\npow(const VecAD_reference<Base>& x, const Base& y)\n{  return pow(x.ADBase(), AD<Base>(y)); }\n// -------------------------------------------------------------------------\n// Operations with double\n\ntemplate <class Base> AD<Base>\npow(const double& x, const AD<Base>& y)\n{  return pow(AD<Base>(x), y); }\n\ntemplate <class Base> AD<Base>\npow(const double& x, const VecAD_reference<Base>& y)\n{  return pow(AD<Base>(x), y.ADBase()); }\n\ntemplate <class Base> AD<Base>\npow(const AD<Base>& x, const double& y)\n{  return pow(x, AD<Base>(y)); }\n\ntemplate <class Base> AD<Base>\npow(const VecAD_reference<Base>& x, const double& y)\n{  return pow(x.ADBase(), AD<Base>(y)); }\n// -------------------------------------------------------------------------\n// Special case to avoid ambiguity when Base is double\n\ninline AD<double>\npow(const double& x, const AD<double>& y)\n{  return pow(AD<double>(x), y); }\n\ninline AD<double>\npow(const double& x, const VecAD_reference<double>& y)\n{  return pow(AD<double>(x), y.ADBase()); }\n\ninline AD<double>\npow(const AD<double>& x, const double& y)\n{  return pow(x, AD<double>(y)); }\n\ninline AD<double>\npow(const VecAD_reference<double>& x, const double& y)\n{  return pow(x.ADBase(), AD<double>(y)); }\n\n// =========================================================================\n// Fold operations for the cases where x is an int,\n// but let cppad/utility/pow_int.hpp handle the cases where y is an int.\n// -------------------------------------------------------------------------\ntemplate <class Base> AD<Base> pow\n(const int& x, const VecAD_reference<Base>& y)\n{  return pow(AD<Base>(x), y.ADBase()); }\n\ntemplate <class Base> AD<Base> pow\n(const int& x, const AD<Base>& y)\n{  return pow(AD<Base>(x), y); }\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/print_for.hpp",
    "content": "# ifndef CPPAD_CORE_PRINT_FOR_HPP\n# define CPPAD_CORE_PRINT_FOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin PrintFor}\n{xrst_spell\n   notpos\n}\n\nPrinting AD Values During Forward Mode\n######################################\n\nSyntax\n******\n| *f* . ``Forward`` (0, *x* )\n| *f* . ``Forward`` (0, *x* , *s* )\n| ``PrintFor`` ( *before* , *value* )\n| ``PrintFor`` ( *notpos* , *before* , *value* , *after* )\n\nSee Also\n********\n:ref:`ad_output-name`\n\nPurpose\n*******\nThe :ref:`zero order forward<forward_zero-name>` mode command\n\n   *f* . ``Forward`` (0, *x* )\n\nsets the\n:ref:`glossary@Tape@Independent Variable` vector\nequal to *x* .\nIt then computes a value for all of the dependent variables in the\n:ref:`operation sequence<glossary@Operation@Sequence>` corresponding\nto *f* .\nPutting a ``PrintFor`` in the operation sequence,\nprints *value* , corresponding to *x* ,\nto be printed during zero order forward operations.\n\nf.Forward(0, x)\n***************\nThe objects *f* , *x* , and the purpose\nfor this operation, are documented in :ref:`Forward-name` .\n\nnotpos\n******\nIf present, the argument *notpos* has one of the following prototypes\n\n| |tab| ``const AD`` < *Base* >& *notpos*\n| |tab| ``const VecAD`` < *Base* >:: ``reference&`` *notpos*\n\nIn this case\nthe text and *value* will be printed if and only if\n*notpos* is not positive (greater than zero) and a finite number.\n\nbefore\n******\nThe argument *before* has prototype\n\n   ``const char`` * *before*\n\nThis text is written to ``std::cout`` before *value* .\n\nvalue\n*****\nThe argument *value* has one of the following prototypes\n\n| |tab| ``const AD`` < *Base* >& *value*\n| |tab| ``const VecAD`` < *Base* >:: ``reference&`` *value*\n\nThe *value* , that corresponds to *x* ,\nis written to ``std::cout`` during the execution of\n\n   *f* . ``Forward`` (0, *x* )\n\nNote that *value* may be a\n:ref:`glossary@Variable` or\n:ref:`glossary@Parameter` .\nIf a parameter is\n:ref:`glossary@Parameter@Dynamic` its value\nwill depend on the previous call to :ref:`new_dynamic-name` .\n\nafter\n*****\nThe argument *after* has prototype\n\n   ``const char`` * *after*\n\nThis text is written to ``std::cout`` after *value* .\n\ns\n*\nYou can redirect this output to any standard output stream using the syntax\n\n   *f* . ``Forward`` (0, *x* , *s* )\n\nsee :ref:`forward_zero@s` in the zero order forward mode documentation.\n\nDiscussion\n**********\nThis is helpful for understanding why tape evaluations have trouble.\nFor example, if one of the operations in *f* is\n``log`` ( *value* ) and *value*  < 0 ,\nthe corresponding result will :ref:`nan-name` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/print_for/print_for.cpp\n   example/general/print_for.cpp\n}\nThe program\n:ref:`print_for_cout.cpp-name`\nis an example and test that prints to standard output.\nThe output of this program\nstates the conditions for passing and failing the test.\nThe function\n:ref:`print_for_string.cpp-name`\nis an example and test that prints to an standard string stream.\nThis function automatically check for correct output.\n\n{xrst_end PrintFor}\n------------------------------------------------------------------------------\n*/\n\n# include <cstring>\n\nnamespace CppAD {\n   template <class Base>\n   void PrintFor(\n      const AD<Base>& notpos        ,\n      const char*     before        ,\n      const AD<Base>& value         ,\n      const char*     after         )\n   {  CPPAD_ASSERT_NARG_NRES(local::PriOp, 5, 0);\n\n      // check for case where we are not recording operations\n      local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n      if( tape == nullptr )\n         return;\n\n      CPPAD_ASSERT_KNOWN(\n         std::strlen(before) <= 1000 ,\n         \"PrintFor: length of before is greater than 1000 characters\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         std::strlen(after) <= 1000 ,\n         \"PrintFor: length of after is greater than 1000 characters\"\n      );\n      addr_t arg0, arg1, arg2, arg3, arg4;\n\n      // arg[0] = base 2 representation of [Var(notpos), Var(value)]\n      arg0 = 0;\n\n      // arg[1] = address for notpos\n      if( Constant(notpos) )\n         arg1  = tape->Rec_.put_con_par(notpos.value_);\n      else if( Dynamic(notpos) )\n         arg1  = notpos.taddr_;\n      else\n      {  arg0 += 1;\n         arg1  = notpos.taddr_;\n      }\n\n      // arg[2] = address of before\n      arg2 = tape->Rec_.PutTxt(before);\n\n      // arg[3] = address for value\n      if( Constant(value) )\n         arg3  = tape->Rec_.put_con_par(value.value_);\n      else if( Dynamic(value) )\n         arg3  = value.taddr_;\n      else\n      {  arg0 += 2;\n         arg3  = value.taddr_;\n      }\n\n      // arg[4] = address of after\n      arg4 = tape->Rec_.PutTxt(after);\n\n      // put the operator in the tape\n      tape->Rec_.PutArg(arg0, arg1, arg2, arg3, arg4);\n      tape->Rec_.PutOp(local::PriOp);\n   }\n   // Fold all other cases into the case above\n   template <class Base>\n   void PrintFor(const char* before, const AD<Base>& value)\n   {  PrintFor(AD<Base>(0), before, value, \"\" ); }\n   //\n   template <class Base>\n   void PrintFor(const char* before, const VecAD_reference<Base>& value)\n   {  PrintFor(AD<Base>(0), before, value.ADBase(), \"\" ); }\n   //\n   template <class Base>\n   void PrintFor(\n      const VecAD_reference<Base>& notpos ,\n      const char                  *before ,\n      const VecAD_reference<Base>& value  ,\n      const char                  *after  )\n   {  PrintFor(notpos.ADBase(), before, value.ADBase(), after); }\n   //\n   template <class Base>\n   void PrintFor(\n      const VecAD_reference<Base>& notpos ,\n      const char                  *before ,\n      const AD<Base>&              value  ,\n      const char                  *after  )\n   {  PrintFor(notpos.ADBase(), before, value, after); }\n   //\n   template <class Base>\n   void PrintFor(\n      const AD<Base>&              notpos ,\n      const char                  *before ,\n      const VecAD_reference<Base>& value  ,\n      const char                  *after  )\n   {  PrintFor(notpos, before, value.ADBase(), after); }\n}\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/rev_hes_sparsity.hpp",
    "content": "# ifndef CPPAD_CORE_REV_HES_SPARSITY_HPP\n# define CPPAD_CORE_REV_HES_SPARSITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin rev_hes_sparsity}\n{xrst_spell\n   rc\n}\n\nReverse Mode Hessian Sparsity Patterns\n######################################\n\nSyntax\n******\n| *f* . ``rev_hes_sparsity`` (\n| |tab| *select_range* , *transpose* , *internal_bool* , *pattern_out*\n| )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to\nthe operation sequence stored in *f* .\nFix :math:`R \\in \\B{R}^{n \\times \\ell}`, :math:`s \\in \\B{R}^m`\nand define the function\n\n.. math::\n\n   H(x) = ( s^\\R{T} F )^{(2)} ( x ) R\n\nGiven a :ref:`glossary@Sparsity Pattern` for :math:`R`\nand for the vector :math:`s`,\n``rev_hes_sparsity`` computes a sparsity pattern for :math:`H(x)`.\n\nx\n*\nNote that the sparsity pattern :math:`H(x)` corresponds to the\noperation sequence stored in *f* and does not depend on\nthe argument *x* .\n\nBoolVector\n**********\nThe type *BoolVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``bool`` .\n\nSizeVector\n**********\nThe type *SizeVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``size_t`` .\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nR\n*\nThe sparsity pattern for the matrix :math:`R` is specified by\n:ref:`for_jac_sparsity@pattern_in` in the previous call\n\n| |tab| *f* . ``for_jac_sparsity`` (\n| |tab| |tab| *pattern_in* , *transpose* , *dependency* , *internal_bool* , *pattern_out*\n| )\n\nselect_range\n************\nThe argument *select_range* has prototype\n\n   ``const`` *BoolVector* & *select_range*\n\nIt has size :math:`m` and specifies which components of the vector\n:math:`s` are non-zero; i.e., *select_range* [ *i* ] is true\nif and only if :math:`s_i` is possibly non-zero.\n\ntranspose\n*********\nThis argument has prototype\n\n   ``bool`` *transpose*\n\nSee :ref:`rev_hes_sparsity@pattern_out` below.\n\ninternal_bool\n*************\nIf this is true, calculations are done with sets represented by a vector\nof boolean values. Otherwise, a vector of sets of integers is used.\nThis must be the same as in the previous call to\n*f* . ``for_jac_sparsity`` .\n\npattern_out\n***********\nThis argument has prototype\n\n   ``sparse_rc`` < *SizeVector* >& *pattern_out*\n\nThis input value of *pattern_out* does not matter.\nIf *transpose* it is false (true),\nupon return *pattern_out* is a sparsity pattern for\n:math:`H(x)` (:math:`H(x)^\\R{T}`).\n\nSparsity for Entire Hessian\n***************************\nSuppose that :math:`R` is the :math:`n \\times n` identity matrix.\nIn this case, *pattern_out* is a sparsity pattern for\n:math:`(s^\\R{T} F)^{(2)} ( x )`.\n\nExample\n*******\n{xrst_toc_hidden\n   example/sparse/rev_hes_sparsity.cpp\n}\nThe file\n:ref:`rev_hes_sparsity.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end rev_hes_sparsity}\n-----------------------------------------------------------------------------\n*/\n# include <cppad/core/ad_fun.hpp>\n# include <cppad/local/sparse/internal.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*!\nReverse Hessian sparsity patterns.\n\n\\tparam Base\nis the base type for this recording.\n\n\\tparam BoolVector\nis the simple vector with elements of type bool that is used for\nsparsity for the vector s.\n\n\\tparam SizeVector\nis the simple vector with elements of type size_t that is used for\nrow, column index sparsity patterns.\n\n\\param select_range\nis a sparsity pattern for for s.\n\n\\param transpose\nIs the returned sparsity pattern transposed.\n\n\\param internal_bool\nIf this is true, calculations are done with sets represented by a vector\nof boolean values. Otherwise, a vector of standard sets is used.\n\n\\param pattern_out\nThe value of transpose is false (true),\nthe return value is a sparsity pattern for H(x) ( H(x)^T ) where\n\\f[\n   H(x) = R * F^{(1)} (x)\n\\f]\nHere F is the function corresponding to the operation sequence\nand x is any argument value.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BoolVector, class SizeVector>\nvoid ADFun<Base,RecBase>::rev_hes_sparsity(\n   const BoolVector&            select_range     ,\n   bool                         transpose        ,\n   bool                         internal_bool    ,\n   sparse_rc<SizeVector>&       pattern_out      )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   size_t m  = Range();\n   //\n   CPPAD_ASSERT_KNOWN(\n      size_t( select_range.size() ) == m,\n      \"rev_hes_sparsity: size of select_range is not equal to \"\n      \"number of dependent variables\"\n   );\n   //\n   // vector that holds reverse Jacobian sparsity flag\n   local::pod_vector<bool> rev_jac_pattern(num_var_tape_);\n   for(size_t i = 0; i < num_var_tape_; i++)\n      rev_jac_pattern[i] = false;\n   //\n   // initialize rev_jac_pattern for dependent variables\n   for(size_t i = 0; i < m; i++)\n      rev_jac_pattern[ dep_taddr_[i] ] = select_range[i];\n   //\n   //\n   if( internal_bool )\n   {  CPPAD_ASSERT_KNOWN(\n         for_jac_sparse_pack_.n_set() > 0,\n         \"rev_hes_sparsity: previous call to for_jac_sparsity did not \"\n         \"use bool for internal sparsity patterns.\"\n      );\n      // column dimension of internal sparstiy pattern\n      size_t ell = for_jac_sparse_pack_.end();\n      //\n      // allocate memory for bool sparsity calculation\n      // (sparsity pattern is empty after a resize)\n      local::sparse::pack_setvec internal_hes;\n      internal_hes.resize(num_var_tape_, ell);\n      //\n      // compute the Hessian sparsity pattern\n      local::sweep::rev_hes(\n         &play_,\n         num_var_tape_,\n         for_jac_sparse_pack_,\n         rev_jac_pattern.data(),\n         internal_hes,\n         not_used_rec_base\n      );\n      // get sparstiy pattern for independent variables\n      local::sparse::get_internal_pattern(\n         transpose, ind_taddr_, internal_hes, pattern_out\n      );\n   }\n   else\n   {  CPPAD_ASSERT_KNOWN(\n         for_jac_sparse_set_.n_set() > 0,\n         \"rev_hes_sparsity: previous call to for_jac_sparsity did not \"\n         \"use bool for internal sparsity patterns.\"\n      );\n      // column dimension of internal sparstiy pattern\n      size_t ell = for_jac_sparse_set_.end();\n      //\n      // allocate memory for bool sparsity calculation\n      // (sparsity pattern is empty after a resize)\n      local::sparse::list_setvec internal_hes;\n      internal_hes.resize(num_var_tape_, ell);\n      //\n      // compute the Hessian sparsity pattern\n      local::sweep::rev_hes(\n         &play_,\n         num_var_tape_,\n         for_jac_sparse_set_,\n         rev_jac_pattern.data(),\n         internal_hes,\n         not_used_rec_base\n      );\n      // get sparstiy pattern for independent variables\n      local::sparse::get_internal_pattern(\n         transpose, ind_taddr_, internal_hes, pattern_out\n      );\n   }\n   return;\n}\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/rev_jac_sparsity.hpp",
    "content": "# ifndef CPPAD_CORE_REV_JAC_SPARSITY_HPP\n# define CPPAD_CORE_REV_JAC_SPARSITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin rev_jac_sparsity}\n\nReverse Mode Jacobian Sparsity Patterns\n#######################################\n\nSyntax\n******\n| *f* . ``rev_jac_sparsity`` (\n| |tab| *pattern_in* , *transpose* , *dependency* , *internal_bool* , *pattern_out*\n| )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to\nthe operation sequence stored in *f* .\nFix :math:`R \\in \\B{R}^{\\ell \\times m}` and define the function\n\n.. math::\n\n   J(x) = R * F^{(1)} ( x )\n\nGiven the :ref:`glossary@Sparsity Pattern` for :math:`R`,\n``rev_jac_sparsity`` computes a sparsity pattern for :math:`J(x)`.\n\nx\n*\nNote that the sparsity pattern :math:`J(x)` corresponds to the\noperation sequence stored in *f* and does not depend on\nthe argument *x* .\n(The operation sequence may contain\n:ref:`CondExp-name` and  :ref:`VecAD-name` operations.)\n\nSizeVector\n**********\nThe type *SizeVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``size_t`` .\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\npattern_in\n**********\nThe argument *pattern_in* has prototype\n\n   ``const sparse_rc`` < *SizeVector* >& *pattern_in*\n\nsee :ref:`sparse_rc-name` .\nIf *transpose* it is false (true),\n*pattern_in* is a sparsity pattern for :math:`R` (:math:`R^\\R{T}`).\n\ntranspose\n*********\nThis argument has prototype\n\n   ``bool`` *transpose*\n\nSee :ref:`rev_jac_sparsity@pattern_in` above and\n:ref:`rev_jac_sparsity@pattern_out` below.\n\ndependency\n**********\nThis argument has prototype\n\n   ``bool`` *dependency*\n\nsee :ref:`rev_jac_sparsity@pattern_out` below.\n\ninternal_bool\n*************\nIf this is true, calculations are done with sets represented by a vector\nof boolean values. Otherwise, a vector of sets of integers is used.\n\npattern_out\n***********\nThis argument has prototype\n\n   ``sparse_rc`` < *SizeVector* >& *pattern_out*\n\nThis input value of *pattern_out* does not matter.\nIf *transpose* it is false (true),\nupon return *pattern_out* is a sparsity pattern for\n:math:`J(x)` (:math:`J(x)^\\R{T}`).\nIf *dependency* is true, *pattern_out* is a\n:ref:`dependency.cpp@Dependency Pattern`\ninstead of sparsity pattern.\n\nSparsity for Entire Jacobian\n****************************\nSuppose that\n:math:`R` is the :math:`m \\times m` identity matrix.\nIn this case, *pattern_out* is a sparsity pattern for\n:math:`F^{(1)} ( x )`  ( :math:`F^{(1)} (x)^\\R{T}` )\nif *transpose* is false (true).\n\nExample\n*******\n{xrst_toc_hidden\n   example/sparse/rev_jac_sparsity.cpp\n}\nThe file\n:ref:`rev_jac_sparsity.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end rev_jac_sparsity}\n-----------------------------------------------------------------------------\n*/\n# include <cppad/core/ad_fun.hpp>\n# include <cppad/local/sparse/internal.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*!\nReverse Jacobian sparsity patterns.\n\n\\tparam Base\nis the base type for this recording.\n\n\\tparam SizeVector\nis the simple vector with elements of type size_t that is used for\nrow, column index sparsity patterns.\n\n\\param pattern_in\nis the sparsity pattern for for R or R^T depending on transpose.\n\n\\param transpose\nIs the input and returned sparsity pattern transposed.\n\n\\param dependency\nAre the derivatives with respect to left and right of the expression below\nconsidered to be non-zero:\n\\code\n   CondExpRel(left, right, if_true, if_false)\n\\endcode\nThis is used by the optimizer to obtain the correct dependency relations.\n\n\\param internal_bool\nIf this is true, calculations are done with sets represented by a vector\nof boolean values. Otherwise, a vector of standard sets is used.\n\n\\param pattern_out\nThe value of transpose is false (true),\nthe return value is a sparsity pattern for J(x) ( J(x)^T ) where\n\\f[\n   J(x) = R * F^{(1)} (x)\n\\f]\nHere F is the function corresponding to the operation sequence\nand x is any argument value.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class SizeVector>\nvoid ADFun<Base,RecBase>::rev_jac_sparsity(\n   const sparse_rc<SizeVector>& pattern_in       ,\n   bool                         transpose        ,\n   bool                         dependency       ,\n   bool                         internal_bool    ,\n   sparse_rc<SizeVector>&       pattern_out      )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   // number or rows, columns, and non-zeros in pattern_in\n   size_t nr_in  = pattern_in.nr();\n   size_t nc_in  = pattern_in.nc();\n   //\n   size_t ell = nr_in;\n   size_t m   = nc_in;\n   if( transpose )\n      std::swap(ell, m);\n   //\n   CPPAD_ASSERT_KNOWN(\n      m == Range() ,\n      \"rev_jac_sparsity: number columns in R \"\n      \"is not equal number of dependent variables.\"\n   );\n   // number of independent variables\n   size_t n = Domain();\n   //\n   bool zero_empty  = true;\n   bool input_empty = true;\n   if( internal_bool )\n   {  // allocate memory for bool sparsity calculation\n      // (sparsity pattern is empty after a resize)\n      local::sparse::pack_setvec internal_jac;\n      internal_jac.resize(num_var_tape_, ell);\n      //\n      // set sparsity pattern for dependent variables\n      local::sparse::set_internal_pattern(\n         zero_empty            ,\n         input_empty           ,\n         ! transpose           ,\n         dep_taddr_            ,\n         internal_jac          ,\n         pattern_in\n      );\n\n      // compute sparsity for other variables\n      local::sweep::rev_jac(\n         &play_,\n         dependency,\n         n,\n         num_var_tape_,\n         internal_jac,\n         not_used_rec_base\n\n      );\n      // get sparstiy pattern for independent variables\n      local::sparse::get_internal_pattern(\n         ! transpose, ind_taddr_, internal_jac, pattern_out\n      );\n   }\n   else\n   {  // allocate memory for bool sparsity calculation\n      // (sparsity pattern is empty after a resize)\n      local::sparse::list_setvec internal_jac;\n      internal_jac.resize(num_var_tape_, ell);\n      //\n      // set sparsity pattern for dependent variables\n      local::sparse::set_internal_pattern(\n         zero_empty            ,\n         input_empty           ,\n         ! transpose           ,\n         dep_taddr_            ,\n         internal_jac          ,\n         pattern_in\n      );\n\n      // compute sparsity for other variables\n      local::sweep::rev_jac(\n         &play_,\n         dependency,\n         n,\n         num_var_tape_,\n         internal_jac,\n         not_used_rec_base\n\n      );\n      // get sparstiy pattern for independent variables\n      local::sparse::get_internal_pattern(\n         ! transpose, ind_taddr_, internal_jac, pattern_out\n      );\n   }\n   return;\n}\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/rev_one.hpp",
    "content": "# ifndef CPPAD_CORE_REV_ONE_HPP\n# define CPPAD_CORE_REV_ONE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin RevOne}\n{xrst_spell\n   dw\n}\n\nFirst Order Derivative: Driver Routine\n######################################\n\nSyntax\n******\n| *dw* = *f* . ``RevOne`` ( *x* , *i* )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to *f* .\nThe syntax above sets *dw* to the\nderivative of :math:`F_i` with respect to :math:`x`; i.e.,\n\n.. math::\n\n   dw =\n   F_i^{(1)} (x)\n   = \\left[\n      \\D{ F_i }{ x_0 } (x) , \\cdots , \\D{ F_i }{ x_{n-1} } (x)\n   \\right]\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nNote that the :ref:`ADFun-name` object *f* is not ``const``\n(see :ref:`RevOne@RevOne Uses Forward` below).\n\nx\n*\nThe argument *x* has prototype\n\n   ``const`` *Vector* & *x*\n\n(see :ref:`RevOne@Vector` below)\nand its size\nmust be equal to *n* , the dimension of the\n:ref:`fun_property@Domain` space for *f* .\nIt specifies\nthat point at which to evaluate the derivative.\n\ni\n*\nThe index *i* has prototype\n\n   ``size_t`` *i*\n\nand is less than :math:`m`, the dimension of the\n:ref:`fun_property@Range` space for *f* .\nIt specifies the\ncomponent of :math:`F` that we are computing the derivative of.\n\ndw\n**\nThe result *dw* has prototype\n\n   *Vector* *dw*\n\n(see :ref:`RevOne@Vector` below)\nand its size is *n* , the dimension of the\n:ref:`fun_property@Domain` space for *f* .\nThe value of *dw* is the derivative of :math:`F_i`\nevaluated at *x* ; i.e.,\nfor :math:`j = 0 , \\ldots , n - 1`\n\n.. math::\n\n   dw[ j ] = \\D{ F_i }{ x_j } ( x )\n\nVector\n******\nThe type *Vector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n*Base* .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nRevOne Uses Forward\n*******************\nAfter each call to :ref:`Forward-name` ,\nthe object *f* contains the corresponding\n:ref:`Taylor coefficients<glossary@Taylor Coefficient>` .\nAfter a call to ``RevOne`` ,\nthe zero order Taylor coefficients correspond to\n*f* . ``Forward`` (0, *x* )\nand the other coefficients are unspecified.\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/rev_one.cpp\n}\nThe routine\n:ref:`RevOne<rev_one.cpp-name>` is both an example and test.\nIt returns ``true`` , if it succeeds and ``false`` otherwise.\n\n{xrst_end RevOne}\n-----------------------------------------------------------------------------\n*/\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base, class RecBase>\ntemplate <class Vector>\nVector ADFun<Base,RecBase>::RevOne(const Vector  &x, size_t i)\n{  size_t i1;\n\n   size_t n = Domain();\n   size_t m = Range();\n\n   // check Vector is Simple Vector class with Base type elements\n   CheckSimpleVector<Base, Vector>();\n\n   CPPAD_ASSERT_KNOWN(\n      x.size() == n,\n      \"RevOne: Length of x not equal domain dimension for f\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      i < m,\n      \"RevOne: the index i is not less than range dimension for f\"\n   );\n\n   // point at which we are evaluating the derivative\n   Forward(0, x);\n\n   // component which are are taking the derivative of\n   Vector w(m);\n   for(i1 = 0; i1 < m; i1++)\n      w[i1] = 0.;\n   w[i] = Base(1.0);\n\n   // dimension the return value\n   Vector dw(n);\n\n   // compute the return value\n   dw = Reverse(1, w);\n\n   return dw;\n}\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/rev_sparse_hes.hpp",
    "content": "# ifndef CPPAD_CORE_REV_SPARSE_HES_HPP\n# define CPPAD_CORE_REV_SPARSE_HES_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin RevSparseHes}\n\nHessian Sparsity Pattern: Reverse Mode\n######################################\n\nSyntax\n******\n| *h* = *f* . ``RevSparseHes`` ( *q* , *s* )\n| *h* = *f* . ``RevSparseHes`` ( *q* , *s* , *transpose* )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to *f* .\nFor a fixed matrix :math:`R \\in \\B{R}^{n \\times q}`\nand a fixed vector :math:`S \\in \\B{R}^{1 \\times m}`,\nwe define\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   H(x)\n   & = & \\partial_x \\left[ \\partial_u S * F[ x + R * u ] \\right]_{u=0}\n   \\\\\n   & = & R^\\R{T} * (S * F)^{(2)} ( x )\n   \\\\\n   H(x)^\\R{T}\n   & = & (S * F)^{(2)} ( x ) * R\n   \\end{eqnarray}\n\nGiven a\n:ref:`glossary@Sparsity Pattern`\nfor the matrix :math:`R` and the vector :math:`S`,\n``RevSparseHes`` returns a sparsity pattern for the :math:`H(x)`.\n\nf\n*\nThe object *f* has prototype\n\n   ``const ADFun`` < *Base* > *f*\n\nx\n*\nIf the operation sequence in *f* is\n:ref:`glossary@Operation@Independent` of\nthe independent variables in :math:`x \\in \\B{R}^n`,\nthe sparsity pattern is valid for all values of\n(even if it has :ref:`CondExp-name` or :ref:`VecAD-name` operations).\n\nq\n*\nThe argument *q* has prototype\n\n   ``size_t`` *q*\n\nIt specifies the number of columns in :math:`R \\in \\B{R}^{n \\times q}`\nand the number of rows in :math:`H(x) \\in \\B{R}^{q \\times n}`.\nIt must be the same value as in the previous :ref:`ForSparseJac-name` call\n\n   *f* . ``ForSparseJac`` ( *q* , *r* , *r_transpose* )\n\nNote that if *r_transpose* is true, *r* in the call above\ncorresponding to :math:`R^\\R{T} \\in \\B{R}^{q \\times n}`\n\ntranspose\n*********\nThe argument *transpose* has prototype\n\n   ``bool`` *transpose*\n\nThe default value ``false`` is used when *transpose* is not present.\n\nr\n*\nThe matrix :math:`R` is specified by the previous call\n\n   *f* . ``ForSparseJac`` ( *q* , *r* , *transpose* )\n\nsee :ref:`ForSparseJac@r` .\nThe type of the elements of\n:ref:`RevSparseHes@SetVector` must be the\nsame as the type of the elements of *r* .\n\ns\n*\nThe argument *s* has prototype\n\n   ``const`` *SetVector* & *s*\n\n(see :ref:`RevSparseHes@SetVector` below)\nIf it has elements of type ``bool`` ,\nits size is :math:`m`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is one and all the elements of *s* [0]\nare between zero and :math:`m - 1`.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the vector *S* .\n\nh\n*\nThe result *h* has prototype\n\n   *SetVector* & *h*\n\n(see :ref:`RevSparseHes@SetVector` below).\n\ntranspose false\n===============\nIf *h* has elements of type ``bool`` ,\nits size is :math:`q * n`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is :math:`q` and all the set elements are between\nzero and *n* ``-1`` inclusive.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the matrix :math:`H(x)`.\n\ntranspose true\n==============\nIf *h* has elements of type ``bool`` ,\nits size is :math:`n * q`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is :math:`n` and all the set elements are between\nzero and *q* ``-1`` inclusive.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the matrix :math:`H(x)^\\R{T}`.\n\nSetVector\n*********\nThe type *SetVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``bool`` or ``std::set<size_t>`` ;\nsee :ref:`glossary@Sparsity Pattern` for a discussion\nof the difference.\nThe type of the elements of\n:ref:`RevSparseHes@SetVector` must be the\nsame as the type of the elements of *r* .\n\nEntire Sparsity Pattern\n***********************\nSuppose that :math:`q = n` and\n:math:`R \\in \\B{R}^{n \\times n}` is the :math:`n \\times n` identity matrix.\nFurther suppose that the :math:`S` is the *k*-th\n:ref:`glossary@Elementary Vector` ; i.e.\n\n.. math::\n\n   S_j = \\left\\{ \\begin{array}{ll}\n      1  & {\\rm if} \\; j = k\n      \\\\\n      0  & {\\rm otherwise}\n   \\end{array} \\right.\n\nIn this case,\nthe corresponding value *h* is a\nsparsity pattern for the Hessian matrix\n:math:`F_k^{(2)} (x) \\in \\B{R}^{n \\times n}`.\n\nExample\n*******\n{xrst_toc_hidden\n   example/sparse/rev_sparse_hes.cpp\n   example/sparse/sparsity_sub.cpp\n}\nThe file\n:ref:`rev_sparse_hes.cpp-name`\ncontains an example and test of this operation.\nThe file\n:ref:`sparsity_sub.cpp<sparsity_sub.cpp@RevSparseHes>`\ncontains an example and test of using ``RevSparseHes``\nto compute the sparsity pattern for a subset of the Hessian.\n\n{xrst_end RevSparseHes}\n-----------------------------------------------------------------------------\n*/\n# include <algorithm>\n# include <cppad/local/pod_vector.hpp>\n# include <cppad/local/std_set.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file core/rev_sparse_hes.hpp\nReverse mode Hessian sparsity patterns.\n*/\n// ===========================================================================\n// RevSparseHesCase\n/*!\nPrivate helper function for RevSparseHes(q, s) bool sparsity.\n\nAll of the description in the public member function RevSparseHes(q, s)\napplies.\n\n\\param set_type\nis a bool value. This argument is used to dispatch to the proper source\ncode depending on the value of SetVector::value_type.\n\n\\param transpose\nSee RevSparseHes(q, s).\n\n\\param q\nSee RevSparseHes(q, s).\n\n\\param s\nSee RevSparseHes(q, s).\n\n\\param h\nis the return value for the corresponding call to RevSparseJac(q, s).\n*/\ntemplate <class Base, class RecBase>\ntemplate <class SetVector>\nvoid ADFun<Base,RecBase>::RevSparseHesCase(\n   bool              set_type         ,\n   bool              transpose        ,\n   size_t            q                ,\n   const SetVector&  s                ,\n   SetVector&        h                )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   size_t n = Domain();\n   size_t m = Range();\n   //\n   h.resize(q * n );\n\n   CPPAD_ASSERT_KNOWN(\n      for_jac_sparse_pack_.n_set() > 0,\n      \"RevSparseHes: previous stored call to ForSparseJac did not \"\n      \"use bool for the elements of r.\"\n   );\n   CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.n_set() == 0 );\n   CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.n_set() == num_var_tape_  );\n   //\n   // temporary indices\n   size_t i, j;\n\n   // check Vector is Simple SetVector class with bool elements\n   CheckSimpleVector<bool, SetVector>();\n\n   CPPAD_ASSERT_KNOWN(\n      q == for_jac_sparse_pack_.end(),\n      \"RevSparseHes: q is not equal to its value\\n\"\n      \"in the previous call to ForSparseJac with this ADFun object.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(s.size()) == m,\n      \"RevSparseHes: size of s is not equal to\\n\"\n      \"range dimension for ADFun object.\"\n   );\n\n   // Array that will hold reverse Jacobian dependency flag.\n   // Initialize as true for the dependent variables.\n   local::pod_vector<bool> RevJac(num_var_tape_);\n   for(i = 0; i < num_var_tape_; i++)\n      RevJac[i] = false;\n   for(i = 0; i < m; i++)\n   {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );\n      RevJac[ dep_taddr_[i] ] = s[i];\n   }\n\n   // vector of sets that will hold reverse Hessain values\n   local::sparse::pack_setvec rev_hes_pattern;\n   rev_hes_pattern.resize(num_var_tape_, q);\n\n   // compute the Hessian sparsity patterns\n   local::sweep::rev_hes(\n      &play_,\n      num_var_tape_,\n      for_jac_sparse_pack_,\n      RevJac.data(),\n      rev_hes_pattern,\n      not_used_rec_base\n\n   );\n\n   // return values corresponding to independent variables\n   CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == n * q );\n   for(j = 0; j < n; j++)\n   {  for(i = 0; i < q; i++)\n      {  if( transpose )\n            h[ j * q + i ] = false;\n         else\n            h[ i * n + j ] = false;\n      }\n   }\n\n   // j is index corresponding to reverse mode partial\n   for(j = 0; j < n; j++)\n   {  CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ );\n\n      // ind_taddr_[j] is operator taddr for j-th independent variable\n      CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j + 1 );\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );\n\n      // extract the result from rev_hes_pattern\n      CPPAD_ASSERT_UNKNOWN( rev_hes_pattern.end() == q );\n      local::sparse::pack_setvec::const_iterator itr(rev_hes_pattern, j + 1);\n      i = *itr;\n      while( i < q )\n      {  if( transpose )\n            h[ j * q + i ] = true;\n         else\n            h[ i * n + j ] = true;\n         i = *(++itr);\n      }\n   }\n}\n/*!\nPrivate helper function for RevSparseHes(q, s) set sparsity.\n\nAll of the description in the public member function RevSparseHes(q, s)\napplies.\n\n\\param set_type\nis a std::set<size_t> value.\nThis argument is used to dispatch to the proper source\ncode depending on the value of SetVector::value_type.\n\n\\param transpose\nSee RevSparseHes(q, s).\n\n\\param q\nSee RevSparseHes(q, s).\n\n\\param s\nSee RevSparseHes(q, s).\n\n\\param h\nis the return value for the corresponding call to RevSparseJac(q, s).\n*/\ntemplate <class Base, class RecBase>\ntemplate <class SetVector>\nvoid ADFun<Base,RecBase>::RevSparseHesCase(\n   const std::set<size_t>&   set_type         ,\n   bool                      transpose        ,\n   size_t                    q                ,\n   const SetVector&          s                ,\n   SetVector&                h                )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   size_t n = Domain();\n# ifndef NDEBUG\n   size_t m = Range();\n# endif\n   //\n   if( transpose )\n      h.resize(n);\n   else\n      h.resize(q);\n\n   CPPAD_ASSERT_KNOWN(\n      for_jac_sparse_set_.n_set() > 0,\n      \"RevSparseHes: previous stored call to ForSparseJac did not \"\n      \"use std::set<size_t> for the elements of r.\"\n   );\n   CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.n_set() == 0 );\n   CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.n_set() == num_var_tape_  );\n   //\n   // temporary indices\n   size_t i, j;\n   std::set<size_t>::const_iterator itr_1;\n\n   // check SetVector is Simple Vector class with sets for elements\n   CheckSimpleVector<std::set<size_t>, SetVector>(\n      local::one_element_std_set<size_t>(), local::two_element_std_set<size_t>()\n   );\n\n   CPPAD_ASSERT_KNOWN(\n      q == for_jac_sparse_set_.end(),\n      \"RevSparseHes: q is not equal to its value\\n\"\n      \"in the previous call to ForSparseJac with this ADFun object.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      s.size() == 1,\n      \"RevSparseHes: size of s is not equal to one.\"\n   );\n\n   // Array that will hold reverse Jacobian dependency flag.\n   // Initialize as true for the dependent variables.\n   local::pod_vector<bool> RevJac(num_var_tape_);\n   for(i = 0; i < num_var_tape_; i++)\n      RevJac[i] = false;\n   itr_1 = s[0].begin();\n   while( itr_1 != s[0].end() )\n   {  i = *itr_1++;\n      CPPAD_ASSERT_KNOWN(\n         i < m,\n         \"RevSparseHes: an element of the set s[0] has value \"\n         \"greater than or equal m\"\n      );\n      CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );\n      RevJac[ dep_taddr_[i] ] = true;\n   }\n\n\n   // vector of sets that will hold reverse Hessain values\n   local::sparse::list_setvec rev_hes_pattern;\n   rev_hes_pattern.resize(num_var_tape_, q);\n\n   // compute the Hessian sparsity patterns\n   local::sweep::rev_hes(\n      &play_,\n      num_var_tape_,\n      for_jac_sparse_set_,\n      RevJac.data(),\n      rev_hes_pattern,\n      not_used_rec_base\n\n   );\n\n   // return values corresponding to independent variables\n   // j is index corresponding to reverse mode partial\n   CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == q || transpose );\n   CPPAD_ASSERT_UNKNOWN( size_t(h.size()) == n || ! transpose );\n   for(j = 0; j < n; j++)\n   {  CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ );\n      CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j + 1 );\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );\n\n      // extract the result from rev_hes_pattern\n      // and add corresponding elements to result sets in h\n      CPPAD_ASSERT_UNKNOWN( rev_hes_pattern.end() == q );\n      local::sparse::list_setvec::const_iterator itr_2(rev_hes_pattern, j+1);\n      i = *itr_2;\n      while( i < q )\n      {  if( transpose )\n            h[j].insert(i);\n         else\n            h[i].insert(j);\n         i = *(++itr_2);\n      }\n   }\n}\n\n// ===========================================================================\n// RevSparseHes\n\n/*!\nUser API for Hessian sparsity patterns using reverse mode.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   h = f.RevSparseHes(q, r)\n\\endverbatim\n\n\\tparam Base\nis the base type for this recording.\n\n\\tparam SetVector\nis a simple vector with elements of type bool\nor std::set<size_t>.\n\n\\param transpose\nis true (false) if is is equal to \\f$ H(x) \\f$ (\\f$ H(x)^T \\f$)\nwhere\n\\f[\n   H(x) = R^T (S * F)^{(2)} (x)\n\\f]\nwhere \\f$ F \\f$ is the function corresponding to the operation sequence\nand x is any argument value.\n\n\\param q\nis the value of q in the\nby the previous call of the form\n\\verbatim\n   f.ForSparseJac(q, r, packed)\n\\endverbatim\nThe value r in this call is a sparsity pattern for the matrix \\f$ R \\f$.\nThe type of the element of r for the previous call to ForSparseJac\nmust be the same as the type of the elements of s.\n\n\\param s\nis a vector with size m that specifies the sparsity pattern\nfor the vector \\f$ S \\f$,\nwhere m is the number of dependent variables\ncorresponding to the operation sequence stored in play.\n\n\\return\nIf transpose is false (true),\nthe return vector is a sparsity pattern for \\f$ H(x) \\f$ (\\f$ H(x)^T \\f$).\n\\f[\n   H(x) = R^T ( S * F)^{(2)} (x)\n\\f]\nwhere \\f$ F \\f$ is the function corresponding to the operation sequence\nand x is any argument value.\n*/\n\ntemplate <class Base, class RecBase>\ntemplate <class SetVector>\nSetVector ADFun<Base,RecBase>::RevSparseHes(\n   size_t q,  const SetVector& s, bool transpose\n)\n{\n   SetVector h;\n   typedef typename SetVector::value_type Set_type;\n\n   // Should check to make sure q is same as in previous call to\n   // forward sparse Jacobian.\n   RevSparseHesCase(\n      Set_type()    ,\n      transpose     ,\n      q             ,\n      s             ,\n      h\n   );\n\n   return h;\n}\n// ===========================================================================\n// RevSparseHesCheckpoint\n/*!\nHessian sparsity patterns calculation used by checkpoint functions.\n\n\\tparam Base\nis the base type for this recording.\n\n\\param transpose\nis true (false) h is equal to \\f$ H(x) \\f$ (\\f$ H(x)^T \\f$)\nwhere\n\\f[\n   H(x) = R^T (S * F)^{(2)} (x)\n\\f]\nwhere \\f$ F \\f$ is the function corresponding to the operation sequence\nand \\f$ x \\f$ is any argument value.\n\n\\param q\nis the value of q in the by the previous call of the form\n\\verbatim\n   f.ForSparseJac(q, r)\n\\endverbatim\nThe value r in this call is a sparsity pattern for the matrix \\f$ R \\f$.\n\n\\param s\nis a vector with size m that specifies the sparsity pattern\nfor the vector \\f$ S \\f$,\nwhere m is the number of dependent variables\ncorresponding to the operation sequence stored in play_.\n\n\\param h\nThe input size and elements of h do not matter.\nOn output, h is the sparsity pattern for the matrix \\f$ H(x) \\f$\nor \\f$ H(x)^T \\f$ depending on transpose.\n\n\\par Assumptions\nThe forward jacobian sparsity pattern must be currently stored\nin this ADFUN object.\n*/\ntemplate <class Base, class RecBase>\nvoid ADFun<Base,RecBase>::RevSparseHesCheckpoint(\n   size_t                        q         ,\n   vector<bool>&                 s         ,\n   bool                          transpose ,\n   local::sparse::list_setvec&   h         )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   size_t n = Domain();\n   size_t m = Range();\n\n   // checkpoint functions should get this right\n   CPPAD_ASSERT_UNKNOWN( for_jac_sparse_pack_.n_set() == 0 );\n   CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.n_set() == num_var_tape_ );\n   CPPAD_ASSERT_UNKNOWN( for_jac_sparse_set_.end()   == q );\n   CPPAD_ASSERT_UNKNOWN( s.size()                    == m );\n\n   // Array that holds the reverse Jacobiain dependency flags.\n   // Initialize as true for dependent variables, false for others.\n   local::pod_vector<bool> RevJac(num_var_tape_);\n   for(size_t i = 0; i < num_var_tape_; i++)\n      RevJac[i] = false;\n   for(size_t i = 0; i < m; i++)\n   {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ )\n      RevJac[ dep_taddr_[i] ] = s[i];\n   }\n\n   // holds reverse Hessian sparsity pattern for all variables\n   local::sparse::list_setvec rev_hes_pattern;\n   rev_hes_pattern.resize(num_var_tape_, q);\n\n   // compute Hessian sparsity pattern for all variables\n   local::sweep::rev_hes(\n      &play_,\n      num_var_tape_,\n      for_jac_sparse_set_,\n      RevJac.data(),\n      rev_hes_pattern,\n      not_used_rec_base\n\n   );\n\n   // dimension the return value\n   if( transpose )\n      h.resize(n, q);\n   else\n      h.resize(q, n);\n\n   // j is index corresponding to reverse mode partial\n   for(size_t j = 0; j < n; j++)\n   {  CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_ );\n\n      // ind_taddr_[j] is operator taddr for j-th independent variable\n      CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == j + 1 );\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );\n\n      // extract the result from rev_hes_pattern\n      CPPAD_ASSERT_UNKNOWN( rev_hes_pattern.end() == q );\n      local::sparse::list_setvec::const_iterator itr(rev_hes_pattern, j + 1);\n      size_t i = *itr;\n      while( i < q )\n      {  if( transpose )\n            h.post_element(j,  i);\n         else\n            h.post_element(i, j);\n         i = *(++itr);\n      }\n   }\n   for(size_t i = 0; i < h.n_set(); ++i)\n      h.process_post(i);\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/rev_sparse_jac.hpp",
    "content": "# ifndef CPPAD_CORE_REV_SPARSE_JAC_HPP\n# define CPPAD_CORE_REV_SPARSE_JAC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin RevSparseJac}\n\nJacobian Sparsity Pattern: Reverse Mode\n#######################################\n\nSyntax\n******\n| *s* = *f* . ``RevSparseJac`` ( *q* , *r* )\n| *s* = *f* . ``RevSparseJac`` ( *q* , *r* , *transpose* , *dependency* )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to *f* .\nFor a fixed matrix :math:`R \\in \\B{R}^{q \\times m}`,\nthe Jacobian of :math:`R * F( x )`\nwith respect to :math:`x` is\n\n.. math::\n\n   S(x) = R * F^{(1)} ( x )\n\nGiven a\n:ref:`glossary@Sparsity Pattern`\nfor :math:`R`,\n``RevSparseJac`` returns a sparsity pattern for the :math:`S(x)`.\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nx\n*\nIf the operation sequence in *f* is\n:ref:`glossary@Operation@Independent` of\nthe independent variables in :math:`x \\in \\B{R}^n`,\nthe sparsity pattern is valid for all values of\n(even if it has :ref:`CondExp-name` or :ref:`VecAD-name` operations).\n\nq\n*\nThe argument *q* has prototype\n\n   ``size_t`` *q*\n\nIt specifies the number of rows in\n:math:`R \\in \\B{R}^{q \\times m}` and the\nJacobian :math:`S(x) \\in \\B{R}^{q \\times n}`.\n\ntranspose\n*********\nThe argument *transpose* has prototype\n\n   ``bool`` *transpose*\n\nThe default value ``false`` is used when *transpose* is not present.\n\ndependency\n**********\nThe argument *dependency* has prototype\n\n   ``bool`` *dependency*\n\nIf *dependency* is true,\nthe :ref:`dependency.cpp@Dependency Pattern`\n(instead of sparsity pattern) is computed.\n\nr\n*\nThe argument *s* has prototype\n\n   ``const`` *SetVector* & *r*\n\nsee :ref:`RevSparseJac@SetVector` below.\n\ntranspose false\n===============\nIf *r* has elements of type ``bool`` ,\nits size is :math:`q * m`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is *q* and all its set elements are between\nzero and :math:`m - 1`.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the matrix :math:`R \\in \\B{R}^{q \\times m}`.\n\ntranspose true\n==============\nIf *r* has elements of type ``bool`` ,\nits size is :math:`m * q`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is *m* and all its set elements are between\nzero and :math:`q - 1`.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the matrix :math:`R^\\R{T} \\in \\B{R}^{m \\times q}`.\n\ns\n*\nThe return value *s* has prototype\n\n   *SetVector* *s*\n\nsee :ref:`RevSparseJac@SetVector` below.\n\ntranspose false\n===============\nIf it has elements of type ``bool`` ,\nits size is :math:`q * n`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is *q* and all its set elements are between\nzero and :math:`n - 1`.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the matrix :math:`S(x) \\in {q \\times n}`.\n\ntranspose true\n==============\nIf it has elements of type ``bool`` ,\nits size is :math:`n * q`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is *n* and all its set elements are between\nzero and :math:`q - 1`.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the matrix :math:`S(x)^\\R{T} \\in {n \\times q}`.\n\nSetVector\n*********\nThe type *SetVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``bool`` or ``std::set<size_t>`` ;\nsee :ref:`glossary@Sparsity Pattern` for a discussion\nof the difference.\n\nEntire Sparsity Pattern\n***********************\nSuppose that :math:`q = m` and\n:math:`R` is the :math:`m \\times m` identity matrix.\nIn this case,\nthe corresponding value for *s* is a\nsparsity pattern for the Jacobian :math:`S(x) = F^{(1)} ( x )`.\n\nExample\n*******\n{xrst_toc_hidden\n   example/sparse/rev_sparse_jac.cpp\n}\nThe file\n:ref:`rev_sparse_jac.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end RevSparseJac}\n-----------------------------------------------------------------------------\n*/\n\n# include <cppad/local/std_set.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file core/rev_sparse_jac.hpp\nReverse mode Jacobian sparsity patterns.\n*/\n// =========================================================================\n// RevSparseJacCase\n\n/*!\nPrivate helper function for RevSparseJac(q, r, transpose) boolean sparsity.\n\nAll of the description in the public member function\n RevSparseJac(q, r, transpose) apply.\n\n\\param set_type\nis a bool value.\nThis argument is used to dispatch to the proper source code\ndepending on the value of SetVector::value_type.\n\n\\param transpose\nSee RevSparseJac(q, r, transpose, dependency)\n\n\\param dependency\nSee RevSparseJac(q, r, transpose, dependency)\n\n\\param q\nSee RevSparseJac(q, r, transpose, dependency)\n\n\\param r\nSee RevSparseJac(q, r, transpose, dependency)\n\n\\param s\nis the return value for the corresponding call to\nRevSparseJac(q, r, transpose).\n*/\n\ntemplate <class Base, class RecBase>\ntemplate <class SetVector>\nvoid ADFun<Base,RecBase>::RevSparseJacCase(\n   bool                set_type          ,\n   bool                transpose         ,\n   bool                dependency        ,\n   size_t              q                 ,\n   const SetVector&    r                 ,\n   SetVector&          s                 )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   size_t n = Domain();\n   size_t m = Range();\n\n   // dimension of the result vector\n   s.resize( q * n );\n\n   // check SetVector is Simple Vector class with bool elements\n   CheckSimpleVector<bool, SetVector>();\n   //\n   CPPAD_ASSERT_KNOWN(\n      q > 0,\n      \"RevSparseJac: q is not greater than zero\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(r.size()) == q * m,\n      \"RevSparseJac: size of r is not equal to\\n\"\n      \"q times range dimension for ADFun object.\"\n   );\n   //\n   // vector of sets that will hold the results\n   local::sparse::pack_setvec    var_sparsity;\n   var_sparsity.resize(num_var_tape_, q);\n\n   // The sparsity pattern corresponding to the dependent variables\n   for(size_t i = 0; i < m; i++)\n   {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );\n      if( transpose )\n      {  for(size_t j = 0; j < q; j++) if( r[ i * q + j ] )\n            var_sparsity.post_element( dep_taddr_[i], j );\n      }\n      else\n      {  for(size_t j = 0; j < q; j++) if( r[ j * m + i ] )\n            var_sparsity.post_element( dep_taddr_[i], j );\n      }\n   }\n   // process posts\n   for(size_t i = 0; i < m; i++)\n      var_sparsity.process_post( dep_taddr_[i] );\n\n   // evaluate the sparsity patterns\n   local::sweep::rev_jac(\n      &play_,\n      dependency,\n      n,\n      num_var_tape_,\n      var_sparsity,\n      not_used_rec_base\n\n   );\n\n   // return values corresponding to dependent variables\n   CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == q * n );\n   for(size_t j = 0; j < n; j++)\n   {  CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) );\n\n      // ind_taddr_[j] is operator taddr for j-th independent variable\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );\n\n      // extract the result from var_sparsity\n      if( transpose )\n      {  for(size_t i = 0; i < q; i++)\n            s[ j * q + i ] = false;\n      }\n      else\n      {  for(size_t i = 0; i < q; i++)\n            s[ i * n + j ] = false;\n      }\n      CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == q );\n      local::sparse::pack_setvec::const_iterator itr(var_sparsity, j+1);\n      size_t i = *itr;\n      while( i < q )\n      {  if( transpose )\n            s[ j * q + i ] = true;\n         else\n            s[ i * n + j ] = true;\n         i  = *(++itr);\n      }\n   }\n}\n\n/*!\nPrivate helper function for RevSparseJac(q, r, transpose) set sparsity\n\nAll of the description in the public member function\n RevSparseJac(q, r, transpose) apply.\n\n\\param set_type\nis a std::set<size_t> object.\nThis argument is used to dispatch to the proper source code\ndepending on the value of SetVector::value_type.\n\n\\param transpose\nSee RevSparseJac(q, r, transpose, dependency)\n\n\\param dependency\nSee RevSparseJac(q, r, transpose, dependency)\n\n\\param q\nSee RevSparseJac(q, r, transpose, dependency)\n\n\\param r\nSee RevSparseJac(q, r, transpose, dependency)\n\n\\param s\nis the return value for the corresponding call to RevSparseJac(q, r, transpose)\n*/\n\ntemplate <class Base, class RecBase>\ntemplate <class SetVector>\nvoid ADFun<Base,RecBase>::RevSparseJacCase(\n   const std::set<size_t>&      set_type          ,\n   bool                         transpose         ,\n   bool                         dependency        ,\n   size_t                       q                 ,\n   const SetVector&             r                 ,\n   SetVector&                   s                 )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   // dimension of the result vector\n   if( transpose )\n      s.resize( Domain() );\n   else\n      s.resize( q );\n\n   // temporary indices\n   std::set<size_t>::const_iterator itr_1;\n\n   // check SetVector is Simple Vector class with sets for elements\n   CheckSimpleVector<std::set<size_t>, SetVector>(\n      local::one_element_std_set<size_t>(), local::two_element_std_set<size_t>()\n   );\n\n   // domain dimensions for F\n   size_t n = ind_taddr_.size();\n   size_t m = dep_taddr_.size();\n\n   CPPAD_ASSERT_KNOWN(\n      q > 0,\n      \"RevSparseJac: q is not greater than zero\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(r.size()) == q || transpose,\n      \"RevSparseJac: size of r is not equal to q and transpose is false.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(r.size()) == m || ! transpose,\n      \"RevSparseJac: size of r is not equal to m and transpose is true.\"\n   );\n\n   // vector of lists that will hold the results\n   local::sparse::list_setvec   var_sparsity;\n   var_sparsity.resize(num_var_tape_, q);\n\n   // The sparsity pattern corresponding to the dependent variables\n   if( transpose )\n   {  for(size_t i = 0; i < m; i++)\n      {  itr_1 = r[i].begin();\n         while(itr_1 != r[i].end())\n         {  size_t j = *itr_1++;\n            CPPAD_ASSERT_KNOWN(\n            j < q,\n            \"RevSparseJac: transpose is true and element of the set\\n\"\n            \"r[i] has value greater than or equal q.\"\n            );\n            CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );\n            var_sparsity.post_element( dep_taddr_[i], j );\n         }\n      }\n   }\n   else\n   {  for(size_t i = 0; i < q; i++)\n      {  itr_1 = r[i].begin();\n         while(itr_1 != r[i].end())\n         {  size_t j = *itr_1++;\n            CPPAD_ASSERT_KNOWN(\n            j < m,\n            \"RevSparseJac: transpose is false and element of the set\\n\"\n            \"r[i] has value greater than or equal range dimension.\"\n            );\n            CPPAD_ASSERT_UNKNOWN( dep_taddr_[j] < num_var_tape_ );\n            var_sparsity.post_element( dep_taddr_[j], i );\n         }\n      }\n   }\n   // process posts\n   for(size_t i = 0; i < m; i++)\n      var_sparsity.process_post( dep_taddr_[i] );\n\n   // evaluate the sparsity patterns\n   local::sweep::rev_jac(\n      &play_,\n      dependency,\n      n,\n      num_var_tape_,\n      var_sparsity,\n      not_used_rec_base\n\n   );\n\n   // return values corresponding to dependent variables\n   CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == q || transpose );\n   CPPAD_ASSERT_UNKNOWN( size_t(s.size()) == n || ! transpose );\n   for(size_t j = 0; j < n; j++)\n   {  CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) );\n\n      // ind_taddr_[j] is operator taddr for j-th independent variable\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );\n\n      CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == q );\n      local::sparse::list_setvec::const_iterator itr_2(var_sparsity, j+1);\n      size_t i = *itr_2;\n      while( i < q )\n      {  if( transpose )\n            s[j].insert(i);\n         else\n            s[i].insert(j);\n         i = *(++itr_2);\n      }\n   }\n}\n\n// =========================================================================\n// RevSparseJac\n/*!\nUser API for Jacobian sparsity patterns using reverse mode.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   s = f.RevSparseJac(q, r, transpose, dependency)\n\\endverbatim\n\n\\tparam Base\nis the base type for this recording.\n\n\\tparam SetVector\nis a simple vector with elements of type bool.\nor std::set<size_t>.\n\n\\param q\nis the number of rows in the matrix \\f$ R \\f$.\n\n\\param r\nis a sparsity pattern for the matrix \\f$ R \\f$.\n\n\\param transpose\nare the sparsity patterns for \\f$ R \\f$ and \\f$ S(x) \\f$ transposed.\n\n\\param dependency\nAre the derivatives with respect to left and right of the expression below\nconsidered to be non-zero:\n\\code\n   CondExpRel(left, right, if_true, if_false)\n\\endcode\nThis is used by the optimizer to obtain the correct dependency relations.\n\n\n\\return\nIf transpose is false (true), the return value is a sparsity pattern\nfor \\f$ S(x) \\f$ (\\f$ S(x)^T \\f$) where\n\\f[\n   S(x) = R * F^{(1)} (x)\n\\f]\nand \\f$ F \\f$ is the function corresponding to the operation sequence\nand x is any argument value.\nIf SetVector::value_type is bool,\nthe return value has size \\f$ q * n \\f$ ( \\f$ n * q \\f$).\nIf SetVector::value_type is std::set<size_t>,\nthe return value has size \\f$ q \\f$ ( \\f$ n \\f$)\nand with all its elements between zero and \\f$ n - 1 \\f$ (\\f$ q - 1 \\f$).\n*/\ntemplate <class Base, class RecBase>\ntemplate <class SetVector>\nSetVector ADFun<Base,RecBase>::RevSparseJac(\n   size_t              q          ,\n   const SetVector&    r          ,\n   bool                transpose  ,\n   bool                dependency )\n{\n   SetVector s;\n   typedef typename SetVector::value_type Set_type;\n\n   RevSparseJacCase(\n      Set_type()    ,\n      transpose     ,\n      dependency    ,\n      q             ,\n      r             ,\n      s\n   );\n   return s;\n}\n// ===========================================================================\n// RevSparseJacCheckpoint\n/*!\nReverse mode Jacobian sparsity calculation used by checkpoint functions.\n\n\\tparam Base\nis the base type for this recording.\n\n\\param transpose\nis true (false) s is equal to \\f$ S(x) \\f$ (\\f$ S(x)^T \\f$)\nwhere\n\\f[\n   S(x) = R * F^{(1)} (x)\n\\f]\nwhere \\f$ F \\f$ is the function corresponding to the operation sequence\nand \\f$ x \\f$ is any argument value.\n\n\\param q\nis the number of rows in the matrix \\f$ R \\f$.\n\n\\param r\nis a sparsity pattern for the matrix \\f$ R \\f$.\n\n\\param transpose\nare the sparsity patterns for \\f$ R \\f$ and \\f$ S(x) \\f$ transposed.\n\n\\param dependency\nAre the derivatives with respect to left and right of the expression below\nconsidered to be non-zero:\n\\code\n   CondExpRel(left, right, if_true, if_false)\n\\endcode\nThis is used by the optimizer to obtain the correct dependency relations.\n\n\\param s\nThe input size and elements of s do not matter.\nOn output, s is the sparsity pattern for the matrix \\f$ S(x) \\f$\nor \\f$ S(x)^T \\f$ depending on transpose.\n\n*/\ntemplate <class Base, class RecBase>\nvoid ADFun<Base,RecBase>::RevSparseJacCheckpoint(\n   size_t                               q          ,\n   const local::sparse::list_setvec&    r          ,\n   bool                                 transpose  ,\n   bool                                 dependency ,\n   local::sparse::list_setvec&          s          )\n{\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   size_t n = Domain();\n   size_t m = Range();\n\n# ifndef NDEBUG\n   if( transpose )\n   {  CPPAD_ASSERT_UNKNOWN( r.n_set() == m );\n      CPPAD_ASSERT_UNKNOWN( r.end()   == q );\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( r.n_set() == q );\n      CPPAD_ASSERT_UNKNOWN( r.end()   == m );\n   }\n   for(size_t i = 0; i < m; i++)\n      CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_ );\n# endif\n\n   // holds reverse Jacobian sparsity pattern for all variables\n   local::sparse::list_setvec var_sparsity;\n   var_sparsity.resize(num_var_tape_, q);\n\n   // set sparsity pattern for dependent variables\n   if( transpose )\n   {  for(size_t i = 0; i < m; i++)\n      {  local::sparse::list_setvec::const_iterator itr(r, i);\n         size_t j = *itr;\n         while( j < q )\n         {  var_sparsity.post_element( dep_taddr_[i], j );\n            j = *(++itr);\n         }\n      }\n   }\n   else\n   {  for(size_t j = 0; j < q; j++)\n      {  local::sparse::list_setvec::const_iterator itr(r, j);\n         size_t i = *itr;\n         while( i < m )\n         {  var_sparsity.post_element( dep_taddr_[i], j );\n            i = *(++itr);\n         }\n      }\n   }\n   // process posts\n   for(size_t i = 0; i < m; i++)\n      var_sparsity.process_post( dep_taddr_[i] );\n\n   // evaluate the sparsity pattern for all variables\n   local::sweep::rev_jac(\n      &play_,\n      dependency,\n      n,\n      num_var_tape_,\n      var_sparsity,\n      not_used_rec_base\n\n   );\n\n   // dimension the return value\n   if( transpose )\n      s.resize(n, m);\n   else\n      s.resize(m, n);\n\n   // return values corresponding to independent variables\n   for(size_t j = 0; j < n; j++)\n   {  CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] == (j+1) );\n\n      // ind_taddr_[j] is operator taddr for j-th independent variable\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );\n\n      // extract the result from var_sparsity\n      CPPAD_ASSERT_UNKNOWN( var_sparsity.end() == q );\n      local::sparse::list_setvec::const_iterator itr(var_sparsity, j+1);\n      size_t i = *itr;\n      while( i < q )\n      {  if( transpose )\n            s.post_element(j, i);\n         else\n            s.post_element(i, j);\n         i  = *(++itr);\n      }\n   }\n   // process posts\n   for(size_t i = 0; i < s.n_set(); i++)\n      s.process_post(i);\n\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/rev_two.hpp",
    "content": "# ifndef CPPAD_CORE_REV_TWO_HPP\n# define CPPAD_CORE_REV_TWO_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin RevTwo}\n{xrst_spell\n   ddw\n}\n\nReverse Mode Second Partial Derivative Driver\n#############################################\n\nSyntax\n******\n| *ddw* = *f* . ``RevTwo`` ( *x* , *i* , *j* )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to *f* .\nThe syntax above sets\n\n.. math::\n\n   ddw [ k * p + \\ell ]\n   =\n   \\DD{ F_{i[ \\ell ]} }{ x_{j[ \\ell ]} }{ x_k } (x)\n\nfor :math:`k = 0 , \\ldots , n-1`\nand :math:`\\ell = 0 , \\ldots , p`,\nwhere :math:`p` is the size of the vectors *i* and *j* .\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nNote that the :ref:`ADFun-name` object *f* is not ``const``\n(see :ref:`RevTwo@RevTwo Uses Forward` below).\n\nx\n*\nThe argument *x* has prototype\n\n   ``const`` *BaseVector* & *x*\n\n(see :ref:`RevTwo@BaseVector` below)\nand its size\nmust be equal to *n* , the dimension of the\n:ref:`fun_property@Domain` space for *f* .\nIt specifies\nthat point at which to evaluate the partial derivatives listed above.\n\ni\n*\nThe argument *i* has prototype\n\n   ``const`` *SizeVector_t* & *i*\n\n(see :ref:`RevTwo@SizeVector_t` below)\nWe use *p* to denote the size of the vector *i* .\nAll of the indices in *i*\nmust be less than *m* , the dimension of the\n:ref:`fun_property@Range` space for *f* ; i.e.,\nfor :math:`\\ell = 0 , \\ldots , p-1`, :math:`i[ \\ell ]  < m`.\n\nj\n*\nThe argument *j* has prototype\n\n   ``const`` *SizeVector_t* & *j*\n\n(see :ref:`RevTwo@SizeVector_t` below)\nand its size must be equal to *p* ,\nthe size of the vector *i* .\nAll of the indices in *j*\nmust be less than *n* ; i.e.,\nfor :math:`\\ell = 0 , \\ldots , p-1`, :math:`j[ \\ell ]  < n`.\n\nddw\n***\nThe result *ddw* has prototype\n\n   *BaseVector* *ddw*\n\n(see :ref:`RevTwo@BaseVector` below)\nand its size is :math:`n * p`.\nIt contains the requested partial derivatives; to be specific,\nfor :math:`k = 0 , \\ldots , n - 1`\nand :math:`\\ell = 0 , \\ldots , p - 1`\n\n.. math::\n\n   ddw [ k * p + \\ell ]\n   =\n   \\DD{ F_{i[ \\ell ]} }{ x_{j[ \\ell ]} }{ x_k } (x)\n\nBaseVector\n**********\nThe type *BaseVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type Base<SimpleVector@Elements of Specified Type>` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nSizeVector_t\n************\nThe type *SizeVector_t* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type size_t<SimpleVector@Elements of Specified Type>` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nRevTwo Uses Forward\n*******************\nAfter each call to :ref:`Forward-name` ,\nthe object *f* contains the corresponding\n:ref:`Taylor coefficients<glossary@Taylor Coefficient>` .\nAfter a call to ``RevTwo`` ,\nthe zero order Taylor coefficients correspond to\n*f* . ``Forward`` (0, *x* )\nand the other coefficients are unspecified.\n\nExamples\n********\n{xrst_toc_hidden\n   example/general/rev_two.cpp\n}\nThe routine\n:ref:`RevTwo<rev_two.cpp-name>` is both an example and test.\nIt returns ``true`` , if it succeeds and ``false`` otherwise.\n\n{xrst_end RevTwo}\n-----------------------------------------------------------------------------\n*/\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector, class SizeVector_t>\nBaseVector ADFun<Base,RecBase>::RevTwo(\n   const BaseVector   &x,\n   const SizeVector_t &i,\n   const SizeVector_t &j)\n{  size_t i1;\n   size_t j1;\n   size_t k;\n   size_t l;\n\n   size_t n = Domain();\n   size_t m = Range();\n   size_t p = i.size();\n\n   // check BaseVector is Simple Vector class with Base elements\n   CheckSimpleVector<Base, BaseVector>();\n\n   // check SizeVector_t is Simple Vector class with size_t elements\n   CheckSimpleVector<size_t, SizeVector_t>();\n\n   CPPAD_ASSERT_KNOWN(\n      x.size() == n,\n      \"RevTwo: Length of x not equal domain dimension for f.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      i.size() == j.size(),\n      \"RevTwo: Length of the i and j vectors are not equal.\"\n   );\n   // point at which we are evaluating the second partials\n   Forward(0, x);\n\n   // dimension the return value\n   BaseVector ddw(n * p);\n\n   // direction vector in argument space\n   BaseVector dx(n);\n   for(j1 = 0; j1 < n; j1++)\n      dx[j1] = Base(0.0);\n\n   // direction vector in range space\n   BaseVector w(m);\n   for(i1 = 0; i1 < m; i1++)\n      w[i1] = Base(0.0);\n\n   // place to hold the results of a reverse calculation\n   BaseVector r(n * 2);\n\n   // check the indices in i and j\n   for(l = 0; l < p; l++)\n   {  i1 = i[l];\n      j1 = j[l];\n      CPPAD_ASSERT_KNOWN(\n      i1 < m,\n      \"RevTwo: an element of i not less than range dimension for f.\"\n      );\n      CPPAD_ASSERT_KNOWN(\n      j1 < n,\n      \"RevTwo: an element of j not less than domain dimension for f.\"\n      );\n   }\n\n   // loop over all forward directions\n   for(j1 = 0; j1 < n; j1++)\n   {  // first order forward mode calculation done\n      bool first_done = false;\n      for(l = 0; l < p; l++) if( j[l] == j1 )\n      {  if( ! first_done )\n         {  first_done = true;\n\n            // first order forward mode in j1 direction\n            dx[j1] = Base(1.0);\n            Forward(1, dx);\n            dx[j1] = Base(0.0);\n         }\n         // execute a reverse in this component direction\n         i1    = i[l];\n         w[i1] = Base(1.0);\n         r     = Reverse(2, w);\n         w[i1] = Base(0.0);\n\n         // place the reverse result in return value\n         for(k = 0; k < n; k++)\n            ddw[k * p + l] = r[k * 2 + 1];\n      }\n   }\n   return ddw;\n}\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/reverse.hpp",
    "content": "# ifndef CPPAD_CORE_REVERSE_HPP\n# define CPPAD_CORE_REVERSE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <algorithm>\n# include <cppad/local/pod_vector.hpp>\n# include <cppad/local/play/sequential_iterator.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file core/reverse.hpp\nCompute derivatives using reverse mode.\n*/\n\n\n/*!\nUse reverse mode to compute derivative of forward mode Taylor coefficients.\n\nThe function\n\\f$ X : {\\bf R} \\times {\\bf R}^{n \\times q} \\rightarrow {\\bf R} \\f$\nis defined by\n\\f[\nX(t , u) = \\sum_{k=0}^{q-1} u^{(k)} t^k\n\\f]\nThe function\n\\f$ Y : {\\bf R} \\times {\\bf R}^{n \\times q} \\rightarrow {\\bf R} \\f$\nis defined by\n\\f[\nY(t , u) = F[ X(t, u) ]\n\\f]\nThe function\n\\f$ W : {\\bf R}^{n \\times q} \\rightarrow {\\bf R} \\f$ is defined by\n\\f[\nW(u) = \\sum_{k=0}^{q-1} ( w^{(k)} )^{\\rm T}\n\\frac{1}{k !} \\frac{ \\partial^k } { t^k } Y(0, u)\n\\f]\n\n\\tparam Base\nbase type for the operator; i.e., this operation sequence was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\tparam BaseVector\nis a Simple Vector class with elements of type Base.\n\n\\param q\nis the number of the number of Taylor coefficients that are being\ndifferentiated (per variable).\n\n\\param w\nis the weighting for each of the Taylor coefficients corresponding\nto dependent variables.\nIf the argument w has size <tt>m * q </tt>,\nfor \\f$ k = 0 , \\ldots , q-1 \\f$ and \\f$ i = 0, \\ldots , m-1 \\f$,\n\\f[\n   w_i^{(k)} = w [ i * q + k ]\n\\f]\nIf the argument w has size m ,\nfor \\f$ k = 0 , \\ldots , q-1 \\f$ and \\f$ i = 0, \\ldots , m-1 \\f$,\n\\f[\nw_i^{(k)} = \\left\\{ \\begin{array}{ll}\n   w [ i ] & {\\rm if} \\; k = q-1\n   \\\\\n   0       & {\\rm otherwise}\n\\end{array} \\right.\n\\f]\n\n\\return\nIs a vector \\f$ dw \\f$ such that\nfor \\f$ j = 0 , \\ldots , n-1 \\f$ and\n\\f$ k = 0 , \\ldots , q-1 \\f$\n\\f[\n   dw[ j * q + k ] = W^{(1)} ( x )_{j,k}\n\\f]\nwhere the matrix \\f$ x \\f$ is the value for \\f$ u \\f$\nthat corresponding to the forward mode Taylor coefficients\nfor the independent variables as specified by previous calls to Forward.\n\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector>\nBaseVector ADFun<Base,RecBase>::Reverse(size_t q, const BaseVector &w)\n{  // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n\n   // constants\n   const Base zero(0);\n\n   // temporary indices\n   size_t i, j, k;\n\n   // number of independent variables\n   size_t n = ind_taddr_.size();\n\n   // number of dependent variables\n   size_t m = dep_taddr_.size();\n\n   // check BaseVector is Simple Vector class with Base type elements\n   CheckSimpleVector<Base, BaseVector>();\n\n   CPPAD_ASSERT_KNOWN(\n      size_t(w.size()) == m || size_t(w.size()) == (m * q),\n      \"Argument w to Reverse does not have length equal to\\n\"\n      \"the dimension of the range or dimension of range times q.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      q > 0,\n      \"The first argument to Reverse must be greater than zero.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      num_order_taylor_ >= q,\n      \"Less than q Taylor coefficients are currently stored\"\n      \" in this ADFun object.\"\n   );\n   // special case where multiple forward directions have been computed,\n   // but we are only using the one direction zero order results\n   if( (q == 1) && (num_direction_taylor_ > 1) )\n   {  num_order_taylor_ = 1;        // number of orders to copy\n      size_t c = cap_order_taylor_; // keep the same capacity setting\n      size_t r = 1;                 // only keep one direction\n      capacity_order(c, r);\n   }\n   CPPAD_ASSERT_KNOWN(\n      num_direction_taylor_ == 1,\n      \"Reverse mode for Forward(q, r, xq) with more than one direction\"\n      \"\\n(r > 1) is not yet supported for q > 1.\"\n   );\n\n   // initialize entire Partial matrix to zero\n   local::pod_vector_maybe<Base> Partial(num_var_tape_ * q);\n   for(i = 0; i < num_var_tape_; i++)\n      for(j = 0; j < q; j++)\n         Partial[i * q + j] = zero;\n\n   // set the dependent variable direction\n   // (use += because two dependent variables can point to same location)\n   if( size_t(w.size()) == m )\n   {  for(i = 0; i < m; ++i)\n      {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_  );\n         Partial[dep_taddr_[i] * q + q - 1] += w[i];\n      }\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(w.size()) == m * q );\n      for(i = 0; i < m; i++)\n      {  CPPAD_ASSERT_UNKNOWN( dep_taddr_[i] < num_var_tape_  );\n         for(k = 0; k < q; k++)\n            Partial[ dep_taddr_[i] * q + k ] += w[i * q + k ];\n      }\n   }\n   // evaluate the derivatives\n   CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_var_op() );\n   CPPAD_ASSERT_UNKNOWN( load_op2var_.size()  == play_.num_var_load() );\n   local::play::const_sequential_iterator play_itr = play_.end();\n   local::sweep::reverse(\n      num_var_tape_,\n      &play_,\n      cap_order_taylor_,\n      taylor_.data(),\n      q,\n      Partial.data(),\n      cskip_op_.data(),\n      load_op2var_,\n      play_itr,\n      not_used_rec_base\n   );\n\n   // return the derivative values\n   BaseVector value(n * q);\n   for(j = 0; j < n; j++)\n   {  CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] < num_var_tape_  );\n\n      // independent variable taddr equals its operator taddr\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp( ind_taddr_[j] ) == local::InvOp );\n\n      // by the Reverse Identity Theorem\n      // partial of y^{(k)} w.r.t. u^{(0)} is equal to\n      // partial of y^{(q-1)} w.r.t. u^{(q - 1 - k)}\n      if( size_t(w.size()) == m )\n      {  for(k = 0; k < q; k++)\n            value[j * q + k ] =\n               Partial[ind_taddr_[j] * q + q - 1 - k];\n      }\n      else\n      {  for(k = 0; k < q; k++)\n            value[j * q + k ] =\n               Partial[ind_taddr_[j] * q + k];\n      }\n   }\n   CPPAD_ASSERT_KNOWN( ! ( hasnan(value) && check_for_nan_ ) ,\n      \"dw = f.Reverse(q, w): has a nan,\\n\"\n      \"but none of its Taylor coefficients are nan.\"\n   );\n\n   return value;\n}\n\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/sign.hpp",
    "content": "# ifndef CPPAD_CORE_SIGN_HPP\n# define CPPAD_CORE_SIGN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin sign}\n{xrst_spell\n   rl\n}\nThe Sign: sign\n##############\n\nSyntax\n******\n| *y* = ``sign`` ( *x* )\n\nDescription\n***********\nEvaluates the ``sign`` function which is defined by\n\n.. math::\n\n   {\\rm sign} (x) =\n   \\left\\{ \\begin{array}{rl}\n      +1 & {\\rm if} \\; x > 0 \\\\\n      0  & {\\rm if} \\; x = 0 \\\\\n      -1 & {\\rm if} \\; x < 0\n   \\end{array} \\right.\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nDerivative\n**********\nCppAD computes the derivative of the ``sign`` function as zero for all\nargument values *x* .\nThe correct mathematical derivative is different and\nis given by\n\n.. math::\n\n   {\\rm sign}^{(1)} (x) =  2 \\delta (x)\n\nwhere :math:`\\delta (x)` is the Dirac Delta function.\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/sign.cpp\n}\nThe file\n:ref:`sign.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end sign}\n-------------------------------------------------------------------------------\n*/\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nAD<Base> AD<Base>::sign_me (void) const\n{\n   AD<Base> result;\n   result.value_ = sign(value_);\n   CPPAD_ASSERT_UNKNOWN( Parameter(result) );\n\n   // check if there is a recording in progress\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n\n   // check if operand is a constant parameter\n   if( tape_id_ != tape->id_ )\n      return result;\n\n   if(ad_type_ == dynamic_enum)\n   {  // dynamic parameter argument\n      result.taddr_   = tape->Rec_.put_dyn_par(\n         result.value_, local::sign_dyn, taddr_\n      );\n      result.tape_id_  = tape_id_;\n      result.ad_type_  = dynamic_enum;\n   }\n   else\n   {  // variable argument\n      CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SignOp) == 1 );\n      CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SignOp) == 1 );\n\n      // corresponding operand address\n      tape->Rec_.PutArg(taddr_);\n\n      // put operator in the tape\n      result.taddr_ = tape->Rec_.PutOp(local::SignOp);\n\n      // make result a variable\n      result.tape_id_ = tape->id_;\n      result.ad_type_ = variable_enum;\n   }\n   return result;\n}\n\ntemplate <class Base>\nAD<Base> sign(const AD<Base> &x)\n{  return x.sign_me();\n}\ntemplate <class Base>\nAD<Base> sign(const VecAD_reference<Base> &x)\n{  return x.ADBase().sign_me(); }\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/sparse.hpp",
    "content": "# ifndef CPPAD_CORE_SPARSE_HPP\n# define CPPAD_CORE_SPARSE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n//\n# include <cppad/core/for_jac_sparsity.hpp>\n# include <cppad/core/rev_jac_sparsity.hpp>\n//\n# include <cppad/core/for_hes_sparsity.hpp>\n# include <cppad/core/rev_hes_sparsity.hpp>\n//\n# include <cppad/core/for_sparse_jac.hpp>\n# include <cppad/core/rev_sparse_jac.hpp>\n//\n# include <cppad/core/for_sparse_hes.hpp>\n# include <cppad/core/rev_sparse_hes.hpp>\n//\n# include <cppad/core/sparse_jac.hpp>\n# include <cppad/core/sparse_hes.hpp>\n//\n# include <cppad/core/sparse_jacobian.hpp>\n# include <cppad/core/sparse_hessian.hpp>\n//\n# include <cppad/core/subgraph_sparsity.hpp>\n# include <cppad/core/subgraph_reverse.hpp>\n# include <cppad/core/subgraph_jac_rev.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/sparse_hes.hpp",
    "content": "# ifndef CPPAD_CORE_SPARSE_HES_HPP\n# define CPPAD_CORE_SPARSE_HES_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin sparse_hes}\n{xrst_spell\n   nr\n   rc\n   rcv\n}\n\nComputing Sparse Hessians\n#########################\n\nSyntax\n******\n| *n_sweep* = *f* . ``sparse_hes`` (\n| |tab| *x* , *w* , *subset* , *pattern* , *coloring* , *work*\n| )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\nfunction corresponding to *f* .\nHere *n* is the :ref:`fun_property@Domain` size,\nand *m* is the :ref:`fun_property@Range` size, or *f* .\nThe syntax above takes advantage of sparsity when computing the Hessian\n\n.. math::\n\n   H(x) = \\dpow{2}{x} \\sum_{i=0}^{m-1} w_i F_i (x)\n\nIn the sparse case, this should be faster and take less memory than\n:ref:`Hessian-name` .\nThe matrix element :math:`H_{i,j} (x)` is the second partial of\n:math:`w^\\R{T} F (x)` with respect to :math:`x_i` and :math:`x_j`.\n\nSizeVector\n**********\nThe type *SizeVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``size_t`` .\n\nBaseVector\n**********\nThe type *BaseVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``size_t`` .\n\nf\n*\nThis object has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nNote that the Taylor coefficients stored in *f* are affected\nby this operation; see\n:ref:`sparse_hes@Uses Forward` below.\n\nx\n*\nThis argument has prototype\n\n   ``const`` *BaseVector* & *x*\n\nand its size is *n* .\nIt specifies the point at which to evaluate the Hessian\n:math:`H(x)`.\n\nw\n*\nThis argument has prototype\n\n   ``const`` *BaseVector* & *w*\n\nand its size is *m* .\nIt specifies the weight for each of the components of :math:`F(x)`;\ni.e. :math:`w_i` is the weight for :math:`F_i (x)`.\n\nsubset\n******\nThis argument has prototype\n\n   ``sparse_rcv`` < *SizeVector* , *BaseVector* >& *subset*\n\nIts row size and column size is *n* ; i.e.,\n*subset* . ``nr`` () == *n* and *subset* . ``nc`` () == *n* .\nIt specifies which elements of the Hessian are computed.\n\n#. The input value of its value vector\n   *subset* . ``val`` () does not matter.\n   Upon return it contains the value of the corresponding elements\n   of the Hessian.\n#. All of the row, column pairs in *subset* must also appear in\n   *pattern* ; i.e., they must be possibly non-zero.\n#. The Hessian is symmetric, so one has a choice as to which off diagonal\n   elements to put in *subset* .\n   It will probably be more efficient if one makes this choice so that\n   the there are more entries in each non-zero column of *subset* ;\n   see :ref:`sparse_hes@n_sweep` below.\n\npattern\n*******\nThis argument has prototype\n\n   ``const sparse_rc`` < *SizeVector* >& *pattern*\n\nIts row size and column size is *n* ; i.e.,\n*pattern* . ``nr`` () == *n* and *pattern* . ``nc`` () == *n* .\nIt is a sparsity pattern for the Hessian :math:`H(x)`.\nIf the *i*-th row (*j*-th column) does not appear in *subset* ,\nthe *i*-th row (*j*-th column) of *pattern* does not matter\nand need not be computed.\nThis argument is not used (and need not satisfy any conditions),\nwhen :ref:`sparse_hes@work` is non-empty.\n\nsubset\n======\nIf the *i*-th row and *i*-th column do not appear in *subset* ,\nthe *i*-th row and column of *pattern* do not matter.\nIn this case the *i-th*-th row and column may have no entries in\n*pattern* even though they are possibly non-zero in :math:`H(x)`.\n(This can be used to reduce the amount of computation required to find\n*pattern* .)\n\ncoloring\n********\nThe coloring algorithm determines which rows and columns\ncan be computed during the same sweep.\nThis field has prototype\n\n   ``const std::string&`` *coloring*\n\nThis value only matters when work is empty; i.e.,\nafter the *work* constructor or *work* . ``clear`` () .\n\ncppad.symmetric\n===============\nThis coloring takes advantage of the fact that the Hessian matrix\nis symmetric when find a coloring that requires fewer\n:ref:`sweeps<sparse_hes@n_sweep>` .\n\ncppad.general\n=============\nThis is the same as the sparse Jacobian\n:ref:`sparse_jac@coloring@cppad` method\nwhich does not take advantage of symmetry.\n\ncolpack.symmetric\n=================\nIf :ref:`colpack_prefix-name` was specified on the\n:ref:`cmake@CMake Command` line,\nyou can set *coloring* to ``colpack.symmetric`` .\nThis also takes advantage of the fact that the Hessian matrix is symmetric.\n\ncolpack.general\n===============\nIf :ref:`colpack_prefix-name` was specified on the\n:ref:`cmake@CMake Command` line,\nyou can set *coloring* to ``colpack.general`` .\nThis is the same as the sparse Jacobian\n:ref:`sparse_jac@coloring@colpack` method\nwhich does not take advantage of symmetry.\n\ncolpack.star Deprecated 2017-06-01\n==================================\nThe ``colpack.star`` method is deprecated.\nIt is the same as the ``colpack.symmetric`` method\nwhich should be used instead.\n\nwork\n****\nThis argument has prototype\n\n   ``sparse_hes_work&`` *work*\n\nWe refer to its initial value,\nand its value after *work* . ``clear`` () , as empty.\nIf it is empty, information is stored in *work* .\nThis can be used to reduce computation when\na future call is for the same object *f* ,\nand the same subset of the Hessian.\nIn fact, it can be used with a different *f*\nand a different *subset* provided that Hessian sparsity pattern\nfor *f* and the sparsity pattern in *subset* are the same.\nIf either of these values change, use *work* . ``clear`` () to\nempty this structure.\n\nn_sweep\n*******\nThe return value *n_sweep* has prototype\n\n   ``size_t`` *n_sweep*\n\nIt is the number of first order forward sweeps\nused to compute the requested Hessian values.\nEach first forward sweep is followed by a second order reverse sweep\nso it is also the number of reverse sweeps.\nIt is also the number of colors determined by the coloring method\nmentioned above.\nThis is proportional to the total computational work,\nnot counting the zero order forward sweep,\nor combining multiple columns and rows into a single sweep.\n\nUses Forward\n************\nAfter each call to :ref:`Forward-name` ,\nthe object *f* contains the corresponding\n:ref:`Taylor coefficients<glossary@Taylor Coefficient>` .\nAfter a call to ``sparse_hes``\nthe zero order coefficients correspond to\n\n   *f* . ``Forward`` (0, *x* )\n\nAll the other forward mode coefficients are unspecified.\n\nExample\n*******\n{xrst_toc_hidden\n   example/sparse/sparse_hes.cpp\n}\nThe files :ref:`sparse_hes.cpp-name`\nis an example and test of ``sparse_hes`` .\nIt returns ``true`` , if it succeeds, and ``false`` otherwise.\n\nSubset Hessian\n**************\nThe routine\n:ref:`sparse_sub_hes.cpp-name`\nis an example and test that compute a subset of a sparse Hessian.\nIt returns ``true`` , for success, and ``false`` otherwise.\n\n{xrst_end sparse_hes}\n*/\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/local/sparse/internal.hpp>\n# include <cppad/local/color_general.hpp>\n# include <cppad/local/color_symmetric.hpp>\n\n/*!\n\\file sparse_hes.hpp\nSparse Hessian calculation routines.\n*/\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*!\nClass used to hold information used by Sparse Hessian routine in this file,\nso it does not need to be recomputed every time.\n*/\nclass sparse_hes_work {\n   public:\n      /// row and column indices for return values\n      /// (some may be reflected by symmetric coloring algorithms)\n      CppAD::vector<size_t> row;\n      CppAD::vector<size_t> col;\n      /// indices that sort the row and col arrays by color\n      CppAD::vector<size_t> order;\n      /// results of the coloring algorithm\n      CppAD::vector<size_t> color;\n\n      /// constructor\n      sparse_hes_work(void)\n      { }\n      /// inform CppAD that this information needs to be recomputed\n      void clear(void)\n      {\n         row.clear();\n         col.clear();\n         order.clear();\n         color.clear();\n      }\n};\n// ----------------------------------------------------------------------------\n/*!\nCalculate sparse Hessians using forward mode\n\n\\tparam Base\nthe base type for the recording that is stored in the ADFun object.\n\n\\tparam SizeVector\na simple vector class with elements of type size_t.\n\n\\tparam BaseVector\na simple vector class with elements of type Base.\n\n\\param x\na vector of length n, the number of independent variables in f\n(this ADFun object).\n\n\\param w\na vector of length m, the number of dependent variables in f\n(this ADFun object).\n\n\\param subset\nspedifies the subset of the sparsity pattern where the Hessian is evaluated.\nsubset.nr() == n,\nsubset.nc() == n.\n\n\\param pattern\nis a sparsity pattern for the Hessian of w^T * f;\npattern.nr() == n,\npattern.nc() == n,\nwhere m is number of dependent variables in f.\n\n\\param coloring\ndetermines which coloring algorithm is used.\nThis must be cppad.symmetric, cppad.general, colpack.symmetric,\nor colpack.star.\n\n\\param work\nthis structure must be empty, or contain the information stored\nby a previous call to sparse_hes.\nThe previous call must be for the same ADFun object f\nand the same subset.\n\n\\return\nThis is the number of first order forward\n(and second order reverse) sweeps used to compute the Hessian.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class SizeVector, class BaseVector>\nsize_t ADFun<Base,RecBase>::sparse_hes(\n   const BaseVector&                    x        ,\n   const BaseVector&                    w        ,\n   sparse_rcv<SizeVector , BaseVector>& subset   ,\n   const sparse_rc<SizeVector>&         pattern  ,\n   const std::string&                   coloring ,\n   sparse_hes_work&                     work     )\n{  size_t n = Domain();\n   //\n   CPPAD_ASSERT_KNOWN(\n      subset.nr() == n,\n      \"sparse_hes: subset.nr() not equal domain dimension for f\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      subset.nc() == n,\n      \"sparse_hes: subset.nc() not equal domain dimension for f\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t( x.size() ) == n,\n      \"sparse_hes: x.size() not equal domain dimension for f\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t( w.size() ) == Range(),\n      \"sparse_hes: w.size() not equal range dimension for f\"\n   );\n   //\n   // work information\n   vector<size_t>& row(work.row);\n   vector<size_t>& col(work.col);\n   vector<size_t>& color(work.color);\n   vector<size_t>& order(work.order);\n   //\n   // subset information\n   const SizeVector& subset_row( subset.row() );\n   const SizeVector& subset_col( subset.col() );\n   //\n   // point at which we are evaluating the Hessian\n   Forward(0, x);\n   //\n   // number of elements in the subset\n   size_t K = subset.nnz();\n   //\n   // check for case were there is nothing to do\n   // (except for call to Forward(0, x)\n   if( K == 0 )\n      return 0;\n   //\n# ifndef NDEBUG\n   if( color.size() != 0 )\n   {  CPPAD_ASSERT_KNOWN(\n         color.size() == n,\n         \"sparse_hes: work is non-empty and conditions have changed\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         row.size() == K,\n         \"sparse_hes: work is non-empty and conditions have changed\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         col.size() == K,\n         \"sparse_hes: work is non-empty and conditions have changed\"\n      );\n      //\n      for(size_t k = 0; k < K; k++)\n      {  bool ok = row[k] == subset_row[k] && col[k] == subset_col[k];\n         ok     |= row[k] == subset_col[k] && col[k] == subset_row[k];\n         CPPAD_ASSERT_KNOWN(\n            ok,\n            \"sparse_hes: work is non-empty and conditions have changed\"\n         );\n      }\n   }\n# endif\n   //\n   // check for case where input work is empty\n   if( color.size() == 0 )\n   {  // compute work color and order vectors\n      CPPAD_ASSERT_KNOWN(\n         pattern.nr() == n,\n         \"sparse_hes: pattern.nr() not equal domain dimension for f\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         pattern.nc() == n,\n         \"sparse_hes: pattern.nc() not equal domain dimension for f\"\n      );\n      //\n      // initialize work row, col to be same as subset row, col\n      row.resize(K);\n      col.resize(K);\n      // cannot assign vectors because may be of different types\n      // (SizeVector and CppAD::vector<size_t>)\n      for(size_t k = 0; k < K; k++)\n      {  row[k] = subset_row[k];\n         col[k] = subset_col[k];\n      }\n      //\n      // convert pattern to an internal version of its transpose\n      local::pod_vector<size_t> internal_index(n);\n      for(size_t j = 0; j < n; j++)\n         internal_index[j] = j;\n      bool transpose   = true;\n      bool zero_empty  = false;\n      bool input_empty = true;\n      local::sparse::list_setvec internal_pattern;\n      internal_pattern.resize(n, n);\n      local::sparse::set_internal_pattern(zero_empty, input_empty,\n         transpose, internal_index, internal_pattern, pattern\n      );\n      //\n      // execute coloring algorithm\n      // (we are using transpose because coloring groups rows, not columns)\n      color.resize(n);\n      if( coloring == \"cppad.general\" )\n         local::color_general_cppad(internal_pattern, col, row, color);\n      else if( coloring == \"cppad.symmetric\" )\n         local::color_symmetric_cppad(internal_pattern, col, row, color);\n      else if( coloring == \"colpack.general\" )\n      {\n# if CPPAD_HAS_COLPACK\n         local::color_general_colpack(internal_pattern, col, row, color);\n# else\n         CPPAD_ASSERT_KNOWN(\n            false,\n            \"sparse_hes: coloring = colpack.star \"\n            \"and colpack_prefix not in cmake command line.\"\n         );\n# endif\n      }\n      else if(\n         coloring == \"colpack.symmetric\" ||\n         coloring == \"colpack.star\"\n      )\n      {\n# if CPPAD_HAS_COLPACK\n         local::color_symmetric_colpack(internal_pattern, col, row, color);\n# else\n         CPPAD_ASSERT_KNOWN(\n            false,\n            \"sparse_hes: coloring = colpack.symmetric or colpack.star \"\n            \"and colpack_prefix not in cmake command line.\"\n         );\n# endif\n      }\n      else CPPAD_ASSERT_KNOWN(\n         false,\n         \"sparse_hes: coloring is not valid.\"\n      );\n      //\n      // put sorting indices in color order\n      SizeVector key(K);\n      order.resize(K);\n      for(size_t k = 0; k < K; k++)\n         key[k] = color[ col[k] ];\n      index_sort(key, order);\n   }\n   // Base versions of zero and one\n   Base one(1.0);\n   Base zero(0.0);\n   //\n   size_t n_color = 1;\n   for(size_t j = 0; j < n; j++) if( color[j] < n )\n      n_color = std::max<size_t>(n_color, color[j] + 1);\n   //\n   // initialize the return Hessian values as zero\n   for(size_t k = 0; k < K; k++)\n      subset.set(k, zero);\n   //\n   // direction vector for calls to first order forward\n   BaseVector dx(n);\n   //\n   // return values for calls to second order reverse\n   BaseVector ddw(2 * n);\n   //\n   // loop over colors\n   size_t k = 0;\n   for(size_t ell = 0; ell < n_color; ell++)\n   if( k  == K )\n   {  // kludge because colpack returns colors that are not used\n      // (it does not know about the subset corresponding to row, col)\n      CPPAD_ASSERT_UNKNOWN(\n         coloring == \"colpack.general\" ||\n         coloring == \"colpack.symmetric\" ||\n         coloring == \"colpack.star\"\n      );\n   }\n   else if( color[ col[ order[k] ] ] != ell )\n   {  // kludge because colpack returns colors that are not used\n      // (it does not know about the subset corresponding to row, col)\n      CPPAD_ASSERT_UNKNOWN(\n         coloring == \"colpack.general\" ||\n         coloring == \"colpack.symmetric\" ||\n         coloring == \"colpack.star\"\n      );\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( color[ col[ order[k] ] ] == ell );\n      //\n      // combine all columns with this color\n      for(size_t j = 0; j < n; j++)\n      {  dx[j] = zero;\n         if( color[j] == ell )\n            dx[j] = one;\n      }\n      // call forward mode for all these rows at once\n      Forward(1, dx);\n      //\n      // evaluate derivative of w^T * F'(x) * dx\n      ddw = Reverse(2, w);\n      //\n      // set the corresponding components of the result\n      while( k < K && color[ col[order[k]] ] == ell )\n      {  size_t index = row[ order[k] ] * 2 + 1;\n         subset.set(order[k], ddw[index] );\n         k++;\n      }\n   }\n   // check that all the required entries have been set\n   CPPAD_ASSERT_UNKNOWN( k == K );\n   return n_color;\n}\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/sparse_hessian.hpp",
    "content": "# ifndef CPPAD_CORE_SPARSE_HESSIAN_HPP\n# define CPPAD_CORE_SPARSE_HESSIAN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin sparse_hessian}\n{xrst_spell\n   valarray\n}\n\nSparse Hessian\n##############\n\nSyntax\n******\n| *hes* = *f* . ``SparseHessian`` ( *x* , *w* )\n| *hes* = *f* . ``SparseHessian`` ( *x* , *w* , *p* )\n| *n_sweep* = *f* . ``SparseHessian`` ( *x* , *w* , *p* , *row* , *col* , *hes* , *work* )\n\nPurpose\n*******\nWe use :math:`n` for the :ref:`fun_property@Domain` size,\nand :math:`m` for the :ref:`fun_property@Range` size of *f* .\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` do denote the\n:ref:`glossary@AD Function`\ncorresponding to *f* .\nThe syntax above sets *hes* to the Hessian\n\n.. math::\n\n   H(x) = \\dpow{2}{x} \\sum_{i=1}^m w_i F_i (x)\n\nThis routine takes advantage of the sparsity of the Hessian\nin order to reduce the amount of computation necessary.\nIf *row* and *col* are present, it also takes\nadvantage of the reduced set of elements of the Hessian that\nneed to be computed.\nOne can use speed tests (e.g. :ref:`speed_test-name` )\nto verify that results are computed faster\nthan when using the routine :ref:`Hessian-name` .\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nNote that the :ref:`ADFun-name` object *f* is not ``const``\n(see :ref:`sparse_hessian@Uses Forward` below).\n\nx\n*\nThe argument *x* has prototype\n\n   ``const`` *BaseVector* & *x*\n\n(see :ref:`sparse_hessian@BaseVector` below)\nand its size\nmust be equal to *n* , the dimension of the\n:ref:`fun_property@Domain` space for *f* .\nIt specifies\nthat point at which to evaluate the Hessian.\n\nw\n*\nThe argument *w* has prototype\n\n   ``const`` *BaseVector* & *w*\n\nand size :math:`m`.\nIt specifies the value of :math:`w_i` in the expression\nfor *hes* .\nThe more components of :math:`w` that are identically zero,\nthe more sparse the resulting Hessian may be (and hence the more efficient\nthe calculation of *hes* may be).\n\np\n*\nThe argument *p* is optional and has prototype\n\n   ``const`` *SetVector* & *p*\n\n(see :ref:`sparse_hessian@SetVector` below)\nIf it has elements of type ``bool`` ,\nits size is :math:`n * n`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is :math:`n` and all its set elements are between\nzero and :math:`n - 1`.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the Hessian :math:`H(x)`.\n\nPurpose\n=======\nIf this sparsity pattern does not change between calls to\n``SparseHessian`` , it should be faster to calculate *p* once and\npass this argument to ``SparseHessian`` .\nIf you specify *p* , CppAD will use the same\ntype of sparsity representation\n(vectors of ``bool`` or vectors of ``std::set<size_t>`` )\nfor its internal calculations.\nOtherwise, the representation\nfor the internal calculations is unspecified.\n\nwork\n====\nIf you specify *work* in the calling sequence,\nit is not necessary to keep the sparsity pattern; see the heading\n:ref:`sparse_hessian@work@p` under the *work* description.\n\nColumn Subset\n=============\nIf the arguments *row* and *col* are present,\nand :ref:`sparse_hessian@work@color_method` is\n``cppad.general`` or ``cppad.symmetric`` ,\nit is not necessary to compute the entire sparsity pattern.\nOnly the following subset of column values will matter:\n\n   { *col* [ *k* ] : *k* = 0 , ... , *K* ``-1`` }\n\n.\n\nrow, col\n********\nThe arguments *row* and *col* are optional and have prototype\n\n| |tab| ``const`` *SizeVector* & *row*\n| |tab| ``const`` *SizeVector* & *col*\n\n(see :ref:`sparse_hessian@SizeVector` below).\nThey specify which rows and columns of :math:`H (x)` are\nreturned and in what order.\nWe use :math:`K` to denote the value *hes* . ``size`` ()\nwhich must also equal the size of *row* and *col* .\nFurthermore,\nfor :math:`k = 0 , \\ldots , K-1`, it must hold that\n:math:`row[k] < n` and :math:`col[k] < n`.\nIn addition,\nall of the :math:`(row[k], col[k])` pairs must correspond to a true value\nin the sparsity pattern *p* .\n\nhes\n***\nThe result *hes* has prototype\n\n   *BaseVector* *hes*\n\nIn the case where *row* and *col* are not present,\nthe size of *hes* is :math:`n * n` and\nits size is :math:`n * n`.\nIn this case, for :math:`i = 0 , \\ldots , n - 1`\nand :math:`ell = 0 , \\ldots , n - 1`\n\n.. math::\n\n   hes [ j * n + \\ell ] = \\DD{ w^{\\rm T} F }{ x_j }{ x_\\ell } ( x )\n\nIn the case where the arguments *row* and *col* are present,\nwe use :math:`K` to denote the size of *hes* .\nThe input value of its elements does not matter.\nUpon return, for :math:`k = 0 , \\ldots , K - 1`,\n\n.. math::\n\n   hes [ k ] = \\DD{ w^{\\rm T} F }{ x_j }{ x_\\ell } (x)\n   \\; , \\;\n   \\; {\\rm where} \\;\n   j = row[k]\n   \\; {\\rm and } \\;\n   \\ell = col[k]\n\nwork\n****\nIf this argument is present, it has prototype\n\n   ``sparse_hessian_work&`` *work*\n\nThis object can only be used with the routines ``SparseHessian`` .\nDuring its the first use, information is stored in *work* .\nThis is used to reduce the work done by future calls to ``SparseHessian``\nwith the same *f* , *p* , *row* , and *col* .\nIf a future call is made where any of these values have changed,\nyou must first call *work* . ``clear`` ()\nto inform CppAD that this information needs to be recomputed.\n\ncolor_method\n============\nThe coloring algorithm determines which rows and columns\ncan be computed during the same sweep.\nThis field has prototype\n\n   ``std::string`` *work* . ``color_method``\n\nThis value only matters on the first call to ``sparse_hessian`` that\nfollows the *work* constructor or a call to\n*work* . ``clear`` () .\n\n   ``\"cppad.symmetric\"``\n\nThis is the default coloring method (after a constructor or ``clear()`` ).\nIt takes advantage of the fact that the Hessian matrix\nis symmetric to find a coloring that requires fewer\n:ref:`sweeps<sparse_hessian@n_sweep>` .\n\n   ``\"cppad.general\"``\n\nThis is the same as the ``\"cppad\"`` method for the\n:ref:`sparse_jacobian<sparse_jacobian@work@color_method>` calculation.\n\n   ``\"colpack.symmetric\"``\n\nThis method requires that\n:ref:`colpack_prefix-name` was specified on the\n:ref:`cmake@CMake Command` line.\nIt also takes advantage of the fact that the Hessian matrix is symmetric.\n\n   ``\"colpack.general\"``\n\nThis is the same as the ``\"colpack\"`` method for the\n:ref:`sparse_jacobian<sparse_jacobian@work@color_method>` calculation.\n\ncolpack.star Deprecated 2017-06-01\n==================================\nThe ``colpack.star`` method is deprecated.\nIt is the same as the ``colpack.symmetric``\nwhich should be used instead.\n\np\n=\nIf *work* is present, and it is not the first call after\nits construction or a clear,\nthe sparsity pattern *p* is not used.\nThis enables one to free the sparsity pattern\nand still compute corresponding sparse Hessians.\n\nn_sweep\n*******\nThe return value *n_sweep* has prototype\n\n   ``size_t`` *n_sweep*\n\nIt is the number of first order forward sweeps\nused to compute the requested Hessian values.\nEach first forward sweep is followed by a second order reverse sweep\nso it is also the number of reverse sweeps.\nThis is proportional to the total work that ``SparseHessian`` does,\nnot counting the zero order forward sweep,\nor the work to combine multiple columns into a single\nforward-reverse sweep pair.\n\nBaseVector\n**********\nThe type *BaseVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n*Base* .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nSetVector\n*********\nThe type *SetVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``bool`` or ``std::set<size_t>`` ;\nsee :ref:`glossary@Sparsity Pattern` for a discussion\nof the difference.\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nRestrictions\n============\nIf *SetVector* has elements of ``std::set<size_t>`` ,\nthen *p* [ *i* ] must return a reference (not a copy) to the\ncorresponding set.\nAccording to section 26.3.2.3 of the 1998 C++ standard,\n``std::valarray< std::set<size_t> >`` does not satisfy\nthis condition.\n\nSizeVector\n**********\nThe type *SizeVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``size_t`` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nUses Forward\n************\nAfter each call to :ref:`Forward-name` ,\nthe object *f* contains the corresponding\n:ref:`Taylor coefficients<glossary@Taylor Coefficient>` .\nAfter a call to any of the sparse Hessian routines,\nthe zero order Taylor coefficients correspond to\n*f* . ``Forward`` (0, *x* )\nand the other coefficients are unspecified.\n{xrst_toc_hidden\n   example/sparse/sparse_hessian.cpp\n   example/sparse/sub_sparse_hes.cpp\n   example/sparse/sparse_sub_hes.cpp\n}\n\nExample\n*******\nThe routine\n:ref:`sparse_hessian.cpp-name`\nis examples and tests of ``sparse_hessian`` .\nIt return ``true`` , if it succeeds and ``false`` otherwise.\n\nSubset Hessian\n**************\nThe routine\n:ref:`sub_sparse_hes.cpp-name`\nis an example and test that compute a sparse Hessian\nfor a subset of the variables.\nIt returns ``true`` , for success, and ``false`` otherwise.\n\n{xrst_end sparse_hessian}\n-----------------------------------------------------------------------------\n*/\n# include <cppad/local/std_set.hpp>\n# include <cppad/local/color_general.hpp>\n# include <cppad/local/color_symmetric.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file sparse_hessian.hpp\nSparse Hessian driver routine and helper functions.\n*/\n// ===========================================================================\n/*!\nclass used by SparseHessian to hold information\nso it does not need to be recomputed.\n*/\nclass sparse_hessian_work {\n   public:\n      /// Coloring method: \"cppad\", or \"colpack\"\n      /// (this field is set by user)\n      std::string color_method;\n      /// row and column indices for return values\n      /// (some may be reflected by star coloring algorithm)\n      CppAD::vector<size_t> row;\n      CppAD::vector<size_t> col;\n      /// indices that sort the user row and col arrays by color\n      CppAD::vector<size_t> order;\n      /// results of the coloring algorithm\n      CppAD::vector<size_t> color;\n\n      /// constructor\n      sparse_hessian_work(void) : color_method(\"cppad.symmetric\")\n      { }\n      /// inform CppAD that this information needs to be recomputed\n      void clear(void)\n      {  color_method = \"cppad.symmetric\";\n         row.clear();\n         col.clear();\n         order.clear();\n         color.clear();\n      }\n};\n// ===========================================================================\n/*!\nPrivate helper function that does computation for all Sparse Hessian cases.\n\n\\tparam Base\nis the base type for the recording that is stored in this ADFun<Base object.\n\n\\tparam BaseVector\nis a simple vector class with elements of type Base.\n\n\\tparam SetVector\nis a simple vector class with elements of type\n bool or std::set<size_t>.\n\n\\tparam SizeVector\nis sparse_pack or sparse_list.\n\n\\param x [in]\nis a vector specifying the point at which to compute the Hessian.\n\n\\param w [in]\nis the weighting vector that defines a scalar valued function by\na weighted sum of the components of the vector valued function\n$latex F(x)$$.\n\n\\param sparsity [in]\nis the sparsity pattern for the Hessian that we are calculating.\n\n\\param user_row [in]\nis the vector of row indices for the returned Hessian values.\n\n\\param user_col [in]\nis the vector of columns indices for the returned Hessian values.\nIt must have the same size as user_row.\n\n\\param hes [out]\nis the vector of Hessian values.\nIt must have the same size as user_row.\nThe return value <code>hes[k]</code> is the second partial of\n\\f$ w^{\\rm T} F(x)\\f$ with respect to the\n<code>row[k]</code> and <code>col[k]</code> component of \\f$ x\\f$.\n\n\\param work\nThis structure contains information that is computed by SparseHessianCompute.\nIf the sparsity pattern, row vector, or col vectors\nare not the same between calls to SparseHessianCompute,\n work.clear() must be called to reinitialize work.\n\n\\return\nIs the number of first order forward sweeps used to compute the\nrequested Hessian values.\n(This is also equal to the number of second order reverse sweeps.)\nThe total work, not counting the zero order\nforward sweep, or the time to combine computations, is proportional to this\nreturn value.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector, class SetVector, class SizeVector>\nsize_t ADFun<Base,RecBase>::SparseHessianCompute(\n   const BaseVector&           x           ,\n   const BaseVector&           w           ,\n          SetVector&            sparsity    ,\n   const SizeVector&           user_row    ,\n   const SizeVector&           user_col    ,\n          BaseVector&           hes         ,\n          sparse_hessian_work&  work        )\n{\n   using   CppAD::vectorBool;\n   size_t i, k, ell;\n\n   CppAD::vector<size_t>& row(work.row);\n   CppAD::vector<size_t>& col(work.col);\n   CppAD::vector<size_t>& color(work.color);\n   CppAD::vector<size_t>& order(work.order);\n\n   size_t n = Domain();\n\n   // some values\n   const Base zero(0);\n   const Base one(1);\n\n   // check BaseVector is Simple Vector class with Base type elements\n   CheckSimpleVector<Base, BaseVector>();\n\n   // number of components of Hessian that are required\n   size_t K = hes.size();\n   CPPAD_ASSERT_UNKNOWN( size_t( user_row.size() ) == K );\n   CPPAD_ASSERT_UNKNOWN( size_t( user_col.size() ) == K );\n\n   CPPAD_ASSERT_UNKNOWN( size_t(x.size()) == n );\n   CPPAD_ASSERT_UNKNOWN( color.size() == 0 || color.size() == n );\n   CPPAD_ASSERT_UNKNOWN( row.size() == 0   || row.size() == K );\n   CPPAD_ASSERT_UNKNOWN( col.size() == 0   || col.size() == K );\n\n\n   // Point at which we are evaluating the Hessian\n   Forward(0, x);\n\n   // check for case where nothing (except Forward above) to do\n   if( K == 0 )\n      return 0;\n\n   // Rows of the Hessian (i below) correspond to the forward mode index\n   // and columns (j below) correspond to the reverse mode index.\n   if( color.size() == 0 )\n   {\n      CPPAD_ASSERT_UNKNOWN( sparsity.n_set() ==  n );\n      CPPAD_ASSERT_UNKNOWN( sparsity.end() ==  n );\n\n      // copy user rwo and col to work space\n      row.resize(K);\n      col.resize(K);\n      for(k = 0; k < K; k++)\n      {  row[k] = user_row[k];\n         col[k] = user_col[k];\n      }\n\n      // execute coloring algorithm\n      color.resize(n);\n      if( work.color_method == \"cppad.general\" )\n         local::color_general_cppad(sparsity, row, col, color);\n      else if( work.color_method == \"cppad.symmetric\" )\n         local::color_symmetric_cppad(sparsity, row, col, color);\n      else if( work.color_method == \"colpack.general\" )\n      {\n# if CPPAD_HAS_COLPACK\n         local::color_general_colpack(sparsity, row, col, color);\n# else\n         CPPAD_ASSERT_KNOWN(\n            false,\n            \"SparseHessian: work.color_method = colpack.general \"\n            \"and colpack_prefix missing from cmake command line.\"\n         );\n# endif\n      }\n      else if(\n         work.color_method == \"colpack.symmetric\" ||\n         work.color_method == \"colpack.star\"\n      )\n      {\n# if CPPAD_HAS_COLPACK\n         local::color_symmetric_colpack(sparsity, row, col, color);\n# else\n         CPPAD_ASSERT_KNOWN(\n            false,\n            \"SparseHessian: work.color_method is \"\n            \"colpack.symmetric or colpack.star\\n\"\n            \"and colpack_prefix missing from cmake command line.\"\n         );\n# endif\n      }\n      else\n      {  CPPAD_ASSERT_KNOWN(\n            false,\n            \"SparseHessian: work.color_method is not valid.\"\n         );\n      }\n\n      // put sorting indices in color order\n      SizeVector key(K);\n      order.resize(K);\n      for(k = 0; k < K; k++)\n         key[k] = color[ row[k] ];\n      index_sort(key, order);\n\n   }\n   size_t n_color = 1;\n   for(ell = 0; ell < n; ell++) if( color[ell] < n )\n      n_color = std::max<size_t>(n_color, color[ell] + 1);\n\n   // direction vector for calls to forward (rows of the Hessian)\n   BaseVector u(n);\n\n   // location for return values from reverse (columns of the Hessian)\n   BaseVector ddw(2 * n);\n\n   // initialize the return value\n   for(k = 0; k < K; k++)\n      hes[k] = zero;\n\n   // loop over colors\n# ifndef NDEBUG\n   const std::string& coloring = work.color_method;\n# endif\n   k = 0;\n   for(ell = 0; ell < n_color; ell++)\n   if( k == K )\n   {  // kludge because colpack returns colors that are not used\n      // (it does not know about the subset corresponding to row, col)\n      CPPAD_ASSERT_UNKNOWN(\n         coloring == \"colpack.general\" ||\n         coloring == \"colpack.symmetric\" ||\n         coloring == \"colpack.star\"\n      );\n   }\n   else if( color[ row[ order[k] ] ] != ell )\n   {  // kludge because colpack returns colors that are not used\n      // (it does not know about the subset corresponding to row, col)\n      CPPAD_ASSERT_UNKNOWN(\n         coloring == \"colpack.general\" ||\n         coloring == \"colpack.symmetric\" ||\n         coloring == \"colpack.star\"\n      );\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( color[ row[ order[k] ] ] == ell );\n\n      // combine all rows with this color\n      for(i = 0; i < n; i++)\n      {  u[i] = zero;\n         if( color[i] == ell )\n            u[i] = one;\n      }\n      // call forward mode for all these rows at once\n      Forward(1, u);\n\n      // evaluate derivative of w^T * F'(x) * u\n      ddw = Reverse(2, w);\n\n      // set the corresponding components of the result\n      while( k < K && color[ row[ order[k] ] ] == ell )\n      {  hes[ order[k] ] = ddw[ col[ order[k] ] * 2 + 1 ];\n         k++;\n      }\n   }\n   return n_color;\n}\n// ===========================================================================\n// Public Member Functions\n// ===========================================================================\n/*!\nCompute user specified subset of a sparse Hessian.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   SparseHessian(x, w, p, row, col, hes, work)\n\\endverbatim\n\n\\tparam Base\nis the base type for the recording that is stored in this ADFun<Base object.\n\n\\tparam BaseVector\nis a simple vector class with elements of type Base.\n\n\\tparam SetVector\nis a simple vector class with elements of type\n bool or std::set<size_t>.\n\n\\tparam SizeVector\nis a simple vector class with elements of type size_t.\n\n\\param x [in]\nis a vector specifying the point at which to compute the Hessian.\n\n\\param w [in]\nis the weighting vector that defines a scalar valued function by\na weighted sum of the components of the vector valued function\n$latex F(x)$$.\n\n\\param p [in]\nis the sparsity pattern for the Hessian that we are calculating.\n\n\\param row [in]\nis the vector of row indices for the returned Hessian values.\n\n\\param col [in]\nis the vector of columns indices for the returned Hessian values.\nIt must have the same size are r.\n\n\\param hes [out]\nis the vector of Hessian values.\nIt must have the same size are r.\nThe return value <code>hes[k]</code> is the second partial of\n\\f$ w^{\\rm T} F(x)\\f$ with respect to the\n<code>row[k]</code> and <code>col[k]</code> component of \\f$ x\\f$.\n\n\\param work\nThis structure contains information that is computed by SparseHessianCompute.\nIf the sparsity pattern, row vector, or col vectors\nare not the same between calls to SparseHessian,\n work.clear() must be called to reinitialize work.\n\n\\return\nIs the number of first order forward sweeps used to compute the\nrequested Hessian values.\n(This is also equal to the number of second order reverse sweeps.)\nThe total work, not counting the zero order\nforward sweep, or the time to combine computations, is proportional to this\nreturn value.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector, class SetVector, class SizeVector>\nsize_t ADFun<Base,RecBase>::SparseHessian(\n   const BaseVector&     x    ,\n   const BaseVector&     w    ,\n   const SetVector&      p    ,\n   const SizeVector&     row  ,\n   const SizeVector&     col  ,\n   BaseVector&           hes  ,\n   sparse_hessian_work&  work )\n{\n   size_t n    = Domain();\n   size_t K    = hes.size();\n# ifndef NDEBUG\n   size_t k;\n   CPPAD_ASSERT_KNOWN(\n      size_t(x.size()) == n ,\n      \"SparseHessian: size of x not equal domain dimension for f.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(row.size()) == K && size_t(col.size()) == K ,\n      \"SparseHessian: either r or c does not have the same size as ehs.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      work.color.size() == 0 || work.color.size() == n,\n      \"SparseHessian: invalid value in work.\"\n   );\n   for(k = 0; k < K; k++)\n   {  CPPAD_ASSERT_KNOWN(\n         row[k] < n,\n         \"SparseHessian: invalid value in r.\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         col[k] < n,\n         \"SparseHessian: invalid value in c.\"\n      );\n   }\n   if( work.color.size() != 0 )\n      for(size_t j = 0; j < n; j++) CPPAD_ASSERT_KNOWN(\n         work.color[j] <= n,\n         \"SparseHessian: invalid value in work.\"\n   );\n# endif\n   // check for case where there is nothing to compute\n   size_t n_sweep = 0;\n   if( K == 0 )\n      return n_sweep;\n\n   typedef typename SetVector::value_type Set_type;\n   typedef typename local::sparse::internal_pattern<Set_type>::pattern_type Pattern_type;\n   Pattern_type s;\n   if( work.color.size() == 0 )\n   {  bool transpose = false;\n      const char* error_msg = \"SparseHessian: sparsity pattern\"\n      \" does not have proper row or column dimension\";\n      sparsity_user2internal(s, p, n, n, transpose, error_msg);\n   }\n   n_sweep = SparseHessianCompute(x, w, s, row, col, hes, work);\n   return n_sweep;\n}\n/*!\nCompute a sparse Hessian.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   hes = SparseHessian(x, w, p)\n\\endverbatim\n\n\n\\tparam Base\nis the base type for the recording that is stored in this\nADFun<Base object.\n\n\\tparam BaseVector\nis a simple vector class with elements of the Base.\n\n\\tparam SetVector\nis a simple vector class with elements of type\n bool or std::set<size_t>.\n\n\\param x [in]\nis a vector specifying the point at which to compute the Hessian.\n\n\\param w [in]\nThe Hessian is computed for a weighted sum of the components\nof the function corresponding to this ADFun<Base> object.\nThe argument w specifies the weights for each component.\nIt must have size equal to the range dimension for this ADFun<Base> object.\n\n\\param p [in]\nis a sparsity pattern for the Hessian.\n\n\\return\nWill be a vector of size n * n containing the Hessian of\nat the point specified by x\n(where n is the domain dimension for this ADFun<Base> object).\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector, class SetVector>\nBaseVector ADFun<Base,RecBase>::SparseHessian(\n   const BaseVector& x, const BaseVector& w, const SetVector& p\n)\n{  size_t i, j, k;\n\n   size_t n = Domain();\n   BaseVector hes(n * n);\n\n   CPPAD_ASSERT_KNOWN(\n      size_t(x.size()) == n,\n      \"SparseHessian: size of x not equal domain size for f.\"\n   );\n\n   typedef typename SetVector::value_type Set_type;\n   typedef typename local::sparse::internal_pattern<Set_type>::pattern_type Pattern_type;\n\n   // initialize the return value as zero\n   Base zero(0);\n   for(i = 0; i < n; i++)\n      for(j = 0; j < n; j++)\n         hes[i * n + j] = zero;\n\n   // arguments to SparseHessianCompute\n   Pattern_type          s;\n   CppAD::vector<size_t> row;\n   CppAD::vector<size_t> col;\n   sparse_hessian_work   work;\n   bool transpose = false;\n   const char* error_msg = \"SparseHessian: sparsity pattern\"\n   \" does not have proper row or column dimension\";\n   sparsity_user2internal(s, p, n, n, transpose, error_msg);\n   k = 0;\n   for(i = 0; i < n; i++)\n   {  typename Pattern_type::const_iterator itr(s, i);\n      j = *itr;\n      while( j != s.end() )\n      {  row.push_back(i);\n         col.push_back(j);\n         k++;\n         j = *(++itr);\n      }\n   }\n   size_t K = k;\n   BaseVector H(K);\n\n   // now we have folded this into the following case\n   SparseHessianCompute(x, w, s, row, col, H, work);\n\n   // now set the non-zero return values\n   for(k = 0; k < K; k++)\n      hes[ row[k] * n + col[k] ] = H[k];\n\n   return hes;\n}\n/*!\nCompute a sparse Hessian\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   hes = SparseHessian(x, w)\n\\endverbatim\n\n\n\\tparam Base\nis the base type for the recording that is stored in this\nADFun<Base object.\n\n\\tparam BaseVector\nis a simple vector class with elements of the Base.\n\n\\param x [in]\nis a vector specifying the point at which to compute the Hessian.\n\n\\param w [in]\nThe Hessian is computed for a weighted sum of the components\nof the function corresponding to this ADFun<Base> object.\nThe argument w specifies the weights for each component.\nIt must have size equal to the range dimension for this ADFun<Base> object.\n\n\\return\nWill be a vector of size n * n containing the Hessian of\nat the point specified by x\n(where n is the domain dimension for this ADFun<Base> object).\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector>\nBaseVector ADFun<Base,RecBase>::SparseHessian(const BaseVector &x, const BaseVector &w)\n{  size_t i, j, k;\n   typedef CppAD::vectorBool BoolVector;\n\n   size_t m = Range();\n   size_t n = Domain();\n\n   // determine the sparsity pattern p for Hessian of w^T F\n   BoolVector r(n * n);\n   for(j = 0; j < n; j++)\n   {  for(k = 0; k < n; k++)\n         r[j * n + k] = false;\n      r[j * n + j] = true;\n   }\n   ForSparseJac(n, r);\n   //\n   BoolVector s(m);\n   for(i = 0; i < m; i++)\n      s[i] = w[i] != 0;\n   BoolVector p = RevSparseHes(n, s);\n\n   // compute sparse Hessian\n   return SparseHessian(x, w, p);\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/sparse_jac.hpp",
    "content": "# ifndef CPPAD_CORE_SPARSE_JAC_HPP\n# define CPPAD_CORE_SPARSE_JAC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin sparse_jac}\n{xrst_spell\n   nr\n   rc\n   rcv\n}\n\nComputing Sparse Jacobians\n##########################\n\nSyntax\n******\n| *n_color* = *f* . ``sparse_jac_for`` (\n| |tab| *group_max* , *x* , *subset* , *pattern* , *coloring* , *work*\n| )\n| *n_color* = *f* . ``sparse_jac_rev`` (\n| |tab| *x* , *subset* , *pattern* , *coloring* , *work*\n| )\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\nfunction corresponding to *f* .\nHere *n* is the :ref:`fun_property@Domain` size,\nand *m* is the :ref:`fun_property@Range` size, or *f* .\nThe syntax above takes advantage of sparsity when computing the Jacobian\n\n.. math::\n\n   J(x) = F^{(1)} (x)\n\nIn the sparse case, this should be faster and take less memory than\n:ref:`Jacobian-name` .\nWe use the notation :math:`J_{i,j} (x)` to denote the partial of\n:math:`F_i (x)` with respect to :math:`x_j`.\n\nSizeVector\n**********\nThe type *SizeVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``size_t`` .\n\nBaseVector\n**********\nThe type *BaseVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``size_t`` .\n\nsparse_jac_for\n**************\nThis function uses first order forward mode sweeps :ref:`forward_one-name`\nto compute multiple columns of the Jacobian at the same time.\n\nsparse_jac_rev\n**************\nThis uses function first order reverse mode sweeps :ref:`reverse_one-name`\nto compute multiple rows of the Jacobian at the same time.\n\nf\n*\nThis object has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nNote that the Taylor coefficients stored in *f* are affected\nby this operation; see\n:ref:`sparse_jac@Uses Forward` below.\n\ngroup_max\n*********\nThis argument has prototype\n\n   ``size_t`` *group_max*\n\nand must be greater than zero.\nIt specifies the maximum number of colors to group during\na single forward sweep.\nIf a single color is in a group,\na single direction for of first order forward mode\n:ref:`forward_one-name` is used for each color.\nIf multiple colors are in a group,\nthe multiple direction for of first order forward mode\n:ref:`forward_dir-name` is used with one direction for each color.\nThis uses separate memory for each direction (more memory),\nbut my be significantly faster.\n\nx\n*\nThis argument has prototype\n\n   ``const`` *BaseVector* & *x*\n\nand its size is *n* .\nIt specifies the point at which to evaluate the Jacobian\n:math:`J(x)`.\n\nsubset\n******\nThis argument has prototype\n\n   ``sparse_rcv`` < *SizeVector* , *BaseVector* >& *subset*\n\nIts row size is *subset* . ``nr`` () == *m* ,\nand its column size is *subset* . ``nc`` () == *n* .\nIt specifies which elements of the Jacobian are computed.\nThe input value of its value vector\n*subset* . ``val`` () does not matter.\nUpon return it contains the value of the corresponding elements\nof the Jacobian.\nAll of the row, column pairs in *subset* must also appear in\n*pattern* ; i.e., they must be possibly non-zero.\n\npattern\n*******\nThis argument has prototype\n\n   ``const sparse_rc`` < *SizeVector* >& *pattern*\n\nIts row size is *pattern* . ``nr`` () == *m* ,\nand its column size is *pattern* . ``nc`` () == *n* .\nIt is a sparsity pattern for the Jacobian :math:`J(x)`.\nThis argument is not used (and need not satisfy any conditions),\nwhen :ref:`sparse_jac@work` is non-empty.\n\ncoloring\n********\nThe coloring algorithm determines which rows (reverse) or columns (forward)\ncan be computed during the same sweep.\nThis field has prototype\n\n   ``const std::string&`` *coloring*\n\nThis value only matters when work is empty; i.e.,\nafter the *work* constructor or *work* . ``clear`` () .\n\ncppad\n=====\nThis uses a general purpose coloring algorithm written for Cppad.\n\ncolpack\n=======\nIf :ref:`colpack_prefix-name` is specified on the\n:ref:`cmake@CMake Command` line,\nyou can set *coloring* to ``colpack`` .\nThis uses a general purpose coloring algorithm that is part of Colpack.\n\nwork\n****\nThis argument has prototype\n\n   ``sparse_jac_work&`` *work*\n\nWe refer to its initial value,\nand its value after *work* . ``clear`` () , as empty.\nIf it is empty, information is stored in *work* .\nThis can be used to reduce computation when\na future call is for the same object *f* ,\nthe same member function ``sparse_jac_for`` or ``sparse_jac_rev`` ,\nand the same subset of the Jacobian.\nIn fact, it can be used with a different *f*\nand a different *subset* provided that Jacobian sparsity pattern\nfor *f* and the sparsity pattern in *subset* are the same.\nIf any of these values change, use *work* . ``clear`` () to\nempty this structure.\n\nn_color\n*******\nThe return value *n_color* has prototype\n\n   ``size_t`` *n_color*\n\nIf ``sparse_jac_for`` (``sparse_jac_rev`` ) is used,\n*n_color* is the number of first order forward directions\nused to compute the requested Jacobian values.\nIt is also the number of colors determined by the coloring method\nmentioned above.\nThis is proportional to the total computational work,\nnot counting the zero order forward sweep,\nor combining multiple columns (rows) into a single sweep.\nNote that if *group_max*  == 1 ,\nor if we are using ``sparse_jac_rev`` ,\n*n_color* is equal to the number of sweeps.\n\nUses Forward\n************\nAfter each call to :ref:`Forward-name` ,\nthe object *f* contains the corresponding\n:ref:`Taylor coefficients<glossary@Taylor Coefficient>` .\nAfter a call to ``sparse_jac_forward`` or ``sparse_jac_rev`` ,\nthe zero order coefficients correspond to\n\n   *f* . ``Forward`` (0, *x* )\n\nAll the other forward mode coefficients are unspecified.\n\nExample\n*******\n{xrst_toc_hidden\n   example/sparse/sparse_jac_for.cpp\n   example/sparse/sparse_jac_rev.cpp\n}\nThe files :ref:`sparse_jac_for.cpp-name` and :ref:`sparse_jac_rev.cpp-name`\nare examples and tests of ``sparse_jac_for`` and ``sparse_jac_rev`` .\nThey return ``true`` , if they succeed, and ``false`` otherwise.\n\n{xrst_end sparse_jac}\n*/\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/local/sparse/internal.hpp>\n# include <cppad/local/color_general.hpp>\n# include <cppad/utility/vector.hpp>\n\n/*!\n\\file sparse_jac.hpp\nSparse Jacobian calculation routines.\n*/\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\nClass used to hold information used by Sparse Jacobian routines in this file,\nso they do not need to be recomputed every time.\n*/\nclass sparse_jac_work {\n   public:\n      /// indices that sort the user row and col arrays by color\n      CppAD::vector<size_t> order;\n      /// results of the coloring algorithm\n      CppAD::vector<size_t> color;\n      //\n      /// constructor\n      sparse_jac_work(void)\n      { }\n      /// reset work to empty.\n      /// This informs CppAD that color and order need to be recomputed\n      void clear(void)\n      {  order.clear();\n         color.clear();\n      }\n};\n// ----------------------------------------------------------------------------\n/*!\nCalculate sparse Jacobains using forward mode\n\n\\tparam Base\nthe base type for the recording that is stored in the ADFun object.\n\n\\tparam SizeVector\na simple vector class with elements of type size_t.\n\n\\tparam BaseVector\na simple vector class with elements of type Base.\n\n\\param group_max\nspecifies the maximum number of colors to group during a single forward sweep.\nThis must be greater than zero and group_max = 1 minimizes memory usage.\n\n\\param x\na vector of length n, the number of independent variables in f\n(this ADFun object).\n\n\\param subset\nspedifies the subset of the sparsity pattern where the Jacobian is evaluated.\nsubset.nr() == m,\nsubset.nc() == n.\n\n\\param pattern\nis a sparsity pattern for the Jacobian of f;\npattern.nr() == m,\npattern.nc() == n,\nwhere m is number of dependent variables in f.\n\n\\param coloring\ndetermines which coloring algorithm is used.\nThis must be cppad or colpack.\n\n\\param work\nthis structure must be empty, or contain the information stored\nby a previous call to sparse_jac_for.\nThe previous call must be for the same ADFun object f\nand the same subset.\n\n\\return\nThis is the number of first order forward sweeps used to compute\nthe Jacobian.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class SizeVector, class BaseVector>\nsize_t ADFun<Base,RecBase>::sparse_jac_for(\n   size_t                               group_max  ,\n   const BaseVector&                    x          ,\n   sparse_rcv<SizeVector, BaseVector>&  subset     ,\n   const sparse_rc<SizeVector>&         pattern    ,\n   const std::string&                   coloring   ,\n   sparse_jac_work&                     work       )\n{  size_t m = Range();\n   size_t n = Domain();\n   //\n   CPPAD_ASSERT_KNOWN(\n      subset.nr() == m,\n      \"sparse_jac_for: subset.nr() not equal range dimension for f\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      subset.nc() == n,\n      \"sparse_jac_for: subset.nc() not equal domain dimension for f\"\n   );\n   //\n   // row and column vectors in subset\n   const SizeVector& row( subset.row() );\n   const SizeVector& col( subset.col() );\n   //\n   vector<size_t>& color(work.color);\n   vector<size_t>& order(work.order);\n   CPPAD_ASSERT_KNOWN(\n      color.size() == 0 || color.size() == n,\n      \"sparse_jac_for: work is non-empty and conditions have changed\"\n   );\n   //\n   // point at which we are evaluating the Jacobian\n   Forward(0, x);\n   //\n   // number of elements in the subset\n   size_t K = subset.nnz();\n   //\n   // check for case were there is nothing to do\n   // (except for call to Forward(0, x)\n   if( K == 0 )\n      return 0;\n   //\n   // check for case where input work is empty\n   if( color.size() == 0 )\n   {  // compute work color and order vectors\n      CPPAD_ASSERT_KNOWN(\n         pattern.nr() == m,\n         \"sparse_jac_for: pattern.nr() not equal range dimension for f\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         pattern.nc() == n,\n         \"sparse_jac_for: pattern.nc() not equal domain dimension for f\"\n      );\n      //\n      // convert pattern to an internal version of its transpose\n      local::pod_vector<size_t> internal_index(n);\n      for(size_t j = 0; j < n; j++)\n         internal_index[j] = j;\n      bool transpose   = true;\n      bool zero_empty  = false;\n      bool input_empty = true;\n      local::sparse::list_setvec pattern_transpose;\n      pattern_transpose.resize(n, m);\n      local::sparse::set_internal_pattern(zero_empty, input_empty,\n         transpose, internal_index, pattern_transpose, pattern\n      );\n      //\n      // execute coloring algorithm\n      // (we are using transpose because coloring groups rows, not columns).\n      color.resize(n);\n      if( coloring == \"cppad\" )\n         local::color_general_cppad(pattern_transpose, col, row, color);\n      else if( coloring == \"colpack\" )\n      {\n# if CPPAD_HAS_COLPACK\n         local::color_general_colpack(pattern_transpose, col, row, color);\n# else\n         CPPAD_ASSERT_KNOWN(\n            false,\n            \"sparse_jac_for: coloring = colpack \"\n            \"and colpack_prefix missing from cmake command line.\"\n         );\n# endif\n      }\n      else CPPAD_ASSERT_KNOWN(\n         false,\n         \"sparse_jac_for: coloring is not valid.\"\n      );\n      //\n      // put sorting indices in color order\n      SizeVector key(K);\n      order.resize(K);\n      for(size_t k = 0; k < K; k++)\n         key[k] = color[ col[k] ];\n      index_sort(key, order);\n   }\n   // Base versions of zero and one\n   Base one(1.0);\n   Base zero(0.0);\n   //\n   size_t n_color = 1;\n   for(size_t j = 0; j < n; j++) if( color[j] < n )\n      n_color = std::max<size_t>(n_color, color[j] + 1);\n   //\n   // initialize the return Jacobian values as zero\n   for(size_t k = 0; k < K; k++)\n      subset.set(k, zero);\n   //\n   // index in subset\n   size_t k = 0;\n   // number of colors computed so far\n   size_t color_count = 0;\n   //\n   while( color_count < n_color )\n   {  // number of colors that will be in this group\n      size_t group_size = std::min<size_t>(group_max, n_color - color_count);\n      //\n      // forward mode values for independent and dependent variables\n      BaseVector dx(n * group_size), dy(m * group_size);\n      //\n      // set dx\n      for(size_t ell = 0; ell < group_size; ell++)\n      {  // combine all columns with this color\n         for(size_t j = 0; j < n; j++)\n         {  dx[j * group_size + ell] = zero;\n            if( color[j] == ell + color_count )\n               dx[j * group_size + ell] = one;\n         }\n      }\n      if( group_size == 1 )\n         dy = Forward(1, dx);\n      else\n         dy = Forward(1, group_size, dx);\n      //\n      // store results in subset\n      for(size_t ell = 0; ell < group_size; ell++)\n      {  // color with index ell + color_count is in this group\n         while(k < K && color[ col[ order[k] ] ] == ell + color_count )\n         {  // subset element with index order[k] is included in this color\n            size_t r = row[ order[k] ];\n            subset.set( order[k], dy[ r * group_size + ell ] );\n            ++k;\n         }\n      }\n      // advance color count\n      color_count += group_size;\n   }\n   CPPAD_ASSERT_UNKNOWN( color_count == n_color );\n   //\n   return n_color;\n}\n// ----------------------------------------------------------------------------\n/*!\nCalculate sparse Jacobains using reverse mode\n\n\\tparam Base\nthe base type for the recording that is stored in the ADFun object.\n\n\\tparam SizeVector\na simple vector class with elements of type size_t.\n\n\\tparam BaseVector\na simple vector class with elements of type Base.\n\n\\param x\na vector of length n, the number of independent variables in f\n(this ADFun object).\n\n\\param subset\nspedifies the subset of the sparsity pattern where the Jacobian is evaluated.\nsubset.nr() == m,\nsubset.nc() == n.\n\n\\param pattern\nis a sparsity pattern for the Jacobian of f;\npattern.nr() == m,\npattern.nc() == n,\nwhere m is number of dependent variables in f.\n\n\\param coloring\ndetermines which coloring algorithm is used.\nThis must be cppad or colpack.\n\n\\param work\nthis structure must be empty, or contain the information stored\nby a previous call to sparse_jac_rev.\nThe previous call must be for the same ADFun object f\nand the same subset.\n\n\\return\nThis is the number of first order reverse sweeps used to compute\nthe Jacobian.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class SizeVector, class BaseVector>\nsize_t ADFun<Base,RecBase>::sparse_jac_rev(\n   const BaseVector&                    x        ,\n   sparse_rcv<SizeVector, BaseVector>&  subset   ,\n   const sparse_rc<SizeVector>&         pattern  ,\n   const std::string&                   coloring ,\n   sparse_jac_work&                     work     )\n{  size_t m = Range();\n   size_t n = Domain();\n   //\n   CPPAD_ASSERT_KNOWN(\n      subset.nr() == m,\n      \"sparse_jac_rev: subset.nr() not equal range dimension for f\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      subset.nc() == n,\n      \"sparse_jac_rev: subset.nc() not equal domain dimension for f\"\n   );\n   //\n   // row and column vectors in subset\n   const SizeVector& row( subset.row() );\n   const SizeVector& col( subset.col() );\n   //\n   vector<size_t>& color(work.color);\n   vector<size_t>& order(work.order);\n   CPPAD_ASSERT_KNOWN(\n      color.size() == 0 || color.size() == m,\n      \"sparse_jac_rev: work is non-empty and conditions have changed\"\n   );\n   //\n   // point at which we are evaluating the Jacobian\n   Forward(0, x);\n   //\n   // number of elements in the subset\n   size_t K = subset.nnz();\n   //\n   // check for case were there is nothing to do\n   // (except for call to Forward(0, x)\n   if( K == 0 )\n      return 0;\n   //\n   // check for case where input work is empty\n   if( color.size() == 0 )\n   {  // compute work color and order vectors\n      CPPAD_ASSERT_KNOWN(\n         pattern.nr() == m,\n         \"sparse_jac_rev: pattern.nr() not equal range dimension for f\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         pattern.nc() == n,\n         \"sparse_jac_rev: pattern.nc() not equal domain dimension for f\"\n      );\n      //\n      // convert pattern to an internal version\n      local::pod_vector<size_t> internal_index(m);\n      for(size_t i = 0; i < m; i++)\n         internal_index[i] = i;\n      bool transpose   = false;\n      bool zero_empty  = false;\n      bool input_empty = true;\n      local::sparse::list_setvec internal_pattern;\n      internal_pattern.resize(m, n);\n      local::sparse::set_internal_pattern(zero_empty, input_empty,\n         transpose, internal_index, internal_pattern, pattern\n      );\n      //\n      // execute coloring algorithm\n      color.resize(m);\n      if( coloring == \"cppad\" )\n         local::color_general_cppad(internal_pattern, row, col, color);\n      else if( coloring == \"colpack\" )\n      {\n# if CPPAD_HAS_COLPACK\n         local::color_general_colpack(internal_pattern, row, col, color);\n# else\n         CPPAD_ASSERT_KNOWN(\n            false,\n            \"sparse_jac_rev: coloring = colpack \"\n            \"and colpack_prefix missing from cmake command line.\"\n         );\n# endif\n      }\n      else CPPAD_ASSERT_KNOWN(\n         false,\n         \"sparse_jac_rev: coloring is not valid.\"\n      );\n      //\n      // put sorting indices in color order\n      SizeVector key(K);\n      order.resize(K);\n      for(size_t k = 0; k < K; k++)\n         key[k] = color[ row[k] ];\n      index_sort(key, order);\n   }\n   // Base versions of zero and one\n   Base one(1.0);\n   Base zero(0.0);\n   //\n   size_t n_color = 1;\n   for(size_t i = 0; i < m; i++) if( color[i] < m )\n      n_color = std::max<size_t>(n_color, color[i] + 1);\n   //\n   // initialize the return Jacobian values as zero\n   for(size_t k = 0; k < K; k++)\n      subset.set(k, zero);\n   //\n   // weighting vector and return values for calls to Reverse\n   BaseVector w(m), dw(n);\n   //\n   // loop over colors\n   size_t k = 0;\n   for(size_t ell = 0; ell < n_color; ell++)\n   if( k  == K )\n   {  // kludge because colpack returns colors that are not used\n      // (it does not know about the subset corresponding to row, col)\n      CPPAD_ASSERT_UNKNOWN( coloring == \"colpack\" );\n   }\n   else if( color[ row[ order[k] ] ] != ell )\n   {  // kludge because colpack returns colors that are not used\n      // (it does not know about the subset corresponding to row, col)\n      CPPAD_ASSERT_UNKNOWN( coloring == \"colpack\" );\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( color[ row[ order[k] ] ] == ell );\n      //\n      // combine all rows with this color\n      for(size_t i = 0; i < m; i++)\n      {  w[i] = zero;\n         if( color[i] == ell )\n            w[i] = one;\n      }\n      // call reverse mode for all these rows at once\n      dw = Reverse(1, w);\n      //\n      // set the corresponding components of the result\n      while( k < K && color[ row[order[k]] ] == ell )\n      {  subset.set(order[k], dw[col[order[k]]] );\n         k++;\n      }\n   }\n   return n_color;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/sparse_jacobian.hpp",
    "content": "# ifndef CPPAD_CORE_SPARSE_JACOBIAN_HPP\n# define CPPAD_CORE_SPARSE_JACOBIAN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// maximum number of sparse directions to compute at the same time\n\n// # define CPPAD_SPARSE_JACOBIAN_MAX_MULTIPLE_DIRECTION 1\n# define CPPAD_SPARSE_JACOBIAN_MAX_MULTIPLE_DIRECTION 64\n\n/*\n{xrst_begin sparse_jacobian}\n{xrst_spell\n   valarray\n}\n\nSparse Jacobian\n###############\n\nSyntax\n******\n| *jac* = *f* . ``SparseJacobian`` ( *x* )\n| *jac* = *f* . ``SparseJacobian`` ( *x* , *p* )\n| *n_sweep* = *f* . ``SparseJacobianForward`` ( *x* , *p* , *row* , *col* , *jac* , *work* )\n| *n_sweep* = *f* . ``SparseJacobianReverse`` ( *x* , *p* , *row* , *col* , *jac* , *work* )\n\nPurpose\n*******\nWe use :math:`n` for the :ref:`fun_property@Domain` size,\nand :math:`m` for the :ref:`fun_property@Range` size of *f* .\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` do denote the\n:ref:`glossary@AD Function`\ncorresponding to *f* .\nThe syntax above sets *jac* to the Jacobian\n\n.. math::\n\n   jac = F^{(1)} (x)\n\nThis routine takes advantage of the sparsity of the Jacobian\nin order to reduce the amount of computation necessary.\nIf *row* and *col* are present, it also takes\nadvantage of the reduced set of elements of the Jacobian that\nneed to be computed.\nOne can use speed tests (e.g. :ref:`speed_test-name` )\nto verify that results are computed faster\nthan when using the routine :ref:`Jacobian-name` .\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nNote that the :ref:`ADFun-name` object *f* is not ``const``\n(see :ref:`sparse_jacobian@Uses Forward` below).\n\nx\n*\nThe argument *x* has prototype\n\n   ``const`` *BaseVector* & *x*\n\n(see :ref:`sparse_jacobian@BaseVector` below)\nand its size\nmust be equal to *n* , the dimension of the\n:ref:`fun_property@Domain` space for *f* .\nIt specifies\nthat point at which to evaluate the Jacobian.\n\np\n*\nThe argument *p* is optional and has prototype\n\n   ``const`` *SetVector* & *p*\n\n(see :ref:`sparse_jacobian@SetVector` below).\nIf it has elements of type ``bool`` ,\nits size is :math:`m * n`.\nIf it has elements of type ``std::set<size_t>`` ,\nits size is :math:`m` and all its set elements are between\nzero and :math:`n - 1`.\nIt specifies a\n:ref:`glossary@Sparsity Pattern`\nfor the Jacobian :math:`F^{(1)} (x)`.\n\nIf this sparsity pattern does not change between calls to\n``SparseJacobian`` , it should be faster to calculate *p* once\n(using :ref:`ForSparseJac-name` or :ref:`RevSparseJac-name` )\nand then pass *p* to ``SparseJacobian`` .\nFurthermore, if you specify *work* in the calling sequence,\nit is not necessary to keep the sparsity pattern; see the heading\n:ref:`sparse_jacobian@work@p` under the *work* description.\n\nIn addition,\nif you specify *p* , CppAD will use the same\ntype of sparsity representation\n(vectors of ``bool`` or vectors of ``std::set<size_t>`` )\nfor its internal calculations.\nOtherwise, the representation\nfor the internal calculations is unspecified.\n\nrow, col\n********\nThe arguments *row* and *col* are optional and have prototype\n\n| |tab| ``const`` *SizeVector* & *row*\n| |tab| ``const`` *SizeVector* & *col*\n\n(see :ref:`sparse_jacobian@SizeVector` below).\nThey specify which rows and columns of :math:`F^{(1)} (x)` are\ncomputes and in what order.\nNot all the non-zero entries in :math:`F^{(1)} (x)` need be computed,\nbut all the entries specified by *row* and *col*\nmust be possibly non-zero in the sparsity pattern.\nWe use :math:`K` to denote the value *jac* . ``size`` ()\nwhich must also equal the size of *row* and *col* .\nFurthermore,\nfor :math:`k = 0 , \\ldots , K-1`, it must hold that\n:math:`row[k] < m` and :math:`col[k] < n`.\n\njac\n***\nThe result *jac* has prototype\n\n   *BaseVector* & *jac*\n\nIn the case where the arguments *row* and *col* are not present,\nthe size of *jac* is :math:`m * n` and\nfor :math:`i = 0 , \\ldots , m-1`,\n:math:`j = 0 , \\ldots , n-1`,\n\n.. math::\n\n   jac [ i * n + j ] = \\D{ F_i }{ x_j } (x)\n\nIn the case where the arguments *row* and *col* are present,\nwe use :math:`K` to denote the size of *jac* .\nThe input value of its elements does not matter.\nUpon return, for :math:`k = 0 , \\ldots , K - 1`,\n\n.. math::\n\n   jac [ k ] = \\D{ F_i }{ x_j } (x)\n   \\; , \\;\n   \\; {\\rm where} \\;\n   i = row[k]\n   \\; {\\rm and } \\;\n   j = col[k]\n\nwork\n****\nIf this argument is present, it has prototype\n\n   ``sparse_jacobian_work&`` *work*\n\nThis object can only be used with the routines\n``SparseJacobianForward`` and ``SparseJacobianReverse`` .\nDuring its the first use, information is stored in *work* .\nThis is used to reduce the work done by future calls to the same mode\n(forward or reverse),\nthe same *f* , *p* , *row* , and *col* .\nIf a future call is for a different mode,\nor any of these values have changed,\nyou must first call *work* . ``clear`` ()\nto inform CppAD that this information needs to be recomputed.\n\ncolor_method\n============\nThe coloring algorithm determines which columns (forward mode)\nor rows (reverse mode) can be computed during the same sweep.\nThis field has prototype\n\n   ``std::string`` *work* . ``color_method``\n\nand its default value (after a constructor or ``clear()`` )\nis ``\"cppad\"`` .\nIf :ref:`colpack_prefix-name` is specified on the\n:ref:`cmake@CMake Command` line,\nyou can set this method to ``\"colpack\"`` .\nThis value only matters on the first call to ``sparse_jacobian``\nthat follows the *work* constructor or a call to\n*work* . ``clear`` () .\n\np\n=\nIf *work* is present, and it is not the first call after\nits construction or a clear,\nthe sparsity pattern *p* is not used.\nThis enables one to free the sparsity pattern\nand still compute corresponding sparse Jacobians.\n\nn_sweep\n*******\nThe return value *n_sweep* has prototype\n\n   ``size_t`` *n_sweep*\n\nIf ``SparseJacobianForward`` (``SparseJacobianReverse`` ) is used,\n*n_sweep* is the number of first order forward (reverse) sweeps\nused to compute the requested Jacobian values.\n(This is also the number of colors determined by the coloring method\nmentioned above).\nThis is proportional to the total work that ``SparseJacobian`` does,\nnot counting the zero order forward sweep,\nor the work to combine multiple columns (rows) into a single sweep.\n\nBaseVector\n**********\nThe type *BaseVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n*Base* .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nSetVector\n*********\nThe type *SetVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``bool`` or ``std::set<size_t>`` ;\nsee :ref:`glossary@Sparsity Pattern` for a discussion\nof the difference.\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nRestrictions\n============\nIf *SetVector* has elements of ``std::set<size_t>`` ,\nthen *p* [ *i* ] must return a reference (not a copy) to the\ncorresponding set.\nAccording to section 26.3.2.3 of the 1998 C++ standard,\n``std::valarray< std::set<size_t> >`` does not satisfy\nthis condition.\n\nSizeVector\n**********\nThe type *SizeVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``size_t`` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nUses Forward\n************\nAfter each call to :ref:`Forward-name` ,\nthe object *f* contains the corresponding\n:ref:`Taylor coefficients<glossary@Taylor Coefficient>` .\nAfter a call to any of the sparse Jacobian routines,\nthe zero order Taylor coefficients correspond to\n*f* . ``Forward`` (0, *x* )\nand the other coefficients are unspecified.\n\nAfter ``SparseJacobian`` ,\nthe previous calls to :ref:`Forward-name` are undefined.\n\nExample\n*******\n{xrst_toc_hidden\n   example/sparse/sparse_jacobian.cpp\n}\nThe routine\n:ref:`sparse_jacobian.cpp-name`\nis examples and tests of ``sparse_jacobian`` .\nIt return ``true`` , if it succeeds and ``false`` otherwise.\n\n{xrst_end sparse_jacobian}\n==============================================================================\n*/\n# include <cppad/local/std_set.hpp>\n# include <cppad/local/color_general.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file sparse_jacobian.hpp\nSparse Jacobian driver routine and helper functions.\n*/\n// ===========================================================================\n/*!\nclass used by SparseJacobian to hold information so it does not need to be\nrecomputed.\n*/\nclass sparse_jacobian_work {\n   public:\n      /// Coloring method: \"cppad\", or \"colpack\"\n      /// (this field is set by user)\n      std::string color_method;\n      /// indices that sort the user row and col arrays by color\n      CppAD::vector<size_t> order;\n      /// results of the coloring algorithm\n      CppAD::vector<size_t> color;\n\n      /// constructor\n      sparse_jacobian_work(void) : color_method(\"cppad\")\n      { }\n      /// reset coloring method to its default and\n      /// inform CppAD that color and order need to be recomputed\n      void clear(void)\n      {  color_method = \"cppad\";\n         order.clear();\n         color.clear();\n      }\n};\n// ===========================================================================\n/*!\nPrivate helper function forward mode cases\n\n\\tparam Base\nis the base type for the recording that is stored in this\n<code>ADFun<Base></code> object.\n\n\\tparam BaseVector\nis a simple vector class with elements of type Base.\n\n\\tparam SetVector\nis either sparse_pack or sparse_list.\n\n\\tparam SizeVector\nis a simple vector class with elements of type size_t.\n\n\\param x [in]\nis a vector specifying the point at which to compute the Jacobian.\n\n\\param p_transpose [in]\nIf <code>work.color.size() != 0</code>,\nthen p_transpose is not used.\nOtherwise, it is a\nsparsity pattern for the transpose of the Jacobian of this ADFun<Base> object.\nNote that we do not change the values in p_transpose,\nbut is not const because we use its iterator facility.\n\n\\param row [in]\nis the vector of row indices for the returned Jacobian values.\n\n\\param col [in]\nis the vector of columns indices for the returned Jacobian values.\nIt must have the same size as row.\n\n\\param jac [out]\nis the vector of Jacobian values. We use K to denote the size of jac.\nThe return value <code>jac[k]</code> is the partial of the\n<code>row[k]</code> range component of the function with respect\nthe the <code>col[k]</code> domain component of its argument.\n\n\\param work\n<code>work.color_method</code> is an input. The rest of\nthis structure contains information that is computed by SparseJacobainFor.\nIf the sparsity pattern, row vector, or col vectors\nare not the same between calls to SparseJacobianFor,\n work.clear() must be called to reinitialize work.\n\n\\return\nIs the number of first order forward sweeps used to compute the\nrequested Jacobian values. The total work, not counting the zero order\nforward sweep, or the time to combine computations, is proportional to this\nreturn value.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector, class SetVector, class SizeVector>\nsize_t ADFun<Base,RecBase>::SparseJacobianFor(\n   const BaseVector&            x           ,\n          SetVector&             p_transpose ,\n   const SizeVector&            row         ,\n   const SizeVector&            col         ,\n          BaseVector&            jac         ,\n           sparse_jacobian_work& work        )\n{\n   size_t j, k, ell;\n\n   CppAD::vector<size_t>& order(work.order);\n   CppAD::vector<size_t>& color(work.color);\n\n   size_t m = Range();\n   size_t n = Domain();\n\n   // some values\n   const Base zero(0);\n   const Base one(1);\n\n   // check BaseVector is Simple Vector class with Base type elements\n   CheckSimpleVector<Base, BaseVector>();\n\n   CPPAD_ASSERT_UNKNOWN( size_t(x.size()) == n );\n   CPPAD_ASSERT_UNKNOWN( color.size() == 0 || color.size() == n );\n\n   // number of components of Jacobian that are required\n   size_t K = size_t(jac.size());\n   CPPAD_ASSERT_UNKNOWN( size_t( row.size() ) == K );\n   CPPAD_ASSERT_UNKNOWN( size_t( col.size() ) == K );\n\n   // Point at which we are evaluating the Jacobian\n   Forward(0, x);\n\n   // check for case where nothing (except Forward above) to do\n   if( K == 0 )\n      return 0;\n\n   if( color.size() == 0 )\n   {\n      CPPAD_ASSERT_UNKNOWN( p_transpose.n_set() ==  n );\n      CPPAD_ASSERT_UNKNOWN( p_transpose.end() ==  m );\n\n      // execute coloring algorithm\n      color.resize(n);\n      if( work.color_method == \"cppad\" )\n         local::color_general_cppad(p_transpose, col, row, color);\n      else if( work.color_method == \"colpack\" )\n      {\n# if CPPAD_HAS_COLPACK\n         local::color_general_colpack(p_transpose, col, row, color);\n# else\n         CPPAD_ASSERT_KNOWN(\n            false,\n            \"SparseJacobianForward: work.color_method = colpack \"\n            \"and colpack_prefix missing from cmake command line.\"\n         );\n# endif\n      }\n      else CPPAD_ASSERT_KNOWN(\n         false,\n         \"SparseJacobianForward: work.color_method is not valid.\"\n      );\n\n      // put sorting indices in color order\n      SizeVector key(K);\n      order.resize(K);\n      for(k = 0; k < K; k++)\n         key[k] = color[ col[k] ];\n      index_sort(key, order);\n   }\n   size_t n_color = 1;\n   for(j = 0; j < n; j++) if( color[j] < n )\n      n_color = std::max<size_t>(n_color, color[j] + 1);\n\n   // initialize the return value\n   for(k = 0; k < K; k++)\n      jac[k] = zero;\n\n# if CPPAD_SPARSE_JACOBIAN_MAX_MULTIPLE_DIRECTION == 1\n   // direction vector and return values for calls to forward\n   BaseVector dx(n), dy(m);\n\n   // loop over colors\n   k = 0;\n   for(ell = 0; ell < n_color; ell++)\n   {  CPPAD_ASSERT_UNKNOWN( color[ col[ order[k] ] ] == ell );\n\n      // combine all columns with this color\n      for(j = 0; j < n; j++)\n      {  dx[j] = zero;\n         if( color[j] == ell )\n            dx[j] = one;\n      }\n      // call forward mode for all these columns at once\n      dy = Forward(1, dx);\n\n      // set the corresponding components of the result\n      while( k < K && color[ col[order[k]] ] == ell )\n      {  jac[ order[k] ] = dy[row[order[k]]];\n         k++;\n      }\n   }\n# else\n   // abbreviation for this value\n   size_t max_r = CPPAD_SPARSE_JACOBIAN_MAX_MULTIPLE_DIRECTION;\n   CPPAD_ASSERT_UNKNOWN( max_r > 1 );\n\n   // count the number of colors done so far\n   size_t count_color = 0;\n   // count the sparse matrix entries done so far\n   k = 0;\n   while( count_color < n_color )\n   {  // number of colors we will do this time\n      size_t r = std::min<size_t>(max_r , n_color - count_color);\n      BaseVector dx(n * r), dy(m * r);\n\n      // loop over colors we will do this time\n      for(ell = 0; ell < r; ell++)\n      {  // combine all columns with this color\n         for(j = 0; j < n; j++)\n         {  dx[j * r + ell] = zero;\n            if( color[j] == ell + count_color )\n               dx[j * r + ell] = one;\n         }\n      }\n      size_t q           = 1;\n      dy = Forward(q, r, dx);\n\n      // store results\n      for(ell = 0; ell < r; ell++)\n      {  // set the components of the result for this color\n         while( k < K && color[ col[order[k]] ] == ell + count_color )\n         {  jac[ order[k] ] = dy[ row[order[k]] * r + ell ];\n            k++;\n         }\n      }\n      count_color += r;\n   }\n# endif\n   return n_color;\n}\n/*!\nPrivate helper function for reverse mode cases.\n\n\\tparam Base\nis the base type for the recording that is stored in this\n<code>ADFun<Base></code> object.\n\n\\tparam BaseVector\nis a simple vector class with elements of type Base.\n\n\\tparam SetVector\nis either sparse_pack or sparse_list.\n\n\\tparam SizeVector\nis a simple vector class with elements of type size_t.\n\n\\param x [in]\nis a vector specifying the point at which to compute the Jacobian.\n\n\\param p [in]\nIf <code>work.color.size() != 0</code>, then p is not used.\nOtherwise, it is a\nsparsity pattern for the Jacobian of this ADFun<Base> object.\nNote that we do not change the values in p,\nbut is not const because we use its iterator facility.\n\n\\param row [in]\nis the vector of row indices for the returned Jacobian values.\n\n\\param col [in]\nis the vector of columns indices for the returned Jacobian values.\nIt must have the same size as row.\n\n\\param jac [out]\nis the vector of Jacobian values.\nIt must have the same size as row.\nThe return value <code>jac[k]</code> is the partial of the\n<code>row[k]</code> range component of the function with respect\nthe the <code>col[k]</code> domain component of its argument.\n\n\\param work\n<code>work.color_method</code> is an input. The rest of\nThis structure contains information that is computed by SparseJacobainRev.\nIf the sparsity pattern, row vector, or col vectors\nare not the same between calls to SparseJacobianRev,\n work.clear() must be called to reinitialize work.\n\n\\return\nIs the number of first order reverse sweeps used to compute the\nreverse Jacobian values. The total work, not counting the zero order\nforward sweep, or the time to combine computations, is proportional to this\nreturn value.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector, class SetVector, class SizeVector>\nsize_t ADFun<Base,RecBase>::SparseJacobianRev(\n   const BaseVector&           x           ,\n          SetVector&            p           ,\n   const SizeVector&           row         ,\n   const SizeVector&           col         ,\n          BaseVector&           jac         ,\n          sparse_jacobian_work& work        )\n{\n   size_t i, k, ell;\n\n   CppAD::vector<size_t>& order(work.order);\n   CppAD::vector<size_t>& color(work.color);\n\n   size_t m = Range();\n   size_t n = Domain();\n\n   // some values\n   const Base zero(0);\n   const Base one(1);\n\n   // check BaseVector is Simple Vector class with Base type elements\n   CheckSimpleVector<Base, BaseVector>();\n\n   CPPAD_ASSERT_UNKNOWN( size_t(x.size()) == n );\n   CPPAD_ASSERT_UNKNOWN (color.size() == m || color.size() == 0 );\n\n   // number of components of Jacobian that are required\n   size_t K = size_t(jac.size());\n   CPPAD_ASSERT_UNKNOWN( size_t( size_t( row.size() ) ) == K );\n   CPPAD_ASSERT_UNKNOWN( size_t( size_t( col.size() ) ) == K );\n\n   // Point at which we are evaluating the Jacobian\n   Forward(0, x);\n\n   // check for case where nothing (except Forward above) to do\n   if( K == 0 )\n      return 0;\n\n   if( color.size() == 0 )\n   {\n      CPPAD_ASSERT_UNKNOWN( p.n_set() == m );\n      CPPAD_ASSERT_UNKNOWN( p.end()   == n );\n\n      // execute the coloring algorithm\n      color.resize(m);\n      if( work.color_method == \"cppad\" )\n         local::color_general_cppad(p, row, col, color);\n      else if( work.color_method == \"colpack\" )\n      {\n# if CPPAD_HAS_COLPACK\n         local::color_general_colpack(p, row, col, color);\n# else\n         CPPAD_ASSERT_KNOWN(\n            false,\n            \"SparseJacobianReverse: work.color_method = colpack \"\n            \"and colpack_prefix missing from cmake command line.\"\n         );\n# endif\n      }\n      else CPPAD_ASSERT_KNOWN(\n         false,\n         \"SparseJacobianReverse: work.color_method is not valid.\"\n      );\n\n      // put sorting indices in color order\n      SizeVector key(K);\n      order.resize(K);\n      for(k = 0; k < K; k++)\n         key[k] = color[ row[k] ];\n      index_sort(key, order);\n   }\n   size_t n_color = 1;\n   for(i = 0; i < m; i++) if( color[i] < m )\n      n_color = std::max<size_t>(n_color, color[i] + 1);\n\n   // weighting vector for calls to reverse\n   BaseVector w(m);\n\n   // location for return values from Reverse\n   BaseVector dw(n);\n\n   // initialize the return value\n   for(k = 0; k < K; k++)\n      jac[k] = zero;\n\n   // loop over colors\n   k = 0;\n   for(ell = 0; ell < n_color; ell++)\n   {  CPPAD_ASSERT_UNKNOWN( color[ row[ order[k] ] ] == ell );\n\n      // combine all the rows with this color\n      for(i = 0; i < m; i++)\n      {  w[i] = zero;\n         if( color[i] == ell )\n            w[i] = one;\n      }\n      // call reverse mode for all these rows at once\n      dw = Reverse(1, w);\n\n      // set the corresponding components of the result\n      while( k < K && color[ row[order[k]] ]  == ell )\n      {  jac[ order[k] ] = dw[col[order[k]]];\n         k++;\n      }\n   }\n   return n_color;\n}\n// ==========================================================================\n// Public Member functions\n// ==========================================================================\n/*!\nCompute user specified subset of a sparse Jacobian using forward mode.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   SparseJacobinanForward(x, p, row, col, jac, work)\n\\endverbatim\n\n\\tparam Base\nis the base type for the recording that is stored in this\n<code>ADFun<Base></code> object.\n\n\\tparam BaseVector\nis a simple vector class with elements of type Base.\n\n\\tparam SetVector\nis a simple vector class with elements of type\n bool or std::set<size_t>.\n\n\\tparam SizeVector\nis a simple vector class with elements of type size_t.\n\n\\param x [in]\nis a vector specifying the point at which to compute the Jacobian.\n\n\\param p [in]\nis the sparsity pattern for the Jacobian that we are calculating.\n\n\\param row [in]\nis the vector of row indices for the returned Jacobian values.\n\n\\param col [in]\nis the vector of columns indices for the returned Jacobian values.\nIt must have the same size as row.\n\n\\param jac [out]\nis the vector of Jacobian values.\nIt must have the same size as row.\nThe return value <code>jac[k]</code> is the partial of the\n<code>row[k]</code> range component of the function with respect\nthe the <code>col[k]</code> domain component of its argument.\n\n\\param work [in,out]\nthis structure contains information that depends on the function object,\nsparsity pattern, row vector, and col vector.\nIf they are not the same between calls to SparseJacobianForward,\n work.clear() must be called to reinitialize them.\n\n\\return\nIs the number of first order forward sweeps used to compute the\nrequested Jacobian values. The total work, not counting the zero order\nforward sweep, or the time to combine computations, is proportional to this\nreturn value.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector, class SetVector, class SizeVector>\nsize_t ADFun<Base,RecBase>::SparseJacobianForward(\n   const BaseVector&     x    ,\n   const SetVector&      p    ,\n   const SizeVector&     row  ,\n   const SizeVector&     col  ,\n   BaseVector&           jac  ,\n   sparse_jacobian_work& work )\n{\n   size_t n = Domain();\n   size_t m = Range();\n   size_t K = jac.size();\n# ifndef NDEBUG\n   size_t k;\n   CPPAD_ASSERT_KNOWN(\n      size_t(x.size()) == n ,\n      \"SparseJacobianForward: size of x not equal domain dimension for f.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(row.size()) == K && size_t(col.size()) == K ,\n      \"SparseJacobianForward: either r or c does not have \"\n      \"the same size as jac.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      work.color.size() == 0 || work.color.size() == n,\n      \"SparseJacobianForward: invalid value in work.\"\n   );\n   for(k = 0; k < K; k++)\n   {  CPPAD_ASSERT_KNOWN(\n         row[k] < m,\n         \"SparseJacobianForward: invalid value in r.\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         col[k] < n,\n         \"SparseJacobianForward: invalid value in c.\"\n      );\n   }\n   if( work.color.size() != 0 )\n      for(size_t j = 0; j < n; j++) CPPAD_ASSERT_KNOWN(\n         work.color[j] <= n,\n         \"SparseJacobianForward: invalid value in work.\"\n   );\n# endif\n   // check for case where there is nothing to compute\n   size_t n_sweep = 0;\n   if( K == 0 )\n      return n_sweep;\n\n   typedef typename SetVector::value_type Set_type;\n   typedef typename local::sparse::internal_pattern<Set_type>::pattern_type Pattern_type;\n   Pattern_type s_transpose;\n   if( work.color.size() == 0 )\n   {  bool transpose = true;\n      const char* error_msg = \"SparseJacobianForward: transposed sparsity\"\n      \" pattern does not have proper row or column dimension\";\n      sparsity_user2internal(s_transpose, p, n, m, transpose, error_msg);\n   }\n   n_sweep = SparseJacobianFor(x, s_transpose, row, col, jac, work);\n   return n_sweep;\n}\n/*!\nCompute user specified subset of a sparse Jacobian using forward mode.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   SparseJacobinanReverse(x, p, row, col, jac, work)\n\\endverbatim\n\n\\tparam Base\nis the base type for the recording that is stored in this\n<code>ADFun<Base></code> object.\n\n\\tparam BaseVector\nis a simple vector class with elements of type Base.\n\n\\tparam SetVector\nis a simple vector class with elements of type\n bool or std::set<size_t>.\n\n\\tparam SizeVector\nis a simple vector class with elements of type size_t.\n\n\\param x [in]\nis a vector specifying the point at which to compute the Jacobian.\n\n\\param p [in]\nis the sparsity pattern for the Jacobian that we are calculating.\n\n\\param row [in]\nis the vector of row indices for the returned Jacobian values.\n\n\\param col [in]\nis the vector of columns indices for the returned Jacobian values.\nIt must have the same size as row.\n\n\\param jac [out]\nis the vector of Jacobian values.\nIt must have the same size as row.\nThe return value <code>jac[k]</code> is the partial of the\n<code>row[k]</code> range component of the function with respect\nthe the <code>col[k]</code> domain component of its argument.\n\n\\param work [in,out]\nthis structure contains information that depends on the function object,\nsparsity pattern, row vector, and col vector.\nIf they are not the same between calls to SparseJacobianReverse,\n work.clear() must be called to reinitialize them.\n\n\\return\nIs the number of first order reverse sweeps used to compute the\nreverse Jacobian values. The total work, not counting the zero order\nforward sweep, or the time to combine computations, is proportional to this\nreturn value.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector, class SetVector, class SizeVector>\nsize_t ADFun<Base,RecBase>::SparseJacobianReverse(\n   const BaseVector&     x    ,\n   const SetVector&      p    ,\n   const SizeVector&     row  ,\n   const SizeVector&     col  ,\n   BaseVector&           jac  ,\n   sparse_jacobian_work& work )\n{\n   size_t m = Range();\n   size_t n = Domain();\n   size_t K = jac.size();\n# ifndef NDEBUG\n   size_t k;\n   CPPAD_ASSERT_KNOWN(\n      size_t(x.size()) == n ,\n      \"SparseJacobianReverse: size of x not equal domain dimension for f.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(row.size()) == K && size_t(col.size()) == K ,\n      \"SparseJacobianReverse: either r or c does not have \"\n      \"the same size as jac.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      work.color.size() == 0 || work.color.size() == m,\n      \"SparseJacobianReverse: invalid value in work.\"\n   );\n   for(k = 0; k < K; k++)\n   {  CPPAD_ASSERT_KNOWN(\n         row[k] < m,\n         \"SparseJacobianReverse: invalid value in r.\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         col[k] < n,\n         \"SparseJacobianReverse: invalid value in c.\"\n      );\n   }\n   if( work.color.size() != 0 )\n      for(size_t i = 0; i < m; i++) CPPAD_ASSERT_KNOWN(\n         work.color[i] <= m,\n         \"SparseJacobianReverse: invalid value in work.\"\n   );\n# endif\n   // check for case where there is nothing to compute\n   size_t n_sweep = 0;\n   if( K == 0 )\n      return n_sweep;\n\n   typedef typename SetVector::value_type Set_type;\n   typedef typename local::sparse::internal_pattern<Set_type>::pattern_type Pattern_type;\n   Pattern_type s;\n   if( work.color.size() == 0 )\n   {  bool transpose = false;\n      const char* error_msg = \"SparseJacobianReverse: sparsity\"\n      \" pattern does not have proper row or column dimension\";\n      sparsity_user2internal(s, p, m, n, transpose, error_msg);\n   }\n   n_sweep = SparseJacobianRev(x, s, row, col, jac, work);\n   return n_sweep;\n}\n/*!\nCompute a sparse Jacobian.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   jac = SparseJacobian(x, p)\n\\endverbatim\n\n\\tparam Base\nis the base type for the recording that is stored in this\n<code>ADFun<Base></code> object.\n\n\\tparam BaseVector\nis a simple vector class with elements of type Base.\n\n\\tparam SetVector\nis a simple vector class with elements of type\n bool or std::set<size_t>.\n\n\\param x [in]\nis a vector specifying the point at which to compute the Jacobian.\n\n\\param p [in]\nis the sparsity pattern for the Jacobian that we are calculating.\n\n\\return\nWill be a vector if size m * n containing the Jacobian at the\nspecified point (in row major order).\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector, class SetVector>\nBaseVector ADFun<Base,RecBase>::SparseJacobian(\n   const BaseVector& x, const SetVector& p\n)\n{  size_t i, j, k;\n\n   size_t m = Range();\n   size_t n = Domain();\n   BaseVector jac(m * n);\n\n   CPPAD_ASSERT_KNOWN(\n      size_t(x.size()) == n,\n      \"SparseJacobian: size of x not equal domain size for f.\"\n   );\n   CheckSimpleVector<Base, BaseVector>();\n\n   typedef typename SetVector::value_type Set_type;\n   typedef typename local::sparse::internal_pattern<Set_type>::pattern_type Pattern_type;\n\n   // initialize the return value as zero\n   Base zero(0);\n   for(i = 0; i < m; i++)\n      for(j = 0; j < n; j++)\n         jac[i * n + j] = zero;\n\n   sparse_jacobian_work work;\n   CppAD::vector<size_t> row;\n   CppAD::vector<size_t> col;\n   if( n <= m )\n   {\n      // need an internal copy of sparsity pattern\n      Pattern_type s_transpose;\n      bool transpose = true;\n      const char* error_msg = \"SparseJacobian: transposed sparsity\"\n      \" pattern does not have proper row or column dimension\";\n      sparsity_user2internal(s_transpose, p, n, m, transpose, error_msg);\n\n      k = 0;\n      for(j = 0; j < n; j++)\n      {  typename Pattern_type::const_iterator itr(s_transpose, j);\n         i = *itr;\n         while( i != s_transpose.end() )\n         {  row.push_back(i);\n            col.push_back(j);\n            k++;\n            i = *(++itr);\n         }\n      }\n      size_t K = k;\n      BaseVector J(K);\n\n      // now we have folded this into the following case\n      SparseJacobianFor(x, s_transpose, row, col, J, work);\n\n      // now set the non-zero return values\n      for(k = 0; k < K; k++)\n         jac[ row[k] * n + col[k] ] = J[k];\n   }\n   else\n   {\n      // need an internal copy of sparsity pattern\n      Pattern_type s;\n      bool transpose = false;\n      const char* error_msg = \"SparseJacobian: sparsity\"\n      \" pattern does not have proper row or column dimension\";\n      sparsity_user2internal(s, p, m, n, transpose, error_msg);\n\n      k = 0;\n      for(i = 0; i < m; i++)\n      {  typename Pattern_type::const_iterator itr(s, i);\n         j = *itr;\n         while( j != s.end() )\n         {  row.push_back(i);\n            col.push_back(j);\n            k++;\n            j = *(++itr);\n         }\n      }\n      size_t K = k;\n      BaseVector J(K);\n\n      // now we have folded this into the following case\n      SparseJacobianRev(x, s, row, col, J, work);\n\n      // now set the non-zero return values\n      for(k = 0; k < K; k++)\n         jac[ row[k] * n + col[k] ] = J[k];\n   }\n\n   return jac;\n}\n\n/*!\nCompute a sparse Jacobian.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   jac = SparseJacobian(x)\n\\endverbatim\n\n\\tparam Base\nis the base type for the recording that is stored in this\n<code>ADFun<Base></code> object.\n\n\\tparam BaseVector\nis a simple vector class with elements of the Base.\n\n\\param x [in]\nis a vector specifying the point at which to compute the Jacobian.\n\n\\return\nWill be a vector of size m * n containing the Jacobian at the\nspecified point (in row major order).\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector>\nBaseVector ADFun<Base,RecBase>::SparseJacobian( const BaseVector& x )\n{  typedef CppAD::vectorBool   BoolVector;\n\n   size_t m = Range();\n   size_t n = Domain();\n\n   // sparsity pattern for Jacobian\n   BoolVector p(m * n);\n\n   if( n <= m )\n   {  size_t j, k;\n\n      // use forward mode\n      BoolVector r(n * n);\n      for(j = 0; j < n; j++)\n      {  for(k = 0; k < n; k++)\n            r[j * n + k] = false;\n         r[j * n + j] = true;\n      }\n      p = ForSparseJac(n, r);\n   }\n   else\n   {  size_t i, k;\n\n      // use reverse mode\n      BoolVector s(m * m);\n      for(i = 0; i < m; i++)\n      {  for(k = 0; k < m; k++)\n            s[i * m + k] = false;\n         s[i * m + i] = true;\n      }\n      p = RevSparseJac(m, s);\n   }\n   return SparseJacobian(x, p);\n}\n\n} // END_CPPAD_NAMESPACE\n# undef CPPAD_SPARSE_JACOBIAN_MAX_MULTIPLE_DIRECTION\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/standard_math.hpp",
    "content": "# ifndef CPPAD_CORE_STANDARD_MATH_HPP\n# define CPPAD_CORE_STANDARD_MATH_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin unary_standard_math}\n{xrst_spell\n   acosh\n   asinh\n   expm\n}\n\nThe Unary Standard Math Functions\n#################################\n\nSyntax\n******\n| *y* = *fun* ( *x* )\n\nPurpose\n*******\nEvaluates the standard math function *fun* .\n\nPossible Types\n**************\n\nBase\n====\nIf *Base* satisfies the\n:ref:`base type requirements<base_require-name>`\nand argument *x* has prototype\n\n   ``const`` *Base* & *x*\n\nthen the result *y* has prototype\n\n   *Base* *y*\n\nAD<Base>\n========\nIf the argument *x* has prototype\n\n   ``const AD`` < *Base* >& *x*\n\nthen the result *y* has prototype\n\n   ``AD`` < *Base* > *y*\n\nVecAD<Base>\n===========\nIf the argument *x* has prototype\n\n   ``const VecAD`` < *Base* >:: ``reference&`` *x*\n\nthen the result *y* has prototype\n\n   ``AD`` < *Base* > *y*\n\n{xrst_toc_hidden\n   include/cppad/core/std_math_11.hpp\n   include/cppad/core/abs.hpp\n   include/cppad/core/sign.hpp\n}\n\nfun\n***\nThe possible values for *fun* are\n\n.. csv-table::\n   :widths: auto\n\n   *fun*,Description\n   abs,:ref:`abs-title`\n   acos,:ref:`acos-title`\n   acosh,:ref:`acosh-title`\n   asin,:ref:`asin-title`\n   asinh,:ref:`asinh-title`\n   atan,:ref:`atan-title`\n   atanh,:ref:`atanh-title`\n   cos,:ref:`cos-title`\n   cosh,:ref:`cosh-title`\n   erf,:ref:`erf-title`\n   exp,:ref:`exp-title`\n   expm1,:ref:`expm1-title`\n   :ref:`fabs<abs-name>` :ref:`abs-title`\n   log10,:ref:`log10-title`\n   log1p,:ref:`log1p-title`\n   log,:ref:`log-title`\n   sign,:ref:`sign-title`\n   sin,:ref:`sin-title`\n   sinh,:ref:`sinh-title`\n   sqrt,:ref:`sqrt-title`\n   tan,:ref:`tan-title`\n   tanh,:ref:`tanh-title`\n\n{xrst_end unary_standard_math}\n*/\n# include <cppad/core/abs.hpp>\n# include <cppad/core/sign.hpp>\n\n/*\n{xrst_begin binary_math}\n\nThe Binary Math Functions\n#########################\n\nContents\n********\n{xrst_toc_table\n   include/cppad/core/atan2.hpp\n   include/cppad/core/pow.hpp\n   include/cppad/core/azmul.hpp\n}\n\n{xrst_end binary_math}\n*/\n# include <cppad/core/atan2.hpp>\n# include <cppad/core/pow.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/std_math_11.hpp",
    "content": "# ifndef CPPAD_CORE_STD_MATH_11_HPP\n# define CPPAD_CORE_STD_MATH_11_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n-------------------------------------------------------------------------------\n{xrst_begin acos}\n\nInverse Cosine Function: acos\n#############################\n\nSyntax\n******\n| *y* = ``acos`` ( *x* )\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nDerivative\n**********\n\n.. math::\n\n   \\R{acos}^{(1)} (x) = - (1 - x * x)^{-1/2}\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/acos.cpp\n}\nThe file\n:ref:`acos.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end acos}\n-------------------------------------------------------------------------------\n{xrst_begin acosh}\nThe Inverse Hyperbolic Cosine Function: acosh\n#############################################\n\nSyntax\n******\n*y* = ``acosh`` ( *x* )\n\nDescription\n***********\nThe inverse hyperbolic cosine function is defined by\n*x* == ``cosh`` ( *y* ) .\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/acosh.cpp\n}\nThe file\n:ref:`acosh.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end acosh}\n-------------------------------------------------------------------------------\n{xrst_begin asin}\n\nInverse Sine Function: asin\n###########################\n\nSyntax\n******\n*y* = ``asin`` ( *x* )\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nDerivative\n**********\n\n.. math::\n\n   \\R{asin}^{(1)} (x) = (1 - x * x)^{-1/2}\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/asin.cpp\n}\nThe file\n:ref:`asin.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end asin}\n-------------------------------------------------------------------------------\n{xrst_begin asinh}\nThe Inverse Hyperbolic Sine Function: asinh\n###########################################\n\nSyntax\n******\n*y* = ``asinh`` ( *x* )\n\nDescription\n***********\nThe inverse hyperbolic sine function is defined by\n*x* == ``sinh`` ( *y* ) .\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/asinh.cpp\n}\nThe file\n:ref:`asinh.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end asinh}\n-------------------------------------------------------------------------------\n{xrst_begin atan}\n\nInverse Tangent Function: atan\n##############################\n\nSyntax\n******\n*y* = ``atan`` ( *x* )\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nDerivative\n**********\n\n.. math::\n\n   \\R{atan}^{(1)} (x) = \\frac{1}{1 + x^2}\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/atan.cpp\n}\nThe file\n:ref:`atan.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end atan}\n-------------------------------------------------------------------------------\n{xrst_begin atanh}\nThe Inverse Hyperbolic Tangent Function: atanh\n##############################################\n\nSyntax\n******\n*y* = ``atanh`` ( *x* )\n\nDescription\n***********\nThe inverse hyperbolic tangent function is defined by\n*x* == ``tanh`` ( *y* ) .\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/atanh.cpp\n}\nThe file\n:ref:`atanh.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end atanh}\n-------------------------------------------------------------------------------\n{xrst_begin cos}\n\nThe Cosine Function: cos\n########################\n\nSyntax\n******\n*y* = ``cos`` ( *x* )\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nDerivative\n**********\n\n.. math::\n\n   \\R{cos}^{(1)} (x) = - \\sin(x)\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/cos.cpp\n}\nThe file\n:ref:`cos.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end cos}\n-------------------------------------------------------------------------------\n{xrst_begin cosh}\n\nThe Hyperbolic Cosine Function: cosh\n####################################\n\nSyntax\n******\n*y* = ``cosh`` ( *x* )\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nDerivative\n**********\n\n.. math::\n\n   \\R{cosh}^{(1)} (x) = \\sinh(x)\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/cosh.cpp\n}\nThe file\n:ref:`cosh.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end cosh}\n-------------------------------------------------------------------------------\n{xrst_begin erf}\nThe Error Function\n##################\n\nSyntax\n******\n*y* = ``erf`` ( *x* )\n\nDescription\n***********\nReturns the value of the error function which is defined by\n\n.. math::\n\n   {\\rm erf} (x) = \\frac{2}{ \\sqrt{\\pi} } \\int_0^x \\exp( - t * t ) \\; {\\bf d} t\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/erf.cpp\n}\nThe file\n:ref:`erf.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end erf}\n-------------------------------------------------------------------------------\n{xrst_begin erfc}\nThe Complementary Error Function: erfc\n######################################\n\nSyntax\n******\n*y* = ``erfc`` ( *x* )\n\nDescription\n***********\nReturns the value of the complementary error function which is defined by\n*y* == 1 ``- erf`` ( *x* ) .\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/erfc.cpp\n}\nThe file\n:ref:`erfc.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end erfc}\n-------------------------------------------------------------------------------\n{xrst_begin exp}\n\nThe Exponential Function: exp\n#############################\n\nSyntax\n******\n*y* = ``exp`` ( *x* )\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nDerivative\n**********\n\n.. math::\n\n   \\R{exp}^{(1)} (x) = \\exp(x)\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/exp.cpp\n}\nThe file\n:ref:`exp.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end exp}\n-------------------------------------------------------------------------------\n{xrst_begin expm1}\nThe Exponential Function Minus One: expm1\n#########################################\n\nSyntax\n******\n*y* = ``expm1`` ( *x* )\n\nDescription\n***********\nReturns the value of the exponential function minus one which is defined\nby *y* == ``exp`` ( *x* ) ``- 1`` .\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/expm1.cpp\n}\nThe file\n:ref:`expm1.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end expm1}\n-------------------------------------------------------------------------------\n{xrst_begin log}\n\nThe Exponential Function: log\n#############################\n\nSyntax\n******\n*y* = ``log`` ( *x* )\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nDerivative\n**********\n\n.. math::\n\n   \\R{log}^{(1)} (x) = \\frac{1}{x}\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/log.cpp\n}\nThe file\n:ref:`log.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end log}\n-------------------------------------------------------------------------------\n{xrst_begin log1p}\n\nThe Logarithm of One Plus Argument: log1p\n#########################################\n\nSyntax\n******\n*y* = ``log1p`` ( *x* )\n\nDescription\n***********\nReturns the value of the logarithm of one plus argument which is defined\nby *y* == ``log`` (1 + *x* ) .\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/log1p.cpp\n}\nThe file\n:ref:`log1p.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end log1p}\n-------------------------------------------------------------------------------\n{xrst_begin log10}\n\nThe Base 10 Logarithm Function: log10\n#####################################\n\nSyntax\n******\n*y* = ``log10`` ( *x* )\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nMethod\n******\nCppAD uses the representation\n\n.. math::\n\n   {\\rm log10} (x) = \\log(x) / \\log(10)\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/log10.cpp\n}\nThe file\n:ref:`log10.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end log10}\n-------------------------------------------------------------------------------\n{xrst_begin sin}\n\nThe Sine Function: sin\n######################\n\nSyntax\n******\n*y* = ``sin`` ( *x* )\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nDerivative\n**********\n\n.. math::\n\n   \\R{sin}^{(1)} (x) = \\cos(x)\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/sin.cpp\n}\nThe file\n:ref:`sin.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end sin}\n-------------------------------------------------------------------------------\n{xrst_begin sinh}\n\nThe Hyperbolic Sine Function: sinh\n##################################\n\nSyntax\n******\n*y* = ``sinh`` ( *x* )\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nDerivative\n**********\n\n.. math::\n\n   \\R{sinh}^{(1)} (x) = \\cosh(x)\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/sinh.cpp\n}\nThe file\n:ref:`sinh.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end sinh}\n-------------------------------------------------------------------------------\n{xrst_begin sqrt}\n\nThe Square Root Function: sqrt\n##############################\n\nSyntax\n******\n*y* = ``sqrt`` ( *x* )\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nDerivative\n**********\n\n.. math::\n\n   \\R{sqrt}^{(1)} (x) = \\frac{1}{2 \\R{sqrt} (x) }\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/sqrt.cpp\n}\nThe file\n:ref:`sqrt.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end sqrt}\n-------------------------------------------------------------------------------\n{xrst_begin tan}\n\nThe Tangent Function: tan\n#########################\n\nSyntax\n******\n*y* = ``tan`` ( *x* )\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nDerivative\n**********\n\n.. math::\n\n   \\R{tan}^{(1)} (x) = 1 + \\tan (x)^2\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/tan.cpp\n}\nThe file\n:ref:`tan.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end tan}\n-------------------------------------------------------------------------------\n{xrst_begin tanh}\n\nThe Hyperbolic Tangent Function: tanh\n#####################################\n\nSyntax\n******\n*y* = ``tanh`` ( *x* )\n\nx, y\n****\nSee the :ref:`unary_standard_math@Possible Types`\nfor a unary standard math function.\n\nAtomic\n******\nThis is an :ref:`atomic operation<glossary@Operation@Atomic>` .\n\nDerivative\n**********\n\n.. math::\n\n   \\R{tanh}^{(1)} (x) = 1 - \\tanh (x)^2\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/tanh.cpp\n}\nThe file\n:ref:`tanh.cpp-name`\ncontains an example and test of this function.\n\n{xrst_end tanh}\n-------------------------------------------------------------------------------\n*/\n\n/*!\n\\file std_math_11.hpp\nDefine AD<Base> standard math functions (using their Base versions)\n*/\n\n/*!\n\\def CPPAD_STANDARD_MATH_UNARY_AD(Name, Op)\nDefines function Name with argument type AD<Base> and tape operation Op\n\nThe macro defines the function x.Name() where x has type AD<Base>.\nIt then uses this function to define Name(x) where x has type\nAD<Base> or VecAD_reference<Base>.\n\nIf x is a variable, the tape unary operator Op is used\nto record the operation and the result is identified as corresponding\nto this operation; i.e., Name(x).taddr_ identifies the operation and\nName(x).tape_id_ identifies the tape.\n\nThis macro is used to define AD<Base> versions of\nacos, asin, atan, cos, cosh, exp, fabs, log, sin, sinh, sqrt, tan, tanh.\n*/\n\n# define CPPAD_STANDARD_MATH_UNARY_AD(Name, Op)                   \\\n   template <class Base>                                         \\\n   inline AD<Base> Name(const AD<Base> &x)                       \\\n   {  return x.Name##_me();                                     \\\n   }                                                             \\\n   template <class Base>                                         \\\n   inline AD<Base> AD<Base>::Name##_me (void) const              \\\n   {                                                             \\\n      AD<Base> result;                                          \\\n      result.value_ = CppAD::Name(value_);                      \\\n      CPPAD_ASSERT_UNKNOWN( Parameter(result) );                \\\n                                                                  \\\n      local::ADTape<Base>* tape = AD<Base>::tape_ptr();         \\\n      if( tape == nullptr )                                  \\\n         return result;                                        \\\n                                                                  \\\n      if( tape_id_ != tape->id_ )                               \\\n         return result;                                        \\\n                                                                  \\\n      if(ad_type_ == dynamic_enum)                        \\\n      {  result.taddr_ = tape->Rec_.put_dyn_par(               \\\n            result.value_, local::Name##_dyn, taddr_          \\\n         );                                                    \\\n         result.tape_id_ = tape_id_;                           \\\n         result.ad_type_ = dynamic_enum;                 \\\n      }                                                         \\\n      else                                                      \\\n      {  CPPAD_ASSERT_UNKNOWN( NumArg(Op) == 1 );              \\\n         tape->Rec_.PutArg(taddr_);                            \\\n         result.taddr_    = tape->Rec_.PutOp(Op);              \\\n         result.tape_id_  = tape->id_;                         \\\n         result.ad_type_  = variable_enum;                \\\n      }                                                         \\\n      return result;                                            \\\n   }                                                             \\\n   template <class Base>                                         \\\n   inline AD<Base> Name(const VecAD_reference<Base> &x)          \\\n   {  return x.ADBase().Name##_me(); }\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\n     CPPAD_STANDARD_MATH_UNARY_AD(acos, local::AcosOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(acosh, local::AcoshOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(asin, local::AsinOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(asinh, local::AsinhOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(atan, local::AtanOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(atanh, local::AtanhOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(cos, local::CosOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(cosh, local::CoshOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(exp, local::ExpOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(expm1, local::Expm1Op)\n     CPPAD_STANDARD_MATH_UNARY_AD(fabs, local::AbsOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(log, local::LogOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(log1p, local::Log1pOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(sin, local::SinOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(sinh, local::SinhOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(sqrt, local::SqrtOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(tan, local::TanOp)\n     CPPAD_STANDARD_MATH_UNARY_AD(tanh, local::TanhOp)\n\n\n   // Error function is a special case\n   template <class Base>\n   inline AD<Base> erf(const AD<Base> &x)\n   {  bool complement = false;\n      return x.erf_me(complement);\n   }\n   template <class Base>\n   inline AD<Base> erfc(const AD<Base> &x)\n   {  bool complement = true;\n      return x.erf_me(complement);\n   }\n   template <class Base>\n   inline AD<Base> AD<Base>::erf_me (bool complement) const\n   {\n      AD<Base> result;\n      if( complement )\n         result.value_ = CppAD::erfc(value_);\n      else\n         result.value_ = CppAD::erf(value_);\n      CPPAD_ASSERT_UNKNOWN( Parameter(result) );\n\n      // check if there is a recording in progress\n      local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n      if( tape == nullptr )\n         return result;\n\n      // check if operand is a constant parameter\n      if( tape_id_ != tape->id_ )\n         return result;\n\n      if(ad_type_ == dynamic_enum)\n      {  local::op_code_dyn op = local::erf_dyn;\n         if( complement )\n            op = local::erfc_dyn;\n\n           // dynamic parameter argument\n         result.taddr_   = tape->Rec_.put_dyn_par(\n            result.value_, op, taddr_\n         );\n         result.tape_id_  = tape_id_;\n         result.ad_type_  = dynamic_enum;\n      }\n      else\n      {  local::op_code_var op = local::ErfOp;\n         if( complement )\n            op = local::ErfcOp;\n\n           // variable argument\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(op) == 3 );\n\n         // arg[0] = argument to erf function\n         tape->Rec_.PutArg(taddr_);\n\n         // arg[1] = zero\n         addr_t p  = tape->Rec_.put_con_par( Base(0.0) );\n         tape->Rec_.PutArg(p);\n\n         // arg[2] = 2 / sqrt(pi)\n         p = tape->Rec_.put_con_par(Base(\n            1.0 / std::sqrt( std::atan(1.0) )\n         ));\n         tape->Rec_.PutArg(p);\n         //\n         result.taddr_   = tape->Rec_.PutOp(op);\n         result.tape_id_ = tape->id_;\n         result.ad_type_ = variable_enum;\n      }\n      return result;\n   }\n   template <class Base>\n   inline AD<Base> erf(const VecAD_reference<Base> &x)\n   {  bool complement = false;\n      return x.ADBase().erf_me(complement);\n   }\n   template <class Base>\n   inline AD<Base> erfc(const VecAD_reference<Base> &x)\n   {  bool complement = true;\n      return x.ADBase().erf_me(complement);\n   }\n\n     /*!\n   Compute the log of base 10 of x where  has type AD<Base>\n\n   \\tparam Base\n   is the base type (different from base for log)\n   for this AD type, see base_require.\n\n   \\param x\n   is the argument for the log10 function.\n\n   \\result\n   if the result is y, then \\f$ x = 10^y \\f$.\n   */\n     template <class Base>\n     inline AD<Base> log10(const AD<Base> &x)\n   {  return CppAD::log(x) / CppAD::log( Base(10) ); }\n     template <class Base>\n     inline AD<Base> log10(const VecAD_reference<Base> &x)\n   {  return CppAD::log(x.ADBase()) / CppAD::log( Base(10) ); }\n}\n\n# undef CPPAD_STANDARD_MATH_UNARY_AD\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/sub.hpp",
    "content": "# ifndef CPPAD_CORE_SUB_HPP\n# define CPPAD_CORE_SUB_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nAD<Base> operator - (const AD<Base> &left , const AD<Base> &right)\n{\n   // compute the Base part\n   AD<Base> result;\n   result.value_  = left.value_ - right.value_;\n   CPPAD_ASSERT_UNKNOWN( Parameter(result) );\n\n   // check if there is a recording in progress\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if left and right tapes match\n   bool match_left  = left.tape_id_  == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n\n   // check if left and right are dynamic parameters\n   bool dyn_left  = match_left  & (left.ad_type_ == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if left and right are variables\n   bool var_left  = match_left  & (left.ad_type_ != dynamic_enum);\n   bool var_right = match_right & (right.ad_type_ != dynamic_enum);\n\n\n   CPPAD_ASSERT_KNOWN(\n      left.tape_id_ == right.tape_id_ || ! match_left || ! match_right ,\n      \"Subtract: AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_left )\n   {  if( var_right )\n      {  // result = variable - variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SubvvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SubvvOp) == 2 );\n\n         // put operand addresses in tape\n         tape->Rec_.PutArg(left.taddr_, right.taddr_);\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::SubvvOp);\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n      else if( (! dyn_right) && IdenticalZero(right.value_) )\n      {  // result = variable - 0\n         result.make_variable(left.tape_id_, left.taddr_);\n      }\n      else\n      {  // result = variable - parameter\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SubvpOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SubvpOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = right.taddr_;\n         if( ! dyn_right )\n            p = tape->Rec_.put_con_par(right.value_);\n         tape->Rec_.PutArg(left.taddr_, p);\n         // put operator in the tape\n         result.taddr_ = tape->Rec_.PutOp(local::SubvpOp);\n         // make result a variable\n         result.tape_id_ = tape_id;\n         result.ad_type_ = variable_enum;\n      }\n   }\n   else if( var_right )\n   {  // result = parameter - variable\n      CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SubpvOp) == 1 );\n      CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SubpvOp) == 2 );\n\n      // put operand addresses in tape\n      addr_t p = left.taddr_;\n      if( ! dyn_left )\n         p = tape->Rec_.put_con_par(left.value_);\n      tape->Rec_.PutArg(p, right.taddr_);\n      // put operator in the tape\n      result.taddr_ = tape->Rec_.PutOp(local::SubpvOp);\n      // make result a variable\n      result.tape_id_ = tape_id;\n      result.ad_type_ = variable_enum;\n   }\n   else if( dyn_left | dyn_right )\n   {  if( (! dyn_right) && IdenticalZero(right.value_) )\n      {  // this is dynamic - 0\n         result.make_dynamic(left.tape_id_, left.taddr_);\n      }\n      else \n      {  \n         addr_t arg0 = left.taddr_;\n         addr_t arg1 = right.taddr_;\n         if( ! dyn_left )\n         arg0 = tape->Rec_.put_con_par(left.value_);\n         if( ! dyn_right )\n         arg1 = tape->Rec_.put_con_par(right.value_);\n         //\n         // parameters with a dynamic parameter result\n         result.taddr_   = tape->Rec_.put_dyn_par(\n            result.value_, local::sub_dyn,   arg0, arg1\n         );\n         result.tape_id_ = tape_id;\n         result.ad_type_ = dynamic_enum;\n      }\n   }\n   return result;\n}\n\n// convert other cases into the case above\nCPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(-)\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/sub_eq.hpp",
    "content": "# ifndef CPPAD_CORE_SUB_EQ_HPP\n# define CPPAD_CORE_SUB_EQ_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nAD<Base>& AD<Base>::operator -= (const AD<Base> &right)\n{\n   // compute the Base part\n   Base left;\n   left    = value_;\n   value_ -= right.value_;\n\n   // check if there is a recording in progress\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return *this;\n   tape_id_t tape_id = tape->id_;\n   // tape_id cannot match the default value for tape_id_; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if left and right tapes match\n   bool match_left  = tape_id_       == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n\n   // check if left and right are dynamic parameters\n   bool dyn_left  = match_left  & (ad_type_ == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if left and right are variables\n   bool var_left  = match_left  & (ad_type_ != dynamic_enum);\n   bool var_right = match_right & (right.ad_type_ != dynamic_enum);\n\n   CPPAD_ASSERT_KNOWN(\n      tape_id_ == right.tape_id_ || ! match_left || ! match_right ,\n      \"-= : AD variables or dynamic parameters on different threads.\"\n   );\n   if( var_left )\n   {  if( var_right )\n      {  // this = variable - variable\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SubvvOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SubvvOp) == 2 );\n\n         // put operand addresses in tape\n         tape->Rec_.PutArg(taddr_, right.taddr_);\n         // put operator in the tape\n         taddr_ = tape->Rec_.PutOp(local::SubvvOp);\n         // check that this is a variable\n         CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id );\n         CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum);\n      }\n      else if( (! dyn_right) && IdenticalZero(right.value_) )\n      {  // this = variable - 0\n      }\n      else\n      {  // this = variable - parameter\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SubvpOp) == 1 );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SubvpOp) == 2 );\n\n         // put operand addresses in tape\n         addr_t p = right.taddr_;\n         if( ! dyn_right )\n            p = tape->Rec_.put_con_par(right.value_);\n         tape->Rec_.PutArg(taddr_, p);\n         // put operator in the tape\n         taddr_ = tape->Rec_.PutOp(local::SubvpOp);\n         // check that this is a variable\n         CPPAD_ASSERT_UNKNOWN( tape_id_ == tape_id );\n         CPPAD_ASSERT_UNKNOWN( ad_type_ == variable_enum);\n      }\n   }\n   else if( var_right  )\n   {  // this = parameter - variable\n      CPPAD_ASSERT_UNKNOWN( local::NumRes(local::SubpvOp) == 1 );\n      CPPAD_ASSERT_UNKNOWN( local::NumArg(local::SubpvOp) == 2 );\n\n      // put operand addresses in tape\n      addr_t p = taddr_;\n      if( ! dyn_left )\n         p = tape->Rec_.put_con_par(left);\n      tape->Rec_.PutArg(p, right.taddr_);\n\n      // put operator in the tape\n      taddr_ = tape->Rec_.PutOp(local::SubpvOp);\n\n      // make this a variable\n      tape_id_ = tape_id;\n      ad_type_ = variable_enum;\n   }\n   else if( dyn_left | dyn_right )\n   {  if( (! dyn_right) && IdenticalZero(right.value_) )\n      {   // this is left -= 0, so do nothing\n      }\n      else\n      {\n         addr_t arg0 = taddr_;\n         addr_t arg1 = right.taddr_;\n         if( ! dyn_left )\n         arg0 = tape->Rec_.put_con_par(left);\n         if( ! dyn_right )\n         arg1 = tape->Rec_.put_con_par(right.value_);\n         //\n         // parameters with a dynamic parameter results\n         taddr_ = tape->Rec_.put_dyn_par(\n            value_, local::sub_dyn, arg0, arg1\n         );\n         tape_id_ = tape_id;\n         ad_type_ = dynamic_enum;\n      }\n   }\n   return *this;\n}\n\nCPPAD_FOLD_ASSIGNMENT_OPERATOR(-=)\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/subgraph_jac_rev.hpp",
    "content": "# ifndef CPPAD_CORE_SUBGRAPH_JAC_REV_HPP\n# define CPPAD_CORE_SUBGRAPH_JAC_REV_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin subgraph_jac_rev}\n{xrst_spell\n   nnz\n   nr\n   subgraphs\n}\n\nCompute Sparse Jacobians Using Subgraphs\n########################################\n\nSyntax\n******\n| *f* . ``subgraph_jac_rev`` ( *x* , *subset* )\n| *f* . ``subgraph_jac_rev`` (\n| |tab| *select_domain* , *select_range* , *x* , *matrix_out*\n| )\n\nSee Also\n********\n:ref:`subgraph_reverse@clear_subgraph` .\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\nfunction corresponding to *f* .\nHere *n* is the :ref:`fun_property@Domain` size,\nand *m* is the :ref:`fun_property@Range` size, or *f* .\nThe syntax above takes advantage of sparsity when computing the Jacobian\n\n.. math::\n\n   J(x) = F^{(1)} (x)\n\nThe  first syntax requires one to know what which elements of the Jacobian\nthey want to compute.\nThe second syntax computes the sparsity pattern and the value\nof the Jacobian at the same time.\nIf one only wants the sparsity pattern,\nit should be faster to use :ref:`subgraph_sparsity-name` .\n\nMethod\n******\nThis routine uses a subgraph technique. To be specific,\nfor each dependent variable,\nit creates a subgraph of the operation sequence\ncontaining the variables that affect the dependent variable.\nThis avoids the overhead of performing set operations\nthat is inherent in other methods for computing sparsity patterns.\n\nBaseVector\n**********\nThe type *BaseVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n*Base* .\n\nSizeVector\n**********\nThe type *SizeVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``size_t`` .\n\nBoolVector\n**********\nThe type *BoolVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``bool`` .\n\nf\n*\nThis object has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nNote that the Taylor coefficients stored in *f* are affected\nby this operation; see\n:ref:`sparse_jac@Uses Forward` below.\n\nx\n*\nThis argument has prototype\n\n   ``const`` *BaseVector* & *x*\n\nIt is the value of *x* at which we are computing the Jacobian.\n\nUses Forward\n************\nAfter each call to :ref:`Forward-name` ,\nthe object *f* contains the corresponding\n:ref:`Taylor coefficients<glossary@Taylor Coefficient>` .\nAfter a call to ``sparse_jac_forward`` or ``sparse_jac_rev`` ,\nthe zero order coefficients correspond to\n\n   *f* . ``Forward`` (0, *x* )\n\nAll the other forward mode coefficients are unspecified.\n\nsubset\n******\nThis argument has prototype\n\n   ``sparse_rcv`` < *SizeVector* , *BaseVector* >& *subset*\n\nIts row size is *subset* . ``nr`` () == *m* ,\nand its column size is *subset* . ``nc`` () == *n* .\nIt specifies which elements of the Jacobian are computed.\nThe input elements in its value vector\n*subset* . ``val`` () do not matter.\nUpon return it contains the value of the corresponding elements\nof the Jacobian.\n\nselect_domain\n*************\nThe argument *select_domain* has prototype\n\n   ``const`` *BoolVector* & *select_domain*\n\nIt has size :math:`n` and specifies which independent variables\nto include.\n\nselect_range\n************\nThe argument *select_range* has prototype\n\n   ``const`` *BoolVector* & *select_range*\n\nIt has size :math:`m` and specifies which components of the range\nto include in the calculation.\nA subgraph is built for each dependent variable and the selected set\nof independent variables.\n\nmatrix_out\n**********\nThis argument has prototype\n\n   ``sparse_rcv`` < *SizeVector* , *BaseVector* >& *matrix_out*\n\nThis input value of *matrix_out* does not matter.\nUpon return *matrix_out* is\n:ref:`sparse matrix<sparse_rcv-name>` representation of :math:`F^{(1)} (x)`.\nThe matrix has :math:`m` rows, :math:`n` columns.\nIf *select_domain* [ *j* ] is true,\n*select_range* [ *i* ] is true, and\n:math:`F_i (x)` depends on :math:`x_j`,\nthen the pair :math:`(i, j)` is in *matrix_out* .\nFor each *k* = 0 , ..., *matrix_out* . ``nnz`` () , let\n\n| |tab| *i* = *matrix_out* . ``row`` ()[ *k* ]\n| |tab| *j* = *matrix_out* . ``col`` ()[ *k* ]\n| |tab| *v* = *matrix_out* . ``val`` ()[ *k* ]\n\nIt follows that the partial of :math:`F_i (x)` with respect to\n:math:`x_j` is equal to :math:`v`.\n\nExample\n*******\n{xrst_toc_hidden\n   example/sparse/subgraph_jac_rev.cpp\n   example/sparse/subgraph_hes2jac.cpp\n}\nThe files :ref:`subgraph_jac_rev.cpp-name` and :ref:`subgraph_hes2jac.cpp-name`\nare examples and tests using ``subgraph_jac_rev`` .\nThey returns ``true`` for success and ``false`` for failure.\n\n{xrst_end subgraph_jac_rev}\n-----------------------------------------------------------------------------\n*/\n# include <cppad/core/ad_fun.hpp>\n# include <cppad/local/subgraph/info.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*!\nSubgraph sparsity patterns.\n\n\\tparam Base\nis the base type for this recording.\n\n\\tparam SizeVector\nis the simple vector with elements of type size_t that is used for\nrow, column index sparsity patterns.\n\n\\tparam BaseVector\na simple vector class with elements of type Base.\n\n\\param x\na vector of length n, the number of independent variables in f\n(this ADFun object).\n\n\\param subset\nspedifies the subset of the sparsity pattern where the Jacobian is evaluated.\nsubset.nr() == m,\nsubset.nc() == n.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class SizeVector, class BaseVector>\nvoid ADFun<Base,RecBase>::subgraph_jac_rev(\n   const BaseVector&                   x      ,\n   sparse_rcv<SizeVector, BaseVector>& subset )\n{  size_t m = Range();\n   size_t n = Domain();\n   //\n   CPPAD_ASSERT_KNOWN(\n      subset.nr() == m,\n      \"subgraph_jac_rev: subset.nr() not equal range dimension for f\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      subset.nc() == n,\n      \"subgraph_jac_rev: subset.nc() not equal domain dimension for f\"\n   );\n   //\n   // point at which we are evaluating Jacobian\n   Forward(0, x);\n   //\n   // nnz and row, column, and row_major vectors for subset\n   size_t nnz = subset.nnz();\n   const SizeVector& row( subset.row() );\n   const SizeVector& col( subset.col() );\n   SizeVector row_major = subset.row_major();\n   //\n   // determine set of independent variables\n   local::pod_vector<bool> select_domain(n);\n   for(size_t j = 0; j < n; j++)\n      select_domain[j] = false;\n   for(size_t k = 0; k < nnz; k++)\n      select_domain[ col[k] ] = true;\n   //\n   // initialize reverse mode computation on subgraphs\n   subgraph_reverse(select_domain);\n   //\n   // memory used to hold subgraph_reverse results\n   BaseVector dw;\n   SizeVector dw_col;\n   //\n   // initialize index in row_major\n   size_t k = 0;\n   Base zero(0);\n   while(k < nnz )\n   {  size_t q   = 1;\n      size_t i_dep = row[ row_major[k] ];\n      size_t i_ind = col[ row_major[k] ];\n      size_t ell   = i_dep;\n      subgraph_reverse(q, ell, dw_col, dw);\n      //\n      size_t c = 0;\n      while( i_dep == ell )\n      {  // row numbers match\n         //\n         // advance c to possible match with column i_ind\n         while( c < size_t( dw_col.size() ) && dw_col[c] < i_ind )\n            ++c;\n         //\n         // check for match with i_ind\n         if( i_ind == dw_col[c] )\n            subset.set( row_major[k], dw[i_ind] );\n         else\n            subset.set( row_major[k], zero);\n         //\n         // advance to next (i_dep, i_ind)\n         ++k;\n         if( k == nnz )\n         {  i_dep = m;\n            i_ind = n;\n         }\n         else\n         {  i_dep = row[ row_major[k] ];\n            i_ind = col[ row_major[k] ];\n         }\n      }\n   }\n   return;\n}\ntemplate <class Base, class RecBase>\ntemplate <class BoolVector, class SizeVector, class BaseVector>\nvoid ADFun<Base,RecBase>::subgraph_jac_rev(\n   const BoolVector&                   select_domain  ,\n   const BoolVector&                   select_range   ,\n   const BaseVector&                   x              ,\n   sparse_rcv<SizeVector, BaseVector>& matrix_out     )\n{  size_t m = Range();\n   size_t n = Domain();\n   //\n   // point at which we are evaluating Jacobian\n   Forward(0, x);\n   //\n   // nnz and row, column, and row_major vectors for subset\n   local::pod_vector<size_t> row_out;\n   local::pod_vector<size_t> col_out;\n   local::pod_vector_maybe<Base>   val_out;\n   //\n   // initialize reverse mode computation on subgraphs\n   subgraph_reverse(select_domain);\n   //\n   // memory used to hold subgraph_reverse results\n   BaseVector dw;\n   SizeVector col;\n   //\n   // loop through selected independent variables\n   for(size_t i = 0; i < m; ++i) if( select_range[i] )\n   {  // compute Jacobian and sparsity for this dependent variable\n      size_t q   = 1;\n      subgraph_reverse(q, i, col, dw);\n      CPPAD_ASSERT_UNKNOWN( size_t( dw.size() ) == n );\n      //\n      // offset for this dependent variable\n      size_t index = row_out.size();\n      CPPAD_ASSERT_UNKNOWN( col_out.size() == index );\n      CPPAD_ASSERT_UNKNOWN( val_out.size() == index );\n      //\n      // extend vectors to hold results for this dependent variable\n      size_t col_size = size_t( col.size() );\n      row_out.extend( col_size );\n      col_out.extend( col_size );\n      val_out.extend( col_size );\n      //\n      // store results for this dependent variable\n      for(size_t c = 0; c < col_size; ++c)\n      {  row_out[index + c] = i;\n         col_out[index + c] = col[c];\n         val_out[index + c] = dw[ col[c] ];\n      }\n   }\n   //\n   // create sparsity pattern corresponding to row_out, col_out\n   size_t nr  = m;\n   size_t nc  = n;\n   size_t nnz = row_out.size();\n   sparse_rc<SizeVector> pattern(nr, nc, nnz);\n   for(size_t k = 0; k < nnz; ++k)\n      pattern.set(k, row_out[k], col_out[k]);\n   //\n   // create sparse matrix\n   sparse_rcv<SizeVector, BaseVector> matrix(pattern);\n   for(size_t k = 0; k < nnz; ++k)\n      matrix.set(k,  val_out[k]);\n   //\n   // return matrix\n   matrix_out = matrix;\n   //\n   return;\n}\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/subgraph_reverse.hpp",
    "content": "# ifndef CPPAD_CORE_SUBGRAPH_REVERSE_HPP\n# define CPPAD_CORE_SUBGRAPH_REVERSE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin subgraph_reverse}\n{xrst_spell\n   dw\n   subgraphs\n}\n\nReverse Mode Using Subgraphs\n############################\n\nSyntax\n******\n| *f* . ``subgraph_reverse`` ( *select_domain* )\n| *f* . ``subgraph_reverse`` ( *q* , *ell* , *col* , *dw* )\n| *f* . ``clear_subgraph`` ()\n\nPurpose\n*******\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to *f* .\nReverse mode computes the derivative of the :ref:`Forward-name` mode\n:ref:`Taylor coefficients<glossary@Taylor Coefficient>`\nwith respect to the domain variable :math:`x`.\n\nNotation\n********\nWe use the reverse mode\n:ref:`reverse_any@Notation` with the following change:\nthe vector\n:ref:`reverse_any@Notation@w^(k)` is defined\n\n.. math::\n\n   w_i^{(k)} = \\left\\{ \\begin{array}{ll}\n      1 & {\\rm if} \\; k = q-1 \\; \\R{and} \\; i = \\ell\n      \\\\\n      0       & {\\rm otherwise}\n   \\end{array} \\right.\n\nBaseVector\n**********\nThe type *BaseVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n*Base* .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nBoolVector\n**********\nThe type *BoolVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``bool`` .\n\nSizeVector\n**********\nThe type *SizeVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``size_t`` .\n\nselect_domain\n*************\nThe argument *select_domain* has prototype\n\n   ``const`` *BoolVector* & *select_domain*\n\nIt has size :math:`n` and specifies which independent variables\nto include in future ``subgraph_reverse`` calculations.\nIf *select_domain* [ *j* ] is false,\nit is assumed that :math:`u^{(k)}_j = 0` for :math:`k > 0`; i.e.,\nthe *j*-th component of the Taylor coefficient for :math:`x`,\nwith order greater that zero, are zero; see\n:ref:`reverse_any@Notation@u^(k)` .\n\nq\n*\nThe argument *q* has prototype\n\n   ``size_t`` *q*\n\nand specifies the number of Taylor coefficient orders to be differentiated.\n\nell\n***\nThe argument *ell* has prototype\n\n   ``size_t`` *ell*\n\nand specifies the dependent variable index that we are computing\nthe derivatives for; i.e. :math:`\\ell`.\nThis index can only be used once per, and after, a call that selects\nthe independent variables using *select_domain* .\n\ncol\n***\nThis argument *col* has prototype\n\n   *SizeVector* *col*\n\nThe input size and value of its elements do not matter.\nThe *col* . ``resize`` member function is used to change its size\nto the number the number of possible non-zero derivative components.\nFor each *c* ,\n\n| |tab| *select_domain* [ *col* [ *c* ] ] == ``true``\n| |tab| *col* [ *c* +1] >= *col* [ *c* ]\n\nand the derivative with respect to the *j*-th independent\nvariable is possibly non-zero where\n*j* = *col* [ *c* ] .\n\ndw\n**\nThe argument *dw* has prototype\n\n   *Vector* *dw*\n\nIts input size and value does not matter.\nUpon return,\nit is a vector with size :math:`n \\times q`.\nFor :math:`c = 0 , \\ldots , %col%.size()-1`,\nand :math:`k = 0, \\ldots , q-1`,\n\n.. math::\n\n   dw[ j * q + k ] = W^{(1)} ( x )_{j,k}\n\nis the derivative of the specified Taylor coefficients w.r.t the *j*-th\nindependent variable where *j* = *col* [ *c* ] .\nNote that this corresponds to the :ref:`reverse_any-name` convention when\n:ref:`reverse_any@w` has size *m* * *q* .\n\nclear_subgraph\n**************\nCalling this routine will free memory that holds\ninformation between calls to subgraph calculations so that\nit does not need to be recalculated.\n(This memory is automatically freed when *f* is deleted.)\nYou cannot free this memory between calls that select the domain\nand corresponding calls that compute reverse mode derivatives.\nSome of this information is also used by :ref:`subgraph_sparsity-name` .\n\nExample\n*******\n{xrst_toc_hidden\n   example/sparse/subgraph_reverse.cpp\n}\nThe file\n:ref:`subgraph_reverse.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end subgraph_reverse}\n*/\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file subgraph_reverse.hpp\nCompute derivatives using reverse mode and subgraphs.\n*/\n\n/// clear all subgraph information\ntemplate <class Base, class RecBase>\nvoid ADFun<Base,RecBase>::clear_subgraph(void)\n{  play_.clear_random();\n   subgraph_info_.clear();\n   subgraph_partial_.clear();\n}\n\n/*!\nInitialize reverse mode derivative computation on subgraphs.\n\n\\param select_domain\nis a vector with size equal to the dimension of the domain for this function.\nOnly derivatives w.r.t. the components that are true will be computed.\n\n\\par subgraph_info_.map_user_op()\nIf the input size of this vector is zero,\nits value for this player (play_) is computed.\n\n\\par subgraph_info.in_subgraph_\nThis vector is initialized for a reverse mode computation on subgraphs.\n\n\\par subgraph_info.select_domain()\nThis vector is set equal to the select_domain argument.\n\n\\par subgraph_info.process_range()\nThis vector is initialized to have size Range() and its elements are false.\n*/\n\ntemplate <class Base, class RecBase>\ntemplate <class BoolVector>\nvoid ADFun<Base,RecBase>::subgraph_reverse( const BoolVector& select_domain )\n{  using local::pod_vector;\n   //\n   CPPAD_ASSERT_UNKNOWN(\n      dep_taddr_.size() == subgraph_info_.n_dep()\n   );\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( select_domain.size() ) == subgraph_info_.n_ind()\n   );\n\n   // map_user_op\n   if( subgraph_info_.map_user_op().size() == 0 )\n      subgraph_info_.set_map_user_op(&play_);\n   else\n   {  CPPAD_ASSERT_UNKNOWN( subgraph_info_.check_map_user_op(&play_) );\n   }\n   CPPAD_ASSERT_UNKNOWN(\n      subgraph_info_.map_user_op().size() == play_.num_var_op()\n   );\n\n   // initialize for reverse mode subgraph computations\n   switch( play_.address_type() )\n   {\n      case local::play::unsigned_short_enum:\n      subgraph_info_.init_rev<unsigned short>(&play_, select_domain);\n      break;\n\n      case local::play::addr_t_enum:\n      subgraph_info_.init_rev<addr_t>(&play_, select_domain);\n      break;\n\n      case local::play::size_t_enum:\n      subgraph_info_.init_rev<size_t>(&play_, select_domain);\n      break;\n\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n   }\n   CPPAD_ASSERT_UNKNOWN(\n      subgraph_info_.in_subgraph().size() == play_.num_var_op()\n   );\n\n   return;\n}\n\n\n/*!\nUse reverse mode to compute derivative of Taylor coefficients on a subgraph.\n\nThe function\n\\f$ X : {\\bf R} \\times {\\bf R}^{n \\times q} \\rightarrow {\\bf R} \\f$\nis defined by\n\\f[\nX(t , u) = \\sum_{k=0}^{q-1} u^{(k)} t^k\n\\f]\nThe function\n\\f$ Y : {\\bf R} \\times {\\bf R}^{n \\times q} \\rightarrow {\\bf R} \\f$\nis defined by\n\\f[\nY(t , u) = F[ X(t, u) ]\n\\f]\nThe function\n\\f$ W : {\\bf R}^{n \\times q} \\rightarrow {\\bf R} \\f$ is defined by\n\\f[\nW(u) = \\sum_{k=0}^{q-1} ( w^{(k)} )^{\\rm T}\n\\frac{1}{k !} \\frac{ \\partial^k } { t^k } Y(0, u)\n\\f]\n\n\\param q\nis the number of Taylor coefficient we are differentiating.\n\n\\param ell\nis the component of the range that is selected for differentiation.\n\n\\param col\nis the set of indices j = col[c] where the return value is defined.\nIf an index j is not in col, then either its derivative is zero,\nor it is not in select_domain.\n\n\\param dw\nIs a vector \\f$ dw \\f$ such that\nfor j = col[c],\n\\f$ k = 0 , \\ldots , q-1 \\f$\n\\f[\n   dw[ j * q + k ] = W^{(1)} ( x )_{j,k}\n\\f]\nwhere the matrix \\f$ x \\f$ is the value for \\f$ u \\f$\nthat corresponding to the forward mode Taylor coefficients\nfor the independent variables as specified by previous calls to Forward.\n\n\\par subgraph_info.process_range()\nThe element process_range[ell] is set to true by this operation.\n\n\\par subgraph_info.in_subgraph_\nsome of the elements of this vector are set to have value ell\n(so it can not longer be used to determine the subgraph corresponding to\nthe ell-th dependent variable).\n*/\ntemplate <class Base, class RecBase>\ntemplate <class Addr, class BaseVector, class SizeVector>\nvoid ADFun<Base,RecBase>::subgraph_reverse_helper(\n   size_t      q   ,\n   size_t      ell ,\n   SizeVector& col ,\n   BaseVector& dw  )\n{  using local::pod_vector;\n   // used to identify the RecBase type in calls to sweeps\n   RecBase not_used_rec_base(0.0);\n   //\n   // get a random iterator for this player\n   Addr not_used;\n   play_.setup_random(not_used);\n   typename local::play::const_random_iterator<Addr> random_itr =\n      play_.get_random( not_used );\n\n   // check BaseVector is Simple Vector class with Base type elements\n   CheckSimpleVector<Base, BaseVector>();\n   CPPAD_ASSERT_KNOWN(\n      q > 0,\n      \"The second argument to Reverse must be greater than zero.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      num_order_taylor_ >= q,\n      \"Less than q Taylor coefficients are currently stored\"\n      \" in this ADFun object.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      num_direction_taylor_ == 1,\n      \"reverse mode for Forward(q, r, xq) with more than one direction\"\n      \"\\n(r > 1) is not yet supported.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      ell < dep_taddr_.size(),\n      \"dependent variable index in to large for this function\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      subgraph_info_.process_range()[ell] == false,\n      \"This dependent variable index has already been processed\\n\"\n      \"after the previous subgraph_reverse(select_domain).\"\n   );\n\n   // subgraph of operators connected to dependent variable ell\n   pod_vector<addr_t> subgraph;\n   subgraph_info_.get_rev(\n      random_itr, dep_taddr_, addr_t(ell), subgraph\n   );\n\n   // Add all the atomic function call operators\n   // for calls that have first operator in the subgraph\n   local::subgraph::entire_call(random_itr, subgraph);\n\n   // First add the BeginOp and EndOp to the subgraph and then sort it\n   // sort the subgraph\n   addr_t i_op_begin_op = 0;\n   addr_t i_op_end_op   = addr_t( play_.num_var_op() - 1);\n   subgraph.push_back(i_op_begin_op);\n   subgraph.push_back(i_op_end_op);\n   std::sort( subgraph.data(), subgraph.data() + subgraph.size() );\n   CPPAD_ASSERT_UNKNOWN( subgraph[0] == i_op_begin_op );\n   CPPAD_ASSERT_UNKNOWN( subgraph[subgraph.size()-1] == i_op_end_op );\n   /*\n   // Use this printout for debugging\n   std::cout << \"{ \";\n   for(size_t k = 0; k < subgraph.size(); k++)\n   {  if( k > 0 )\n         std::cout << \", \";\n      std::cout << subgraph[k];\n   }\n   std::cout << \"}\\n\";\n   */\n\n   // initialize subgraph_partial_ matrix to zero on subgraph\n   Base zero(0);\n   subgraph_partial_.resize(num_var_tape_ * q);\n   for(size_t k = 0; k < subgraph.size(); ++k)\n   {\n      size_t               i_op = size_t( subgraph[k] );\n      local::op_code_var   op;\n      const addr_t*        arg;\n      size_t               i_var;\n      random_itr.op_info(i_op, op, arg, i_var);\n      if( NumRes(op) == 0 )\n      {  CPPAD_ASSERT_UNKNOWN(\n            op == local::AFunOp  ||\n            op == local::FunapOp ||\n            op == local::FunavOp ||\n            op == local::FunrpOp ||\n            op == local::EndOp\n         );\n      }\n      else if( op != local::BeginOp )\n      {  CPPAD_ASSERT_UNKNOWN( i_var >= NumRes(op) );\n         size_t j_var = i_var + 1 - NumRes(op);\n         for(size_t i = j_var; i <= i_var; ++i)\n         {  for(size_t j = 0; j < q; ++j)\n               subgraph_partial_[i * q + j] = zero;\n         }\n      }\n   }\n\n   // set partial to one for component we are differentiating\n   subgraph_partial_[ dep_taddr_[ell] * q + q - 1] = Base(1);\n\n   // evaluate the derivatives\n   CPPAD_ASSERT_UNKNOWN( cskip_op_.size() == play_.num_var_op() );\n   CPPAD_ASSERT_UNKNOWN( load_op2var_.size()  == play_.num_var_load() );\n   size_t n = Domain();\n   //\n   local::play::const_subgraph_iterator<Addr> subgraph_itr =\n      play_.end_subgraph(random_itr, &subgraph);\n   //\n   local::sweep::reverse(\n      num_var_tape_,\n      &play_,\n      cap_order_taylor_,\n      taylor_.data(),\n      q,\n      subgraph_partial_.data(),\n      cskip_op_.data(),\n      load_op2var_,\n      subgraph_itr,\n      not_used_rec_base\n   );\n\n   // number of non-zero in return value\n   size_t col_size       = 0;\n   size_t subgraph_index = 0;\n   CPPAD_ASSERT_UNKNOWN( subgraph[subgraph_index] == 0 );\n   // Skip BeginOp\n   ++subgraph_index;\n   while( subgraph_index < subgraph.size() )\n   {  // check for InvOp\n      if( subgraph[subgraph_index] > addr_t(n) )\n         subgraph_index = subgraph.size();\n      else\n      {  ++col_size;\n         ++subgraph_index;\n      }\n   }\n   col.resize(col_size);\n\n   // return the derivative values\n   dw.resize(n * q);\n   for(size_t c = 0; c < col_size; ++c)\n   {  size_t i_op = size_t( subgraph[c + 1] );\n      CPPAD_ASSERT_UNKNOWN( play_.GetOp(i_op) == local::InvOp );\n      //\n      size_t j = i_op - 1;\n      CPPAD_ASSERT_UNKNOWN( i_op == random_itr.var2op( ind_taddr_[j] ) );\n      //\n      // return partial for this independent variable\n      col[c] = j;\n      for(size_t k = 0; k < q; k++)\n         dw[j * q + k ] = subgraph_partial_[ind_taddr_[j] * q + k];\n   }\n   //\n   CPPAD_ASSERT_KNOWN( ! ( hasnan(dw) && check_for_nan_ ) ,\n      \"f.subgraph_reverse(dw, q, ell): dw has a nan,\\n\"\n      \"but none of f's Taylor coefficients are nan.\"\n   );\n   //\n   return;\n}\n/*!\n\\copydoc subgraph_reverse_helper\n\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BaseVector, class SizeVector>\nvoid ADFun<Base,RecBase>::subgraph_reverse(\n   size_t      q   ,\n   size_t      ell ,\n   SizeVector& col ,\n   BaseVector& dw  )\n{  using local::pod_vector;\n   //\n   // call proper version of helper function\n   switch( play_.address_type() )\n   {\n      case local::play::unsigned_short_enum:\n      subgraph_reverse_helper<unsigned short>(q, ell, col, dw);\n      break;\n\n      case local::play::addr_t_enum:\n      subgraph_reverse_helper<addr_t>(q, ell, col, dw);\n      break;\n\n      case local::play::size_t_enum:\n      subgraph_reverse_helper<size_t>(q, ell, col, dw);\n      break;\n\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n   }\n   //\n   return;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/subgraph_sparsity.hpp",
    "content": "# ifndef CPPAD_CORE_SUBGRAPH_SPARSITY_HPP\n# define CPPAD_CORE_SUBGRAPH_SPARSITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin subgraph_sparsity}\n{xrst_spell\n   rc\n   subgraphs\n}\n\nSubgraph Dependency Sparsity Patterns\n#####################################\n\nSyntax\n******\n| *f* . ``subgraph_sparsity`` (\n| |tab| *select_domain* , *select_range* , *transpose* , *pattern_out*\n| )\n\nSee Also\n********\n:ref:`subgraph_reverse@clear_subgraph` .\n\nNotation\n********\nWe use :math:`F : \\B{R}^n \\rightarrow \\B{R}^m` to denote the\n:ref:`glossary@AD Function` corresponding to\nthe operation sequence stored in *f* .\n\nMethod\n******\nThis routine uses a subgraph technique. To be specific,\nfor each dependent variable,\nit creates a subgraph of the operation sequence\ncontaining the variables that affect the dependent variable.\nThis avoids the overhead of performing set operations\nthat is inherent in other methods for computing sparsity patterns.\n\nAtomic Function\n***************\nThe sparsity calculation for\n:ref:`atomic functions<atomic_two_afun-name>` in the *f* operation sequence\nare not efficient. To be specific, each atomic function is treated as if\nall of its outputs depend on all of its inputs.\nThis may be improved upon in the future; see the\n:ref:`subgraph sparsity<wish_list@Subgraph@Sparsity>`\nwish list item.\n\nBoolVector\n**********\nThe type *BoolVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``bool`` .\n\nSizeVector\n**********\nThe type *SizeVector* is a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n``size_t`` .\n\nf\n*\nThe object *f* has prototype\n\n   ``ADFun`` < *Base* > *f*\n\nselect_domain\n*************\nThe argument *select_domain* has prototype\n\n   ``const`` *BoolVector* & *select_domain*\n\nIt has size :math:`n` and specifies which independent variables\nto include in the calculation.\nIf not all the independent variables are included in the calculation,\na forward pass on the operation sequence is used to determine which\nnodes may be in the subgraphs.\n\nselect_range\n************\nThe argument *select_range* has prototype\n\n   ``const`` *BoolVector* & *select_range*\n\nIt has size :math:`m` and specifies which components of the range\nto include in the calculation.\nA subgraph is built for each dependent variable\nand the selected set of independent variables.\n\ntranspose\n*********\nThis argument has prototype\n\n   ``bool`` *transpose*\n\nIf *transpose* it is false (true),\nupon return *pattern_out* is a sparsity pattern for\n:math:`J(x)` (:math:`J(x)^\\R{T}`) defined below.\n\npattern_out\n***********\nThis argument has prototype\n\n   ``sparse_rc`` < *SizeVector* >& *pattern_out*\n\nThis input value of *pattern_out* does not matter.\nUpon return *pattern_out* is a\n:ref:`dependency.cpp@Dependency Pattern`\nfor :math:`F(x)`.\nThe pattern has :math:`m` rows, :math:`n` columns.\nIf *select_domain* [ *j* ] is true,\n*select_range* [ *i* ] is true, and\n:math:`F_i (x)` depends on :math:`x_j`,\nthen the pair :math:`(i, j)` is in *pattern_out* .\nNot that this is also a sparsity pattern for the Jacobian\n\n.. math::\n\n   J(x) = R F^{(1)} (x) D\n\nwhere :math:`D` (:math:`R`) is the diagonal matrix corresponding\nto *select_domain* ( *select_range* ).\n\nExample\n*******\n{xrst_toc_hidden\n   example/sparse/subgraph_sparsity.cpp\n}\nThe file\n:ref:`subgraph_sparsity.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end subgraph_sparsity}\n-----------------------------------------------------------------------------\n*/\n# include <cppad/core/ad_fun.hpp>\n# include <cppad/local/subgraph/sparsity.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/*!\nSubgraph sparsity patterns.\n\n\\tparam Base\nis the base type for this recording.\n\n\\tparam SizeVector\nis the simple vector with elements of type size_t that is used for\nrow, column index sparsity patterns.\n\n\\param select_domain\nsparsity pattern for the diagonal of the square matrix D.\n\n\\param select_range\nsparsity pattern for the diagonal of the square matrix R\n\n\\param transpose\nIf true, the return is a dependency sparsity pattern for\n\\f$ D F^{(1)} (x)^T R \\f$\n\n\\param pattern_out\nThe input value does not matter.\nThe return value is a dependency sparsity pattern for  \\f$ R F^{(1)} (x) D \\f$\nwhere F is the function corresponding to the operation sequence\nand x is any argument value.\nis the sparsity pattern transposed.\n*/\ntemplate <class Base, class RecBase>\ntemplate <class BoolVector, class SizeVector>\nvoid ADFun<Base,RecBase>::subgraph_sparsity(\n   const BoolVector&            select_domain    ,\n   const BoolVector&            select_range     ,\n   bool                         transpose        ,\n   sparse_rc<SizeVector>&       pattern_out      )\n{\n   // compute the sparsity pattern in row, col\n   local::pod_vector<size_t> row;\n   local::pod_vector<size_t> col;\n\n   // create the optimized recording\n   switch( play_.address_type() )\n   {\n      case local::play::unsigned_short_enum:\n      local::subgraph::subgraph_sparsity<unsigned short>(\n         &play_,\n         subgraph_info_,\n         dep_taddr_,\n         select_domain,\n         select_range,\n         row,\n         col\n      );\n      break;\n\n      case local::play::addr_t_enum:\n      local::subgraph::subgraph_sparsity<addr_t>(\n         &play_,\n         subgraph_info_,\n         dep_taddr_,\n         select_domain,\n         select_range,\n         row,\n         col\n      );\n      break;\n\n      case local::play::size_t_enum:\n      local::subgraph::subgraph_sparsity<size_t>(\n         &play_,\n         subgraph_info_,\n         dep_taddr_,\n         select_domain,\n         select_range,\n         row,\n         col\n      );\n      break;\n\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n   }\n\n   CPPAD_ASSERT_UNKNOWN( row.size() == col.size() );\n\n   // return the sparsity pattern\n   size_t nr  = dep_taddr_.size();\n   size_t nc  = ind_taddr_.size();\n   size_t nnz = row.size();\n   if( transpose )\n   {  pattern_out.resize(nc, nr, nnz);\n      for(size_t k = 0; k < nnz; k++)\n         pattern_out.set(k, col[k], row[k]);\n   }\n   else\n   {  pattern_out.resize(nr, nc, nnz);\n      for(size_t k = 0; k < nnz; k++)\n         pattern_out.set(k, row[k], col[k]);\n   }\n   return;\n}\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/tape_link.hpp",
    "content": "# ifndef CPPAD_CORE_TAPE_LINK_HPP\n# define CPPAD_CORE_TAPE_LINK_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/define.hpp>\n# include <cppad/utility/thread_alloc.hpp>\n# include <cppad/core/cppad_assert.hpp>\n\n// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file tape_link.hpp\nRoutines that Link AD<Base> and local::ADTape<Base> Objects.\n\nThe routines that connect the AD<Base> class to the corresponding tapes\n(one for each thread).\n*/\n\n/*!\nPointer to the tape identifier for this AD<Base> class and the specific thread.\n\n\\tparam Base\nis the base type for this AD<Base> class.\n\n\\param thread\nis the thread number. The following condition must hold\n\\code\n(! thread_alloc::in_parallel()) || thread == thread_alloc::thread_num()\n\\endcode\n\n\\return\nis a pointer to the tape identifier for this thread and AD<Base> class.\n*/\ntemplate <class Base>\ntape_id_t* AD<Base>::tape_id_ptr(size_t thread)\n{  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n   static tape_id_t tape_id_table[CPPAD_MAX_NUM_THREADS];\n   CPPAD_ASSERT_UNKNOWN(\n      (! thread_alloc::in_parallel()) || thread == thread_alloc::thread_num()\n   );\n   return tape_id_table + thread;\n}\n\n/*!\nHandle for the tape for this AD<Base> class and the specific thread.\n\n\\tparam Base\nis the base type for this AD<Base> class.\n\n\n\\param thread\nis the thread number; i.e.,\n\\code\n(! thread_alloc::in_parallel()) || thread == thread_alloc::thread_num()\n\\endcode\n\n\\return\nis a handle for the tape for this AD<Base> class and the specified thread.\n*/\ntemplate <class Base>\nlocal::ADTape<Base>** AD<Base>::tape_handle(size_t thread)\n{  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n   static local::ADTape<Base>* tape_table[CPPAD_MAX_NUM_THREADS];\n   CPPAD_ASSERT_UNKNOWN(\n      (! thread_alloc::in_parallel()) || thread == thread_alloc::thread_num()\n   );\n   return tape_table + thread;\n}\n\n/*!\nPointer for the tape for this AD<Base> class and the current thread.\n\n\\code\nthread == thread_alloc::thread_num()\n\\endcode\n\n\\tparam Base\nis the base type corresponding to AD<Base> operations.\n\n\\return\nis a pointer to the tape that is currently recording AD<Base> operations\nfor the current thread.\nIf this value is nullptr, there is no tape currently\nrecording AD<Base> operations for this thread.\n*/\ntemplate <class Base>\nlocal::ADTape<Base>* AD<Base>::tape_ptr(void)\n{  size_t thread = thread_alloc::thread_num();\n   return *tape_handle(thread);\n}\n\n/*!\nPointer for the tape for this AD<Base> class and the specified tape\nidentifier.\n\n\\tparam Base\nis the base type corresponding to AD<Base> operations.\n\n\\param tape_id\nis the identifier for the tape that is currently recording\nAD<Base> operations for the current thread.\nIt must hold that the current thread is\n\\code\n   thread = size_t( tape_id % CPPAD_MAX_NUM_THREADS )\n\\endcode\nand that there is a tape recording AD<Base> operations\nfor this thread.\nIf this is not the currently executing thread,\na variable from a different thread is being recorded on the\ntape for this thread which is a user error.\n\n\\return\nis a pointer to the tape that is currently recording AD<Base> operations\nfor the current thread (and it is not nullptr).\n\n\\par Restrictions\nThis routine should only be called if there is a tape recording operations\nfor the specified thread.\n*/\ntemplate <class Base>\nlocal::ADTape<Base>* AD<Base>::tape_ptr(tape_id_t tape_id)\n{  size_t thread = size_t( tape_id % CPPAD_MAX_NUM_THREADS );\n   CPPAD_ASSERT_KNOWN(\n      thread == thread_alloc::thread_num(),\n      \"Attempt to use an AD variable with two different threads.\"\n   );\n   CPPAD_ASSERT_UNKNOWN( tape_id == *tape_id_ptr(thread) );\n   CPPAD_ASSERT_UNKNOWN( *tape_handle(thread) != nullptr );\n   return *tape_handle(thread);\n}\n\n/*!\nCreate and delete tapes that record AD<Base> operations for current thread.\n\n\\par thread\nthe current thread is given by\n\\code\nthread = thread_alloc::thread_num()\n\\endcode\n\n\\tparam Base\nis the base type corresponding to AD<Base> operations.\n\n\\param job\nThis argument determines if we are creating a new tape, or deleting an\nold one.\n\n- new_tape_manage :\nCreates and a new tape.\nIt is assumed that there is no tape recording AD<Base> operations\nfor this thread when tape_manage is called.\n\n- delete_tape_manage :\nIt is assumed that there is a tape recording AD<Base> operations\nfor this thread when tape_manage is called.\nThe value of <tt>*tape_id_ptr(thread)</tt> will be advanced by\n CPPAD_MAX_NUM_THREADS.\n\n\n\\return\n- <tt>job == new_tape_manage</tt>: a pointer to the new tape is returned.\n- <tt>job == delete_tape_manage</tt>: the value nullptr is returned.\n*/\ntemplate <class Base>\nlocal::ADTape<Base>*  AD<Base>::tape_manage(tape_manage_enum job)\n{\n   CPPAD_ASSERT_UNKNOWN(\n      job == new_tape_manage || job == delete_tape_manage\n   );\n   // thread, tape_id, and tape for this call\n   size_t                thread     = thread_alloc::thread_num();\n   tape_id_t*            tape_id_p  = tape_id_ptr(thread);\n   local::ADTape<Base>** tape_h     = tape_handle(thread);\n\n\n   // -----------------------------------------------------------------------\n   // new_tape_manage\n   if( job == new_tape_manage )\n   {\n      // tape for this thread must be null at the start\n      CPPAD_ASSERT_UNKNOWN( *tape_h  == nullptr );\n\n      // allocate separate memory to avoid false sharing\n      *tape_h = new local::ADTape<Base>();\n\n      // if tape id is zero, initialize it so that\n      // thread == tape id % CPPAD_MAX_NUM_THREADS\n      if( *tape_id_p == 0 )\n      {  size_t new_tape_id = thread + CPPAD_MAX_NUM_THREADS;\n         CPPAD_ASSERT_KNOWN(\n            size_t( std::numeric_limits<tape_id_t>::max() ) >= new_tape_id,\n            \"cppad_tape_id_type maximum value has been exceeded\"\n         );\n         *tape_id_p = static_cast<tape_id_t>( new_tape_id );\n      }\n      // make sure tape_id value is valid for this thread\n      CPPAD_ASSERT_UNKNOWN(\n         size_t( *tape_id_p % CPPAD_MAX_NUM_THREADS ) == thread\n      );\n      // set the tape_id for this tape\n      (*tape_h)->id_ = *tape_id_p;\n   }\n   // -----------------------------------------------------------------------\n   // delete_tape_manage\n   if( job == delete_tape_manage )\n   {  // delete this tape\n      CPPAD_ASSERT_UNKNOWN( *tape_h  != nullptr );\n      delete *tape_h;\n      *tape_h = nullptr;\n      //\n      // advance tape_id so that all AD<Base> variables become parameters\n      CPPAD_ASSERT_KNOWN(\n         std::numeric_limits<CPPAD_TAPE_ID_TYPE>::max()\n         - CPPAD_MAX_NUM_THREADS > *tape_id_p,\n         \"To many different tapes given the type used for \"\n         \"CPPAD_TAPE_ID_TYPE\"\n      );\n      *tape_id_p  += CPPAD_MAX_NUM_THREADS;\n   }\n   // -----------------------------------------------------------------------\n   return *tape_h;\n}\n\n/*!\nGet a pointer to tape that records AD<Base> operations for the current thread.\n\n\\tparam Base\nis the base type corresponding to AD<Base> operations.\n\n\\par thread\nThe current thread must be given by\n\\code\n   thread = this->tape_id_ % CPPAD_MAX_NUM_THREADS\n\\endcode\n\n\\return\nis a pointer to the tape that is currently recording AD<Base> operations\nfor the current thread.\nThis value must not be nullptr; i.e., there must be a tape currently\nrecording AD<Base> operations for this thread.\n*/\n\ntemplate <class Base>\nlocal::ADTape<Base> *AD<Base>::tape_this(void) const\n{\n   size_t thread = size_t( tape_id_ % CPPAD_MAX_NUM_THREADS );\n   CPPAD_ASSERT_UNKNOWN( tape_id_ == *tape_id_ptr(thread) );\n   CPPAD_ASSERT_UNKNOWN( *tape_handle(thread) != nullptr );\n   return *tape_handle(thread);\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/testvector.hpp",
    "content": "# ifndef CPPAD_CORE_TESTVECTOR_HPP\n# define CPPAD_CORE_TESTVECTOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin testvector}\n{xrst_spell\n   ublas\n}\n\nUsing The CppAD Test Vector Template Class\n##########################################\n\nSyntax\n******\n| ``CPPAD_TESTVECTOR`` ( *Scalar* )\n\nChoice\n******\nThe user can choose, during the install procedure,\nwhich template class to use in the examples and tests; see below.\nThis shows that any\n:ref:`simple vector<SimpleVector-name>` class can be used in place of\n\n   ``CPPAD_TESTVECTOR`` ( *Type* )\n\nWhen writing their own code,\nusers can choose a specific simple vector they prefer; for example,\n\n   ``CppAD::vector<`` *Type* >\n\nCppAD::vector\n*************\nIf in the :ref:`cmake@CMake Command`\nyou specify :ref:`cppad_testvector-name` to be ``cppad`` ,\n\n   # ``define CPPAD_TESTVECTOR`` ( *Scalar* ) ``CppAD::vector<`` *Scalar*  >\n\nCPPAD_CPPADVECTOR, Deprecated 2022-06-22\n========================================\nThis symbol is 1 (0) if the definition above\nis used (is not used) for ``CPPAD_TESTVECTOR`` .\n\nstd::vector\n***********\nIf in the cmake command\nyou specify *cppad_testvector* to be ``std`` ,\n\n   # ``define CPPAD_TESTVECTOR`` ( *Scalar* ) ``std::vector<`` *Scalar*  >\n\nCPPAD_STDVECTOR, Deprecated 2022-06-22\n======================================\nThis symbol is 1 (0) if the definition above\nis used (is not used) for ``CPPAD_TESTVECTOR`` .\n\nboost::numeric::ublas::vector\n*****************************\nIf in the cmake command\nyou specify *cppad_testvector* to be ``boost`` ,\n\n   # ``define CPPAD_TESTVECTOR`` ( *Scalar* ) ``boost::numeric::ublas::vector<`` *Scalar*  >\n\nCPPAD_BOOSTVECTOR, Deprecated 2022-06-22\n========================================\nThis symbol is 1 (0) if the definition above\nis used (is not used) for ``CPPAD_TESTVECTOR`` .\n\nCppAD::eigen_vector\n*******************\nIf in the cmake command\nyou specify *cppad_testvector* to be ``eigen`` ,\n\n   # ``define CPPAD_TESTVECTOR`` ( *Scalar* ) ``CppAD::eigen_vector<`` *Scalar*  >\n\nsee :ref:`cppad_eigen.hpp@eigen_vector` .\nIn this case CppAD will use the Eigen vector\nfor many of its examples and tests.\n\nCPPAD_EIGENVECTOR, Deprecated 2022-06-22\n========================================\nThis symbol is 1 (0) if the definition above\nis used (is not used) for ``CPPAD_TESTVECTOR`` .\n\n{xrst_end testvector}\n------------------------------------------------------------------------\n*/\n# include <cppad/configure.hpp>\n#\n# if CPPAD_CPPADVECTOR\n# define CPPAD_TESTVECTOR(Scalar) CppAD::vector< Scalar >\n# endif\n//\n# if CPPAD_STDVECTOR\n# include <vector>\n# define CPPAD_TESTVECTOR(Scalar) std::vector< Scalar >\n# endif\n//\n# if CPPAD_BOOSTVECTOR\n# include <boost/numeric/ublas/vector.hpp>\n# define CPPAD_TESTVECTOR(Scalar) boost::numeric::ublas::vector< Scalar >\n# endif\n//\n# if CPPAD_EIGENVECTOR\n# include <cppad/example/cppad_eigen.hpp>\n# define CPPAD_TESTVECTOR(Scalar) CppAD::eigen_vector< Scalar >\n# endif\n//\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/to_csrc.hpp",
    "content": "# ifndef CPPAD_CORE_TO_CSRC_HPP\n# define CPPAD_CORE_TO_CSRC_HPP\n\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/core/ad_fun.hpp>\n# include <cppad/local/op_code_dyn.hpp>\n# include <cppad/local/graph/cpp_graph_op.hpp>\n# include <cppad/core/graph/cpp_graph.hpp>\n# include <cppad/local/graph/csrc_writer.hpp>\n/*\n------------------------------------------------------------------------------\n{xrst_begin to_csrc}\n{xrst_spell\n   cdecl\n   declspec\n   dllimport\n   ny\n   typedef\n   underbar\n}\n\nC Source Code Corresponding to an ADFun Object\n##############################################\n\nSyntax\n******\n| *fun* . ``to_csrc`` ( *os* , *c_type* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nfun\n***\nis the :ref:`adfun-name` object.\n\nBase\n****\nis the type corresponding to this :ref:`adfun-name` object;\ni.e., its calculations are done using the type *Base* .\n\nRecBase\n*******\nin the prototype above, *RecBase* is the same type as *Base* .\n\nos\n**\nThe C source code representation of the function *fun*\nis written to *os* .\n\nc_type\n******\nThe possible values for this argument are:\n``float`` , ``double`` , or ``long_double`` .\n\nJIT Functions\n*************\n\nFunction Type\n=============\nThe function type ``jit_``\\ *c_type* is defined in the CppAD namespace as:\n\n| ``typedef int`` (* ``jit_``\\ *c_type* )(\n| |tab| ``size_t`` , ``const`` *type* * , ``size_t`` , *type* * , ``size_t`` *\n| )\n\nHere *type* is the same as *c_type* except that the\nunderbar in ``long_double`` is replaced by a space.\nIn the case of the Visual C++ compiler (``_MSC_VER`` is defined),\n``__cdecl`` and ``__declspec(dllimport)`` are added to\nthe function type definition.\n\nSyntax\n======\n| *flag* = ``cppad_jit_``\\ *function_name* (\n| |tab| *nu* , *u* , *ny* , *y* , *compare_change*\n| )\n\nA corresponding function call evaluations zero order forward mode\nfor the function *fun* and\n\n| *function_name* = *fun*\\ ``.function_name_get`` ()\n\nsee :ref:`function_name-name` .\n\n\nAtomic Callbacks\n****************\n\nFunction Type\n=============\nThe function type ``atomic_``\\ *c_type* is defined in the CppAD namespace.\n\n| ``typedef int`` (* ``atomic_`` *c_type* )(\n| |tab| ``size_t`` , ``size_t`` , ``const`` *type* * , ``size_t`` , *type* * , ``size_t`` *\n| )\n\nSyntax\n======\n| *flag* = ``cppad_atomic_``\\ *atomic_name* (\n| |tab| *call_id* , *nu* , *u* , *ny* , *y* , *compare_change*\n| )\n\nA corresponding function call evaluates zero order forward mode for the\natomic function with the specified *atomic_name* ; see\natomic_four :ref:`atomic_four_ctor@atomic_four@name` .\n\ncall_id\n*******\nThis argument is only used during atomic four function callbacks,\nin which case it is the corresponding\n:ref:`atomic_four_call@call_id` .\n\nnu\n**\nis the number of independent dynamic parameters\nplus number of independent variables for the function *fun* .\n\nu\n*\nis a C vector of size *nu* containing the independent dynamic parameters\nand independent variables.\nThe independent dynamic parameter come first as in the same order as\n:ref:`Independent@dynamic` in the call to ``Independent``\nfor this function.\nThe independent variables are in the same order as\n:ref:`Independent@x` in the call to ``Independent`` for this function.\n\nny\n**\nis the number of dependent values for this function\n(a dependent value can be a variable, dynamic parameter, or constant parameter).\n\ny\n*\nis a C vector of size *ny* .\nThis input values of its elements do not matter.\nUpon return, it contains the function value correspond to *u* .\n\ncompare_change\n**************\nThis argument is both an input and an output.\nThe number of comparison operators that change their bool result value\nis added to *compare_change* . This way, *compare_change*\ncan be used to accumulate the number of changes between multiplier calls.\n\nflag\n****\nIf this is zero, no error was detected.\nIf it is one (two), *nu* ( *ny* ) does not have its expected value.\n\nRestrictions\n************\nThe ``to_csrc`` routine is not implemented for\n:ref:`vecad-name` operations.\n{xrst_toc_hidden\n   example/jit/jit.xrst\n}\nExample\n*******\nThe section :ref:`example_jit-name` contains examples and tests\nthat use ``to_csrc`` .\n\n{xrst_end to_csrc}\n*/\n# include <cppad/local/graph/csrc_writer.hpp>\n\n# if CPPAD_C_COMPILER_MSVC_FLAGS\n# define CPPAD_FUN_TYPE __cdecl\n# define CPPAD_IMPORT   __declspec(dllimport)\n# else\n# define CPPAD_FUN_TYPE\n# define CPPAD_IMPORT\n# endif\n\n\nnamespace CppAD {\n   extern \"C\" {\n      //\n      // jit_c_type\n      CPPAD_IMPORT typedef int (CPPAD_FUN_TYPE *jit_float)(\n         size_t, const float*, size_t, float*, size_t*\n      );\n      CPPAD_IMPORT typedef int (CPPAD_FUN_TYPE *jit_double)(\n         size_t, const double*, size_t, double*, size_t*\n      );\n      CPPAD_IMPORT typedef int (CPPAD_FUN_TYPE *jit_long_double)(\n         size_t, const long double*, size_t, long double*, size_t*\n      );\n      //\n      // atomic_c_type\n      CPPAD_IMPORT typedef int (CPPAD_FUN_TYPE *atomic_float)(\n         size_t, size_t, const float*, size_t, float*, size_t*\n      );\n      CPPAD_IMPORT typedef int (CPPAD_FUN_TYPE *atomic_double)(\n         size_t, size_t, const double*, size_t, double*, size_t*\n      );\n      CPPAD_IMPORT typedef int (CPPAD_FUN_TYPE *atomic_long_double)(\n         size_t, size_t, const long double*, size_t, long double*, size_t*\n      );\n   }\n}\n\n# undef CPPAD_FUN_TYPE\n# undef CPPAD_IMPORT\n\n// BEGIN_PROTOTYPE\ntemplate <class Base, class RecBase>\nvoid CppAD::ADFun<Base,RecBase>::to_csrc(\n   std::ostream&      os     ,\n   const std::string& c_type )\n// END_PROTOTYPE\n{  //\n   // type\n# ifndef NDEBUG\n   bool ok = false;\n   ok |= c_type == \"float\";\n   ok |= c_type == \"double\";\n   ok |= c_type == \"long_double\";\n   CPPAD_ASSERT_KNOWN(ok,\n      \"f.to_csrc: c_type is not one of the following: \"\n      \"float, double, long_double\"\n      );\n# endif\n   // to_graph return values\n   cpp_graph graph_obj;\n   //\n   // graph corresponding to this function\n   to_graph(graph_obj);\n   //\n   // os\n   local::graph::csrc_writer(os, graph_obj, c_type);\n   //\n   return;\n}\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/unary_minus.hpp",
    "content": "# ifndef CPPAD_CORE_UNARY_MINUS_HPP\n# define CPPAD_CORE_UNARY_MINUS_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin unary_minus}\n\nAD Unary Minus Operator\n#######################\n\nSyntax\n******\n| *y* = ``-`` *x*\n\nPurpose\n*******\nComputes the negative of *x* .\n\nBase\n****\nThe operation in the syntax above must be supported for the case where\nthe operand is a ``const`` *Base* object.\n\nx\n*\nThe operand *x* has one of the following prototypes\n\n| |tab| ``const AD`` < *Base* >               & *x*\n| |tab| ``const VecAD`` < *Base* >:: ``reference &`` *x*\n\ny\n*\nThe result *y* has type\n\n   ``AD`` < *Base* > *y*\n\nIt is equal to the negative of the operand *x* .\n\nOperation Sequence\n******************\nThis is an AD of *Base*\n:ref:`atomic operation<glossary@Operation@Atomic>`\nand hence is part of the current\nAD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nDerivative\n**********\nIf :math:`f` is a\n:ref:`glossary@Base Function` ,\n\n.. math::\n\n   \\D{[ - f(x) ]}{x} = - \\D{f(x)}{x}\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/unary_minus.cpp\n}\nThe file\n:ref:`unary_minus.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end unary_minus}\n-------------------------------------------------------------------------------\n*/\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n//\ntemplate <class Base>\nAD<Base> AD<Base>::operator - (void) const\n{\n   // compute the Base part of this AD object\n   AD<Base> result;\n   result.value_ = - value_;\n   CPPAD_ASSERT_UNKNOWN( Parameter(result) );\n\n   // check if there is a recording in progress\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return result;\n   // tape_id cannot match the default value for tape_id; i.e., 0\n   CPPAD_ASSERT_UNKNOWN( tape->id_ > 0 );\n   //\n   if( tape->id_ != tape_id_ )\n      return result;\n   //\n   if( ad_type_ == variable_enum )\n   {  // result is a variable\n      CPPAD_ASSERT_UNKNOWN( local::NumRes(local::NegOp) == 1 );\n      CPPAD_ASSERT_UNKNOWN( local::NumRes(local::NegOp) == 1 );\n      //\n      // put operand address in the tape\n      tape->Rec_.PutArg(taddr_);\n      // put operator in the tape\n      result.taddr_ = tape->Rec_.PutOp(local::NegOp);\n      // make result a variable\n      result.tape_id_ = tape_id_;\n      result.ad_type_ = variable_enum;\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( ad_type_ == dynamic_enum );\n      addr_t arg0 = taddr_;\n      result.taddr_ = tape->Rec_.put_dyn_par(\n         result.value_, local::neg_dyn, arg0\n      );\n      result.tape_id_  = tape_id_;\n      result.ad_type_  = dynamic_enum;\n   }\n   return result;\n}\n//\ntemplate <class Base>\nAD<Base> operator - (const VecAD_reference<Base> &right)\n{  return - right.ADBase(); }\n\n}\n//  END CppAD namespace\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/unary_plus.hpp",
    "content": "# ifndef CPPAD_CORE_UNARY_PLUS_HPP\n# define CPPAD_CORE_UNARY_PLUS_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin unary_plus}\n\nAD Unary Plus Operator\n######################\n\nSyntax\n******\n| *y* = + *x*\n\nPurpose\n*******\nPerforms the unary plus operation\n(the result *y* is equal to the operand *x* ).\n\nx\n*\nThe operand *x* has one of the following prototypes\n\n| |tab| ``const AD`` < *Base* >               & *x*\n| |tab| ``const VecAD`` < *Base* >:: ``reference &`` *x*\n\ny\n*\nThe result *y* has type\n\n   ``AD`` < *Base* > *y*\n\nIt is equal to the operand *x* .\n\nOperation Sequence\n******************\nThis is an AD of *Base*\n:ref:`atomic operation<glossary@Operation@Atomic>`\nand hence is part of the current\nAD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nDerivative\n**********\nIf :math:`f` is a\n:ref:`glossary@Base Function` ,\n\n.. math::\n\n   \\D{[ + f(x) ]}{x} = \\D{f(x)}{x}\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/unary_plus.cpp\n}\nThe file\n:ref:`unary_plus.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end unary_plus}\n-------------------------------------------------------------------------------\n*/\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nAD<Base> AD<Base>::operator + (void) const\n{  AD<Base> result(*this);\n\n   return result;\n}\n\n\ntemplate <class Base>\nAD<Base> operator + (const VecAD_reference<Base> &right)\n{  return right.ADBase(); }\n\n}\n//  END CppAD namespace\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/undef.hpp",
    "content": "# ifndef CPPAD_CORE_UNDEF_HPP\n# define CPPAD_CORE_UNDEF_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n----------------------------------------------------------------------------\nPreprecessor definitions that persist after cppad/cppad.hpp is included.\nThese are part of the user API (see omh/preprocessor.omh) with some exceptions\nthat are used by the CppAD examples and tests.\n\n// BEGIN_SORT_THIS_LINE_PLUS_1\n# undef CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL used by CPPAD_USER_ATOMIC\n# undef CPPAD_ASSERT_KNOWN                   used by cppad_ipopt\n# undef CPPAD_ASSERT_UNKNOWN                 used by cppad_ipopt\n# undef CPPAD_C_COMPILER_CMD                 used by dll examples.\n# undef CPPAD_C_COMPILER_GNU_FLAGS           used by dll examples.\n# undef CPPAD_C_COMPILER_MSVC_FLAGS          used by dll examples.\n# undef CPPAD_HASH_TABLE_SIZE                used by test_more/optimize.cpp\n# undef CPPAD_HAS_COLPACK                    used by speed/cppad/sparse_*.cpp\n# undef CPPAD_LINK_FLAGS_HAS_M32             used to exclude certain tests\n# undef EIGEN_MATRIXBASE_PLUGIN              example use of Eigen with CppAD\n// END_SORT_THIS_LINE_MINUS_1\n\n// for conditional testing when implicit conversion is not present\n# undef CPPAD_DEPRECATED\n-----------------------------------------------------------------------------\n*/\n// Preprecessor definitions that do not persist. None of these are in the\n// user API.\n// BEGIN_SORT_THIS_LINE_PLUS_1\n# undef CPPAD_ASSERT_AD_TYPE\n# undef CPPAD_ASSERT_NARG_NRES\n# undef CPPAD_AZMUL\n# undef CPPAD_BOOSTVECTOR\n# undef CPPAD_COMPILER_HAS_CONVERSION_WARN\n# undef CPPAD_COND_EXP\n# undef CPPAD_COND_EXP_BASE_REL\n# undef CPPAD_COND_EXP_REL\n# undef CPPAD_CPPADVECTOR\n# undef CPPAD_DEBUG_AND_RELEASE\n# undef CPPAD_EIGENVECTOR\n# undef CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR\n# undef CPPAD_FOLD_ASSIGNMENT_OPERATOR\n# undef CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR\n# undef CPPAD_HAS_ADOLC\n# undef CPPAD_HAS_EIGEN\n# undef CPPAD_HAS_GETTIMEOFDAY\n# undef CPPAD_HAS_IPOPT\n# undef CPPAD_HAS_MKSTEMP\n# undef CPPAD_HAS_TMPNAM_S\n# undef CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\n# undef CPPAD_IS_SAME_TAPE_ADDR_TYPE_SIZE_T\n# undef CPPAD_IS_SAME_UNSIGNED_INT_SIZE_T\n# undef CPPAD_LIB_EXPORT\n# undef CPPAD_MAX_NUM_CAPACITY\n# undef CPPAD_MIN_DOUBLE_CAPACITY\n# undef CPPAD_NDEBUG_NOEXCEPT\n# undef CPPAD_NOEXCEPT\n# undef CPPAD_PADDING_BLOCK_T\n# undef CPPAD_STANDARD_MATH_UNARY_AD\n# undef CPPAD_STDVECTOR\n# undef CPPAD_TRACE_CAPACITY\n# undef CPPAD_TRACE_THREAD\n# undef CPPAD_TRACK_DEBUG\n# undef CPPAD_USER_MACRO\n# undef CPPAD_USER_MACRO_ONE\n# undef CPPAD_USER_MACRO_TWO\n# undef CPPAD_VEC_AD_COMP_ASSIGN\n# undef CPPAD_VEC_ENUM_TYPE\n// END_SORT_THIS_LINE_MINUS_1\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/user_ad.hpp",
    "content": "# ifndef CPPAD_CORE_USER_AD_HPP\n# define CPPAD_CORE_USER_AD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n---------------------------------------------------------------------------\n\n{xrst_begin AD}\n\nAD Objects\n##########\n\nPurpose\n*******\nThe sections listed below describe the operations\nthat are available to :ref:`glossary@AD of Base` objects.\nThese objects are used to :ref:`glossary@Tape`\nan AD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\nThis operation sequence can\nbe transferred to an :ref:`ADFun-name` object where it\ncan be used to evaluate the corresponding\nfunction and derivative values.\n\nBase Type Requirements\n**********************\nThe *Base* requirements are provided by the CppAD package\nfor the following base types:\n``float`` ,\n``double`` ,\n``std::complex<float>`` ,\n``std::complex<double>`` .\nOtherwise, see :ref:`base_require-name` .\n\nContents\n********\n{xrst_toc_table\n   include/cppad/core/ad_ctor.hpp\n   include/cppad/core/ad_assign.hpp\n   include/cppad/core/convert.hpp\n   include/cppad/core/ad_valued.hpp\n   include/cppad/core/bool_valued.hpp\n   include/cppad/core/vec_ad/user.xrst\n   include/cppad/base_require.hpp\n}\n\n{xrst_end AD}\n---------------------------------------------------------------------------\n*/\n\n# include <cppad/core/ad_ctor.hpp>\n# include <cppad/core/ad_assign.hpp>\n# include <cppad/core/convert.hpp>\n# include <cppad/core/vec_ad/vec_ad.hpp>\n# include <cppad/core/ad_valued.hpp>\n# include <cppad/core/bool_valued.hpp>\n# include <cppad/core/zdouble.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/value.hpp",
    "content": "# ifndef CPPAD_CORE_VALUE_HPP\n# define CPPAD_CORE_VALUE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin Value}\n\nConvert From an AD Type to its Base Type\n########################################\n\nSyntax\n******\n| *b* = ``Value`` ( *x* )\n\nSee Also\n********\n:ref:`var2par-name`\n\nPurpose\n*******\nConverts from an AD type to the corresponding\n:ref:`glossary@Base Type` .\n\nx\n*\nThe argument *x* has prototype\n\n   ``const AD`` < *Base* > & *x*\n\nb\n*\nThe return value *b* has prototype\n\n   *Base* *b*\n\nOperation Sequence\n******************\nThe result of this operation is not an\n:ref:`glossary@AD of Base` object.\nThus it will not be recorded as part of an\nAD of *Base*\n:ref:`operation sequence<glossary@Operation@Sequence>` .\n\nRestriction\n***********\nThe argument *x* must not be a\n:ref:`glossary@Variable` or\n:ref:`glossary@Parameter@Dynamic` parameter\nbecause its dependency information\nwould not be included in the ``Value`` result *b* .\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/value.cpp\n}\nThe file\n:ref:`value.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end Value}\n-------------------------------------------------------------------------------\n*/\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nBase Value(const AD<Base> &x)\n{  Base result;\n   //\n   CPPAD_ASSERT_KNOWN(\n      ! ( Variable(x) || Dynamic(x) ) ,\n      \"Value: argument is a variable or dynamic parameter\"\n   );\n   //\n   result = x.value_;\n   return result;\n}\n\n}\n//  END CppAD namespace\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/var2par.hpp",
    "content": "# ifndef CPPAD_CORE_VAR2PAR_HPP\n# define CPPAD_CORE_VAR2PAR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n------------------------------------------------------------------------------\n\n{xrst_begin Var2Par}\n\nConvert an AD Variable or Dynamic Parameter to a Constant\n#########################################################\n\nSyntax\n******\n| *y* = ``Var2Par`` ( *x* )\n\nSee Also\n********\n:ref:`value-name`\n\nPurpose\n*******\nReturns a\n:ref:`constant parameter<glossary@Parameter@Constant>` *y*\nwith the same value as *x* .\n\nx\n*\nThe argument *x* has prototype\n\n   ``const AD`` < *Base* > & ``x``\n\nThe argument *x* may be a\nvariable, dynamic parameter, or constant parameter.\n\ny\n*\nThe result *y* has prototype\n\n   ``AD`` < *Base* > & ``y``\n\nand is a constant parameter.\n\nExample\n*******\n{xrst_toc_hidden\n   example/general/var2par.cpp\n}\nThe file\n:ref:`var2par.cpp-name`\ncontains an example and test of this operation.\n\n{xrst_end Var2Par}\n------------------------------------------------------------------------------\n*/\n\n//  BEGIN CppAD namespace\nnamespace CppAD {\n\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nAD<Base> Var2Par(const AD<Base> &x)\n{  AD<Base> y(x.value_);\n   return y;\n}\n\n\ntemplate <class Base>\nCPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nAD<Base> Var2Par(const VecAD_reference<Base> &x)\n{  AD<Base> y(x.ADBase());\n   y.id_ = 0;\n}\n\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/vec_ad/vec_ad.hpp",
    "content": "# ifndef CPPAD_CORE_VEC_AD_VEC_AD_HPP\n# define CPPAD_CORE_VEC_AD_VEC_AD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/pod_vector.hpp>\nnamespace CppAD { //  BEGIN_CPPAD_NAMESPACE\n/*\n{xrst_begin_parent dev_vec_ad dev}\n\nDeveloper Documentation for VecAD Operations\n############################################\n\nContents\n********\n{xrst_toc_table\n}\n\n{xrst_end dev_vec_ad}\n ------------------------------------------------------------------------------\n{xrst_begin vec_ad_comp_assign dev}\nVecAD: Prints Error Message If A Compound Assignment Is Used\n############################################################\n\nSyntax\n******\n| ``CPPAD_VEC_AD_COMP_ASSIGN`` ( *cop* )\n| ``ref cop right``\n\nCPPAD_VEC_AD_COMP_ASSIGN\n************************\nThis macro defines the compound assignment operator *cop*\nfor a VecAD reference element to be an error with an error message.\n\ncop\n***\nIs one of the following computed assignment operators:\n+= , -= , \\*= , /=.\n\nref\n***\nis the VecAD reference.\n\nright\n*****\nis the right hand side for the compound assignment.\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_VEC_AD_COMP_ASSIGN(cop)                              \\\nVecAD_reference& operator cop (const VecAD_reference<Base> &right)  \\\n{  CPPAD_ASSERT_KNOWN(false,                                       \\\n      \"Can't use VecAD<Base>::reference on left side of \" #cop    \\\n   );                                                              \\\n   return *this;                                                   \\\n}                                                                   \\\nVecAD_reference& operator cop (const AD<Base> &right)               \\\n{  CPPAD_ASSERT_KNOWN(false,                                       \\\n      \"Can't use VecAD<Base>::reference on left side of \" #cop    \\\n   );                                                              \\\n   return *this;                                                   \\\n}                                                                   \\\nVecAD_reference& operator cop (const Base &right)                   \\\n{  CPPAD_ASSERT_KNOWN(false,                                       \\\n      \"Can't use VecAD<Base>::reference on left side of \" #cop    \\\n   );                                                              \\\n   return *this;                                                   \\\n}                                                                   \\\nVecAD_reference& operator cop (int right)                           \\\n{  CPPAD_ASSERT_KNOWN(false,                                       \\\n      \"Can't use VecAD<Base>::reference on left side of \" #cop    \\\n   );                                                              \\\n   return *this;                                                   \\\n}\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end vec_ad_comp_assign}\n------------------------------------------------------------------------------\n{xrst_begin vec_ad_reference dev}\nVecAD Element Reference Class\n#############################\n\nSyntax\n******\n\n| ``VecAD_reverence`` *ref* ( *vec* , *ind* )\n| *ref* = *right*\n| ``ref cop right``\n| ``element`` = ``ref`` . *ADBase* ()\n\nMember Variables\n****************\n\nvec\\_\n=====\nThis private data is a reference to *vec* in the constructor.\n\nind\\_\n=====\nThis private data is a copy of *ind* in the constructor.\n\nBase\n****\nElements of this reference class act like an\n``AD`` < *Base* > object (in a restricted sense),\nin addition they track (on the tape) the index *ind* they correspond to.\n\nvec\n***\nis the vector containing the element being referenced and has prototype\n\n   ``VecAD`` < *Base* > *vec*\n\nind\n***\nis the index of the element being referenced and has prototype\n\n   ``const AD`` < *Base* >& ``ind``\n\nIf *ind* . ``tape_id_`` matches a current recording,\nso does *vec* . ``tape_id_`` and\nthe :ref:`AD type<atomic_three_define@ad_type>` corresponding to *vec*\nincludes this indexing operation; i.e., it is greater than or equal\nthe AD type corresponding to *ind* .\n\nright\n*****\nIs the right hand side of the assignment statement and has one\nof the following prototypes:\n\n| |tab| ``int`` *right*\n| |tab| ``const`` *Base* & *right*\n| |tab| ``const AD`` < *Base* >& *right*\n| |tab| ``const VecAD_reverence`` < *Base* >& *right*\n\ncop\n***\nIs one of the following computed assignment operators:\n+= , -= , \\*= , /=.\nAll of these operations report an error.\n\nelement\n*******\nIs a copy of the element corresponding to the reference *ref*\nand has prototype:\n\n   ``AD`` < *Base* > *element*\n\n{xrst_end vec_ad_reference}\n*/\ntemplate <class Base>\nclass VecAD_reference {\n   friend bool  Constant<Base>  (const VecAD<Base> &vec);\n   friend bool  Parameter<Base> (const VecAD<Base> &vec);\n   friend bool  Dynamic<Base>   (const VecAD<Base> &vec);\n   friend bool  Variable<Base>  (const VecAD<Base> &vec);\n   friend class VecAD<Base>;\n   friend class local::ADTape<Base>;\n\nprivate:\n   VecAD<Base>& vec_;  // reverence to vector\n   AD<Base>     ind_;  // index for this element\npublic:\n   VecAD_reference(VecAD<Base>& vec, const AD<Base>& ind)\n      : vec_( vec ) , ind_(ind)\n   { }\n\n   // assignment operators\n   void operator = (const VecAD_reference<Base> &right);\n   void operator = (const AD<Base> &right);\n   void operator = (const Base     &right);\n   void operator = (int             right);\n\n   // compound assignments\n   CPPAD_VEC_AD_COMP_ASSIGN( += )\n   CPPAD_VEC_AD_COMP_ASSIGN( -= )\n   CPPAD_VEC_AD_COMP_ASSIGN( *= )\n   CPPAD_VEC_AD_COMP_ASSIGN( /= )\n\n\n   /// Conversion from VecAD_reference to AD<Base>.\n   /// puts the correspond vecad load instruction in the tape.\n   AD<Base> ADBase(void) const\n   {  // start with default constructor (hence dynamic_ is false).\n      AD<Base> result;\n\n      size_t i = static_cast<size_t>( Integer(ind_) );\n      CPPAD_ASSERT_UNKNOWN( i < vec_.length_ );\n\n      // AD<Base> value corresponding to this element\n      result.value_ = vec_.data_[i];\n      CPPAD_ASSERT_UNKNOWN( Constant(result) );\n\n      // check if there is a recording in progress\n      local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n      if( tape == nullptr )\n         return result;\n\n      // tape_id cannot match the default value zero\n      CPPAD_ASSERT_UNKNOWN( tape->id_ > 0 );\n\n      // check if vector, index match tape_id\n      bool match_vec   = vec_.tape_id_  == tape->id_;\n      bool match_ind   = ind_.tape_id_  == tape->id_;\n\n      // check if vector, index are dynamic parmaerters\n      CPPAD_ASSERT_UNKNOWN( vec_.ad_type_ != dynamic_enum);\n      bool dyn_ind   = match_ind   & (ind_.ad_type_  == dynamic_enum);\n\n      // check if vector, index are variables\n      bool var_vec   = match_vec   & (vec_.ad_type_   == variable_enum);\n      bool var_ind   = match_ind   & (ind_.ad_type_   == variable_enum);\n\n      // check if vector, index are constants\n      bool con_vec   = ! var_vec;\n      bool con_ind   = ! ( dyn_ind   | var_ind);\n      if( con_vec & con_ind )\n         return result;\n# ifndef NDEBUG\n   if( match_vec & match_ind ) CPPAD_ASSERT_KNOWN(\n      vec_.tape_id_ == ind_.tape_id_ ,\n      \"VecAD: vector and index are dynamic parameters or variables \"\n      \"on different treads.\"\n   );\n# endif\n      // parameter or variable index corresponding to ind_\n      addr_t ind_taddr = ind_.taddr_;\n      if( con_ind )\n         ind_taddr = tape->Rec_.put_con_par(ind_.value_);\n\n      // index corresponding to this element\n      CPPAD_ASSERT_UNKNOWN( var_vec );\n      {  CPPAD_ASSERT_UNKNOWN( vec_.offset_ > 0  );\n         size_t load_op_index = tape->Rec_.num_var_load();\n         //\n         if( var_ind )\n         {  CPPAD_ASSERT_UNKNOWN( local::NumRes(local::LdvOp) == 1 );\n            CPPAD_ASSERT_UNKNOWN( local::NumArg(local::LdvOp) == 3 );\n\n            // put operand addresses in tape, ind_ is a variable\n            result.taddr_ = tape->Rec_.PutLoadOp(local::LdvOp);\n            tape->Rec_.PutArg(\n               (addr_t) vec_.offset_, ind_taddr, (addr_t) load_op_index\n            );\n\n            // change result to variable for this load\n            result.tape_id_ = tape->id_;\n            result.ad_type_ = variable_enum;\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( local::NumRes(local::LdpOp) == 1 );\n            CPPAD_ASSERT_UNKNOWN( local::NumArg(local::LdpOp) == 3 );\n            CPPAD_ASSERT_UNKNOWN( con_ind | dyn_ind );\n\n\n            // put operand addresses in tape\n            tape->Rec_.PutArg(\n               (addr_t) vec_.offset_, ind_taddr, (addr_t) load_op_index\n            );\n            // put operator in the tape, ind_ is a parameter\n            result.taddr_ = tape->Rec_.PutLoadOp(local::LdpOp);\n\n            // change result to variable for this load\n            result.tape_id_ = tape->id_;\n            result.ad_type_ = variable_enum;\n         }\n      }\n      return result;\n   }\n};\n// ---------------------------------------------------------------------------\n/*!\n{xrst_begin vec_ad_class dev}\n{xrst_spell\n   taddr\n}\nVecAD Class Objects\n###################\n\nSyntax\n******\n\n| ``VecAD`` *empty* , *vec* ( *length* )\n| *length* = *vec* . ``size`` ()\n| *b* = *vec* [ *i* ]\n| *ref* = *vec* [ *ind* ]\n\nlength\n******\nis the size of the vector and has prototype\n\n   ``size_t`` *length*\n\nPrivate Members\n***************\n{xrst_literal\n   // BEGIN_VECAD_PRIVATE_DATA\n   // END_VECAD_PRIVATE_DATA\n}\n\nlength\\_\n========\nis a copy of *length* .\n\ndata\\_\n======\nThis vector has size *length* and\ncontains the value of the elements of the vector.\n\ntaddr\\_\n=======\nThis vector has size *length* .\nIf ``tape_id_`` matches the current recording\nand ``ad_type_`` is ``dynamic_enum`` ,\n``taddr`` [ *i* ] is the parameter index for the corresponding element.\n\noffset\\_\n========\nIf *tape_id_* is the current tape,\n*offset_* is the index of the first element of this vector\nin the combined vector that contains all the VecAD elements for this recording.\n*offset_* ``-1`` is the index of the size of this vector\nin the combined vector.\n\ntape_id\\_\n=========\nis the tape currently associated with this vector.\n\nad_type\\_\n=========\nis the :ref:`atomic_three_define@ad_type` corresponding to this\nvector.\n\ni\n*\nis a ``size_t`` value less than *length* .\nThis form of indexing can only be used when *vec* is a\nconstant parameter; i.e., its operations are not being recorded.\n\nb\n*\nis a reference to the *Base* value\nfor the *i*-th element of the vector.\n\nind\n***\nis a ``AD`` < *Base* > value less than *length* .\nThis form of indexing gets recorded and the value of the index\ncan change.\n\nref\n***\nis a reference to the ``AD`` < *Base* > value\nfor the *x*-th element of the vector.\nIf the vector is a parameter and the index is a variable,\nthe vector is changed to be a variable.\n\n{xrst_end vec_ad_class}\n*/\ntemplate <class Base>\nclass VecAD {\n   friend bool  Constant<Base>  (const VecAD<Base> &vec);\n   friend bool  Parameter<Base> (const VecAD<Base> &vec);\n   friend bool  Dynamic<Base>   (const VecAD<Base> &vec);\n   friend bool  Variable<Base>  (const VecAD<Base> &vec);\n   friend class local::ADTape<Base>;\n   friend class VecAD_reference<Base>;\n\n   friend std::ostream& operator << <Base>\n      (std::ostream &os, const VecAD<Base> &vec_);\nprivate:\n// BEGIN_VECAD_PRIVATE_DATA\n   const  size_t                 length_;\n   local::pod_vector_maybe<Base> data_;\n   local::pod_vector<addr_t>     taddr_;\n   tape_id_t                     tape_id_;\n   addr_t                        offset_;\n   ad_type_enum                  ad_type_;\n// END_VECAD_PRIVATE_DATA\npublic:\n   // declare the user's view of this type here\n   typedef VecAD_reference<Base> reference;\n\n   // default constructor\n   // initialize tape_id_ same as for default constructor; see default.hpp\n   VecAD(void)\n   : length_(0), tape_id_(0), offset_(0), ad_type_(constant_enum)\n   {  CPPAD_ASSERT_UNKNOWN( Constant(*this) ); }\n\n   // sizing constructor\n   // initialize tape_id_ same as for constants; see ad_copy.hpp\n   VecAD(size_t length)\n   : length_(length), tape_id_(0), offset_(0), ad_type_(constant_enum)\n   {  if( length_ > 0 )\n      {  size_t i;\n         Base zero(0);\n         data_.extend(length_);\n         taddr_.extend(length_);\n\n         // Initialize data to zero so all have same value.\n         // This uses less memory and avoids a valgrind error\n         // during TapeRec<Base>::PutPar\n         for(i = 0; i < length_; i++)\n         {  data_[i]  = zero;\n            taddr_[i] = 0;\n         }\n      }\n      CPPAD_ASSERT_UNKNOWN( Constant(*this) );\n   }\n\n   // destructor\n   ~VecAD(void)\n   { }\n\n   // number of elements in the vector\n   size_t size(void)\n   {  return length_; }\n\n   // element access (not taped)\n   Base& operator[](size_t i)\n   {\n      CPPAD_ASSERT_KNOWN(\n         Constant(*this),\n         \"VecAD: cannot use size_t indexing because this\"\n         \" VecAD vector is not a constant parameter.\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         i < length_,\n         \"VecAD: element index is >= vector length\"\n      );\n\n      return data_[i];\n   }\n\n   // element access (taped)\n   VecAD_reference<Base> operator[](const AD<Base> &ind)\n   {\n      CPPAD_ASSERT_KNOWN(\n         0 <= Integer(ind),\n         \"VecAD: element index is less than zero\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         static_cast<size_t>( Integer(ind) ) < length_,\n         \"VecAD: element index is >= vector length\"\n      );\n\n      // check if there is a recording in progress\n      local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n      if( tape == nullptr )\n         return VecAD_reference<Base>(*this, ind);\n\n      // tape_id cannot match the default value zero\n      CPPAD_ASSERT_UNKNOWN( tape->id_ > 0 );\n\n      // check if vector, index match tape_id\n      bool match_vec   = tape_id_      == tape->id_;\n      bool match_ind   = ind.tape_id_  == tape->id_;\n\n      // check if vector, index are dynamic parmaerters\n      CPPAD_ASSERT_UNKNOWN( ad_type_ != dynamic_enum );\n      bool dyn_ind   = match_ind   & (ind.ad_type_  == dynamic_enum);\n\n      // check if vector, index are variables\n      bool var_vec   = match_vec   & (ad_type_       == variable_enum);\n      bool var_ind   = match_ind   & (ind.ad_type_   == variable_enum);\n\n      // check if vector, index are constants\n      bool con_vec   = ! var_vec;\n      bool con_ind   = ! ( dyn_ind   | var_ind);\n      if( con_vec & con_ind )\n         return VecAD_reference<Base>(*this, ind);\n# ifndef NDEBUG\n      if( match_vec & match_ind ) CPPAD_ASSERT_KNOWN(\n         tape_id_ == ind.tape_id_ ,\n         \"VecAD: vector and index are dynamic parameters or variables \"\n         \"on different treads.\"\n      );\n# endif\n      if( con_vec )\n      {  // place a copy of vector in tape\n         for(size_t i = 0; i < length_; ++i)\n            taddr_[i] = tape->Rec_.put_con_par( data_[i] );\n         offset_ = tape->Rec_.put_var_vecad(length_, taddr_);\n\n         // Advance pointer by one so starts at first component of this\n         // vector; i.e., skip length at beginning (so is always > 0)\n         offset_++;\n\n         // tape_id corresponding to this vector\n         tape_id_ = ind.tape_id_;\n\n         // VecAD objects go straight from constants to variables; i.e.,\n         // they never are dynamic parameters.\n         ad_type_ = variable_enum;\n      }\n      CPPAD_ASSERT_UNKNOWN( Variable(*this) );\n      return VecAD_reference<Base>(*this, ind);\n   }\n\n};\n// ---------------------------------------------------------------------------\n// ref = right\ntemplate <class Base>\nvoid VecAD_reference<Base>::operator=(const AD<Base> &right)\n{\n   // index in vector for this element\n   size_t index = static_cast<size_t>( Integer(ind_) );\n   CPPAD_ASSERT_UNKNOWN( index < vec_.length_ );\n\n   // Base part of assignment for this element\n   vec_.data_[index] = right.value_;\n\n   // check if there is a recording in progress\n   local::ADTape<Base>* tape = AD<Base>::tape_ptr();\n   if( tape == nullptr )\n      return;\n\n   // tape_id cannot match the default value zero\n   tape_id_t tape_id = tape->id_;\n   CPPAD_ASSERT_UNKNOWN( tape_id > 0 );\n\n   // check if vector, index, right match tape_id\n   bool match_vec   = vec_.tape_id_  == tape_id;\n   bool match_ind   = ind_.tape_id_  == tape_id;\n   bool match_right = right.tape_id_ == tape_id;\n   CPPAD_ASSERT_UNKNOWN( match_vec || ! match_ind );\n\n   // check if vector, index, right are dynamic parmaerters\n   CPPAD_ASSERT_UNKNOWN(vec_.ad_type_  != dynamic_enum);\n   bool dyn_ind   = match_ind   & (ind_.ad_type_  == dynamic_enum);\n   bool dyn_right = match_right & (right.ad_type_ == dynamic_enum);\n\n   // check if vector, index, right are variables\n   bool var_vec   = match_vec   & (vec_.ad_type_   == variable_enum);\n   bool var_ind   = match_ind   & (ind_.ad_type_   == variable_enum);\n   bool var_right = match_right & (right.ad_type_  == variable_enum);\n\n   // check if vector, index, right are constants\n   bool con_vec   = ! var_vec;\n   bool con_ind   = ! ( dyn_ind   | var_ind);\n   bool con_right = ! ( dyn_right | var_right);\n   if( con_vec & con_right )\n      return;\n\n# ifndef NDEBUG\n   if( match_ind )\n   {  CPPAD_ASSERT_UNKNOWN( ind_.tape_id_ == vec_.tape_id_ );\n      CPPAD_ASSERT_UNKNOWN( ind_.ad_type_ <= vec_.ad_type_ );\n   }\n   if( match_vec & match_right ) CPPAD_ASSERT_KNOWN(\n      vec_.tape_id_ == right.tape_id_ ,\n      \"VecAD: vector and element are dynamic parameters or variables \"\n      \"on different treads.\"\n   );\n# endif\n\n   if( con_vec )\n   {  CPPAD_ASSERT_UNKNOWN( con_ind );\n\n      // place a copy of vector in tape\n      for(size_t i = 0; i < vec_.length_; ++i)\n         vec_.taddr_[i] = tape->Rec_.put_con_par( vec_.data_[i] );\n      vec_.offset_ = tape->Rec_.put_var_vecad(vec_.length_, vec_.taddr_);\n\n      // advance offset from size of vector to first element in vector\n      (vec_.offset_)++;\n\n      // tape_id corresponding to this vector\n      vec_.tape_id_ = right.tape_id_;\n\n      // VecAD objects go straight from constants to variables; i.e.,\n      // they never are dynamic parameters.\n      vec_.ad_type_ = variable_enum;\n   }\n   CPPAD_ASSERT_UNKNOWN( Variable(vec_) );\n   CPPAD_ASSERT_UNKNOWN( vec_.offset_ > 0 );\n\n   // parameter or variable index for ind_\n   addr_t ind_taddr = ind_.taddr_;\n   if( con_ind )\n      ind_taddr = tape->Rec_.put_con_par(ind_.value_);\n   CPPAD_ASSERT_UNKNOWN( ind_taddr > 0 );\n\n   // parameter or variable index for right\n   addr_t right_taddr = right.taddr_;\n   if( con_right )\n      right_taddr = tape->Rec_.put_con_par(right.value_);\n   CPPAD_ASSERT_UNKNOWN( right_taddr > 0 );\n\n   // record the setting of this array element\n   if( var_right )\n   {  // resulting vector is a variable\n      vec_.ad_type_ = variable_enum;\n\n      // put operator arguments in tape\n      tape->Rec_.PutArg(vec_.offset_, ind_taddr, right_taddr);\n\n      if( con_ind | dyn_ind)\n      {  CPPAD_ASSERT_UNKNOWN( local::NumArg(local::StpvOp) == 3 );\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::StpvOp) == 0 );\n\n         // put operator in the tape, ind_ is parameter, right is variable\n         tape->Rec_.PutOp(local::StpvOp);\n\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN( var_ind );\n         CPPAD_ASSERT_UNKNOWN( local::NumArg(local::StvvOp) == 3 );\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::StvvOp) == 0 );\n\n         // put operator in the tape, ind_ is variable, right is variable\n         tape->Rec_.PutOp(local::StvvOp);\n      }\n   }\n   else\n   {\n      // put operator arguments in tape\n      tape->Rec_.PutArg(vec_.offset_, ind_taddr, right_taddr);\n\n      // record the setting of this array element\n      if( con_ind | dyn_ind )\n      {  CPPAD_ASSERT_UNKNOWN( local::NumArg(local::StppOp) == 3 );\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::StppOp) == 0 );\n\n         // put operator in the tape, ind_ is parameter, right is parameter\n         tape->Rec_.PutOp(local::StppOp);\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN( local::NumArg(local::StvpOp) == 3 );\n         CPPAD_ASSERT_UNKNOWN( local::NumRes(local::StvpOp) == 0 );\n\n         // put operator in the tape, ind_ is variable, right is parameter\n         tape->Rec_.PutOp(local::StvpOp);\n      }\n   }\n}\ntemplate <class Base>\nvoid VecAD_reference<Base>::operator=(const Base &right)\n{  *this = AD<Base>(right); }\n//\ntemplate <class Base>\nvoid VecAD_reference<Base>::operator=\n(const VecAD_reference<Base> &right)\n{  *this = right.ADBase(); }\n//\ntemplate <class Base>\nvoid VecAD_reference<Base>::operator=(int right)\n{  *this = Base(right); }\n// ---------------------------------------------------------------------------\n\n} // END_CPPAD_NAMESPACE\n\n// preprocessor symbols that are local to this file\n# undef CPPAD_VEC_AD_COMP_ASSIGN\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/core/zdouble.hpp",
    "content": "# ifndef CPPAD_CORE_ZDOUBLE_HPP\n# define CPPAD_CORE_ZDOUBLE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin zdouble app}\nzdouble: An AD Base Type With Absolute Zero\n###########################################\n\nDeprecated 2015-09-26\n*********************\nUse the function :ref:`azmul-name` instead.\n\nAbsolute Zero\n*************\nThe ``zdouble`` class acts like the ``double`` type\nwith the added property that zero times any value is zero.\nThis includes zero time :ref:`nan-name` and zero times infinity.\nIn addition, zero divided by any value and any value times zero\nare also zero.\n\nSyntax\n******\n\nConstructor and Assignment\n==========================\n\n| ``zdouble z``\n| ``zdouble z`` ( ``x`` )\n| ``zdouble z`` ( ``i`` )\n| *z1* *op* *x*\n\nwere *i* is a ``size_t`` or *long* or ``int`` ,\n*x* is a ``double`` or ``zdouble`` ,\nand *op* is ``=`` or ``+=`` or ``-=`` or ``*=``\nor ``/=-`` .\n\nComparison Operators\n====================\n\n| *b* = *z* *op* *x*\n| *b* = *x* *op* *z*\n\nwhere *b* is a ``bool`` object,\n*z* is a ``zdouble`` object,\n*x* is a ``double`` or ``zdouble`` object, and\n*op* is ``==`` , ``!=`` , ``<=`` , ``>=`` ,\n``<`` or ``>`` .\n\nArithmetic Operators\n====================\n\n| *z2* = *z1* *op* *x*\n| *z2* = *x* *op* *z1*\n\nwhere *z1* , *z2* are ``zdouble`` objects,\n*x* is a ``double`` or ``zdouble`` object, and\n*op* is ``+`` , ``-`` , ``*`` or ``/`` .\n\nStandard Math\n=============\n\n| *z2* = *fun* ( *z1* )\n| *z3* = ``pow`` ( *z1* , *z2* )\n\nwhere *z1* , *z2* , *z3* are ``zdouble`` objects and\n*fun* is a :ref:`unary_standard_math-name` function.\n\nNan\n===\nThere is a specialization of :ref:`nan-name` so that\n\n   ``z2`` = *nan* ( ``z1`` )\n\nreturns 'not a number' when *z1* has type ``zdouble`` .\nNote that this template function needs to be specialized because\n\n   ``zdouble`` (0.0) == ``zdouble`` (0.0) / ``zdouble`` (0.0)\n\nMotivation\n**********\n\nGeneral\n=======\nOften during computing (and more so in parallel computing) alternative\nvalues for an expression are computed and one of the alternatives\nis chosen using some boolean variable.\nThis is often represented by\n\n   *result* = *flag* * *value_if_true* + (1 ``-`` *flag* ) * *value_if_false*\n\nwhere *flag* is one for true and zero for false.\nThis representation does not work for ``double`` when the value\nbeing multiplied by zero is ``+inf`` , ``-inf`` , or ``nan`` .\n\nCppAD\n=====\nIn CppAD one can use\n:ref:`conditional expressions<CondExp-name>` to achieve the representation\n\n   *result* = *flag* * *value_if_true* + (1 ``-`` *flag* ) * *value_if_false*\n\nThis works fine except when there are\n:ref:`multiple levels of AD<mul_level-name>` ; e.g.,\nwhen using ``AD< AD<double> >`` .\nIn this case the corresponding AD function objects have type\n:ref:`ADFun\\< AD\\<double> ><fun_construct-name>` .\nWhen these AD function objects compute derivatives using\n:ref:`reverse-name` mode, the conditional expressions are represented use\nzeros to multiply the expression that is not used.\nUsing ``AD< AD<zdouble> >`` instead of ``AD< AD<double> >``\nmakes this representation work and fixes the problem.\n\nBase Type Requirements\n**********************\nThe type ``zdouble`` satisfies all of the CppAD\n:ref:`base type requirements<base_require-name>` .\n\n{xrst_end zdouble}\n*/\n# include <cppad/base_require.hpp>\n# include <cppad/utility/nan.hpp>\n\n/*!\n\\file zdouble.hpp\nDefine a class like double but with an absolute zero.\n*/\n\n/*!\n\\def CPPAD_ZDOUBLE_NORMAL_ASSIGN_OPERATOR(op)\nDefine a compound assignment member operator that functions the same\nas corresponding double operator.\n*/\n# define CPPAD_ZDOUBLE_NORMAL_ASSIGN_OPERATOR(op) \\\n   zdouble& operator op (const zdouble& z) \\\n   {  dbl_ op z.dbl_;                     \\\n      return *this;                       \\\n   }                                       \\\n   zdouble& operator op (const double& x)  \\\n   {  dbl_ op x;                          \\\n      return *this;                       \\\n   }\n\n/*!\n\\def CPPAD_ZDOUBLE_UNARY_OPERATOR(op)\nDefine a unary compound assignment member operator.\n*/\n# define CPPAD_ZDOUBLE_UNARY_OPERATOR(op) \\\n   zdouble operator op (void) const      \\\n   {  return zdouble( op dbl_ ); }\n\n/*!\n# define CPPAD_ZDOUBLE_NORMAL_BINARY_OPERATOR(op)\nDefine a binary arithmetic member operator that functions the same\nas corresponding double operator.\n*/\n# define CPPAD_ZDOUBLE_NORMAL_BINARY_OPERATOR(op) \\\n   zdouble operator op (const zdouble& z) const  \\\n   {  return zdouble( dbl_ op z.dbl_ ); }       \\\n   zdouble operator op (const double& x) const   \\\n   {  return zdouble( dbl_ op x ); }\n\n/*!\n\\def CPPAD_ZDOUBLE_COMPARE_OPERATOR(op)\nDefine a comparison member operator.\n*/\n# define CPPAD_ZDOUBLE_COMPARE_OPERATOR(op)   \\\n   bool operator op (const zdouble& z) const \\\n   {  return dbl_ op z.dbl_; }             \\\n   bool operator op (const double& x) const \\\n   {  return dbl_ op x; }\n\n/*!\n\\def CPPAD_ZDOUBLE_OTHER_BINARY_OPERATOR(op)\nDefine a binary arithmetic operator that is not a member because\nthe double operand is on the left.\n*/\n# define CPPAD_ZDOUBLE_OTHER_BINARY_OPERATOR(op) \\\n   inline zdouble operator op(const double& x, const zdouble& z) \\\n   {  return zdouble(x) op z; }\n\n/*!\n\\def CPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(op, op_switch)\nDefine a comparison operator that is not a member because\nthe double operand is on the left.\nConvert it to the case where the double operand is on the right by\nby using op_switch instead of op.\n*/\n# define CPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(op, op_switch) \\\n   inline bool operator op(const double& x, const zdouble& z)    \\\n   {  return z op_switch x; }\n\n/*!\n\\def CPPAD_ZDOUBLE_STD_MATH_FRIEND(fun)\nDeclare that a standard math function is a friend.\n*/\n# define CPPAD_ZDOUBLE_STD_MATH_FRIEND(fun) \\\n   friend zdouble fun(const zdouble& z);\n/*!\n\\def CPPAD_ZDOUBLE_STD_MATH(fun)\nDefine a standard math function.\n*/\n# define CPPAD_ZDOUBLE_STD_MATH(fun)        \\\n   inline zdouble fun(const zdouble& z )    \\\n   {  return zdouble( std::fun(z.dbl_) ); }\n\nnamespace CppAD { // CPPAD_BEGIN_NAMESPACDE\n\n\n/*!\nClass that is like double, except that it has an absolute zero.\n*/\nclass zdouble {\n   /*!\n   For zdouble objects z1, z2, and std::ostream os,\n   declare the following friends:\n   \\code\n      os << z1\n      Integer(z1)\n      fabs(z1)\n      pow(z1, z2)\n      fabs_geq(z1, z2)\n      fun(z1)\n   \\endcode\n   where fun is any of the standard math unary functions.\n   */\n   friend std::ostream& operator << (std::ostream &os, const zdouble& z);\n   friend int Integer(const zdouble& z);\n   friend zdouble pow(const zdouble& x, const zdouble& y);\n   friend bool abs_geq(const zdouble& x, const zdouble& y);\n   //\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(acos)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(asin)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(atan)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(cos)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(cosh)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(exp)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(fabs)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(log)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(log10)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(sin)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(sinh)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(sqrt)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(tan)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(tanh)\n   //\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(asinh)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(acosh)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(atanh)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(erf)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(erfc)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(expm1)\n   CPPAD_ZDOUBLE_STD_MATH_FRIEND(log1p)\n   //\nprivate:\n   /// The value for this object\n   double dbl_;\npublic:\n   /// Default constructor\n   zdouble(void)\n   : dbl_()\n   { }\n   /// Copy constructor\n   zdouble(const zdouble& z)\n   : dbl_(z.dbl_)\n   { }\n   /// Constructor from double\n   zdouble(const double& dbl)\n   : dbl_(dbl)\n   { }\n   /// Constructor from size_t\n   zdouble(const size_t& i)\n   : dbl_( double(i) )\n   { }\n   /// Constructor from long\n   zdouble(const long& i)\n   : dbl_( double(i) )\n   { }\n   /// Constructor from int\n   zdouble(const int& i)\n   : dbl_( double(i) )\n   { }\n   //\n   /// Destructor\n   ~zdouble(void)\n   { }\n   //\n   /// Assignment from zdouble\n   zdouble& operator=(const zdouble& z)\n   {  dbl_ = z.dbl_;\n      return *this;\n   }\n   /// Assignment from double\n   zdouble& operator=(const double& dbl)\n   {  dbl_ = dbl;\n      return *this;\n   }\n   //\n   /// Normal compound assignment\n   CPPAD_ZDOUBLE_NORMAL_ASSIGN_OPERATOR(+=)\n   /// Normal compound assignment\n   CPPAD_ZDOUBLE_NORMAL_ASSIGN_OPERATOR(-=)\n   /// Normal unary operator\n   CPPAD_ZDOUBLE_UNARY_OPERATOR(+)\n   /// Normal unary operator\n   CPPAD_ZDOUBLE_UNARY_OPERATOR(-)\n   /// Normal compare operator\n   CPPAD_ZDOUBLE_COMPARE_OPERATOR(==)\n   /// Normal compare operator\n   CPPAD_ZDOUBLE_COMPARE_OPERATOR(!=)\n   /// Normal compare operator\n   CPPAD_ZDOUBLE_COMPARE_OPERATOR(<=)\n   /// Normal compare operator\n   CPPAD_ZDOUBLE_COMPARE_OPERATOR(>=)\n   /// Normal compare operator\n   CPPAD_ZDOUBLE_COMPARE_OPERATOR(<)\n   /// Normal compare operator\n   CPPAD_ZDOUBLE_COMPARE_OPERATOR(>)\n   //\n   /// Normal binary arithmetic operator\n   CPPAD_ZDOUBLE_NORMAL_BINARY_OPERATOR(+)\n   /// Normal binary arithmetic operator\n   CPPAD_ZDOUBLE_NORMAL_BINARY_OPERATOR(-)\n   //\n   /// Binary arithmetic * with absolute zero\n   zdouble operator * (const zdouble& z) const\n   {  bool zero = (dbl_ == 0.0) || (z.dbl_ == 0.0);\n      return zdouble( zero ? 0.0 : (dbl_ * z.dbl_) );\n   }\n   /// Binary arithmetic * with absolute zero\n   zdouble operator * (const double& x) const\n   {  bool zero = (dbl_ == 0.0) || (x == 0.0);\n      return zdouble( zero ? 0.0 : (dbl_ * x) );\n   }\n   /// Binary arithmetic / with absolute zero\n   zdouble operator / (const zdouble& z) const\n   {  bool zero = (dbl_ == 0.0);\n      return zdouble( zero ? 0.0 : (dbl_ / z.dbl_) );\n   }\n   /// Binary arithmetic / with absolute zero\n   zdouble operator / (const double& x) const\n   {  bool zero = (dbl_ == 0.0);\n      return zdouble( zero ? 0.0 : (dbl_ / x) );\n   }\n   //\n   /// Compute assignment *= with absolute zero\n   zdouble& operator *= (const zdouble& z)\n   {  bool zero = (dbl_ == 0.0) || (z.dbl_ == 0.0);\n      zero ? (dbl_ = 0.0) : (dbl_ *= z.dbl_);\n      return *this;\n   }\n   /// Compute assignment *= with absolute zero\n   zdouble& operator *= (const double& x)\n   {  bool zero = (dbl_ == 0.0) || (x == 0.0);\n      zero ? (dbl_ = 0.0) : (dbl_ *= x);\n      return *this;\n   }\n   //\n   /// Compute assignment /= with absolute zero\n   zdouble& operator /= (const zdouble& z)\n   {  bool zero = (dbl_ == 0.0);\n      zero ? (dbl_ = 0.0) : (dbl_ /= z.dbl_);\n      return *this;\n   }\n   /// Compute assignment /= with absolute zero\n   zdouble& operator /= (const double& x)\n   {  bool zero = (dbl_ == 0.0);\n      zero ? (dbl_ = 0.0) : (dbl_ /= x);\n      return *this;\n   }\n};\n// BEGIN nan\n/// Must specialize CppAD::nan because zdouble 0/0 is not nan.\ntemplate <> inline\nzdouble nan<zdouble>(const zdouble& zero)\n{\n   return zdouble( std::numeric_limits<double>::quiet_NaN() );\n}\n// END nan\n//\n/// Normal non-member compare operator\nCPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(==, ==)\n/// Normal non-member compare operator\nCPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(!=, !=)\n/// Normal non-member compare operator\nCPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(<=, >=)\n/// Normal non-member compare operator\nCPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(>=, <=)\n/// Normal non-member compare operator\nCPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(<,  >)\n/// Normal non-member compare operator\nCPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR(>,  <)\n//\n/// Normal binary arithmetic operator\nCPPAD_ZDOUBLE_OTHER_BINARY_OPERATOR(+)\n/// Normal binary arithmetic operator\nCPPAD_ZDOUBLE_OTHER_BINARY_OPERATOR(-)\n/// Binary arithmetic operator with absolute zero\nCPPAD_ZDOUBLE_OTHER_BINARY_OPERATOR(*)\n/// Binary arithmetic operator with absolute zero\nCPPAD_ZDOUBLE_OTHER_BINARY_OPERATOR(/)\n// -------------------------------------------------------------------------\n// Base type requirements\n// -------------------------------------------------------------------------\n\n/// Base type requirement: CondExpOp\ninline zdouble CondExpOp(\n   enum CompareOp     cop          ,\n   const zdouble&       left         ,\n   const zdouble&       right        ,\n   const zdouble&       exp_if_true  ,\n   const zdouble&       exp_if_false )\n{  return CondExpTemplate(cop, left, right, exp_if_true, exp_if_false);\n}\n\n/// Base type requirement: CondExpRel\nCPPAD_COND_EXP_REL(zdouble)\n\n/// Base type requirement: EqualOpSeq\ninline bool EqualOpSeq(const zdouble& x, const zdouble& y)\n{  return x == y; }\n\n/// Base type requirement: Identical\ninline bool IdenticalCon(const zdouble& x)\n{  return true; }\ninline bool IdenticalZero(const zdouble& x)\n{  return (x == 0.0); }\ninline bool IdenticalOne(const zdouble& x)\n{  return (x == 1.); }\ninline bool IdenticalEqualCon(const zdouble& x, const zdouble& y)\n{  return (x == y); }\n\n/// Base type requirement: output operator\ninline std::ostream& operator << (std::ostream &os, const zdouble& z)\n{  os << z.dbl_;\n   return os;\n}\n\n/// Base type requirement: Integer\ninline int Integer(const zdouble& x)\n{  return static_cast<int>(x.dbl_); }\n\n/// Base type requirement: azmul\ninline zdouble azmul(const zdouble& x, const zdouble& y)\n{  return x * y; }\n\n/// Base type requirement: Ordered\ninline bool GreaterThanZero(const zdouble& x)\n{  return x > 0.0; }\ninline bool GreaterThanOrZero(const zdouble& x)\n{  return x >= 0.0; }\ninline bool LessThanZero(const zdouble& x)\n{  return x < 0.0; }\ninline bool LessThanOrZero(const zdouble& x)\n{  return x <= 0.0; }\ninline bool abs_geq(const zdouble& x, const zdouble& y)\n{  return std::fabs(x.dbl_) >= std::fabs(y.dbl_); }\n\n/// Normal standard math function\nCPPAD_ZDOUBLE_STD_MATH(acos)\n/// Normal standard math function\nCPPAD_ZDOUBLE_STD_MATH(asin)\n/// Normal standard math function\nCPPAD_ZDOUBLE_STD_MATH(atan)\n/// Normal standard math function\nCPPAD_ZDOUBLE_STD_MATH(cos)\n/// Normal standard math function\nCPPAD_ZDOUBLE_STD_MATH(cosh)\n/// Normal standard math function\nCPPAD_ZDOUBLE_STD_MATH(exp)\n/// Normal standard math function\nCPPAD_ZDOUBLE_STD_MATH(fabs)\n/// Normal standard math function\nCPPAD_ZDOUBLE_STD_MATH(log)\n/// Normal standard math function\nCPPAD_ZDOUBLE_STD_MATH(log10)\n/// Normal standard math function\nCPPAD_ZDOUBLE_STD_MATH(sin)\n/// Normal standard math function\nCPPAD_ZDOUBLE_STD_MATH(sinh)\n/// Normal standard math function\nCPPAD_ZDOUBLE_STD_MATH(sqrt)\n/// Normal standard math function\nCPPAD_ZDOUBLE_STD_MATH(tan)\n/// Normal standard math function\nCPPAD_ZDOUBLE_STD_MATH(tanh)\n//\n/// C++2011 standard math function\nCPPAD_ZDOUBLE_STD_MATH(asinh)\n/// C++2011 standard math function\nCPPAD_ZDOUBLE_STD_MATH(acosh)\n/// C++2011 standard math function\nCPPAD_ZDOUBLE_STD_MATH(atanh)\n/// C++2011 standard math function\nCPPAD_ZDOUBLE_STD_MATH(erf)\n/// C++2011 standard math function\nCPPAD_ZDOUBLE_STD_MATH(erfc)\n/// C++2011 standard math function\nCPPAD_ZDOUBLE_STD_MATH(expm1)\n/// C++2011 standard math function\nCPPAD_ZDOUBLE_STD_MATH(log1p)\n\n/// Base type requirement: abs\ninline zdouble abs(const zdouble& x)\n{  return fabs(x); }\n\n/// Base type requirement: sign\ninline zdouble sign(const zdouble& x)\n{  if( x > 0.0 )\n      return zdouble(1.);\n   if( x == 0.0 )\n      return zdouble(0.0);\n   return zdouble(-1.);\n}\n\n/// Base type requirement: pow\ninline zdouble pow(const zdouble& x, const zdouble& y)\n{ return std::pow(x.dbl_, y.dbl_); }\n\n/// Base type requirement: limits\nCPPAD_NUMERIC_LIMITS(double, zdouble)\n\n} // CPPAD_END_NAMESPACE\n\n/// undef all macros defined in this file\n# undef CPPAD_ZDOUBLE_NORMAL_ASSIGN_OPERATOR\n# undef CPPAD_ZDOUBLE_UNARY_OPERATOR\n# undef CPPAD_ZDOUBLE_NORMAL_BINARY_OPERATOR\n# undef CPPAD_ZDOUBLE_COMPARE_OPERATOR\n# undef CPPAD_ZDOUBLE_OTHER_BINARY_OPERATOR\n# undef CPPAD_ZDOUBLE_OTHER_COMPARE_OPERATOR\n# undef CPPAD_ZDOUBLE_STD_MATH_FRIEND\n# undef CPPAD_ZDOUBLE_STD_MATH\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/cppad.hpp",
    "content": "# ifndef CPPAD_CPPAD_HPP\n# define CPPAD_CPPAD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*!\n\\file cppad.hpp\n\\brief includes the entire CppAD package in the necessary order.\n\n\\namespace CppAD\n\\brief contains all the variables and functions defined by the CppAD package.\n*/\n\n# include <cppad/base_require.hpp> // all base type requirements\n// ---------------------------------------------------------------------------\n// CppAD general purpose library routines (can be included separately)\n# include <cppad/utility.hpp>\n// --------------------------------------------------------------------------\n// System routines that can be used by rest of CppAD with out including\n\n# include <cstddef>\n# include <iostream>\n# include <complex>\n# include <cmath>\n\n// ---------------------------------------------------------------------------\n// definitions needed by rest of includes\n\n// definitions that come from the installation\n# include <cppad/configure.hpp>\n\n// definitions that are local to the CppAD include files\n# include <cppad/local/define.hpp>\n\n// vectors used with CppAD\n# include <cppad/core/testvector.hpp>\n\n// Declare classes and functions that are used before defined\n# include <cppad/local/declare_ad.hpp>\n\n// ---------------------------------------------------------------------------\n// declare the AD<Base> template class\n\n# include <cppad/core/ad.hpp>\n\n// ---------------------------------------------------------------------------\n\n# include <cppad/core/user_ad.hpp>  // AD class methods available to the user\n// tape that tape for AD<Base> acts as a user of Base operations\n// so user_ad.hpp must come before op.hpp\n# include <cppad/local/var_op/var_op.hpp>       // executes taped operations\n# include <cppad/core/ad_fun.hpp>   // ADFun objects\n//\n// Putting these includes in ad_fun.hpp leads to circular including; i.e,\n// a file needs to include itself and the include guard stops it.\n# include <cppad/local/val_graph/fun2val.hpp>\n# include <cppad/local/val_graph/val2fun.hpp>\n\n// ---------------------------------------------------------------------------\n// library routines that require the rest of CppAD\n# include <cppad/core/lu_ratio.hpp>\n# include <cppad/core/bender_quad.hpp>\n# include <cppad/core/opt_val_hes.hpp>\n# include <cppad/local/graph/cpp_graph_op.hpp>\n# include <cppad/local/graph/json_lexer.hpp>\n# if CPPAD_HAS_IPOPT\n# include <cppad/ipopt/solve.hpp>\n# endif\n\n// undo definitions in Define.h\n# include <cppad/core/undef.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/ad_tape.hpp",
    "content": "# ifndef CPPAD_LOCAL_AD_TAPE_HPP\n# define CPPAD_LOCAL_AD_TAPE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/define.hpp>\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL__NAMESPACE\n\n/*!\nClass used to hold tape that records AD<Base> operations.\n\n\\tparam Base\nAn <tt>AD<Base></tt> object is used to recording <tt>AD<Base></tt> operations.\n*/\n\ntemplate <class Base>\nclass ADTape {\n   // Friends =============================================================\n\n   // classes -------------------------------------------------------------\n   friend class AD<Base>;\n   friend class ADFun<Base>;\n   friend class atomic_base<Base>;\n   friend class atomic_three<Base>;\n   friend class atomic_four<Base>;\n   friend class discrete<Base>;\n   friend class VecAD<Base>;\n   friend class VecAD_reference<Base>;\n\n   // functions -----------------------------------------------------------\n   // PrintFor\n   friend void CppAD::PrintFor <Base> (\n      const AD<Base>&    flag   ,\n      const char*        before ,\n      const AD<Base>&    var    ,\n      const char*        after\n   );\n   // CondExpOp\n   friend AD<Base> CppAD::CondExpOp <Base> (\n      enum CompareOp  cop          ,\n      const AD<Base> &left         ,\n      const AD<Base> &right        ,\n      const AD<Base> &trueCase     ,\n      const AD<Base> &falseCase\n   );\n   // pow\n   friend AD<Base> CppAD::pow <Base>\n      (const AD<Base> &x, const AD<Base> &y);\n   // azmul\n   friend AD<Base> CppAD::azmul <Base>\n      (const AD<Base> &x, const AD<Base> &y);\n   // Parameter\n   friend bool CppAD::Parameter     <Base>\n      (const AD<Base> &u);\n   // Variable\n   friend bool CppAD::Variable      <Base>\n      (const AD<Base> &u);\n   // operators -----------------------------------------------------------\n   // arithematic binary operators\n# if _MSC_VER && !defined(__clang__)\n   // see https://stackoverflow.com/questions/63288453\n   template <class Type> friend AD<Type> CppAD::operator * <Type>\n      (const AD<Type> &left, const AD<Type> &right);\n# else\n   friend AD<Base> CppAD::operator * <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n# endif\n   friend AD<Base> CppAD::operator + <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   friend AD<Base> CppAD::operator - <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   friend AD<Base> CppAD::operator / <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n\n   // comparison operators\n# if _MSC_VER && !defined(__clang__)\n   template <class Type> friend bool CppAD::operator == <Type>\n      (const AD<Type> &left, const AD<Type> &right);\n   template <class Type> friend bool CppAD::operator != <Type>\n      (const AD<Type> &left, const AD<Type> &right);\n# else\n   friend bool CppAD::operator == <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   friend bool CppAD::operator != <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n# endif\n   friend bool CppAD::operator < <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   friend bool CppAD::operator <= <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   friend bool CppAD::operator > <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   friend bool CppAD::operator >= <Base>\n      (const AD<Base> &left, const AD<Base> &right);\n   // ======================================================================\n\n// --------------------------------------------------------------------------\nprivate:\n   // ----------------------------------------------------------------------\n   // private data\n   /*!\n   Unique identifier for this tape.  It is always greater than\n   CPPAD_MAX_NUM_THREADS, and different for every tape (even ones that have\n   been deleted). In addition, id_ % CPPAD_MAX_NUM_THREADS is the thread\n   number for this tape. Set by Independent and effectively const\n   */\n   tape_id_t                    id_;\n   /// Number of independent variables in this tapes reconding.\n   /// Set by Independent and effectively const\n   size_t         size_independent_;\n   /// This is where the information is recorded.\n   local::recorder<Base>              Rec_;\n   // ----------------------------------------------------------------------\n   // private functions\n   //\n   // add a parameter to the tape\n   addr_t RecordParOp(const AD<Base>& y);\n\n   // see CondExp.h\n   void RecordCondExp(\n      enum CompareOp  cop           ,\n      AD<Base>       &returnValue   ,\n      const AD<Base> &left          ,\n      const AD<Base> &right         ,\n      const AD<Base> &trueCase      ,\n      const AD<Base> &falseCase\n   );\n\npublic:\n   // public function only used by CppAD::Independent\n   template <class ADBaseVector>\n   void Independent(\n      ADBaseVector&   x              ,\n      size_t          abort_op_index ,\n      bool            record_compare ,\n      ADBaseVector&   dynamic\n   );\n\n};\n// ---------------------------------------------------------------------------\n// Private functions\n//\n\n/*!\nPlace a parameter in the tape as a variable.\n\nOn rare occasions it is necessary to place a parameter in the tape; e.g.,\nwhen it is one of the dependent variables.\n\n\\param y\nvalue of the parameter that we are placing in the tape as a variable.\n\n\\return\nvariable index (for this recording) corresponding to the parameter.\n\n\\par 2DO\nAll these operates are preformed in Rec_, so we should\nmove this routine from <tt>ADTape<Base></tt> to <tt>recorder<Base></tt>.\n*/\ntemplate <class Base>\naddr_t ADTape<Base>::RecordParOp(const AD<Base>& y)\n{  CPPAD_ASSERT_UNKNOWN( NumRes(ParOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumArg(ParOp) == 1 );\n   addr_t z_taddr = Rec_.PutOp(ParOp);\n   if( Dynamic(y) )\n   {  addr_t ind  = y.taddr_;\n      Rec_.PutArg(ind);\n   }\n   else\n   {  addr_t ind  = Rec_.put_con_par(y.value_);\n      Rec_.PutArg(ind);\n   }\n   return z_taddr;\n}\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/atom_state.hpp",
    "content": "# ifndef CPPAD_LOCAL_ATOM_STATE_HPP\n# define CPPAD_LOCAL_ATOM_STATE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n\nenum enum_atom_state {\n   /// next AFunOp marks beginning of a atomic function call\n   start_atom,\n\n   /// next FunapOp (FunavOp) is a parameter (variable) argument\n   arg_atom,\n\n   /// next FunrpOp (FunrvOp) is a parameter (variable) result\n   ret_atom,\n\n   /// next AFunOp marks end of a atomic function call\n   end_atom\n};\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/atomic_index.hpp",
    "content": "# ifndef CPPAD_LOCAL_ATOMIC_INDEX_HPP\n# define CPPAD_LOCAL_ATOMIC_INDEX_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*!\n{xrst_begin atomic_index dev}\n\nStore and Retrieve Atomic Function Information by Index\n#######################################################\n\nSyntax\n******\n| *index_out* = ``local::atomic_index<`` *Base* >(\n| |tab| *set_null* , *index_in* , *type* , *name* , *ptr*\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ATOMIC_INDEX\n   // END_PROTOTYPE\n}\n\nBase\n****\nIs the base type for the tape for the atomic functions\nthat we are using an index to identify.\n\nGet Number Case\n***************\nThe get number case is defined by\n*set_null* is true and *index_in* is zero.\nFor this case, *index_out* is set to\nthe number of atomic functions stored in ``atomic_index`` < *Base* >\nand no information is stored or changed.\nIn this case, the atomic functions correspond to *index_in* from\none to *index_out* inclusive.\n\nset_null\n********\nIf *set_null* is true and *index_in* is zero,\nthis argument is just used to signal the get number case.\nOtherwise, *set_null*\nshould only be true during a call to an atomic function destructor.\nIn this case, the *ptr* corresponding to *index_in*\nis set to null\n(so that CppAD knows the corresponding atomic function no longer works).\n\nindex_in\n********\nIf *index_in* is zero and *set_null* is true,\nthis argument is just used to signal the get number case.\nOtherwise, see below:\n\nzero\n====\nThe value *index_in* should only be zero\nduring a call to an atomic function constructor.\nIn this case, a copy of the input value of\n*type* , * *name* , and *ptr* are stored.\nThe value *index_out*\nis the *index_in* value corresponding to these input values.\n\nnon-zero\n========\nIf *index_in* is non-zero,\nthe information corresponding to this index is returned.\n\ntype\n****\nThis argument is not used in the get number case.\nOtherwise if *index_in* is zero, *type* is an input.\nOtherwise it is set to the value corresponding to *index_in* .\nThe type corresponding to an index is intended to be\n2 for :ref:`atomic_two-name` functions,\n3 for :ref:`atomic_three-name` functions, and\n4 for :ref:`atomic_four-name` functions,\n\nname\n****\nThis argument is not used in the get number case.\nOtherwise if *index_in* is zero,\n*name* is an input and must not be null.\nOtherwise, if *name* is not null, * *name*\nis set to the name corresponding to *index_in* .\nAllowing for *name* to be null avoids\na string copy when it is not needed.\n\nptr\n***\nThis argument is not used in the get number case.\nOtherwise if *index_in* is zero, *ptr* is an input.\nOtherwise it is set to the value corresponding to *index_in* .\nIn the special case where *set_null* is true,\n*ptr* is set to the null pointer and this is the *ptr* value\ncorresponding to *index_in* for future calls to ``atomic_index`` .\n\nindex_out\n*********\nIn the get number case, this is the number of atomic functions.\nOtherwise if *index_in* is zero,\n*index_out* is non-zero and is the *index_in* value\ncorresponding to the input values for\n*type* , * *name* , and *ptr* .\nOtherwise, *index_out* is zero.\n\n{xrst_end atomic_index}\n*/\n# include <vector>\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n\nstruct atomic_index_info {\n   size_t      type;\n   std::string name;\n   void*       ptr;\n};\n\n// BEGIN_ATOMIC_INDEX\ntemplate <class Base>\nsize_t atomic_index(\n   bool               set_null      ,\n   const size_t&      index_in      ,\n   size_t&            type          ,\n   std::string*       name          ,\n   void*&             ptr           )\n// END_PROTOTYPE\n{  //\n   // information for each index\n   static std::vector<atomic_index_info> vec;\n# ifndef NDEBUG\n   if( index_in == 0 || set_null )\n   {  CPPAD_ASSERT_KNOWN( ! thread_alloc::in_parallel(),\n      \"calling atomic function constructor or destructor in parallel mode\"\n      );\n   }\n# endif\n   if( set_null & (index_in == 0) )\n      return vec.size();\n   //\n   // case were we are retrieving information for an atomic function\n   if( 0 < index_in )\n   {  CPPAD_ASSERT_UNKNOWN( index_in <= vec.size() )\n      //\n      // case where we are setting the pointer to null\n      if( set_null )\n         vec[index_in-1].ptr = nullptr;\n      //\n      atomic_index_info& entry = vec[index_in - 1];\n      type = entry.type;\n      ptr  = entry.ptr;\n      if( name != nullptr )\n         *name  = entry.name;\n      return 0;\n   }\n   //\n   // case where we are storing information for an atomic function\n   atomic_index_info entry;\n   entry.type = type;\n   entry.name = *name;\n   entry.ptr  = ptr;\n   vec.push_back(entry);\n   //\n   return vec.size();\n}\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/color_general.hpp",
    "content": "# ifndef CPPAD_LOCAL_COLOR_GENERAL_HPP\n# define CPPAD_LOCAL_COLOR_GENERAL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/configure.hpp>\n# include <cppad/local/cppad_colpack.hpp>\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*!\n\\file color_general.hpp\nColoring algorithm for a general sparse matrix.\n*/\n// --------------------------------------------------------------------------\n/*!\nDetermine which rows of a general sparse matrix can be computed together;\ni.e., do not have non-zero entries with the same column index.\n\n\\tparam SizeVector\nis a simple vector class with elements of type size_t.\n\n\\tparam SetVector\nis vector_of_sets class.\n\n\\param pattern [in]\nIs a representation of the sparsity pattern for the matrix.\n\n\\param row [in]\nis a vector specifying which row indices to compute.\n\n\\param col [in]\nis a vector, with the same size as row,\nthat specifies which column indices to compute.\nFor each  valid index k, the index pair\n<code>(row[k], col[k])</code> must be present in the sparsity pattern.\nIt may be that some entries in the sparsity pattern do not need to be computed;\ni.e, do not appear in the set of\n<code>(row[k], col[k])</code> entries.\n\n\\param color [out]\nis a vector with size m.\nThe input value of its elements does not matter.\nUpon return, it is a coloring for the rows of the sparse matrix.\n\\n\n\\n\nIf for some i, <code>color[i] == m</code>, then\nthe i-th row does not appear in the vector row.\nOtherwise, <code>color[i] < m</code>.\n\\n\n\\n\nSuppose two different rows, <code>i != r</code> have the same color and\ncolumn index j is such that both of the pairs\n<code>(i, j)</code> and <code>(r, j)</code> appear in the sparsity pattern.\nIt follows that neither of these pairs appear in the set of\n<code>(row[k], col[k])</code> entries.\n\\n\n\\n\nThis routine tries to minimize, with respect to the choice of colors,\nthe maximum, with respct to k, of <code>color[ row[k] ]</code>\n(not counting the indices k for which row[k] == m).\n*/\ntemplate <class SetVector, class SizeVector>\nvoid color_general_cppad(\n   const SetVector&        pattern ,\n   const SizeVector&       row     ,\n   const SizeVector&       col     ,\n   CppAD::vector<size_t>&  color   )\n{\n   size_t K = row.size();\n   size_t m = pattern.n_set();\n   size_t n = pattern.end();\n\n   CPPAD_ASSERT_UNKNOWN( size_t( col.size() )   == K );\n   CPPAD_ASSERT_UNKNOWN( size_t( color.size() ) == m );\n\n   // We define the set of rows, columns, and pairs that appear\n   // by the set ( row[k], col[k] ) for k = 0, ... , K-1.\n\n   // initialize rows that appear\n   CppAD::vector<bool> row_appear(m);\n   for(size_t i = 0; i < m; i++)\n         row_appear[i] = false;\n\n   // rows and columns that appear\n   SetVector c2r_appear, r2c_appear;\n   c2r_appear.resize(n, m);\n   r2c_appear.resize(m, n);\n   for(size_t k = 0;  k < K; k++)\n   {  CPPAD_ASSERT_KNOWN( pattern.is_element(row[k], col[k]) ,\n         \"color_general_cppad: requesting value for a matrix element\\n\"\n         \"that is not in the matrice's sparsity pattern.\\n\"\n         \"Such a value must be zero.\"\n      );\n      row_appear[ row[k] ] = true;\n      c2r_appear.post_element(col[k], row[k]);\n      r2c_appear.post_element(row[k], col[k]);\n   }\n   // process posts\n   for(size_t j = 0; j < n; ++j)\n      c2r_appear.process_post(j);\n   for(size_t i = 0; i < m; ++i)\n      r2c_appear.process_post(i);\n\n   // for each column, which rows are non-zero and do not appear\n   SetVector not_appear;\n   not_appear.resize(n, m);\n   for(size_t i = 0; i < m; i++)\n   {  typename SetVector::const_iterator pattern_itr(pattern, i);\n      size_t j = *pattern_itr;\n      while( j != pattern.end() )\n      {  if( ! c2r_appear.is_element(j , i) )\n            not_appear.post_element(j, i);\n         j = *(++pattern_itr);\n      }\n   }\n   // process posts\n   for(size_t j = 0; j < n; ++j)\n      not_appear.process_post(j);\n\n   // initial coloring\n   color.resize(m);\n   size_t ell = 0;\n   for(size_t i = 0; i < m; i++)\n   {  if( row_appear[i] )\n         color[i] = ell++;\n      else\n         color[i] = m;\n   }\n   /*\n   See GreedyPartialD2Coloring Algorithm Section 3.6.2 of\n   Graph Coloring in Optimization Revisited by\n   Assefaw Gebremedhin, Fredrik Maane, Alex Pothen\n\n   The algorithm above was modified (by Brad Bell) to take advantage of the\n   fact that only the entries (subset of the sparsity pattern) specified by\n   row and col need to be computed.\n   */\n   CppAD::vector<bool> forbidden(m);\n   for(size_t i = 1; i < m; i++) // for each row that appears\n   if( color[i] < m )\n   {\n      // initial all colors as ok for this row\n      // (value of forbidden for ell > initial color[i] does not matter)\n      for(ell = 0; ell <= color[i]; ell++)\n         forbidden[ell] = false;\n\n      // -----------------------------------------------------\n      // Forbid colors for which this row would destroy results:\n      //\n      // for each column that is non-zero for this row\n      typename SetVector::const_iterator pattern_itr(pattern, i);\n      size_t j = *pattern_itr;\n      while( j != pattern.end() )\n      {  // for each row that appears with this column\n         typename SetVector::const_iterator c2r_itr(c2r_appear, j);\n         size_t r = *c2r_itr;\n         while( r != c2r_appear.end() )\n         {  // if this is not the same row, forbid its color\n            if( (r < i) && (color[r] < m) )\n               forbidden[ color[r] ] = true;\n            r = *(++c2r_itr);\n         }\n         j = *(++pattern_itr);\n      }\n\n\n      // -----------------------------------------------------\n      // Forbid colors that destroy results needed for this row.\n      //\n      // for each column that appears with this row\n      typename SetVector::const_iterator r2c_itr(r2c_appear, i);\n      j = *r2c_itr;\n      while( j != r2c_appear.end() )\n      {  // For each row that is non-zero for this column\n         // (the appear rows have already been checked above).\n         typename SetVector::const_iterator not_itr(not_appear, j);\n         size_t r = *not_itr;\n         while( r != not_appear.end() )\n         {  // if this is not the same row, forbid its color\n            if( (r < i) && (color[r] < m) )\n               forbidden[ color[r] ] = true;\n            r = *(++not_itr);\n         }\n         j = *(++r2c_itr);\n      }\n\n      // pick the color with smallest index\n      ell = 0;\n      while( forbidden[ell] )\n      {  ell++;\n         CPPAD_ASSERT_UNKNOWN( ell <= color[i] );\n      }\n      color[i] = ell;\n   }\n   return;\n}\n\n# if CPPAD_HAS_COLPACK\n/*!\nColpack version of determining which rows of a sparse matrix\ncan be computed together.\n\n\\copydetails color_general\n*/\ntemplate <class SetVector, class SizeVector>\nvoid color_general_colpack(\n   const SetVector&        pattern ,\n   const SizeVector&       row     ,\n   const SizeVector&       col     ,\n   CppAD::vector<size_t>&  color   )\n{\n   size_t m = pattern.n_set();\n   size_t n = pattern.end();\n\n   // Determine number of non-zero entries in each row\n   CppAD::vector<size_t> n_nonzero(m);\n   size_t n_nonzero_total = 0;\n   for(size_t i = 0; i < m; i++)\n   {  n_nonzero[i] = 0;\n      typename SetVector::const_iterator pattern_itr(pattern, i);\n      size_t j = *pattern_itr;\n      while( j != pattern.end() )\n      {  n_nonzero[i]++;\n         j = *(++pattern_itr);\n      }\n      n_nonzero_total += n_nonzero[i];\n   }\n\n   // Allocate memory and fill in Adolc sparsity pattern\n   CppAD::vector<unsigned int*> adolc_pattern(m);\n   CppAD::vector<unsigned int>  adolc_memory(m + n_nonzero_total);\n   size_t i_memory = 0;\n   for(size_t i = 0; i < m; i++)\n   {  adolc_pattern[i]    = adolc_memory.data() + i_memory;\n      CPPAD_ASSERT_KNOWN(\n         std::numeric_limits<unsigned int>::max() >= n_nonzero[i],\n         \"Matrix is too large for colpack\"\n      );\n      adolc_pattern[i][0] = static_cast<unsigned int>( n_nonzero[i] );\n      typename SetVector::const_iterator pattern_itr(pattern, i);\n      size_t j = *pattern_itr;\n      size_t k = 1;\n      while(j != pattern.end() )\n      {\n         CPPAD_ASSERT_KNOWN(\n            std::numeric_limits<unsigned int>::max() >= j,\n            \"Matrix is too large for colpack\"\n         );\n         adolc_pattern[i][k++] = static_cast<unsigned int>( j );\n         j = *(++pattern_itr);\n      }\n      CPPAD_ASSERT_UNKNOWN( k == 1 + n_nonzero[i] );\n      i_memory += k;\n   }\n   CPPAD_ASSERT_UNKNOWN( i_memory == m + n_nonzero_total );\n\n   // Must use an external routine for this part of the calculation because\n   // ColPack/ColPackHeaders.h has as 'using namespace std' at global level.\n   cppad_colpack_general(color, m, n, adolc_pattern);\n\n   return;\n}\n# endif // CPPAD_HAS_COLPACK\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/color_symmetric.hpp",
    "content": "# ifndef CPPAD_LOCAL_COLOR_SYMMETRIC_HPP\n# define CPPAD_LOCAL_COLOR_SYMMETRIC_HPP\n# include <cppad/configure.hpp>\n# include <cppad/local/cppad_colpack.hpp>\n\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*!\n\\file color_symmetric.hpp\nColoring algorithm for a symmetric sparse matrix.\n*/\n// --------------------------------------------------------------------------\n/*!\nCppAD algorithm for determining which rows of a symmetric sparse matrix can be\ncomputed together.\n\n\\tparam SizeVector\nis a simple vector class with elements of type size_t.\n\n\\tparam SetVector\nis a vector_of_sets class.\n\n\\param pattern [in]\nIs a representation of the sparsity pattern for the matrix.\n\n\\param row [in/out]\nis a vector specifying which row indices to compute.\n\n\\param col [in/out]\nis a vector, with the same size as row,\nthat specifies which column indices to compute.\n\\n\n\\n\nInput:\nFor each  valid index k, the index pair\n<code>(row[k], col[k])</code> must be present in the sparsity pattern.\nIt may be that some entries in the sparsity pattern do not need to be computed;\ni.e, do not appear in the set of\n<code>(row[k], col[k])</code> entries.\n\\n\n\\n\nOutput:\nOn output, some of row and column indices may have been swapped\n\\code\n   std::swap( row[k], col[k] )\n\\endcode\nSo the the the color for row[k] can be used to compute entry\n(row[k], col[k]).\n\n\\param color [out]\nis a vector with size m.\nThe input value of its elements does not matter.\nUpon return, it is a coloring for the rows of the sparse matrix.\nNote that if color[i] == m, then there is no index k for which\nrow[k] == i (for the return value of row).\n\\n\n\\n\nFix any (i, j) in the sparsity pattern.\nSuppose that there is a row index i1 with\ni1 != i, color[i1] == color[i] and (i1, j) is in the sparsity pattern.\nIf follows that for all j1 with\nj1 != j and color[j1] == color[j],\n(j1, i ) is not in the sparsity pattern.\n\\n\n\\n\nThis routine tries to minimize, with respect to the choice of colors,\nthe maximum, with respect to k, of <code>color[ row[k] ]</code>.\n*/\ntemplate <class SetVector>\nvoid color_symmetric_cppad(\n   const SetVector&        pattern   ,\n   CppAD::vector<size_t>&  row       ,\n   CppAD::vector<size_t>&  col       ,\n   CppAD::vector<size_t>&  color     )\n{\n   size_t K = row.size();\n   size_t m = pattern.n_set();\n   CPPAD_ASSERT_UNKNOWN( m == pattern.end() );\n   CPPAD_ASSERT_UNKNOWN( color.size() == m );\n   CPPAD_ASSERT_UNKNOWN( col.size()   == K );\n\n   // row, column pairs that appear in ( row[k], col[k] )\n   CppAD::vector< std::set<size_t> > pair_needed(m);\n   std::set<size_t>::iterator itr1, itr2;\n   for(size_t k1 = 0;  k1 < K; k1++)\n   {  CPPAD_ASSERT_UNKNOWN( pattern.is_element(row[k1], col[k1]) );\n      pair_needed[ row[k1] ].insert( col[k1] );\n      pair_needed[ col[k1] ].insert( row[k1] );\n   }\n\n   // order the rows descending by number of pairs needed\n   CppAD::vector<size_t> key(m), order2row(m);\n   for(size_t i1 = 0; i1 < m; i1++)\n   {  CPPAD_ASSERT_UNKNOWN( pair_needed[i1].size() <= m );\n      key[i1] = m - pair_needed[i1].size();\n   }\n   CppAD::index_sort(key, order2row);\n\n   // mapping from order index to row index\n   CppAD::vector<size_t> row2order(m);\n   for(size_t o1 = 0; o1 < m; o1++)\n      row2order[ order2row[o1] ] = o1;\n\n   // initial coloring\n   color.resize(m);\n   size_t c1 = 0;\n   for(size_t o1 = 0; o1 < m; o1++)\n   {  size_t i1 = order2row[o1];\n      if( pair_needed[i1].empty() )\n         color[i1] = m;\n      else\n         color[i1] = c1++;\n   }\n\n   // which colors are forbidden for this row\n   CppAD::vector<bool> forbidden(m);\n\n   // must start with row zero so that we remove results computed for it\n   for(size_t o1 = 0; o1 < m; o1++) // for each row that appears (in order)\n   if( color[ order2row[o1] ] < m )\n   {  size_t i1 = order2row[o1];\n      c1 = color[i1];\n\n      // initial all colors as ok for this row\n      // (value of forbidden for c > c1 does not matter)\n      for(size_t c2 = 0; c2 <= c1; c2++)\n         forbidden[c2] = false;\n\n      // -----------------------------------------------------\n      // Forbid grouping with rows that would destroy results that are\n      // needed for this row.\n      itr1 = pair_needed[i1].begin();\n      while( itr1 != pair_needed[i1].end() )\n      {  // entry (i1, j1) is needed for this row\n         size_t j1 = *itr1;\n\n         // Forbid rows i2 != i1 that have non-zero sparsity at (i2, j1).\n         // Note that this is the same as non-zero sparsity at (j1, i2)\n         typename SetVector::const_iterator pattern_itr(pattern, j1);\n         size_t i2 = *pattern_itr;\n         while( i2 != pattern.end() )\n         {  size_t c2 = color[i2];\n            if( c2 < c1 )\n               forbidden[c2] = true;\n            i2 = *(++pattern_itr);\n         }\n         itr1++;\n      }\n      // -----------------------------------------------------\n      // Forbid grouping with rows that this row would destroy results for\n      for(size_t o2 = 0; o2 < o1; o2++)\n      {  size_t i2 = order2row[o2];\n         size_t c2 = color[i2];\n         itr2 = pair_needed[i2].begin();\n         while( itr2 != pair_needed[i2].end() )\n         {  size_t j2 = *itr2;\n            // row i2 needs pair (i2, j2).\n            // Forbid grouping with i1 if (i1, j2) has non-zero sparsity\n            if( pattern.is_element(i1, j2) )\n               forbidden[c2] = true;\n            itr2++;\n         }\n      }\n\n      // pick the color with smallest index\n      size_t c2 = 0;\n      while( forbidden[c2] )\n      {  c2++;\n         CPPAD_ASSERT_UNKNOWN( c2 <= c1 );\n      }\n      color[i1] = c2;\n\n      // no longer need results that are computed by this row\n      itr1 = pair_needed[i1].begin();\n      while( itr1 != pair_needed[i1].end() )\n      {  size_t j1 = *itr1;\n         if( row2order[j1] > o1 )\n         {  itr2 = pair_needed[j1].find(i1);\n            if( itr2 != pair_needed[j1].end() )\n            {  pair_needed[j1].erase(itr2);\n               if( pair_needed[j1].empty() )\n                  color[j1] = m;\n            }\n         }\n         itr1++;\n      }\n   }\n\n   // determine which sparsity entries need to be reflected\n   for(size_t k1 = 0; k1 < row.size(); k1++)\n   {  size_t i1   = row[k1];\n      size_t j1   = col[k1];\n      itr1 = pair_needed[i1].find(j1);\n      if( itr1 == pair_needed[i1].end() )\n      {  row[k1] = j1;\n         col[k1] = i1;\n# ifndef NDEBUG\n         itr1 = pair_needed[j1].find(i1);\n         CPPAD_ASSERT_UNKNOWN( itr1 != pair_needed[j1].end() );\n# endif\n      }\n   }\n   return;\n}\n\n// --------------------------------------------------------------------------\n/*!\nColpack algorithm for determining which rows of a symmetric sparse matrix\ncan be computed together.\n\n\\copydetails CppAD::local::color_symmetric_cppad\n*/\ntemplate <class SetVector>\nvoid color_symmetric_colpack(\n   const SetVector&        pattern   ,\n   CppAD::vector<size_t>&  row       ,\n   CppAD::vector<size_t>&  col       ,\n   CppAD::vector<size_t>&  color     )\n{\n# if ! CPPAD_HAS_COLPACK\n   CPPAD_ASSERT_UNKNOWN(false);\n   return;\n# else\n   size_t i, j, k;\n   size_t m = pattern.n_set();\n   CPPAD_ASSERT_UNKNOWN( m == pattern.end() );\n   CPPAD_ASSERT_UNKNOWN( row.size() == col.size() );\n\n   // Determine number of non-zero entries in each row\n   CppAD::vector<size_t> n_nonzero(m);\n   size_t n_nonzero_total = 0;\n   for(i = 0; i < m; i++)\n   {  n_nonzero[i] = 0;\n      typename SetVector::const_iterator pattern_itr(pattern, i);\n      j = *pattern_itr;\n      while( j != pattern.end() )\n      {  n_nonzero[i]++;\n         j = *(++pattern_itr);\n      }\n      n_nonzero_total += n_nonzero[i];\n   }\n\n   // Allocate memory and fill in Adolc sparsity pattern\n   CppAD::vector<unsigned int*> adolc_pattern(m);\n   CppAD::vector<unsigned int>  adolc_memory(m + n_nonzero_total);\n   size_t i_memory = 0;\n   for(i = 0; i < m; i++)\n   {  adolc_pattern[i]    = adolc_memory.data() + i_memory;\n      CPPAD_ASSERT_KNOWN(\n         std::numeric_limits<unsigned int>::max() >= n_nonzero[i],\n         \"Matrix is too large for colpack\"\n      );\n      adolc_pattern[i][0] = static_cast<unsigned int>( n_nonzero[i] );\n      typename SetVector::const_iterator pattern_itr(pattern, i);\n      j = *pattern_itr;\n      k = 1;\n      while(j != pattern.end() )\n      {\n         CPPAD_ASSERT_KNOWN(\n            std::numeric_limits<unsigned int>::max() >= j,\n            \"Matrix is too large for colpack\"\n         );\n         adolc_pattern[i][k++] = static_cast<unsigned int>( j );\n         j = *(++pattern_itr);\n      }\n      CPPAD_ASSERT_UNKNOWN( k == 1 + n_nonzero[i] );\n      i_memory += k;\n   }\n   CPPAD_ASSERT_UNKNOWN( i_memory == m + n_nonzero_total );\n\n   // Must use an external routine for this part of the calculation because\n   // ColPack/ColPackHeaders.h has as 'using namespace std' at global level.\n   cppad_colpack_symmetric(color, m, adolc_pattern);\n\n   // determine which sparsity entries need to be reflected\n   for(size_t k1 = 0; k1 < row.size(); k1++)\n   {  size_t i1 = row[k1];\n      size_t j1 = col[k1];\n      bool reflect = false;\n      for(size_t i2 = 0; i2 < m; i2++)\n      if( (i1 != i2) && (color[i1]==color[i2]) )\n      {  for(size_t k2 = 1; k2 <= adolc_pattern[i2][0]; k2++)\n         {  size_t j2 = adolc_pattern[i2][k2];\n            reflect |= (j1 == j2);\n         }\n      }\n      if( reflect )\n      {  row[k1] = j1;\n         col[k1] = i1;\n      }\n   }\n   return;\n# endif // CPPAD_HAS_COLPACK\n}\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/cppad_colpack.hpp",
    "content": "# ifndef CPPAD_LOCAL_CPPAD_COLPACK_HPP\n# define CPPAD_LOCAL_CPPAD_COLPACK_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# if CPPAD_HAS_COLPACK\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*!\n\\file cppad_colpack.hpp\nExternal interface to Colpack routines used by cppad.\n*/\n// ---------------------------------------------------------------------------\n/*!\nLink from CppAD to ColPack used for general sparse matrices.\n\nThis CppAD library routine is necessary because\n<code>ColPack/ColPackHeaders.h</code> has a\n<code>using namespace std</code> at the global level.\n\n\\param m [in]\nis the number of rows in the sparse matrix\n\n\\param n [in]\nis the number of columns in the sparse matrix.\n\n\\param adolc_pattern [in]\nThis vector has size m,\n<code>adolc_pattern[i][0]</code> is the number of non-zeros in row i.\nFor <code>j = 1 , ... , adolc_sparsity[i]<code>,\n<code>adolc_pattern[i][j]</code> is the column index (base zero) for the\nnon-zeros in row i.\n\n\\param color [out]\nis a vector with size m.\nThe input value of its elements does not matter.\nUpon return, it is a coloring for the rows of the sparse matrix.\n\\n\n\\n\nIf for some i, <code>color[i] == m</code>, then\n<code>adolc_pattern[i][0] == 0</code>.\nOtherwise, <code>color[i] < m</code>.\n\\n\n\\n\nSuppose two different rows, <code>i != r</code> have the same color.\nIt follows that for all column indices j;\nit is not the case that both\n<code>(i, j)</code> and <code>(r, j)</code> appear in the sparsity pattern.\n\\n\n\\n\nThis routine tries to minimize, with respect to the choice of colors,\nthe number of colors.\n*/\nCPPAD_LIB_EXPORT void cppad_colpack_general(\n          CppAD::vector<size_t>&         color         ,\n   size_t                               m             ,\n   size_t                               n             ,\n   const CppAD::vector<unsigned int*>&  adolc_pattern\n);\n\n/*!\nLink from CppAD to ColPack used for symmetric sparse matrices\n(not yet used or tested).\n\nThis CppAD library routine is necessary because\n<code>ColPack/ColPackHeaders.h</code> has a\n<code>using namespace std</code> at the global level.\n\n\\param n [in]\nis the number of rows and columns in the symmetric sparse matrix.\n\n\\param adolc_pattern [in]\nThis vector has size n,\n<code>adolc_pattern[i][0]</code> is the number of non-zeros in row i.\nFor <code>j = 1 , ... , adolc_sparsity[i]<code>,\n<code>adolc_pattern[i][j]</code> is the column index (base zero) for the\nnon-zeros in row i.\n\n\\param color [out]\nThe input value of its elements does not matter.\nUpon return, it is a coloring for the rows of the sparse matrix.\nThe properties of this coloring have not yet been determined; see\nEfficient Computation of Sparse Hessians Using Coloring\nand Automatic Differentiation (pdf/ad/gebemedhin14.pdf)\n*/\nCPPAD_LIB_EXPORT void cppad_colpack_symmetric(\n          CppAD::vector<size_t>&         color         ,\n   size_t                               n             ,\n   const CppAD::vector<unsigned int*>&  adolc_pattern\n);\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n\n# endif\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/declare_ad.hpp",
    "content": "# ifndef CPPAD_LOCAL_DECLARE_AD_HPP\n# define CPPAD_LOCAL_DECLARE_AD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/configure.hpp>\n# include <cstdint>\n\n/*!\n\\file declare_ad.hpp CppAD forward declarations; i.e., before definition\n*/\n\nnamespace CppAD { namespace local {\n   template <class Base> class ADTape;\n   template <class Base> class player;\n   template <class Base> class dyn_player;\n   template <class Base> class recorder;\n} }\nnamespace CppAD { namespace local { namespace val_graph {\n   template <class Value> class tape_t;\n} } }\n\nnamespace CppAD {\n   // BEGIN_COMPARE_OP\n   enum CompareOp\n   {  // operator // Rel: description\n      CompareLt,  //  Lt: less than\n      CompareLe,  //  Le: less than or equal\n      CompareEq,  //  Eq: equal\n      CompareGe,  //  Ge: greater than or equal\n      CompareGt,  //  Gt: greater than\n      CompareNe   //  Ne: not equal\n   };\n   // END_COMPARE_OP\n\n   // simple typedefs\n   typedef CPPAD_TAPE_ADDR_TYPE addr_t;\n   typedef CPPAD_TAPE_ID_TYPE   tape_id_t;\n\n   // classes\n   class sparse_hes_work;\n   class sparse_jac_work;\n   class sparse_jacobian_work;\n   class sparse_hessian_work;\n   template <class Base> class AD;\n   template <class Base, class RecBase=Base> class ADFun;\n   template <class Base> class atomic_base;\n   template <class Base> class atomic_three;\n   template <class Base> class atomic_four;\n   template <class Base> class discrete;\n   template <class Base> class VecAD;\n   template <class Base> class VecAD_reference;\n\n   // functions with one VecAD<Base> argument\n   template <class Base> bool Constant          (const VecAD<Base> &u);\n   template <class Base> bool Dynamic           (const VecAD<Base> &u);\n   template <class Base> bool Parameter         (const VecAD<Base> &u);\n   template <class Base> bool Variable          (const VecAD<Base> &u);\n\n   // functions with one AD<Base> argument\n   template <class Base> bool Constant          (const AD<Base> &u);\n   template <class Base> bool Dynamic           (const AD<Base> &u);\n   template <class Base> bool Parameter         (const AD<Base> &u);\n   template <class Base> bool Variable          (const AD<Base> &u);\n   //\n   template <class Base> int  Integer           (const AD<Base> &u);\n   template <class Base> bool IdenticalZero     (const AD<Base> &u);\n   template <class Base> bool IdenticalOne      (const AD<Base> &u);\n   template <class Base> bool IdenticalCon      (const AD<Base> &u);\n   template <class Base> bool LessThanZero      (const AD<Base> &u);\n   template <class Base> bool LessThanOrZero    (const AD<Base> &u);\n   template <class Base> bool GreaterThanZero   (const AD<Base> &u);\n   template <class Base> bool GreaterThanOrZero (const AD<Base> &u);\n   template <class Base> AD<Base> Var2Par       (const AD<Base> &u);\n   template <class Base> AD<Base> abs           (const AD<Base> &u);\n   template <class Base> AD<Base> acos          (const AD<Base> &u);\n   template <class Base> AD<Base> asin          (const AD<Base> &u);\n   template <class Base> AD<Base> atan          (const AD<Base> &u);\n   template <class Base> AD<Base> cos           (const AD<Base> &u);\n   template <class Base> AD<Base> cosh          (const AD<Base> &u);\n   template <class Base> AD<Base> exp           (const AD<Base> &u);\n   template <class Base> AD<Base> log           (const AD<Base> &u);\n   template <class Base> AD<Base> log10         (const AD<Base> &u);\n   template <class Base> AD<Base> sin           (const AD<Base> &u);\n   template <class Base> AD<Base> sinh          (const AD<Base> &u);\n   template <class Base> AD<Base> sqrt          (const AD<Base> &u);\n   template <class Base> AD<Base> tan           (const AD<Base> &u);\n   //\n   template <class Base> unsigned short hash_code(const AD<Base>& u);\n\n   // arithematic operators\n   template <class Base> AD<Base> operator + (\n      const AD<Base> &left, const AD<Base> &right);\n   template <class Base> AD<Base> operator - (\n      const AD<Base> &left, const AD<Base> &right);\n   template <class Base> AD<Base> operator * (\n      const AD<Base> &left, const AD<Base> &right);\n   template <class Base> AD<Base> operator / (\n      const AD<Base> &left, const AD<Base> &right);\n\n   // comparison operators\n   template <class Base> bool operator < (\n      const AD<Base> &left, const AD<Base> &right);\n   template <class Base> bool operator <= (\n      const AD<Base> &left, const AD<Base> &right);\n   template <class Base> bool operator > (\n      const AD<Base> &left, const AD<Base> &right);\n   template <class Base> bool operator >= (\n      const AD<Base> &left, const AD<Base> &right);\n   template <class Base> bool operator == (\n      const AD<Base> &left, const AD<Base> &right);\n   template <class Base> bool operator != (\n      const AD<Base> &left, const AD<Base> &right);\n\n   // pow\n   template <class Base> AD<Base> pow (\n      const AD<Base> &x, const AD<Base> &y);\n\n   // azmul\n   template <class Base> AD<Base> azmul (\n      const AD<Base> &x, const AD<Base> &y);\n\n   // NearEqual\n   template <class Base> bool NearEqual(\n   const AD<Base> &x, const AD<Base> &y, const Base &r, const Base &a);\n\n   template <class Base> bool NearEqual(\n   const Base &x, const AD<Base> &y, const Base &r, const Base &a);\n\n   template <class Base> bool NearEqual(\n   const AD<Base> &x, const Base &y, const Base &r, const Base &a);\n\n   // CondExpOp\n   template <class Base> AD<Base> CondExpOp (\n      enum CompareOp         cop ,\n      const AD<Base>       &left ,\n      const AD<Base>      &right ,\n      const AD<Base>   &trueCase ,\n      const AD<Base>  &falseCase\n   );\n\n   // IdenticalEqualCon\n   template <class Base>\n   bool IdenticalEqualCon (const AD<Base> &u, const AD<Base> &v);\n\n   // EqualOpSeq\n   template <class Base>\n   bool EqualOpSeq (const AD<Base> &u, const AD<Base> &v);\n\n   // PrintFor\n   template <class Base>\n   void PrintFor(\n      const AD<Base>&    flag   ,\n      const char*        before ,\n      const AD<Base>&    var    ,\n      const char*        after\n   );\n\n   // Value\n   template <class Base> Base Value(const AD<Base> &x);\n\n   // Pow function\n   template <class Base> AD<Base> pow\n      (const AD<Base> &x, const AD<Base> &y);\n\n   // input operator\n   template <class Base> std::istream&\n      operator >> (std::istream &is, AD<Base> &x);\n\n   // output operator\n   template <class Base> std::ostream&\n      operator << (std::ostream &os, const AD<Base> &x);\n   template <class Base> std::ostream&\n      operator << (std::ostream &os, const VecAD_reference<Base> &e);\n   template <class Base> std::ostream&\n      operator << (std::ostream &os, const VecAD<Base> &vec);\n}\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/define.hpp",
    "content": "# ifndef CPPAD_LOCAL_DEFINE_HPP\n# define CPPAD_LOCAL_DEFINE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*!\n\\file define.hpp\nDefine processor symbols and macros that are used by CppAD.\n*/\n\n/*!\n\\def CPPAD_VEC_ENUM_TYPE\nIs the type used to store vectors of enum values when the vector\nmay be large and we want to conserve memory. The following must hold for\nany enum_value that is stored using the type CPPAD_VEC_ENUM_TYPE:\n<code>\n      size_t(enum_value) <= std::numeric_limits<CPPAD_VEC_ENUM_TYPE>::max()\n      && is_pod<CPPAD_VEC_ENUM_TYPE>\n</code>\n*/\n# define CPPAD_VEC_ENUM_TYPE unsigned char\n\n// ----------------------------------------------------------------------------\n/*!\n\\def CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\nA version of the inline command that works with MC compiler.\n\nMicrosoft Visual C++ version 9.0 generates a warning if a template\nfunction is declared as a friend\n(this was not a problem for version 7.0).\nThe warning identifier is\n\\verbatim\n   warning C4396\n\\endverbatim\nand it contains the text\n\\verbatim\n   the inline specifier cannot be used when a friend declaration refers\n   to a specialization of a function template\n\\endverbatim\nThis happens even if the function is not a specialization.\nThis macro is defined as empty for Microsoft compilers.\n*/\n# ifdef _MSC_VER\n# define CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION\n# else\n# define CPPAD_INLINE_FRIEND_TEMPLATE_FUNCTION inline\n# endif\n\n// ----------------------------------------------------------------------------\n/*!\n\\def CPPAD_LIB_EXPORT\nSpecial macro for exporting windows DLL symbols; see\nhttps://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/BuildingWinDLL\n*/\n/*\nThis commented out code is for building windows shared libraries which\ncurrently does not work for CppAD:\n# ifdef  _MSC_VER\n# ifdef  cppad_lib_EXPORTS\n# define CPPAD_LIB_EXPORT __declspec(dllexport)\n# else\n# define CPPAD_LIB_EXPORT __declspec(dllimport)\n# endif  // cppad_lib_EXPORTS\n# else   // _MSC_VER\n# define CPPAD_LIB_EXPORT\n# endif\n*/\n# define CPPAD_LIB_EXPORT\n\n// ============================================================================\n/*!\n\\def CPPAD_FOLD_ASSIGNMENT_OPERATOR(Op)\nDeclares automatic coercion for certain AD assignment operations.\n\nThis macro assumes that the operator\n\\verbatim\n   left Op right\n\\endverbatim\nis defined for the case where left and right have type AD<Base>.\nIt uses this case to define the cases where\nleft has type AD<Base> and right has type\nVecAD_reference<Base>,\nBase, or\ndouble.\nThe argument right is const and call by reference.\nThis macro converts the operands to AD<Base> and then\nuses the definition of the same operation for that case.\n*/\n\n# define CPPAD_FOLD_ASSIGNMENT_OPERATOR(Op)                             \\\n/* ----------------------------------------------------------------*/   \\\ntemplate <class Base>                                                   \\\nAD<Base>& operator Op                                            \\\n(AD<Base> &left, double right)                                          \\\n{  return left Op AD<Base>(right); }                                  \\\n                                                      \\\ntemplate <class Base>                                                   \\\nAD<Base>& operator Op                                            \\\n(AD<Base> &left, const Base &right)                                     \\\n{  return left Op AD<Base>(right); }                                  \\\n                                                      \\\ninline AD<double>& operator Op                                          \\\n(AD<double> &left, const double &right)                                 \\\n{  return left Op AD<double>(right); }                                \\\n                                                      \\\ntemplate <class Base>                                                   \\\nAD<Base>& operator Op                                            \\\n(AD<Base> &left, const VecAD_reference<Base> &right)                    \\\n{  return left Op right.ADBase(); }\n\n// =====================================================================\n/*!\n\\def CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(Op)\nDeclares automatic coercion for certain binary operations with AD result.\n\nThis macro assumes that the operator\n\\verbatim\n   left Op right\n\\endverbatim\nis defined for the case where left and right\nand the result of the operation all\nhave type AD<Base>.\nIt uses this case to define the cases either left\nor right has type VecAD_reference<Base> or AD<Base>\nand the type of the other operand is one of the following:\nVecAD_reference<Base>, AD<Base>, Base, double.\nAll of the arguments are const and call by reference.\nThis macro converts the operands to AD<Base> and then\nuses the definition of the same operation for that case.\n*/\n# define CPPAD_FOLD_AD_VALUED_BINARY_OPERATOR(Op)                      \\\n/* ----------------------------------------------------------------*/  \\\n/* Operations with VecAD_reference<Base> and AD<Base> only*/           \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nAD<Base> operator Op                                            \\\n(const AD<Base> &left, const VecAD_reference<Base> &right)             \\\n{  return left Op right.ADBase(); }                                  \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nAD<Base> operator Op                                            \\\n(const VecAD_reference<Base> &left, const VecAD_reference<Base> &right)\\\n{  return left.ADBase() Op right.ADBase(); }                         \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nAD<Base> operator Op                                            \\\n   (const VecAD_reference<Base> &left, const AD<Base> &right)        \\\n{  return left.ADBase() Op right; }                                  \\\n/* ----------------------------------------------------------------*/  \\\n/* Operations Base */                                                  \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nAD<Base> operator Op                                            \\\n   (const Base &left, const AD<Base> &right)                         \\\n{  return AD<Base>(left) Op right; }                                 \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nAD<Base> operator Op                                            \\\n   (const Base &left, const VecAD_reference<Base> &right)            \\\n{  return AD<Base>(left) Op right.ADBase(); }                        \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nAD<Base> operator Op                                            \\\n   (const AD<Base> &left, const Base &right)                         \\\n{  return left Op AD<Base>(right); }                                 \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nAD<Base> operator Op                                            \\\n   (const VecAD_reference<Base> &left, const Base &right)            \\\n{  return left.ADBase() Op AD<Base>(right); }                        \\\n                                                                       \\\n/* ----------------------------------------------------------------*/  \\\n/* Operations double */                                                \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nAD<Base> operator Op                                            \\\n   (const double &left, const AD<Base> &right)                       \\\n{  return AD<Base>(left) Op right; }                                 \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nAD<Base> operator Op                                            \\\n   (const double &left, const VecAD_reference<Base> &right)          \\\n{  return AD<Base>(left) Op right.ADBase(); }                        \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nAD<Base> operator Op                                            \\\n   (const AD<Base> &left, const double &right)                       \\\n{  return left Op AD<Base>(right); }                                 \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nAD<Base> operator Op                                            \\\n   (const VecAD_reference<Base> &left, const double &right)          \\\n{  return left.ADBase() Op AD<Base>(right); }                        \\\n/* ----------------------------------------------------------------*/  \\\n/* Special case to avoid ambiguity when Base is double */              \\\n                                                                       \\\ninline AD<double> operator Op                                          \\\n   (const double &left, const AD<double> &right)                     \\\n{  return AD<double>(left) Op right; }                               \\\n                                                                       \\\ninline AD<double> operator Op                                          \\\n   (const double &left, const VecAD_reference<double> &right)        \\\n{  return AD<double>(left) Op right.ADBase(); }                      \\\n                                                                       \\\ninline AD<double> operator Op                                          \\\n   (const AD<double> &left, const double &right)                     \\\n{  return left Op AD<double>(right); }                               \\\n                                                                       \\\ninline AD<double> operator Op                                          \\\n   (const VecAD_reference<double> &left, const double &right)        \\\n{  return left.ADBase() Op AD<double>(right); }\n\n// =======================================================================\n\n/*!\n\\def CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(Op)\nDeclares automatic coercion for certain binary operations with bool result.\n\nThis macro assumes that the operator\n\\verbatim\n   left Op right\n\\endverbatim\nis defined for the case where left and right\nhave type AD<Base> and the result has type bool.\nIt uses this case to define the cases either left\nor right has type\nVecAD_reference<Base> or AD<Base>\nand the type of the other operand is one of the following:\nVecAD_reference<Base>, AD<Base>, Base, double.\nAll of the arguments are const and call by reference.\nThis macro converts the operands to AD<Base> and then\nuses the definition of the same operation for that case.\n*/\n# define CPPAD_FOLD_BOOL_VALUED_BINARY_OPERATOR(Op)                    \\\n/* ----------------------------------------------------------------*/  \\\n/* Operations with VecAD_reference<Base> and AD<Base> only*/           \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nbool operator Op                                                \\\n(const AD<Base> &left, const VecAD_reference<Base> &right)             \\\n{  return left Op right.ADBase(); }                                  \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nbool operator Op                                                \\\n(const VecAD_reference<Base> &left, const VecAD_reference<Base> &right)\\\n{  return left.ADBase() Op right.ADBase(); }                         \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nbool operator Op                                                \\\n   (const VecAD_reference<Base> &left, const AD<Base> &right)        \\\n{  return left.ADBase() Op right; }                                  \\\n/* ----------------------------------------------------------------*/  \\\n/* Operations Base */                                                  \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nbool operator Op                                                \\\n   (const Base &left, const AD<Base> &right)                         \\\n{  return AD<Base>(left) Op right; }                                 \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nbool operator Op                                                \\\n   (const Base &left, const VecAD_reference<Base> &right)            \\\n{  return AD<Base>(left) Op right.ADBase(); }                        \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nbool operator Op                                                \\\n   (const AD<Base> &left, const Base &right)                         \\\n{  return left Op AD<Base>(right); }                                 \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nbool operator Op                                                \\\n   (const VecAD_reference<Base> &left, const Base &right)            \\\n{  return left.ADBase() Op AD<Base>(right); }                        \\\n                                                                       \\\n/* ----------------------------------------------------------------*/  \\\n/* Operations double */                                                \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nbool operator Op                                                \\\n   (const double &left, const AD<Base> &right)                       \\\n{  return AD<Base>(left) Op right; }                                 \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nbool operator Op                                                \\\n   (const double &left, const VecAD_reference<Base> &right)          \\\n{  return AD<Base>(left) Op right.ADBase(); }                        \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nbool operator Op                                                \\\n   (const AD<Base> &left, const double &right)                       \\\n{  return left Op AD<Base>(right); }                                 \\\n                                                                       \\\ntemplate <class Base>                                                  \\\nbool operator Op                                                \\\n   (const VecAD_reference<Base> &left, const double &right)          \\\n{  return left.ADBase() Op AD<Base>(right); }                        \\\n/* ----------------------------------------------------------------*/  \\\n/* Special case to avoid ambiguity when Base is double */              \\\n                                                                       \\\ninline bool operator Op                                                \\\n   (const double &left, const AD<double> &right)                     \\\n{  return AD<double>(left) Op right; }                               \\\n                                                                       \\\ninline bool operator Op                                                \\\n   (const double &left, const VecAD_reference<double> &right)        \\\n{  return AD<double>(left) Op right.ADBase(); }                      \\\n                                                                       \\\ninline bool operator Op                                                \\\n   (const AD<double> &left, const double &right)                     \\\n{  return left Op AD<double>(right); }                               \\\n                                                                       \\\ninline bool operator Op                                                \\\n   (const VecAD_reference<double> &left, const double &right)        \\\n{  return left.ADBase() Op AD<double>(right); }\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/graph/cpp_graph_itr.hpp",
    "content": "# ifndef CPPAD_LOCAL_GRAPH_CPP_GRAPH_ITR_HPP\n# define CPPAD_LOCAL_GRAPH_CPP_GRAPH_ITR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/utility/vector.hpp>\n# include <cppad/local/graph/cpp_graph_op.hpp>\n\n// BEGIN_CPPAD_LOCAL_GRAPH_NAMESPACE\nnamespace CppAD { namespace local { namespace graph {\n\nclass cpp_graph_itr {\n/*\n{xrst_begin cpp_graph_itr_data dev}\n\nC++ AD Graph Iterator Private Member Data\n#########################################\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   // values set by constructor\n   const vector<graph_op_enum>*   operator_vec_;\n   const vector<size_t>*          operator_arg_;\n   //\n   // set by constructor and ++\n   size_t                         op_index_;\n   size_t                         first_arg_;\n   //\n   // set by set_value\n   graph_op_enum                  op_enum_;\n   size_t                         first_node_;\n   size_t                         n_result_;\n   size_t                         call_id_;\n   vector<size_t>                 str_index_;\n   vector<size_t>                 arg_node_;\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cpp_graph_itr_data}\n------------------------------------------------------------------------------\n{xrst_begin cpp_graph_itr_set_value dev}\n{xrst_spell\n   str\n}\n\nC++ AD Graph Iterator set_value()\n#################################\n\nSyntax\n******\n| *itr* . ``set_value`` ()\n\nop_index\\_\n**********\nThis input is the operator index for the value we are retrieving.\n\nfirst_arg\\_\n***********\nThis input is the first argument index for the value we are retrieving.\n\nfirst_node\\_\n************\nThe input value of this argument does not matter.\nIt is set to the index in ``operator_arg_``\nof the first node argument for this operator.\n\nop_enum\\_\n*********\nThe input value of this argument does not matter.\nIt is set to the :ref:`graph_op_enum-name` for the operator\n\nstr_index\\_\n***********\nThe input value of this argument does not matter.\nUpon return its size is zero except for the special cases\nlisted below:\n\natom_graph_op, atom4_graph_op\n=============================\nIf *op_enum_* is ``atom_graph_op`` or ``atom4_graph_op`` ,\n``str_index_.size() == 1`` and\n``str_index_[0]`` is the index in\n:ref:`cpp_ad_graph@atomic_name_vec`\nfor the function called by this operator.\n\ndiscrete_graph_op\n=================\nIf *op_enum_* is ``discrete_graph_op`` ,\n``str_index_.size() == 1`` and\n``str_index_[0]`` is the index in\n:ref:`cpp_ad_graph@discrete_name_vec`\nfor the function called by this operator.\n\nprint_graph_op\n==============\nIf *op_enum_* is ``print_graph_op`` ,\n``str_index_.size() == 2`` and\n``str_index_[0]`` ( ``str_index_[1]`` )\nis the index in\n:ref:`cpp_ad_graph@print_text_vec` for the\n:ref:`PrintFor@before`  (:ref:`PrintFor@after` ) text.\n\nn_result\\_\n**********\nThe input value of this argument does not matter.\nThis is set to the number of result nodes for this operator.\n\ncall_id\\_\n*********\nIf *op_enum_* is ``atom4_graph_op`` ,\n``call_id_`` is set to the :ref:`atomic_four_call@call_id`\nfor this function call.\nIf *op_enum_* is ``atom_graph_op`` ,\n``call_id`` is set to zero.\n\narg_node\\_\n**********\nThe input value of this argument does not matter.\nUpon return, its size is the number of arguments,\nthat are node indices, for this operator usage.\nThe value of the elements are the node indices.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\n   void set_value(void)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cpp_graph_itr_set_value}\n*/\n{  // initialize output values\n   size_t invalid_index   = std::numeric_limits<size_t>::max();\n   size_t n_arg      = invalid_index;\n   first_node_       = invalid_index;\n   n_result_         = invalid_index;\n   call_id_          = invalid_index;\n   str_index_.resize(0);\n   arg_node_.resize(0);\n   //\n   // op_enum\n   op_enum_          = (*operator_vec_)[op_index_];\n   //\n   // n_result_, n_arg, call_id_, str_index_\n   switch( op_enum_ )\n   {\n      // unary operators\n      case abs_graph_op:\n      case acos_graph_op:\n      case acosh_graph_op:\n      case asin_graph_op:\n      case asinh_graph_op:\n      case atan_graph_op:\n      case atanh_graph_op:\n      case cos_graph_op:\n      case cosh_graph_op:\n      case erf_graph_op:\n      case erfc_graph_op:\n      case exp_graph_op:\n      case expm1_graph_op:\n      case log1p_graph_op:\n      case log_graph_op:\n      case neg_graph_op:\n      case sign_graph_op:\n      case sin_graph_op:\n      case sinh_graph_op:\n      case sqrt_graph_op:\n      case tan_graph_op:\n      case tanh_graph_op:\n      first_node_ = first_arg_;\n      n_result_   = 1;\n      n_arg       = 1;\n      break;\n\n      // binary operators\n      case add_graph_op:\n      case azmul_graph_op:\n      case div_graph_op:\n      case mul_graph_op:\n      case pow_graph_op:\n      case sub_graph_op:\n      first_node_ = first_arg_;\n      n_result_   = 1;\n      n_arg       = 2;\n      break;\n\n      // discrete_graph_op\n      case discrete_graph_op:\n      first_node_ = first_arg_ + 1;\n      str_index_.push_back( (*operator_arg_)[first_node_ - 1] );\n      n_result_   = 1;\n      n_arg       = 1;\n      break;\n\n      // atom_graph_op\n      case atom_graph_op:\n      first_node_ = first_arg_ + 3;\n      str_index_.push_back( (*operator_arg_)[first_node_ - 3] );\n      call_id_    = 0;\n      n_result_   = (*operator_arg_)[first_node_ - 2];\n      n_arg       = (*operator_arg_)[first_node_ - 1];\n      break;\n\n      // atom4_graph_op\n      case atom4_graph_op:\n      first_node_ = first_arg_ + 4;\n      str_index_.push_back( (*operator_arg_)[first_node_ - 4] );\n      call_id_    = (*operator_arg_)[first_node_ - 3];\n      n_result_   = (*operator_arg_)[first_node_ - 2];\n      n_arg       = (*operator_arg_)[first_node_ - 1];\n      break;\n\n      // print_graph_op\n      case print_graph_op:\n      first_node_ = first_arg_ + 2;\n      str_index_.push_back( (*operator_arg_)[first_node_ - 2] );\n      str_index_.push_back( (*operator_arg_)[first_node_ - 1] );\n      n_result_   = 0;\n      n_arg       = 2;\n      break;\n\n\n      // conditional expressions\n      case cexp_eq_graph_op:\n      case cexp_le_graph_op:\n      case cexp_lt_graph_op:\n      first_node_ = first_arg_;\n      n_result_   = 1;\n      n_arg       = 4;\n      break;\n\n      // comparison operators\n      case comp_eq_graph_op:\n      case comp_le_graph_op:\n      case comp_lt_graph_op:\n      case comp_ne_graph_op:\n      first_node_ = first_arg_;\n      n_result_   = 0;\n      n_arg       = 2;\n      break;\n\n      // sum_graph_op\n      case sum_graph_op:\n      first_node_ = first_arg_ + 1;\n      n_result_   = 1;\n      n_arg       = (*operator_arg_)[first_node_ - 1];\n      break;\n\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n      break;\n   }\n   // set arg_node\n   arg_node_.resize(n_arg);\n   for(size_t i = 0; i < n_arg; i++)\n      arg_node_[i] = (*operator_arg_)[first_node_ + i];\n\n   return;\n}\n/* %$$\n-------------------------------------------------------------------------------\n{xrst_begin cpp_graph_itr_types dev}\n\nC++ AD Graph Iterator Types\n###########################\n\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   typedef struct {\n      graph_op_enum          op_enum;\n      size_t                 n_result;\n      size_t                 call_id;\n      const vector<size_t>*  str_index_ptr;\n      const vector<size_t>*  arg_node_ptr;\n   } value_type;\n   typedef std::input_iterator_tag    iterator_category;\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cpp_graph_itr_types}\n------------------------------------------------------------------------------\n{xrst_begin cpp_graph_itr_ctor dev}\n\nC++ AD Graph Iterator Constructors\n##################################\n\nSyntax\n******\n\n| ``cpp_graph_itr`` *default*\n| ``cpp_graph_itr`` *itr* ( *operator_vec* , *operator_arg* , *op_index*\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CTOR\n   // END_CTOR\n}\n\ndefault\n*******\nThe result of the default constructor can only be used as a target\nfor the assignment operator.\n\noperator_vec\n************\nIs the :ref:`cpp_ad_graph@operator_vec`\nfor the ``cpp_graph`` container that this iterator refers to.\n\noperator_arg\n************\nIs the :ref:`operator_arg<cpp_ad_graph@operator_vec>`\nfor the ``cpp_graph`` container that this iterator refers to.\n\nop_index\n********\nThis must be either zero (the ``begin()`` for the container)\nor equal to the size of *operator_vec*\n(the ``end()`` for the container).\n\n{xrst_end cpp_graph_itr_ctor}\n*/\n   cpp_graph_itr(void)\n   : operator_vec_(nullptr), operator_arg_(nullptr)\n   { }\n   // BEGIN_CTOR\n   cpp_graph_itr(\n      const vector<graph_op_enum>& operator_vec   ,\n      const vector<size_t>&        operator_arg   ,\n      size_t                       op_index       )\n   // END_CTOR\n   :\n   operator_vec_(&operator_vec) ,\n   operator_arg_(&operator_arg) ,\n   op_index_(op_index)\n   {  // end constructor\n      if( op_index == operator_vec.size() )\n         return;\n      //\n      // begin constructor\n      CPPAD_ASSERT_KNOWN( op_index == 0,\n         \"cpp_graph_itr: constructor op_index not 0 or operator_vec.size()\"\n      );\n      // start at the beginning of operator_vec\n      first_arg_ = 0;\n      //\n      // get the value, and first_node_, for this operator\n      set_value();\n   }\n/* %$$\n------------------------------------------------------------------------------\n{xrst_begin cpp_graph_itr_input dev}\n\nC++ AD Graph Iterator Input Operations\n######################################\n\n{xrst_spell_off}\n{xrst_code hpp} */\n   // itr == other\n   bool operator==(const cpp_graph_itr& other) const\n   {  return op_index_ == other.op_index_;\n   }\n   // itr != other\n   bool operator!=(const cpp_graph_itr& other) const\n   {  return op_index_ != other.op_index_;\n   }\n   // *itr\n   value_type operator*(void)\n   {  CPPAD_ASSERT_KNOWN( operator_vec_ != nullptr,\n         \"cpp_graph_itr: attempt to dereference default iterator\"\n      );\n      CPPAD_ASSERT_KNOWN( op_index_ < operator_vec_->size(),\n         \"cpp_graph_itr: attempt to dereference past last element in graph\"\n      );\n      value_type ret;\n      ret.op_enum       = op_enum_;\n      ret.n_result      = n_result_;\n      ret.call_id       = call_id_;\n      ret.str_index_ptr = &str_index_;\n      ret.arg_node_ptr  = &arg_node_;\n      return ret;\n   }\n   // ++itr\n   cpp_graph_itr& operator++(void)\n   {  ++op_index_;\n      first_arg_ = first_node_ + arg_node_.size();\n      set_value();\n      return *this;\n   }\n   // itr++\n   cpp_graph_itr operator++(int)\n   {  cpp_graph_itr ret(*this);\n      ++op_index_;\n      first_arg_ = first_node_ + arg_node_.size();\n      set_value();\n      return ret;\n   }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cpp_graph_itr_input}\n*/\n\n};\n\n} } } // END_CPPAD_LOCAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/graph/cpp_graph_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_GRAPH_CPP_GRAPH_OP_HPP\n# define CPPAD_LOCAL_GRAPH_CPP_GRAPH_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cstddef>\n# include <string>\n# include <map>\n\n# include <cppad/utility/vector.hpp>\n# include <cppad/configure.hpp>\n# include <cppad/core/graph/graph_op_enum.hpp>\n\nnamespace CppAD { namespace local { namespace graph {\n/*\n{xrst_begin cpp_graph_op dev}\n\nC++ AD Graph Operators\n######################\n\nNamespace\n*********\nAll of these definitions\nare in the ``CppAD::local::graph`` namespace.\n\nCppAD::graph\n************\n{xrst_spell_off}\n{xrst_code hpp} */\n   using namespace CppAD::graph;\n/* {xrst_code}\n{xrst_spell_on}\n\naddr_t\n******\n{xrst_spell_off}\n{xrst_code hpp} */\n   typedef CPPAD_TAPE_ADDR_TYPE addr_t;\n/* {xrst_code}\n{xrst_spell_on}\n\nop_name2enum\n************\nThis is a mapping from the operator name to its enum value.\nThe name is the operator enum without the ``_operator`` at the end.\n{xrst_spell_off}\n{xrst_code hpp} */\n   extern CPPAD_LIB_EXPORT std::map< std::string, graph_op_enum > op_name2enum;\n/* {xrst_code}\n{xrst_spell_on}\n\nop_enum2fixed_n_arg\n*******************\nThis is the number of arguments for the operators that have\na fixed number of arguments and one result.\nFor other operators, this value is zero.\n{xrst_spell_off}\n{xrst_code hpp} */\n   extern CPPAD_LIB_EXPORT size_t op_enum2fixed_n_arg[];\n/* {xrst_code}\n{xrst_spell_on}\n\nop_enum2name\n************\nThis is mapping from operator enum value to its name.\nIn the ``local::graph`` namespace:\n{xrst_spell_off}\n{xrst_code hpp} */\n   extern CPPAD_LIB_EXPORT const char* op_enum2name[];\n/* {xrst_code}\n{xrst_spell_on}\n\nset_operator_info\n*****************\nThis routine sets the values in\n``op_enum2fixed_n_arg`` ,\n``op_enum2name`` , and\n``op_name2enum`` .\n{xrst_spell_off}\n{xrst_code hpp} */\n   extern CPPAD_LIB_EXPORT void set_operator_info(void);\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cpp_graph_op}\n*/\n\n} } } // END_CPPAD_LOCAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/graph/csrc_writer.hpp",
    "content": "# ifndef CPPAD_LOCAL_GRAPH_CSRC_WRITER_HPP\n# define CPPAD_LOCAL_GRAPH_CSRC_WRITER_HPP\n\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <string>\n# include <cppad/local/graph/cpp_graph_op.hpp>\n\n/*\n{xrst_begin csrc_writer dev}\n\nPrototype for csrc_writer\n#########################\n\nSyntax\n******\n| ``csrc_writer`` ( *csrc* , *graph_obj* , *type*  )\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\nnamespace CppAD { namespace local { namespace graph {\n   CPPAD_LIB_EXPORT void csrc_writer(\n      std::ostream&       os          ,\n      const cpp_graph&    graph_obj   ,\n      const std::string&  type\n   );\n} } }\n/* {xrst_code}\n{xrst_spell_on}\n\nSee\n***\n:ref:`cpp_csrc_writer-name`\n\n{xrst_end csrc_writer}\n*/\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/graph/json_lexer.hpp",
    "content": "# ifndef CPPAD_LOCAL_GRAPH_JSON_LEXER_HPP\n# define CPPAD_LOCAL_GRAPH_JSON_LEXER_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <string>\n# include <cppad/core/cppad_assert.hpp>\n\n// BEGIN_NAMESPACE_CPPAD_LOCAL_GRAPH\nnamespace CppAD { namespace local { namespace graph {\n\n// ===========================================================================\nclass json_lexer {\n// ===========================================================================\n\n/*\n-------------------------------------------------------------------------------\n{xrst_begin json_lexer_member_data dev}\n\njson lexer: Private Data\n########################\n\nMember Variables\n****************\n\ngraph\\_\n=======\nThe :ref:`json_ad_graph-name` .\n\nindex\\_\n=======\nis the index in the graph for the current character.\nIf a token is returned, this corresponds to the last character\nit the token.\n\nline_number\\_\n=============\nline number in the graph for the current character\n\nchar_number\\_\n=============\ncharacter number in the graph for the current character\n\ntoken\\_\n=======\nused to return tokens.\n\nfunction_name\\_\n===============\nis the function name for this graph.\nThis is initialized as empty,\nshould be set as soon as it is parsed,\nand is used for error reporting.\n\ntoken\n*****\nreturns current value of ``token_`` .\n\nline_number\n***********\nreturns current value of ``line_number_``\n(which corresponds to last character in the token).\n\nchar_number\n***********\nreturns current value of ``char_number_`` .\n(which corresponds to last character in the token).\n\nset_function_name\n*****************\nsets the value of ``function_name_`` .\n\nSource Code\n***********\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   const std::string& json_;\n   size_t             index_;\n   size_t             line_number_;\n   size_t             char_number_;\n   std::string        token_;\n   std::string        function_name_;\npublic:\n   const std::string& token(void)       const;\n   size_t             line_number(void) const;\n   size_t             char_number(void) const;\n   void               set_function_name(const std::string& function_name);\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end json_lexer_member_data}\n-------------------------------------------------------------------------------\n{xrst_begin json_lexer_report_error dev}\n\njson lexer: Report an Error\n###########################\n\nSyntax\n******\n| *json_lexer* . ``report_error`` ( *expected* , *found* )\n\njson_lexer\n**********\nis a ``local::graph::json_lexer`` object.\n\nexpected\n********\nis the token that is expected.\n\nfound\n*****\nis the token or text that was found.\n\nReport\n******\nThe current CppAD :ref:`ErrorHandler-name` is used to report\nan error parsing this Json AD graph.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void report_error(const std::string& expected, const std::string& found);\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end json_lexer_report_error}\n-------------------------------------------------------------------------------\n{xrst_begin json_lexer_next_index dev}\n\njson lexer: Advance Index by One\n################################\n\nSyntax\n******\n\n   *json_lexer* . ``next_index`` ()\n\njson_lexer\n**********\nis a ``local::graph::json_lexer`` object.\n\nindex\\_\n*******\nThe input value of ``index_`` is increased by one.\nIt is an error to call this routine when the input value\nof ``index_`` is greater than or equal ``json_.size()`` .\n\nline_number\\_\n*************\nIf the previous character, before  the call, was a new line,\n``line_number_`` is increased by one.\n\nchar_number\\_\n*************\nIf the previous character, before the call, was a new line,\n``char_number`` is set to one.\nOtherwise, ``char_number_`` is increased by one.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   void next_index(void);\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end json_lexer_next_index}\n-------------------------------------------------------------------------------\n{xrst_begin json_lexer_skip_white_space dev}\n\njson lexer: Skip White Space That Separates Tokens\n##################################################\n\nSyntax\n******\n\n   *json_lexer* . ``skip_white_space`` ()\n\njson_lexer\n**********\nis a json lexer object.\n\nDiscussion\n**********\nThis member functions is used to increase ``index_`` until either\na non-white space character is found or ``index_`` is equal\nto ``json_.size()`` .\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   void skip_white_space(void);\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end json_lexer_skip_white_space}\n-------------------------------------------------------------------------------\n{xrst_begin json_lexer_constructor dev}\n\njson lexer: Constructor\n#######################\n\nSyntax\n******\n\n   ``local::graph::lexer`` *json_lexer* ( *json* )\n\njson\n****\nThe argument *json* is an :ref:`json_ad_graph-name`\nand it is assumed that *json* does not change\nfor as long as *json_lexer* exists.\n\nInitialization\n**************\nThe current token, index, line number, and character number\nare set to the first non white space character in ``json_`` .\nIf this is not a left brace character ``'{'`` ,\nthe error is reported and the constructor does not return.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   json_lexer(const std::string& json);\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end json_lexer_constructor}\n-------------------------------------------------------------------------------\n{xrst_begin json_lexer_check_next_char dev}\n\nGet and Check Next Single Character Token\n#########################################\n\nSyntax\n******\n\n   *json_lexer* . ``check_next_char`` ( *ch* )\n\nindex\\_\n*******\nThe search for the character starts\nat one greater than the input value for ``index_`` and skips white space.\n\nch\n**\nIs a non white space\nsingle character token that is expected.\nIf this character is not found,\nthe error is reported and this function does not return.\nIn the special case where *ch* is ``'\\0'`` ,\nany non-white space character will be accepted\n(but there must be such a character).\n\ntoken\\_\n*******\nIf this routine returns, ``token_`` has size one\nand contains the character that is found.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void check_next_char(char ch);\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end json_lexer_check_next_char}\n-------------------------------------------------------------------------------\n{xrst_begin json_lexer_check_next_string dev}\n\nGet and Check Next Single Character Token\n#########################################\n\nSyntax\n******\n\n   *json_lexer* . ``check_next_string`` ( *expected* )\n\nindex\\_\n*******\nThe search for the string starts\nat one greater than the input value for ``index_`` and skips white space.\n\nexpected\n********\nIs the value (not including double quotes) for the string that is expected.\nIf this string is not found, the error is reported\nand this function does not return.\nIn the special case where *expected* is empty,\nany string will be accepted.\n\ntoken\\_\n*******\nIf this routine returns,\n*token_* is the string that was found.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void check_next_string(const std::string& expected);\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end json_lexer_check_next_string}\n-------------------------------------------------------------------------------\n{xrst_begin json_lexer_next_non_neg_int dev}\n\nGet Next Non-Negative Integer\n#############################\n\nSyntax\n******\n\n| |tab| *json_lexer* . ``next_non_neg_int`` ()\n| |tab| *value* = *json_lexer* . ``token2size_t`` ()\n\nindex\\_\n*******\nThe search for the non-negative integer starts\nat one greater than the input value for ``index_`` and skips white space.\n\ntoken\\_\n*******\nis set to the non-negative integer.\nIf the next token is not a non-negative integer,\nthe error is reported and this function does not return.\n\nvalue\n*****\nIf the current token is a non-negative integer,\n*value* is the corresponding value.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void next_non_neg_int(void);\n   size_t token2size_t(void) const;\n\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end json_lexer_next_non_neg_int}\n-------------------------------------------------------------------------------\n{xrst_begin json_lexer_next_float dev}\n\nGet Next Floating Point Number\n##############################\n\nSyntax\n******\n\n| |tab| *ok* = *json_lexer* . ``next_float`` ()\n| |tab| *value* = *json_lexer* . ``token2double`` ()\n\nindex\\_\n*******\nThe search for the floating point number starts\nat one greater than the input value for ``index_`` and skips white space.\n\ntoken\\_\n*******\nis set to the floating point number.\nIf the next token is not a floating point number,\nthe error is reported and this function does not return.\n\nvalue\n*****\nIf the current token is a floating point number,\n*value* is the corresponding value.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void next_float(void);\n   double token2double(void) const;\n\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end json_lexer_next_float}\n*/\n\n// ==========================================================================\n}; // end class lexer\n// ==========================================================================\n\n\n} } } // END_NAMESPACE_CPPAD_LOCAL_GRAPH\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/graph/json_parser.hpp",
    "content": "# ifndef CPPAD_LOCAL_GRAPH_JSON_PARSER_HPP\n# define CPPAD_LOCAL_GRAPH_JSON_PARSER_HPP\n\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <string>\n# include <cppad/utility/vector.hpp>\n# include <cppad/local/graph/cpp_graph_op.hpp>\n# include <cppad/core/graph/cpp_graph.hpp>\n\n/*\n{xrst_begin json_parser dev}\n\nJson AD Graph Parser\n####################\n\nSyntax\n******\n| ``json_parser`` ( *json* , *graph_obj* )\n\njson\n****\nThe :ref:`json_ad_graph-name` .\n\ngraph_obj\n*********\nThis is a ``cpp_graph`` object.\nThe input value of the object does not matter.\nUpon return it is a :ref:`cpp_ad_graph-name` representation of this function.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\nnamespace CppAD { namespace local { namespace graph {\n   CPPAD_LIB_EXPORT void json_parser(\n      const std::string&  json      ,\n      cpp_graph&          graph_obj\n   );\n} } }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end json_parser}\n*/\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/graph/json_writer.hpp",
    "content": "# ifndef CPPAD_LOCAL_GRAPH_JSON_WRITER_HPP\n# define CPPAD_LOCAL_GRAPH_JSON_WRITER_HPP\n\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <string>\n# include <cppad/local/graph/cpp_graph_op.hpp>\n\n/*\n{xrst_begin json_writer dev}\n\nJson AD Graph Writer\n####################\n\nSyntax\n******\n| ``json_writer`` ( *json* , *graph_obj*  )\n\njson\n****\nThe input value of *json* does not matter,\nupon return it a :ref:`json<json_ad_graph-name>` representation of the AD graph.\n\ngraph_obj\n*********\nThis is a ``cpp_graph`` object.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\nnamespace CppAD { namespace local { namespace graph {\n   CPPAD_LIB_EXPORT void json_writer(\n      std::string&       json        ,\n      const cpp_graph&   graph_obj\n   );\n} } }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end json_writer}\n*/\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/hash_code.hpp",
    "content": "# ifndef CPPAD_LOCAL_HASH_CODE_HPP\n# define CPPAD_LOCAL_HASH_CODE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/core/base_hash.hpp>\n/*!\n\\file local/hash_code.hpp\nCppAD hashing utility.\n*/\n\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*!\nGeneral purpose hash code for an arbitrary value.\n\n\\tparam Value\nis the type of the argument being hash coded.\nIt should be a plain old data class; i.e.,\nthe values included in the equality operator in the object and\nnot pointed to by the object.\n\n\\param value\nthe value that we are generating a hash code for.\nAll of the fields in value should have been set before the hash code\nis computed (otherwise undefined values are used).\n\n\\return\nis a hash code that is between zero and CPPAD_HASH_TABLE_SIZE - 1.\n\n\\par Checked Assertions\n\\li std::numeric_limits<unsigned short>::max() >= CPPAD_HASH_TABLE_SIZE\n\\li sizeof(value) is even\n\\li sizeof(unsigned short)  == 2\n*/\ntemplate <class Value>\nunsigned short local_hash_code(const Value& value)\n{  CPPAD_ASSERT_UNKNOWN(\n      std::numeric_limits<unsigned short>::max()\n      >=\n      CPPAD_HASH_TABLE_SIZE\n   );\n   CPPAD_ASSERT_UNKNOWN( sizeof(unsigned short) == 2 );\n   CPPAD_ASSERT_UNKNOWN( sizeof(value) % 2  == 0 );\n   //\n   const unsigned short* v\n             = reinterpret_cast<const unsigned short*>(& value);\n   //\n   size_t i = sizeof(value) / 2 - 1;\n   //\n   size_t sum = v[i];\n   //\n   while(i--)\n      sum += v[i];\n   //\n   unsigned short code = static_cast<unsigned short>(\n      sum % CPPAD_HASH_TABLE_SIZE\n   );\n   return code;\n}\n\n/*!\nSpecialized hash code for a CppAD operator and its arguments.\n\n\\param op\nis the operator that we are computing a hash code for.\nIf it is not one of the following operartors, the operator is not\nhash coded and zero is returned:\n\n\\li unary operators:\nAbsOp, AcosOp, AcoshOp, AsinOp, AsinhOp, AtanOp, AtanhOp, CosOp, CoshOp\nExpOp, Expm1Op, LogOp, Log1pOp, SinOp, SinhOp, SqrtOp, TanOp, TanhOp\n\n\\li binary operators where first argument is a parameter:\nAddpvOp, DivpvOp, MulpvOp, PowpvOp, SubpvOp, ZmulpvOp\n\n\\li binary operators where second argument is a parameter:\nDivvpOp, PowvpOp, SubvpOp, Zmulvp\n\n\\li binary operators where first is an index and second is a variable:\nDisOp\n\n\\li binary operators where both arguments are variables:\nAddvvOp, DivvvOp, MulvvOp, PowvvOp, SubvvOp, ZmulvvOp\n\n\\param arg\nis a vector of length NumArg(op) or 2 (which ever is smaller),\ncontaining the corresponding argument indices for this operator.\n\n\\param npar\nis the number of parameters corresponding to this operation sequence.\n\n\\param par\nis a vector of length npar containing the parameters\nfor this operation sequence; i.e.,\ngiven a parameter index of i, the corresponding parameter value is\n par[i].\n\n\n\\return\nis a hash code that is between zero and CPPAD_HASH_TABLE_SIZE - 1.\n\n\\par Checked Assertions\n op must be one of the operators specified above. In addition,\n\\li std::numeric_limits<unsigned short>::max() >= CPPAD_HASH_TABLE_SIZE\n\\li sizeof(size_t) is even\n\\li sizeof(Base) is even\n\\li sizeof(unsigned short)  == 2\n\\li size_t(op) < size_t(NumberOp) <= CPPAD_HASH_TABLE_SIZE\n\\li if the j-th argument for this operation is a parameter, arg[j] < npar.\n*/\n\ntemplate <class Base>\nunsigned short local_hash_code(\n   op_code_var   op      ,\n   const addr_t* arg     ,\n   size_t        npar    ,\n   const Base*   par     )\n{  CPPAD_ASSERT_UNKNOWN(\n      std::numeric_limits<unsigned short>::max()\n      >=\n      CPPAD_HASH_TABLE_SIZE\n   );\n   CPPAD_ASSERT_UNKNOWN( size_t (op) < size_t(NumberOp) );\n   CPPAD_ASSERT_UNKNOWN( sizeof(unsigned short) == 2 );\n   CPPAD_ASSERT_UNKNOWN( sizeof(addr_t) % 2  == 0 );\n   CPPAD_ASSERT_UNKNOWN( sizeof(Base) % 2  == 0 );\n   unsigned short op_fac = static_cast<unsigned short> (\n      CPPAD_HASH_TABLE_SIZE / static_cast<unsigned short>(NumberOp)\n   );\n   CPPAD_ASSERT_UNKNOWN( op_fac > 0 );\n\n   // number of shorts per addr_t value\n   size_t short_addr_t   = sizeof(addr_t) / 2;\n\n   // initialize with value that separates operators as much as possible\n   unsigned short code = static_cast<unsigned short>(\n      static_cast<unsigned short>(op) * op_fac\n   );\n\n   // now code in the operands\n   size_t i;\n   const unsigned short* v;\n\n   // first argument\n   switch(op)\n   {  // Binary operators where first argument is a parameter.\n      // Code parameters by value instead of\n      // by index for two reasons. One, it gives better separation.\n      // Two, different indices can be same parameter value.\n      case AddpvOp:\n      case DivpvOp:\n      case MulpvOp:\n      case PowpvOp:\n      case SubpvOp:\n      case ZmulpvOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );\n      code += hash_code( par[arg[0]] );\n      //\n      v = reinterpret_cast<const unsigned short*>(arg + 1);\n      i = short_addr_t;\n      while(i--)\n         code += v[i];\n      break;\n\n      // Binary operator where first argument is an index and\n      // second is a variable (same as both variables).\n      case DisOp:\n\n      // Binary operators where both arguments are variables\n      case AddvvOp:\n      case DivvvOp:\n      case MulvvOp:\n      case PowvvOp:\n      case SubvvOp:\n      case ZmulvvOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );\n      v = reinterpret_cast<const unsigned short*>(arg + 0);\n      i = 2 * short_addr_t;\n      while(i--)\n         code += v[i];\n      break;\n\n      // Binary operators where second argument is a parameter.\n      case DivvpOp:\n      case PowvpOp:\n      case SubvpOp:\n      case ZmulvpOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );\n      v = reinterpret_cast<const unsigned short*>(arg + 0);\n      i = short_addr_t;\n      while(i--)\n         code += v[i];\n      code += hash_code( par[arg[1]] );\n      break;\n\n      // Unary operators\n      case AbsOp:\n      case AcosOp:\n      case AcoshOp:\n      case AsinOp:\n      case AsinhOp:\n      case AtanOp:\n      case AtanhOp:\n      case CosOp:\n      case CoshOp:\n      case ErfOp:\n      case ErfcOp:\n      case ExpOp:\n      case Expm1Op:\n      case LogOp:\n      case Log1pOp:\n      case SignOp:\n      case SinOp:\n      case SinhOp:\n      case SqrtOp:\n      case TanOp:\n      case TanhOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 || op == ErfOp );\n      v = reinterpret_cast<const unsigned short*>(arg + 0);\n      i = short_addr_t;\n      while(i--)\n         code += v[i];\n      break;\n\n      // should have been one of he cases above\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n   }\n\n   return code % CPPAD_HASH_TABLE_SIZE;\n}\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/independent.hpp",
    "content": "# ifndef CPPAD_LOCAL_INDEPENDENT_HPP\n# define CPPAD_LOCAL_INDEPENDENT_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\nnamespace CppAD { namespace local { //  BEGIN_CPPAD_LOCAL_NAMESPACE\n/*\n\\file local/independent.hpp\nStart recording AD<Base> operations.\n*/\n\n/*!\nStart recording AD<Base> operations: Implementation in local namespace.\n\n\\tparam ADVector\nThis is simple vector type with elements of type AD<Base>.\n\n\\param x\nVector of the independent variables.\n\n\\param abort_op_index\noperator index at which execution will be aborted (during  the recording\n\n\\param record_compare\nshould comparison operators be recorded.\nof operations). The value zero corresponds to not aborting (will not match).\n\n\\param dynamic\nVector of dynamic parameters.\n*/\ntemplate <class Base>\ntemplate <class ADVector>\nvoid ADTape<Base>::Independent(\n   ADVector&    x               ,\n   size_t       abort_op_index  ,\n   bool         record_compare  ,\n   ADVector&    dynamic\n) {\n   // check ADVector is Simple Vector class with AD<Base> elements\n   CheckSimpleVector< AD<Base>, ADVector>();\n\n   // dimension of the domain space\n   size_t n = x.size();\n   CPPAD_ASSERT_KNOWN(\n      n > 0,\n      \"Independent: the argument vector x has zero size\"\n   );\n   CPPAD_ASSERT_UNKNOWN( Rec_.num_var() == 0 );\n   CPPAD_ASSERT_UNKNOWN( Rec_.get_abort_op_index() == 0 );\n   CPPAD_ASSERT_UNKNOWN( Rec_.get_record_compare() == true );\n   CPPAD_ASSERT_UNKNOWN( Rec_.n_dyn_independent()    == 0 );\n\n   // set record_compare and abort_op_index before doing anything else\n   Rec_.set_record_compare(record_compare);\n   Rec_.set_abort_op_index(abort_op_index);\n   Rec_.set_n_dyn_independent( dynamic.size() );\n\n   // mark the beginning of the tape and skip the first variable index\n   // (zero) because parameters use taddr zero\n   CPPAD_ASSERT_NARG_NRES(BeginOp, 1, 1);\n   Rec_.PutOp(BeginOp);\n   Rec_.PutArg(0);\n\n   // place each of the independent variables in the tape\n   CPPAD_ASSERT_NARG_NRES(InvOp, 0, 1);\n   for(size_t j = 0; j < n; j++)\n   {  // tape address for this independent variable\n      CPPAD_ASSERT_UNKNOWN( ! Variable(x[j] ) );\n      x[j].taddr_     = Rec_.PutOp(InvOp);\n      x[j].tape_id_   = id_;\n      x[j].ad_type_   = variable_enum;\n      CPPAD_ASSERT_UNKNOWN( size_t(x[j].taddr_) == j+1 );\n      CPPAD_ASSERT_UNKNOWN( Variable(x[j] ) );\n   }\n\n   // done specifying all of the independent variables\n   size_independent_ = n;\n\n   // parameter index zero is used by dynamic parameter tape\n   // to indicate that an argument is a variable\n   Base nan = CppAD::numeric_limits<Base>::quiet_NaN();\n# ifndef NDEBUG\n   CPPAD_ASSERT_UNKNOWN( Rec_.put_con_par(nan) == 0 );\n# else\n   Rec_.put_con_par(nan);\n# endif\n\n   // Place independent dynamic parameters at beginning of parameter vector,\n   // just after the nan at index zero.\n   CPPAD_ASSERT_UNKNOWN( Rec_.n_dyn_independent() <= dynamic.size() );\n   for(size_t j = 0; j < Rec_.n_dyn_independent(); ++j)\n   {  CPPAD_ASSERT_UNKNOWN( ! Dynamic( dynamic[j] ) );\n      CPPAD_ASSERT_UNKNOWN( Parameter( dynamic[j] ) );\n      //\n      // dynamic parameters are placed at the end, so i == j\n# ifndef NDEBUG\n      addr_t i = Rec_.put_dyn_par(dynamic[j].value_ , ind_dyn);\n      CPPAD_ASSERT_UNKNOWN( size_t(i) == j+1 );\n# else\n      Rec_.put_dyn_par(dynamic[j].value_ , ind_dyn);\n# endif\n      //\n      // make this parameter dynamic\n      dynamic[j].taddr_   = static_cast<addr_t>(j+1);\n      dynamic[j].tape_id_ = id_;\n      dynamic[j].ad_type_ = dynamic_enum;\n      CPPAD_ASSERT_UNKNOWN( Dynamic( dynamic[j] ) );\n   }\n}\n} } // END_CPPAD_LOCAL_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/is_pod.hpp",
    "content": "# ifndef CPPAD_LOCAL_IS_POD_HPP\n# define CPPAD_LOCAL_IS_POD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin is_pod dev}\n{xrst_spell\n   nullptr\n}\n\nThe is_pod Template Function\n############################\n\nDefault Definition\n******************\nThe default template definition is that\n\n   ``is_pod`` < *Type* >()\n\nis false for all types.\n\nFundamental Types\n*****************\nThis file specializes ``is_pod`` < *Type* > to be true where *Type*\nis any of the c++11 fundamental types that hold data; i.e.,\n``void`` and ``nullptr_t`` are excluded.\n\nOther Type\n**********\nYou can inform CppAD that a particular *Type* is plain old data by\ndefining\n\n| |tab| ``namespace CppAD`` { ``namespace local`` {\n| |tab| |tab| ``template <> inline bool is_pod<`` *Type* >( ``void`` ) { ``return true`` ; }\n| |tab| } }\n\n{xrst_end is_pod}\n*/\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n   //\n   template <class T> inline bool is_pod(void) { return false; }\n   // bool\n   template <> inline bool is_pod<bool>(void)                   {return true;}\n   // short\n   template <> inline bool is_pod<short int>(void)              {return true;}\n   template <> inline bool is_pod<unsigned short int>(void)     {return true;}\n   // int\n   template <> inline bool is_pod<int>(void)                    {return true;}\n   template <> inline bool is_pod<unsigned int>(void)           {return true;}\n   // long\n   template <> inline bool is_pod<long int>(void)               {return true;}\n   template <> inline bool is_pod<unsigned long int>(void)      {return true;}\n   // long long\n   template <> inline bool is_pod<long long int>(void)          {return true;}\n   template <> inline bool is_pod<unsigned long long int>(void) {return true;}\n   // Character types\n   template <> inline bool is_pod<char>(void)                   {return true;}\n   template <> inline bool is_pod<signed char>(void)            {return true;}\n   template <> inline bool is_pod<unsigned char>(void)          {return true;}\n   template <> inline bool is_pod<wchar_t>(void)                {return true;}\n   template <> inline bool is_pod<char16_t>(void)               {return true;}\n   template <> inline bool is_pod<char32_t>(void)               {return true;}\n   // floating point types\n   template <> inline bool is_pod<float>(void)                  {return true;}\n   template <> inline bool is_pod<double>(void)                 {return true;}\n   template <> inline bool is_pod<long double>(void)            {return true;}\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/is_pod.hpp.in",
    "content": "# ifndef CPPAD_LOCAL_IS_POD_HPP\n# define CPPAD_LOCAL_IS_POD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n// make sure size_t is defined because autotools version of\n// is_pod_specialize_98 uses it\n# include <cstddef>\n\n/*!\n\\file is_pod.hpp\nFile that defines is_pod<Type>(void)\n*/\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*!\nIs this type plain old data; i.e., its constructor need not be called.\n\nThe default definition is false. This include file defines it as true\nfor all the fundamental types except for void and nullptr_t.\n*/\ntemplate <class T> bool is_pod(void) { return false; }\n// The following command suppresses doxygen processing for the code below\n/// \\cond\n// C++98 Fundamental types\n@is_pod_specialize_98@\n\n// C++11 Fundamental types\n@is_pod_specialize_11@\n\n/// \\endcond\n} } // END_CPPAD_LOCAL_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/op_code_dyn.hpp",
    "content": "# ifndef CPPAD_LOCAL_OP_CODE_DYN_HPP\n# define CPPAD_LOCAL_OP_CODE_DYN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*!\n{xrst_begin op_code_dyn dev}\n{xrst_spell\n   zmul\n}\n\nDynamic Parameter Op Codes\n##########################\n\nNamespace\n*********\nThe ``op_code_dyn`` enum type is in the ``CppAD::local`` namespace.\n\nAD Type\n*******\nAll the operators below have no variable arguments,\nat least one dynamic parameter argument,\nand at most one constant argument; see\n:ref:`ad_type_enum-name` .\nFor example, all the unary operators have one dynamic parameter argument\nand one dynamic parameter result.\n\nUnary\n*****\nThe number of arguments for a unary operator is one\nand it is a parameter index.\nAll the unary operators have one result that is a dynamic parameter.\n\nBinary\n******\nThe number of arguments for a binary operator is two\nand they are parameter indices.\nAll the binary operators have one result that is a dynamic parameter.\nFor binary operators the first argument is the left operand\nand the second is the right operand.\n\nzmul_dyn\n========\nThis binary operator has a non-standard name; see :ref:`azmul-name` for\nits definition.\n\nind_dyn\n*******\nThis is an independent dynamic parameter operator.\nIt has no arguments and one result which is the value of the corresponding\nindependent dynamic parameter in the call to :ref:`new_dynamic-name` .\n\n{xrst_comment ------------------------------------------------------------ }\natom_dyn\n********\nThis operator is a call to an atomic function.\nThe number of arguments to this operator is\n*arg* [4+ *n* + *m* ] ; see below.\n\narg[0]\n======\nThis is the index that identifies this atomic function; see\n``local/atomic_index.hpp`` .\n\narg[1]\n======\nThis is the :ref:`atomic_four_call@call_id` for this\nfunction call.\n\narg[2]\n======\nThis is the number of arguments to this atomic function.\nWe use the notation *n* = *arg* [2] below.\n\narg[3]\n======\nThis is the number of results for this atomic function.\nWe use the notation *m* = *arg* [3] below.\n\narg[4]\n======\nThis is the number of result values that are dynamic parameters\nfor this function call.\n\narg[5+j]\n========\nFor *j* = 0 , ... , *n* ``-1`` ,\nthis is the parameter index for the *j*-th argument to this atomic\nfunction call.\n\narg[5+n+i]\n==========\nFor *i* = 0 , ... , *m* ``-1`` ,\nthis is the parameter index for the *i*-th result to this atomic\nfunction call.\n\narg[5+n+m]\n==========\nThis is the number of arguments to this operator; i.e.,\n6+ *n* + *m* .\n\nresult_dyn\n**********\nThis is a place holder for a result of an atomic function call\nthat is a dynamic parameter.\nIt has no arguments, no results, and is only there so that the\nnumber of dynamic parameters and the number of dynamic operators are equal.\n\n{xrst_comment ------------------------------------------------------------ }\ncond_exp_dyn\n************\nThis is a conditional expression operator and has five arguments\nand one result.\n\narg[0]\n======\nThis is the\n:ref:`base_cond_exp@CompareOp` value for this operator.\n\narg[1]\n======\nThis is the parameter index for the left operand to the comparison.\n\narg[2]\n======\nThis is the parameter index for the right operand to the comparison.\n\narg[3]\n======\nThis is the index of the parameter equal to the operator result if\nthe comparison result is true.\n\narg[4]\n======\nThis is the index of the parameter equal to the operator result if\nthe comparison result is false.\n\n{xrst_comment ------------------------------------------------------------ }\ndis_dyn\n*******\nThis is a call to a discrete function.\nThe discrete function has one argument and one result.\nThis operator has two arguments and one result.\nIt is not a binary operator because the first argument\nis not the index of a parameter.\n\narg[0]\n======\nIs the discrete function index which depends on the *Base*\ntype used when this function was recorded.\n\narg[1]\n======\nIs the parameter index for the argument to the function.\n\n{xrst_comment ------------------------------------------------------------ }\nSource\n******\n{xrst_literal\n   // BEGIN_OP_CODE_DYN\n   // END_OP_CODE_DYN\n}\n\n{xrst_end op_code_dyn}\n*/\n\n// BEGIN_SORT_THIS_LINE_PLUS_3\n// BEGIN_OP_CODE_DYN\nenum op_code_dyn {\n   abs_dyn,       // unary\n   acos_dyn,      // unary\n   acosh_dyn,     // unary\n   add_dyn,       // binary\n   asin_dyn,      // unary\n   asinh_dyn,     // unary\n   atan_dyn,      // unary\n   atanh_dyn,     // unary\n   atom_dyn,      // ? arguments: atomic function call\n   cond_exp_dyn,  // 5 arguments: conditional expression\n   cos_dyn,       // unary\n   cosh_dyn,      // unary\n   dis_dyn,       // 2 arguments: discrete function\n   div_dyn,       // binary\n   erf_dyn,       // unary\n   erfc_dyn,      // unary\n   exp_dyn,       // unary\n   expm1_dyn,     // unary\n   fabs_dyn,      // unary\n   ind_dyn,       // 0 arguments: independent parameter\n   log1p_dyn,     // unary\n   log_dyn,       // unary\n   mul_dyn,       // binary\n   neg_dyn,       // unary\n   pow_dyn,       // binary\n   result_dyn,    // 0 arguments: atomic function result\n   sign_dyn,      // unary\n   sin_dyn,       // unary\n   sinh_dyn,      // unary\n   sqrt_dyn,      // unary\n   sub_dyn,       // binary\n   tan_dyn,       // unary\n   tanh_dyn,      // unary\n   zmul_dyn,      // binary\n   number_dyn     // number of operator codes and invalid operator value\n};\n// END_OP_CODE_DYN\n// END_SORT_THIS_LINE_MINUS_4\n\n/*\n{xrst_begin num_arg_dyn dev}\n\nNumber of Arguments to a Dynamic Parameter Operator\n###################################################\n\nSyntax\n******\n| *n_arg* = ``local::num_arg_dyn`` ( *op* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_NUM_ARG_DYN_PROTOTYPE\n   // END_NUM_ARG_DYN_PROTOTYPE\n}\n\nParallel Mode\n*************\nThis routine has static data so its first call cannot be in Parallel mode.\n\nop\n**\nis the operator in question.\n\nn_arg\n*****\nThe return value is the number of arguments as commented in the\n:ref:`op_code_dyn@Source` for ``enum op_code_dyn`` .\nThere is one exception: if *op* is ``atom_dyn`` ,\n*n_arg* is zero; see :ref:`op_code_dyn@atom_dyn`\nfor the true number of arguments in this case.\n\natom_dyn\n********\nAll of the dynamic parameter operators have a fixed number of arguments\nexcept for the :ref:`op_code_dyn@atom_dyn`\noperator which calls an atomic functions.\nIn this special case the return value *n_arg* is zero\nwhich is not correct.\n\n{xrst_end num_arg_dyn}\n*/\n// BEGIN_NUM_ARG_DYN_PROTOTYPE\ninline size_t num_arg_dyn(op_code_dyn op)\n// END_NUM_ARG_DYN_PROTOTYPE\n{  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n\n   // BEGIN_SORT_THIS_LINE_PLUS_2\n   static const size_t num_arg_table[] = {\n      /* abs_dyn */      1,\n      /* acos_dyn */     1,\n      /* acosh_dyn */    1,\n      /* add_dyn */      2,\n      /* asin_dyn */     1,\n      /* asinh_dyn */    1,\n      /* atan_dyn */     1,\n      /* atanh_dyn */    1,\n      /* atom_dyn */     0,\n      /* cond_exp_dyn */ 5,\n      /* cos_dyn */      1,\n      /* cosh_dyn */     1,\n      /* dis_dyn */      2,\n      /* div_dyn */      2,\n      /* erf_dyn */      1,\n      /* erfc_dyn */     1,\n      /* exp_dyn */      1,\n      /* expm1_dyn */    1,\n      /* fabs_dyn */     1,\n      /* ind_dyn */      0,\n      /* log1p_dyn */    1,\n      /* log_dyn */      1,\n      /* mul_dyn */      2,\n      /* neg_dyn */      1,\n      /* pow_dyn */      2,\n      /* result_dyn */   0,\n      /* sign_dyn */     1,\n      /* sin_dyn */      1,\n      /* sinh_dyn */     1,\n      /* sqrt_dyn */     1,\n      /* sub_dyn */      2,\n      /* tan_dyn */      1,\n      /* tanh_dyn */     1,\n      /* zmul_dyn */     2,\n      0  // number_dyn (not used)\n   };\n   // END_SORT_THIS_LINE_MINUS_3\n   //\n   static bool first = true;\n   if( first )\n   {  CPPAD_ASSERT_UNKNOWN(\n      size_t(number_dyn)+1 == sizeof(num_arg_table)/sizeof(num_arg_table[0])\n      );\n      first = false;\n   }\n   return num_arg_table[op];\n}\n\n/*\n{xrst_begin op_name_dyn dev}\n\nNumber of Arguments to a Dynamic Parameter Operator\n###################################################\n\nSyntax\n******\n\n   *name* = ``local::op_name_dyn`` ( *op* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_OP_NAME_DYN_PROTOTYPE\n   // END_OP_NAME_DYN_PROTOTYPE\n}\n\nParallel Mode\n*************\nThis routine has static data so its first call cannot be in Parallel mode.\n\nop\n**\nis the operator in question.\n\nname\n****\nThe return value *name* is the same as the operator enum symbol\n(see :ref:`op_code_dyn@Source` for ``enum op_code_dyn`` )\nwithout the ``_dyn`` at the end. For example,\nthe name corresponding to the\n:ref:`op_code_dyn@cond_exp_dyn` operator is ``cond_exp`` .\n\n{xrst_end op_name_dyn}\n*/\n// BEGIN_OP_NAME_DYN_PROTOTYPE\ninline const char* op_name_dyn(op_code_dyn op)\n// END_OP_NAME_DYN_PROTOTYPE\n{  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n\n   // BEGIN_SORT_THIS_LINE_PLUS_2\n   static const char* op_name_table[] = {\n      /* abs_dyn */      \"abs\",\n      /* acos_dyn */     \"acos\",\n      /* acosh_dyn */    \"acosh\",\n      /* add_dyn */      \"add\",\n      /* asin_dyn */     \"asin\",\n      /* asinh_dyn */    \"asinh\",\n      /* atan_dyn */     \"atan\",\n      /* atanh_dyn */    \"atanh\",\n      /* atom_dyn */     \"call\",\n      /* cond_exp_dyn */ \"cond_exp\",\n      /* cos_dyn */      \"cos\",\n      /* cosh_dyn */     \"cosh\",\n      /* dis_dyn */      \"dis\",\n      /* div_dyn */      \"div\",\n      /* erf_dyn */      \"erf\",\n      /* erfc_dyn */     \"erfc\",\n      /* exp_dyn */      \"exp\",\n      /* expm1_dyn */    \"expm1\",\n      /* fabs_dyn */     \"fabs\",\n      /* ind_dyn */      \"ind\",\n      /* log1p_dyn */    \"log1p\",\n      /* log_dyn */      \"log\",\n      /* mul_dyn */      \"mul\",\n      /* neg_dyn */      \"neg\",\n      /* pow_dyn */      \"pow\",\n      /* result_dyn */   \"result\",\n      /* sign_dyn */     \"sign\",\n      /* sin_dyn */      \"sin\",\n      /* sinh_dyn */     \"sinh\",\n      /* sqrt_dyn */     \"sqrt\",\n      /* sub_dyn */      \"sub\",\n      /* tan_dyn */      \"tan\",\n      /* tanh_dyn */     \"tanh\",\n      /* zmul_dyn */     \"zmul\",\n      /* number_dyn */   \"number\"\n   };\n   // END_SORT_THIS_LINE_MINUS_3\n   static bool first = true;\n   if( first )\n   {  CPPAD_ASSERT_UNKNOWN(\n      size_t(number_dyn)+1 == sizeof(op_name_table)/sizeof(op_name_table[0])\n      );\n      first = false;\n   }\n   return op_name_table[op];\n}\n\n/*\n{xrst_begin num_non_par_arg_dyn dev}\n\nNumber Non-Parameter Arguments to a Dynamic Parameters Operator\n###############################################################\n\nSyntax\n******\n\n   *num* = ``local::num_non_par_arg_dyn`` ( *op* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_NUM_NON_PAR_ARG_DYN\n   // END_NUM_NON_PAR_ARG_DYN\n}\n\nop\n**\nis the operator in question.\n\nnum\n***\nThe return value *num* is the number of arguments,\nfor this operator *op* , that are not parameters indices.\nAll of the non-parameter arguments come first\nso *num* is also the offset for the\nfirst argument that is a parameter index.\n\nSpecial Case\n************\nIf :ref:`num_arg_dyn-name` ( *op* ) is zero and *num* is non-zero,\nthis operator has a variable number of arguments.\n(The only such operator so far is ``atom_dyn`` .)\nIn this case the last argument is not a parameter index and\nthere are *num* - 1 arguments that are not parameter indices\nbefore the first parameter index.\n\n{xrst_end num_non_par_arg_dyn}\n*/\n// BEGIN_NUM_NON_PAR_ARG_DYN\ninline size_t num_non_par_arg_dyn(op_code_dyn op)\n// END_NUM_NON_PAR_ARG_DYN\n{\n   size_t num;\n   switch(op)\n   {  case atom_dyn:\n      num = 6;\n      break;\n\n      case cond_exp_dyn:\n      case dis_dyn:\n      num = 1;\n      break;\n\n      default:\n      num = 0;\n   }\n   //\n   return num;\n}\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/op_code_var.hpp",
    "content": "# ifndef CPPAD_LOCAL_OP_CODE_VAR_HPP\n# define CPPAD_LOCAL_OP_CODE_VAR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <string>\n# include <sstream>\n# include <iomanip>\n\n# include <cppad/local/atomic_index.hpp>\n# include <cppad/local/define.hpp>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/local/pod_vector.hpp>\n\n// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*!\n{xrst_begin op_code_var dev}\n{xrst_spell\n   funap\n   funav\n   funrp\n   funrv\n   ldp\n   ldv\n   opcode\n   pri\n}\n\nVariable Op Codes\n#################\n\nNamespace\n*********\nAll of these definitions are in the ``CppAD::local`` namespace.\n\nopcode_t\n********\nThis type is used to save space when storing operator enum type in vectors.\n{xrst_spell_off}\n{xrst_code hpp} */\ntypedef CPPAD_VEC_ENUM_TYPE opcode_t;\n/* {xrst_code}\n{xrst_spell_on}\n\nop_code_var\n***********\nThis enum type is used to distinguish different ``AD`` < *Base* >\natomic operations.\nEach value in the enum type ends with the characters ``Op`` .\nIgnoring the ``Op`` at the end,\nthe operators appear in alphabetical order.\n\narg[i]\n******\nWe use the notation *arg* [ ``i`` ] below\nfor the *i*-th operator argument which is a position integer\nrepresented using the type ``addr_t`` .\n\n{xrst_comment ------------------------------------------------------------- }\nUnary\n*****\nsee :ref:`var_unary_op-name`\n\n{xrst_comment ------------------------------------------------------------- }\nBinary\n******\nsee :ref:`var_binary_op-name`\n\n{xrst_comment ------------------------------------------------------------- }\n{xrst_spell_off}\n\nEqppOp, LeppOp, LtppOp, NeppOp\n******************************\nsee :ref:`var_compare_op@op_code@EqppOp, LeppOp, LtppOp, NeppOp`\n\nEqpvOp, LepvOp, LtpvOp, NepvOp\n******************************\nsee :ref:`var_compare_op@op_code@EqpvOp, LepvOp, LtpvOp, NepvOp`\n\nLevpOp, LtvpOp\n**************\nsee :ref:`var_compare_op@op_code@LevpOp, LtvpOp`\n\nEqvvOp, LevvOp, LtvvOp, NevvOp\n******************************\nsee :ref:`var_compare_op@op_code@EqvvOp, LevvOp, LtvvOp, NevvOp`\n\n{xrst_spell_on}\n{xrst_comment ------------------------------------------------------------- }\n\nAFunOp\n******\nsee :ref:`var_atomic_op@AFunOp`\n\nFunapOp, FunavOp\n****************\nsee :ref:`var_atomic_op@FunapOp, FunavOp`\n\nFunrpOp, FunrvOp\n****************\nsee :ref:`var_atomic_op@FunrpOp, FunrvOp`\n\n\n{xrst_comment ------------------------------------------------------------- }\nBeginOp\n*******\nThis operator marks the start of the tape.\nIt has one parameter index argument that is nan and corresponds\nto parameter index zero.\nIt also has one variable result that has index zero which is used to\nindicate that a value is not a variable.\nfor indicate an parameter.\n\n{xrst_comment ------------------------------------------------------------- }\n\nCExpOp\n******\nsee :ref:`var_cexp_op@CExpOp`\n\n{xrst_comment ------------------------------------------------------------- }\n\nCSkipOp\n*******\nsee :ref:`var_cskip_op@CSkipOp` .\n\n{xrst_comment ------------------------------------------------------------- }\n\nCSumOp\n******\nsee :ref:`var_csum_op@CSumOp`\n\n{xrst_comment ------------------------------------------------------------- }\n\nDisOp\n*****\nsee :ref:`var_dis_op@DisOp`\n\n{xrst_comment ------------------------------------------------------------- }\n\nLdpOp, LdvOp\n============\nsee :ref:`var_load_op@LdpOp, LdvOp`\n\n{xrst_comment ------------------------------------------------------------- }\n{xrst_spell_off}\n\nStppOp, StpvOp, StvpOp, StvvOp\n==============================\nsee :ref:`var_store_op@StppOp, StpvOp, StvpOp, StvvOp`\n\n{xrst_spell_on}\n{xrst_comment ------------------------------------------------------------- }\n\nParOp\n=====\nsee :ref:`var_par_op@ParOp`\n\n{xrst_comment ------------------------------------------------------------- }\n\nPriOp\n*****\nsee :ref:`var_pri_op@PriOp`\n\n{xrst_comment ------------------------------------------------------------- }\n\n{xrst_comment // BEGIN_SORT_THIS_LINE_PLUS_2 }\n{xrst_toc_table\n   include/cppad/local/var_op/atomic_op.hpp\n   include/cppad/local/var_op/binary_op.xrst\n   include/cppad/local/var_op/cexp_op.hpp\n   include/cppad/local/var_op/compare_op.hpp\n   include/cppad/local/var_op/cskip_op.hpp\n   include/cppad/local/var_op/csum_op.hpp\n   include/cppad/local/var_op/dis_op.hpp\n   include/cppad/local/var_op/load_op.hpp\n   include/cppad/local/var_op/one_var.hpp\n   include/cppad/local/var_op/par_op.hpp\n   include/cppad/local/var_op/pri_op.hpp\n   include/cppad/local/var_op/store_op.hpp\n   include/cppad/local/var_op/two_var.hpp\n   include/cppad/local/var_op/unary_op.xrst\n}\n{xrst_comment // END_SORT_THIS_LINE_MINUS_2 }\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\n// BEGIN_SORT_THIS_LINE_PLUS_2\nenum op_code_var {\n   AFunOp,   // see its heading above\n   AbsOp,    // unary fabs\n   AcosOp,   // unary acos\n   AcoshOp,  // unary acosh\n   AddpvOp,  // binary +\n   AddvvOp,  // ...\n   AsinOp,   // unary asin\n   AsinhOp,  // unary asinh\n   AtanOp,   // unary atan\n   AtanhOp,  // unary atanh\n   BeginOp,  // see its heading above\n   CExpOp,   // ...\n   CSkipOp,  // see its heading above\n   CSumOp,   // ...\n   CosOp,    // unary cos\n   CoshOp,   // unary cosh\n   DisOp,    // ...\n   DivpvOp,  // binary /\n   DivvpOp,  // ...\n   DivvvOp,  // ...\n   EndOp,    // used to mark the end of the tape\n   EqppOp,   // compare equal\n   EqpvOp,   // ...\n   EqvvOp,   // ...\n   ErfOp,    // unary erf\n   ErfcOp,   // unary erfc\n   ExpOp,    // unary exp\n   Expm1Op,  // unary expm1\n   FunapOp,  // see AFun heading above\n   FunavOp,  // ...\n   FunrpOp,  // ...\n   FunrvOp,  // ...\n   InvOp,    // independent variable, no arguments, one result variable\n   LdpOp,    // see its heading above\n   LdvOp,    // ...\n   LeppOp,   // compare <=\n   LepvOp,   // ...\n   LevpOp,   // ...\n   LevvOp,   // ...\n   Log1pOp,  // unary log1p\n   LogOp,    // unary log\n   LtppOp,   // compare <\n   LtpvOp,   // ...\n   LtvpOp,   // ...\n   LtvvOp,   // ...\n   MulpvOp,  // binary *\n   MulvvOp,  // ...\n   NegOp,    // unary negative\n   NeppOp,   // compare !=\n   NepvOp,   // ...\n   NevvOp,   // ...\n   ParOp,    // see its heading above\n   PowpvOp,  // see its heading above\n   PowvpOp,  // binary pow\n   PowvvOp,  // ..\n   PriOp,    // ..\n   SignOp,   // unary sign\n   SinOp,    // unary sin\n   SinhOp,   // unary sinh\n   SqrtOp,   // unary sqrt\n   StppOp,   // see its heading above\n   StpvOp,   // ...\n   StvpOp,   // ...\n   StvvOp,   // ...\n   SubpvOp,  // binary -\n   SubvpOp,  // ...\n   SubvvOp,  // ...\n   TanOp,    // unary tan\n   TanhOp,   // unary tanh\n   ZmulpvOp, // binary azmul\n   ZmulvpOp, // ...\n   ZmulvvOp, // ...\n   NumberOp  // number of operator codes (not an operator)\n};\n// END_SORT_THIS_LINE_MINUS_3\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end op_code_var}\n*/\n// Note that bin/check_op_code.sh assumes the pattern NumberOp occurs\n// at the end of this list and only at the end of this list.\n\n/*!\nNumber of arguments for a specified operator.\n\n\\return\nNumber of arguments corresponding to the specified operator.\n\n\\param op\nOperator for which we are fetching the number of arguments.\n\n\\par NumArgTable\nthis table specifies the number of arguments stored for each\noccurrence of the operator that is the i-th value in the op_code_var enum type.\nFor example, for the first three op_code_var enum values we have\n\\verbatim\nop_code_var j   NumArgTable[j]  Meaning\nAbsOp    0                1  index of variable we are taking absolute value of\nAcosOp   1                1  index of variable we are taking acos of\nAcoshOp  2                1  index of variable we are taking acosh of\n\\endverbatim\nNote that the meaning of the arguments depends on the operator.\n*/\ninline size_t NumArg( op_code_var op)\n{  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n\n   // agreement with op_code_var is checked by bin/check_op_code.sh\n   // BEGIN_SORT_THIS_LINE_PLUS_2\n   static const size_t NumArgTable[] = {\n      /* AFunOp   */ 4,\n      /* AbsOp    */ 1,\n      /* AcosOp   */ 1,\n      /* AcoshOp  */ 1,\n      /* AddpvOp  */ 2,\n      /* AddvvOp  */ 2,\n      /* AsinOp   */ 1,\n      /* AsinhOp  */ 1,\n      /* AtanOp   */ 1,\n      /* AtanhOp  */ 1,\n      /* BeginOp  */ 1,  // offset first real argument to have index 1\n      /* CExpOp   */ 6,\n      /* CSkipOp  */ 0,  // (has a variable number of arguments, not zero)\n      /* CSumOp   */ 0,  // (has a variable number of arguments, not zero)\n      /* CosOp    */ 1,\n      /* CoshOp   */ 1,\n      /* DisOp    */ 2,\n      /* DivpvOp  */ 2,\n      /* DivvpOp  */ 2,\n      /* DivvvOp  */ 2,\n      /* EndOp    */ 0,\n      /* EqppOp   */ 2,\n      /* EqpvOp   */ 2,\n      /* EqvvOp   */ 2,\n      /* ErfOp    */ 3,\n      /* ErfcOp   */ 3,\n      /* ExpOp    */ 1,\n      /* Expm1Op  */ 1,\n      /* FunapOp  */ 1,\n      /* FunavOp  */ 1,\n      /* FunrpOp  */ 1,\n      /* FunrvOp  */ 0,\n      /* InvOp    */ 0,\n      /* LdpOp    */ 3,\n      /* LdvOp    */ 3,\n      /* LeppOp   */ 2,\n      /* LepvOp   */ 2,\n      /* LevpOp   */ 2,\n      /* LevvOp   */ 2,\n      /* Log1pOp  */ 1,\n      /* LogOp    */ 1,\n      /* LtppOp   */ 2,\n      /* LtpvOp   */ 2,\n      /* LtvpOp   */ 2,\n      /* LtvvOp   */ 2,\n      /* MulpvOp  */ 2,\n      /* MulvvOp  */ 2,\n      /* NegOp    */ 1,\n      /* NeppOp   */ 2,\n      /* NepvOp   */ 2,\n      /* NevvOp   */ 2,\n      /* ParOp    */ 1,\n      /* PowpvOp  */ 2,\n      /* PowvpOp  */ 2,\n      /* PowvvOp  */ 2,\n      /* PriOp    */ 5,\n      /* SignOp   */ 1,\n      /* SinOp    */ 1,\n      /* SinhOp   */ 1,\n      /* SqrtOp   */ 1,\n      /* StppOp   */ 3,\n      /* StpvOp   */ 3,\n      /* StvpOp   */ 3,\n      /* StvvOp   */ 3,\n      /* SubpvOp  */ 2,\n      /* SubvpOp  */ 2,\n      /* SubvvOp  */ 2,\n      /* TanOp    */ 1,\n      /* TanhOp   */ 1,\n      /* ZmulpvOp */ 2,\n      /* ZmulvpOp */ 2,\n      /* ZmulvvOp */ 2,\n      0  // NumberOp not used\n   };\n   // END_SORT_THIS_LINE_MINUS_3\n# ifndef NDEBUG\n   // only do these checks once to save time\n   static bool first = true;\n   if( first )\n   {  first = false;\n      // check that NumberOp is last value in op code table\n      CPPAD_ASSERT_UNKNOWN(\n         size_t(NumberOp) + 1 == sizeof(NumArgTable)/sizeof(NumArgTable[0])\n      );\n      //Check that the type CPPAD_VEC_ENUM_TYPE as required by define.hpp\n      CPPAD_ASSERT_UNKNOWN( is_pod<opcode_t>() );\n      size_t number_op_size_t = size_t( NumberOp );\n      CPPAD_ASSERT_UNKNOWN(\n         number_op_size_t < std::numeric_limits<opcode_t>::max()\n      );\n   }\n   // do this check every time\n   CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) );\n# endif\n\n   return NumArgTable[op];\n}\n\n/*!\nNumber of variables resulting from the specified operation.\n\n\\param op\nOperator for which we are fecching the number of results.\n\n\\par NumResTable\ntable specifies the number of variables that result for each\noccurrence of the operator that is the i-th value in the op_code_var enum type.\nFor example, for the first three op_code_var enum values we have\n\\verbatim\nop_code_var j   NumResTable[j]  Meaning\nAbsOp    0                1  variable that is the result of the absolute value\nAcosOp   1                2  acos(x) and sqrt(1-x*x) are required for this op\nAcoshOp  2                2  acosh(x) and sqrt(x*x-1) are required for this op\n\\endverbatim\n*/\ninline size_t NumRes(op_code_var op)\n{  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n\n   // agreement with op_code_var is checked by bin/check_op_code.sh\n   // BEGIN_SORT_THIS_LINE_PLUS_2\n   static const size_t NumResTable[] = {\n      /* AFunOp   */ 0,\n      /* AbsOp    */ 1,\n      /* AcosOp   */ 2,\n      /* AcoshOp  */ 2,\n      /* AddpvOp  */ 1,\n      /* AddvvOp  */ 1,\n      /* AsinOp   */ 2,\n      /* AsinhOp  */ 2,\n      /* AtanOp   */ 2,\n      /* AtanhOp  */ 2,\n      /* BeginOp  */ 1,  // offsets first variable to have index one (not zero)\n      /* CExpOp   */ 1,\n      /* CSkipOp  */ 0,\n      /* CSumOp   */ 1,\n      /* CosOp    */ 2,\n      /* CoshOp   */ 2,\n      /* DisOp    */ 1,\n      /* DivpvOp  */ 1,\n      /* DivvpOp  */ 1,\n      /* DivvvOp  */ 1,\n      /* EndOp    */ 0,\n      /* EqppOp   */ 0,\n      /* EqpvOp   */ 0,\n      /* EqvvOp   */ 0,\n      /* ErfOp    */ 5,\n      /* ErfcOp   */ 5,\n      /* ExpOp    */ 1,\n      /* Expm1Op  */ 1,\n      /* FunapOp  */ 0,\n      /* FunavOp  */ 0,\n      /* FunrpOp  */ 0,\n      /* FunrvOp  */ 1,\n      /* InvOp    */ 1,\n      /* LdpOp    */ 1,\n      /* LdvOp    */ 1,\n      /* LeppOp   */ 0,\n      /* LepvOp   */ 0,\n      /* LevpOp   */ 0,\n      /* LevvOp   */ 0,\n      /* Log1pOp  */ 1,\n      /* LogOp    */ 1,\n      /* LtppOp   */ 0,\n      /* LtpvOp   */ 0,\n      /* LtvpOp   */ 0,\n      /* LtvvOp   */ 0,\n      /* MulpvOp  */ 1,\n      /* MulvvOp  */ 1,\n      /* NegOp    */ 1,\n      /* NeppOp   */ 0,\n      /* NepvOp   */ 0,\n      /* NevvOp   */ 0,\n      /* ParOp    */ 1,\n      /* PowpvOp  */ 3,\n      /* PowvpOp  */ 1,\n      /* PowvvOp  */ 3,\n      /* PriOp    */ 0,\n      /* SignOp   */ 1,\n      /* SinOp    */ 2,\n      /* SinhOp   */ 2,\n      /* SqrtOp   */ 1,\n      /* StppOp   */ 0,\n      /* StpvOp   */ 0,\n      /* StvpOp   */ 0,\n      /* StvvOp   */ 0,\n      /* SubpvOp  */ 1,\n      /* SubvpOp  */ 1,\n      /* SubvvOp  */ 1,\n      /* TanOp    */ 2,\n      /* TanhOp   */ 2,\n      /* ZmulpvOp */ 1,\n      /* ZmulvpOp */ 1,\n      /* ZmulvvOp */ 1,\n      0  // NumberOp not used and avoids g++ 4.3.2 warn when pycppad builds\n   };\n   // END_SORT_THIS_LINE_MINUS_3\n   // check ensuring conversion to size_t is as expected\n   CPPAD_ASSERT_UNKNOWN( size_t(NumberOp) + 1 ==\n      sizeof(NumResTable) / sizeof(NumResTable[0])\n   );\n   // this test ensures that all indices are within the table\n   CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) );\n\n   return NumResTable[op];\n}\n\n\n/*!\nFetch the name for a specified operation.\n\n\\return\nname of the specified operation.\n\n\\param op\nOperator for which we are fetching the name\n*/\ninline std::string OpName(op_code_var op)\n{  // agreement with op_code_var is checked by bin/check_op_code.sh\n   // BEGIN_SORT_THIS_LINE_PLUS_2\n   static const char *OpNameTable[] = {\n      \"AFunOp\"  ,\n      \"AbsOp\"   ,\n      \"AcosOp\"  ,\n      \"AcoshOp\" ,\n      \"AddpvOp\" ,\n      \"AddvvOp\" ,\n      \"AsinOp\"  ,\n      \"AsinhOp\" ,\n      \"AtanOp\"  ,\n      \"AtanhOp\" ,\n      \"BeginOp\" ,\n      \"CExpOp\"  ,\n      \"CSkipOp\" ,\n      \"CSumOp\"  ,\n      \"CosOp\"   ,\n      \"CoshOp\"  ,\n      \"DisOp\"   ,\n      \"DivpvOp\" ,\n      \"DivvpOp\" ,\n      \"DivvvOp\" ,\n      \"EndOp\"   ,\n      \"EqppOp\"  ,\n      \"EqpvOp\"  ,\n      \"EqvvOp\"  ,\n      \"ErfOp\"   ,\n      \"ErfcOp\"  ,\n      \"ExpOp\"   ,\n      \"Expm1Op\" ,\n      \"FunapOp\" ,\n      \"FunavOp\" ,\n      \"FunrpOp\" ,\n      \"FunrvOp\" ,\n      \"InvOp\"   ,\n      \"LdpOp\"   ,\n      \"LdvOp\"   ,\n      \"LeppOp\"  ,\n      \"LepvOp\"  ,\n      \"LevpOp\"  ,\n      \"LevvOp\"  ,\n      \"Log1pOp\" ,\n      \"LogOp\"   ,\n      \"LtppOp\"  ,\n      \"LtpvOp\"  ,\n      \"LtvpOp\"  ,\n      \"LtvvOp\"  ,\n      \"MulpvOp\" ,\n      \"MulvvOp\" ,\n      \"NegOp\"   ,\n      \"NeppOp\"  ,\n      \"NepvOp\"  ,\n      \"NevvOp\"  ,\n      \"ParOp\"   ,\n      \"PowpvOp\" ,\n      \"PowvpOp\" ,\n      \"PowvvOp\" ,\n      \"PriOp\"   ,\n      \"SignOp\"  ,\n      \"SinOp\"   ,\n      \"SinhOp\"  ,\n      \"SqrtOp\"  ,\n      \"StppOp\"  ,\n      \"StpvOp\"  ,\n      \"StvpOp\"  ,\n      \"StvvOp\"  ,\n      \"SubpvOp\" ,\n      \"SubvpOp\" ,\n      \"SubvvOp\" ,\n      \"TanOp\"   ,\n      \"TanhOp\"  ,\n      \"ZmulpvOp\",\n      \"ZmulvpOp\",\n      \"ZmulvvOp\",\n      \"Number\"  // not used\n   };\n   // END_SORT_THIS_LINE_MINUS_3\n\n   // check ensuring conversion to size_t is as expected\n   CPPAD_ASSERT_UNKNOWN(\n      size_t(NumberOp) + 1 == sizeof(OpNameTable)/sizeof(OpNameTable[0])\n   );\n   // this test ensures that all indices are within the table\n   CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) );\n\n   // result\n   std::string result = OpNameTable[op];\n   result             = result.substr(0, result.size() - 2);\n\n   return result;\n}\n\n/*!\nPrints a single field corresponding to an operator.\n\nA specified leader is printed in front of the value\nand then the value is left justified in the following width character.\n\n\\tparam Type\nis the type of the value we are printing.\n\n\\param os\nis the stream that we are printing to.\n\n\\param leader\nare characters printed before the value.\n\n\\param value\nis the value being printed.\n\n\\param width\nis the number of character to print the value in.\nIf the value does not fit in the width, the value is replace\nby width '*' characters.\n*/\ntemplate <class Type>\nvoid printOpField(\n   std::ostream      &os ,\n   const char *   leader ,\n   const Type     &value ,\n   size_t          width )\n{\n   std::ostringstream buffer;\n   std::string        str;\n\n   // first print the leader\n   os << leader;\n\n   // print the value into an internal buffer\n   buffer << value;\n   str = buffer.str();\n\n   // length of the string\n   size_t len = str.size();\n   if( len > width )\n   {\n      for(size_t i = 0; i < width-1; i++)\n         os << str[i];\n      os << \"*\";\n      return;\n   }\n\n   // count number of spaces at beginning\n   size_t nspace = 0;\n   while(str[nspace] == ' ' && nspace < len)\n      nspace++;\n\n   // left justify the string\n   size_t i = nspace;\n   while( i < len )\n      os << str[i++];\n\n   i = width - len + nspace;\n   while(i--)\n      os << \" \";\n}\n\n/*!\nPrints a single operator and its operands\n\n\\tparam Base\nIs the base type for these AD< Base > operations.\n\n\\param os\nis the output stream that the information is printed on.\n\n\\param play\nIs the entire recording for the tape that this operator is in.\n\n\\param i_op\nis the index for the operator corresponding to this operation.\n\n\\param i_var\nis the index for the variable corresponding to the result of this operation\n(if NumRes(op) > 0).\n\n\\param op\nThe operator code (op_code_var) for this operation.\n\n\\param arg\nis the vector of argument indices for this operation\n(must have NumArg(op) elements).\n*/\ntemplate <class Base, class RecBase>\nvoid printOp(\n   std::ostream&          os     ,\n   const local::player<Base>* play,\n   size_t                 i_op   ,\n   size_t                 i_var  ,\n   op_code_var            op     ,\n   const addr_t*          arg    )\n{\n   CPPAD_ASSERT_KNOWN(\n      ! thread_alloc::in_parallel() ,\n      \"cannot print trace of AD operations in parallel mode\"\n   );\n   static const char *CompareOpName[] =\n      { \"Lt\", \"Le\", \"Eq\", \"Ge\", \"Gt\", \"Ne\" };\n\n   // print operator\n   printOpField(os,  \"o=\",      i_op,  5);\n   if( NumRes(op) > 0 && op != BeginOp )\n      printOpField(os,  \"v=\",      i_var, 5);\n   else\n      printOpField(os,  \"v=\",      \"\",    5);\n   if( op == CExpOp || op == CSkipOp )\n   {  printOpField(os, \"\", OpName(op).c_str(), 5);\n      printOpField(os, \"\", CompareOpName[ arg[0] ], 3);\n   }\n   else\n      printOpField(os, \"\", OpName(op).c_str(), 8);\n\n   // print other fields\n   size_t ncol = 5;\n   switch( op )\n   {\n      case CSkipOp:\n      /*\n      arg[0]     = the Rel operator: Lt, Le, Eq, Ge, Gt, or Ne\n      arg[1] & 1 = is left a variable\n      arg[1] & 2 = is right a variable\n      arg[2]     = index corresponding to left\n      arg[3]     = index corresponding to right\n      arg[4] = number of operations to skip if CExpOp comparison is true\n      arg[5] = number of operations to skip if CExpOp comparison is false\n      arg[6] -> arg[5+arg[4]]               = skip operations if true\n      arg[6+arg[4]] -> arg[5+arg[4]+arg[5]] = skip operations if false\n      arg[6+arg[4]+arg[5]] = 6+arg[4]+arg[5]+1\n      */\n      CPPAD_ASSERT_UNKNOWN( arg[6+arg[4]+arg[5]] == 6+arg[4]+arg[5]+1 );\n      CPPAD_ASSERT_UNKNOWN(arg[1] != 0);\n      if( arg[1] & 1 )\n         printOpField(os, \" vl=\", arg[2], ncol);\n      else\n         printOpField(os, \" pl=\", play->par_one( size_t(arg[2]) ), ncol);\n      if( arg[1] & 2 )\n         printOpField(os, \" vr=\", arg[3], ncol);\n      else\n         printOpField(os, \" pr=\", play->par_one( size_t(arg[3]) ), ncol);\n      if( size_t(arg[4]) < 3 )\n      {  for(addr_t i = 0; i < arg[4]; i++)\n            printOpField(os, \" ot=\", arg[6+i], ncol);\n      }\n      else\n      {  printOpField(os, \"\\n\\tot=\", arg[6+0], ncol);\n         for(addr_t i = 1; i < arg[4]; i++)\n            printOpField(os, \" ot=\", arg[6+i], ncol);\n      }\n      if( size_t(arg[5]) < 3 )\n      {  for(addr_t i = 0; i < arg[5]; i++)\n            printOpField(os, \" of=\", arg[6+arg[4]+i], ncol);\n      }\n      else\n      {  printOpField(os, \"\\n\\tof=\", arg[6+arg[4]+0], ncol);\n         {  for(addr_t i = 1; i < arg[5]; i++)\n               printOpField(os, \" of=\", arg[6+arg[4]+i], ncol);\n         }\n      }\n      break;\n\n      case CSumOp:\n      /*\n      arg[0] = index of parameter that initializes summation\n      arg[1] = end in arg of addition variables in summation\n      arg[2] = end in arg of subtraction variables in summation\n      arg[3] = end in arg of addition dynamic parameters in summation\n      arg[4] = end in arg of subtraction dynamic parameters in summation\n      arg[5],      ... , arg[arg[1]-1]: indices for addition variables\n      arg[arg[1]], ... , arg[arg[2]-1]: indices for subtraction variables\n      arg[arg[2]], ... , arg[arg[3]-1]: indices for addition dynamics\n      arg[arg[3]], ... , arg[arg[4]-1]: indices for subtraction dynamics\n      arg[arg[4]] = arg[4] + 1\n      */\n      CPPAD_ASSERT_UNKNOWN( arg[arg[4]] == arg[4] + 1 );\n      printOpField(os, \" pr=\", play->par_one( size_t(arg[0]) ), ncol);\n      for(addr_t i = 5; i < arg[1]; i++)\n             printOpField(os, \" +v=\", arg[i], ncol);\n      for(addr_t i = arg[1]; i < arg[2]; i++)\n             printOpField(os, \" -v=\", arg[i], ncol);\n      for(addr_t i = arg[2]; i < arg[3]; i++)\n             printOpField(os, \" +d=\", play->par_one( size_t(arg[i]) ), ncol);\n      for(addr_t i = arg[3]; i < arg[4]; i++)\n             printOpField(os, \" -d=\", play->par_one( size_t(arg[i]) ), ncol);\n      break;\n\n      case LdpOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n      printOpField(os, \"off=\", arg[0], ncol);\n      printOpField(os, \"  p=\", play->par_one( size_t(arg[1]) ), ncol);\n      break;\n\n      case LdvOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n      printOpField(os, \"off=\", arg[0], ncol);\n      printOpField(os, \"  v=\", arg[1], ncol);\n      break;\n\n      case StppOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n      printOpField(os, \"off=\", arg[0], ncol);\n      printOpField(os, \" pl=\", play->par_one( size_t(arg[1]) ), ncol);\n      printOpField(os, \" pr=\", play->par_one( size_t(arg[2]) ), ncol);\n      break;\n\n      case StpvOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n      printOpField(os, \"off=\", arg[0], ncol);\n      printOpField(os, \"  p=\", play->par_one( size_t(arg[1]) ), ncol);\n      printOpField(os, \"  v=\", arg[2], ncol);\n      break;\n\n      case StvpOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n      printOpField(os, \"off=\", arg[0], ncol);\n      printOpField(os, \"  v=\", arg[1], ncol);\n      printOpField(os, \"  p=\", play->par_one( size_t(arg[2]) ), ncol);\n      break;\n\n      case StvvOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n      printOpField(os, \"off=\", arg[0], ncol);\n      printOpField(os, \" vl=\", arg[1], ncol);\n      printOpField(os, \" vr=\", arg[2], ncol);\n      break;\n\n      case AddvvOp:\n      case DivvvOp:\n      case EqvvOp:\n      case LevvOp:\n      case LtvvOp:\n      case NevvOp:\n      case MulvvOp:\n      case PowvvOp:\n      case SubvvOp:\n      case ZmulvvOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );\n      printOpField(os, \" vl=\", arg[0], ncol);\n      printOpField(os, \" vr=\", arg[1], ncol);\n      break;\n\n      case AddpvOp:\n      case EqpvOp:\n      case DivpvOp:\n      case LepvOp:\n      case LtpvOp:\n      case NepvOp:\n      case SubpvOp:\n      case MulpvOp:\n      case PowpvOp:\n      case ZmulpvOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );\n      printOpField(os, \" pl=\", play->par_one( size_t(arg[0]) ), ncol);\n      printOpField(os, \" vr=\", arg[1], ncol);\n      break;\n\n      case DivvpOp:\n      case LevpOp:\n      case LtvpOp:\n      case PowvpOp:\n      case SubvpOp:\n      case ZmulvpOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );\n      printOpField(os, \" vl=\", arg[0], ncol);\n      printOpField(os, \" pr=\", play->par_one( size_t(arg[1]) ), ncol);\n      break;\n\n      case AbsOp:\n      case AcosOp:\n      case AcoshOp:\n      case AsinOp:\n      case AsinhOp:\n      case AtanOp:\n      case AtanhOp:\n      case CosOp:\n      case CoshOp:\n      case ExpOp:\n      case Expm1Op:\n      case LogOp:\n      case Log1pOp:\n      case NegOp:\n      case SignOp:\n      case SinOp:\n      case SinhOp:\n      case SqrtOp:\n      case FunavOp:\n      case TanOp:\n      case TanhOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );\n      printOpField(os, \"  v=\", arg[0], ncol);\n      break;\n\n      case ErfOp:\n      case ErfcOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n      // arg[1] points to the parameter 0\n      // arg[2] points to the parameter 2 / sqrt(pi)\n      printOpField(os, \"  v=\", arg[0], ncol);\n      break;\n\n      case ParOp:\n      case FunapOp:\n      case FunrpOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );\n      printOpField(os, \"  p=\", play->par_one( size_t(arg[0]) ), ncol);\n      break;\n\n      case AFunOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 4 );\n      {\n         // get the name of this atomic function\n         bool         set_null   = false;\n         size_t       atom_index = size_t( arg[0] );\n         size_t       type       = 0;          // set to avoid warning\n         std::string name;\n         void*        v_ptr    = nullptr; // set to avoid warning\n         atomic_index<RecBase>(set_null, atom_index, type, &name, v_ptr);\n         printOpField(os, \" f=\",   name.c_str(), ncol);\n         printOpField(os, \" i=\", arg[1], ncol);\n         printOpField(os, \" n=\", arg[2], ncol);\n         printOpField(os, \" m=\", arg[3], ncol);\n      }\n      break;\n\n      case PriOp:\n      CPPAD_ASSERT_NARG_NRES(op, 5, 0);\n      if( arg[0] & 1 )\n         printOpField(os, \" v=\", arg[1], ncol);\n      else\n         printOpField(os, \" p=\", play->par_one( size_t(arg[1]) ), ncol);\n      os << \"before=\\\"\" << play->GetTxt( size_t(arg[2]) ) << \"\\\"\";\n      if( arg[0] & 2 )\n         printOpField(os, \" v=\", arg[3], ncol);\n      else\n         printOpField(os, \" p=\", play->par_one( size_t(arg[3]) ), ncol);\n      os << \"after=\\\"\" << play->GetTxt( size_t(arg[4]) ) << \"\\\"\";\n      break;\n\n      case BeginOp:\n      // argument not used (created by independent)\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );\n      break;\n\n      case EndOp:\n      case InvOp:\n      case FunrvOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 0 );\n      break;\n\n      case DisOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );\n      {  const std::string name = discrete<Base>::name( size_t(arg[0]) );\n         printOpField(os, \" f=\", name.c_str(), ncol);\n         printOpField(os, \" x=\", arg[1], ncol);\n      }\n      break;\n\n\n      case CExpOp:\n      CPPAD_ASSERT_UNKNOWN(arg[1] != 0);\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 6 );\n      if( arg[1] & 1 )\n         printOpField(os, \" vl=\", arg[2], ncol);\n      else\n         printOpField(os, \" pl=\", play->par_one( size_t(arg[2]) ), ncol);\n      if( arg[1] & 2 )\n         printOpField(os, \" vr=\", arg[3], ncol);\n      else\n         printOpField(os, \" pr=\", play->par_one( size_t(arg[3]) ), ncol);\n      if( arg[1] & 4 )\n         printOpField(os, \" vt=\", arg[4], ncol);\n      else\n         printOpField(os, \" pt=\", play->par_one( size_t(arg[4]) ), ncol);\n      if( arg[1] & 8 )\n         printOpField(os, \" vf=\", arg[5], ncol);\n      else\n         printOpField(os, \" pf=\", play->par_one( size_t(arg[5]) ), ncol);\n      break;\n\n      case EqppOp:\n      case LeppOp:\n      case LtppOp:\n      case NeppOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );\n      printOpField(os, \" pl=\", play->par_one( size_t(arg[0]) ), ncol);\n      printOpField(os, \" pr=\", play->par_one( size_t(arg[1]) ), ncol);\n      break;\n\n      default:\n      CPPAD_ASSERT_UNKNOWN(0);\n   }\n}\n\n/*!\nPrints the result values corresponding to an operator.\n\n\\tparam Base\nIs the base type for these AD< Base > operations.\n\n\\tparam Value\nDetermines the type of the values that we are printing.\n\n\\param os\nis the output stream that the information is printed on.\n\n\\param nfz\nis the number of forward sweep calculated values of type Value\nthat correspond to this operation\n(ignored if NumRes(op) == 0).\n\n\\param fz\npoints to the first forward calculated value\nthat correspond to this operation\n(ignored if NumRes(op) == 0).\n\n\\param nrz\nis the number of reverse sweep calculated values of type Value\nthat correspond to this operation\n(ignored if NumRes(op) == 0).\n\n\\param rz\npoints to the first reverse calculated value\nthat correspond to this operation\n(ignored if NumRes(op) == 0).\n*/\ntemplate <class Value>\nvoid printOpResult(\n   std::ostream          &os     ,\n   size_t                 nfz    ,\n   const  Value          *fz     ,\n   size_t                 nrz    ,\n   const  Value          *rz     )\n{\n   size_t k;\n   for(k = 0; k < nfz; k++)\n      os << \"| fz[\" << k << \"]=\" << fz[k];\n   for(k = 0; k < nrz; k++)\n      os << \"| rz[\" << k << \"]=\" << rz[k];\n}\n\n/*!\nDetermines which arguments are variaibles for an operator.\n\n\\param op\nis the operator. Note that CSkipOp and CSumOp are special cases\nbecause the true number of arguments is not equal to NumArg(op)\nand the true number of arguments num_arg can be large.\nIt may be more efficient to handle these cases separately\n(see below).\n\n\\param arg\nis the argument vector for this operator.\n\n\\param is_variable\nIf the input value of the elements in this vector do not matter.\nUpon return, resize has been used to set its size to the true number\nof arguments to this operator.\nIf op != CSkipOp and op != CSumOp, is_variable.size() = NumArg(op).\nThe j-th argument for this operator is a\nvariable index if and only if is_variable[j] is true. Note that the variable\nindex 0, for the BeginOp, does not correspond to a real variable and false\nis returned for this case.\n\n\\par CSkipOp\nIn the case of CSkipOp,\n\\code\n      is_variable.size()  = 7 + arg[4] + arg[5];\n      is_variable[2]      = (arg[1] & 1) != 0;\n      is_variable[3]      = (arg[1] & 2) != 0;\n\\endcode\nand all the other is_variable[j] values are false.\n\n\\par CSumOp\nIn the case of CSumOp,\n\\code\n      is_variable.size() = arg[4]\n      for(size_t j = 5; j < arg[2]; ++j)\n         is_variable[j] = true;\n\\endcode\nand all the other is_variable values are false.\n*/\ntemplate <class Addr>\nvoid arg_is_variable(\n   op_code_var       op          ,\n   const Addr*       arg         ,\n   pod_vector<bool>& is_variable )\n{  size_t num_arg = NumArg(op);\n   is_variable.resize( num_arg );\n   //\n   switch(op)\n   {\n      // -------------------------------------------------------------------\n      // cases where true number of arguments = NumArg(op) == 0\n\n      case EndOp:\n      case InvOp:\n      case FunrvOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 0 );\n      break;\n\n      // -------------------------------------------------------------------\n      // cases where NumArg(op) == 1\n      case AbsOp:\n      case AcoshOp:\n      case AcosOp:\n      case AsinhOp:\n      case AsinOp:\n      case AtanhOp:\n      case AtanOp:\n      case CoshOp:\n      case CosOp:\n      case Expm1Op:\n      case ExpOp:\n      case Log1pOp:\n      case LogOp:\n      case NegOp:\n      case SignOp:\n      case SinhOp:\n      case SinOp:\n      case SqrtOp:\n      case TanhOp:\n      case TanOp:\n      case FunavOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );\n      is_variable[0] = true;\n      break;\n\n      case BeginOp:\n      case ParOp:\n      case FunapOp:\n      case FunrpOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );\n      is_variable[0] = false;\n      break;\n\n\n      // -------------------------------------------------------------------\n      // cases where NumArg(op) == 2\n\n      case AddpvOp:\n      case DisOp:\n      case DivpvOp:\n      case EqpvOp:\n      case LepvOp:\n      case LtpvOp:\n      case MulpvOp:\n      case NepvOp:\n      case PowpvOp:\n      case SubpvOp:\n      case ZmulpvOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );\n      is_variable[0] = false;\n      is_variable[1] = true;\n      break;\n\n      case DivvpOp:\n      case LevpOp:\n      case LtvpOp:\n      case PowvpOp:\n      case SubvpOp:\n      case ZmulvpOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );\n      is_variable[0] = true;\n      is_variable[1] = false;\n      break;\n\n      case AddvvOp:\n      case DivvvOp:\n      case EqvvOp:\n      case LevvOp:\n      case LtvvOp:\n      case MulvvOp:\n      case NevvOp:\n      case PowvvOp:\n      case SubvvOp:\n      case ZmulvvOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );\n      is_variable[0] = true;\n      is_variable[1] = true;\n      break;\n\n      case ErfOp:\n      case ErfcOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n      is_variable[0] = true;\n      is_variable[1] = false; // parameter index corresponding to zero\n      is_variable[2] = false; // parameter index corresponding to one\n      break;\n\n      // --------------------------------------------------------------------\n      // cases where NumArg(op) == 3\n\n      case LdpOp:\n      case StppOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n      is_variable[0] = false;\n      is_variable[1] = false;\n      is_variable[2] = false;\n      break;\n\n      case LdvOp:\n      case StvpOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n      is_variable[0] = false;\n      is_variable[1] = true;\n      is_variable[2] = false;\n      break;\n\n      case StpvOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n      is_variable[0] = false;\n      is_variable[1] = false;\n      is_variable[2] = true;\n      break;\n\n      case StvvOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n      is_variable[0] = false;\n      is_variable[1] = true;\n      is_variable[2] = true;\n      break;\n\n      // --------------------------------------------------------------------\n      // case where NumArg(op) == 4\n      case AFunOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 4 );\n      for(size_t i = 0; i < 4; i++)\n         is_variable[i] = false;\n      break;\n\n      // --------------------------------------------------------------------\n      // case where NumArg(op) == 5\n      case PriOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 5 );\n      is_variable[0] = false;\n      is_variable[1] = (arg[0] & 1) != 0;\n      is_variable[2] = false;\n      is_variable[3] = (arg[0] & 2) != 0;\n      is_variable[4] = false;\n      break;\n\n      // --------------------------------------------------------------------\n      // case where NumArg(op) == 6\n      case CExpOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 6 );\n      is_variable[0] = false;\n      is_variable[1] = false;\n      is_variable[2] = (arg[1] & 1) != 0;\n      is_variable[3] = (arg[1] & 2) != 0;\n      is_variable[4] = (arg[1] & 4) != 0;\n      is_variable[5] = (arg[1] & 8) != 0;\n      break;\n\n      // -------------------------------------------------------------------\n      // CSkipOp:\n      case CSkipOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 0 )\n      //\n      // true number of arguments\n      num_arg = size_t(7 + arg[4] + arg[5]);\n      is_variable.resize(num_arg);\n      is_variable[0] = false;\n      is_variable[1] = false;\n      is_variable[2] = (arg[1] & 1) != 0;\n      is_variable[3] = (arg[1] & 2) != 0;\n      for(size_t i = 4; i < num_arg; ++i)\n         is_variable[i] = false;\n      break;\n\n      // -------------------------------------------------------------------\n      // CSumOp:\n      case CSumOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 0 )\n      //\n      // true number of arguments\n      num_arg = size_t(arg[4] + 1);\n      //\n      is_variable.resize( num_arg );\n      for(size_t i = 0; i < num_arg; ++i)\n         is_variable[i] = (5 <= i) && (i < size_t(arg[2]));\n      break;\n\n      case EqppOp:\n      case LeppOp:\n      case LtppOp:\n      case NeppOp:\n      CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );\n      is_variable[0] = false;\n      is_variable[1] = false;\n      break;\n\n      // --------------------------------------------------------------------\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n      break;\n   }\n   return;\n}\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/cexp_info.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_CEXP_INFO_HPP\n# define CPPAD_LOCAL_OPTIMIZE_CEXP_INFO_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/declare_ad.hpp> // defines CompareOp\n# include <cppad/utility/vector.hpp>\n\n/*!\n{xrst_begin optimize_cexp_info dev}\n{xrst_spell\n   cskip\n   struct\n}\n\nOptimization Information About Conditional Expressions\n######################################################\n\nstruct_cexp_info\n****************\ninformation about a conditional expression\nin the old operation sequence (before optimization).\n{xrst_literal\n   // BEGIN_STRUCT_CEXP_INFO\n   // END_STRUCT_CEXP_INFO\n}\n\ni_op\n====\nis the operator index for this conditional expression.\n\nleft\n====\nis the variable or parameter index (depending on flag)\nfor left operand in the comparison.\n\nright\n=====\nis the variable or parameter index (depending on flag)\nfor right operand in the comparison.\n\nmax_left_right\n==============\nis the maximum of the left and right variable indices.\nThis is a variable index, so parameters correspond to index zero.\n\ncop\n===\nis the comparison operator for this conditional expression.\n\nflag\n====\n\n#. (flag & 1) is true if and only if left is a variable\n#. (flag & 2) is true if and only if right is a variable\n\nstruct_cskip_new\n****************\ninformation about a conditional expression\nin thew new operation sequence (after optimization).\n{xrst_literal\n   // BEGIN_STRUCT_CSKIP_NEW\n   // END_STRUCT_CSKIP_NEW\n}\n\nleft\n====\nis the variable or parameter index (depending on flag)\nfor left operand in the comparison.\n\nright\n=====\nis the variable or parameter index (depending on flag)\nfor right operand in the comparison.\n\nmax_left_right\n==============\nis the maximum of the left and right variable indices.\nThis is a variable index, so parameters correspond to index zero.\n\ni_arg\n=====\nindex where this conditional skips arguments start\n(in the vector or arguments for all operators).\n\n{xrst_end optimize_cexp_info}\n*/\n\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize  {\n/*!\nInformation about one conditional expression.\n*/\n// BEGIN_STRUCT_CEXP_INFO\nstruct struct_cexp_info {\n   addr_t                i_op;\n   addr_t                left;\n   addr_t                right;\n   addr_t                max_left_right;\n   CompareOp             cop;\n   unsigned char         flag;\n};\n// END_STRUCT_CEXP_INFO\n\n// BEGIN_STRUCT_CSKIP_NEW\nstruct struct_cskip_new {\n   size_t left;\n   size_t right;\n   size_t max_left_right;\n   size_t i_arg;\n};\n// END_STRUCT_CSKIP_NEW\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\nnamespace CppAD { namespace local {\n   template <> inline bool is_pod<optimize::struct_cskip_new>(void)\n   { return true; }\n} }\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/csum_op_info.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_CSUM_OP_INFO_HPP\n# define CPPAD_LOCAL_OPTIMIZE_CSUM_OP_INFO_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/op_code_var.hpp>\n# include <cppad/local/declare_ad.hpp> // defines addr_t\n\n/*!\n\\file csum_op_info.hpp\nInformation about one old variable that is part of a new CSumOp operation.\n*/\n\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize  {\n/*!\nInformation about one old variable that is part of a new CSumOp operation.\n*/\nstruct struct_csum_op_info {\n   /// Pointer to first argument (child) for this old operator.\n   /// Set by the reverse sweep at beginning of optimization.\n   const addr_t*       arg;\n\n   /// Was this old variable added to the summation\n   /// (if not it was subtracted)\n   bool                add;\n\n   /// Operator for which this old variable is the result, NumRes(op) > 0.\n   op_code_var         op;\n};\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/csum_stacks.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_CSUM_STACKS_HPP\n# define CPPAD_LOCAL_OPTIMIZE_CSUM_STACKS_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <stack>\n# include <cppad/local/optimize/csum_op_info.hpp>\n\n/*!\n\\file csum_stacks.hpp\nInformation about one cumulative summation operation.\n*/\n\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize  {\n/*!\nInformation about one cumulative summation operation.\n*/\nstruct struct_csum_stacks {\n\n   /// old operator indices for this cumulative summation\n   std::stack<struct struct_csum_op_info>      op_info;\n\n   /// old variable indices to be added\n   std::stack<addr_t>                          add_var;\n\n   /// old variable indices to be subtracted\n   std::stack<addr_t>                          sub_var;\n\n   /// dynamic parameter indices to be added\n   std::stack<addr_t>                          add_dyn;\n\n   /// dynamic parameter indices to be subtracted\n   std::stack<addr_t>                          sub_dyn;\n};\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/extract_option.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_EXTRACT_OPTION_HPP\n# define CPPAD_LOCAL_OPTIMIZE_EXTRACT_OPTION_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*!\n{xrst_begin optimize_extract_option dev}\n{xrst_spell\n   struct\n}\n\nConvert Optimizer Options From String to Struct\n###############################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_OPTIMIZE_OPTIONS\n   // END_OPTIMIZE_OPTIONS\n}\n\nresult\n******\nThe return value, *result* below,  has the following type\n{xrst_literal\n   // BEGIN_OPTIONS_T\n   // END_OPTIONS_T\n}\n\n\noptions\n*******\nSee :ref:`optimize@options`\n\n{xrst_end optimize_extract_option}\n*/\n\n# include <cppad/core/cppad_assert.hpp>\n\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize  {\n\n// BEGIN_SORT_THIS_LINE_PLUS_3\n// BEGIN_OPTIONS_T\nstruct options_t {\n   bool   compare_op;\n   bool   conditional_skip;\n   bool   cumulative_sum_op;\n   bool   print_for_op;\n   bool   val_graph;\n   size_t collision_limit;\n};\n// END_OPTIONS_T\n// END_SORT_THIS_LINE_MINUS_3\n\n// BEGIN_OPTIMIZE_OPTIONS\ninline options_t extract_option(const std::string& options)\n// END_OPTIMIZE_OPTIONS\n{  //\n   // result: default value\n   struct options_t result = {\n      true,  // compare_op\n      true,  // conditional_skip\n      true,  // cumulative_sum_op\n      true,  // print_for_op\n      false, // val_graph\n      10     // collision_limit\n   };\n   size_t index = 0;\n   while( index < options.size() )\n   {  while( index < options.size() && options[index] == ' ' )\n         ++index;\n      std::string option;\n      while( index < options.size() && options[index] != ' ' )\n         option += options[index++];\n      if( option != \"\" )\n      {\n         if( option == \"no_compare_op\" )\n            result.compare_op = false;\n         else if( option == \"no_conditional_skip\" )\n            result.conditional_skip = false;\n         else if( option == \"no_cumulative_sum_op\" )\n            result.cumulative_sum_op = false;\n         else if( option == \"no_print_for_op\" )\n            result.print_for_op = false;\n         else if( option == \"val_graph\" )\n            result.val_graph = true;\n         else if( option.substr(0, 16)  == \"collision_limit=\" )\n         {  std::string value = option.substr(16, option.size());\n            bool value_ok = value.size() > 0;\n            for(size_t i = 0; i < value.size(); ++i)\n            {  value_ok &= '0' <= value[i];\n               value_ok &= value[i] <= '9';\n            }\n            if( ! value_ok )\n            {  option += \" value is not a sequence of decimal digits\";\n               CPPAD_ASSERT_KNOWN( false , option.c_str() );\n            }\n            result.collision_limit = size_t( std::atoi( value.c_str() ) );\n            if( result.collision_limit < 1 )\n            {  option += \" value must be greater than zero\";\n               CPPAD_ASSERT_KNOWN( false , option.c_str() );\n            }\n         }\n         else\n         {  option += \" is not a valid optimize option\";\n            CPPAD_ASSERT_KNOWN( false , option.c_str() );\n         }\n      }\n   }\n   return result;\n}\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/get_cexp_info.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_GET_CEXP_INFO_HPP\n# define CPPAD_LOCAL_OPTIMIZE_GET_CEXP_INFO_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/optimize/match_op.hpp>\n# include <cppad/local/optimize/cexp_info.hpp>\n# include <cppad/local/optimize/usage.hpp>\n\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize {\n\n/*!\n{xrst_begin optimize_get_cexp_info.hpp dev}\n{xrst_spell\n   deallocate\n   funap\n   funav\n   funrp\n   funrv\n}\n\nInformation for Each Conditional Expression\n###########################################\n\nSyntax\n******\n| ``get_cexp_info`` (\n| |tab| *play* ,\n| |tab| *random_itr* ,\n| |tab| *op_previous* ,\n| |tab| *op_usage* ,\n| |tab| *cexp2op* ,\n| |tab| *cexp_set* ,\n| |tab| *cexp_info* ,\n| |tab| *skip_op_true* ,\n| |tab| *skip_op_false*\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nRestrictions\n************\nDo not call this routine unless you are optimizing conditional expressions\nand there are conditional expressions in the operation sequence.\n\nBase\n****\nbase type for the operator; i.e., this operation was recorded\nusing AD<Base> and computations by this routine are done using type Base.\n\nplay\n****\nThis is the old operation sequence.\n\nrandom_itr\n**********\nThis is a random iterator for the old operation sequence.\n\ncexp2op\n*******\nThis is the number of conditional expressions in the operation sequence\nand must be non-zero.\n\ncexp_set\n********\nThis is a vector of sets, the i-th set, set[i],\nis a set of elements for the i-th operator.\nIf e is an element of set[i], let j = e / 2 and k = e % 2.\nIf the comparison for the j-th conditional expression is equal to bool(k),\nthe i-th operator can be skipped (is not used by any of the results).\nNote that j indexes the subset of operators that are conditional expressions\nin the old operation sequence.\n\ncexp_info\n*********\nThe input size of this vector must be zero.\nUpon return cexp_info has size equal to the number of conditional expressions\nin the operation sequence; i.e., the number of CExpOp operators.\nThe value cexp_info[j] is the information corresponding to the j-th\nconditional expression in the operation sequence.\nThis vector is in the same order as the operation sequence; i.e.\nif j1 > j2, cexp_info[j1].i_op > cexp_info[j2].i_op.\nNote that skip_op_true and skip_op_false could be part of this structure,\nbut then we would allocate and deallocate two vectors for each conditional\nexpression in the operation sequence.\n\nskip_op_true\n************\nThis vector of sets is empty on input.\nUpon return, the j-th set is the operators that are not used when\ncomparison result for cexp_info[j] is true.\nNote that FunapOp, FunavOp, FunrpOp, and FunrvOp, are not in this\nset and should be skipped when the corresponding AFunOp are skipped.\n\nskip_op_false\n*************\nThis vector of sets is empty on input.\nUpon return, the j-th set is the operators that are not used when\ncomparison result for cexp_info[j] is false.\nNote that FunapOp, FunavOp, FunrpOp, and FunrvOp, are not in this\nset and should be skipped when the corresponding AFunOp are skipped.\n\nop_previous\n***********\nThis argument has size equal to the number of operators\nin the operation sequence; i.e., num_op = play->nun_var_rec().\nIf op_previous[i] == 0, no replacement was found for the i-th operator.\nIf op_previous[i] != 0, op_usage[ op_previous[i] ] == usage_t(yes_usage).\n\nop_usage\n********\nThis argument has size equal to the number of operators\nin the operation sequence; i.e., num_op = play->nun_var_rec().\nThe value op_usage[i] is the usage for\nthe i-th operator in the operation sequence.\n\n{xrst_end optimize_get_cexp_info.hpp}\n*/\n\n// BEGIN_PROTOTYPE\ntemplate <class Addr, class Base>\nvoid get_cexp_info(\n   const player<Base>*                         play                ,\n   const play::const_random_iterator<Addr>&    random_itr          ,\n   const pod_vector<addr_t>&                   op_previous         ,\n   const pod_vector<usage_t>&                  op_usage            ,\n   const pod_vector<addr_t>&                   cexp2op             ,\n   const sparse::list_setvec&                  cexp_set            ,\n   vector<struct_cexp_info>&                   cexp_info           ,\n   sparse::list_setvec&                        skip_op_true        ,\n   sparse::list_setvec&                        skip_op_false       )\n// END_PROTOTYPE\n{\n   CPPAD_ASSERT_UNKNOWN( cexp_set.n_set() > 0  );\n   CPPAD_ASSERT_UNKNOWN( cexp_info.size() == 0 );\n\n   // number of operators in the tape\n   const size_t num_op = play->num_var_op();\n   CPPAD_ASSERT_UNKNOWN( op_usage.size() == num_op );\n   CPPAD_ASSERT_UNKNOWN( op_previous.size() == num_op );\n   //\n   // number of conditional expressions in the tape\n   size_t num_cexp_op = cexp2op.size();\n   //\n   // initialize mapping from variable index to operator index\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( (std::numeric_limits<addr_t>::max)() ) >= num_op\n   );\n   // ----------------------------------------------------------------------\n   // compute cexp_info\n   // ----------------------------------------------------------------------\n   //\n   // initialize information for each conditional expression\n   cexp_info.resize(num_cexp_op);\n   skip_op_true.resize(num_cexp_op, num_op);\n   skip_op_false.resize(num_cexp_op, num_op);\n   //\n   for(size_t i = 0; i < num_cexp_op; i++)\n   {  size_t i_op = size_t( cexp2op[i] );\n      CPPAD_ASSERT_UNKNOWN(\n         op_previous[i_op] == 0 || op_usage[i_op] == usage_t(yes_usage)\n      );\n      op_code_var   op;     // operator\n      const addr_t* arg;    // arguments\n      size_t        i_var;  // variable index of first result\n      random_itr.op_info(i_op, op, arg, i_var);\n      CPPAD_ASSERT_UNKNOWN( op == CExpOp );\n      //\n      struct_cexp_info info;\n      info.i_op       = addr_t(i_op);\n      info.cop        = CompareOp( arg[0] );\n      info.flag       = static_cast<unsigned char>(arg[1]);\n      info.left       = arg[2];\n      info.right      = arg[3];\n      //\n      // max_left_right\n      addr_t index    = 0;\n      if( arg[1] & 1 )\n         index = std::max<addr_t>(index, info.left);\n      if( arg[1] & 2 )\n         index = std::max<addr_t>(index, info.right);\n      info.max_left_right = index;\n      //\n      cexp_info[i] = info;\n   };\n   // Determine which operators can be conditionally skipped\n   size_t i_op = 0;\n   while(i_op < num_op)\n   {  size_t j_op = i_op;\n      bool keep = op_usage[i_op] != usage_t(no_usage);\n      keep     &= op_usage[i_op] != usage_t(csum_usage);\n      keep     &= op_previous[i_op] == 0;\n      if( keep )\n      {  sparse::list_setvec_const_iterator itr(cexp_set, i_op);\n         if( *itr != cexp_set.end() )\n         {  if( play->GetOp(i_op) == AFunOp )\n            {  // i_op is the first operations in this atomic function call.\n               // Find the last operation in this call.\n               ++j_op;\n               while( play->GetOp(j_op) != AFunOp )\n               {  switch( play->GetOp(j_op) )\n                  {  case FunapOp:\n                     case FunavOp:\n                     case FunrpOp:\n                     case FunrvOp:\n                     break;\n\n                     default:\n                     CPPAD_ASSERT_UNKNOWN(false);\n                  }\n                  ++j_op;\n               }\n            }\n         }\n         while( *itr != cexp_set.end() )\n         {  size_t element = *itr;\n            size_t index   = element / 2;\n            bool   compare = bool( element % 2 );\n            if( compare == false )\n            {  // cexp_info[index].skip_op_false.push_back(i_op);\n               skip_op_false.post_element(index, i_op);\n               if( j_op != i_op )\n               {  // cexp_info[index].skip_op_false.push_back(j_op);\n                  skip_op_false.post_element(index, j_op);\n               }\n            }\n            else\n            {  // cexp_info[index].skip_op_true.push_back(i_op);\n               skip_op_true.post_element(index, i_op);\n               if( j_op != i_op )\n               {  // cexp_info[index].skip_op_true.push_back(j_op);\n                  skip_op_true.post_element(index, j_op);\n               }\n            }\n            ++itr;\n         }\n      }\n      CPPAD_ASSERT_UNKNOWN( i_op <= j_op );\n      i_op += (1 + j_op) - i_op;\n   }\n   // process postings for skip_op_false, skip_op_true\n   for(size_t i = 0; i < num_cexp_op; ++i)\n   {  skip_op_false.process_post(i);\n      skip_op_true.process_post(i);\n   }\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/get_dyn_previous.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_GET_DYN_PREVIOUS_HPP\n# define CPPAD_LOCAL_OPTIMIZE_GET_DYN_PREVIOUS_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*!\n\\file get_cexp_info.hpp\nCreate operator information tables\n*/\n\n# include <cppad/local/optimize/match_op.hpp>\n# include <cppad/local/optimize/usage.hpp>\n# include <cppad/local/optimize/hash_code.hpp>\n\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize {\n\n/*!\nmapping from a dynamic parameter index to its arguments\n\n\\param i_dyn\nis the dynamic parameter index\n\n\\param dyn2par_index\nis the mapping from dynamic parameter index to parameter index\n(size is number of dynamic parameters).\n\n\\param par_is_dyn\ni-th element is true (false) if i-th parameter is (is not) dynamic\n(size is number of parameters).\n\n\\param dyn_arg_offset\nj-th element is the offset in dyn_par_arg of the first argument for j-th\ndynamic parameter's operator (size is number of dynamic parameters).\nThis is only defined for dynamic parameters indices less than or equal i_dyn.\n\n\\param dyn_par_arg\nit the vector of arguments for all the dynamic parameter operators.\nThis is only defined for dynamic parameters indices less than or equal i_dyn.\n\n\\param par_ind2dyn_ind\nis the mapping from parameter index to dynamic parameter index\n(size is number of parameters). This is only defined for parameter\nindices less than or equal the parameter index corresponding to i_dyn.\n\n\\param dyn_previous\nis the mapping from dynamic parameter index to previous dynamic parameter\nthat can be used as a replacement (size is number of dynamic parameters).\nThis is only defined for dynamic parameters indices less than or equal i_dyn.\n\n\\param arg_match\nSize of this vector must be number of arguments for operator for i_dyn.\nThe input value of its elements does not matter.\nUpn return it contains the parameter indices for the arguments\nto use when matching this operator\nArguments that are dynamic parameters, and have previous matches,\nhave been replaced by their previous matches.\n*/\ninline void dyn_arg_match(\n   size_t                    i_dyn           ,\n   const pod_vector<addr_t>& dyn2par_index ,\n   const pod_vector<bool>  & par_is_dyn      ,\n   const pod_vector<addr_t>& dyn_arg_offset  ,\n   const pod_vector<addr_t>& dyn_par_arg     ,\n   const pod_vector<addr_t>& par_ind2dyn_ind ,\n   const pod_vector<addr_t>& dyn_previous    ,\n   pod_vector<addr_t>&       arg_match       )\n{\n   // number of dynamic parameters\n   addr_t num_dynamic_par = addr_t( dyn2par_index.size() );\n   //\n   // check some assumptions\n   CPPAD_ASSERT_UNKNOWN( size_t( num_dynamic_par ) == dyn_arg_offset.size() );\n   CPPAD_ASSERT_UNKNOWN( size_t( num_dynamic_par ) == dyn_previous.size() );\n   CPPAD_ASSERT_UNKNOWN( par_is_dyn.size() == par_ind2dyn_ind.size() );\n   //\n   // number of arguments for this operator\n   addr_t n_arg = addr_t( arg_match.size() );\n   //\n   // index in dyn_par_arg of first argument for this operator\n   addr_t i_arg = dyn_arg_offset[i_dyn];\n   //\n   // loop over arguments for this operator\n   for(addr_t j = 0; j < n_arg; ++j)\n   {  // parameter index for this argument\n      addr_t j_par = dyn_par_arg[i_arg + j];\n      CPPAD_ASSERT_UNKNOWN( j_par < dyn2par_index[i_dyn] );\n      //\n      // map dynamic parameters arguments to previous matches\n      if( par_is_dyn[j_par] )\n      {  addr_t j_dyn = par_ind2dyn_ind[j_par];\n         if( dyn_previous[j_dyn] != num_dynamic_par )\n         {  CPPAD_ASSERT_UNKNOWN( dyn_previous[j_dyn] < j_dyn );\n            // previous dynamic parameter\n            j_dyn = dyn_previous[j_dyn];\n            // corresponding parameter\n            j_par = dyn2par_index[j_dyn];\n         }\n      }\n      arg_match[j] = j_par;\n   }\n   return;\n}\n\n/*!\nGet mapping from each dynamic parameter to a previous dynamic parameter\nthat can be used to replace it (if one exists).\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param play\nThis is the old operation sequence.\n\n\\param par_usage\nThe size of this vector is the number of parameters in the\noperation sequence.i.e., play->nun_var_rec().\nIt is the usage counting previous operator optimization of operators.\n\n\\param dyn_previous\nThe input size of this vector must be zero.\nUpon return it has size equal to the number of dynamic parameters in the\noperation sequence; i.e., num_dyn = play->num_dynamic_par().\nLet k = dyn_parvious[j]. If k == num_dyn, no replacement was found for the\nj-th dynamic parameter. If k != num_dyn, the k-th dynamic parameter can be\nused in place of the j-th dynamic parameter, k < j, dyn_previous[k] != num_dyn,\npar_usage[dyn2par_index[k]] == true.\n*/\n\ntemplate <class Base>\nvoid get_dyn_previous(\n   const player<Base>*                         play                ,\n   pod_vector<bool>&                           par_usage           ,\n   pod_vector<addr_t>&                         dyn_previous        )\n{\n   // number of parameters in the recording\n   size_t num_par = play->num_par_all();\n\n   // number of dynamic parameters in the recording\n   size_t num_dynamic_par = play->num_dynamic_par();\n\n   // number of independent dynamic parameters in the recording\n   size_t n_dyn_independent= play->n_dyn_independent();\n\n   // check some assumptions\n   CPPAD_ASSERT_UNKNOWN( dyn_previous.size() == 0 );\n   CPPAD_ASSERT_UNKNOWN( par_usage.size() == num_par );\n   CPPAD_ASSERT_UNKNOWN( num_dynamic_par <= num_par );\n   CPPAD_ASSERT_UNKNOWN( n_dyn_independent <= num_dynamic_par );\n   CPPAD_ASSERT_UNKNOWN( num_arg_dyn( ind_dyn ) == 0 );\n\n   // dynamic parameter information\n   dyn_previous.resize( num_dynamic_par );\n   const pod_vector<addr_t>&   dyn2par_index( play->dyn2par_index() );\n   const pod_vector<bool>&     par_is_dyn( play->par_is_dyn() );\n   const pod_vector<opcode_t>& dyn_par_op( play->dyn_par_op() );\n   const pod_vector<addr_t>&   dyn_par_arg( play->dyn_par_arg() );\n\n   // mapping from parameter index to dynamic parameter index\n   // only defined when par_is_dyn is true\n   pod_vector<addr_t> par_ind2dyn_ind(num_par);\n\n   // mapping from dynamic parameter index to first argument index\n   pod_vector<addr_t> dyn_arg_offset(num_dynamic_par);\n\n   // ----------------------------------------------------------------------\n   // compute dyn_previous\n   // ----------------------------------------------------------------------\n   sparse::list_setvec  hash_table_dyn;\n   hash_table_dyn.resize(CPPAD_HASH_TABLE_SIZE, num_dynamic_par);\n   //\n   // Initialize in dyn_par_arg\n   // (independent dynamic parameters do not have any arguments)\n   size_t i_arg = 0;\n   //\n   // independent dynamic parameters\n   for(size_t i_dyn = 0; i_dyn < n_dyn_independent; ++i_dyn)\n   {  // parameter index\n      size_t i_par = size_t( dyn2par_index[i_dyn] );\n      // dynamic parameter index is one greater because phantom parameter\n      // at index 0 is not dynamic\n      CPPAD_ASSERT_UNKNOWN( i_par == i_dyn + 1 );\n      // mapping from parameter index to dynamic parameter index\n      par_ind2dyn_ind[i_par] = addr_t( i_dyn );\n      // never get optimized out\n      dyn_previous[i_dyn]    = addr_t( num_dynamic_par );\n   }\n   //\n   // other dynamic parameters\n   for(size_t i_dyn = n_dyn_independent; i_dyn < num_dynamic_par; ++i_dyn)\n   {  // Initialize previous for this dynamic parameter. This is only\n      // defined for dynamic parameter indices less than or equal i_dyn\n      dyn_previous[i_dyn] = addr_t( num_dynamic_par );\n      //\n      // mapping from dynamic parameter index to argument offset\n      // is only defined for j_dyn <= i_dyn\n      dyn_arg_offset[i_dyn] = addr_t( i_arg );\n      //\n      // parameter index for this dynamic parameter\n      size_t i_par = size_t( dyn2par_index[i_dyn] );\n      //\n      // mapping from parameter indices to dynamic parameter indices\n      // is only defined when par_is_dyn[i_par] is true and for parameter\n      // indices less than or equal i_par\n      CPPAD_ASSERT_UNKNOWN( par_is_dyn[i_par] );\n      par_ind2dyn_ind[i_par] = addr_t( i_dyn );\n      //\n      // operator for this dynamic parameter\n      op_code_dyn op = op_code_dyn( dyn_par_op[i_dyn] );\n      //\n      // temporary used below and decaled here to reduce memory allocation\n      pod_vector<addr_t> arg_match;\n      //\n      // temporaries used below and decaled here to reduce indentation level\n      bool   match;\n      size_t code;\n      size_t count;\n      //\n      // check for a previous match for i_dyn\n      if( par_usage[i_par] ) switch( op )\n      {\n         // ---------------------------------------------------------------\n         // unary operators\n         case abs_dyn:\n         case acos_dyn:\n         case acosh_dyn:\n         case asin_dyn:\n         case asinh_dyn:\n         case atan_dyn:\n         case atanh_dyn:\n         case cos_dyn:\n         case cosh_dyn:\n         case erf_dyn:\n         case erfc_dyn:\n         case exp_dyn:\n         case expm1_dyn:\n         case fabs_dyn:\n         case log_dyn:\n         case log1p_dyn:\n         case neg_dyn:\n         case sign_dyn:\n         case sin_dyn:\n         case sinh_dyn:\n         case sqrt_dyn:\n         case tan_dyn:\n         case tanh_dyn:\n         CPPAD_ASSERT_UNKNOWN( num_arg_dyn(op) == 1);\n         CPPAD_ASSERT_UNKNOWN( par_is_dyn[i_par] );\n         {  size_t num_arg = 1;\n            arg_match.resize(num_arg);\n            dyn_arg_match(\n               i_dyn,\n               dyn2par_index,\n               par_is_dyn,\n               dyn_arg_offset,\n               dyn_par_arg,\n               par_ind2dyn_ind,\n               dyn_previous,\n               arg_match\n            );\n            opcode_t op_t  = opcode_t(op);\n            code           = optimize_hash_code(\n               op_t, num_arg, arg_match.data()\n            );\n            //\n            // iterator for the set with this hash code\n            sparse::list_setvec_const_iterator itr(hash_table_dyn, code);\n            //\n            // check for a match\n            count = 0;\n            match = false;\n            while( ! match && *itr != num_dynamic_par )\n            {  ++count;\n               //\n               // candidate for current dynamic parameter\n               size_t  k_dyn  = *itr;\n               CPPAD_ASSERT_UNKNOWN( k_dyn < i_dyn );\n               //\n               // argument offset for the candidate\n               addr_t k_arg   = dyn_arg_offset[k_dyn];\n               //\n               match  = op_t == dyn_par_op[k_dyn];\n               match &= arg_match[0] == dyn_par_arg[k_arg + 0];\n               if( ! match )\n                  ++itr;\n            }\n            if( match )\n            {  size_t  k_dyn  = *itr;\n               CPPAD_ASSERT_UNKNOWN( k_dyn < i_dyn );\n               dyn_previous[i_dyn] = addr_t( k_dyn );\n            }\n            else\n            {  CPPAD_ASSERT_UNKNOWN( count < 11 );\n               if( count == 10 )\n               {  // restart list for this hash code\n                  hash_table_dyn.clear(code);\n               }\n               // Add this entry to hash table.\n               // Not using post_element because we need to iterate for\n               // this code before adding another element for this code.\n               hash_table_dyn.add_element(code, i_dyn);\n            }\n         }\n         break;\n\n         // ---------------------------------------------------------------\n         // binary operators\n         case add_dyn:\n         case div_dyn:\n         case mul_dyn:\n         case pow_dyn:\n         case sub_dyn:\n         case zmul_dyn:\n         CPPAD_ASSERT_UNKNOWN( num_arg_dyn(op) == 2);\n         CPPAD_ASSERT_UNKNOWN( par_is_dyn[i_par] );\n         match = false;\n         {  size_t num_arg = 2;\n            arg_match.resize(num_arg);\n            dyn_arg_match(\n               i_dyn,\n               dyn2par_index,\n               par_is_dyn,\n               dyn_arg_offset,\n               dyn_par_arg   ,\n               par_ind2dyn_ind,\n               dyn_previous,\n               arg_match\n            );\n            opcode_t op_t  = opcode_t(op);\n            code           = optimize_hash_code(\n               op_t, num_arg, arg_match.data()\n            );\n            //\n            // iterator for the set with this hash code\n            sparse::list_setvec_const_iterator itr(hash_table_dyn, code);\n            //\n            // check for a match\n            count = 0;\n            while( ! match && *itr != num_dynamic_par )\n            {  ++count;\n               //\n               // candidate for current dynamic parameter\n               size_t  k_dyn  = *itr;\n               CPPAD_ASSERT_UNKNOWN( k_dyn < i_dyn );\n               //\n               // argument offset for the candidate\n               addr_t k_arg   = dyn_arg_offset[k_dyn];\n               //\n               match  = op_t == dyn_par_op[k_dyn];\n               match &= arg_match[0] == dyn_par_arg[k_arg + 0];\n               match &= arg_match[1] == dyn_par_arg[k_arg + 1];\n               if( ! match )\n                  ++itr;\n            }\n            if( match )\n            {  size_t  k_dyn  = *itr;\n               CPPAD_ASSERT_UNKNOWN( k_dyn < i_dyn );\n               dyn_previous[i_dyn] = addr_t( k_dyn );\n            }\n         }\n         if( (! match) && ( (op == add_dyn) || (op == mul_dyn) ) )\n         {  size_t num_arg = 2;\n            std::swap( arg_match[0], arg_match[1] );\n            opcode_t op_t    = opcode_t(op);\n            size_t code_swp  = optimize_hash_code(\n               op_t, num_arg, arg_match.data()\n            );\n            //\n            // iterator for the set with this hash code\n            sparse::list_setvec_const_iterator itr(hash_table_dyn, code_swp);\n            //\n            // check for a match\n            while( ! match && *itr != num_dynamic_par )\n            {  //\n               // candidate for current dynamic parameter\n               size_t  k_dyn  = *itr;\n               CPPAD_ASSERT_UNKNOWN( k_dyn < i_dyn );\n               //\n               // argument offset for the candidate\n               addr_t k_arg   = dyn_arg_offset[k_dyn];\n               //\n               match  = op_t == dyn_par_op[k_dyn];\n               match &= arg_match[0] == dyn_par_arg[k_arg + 0];\n               match &= arg_match[1] == dyn_par_arg[k_arg + 1];\n               if( ! match )\n                  ++itr;\n            }\n            if( match )\n            {  size_t  k_dyn  = *itr;\n               CPPAD_ASSERT_UNKNOWN( k_dyn < i_dyn );\n               dyn_previous[i_dyn] = addr_t( k_dyn );\n            }\n         }\n         if( ! match )\n         {  CPPAD_ASSERT_UNKNOWN( count < 11 );\n            if( count == 10 )\n            {  // restart list for this hash code\n               hash_table_dyn.clear(code);\n            }\n            // Add the entry to hash table\n            // Not using post_element because we need to iterate for\n            // this code before adding another element for this code.\n            hash_table_dyn.add_element(code, i_dyn);\n         }\n\n         // --------------------------------------------------------------\n         // skipping these cases for now\n         case dis_dyn:\n         case cond_exp_dyn:\n         case atom_dyn:\n         case result_dyn:\n         break;\n\n\n         // --------------------------------------------------------------\n         // should be no other cases; e.g., no ind_dyn or number_dyn.\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n      }\n      i_arg += num_arg_dyn(op);\n      if( op == atom_dyn )\n      {  CPPAD_ASSERT_UNKNOWN( num_arg_dyn(op) == 0 );\n         size_t n     = size_t( dyn_par_arg[i_arg + 2] );\n         size_t m     = size_t( dyn_par_arg[i_arg + 3] );\n         size_t n_arg = 6 + n + m;\n         i_arg += n_arg;\n      }\n   }\n}\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/get_op_previous.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_GET_OP_PREVIOUS_HPP\n# define CPPAD_LOCAL_OPTIMIZE_GET_OP_PREVIOUS_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/optimize/match_op.hpp>\n# include <cppad/local/optimize/usage.hpp>\n\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize {\n/*\n{xrst_begin optimize_get_op_previous dev}\n{xrst_spell\n   cexp\n}\n\nGet Mapping From Op to Previous Op That is Equivalent\n#####################################################\n\nSyntax\n******\n| *exceed_collision_limit* = ``get_op_previous`` (\n| |tab| *collision_limit* ,\n| |tab| *play* ,\n| |tab| *random_itr* ,\n| |tab| *cexp_set* ,\n| |tab| *op_previous* ,\n| |tab| *op_usage*\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nBase\n****\nbase type for the operator; i.e., this operation was recorded\nusing AD<Base> and computations by this routine are done using type Base.\n\ncollision_limit\n***************\nis the maximum number of collisions (matches)\nallowed in the hash expression has table.\n\nplay\n****\nis the old operation sequence.\n\nrandom_itr\n**********\nis a random iterator for the old operation sequence.\n\ncexp_set\n********\nset[i] is a set of elements for the i-th operator.\nSuppose that e is an element of set[i], j = e / 2, k = e % 2.\nIf the comparison for the j-th conditional expression is equal to bool(k),\nthe i-th operator can be skipped (is not used by any of the results).\nNote the j indexes the CExpOp operators in the operation sequence.\nOn input, cexp_set is does not count previous optimization.\nOn output, it does count previous optimization.\n\nop_previous\n***********\nThe input size of this vector must be zero.\nUpon return it has size equal to the number of operators\nin the operation sequence; i.e., num_op = play->nun_var_rec().\nLet j = op_previous[i]. If j = 0, no replacement was found for i-th operator.\nIf j != 0:\n\n#. j < i\n#. op_previous[j] == 0\n#. op_usage[j] == usage_t(yes_usage)\n#. i-th operator has NumArg(op) <= 3\n#. i-th operator has 0 < NumRes(op)\n#. i-th operator is not one of the following:\n   {xrst_spell_off}\n   PriOp, ParOp, InvOp, EndOp, CexpOp, BeginOp.\n   {xrst_spell_on}\n#. i-th operator is not one of the load store operator:\n   {xrst_spell_off}\n   LtpvOp, LtvpOp, LtvvOp, StppOp, StpvOp, StvpOp, StvvOp.\n   {xrst_spell_on}\n#. i-th operator is not a atomic function operator:\n   {xrst_spell_off}\n   AFunOp, FunapOp, FunavOp, FunrpOp, FunrvOp.\n   {xrst_spell_on}\n\nop_usage\n********\nThe size of this vector is the number of operators in the\nold operation sequence.i.e., play->nun_var_rec().\nOn input, op_usage[i] is the usage for\nthe i-th operator in the operation sequence not counting previous\noptimization.\nOn output, it is the usage counting previous operator optimization.\n\nexceed_collision_limit\n**********************\nIf the *collision_limit* is exceeded (is not exceeded),\nthe return value is true (false).\n\n{xrst_end optimize_get_op_previous}\n*/\n\n// BEGIN_PROTOTYPE\ntemplate <class Addr, class Base>\nbool get_op_previous(\n   size_t                                      collision_limit     ,\n   const player<Base>*                         play                ,\n   const play::const_random_iterator<Addr>&    random_itr          ,\n   sparse::list_setvec&                        cexp_set            ,\n   pod_vector<addr_t>&                         op_previous         ,\n   pod_vector<usage_t>&                        op_usage            )\n// END_PROTOTYPE\n{  bool exceed_collision_limit = false;\n   //\n   // number of operators in the tape\n   const size_t num_op = random_itr.num_op();\n   CPPAD_ASSERT_UNKNOWN( op_previous.size() == 0 );\n   CPPAD_ASSERT_UNKNOWN( op_usage.size() == num_op );\n   op_previous.resize( num_op );\n   //\n   // number of conditional expressions in the tape\n   //\n   // initialize mapping from variable index to operator index\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( (std::numeric_limits<addr_t>::max)() ) >= num_op\n   );\n   // ----------------------------------------------------------------------\n   // compute op_previous\n   // ----------------------------------------------------------------------\n   sparse::list_setvec  hash_table_op;\n   hash_table_op.resize(CPPAD_HASH_TABLE_SIZE, num_op);\n   //\n   pod_vector<bool> work_bool;\n   pod_vector<addr_t> work_addr_t;\n   for(size_t i_op = 0; i_op < num_op; ++i_op)\n   {  op_previous[i_op] = 0;\n\n      if( op_usage[i_op] == usage_t(yes_usage) )\n      switch( random_itr.get_op(i_op) )\n      {\n         // ----------------------------------------------------------------\n         // these operators never match previous operators\n         case BeginOp:\n         case CExpOp:\n         case CSkipOp:\n         case CSumOp:\n         case EndOp:\n         case InvOp:\n         case LdpOp:\n         case LdvOp:\n         case ParOp:\n         case PriOp:\n         case StppOp:\n         case StpvOp:\n         case StvpOp:\n         case StvvOp:\n         case AFunOp:\n         case FunapOp:\n         case FunavOp:\n         case FunrpOp:\n         case FunrvOp:\n         break;\n\n         // ----------------------------------------------------------------\n         // check for a previous match\n         // BEGIN_SORT_THIS_LINE_PLUS_1\n         case AbsOp:\n         case AcosOp:\n         case AcoshOp:\n         case AddpvOp:\n         case AddvvOp:\n         case AsinOp:\n         case AsinhOp:\n         case AtanOp:\n         case AtanhOp:\n         case CosOp:\n         case CoshOp:\n         case DisOp:\n         case DivpvOp:\n         case DivvpOp:\n         case DivvvOp:\n         case EqppOp:\n         case EqpvOp:\n         case EqvvOp:\n         case ErfOp:\n         case ErfcOp:\n         case ExpOp:\n         case Expm1Op:\n         case LeppOp:\n         case LepvOp:\n         case LevpOp:\n         case LevvOp:\n         case Log1pOp:\n         case LogOp:\n         case LtppOp:\n         case LtpvOp:\n         case LtvpOp:\n         case LtvvOp:\n         case MulpvOp:\n         case MulvvOp:\n         case NegOp:\n         case NeppOp:\n         case NepvOp:\n         case NevvOp:\n         case PowpvOp:\n         case PowvpOp:\n         case PowvvOp:\n         case SignOp:\n         case SinOp:\n         case SinhOp:\n         case SqrtOp:\n         case SubpvOp:\n         case SubvpOp:\n         case SubvvOp:\n         case TanOp:\n         case TanhOp:\n         case ZmulpvOp:\n         case ZmulvpOp:\n         case ZmulvvOp:\n         // END_SORT_THIS_LINE_MINUS_1\n         exceed_collision_limit |= match_op(\n            collision_limit,\n            random_itr,\n            op_previous,\n            i_op,\n            hash_table_op,\n            work_bool,\n            work_addr_t\n         );\n         if( op_previous[i_op] != 0 )\n         {  // like a unary operator that assigns i_op equal to previous.\n            size_t previous = size_t( op_previous[i_op] );\n            bool sum_op = false;\n            CPPAD_ASSERT_UNKNOWN( previous < i_op );\n            op_inc_arg_usage(\n               play, sum_op, i_op, previous, op_usage, cexp_set\n            );\n         }\n         break;\n\n         // ----------------------------------------------------------------\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n      }\n   }\n   /* ---------------------------------------------------------------------\n   // Print out hash code usage summary\n   CppAD::vector<size_t> count(collision_limit + 1);\n   for(size_t i = 0; i <= collision_limit; ++i)\n      count[i] = 0;\n   for(size_t code = 0; code < CPPAD_HASH_TABLE_SIZE; ++code)\n   {  size_t size = hash_table_op.number_elements(code);\n      ++count[size];\n   }\n   std::cout << \"count = \" << count << \"\\n\";\n   --------------------------------------------------------------------- */\n   return exceed_collision_limit;\n}\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/get_op_usage.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_GET_OP_USAGE_HPP\n# define CPPAD_LOCAL_OPTIMIZE_GET_OP_USAGE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/optimize/cexp_info.hpp>\n# include <cppad/local/optimize/usage.hpp>\n# include <cppad/local/sweep/call_atomic.hpp>\n\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize {\n\n/// Is this an addition or subtraction operator\ninline bool op_add_or_sub(\n   op_code_var op ///< operator we are checking\n)\n{  bool result;\n   switch(op)\n   {\n      case AddpvOp:\n      case AddvvOp:\n      case SubpvOp:\n      case SubvpOp:\n      case SubvvOp:\n      result = true;\n      break;\n\n      default:\n      result = false;\n      break;\n   }\n   return result;\n}\n\n/*!\n{xrst_begin optimize_op_inc_arg_usage dev}\n{xrst_spell\n   cexp\n   csum\n}\n\nIncrease Argument Usage and Propagate cexp_set From Result to Argument\n######################################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_OP_INC_ARG_USAGE\n   // END_OP_INC_ARG_USAGE\n}\n\nplay\n****\nis the player for the old operation sequence.\n\ncheck_csum\n**********\nis result an addition or subtraction operator,\nand the optimizer is allowed to generate cumulative sum operators.\n\ni_result\n********\nis the operator index for the result operator.\nThere are no posting waiting to be processed for the corresponding cexp_set.\n\ni_arg\n*****\nis the operator index for the argument to the result operator.\nThere may be postings waiting to be processed for the corresponding cexp_set.\n\nop_usage\n********\nstructure that holds the information for each of the operators.\nThe output value of op_usage[i_arg] is increased; to be specific,\nIf check_csum is true and the input value of op_usage[i_arg]\nis usage_t(no_usage), its output value is usage_t(csum_usage).\nOtherwise, the output value of op_usage[i_arg] is usage_t(yes_usage).\n\ncexp_set\n********\nThis is a vector of sets with one set for each operator.\nWe denote the i-th set by set[i].\nThese are the conditional expression conditions that must be\nsatisfied for this argument to be used.\n\n#. In the special case where cexp_set.n_set() is zero,\n   cexp_set is not changed.\n#. If cexp_set.n_set() != 0 and op_usage[i_arg] == usage_t(no_usage),\n   the input value of set[i_arg] must be empty.\n   In this case the output value if set[i_arg] is equal to set[i_result]\n   (which may also be empty).\n#. If cexp_set.n_set() != 0 and op_usage[i_arg] != usage_t(no_usage),\n   the output value of set[i_arg] is the intersection of\n   its input value and set[i_result].\n\n{xrst_end optimize_op_inc_arg_usage}\n*/\n// BEGIN_OP_INC_ARG_USAGE\ntemplate <class Base>\nvoid op_inc_arg_usage(\n   const player<Base>*         play           ,\n   bool                        check_csum     ,\n   size_t                      i_result       ,\n   size_t                      i_arg          ,\n   pod_vector<usage_t>&        op_usage       ,\n   sparse::list_setvec&        cexp_set       )\n// END_OP_INC_ARG_USAGE\n{  // value of argument input on input to this routine\n   enum_usage arg_usage = enum_usage( op_usage[i_arg] );\n   //\n   // new value for usage\n   op_usage[i_arg] = usage_t(yes_usage);\n   if( check_csum )\n   {  if( arg_usage == no_usage )\n      {  op_code_var op_a = play->GetOp(i_arg);\n         if( op_add_or_sub( op_a ) )\n         {  op_usage[i_arg] = usage_t(csum_usage);\n         }\n      }\n   }\n   //\n   // cexp_set\n   if( cexp_set.n_set() == 0 )\n      return;\n   //\n   if( arg_usage == no_usage )\n   {  // set[i_arg] = set[i_result]\n      // not necessary to process posts for set i_result\n      cexp_set.assignment(i_arg, i_result, cexp_set);\n   }\n   else\n   {  // set[i_arg] = set[i_arg] intersect set[i_result]\n      // is necessary to process postts for set i_arg\n      cexp_set.process_post(i_arg);\n      cexp_set.binary_intersection(i_arg, i_arg, i_result, cexp_set);\n   }\n   //\n   return;\n}\n\n/*!\n{xrst_begin optimize_get_op_usage dev}\n{xrst_spell\n   cexp\n   dep\n   pri\n   taddr\n}\n\nUse Reverse Activity Analysis to Get Usage Information for Each Operator\n########################################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_GET_OP_USAGE\n   // END_GET_OP_USAGE\n}\n\nBase\n****\nBase type for the operator; i.e., this operation was recorded\nusing ``AD`` < *Base* > and computations by this routine are done\nusing type *Base* .\n\nAddr\n****\nType used by random iterator for the player.\n\ncumulative_sum_op\n*****************\nIf this is true (false), cumulative summation operator are allowed\n(not allowed) to be generated by the optimization.\n\ncompare_op\n**********\nif this is true, arguments are considered used if they appear in compare\noperators. This is a side effect because compare operators have boolean\nresults (and the result is not in the tape; i.e. NumRes(op) is zero\nfor these operators. (This is an example of a side effect.)\n\nprint_for_op\n************\nif this is true, arguments are considered used if they appear in\nprint forward operators; i.e., PriOp.\nThis is also a side effect; i.e. NumRes(PriOp) is zero.\n\nconditional_skip\n****************\nIf this is true,\nthe conditional expression information cexp_info will be calculated.\nThis may be time intensive and may not have much benefit in the optimized\nrecording.\n\nplay\n****\nThis is the operation sequence.\n\nrandom_itr\n**********\nThis is a random iterator for the operation sequence.\n\ndep_taddr\n*********\nis a vector of indices for the dependent variables\n(where the reverse activity analysis starts).\n\ncexp2op\n*******\nThe input size of this vector must be zero.\nUpon return it has size equal to the number of conditional expressions,\nCExpOp operators. The value *cexp2op* [ ``j`` ] is the operator\nindex corresponding to the *j*-th conditional expressions.\n\ncexp_set\n********\nThis is a vector of sets that is empty on input.\nIf *conditional_skip* is false, *cexp_usage* is not modified.\nOtherwise, set[i] is a set of elements for the i-th operator.\nSuppose that e is an element of set[i], j = e / 2, k = e % 2.\nIf the comparison for the j-th conditional expression is equal to bool(k),\nthe i-th operator can be skipped (is not used by any of the results).\nNote that j indexes the CExpOp operators in the operation sequence.\n\nvecad_used\n**********\nThe input size of this vector must be zero.\nUpon return it has size equal to the number of VecAD vectors\nin the operations sequences; i.e., play->num_var_vecad().\nThe VecAD vectors are indexed in the order that their indices appear\nin the one large play->GetVecInd that holds all the VecAD vectors.\n\nop_usage\n********\nThe input size of this vector must be zero.\nUpon return it has size equal to the number of operators\nin the operation sequence; i.e., num_op = play->nun_var_rec().\nThe value *op_usage* [ *i* ] has been set to the usage for\nthe i-th operator in the operation sequence.\nAtomic function calls are a special case,\nthe first and second AFunOp have usage corresponding to the entire call.\nThe arguments have the usage for particular parameter or variable.\nThis usage is only for creating variables, not for creating\ndynamic parameters.\n\n{xrst_end optimize_get_op_usage}\n*/\n// BEGIN_GET_OP_USAGE\ntemplate <class Addr, class Base>\nvoid get_op_usage(\n   bool                                        conditional_skip    ,\n   bool                                        compare_op          ,\n   bool                                        print_for_op        ,\n   bool                                        cumulative_sum_op   ,\n   const player<Base>*                         play                ,\n   const play::const_random_iterator<Addr>&    random_itr          ,\n   const pod_vector<size_t>&                   dep_taddr           ,\n   pod_vector<addr_t>&                         cexp2op             ,\n   sparse::list_setvec&                        cexp_set            ,\n   pod_vector<bool>&                           vecad_used          ,\n   pod_vector<usage_t>&                        op_usage            )\n// END_GET_OP_USAGE\n{\n   CPPAD_ASSERT_UNKNOWN( cexp_set.n_set()  == 0 );\n   CPPAD_ASSERT_UNKNOWN( vecad_used.size() == 0 );\n   CPPAD_ASSERT_UNKNOWN( op_usage.size()   == 0 );\n\n   // number of operators in the tape\n   const size_t num_op = play->num_var_op();\n   //\n   // initialize mapping from variable index to operator index\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( (std::numeric_limits<addr_t>::max)() ) >= num_op\n   );\n   // -----------------------------------------------------------------------\n   // information about current operator\n   op_code_var   op;     // operator\n   const addr_t* arg;    // arguments\n   size_t        i_op;   // operator index\n   size_t        i_var;  // variable index of first result\n   // -----------------------------------------------------------------------\n   // information about atomic function calls\n   size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0;\n   enum_atom_state atom_state;\n   //\n   // work space used by user atomic functions\n   vector<Base>         atom_x;    // value of parameters in x\n   vector<ad_type_enum> type_x;    // type for each argument\n   vector<size_t>       atom_ix;   // variables indices for argument vector\n   vector<bool>         depend_y;  // results that are used\n   vector<bool>         depend_x;  // arguments that are used\n   //\n   // parameter information (used by atomic function calls)\n# ifndef NDEBUG\n   size_t num_par = play->num_par_all();\n# endif\n   CPPAD_ASSERT_UNKNOWN( num_par > 0 )\n   const Base* parameter = play->par_ptr();\n   // -----------------------------------------------------------------------\n   // vecad information\n   size_t num_vecad      = play->num_var_vecad();\n   size_t num_vecad_ind  = play->num_var_vec_ind();\n   //\n   vecad_used.resize(num_vecad);\n   for(size_t i = 0; i < num_vecad; i++)\n      vecad_used[i] = false;\n   //\n   vector<size_t> arg2vecad(num_vecad_ind);\n   for(size_t i = 0; i < num_vecad_ind; i++)\n      arg2vecad[i] = num_vecad; // invalid value\n   size_t arg_0 = 1; // value of arg[0] for theh first vecad\n   for(size_t i = 0; i < num_vecad; i++)\n   {\n      // mapping from arg[0] value to index for this vecad object.\n      arg2vecad[arg_0] = i;\n      //\n      // length of this vecad object\n      size_t length = play->GetVecInd(arg_0 - 1);\n      //\n      // set to proper index in GetVecInd for next VecAD arg[0] value\n      arg_0        += length + 1;\n   }\n   CPPAD_ASSERT_UNKNOWN( arg_0 == num_vecad_ind + 1 );\n   // -----------------------------------------------------------------------\n   // conditional expression information\n   //\n   size_t num_cexp_op = 0;\n   if( conditional_skip )\n   {  for(i_op = 0; i_op < num_op; ++i_op)\n      {  if( random_itr.get_op(i_op) == CExpOp )\n         {  // count the number of conditional expressions.\n            ++num_cexp_op;\n         }\n      }\n   }\n   //\n   cexp2op.resize( num_cexp_op );\n   //\n   // number of sets\n   size_t num_set = 0;\n   if( conditional_skip && num_cexp_op > 0)\n      num_set = num_op;\n   //\n   // conditional expression index   = element / 2\n   // conditional expression compare = bool ( element % 2)\n   size_t end_set = 2 * num_cexp_op;\n   //\n   if( num_set > 0 )\n      cexp_set.resize(num_set, end_set);\n   // -----------------------------------------------------------------------\n   // initialize operator usage for reverse dependency analysis.\n   op_usage.resize( num_op );\n   for(i_op = 0; i_op < num_op; ++i_op)\n      op_usage[i_op] = usage_t(no_usage);\n   for(size_t i = 0; i < dep_taddr.size(); i++)\n   {  i_op           = random_itr.var2op(dep_taddr[i]);\n      op_usage[i_op] = usage_t(yes_usage);    // dependent variables\n   }\n   // ----------------------------------------------------------------------\n   // Reverse pass to compute usage and cexp_set for each operator\n   // ----------------------------------------------------------------------\n   //\n   // Initialize reverse pass\n   size_t last_atom_i_op = 0;\n   size_t cexp_index     = num_cexp_op;\n   atom_state            = end_atom;\n   i_op = num_op;\n   while(i_op != 0 )\n   {  --i_op;\n      if( num_set > 0 )\n      {  // no more elements will be added to this set\n         cexp_set.process_post(i_op);\n      }\n      //\n      // this operator information\n      random_itr.op_info(i_op, op, arg, i_var);\n      //\n      // Is the result of this operation used.\n      // (This only makes sense when NumRes(op) > 0.)\n      usage_t use_result = op_usage[i_op];\n      //\n      bool check_csum = false;\n      switch( op )\n      {\n         // =============================================================\n         // normal operators\n         // =============================================================\n\n         // Only one variable with index arg[0]\n         case SubvpOp:\n         check_csum = cumulative_sum_op;\n         //\n         case AbsOp:\n         case AcosOp:\n         case AcoshOp:\n         case AsinOp:\n         case AsinhOp:\n         case AtanOp:\n         case AtanhOp:\n         case CosOp:\n         case CoshOp:\n         case DivvpOp:\n         case ErfOp:\n         case ErfcOp:\n         case ExpOp:\n         case Expm1Op:\n         case LogOp:\n         case Log1pOp:\n         case NegOp:\n         case PowvpOp:\n         case SignOp:\n         case SinOp:\n         case SinhOp:\n         case SqrtOp:\n         case TanOp:\n         case TanhOp:\n         case ZmulvpOp:\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 );\n         if( use_result != usage_t(no_usage) )\n         {  size_t j_op = random_itr.var2op(size_t(arg[0]));\n            op_inc_arg_usage(\n               play, check_csum, i_op, j_op, op_usage, cexp_set\n            );\n         }\n         break; // --------------------------------------------\n\n         // Only one variable with index arg[1]\n         case AddpvOp:\n         case SubpvOp:\n         check_csum = cumulative_sum_op;\n         //\n         case DisOp:\n         case DivpvOp:\n         case MulpvOp:\n         case PowpvOp:\n         case ZmulpvOp:\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 );\n         if( use_result != usage_t(no_usage) )\n         {  size_t j_op = random_itr.var2op(size_t(arg[1]));\n            op_inc_arg_usage(\n               play, check_csum, i_op, j_op, op_usage, cexp_set\n            );\n         }\n         break; // --------------------------------------------\n\n         // arg[0] and arg[1] are the only variables\n         case AddvvOp:\n         case SubvvOp:\n         check_csum = cumulative_sum_op;\n         //\n         case DivvvOp:\n         case MulvvOp:\n         case PowvvOp:\n         case ZmulvvOp:\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 );\n         if( use_result != usage_t(no_usage) )\n         {  for(size_t i = 0; i < 2; i++)\n            {  size_t j_op = random_itr.var2op(size_t(arg[i]));\n               op_inc_arg_usage(\n                  play, check_csum, i_op, j_op, op_usage, cexp_set\n               );\n            }\n         }\n         break; // --------------------------------------------\n\n         // Conditional expression operators\n         // arg[2], arg[3], arg[4], arg[5] are parameters or variables\n         case CExpOp:\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 );\n         if( conditional_skip )\n         {  --cexp_index;\n            cexp2op[ cexp_index ] = addr_t(i_op);\n         }\n         if( use_result != usage_t(no_usage) )\n         {  CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n            // propagate from result to left argument\n            if( arg[1] & 1 )\n            {  size_t j_op = random_itr.var2op(size_t(arg[2]));\n               op_inc_arg_usage(\n                  play, check_csum, i_op, j_op, op_usage, cexp_set\n               );\n            }\n            // propagate from result to right argument\n            if( arg[1] & 2 )\n            {  size_t j_op = random_itr.var2op(size_t(arg[3]));\n               op_inc_arg_usage(\n                     play, check_csum, i_op, j_op, op_usage, cexp_set\n               );\n            }\n            // are if_true and if_false cases the same variable\n            bool same_variable = (arg[1] & 4) != 0;\n            same_variable     &= (arg[1] & 8) != 0;\n            same_variable     &= arg[4] == arg[5];\n            //\n            // if_true\n            if( arg[1] & 4 )\n            {  size_t j_op = random_itr.var2op(size_t(arg[4]));\n               bool can_skip = conditional_skip & (! same_variable);\n               can_skip     &= op_usage[j_op] == usage_t(no_usage);\n               op_inc_arg_usage(\n                  play, check_csum, i_op, j_op, op_usage, cexp_set\n               );\n               if( can_skip )\n               {  // j_op corresponds to the value used when the\n                  // comparison result is true. It can be skipped when\n                  // the comparison is false (0).\n                  size_t element = 2 * cexp_index + 0;\n                  cexp_set.post_element(j_op, element);\n                  //\n                  op_usage[j_op] = usage_t(yes_usage);\n               }\n            }\n            //\n            // if_false\n            if( arg[1] & 8 )\n            {  size_t j_op = random_itr.var2op(size_t(arg[5]));\n               bool can_skip = conditional_skip & (! same_variable);\n               can_skip     &= op_usage[j_op] == usage_t(no_usage);\n               op_inc_arg_usage(\n                  play, check_csum, i_op, j_op, op_usage, cexp_set\n               );\n               if( can_skip )\n               {  // j_op corresponds to the value used when the\n                  // comparison result is false. It can be skipped when\n                  // the comparison is true (0).\n                  size_t element = 2 * cexp_index + 1;\n                  cexp_set.post_element(j_op, element);\n                  //\n                  op_usage[j_op] = usage_t(yes_usage);\n               }\n            }\n         }\n         break;  // --------------------------------------------\n\n         // Operations that are never used\n         // (new CSkip options are generated if conditional_skip is true)\n         case CSkipOp:\n         case ParOp:\n         break;\n\n         // Operators that are always used\n         case InvOp:\n         case BeginOp:\n         case EndOp:\n         op_usage[i_op] = usage_t(yes_usage);\n         break;  // -----------------------------------------------\n\n         // The print forward operator\n         case PriOp:\n         CPPAD_ASSERT_NARG_NRES(op, 5, 0);\n         if( print_for_op )\n         {  op_usage[i_op] = usage_t(yes_usage);\n            if( arg[0] & 1 )\n            {  // arg[1] is a variable\n               size_t j_op = random_itr.var2op(size_t(arg[1]));\n               op_inc_arg_usage(\n                  play, check_csum, i_op, j_op, op_usage, cexp_set\n               );\n            }\n            if( arg[0] & 2 )\n            {  // arg[3] is a variable\n               size_t j_op = random_itr.var2op(size_t(arg[3]));\n               op_inc_arg_usage(\n                  play, check_csum, i_op, j_op, op_usage, cexp_set\n               );\n            }\n         }\n         break; // -----------------------------------------------------\n\n         // =============================================================\n         // Comparison operators\n         // =============================================================\n\n         // Compare operator were none of the operatros are variables\n         case EqppOp:\n         case LeppOp:\n         case LtppOp:\n         case NeppOp:\n         if( compare_op )\n            op_usage[i_op] = usage_t(yes_usage);\n         break; // ----------------------------------------------\n\n         // Compare operators where arg[1] is only variable\n         case LepvOp:\n         case LtpvOp:\n         case EqpvOp:\n         case NepvOp:\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 );\n         if( compare_op )\n         {  op_usage[i_op] = usage_t(yes_usage);\n            //\n            size_t j_op = random_itr.var2op(size_t(arg[1]));\n            op_inc_arg_usage(\n               play, check_csum, i_op, j_op, op_usage, cexp_set\n            );\n         }\n         break; // ----------------------------------------------\n\n         // Compare operators where arg[0] is only variable\n         case LevpOp:\n         case LtvpOp:\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 );\n         if( compare_op )\n         {  op_usage[i_op] = usage_t(yes_usage);\n            //\n            size_t j_op = random_itr.var2op(size_t(arg[0]));\n            op_inc_arg_usage(\n               play, check_csum, i_op, j_op, op_usage, cexp_set\n            );\n         }\n         break; // ----------------------------------------------\n\n         // Compare operators where arg[0] and arg[1] are variables\n         case LevvOp:\n         case LtvvOp:\n         case EqvvOp:\n         case NevvOp:\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 );\n         if( compare_op )\n         {  op_usage[i_op] = usage_t(yes_usage);\n            //\n            for(size_t i = 0; i < 2; i++)\n            {  size_t j_op = random_itr.var2op(size_t(arg[i]));\n               op_inc_arg_usage(\n                  play, check_csum, i_op, j_op, op_usage, cexp_set\n               );\n            }\n         }\n         break; // ----------------------------------------------\n\n         // =============================================================\n         // VecAD operators\n         // =============================================================\n\n         // load operator using a parameter index\n         case LdpOp:\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 );\n         if( use_result != usage_t(no_usage) )\n         {  size_t i_vec = arg2vecad[ arg[0] ];\n            vecad_used[i_vec] = true;\n         }\n         break; // --------------------------------------------\n\n         // load operator using a variable index\n         case LdvOp:\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 );\n         if( use_result != usage_t(no_usage) )\n         {  size_t i_vec = arg2vecad[ arg[0] ];\n            vecad_used[i_vec] = true;\n            //\n            size_t j_op = random_itr.var2op(size_t(arg[1]));\n            op_usage[j_op] = usage_t(yes_usage);\n         }\n         break; // --------------------------------------------\n\n         // Store a variable using a parameter index\n         case StpvOp:\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 );\n         if( vecad_used[ arg2vecad[ arg[0] ] ] )\n         {  op_usage[i_op] = usage_t(yes_usage);\n            //\n            size_t j_op = random_itr.var2op(size_t(arg[2]));\n            op_usage[j_op] = usage_t(yes_usage);\n         }\n         break; // --------------------------------------------\n\n         // Store a variable using a variable index\n         case StvvOp:\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 );\n         if( vecad_used[ arg2vecad[ arg[0] ] ] )\n         {  op_usage[i_op] = usage_t(yes_usage);\n            //\n            size_t j_op = random_itr.var2op(size_t(arg[1]));\n            op_usage[j_op] = usage_t(yes_usage);\n            size_t k_op = random_itr.var2op(size_t(arg[2]));\n            op_usage[k_op] = usage_t(yes_usage);\n         }\n         break; // -----------------------------------------------------\n\n         // =============================================================\n         // cumulative summation operator\n         // ============================================================\n         case CSumOp:\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 );\n         {\n            for(size_t i = 5; i < size_t(arg[2]); i++)\n            {  size_t j_op = random_itr.var2op(size_t(arg[i]));\n               op_inc_arg_usage(\n                  play, check_csum, i_op, j_op, op_usage, cexp_set\n               );\n            }\n         }\n         break;\n\n         // =============================================================\n         // user defined atomic operators\n         // ============================================================\n\n         case AFunOp:\n         // start or end atomic operation sequence\n         if( atom_state == end_atom )\n         {  // reverse_user using random_itr instead of play\n            atom_index        = size_t(arg[0]);\n            atom_old          = size_t(arg[1]);\n            atom_n            = size_t(arg[2]);\n            atom_m            = size_t(arg[3]);\n            atom_j            = atom_n;\n            atom_i            = atom_m;\n            atom_state        = ret_atom;\n            // -------------------------------------------------------\n            last_atom_i_op = i_op;\n            CPPAD_ASSERT_UNKNOWN( i_op > atom_n + atom_m + 1 );\n            CPPAD_ASSERT_UNKNOWN(\n               op_usage[last_atom_i_op] == usage_t(no_usage)\n            );\n# ifndef NDEBUG\n            if( cexp_set.n_set() > 0 )\n            {  cexp_set.process_post(last_atom_i_op);\n               CPPAD_ASSERT_UNKNOWN(\n                  cexp_set.number_elements(last_atom_i_op) == 0\n               );\n            }\n# endif\n            //\n            atom_x.resize(  atom_n );\n            type_x.resize( atom_n );\n            atom_ix.resize( atom_n );\n            //\n            depend_y.resize( atom_m );\n            depend_x.resize( atom_n );\n            for(size_t i = 0; i < atom_m; i++)\n               depend_y[ i ] = false;\n         }\n         else\n         {  // reverse_user using random_itr instead of play\n            CPPAD_ASSERT_UNKNOWN( atom_state == start_atom );\n            CPPAD_ASSERT_UNKNOWN( atom_n == size_t(arg[2]) );\n            CPPAD_ASSERT_UNKNOWN( atom_m == size_t(arg[3]) );\n            CPPAD_ASSERT_UNKNOWN( atom_j == 0 );\n            CPPAD_ASSERT_UNKNOWN( atom_i == 0 );\n            atom_state = end_atom;\n            // -------------------------------------------------------\n            CPPAD_ASSERT_UNKNOWN(\n               i_op + atom_n + atom_m + 1 == last_atom_i_op\n            );\n            if( op_usage[last_atom_i_op] != usage_t(no_usage) )\n            {  // call atomic function for this operation\n               sweep::call_atomic_rev_depend<Base, Base>(\n               atom_index, atom_old, atom_x, type_x, depend_x, depend_y\n               );\n               for(size_t j = 0; j < atom_n; j++)\n               if( depend_x[j] )\n               {  // The parameter or variable corresponding to the j-th\n                  // argument gets used\n                  op_usage[i_op + 1 + j] = true;\n                  if( type_x[j] == variable_enum )\n                  {  CPPAD_ASSERT_UNKNOWN( atom_ix[j] > 0 );\n                     if( depend_x[j] )\n                     {  size_t j_op = random_itr.var2op(atom_ix[j]);\n                        op_inc_arg_usage(play, check_csum,\n                           last_atom_i_op, j_op, op_usage, cexp_set\n                        );\n                     }\n                  }\n               }\n            }\n            // copy set information from last to first\n            if( cexp_set.n_set() > 0 )\n            {  cexp_set.process_post(last_atom_i_op);\n               cexp_set.assignment(i_op, last_atom_i_op, cexp_set);\n            }\n            // copy usage information from last to first\n            op_usage[i_op] = op_usage[last_atom_i_op];\n         }\n         break; // -------------------------------------------------------\n\n         case FunapOp:\n         // parameter argument in an atomic operation sequence\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         //\n         // reverse_user using random_itr instead of play\n         CPPAD_ASSERT_NARG_NRES(op, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( 0 < atom_j && atom_j <= atom_n );\n         --atom_j;\n         if( atom_j == 0 )\n            atom_state = start_atom;\n         // -------------------------------------------------------------\n         atom_ix[atom_j] = 0;\n         //\n         // parameter arguments\n         atom_x[atom_j] = parameter[arg[0]];\n         if( play->par_is_dyn()[arg[0]] )\n            type_x[atom_j] = dynamic_enum;\n         else\n            type_x[atom_j] = constant_enum;\n         //\n         break;\n\n         case FunavOp:\n         // variable argument in an atomic operation sequence\n         CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );\n         //\n         // reverse_user using random_itr instead of play\n         CPPAD_ASSERT_NARG_NRES(op, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( 0 < atom_j && atom_j <= atom_n );\n         --atom_j;\n         if( atom_j == 0 )\n            atom_state = start_atom;\n         // -------------------------------------------------------------\n         atom_ix[atom_j] = size_t(arg[0]);\n         //\n         // variable arguments as parameters\n         atom_x[atom_j] = CppAD::numeric_limits<Base>::quiet_NaN();\n         type_x[atom_j] = variable_enum;\n         //\n         break;\n\n         case FunrvOp:\n         // variable result in an atomic operation sequence\n         //\n         // reverse_user using random_itr instead of play\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         CPPAD_ASSERT_UNKNOWN( 0 < atom_i && atom_i <= atom_m );\n         --atom_i;\n         if( atom_i == 0 )\n            atom_state = arg_atom;\n         // -------------------------------------------------------------\n         if( use_result )\n         {  depend_y[atom_i] = true;\n            op_inc_arg_usage(\n               play, check_csum, i_op, last_atom_i_op, op_usage, cexp_set\n            );\n         }\n         break; // --------------------------------------------------------\n\n         case FunrpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         //\n         // reverse_user using random_itr instead of play\n         CPPAD_ASSERT_NARG_NRES(op, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( 0 < atom_i && atom_i <= atom_m );\n         --atom_i;\n         if( atom_i == 0 )\n            atom_state = arg_atom;\n         break;\n         // ============================================================\n\n         // all cases should be handled above\n         default:\n         CPPAD_ASSERT_UNKNOWN(0);\n      }\n   }\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/get_par_usage.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_GET_PAR_USAGE_HPP\n# define CPPAD_LOCAL_OPTIMIZE_GET_PAR_USAGE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*!\n\\file get_cexp_info.hpp\nCreate operator information tables\n*/\n# include <cppad/local/optimize/get_op_usage.hpp>\n\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize {\n\n/*!\n{xrst_begin optimize_get_par_usage dev}\n\nUse Reverse Activity Analysis to Get Usage for Each Parameter\n#############################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_GET_PAR_USAGE\n   // END_PROTOTYPE\n}\n\nBase\n****\nBase type for the operator; i.e., this operation was recorded\nusing ``AD`` < *Base* >\nand computations by this routine are done using type *Base* .\n\nAddr\n****\nType used by random iterator for the player.\n\nplay\n****\nThis is the operation sequence.\n\nrandom_itr\n**********\nThis is a random iterator for the operation sequence.\n\nop_usage\n********\nThis argument has size equal to the number of operators\nin the operation sequence; i.e., num_op = play->nun_var_rec().\nThe value *op_usage* [ *i* ] have been set to the usage for\nthe i-th operator in the operation sequence.\n\nvecad_used\n**********\nThis argument has size equal to the number of VecAD vectors\nin the operations sequences; i.e., play->num_var_vecad().\nThe VecAD vectors are indexed in the order that their indices appear\nin the one large play->GetVecInd that holds all the VecAD vectors.\n\npar_usage\n*********\nThe input size of this vector must be zero.\nUpon return it has size equal to the number of parameters\nin the operation sequence; i.e., play->num_par_all();\nThe value *par_usage* [ *i* ] is true if an only if\nthe i-th parameter is used to compute a dependent variable\nor parameter.\nThe nan at the beginning of the parameter vector\nand the independent dynamic parameters are always used.\n\n{xrst_end optimize_get_par_usage}\n*/\n\n// BEGIN_GET_PAR_USAGE\ntemplate <class Addr, class Base>\nvoid get_par_usage(\n   const player<Base>*                         play                ,\n   const play::const_random_iterator<Addr>&    random_itr          ,\n   const pod_vector<usage_t>&                  op_usage            ,\n   pod_vector<bool>&                           vecad_used          ,\n   pod_vector<bool>&                           par_usage           )\n// END_PROTOTYPE\n{\n   CPPAD_ASSERT_UNKNOWN( op_usage.size()   == play->num_var_op() );\n   CPPAD_ASSERT_UNKNOWN( par_usage.size()  == 0 );\n   //\n   // number of operators in the tape\n   const size_t num_op = play->num_var_op();\n   //\n   // number of parameters in the tape\n   const size_t num_par = play->num_par_all();\n   //\n   // number of dynamic parameters\n   const size_t num_dynamic_par = play->num_dynamic_par();\n   //\n   // number of independent dynamic parameters\n   size_t n_dyn_independent = play->n_dyn_independent();\n   //\n   // number of VecAD vectors\n   size_t num_vecad_vec = play->num_var_vecad();\n   //\n   // dynamic parameter information\n   const pod_vector<bool>&        par_is_dyn( play->par_is_dyn() );\n   const pod_vector<opcode_t>&    dyn_par_op( play->dyn_par_op() );\n   const pod_vector<addr_t>&      dyn_par_arg( play->dyn_par_arg() );\n   const pod_vector<addr_t>&      dyn2par_index( play->dyn2par_index() );\n   const pod_vector_maybe<Base>&  par_all( play->par_all() );\n   // -----------------------------------------------------------------------\n   // initialize par_usage\n   par_usage.resize(num_par);\n   par_usage[0] = true; // true for nan at beginning of parameter vector\n   for(size_t i_par = 1; i_par <= n_dyn_independent; ++i_par)\n      par_usage[i_par] = true;  // true for independent dynamic parameters\n   for(size_t i_par = n_dyn_independent+1; i_par < num_par; ++i_par)\n      par_usage[i_par] = false; // initialize as false for other parameters\n   //\n   // -----------------------------------------------------------------------\n   // set usage to true for VecAD parameters that get used\n   size_t start_this_vector = 0;\n   for(size_t i_vec = 0; i_vec < num_vecad_vec; ++i_vec)\n   {  // length of this vector (note length is not a parameter)\n      size_t length = play->GetVecInd(start_this_vector);\n      //\n      if( vecad_used[i_vec] )\n      {  // this vector gets used\n         for(size_t k = 1; k <= length; ++k)\n         {  // index of parameter used by this VecAD vector\n            size_t i_par = play->GetVecInd(start_this_vector + k);\n            // must not be a dynamic parameter\n            CPPAD_ASSERT_UNKNOWN( ! par_is_dyn[i_par] );\n            // set usage for this parameter\n            par_usage[i_par] = true;\n         }\n      }\n      start_this_vector += length + 1;\n   }\n   CPPAD_ASSERT_UNKNOWN( start_this_vector == play->num_var_vec_ind() );\n   //\n   // -----------------------------------------------------------------------\n   // forward pass to mark which parameters are used by necessary operators\n   // -----------------------------------------------------------------------\n   //\n   // information about atomic function calls\n   size_t atom_index=0, call_id=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0;\n   enum_atom_state atom_state = start_atom;\n   //\n   // work space used by user atomic functions\n   vector<Base>         parameter_x; // value of parameters in x\n   vector<ad_type_enum> type_x;      // type for each component of z\n   vector<size_t>       atom_ix;     // variables indices for argument vector\n   vector<bool>         depend_y;    // results that are used\n   vector<bool>         depend_x;    // arguments that are used\n   //\n   for(size_t i_op = 0; i_op < num_op; ++i_op)\n   {\n      // information about current operator\n      op_code_var   op;     // operator\n      const addr_t* arg;    // arguments\n      size_t        i_var;  // variable index of first result\n      random_itr.op_info(i_op, op, arg, i_var);\n      //\n      bool skip = op_usage[i_op] == usage_t(no_usage);\n      skip     &= atom_state == start_atom;\n      if( ! skip ) switch( op )\n      {\n         // add or subtract with left a parameter and right a variable\n         case AddpvOp:\n         case SubpvOp:\n         if( par_is_dyn[ arg[0] ] )\n            par_usage[ arg[0] ] = true;\n         else\n         {  // determine if this parameter will be absorbed by csum\n            if( ! (op_usage[i_op] == csum_usage) )\n            {  // determine operator corresponding to variable\n               size_t j_op = random_itr.var2op(size_t(arg[1]));\n               CPPAD_ASSERT_UNKNOWN( op_usage[j_op] != no_usage );\n               if( op_usage[j_op] != csum_usage )\n                  par_usage[ arg[0] ] = true;\n            }\n         }\n         break;\n\n         // subtract with left a variable and right a parameter\n         case SubvpOp:\n         if( par_is_dyn[ arg[1] ] )\n            par_usage[ arg[1] ] = true;\n         else\n         {  // determine if this parameter will be absorbed by csum\n            if( ! (op_usage[i_op] == csum_usage) )\n            {  // determine operator corresponding to variable\n               size_t j_op = random_itr.var2op(size_t(arg[0]));\n               CPPAD_ASSERT_UNKNOWN( op_usage[j_op] != no_usage );\n               if( op_usage[j_op] != csum_usage )\n                  par_usage[ arg[1] ] = true;\n            }\n         }\n         break;\n\n\n\n         // cases with no parameter arguments\n         case AbsOp:\n         case AcosOp:\n         case AcoshOp:\n         case AddvvOp:\n         case AsinOp:\n         case AsinhOp:\n         case AtanOp:\n         case AtanhOp:\n         case BeginOp:\n         case CosOp:\n         case CoshOp:\n         case CSkipOp:\n         case DisOp:\n         case DivvvOp:\n         case EndOp:\n         case EqvvOp:\n         case ExpOp:\n         case Expm1Op:\n         case InvOp:\n         case LdvOp:\n         case LevvOp:\n         case LogOp:\n         case Log1pOp:\n         case LtvvOp:\n         case MulvvOp:\n         case NegOp:\n         case NevvOp:\n         case PowvvOp:\n         case SignOp:\n         case SinOp:\n         case SinhOp:\n         case SqrtOp:\n         case StvvOp:\n         case SubvvOp:\n         case TanOp:\n         case TanhOp:\n         case ZmulvvOp:\n         break;\n\n         // cases where first and second arguments are parameters\n         case EqppOp:\n         case LeppOp:\n         case LtppOp:\n         case NeppOp:\n         CPPAD_ASSERT_UNKNOWN( 2 <= NumArg(op) )\n         par_usage[arg[0]] = true;\n         par_usage[arg[1]] = true;\n         break;\n\n\n         // cases where only first argument is a parameter\n         case CSumOp:\n         case EqpvOp:\n         case DivpvOp:\n         case LepvOp:\n         case LtpvOp:\n         case MulpvOp:\n         case NepvOp:\n         case ParOp:\n         case PowpvOp:\n         case ZmulpvOp:\n         CPPAD_ASSERT_UNKNOWN( 1 <= NumArg(op) || op == CSumOp )\n         par_usage[arg[0]] = true;\n         break;\n\n         // cases where only second argument is a parameter\n         case DivvpOp:\n         case LevpOp:\n         case LdpOp:\n         case LtvpOp:\n         case PowvpOp:\n         case StpvOp:\n         case ZmulvpOp:\n         CPPAD_ASSERT_UNKNOWN( 2 <= NumArg(op) )\n         par_usage[arg[1]] = true;\n         break;\n\n         // cases where second and third arguments are parameters\n         case ErfOp:\n         case ErfcOp:\n         case StppOp:\n         CPPAD_ASSERT_UNKNOWN( 3 <= NumArg(op) )\n         par_usage[arg[1]] = true;\n         par_usage[arg[2]] = true;\n         break;\n\n         // cases where only third argument is a parameter\n         case StvpOp:\n         CPPAD_ASSERT_UNKNOWN( 3 <= NumArg(op) )\n         par_usage[arg[2]] = true;\n         break;\n\n         // conditional expression operator\n         case CExpOp:\n         CPPAD_ASSERT_UNKNOWN( 6 == NumArg(op) )\n         if( (arg[1] & 1) == 0 )\n            par_usage[arg[2]] = true;\n         if( (arg[1] & 2) == 0 )\n            par_usage[arg[3]] = true;\n         if( (arg[1] & 4) == 0 )\n            par_usage[arg[4]] = true;\n         if( (arg[1] & 8) == 0 )\n            par_usage[arg[5]] = true;\n         break;\n\n         // print function\n         case PriOp:\n         if( (arg[0] & 1) == 0 )\n            par_usage[arg[1]] = true;\n         if( (arg[0] & 2) == 0 )\n            par_usage[arg[3]] = true;\n         CPPAD_ASSERT_UNKNOWN( 5 == NumArg(op) )\n         break;\n\n         // --------------------------------------------------------------\n         // atomic function calls\n         case AFunOp:\n         if( atom_state == start_atom )\n         {  atom_index        = size_t(arg[0]);\n            call_id           = size_t(arg[1]);\n            atom_n            = size_t(arg[2]);\n            atom_m            = size_t(arg[3]);\n            atom_j            = 0;\n            atom_i            = 0;\n            atom_state        = arg_atom;\n            // -------------------------------------------------------\n            parameter_x.resize(  atom_n );\n            type_x.resize( atom_n );\n            atom_ix.resize( atom_n );\n            //\n            depend_y.resize( atom_m );\n            depend_x.resize( atom_n );\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( atom_state == end_atom );\n            CPPAD_ASSERT_UNKNOWN( atom_n == size_t(arg[2]) );\n            CPPAD_ASSERT_UNKNOWN( atom_m == size_t(arg[3]) );\n            CPPAD_ASSERT_UNKNOWN( atom_j == atom_n );\n            CPPAD_ASSERT_UNKNOWN( atom_i == atom_m );\n            atom_state = start_atom;\n            //\n            // call atomic function for this operation\n            sweep::call_atomic_rev_depend<Base, Base>(\n            atom_index, call_id, parameter_x, type_x, depend_x, depend_y\n            );\n            for(size_t j = 0; j < atom_n; j++)\n            if( depend_x[j] && type_x[j] != variable_enum )\n            {  // This user argument is a parameter that is needed\n               CPPAD_ASSERT_UNKNOWN( atom_ix[j] > 0 );\n               par_usage[ atom_ix[j] ] = true;\n            }\n         }\n         break;\n\n         case FunavOp:\n         // this argument is a variable\n         CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom );\n         atom_ix[atom_j]     = 0;\n         parameter_x[atom_j] = par_all[0]; // variables get value nan\n         type_x[atom_j]      = variable_enum;\n         ++atom_j;\n         if( atom_j == atom_n )\n            atom_state = ret_atom;\n         break;\n\n         case FunapOp:\n         // this argument is a parameter\n         CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom );\n         atom_ix[atom_j]     = size_t( arg[0] );\n         parameter_x[atom_j] = par_all[arg[0]]; // parameter value\n         if( par_is_dyn[arg[0]] )\n            type_x[atom_j] = dynamic_enum;\n         else\n            type_x[atom_j] = constant_enum;\n         ++atom_j;\n         if( atom_j == atom_n )\n            atom_state = ret_atom;\n         break;\n\n         case FunrpOp:\n         // this result is a parameter\n         CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom );\n         depend_y[atom_i] = op_usage[i_op] != usage_t(no_usage);\n         ++atom_i;\n         if( atom_i == atom_m )\n            atom_state = end_atom;\n         break;\n\n         case FunrvOp:\n         // this result is a variable\n         CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom );\n         depend_y[atom_i] = op_usage[i_op] != usage_t(no_usage);\n         ++atom_i;\n         if( atom_i == atom_m )\n            atom_state = end_atom;\n         break;\n         // --------------------------------------------------------------\n\n\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n      }\n   }\n   // -----------------------------------------------------------------------\n   // reverse pass to determine which dynamic parameters are necessary\n   // -----------------------------------------------------------------------\n   size_t i_arg = dyn_par_arg.size(); // index in dyn_par_arg\n   size_t i_dyn = num_dynamic_par;    // index in dyn2par_index\n     while(i_dyn)\n   {  // next dynamic parameter in reverse order\n      --i_dyn;\n      op_code_dyn op = op_code_dyn( dyn_par_op[i_dyn] );\n      while( op == result_dyn )\n      {  --i_dyn;\n         op = op_code_dyn( dyn_par_op[i_dyn] );\n         CPPAD_ASSERT_UNKNOWN( op == result_dyn || op == atom_dyn );\n      }\n      if( op == atom_dyn )\n      {  // number of arguments for this operator\n         size_t n_arg = size_t( dyn_par_arg[i_arg - 1] );\n         //\n         // index of first argument for this operation\n         i_arg -= n_arg;\n         //\n         atom_index = size_t( dyn_par_arg[i_arg + 0] );\n         call_id    = size_t( dyn_par_arg[i_arg + 1] );\n         size_t n   = size_t( dyn_par_arg[i_arg + 2] );\n         size_t m   = size_t( dyn_par_arg[i_arg + 3] );\n         CPPAD_ASSERT_UNKNOWN( n_arg == 6 + n + m );\n         //\n         // parameter_x, type_x\n         parameter_x.resize(n);\n         type_x.resize(n);\n         for(size_t j = 0; j < n; ++j)\n         {  // parameter index zero is used for variable\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( par_all[0] ) );\n            addr_t arg_j = dyn_par_arg[i_arg + 5 + j];\n            parameter_x[j] = par_all[arg_j];\n            if( arg_j == 0 )\n               type_x[j] = variable_enum;\n            else if( par_is_dyn[arg_j] )\n               type_x[j] = dynamic_enum;\n            else\n               type_x[j] = constant_enum;\n         }\n         //\n         // depend_y\n         depend_y.resize(m);\n         for(size_t i = 0; i < m; ++i)\n         {  // a constant parameter cannot depend on a dynamic parameter\n            // so do not worry about constant parameters in depend_y\n            size_t i_par = size_t( dyn_par_arg[i_arg + 5 + n + i] );\n            depend_y[i]  = par_usage[i_par];\n         }\n         //\n         // call back to atomic function for this operation\n         depend_x.resize(n);\n         sweep::call_atomic_rev_depend<Base, Base>(\n            atom_index, call_id, parameter_x, type_x, depend_x, depend_y\n         );\n         //\n         // transfer depend_x to par_usage\n         for(size_t j = 0; j < n; ++j)\n         {  size_t i_par = size_t( dyn_par_arg[i_arg + 5 + j] );\n            par_usage[i_par] = par_usage[i_par] || depend_x[j];\n         }\n      }\n      else\n      {  // corresponding parameter index\n         size_t i_par = size_t( dyn2par_index[i_dyn] );\n         CPPAD_ASSERT_UNKNOWN( par_is_dyn[i_par] );\n         //\n         // number of arguments to this operator\n         size_t n_arg = num_arg_dyn(op);\n         //\n         // index of first argument for this operator\n         CPPAD_ASSERT_UNKNOWN( op != atom_dyn );\n         i_arg -= n_arg;\n         //\n         // if this dynamic parameter is needed\n         if( par_usage[i_par] )\n         {  // need dynamic parameters that are used to generate this one\n            size_t offset = num_non_par_arg_dyn(op);\n            for(size_t i = offset; i < n_arg; ++i)\n               par_usage[ dyn_par_arg[i_arg + i] ] = true;\n         }\n      }\n   }\n   CPPAD_ASSERT_UNKNOWN( i_arg == 0 );\n   //\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/hash_code.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_HASH_CODE_HPP\n# define CPPAD_LOCAL_OPTIMIZE_HASH_CODE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*!\n\\file local/optimize/hash_code.hpp\nCppAD hashing utility.\n*/\n\n\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize {\n/*!\nSpecialized hash code for a CppAD operator and its arguments\n(used during optimization).\n\n\\param op\nis the operator that we are computing a hash code for.\n\n\\param num_arg\nnumber of elements of arg to include in the hash code.\n\n\\param arg\nis a vector of length num_arg\ncontaining the corresponding argument indices for this operator.\n\n\\return\nis a hash code that is between zero and CPPAD_HASH_TABLE_SIZE - 1.\n*/\n\ninline size_t optimize_hash_code(\n   opcode_t      op      ,\n   size_t        num_arg ,\n   const addr_t* arg     )\n{  CPPAD_ASSERT_UNKNOWN( num_arg < 4 );\n   size_t prime = 1;\n   size_t sum   = prime * size_t(op);\n   for(size_t i = 0; i < num_arg; i++)\n   {  prime    = prime + 2;  // 3, 5, 7 in that order\n      sum += prime * size_t(arg[i]);\n   }\n   //\n   return sum % CPPAD_HASH_TABLE_SIZE;\n}\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/match_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_MATCH_OP_HPP\n# define CPPAD_LOCAL_OPTIMIZE_MATCH_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/optimize/hash_code.hpp>\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize  {\n/*\n{xrst_begin optimize_match_op dev}\n{xrst_spell\n   erfc\n}\n\nSearch for a Previous Operator that Matches Current Operator\n############################################################\n\nSyntax\n******\n| *exceed_collision_limit* = ``match_op`` (\n| |tab| ``collision_limit`` ,\n| |tab| ``random_itr`` ,\n| |tab| ``op_previous`` ,\n| |tab| ``current`` ,\n| |tab| ``hash_tape_op`` ,\n| |tab| ``work_bool`` ,\n| |tab| ``work_addr_t``\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nOperator Arguments\n******************\nIf an argument for the current operator is a variable,\nand the argument has previous match,\nthe previous match for the argument is used when checking for a match\nfor the current operator.\n\ncollision_limit\n***************\nis the maximum number of collisions (matches) allowed for one\nexpression hash code value.\n\nrandom_itr\n**********\nis a random iterator for the old operation sequence.\n\nop_previous\n***********\nMapping from operator index to previous operator that can replace this one.\nThe input value of\n\n   *previous* = *op_previous* [ *current* ]\n\nis assumed to be zero.  If a match if found, the output value of\n*previous* is set to the matching operator index,\notherwise it is left as is.  Note that *previous* < *current*\nand *op_previous* [ ``previous`` ] is zero.\n\ncurrent\n*******\nis the index of the current operator which cannot be any of the\noperators in the list below:\n{xrst_literal\n   // BEGIN_INVALID_OP\n   // END_INVALID_OP\n}\nAfter this initialization, the value of *current*\nincreases with each call to match_op.\n\nerf\n===\nThe operators ``ErfOp`` and ``ErfcOp`` have\nthree arguments, but only one true argument (the others are always the same).\n\nhash_table_op\n*************\nis assumed to be initialized as a vector of empty sets before the\nfirst call to match_op (for a pass of the operation sequence).\n\n| |tab| *hash_table_op* . ``n_set`` () == ``CPPAD_HASH_TABLE_SIZE``\n| |tab| *hash_table_op* . ``end`` ()   == *op_previous* . ``size`` ()\n\nIf *i_op* is an element of the j-th set,\nthen the operation *op_previous* [ *i_op* ] has hash code j,\nand does not match any other element of the j-th set.\nAn entry to j-th set for the current operator is added each time\nmatch_op is called and a match for the current operator is not found.\n\nwork_bool\n*********\nwork space that is used by match_op between calls to increase speed.\nShould be empty on first call for this forward pass of the operation\nsequence and not modified until forward pass is done\n\nwork_addr_t\n***********\nwork space that is used by match_op between calls to increase speed.\nShould be empty on first call for this forward pass of the operation\nsequence and not modified until forward pass is done\n\nexceed_collision_limit\n**********************\nIf the *collision_limit* is exceeded (is not exceeded),\nthe return value is true (false).\n\n{xrst_end optimize_match_op}\n*/\n// BEGIN_PROTOTYPE\ntemplate <class Addr>\nbool match_op(\n   size_t                                      collision_limit ,\n   const play::const_random_iterator<Addr>&    random_itr      ,\n   pod_vector<addr_t>&                         op_previous     ,\n   size_t                                      current         ,\n   sparse::list_setvec&                        hash_table_op   ,\n   pod_vector<bool>&                           work_bool       ,\n   pod_vector<addr_t>&                         work_addr_t     )\n// END_PROTOTYPE\n{\n# ifndef NDEBUG\n   switch( random_itr.get_op(current) )\n   {\n      // BEGIN_INVALID_OP\n      case BeginOp:\n      case CExpOp:\n      case CSkipOp:\n      case CSumOp:\n      case EndOp:\n      case InvOp:\n      case LdpOp:\n      case LdvOp:\n      case ParOp:\n      case PriOp:\n      case StppOp:\n      case StpvOp:\n      case StvpOp:\n      case StvvOp:\n      case AFunOp:\n      case FunapOp:\n      case FunavOp:\n      case FunrpOp:\n      case FunrvOp:\n      // END_INVALID_OP\n      CPPAD_ASSERT_UNKNOWN(false);\n      break;\n\n      default:\n      break;\n   }\n# endif\n   // initialize return value\n   bool exceed_collision_limit = false;\n   // num_op\n   size_t num_op = random_itr.num_op();\n   //\n   // num_var\n   size_t num_var = random_itr.num_var();\n   //\n   // variable is a reference to, and better name for, work_bool\n   pod_vector<bool>&  variable(work_bool);\n   //\n   // var2previous_var is a reference to, and better name for, work_addr_t\n   pod_vector<addr_t>&  var2previous_var(work_addr_t);\n   if( var2previous_var.size() == 0 )\n   {  var2previous_var.resize(num_var);\n      for(size_t i = 0; i < num_var; ++i)\n         var2previous_var[i] = addr_t(i);\n   }\n   //\n   CPPAD_ASSERT_UNKNOWN( var2previous_var.size() == num_var );\n   CPPAD_ASSERT_UNKNOWN( num_op == op_previous.size() );\n   CPPAD_ASSERT_UNKNOWN( op_previous[current] == 0 );\n   CPPAD_ASSERT_UNKNOWN(\n      hash_table_op.n_set() == CPPAD_HASH_TABLE_SIZE\n   );\n   CPPAD_ASSERT_UNKNOWN( hash_table_op.end() == num_op );\n   CPPAD_ASSERT_UNKNOWN( current < num_op );\n   //\n   // op, arg, i_var\n   op_code_var   op;\n   const addr_t* arg;\n   size_t        i_var;\n   random_itr.op_info(current, op, arg, i_var);\n   //\n   // num_arg\n   size_t num_arg = NumArg(op);\n   CPPAD_ASSERT_UNKNOWN( 0 < num_arg );\n   CPPAD_ASSERT_UNKNOWN(\n      (num_arg < 3) || ( (num_arg == 3) && (op == ErfOp || op == ErfcOp) )\n   );\n   //\n   arg_is_variable(op, arg, variable);\n   CPPAD_ASSERT_UNKNOWN( variable.size() == num_arg );\n   //\n   // If j-th argument to this operator is a variable, and a previous\n   // variable will be used in its place, use the previous variable for\n   // hash coding and matching.\n   addr_t arg_match[] = {\n      // Invalid value that will not be used. This initialization avoid\n      // a warning on some compilers\n      std::numeric_limits<addr_t>::max(),\n      std::numeric_limits<addr_t>::max(),\n      std::numeric_limits<addr_t>::max()\n   };\n   if( (op == AddvvOp) || (op == MulvvOp ) )\n   {  // in special case where operator is commutative and operands are variables,\n      // put lower index first so hash code does not depend on operator order\n      CPPAD_ASSERT_UNKNOWN( num_arg == 2 );\n      arg_match[0] = var2previous_var[ arg[0] ];\n      arg_match[1] = var2previous_var[ arg[1] ];\n      if( arg_match[1] < arg_match[0] )\n         std::swap( arg_match[0], arg_match[1] );\n   }\n   else for(size_t j = 0; j < num_arg; ++j)\n   {  arg_match[j] = arg[j];\n      if( variable[j] )\n         arg_match[j] = var2previous_var[ arg[j] ];\n   }\n\n   //\n   size_t code = optimize_hash_code(opcode_t(op), num_arg, arg_match);\n   //\n   // iterator for the set with this hash code\n   sparse::list_setvec_const_iterator itr(hash_table_op, code);\n   //\n   // check for a match\n   size_t count = 0;\n   while( *itr != num_op )\n   {  ++count;\n      //\n      // candidate previous for current operator\n      size_t  candidate  = *itr;\n      CPPAD_ASSERT_UNKNOWN( candidate < current );\n      CPPAD_ASSERT_UNKNOWN( op_previous[candidate] == 0 );\n      //\n      op_code_var   op_c;\n      const addr_t* arg_c;\n      size_t        i_var_c;\n      random_itr.op_info(candidate, op_c, arg_c, i_var_c);\n      //\n      // check for a match\n      bool match = op == op_c;\n      size_t j   = 0;\n      while( match & (j < num_arg) )\n      {  if( variable[j] )\n            match &= arg_match[j] == var2previous_var[ arg_c[j] ];\n         else\n            match &= arg_match[j] == arg_c[j];\n         ++j;\n      }\n      if( (! match) && ( (op == AddvvOp) || (op == MulvvOp) ) )\n      {  // communative so check for reverse order match\n         match  = op == op_c;\n         //\n         // 2024-02-14:\n         // If op_c is not AddvvOp or MulvvOp, its arguments may not be\n         // variables and the code below could attempt to access\n         // var2previous_var out of range. See 2024@mm-dd@02-14.\n         if( match )\n         {  match &= arg_match[0] == var2previous_var[ arg_c[1] ];\n            match &= arg_match[1] == var2previous_var[ arg_c[0] ];\n         }\n      }\n      if( match )\n      {  op_previous[current] = static_cast<addr_t>( candidate );\n         if( NumRes(op) > 0 )\n         {  CPPAD_ASSERT_UNKNOWN( i_var_c < i_var );\n            var2previous_var[i_var] = addr_t( i_var_c );\n         }\n         return exceed_collision_limit;\n      }\n      ++itr;\n   }\n\n   // see print (that is commented out) at bottom of get_op_previous.hpp\n   CPPAD_ASSERT_UNKNOWN( count <= collision_limit );\n   if( count == collision_limit )\n   {  // restart the list\n      hash_table_op.clear(code);\n      // limit has been exceeded\n      exceed_collision_limit = true;\n   }\n   // No match was found. Add this operator to the set for this hash code\n   // Not using post_element because we need to iterate for\n   // this code before adding another element for this code.\n   hash_table_op.add_element(code, current);\n   //\n   return exceed_collision_limit;\n}\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/optimize_run.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_OPTIMIZE_RUN_HPP\n# define CPPAD_LOCAL_OPTIMIZE_OPTIMIZE_RUN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <stack>\n# include <iterator>\n# include <cppad/local/optimize/extract_option.hpp>\n# include <cppad/local/optimize/get_op_usage.hpp>\n# include <cppad/local/optimize/get_par_usage.hpp>\n# include <cppad/local/optimize/get_dyn_previous.hpp>\n# include <cppad/local/optimize/get_op_previous.hpp>\n# include <cppad/local/optimize/get_cexp_info.hpp>\n# include <cppad/local/optimize/size_pair.hpp>\n# include <cppad/local/optimize/csum_stacks.hpp>\n# include <cppad/local/optimize/cexp_info.hpp>\n# include <cppad/local/optimize/record_pv.hpp>\n# include <cppad/local/optimize/record_vp.hpp>\n# include <cppad/local/optimize/record_vv.hpp>\n# include <cppad/local/optimize/record_csum.hpp>\n\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize  {\n\n/*!\n{xrst_begin optimize_run dev}\n{xrst_spell\n   dep\n   pri\n   substring\n   taddr\n}\n\nConvert a player object to an optimized recorder object\n#######################################################\n\nSyntax\n******\n| *exceed_collision_limit* = ``local::optimize::optimize_run`` (\n| |tab| ``options`` , ``n`` , ``dep_taddr`` , ``play`` , ``rec``\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nAddr\n****\nType to use for array elements in ``const_random_iterator`` .\n\nBase\n****\nBase type for the operator; i.e., this operation was recorded\nusing ``AD`` < *Base* >\nand computations by this routine are done using type *Base* .\n\noptions\n*******\n\nno_conditional_skip\n===================\nIf this sub-string appears,\nconditional skip operations will not be generated.\nThis may make the optimize routine use significantly less memory\nand take significantly less time.\n\nno_compare_op\n=============\nIf this sub-string appears,\nthen comparison operators will be removed from the optimized tape.\nThese operators are necessary for the :ref:`compare_change-name` feature to be\nmeaningful in the resulting recording.\nOn the other hand, they are not necessary and take extra time\nwhen this feature is not needed.\n\nno_print_for_op\n===============\nIf this sub-string appears,\nthen :ref:`printfor-name` operators ``PriOp``\nwill be removed from the optimized tape.\nThese operators are useful for reporting problems evaluating derivatives\nat independent variable values different from those used to record a function.\n\nno_cumulative_sum_op\n====================\nIf this sub-string appears,\nno cumulative sum operations will be generated during the optimization; see\n:ref:`optimize_cumulative_sum.cpp-name` .\n\ncollision_limit=value\n=====================\nIf this substring appears,\nwhere *value* is a sequence of decimal digits,\nthe optimizer's hash code collision limit will be set to *value* .\nWhen the collision limit is exceeded, the expressions with that hash code\nare removed and a new lists of expressions with that has code is started.\nThe larger *value* , the more identical expressions the optimizer\ncan recognize, but the slower the optimizer may run.\nThe default for *value* is ``10`` .\n\nn\n*\nis the number of independent variables on the tape.\n\ndep_taddr\n*********\nOn input this vector contains the indices for each of the dependent\nvariable values in the operation sequence corresponding to *play* .\nUpon return it contains the indices for the same variables but in\nthe operation sequence corresponding to *rec* .\n\nplay\n****\nThis is the operation sequence that we are optimizing.\nIt is ``const`` except for the fact that\n*play* ``->setup_random`` () is called.\n\nrec\n***\nThe input contents of this recording must be empty; i.e.,\nit corresponds to directly after the default constructor.\nUpon return, it contains an optimized version of the\noperation sequence corresponding to *play* .\n\nexceed_collision_limit\n**********************\nIf the *collision_limit* is exceeded (is not exceeded),\nthe return value is true (false).\n\nContents\n********\n{xrst_toc_table\n   include/cppad/local/optimize/extract_option.hpp\n   include/cppad/local/optimize/cexp_info.hpp\n   include/cppad/local/optimize/get_cexp_info.hpp\n   include/cppad/local/optimize/get_op_usage.hpp\n   include/cppad/local/optimize/get_par_usage.hpp\n   include/cppad/local/optimize/record_csum.hpp\n   include/cppad/local/optimize/match_op.hpp\n   include/cppad/local/optimize/get_op_previous.hpp\n}\n\n{xrst_end optimize_run}\n*/\n\n// BEGIN_PROTOTYPE\ntemplate <class Addr, class Base>\nbool optimize_run(\n   const std::string&                         options    ,\n   size_t                                     n          ,\n   pod_vector<size_t>&                        dep_taddr  ,\n   player<Base>*                              play       ,\n   recorder<Base>*                            rec        )\n// END_PROTOTYPE\n{  bool exceed_collision_limit = false;\n   //\n   // check that recorder is empty\n   CPPAD_ASSERT_UNKNOWN( rec->num_var_op() == 0 );\n   //\n   // get a random iterator for this player\n   Addr not_used;\n   play->setup_random( not_used );\n   local::play::const_random_iterator<Addr> random_itr =\n      play->get_random( not_used );\n   //\n   // compare_op, conditional_skip, cumulative_sum_op, print_for_op,\n   // collision_limit\n   options_t result         = extract_option(options);\n   bool compare_op          = result.compare_op;\n   bool conditional_skip    = result.conditional_skip;\n   bool cumulative_sum_op   = result.cumulative_sum_op;\n   bool print_for_op        = result.print_for_op;\n   size_t collision_limit   = result.collision_limit;\n   CPPAD_ASSERT_UNKNOWN( result.val_graph == false );\n   //\n   // number of operators in the player\n   const size_t num_op = play->num_var_op();\n   CPPAD_ASSERT_UNKNOWN(\n      num_op < size_t( (std::numeric_limits<addr_t>::max)() )\n   );\n\n   // number of variables in the player\n# ifndef NDEBUG\n   const size_t num_var = play->num_var();\n# endif\n\n   // number of parameter in the player\n   const size_t num_par = play->num_par_all();\n\n   // number of  VecAD indices\n   size_t num_vecad_ind   = play->num_var_vec_ind();\n\n   // number of VecAD vectors\n   size_t num_vecad_vec   = play->num_var_vecad();\n\n   // number of independent dynamic parameters\n   size_t n_dyn_independent = play->n_dyn_independent();\n\n   // number of dynamic parameters\n   size_t num_dynamic_par = play->num_dynamic_par();\n\n   // mapping from dynamic parameter index to parameter index\n   const pod_vector<addr_t>& dyn2par_index( play->dyn2par_index() );\n\n   // number of dynamic parameters\n   CPPAD_ASSERT_UNKNOWN( n_dyn_independent <= play->num_dynamic_par () );\n\n   // -----------------------------------------------------------------------\n   // operator information\n   pod_vector<addr_t>        cexp2op;\n   sparse::list_setvec       cexp_set;\n   pod_vector<bool>          vecad_used;\n   pod_vector<usage_t>       op_usage;\n   get_op_usage(\n      conditional_skip,\n      compare_op,\n      print_for_op,\n      cumulative_sum_op,\n      play,\n      random_itr,\n      dep_taddr,\n      cexp2op,\n      cexp_set,\n      vecad_used,\n      op_usage\n   );\n   pod_vector<addr_t>        op_previous;\n   exceed_collision_limit |= get_op_previous(\n      collision_limit,\n      play,\n      random_itr,\n      cexp_set,\n      op_previous,\n      op_usage\n   );\n   size_t num_cexp = cexp2op.size();\n   CPPAD_ASSERT_UNKNOWN( conditional_skip || num_cexp == 0 );\n   vector<struct_cexp_info>  cexp_info; // struct_cexp_info not POD\n   sparse::list_setvec       skip_op_true;\n   sparse::list_setvec       skip_op_false;\n   //\n   if( cexp2op.size() > 0 ) get_cexp_info(\n      play,\n      random_itr,\n      op_previous,\n      op_usage,\n      cexp2op,\n      cexp_set,\n      cexp_info,\n      skip_op_true,\n      skip_op_false\n   );\n\n   // We no longer need cexp_set, and cexp2op, so free their memory\n   cexp_set.resize(0, 0);\n   cexp2op.clear();\n   // -----------------------------------------------------------------------\n   // dynamic parameter information\n   pod_vector<bool> par_usage;\n   get_par_usage(\n      play,\n      random_itr,\n      op_usage,\n      vecad_used,\n      par_usage\n   );\n   pod_vector<addr_t> dyn_previous;\n   get_dyn_previous(\n      play                ,\n      par_usage           ,\n      dyn_previous\n   );\n   // -----------------------------------------------------------------------\n   // conditional expression information\n   //\n   // Size of the conditional expression information structure.\n   // This is equal to the number of conditional expressions when\n   // conditional_skip is true, otherwise it is zero.\n   //\n   // sort the conditional expression information by max_left_right\n   // this is the conditional skip order\n   vector<size_t> cskip_order(num_cexp);\n   if( num_cexp > 0 )\n   {  vector<size_t> keys(num_cexp);\n      for(size_t i = 0; i < num_cexp; i++)\n         keys[i] = size_t( cexp_info[i].max_left_right );\n      CppAD::index_sort(keys, cskip_order);\n   }\n   // initial index in conditional skip order\n   size_t cskip_order_next = 0;\n   //\n   // initialize index in conditional expression order\n   size_t cexp_next = 0;\n\n   // mapping from conditional expression index to conditional skip\n   // information on new tape\n   pod_vector<struct_cskip_new> cskip_new(num_cexp);\n   //\n   // flag used to indicate that there is no conditional skip\n   // for this conditional expression\n   for(size_t i = 0; i < num_cexp; i++)\n      cskip_new[i].i_arg = 0;\n   // =======================================================================\n   // Create new recording\n   // =======================================================================\n   //\n   // dynamic parameter information in player\n   const pod_vector<bool>&     par_is_dyn( play->par_is_dyn() );\n   const pod_vector<opcode_t>& dyn_par_op( play->dyn_par_op() );\n   const pod_vector<addr_t>&   dyn_par_arg( play->dyn_par_arg() );\n   //\n   // start mapping from old parameter indices to new parameter indices\n   // for all parameters that get used.\n   pod_vector<addr_t> new_par( num_par );\n   addr_t addr_t_max = (std::numeric_limits<addr_t>::max)();\n   for(size_t i_par = 0; i_par < num_par; ++i_par)\n      new_par[i_par] = addr_t_max; // initialize as not used\n   //\n   // start new recording\n   CPPAD_ASSERT_UNKNOWN( rec->num_var_op() == 0 );\n   rec->set_n_dyn_independent(n_dyn_independent);\n   rec->set_abort_op_index(0);\n   rec->set_record_compare( compare_op );\n\n   // copy parameters with index 0\n   CPPAD_ASSERT_UNKNOWN( ! par_is_dyn[0] && CppAD::isnan( play->par_one(0) ) );\n   rec->put_con_par( play->par_one(0) );\n   new_par[0] = 0;\n\n   // set new_par for the independent dynamic parameters\n   for(size_t i_par = 1; i_par <= n_dyn_independent; i_par++)\n   {  CPPAD_ASSERT_UNKNOWN( par_is_dyn[i_par] );\n      addr_t i = rec->put_dyn_par(play->par_one(i_par), ind_dyn);\n      CPPAD_ASSERT_UNKNOWN( size_t(i) == i_par );\n      new_par[i_par] = i;\n   }\n\n   // set new_par for the constant parameters that are used\n   for(size_t i_par = n_dyn_independent + 1; i_par < num_par; ++i_par)\n   if( ! par_is_dyn[i_par] )\n   {  CPPAD_ASSERT_UNKNOWN( i_par == 0 || n_dyn_independent < i_par );\n      if( par_usage[i_par] )\n      {  // value of this parameter\n         Base par       = play->par_one(i_par);\n         new_par[i_par] = rec->put_con_par(par);\n      }\n   }\n\n   // index corresponding to the parameter zero\n   addr_t zero_par_index = rec->put_con_par( Base(0) );\n\n   // set new_par for the dependent dynamic parameters\n   size_t i_dyn = n_dyn_independent;// dynamic parameter index\n   size_t i_arg = 0;                // dynamic parameter argument index\n   pod_vector<addr_t> arg_vec;\n   for(size_t i_par = n_dyn_independent + 1; i_par < num_par; ++i_par)\n   if( par_is_dyn[i_par] )\n   {  // operator for this dynamic parameter\n      op_code_dyn op = op_code_dyn( dyn_par_op[i_dyn] );\n      //\n      // number of arguments for this dynamic parameter\n      size_t n_arg   = num_arg_dyn(op);\n      //\n      // number of dynamic parameter results for this operator\n      size_t n_dyn   = 1;\n      //\n      if( op == atom_dyn )\n      {  size_t atom_index = size_t( dyn_par_arg[i_arg + 0]  );\n         size_t call_id    = size_t( dyn_par_arg[i_arg + 1]  );\n         size_t atom_n     = size_t( dyn_par_arg[i_arg + 2]  );\n         size_t atom_m     = size_t( dyn_par_arg[i_arg + 3]  );\n         n_dyn             = size_t( dyn_par_arg[i_arg + 4]  );\n         n_arg             = 6 + atom_n + atom_m;\n         //\n         // check if any dynamic parameter result for this operator is used\n         bool call_used = false;\n# ifndef NDEBUG\n         bool found_i_par = false;\n         for(size_t i = 0; i < atom_m; ++i)\n         {  size_t j_par = size_t( dyn_par_arg[i_arg + 5 + atom_n + i] );\n            if( par_is_dyn[j_par] )\n            {  call_used |= par_usage[j_par];\n               CPPAD_ASSERT_UNKNOWN( j_par == i_par || found_i_par );\n               // j_par > i_par corresponds to result_dyn operator\n               CPPAD_ASSERT_UNKNOWN( j_par >= i_par );\n               found_i_par |= j_par == i_par;\n            }\n         }\n         CPPAD_ASSERT_UNKNOWN( found_i_par );\n# else\n         for(size_t i = 0; i < atom_m; ++i)\n         {  size_t j_par = size_t( dyn_par_arg[i_arg + 5 + atom_n + i] );\n            if( par_is_dyn[j_par] )\n               call_used |= par_usage[j_par];\n         }\n# endif\n         if( call_used )\n         {  arg_vec.resize(0);\n            arg_vec.push_back( addr_t( atom_index ) );\n            arg_vec.push_back( addr_t( call_id ) );\n            arg_vec.push_back( addr_t( atom_n ) );\n            arg_vec.push_back( addr_t( atom_m ) );\n            arg_vec.push_back( addr_t( n_dyn ) );\n            for(size_t j = 0; j < atom_n; ++j)\n            {  addr_t arg_j = dyn_par_arg[i_arg + 5 + j];\n               if( arg_j > 0 && par_usage[arg_j] )\n                  arg_vec.push_back( new_par[ arg_j ] );\n               else\n                  arg_vec.push_back(0);\n            }\n            bool first_dynamic_result = true;\n            for(size_t i = 0; i < atom_m; ++i)\n            {  addr_t res_i = dyn_par_arg[i_arg + 5 + atom_n + i];\n               CPPAD_ASSERT_UNKNOWN( par_is_dyn[res_i] || res_i == 0 );\n               //\n               if( par_is_dyn[res_i] )\n               {  Base par = play->par_one( size_t(res_i) );\n                  if( first_dynamic_result )\n                  {  first_dynamic_result = false;\n                     new_par[res_i] = rec->put_dyn_par(par, atom_dyn);\n                  }\n                  else\n                     new_par[res_i] = rec->put_dyn_par(par, result_dyn);\n                  arg_vec.push_back( new_par[res_i] );\n               }\n               else\n               {  // this result is a constant parameter\n                  if( new_par[res_i] != addr_t_max )\n                     arg_vec.push_back( new_par[res_i] );\n                  else\n                  {  // this constant parameter is not used\n                     arg_vec.push_back(0); // phantom parameter\n                  }\n               }\n            }\n            arg_vec.push_back( addr_t(6 + atom_n + atom_m ) );\n            rec->put_dyn_arg_vec( arg_vec );\n         }\n      }\n      else if( par_usage[i_par] && (op != result_dyn) )\n      {  size_t j_dyn = size_t( dyn_previous[i_dyn] );\n         if( j_dyn != num_dynamic_par )\n         {  size_t j_par = size_t( dyn2par_index[j_dyn] );\n            CPPAD_ASSERT_UNKNOWN( j_par < i_par );\n            new_par[i_par] = new_par[j_par];\n         }\n         else\n         {\n            // value of this parameter\n            Base par       = play->par_one(i_par);\n            //\n            if( op == cond_exp_dyn )\n            {  // cond_exp_dyn\n               CPPAD_ASSERT_UNKNOWN( n_dyn_independent <= i_par );\n               CPPAD_ASSERT_UNKNOWN( n_arg == 5 );\n               new_par[i_par] = rec->put_dyn_cond_exp(\n                  par                                ,   // par\n                  CompareOp( dyn_par_arg[i_arg + 0] ),   // cop\n                  new_par[ dyn_par_arg[i_arg + 1] ]  ,   // left\n                  new_par[ dyn_par_arg[i_arg + 2] ]  ,   // right\n                  new_par[ dyn_par_arg[i_arg + 3] ]  ,   // if_true\n                  new_par[ dyn_par_arg[i_arg + 4] ]      // if_false\n               );\n            }\n            else if(  op == dis_dyn )\n            {  // dis_dyn\n               CPPAD_ASSERT_UNKNOWN( n_arg == 2 );\n               new_par[i_par] = rec->put_dyn_par(\n                  par                               ,  // par\n                  op                                ,  // op\n                  dyn_par_arg[i_arg + 0]            ,  // index\n                  new_par[ dyn_par_arg[i_arg + 1] ]    // parameter\n               );\n            }\n            else if( n_arg == 1 )\n            {  // cases with one argument\n               CPPAD_ASSERT_UNKNOWN( num_non_par_arg_dyn(op) == 0 );\n               CPPAD_ASSERT_UNKNOWN( n_dyn_independent <= i_par );\n               new_par[i_par] = rec->put_dyn_par( par, op,\n                  new_par[ dyn_par_arg[i_arg + 0] ]\n               );\n            }\n            else if( n_arg == 2 )\n            {  // cases with two arguments\n               CPPAD_ASSERT_UNKNOWN( n_dyn_independent <= i_par );\n               CPPAD_ASSERT_UNKNOWN( num_non_par_arg_dyn(op) == 0 );\n               new_par[i_par] = rec->put_dyn_par( par, op,\n                  new_par[ dyn_par_arg[i_arg + 0] ],\n                  new_par[ dyn_par_arg[i_arg + 1] ]\n               );\n            }\n            else\n            {  // independent dynamic parameter case\n               CPPAD_ASSERT_UNKNOWN( op == ind_dyn )\n               CPPAD_ASSERT_UNKNOWN( i_par <= n_dyn_independent );\n               CPPAD_ASSERT_UNKNOWN( n_arg == 0 );\n               new_par[i_par] = rec->put_dyn_par( par, op);\n            }\n         }\n      }\n      ++i_dyn;\n      i_arg += n_arg;\n   }\n   // -----------------------------------------------------------------------\n   // There is an additional constant parameter for each cumulative summation\n   // (that does not have a corresponding old parameter index).\n   // ------------------------------------------------------------------------\n   // initialize mapping from old VecAD index to new VecAD index\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( (std::numeric_limits<addr_t>::max)() ) >= num_vecad_ind\n   );\n   pod_vector<addr_t> new_vecad_ind(num_vecad_ind);\n   for(size_t i = 0; i < num_vecad_ind; i++)\n      new_vecad_ind[i] = addr_t( num_vecad_ind ); // invalid index\n   {\n      size_t j = 0;     // index into the old set of indices\n      for(size_t i = 0; i < num_vecad_vec; i++)\n      {  // length of this VecAD\n         size_t length = play->GetVecInd(j);\n         if( vecad_used[i] )\n         {  // Put this VecAD vector in new recording\n            CPPAD_ASSERT_UNKNOWN(length < num_vecad_ind);\n            new_vecad_ind[j] = rec->put_var_vecad_ind( addr_t(length) );\n            for(size_t k = 1; k <= length; k++) new_vecad_ind[j+k] =\n               rec->put_var_vecad_ind(\n                  new_par[ play->GetVecInd(j+k) ]\n            );\n         }\n         // start of next VecAD\n         j       += length + 1;\n      }\n      CPPAD_ASSERT_UNKNOWN( j == num_vecad_ind );\n   }\n\n   // temporary buffer for new argument values\n   addr_t new_arg[6];\n\n   // temporary work space used by record_csum\n   // (declared here to avoid realloaction of memory)\n   struct_csum_stacks csum_work;\n\n   // temporary used to hold a size_pair\n   struct_size_pair size_pair;\n   //\n   // Mapping from old operator index to new variable index,\n   // zero is invalid except for new_var[0].\n   pod_vector<addr_t> new_var(num_op);\n   //\n   // Mapping from old operator index to new operator index will share\n   // memory with op_previous. Must get op_previous[i_op] for this operator\n   // before over writing it with new_op[i_op].\n   pod_vector<addr_t>& new_op( op_previous );\n   CPPAD_ASSERT_UNKNOWN( new_op.size() == num_op );\n   // -------------------------------------------------------------\n   // information for current operator\n   size_t          i_op;   // index\n   op_code_var     op;     // operator\n   const addr_t*   arg;    // arguments\n   size_t          i_var;  // variable index of primary (last) result\n   //\n   // information about atomic function\n   enum_atom_state atom_state = start_atom;\n   size_t atom_i              = 0;\n   size_t atom_j              = 0;\n   //\n   i_var      = 0;\n   for(i_op = 0; i_op < num_op; ++i_op)\n   {  // if non-zero, use previous result in place of this operator.\n      // Must get this information before writing new_op[i_op].\n      size_t previous = size_t( op_previous[i_op] );\n      //\n      // zero is invalid except for new_op[0].\n      new_op[i_op] = 0;\n      //\n      // Zero is invalid except for new_var[0] and previous is zero unless\n      // this operator is replace by a previous operator.\n      new_var[i_op] = 0;\n      if( op_usage[i_op] == usage_t(yes_usage) )\n         new_var[i_op] = new_var[previous];\n      //\n      // temporary used in some switch cases\n      addr_t mask;\n      //\n      // this operator information\n      size_t i_tmp;\n      random_itr.op_info(i_op, op, arg, i_tmp);\n      if( NumRes(op) > 0 )\n         i_var = i_tmp;\n      //\n      // is this new result the top of a cumulative summation\n      bool top_csum;\n      //\n      // determine if we should insert a conditional skip here\n      bool skip  = conditional_skip;\n      if( skip )\n      {  skip      &= cskip_order_next < num_cexp;\n         skip      &= op != BeginOp;\n         skip      &= op != InvOp;\n         skip      &= atom_state == start_atom;\n         if( skip )\n         {  size_t j = cskip_order[cskip_order_next];\n            if( NumRes(op) > 0 )\n               skip &= size_t( cexp_info[j].max_left_right ) < i_var;\n            else\n               skip &= size_t( cexp_info[j].max_left_right ) <= i_var;\n         }\n         if( skip )\n         {  size_t j = cskip_order[cskip_order_next];\n            cskip_order_next++;\n            size_t n_true   = skip_op_true.number_elements(j);\n            size_t n_false  = skip_op_false.number_elements(j);\n            skip &= n_true > 0 || n_false > 0;\n            if( skip )\n            {  CPPAD_ASSERT_UNKNOWN( NumRes(CSkipOp) == 0 );\n               size_t n_arg   = 7 + size_t(n_true) + size_t(n_false);\n               // reserve space for the arguments to this operator but\n               // delay setting them until we have all the new addresses\n               cskip_new[j].i_arg = rec->ReserveArg(n_arg);\n               // i_arg == 0 is used to check if conditional expression\n               // has been skipped.\n               CPPAD_ASSERT_UNKNOWN( cskip_new[j].i_arg > 0 );\n               // There is no corresponding old operator in this case\n               rec->PutOp(CSkipOp);\n            }\n         }\n      }\n      //\n      CPPAD_ASSERT_UNKNOWN(\n         size_t( (std::numeric_limits<addr_t>::max)() ) >= rec->num_var_op()\n      );\n      //\n      // For each call, first and second AFunOp will have same op_usage\n      skip  = op_usage[i_op] != usage_t( yes_usage );\n      skip &= atom_state != arg_atom && atom_state != ret_atom;\n      if( skip )\n      {  if( op == CExpOp )\n            ++cexp_next;\n         //\n         if( op == AFunOp )\n         {  if( atom_state == start_atom )\n               atom_state = end_atom;\n            else\n            {  CPPAD_ASSERT_UNKNOWN( atom_state == end_atom );\n               atom_state = start_atom;\n            }\n         }\n      }\n      else switch( op )\n      {  // op_usage[i_op] == usage_t(yes_usage)\n\n         case BeginOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1);\n         // Put BeginOp at beginning of recording\n         new_op[i_op]  = addr_t( rec->num_var_op() );\n         new_var[i_op] = rec->PutOp(BeginOp);\n         rec->PutArg(arg[0]);\n         break;\n\n         // --------------------------------------------------------------\n         // Unary operators, argument a variable, one result\n         case AbsOp:\n         case AcosOp:\n         case AcoshOp:\n         case AsinOp:\n         case AsinhOp:\n         case AtanOp:\n         case AtanhOp:\n         case CosOp:\n         case CoshOp:\n         case ErfOp:\n         case ErfcOp:\n         case ExpOp:\n         case Expm1Op:\n         case LogOp:\n         case Log1pOp:\n         case NegOp:\n         case SignOp:\n         case SinOp:\n         case SinhOp:\n         case SqrtOp:\n         case TanOp:\n         case TanhOp:\n         if( previous == 0 )\n         {  //\n            new_arg[0]   = new_var[ random_itr.var2op(size_t(arg[0])) ];\n            rec->PutArg( new_arg[0] );\n            //\n            new_op[i_op]  = addr_t( rec->num_var_op() );\n            new_var[i_op] = rec->PutOp(op);\n            CPPAD_ASSERT_UNKNOWN(\n               new_arg[0] < new_var[random_itr.var2op(i_var)]\n            );\n            if( op == ErfOp || op == ErfcOp )\n            {  CPPAD_ASSERT_NARG_NRES(op, 3, 5);\n               // Error function is a special case\n               // second argument is always the parameter 0\n               // third argument is always the parameter 2 / sqrt(pi)\n               CPPAD_ASSERT_UNKNOWN( NumArg(ErfOp) == 3 );\n               rec->PutArg( rec->put_con_par( Base(0.0) ) );\n               rec->PutArg( rec->put_con_par(\n                  Base( 1.0 / std::sqrt( std::atan(1.0) ) )\n               ) );\n            }\n            else\n            {  // some of these operators have an auxiliary result;\n               // e.g. sine and cosine are computed together.\n               CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );\n               CPPAD_ASSERT_UNKNOWN( NumRes(op) ==1 || NumRes(op) == 2 );\n            }\n         }\n         break;\n         // ---------------------------------------------------\n         // Binary operators, left variable, right parameter, one result\n         case SubvpOp:\n         // check if this is the top of a csum connection\n         i_tmp    = random_itr.var2op(size_t(arg[0]));\n         top_csum = op_usage[i_tmp] == usage_t(csum_usage);\n         if( top_csum )\n         {  CPPAD_ASSERT_UNKNOWN( previous == 0 );\n            //\n            // convert to a sequence of summation operators\n            size_pair = record_csum(\n               play                ,\n               random_itr          ,\n               op_usage            ,\n               new_par             ,\n               new_var             ,\n               i_var               ,\n               rec                 ,\n               csum_work\n            );\n            new_op[i_op]  = addr_t( size_pair.i_op );\n            new_var[i_op] = addr_t( size_pair.i_var );\n            // abort rest of this case\n            break;\n         }\n         case DivvpOp:\n         case PowvpOp:\n         case ZmulvpOp:\n         if( previous == 0 )\n         {  //\n            size_pair = record_vp(\n               play                ,\n               random_itr          ,\n               new_par             ,\n               new_var             ,\n               i_op                ,\n               rec\n            );\n            new_op[i_op]  = addr_t( size_pair.i_op );\n            new_var[i_op] = addr_t( size_pair.i_var );\n         }\n         break;\n         // ---------------------------------------------------\n         // Binary operators, left index, right variable, one result\n         case DisOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         if( previous == 0 )\n         {  //\n            new_arg[0] = arg[0];\n            new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ];\n            rec->PutArg( new_arg[0], new_arg[1] );\n            //\n            new_op[i_op]  = addr_t( rec->num_var_op() );\n            new_var[i_op] = rec->PutOp(op);\n            CPPAD_ASSERT_UNKNOWN(\n               new_arg[1] < new_var[random_itr.var2op(i_var)]\n            );\n         }\n         break;\n\n         // ---------------------------------------------------\n         // Binary operators, left parameter, right variable, one result\n         case SubpvOp:\n         case AddpvOp:\n         // check if this is the top of a csum connection\n         i_tmp    = random_itr.var2op(size_t(arg[1]));\n         top_csum = op_usage[i_tmp] == usage_t(csum_usage);\n         if( top_csum )\n         {  CPPAD_ASSERT_UNKNOWN( previous == 0 );\n            //\n            // convert to a sequence of summation operators\n            size_pair = record_csum(\n               play                ,\n               random_itr          ,\n               op_usage            ,\n               new_par             ,\n               new_var             ,\n               i_var               ,\n               rec                 ,\n               csum_work\n            );\n            new_op[i_op]  = addr_t( size_pair.i_op );\n            new_var[i_op] = addr_t( size_pair.i_var );\n            // abort rest of this case\n            break;\n         }\n         case DivpvOp:\n         case MulpvOp:\n         case PowpvOp:\n         case ZmulpvOp:\n         if( previous == 0 )\n         {  //\n            size_pair = record_pv(\n               play                ,\n               random_itr          ,\n               new_par             ,\n               new_var             ,\n               i_op                ,\n               rec\n            );\n            new_op[i_op]  = addr_t( size_pair.i_op );\n            new_var[i_op] = addr_t( size_pair.i_var );\n         }\n         break;\n         // ---------------------------------------------------\n         // Binary operator, left and right variables, one result\n         case AddvvOp:\n         case SubvvOp:\n         // check if this is the top of a csum connection\n         i_tmp     = random_itr.var2op(size_t(arg[0]));\n         top_csum  = op_usage[i_tmp] == usage_t(csum_usage);\n         i_tmp     = random_itr.var2op(size_t(arg[1]));\n         top_csum |= op_usage[i_tmp] == usage_t(csum_usage);\n         if( top_csum )\n         {  CPPAD_ASSERT_UNKNOWN( previous == 0 );\n            //\n            // convert to a sequence of summation operators\n            size_pair = record_csum(\n               play                ,\n               random_itr          ,\n               op_usage            ,\n               new_par             ,\n               new_var             ,\n               i_var               ,\n               rec                 ,\n               csum_work\n            );\n            new_op[i_op]  = addr_t( size_pair.i_op );\n            new_var[i_op] = addr_t( size_pair.i_var );\n            // abort rest of this case\n            break;\n         }\n         case DivvvOp:\n         case MulvvOp:\n         case PowvvOp:\n         case ZmulvvOp:\n         if( previous == 0 )\n         {  //\n            size_pair = record_vv(\n               play                ,\n               random_itr          ,\n               new_var             ,\n               i_op                ,\n               rec\n            );\n            new_op[i_op]  = addr_t( size_pair.i_op );\n            new_var[i_op] = addr_t( size_pair.i_var );\n         }\n         break;\n         // ---------------------------------------------------\n         // Conditional expression operators\n         case CExpOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 6, 1);\n         new_arg[0] = arg[0];\n         new_arg[1] = arg[1];\n         mask = 1;\n         for(size_t i = 2; i < 6; i++)\n         {  if( arg[1] & mask )\n            {  new_arg[i] = new_var[ random_itr.var2op(size_t(arg[i])) ];\n               CPPAD_ASSERT_UNKNOWN(\n                  size_t(new_arg[i]) < num_var\n           );\n            }\n            else\n               new_arg[i] = new_par[ arg[i] ];\n            mask = mask << 1;\n         }\n         rec->PutArg(\n            new_arg[0] ,\n            new_arg[1] ,\n            new_arg[2] ,\n            new_arg[3] ,\n            new_arg[4] ,\n            new_arg[5]\n         );\n         new_op[i_op]  = addr_t( rec->num_var_op() );\n         new_var[i_op] = rec->PutOp(op);\n         //\n         // The new addresses for left and right are used during\n         // fill in the arguments for the CSkip operations. This does not\n         // affect max_left_right which is used during this sweep.\n         if( conditional_skip )\n         {  CPPAD_ASSERT_UNKNOWN( cexp_next < num_cexp );\n            CPPAD_ASSERT_UNKNOWN(\n               size_t( cexp_info[cexp_next].i_op ) == i_op\n            );\n            cskip_new[ cexp_next ].left  = size_t( new_arg[2] );\n            cskip_new[ cexp_next ].right = size_t( new_arg[3] );\n            ++cexp_next;\n         }\n         break;\n         // ---------------------------------------------------\n         // Operations with no arguments and no results\n         case EndOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 0, 0);\n         new_op[i_op] = addr_t( rec->num_var_op() );\n         rec->PutOp(op);\n         break;\n         // ---------------------------------------------------\n         // Comparison operations: two arguments and no results\n         //\n         case LeppOp:\n         case LtppOp:\n         case EqppOp:\n         case NeppOp:\n         CPPAD_ASSERT_UNKNOWN( compare_op );\n         CPPAD_ASSERT_NARG_NRES(op, 2, 0);\n         if( previous == 0 )\n         {  new_arg[0] = new_par[ arg[0] ];\n            new_arg[1] = new_par[ arg[1] ];\n            rec->PutArg(new_arg[0], new_arg[1]);\n            new_op[i_op] = addr_t( rec->num_var_op() );\n            rec->PutOp(op);\n         }\n         break;\n         //\n         case LepvOp:\n         case LtpvOp:\n         case EqpvOp:\n         case NepvOp:\n         CPPAD_ASSERT_UNKNOWN( compare_op );\n         CPPAD_ASSERT_NARG_NRES(op, 2, 0);\n         if( previous == 0 )\n         {  new_arg[0] = new_par[ arg[0] ];\n            new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ];\n            rec->PutArg(new_arg[0], new_arg[1]);\n            new_op[i_op] = addr_t( rec->num_var_op() );\n            rec->PutOp(op);\n         }\n         break;\n         //\n         case LevpOp:\n         case LtvpOp:\n         CPPAD_ASSERT_UNKNOWN( compare_op );\n         CPPAD_ASSERT_NARG_NRES(op, 2, 0);\n         if( previous == 0 )\n         {  new_arg[0] = new_var[ random_itr.var2op(size_t(arg[0])) ];\n            new_arg[1] = new_par[ arg[1] ];\n            rec->PutArg(new_arg[0], new_arg[1]);\n            new_op[i_op] = addr_t( rec->num_var_op() );\n            rec->PutOp(op);\n         }\n         break;\n         //\n         case LevvOp:\n         case LtvvOp:\n         case EqvvOp:\n         case NevvOp:\n         CPPAD_ASSERT_UNKNOWN( compare_op );\n         CPPAD_ASSERT_NARG_NRES(op, 2, 0);\n         if( previous == 0 )\n         {  new_arg[0] = new_var[ random_itr.var2op(size_t(arg[0])) ];\n            new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ];\n            rec->PutArg(new_arg[0], new_arg[1]);\n            new_op[i_op] = addr_t( rec->num_var_op() );\n            rec->PutOp(op);\n         }\n         break;\n\n         // ---------------------------------------------------\n         // Operations with no arguments and one result\n         case InvOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         new_op[i_op]  = addr_t( rec->num_var_op() );\n         new_var[i_op] = rec->PutOp(op);\n         break;\n\n         // ---------------------------------------------------\n         // Unary operators, argument a parameter, one result\n         case ParOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1);\n         new_arg[0] = new_par[ arg[0] ];\n         rec->PutArg( new_arg[0] );\n         //\n         new_op[i_op]  = addr_t( rec->num_var_op() );\n         new_var[i_op] = rec->PutOp(op);\n         break;\n\n         // ---------------------------------------------------\n         // print forward operator\n         case PriOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 5, 0);\n         // arg[0]\n         new_arg[0] = arg[0];\n         //\n         // arg[1]\n         if( arg[0] & 1 )\n         {  new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ];\n            CPPAD_ASSERT_UNKNOWN( size_t(new_arg[1]) < num_var );\n         }\n         else\n         {  new_arg[1] = new_par[ arg[1] ];\n         }\n         //\n         // arg[3]\n         if( arg[0] & 2 )\n         {  new_arg[3] = new_var[ random_itr.var2op(size_t(arg[3])) ];\n            CPPAD_ASSERT_UNKNOWN( size_t(new_arg[3]) < num_var );\n         }\n         else\n         {  new_arg[3] = new_par[ arg[3] ];\n         }\n         new_arg[2] = rec->PutTxt( play->GetTxt(size_t(arg[2])) );\n         new_arg[4] = rec->PutTxt( play->GetTxt(size_t(arg[4])) );\n         //\n         rec->PutArg(\n            new_arg[0] ,\n            new_arg[1] ,\n            new_arg[2] ,\n            new_arg[3] ,\n            new_arg[4]\n         );\n         // new operator\n         new_op[i_op]  = addr_t( rec->num_var_op() );\n         // no new variable\n         rec->PutOp(op);\n         break;\n\n         // ---------------------------------------------------\n         // VecAD operators\n\n         // Load using a parameter index\n         case LdpOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 3, 1);\n         new_arg[0] = new_vecad_ind[ arg[0] ];\n         new_arg[1] = new_par[ arg[1] ];\n         CPPAD_ASSERT_UNKNOWN(\n            size_t( (std::numeric_limits<addr_t>::max)() ) >= rec->num_var_load()\n         );\n         new_arg[2] = addr_t( rec->num_var_load() );\n         CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < num_vecad_ind );\n         rec->PutArg(\n            new_arg[0],\n            new_arg[1],\n            new_arg[2]\n         );\n         new_op[i_op]  = addr_t( rec->num_var_op() );\n         new_var[i_op] = rec->PutLoadOp(op);\n         break;\n\n         // Load using a variable index\n         case LdvOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 3, 1);\n         new_arg[0] = new_vecad_ind[ arg[0] ];\n         new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ];\n         CPPAD_ASSERT_UNKNOWN(\n            size_t( (std::numeric_limits<addr_t>::max)() ) >= rec->num_var_load()\n         );\n         new_arg[2] = addr_t( rec->num_var_load() );\n         CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < num_vecad_ind );\n         CPPAD_ASSERT_UNKNOWN( size_t(new_arg[1]) < num_var );\n         rec->PutArg(\n            new_arg[0],\n            new_arg[1],\n            new_arg[2]\n         );\n         new_op[i_op]  = addr_t( rec->num_var_op() );\n         new_var[i_op] = rec->PutLoadOp(op);\n         break;\n\n         // Store a parameter using a parameter index\n         case StppOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 3, 0);\n         new_arg[0] = new_vecad_ind[ arg[0] ];\n         new_arg[1] = new_par[ arg[1] ];\n         new_arg[2] = new_par[ arg[2] ];\n         CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < num_vecad_ind );\n         rec->PutArg(\n            new_arg[0],\n            new_arg[1],\n            new_arg[2]\n         );\n         new_op[i_op] = addr_t( rec->num_var_op() );\n         rec->PutOp(op);\n         break;\n\n         // Store a parameter using a variable index\n         case StvpOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 3, 0);\n         new_arg[0] = new_vecad_ind[ arg[0] ];\n         new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ];\n         new_arg[2] = new_par[ arg[2] ];\n         CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < num_vecad_ind );\n         CPPAD_ASSERT_UNKNOWN( size_t(new_arg[1]) < num_var );\n         rec->PutArg(\n            new_arg[0],\n            new_arg[1],\n            new_arg[2]\n         );\n         new_op[i_op] = addr_t( rec->num_var_op() );\n         rec->PutOp(op);\n         break;\n\n         // Store a variable using a parameter index\n         case StpvOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 3, 0);\n         new_arg[0] = new_vecad_ind[ arg[0] ];\n         new_arg[1] = new_par[ arg[1] ];\n         new_arg[2] = new_var[ random_itr.var2op(size_t(arg[2])) ];\n         CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < num_vecad_ind );\n         CPPAD_ASSERT_UNKNOWN( size_t(new_arg[2]) < num_var );\n         rec->PutArg(\n            new_arg[0],\n            new_arg[1],\n            new_arg[2]\n         );\n         new_op[i_op] = addr_t( rec->num_var_op() );\n         rec->PutOp(op);\n         break;\n\n         // Store a variable using a variable index\n         case StvvOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 3, 0);\n         new_arg[0] = new_vecad_ind[ arg[0] ];\n         new_arg[1] = new_var[ random_itr.var2op(size_t(arg[1])) ];\n         new_arg[2] = new_var[ random_itr.var2op(size_t(arg[2])) ];\n         CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < num_vecad_ind );\n         CPPAD_ASSERT_UNKNOWN( size_t(new_arg[1]) < num_var );\n         CPPAD_ASSERT_UNKNOWN( size_t(new_arg[2]) < num_var );\n         rec->PutArg(\n            new_arg[0],\n            new_arg[1],\n            new_arg[2]\n         );\n         new_op[i_op] = addr_t( rec->num_var_op() );\n         rec->PutOp(op);\n         break;\n\n         // -----------------------------------------------------------\n         // atomic function call operators\n\n         case AFunOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 4, 0);\n         // atom_index, atom_old, atom_n, atom_m\n         rec->PutArg(arg[0], arg[1], arg[2], arg[3]);\n         new_op[i_op] = addr_t( rec->num_var_op() );\n         rec->PutOp(AFunOp);\n         if( atom_state == start_atom )\n         {  atom_state = arg_atom;\n            atom_j     = size_t( arg[2] ); // just for counting arguments\n            atom_i     = size_t( arg[3] ); // just for counting results\n            CPPAD_ASSERT_UNKNOWN( atom_j > 0 );\n            CPPAD_ASSERT_UNKNOWN( atom_i > 0 );\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( atom_state == end_atom );\n            atom_state = start_atom;\n         }\n         break;\n\n         case FunapOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 1, 0);\n         new_arg[0] = new_par[ arg[0] ];\n         if( new_arg[0] == addr_t_max )\n         {  // This parameter is not used, so we put zero here. If we\n            // put nan here, atomic reverse mode would have to use azmul.\n            new_arg[0] = zero_par_index;\n         }\n         rec->PutArg(new_arg[0]);\n         new_op[i_op] = addr_t( rec->num_var_op() );\n         rec->PutOp(FunapOp);\n         CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom );\n         --atom_j;\n         if( atom_j == 0 )\n            atom_state = ret_atom;\n         break;\n\n         case FunavOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 1, 0);\n         new_arg[0] = new_var[ random_itr.var2op(size_t(arg[0])) ];\n         CPPAD_ASSERT_UNKNOWN( size_t(new_arg[0]) < num_var );\n         if( new_arg[0] != 0 )\n         {  rec->PutArg(new_arg[0]);\n            new_op[i_op] = addr_t( rec->num_var_op() );\n            rec->PutOp(FunavOp);\n         }\n         else\n         {  // This argument does not affect the result.\n            new_arg[0] = zero_par_index;\n            rec->PutArg(new_arg[0]);\n            new_op[i_op] = addr_t( rec->num_var_op() );\n            rec->PutOp(FunapOp);\n         }\n         CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom );\n         --atom_j;\n         if( atom_j == 0 )\n            atom_state = ret_atom;\n         break;\n\n         case FunrpOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 1, 0);\n         new_arg[0] = new_par[ arg[0] ];\n         if( new_arg[0] == addr_t_max )\n         {  // This parameter is not used here or anywhere.\n            CPPAD_ASSERT_UNKNOWN( op_usage[i_op] == usage_t(no_usage) );\n            new_arg[0] = zero_par_index;\n         }\n         rec->PutArg(new_arg[0]);\n         //\n         new_op[i_op] = addr_t( rec->num_var_op() );\n         rec->PutOp(FunrpOp);\n         CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom );\n         --atom_i;\n         if( atom_i == 0 )\n            atom_state = end_atom;\n         break;\n\n         case FunrvOp:\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         new_op[i_op]  = addr_t( rec->num_var_op() );\n         if( op_usage[i_op] == usage_t(yes_usage) )\n            new_var[i_op] = rec->PutOp(FunrvOp);\n         else\n         {  // This result is not used.\n            CPPAD_ASSERT_UNKNOWN( op_usage[i_op] == usage_t(no_usage) );\n            CPPAD_ASSERT_NARG_NRES(FunrpOp, 1, 0);\n            rec->PutArg( zero_par_index );\n            rec->PutOp(FunrpOp);\n         }\n\n         --atom_i;\n         if( atom_i == 0 )\n            atom_state = end_atom;\n         break;\n         // ---------------------------------------------------\n         case CSumOp:\n         // ---------------------------------------------------\n         CPPAD_ASSERT_UNKNOWN( previous == 0 );\n         //\n         // check if more entries can be included in this summation\n         size_pair = record_csum(\n            play                ,\n            random_itr          ,\n            op_usage            ,\n            new_par             ,\n            new_var             ,\n            i_var               ,\n            rec                 ,\n            csum_work\n         );\n         new_op[i_op]  = addr_t( size_pair.i_op );\n         new_var[i_op] = addr_t( size_pair.i_var );\n         break;\n         // ---------------------------------------------------\n\n         // all cases should be handled above\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n      }\n   }\n   // modify the dependent variable vector to new indices\n   for(size_t i = 0; i < dep_taddr.size(); i++ )\n   {  dep_taddr[i] = size_t(new_var[ random_itr.var2op(dep_taddr[i]) ]);\n      CPPAD_ASSERT_UNKNOWN( size_t(dep_taddr[i]) < num_var );\n   }\n\n# ifndef NDEBUG\n   for(i_op = 0; i_op < num_op; i_op++)\n   {  random_itr.op_info(i_op, op, arg, i_var);\n      if( NumRes(op) > 0 )\n         CPPAD_ASSERT_UNKNOWN(\n            size_t(new_op[i_op]) < rec->num_var_op()\n         );\n   }\n# endif\n   // make sure that all the conditional expressions have been\n   // checked to see if they are still present\n   CPPAD_ASSERT_UNKNOWN( cskip_order_next == num_cexp );\n   // fill in the arguments for the CSkip operations\n   for(size_t i = 0; i < num_cexp; i++)\n   {  // if cskip_new[i].i_arg == 0, this conditional expression was skipped\n      if( cskip_new[i].i_arg > 0 )\n      {  // size_t i_arg\n         struct_cexp_info info = cexp_info[i];\n         addr_t n_true  = addr_t( skip_op_true.number_elements(i) );\n         addr_t n_false = addr_t( skip_op_false.number_elements(i) );\n         i_arg          = cskip_new[i].i_arg;\n         addr_t left    = addr_t( cskip_new[i].left );\n         addr_t right   = addr_t( cskip_new[i].right );\n         rec->ReplaceArg(i_arg++, addr_t(info.cop)   );\n         rec->ReplaceArg(i_arg++, addr_t(info.flag)  );\n         rec->ReplaceArg(i_arg++, left  );\n         rec->ReplaceArg(i_arg++, right );\n         rec->ReplaceArg(i_arg++, n_true     );\n         rec->ReplaceArg(i_arg++, n_false    );\n         sparse::list_setvec::const_iterator itr_true(skip_op_true, i);\n         while( *itr_true != skip_op_true.end() )\n         {  i_op = *itr_true;\n            // op_usage[i_op] == usage_t(yes_usage)\n            CPPAD_ASSERT_UNKNOWN( new_op[i_op] != 0 );\n            rec->ReplaceArg(i_arg++, new_op[i_op] );\n            //\n            ++itr_true;\n         }\n         sparse::list_setvec::const_iterator itr_false(skip_op_false, i);\n         while( *itr_false != skip_op_false.end() )\n         {  i_op   = *itr_false;\n            // op_usage[i_op] == usage_t(yes_usage)\n            CPPAD_ASSERT_UNKNOWN( new_op[i_op] != 0 );\n            rec->ReplaceArg(i_arg++, new_op[i_op] );\n            //\n            ++itr_false;\n         }\n         rec->ReplaceArg(i_arg++, 7 + n_true + n_false);\n# ifndef NDEBUG\n         size_t n_arg   = 7 + size_t(n_true) + size_t(n_false);\n         CPPAD_ASSERT_UNKNOWN( cskip_new[i].i_arg + n_arg == i_arg );\n# endif\n      }\n   }\n   return exceed_collision_limit;\n}\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/record_csum.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_RECORD_CSUM_HPP\n# define CPPAD_LOCAL_OPTIMIZE_RECORD_CSUM_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize  {\n\n/*!\n{xrst_begin optimize_record_csum dev}\n{xrst_spell\n   addpv\n   addvv\n   subpv\n   subvp\n   subvv\n}\n\nRecording a Cumulative Summation Operator\n#########################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_RECORD_CSUM\n   // END_PROTOTYPE\n}\n\nplay\n****\nplayer object corresponding to the old recording.\n\nrandom_itr\n**********\nis a random iterator corresponding to the old operation sequence.\n\nop_usage\n********\nmapping from old operator index to how it is used.\n\nnew_par\n*******\nmapping from old parameter index to parameter index in new recording.\n\nnew_var\n*******\nmapping from old operator index to variable index in new recording.\n\ncurrent\n*******\nis the index in the old operation sequence for\nthe variable corresponding to the result for the current operator.\nWe use the notation *i_op* = *random_itr* . ``var2op`` ( *current* ) .\nIt follows that  NumRes( random_itr.get_op[i_op] ) > 0.\nIf 0 < j_op < i_op, either op_usage[j_op] == usage_t(csum_usage),\nop_usage[j_op] = usage_t(no_usage), or new_var[j_op] != 0.\n\nrec\n***\nis the object that will record the new operations.\n\nreturn\n******\nis the operator and variable indices in the new operation sequence.\n\nstack\n*****\nIs temporary work space. On input and output,\nstack.op_info, stack.add_var, and stack.sub_var, are all empty.\nThese stacks are passed in so that they are created once\nand then be reused with calls to ``record_csum`` .\n\nAssumptions\n***********\n\n#. random_itr.get_op[i_op] must be one of the following:\n   CSumOp, AddpvOp, AddvvOp, SubpvOp, SubvpOp, SubvvOp.\n#. op_usage[i_op] == usage_t(yes_usage).\n#. Either this is a CSumOp, or\n   op_usage[j_op] == usage_t(csum_usage) is true from some\n   j_op that corresponds to a variable that is an argument to\n   random_itr.get_op[i_op].\n\n{xrst_end optimize_record_csum}\n*/\n\n// BEGIN_RECORD_CSUM\ntemplate <class Addr, class Base>\nstruct_size_pair record_csum(\n   const player<Base>*                                play           ,\n   const play::const_random_iterator<Addr>&           random_itr     ,\n   const pod_vector<usage_t>&                         op_usage       ,\n   const pod_vector<addr_t>&                          new_par        ,\n   const pod_vector<addr_t>&                          new_var        ,\n   size_t                                             current        ,\n   recorder<Base>*                                    rec            ,\n   // local information passed so stacks need not be allocated for every call\n   struct_csum_stacks&                                stack          )\n// END_PROTOTYPE\n{\n# ifndef NDEBUG\n   // number of parameters corresponding to the old operation sequence.\n   size_t npar = play->num_par_all();\n# endif\n\n   // vector of length npar containing the parameters the old operation\n   // sequence; i.e., given a parameter index i < npar, the corresponding\n   // parameter value is par[i].\n   const Base* par = play->par_ptr();\n\n   // which parameters are dynamic\n   const pod_vector<bool>& par_is_dyn( play->par_is_dyn() );\n\n   // check assumption about work space\n   CPPAD_ASSERT_UNKNOWN( stack.op_info.empty() );\n   CPPAD_ASSERT_UNKNOWN( stack.add_var.empty() );\n   CPPAD_ASSERT_UNKNOWN( stack.sub_var.empty() );\n   //\n   // this operator is not csum connected to some other result\n   size_t i_op = random_itr.var2op(current);\n   CPPAD_ASSERT_UNKNOWN( ! ( op_usage[i_op] == usage_t(csum_usage) ) );\n   //\n   // information corresponding to the root node in the cumulative summation\n   struct struct_csum_op_info info;\n   size_t not_used;\n   random_itr.op_info(i_op, info.op, info.arg, not_used);\n   info.add = true;  // was parent operator positive or negative\n   //\n   // initialize stack as containing this one operator\n   stack.op_info.push( info );\n   //\n   // initialize sum of parameter values as zero\n   Base sum_par(0);\n   //\n# ifndef NDEBUG\n   // one argument of this operator must have been csum connected to it\n   bool ok = info.op == CSumOp;\n   if( (! ok) && (info.op != SubpvOp) && (info.op != AddpvOp) )\n   {  // first argument is a variable being added\n      i_op = random_itr.var2op(size_t(info.arg[0]));\n      ok  |= op_usage[i_op] == usage_t(csum_usage);\n   }\n   if( (! ok) && (info.op != SubvpOp) )\n   {  // second argument is a variable being added or subtracted\n      i_op = random_itr.var2op(size_t(info.arg[1]));\n      ok  |= op_usage[i_op] == usage_t(csum_usage);\n   }\n   CPPAD_ASSERT_UNKNOWN( ok );\n# endif\n   //\n   // while there are operators left on the stack\n   while( ! stack.op_info.empty() )\n   {  // get this summation operator\n      info = stack.op_info.top();\n      stack.op_info.pop();\n      op_code_var   op      = info.op;\n      const addr_t* arg     = info.arg;\n      bool          add     = info.add;\n      CPPAD_ASSERT_UNKNOWN( NumRes(op) == 1 );\n      //\n      if( op == CSumOp )\n      {  // ---------------------------------------------------------------\n         // Begin op == CSumOp\n         //\n         // arg[0] is constant parameter that initializes the sum\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < npar );\n         CPPAD_ASSERT_UNKNOWN( ! par_is_dyn[ arg[0] ] );\n         if( add )\n            sum_par += par[arg[0]];\n         else\n            sum_par -= par[arg[0]];\n         //\n         // stack entries for addition variable\n         size_t var_start = 5;                  // start addition variables\n         size_t var_end   = size_t( arg[1] );   // end addition variables\n         bool   add_var   = add;                // addition variables\n         for(size_t j = 0; j < 2; ++j)\n         {  for(size_t i = var_start; i < var_end; ++i)\n            {  //\n               // check if the i-th argument has csum usage\n               i_op = random_itr.var2op(size_t(arg[i]));\n               if( op_usage[i_op] == usage_t(csum_usage) )\n               {  // there is no result corresponding to i-th argument\n                  CPPAD_ASSERT_UNKNOWN( size_t( new_var[i_op]) == 0 );\n\n                  // push operator corresponding to the i-th argument\n                  random_itr.op_info(i_op, info.op, info.arg, not_used);\n                  info.add = add;\n                  stack.op_info.push( info );\n               }\n               else\n               {  // there are no nodes below this one\n                  CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < current );\n                  if( add_var )\n                     stack.add_var.push(arg[i]);\n                  else\n                     stack.sub_var.push(arg[i]);\n               }\n            }\n            var_start = var_end;  // start subtraction variables\n            var_end   = size_t( arg[2] ); // end subtraction variables\n            add_var   = ! add;    // subtraction variables\n         }\n         //\n         // stack entries for addition dynamic parameters\n         size_t dyn_start = var_end;           // start addition dynamics\n         size_t dyn_end   = size_t( arg[3] );  // end addition dynamics\n         bool   dny_add   = add;               // addition dynamics\n         for(size_t j = 0; j < 2; ++j)\n         {  for(size_t i = dyn_start; i < dyn_end; ++i)\n            {  // i-th argument is a dynamic parameter\n               // (can't yet be a result, so no nodes below)\n               CPPAD_ASSERT_UNKNOWN( par_is_dyn[ arg[i] ] );\n               if( dny_add )\n                  stack.add_dyn.push(arg[i]);\n               else\n                  stack.sub_dyn.push(arg[i]);\n            }\n            dyn_start = dyn_end; // start subtraction dynamics\n            dyn_end   = size_t( arg[4] ); // end subtraction dynamics\n            dny_add   = ! add;   // subtraction dynamics\n         }\n         // End op == CSumOp\n         // ---------------------------------------------------------------\n      }\n      else\n      {  // ---------------------------------------------------------------\n         // Begin op != CSumOp\n         //\n         // is this a subtraction operator\n         bool subtract = (op==SubpvOp) || (op==SubvpOp) || (op==SubvvOp);\n         //\n         // is the i-th argument a parameter\n         CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );\n         bool par_arg[2];\n         switch(op)\n         {  case SubpvOp:\n            case AddpvOp:\n            par_arg[0] = true;\n            par_arg[1] = false;\n            break;\n            //\n            case SubvpOp:\n            par_arg[0] = false;\n            par_arg[1] = true;\n            break;\n            //\n            default:\n            par_arg[0] = false;\n            par_arg[1] = false;\n            break;\n         }\n         //\n         // loop over the arguments to this operator\n         for(size_t i = 0; i < 2; ++i)\n         {  if( subtract & (i == 1) )\n               add = ! add;\n            if( par_arg[i] )\n            {  // case where i-th argument is a parameter\n               CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < npar );\n               //\n               if( par_is_dyn[ arg[i] ] )\n               {  // i-th argument is a dynamic parameter\n                  // (can't yet be a result, so no nodes below)\n                  if( add )\n                     stack.add_dyn.push(arg[i]);\n                  else\n                     stack.sub_dyn.push(arg[i]);\n               }\n               else\n               {  // i-th argument is constant parameter\n                  if( add )\n                     sum_par += par[arg[i]];\n                  else\n                     sum_par -= par[arg[i]];\n               }\n            }\n            else\n            {    // case where i-th argument is a variable\n               //\n               // check if the i-th argument has csum usage\n               i_op = random_itr.var2op(size_t(arg[i]));\n               if( op_usage[i_op] == usage_t(csum_usage) )\n               {  // there is no result corresponding to i-th argument\n                  CPPAD_ASSERT_UNKNOWN( size_t( new_var[i_op]) == 0 );\n\n                  // push operator corresponding to the i-th argument\n                  random_itr.op_info(i_op, info.op, info.arg, not_used);\n                  info.add = add;\n                  stack.op_info.push( info );\n               }\n               else\n               {  // there are no nodes below this one\n                  CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < current );\n                  if( add )\n                     stack.add_var.push(arg[i]);\n                  else\n                     stack.sub_var.push(arg[i]);\n               }\n            }\n         }\n         // End op != CSumOp\n         // ---------------------------------------------------------------\n      }\n   }\n   // number of variables to add in this cumulative sum operator\n   size_t n_add_var = stack.add_var.size();\n\n   // number of variables to subtract in this cumulative sum operator\n   size_t n_sub_var = stack.sub_var.size();\n\n   // number of dynamics to add in this cumulative sum operator\n   size_t n_add_dyn = stack.add_dyn.size();\n\n   // number of dynamics to subtract in this cumulative sum operator\n   size_t n_sub_dyn = stack.sub_dyn.size();\n\n   // first five arguments to cumulative sum operator\n   addr_t new_arg = rec->put_con_par(sum_par);\n   rec->PutArg(new_arg);            // arg[0]: initial sum\n   size_t end   = n_add_var + 5;\n   rec->PutArg( addr_t(end) );      // arg[1]: end for add variables\n   end           += n_sub_var;\n   rec->PutArg( addr_t(end) );      // arg[2]: end for sub variables\n   end           += n_add_dyn;\n   rec->PutArg( addr_t(end) );      // arg[3]: end for add dynamics\n   end           += n_sub_dyn;\n   rec->PutArg( addr_t(end) );      // arg[4]: end for sub dynamics\n\n   // addition variable arguments\n   for(size_t i = 0; i < n_add_var; i++)\n   {  CPPAD_ASSERT_UNKNOWN( ! stack.add_var.empty() );\n      addr_t old_arg = stack.add_var.top();\n      new_arg        = new_var[ random_itr.var2op(size_t(old_arg)) ];\n      CPPAD_ASSERT_UNKNOWN( 0 < new_arg && size_t(new_arg) < current );\n      rec->PutArg(new_arg);         // arg[5+i]\n      stack.add_var.pop();\n   }\n\n   // subtraction variable arguments\n   for(size_t i = 0; i < n_sub_var; i++)\n   {  CPPAD_ASSERT_UNKNOWN( ! stack.sub_var.empty() );\n      addr_t old_arg = stack.sub_var.top();\n      new_arg        = new_var[ random_itr.var2op(size_t(old_arg)) ];\n      CPPAD_ASSERT_UNKNOWN( 0 < new_arg && size_t(new_arg) < current );\n      rec->PutArg(new_arg);      // arg[arg[1] + i]\n      stack.sub_var.pop();\n   }\n\n   // addition dynamic arguments\n   for(size_t i = 0; i < n_add_dyn; ++i)\n   {  addr_t old_arg = stack.add_dyn.top();\n      new_arg        = new_par[ old_arg ];\n      rec->PutArg(new_arg);      // arg[arg[2] + i]\n      stack.add_dyn.pop();\n   }\n\n   // subtraction dynamic arguments\n   for(size_t i = 0; i < n_sub_dyn; ++i)\n   {  addr_t old_arg = stack.sub_dyn.top();\n      new_arg        = new_par[ old_arg ];\n      rec->PutArg(new_arg);      // arg[arg[3] + i]\n      stack.sub_dyn.pop();\n   }\n\n   // number of arguments to this operator\n   rec->PutArg( addr_t(end + 1) );    // arg[4] + 1\n   //\n   // return value\n   struct_size_pair ret;\n   ret.i_op  = rec->num_var_op();\n   ret.i_var = size_t(rec->PutOp(CSumOp));\n   //\n   return ret;\n}\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/record_pv.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_RECORD_PV_HPP\n# define CPPAD_LOCAL_OPTIMIZE_RECORD_PV_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*!\n\\file record_pv.hpp\nRecord an operation of the form (parameter op variable).\n*/\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize  {\n\n/*!\nRecord an operation of the form (parameter op variable).\n\n\\param play\nplayer object corresponding to the old recroding.\n\n\\param random_itr\nrandom iterator corresponding to old recording.\n\n\\param new_par\nmapping from old parameter index to parameter index in new recording.\n\n\\param new_var\nmapping from old operator index to variable index in new recording.\n\n\\param i_op\nis the index in the old operation sequence for this operator.\nThe operator must be one of the following:\nAddpvOp, DivpvOp, MulpvOp, PowpvOp, SubpvOp, ZmulpvOp.\n\n\\param rec\nis the object that will record the new operations.\n\n\\return\nis the operator and variable indices in the new operation sequence.\n*/\ntemplate <class Addr, class Base>\nstruct_size_pair record_pv(\n   const player<Base>*                                play           ,\n   const play::const_random_iterator<Addr>&           random_itr     ,\n   const pod_vector<addr_t>&                          new_par        ,\n   const pod_vector<addr_t>&                          new_var        ,\n   size_t                                             i_op           ,\n   recorder<Base>*                                    rec            )\n{\n   // get_op_info\n   op_code_var   op;\n   const addr_t* arg;\n   size_t        i_var;\n   random_itr.op_info(i_op, op, arg, i_var);\n   //\n# ifndef NDEBUG\n   switch(op)\n   {  case AddpvOp:\n      case DivpvOp:\n      case MulpvOp:\n      case PowpvOp:\n      case SubpvOp:\n      case ZmulpvOp:\n      break;\n\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n   }\n   // number of parameters corresponding to the old operation sequence.\n   size_t npar = play->num_par_all();\n# endif\n   //\n   // vector of length npar containing the parameters the old operation\n   // sequence; i.e., given a parameter index i < npar, the corresponding\n   // parameter value is par[i].\n   //\n   CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < npar  );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_var ); // DAG condition\n   //\n   addr_t new_arg[2];\n   new_arg[0]   = new_par[ arg[0] ];\n   new_arg[1]   = new_var[ random_itr.var2op(size_t(arg[1])) ];\n   rec->PutArg( new_arg[0], new_arg[1] );\n   //\n   struct_size_pair ret;\n   ret.i_op  = rec->num_var_op();\n   ret.i_var = size_t(rec->PutOp(op));\n   CPPAD_ASSERT_UNKNOWN( 0 < new_arg[1] && size_t(new_arg[1]) < ret.i_var );\n   return ret;\n}\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/record_vp.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_RECORD_VP_HPP\n# define CPPAD_LOCAL_OPTIMIZE_RECORD_VP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*!\n\\file record_vp.hpp\nRecord an operation of the form (variable op parameter).\n*/\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize  {\n\n\n/*!\nRecord an operation of the form (variable op parameter).\n\n\\param play\nplayer object corresponding to the old recroding.\n\n\\param random_itr\nis a random iterator corresponding to the old recording.\n\n\\param new_par\nmapping from old parameter index to parameter index in new recording.\n\n\\param new_var\nmapping from old operator index to variable index in new recording.\n\n\\param i_op\nis the index in the old operation sequence for this operator.\nthe must be one of the following:\nDivvpOp, PowvpOp, SubvpOp, ZmulvpOp.\n\n\\param rec\nis the object that will record the new operations.\n\n\\return\nis the operator and variable indices in the new operation sequence.\n*/\ntemplate <class Addr, class Base>\nstruct_size_pair record_vp(\n   const player<Base>*                                play           ,\n   const play::const_random_iterator<Addr>&           random_itr     ,\n   const pod_vector<addr_t>&                          new_par        ,\n   const pod_vector<addr_t>&                          new_var        ,\n   size_t                                             i_op           ,\n   recorder<Base>*                                    rec            )\n{\n   // get_op_info\n   op_code_var   op;\n   const addr_t* arg;\n   size_t        i_var;\n   random_itr.op_info(i_op, op, arg, i_var);\n   //\n# ifndef NDEBUG\n   switch(op)\n   {  case DivvpOp:\n      case PowvpOp:\n      case SubvpOp:\n      case ZmulvpOp:\n      break;\n\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n   }\n   // number of parameters corresponding to the old operation sequence.\n   size_t npar = play->num_par_all();\n# endif\n\n   // vector of length npar containing the parameters the old operation\n   // sequence; i.e., given a parameter index i < npar, the corresponding\n   // parameter value is par[i].\n   //\n   CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_var ); // DAG condition\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < npar  );\n   //\n   addr_t new_arg[2];\n   new_arg[0]   = new_var[ random_itr.var2op(size_t(arg[0])) ];\n   new_arg[1]   = new_par[ arg[1] ];\n   rec->PutArg( new_arg[0], new_arg[1] );\n   //\n   struct_size_pair ret;\n   ret.i_op  = rec->num_var_op();\n   ret.i_var = size_t(rec->PutOp(op));\n   CPPAD_ASSERT_UNKNOWN( 0 < new_arg[0] && size_t(new_arg[0]) < ret.i_var );\n   return ret;\n}\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/record_vv.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_RECORD_VV_HPP\n# define CPPAD_LOCAL_OPTIMIZE_RECORD_VV_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*!\n\\file record_vv.hpp\nRecord an operation of the form (variable op variable).\n*/\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize  {\n/*!\nRecord an operation of the form (variable op variable).\n\n\\param play\nplayer object corresponding to the old recroding.\n\n\\param random_itr\nrandom iterator corresponding to the old recording.\n\n\\param new_var\nmapping from old operator index to variable index in new recording.\n\n\\param i_op\nis the index in the old operation sequence for this operator.\nthe must be one of the following:\nAddvvOp, DivvvOp, MulvvOp, PowvvOp, SubvvOp, ZmulvvOp.\n\n\\param rec\nis the object that will record the new operations.\n\n\\return\nis the operator and variable indices in the new operation sequence.\n*/\ntemplate <class Addr, class Base>\nstruct_size_pair record_vv(\n   const player<Base>*                                play           ,\n   const play::const_random_iterator<Addr>&           random_itr     ,\n   const pod_vector<addr_t>&                          new_var        ,\n   size_t                                             i_op           ,\n   recorder<Base>*                                    rec            )\n{\n   // get_op_info\n   op_code_var   op;\n   const addr_t* arg;\n   size_t        i_var;\n   random_itr.op_info(i_op, op, arg, i_var);\n   //\n# ifndef NDEBUG\n   switch(op)\n   {  case AddvvOp:\n      case DivvvOp:\n      case MulvvOp:\n      case PowvvOp:\n      case SubvvOp:\n      case ZmulvvOp:\n      break;\n\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n   }\n# endif\n   CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_var ); // DAG condition\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_var ); // DAG condition\n   //\n   addr_t new_arg[2];\n   new_arg[0]   = new_var[ random_itr.var2op(size_t(arg[0])) ];\n   new_arg[1]   = new_var[ random_itr.var2op(size_t(arg[1])) ];\n   rec->PutArg( new_arg[0], new_arg[1] );\n   //\n   struct_size_pair ret;\n   ret.i_op  = rec->num_var_op();\n   ret.i_var = size_t(rec->PutOp(op));\n   CPPAD_ASSERT_UNKNOWN( 0 < new_arg[0] && size_t(new_arg[0]) < ret.i_var );\n   CPPAD_ASSERT_UNKNOWN( 0 < new_arg[1] && size_t(new_arg[1]) < ret.i_var );\n   return ret;\n}\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/size_pair.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_SIZE_PAIR_HPP\n# define CPPAD_LOCAL_OPTIMIZE_SIZE_PAIR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*!\n\\file size_pair.hpp\nInformation for one variable and one operation sequence.\n*/\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize  {\n\n/*!\n\\file size_pair.hpp\nInformation for one variable in one operation sequence.\n*/\nstruct struct_size_pair {\n   size_t i_op;  /// operator index for this variable\n   size_t i_var; /// variable index for this variable\n};\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/optimize/usage.hpp",
    "content": "# ifndef CPPAD_LOCAL_OPTIMIZE_USAGE_HPP\n# define CPPAD_LOCAL_OPTIMIZE_USAGE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/define.hpp>\n\n// BEGIN_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\nnamespace CppAD { namespace local { namespace optimize {\n\ntypedef CPPAD_VEC_ENUM_TYPE usage_t;\n\nenum enum_usage {\n   /// This operator is not used.\n   no_usage,\n\n   /// This operator is used one or more times.\n   yes_usage,\n\n   /*!\n   This operator is only used once, it is a summation operator,\n   and its parent is a summation operator. Furthermore, its result is not\n   a dependent variable. Hence case it can be removed as part of a\n   cumulative summation starting at its parent or above.\n   */\n   csum_usage\n};\n\n\n} } } // END_CPPAD_LOCAL_OPTIMIZE_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/play/addr_enum.hpp",
    "content": "# ifndef CPPAD_LOCAL_PLAY_ADDR_ENUM_HPP\n# define CPPAD_LOCAL_PLAY_ADDR_ENUM_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE\nnamespace CppAD { namespace local { namespace play {\n\n/*!\n\\file addr_enum.hpp\n*/\n/// enum corresponding to type used for addressing iterators for a player\nenum addr_enum {\n   unsigned_short_enum  ,\n   addr_t_enum    ,\n   size_t_enum\n};\n\n} } } // BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/play/atom_op_info.hpp",
    "content": "# ifndef CPPAD_LOCAL_PLAY_ATOM_OP_INFO_HPP\n# define CPPAD_LOCAL_PLAY_ATOM_OP_INFO_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE\nnamespace CppAD { namespace local { namespace play {\n\n/*!\n\\file atom_op_info.hpp\n*/\n\n/*!\n\\brief\nUnpack extra information corresponding to a AFunOp\n\n\\param op [in]\nmust be a AFunOp\n\n\\param op_arg [in]\nis the arguments for this operator\n\n\\param atom_index [out]\nis the index in local::atomic_index corresponding to this atomic functions.\n\n\\param call_id  [out]\nis the call_id for this atomic function call.\n\n\\param atom_m   [out]\nis the number of results for this user atomic function.\n\n\\param atom_n   [out]\nis the number of arguments for this user atomic function.\n\n\\return\nIs a pointer to this atomic function.\n*/\n// MUSTDO: change return to void once all sweeps switch to use call_atomic.\ntemplate <class Base>\natomic_base<Base>* atom_op_info(\n   const op_code_var op         ,\n   const addr_t*    op_arg     ,\n   size_t&          atom_index ,\n   size_t&          call_id    ,\n   size_t&          atom_m     ,\n   size_t&          atom_n     )\n{  atomic_base<Base>* atom_fun;\n   //\n   CPPAD_ASSERT_UNKNOWN( op == AFunOp );\n   CPPAD_ASSERT_NARG_NRES(op, 4, 0);\n   //\n   atom_index = size_t(op_arg[0]);\n   call_id    = size_t(op_arg[1]);\n   atom_n     = size_t(op_arg[2]);\n   atom_m     = size_t(op_arg[3]);\n   CPPAD_ASSERT_UNKNOWN( atom_n > 0 );\n   //\n   bool         set_null = false;\n   size_t       type     = 0;          // set to avoid warning\n   std::string* name_ptr = nullptr;\n   void*        v_ptr    = nullptr; // set to avoid warning\n   local::atomic_index<Base>(set_null, atom_index, type, name_ptr, v_ptr);\n   if( type == 3 )\n      return nullptr;\n# ifndef NDEBUG\n   if( v_ptr == nullptr )\n   {  // atom_fun is null so cannot use atom_fun->atomic_name()\n      std::string msg = atomic_base<Base>::class_name(atom_index)\n         + \": atomic_base function has been deleted\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# endif\n   // the atomic_base object corresponding to this atomic function\n   atom_fun = reinterpret_cast< atomic_base<Base>* >( v_ptr );\n   return atom_fun;\n}\n\n} } } // END_CPPAD_LOCAL_PLAY_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/play/dyn_player.hpp",
    "content": "# ifndef CPPAD_LOCAL_PLAY_DYN_PLAYER_HPP\n# define CPPAD_LOCAL_PLAY_DYN_PLAYER_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/pod_vector.hpp>\n\n/*\n------------------------------------------------------------------------------\n{xrst_begin dyn_player dev}\n\nClass That Records a Dynamic Parameter Operation Sequence\n#########################################################\n\ndyn_play\n********\nWe use dyn_play to denote a dynamic player create with one of these\nconstructors.\n{xrst_literal ,\n   // BEGIN_CLASS , // END_CLASS\n   // BEGIN_DYN_PLAY , // END_DYN_PLAY\n}\n\n\ncheck_dynamic_dag\n*****************\nThis checks that the dynamic parameter operation sequence is an acyclic graph.\n{xrst_literal\n   // BEGIN_CHECK_DYNAMIC_DAG\n   // END_CHECK_DYNAMIC_DAG\n}\n\nAssignment\n**********\n{xrst_literal ,\n   // BEGIN_MOVE_ASSIGNMENT , // END_MOVE_ASSIGNMENT\n   // BEGIN_COPY_ASSIGNMENT , // END_COPY_ASSIGNMENT\n}\n\nswap\n****\nThis switches the contents of the two players.\n{xrst_literal\n   // BEGIN_SWAP\n   // END_SWAP\n}\n\nbase2ad\n*******\nThis returns a AD<Base> player corresponding with the same operation sequence.\n{xrst_literal\n   // BEGIN_BASE2AD\n   // END_BASE2AD\n}\n\nget_recording\n*************\nThis transfers a dynamic parameter recording to a dynamic parameter player.\n{xrst_literal\n   // BEGIN_GET_RECORDING\n   // END_GET_RECORDING\n}\n\ndyn_rec\n=======\nThe contents of *dyn_rec* are modified in an unspecified way by this operation.\n\npar_all\n*******\nThis vector holds all the parameter values (constant and dynamic parameters).\n{xrst_literal\n   // BEGIN_PAR_ALL\n   // END_PAR_ALL\n}\n\npar_is_dyn\n**********\nThis vector identifies which parameters are dynamic.\n{xrst_literal\n   // BEGIN_PAR_IS_DYN\n   // END_PAR_IS_DYN\n}\n\ndyn2par_index\n*************\nThis vector maps the dynamic parameter index to the\ncorresponding index in the vector of all the parameters.\n{xrst_literal\n   // BEGIN_DYN2PAR_INDEX\n   // END_DYN2PAR_INDEX\n}\n\npar_ptr\n*******\n{xrst_literal\n   // BEGIN_PAR_PTR\n   // END_PAR_PTR\n}\n\npar_one\n*******\n{xrst_literal\n   // BEGIN_PAR_ONE\n   // END_PAR_ONE\n}\n\npar_value\n=========\nis the value of one of the parameters.\n\npar_ptr\n=======\nis a raw pointer to all of the parameters\n\nn_dyn_independent\n*****************\nis the number of independent dynamic parameters\n{xrst_literal\n   // BEGIN_N_DYN_INDEPENDENT\n   // END_N_DYN_INDEPENDENT\n}\n\nnum_dynamic_par\n***************\nis the number of dynamic parameters\n{xrst_literal\n   // BEGIN_NUM_DYNAMIC_PAR\n   // END_NUM_DYNAMIC_PAR\n}\n\nnum_dynamic_arg\n***************\nis the length of the dynamic parameter argument vector\n{xrst_literal\n   // BEGIN_NUM_DYNAMIC_ARG\n   // END_NUM_DYNAMIC_ARG\n}\n\nsize_op_seq\n***********\nThis is a measure of how may bytes are needed to store the operation sequence.\nJust lengths (not capacities) are used for this computation.\nThis used to compute :ref:`fun_property@size_op_seq` for an ADFun object.\n{xrst_literal\n   // BEGIN_SIZE_OP_SEQ\n   // END_SIZE_OP_SEQ\n}\n\n{xrst_end dyn_player}\n*/\n\n// BEGIN_CPPAD_LOCAL_NAMESPACE\n// BEGIN_CLASS\nnamespace CppAD { namespace local {\ntemplate <class Base> class dyn_player {\n   // END_CLASS\n   //\n   // friend\n   template <class AnotherBase> friend class dyn_player;\nprivate:\n   //\n   // n_dyn_independent_\n   // Number of dynamic parameters in the recording\n   size_t n_dyn_independent_;\n   //\n   // par_all_;\n   // Vector containing all the parameters in the recording.\n   // Use pod_vector_maybe because Base may not be plain old data.\n   pod_vector_maybe<Base> par_all_;\n   //\n   // par_is_dyn_\n   // Which elements of par_all_ are dynamic parameters\n   // (same size are par_all_)\n   pod_vector<bool> par_is_dyn_;\n   //\n   // dyn2par_index_\n   // mapping from dynamic parameter index to parameter index\n   // dyn2par_index_.size() equal to number of dynamic parameters\n   // dyn2par_index_[j] < dyn2par_index_[j+1]\n   pod_vector<addr_t> dyn2par_index_;\n   //\n   // dyn_par_op_\n   // operators for just the dynamic parameters in par_all_\n       pod_vector<opcode_t> dyn_par_op_;\n   //\n   // dyn_par_arg_\n   // arguments for the dynamic parameter operators\n   pod_vector<addr_t> dyn_par_arg_;\n   //\npublic:\n   // set all scalars to zero to avoid valgraind warning when ani assignment\n   // occurs before values get set.\n   // BEGIN_DYN_PLAY\n   // dyn_player<Base> dyn_play\n   // dyn_player<Base> dyn_play(play)\n   dyn_player(void)\n   : n_dyn_independent_(0)\n   { }\n   dyn_player(dyn_player& dyn_play)\n   {  swap(dyn_play);  }\n   // END_DYN_PLAY\n   //\n   // destructor\n   ~dyn_player(void)\n   { }\n   //\n   // check_dynamic_dag\n   // Check dynamic parameter graph to make sure arguments have value less\n   // than or equal to the previously created dynamic parameter.\n   // This is the directed acyclic graph condition (DAG).\n# ifdef NDEBUG\n   void check_dynamic_dag(void) const\n   {  return; }\n# else\n   // BEGIN_CHECK_DYNAMIC_DAG\n   void check_dynamic_dag(void) const\n   // END_CHECK_DYNAMIC_DAG\n   {  // number of dynamic parameters\n      size_t num_dyn = dyn_par_op_.size();\n      //\n      size_t i_arg = 0; // initialize dynamic parameter argument index\n      for(size_t i_dyn = 0; i_dyn < num_dyn; ++i_dyn)\n      {  // i_par is parameter index\n         addr_t i_par = dyn2par_index_[i_dyn];\n         CPPAD_ASSERT_UNKNOWN( par_is_dyn_[i_par] );\n         //\n         // operator for this dynamic parameter\n         op_code_dyn op = op_code_dyn( dyn_par_op_[i_dyn] );\n         //\n         // number of arguments for this dynamic parameter\n         size_t n_arg       = num_arg_dyn(op);\n         if( op == atom_dyn )\n         {  size_t n = size_t( dyn_par_arg_[i_arg + 2] );\n            size_t m = size_t( dyn_par_arg_[i_arg + 3] );\n            n_arg    = 6 + n + m;\n            CPPAD_ASSERT_UNKNOWN(\n               n_arg == size_t( dyn_par_arg_[i_arg + 5 + n + m] )\n            );\n            for(size_t i = 5; i < n - 1; ++i)\n               CPPAD_ASSERT_UNKNOWN( dyn_par_arg_[i_arg + i] <  i_par );\n# ifndef NDEBUG\n            for(size_t i = 5+n; i < 5+n+m; ++i)\n            {  addr_t j_par = dyn_par_arg_[i_arg + i];\n               CPPAD_ASSERT_UNKNOWN( (j_par == 0) || (j_par >= i_par) );\n            }\n# endif\n         }\n         else\n         {  size_t num_non_par = num_non_par_arg_dyn(op);\n            for(size_t i = num_non_par; i < n_arg; ++i)\n               CPPAD_ASSERT_UNKNOWN( dyn_par_arg_[i_arg + i] < i_par);\n         }\n         //\n         // next dynamic parameter\n         i_arg += n_arg;\n      }\n      return;\n   }\n# endif\n   // BEGIN_MOVE_ASSIGNMENT\n   // dyn_play_1 = dyn_play_2\n   void operator=(dyn_player&& dyn_play)\n   // END_MOVE_ASSIGNMENT\n   {  swap(dyn_play); }\n   //\n   // BEGIN_COPY_ASSIGNMENT\n   // dyn_play_1 = dyn_play_2\n   void operator=(const dyn_player& dyn_play)\n   // END_COPY_ASSIGNMENT\n   {\n      // size_t objects\n      n_dyn_independent_  = dyn_play.n_dyn_independent_;\n      //\n      // pod_vectors\n      par_is_dyn_         = dyn_play.par_is_dyn_;\n      dyn2par_index_      = dyn_play.dyn2par_index_;\n      dyn_par_op_         = dyn_play.dyn_par_op_;\n      dyn_par_arg_        = dyn_play.dyn_par_arg_;\n      //\n      // pod_maybe_vectors\n      par_all_            = dyn_play.par_all_;\n   }\n   //\n   // BEGIN_BASE2AD\n   // ad_dyn_play = dyn_play\n   dyn_player< AD<Base> > base2ad(void) const\n   // END_BASE2AD\n   {  //\n      // dyn_play\n      dyn_player< AD<Base> > dyn_play;\n      //\n      // size_t objects\n      dyn_play.n_dyn_independent_  = n_dyn_independent_;\n      //\n      // pod_vectors\n      dyn_play.par_is_dyn_         = par_is_dyn_;\n      dyn_play.dyn2par_index_      = dyn2par_index_;\n      dyn_play.dyn_par_op_         = dyn_par_op_;\n      dyn_play.dyn_par_arg_        = dyn_par_arg_;\n      //\n      // pod_maybe_vector< AD<Base> > = pod_maybe_vector<Base>\n      dyn_play.par_all_.resize( par_all_.size() );\n      for(size_t i = 0; i < par_all_.size(); ++i)\n         dyn_play.par_all_[i] = par_all_[i];\n      //\n      return dyn_play;\n   }\n   // BEGIN_SWAP\n   // dyn_play_1.swap( dyn_play_2 )\n   void swap(dyn_player& other)\n   // END_SWAP\n   {  // size_t objects\n      std::swap(n_dyn_independent_,  other.n_dyn_independent_);\n      //\n      // pod_vectors\n      par_is_dyn_.swap(         other.par_is_dyn_);\n      dyn2par_index_.swap(      other.dyn2par_index_);\n      dyn_par_op_.swap(         other.dyn_par_op_);\n      dyn_par_arg_.swap(        other.dyn_par_arg_);\n      //\n      // pod_maybe_vectors\n      par_all_.swap(    other.par_all_);\n   }\n   //\n   // BEGIN_GET_RECORDING\n   void get_recording(dyn_recorder<Base>& dyn_rec)\n   // END_GET_RECORDING\n   {  //\n# ifndef NDEBUG\n      size_t addr_t_max = size_t( std::numeric_limits<addr_t>::max() );\n      CPPAD_ASSERT_UNKNOWN( dyn_rec.par_is_dyn_.size() < addr_t_max );\n      CPPAD_ASSERT_UNKNOWN( dyn_rec.dyn_par_op_.size() < addr_t_max );\n      CPPAD_ASSERT_UNKNOWN( dyn_rec.dyn_par_arg_.size() < addr_t_max );\n      CPPAD_ASSERT_UNKNOWN( dyn_rec.par_all_.size() < addr_t_max );\n# endif\n\n      // size_t values\n      n_dyn_independent_ = dyn_rec.n_dyn_independent_;\n      //\n      // pod_vectors\n      par_is_dyn_.swap( dyn_rec.par_is_dyn_ );\n      dyn_par_op_.swap( dyn_rec.dyn_par_op_ );\n      dyn_par_arg_.swap( dyn_rec.dyn_par_arg_ );\n      //\n      // pod_maybe\n      par_all_.swap( dyn_rec.par_all_ );\n      //\n      // dyn2par_index_\n      dyn2par_index_.resize( dyn_par_op_.size() );\n      size_t i_dyn = 0;\n      for(size_t i_par = 0; i_par < par_all_.size(); ++i_par)\n      {  if( par_is_dyn_[i_par] )\n         {  dyn2par_index_[i_dyn] = addr_t( i_par );\n            ++i_dyn;\n         }\n      }\n      CPPAD_ASSERT_UNKNOWN( i_dyn == dyn2par_index_.size() );\n      //\n      // check_dynamic_dag\n      check_dynamic_dag();\n   }\n   //\n   // BEGIN_PAR_ALL\n   // par_all = dyn_play.par_all()\n   pod_vector_maybe<Base>& par_all(void)\n   // END_PAR_ALL\n   {  return par_all_; }\n   const pod_vector_maybe<Base>& par_all(void) const\n   {  return par_all_; }\n   //\n   // BEGIN_PAR_IS_DYN\n   // par_is_dyn = dyn_play.par_is_dyn()\n   const pod_vector<bool>& par_is_dyn(void) const\n   // END_PAR_IS_DYN\n   {  return par_is_dyn_; }\n   //\n   // BEGIN_DYN2PAR_INDEX\n   // dyn2par_index = dyn_play.dyn2par_index()\n   const pod_vector<addr_t>& dyn2par_index(void) const\n   // END_DYN2PAR_INDEX\n   {  return dyn2par_index_; }\n   //\n   // BEGIN_DYN_OP_ALL\n   // dyn_par_op = dyn_play.dyn_par_op()\n   const pod_vector<opcode_t>& dyn_par_op(void) const\n   // END_DYN_OP_ALL\n   {  return dyn_par_op_; }\n   //\n   // BEGIN_DYN_ARG_ALL\n   // dyn_par_arg = dyn_play.dyn_par_arg()\n   const pod_vector<addr_t>& dyn_par_arg(void) const\n   {  return dyn_par_arg_; }\n   // END_DYN_ARG_ALL\n   //\n   // BEGIN_PAR_ONE\n   // par_one = dyn_play.par_one(i)\n   Base par_one(size_t i) const\n   // END_PAR_ONE\n   {  return par_all_[i]; }\n   //\n   // BEGIN_PAR_PTR\n   // par_ptr = dyn_play.par_ptr()\n   const Base* par_ptr(void) const\n   // END_PAR_PTR\n   {  return par_all_.data(); }\n   //\n   // BEGIN_N_DYN_INDEPENDENT\n   // n_dyn_independent\n   size_t n_dyn_independent(void) const\n   // END_N_DYN_INDEPENDENT\n   {  return n_dyn_independent_; }\n   //\n   // BEGIN_NUM_DYNAMIC_PAR\n   // num_dynamic_par = dy_play.num_dynamic_par()\n   size_t num_dynamic_par(void) const\n   // END_NUM_DYNAMIC_PAR\n   {  return dyn_par_op_.size(); }\n   //\n   // BEGIN_NUM_DYNAMIC_ARG\n   // num_dynamic_arg = dyn_play.num_dynamic_arg()\n   size_t num_dynamic_arg(void) const\n   // END_NUM_DYNAMIC_ARG\n   {  return dyn_par_arg_.size(); }\n   //\n   // BEGIN_NUM_PAR_REC\n   // num_par_all = dyn_play.rec()\n   size_t num_par_all(void) const\n   // END_NUM_PAR_REC\n   {  return par_all_.size(); }\n   //\n   // BEGIN_SIZE_OP_SEQ\n   // size_op_seq = dyn_play.size_op_seq()\n   size_t size_op_seq(void) const\n   // END_SIZE_OP_SEQ\n   {  return 0\n         + par_all_.size()       * sizeof(Base)\n         + par_is_dyn_.size()    * sizeof(bool)\n         + dyn2par_index_.size() * sizeof(addr_t)\n         + dyn_par_op_.size()    * sizeof(opcode_t)\n         + dyn_par_arg_.size()   * sizeof(addr_t)\n      ;\n   }\n};\n\n} } // END_CPPAD_lOCAL_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/play/player.hpp",
    "content": "# ifndef CPPAD_LOCAL_PLAY_PLAYER_HPP\n# define CPPAD_LOCAL_PLAY_PLAYER_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/play/addr_enum.hpp>\n# include <cppad/local/play/sequential_iterator.hpp>\n# include <cppad/local/play/subgraph_iterator.hpp>\n# include <cppad/local/play/dyn_player.hpp>\n# include <cppad/local/play/random_setup.hpp>\n# include <cppad/local/atom_state.hpp>\n# include <cppad/local/is_pod.hpp>\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*!\n\\file player.hpp\nFile used to define the player class.\n*/\n\n/*!\nClass used to store and play back an operation sequence recording.\n\n\\tparam Base\nThese were AD< Base > operations when recorded. Operations during playback\nare done using the type Base .\n*/\n\n// random_itr_info\nstruct random_itr_info_t {\n   //\n   // *_op2arg\n   // index in var_arg_ corresponding to the first argument for each operator\n   pod_vector<unsigned  short> short_op2arg;\n   pod_vector<addr_t>          addr_t_op2arg;\n   pod_vector<size_t>          size_t_op2arg;\n   /*\n   *_op2var\n   Index of the result variable for each operator. If the operator has\n   no results, this is not defined. The invalid index num_var_ is used\n   when NDEBUG is not defined. If the operator has more than one result, this\n   is the primary result; i.e., the last result. Auxiliary results are only\n   used by the current operator and not used by other operators.\n   */\n   pod_vector<unsigned  short> short_op2var;\n   pod_vector<addr_t>          addr_t_op2var;\n   pod_vector<size_t>          size_t_op2var;\n   /*\n   *_var2op\n   Mapping from primary variable index to corresponding operator index.\n   This is used to traverse sub-graphs of the operation sequence.\n   This value is valid (invalid) for primary (auxiliary) variables.\n   */\n   pod_vector<unsigned  short> short_var2op;\n   pod_vector<addr_t>          addr_t_var2op;\n   pod_vector<size_t>          size_t_var2op;\n   //\n   // swap\n   void swap( random_itr_info_t& other )\n   {  //\n      short_op2arg.swap( other.short_op2arg );\n      short_op2var.swap( other.short_op2var );\n      short_var2op.swap( other.short_var2op );\n      //\n      addr_t_op2arg.swap( other.addr_t_op2arg );\n      addr_t_op2var.swap( other.addr_t_op2var );\n      addr_t_var2op.swap( other.addr_t_var2op );\n      //\n      size_t_op2arg.swap( other.size_t_op2arg );\n      size_t_op2var.swap( other.size_t_op2var );\n      size_t_var2op.swap( other.size_t_var2op );\n   }\n   //\n   // clear\n   void clear(void)\n   {  //\n      short_op2arg.clear();\n      short_op2var.clear();\n      short_var2op.clear();\n      //\n      addr_t_op2arg.clear();\n      addr_t_op2var.clear();\n      addr_t_var2op.clear();\n      //\n      size_t_op2arg.clear();\n      size_t_op2var.clear();\n      size_t_var2op.clear();\n   }\n   //\n   // size\n   size_t size(void) const\n   {  //\n      CPPAD_ASSERT_UNKNOWN( short_op2arg.size()  == short_op2var.size() );\n      CPPAD_ASSERT_UNKNOWN( addr_t_op2arg.size() == addr_t_op2var.size() );\n      CPPAD_ASSERT_UNKNOWN( size_t_op2arg.size() == size_t_op2var.size() );\n      //\n      size_t short_num_arg  = short_op2arg.size();\n      size_t int_num_arg    = addr_t_op2arg.size();\n      size_t size_t_num_arg = size_t_op2arg.size();\n      //\n      size_t short_num_var  = short_var2op.size();\n      size_t int_num_var= addr_t_var2op.size();\n      size_t size_t_num_var = size_t_var2op.size();\n      //\n      // result\n      size_t result = 0;\n      //\n      // result\n      if( short_num_arg != 0 )\n      {  CPPAD_ASSERT_UNKNOWN( int_num_arg    == 0 );\n         CPPAD_ASSERT_UNKNOWN( size_t_num_arg == 0 );\n         //\n         result = 2 * short_num_arg + short_num_var;\n      }\n      else\n         CPPAD_ASSERT_UNKNOWN( short_num_var == 0 );\n      //\n      // result\n      if( int_num_arg != 0 )\n      {  CPPAD_ASSERT_UNKNOWN( short_num_arg  == 0 );\n         CPPAD_ASSERT_UNKNOWN( size_t_num_arg == 0 );\n         //\n         result = 2 * int_num_arg + int_num_var;\n      }\n      else\n         CPPAD_ASSERT_UNKNOWN( int_num_var == 0 );\n      //\n      // result\n      if( size_t_num_arg != 0 )\n      {  CPPAD_ASSERT_UNKNOWN( short_num_arg  == 0 );\n         CPPAD_ASSERT_UNKNOWN( int_num_arg    == 0 );\n         //\n         result = 2 * size_t_num_arg + size_t_num_var;\n      }\n      else\n         CPPAD_ASSERT_UNKNOWN( size_t_num_var == 0 );\n      //\n      return result;\n   }\n};\n\ntemplate <class Base>\nclass player {\n   //\n   // friend\n   // player<Base> must be a friend of player< AD<Base> > for base2ad to work\n   template <class AnotherBase> friend class player;\nprivate:\n   // ----------------------------------------------------------------------\n   //\n   // dyn_play_\n   dyn_player<Base> dyn_play_;\n   //\n   // num_var_\n       // Number of variables in the recording.\n   size_t num_var_;\n\n   // num_var_load_\n       // number of vecad load operations in the reconding\n   size_t num_var_load_;\n\n   // num_var_vecad_\n       // Number of VecAD vectors in the recording\n   size_t num_var_vecad_;\n\n   // var_op_\n   // The operators in the recording.\n   pod_vector<opcode_t> var_op_;\n\n   // var_arg_\n   // The operation argument indices in the recording\n   pod_vector<addr_t> var_arg_;\n\n   // var_text_\n   // Character strings ('\\\\0' terminated) in the recording.\n   pod_vector<char> var_text_;\n\n   // var_vecad_ind_\n       // The VecAD indices in the recording.\n   pod_vector<addr_t> var_vecad_ind_;\n   //\n   // random_itr_info_\n   // Information needed to use member functions that begin with random_\n   // and for using const_subgraph_iterator.\n   random_itr_info_t random_itr_info_;\n   //\npublic:\n   //\n   /// default constructor\n   // set all scalars to zero to avoid valgraind warning when ani assignment\n   // occurs before values get set.\n   player(void)\n   : num_var_(0)\n   , num_var_load_(0)\n   , num_var_vecad_(0)\n   { }\n   //\n   // move semantics constructor\n   // (none of the default constructor values matter to the destructor)\n   player(player& play)\n   {  swap(play);  }\n   //\n   // destructor\n   ~player(void)\n   { }\n   //\n   // address_type\n   // type used for addressing iterators for this player\n   play::addr_enum address_type(void) const\n   {\n      // required\n      size_t required = 0;\n      required = std::max(required, num_var_       );  // number variables\n      required = std::max(required, var_op_.size()  ); // number operators\n      required = std::max(required, var_arg_.size() ); // number arguments\n      //\n      // unsigned short\n      if( required <= std::numeric_limits<unsigned short>::max() )\n         return play::unsigned_short_enum;\n      //\n      // addr_t\n      if( required <= std::numeric_limits<addr_t>::max() )\n         return play::addr_t_enum;\n      //\n      // unsigned size_t\n      CPPAD_ASSERT_UNKNOWN(\n         required <= std::numeric_limits<size_t>::max()\n      );\n      return play::size_t_enum;\n   }\n   //\n   // get_recording\n   /*!\n   Moving an operation sequence from a recorder to this player\n\n   \\param rec\n   the object that was used to record the operation sequence. After this\n   operation, the state of the recording is no longer defined. For example,\n   the pod_vector member variables in this have been swapped with rec.\n\n   \\param n_ind\n   the number of independent variables (only used for error checking\n   when NDEBUG is not defined).\n\n   \\par\n   Use an assert to check that the length of the following vectors is\n   less than the maximum possible value for addr_t; i.e., that an index\n   in these vectors can be represented using the type addr_t:\n   var_op_, var_vecad_ind_, var_arg_, test_vec_, par_all_, var_text_,\n   dyn_par_arg_.\n   */\n   void get_recording(recorder<Base>& rec, size_t n_ind)\n   {\n# ifndef NDEBUG\n      size_t addr_t_max = size_t( std::numeric_limits<addr_t>::max() );\n# endif\n      //\n      // dyn_play_\n      dyn_play_.get_recording( rec.dyn_record_ );\n\n      // size_t values\n      num_var_            = rec.num_var_;\n      num_var_load_       = rec.num_var_load_;\n\n      // var_op_\n      var_op_.swap(rec.var_op_);\n      CPPAD_ASSERT_UNKNOWN(var_op_.size() < addr_t_max );\n\n      // var_arg_\n      var_arg_.swap(rec.var_arg_);\n      CPPAD_ASSERT_UNKNOWN(var_arg_.size()    < addr_t_max );\n\n      // var_text_\n      var_text_.swap(rec.var_text_);\n      CPPAD_ASSERT_UNKNOWN(var_text_.size() < addr_t_max );\n\n      // var_vecad_ind_\n          var_vecad_ind_.swap(rec.var_vecad_ind_);\n      CPPAD_ASSERT_UNKNOWN(var_vecad_ind_.size() < addr_t_max );\n\n      // num_var_vecad_\n          num_var_vecad_ = 0;\n      {  // var_vecad_ind_ contains size of each VecAD followed by\n         // the parameter indices used to initialize it.\n         size_t i = 0;\n         while( i < var_vecad_ind_.size() )\n         {  num_var_vecad_++;\n            i += size_t( var_vecad_ind_[i] ) + 1;\n         }\n         CPPAD_ASSERT_UNKNOWN( i == var_vecad_ind_.size() );\n      }\n\n      // random access information\n      clear_random();\n\n      // some checks\n      check_inv_op(n_ind);\n      check_variable_dag();\n   }\n   //\n   // check_inv_op\n# ifdef NDEBUG\n   void check_inv_op(size_t n_ind) const\n   {  return; }\n# else\n   void check_inv_op(size_t n_ind) const\n   {  play::const_sequential_iterator itr = begin();\n      op_code_var   op;\n      const addr_t* op_arg;\n      size_t        var_index;\n      itr.op_info(op, op_arg, var_index);\n      CPPAD_ASSERT_UNKNOWN( op == BeginOp );\n      size_t i_op = 0;\n      while( op != EndOp )\n      {  // start at second operator\n         (++itr).op_info(op, op_arg, var_index);\n         ++i_op;\n         CPPAD_ASSERT_UNKNOWN( (op == InvOp) == (i_op <= n_ind) );\n      }\n      return;\n   }\n# endif\n   //\n   // check_variable_dag\n# ifdef NDEBUG\n   void check_variable_dag(void) const\n   {  return; }\n# else\n   void check_variable_dag(void) const\n   {  play::const_sequential_iterator itr = begin();\n      op_code_var   op;\n      const addr_t* op_arg;\n      size_t        var_index;\n      itr.op_info(op, op_arg, var_index);\n      CPPAD_ASSERT_UNKNOWN( op == BeginOp );\n      //\n      addr_t arg_var_bound = 0;\n      while( op != EndOp )\n      {  (++itr).op_info(op, op_arg, var_index);\n         switch(op)\n         {\n            // cases where nothing to do\n            case BeginOp:\n            case EndOp:\n            case EqppOp:\n            case InvOp:\n            case LdpOp:\n            case LeppOp:\n            case LtppOp:\n            case NeppOp:\n            case ParOp:\n            case AFunOp:\n            case FunapOp:\n            case FunrpOp:\n            case FunrvOp:\n            case StppOp:\n            break;\n\n            // only first argument is a variable\n            case AbsOp:\n            case AcosOp:\n            case AcoshOp:\n            case AsinOp:\n            case AsinhOp:\n            case AtanOp:\n            case AtanhOp:\n            case CosOp:\n            case CoshOp:\n            case DivvpOp:\n            case ErfOp:\n            case ErfcOp:\n            case ExpOp:\n            case Expm1Op:\n            case LevpOp:\n            case LogOp:\n            case Log1pOp:\n            case LtvpOp:\n            case NegOp:\n            case PowvpOp:\n            case SignOp:\n            case SinOp:\n            case SinhOp:\n            case SqrtOp:\n            case SubvpOp:\n            case TanOp:\n            case TanhOp:\n            case FunavOp:\n            case ZmulvpOp:\n            CPPAD_ASSERT_UNKNOWN(op_arg[0] <= arg_var_bound );\n            break;\n\n            // only second argument is a variable\n            case AddpvOp:\n            case DisOp:\n            case DivpvOp:\n            case EqpvOp:\n            case LdvOp:\n            case LepvOp:\n            case LtpvOp:\n            case MulpvOp:\n            case NepvOp:\n            case PowpvOp:\n            case StvpOp:\n            case SubpvOp:\n            case ZmulpvOp:\n            CPPAD_ASSERT_UNKNOWN(op_arg[1] <= arg_var_bound );\n            break;\n\n            // only first and second arguments are variables\n            case AddvvOp:\n            case DivvvOp:\n            case EqvvOp:\n            case LevvOp:\n            case LtvvOp:\n            case MulvvOp:\n            case NevvOp:\n            case PowvvOp:\n            case SubvvOp:\n            case ZmulvvOp:\n            CPPAD_ASSERT_UNKNOWN(op_arg[0] <= arg_var_bound );\n            CPPAD_ASSERT_UNKNOWN(op_arg[1] <= arg_var_bound );\n            break;\n\n            // StpvOp\n            case StpvOp:\n            CPPAD_ASSERT_UNKNOWN(op_arg[2] <= arg_var_bound );\n            break;\n\n            // StvvOp\n            case StvvOp:\n            CPPAD_ASSERT_UNKNOWN(op_arg[1] <= arg_var_bound );\n            CPPAD_ASSERT_UNKNOWN(op_arg[2] <= arg_var_bound );\n            break;\n\n            // CSumOp\n            case CSumOp:\n            {  CPPAD_ASSERT_UNKNOWN( 5 < op_arg[2] );\n               for(addr_t j = 5; j < op_arg[2]; j++)\n                  CPPAD_ASSERT_UNKNOWN(op_arg[j] <= arg_var_bound);\n            }\n            itr.correct_before_increment();\n            break;\n\n            // CExpOp\n            case CExpOp:\n            if( op_arg[1] & 1 )\n               CPPAD_ASSERT_UNKNOWN( op_arg[2] <= arg_var_bound);\n            if( op_arg[1] & 2 )\n               CPPAD_ASSERT_UNKNOWN( op_arg[3] <= arg_var_bound);\n            if( op_arg[1] & 4 )\n               CPPAD_ASSERT_UNKNOWN( op_arg[4] <= arg_var_bound);\n            if( op_arg[1] & 8 )\n               CPPAD_ASSERT_UNKNOWN( op_arg[5] <= arg_var_bound);\n            break;\n\n            // PriOp\n            case PriOp:\n            if( op_arg[0] & 1 )\n               CPPAD_ASSERT_UNKNOWN( op_arg[1] <= arg_var_bound);\n            if( op_arg[0] & 2 )\n               CPPAD_ASSERT_UNKNOWN( op_arg[3] <= arg_var_bound);\n            break;\n\n            // CSkipOp\n            case CSkipOp:\n            if( op_arg[1] & 1 )\n               CPPAD_ASSERT_UNKNOWN( op_arg[2] <= arg_var_bound);\n            if( op_arg[1] & 2 )\n               CPPAD_ASSERT_UNKNOWN( op_arg[3] <= arg_var_bound);\n            itr.correct_before_increment();\n            break;\n\n            default:\n            CPPAD_ASSERT_UNKNOWN(false);\n            break;\n\n\n         }\n         if( NumRes(op) > 0 )\n         {  if( var_index > 0 )\n            {  CPPAD_ASSERT_UNKNOWN(size_t(arg_var_bound) < var_index);\n            }\n            else\n            {  CPPAD_ASSERT_UNKNOWN(size_t(arg_var_bound) == var_index);\n            }\n            //\n            arg_var_bound = addr_t(var_index);\n         }\n      }\n      return;\n   }\n# endif\n   //\n   // operator=\n   // move semantics assignment\n   void operator=(player&& play)\n   {  swap(play); }\n   //\n   // operator=\n   void operator=(const player& play)\n   {\n      //\n      // dyn_play_\n      dyn_play_           = play.dyn_play_;\n      //\n      // size_t objects\n      num_var_            = play.num_var_;\n          num_var_load_       = play.num_var_load_;\n          num_var_vecad_      = play.num_var_vecad_;\n          //\n      // pod_vectors\n      var_op_             = play.var_op_;\n      var_arg_            = play.var_arg_;\n      var_text_           = play.var_text_;\n      var_vecad_ind_      = play.var_vecad_ind_;\n      //\n      // random_itr_info_\n      random_itr_info_    = play.random_itr_info_;\n   }\n   //\n   // base2ad\n   // Create a player< AD<Base> > from this player<Base>\n   player< AD<Base> > base2ad(void) const\n   {  player< AD<Base> > play;\n      //\n      // dyn_play_\n      play.dyn_play_            = dyn_play_.base2ad();\n      //\n      // size_t objects\n      play.num_var_            = num_var_;\n          play.num_var_load_       = num_var_load_;\n          play.num_var_vecad_      = num_var_vecad_;\n          //\n      // pod_vectors\n      play.var_op_             = var_op_;\n      play.var_arg_            = var_arg_;\n      play.var_text_           = var_text_;\n      play.var_vecad_ind_      = var_vecad_ind_;\n      //\n      // random_itr_info_\n      play.random_itr_info_    = random_itr_info_;\n      //\n      return play;\n   }\n   //\n   // swap\n   /// used for move semantics version of ADFun assignment operation\n   void swap(player& other)\n   {  //\n      // dyn_play_\n      dyn_play_.swap( other.dyn_play_ );\n      //\n      // size_t objects\n      std::swap(num_var_,            other.num_var_);\n      std::swap(num_var_load_,       other.num_var_load_);\n      std::swap(num_var_vecad_,      other.num_var_vecad_);\n      //\n      // pod_vectors\n      var_op_.swap(             other.var_op_);\n      var_arg_.swap(            other.var_arg_);\n      var_text_.swap(           other.var_text_);\n      var_vecad_ind_.swap(  other.var_vecad_ind_);\n      //\n      // random_itr_info_\n      random_itr_info_.swap(    other.random_itr_info_);\n   }\n   //\n   // setup_random\n   /// Enable use of const_subgraph_iterator and member functions that begin\n   // with random_(no work if already setup).\n   void setup_random(unsigned short& not_used)\n   {  play::random_setup(\n         num_var_                            ,\n         var_op_                             ,\n         var_arg_                            ,\n         &random_itr_info_.short_op2arg      ,\n         &random_itr_info_.short_op2var      ,\n         &random_itr_info_.short_var2op\n      );\n   }\n   void setup_random(addr_t& not_used)\n   {  play::random_setup(\n         num_var_                            ,\n         var_op_                             ,\n         var_arg_                            ,\n         &random_itr_info_.addr_t_op2arg     ,\n         &random_itr_info_.addr_t_op2var     ,\n         &random_itr_info_.addr_t_var2op\n      );\n   }\n# if ! CPPAD_IS_SAME_TAPE_ADDR_TYPE_SIZE_T\n   void setup_random(size_t& not_used)\n   {  play::random_setup(\n         num_var_                            ,\n         var_op_                             ,\n         var_arg_                            ,\n         &random_itr_info_.size_t_op2arg     ,\n         &random_itr_info_.size_t_op2var     ,\n         &random_itr_info_.size_t_var2op\n      );\n   }\n# endif\n   //\n   // clear_\n   /// Free memory used for functions that begin with random_\n   /// and random iterators and subgraph iterators\n   void clear_random(void)\n   {  random_itr_info_.clear();\n      CPPAD_ASSERT_UNKNOWN( random_itr_info_.size() == 0  );\n   }\n   //\n   // par_all\n       pod_vector_maybe<Base>& par_all(void)\n   {  return dyn_play_.par_all(); }\n   const pod_vector_maybe<Base>& par_all(void) const\n   {  return dyn_play_.par_all(); }\n   //\n   // par_is_dyn\n   const pod_vector<bool>& par_is_dyn(void) const\n   {  return dyn_play_.par_is_dyn(); }\n   //\n   // dyn2par_index\n   const pod_vector<addr_t>& dyn2par_index(void) const\n   {  return dyn_play_.dyn2par_index(); }\n   //\n   // dyn_par_op\n   const pod_vector<opcode_t>& dyn_par_op(void) const\n   {  return dyn_play_.dyn_par_op(); }\n   //\n   // dyn_par_arg\n   const pod_vector<addr_t>& dyn_par_arg(void) const\n   {  return dyn_play_.dyn_par_arg(); }\n   //\n   // GetOp\n   /*!\n   \\brief\n   fetch an operator from the recording.\n\n   \\return\n   the i-th operator in the recording.\n\n   \\param i\n   the index of the operator in recording\n   */\n   op_code_var GetOp (size_t i) const\n   {  return op_code_var(var_op_[i]); }\n   //\n   // GetVecInd\n   /*!\n   \\brief\n   Fetch a VecAD index from the recording.\n\n   \\return\n   the i-th VecAD index in the recording.\n\n   \\param i\n   the index of the VecAD index in recording\n   */\n   size_t GetVecInd (size_t i) const\n   {  return size_t( var_vecad_ind_[i] ); }\n   //\n   // par_one\n   Base par_one(size_t i) const\n   {  return dyn_play_.par_one(i);  }\n   //\n   // par_ptr\n   const Base* par_ptr(void) const\n   {  return dyn_play_.par_ptr(); }\n   //\n   // GetTxt\n   /*!\n   \\brief\n   Fetch a '\\\\0' terminated string from the recording.\n\n   \\return\n   the beginning of the string.\n\n   \\param i\n   the index where the string begins.\n   */\n   const char *GetTxt(size_t i) const\n   {  CPPAD_ASSERT_UNKNOWN(i < var_text_.size() );\n      return var_text_.data() + i;\n   }\n   //\n   // n_dyn_independent\n   size_t n_dyn_independent(void) const\n   {  return dyn_play_.n_dyn_independent(); }\n   //\n   // num_dynamic_par\n   size_t num_dynamic_par(void) const\n   {  return dyn_play_.num_dynamic_par(); }\n   //\n   // num_dynamic_arg\n   size_t num_dynamic_arg(void) const\n   {  return dyn_play_.num_dynamic_arg(); }\n   //\n   // num_var\n   size_t num_var(void) const\n   {  return num_var_; }\n   //\n   // num_var_load\n   size_t num_var_load(void) const\n   {  return num_var_load_; }\n   //\n   // num_var_op\n   size_t num_var_op(void) const\n   {  return var_op_.size(); }\n   //\n   // num_var_vecad_ind\n   size_t num_var_vec_ind(void) const\n   {  return var_vecad_ind_.size(); }\n   //\n   // num_var_vecad\n   size_t num_var_vecad(void) const\n   {  return num_var_vecad_; }\n   //\n   // num_var_arg\n   size_t num_var_arg(void) const\n   {  return var_arg_.size(); }\n   //\n   // num_par_all\n   size_t num_par_all(void) const\n   {  return dyn_play_.num_par_all(); }\n   //\n   // num_var_text\n   size_t num_var_text(void) const\n   {  return var_text_.size(); }\n   //\n   // size_op_seq\n   // A measure of amount of memory used to store\n   // the operation sequence, just lengths, not capacities.\n   // In user api as f.size_op_seq(); see the file fun_property.omh.\n   size_t size_op_seq(void) const\n   {  return 0\n         + dyn_play_.size_op_seq()\n         + var_op_.size()            * sizeof(opcode_t)\n         + var_arg_.size()           * sizeof(addr_t)\n         + var_text_.size()          * sizeof(char)\n         + var_vecad_ind_.size() * sizeof(addr_t)\n      ;\n   }\n   // size_random\n   // A measure of amount of memory used for random access routine\n   // In user api as f.size_random(); see the file fun_property.omh.\n   size_t size_random(void) const\n   {  return random_itr_info_.size(); }\n   //\n   // begin\n   /// const sequential iterator begin\n   play::const_sequential_iterator begin(void) const\n   {  size_t op_index = 0;\n      size_t num_var      = num_var_;\n          return play::const_sequential_iterator(\n         num_var, &var_op_, &var_arg_, op_index\n      );\n   }\n   //\n   // end\n   play::const_sequential_iterator end(void) const\n   {  size_t op_index = var_op_.size() - 1;\n      size_t num_var      = num_var_;\n          return play::const_sequential_iterator(\n         num_var, &var_op_, &var_arg_, op_index\n      );\n   }\n   //\n   // begin_subgraph\n   play::const_subgraph_iterator<addr_t>  begin_subgraph(\n      const play::const_random_iterator<addr_t>& random_itr ,\n      const pod_vector<addr_t>*                  subgraph   ) const\n   {  size_t subgraph_index = 0;\n      return play::const_subgraph_iterator<addr_t>(\n         random_itr,\n         subgraph,\n         subgraph_index\n      );\n   }\n   //\n   // end_subgraph\n   template <class Addr>\n   play::const_subgraph_iterator<Addr>  end_subgraph(\n      const play::const_random_iterator<Addr>&   random_itr ,\n      const pod_vector<addr_t>*                  subgraph   ) const\n   {  size_t subgraph_index = subgraph->size() - 1;\n      return play::const_subgraph_iterator<Addr>(\n         random_itr,\n         subgraph,\n         subgraph_index\n      );\n   }\n   //\n   /// const random iterator\n   play::const_random_iterator<unsigned short>\n   get_random(unsigned short& not_used) const\n   {  return play::const_random_iterator<unsigned short>(\n         var_op_                             ,\n         var_arg_                            ,\n         &random_itr_info_.short_op2arg      ,\n         &random_itr_info_.short_op2var      ,\n         &random_itr_info_.short_var2op\n      );\n   }\n   play::const_random_iterator<addr_t>\n   get_random(addr_t& not_used) const\n   {  return play::const_random_iterator<addr_t>(\n         var_op_                             ,\n         var_arg_                            ,\n         &random_itr_info_.addr_t_op2arg     ,\n         &random_itr_info_.addr_t_op2var     ,\n         &random_itr_info_.addr_t_var2op\n      );\n   }\n# if ! CPPAD_IS_SAME_TAPE_ADDR_TYPE_SIZE_T\n   play::const_random_iterator<size_t>\n   get_random(size_t& not_used)\n   {  return play::const_random_iterator<size_t>(\n         var_op_                             ,\n         var_arg_                            ,\n         &random_itr_info_.size_t_op2arg     ,\n         &random_itr_info_.size_t_op2var     ,\n         &random_itr_info_.size_t_var2op\n      );\n   }\n# endif\n};\n\n} } // END_CPPAD_lOCAL_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/play/random_iterator.hpp",
    "content": "# ifndef CPPAD_LOCAL_PLAY_RANDOM_ITERATOR_HPP\n# define CPPAD_LOCAL_PLAY_RANDOM_ITERATOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE\nnamespace CppAD { namespace local { namespace play {\n\n/*!\n\\file random_iterator.hpp\n*/\n\n/*!\nConstant random iterator for a player object.\n\n\\tparam Addr\nAn integer type capable of representing the largest value in the vectors\nvar_arg, op2arg_index, op2var_index, var2op_index.\n*/\ntemplate <class Addr>\nclass const_random_iterator {\nprivate:\n   /// vector of operators on the tape\n   const pod_vector<opcode_t>* var_op_;\n\n   /// vector of arguments for all the operators\n   /// (note that this is same type as used in recorder; i.e., addr_t)\n   const pod_vector<addr_t>* var_arg_;\n\n   /// mapping from operator index to index of first argument in var_arg_\n   const pod_vector<Addr>* op2arg_index_;\n\n   /// mapping from operator index to index of primary (last) result\n   const pod_vector<Addr>* op2var_index_;\n\n   /// mapping from primary variable index to operator index\n   /// (only specified for primary variables)\n   const pod_vector<Addr>* var2op_index_;\n\npublic:\n   /// index_t\n   typedef Addr index_t;\n   //\n   /// default constructor\n   const_random_iterator(void) :\n   var_op_(nullptr)     ,\n   var_arg_(nullptr)    ,\n   op2arg_index_(nullptr) ,\n   op2var_index_(nullptr) ,\n   var2op_index_(nullptr)\n   { }\n   /// default assignment operator\n   void operator=(const const_random_iterator& rhs)\n   {\n      var_op_          = rhs.var_op_;\n      op2arg_index_    = rhs.op2arg_index_;\n      op2var_index_    = rhs.op2var_index_;\n      var2op_index_    = rhs.var2op_index_;\n      return;\n   }\n   /*!\n   Create a random iterator\n\n   \\par var2op_index\n   This variable is not needed and can be null if the var2op member\n   function is not used.\n   */\n   const_random_iterator(\n      const pod_vector<opcode_t>&           var_op     , ///< var_op_\n      const pod_vector<addr_t>&             var_arg    , ///< var_arg_\n      const pod_vector<Addr>*               op2arg_index , ///< op2ar_vec_\n      const pod_vector<Addr>*               op2var_index , ///< op2var_index_\n      const pod_vector<Addr>*               var2op_index ) ///< var2op_index_\n   :\n   var_op_          ( &var_op    )   ,\n   var_arg_         ( &var_arg   )   ,\n   op2arg_index_    ( op2arg_index )   ,\n   op2var_index_    ( op2var_index )   ,\n   var2op_index_    ( var2op_index )\n   { }\n   /*!\n   \\brief\n   fetch the information corresponding to an operator\n\n   \\param op_index\n   index for this operator [in]\n\n   \\param op [out]\n   op code for this operator.\n\n   \\param op_arg [out]\n   pointer to the first argument to this operator.\n\n   \\param var_index [out]\n   index of the last variable (primary variable) for this operator.\n   If there is no primary variable for this operator, i_var not specified\n   and could have any value.\n   */\n   void op_info(\n      size_t         op_index   ,\n      op_code_var&   op         ,\n      const addr_t*& op_arg     ,\n      size_t&        var_index  ) const\n   {  op        = op_code_var( (*var_op_)[op_index] );\n      op_arg    = (*op2arg_index_)[op_index] + var_arg_->data();\n      var_index = size_t( (*op2var_index_)[op_index] );\n      return;\n   }\n   /*!\n   \\brief\n   map variable index to operator index.\n\n   \\param var_index\n   must be the index of a primary variable.\n\n   \\return\n   is the index of the operator corresponding to this primary variable.\n   */\n   size_t var2op(size_t var_index) const\n   {  // check that var2op_index was not null in constructor\n      CPPAD_ASSERT_UNKNOWN( var2op_index_ != nullptr );\n      //\n      // operator index\n      size_t op_index = size_t( (*var2op_index_)[var_index] );\n      //\n      // check that var_index is a primary variable index (see random_setup)\n      CPPAD_ASSERT_UNKNOWN( op_index < var_op_->size() );\n      //\n      return op_index;\n   }\n   /// get operator corresponding to operator index\n   op_code_var get_op(size_t op_index) const\n   {  return op_code_var( (*var_op_)[op_index] );\n   }\n   /// number of operators\n   size_t num_op(void) const\n   {  return var_op_->size(); }\n   //\n   /// number of variables\n   size_t num_var(void) const\n   {  return var2op_index_->size(); }\n};\n\n} } } // BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/play/random_setup.hpp",
    "content": "# ifndef CPPAD_LOCAL_PLAY_RANDOM_SETUP_HPP\n# define CPPAD_LOCAL_PLAY_RANDOM_SETUP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE\nnamespace CppAD { namespace local { namespace play {\n\n/*!\n\\file random_setup.hpp\n*/\n\n/*!\nSet up random access to a player object.\n\n\\tparam Addr\nAn integer type capable of representing the largest value in the vectors\nvar_arg, op2arg_index, op2var_index, var2op_index.\n\n\\param num_var\nnum_var is the number of variables in this operation sequence.\n\n\\param var_op\nThe mapping\n<code>op = op_code_var[ var_op[op_index] ]</code>\nmaps from operator index op_index to the operator op.\n\n\\param var_arg\nis a vector of all the arguments for all the operators.\nThe mapping op2arg_index will map from operator indices\nto index in this vector.\n\n\\param op2arg_index\nOn input, op2arg_index is either the empty vector\n(or contains the proper result from a previous call to random_setup).\nUpon return it maps each operator index to the index in op_var_arg of its\nfirst argument for the operator.\n\n\\param op2var_index\nOn input, op2var_index is either the empty vector\n(or contains the proper result from a previous call to random_setup).\nUpon return it maps each operator index to the primary (last)\nresult for the operator. If there are no results for the operator,\nthe return value map value is not specified.\n\n\\param var2op_index\nOn input, var2op_index is either the empty vector\n(or contains the proper result from a previous call to random_setup).\nUpon return it maps each primary variable index to the corresponding\noperator index. The value of the map is only specified for primary variable\nindices.\n*/\ntemplate <class Addr>\nvoid random_setup(\n   size_t                                    num_var    ,\n   const pod_vector<opcode_t>&               var_op     ,\n   const pod_vector<addr_t>&                 var_arg    ,\n   pod_vector<Addr>*                         op2arg_index ,\n   pod_vector<Addr>*                         op2var_index ,\n   pod_vector<Addr>*                         var2op_index )\n{\n   if( op2arg_index->size() != 0 )\n   {  CPPAD_ASSERT_UNKNOWN( op2arg_index->size() == var_op.size() );\n      CPPAD_ASSERT_UNKNOWN( op2var_index->size() == var_op.size() );\n      CPPAD_ASSERT_UNKNOWN( var2op_index->size() == num_var        );\n      return;\n   }\n   CPPAD_ASSERT_UNKNOWN( op2var_index->size() == 0         );\n   CPPAD_ASSERT_UNKNOWN( op2var_index->size() == 0         );\n   CPPAD_ASSERT_UNKNOWN( var2op_index->size() == 0         );\n   CPPAD_ASSERT_UNKNOWN( op_code_var( var_op[0] ) == BeginOp );\n   CPPAD_ASSERT_NARG_NRES(BeginOp, 1, 1);\n   //\n   size_t num_op     = var_op.size();\n   size_t  var_index = 0;\n   size_t  arg_index = 0;\n   //\n   op2arg_index->resize( num_op );\n   op2var_index->resize( num_op );\n   var2op_index->resize( num_var  );\n# ifndef NDEBUG\n   // value of var2op for auxiliary variables is num_op (invalid)\n   for(size_t i_var = 0; i_var < num_var; ++i_var)\n      (*var2op_index)[i_var] = Addr( num_op );\n   // value of op2var is num_var (invalid) when NumRes(op) = 0\n   for(size_t i_op = 0; i_op < num_op; ++i_op)\n      (*op2var_index)[i_op] = Addr( num_var );\n# endif\n   for(size_t i_op = 0; i_op < num_op; ++i_op)\n   {  op_code_var op          = op_code_var( var_op[i_op] );\n      //\n      // index of first argument for this operator\n      (*op2arg_index)[i_op]   = Addr( arg_index );\n      arg_index            += NumArg(op);\n      //\n      // index of first result for next operator\n      var_index  += NumRes(op);\n      if( NumRes(op) > 0 )\n      {  // index of last (primary) result for this operator\n         (*op2var_index)[i_op] = Addr( var_index - 1 );\n         //\n         // mapping from primary variable to its operator\n         (*var2op_index)[var_index - 1] = Addr( i_op );\n      }\n      // CSumOp\n      if( op == CSumOp )\n      {  CPPAD_ASSERT_UNKNOWN( NumArg(CSumOp) == 0 );\n         //\n         // pointer to first argument for this operator\n         const addr_t* op_arg = var_arg.data() + arg_index;\n         //\n         // The actual number of arguments for this operator is\n         // op_arg[4] + 1\n         // Correct index of first argument for next operator\n         arg_index += size_t(op_arg[4] + 1);\n      }\n      //\n      // CSkip\n      if( op == CSkipOp )\n      {  CPPAD_ASSERT_UNKNOWN( NumArg(CSumOp) == 0 );\n         //\n         // pointer to first argument for this operator\n         const addr_t* op_arg = var_arg.data() + arg_index;\n         //\n         // The actual number of arguments for this operator is\n         // 7 + op_arg[4] + op_arg[5].\n         // Correct index of first argument for next operator.\n         arg_index += size_t(7 + op_arg[4] + op_arg[5]);\n      }\n   }\n}\n\n} } } // BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/play/sequential_iterator.hpp",
    "content": "# ifndef CPPAD_LOCAL_PLAY_SEQUENTIAL_ITERATOR_HPP\n# define CPPAD_LOCAL_PLAY_SEQUENTIAL_ITERATOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE\nnamespace CppAD { namespace local { namespace play {\n\n/*!\n\\file sequential_iterator.hpp\n*/\n\n/*!\nConstant sequential iterator for a player object.\n\n\\tparam Addr\nAn integer type capable of representing the largest value in the vectors\nvar_arg, op2arg_index, op2var_index, var2op_index.\n\n\\par\nExcept for constructor, the public API for this class is the same as\nfor the subgraph_iterator class.\n*/\nclass const_sequential_iterator {\nprivate:\n   /// pointer to the first operator in the player, BeginOp = *op_begin_\n   const opcode_t*           op_begin_;\n\n   /// pointer one past last operator in the player, EndOp = *(op_end_ - 1)\n   const opcode_t*           op_end_;\n\n   /// pointer to the first argument for the first operator\n   const addr_t*             arg_begin_;\n\n   /// pointer on past last argument for last operator\n   const addr_t*             arg_end_;\n\n   /// pointer to current operator\n   const opcode_t*           op_cur_;\n\n   /// pointer to first argument for current operator\n   const addr_t*             arg_;\n\n   /// number of variables in tape (not const for assignment operator)\n   size_t                    num_var_;\n\n   /// index of last result for current operator\n   size_t                    var_index_;\n\n   /// value of current operator; i.e. op_ = *op_cur_\n   op_code_var               op_;\npublic:\n   /// default constructor\n   const_sequential_iterator(void) :\n   op_begin_(nullptr)  ,\n   op_end_(nullptr)    ,\n   arg_begin_(nullptr) ,\n   arg_end_(nullptr)   ,\n   op_cur_(nullptr)    ,\n   arg_(nullptr)       ,\n   num_var_(0)            ,\n   var_index_(0)          ,\n   op_(NumberOp)\n   { }\n   /// assignment operator\n   void operator=(const const_sequential_iterator& rhs)\n   {\n      op_begin_  = rhs.op_begin_;\n      op_end_    = rhs.op_end_;\n      arg_begin_ = rhs.arg_begin_;\n      arg_end_   = rhs.arg_end_;\n      op_cur_    = rhs.op_cur_;\n      arg_       = rhs.arg_;\n      num_var_   = rhs.num_var_;\n      var_index_ = rhs.var_index_;\n      op_        = rhs.op_;\n      return;\n   }\n   /*!\n   Create a sequential iterator starting either at beginning or end of tape\n\n   \\param num_var\n   is the number of variables in the tape.\n\n   \\param var_op\n   is the vector of operators on the tape.\n\n   \\param var_arg\n   is the vector of arguments for all the operators\n\n   \\param op_index\n   is the operator index that iterator will start at.\n   It must be zero or var_op_->size() - 1.\n\n   \\par Assumptions\n   - op_code_var(var_op_[0]) == BeginOp\n   - op_code_var(var_op_[var_op_->size() - 1]) == EndOp\n   */\n   const_sequential_iterator(\n      size_t                                num_var    ,\n      const pod_vector<opcode_t>*           var_op     ,\n      const pod_vector<addr_t>*             var_arg    ,\n      size_t                                op_index   )\n   :\n   op_begin_   ( var_op->data() )                   ,\n   op_end_     ( var_op->data() + var_op->size() )  ,\n   arg_begin_  ( var_arg->data() )                  ,\n   arg_end_    ( var_arg->data() + var_arg->size() ),\n   num_var_    ( num_var )\n   {  if( op_index == 0 )\n      {\n         // index of last result for BeginOp\n         var_index_ = 0;\n         //\n         // first argument to BeginOp\n         arg_       = var_arg->data();\n         //\n         // BeginOp\n         op_cur_    = op_begin_;\n         op_        = op_code_var( *op_cur_ );\n         CPPAD_ASSERT_UNKNOWN( op_ == BeginOp );\n         CPPAD_ASSERT_NARG_NRES(op_, 1, 1);\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN(op_index == var_op->size()-1);\n         //\n         // index of last result for EndOp\n         var_index_ = num_var - 1;\n         //\n         // first argument to EndOp (has no arguments)\n         arg_ = var_arg->data() + var_arg->size();\n         //\n         // EndOp\n         op_cur_    = op_end_ - 1;\n         op_        = op_code_var( *op_cur_ );\n         CPPAD_ASSERT_UNKNOWN( op_ == EndOp );\n         CPPAD_ASSERT_NARG_NRES(op_, 0, 0);\n      }\n   }\n   /*!\n   Advance iterator to next operator\n   */\n   const_sequential_iterator& operator++(void)\n   {\n      // first argument for next operator\n      arg_ += NumArg(op_);\n      //\n      // next operator\n      ++op_cur_;\n      op_ = op_code_var( *op_cur_ );\n      //\n      // last result for next operator\n      var_index_ += NumRes(op_);\n      //\n      return *this;\n   }\n   /*!\n   Correction applied before ++ operation when current operator\n   is CSumOp, CSkipOp, or AFunOP.\n   */\n   void correct_before_increment(void)\n   {  //\n      // arg_\n      // actual number of arguments for this operator depends on argument data\n      CPPAD_ASSERT_UNKNOWN( NumArg(op_) == 0 );\n      const addr_t* arg = arg_;\n      //\n      switch( op_ )\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN( false );\n         break;\n         //\n         // CSumOp\n         case CSumOp:\n         CPPAD_ASSERT_UNKNOWN( arg + 4 < arg_end_ );\n         arg_ += arg[4] + 1;\n         CPPAD_ASSERT_UNKNOWN( *(arg_ - 1) == arg[4] + 1 );\n         break;\n         //\n         // CSkipOp\n         case CSkipOp:\n         CPPAD_ASSERT_UNKNOWN( arg + 5 < arg_end_ );\n         arg_ += 7 + arg[4] + arg[5];\n         CPPAD_ASSERT_UNKNOWN( *(arg_ - 1) == 7 + arg[4] + arg[5] );\n         break;\n      }\n      CPPAD_ASSERT_UNKNOWN( arg_ <= arg_end_ );\n      return;\n   }\n   /*!\n   Backup iterator to previous operator\n   */\n   const_sequential_iterator& operator--(void)\n   {  //\n      // last result for next operator\n      var_index_ -= NumRes(op_);\n      //\n      // next operator\n      --op_cur_;\n      op_ = op_code_var( *op_cur_ );\n      //\n      // first argument for next operator\n      arg_ -= NumArg(op_);\n      //\n      return *this;\n   }\n   /*!\n   Correction applied after -- operation when current operator\n   is CSumOp or CSkipOp.\n\n   \\param arg [out]\n   corrected point to arguments for this operation.\n   */\n   void correct_after_decrement(const addr_t*& arg)\n   {  //\n      // arg\n      // actual number of arguments for this operator depends on argument data\n      CPPAD_ASSERT_UNKNOWN( NumArg(op_) == 0 );\n      CPPAD_ASSERT_UNKNOWN( arg_begin_ < arg_ );\n      //\n      switch( op_ )\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN( false );\n         break;\n         //\n         // CSumOp\n         case CSumOp:\n         {  // index of arg[4]\n            addr_t n_arg = *(arg_ - 1);\n            arg          = arg_ - n_arg;\n            CPPAD_ASSERT_UNKNOWN( arg[4] + 1 == n_arg );\n         }\n         break;\n         //\n         // CSkipOp\n         case CSkipOp:\n         {  addr_t n_arg = *(arg_ - 1);\n            arg          = arg_ - n_arg;\n            CPPAD_ASSERT_UNKNOWN( 7 + arg[4] + arg[5] == n_arg );\n         }\n         break;\n      }\n      //\n      // arg_\n      CPPAD_ASSERT_UNKNOWN( arg_begin_ <= arg );\n      CPPAD_ASSERT_UNKNOWN( arg + NumArg(op_) <= arg_end_ );\n      arg_ = arg;\n   }\n   /*!\n   \\brief\n   Get information corresponding to current operator.\n\n   \\param op [out]\n   op code for this operator.\n\n   \\param arg [out]\n   pointer to the first argument to this operator.\n\n   \\param var_index [out]\n   index of the last variable (primary variable) for this operator.\n   If there is no primary variable for this operator, var_index\n   is not specified and could have any value.\n   */\n   void op_info(\n      op_code_var&   op         ,\n      const addr_t*& arg        ,\n      size_t&        var_index  ) const\n   {  // op\n      CPPAD_ASSERT_UNKNOWN( op_begin_ <= op_cur_ && op_cur_ < op_end_ )\n      op        = op_;\n      //\n      // arg\n      arg = arg_;\n      CPPAD_ASSERT_UNKNOWN( arg_begin_ <= arg );\n      CPPAD_ASSERT_UNKNOWN( arg + NumArg(op) <= arg_end_ );\n      //\n      // var_index\n      CPPAD_ASSERT_UNKNOWN( var_index_ < num_var_ || NumRes(op) == 0 );\n      var_index = var_index_;\n   }\n   /// current operator index\n   size_t op_index(void)\n   {  return size_t(op_cur_ - op_begin_); }\n};\n\n} } } // BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/play/subgraph_iterator.hpp",
    "content": "# ifndef CPPAD_LOCAL_PLAY_SUBGRAPH_ITERATOR_HPP\n# define CPPAD_LOCAL_PLAY_SUBGRAPH_ITERATOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/play/random_iterator.hpp>\n\n// BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE\nnamespace CppAD { namespace local { namespace play {\n\n/*!\n\\file random_iterator.hpp\n*/\n\n/*!\nConstant subgraph iterator for a player object.\n\n\\tparam Addr\nAn integer type capable of representing the largest value in the vectors\nvar_arg, op2arg_index, op2var_index, var2op_index.\n\nExcept for constructor, the public API for this class is the same as\nfor the sequential iterator class.\n*/\ntemplate <class Addr>\nclass const_subgraph_iterator {\nprivate:\n   /// a random iterator used to access player information\n   const const_random_iterator<Addr>* random_itr_;\n\n   /// sorted subset of operator indices that we will include\n   const pod_vector<addr_t>* subgraph_;\n\n   /// index in subgraph of current operator\n   /// The initial value for this index must be zero or subgraph.size()-1.\n   size_t subgraph_index_;\n\npublic:\n   /// default constructor\n   const_subgraph_iterator(void) :\n   random_itr_(nullptr) ,\n   subgraph_(nullptr)   ,\n   subgraph_index_(0)\n   { }\n   /// default assignment operator\n   void operator=(const const_subgraph_iterator& rhs)\n   {\n      random_itr_      = rhs.random_itr_;\n      subgraph_        = rhs.subgraph_;\n      subgraph_index_  = rhs.subgraph_index_;\n      return;\n   }\n   /*!\n   Create a subgraph iterator starting either at beginning or end of subgraph\n   */\n   const_subgraph_iterator(\n      const const_random_iterator<Addr>&    random_itr , ///< random_itr_\n      const pod_vector<addr_t>*             subgraph   , ///< subgraph_\n      size_t subgraph_index                            ) ///< subgraph_index_\n   :\n   random_itr_      ( &random_itr )       ,\n   subgraph_        ( subgraph )          ,\n   subgraph_index_  ( subgraph_index )\n   {  CPPAD_ASSERT_UNKNOWN(\n         subgraph_index == 0 || subgraph_index == subgraph->size() - 1\n      );\n   }\n   /*!\n   Advance iterator to next operator\n   */\n   const_subgraph_iterator<Addr>& operator++(void)\n   {  ++subgraph_index_;\n      return *this;\n   }\n   /// No correction necessary when using random access to player\n   void correct_before_increment(void)\n   {  return; }\n   /*!\n   Backup iterator to previous operator\n   */\n   const_subgraph_iterator<Addr>& operator--(void)\n   {  --subgraph_index_;\n      return *this;\n   }\n   /*!\n   No correction necessary when using random access to player.\n\n   \\param op_arg\n   not used or modified.\n   */\n   void correct_after_decrement(const addr_t*& op_arg)\n   {  return; }\n   /*!\n   \\brief\n   Get information corresponding to current operator.\n\n   \\param op [out]\n   op code for this operator.\n\n   \\param op_arg [out]\n   pointer to the first argument to this operator.\n\n   \\param var_index [out]\n   index of the last variable (primary variable) for this operator.\n   If there is no primary variable for this operator, var_index\n   is not specified and could have any value.\n   */\n   void op_info(\n      op_code_var&   op         ,\n      const addr_t*& op_arg     ,\n      size_t&        var_index  ) const\n   {  // op\n      size_t op_index = size_t( (*subgraph_)[subgraph_index_] );\n      random_itr_->op_info(op_index, op, op_arg, var_index);\n   }\n   /// current operator index\n   size_t op_index(void)\n   {  return size_t( (*subgraph_)[subgraph_index_] ); }\n};\n\n} } } // BEGIN_CPPAD_LOCAL_PLAY_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/pod_vector.hpp",
    "content": "# ifndef CPPAD_LOCAL_POD_VECTOR_HPP\n# define CPPAD_LOCAL_POD_VECTOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# if CPPAD_CSTDINT_HAS_8_TO_64\n# include <cstdint>\n# endif\n# include <cstring>\n# include <algorithm>\n# include <cppad/utility/thread_alloc.hpp>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/local/is_pod.hpp>\n\n/*\n{xrst_begin_parent pod_vector dev}\n\nA Template Vector Class That does not construct or destruct Elements\n####################################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_POD_VECTOR_CLASS\n   // END_POD_VECTOR_CLASS\n}\n\nMember Functions\n****************\nAll the member functions in this class are public.\n\nis_pod\n******\nThe :ref:`is_pod-name` function must return true for this *Type* .\n\n{xrst_end pod_vector}\n*/\n// BEGIN_POD_VECTOR_CLASS\nnamespace CppAD { namespace local {\ntemplate <class Type> class pod_vector\n// END_POD_VECTOR_CLASS\n{\n/*\n{xrst_begin pod_vector_private dev}\n\npod_vector Private Data\n#######################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PRIVATE\n   // END_PRIVATE\n}\n\nsize\\_\n******\nis the number of elements currently in this vector.\n\ncapacity\\_\n**********\nis the maximum number of elements that the current allocation can hold.\nIt is always greater than or equal size\\_ .\nThe only operations that can decrease the capacity are\n:ref:`pod_vector_vector@swap` and :ref:`pod_vector_resize@clear` .\n\ndata\\_\n******\nis a pointer to the first element of the vector.\nThis is the null pointer when capacity\\_ is zero.\n\n{xrst_end pod_vector_private}\n*/\n// BEGIN_PRIVATE\nprivate:\n   size_t size_;\n   size_t capacity_;\n   Type   *data_;\n// END_PRIVATE\n// ---------------------------------------------------------------------------\npublic:\n// ---------------------------------------------------------------------------\n/*\n{xrst_begin pod_vector_ctor dev}\n\npod_vector Constructors and Destructor\n######################################\n\nCopy\n****\n{xrst_literal\n   // BEGIN_COPY_CTOR\n   // END_COPY_CTOR\n}\nThis constructor cannot be used.\n\nDefault\n*******\n{xrst_literal\n   // BEGIN_DEFAULT_CTOR\n   // END_DEFAULT_CTOR\n}\nThis constructor sets the size and capacity to zero.\n\nSize\n****\n{xrst_literal\n   // BEGIN_SIZE_CTOR\n   // END_SIZE_CTOR\n}\nThis constructor sets the size (capacity) equal *n*\n( greater that or equal *n* ).\n\nDestructor\n**********\n{xrst_literal\n   // BEGIN_DESTRUCTOR\n   // END_DESTRUCTOR\n}\nThe memory is returned using :ref:`ta_return_memory-name` .\n\n\n{xrst_end pod_vector_ctor}\n*/\n   // BEGIN_COPY_CTOR\n   pod_vector(const pod_vector&) = delete;\n   // END_COPY_CTOR\n\n   // BEGIN_DEFAULT_CTOR\n   pod_vector(void)\n   // END_DEFAULT_CTOR\n   : size_(0), capacity_(0), data_(nullptr)\n   {  CPPAD_ASSERT_UNKNOWN( is_pod<Type>() );\n   }\n\n   // BEGIN_SIZE_CTOR\n   pod_vector(size_t n)\n   // END_SIZE_CTOR\n   : size_(0), capacity_(0), data_(nullptr)\n   {  CPPAD_ASSERT_UNKNOWN( is_pod<Type>() );\n      extend(n);\n   }\n\n   // BEGIN_DESTRUCTOR\n   ~pod_vector(void)\n   // END_DESTRUCTOR\n   {  if( capacity_ > 0 )\n      {\n         void* v_ptr = reinterpret_cast<void*>( data_ );\n         thread_alloc::return_memory(v_ptr);\n      }\n   }\n/*\n------------------------------------------------------------------------------\n{xrst_begin pod_vector_state dev}\n\nThe Current State of a pod_vector\n#################################\n\nsize\n****\n{xrst_literal\n   // BEGIN_SIZE_STATE\n   // END_SIZE_STATE\n}\n\ncapacity\n********\n{xrst_literal\n   // BEGIN_CAPACITY_STATE\n   // END_CAPACITY_STATE\n}\n\ndata\n****\n{xrst_literal\n   // BEGIN_DATA_STATE\n   // END_DATA_STATE\n}\nThis pointer is no longer valid after the following operations:\nextend, resize, clear, assignment, destructor.\n\n{xrst_end pod_vector_state}\n*/\n\n   // BEGIN_SIZE_STATE\n   size_t size(void) const\n   {  return size_; }\n   // END_SIZE_STATE\n\n   // BEGIN_CAPACITY_STATE\n   size_t capacity(void) const\n   {  return capacity_; }\n   // END_CAPACITY_STATE\n\n   // BEGIN_DATA_STATE\n   Type* data(void)\n   {  return data_; }\n   const Type* data(void) const\n   {  return data_; }\n   // END_DATA_STATE\n\n/*\n------------------------------------------------------------------------------\n{xrst_begin pod_vector_element dev}\n\nAccess and Change an Element of a pod_vector\n############################################\n\nNot Constant\n************\n{xrst_literal\n   // BEGIN_ELEMENT\n   // END_ELEMENT\n}\nThis accesses the element at the specified index\n(in a way that allows the element's value to be changed).\nAn assert is generated the index is greater than or equal to\n`size_`` for this vector.\n\nConstant\n********\n{xrst_literal\n   // BEGIN_CONST_ELEMENT\n   // END_CONST_ELEMENT\n}\nThis accesses the element at the specified index\n(in a way that does not allow the element's value to be changed).\nAn assert is generated the index is greater than or equal to\n`size_`` for this vector.\n\npush_back\n*********\n{xrst_literal\n   // BEGIN_PUSH_BACK\n   // END_PUSH_BACK\n}\nThis increases the size by one and places the specified element\nat the end (highest valid index) of the vector.\n\n{xrst_end pod_vector_element}\n*/\n   // BEGIN_ELEMENT\n   template <class Index>\n   Type& operator[](Index index)\n   // END_ELEMENT\n   {  CPPAD_ASSERT_UNKNOWN( size_t(index)  < size_ );\n      return data_[index];\n   }\n   // BEGIN_CONST_ELEMENT\n   template <class Index>\n   const Type& operator[](Index index) const\n   // END_CONST_ELEMENT\n   {  CPPAD_ASSERT_UNKNOWN( size_t(index)  < size_ );\n      return data_[index];\n   }\n   // BEGIN_PUSH_BACK\n   void push_back(const Type& element)\n   // END_PUSH_BACK\n   {  size_t i = extend(1);\n      data_[i] = element;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin pod_vector_vector dev}\n\npod_vector Operations With Vector Arguments\n###########################################\n\nswap\n****\n{xrst_literal\n   // BEGIN_SWAP\n   // END_SWAP\n}\nThis exchanges this all the information in this vector with another vector.\nIt is faster that assignment because it does not allocate or free memory and\ndoes not do any element by element operations.\n\nAssignment\n**********\n{xrst_literal\n   // BEGIN_ASSIGNMENT\n   // END_ASSIGNMENT\n}\nThis copies all the information from the other vector to this vector.\nIt copies each element from other and it may free and allocate memory.\n\n{xrst_end pod_vector_vector}\n*/\n   // BEGIN_SWAP\n   void swap(pod_vector& other)\n   // END_SWAP\n   {  std::swap(capacity_,      other.capacity_);\n      std::swap(size_,          other.size_);\n      std::swap(data_,          other.data_);\n   }\n   // BEGIN_ASSIGNMENT\n   void operator=(const pod_vector& other)\n   // END_ASSIGNMENT\n   {  resize( other.size_ );\n      if( size_ > 0 )\n      {  size_t bytes      = size_ * sizeof(Type);\n         void* v_ptr       = reinterpret_cast<void*>( data_ );\n         void* v_ptr_other = reinterpret_cast<void*>( other.data_ );\n         std::memcpy(v_ptr, v_ptr_other, bytes);\n      }\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin pod_vector_resize dev}\n\nChanging the Size of a pod_vector\n#################################\n\nextent\n******\n{xrst_literal\n   // BEGIN_EXTEND\n   // END_EXTEND\n}\n#. This increases the size of the vector by *n* .\n#. It returns the size before the increase\n   which is the index of the first new element added to the vector.\n#. All of the elements in the vector, before the extension,\n   are preserved by this operation.\n\nresize\n******\n{xrst_literal\n   // BEGIN_RESIZE\n   // END_RESIZE\n}\n#. This changes the size of the vector to *n* .\n#. If on input, *n* is less that or equal :ref:`pod_vector_private@capacity\\_` ,\n   all the elements in the vector, before the extension,\n   are preserved by this operation.\n#. If on input, *n* is greater than capacity\\_ ,\n   the elements in the vector are lost.\n\nclear\n*****\n{xrst_literal\n   // BEGIN_CLEAR\n   // END_CLEAR\n}\nThis sets the size and capacity for the vector to zero\nand frees all the memory that it was using.\n\n\n{xrst_end pod_vector_resize}\n*/\n   // BEGIN_EXTEND\n   size_t extend(size_t n)\n   // END_EXTEND\n   {  size_t old_size   = size_;\n      size_              += n;\n\n      // check if we can use current memory\n      if( size_ <= capacity_ )\n         return old_size;\n\n      // save more old information\n      size_t old_capacity = capacity_;\n      void* old_v_ptr     = reinterpret_cast<void*>(data_);\n\n      // get new memory and set capacity\n      size_t byte_capacity;\n      size_t bytes = size_ * sizeof(Type);\n      void* v_ptr  = thread_alloc::get_memory(bytes, byte_capacity);\n      capacity_    = byte_capacity / sizeof(Type);\n      data_        = reinterpret_cast<Type*>(v_ptr);\n\n      // copy old data to new\n      if( old_size >  0 )\n         std::memcpy(v_ptr, old_v_ptr, old_size * sizeof(Type));\n\n      // return old memory to available pool\n      if( old_capacity > 0 )\n         thread_alloc::return_memory(old_v_ptr);\n\n      // return value for extend(n) is the old length\n      CPPAD_ASSERT_UNKNOWN( size_ <= capacity_ );\n      return old_size;\n   }\n   // BEGIN_RESIZE\n   void resize(size_t n)\n   // END_RESIZE\n   {  size_      = n;\n\n      // check if we must allocate new memory\n      if( capacity_ < size_ )\n      {  void* v_ptr;\n         //\n         if( capacity_ > 0 )\n         {  // return old memory to available pool\n            v_ptr = reinterpret_cast<void*>( data_ );\n            thread_alloc::return_memory(v_ptr);\n         }\n         //\n         // get new memory and set capacity\n         size_t byte_capacity;\n         size_t bytes = size_ * sizeof(Type);\n         v_ptr        = thread_alloc::get_memory(bytes, byte_capacity);\n         capacity_    = byte_capacity / sizeof(Type);\n         data_        = reinterpret_cast<Type*>(v_ptr);\n         //\n      }\n      CPPAD_ASSERT_UNKNOWN( size_ <= capacity_ );\n   }\n   // BEGIN_CLEAR\n   void clear(void)\n   // END_CLEAR\n   {  if( capacity_ > 0 )\n      {\n         void* v_ptr = reinterpret_cast<void*>( data_ );\n         thread_alloc::return_memory(v_ptr);\n      }\n      data_        = nullptr;\n      capacity_    = 0;\n      size_        = 0;\n   }\n};\n// ---------------------------------------------------------------------------\n/*!\nA vector class with that does not use element constructors or destructors\nwhen is_pod<Type> is true.\n*/\ntemplate <class Type>\nclass pod_vector_maybe {\nprivate:\n   /// maximum number of Type elements current allocation can hold\n   size_t capacity_;\n\n   /// number of elements currently in this vector\n   size_t length_;\n\n   /// pointer to the first type elements\n   /// (not defined and should not be used when capacity_ = 0)\n   Type   *data_;\n\n   /// do not use the copy constructor\n   explicit pod_vector_maybe(const pod_vector_maybe& )\n   {  CPPAD_ASSERT_UNKNOWN(false); }\npublic:\n   /// default constructor sets capacity_ = length_ = data_ = 0\n   pod_vector_maybe(void)\n   : capacity_(0), length_(0), data_(nullptr)\n   {  CPPAD_ASSERT_UNKNOWN( is_pod<size_t>() );\n   }\n\n   /// sizing constructor\n   pod_vector_maybe(\n      /// number of elements in this vector\n      size_t n )\n   : capacity_(0), length_(0), data_(nullptr)\n   {  extend(n); }\n\n\n   /// Destructor: returns allocated memory to thread_alloc;\n   /// see extend and resize.  If this is not plain old data,\n   /// the destructor for each element is called.\n   ~pod_vector_maybe(void)\n   {  if( capacity_ > 0 )\n      {  if( ! is_pod<Type>() )\n         {  // call destructor for each element\n            for(size_t i = 0; i < capacity_; i++)\n               (data_ + i)->~Type();\n         }\n         void* v_ptr = reinterpret_cast<void*>( data_ );\n         thread_alloc::return_memory(v_ptr);\n      }\n   }\n\n   /// current number of elements in this vector.\n   size_t size(void) const\n   {  return length_; }\n\n   /// current capacity (amount of allocated storage) for this vector.\n   size_t capacity(void) const\n   {  return capacity_; }\n\n   /// current data pointer is no longer valid after any of the following:\n   /// extend, resize, erase, clear, assignment, and destructor.\n   Type* data(void)\n   {  return data_; }\n\n   /// const version of data pointer (see non-const documentation)\n   const Type* data(void) const\n   {  return data_; }\n   // ----------------------------------------------------------------------\n   /// non-constant element access; i.e., we can change this element value\n   Type& operator[](\n      /// element index, must be less than length\n      size_t i\n   )\n   {  CPPAD_ASSERT_UNKNOWN( i < length_ );\n      return data_[i];\n   }\n   /// non-constant element access; i.e., we can change this element value\n   template <class Index>\n   Type& operator[](\n      /// element index, must be less than length and convertible to size_t\n      Index i\n   )\n   {  return (*this)[size_t(i)]; }\n\n   // ----------------------------------------------------------------------\n   /// constant element access; i.e., we cannot change this element value\n   const Type& operator[](\n      /// element index, must be less than length\n      size_t i\n   ) const\n   {  CPPAD_ASSERT_UNKNOWN( i < length_ );\n      return data_[i];\n   }\n   /// constant element access; i.e., we cannot change this element value\n   template <class Index>\n   const Type& operator[](\n      /// element index, must be less than length and convertible to size_t\n      Index i\n   ) const\n   {  return (*this)[size_t(i)]; }\n\n   // ----------------------------------------------------------------------\n   /*!\n   Add an element to theh back of this vector\n\n   \\param e\n   is the element we are adding to the back of the vector.\n   */\n   void push_back(const Type& e)\n   {  size_t i = extend(1);\n      data_[i] = e;\n   }\n\n   /*!\n   Swap all properties of this vector with another.\n   This is useful when moving a vector that grows after it has reached\n   its final size (without copying every element).\n\n   \\param other\n   is the other vector that we are swapping this vector with.\n   */\n   void swap(pod_vector_maybe& other)\n   {  std::swap(capacity_, other.capacity_);\n      std::swap(length_,   other.length_);\n      std::swap(data_,     other.data_);\n   }\n   // ----------------------------------------------------------------------\n   /*!\n   Increase the number of elements the end of this vector\n   (existing elements are always preserved).\n\n   \\param n\n   is the number of elements to add to end of this vector.\n\n   \\return\n   is the number of elements in the vector before it was extended.\n   This is the index of the first new element added to the vector.\n\n   - If Type is plain old data, new elements are not initialized;\n   i.e., their constructor is not called. Otherwise, the constructor\n   is called for each new element.\n\n   - This and resize are the only routine that allocate memory for\n   pod_vector_maybe. They uses thread_alloc for this allocation.\n   */\n   size_t extend(size_t n)\n   {  size_t old_length   = length_;\n      length_            += n;\n\n      // check if we can use current memory\n      if( length_ <= capacity_ )\n         return old_length;\n\n      // save more old information\n      size_t old_capacity = capacity_;\n      Type* old_data      = data_;\n\n      // get new memory and set capacity\n      size_t length_bytes = length_ * sizeof(Type);\n      size_t capacity_bytes;\n      void* v_ptr = thread_alloc::get_memory(length_bytes, capacity_bytes);\n      capacity_   = capacity_bytes / sizeof(Type);\n      data_       = reinterpret_cast<Type*>(v_ptr);\n\n      if( ! is_pod<Type>() )\n      {  // call constructor for each new element\n         for(size_t i = 0; i < capacity_; i++)\n            new(data_ + i) Type();\n      }\n\n      // copy old data to new\n      for(size_t i = 0; i < old_length; i++)\n         data_[i] = old_data[i];\n\n      // return old memory to available pool\n      if( old_capacity > 0 )\n      {  if( ! is_pod<Type>() )\n         {  for(size_t i = 0; i < old_capacity; i++)\n               (old_data + i)->~Type();\n         }\n         v_ptr = reinterpret_cast<void*>( old_data );\n         thread_alloc::return_memory(v_ptr);\n      }\n\n      // return value for extend(n) is the old length\n      CPPAD_ASSERT_UNKNOWN( length_ <= capacity_ );\n      return old_length;\n   }\n   // ----------------------------------------------------------------------\n   /*!\n   resize the vector (existing elements preserved when n <= capacity_).\n\n   \\param n\n   is the new size for this vector.\n\n   \\par\n   if n <= capacity(), no memory is freed or allocated, the capacity\n   is not changed, and existing elements are preserved.\n   If n > capacity(), new memory is allocates and all the\n   data in the vector is lost.\n\n   - If  Type is plain old data, new elements are not initialized;\n   i.e., their constructor is not called. Otherwise, the constructor\n   is called for each new element.\n\n   - This and extend are the only routine that allocate memory for\n   pod_vector_maybe. They uses thread_alloc for this allocation.\n   */\n   void resize(size_t n)\n   {  length_ = n;\n\n      // check if we must allocate new memory\n      if( capacity_ < length_ )\n      {  void* v_ptr;\n         //\n         // return old memory to available pool\n         if( capacity_ > 0 )\n         {  if( ! is_pod<Type>() )\n            {  // call destructor for each old element\n               for(size_t i = 0; i < capacity_; i++)\n                  (data_ + i)->~Type();\n            }\n            v_ptr = reinterpret_cast<void*>( data_ );\n            thread_alloc::return_memory(v_ptr);\n         }\n         //\n         // get new memory and set capacity\n         size_t length_bytes = length_ * sizeof(Type);\n         size_t capacity_bytes;\n         v_ptr     = thread_alloc::get_memory(length_bytes, capacity_bytes);\n         capacity_ = capacity_bytes / sizeof(Type);\n         data_     = reinterpret_cast<Type*>(v_ptr);\n         //\n         CPPAD_ASSERT_UNKNOWN( length_ <= capacity_ );\n         //\n         if( ! is_pod<Type>() )\n         {  // call constructor for each new element\n            for(size_t i = 0; i < capacity_; i++)\n               new(data_ + i) Type();\n         }\n      }\n   }\n   // ----------------------------------------------------------------------\n   /*!\n   Remove all the elements from this vector and free its memory.\n   */\n   void clear(void)\n   {  if( capacity_ > 0 )\n      {  if( ! is_pod<Type>() )\n         {  // call destructor for each element\n            for(size_t i = 0; i < capacity_; i++)\n               (data_ + i)->~Type();\n         }\n         void* v_ptr = reinterpret_cast<void*>( data_ );\n         thread_alloc::return_memory(v_ptr);\n      }\n      data_     = nullptr;\n      capacity_ = 0;\n      length_   = 0;\n   }\n   // -----------------------------------------------------------------------\n   /// vector assignment operator\n   void operator=(\n      /// right hand size of the assignment operation\n      const pod_vector_maybe& x\n   )\n   {  resize( x.length_ );\n      //\n      CPPAD_ASSERT_UNKNOWN( length_   == x.length_ );\n      for(size_t i = 0; i < length_; i++)\n      {  data_[i] = x.data_[i]; }\n   }\n};\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/record/comp_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_RECORD_COMP_OP_HPP\n# define CPPAD_LOCAL_RECORD_COMP_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/record/recorder.hpp>\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*\n{xrst_begin recorder_put_comp_op dev}\n{xrst_spell\n   aleft\n   dyn\n   taddr\n}\n\nPut Compare Operators in Recording\n##################################\n\nSyntax\n******\n| *rec* . ``put_comp_`` *rel* ( *aleft* , *aright* , *result* )\n\nrel\n===\nThe text *rel* in the function name above\nis ``eq`` (for equals),\n``le`` (for less than or equal), or\n``lt`` (for less than).\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_COMP_EQ\n   // END_COMP_EQ\n}\nThe other prototypes for the functions ``comp_le`` and ``comp_lt``\nare same except for the function name.\n\nvar_left\n********\nis true if the left operand is a variable.\n\nvar_right\n*********\nis true if the right operand is a variable.\n\ndyn_left\n********\nis true if the left operand is a dynamic parameter.\n\ndyn_right\n*********\nis true if the right operand is a dynamic parameter.\n\naleft\n*****\nis the compare operator left operand.\n\naright\n******\nis the compare operator right operand.\n\ntaddr\\_\n*******\nThe values *aleft.taddr_* and *aright* . ``taddr_``\nare the proper address for dynamic parameters and variables\nand does not matter for constants.\n\nvalue\\_\n*******\nThe values *aleft.value_* and *aright* . ``value_``\nare the proper address for constants and does not matter\nfor variables and dynamic parameters.\n\nresult\n******\nThis is the result for this comparison corresponding to this\nrecording (sequence of operations).\n\n{xrst_end recorder_put_comp_op}\n*/\n// BEGIN_COMP_EQ\ntemplate <class Base>\nvoid recorder<Base>::comp_eq(\n   bool                        var_left     ,\n   bool                        var_right    ,\n   bool                        dyn_left     ,\n   bool                        dyn_right    ,\n   const AD<Base>&             aleft        ,\n   const AD<Base>&             aright       ,\n   bool                        result       )\n// END_COMP_EQ\n{  if( var_left )\n   {  if( var_right )\n      {  // variable == variable\n         PutArg(aleft.taddr_, aright.taddr_);\n         if( result )\n            PutOp(EqvvOp);\n         else\n            PutOp(NevvOp);\n      }\n      else\n      {  // variable == parameter\n         addr_t p = aright.taddr_;\n         if( ! dyn_right )\n            p = put_con_par(aright.value_);\n         PutArg(p, aleft.taddr_);\n         if( result )\n            PutOp(EqpvOp);\n         else\n            PutOp(NepvOp);\n      }\n   }\n   else if ( var_right )\n   {  // parameter == variable\n      addr_t p = aleft.taddr_;\n      if( ! dyn_left )\n         p = put_con_par(aleft.value_);\n      PutArg(p, aright.taddr_);\n      if( result )\n         PutOp(EqpvOp);\n      else\n         PutOp(NepvOp);\n   }\n   else if( dyn_left | dyn_right )\n   {  // parameter == parameter\n      addr_t arg0 = aleft.taddr_;\n      addr_t arg1 = aright.taddr_;\n      if( ! dyn_left )\n         arg0 = put_con_par(aleft.value_);\n      if( ! dyn_right )\n         arg1 = put_con_par(aright.value_);\n      //\n      PutArg(arg0, arg1);\n      if( result )\n         PutOp(EqppOp);\n      else\n         PutOp(NeppOp);\n   }\n}\n// ---------------------------------------------------------------------------\n// comp_le\ntemplate <class Base>\nvoid recorder<Base>::comp_le(\n   bool                        var_left     ,\n   bool                        var_right    ,\n   bool                        dyn_left     ,\n   bool                        dyn_right    ,\n   const AD<Base>&             aleft        ,\n   const AD<Base>&             aright       ,\n   bool                        result       )\n{\n   if( var_left )\n   {  if( var_right )\n      {  // variable <= variable\n         if( result )\n         {  PutOp(LevvOp);\n            PutArg(aleft.taddr_, aright.taddr_);\n         }\n         else\n         {  PutOp(LtvvOp);\n            PutArg(aright.taddr_, aleft.taddr_);\n         }\n      }\n      else\n      {  // variable <= parameter\n         addr_t p = aright.taddr_;\n         if( ! dyn_right )\n            p = put_con_par(aright.value_);\n         if( result )\n         {  PutOp(LevpOp);\n            PutArg(aleft.taddr_, p);\n         }\n         else\n         {  PutOp(LtpvOp);\n            PutArg(p, aleft.taddr_);\n         }\n      }\n   }\n   else if ( var_right )\n   {  // parameter <= variable\n      addr_t p = aleft.taddr_;\n      if( ! dyn_left )\n         p = put_con_par(aleft.value_);\n      if( result )\n      {  PutOp(LepvOp);\n         PutArg(p, aright.taddr_);\n      }\n      else\n      {  PutOp(LtvpOp);\n         PutArg(aright.taddr_, p);\n      }\n   }\n   else if( dyn_left | dyn_right )\n   {  // parameter <= parameter\n      addr_t arg0 = aleft.taddr_;\n      addr_t arg1 = aright.taddr_;\n      if( ! dyn_left )\n         arg0 = put_con_par(aleft.value_);\n      if( ! dyn_right )\n         arg1 = put_con_par(aright.value_);\n      //\n      if( result )\n      {  PutOp(LeppOp);\n         PutArg(arg0, arg1);\n      }\n      else\n      {  PutOp(LtppOp);\n         PutArg(arg1, arg0);\n      }\n   }\n}\n// --------------------------------------------------------------------------\n// comp_lt\ntemplate <class Base>\nvoid recorder<Base>::comp_lt(\n   bool                        var_left     ,\n   bool                        var_right    ,\n   bool                        dyn_left     ,\n   bool                        dyn_right    ,\n   const AD<Base>&             aleft        ,\n   const AD<Base>&             aright       ,\n   bool                        result       )\n{\n   if( var_left )\n   {  if( var_right )\n      {  // variable < variable\n         if( result )\n         {  PutOp(LtvvOp);\n            PutArg(aleft.taddr_, aright.taddr_);\n         }\n         else\n         {  PutOp(LevvOp);\n            PutArg(aright.taddr_, aleft.taddr_);\n         }\n      }\n      else\n      {  // variable < parameter\n         addr_t p = aright.taddr_;\n         if( ! dyn_right )\n            p = put_con_par(aright.value_);\n         if( result )\n         {  PutOp(LtvpOp);\n            PutArg(aleft.taddr_, p);\n         }\n         else\n         {  PutOp(LepvOp);\n            PutArg(p, aleft.taddr_);\n         }\n      }\n   }\n   else if ( var_right )\n   {  // parameter < variable\n      addr_t p = aleft.taddr_;\n      if( ! dyn_left )\n         p = put_con_par(aleft.value_);\n      if( result )\n      {  PutOp(LtpvOp);\n         PutArg(p, aright.taddr_);\n      }\n      else\n      {  PutOp(LevpOp);\n         PutArg(aright.taddr_, p);\n      }\n   }\n   else if( dyn_left | dyn_right )\n   {  // parameter < parameter\n      addr_t arg0 = aleft.taddr_;\n      addr_t arg1 = aright.taddr_;\n      if( ! dyn_left )\n         arg0 = put_con_par(aleft.value_);\n      if( ! dyn_right )\n         arg1 = put_con_par(aright.value_);\n      //\n      if( result )\n      {  PutOp(LtppOp);\n         PutArg(arg0, arg1);\n      }\n      else\n      {  PutOp(LeppOp);\n         PutArg(arg1, arg0);\n      }\n   }\n}\n} } // END_CPPAD_LOCAL_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/record/cond_exp.hpp",
    "content": "# ifndef CPPAD_LOCAL_RECORD_COND_EXP_HPP\n# define CPPAD_LOCAL_RECORD_COND_EXP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/record/recorder.hpp>\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*\n{xrst_begin recorder_cond_exp dev}\n\nRecord a Variable or Dynamic Parameter Conditional Expression\n#############################################################\n\nSyntax\n******\n| *rec* . ``cond_exp`` (\n| |tab| *tape_id* , *cop* , *result* , *left* , *right* , *if_true* , *if_false*\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_COND_EXP\n   // END_COND_EXP\n}\n\ntape_id\n*******\nidentifier for the tape that this operation is being recorded on.\nPassing tape_id avoids having to call tape_ptr() in case where\nleft, right, if_true, and if_false are all be constant at this AD level\n(but left and right are not identically constant).\n\ncop\n***\nWhich :ref:`comparison operator<base_cond_exp@CompareOp>` ;\ni.e., <, <=, ==, >=, >, or !=.\n\nresult\n******\nis the result for this operation conditional expression.\nOn input, *result* . ``value_`` is the proper value and\nthe other fields do not matter.\nUpon return, the other fields have been set to their proper values.\nIt is an error to call this routine when all the arguments are constants; i.e.,\nwhen the result is a constant.\n\nleft\n****\nvalue of the left operand in the comparison.\nIf *left* . ``tape_id_`` is not zero it must equal *tape_id* .\n\nright\n*****\nvalue of the right operand in the comparison.\nIf *right* . ``tape_id_`` is not zero it must equal *tape_id* .\n\nif_true\n*******\nvalue of the result if the comparison value is true.\nIf *if_true* . ``tape_id_`` is not zero it must equal *tape_id* .\n\nif_false\n********\nvalue of the result if the comparison value is false.\nIf *if_false* . ``tape_id_`` is not zero it must equal *tape_id* .\n\n{xrst_end recorder_cond_exp}\n*/\n// BEGIN_COND_EXP\ntemplate <class Base>\nvoid recorder<Base>::cond_exp(\n   tape_id_t       tape_id     ,\n   enum CompareOp  cop         ,\n   AD<Base>       &result      ,\n   const AD<Base> &left        ,\n   const AD<Base> &right       ,\n   const AD<Base> &if_true     ,\n   const AD<Base> &if_false    )\n// END_COND_EXP\n{  // check for invalid tape_id\n   CPPAD_ASSERT_UNKNOWN( tape_id != 0 );\n\n   // arg[0] = cop\n   addr_t arg0 = addr_t( cop );\n\n   // arg[1] = base 2 representation of the value\n   // [Var(left), Var(right), Var(if_true), Var(if_false)]\n   addr_t arg1 = 0;\n\n   // arg[2] = left address\n   // set first bit in arg1\n   addr_t arg2 = left.taddr_;\n   if( Constant(left) )\n      arg2 = put_con_par(left.value_);\n   else\n   {  CPPAD_ASSERT_KNOWN( tape_id == left.tape_id_ ,\n      \"CondExpRel: arguments are variables or dynamics for different thread\"\n      );\n      if(left.ad_type_ != dynamic_enum)\n         arg1 += 1;\n   }\n\n   // arg[3] = right address\n   // set second bit in arg1\n   addr_t arg3 = right.taddr_;\n   if( Constant(right) )\n      arg3 = put_con_par(right.value_);\n   else\n   {  CPPAD_ASSERT_KNOWN( tape_id == right.tape_id_ ,\n      \"CondExpRel: arguments are variables or dynamics for different thread\"\n      );\n      if(right.ad_type_ != dynamic_enum)\n         arg1 += 2;\n   }\n\n   // arg[4] = if_true address\n   // set third bit in arg1\n   addr_t arg4 = if_true.taddr_;\n   if( Constant(if_true) )\n      arg4 = put_con_par(if_true.value_);\n   else\n   {  CPPAD_ASSERT_KNOWN( tape_id == if_true.tape_id_ ,\n      \"CondExpRel: arguments are variables or dynamics for different thread\"\n      );\n      if(if_true.ad_type_ != dynamic_enum)\n         arg1 += 4;\n   }\n\n   // arg[5] =  if_false address\n   // set fourth bit in arg1\n   addr_t arg5 = if_false.taddr_;\n   if( Constant(if_false) )\n      arg5 = put_con_par(if_false.value_);\n   else\n   {  CPPAD_ASSERT_KNOWN( tape_id == if_false.tape_id_ ,\n      \"CondExpRel: arguments are variables or dynamics for different thread\"\n      );\n      if(if_false.ad_type_ != dynamic_enum)\n         arg1 += 8;\n   }\n   if( arg1 == 0 )\n   {  // none of the arguments are variables, record cond_exp_dyn\n\n      // put the result at the end of the parameter vector as dynamic\n      // put_dyn_cond_exp(par, cop, left, right, if_true, if_false)\n      result.taddr_   = put_dyn_cond_exp(\n         result.value_, CompareOp(arg0), arg2, arg3, arg4, arg5\n      );\n      result.ad_type_ = dynamic_enum;\n      result.tape_id_ = tape_id;\n\n      // check that result is a dynamic parameter\n      CPPAD_ASSERT_UNKNOWN( Dynamic(result) );\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n      CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n\n      // put operator in tape\n      result.taddr_ = PutOp(CExpOp);\n      PutArg(arg0, arg1, arg2, arg3, arg4, arg5);\n\n      // make result a variable\n      CPPAD_ASSERT_UNKNOWN( result.ad_type_ == constant_enum );\n      result.ad_type_ = variable_enum;\n      result.tape_id_ = tape_id;\n\n      // check that result is a variable\n      CPPAD_ASSERT_UNKNOWN( Variable(result) );\n   }\n}\n} } // END_CPPAD_LOCAL_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/record/dyn_recorder.hpp",
    "content": "# ifndef CPPAD_LOCAL_RECORD_DYN_RECORDER_HPP\n# define CPPAD_LOCAL_RECORD_DYN_RECORDER_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/core/hash_code.hpp>\n# include <cppad/local/pod_vector.hpp>\n# include <cppad/core/ad_type.hpp>\n/*\n-- ----------------------------------------------------------------------------\n{xrst_begin_parent dyn_recorder dev}\n\nClass That Records a Dynamic Parameter Operation Sequence\n#########################################################\n\ndyn_record\n**********\n{xrst_literal ,\n   // BEGIN_CLASS , // END_CLASS\n   // BEGIN_DYN_RECORD , // END_DYN_RECORD\n}\n\nset_n_dyn_independent\n*********************\n{xrst_literal\n   // BEGIN_SET_NUM_DYNAMIC_IND\n   // END_SET_NUM_DYNAMIC_IND\n}\n\nn_dyn_independent\n*****************\n{xrst_literal\n   // BEGIN_N_DYN_INDEPENDENT\n   // END_N_DYN_INDEPENDENT\n}\n\npar_all\n*******\n{xrst_literal\n   // BEGIN_PAR_ALL\n   // END_PAR_ALL\n}\n\nmemory\n******\n{xrst_literal\n   // BEGIN_MEMORY\n   // END_MEMORY\n}\n\n\n{xrst_end dyn_recorder}\n*/\n// BEGIN_CPPAD_LOCAL_NAMESPACE\n// BEGIN_CLASS\nnamespace CppAD { namespace local {\ntemplate <class Base> class dyn_recorder {\n// END_CLASS\n   //\n   // friend\n   friend class dyn_player<Base>;\n//\nprivate:\n   //\n   // n_dyn_independent_\n   // Number of dynamic parameters in the recording\n   size_t n_dyn_independent_;\n   //\n   // all_dyn_vec_ind_;\n   // The VecAD indices in the recording.\n   pod_vector<addr_t> dyn_vecad_ind_;\n   //\n   // par_hash_table_\n   // Hash table to reduced number of duplicate parameters in par_all_\n       pod_vector<addr_t> par_hash_table_;\n   //\n   // par_all_;\n   // Vector containing all the parameters in the recording.\n   // Use pod_vector_maybe because Base may not be plain old data.\n   pod_vector_maybe<Base> par_all_;\n   //\n   // par_is_dyn_\n   // Which elements of par_all_ are dynamic parameters\n   // (same size are par_all_)\n   pod_vector<bool> par_is_dyn_;\n   //\n   // dyn_par_op_\n   // operators for just the dynamic parameters in par_all_\n       pod_vector<opcode_t> dyn_par_op_;\n   //\n   // dyn_par_arg_\n   // arguments for the dynamic parameter operators\n   pod_vector<addr_t> dyn_par_arg_;\n//\npublic:\n   // BEGIN_DYN_RECORD\n   // dyn_recorder<Base> dyn_record\n   dyn_recorder(void)\n   // END_DYN_RECORD\n   : n_dyn_independent_(0)\n   , par_hash_table_( CPPAD_HASH_TABLE_SIZE )\n   {  //\n      // par_hash_table_\n      // It does not matter if uninitialized hash codes match but this\n      // initilaization is here to avoid valgrind warnings.\n      void*  ptr   = static_cast<void*>( par_hash_table_.data() );\n      int    value = 0;\n      size_t num   = CPPAD_HASH_TABLE_SIZE * sizeof(addr_t);\n      std::memset(ptr, value, num);\n   }\n   //\n   // Destructor\n   ~dyn_recorder(void)\n   { }\n   //\n   // BEGIN_SET_NUM_DYNAMIC_IND\n   // dyn_record.set_n_dyn_independent(n_dyn_independent)\n   void set_n_dyn_independent(size_t n_dyn_independent)\n   // END_SET_NUM_DYNAMIC_IND\n   {  n_dyn_independent_ = n_dyn_independent; }\n   //\n   // BEGIN_N_DYN_INDEPENDENT\n   // n_dyn_independent = dyn_record.n_dyn_independent()\n   size_t n_dyn_independent(void) const\n   // END_N_DYN_INDEPENDENT\n   {  return n_dyn_independent_; }\n   //\n   // put_dyn_par\n   addr_t put_dyn_par(\n      const Base &par, op_code_dyn op\n   );\n   addr_t put_dyn_par(\n      const Base &par, op_code_dyn op, addr_t a0\n   );\n   addr_t put_dyn_par(\n      const Base &par, op_code_dyn op, addr_t a0, addr_t a1\n   );\n   //\n   // put_dyn_cond_exp\n   addr_t put_dyn_cond_exp(const Base &par, CompareOp cop,\n      addr_t left, addr_t right, addr_t if_true, addr_t if_false\n   );\n   //\n   // put_dyn_arg_vec\n   void put_dyn_arg_vec(const pod_vector<addr_t>& arg);\n   //\n   // put_con_par\n   addr_t put_con_par(const Base &par);\n   //\n   // put_dyn_atomic\n   template <class VectorAD>\n   void put_dyn_atomic(\n      tape_id_t                   tape_id    ,\n      size_t                      atom_index ,\n      size_t                      call_id    ,\n      const vector<ad_type_enum>& type_x     ,\n      const vector<ad_type_enum>& type_y     ,\n      const VectorAD&             ax         ,\n      VectorAD&                   ay\n   );\n   //\n   // BEGIN_PAR_ALL\n   // par_all = dyn_record.par_all()\n   const pod_vector_maybe<Base>& par_all(void) const\n   {  return par_all_; }\n   // END_PAR_ALL\n   //\n   // BEGIN_MEMORY\n   /// memory = dyn_record.Memory()\n   size_t Memory(void) const\n   // END_MEMORY\n   {  return 0\n         + dyn_vecad_ind_.capacity() * sizeof(addr_t)\n         + par_hash_table_.capacity()    * sizeof(addr_t)\n         + par_all_.capacity()       * sizeof(Base)\n         + par_is_dyn_.capacity()        * sizeof(bool)\n         + dyn_par_op_.capacity()        * sizeof(opcode_t)\n         + dyn_par_arg_.capacity()       * sizeof(addr_t)\n      ;\n   }\n\n};\n/*\n------------------------------------------------------------------------------\n{xrst_begin put_dyn_par dev}\n\nPut a Dynamic Parameter at End of Parameter Vector\n##################################################\n\nSyntax\n******\n| *par_index* = *dyn_record* . ``put_dyn_par`` ( *par* , *op* )\n| *par_index* = *dyn_record* . ``put_dyn_par`` ( *par* , *op* , *a0* )\n| *par_index* = *dyn_record* . ``put_dyn_par`` ( *par* , *op* , *a0* , *a1* )\n\npar\n***\nis value of dynamic parameter to be placed at the end of the\nparameter vector.\n\nop\n**\nis the operator for this dynamic parameter.\n\na0\n**\nis the first argument for this operation.\nIt must be present if :ref:`num_arg_dyn@n_arg` for this\noperator is greater than zero.\n\na1\n**\nis the second argument for this operation.\nIt must be present if :ref:`num_arg_dyn@n_arg` for this\noperator is greater than one.\n\npar_index\n*********\nis the index of this dynamic parameter in the vector of all parameters.\n\nPrototype\n*********\n{xrst_literal ,\n   // BEGIN_PUT_DYN_PAR_0 , // END_PUT_DYN_PAR_0\n   // BEGIN_PUT_DYN_PAR_1 , // END_PUT_DYN_PAR_1\n   // BEGIN_PUT_DYN_PAR_2 , // END_PUT_DYN_PAR_2\n}\n\n{xrst_end put_dyn_par}\n*/\n// BEGIN_PUT_DYN_PAR_0\ntemplate <class Base> addr_t dyn_recorder<Base>::put_dyn_par(\n   const Base &par, op_code_dyn op\n)\n// END_PUT_DYN_PAR_0\n{\n   CPPAD_ASSERT_UNKNOWN(\n      op == ind_dyn || op == result_dyn || op == atom_dyn\n   );\n   CPPAD_ASSERT_UNKNOWN( num_arg_dyn(op) == 0 );\n   par_all_.push_back( par );\n   par_is_dyn_.push_back(true);\n   dyn_par_op_.push_back( opcode_t(op) );\n   return static_cast<addr_t>( par_all_.size() - 1 );\n}\n// BEGIN_PUT_DYN_PAR_1\ntemplate <class Base> addr_t dyn_recorder<Base>::put_dyn_par(\n   const Base &par, op_code_dyn op, addr_t a0\n)\n// END_PUT_DYN_PAR_1\n{\n   CPPAD_ASSERT_UNKNOWN( num_arg_dyn(op) == 1 );\n   par_all_.push_back( par );\n   par_is_dyn_.push_back(true);\n   dyn_par_op_.push_back( opcode_t(op) );\n   dyn_par_arg_.push_back(a0);\n   return static_cast<addr_t>( par_all_.size() - 1 );\n}\n// BEGIN_PUT_DYN_PAR_2\ntemplate <class Base> addr_t dyn_recorder<Base>::put_dyn_par(\n   const Base &par, op_code_dyn op, addr_t a0, addr_t a1\n)\n// END_PUT_DYN_PAR_2\n{\n   CPPAD_ASSERT_UNKNOWN( num_arg_dyn(op) == 2 );\n   par_all_.push_back( par );\n   par_is_dyn_.push_back(true);\n   dyn_par_op_.push_back( opcode_t(op) );\n   dyn_par_arg_.push_back(a0);\n   dyn_par_arg_.push_back(a1);\n   return static_cast<addr_t>( par_all_.size() - 1 );\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin put_dyn_cond_exp dev}\n\nPut a Conditional Expression Dynamic Parameter at End of Parameter Vector\n#########################################################################\n\nSyntax\n******\n| *par_index* = *dyn_record* . ``put_dyn_cond_exp`` (\n|     *par* , *cop* , *left* , *right* , *if_true* , *if_false*\n| )\n\npar\n***\nis value of dynamic parameter to be placed at the end of the\nparameter vector.\n\ncop\n***\nis the operator comparison operator; i.e., Lt, Le, Eq, Ge, Gt, or Ne.\n\nleft\n****\nis the left argument in conditional expression (which is a parameter).\n\nright\n*****\nis the right argument in conditional expression (which is a parameter).\n\nif_true\n*******\nis the if_true argument in conditional expression (which is a parameter).\n\nif_false\n********\nis the if_false argument in conditional expression (which is a parameter).\n\npar_index\n*********\nis the index of this dynamic parameter in the vector of all parameters.\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PUT_DYN_COND_EXP\n   // END_PUT_DYN_COND_EXP\n}\n\n{xrst_end put_dyn_cond_exp}\n*/\n// BEGIN_PUT_DYN_COND_EXP\ntemplate <class Base> addr_t dyn_recorder<Base>::put_dyn_cond_exp(\n   const Base &par,\n   CompareOp   cop,\n   addr_t      left,\n   addr_t      right,\n   addr_t      if_true,\n   addr_t      if_false\n)\n// END_PUT_DYN_COND_EXP\n{\n   CPPAD_ASSERT_UNKNOWN( num_arg_dyn(cond_exp_dyn) == 5 );\n   addr_t ret = addr_t( par_all_.size() );\n   par_all_.push_back( par );\n   par_is_dyn_.push_back(true);\n   dyn_par_op_.push_back( opcode_t(cond_exp_dyn) );\n   dyn_par_arg_.push_back( addr_t(cop) );\n   dyn_par_arg_.push_back(left);\n   dyn_par_arg_.push_back(right);\n   dyn_par_arg_.push_back(if_true);\n   dyn_par_arg_.push_back(if_false);\n   return ret;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin put_dyn_arg_vec dev}\n\nPut a Vector of Arguments at End of Dynamic Parameter Argument Vector\n#####################################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PUT_DYN_ARG_VEC\n   // END_PUT_DYN_ARG_VEC\n}\n\narg_vec\n*******\nis the vector of values to be added at the end of the\ndynamic parameter operator argument vector.\n\n{xrst_end put_dyn_arg_vec}\n*/\n// BEGIN_PUT_DYN_ARG_VEC\n// dyn_record.put_dyn_arg_vec(arg_vec)\ntemplate <class Base>\nvoid dyn_recorder<Base>::put_dyn_arg_vec(const pod_vector<addr_t>& arg_vec)\n// END_PUT_DYN_ARG_VEC\n{  for(size_t i = 0; i < arg_vec.size(); ++i)\n      dyn_par_arg_.push_back( arg_vec[i] );\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin put_con_par dev}\n\nFind or Add a Constant Parameter to Current Parameter Vector\n############################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PUT_CON_PAR\n   // END_PUT_CON_PAR\n}\n\npar\n***\nis the parameter to be found or placed in the vector of parameters.\n\npar_index\n*********\nis the index in the parameter vector corresponding to this parameter value.\nThis value is not necessarily placed at the end of the vector\n(because values that are identically equal may be reused).\n\n\n{xrst_end put_con_par}\n*/\n// BEGIN_PUT_CON_PAR\n// par_index = dyn_record.put_con_par(par)\ntemplate <class Base> addr_t dyn_recorder<Base>::put_con_par(const Base &par)\n// END_PUT_CON_PAR\n{\n# ifndef NDEBUG\n   // index zero is used to signify that a value is not a parameter;\n   // i.e., it is a variable.\n   if( par_all_.size() == 0 )\n      CPPAD_ASSERT_UNKNOWN( CppAD::isnan(par) );\n# endif\n   // ---------------------------------------------------------------------\n   // check for a match with a previous parameter\n   //\n   // get hash code for this value\n   size_t code  = static_cast<size_t>( hash_code(par) );\n\n   // current index in par_all_ corresponding to this hash code\n   size_t index = static_cast<size_t>( par_hash_table_[code] );\n\n   // check if the old parameter matches the new one\n   if( (0 < index) && (index < par_all_.size()) )\n   {  if( ! par_is_dyn_[index] )\n         if( IdenticalEqualCon(par_all_[index], par) )\n            return static_cast<addr_t>( index );\n   }\n   // ---------------------------------------------------------------------\n   // put parameter in par_all_ and replace hash entry for this codee\n   //\n   index = par_all_.size();\n   par_all_.push_back( par );\n   par_is_dyn_.push_back(false);\n   //\n   // change the hash table for this code to point to new value\n   par_hash_table_[code] = static_cast<addr_t>( index );\n   //\n   // return the parameter index\n   CPPAD_ASSERT_KNOWN(\n      static_cast<size_t>( std::numeric_limits<addr_t>::max() ) >= index,\n      \"cppad_tape_addr_type maximum value has been exceeded\"\n   )\n   return static_cast<addr_t>( index );\n}\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n\n// ----------------------------------------------------------------------------\n// member function implementations\n# include <cppad/local/record/put_dyn_atomic.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/record/put_dyn_atomic.hpp",
    "content": "# ifndef CPPAD_LOCAL_RECORD_PUT_DYN_ATOMIC_HPP\n# define CPPAD_LOCAL_RECORD_PUT_DYN_ATOMIC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/record/recorder.hpp>\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*\n{xrst_begin recorder_put_dyn_atomic dev}\n{xrst_spell\n   taddr\n}\n\nPut a Dynamic Parameter Atomic Call Operator in Recording\n#########################################################\n\nSyntax\n******\n| *dyn_record* . ``put_dyn_atomic`` (\n| |tab| *tape_id* , *atomic_index* , *call_id* , *type_x* , *type_y* , *ax* , *ay*\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PUT_DYN_ATOMIC\n   // END_PROTOTYPE\n}\n\ntape_id\n*******\nidentifies the tape that this recording corresponds to.\nThis is zero if and only if there is no tape for this recording; i.e.\n``AD`` < *Base* >. ``tape_ptr`` () is null.\n\natomic_index\n************\nis the :ref:`atomic_index-name` for this atomic function.\n\ncall_id\n*******\nis the :ref:`atomic_four_call@call_id` for this atomic function.\n\ntype_x\n******\nis the :ref:`ad_type_enum-name` for each of the atomic function arguments.\n\ntype_y\n******\nis the ``ad_type_enum`` for each of the atomic function results.\n\nax\n**\nis the atomic function argument vector for this call.\n\nvalue\\_\n=======\nThe value *ax* [ *j* ]. ``value_`` is the proper value for\nparameters and does not matter for variables.\n\ntaddr\\_\n=======\nThe value *ax* [ *j* ]. ``taddr_`` is the proper address for\ndynamic parameters and does not matter for constants or variables.\n\nay\n**\nis the atomic function result vector for this call.\n\nInput\n=====\nOn input, *ay* [ *j* ]. ``value_`` has the proper value for parameters\n(result for the atomic function).\n\nOutput\n======\nUpon return, if the *i*-th result is a dynamic parameter,\n\n| |tab| *ay* [ *i* ]. ``ad_type_`` = ``dynamic_enum``\n| |tab| *ay* [ *i* ]. ``tape_id_`` = *tape_id*\n| |tab| *ay* [ *i* ]. ``taddr_`` = *p_index*\n\nwhere *p_index* is the index of this dynamic parameter\nin the vector of all parameters.\n\n{xrst_end recorder_put_dyn_atomic}\n*/\n\n// BEGIN_PUT_DYN_ATOMIC\ntemplate <class Base> template <class VectorAD>\nvoid dyn_recorder<Base>::put_dyn_atomic(\n   tape_id_t                   tape_id      ,\n   size_t                      atomic_index ,\n   size_t                      call_id      ,\n   const vector<ad_type_enum>& type_x       ,\n   const vector<ad_type_enum>& type_y       ,\n   const VectorAD&             ax           ,\n   VectorAD&                   ay           )\n// END_PROTOTYPE\n{  CPPAD_ASSERT_UNKNOWN(\n      (tape_id == 0) == (AD<Base>::tape_ptr() == nullptr)\n   );\n   CPPAD_ASSERT_UNKNOWN( ax.size() == type_x.size() );\n   CPPAD_ASSERT_UNKNOWN( ay.size() == type_y.size() );\n   size_t n       = ax.size();\n   size_t m       = ay.size();\n   size_t num_dyn = 0;\n   for(size_t i = 0; i < m; ++i)\n      if( type_y[i] == dynamic_enum )\n         ++num_dyn;\n   CPPAD_ASSERT_UNKNOWN( num_dyn > 0 );\n   //\n   dyn_par_arg_.push_back( addr_t(atomic_index )); // arg[0] = atomic_index\n   dyn_par_arg_.push_back( addr_t(call_id ));      // arg[1] = call_id\n   dyn_par_arg_.push_back( addr_t( n ) );          // arg[2] = n\n   dyn_par_arg_.push_back( addr_t( m ) );          // arg[3] = m\n   dyn_par_arg_.push_back( addr_t( num_dyn ) );    // arg[4] = num_dyn\n   // arg[5 + j] for j = 0, ... , n-1\n   for(size_t j = 0; j < n; ++j)\n   {  addr_t arg = 0;\n      switch( type_x[j] )\n      {  case identical_zero_enum:\n         case constant_enum:\n         arg = put_con_par( ax[j].value_ );\n         break;\n\n         case dynamic_enum:\n         arg = ax[j].taddr_;\n         break;\n\n         case variable_enum:\n         arg = 0; // phantom parameter index\n         CPPAD_ASSERT_UNKNOWN( CppAD::isnan( par_all_[arg] ) )\n         break;\n\n         default:\n         arg = 0;\n         CPPAD_ASSERT_UNKNOWN( false );\n      }\n      dyn_par_arg_.push_back( arg );              // arg[5 + j]\n   }\n   // arg[5 + n + i] for i = 0, ... , m-1\n   bool first_dynamic_result = true;\n   for(size_t i = 0; i < m; ++i)\n   {  addr_t arg;\n      switch( type_y[i] )\n      {  case identical_zero_enum:\n         case constant_enum:\n         arg = 0; // phantom parameter index\n         break;\n\n         case dynamic_enum:\n         // one operator for each dynamic parameter result\n         // so number of operators is equal number of dynamic parameters\n         if( first_dynamic_result )\n            arg = put_dyn_par(ay[i].value_, atom_dyn );    // atom_dyn\n         else\n            arg = put_dyn_par(ay[i].value_, result_dyn );  // result_dyn\n         ay[i].ad_type_ = dynamic_enum;\n         ay[i].taddr_   = arg;\n         ay[i].tape_id_ = tape_id;\n         first_dynamic_result = false;\n         break;\n\n         case variable_enum:\n         arg = 0; // phantom parameter (has value nan)\n         break;\n\n         default:\n         arg = 0;\n         CPPAD_ASSERT_UNKNOWN( false );\n      }\n      dyn_par_arg_.push_back( arg );              // arg[5 + n + i]\n   }\n   dyn_par_arg_.push_back( addr_t(6 + n + m) );    // arg[5 + n + m]\n}\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/record/put_var_atomic.hpp",
    "content": "# ifndef CPPAD_LOCAL_RECORD_PUT_VAR_ATOMIC_HPP\n# define CPPAD_LOCAL_RECORD_PUT_VAR_ATOMIC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/record/recorder.hpp>\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*\n{xrst_begin recorder_put_var_atomic dev}\n{xrst_spell\n   taddr\n}\n\nPut a Variable Atomic Call Operator in Recording\n################################################\n\nSyntax\n******\n| *rec* . ``put_var_atomic`` (\n| |tab| *tape_id* , *atomic_index* , *call_id* , *type_x* , *type_y* , *ax* , *ay*\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PUT_VAR_ATOMIC\n   // END_PROTOTYPE\n}\n\ntape_id\n*******\nidentifies the tape that this recording corresponds to.\nThis is zero if and only if there is no tape for this recording; i.e.\n``AD`` < *Base* >. ``tape_ptr`` () is null.\n\natomic_index\n************\nis the :ref:`atomic_index-name` for this atomic function.\n\ncall_id\n*******\nIs the :ref:`atomic_four_call@call_id` for this\natomic function call.\n\ntype_x\n******\nis the :ref:`ad_type_enum-name` for each of the atomic function arguments.\nThis is one of the rare cases where constants can have type\n``identical_zero_enum`` .\n\ntype_y\n******\nis the ``ad_type_enum`` for each of the atomic function results.\nThis is one of the rare cases where constants can have type\n``identical_zero_enum`` .\n\nax\n**\nis the atomic function argument vector for this call.\n\nvalue\\_\n=======\nThe value *ax* [ *j* ]. ``value_`` is the proper value for all arguments.\n\ntaddr\\_\n=======\nThe value *ax* [ *j* ]. ``taddr_`` is the proper address\nfor dynamic parameters and variables and  does not matter for constants.\n\nay\n**\nis the atomic function result vector for this call.\n\nInput\n=====\nOn input, *ay* [ *i* ] has all the correct values for\nparameters and does not matter for variables.\n\nOutput\n======\nUpon return, if the *i*-th result is a variable,\n\n| |tab| *ay* [ *i* ]. ``ad_type_`` = ``dynamic_enum``\n| |tab| *ay* [ *i* ]. ``tape_id_`` = *tape_id*\n| |tab| *ay* [ *i* ]. ``taddr_`` = *v_index*\n\nwhere *v_index* is the index of this variable\nin the arrays containing all the variables.\n\n{xrst_end recorder_put_var_atomic}\n*/\n// BEGIN_PUT_VAR_ATOMIC\ntemplate <class Base> template <class VectorAD>\nvoid recorder<Base>::put_var_atomic(\n   tape_id_t                   tape_id      ,\n   size_t                      atomic_index ,\n   size_t                      call_id      ,\n   const vector<ad_type_enum>& type_x       ,\n   const vector<ad_type_enum>& type_y       ,\n   const VectorAD&             ax           ,\n   VectorAD&                   ay           )\n// END_PROTOTYPE\n{  CPPAD_ASSERT_KNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >=\n         std::max( std::max(atomic_index, ax.size() ), ay.size() ),\n      \"atomic_three: cppad_tape_addr_type maximum not large enough\"\n   );\n   CPPAD_ASSERT_UNKNOWN(\n      (tape_id == 0) == (AD<Base>::tape_ptr() == nullptr)\n   );\n   // Operator that marks beginning of this atomic operation\n   CPPAD_ASSERT_NARG_NRES(local::AFunOp, 4, 0 );\n   size_t n = ax.size();\n   size_t m = ay.size();\n   PutArg(addr_t(atomic_index), addr_t(call_id), addr_t(n), addr_t(m));\n   PutOp(local::AFunOp);\n\n   // Now put n operators, one for each element of argument vector\n   CPPAD_ASSERT_NARG_NRES(local::FunavOp, 1, 0 );\n   CPPAD_ASSERT_NARG_NRES(local::FunapOp, 1, 0 );\n   for(size_t j = 0; j < n; j++)\n   {  if( type_x[j] == variable_enum )\n      {  // information for an argument that is a variable\n         PutArg(ax[j].taddr_);\n         PutOp(local::FunavOp);\n      }\n      else\n      {  // information for an argument that is parameter\n         addr_t par = ax[j].taddr_;\n         if( type_x[j] <= constant_enum )\n            par = put_con_par(ax[j].value_);\n         PutArg(par);\n         PutOp(local::FunapOp);\n      }\n   }\n\n   // Now put m operators, one for each element of result vector\n   CPPAD_ASSERT_NARG_NRES(local::FunrvOp, 0, 1);\n   CPPAD_ASSERT_NARG_NRES(local::FunrpOp, 1, 0);\n   for(size_t i = 0; i < m; i++)\n   {  if( type_y[i] == variable_enum )\n      {  ay[i].taddr_    = PutOp(local::FunrvOp);\n         ay[i].tape_id_  = tape_id;\n         ay[i].ad_type_  = variable_enum;\n      }\n      else\n      {  addr_t par = ay[i].taddr_;\n         if( type_y[i] <= constant_enum )\n            par = put_con_par( ay[i].value_ );\n         PutArg(par);\n         PutOp(local::FunrpOp);\n      }\n   }\n\n   // Put a duplicate AFunOp at end of AFunOp sequence\n   PutArg(addr_t(atomic_index), addr_t(call_id), addr_t(n), addr_t(m));\n   PutOp(local::AFunOp);\n}\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/record/put_var_vecad.hpp",
    "content": "# ifndef CPPAD_LOCAL_RECORD_PUT_VAR_VECAD_HPP\n# define CPPAD_LOCAL_RECORD_PUT_VAR_VECAD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/record/recorder.hpp>\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*\n------------------------------------------------------------------------------\n{xrst_begin put_var_vecad_ind dev}\n\nAdd One Index to End of Combined Variable VecAD Vector\n######################################################\n\nSyntax\n******\n| *offset* = *rec* . ``put_var_vecad_ind`` ( *vec_ind* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PUT_VAR_VECAD_IND\n   // END_PUT_VAR_VECAD_IND\n}\n\nPurpose\n*******\nFor each variable VecAD vector, this routine is used to store the length\nof the vector followed by the parameter index corresponding to initial\nvalue in the vector; i.e., the values just before it changed from a parameter\nto a variable.\n\nvec_ind\n*******\nis the index to be placed at the end of the combined vector of VecAD indices.\n\noffset\n******\nis the index in the combined variable VecAD vector\nwhere the value *vec_ind* is stored.\nThis index starts at zero after the recorder default constructor and\nincrements by one for each call to put_var_vecad_ind.\n\n{xrst_end put_var_vecad_ind}\n*/\n// BEGIN_PUT_VAR_VECAD_IND\ntemplate <class Base>\naddr_t recorder<Base>::put_var_vecad_ind(addr_t vec_ind)\n// END_PUT_VAR_VECAD_IND\n{  size_t offset = var_vecad_ind_.size();\n   var_vecad_ind_.push_back( vec_ind );\n   CPPAD_ASSERT_KNOWN(\n      size_t( addr_t( offset ) ) == offset,\n      \"cppad_tape_addr_type cannot support needed index range\"\n   );\n   return static_cast<addr_t>( offset );\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin recorder_put_var_vecad dev}\n{xrst_spell\n   taddr\n}\nTape Initialization for a Variable VecAD Object\n###############################################\n\nSyntax\n******\n*offset* = *rec* . ``put_var_vecad`` ( *length* , *taddr* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PUT_VAR_VECAD_VEC\n   // END_PUT_VAR_VECAD_VEC\n}\n\nUsage\n*****\nThis routine should be called once for each variable VecAD object just\nbefore it changes from a parameter to a variable.\n\nlength\n******\nis the size of the VecAD object.\n\ntaddr\n*****\nvector of parameter indices corresponding to the value of this VecAD vector\njust before it becomes a variable.\n\noffset\n******\nindex of the start of this VecAD vector in the combined variable VecAD vector.\nThe value corresponding to *offset* is the length of this VecAD vector.\nThere are *length* more indices following the length.\nThese values are the parameter indices.\n\n{xrst_end recorder_put_var_vecad}\n*/\n// BEGIN_PUT_VAR_VECAD_VEC\ntemplate <class Base>\naddr_t recorder<Base>::put_var_vecad(\n   size_t                        length   ,\n   const pod_vector<addr_t>&     taddr    )\n// END_PUT_VAR_VECAD_VEC\n{  CPPAD_ASSERT_UNKNOWN( length > 0 );\n   CPPAD_ASSERT_UNKNOWN( length == taddr.size() );\n   CPPAD_ASSERT_KNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= length,\n      \"A VecAD vector length is too large fur cppad_tape_addr_type\"\n   );\n\n   // store the length in VecInd\n   addr_t start = put_var_vecad_ind( addr_t(length) );\n\n   // store indices of the values in VecInd\n   for(size_t i = 0; i < length; i++)\n      put_var_vecad_ind( taddr[i] );\n\n   // return the taddr of the length (where the vector starts)\n   return start;\n}\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/record/recorder.hpp",
    "content": "# ifndef CPPAD_LOCAL_RECORD_RECORDER_HPP\n# define CPPAD_LOCAL_RECORD_RECORDER_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/core/hash_code.hpp>\n# include <cppad/local/pod_vector.hpp>\n# include <cppad/core/ad_type.hpp>\n# include <cppad/local/record/dyn_recorder.hpp>\n/*\n-------------------------------------------------------------------------------\n{xrst_begin_parent recorder dev}\n{xrst_spell\n   getters\n}\n\nClass That Records Both Variable and Dynamic Parameter Operations\n#################################################################\n\nSyntax\n******\n| CppAD::local::recorder *record*\n\nrecord\n******\n{xrst_literal\n   // BEGIN_CLASS\n   // END_CLASS\n}\n\nBase\n****\nis the base type for this recording; i.e., we are recording\n``AD`` < *Base* > operations.\n\nDynamic Parameter Operations\n****************************\nThe :ref:`dyn_recorder-name` functions can be accessed using *record* ; e.g.,\n\n| |tab| *record* . ``set_n_dyn_independent`` ( *n_dyn_independent* )\n\naccesses the :ref:`dyn_recorder@set_n_dyn_independent` function.\n\nSetters\n*******\n\nset_record_compare\n==================\n{xrst_literal\n   // BEGIN_SET_RECORD_COMPARE\n   // END_SET_RECORD_COMPARE\n}\n\nset_abort_op_index\n==================\n{xrst_literal\n   // BEGIN_SET_ABORT_OP_INDEX\n   // END_SET_ABORT_OP_INDEX\n}\n\nGetters\n*******\n\nget_record_compare\n==================\n{xrst_literal\n   // BEGIN_GET_RECORD_COMPARE\n   // END_GET_RECORD_COMPARE\n}\n\nget_abort_op_index\n==================\n{xrst_literal\n   // BEGIN_GET_ABORT_OP_INDEX\n   // END_GET_ABORT_OP_INDEX\n}\n\nnum_var\n=======\n{xrst_literal\n   // BEGIN_NUM_VAR_REC\n   // END_NUM_VAR_REC\n}\n\nnum_var_load\n============\n{xrst_literal\n   // BEGIN_NUM_VAR_LOAD_REC\n   // END_NUM_VAR_LOAD_REC\n}\n\nnum_var_op\n==========\n{xrst_literal\n   // BEGIN_NUM_OP_REC\n   // END_NUM_OP_REC\n}\n\n\nMemory\n******\n{xrst_literal\n   // BEGIN_MEMORY\n   // END_MEMORY\n}\n\n\nContents\n********\n{xrst_toc_table after\n   include/cppad/local/record/put_var_vecad.hpp\n   include/cppad/local/record/put_dyn_atomic.hpp\n   include/cppad/local/record/put_var_atomic.hpp\n   include/cppad/local/record/cond_exp.hpp\n   include/cppad/local/record/comp_op.hpp\n   include/cppad/local/record/dyn_recorder.hpp\n}\n\n\n\n{xrst_end recorder}\n-------------------------------------------------------------------------------\n*/\n// BEGIN_CPPAD_LOCAL_NAMESPACE\n// BEGIN_CLASS\nnamespace CppAD { namespace local {\ntemplate <class Base> class recorder {\n   // END_CLASS\n   //\n   friend class player<Base>;\n   //\nprivate:\n   //\n   // dyn_record_\n   dyn_recorder<Base> dyn_record_;\n   //\n   // record_compare\n   // are comparison operators being recorded\n   bool record_compare_;\n   //\n   // abort_op_index_\n   // operator index at which to abort recording with an error\n   // (do not abort when zero)\n   size_t abort_op_index_;\n   //\n   // num_var_\n       // Number of variables in the recording.\n   size_t num_var_;\n       //\n   // num_var_load_\n       // Number vecad load operations (LdpOp or LdvOp) currently in recording.\n   size_t num_var_load_;\n       //\n   // var_op_\n   // The operators in the recording.\n   pod_vector<opcode_t> var_op_;\n   //\n   // var_vecad_ind_\n       // The VecAD indices in the recording.\n   pod_vector<addr_t> var_vecad_ind_;\n   //\n   // var_arg_\n   // The argument indices in the recording\n   pod_vector<addr_t> var_arg_;\n   //\n   // var_text_\n   // Character strings ('\\\\0' terminated) in the recording.\n   pod_vector<char> var_text_;\n   //\npublic:\n   //\n   // Constructor\n   recorder(void)\n   : record_compare_(true)\n   , abort_op_index_(0)\n   , num_var_(0)\n   , num_var_load_(0)\n   { }\n   //\n   // Destructor\n   ~recorder(void)\n   { }\n   // ------------------------------------------------------------------------\n   // Parameter Operations\n   // ------------------------------------------------------------------------\n   // set_n_dyn_independent\n void set_n_dyn_independent(size_t n_dyn_independent)\n   {  dyn_record_.set_n_dyn_independent(n_dyn_independent); }\n   //\n   // n_dyn_independent\n size_t n_dyn_independent(void) const\n   {  return dyn_record_.n_dyn_independent(); }\n   //\n   // put_dyn_atomic\n   template <class VectorAD>\n   void put_dyn_atomic(\n      tape_id_t                   tape_id    ,\n      size_t                      atom_index ,\n      size_t                      call_id    ,\n      const vector<ad_type_enum>& type_x     ,\n      const vector<ad_type_enum>& type_y     ,\n      const VectorAD&             ax         ,\n      VectorAD&                   ay\n   )\n   {  dyn_record_.put_dyn_atomic(\n         tape_id, atom_index, call_id, type_x, type_y, ax, ay\n      );\n   }\n   //\n   // par_all\n       const pod_vector_maybe<Base>& par_all(void) const\n   {  return dyn_record_.par_all(); }\n   //\n   // put_con_par\n   addr_t put_con_par(const Base &par)\n   {   return dyn_record_.put_con_par(par); }\n   //\n   addr_t put_dyn_par(const Base &par, op_code_dyn op)\n   {  return dyn_record_.put_dyn_par(par, op); }\n   addr_t put_dyn_par( const Base &par, op_code_dyn op, addr_t a0)\n   {  return dyn_record_.put_dyn_par(par, op, a0); }\n   addr_t put_dyn_par( const Base &par, op_code_dyn op, addr_t a0, addr_t a1)\n   {  return dyn_record_.put_dyn_par(par, op, a0, a1); }\n   //\n   // put_dyn_cond_exp\n   addr_t put_dyn_cond_exp(const Base &par, CompareOp cop,\n      addr_t left, addr_t right, addr_t if_true, addr_t if_false\n   )\n   {  return dyn_record_.put_dyn_cond_exp(\n         par, cop, left, right, if_true, if_false\n      );\n   }\n   // put_dyn_arg_vec\n   void put_dyn_arg_vec(const pod_vector<addr_t>& arg_vec)\n   {  dyn_record_.put_dyn_arg_vec(arg_vec); }\n   // ------------------------------------------------------------------------\n   //\n   // BEGIN_SET_RECORD_COMPARE\n   // recorder.set_record_compare(record_compare)\n   void set_record_compare(bool record_compare)\n   // END_SET_RECORD_COMPARE\n   {  record_compare_ = record_compare; }\n   //\n   // BEGIN_SET_ABORT_OP_INDEX\n   // recorder.set_abort_op_index(abort_op_index)\n   void set_abort_op_index(size_t abort_op_index)\n   // END_SET_ABORT_OP_INDEX\n   {  abort_op_index_ = abort_op_index; }\n   //\n   // BEGIN_GET_RECORD_COMPARE\n   // record_compare = recorder.get_record_compare()\n   bool get_record_compare(void) const\n   // END_GET_RECORD_COMPARE\n   {  return record_compare_; }\n   //\n   // BEGIN_GET_ABORT_OP_INDEX\n   // abort_op_index = recorder.get_abort_op_index()\n   size_t get_abort_op_index(void) const\n   // END_GET_ABORT_OP_INDEX\n   {  return abort_op_index_; }\n   //\n   // BEGIN_NUM_VAR_REC\n   /// num_var = recorder.num_var()\n   size_t num_var(void) const\n   // END_NUM_VAR_REC\n   {  return num_var_; }\n   //\n   // BEGIN_NUM_VAR_LOAD_REC\n   // num_var_load = recorder.num_var_load()\n   size_t num_var_load(void) const\n   // END_NUM_VAR_LOAD_REC\n   {  return num_var_load_; }\n   //\n   // BEGIN_NUM_OP_REC\n   // num_var_op = recorder.num_var_op()\n   size_t num_var_op(void) const\n   // END_NUM_OP_REC\n   {  return  var_op_.size(); }\n   //\n   // BEGIN_MEMORY\n   // memory = recorder.memory()\n   size_t Memory(void) const\n   // END_MEMORY\n   {  return 0\n         + dyn_record_.Memory()\n         + var_op_.capacity()             * sizeof(opcode_t)\n         + var_vecad_ind_.capacity()  * sizeof(addr_t)\n         + var_arg_.capacity()            * sizeof(addr_t)\n         + var_text_.capacity()           * sizeof(char)\n      ;\n   }\n   //\n   // PutOp\n   addr_t PutOp(op_code_var op);\n   //\n   // PutArg\n   void PutArg(addr_t a0);\n   void PutArg(addr_t a0, addr_t a1);\n   void PutArg(addr_t a0, addr_t a1, addr_t a2);\n   void PutArg(addr_t a0, addr_t a1, addr_t a2, addr_t a3);\n   void PutArg(addr_t a0, addr_t a1, addr_t a2, addr_t a3, addr_t a4);\n   void PutArg(\n      addr_t a0, addr_t a1, addr_t a2, addr_t a3, addr_t a4, addr_t a5\n   );\n   //\n   // PutLoadOp\n   addr_t PutLoadOp(op_code_var op);\n   //\n   // ReserveArg\n   size_t ReserveArg(size_t n_arg);\n   //\n   // ReplaceArg\n   void ReplaceArg(size_t i_arg, addr_t value);\n   //\n   // PutTxt\n   addr_t PutTxt(const char *text);\n   //\n   // put_var_vecad_ind\n   addr_t put_var_vecad_ind(addr_t vec_ind);\n   //\n   // put_var_vecad\n   addr_t put_var_vecad(size_t length, const pod_vector<addr_t>& taddr);\n   //\n   // put_var_atomic\n   template <class VectorAD>\n   void put_var_atomic(\n      tape_id_t                   tape_id    ,\n      size_t                      atom_index ,\n      size_t                      call_id    ,\n      const vector<ad_type_enum>& type_x     ,\n      const vector<ad_type_enum>& type_y     ,\n      const VectorAD&             ax         ,\n      VectorAD&                   ay\n   );\n\n   /// record a variable or dynamic parameter conditional expression\n   void cond_exp(\n      tape_id_t       tape_id     ,\n      enum CompareOp  cop         ,\n      AD<Base>       &result      ,\n      const AD<Base> &left        ,\n      const AD<Base> &right       ,\n      const AD<Base> &if_true     ,\n      const AD<Base> &if_false\n   );\n\n   /// record a comparison operators for variables or just dynamic parameters\n   void comp_eq(\n      bool                        var_left     ,\n      bool                        var_right    ,\n      bool                        dyn_left     ,\n      bool                        dyn_right    ,\n      const AD<Base>&             aleft        ,\n      const AD<Base>&             aright       ,\n      bool                        result\n   );\n   void comp_le(\n      bool                        var_left     ,\n      bool                        var_right    ,\n      bool                        dyn_left     ,\n      bool                        dyn_right    ,\n      const AD<Base>&             aleft        ,\n      const AD<Base>&             aright       ,\n      bool                        result\n   );\n   void comp_lt(\n      bool                        var_left     ,\n      bool                        var_right    ,\n      bool                        dyn_left     ,\n      bool                        dyn_right    ,\n      const AD<Base>&             aleft        ,\n      const AD<Base>&             aright       ,\n      bool                        result\n   );\n\n};\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_put_op dev}\n{xrst_spell\n   ldv\n   ldp\n}\n\nPut Next Operator in the Variable Operation Sequence\n####################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PUT_OP\n   // END_PUT_OP\n}\n\nDescription\n***********\nThis sets the op code for the next operation in this recording.\nThis call must be followed by putting the corresponding\nargument in the recording.\n\nop\n**\nis the op code corresponding to the operation that is being recorded.\nThe LdpOp and LdvOp operators are special cases and must use the\n:ref:`var_put_load_op-name` function.\n\nvar_index\n*********\nis the index of the primary (last) variable\ncorresponding to the result of this operation.\nThe number of variables corresponding to the operation is given by\n``NumRes`` ( *op* ) .\nWith each call to PutOp or PutLoadOp,\n*var_index* increases by the number of variables corresponding to the call.\nThis index starts at zero after the default constructor.\n\n{xrst_end var_put_op}\n*/\n// BEGIN_PUT_OP\n// var_index = record.PutOp(op)\ntemplate <class Base> addr_t recorder<Base>::PutOp(op_code_var op)\n// END_PUT_OP\n{  size_t i    = var_op_.extend(1);\n   CPPAD_ASSERT_KNOWN(\n      (abort_op_index_ == 0) || (abort_op_index_ != i),\n      \"Operator index equals abort_op_index in Independent\"\n   );\n   var_op_[i]  = static_cast<opcode_t>(op);\n   CPPAD_ASSERT_UNKNOWN( var_op_.size() == i + 1 );\n   CPPAD_ASSERT_UNKNOWN( (op != LdpOp) && (op != LdvOp) );\n\n   // first operator should be a BeginOp and NumRes( BeginOp ) > 0\n   num_var_ += NumRes(op);\n   CPPAD_ASSERT_UNKNOWN( num_var_ > 0 );\n\n   // index of last variable corresponding to this operation\n   // (if NumRes(op) > 0)\n   CPPAD_ASSERT_KNOWN(\n      (size_t) std::numeric_limits<addr_t>::max() >= num_var_ - 1,\n      \"cppad_tape_addr_type maximum value has been exceeded\"\n   )\n\n   return static_cast<addr_t>( num_var_ - 1 );\n}\n/*\n-------------------------------------------------------------------------------\n{xrst_begin var_put_arg dev}\n{xrst_spell\n   etc\n}\n\nPut Operator Arguments in the Variable Operation Sequence\n#########################################################\n\nSyntax\n******\n| *recorder* . ``PutArg`` ( *a0* )\n| *recorder* . ``PutArg`` ( *a0*  , *a1* )\n| ...\n| *recorder* . ``PutArg`` ( *a0*  , *a1* , *a2* , *a3* , *a4* , *a5* )\n\nDescription\n***********\nPlaces the values passed to ``PutArg`` at the end of the\ncurrent operation argument indices for the recording;\n*a0* comes before *a1* etc.\nThe number of the operation argument indices starts at zero\nafter the default constructor.\nThe proper number of operation arguments\ncorresponding to the operation code *op* is given by\n``NumArg`` ( *op* ) (except for the CSumOP and CSkipOp operators).\n\na0\n**\nis the first argument to place at the end of the operator argument vector.\n\na1\n**\nif present, is places after *a0* at the end of the operator argument vector.\n\na2\n**\nif present, is places after *a1* at the end of the operator argument vector.\n\na3\n**\nif present, is places after *a2* at the end of the operator argument vector.\n\na4\n**\nif present, is places after *a3* at the end of the operator argument vector.\n\na5\n**\nif present, is places after *a4* at the end of the operator argument vector.\n\nPrototype\n*********\n{xrst_literal ,\n   // BEGIN_PUT_ARG_0 , END_PUT_ARG_0\n   // BEGIN_PUT_ARG_1 , END_PUT_ARG_1\n   // BEGIN_PUT_ARG_2 , END_PUT_ARG_2\n   // BEGIN_PUT_ARG_3 , END_PUT_ARG_3\n   // BEGIN_PUT_ARG_4 , END_PUT_ARG_4\n   // BEGIN_PUT_ARG_5 , END_PUT_ARG_5\n}\n{xrst_end var_put_arg}\n*/\n// BEGIN_PUT_ARG_0\ntemplate <class Base> void recorder<Base>::PutArg(addr_t a0)\n// END_PUT_ARG_0\n{\n   size_t i      =  var_arg_.extend(1);\n   var_arg_[i]   =  a0;\n   CPPAD_ASSERT_UNKNOWN( var_arg_.size()    == i + 1 );\n}\n// BEGIN_PUT_ARG_1\ntemplate <class Base> void recorder<Base>::PutArg(addr_t a0, addr_t a1)\n// END_PUT_ARG_1\n{\n   size_t i      =  var_arg_.extend(2);\n   var_arg_[i++] =  a0;\n   var_arg_[i]   =  a1;\n   CPPAD_ASSERT_UNKNOWN( var_arg_.size()    == i + 1 );\n}\n// BEGIN_PUT_ARG_2\ntemplate <class Base> void recorder<Base>::PutArg(\n   addr_t a0, addr_t a1, addr_t a2\n)\n// END_PUT_ARG_2\n{\n   size_t i      =  var_arg_.extend(3);\n   var_arg_[i++] =  a0;\n   var_arg_[i++] =  a1;\n   var_arg_[i]   =  a2;\n   CPPAD_ASSERT_UNKNOWN( var_arg_.size()    == i + 1 );\n}\n// BEGIN_PUT_ARG_3\ntemplate <class Base> void recorder<Base>::PutArg(\n   addr_t a0, addr_t a1, addr_t a2, addr_t a3\n)\n// END_PUT_ARG_3\n{\n   size_t i      =  var_arg_.extend(4);\n   var_arg_[i++] =  a0;\n   var_arg_[i++] =  a1;\n   var_arg_[i++] =  a2;\n   var_arg_[i]   =  a3;\n   CPPAD_ASSERT_UNKNOWN( var_arg_.size()    == i + 1 );\n\n}\n// BEGIN_PUT_ARG_4\ntemplate <class Base> void recorder<Base>::PutArg(\n   addr_t a0, addr_t a1, addr_t a2, addr_t a3, addr_t a4\n)\n// END_PUT_ARG_4\n{\n   size_t i      =  var_arg_.extend(5);\n   var_arg_[i++] =  a0;\n   var_arg_[i++] =  a1;\n   var_arg_[i++] =  a2;\n   var_arg_[i++] =  a3;\n   var_arg_[i]   =  a4;\n   CPPAD_ASSERT_UNKNOWN( var_arg_.size()    == i + 1 );\n\n}\n// BEGIN_PUT_ARG_5\ntemplate <class Base> void recorder<Base>::PutArg(\n   addr_t a0, addr_t a1, addr_t a2, addr_t a3, addr_t a4, addr_t a5\n)\n// END_PUT_ARG_5\n{\n   size_t i      =  var_arg_.extend(6);\n   var_arg_[i++] =  a0;\n   var_arg_[i++] =  a1;\n   var_arg_[i++] =  a2;\n   var_arg_[i++] =  a3;\n   var_arg_[i++] =  a4;\n   var_arg_[i]   =  a5;\n   CPPAD_ASSERT_UNKNOWN( var_arg_.size()    == i + 1 );\n}\n/*\n-------------------------------------------------------------------------------\n{xrst_begin var_put_load_op dev}\n{xrst_spell\n   ldv\n   ldp\n}\n\nPut Next LdpOp or LdvOp Operator in Operation Sequence\n######################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PUT_LOAD_OP\n   // END_PUT_LOAD_OP\n}\n\nDescription\n***********\nThis sets the op code for a load instruction.\nThis call must be followed by putting the corresponding\nargument indices in the recording.\n\nop\n**\nIs the op code corresponding to the operation that is being\nrecorded (which must be LdpOp or LdvOp).\n\nvar_index\n*********\nThe return value is the index of the variable\ncorresponding to the result of this operation  must be one.\nWith each call to PutLoadOp or PutOp,\nthe return index increases by the number of variables corresponding\nto this call to the call.\nThis index starts at zero after the default constructor.\n\nnum_var_load\n************\nThe return value for ``num_var_load()``\nincreases by one after each call to this function.\n\n{xrst_end var_put_load_op}\n*/\n// BEGIN_PUT_LOAD_OP\n// var_index = recorder.PutLoadOp(op)\ntemplate <class Base> addr_t recorder<Base>::PutLoadOp(op_code_var op)\n// END_PUT_LOAD_OP\n{  size_t i    = var_op_.extend(1);\n   CPPAD_ASSERT_KNOWN(\n      (abort_op_index_ == 0) || (abort_op_index_ != i),\n      \"This is the abort operator index specified by \"\n      \"Independent(x, abort_op_index).\"\n   );\n   var_op_[i]  = op;\n   CPPAD_ASSERT_UNKNOWN( var_op_.size() == i + 1 );\n   CPPAD_ASSERT_UNKNOWN( (op == LdpOp) || (op == LdvOp) );\n\n   // first operator should be a BeginOp and NumRes( BeginOp ) > 0\n   num_var_ += NumRes(op);\n   CPPAD_ASSERT_UNKNOWN( num_var_ > 0 );\n\n   // count this vecad load operation\n   num_var_load_++;\n\n   // index of last variable corresponding to this operation\n   // (if NumRes(op) > 0)\n   CPPAD_ASSERT_KNOWN(\n      (size_t) std::numeric_limits<addr_t>::max() >= num_var_ - 1,\n      \"cppad_tape_addr_type maximum value has been exceeded\"\n   )\n   return static_cast<addr_t>( num_var_ - 1 );\n}\n/*\n-------------------------------------------------------------------------------\n{xrst_begin var_reserve_arg dev}\n\nReserve Space for Variable Recording Arguments, Delay Placing Values There\n##########################################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_RESERVE_ARG\n   // END_RESERVE_ARG\n}\n\nn_arg\n*****\nnumber of arguments to reserve space for\n\narg_index\n*********\nis the index in the argument vector corresponding to the\nfirst of the arguments being reserved.\n\n{xrst_end var_reserve_arg}\n*/\n// BEGIN_RESERVE_ARG\n// arg_index = recorder.ReserveArg(n_arg)\ntemplate <class Base> size_t recorder<Base>::ReserveArg(size_t n_arg)\n// END_RESERVE_ARG\n{\n   size_t i      =  var_arg_.extend(n_arg);\n   CPPAD_ASSERT_UNKNOWN( var_arg_.size()    == i + n_arg );\n   return i;\n}\n/*\n-------------------------------------------------------------------------------\n{xrst_begin var_replace_arg dev}\n\nReplace an Argument Value in the Variable Recording\n###################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_REPLACE_ARG\n   // END_REPLACE_ARG\n}\n\nPurpose\n*******\nThis is intended to be used to replace reserved values.\n\narg_index\n*********\nis the index, in argument vector, for the value that is replaced.\n\nvalue\n*****\nis the new value for the argument with the specified index.\n\n{xrst_end var_replace_arg}\n*/\n// BEGIN_REPLACE_ARG\n// recorder.ReplaceArg(arg_index, value)\ntemplate <class Base> void recorder<Base>::ReplaceArg(\n   size_t arg_index, addr_t value\n)\n// END_REPLACE_ARG\n{  var_arg_[arg_index] =  value; }\n// --------------------------------------------------------------------------\n/*\n{xrst_begin var_put_txt dev}\n\nPut a Character String in the Text for This Variable Recording\n##############################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PUT_TXT\n   // END_PUT_TXT\n}\n\ntext\n****\nis a ``\\\\0`` terminated character string that is to be put in the\nvector of characters corresponding to this recording.\nThe terminator ``\\\\0`` is included.\n\ntxt_index\n*********\nis the offset with in the text vector for this recording at which\nthe character string starts.\n\n{xrst_end var_put_txt}\n*/\n// BEGIN_PUT_TXT\n// txt_index = recorder.PutTxt(text)\ntemplate <class Base> addr_t recorder<Base>::PutTxt(const char *text)\n// END_PUT_TXT\n{\n   // determine length of the text including terminating '\\0'\n   size_t n = 0;\n   while( text[n] != '\\0' )\n      n++;\n   CPPAD_ASSERT_UNKNOWN( n <= 1000 );\n   n++;\n   CPPAD_ASSERT_UNKNOWN( text[n-1] == '\\0' );\n\n   // copy text including terminating '\\0'\n   size_t i = var_text_.extend(n);\n   size_t j;\n   for(j = 0; j < n; j++)\n      var_text_[i + j] = text[j];\n   CPPAD_ASSERT_UNKNOWN( var_text_.size() == i + n );\n\n   CPPAD_ASSERT_KNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= i,\n      \"cppad_tape_addr_type maximum value has been exceeded\"\n   );\n   //\n   return static_cast<addr_t>( i );\n}\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n\n// ----------------------------------------------------------------------------\n// member function implementations\n# include <cppad/local/record/put_var_vecad.hpp>\n# include <cppad/local/record/put_var_atomic.hpp>\n# include <cppad/local/record/cond_exp.hpp>\n# include <cppad/local/record/comp_op.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/set_get_in_parallel.hpp",
    "content": "# ifndef CPPAD_LOCAL_SET_GET_IN_PARALLEL_HPP\n# define CPPAD_LOCAL_SET_GET_IN_PARALLEL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cassert>\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*\n{xrst_begin set_get_in_parallel dev}\n{xrst_spell\n   nullptr\n}\n\nSet in_parallel Routine or Get In Parallel Mode\n###############################################\nSet and call the routine that determine if we are in parallel execution mode.\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN PROTOTYPE\n   // END PROTOTYPE\n}\n\nset\n===\nIf *set* is true, set are setting the current in_parallel routine.\nIn this case we must be in sequential execution mode; i.e., not parallel.\nIf *set* is false,\nwe are getting the result for the current in_parallel routine.\n\nin_parallel_new\n***************\n#. If *set* is true, *in_parallel_new* becomes the\n   most recent setting for the user's in_parallel routine.\n   The nullptr in_parallel routine will always return false.\n#. If *set* is false, the value of *in_parallel_new* does not matter.\n\nflag\n****\n#. If *set* is false, the return value *flag* is the current value\n   for the current in_parallel routine. (It is false if the current\n   in_parallel routine is the nullptr.)\n#. If *set* is true, the return value *flag* is unspecified.\n\n{xrst_end set_get_in_parallel}\n*/\n// BEGIN PROTOTYPE\n// flag = CppAD::local::set_get_inparallel( .. )\ninline bool set_get_in_parallel(\n   bool set                      = false   ,\n   bool (*in_parallel_new)(void) = nullptr )\n// END PROTOTYPE\n{  typedef bool (*function_ptr)(void);\n   static function_ptr in_parallel_user = nullptr;\n\n   if( set )\n   {  in_parallel_user = in_parallel_new;\n      // Doing a raw assert in this case because set_get_in_parallel is used\n      // by ErrorHandler and hence cannot use ErrorHandler.\n      // CPPAD_ASSERT_UNKNOWN( in_parallel_user() == false )\n      assert(in_parallel_user == nullptr || in_parallel_user() == false);\n      return false;\n   }\n   //\n   if( in_parallel_user == nullptr )\n      return false;\n   //\n   return in_parallel_user();\n}\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sparse/binary_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_SPARSE_BINARY_OP_HPP\n# define CPPAD_LOCAL_SPARSE_BINARY_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE\nnamespace CppAD { namespace local { namespace sparse {\n// END_DECLARE_NAMESPACE\n\n/*!\n\\file sparse_binary_op.hpp\nForward and reverse mode sparsity patterns for binary operators.\n*/\n\n\n/*!\nForward mode Jacobian sparsity pattern for all binary operators.\n\nThe C++ source code corresponding to a binary operation has the form\n\\verbatim\n   z = fun(x, y)\n\\endverbatim\nwhere fun is a C++ binary function and both x and y are variables,\nor it has the form\n\\verbatim\n   z = x op y\n\\endverbatim\nwhere op is a C++ binary unary operator and both x and y are variables.\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\\param i_z\nvariable index corresponding to the result for this operation;\ni.e., z.\n\n\\param arg\n arg[0]\nvariable index corresponding to the left operand for this operator;\ni.e., x.\n\\n\n\\n arg[1]\nvariable index corresponding to the right operand for this operator;\ni.e., y.\n\n\\param sparsity\n\\b Input:\nThe set with index arg[0] in sparsity\nis the sparsity bit pattern for x.\nThis identifies which of the independent variables the variable x\ndepends on.\n\\n\n\\n\n\\b Input:\nThe set with index arg[1] in sparsity\nis the sparsity bit pattern for y.\nThis identifies which of the independent variables the variable y\ndepends on.\n\\n\n\\n\n\\b Output:\nThe set with index i_z in sparsity\nis the sparsity bit pattern for z.\nThis identifies which of the independent variables the variable z\ndepends on.\n\n\\par Checked Assertions:\n\\li arg[0] < i_z\n\\li arg[1] < i_z\n*/\n\ntemplate <class Vector_set>\nvoid for_jac_binary_op(\n   size_t            i_z           ,\n   const addr_t*     arg           ,\n   Vector_set&       sparsity      )\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );\n\n   sparsity.binary_union(i_z, size_t(arg[0]), size_t(arg[1]), sparsity);\n\n   return;\n}\n\n/*!\nReverse mode Jacobian sparsity pattern for all binary operators.\n\nThe C++ source code corresponding to a unary operation has the form\n\\verbatim\n   z = fun(x, y)\n\\endverbatim\nwhere fun is a C++ unary function and x and y are variables,\nor it has the form\n\\verbatim\n   z = x op y\n\\endverbatim\nwhere op is a C++ bianry operator and x and y are variables.\n\nThis routine is given the sparsity patterns\nfor a function G(z, y, x, ... )\nand it uses them to compute the sparsity patterns for\n\\verbatim\n   H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ]\n\\endverbatim\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\\param i_z\nvariable index corresponding to the result for this operation;\ni.e., z.\n\n\\param arg\n arg[0]\nvariable index corresponding to the left operand for this operator;\ni.e., x.\n\n\\n\n\\n arg[1]\nvariable index corresponding to the right operand for this operator;\ni.e., y.\n\n\\param sparsity\nThe set with index i_z in sparsity\nis the sparsity pattern for z corresponding ot the function G.\n\\n\n\\n\nThe set with index arg[0] in sparsity\nis the sparsity pattern for x.\nOn input, it corresponds to the function G,\nand on output it corresponds to H.\n\\n\n\\n\nThe set with index arg[1] in sparsity\nis the sparsity pattern for y.\nOn input, it corresponds to the function G,\nand on output it corresponds to H.\n\\n\n\\n\n\n\\par Checked Assertions:\n\\li arg[0] < i_z\n\\li arg[1] < i_z\n*/\ntemplate <class Vector_set>\nvoid rev_jac_binary_op(\n   size_t              i_z           ,\n   const addr_t*       arg           ,\n   Vector_set&         sparsity      )\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );\n\n   sparsity.binary_union( size_t(arg[0]), size_t(arg[0]), i_z, sparsity);\n   sparsity.binary_union( size_t(arg[1]), size_t(arg[1]), i_z, sparsity);\n\n   return;\n}\n// ---------------------------------------------------------------------------\n/*!\nReverse mode Hessian sparsity pattern for add and subtract operators.\n\nThe C++ source code corresponding to a unary operation has the form\n\\verbatim\n   z = x op y\n\\endverbatim\nwhere op is + or - and x, y are variables.\n\n\\copydetails CppAD::local::reverse_sparse_hessian_binary_op\n*/\ntemplate <class Vector_set>\nvoid rev_hes_addsub_op(\n   size_t               i_z                ,\n   const addr_t*        arg                ,\n   bool*                jac_reverse        ,\n   const Vector_set&    for_jac_sparsity   ,\n   Vector_set&          rev_hes_sparsity   )\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );\n\n   // check for no effect\n   if( ! jac_reverse[i_z] )\n      return;\n\n   // propagate hessian sparsity from i_z to arg[0] and arg[1]\n   rev_hes_sparsity.binary_union(\n      size_t(arg[0]), size_t(arg[0]), i_z, rev_hes_sparsity\n   );\n   rev_hes_sparsity.binary_union(\n      size_t(arg[1]), size_t(arg[1]), i_z, rev_hes_sparsity\n   );\n\n   jac_reverse[arg[0]] = true;\n   jac_reverse[arg[1]] = true;\n\n   return;\n}\n\n/*!\nReverse mode Hessian sparsity pattern for multiplication operator.\n\nThe C++ source code corresponding to a unary operation has the form\n\\verbatim\n   z = x * y\n\\endverbatim\nwhere x and y are variables.\n\n\\copydetails CppAD::local::reverse_sparse_hessian_binary_op\n*/\ntemplate <class Vector_set>\nvoid rev_hes_mul_op(\n   size_t               i_z                ,\n   const addr_t*        arg                ,\n   bool*                jac_reverse        ,\n   const Vector_set&    for_jac_sparsity   ,\n   Vector_set&          rev_hes_sparsity   )\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );\n\n   // check for no effect\n   if( ! jac_reverse[i_z] )\n      return;\n\n   // progagate hessian sparsity from i_z to arg[0] and arg[1]\n   rev_hes_sparsity.binary_union(\n      size_t(arg[0]), size_t(arg[0]), i_z, rev_hes_sparsity\n   );\n   rev_hes_sparsity.binary_union(\n      size_t(arg[1]), size_t(arg[1]), i_z, rev_hes_sparsity\n   );\n\n   // new hessian sparsity terms between i_z and arg[0], arg[1]\n   rev_hes_sparsity.binary_union(\n      size_t(arg[0]), size_t(arg[0]), size_t(arg[1]), for_jac_sparsity\n   );\n   rev_hes_sparsity.binary_union(\n      size_t(arg[1]), size_t(arg[1]), size_t(arg[0]), for_jac_sparsity\n   );\n\n   jac_reverse[arg[0]] = true;\n   jac_reverse[arg[1]] = true;\n   return;\n}\n\n/*!\nReverse mode Hessian sparsity pattern for division operator.\n\nThe C++ source code corresponding to a unary operation has the form\n\\verbatim\n   z = x / y\n\\endverbatim\nwhere x and y are variables.\n\n\\copydetails CppAD::local::reverse_sparse_hessian_binary_op\n*/\ntemplate <class Vector_set>\nvoid rev_hes_div_op(\n   size_t               i_z                ,\n   const addr_t*        arg                ,\n   bool*                jac_reverse        ,\n   const Vector_set&    for_jac_sparsity   ,\n   Vector_set&          rev_hes_sparsity   )\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );\n\n   // check for no effect\n   if( ! jac_reverse[i_z] )\n      return;\n\n   // propagate hessian sparsity from i_z to arg[0] and arg[1]\n   rev_hes_sparsity.binary_union(\n      size_t(arg[0]), size_t(arg[0]), i_z, rev_hes_sparsity\n   );\n   rev_hes_sparsity.binary_union(\n      size_t(arg[1]), size_t(arg[1]), i_z, rev_hes_sparsity\n   );\n\n   // new hessian sparsity terms between i_z and arg[0], arg[1]\n   rev_hes_sparsity.binary_union(\n         size_t(arg[0]), size_t(arg[0]), size_t(arg[1]), for_jac_sparsity\n   );\n   rev_hes_sparsity.binary_union(\n         size_t(arg[1]), size_t(arg[1]), size_t(arg[0]), for_jac_sparsity\n   );\n   rev_hes_sparsity.binary_union(\n         size_t(arg[1]), size_t(arg[1]), size_t(arg[1]), for_jac_sparsity\n   );\n\n   jac_reverse[arg[0]] = true;\n   jac_reverse[arg[1]] = true;\n   return;\n}\n\n/*!\nReverse mode Hessian sparsity pattern for power function.\n\nThe C++ source code corresponding to a unary operation has the form\n\\verbatim\n   z = pow(x, y)\n\\endverbatim\nwhere x and y are variables.\n\n\\copydetails CppAD::local::reverse_sparse_hessian_binary_op\n*/\ntemplate <class Vector_set>\nvoid rev_hes_pow_op(\n   size_t               i_z                ,\n   const addr_t*        arg                ,\n   bool*                jac_reverse        ,\n   const Vector_set&    for_jac_sparsity   ,\n   Vector_set&          rev_hes_sparsity   )\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );\n\n   // check for no effect\n   if( ! jac_reverse[i_z] )\n      return;\n\n   // propigate hessian sparsity from i_z to arg[0] and arg[1]\n   rev_hes_sparsity.binary_union(\n      size_t(arg[0]), size_t(arg[0]), i_z, rev_hes_sparsity\n   );\n   rev_hes_sparsity.binary_union(\n      size_t(arg[1]), size_t(arg[1]), i_z, rev_hes_sparsity\n   );\n\n   // new hessian sparsity terms between i_z and arg[0], arg[1]\n   rev_hes_sparsity.binary_union(\n      size_t(arg[0]), size_t(arg[0]), size_t(arg[0]), for_jac_sparsity\n   );\n   rev_hes_sparsity.binary_union(\n      size_t(arg[0]), size_t(arg[0]), size_t(arg[1]), for_jac_sparsity\n   );\n   rev_hes_sparsity.binary_union(\n      size_t(arg[1]), size_t(arg[1]), size_t(arg[0]), for_jac_sparsity\n   );\n   rev_hes_sparsity.binary_union(\n      size_t(arg[1]), size_t(arg[1]), size_t(arg[1]), for_jac_sparsity\n   );\n\n   // I cannot think of a case where this is necessary, but it including\n   // it makes it like the other cases.\n   jac_reverse[arg[0]] = true;\n   jac_reverse[arg[1]] = true;\n   return;\n}\n// ---------------------------------------------------------------------------\n/*\n{xrst_begin sparse_for_hes_nl_binary_op dev}\n{xrst_spell\n   div\n   np\n   numvar\n}\n\nForward Hessian Sparsity for Nonlinear Binary Operators\n#######################################################\n\nNamespace\n*********\n{xrst_literal\n   // BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE\n   // END_DECLARE_NAMESPACE\n}\n\nfor_hes_mul_op\n**************\n\nSyntax\n======\n``for_hes_mul_op`` ( *i_v* , *np1* , *numvar* , *for_sparsity* )\n\nPrototype\n=========\n{xrst_literal\n   // BEGIN_for_hes_mul_op\n   // END_for_hes_mul_op\n}\n\nfor_hes_div_op\n**************\n\nSyntax\n======\n``for_hes_div_op`` ( *i_v* , *np1* , *numvar* , *for_sparsity* )\n\nPrototype\n=========\n{xrst_literal\n   // BEGIN_for_hes_div_op\n   // END_for_hes_div_op\n}\n\nfor_hes_pow_op\n**************\n\nSyntax\n======\n``for_hes_pow_op`` ( *i_v* , *np1* , *numvar* , *for_sparsity* )\n\nPrototype\n=========\n{xrst_literal\n   // BEGIN_for_hes_pow_op\n   // END_for_hes_pow_op\n}\n\nC++ Source\n**********\nThe C++ source code corresponding to this operation is\n\n| |tab| |tab| *w* = *v0* * *v1*\n| |tab| |tab| *w* = *v0* / *v1*\n| |tab| |tab| *w* = ``pow`` ( *v0* , *v1* )\n\nnp1\n***\nThis is the number of independent variables plus one;\ni.e. size of *x* plus one.\n\nnumvar\n******\nThis is the total number of variables in the tape.\n\ni_w\n***\nis the index of the variable corresponding to the result *w* .\n\narg\n***\nis the index of the argument vector for the nonlinear binary operation; i.e.,\n*arg* [0] , *arg* [1] are the left and right operands; i.e.,\ncorresponding to *v0* , *v1* .\n\nfor_sparsity\n************\nWe have the conditions *np1* = *for_sparsity* . ``end`` ()\nand *for_sparsity* . ``n_set`` () = *np1* + *numvar* .\n\nInput Jacobian Sparsity\n=======================\nFor *i* = 0, ..., *i_w* ``-1`` ,\nthe *np1* + *i* row of *for_sparsity* is the Jacobian sparsity\nfor the *i*-th variable. These values do not change.\nNote that *i* =0 corresponds to a parameter and\nthe corresponding Jacobian sparsity is empty.\n\nInput Hessian Sparsity\n======================\nFor *j* =1, ..., *n* ,\nthe *j*-th row of *for_sparsity* is the Hessian sparsity\nbefore including the function :math:`w(x)`.\n\nOutput Jacobian Sparsity\n========================\nthe *i_w* row of *for_sparsity* is the Jacobian sparsity\nfor the variable *w* .\n\nOutput Hessian Sparsity\n=======================\nFor *j* =1, ..., *n* ,\nthe *j*-th row of *for_sparsity* is the Hessian sparsity\nafter including the function :math:`w(x)`.\n\n{xrst_end sparse_for_hes_nl_binary_op}\n*/\n// BEGIN_for_hes_mul_op\ntemplate <class Vector_set>\nvoid for_hes_mul_op(\n   size_t              np1           ,\n   size_t              numvar        ,\n   size_t              i_w           ,\n   const addr_t*       arg           ,\n   Vector_set&         for_sparsity  )\n// END_for_hes_mul_op\n{  //\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + numvar );\n   //\n   size_t i_v0 = size_t(arg[0]);\n   size_t i_v1 = size_t(arg[1]);\n   CPPAD_ASSERT_UNKNOWN( i_v0 < i_w );\n   CPPAD_ASSERT_UNKNOWN( i_v1 < i_w );\n   CPPAD_ASSERT_UNKNOWN( i_w  < numvar );\n\n   // set Jacobian sparsity J(i_w)\n   for_sparsity.binary_union(np1 + i_w, np1 + i_v0, np1 + i_v1, for_sparsity);\n\n   // --------------------------------------------------\n   // set of independent variables that v0 depends on\n   typename Vector_set::const_iterator itr_0(for_sparsity, i_v0 + np1);\n\n   // loop over independent variables non-zero partial for v0\n   size_t i_x = *itr_0;\n   while( i_x < np1 )\n   {  // N(i_x) = N(i_x) union J(v1)\n      for_sparsity.binary_union(i_x, i_x, i_v1 + np1, for_sparsity);\n      i_x = *(++itr_0);\n   }\n   // --------------------------------------------------\n   // set of independent variables that v1 depends on\n   typename Vector_set::const_iterator itr_1(for_sparsity, i_v1 + np1);\n\n   // loop over independent variables with non-zero partial for v1\n   i_x = *itr_1;\n   while( i_x < np1 )\n   {  // N(i_x) = N(i_x) union J(v0)\n      for_sparsity.binary_union(i_x, i_x, i_v0 + np1, for_sparsity);\n      i_x = *(++itr_1);\n   }\n   return;\n}\n// BEGIN_for_hes_div_op\ntemplate <class Vector_set>\nvoid for_hes_div_op(\n   size_t              np1           ,\n   size_t              numvar        ,\n   size_t              i_w           ,\n   const addr_t*       arg           ,\n   Vector_set&         for_sparsity  )\n// END_for_hes_div_op\n{  //\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + numvar );\n   //\n   size_t i_v0 = size_t(arg[0]);\n   size_t i_v1 = size_t(arg[1]);\n   CPPAD_ASSERT_UNKNOWN( i_v0 < i_w );\n   CPPAD_ASSERT_UNKNOWN( i_v1 < i_w );\n   CPPAD_ASSERT_UNKNOWN( i_w  < numvar );\n\n   // set Jacobian sparsity J(i_w)\n   for_sparsity.binary_union(np1 + i_w, np1 + i_v0, np1 + i_v1, for_sparsity);\n\n   // --------------------------------------------------\n   // set of independent variables that v0 depends on\n   typename Vector_set::const_iterator itr_0(for_sparsity, i_v0 + np1);\n\n   // loop over independent variables non-zero partial for v0\n   size_t i_x = *itr_0;\n   while( i_x < np1 )\n   {  // N(i_x) = N(i_x) union J(v1)\n      for_sparsity.binary_union(i_x, i_x, i_v1 + np1, for_sparsity);\n      i_x = *(++itr_0);\n   }\n   // --------------------------------------------------\n   // set of independent variables that v1 depends on\n   typename Vector_set::const_iterator itr_1(for_sparsity, i_v1 + np1);\n\n   // loop over independent variables with non-zero partial for v1\n   i_x = *itr_1;\n   while( i_x < np1 )\n   {  // N(i_x) = N(i_x) union J(v0)\n      for_sparsity.binary_union(i_x, i_x, i_v0 + np1, for_sparsity);\n      // N(i_x) = N(i_x) union J(v1)\n      for_sparsity.binary_union(i_x, i_x, i_v1 + np1, for_sparsity);\n      i_x = *(++itr_1);\n   }\n   return;\n}\n// BEGIN_for_hes_pow_op\ntemplate <class Vector_set>\nvoid for_hes_pow_op(\n   size_t              np1           ,\n   size_t              numvar        ,\n   size_t              i_w           ,\n   const addr_t*       arg           ,\n   Vector_set&         for_sparsity  )\n// END_for_hes_pow_op\n{  //\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + numvar );\n   //\n   size_t i_v0 = size_t(arg[0]);\n   size_t i_v1 = size_t(arg[1]);\n   CPPAD_ASSERT_UNKNOWN( i_v0 < i_w );\n   CPPAD_ASSERT_UNKNOWN( i_v1 < i_w );\n   CPPAD_ASSERT_UNKNOWN( i_w  < numvar );\n\n   // set Jacobian sparsity J(i_w)\n   for_sparsity.binary_union(np1 + i_w, np1 + i_v0, np1 + i_v1, for_sparsity);\n\n   // --------------------------------------------------\n   // set of independent variables that v0 depends on\n   typename Vector_set::const_iterator itr_0(for_sparsity, i_v0 + np1);\n\n   // loop over independent variables non-zero partial for v0\n   size_t i_x = *itr_0;\n   while( i_x < np1 )\n   {  // N(i_x) = N(i_x) union J(v0)\n      for_sparsity.binary_union(i_x, i_x, i_v0 + np1, for_sparsity);\n      // N(i_x) = N(i_x) union J(v1)\n      for_sparsity.binary_union(i_x, i_x, i_v1 + np1, for_sparsity);\n      i_x = *(++itr_0);\n   }\n   // --------------------------------------------------\n   // set of independent variables that v1 depends on\n   typename Vector_set::const_iterator itr_1(for_sparsity, i_v1 + np1);\n\n   // loop over independent variables with non-zero partial for v1\n   i_x = *itr_1;\n   while( i_x < np1 )\n   {  // N(i_x) = N(i_x) union J(v0)\n      for_sparsity.binary_union(i_x, i_x, i_v0 + np1, for_sparsity);\n      // N(i_x) = N(i_x) union J(v1)\n      for_sparsity.binary_union(i_x, i_x, i_v1 + np1, for_sparsity);\n      i_x = *(++itr_1);\n   }\n   return;\n}\n// ---------------------------------------------------------------------------\n} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sparse/internal.hpp",
    "content": "# ifndef CPPAD_LOCAL_SPARSE_INTERNAL_HPP\n# define CPPAD_LOCAL_SPARSE_INTERNAL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// necessary definitions\n# include <cppad/local/define.hpp>\n# include <cppad/local/sparse/pack_setvec.hpp>\n# include <cppad/local/sparse/list_setvec.hpp>\n# include <cppad/local/sparse/svec_setvec.hpp>\n\n// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE\nnamespace CppAD { namespace local { namespace sparse {\n\n/*!\n\\file sparse_internal.hpp\nRoutines that enable code to be independent of which internal spasity pattern\nis used.\n*/\n// ---------------------------------------------------------------------------\n/*!\nTemplate structure used obtain the internal sparsity pattern type\nform the corresponding element type.\nThe general form is not valid, must use a specialization.\n\n\\tparam Element_type\ntype of an element in the sparsity structure.\n\n\\par <code>internal_pattern<Element_type>::pattern_type</code>\nis the type of the corresponding internal sparsity pattern.\n*/\ntemplate <class Element_type> struct internal_pattern;\n/// Specialization for bool elements.\ntemplate <>\nstruct internal_pattern<bool>\n{\n   typedef sparse::pack_setvec pattern_type;\n};\n/// Specialization for <code>std::set<size_t></code> elements.\ntemplate <>\nstruct internal_pattern< std::set<size_t> >\n{\n   typedef list_setvec pattern_type;\n};\n// ---------------------------------------------------------------------------\n/*!\nUpdate the internal sparsity pattern for a sub-set of rows\n\n\\tparam SizeVector\nThe type used for index sparsity patterns. This is a simple vector\nwith elements of type size_t.\n\n\\tparam InternalSparsitiy\nThe type used for internal sparsity patterns. This can be either\nsparse::pack_setvec or list_setvec.\n\n\\param zero_empty\nIf this is true, the internal sparstity pattern corresponds to row zero\nmust be empty on input and will be empty output; i.e., any corresponding\nvalues in pattern_in will be ignored.\n\n\\param input_empty\nIf this is true, the initial sparsity pattern for row\ninternal_index[i] is empty for all i.\nIn this case, one is setting the sparsity patterns; i.e.,\nthe output pattern in row internal_index[i] is the corresponding\nentries in pattern.\n\n\\param transpose\nIf this is true, pattern_in is transposed.\n\n\\param internal_index\nThis specifies the sub-set of rows in internal_pattern that we are updating.\nIf transpose is false (true),\nthis is the mapping from row (column) index in pattern_in to the corresponding\nrow index in the internal_pattern.\n\n\\param internal_pattern\nOn input, the number of sets internal_pattern.n_set(),\nand possible elements internal_pattern.end(), have been set.\nIf input_empty is true, and all of the sets\nin internal_index are empty on input.\nOn output, the entries in pattern_in are added to internal_pattern.\nTo be specific, suppose transpose is false, and (i, j) is a possibly\nnon-zero entry in pattern_in, the entry (internal_index[i], j) is added\nto internal_pattern.\nOn the other hand, if transpose is true,\nthe entry (internal_index[j], i) is added to internal_pattern.\n\n\\param pattern_in\nThis is the sparsity pattern for variables,\nor its transpose, depending on the value of transpose.\n*/\ntemplate <class SizeVector, class InternalSparsity>\nvoid set_internal_pattern(\n   bool                          zero_empty       ,\n   bool                          input_empty      ,\n   bool                          transpose        ,\n   const pod_vector<size_t>&     internal_index   ,\n   InternalSparsity&             internal_pattern ,\n   const sparse_rc<SizeVector>&  pattern_in       )\n{\n   size_t nr = internal_index.size();\n# ifndef NDEBUG\n   size_t nc = internal_pattern.end();\n   if( transpose )\n   {  CPPAD_ASSERT_UNKNOWN( pattern_in.nr() == nc );\n      CPPAD_ASSERT_UNKNOWN( pattern_in.nc() == nr );\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( pattern_in.nr() == nr );\n      CPPAD_ASSERT_UNKNOWN( pattern_in.nc() == nc );\n   }\n   if( input_empty ) for(size_t i = 0; i < nr; i++)\n   {  size_t i_var = internal_index[i];\n      CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 );\n   }\n# endif\n   const SizeVector& row( pattern_in.row() );\n   const SizeVector& col( pattern_in.col() );\n   size_t nnz = row.size();\n   for(size_t k = 0; k < nnz; k++)\n   {  size_t r = row[k];\n      size_t c = col[k];\n      if( transpose )\n         std::swap(r, c);\n      //\n      size_t i_var = internal_index[r];\n      CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() );\n      CPPAD_ASSERT_UNKNOWN( c < nc );\n      bool ignore  = zero_empty && i_var == 0;\n      if( ! ignore )\n         internal_pattern.post_element( internal_index[r], c );\n   }\n   // process posts\n   for(size_t i = 0; i < nr; ++i)\n      internal_pattern.process_post( internal_index[i] );\n}\ntemplate <class InternalSparsity>\nvoid set_internal_pattern(\n   bool                          zero_empty       ,\n   bool                          input_empty      ,\n   bool                          transpose        ,\n   const pod_vector<size_t>&     internal_index   ,\n   InternalSparsity&             internal_pattern ,\n   const vectorBool&             pattern_in       )\n{  size_t nr = internal_index.size();\n   size_t nc = internal_pattern.end();\n# ifndef NDEBUG\n   CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nr * nc );\n   if( input_empty ) for(size_t i = 0; i < nr; i++)\n   {  size_t i_var = internal_index[i];\n      CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 );\n   }\n# endif\n   for(size_t i = 0; i < nr; i++)\n   {  for(size_t j = 0; j < nc; j++)\n      {  bool flag = pattern_in[i * nc + j];\n         if( transpose )\n            flag = pattern_in[j * nr + i];\n         if( flag )\n         {  size_t i_var = internal_index[i];\n            CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() );\n            CPPAD_ASSERT_UNKNOWN( j < nc );\n            bool ignore  = zero_empty && i_var == 0;\n            if( ! ignore )\n               internal_pattern.post_element( i_var, j);\n         }\n      }\n   }\n   // process posts\n   for(size_t i = 0; i < nr; ++i)\n      internal_pattern.process_post( internal_index[i] );\n   return;\n}\ntemplate <class InternalSparsity>\nvoid set_internal_pattern(\n   bool                          zero_empty       ,\n   bool                          input_empty      ,\n   bool                          transpose        ,\n   const pod_vector<size_t>&     internal_index   ,\n   InternalSparsity&             internal_pattern ,\n   const vector<bool>&           pattern_in       )\n{  size_t nr = internal_index.size();\n   size_t nc = internal_pattern.end();\n# ifndef NDEBUG\n   CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nr * nc );\n   if( input_empty ) for(size_t i = 0; i < nr; i++)\n   {  size_t i_var = internal_index[i];\n      CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 );\n   }\n# endif\n   for(size_t i = 0; i < nr; i++)\n   {  for(size_t j = 0; j < nc; j++)\n      {  bool flag = pattern_in[i * nc + j];\n         if( transpose )\n            flag = pattern_in[j * nr + i];\n         if( flag )\n         {  size_t i_var = internal_index[i];\n            CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() );\n            CPPAD_ASSERT_UNKNOWN( j < nc );\n            bool ignore  = zero_empty && i_var == 0;\n            if( ! ignore )\n               internal_pattern.post_element( i_var, j);\n         }\n      }\n   }\n   // process posts\n   for(size_t i = 0; i < nr; ++i)\n      internal_pattern.process_post( internal_index[i] );\n   return;\n}\ntemplate <class InternalSparsity>\nvoid set_internal_pattern(\n   bool                               zero_empty       ,\n   bool                               input_empty      ,\n   bool                               transpose        ,\n   const pod_vector<size_t>&          internal_index   ,\n   InternalSparsity&                  internal_pattern ,\n   const vector< std::set<size_t> >&  pattern_in       )\n{  size_t nr = internal_index.size();\n   size_t nc = internal_pattern.end();\n# ifndef NDEBUG\n   if( input_empty ) for(size_t i = 0; i < nr; i++)\n   {  size_t i_var = internal_index[i];\n      CPPAD_ASSERT_UNKNOWN( internal_pattern.number_elements(i_var) == 0 );\n   }\n# endif\n   if( transpose )\n   {  CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nc );\n      for(size_t j = 0; j < nc; j++)\n      {  std::set<size_t>::const_iterator itr( pattern_in[j].begin() );\n         while( itr != pattern_in[j].end() )\n         {  size_t i = *itr;\n            size_t i_var = internal_index[i];\n            CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() );\n            CPPAD_ASSERT_UNKNOWN( j < nc );\n            bool ignore  = zero_empty && i_var == 0;\n            if( ! ignore )\n               internal_pattern.post_element( i_var, j);\n            ++itr;\n         }\n      }\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( pattern_in.size() == nr );\n      for(size_t i = 0; i < nr; i++)\n      {  std::set<size_t>::const_iterator itr( pattern_in[i].begin() );\n         while( itr != pattern_in[i].end() )\n         {  size_t j = *itr;\n            size_t i_var = internal_index[i];\n            CPPAD_ASSERT_UNKNOWN( i_var < internal_pattern.n_set() );\n            CPPAD_ASSERT_UNKNOWN( j < nc );\n            bool ignore  = zero_empty && i_var == 0;\n            if( ! ignore )\n               internal_pattern.post_element( i_var, j);\n            ++itr;\n         }\n      }\n   }\n   // process posts\n   for(size_t i = 0; i < nr; ++i)\n      internal_pattern.process_post( internal_index[i] );\n   return;\n}\n// ---------------------------------------------------------------------------\n/*!\nGet sparsity pattern for a sub-set of variables\n\n\\tparam SizeVector\nThe type used for index sparsity patterns. This is a simple vector\nwith elements of type size_t.\n\n\\tparam InternalSparsitiy\nThe type used for internal sparsity patterns. This can be either\nsparse::pack_setvec or list_setvec.\n\n\\param transpose\nIf this is true, pattern_out is transposed.\n\n\\param internal_index\nIf transpose is false (true)\nthis is the mapping from row (column) an index in pattern_out\nto the corresponding row index in internal_pattern.\n\n\\param internal_pattern\nThis is the internal sparsity pattern.\n\n\\param pattern_out\nThe input value of pattern_out does not matter.\nUpon return it is an index sparsity pattern for each of the variables\nin internal_index, or its transpose, depending on the value of transpose.\n*/\ntemplate <class SizeVector, class InternalSparsity>\nvoid get_internal_pattern(\n   bool                          transpose         ,\n   const pod_vector<size_t>&     internal_index    ,\n   const InternalSparsity&       internal_pattern  ,\n   sparse_rc<SizeVector>&        pattern_out        )\n{  typedef typename InternalSparsity::const_iterator iterator;\n   // number variables\n   size_t nr = internal_index.size();\n   // column size of internal sparstiy pattern\n   size_t nc = internal_pattern.end();\n   // determine nnz, the number of possibly non-zero index pairs\n   size_t nnz = 0;\n   for(size_t i = 0; i < nr; i++)\n   {  CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() );\n      iterator itr(internal_pattern, internal_index[i]);\n      size_t j = *itr;\n      while( j < nc )\n      {  ++nnz;\n         j = *(++itr);\n      }\n   }\n   // transposed\n   if( transpose )\n   {  pattern_out.resize(nc, nr, nnz);\n      //\n      size_t k = 0;\n      for(size_t i = 0; i < nr; i++)\n      {  iterator itr(internal_pattern, internal_index[i]);\n         size_t j = *itr;\n         while( j < nc )\n         {  pattern_out.set(k++, j, i);\n            j = *(++itr);\n         }\n      }\n      return;\n   }\n   // not transposed\n   pattern_out.resize(nr, nc, nnz);\n   //\n   size_t k = 0;\n   for(size_t i = 0; i < nr; i++)\n   {  iterator itr(internal_pattern, internal_index[i]);\n      size_t j = *itr;\n      while( j < nc )\n      {  pattern_out.set(k++, i, j);\n         j = *(++itr);\n      }\n   }\n   return;\n}\ntemplate <class InternalSparsity>\nvoid get_internal_pattern(\n   bool                          transpose         ,\n   const pod_vector<size_t>&     internal_index    ,\n   const InternalSparsity&       internal_pattern  ,\n   vectorBool&                   pattern_out       )\n{  typedef typename InternalSparsity::const_iterator iterator;\n   // number variables\n   size_t nr = internal_index.size();\n   //\n   // column size of internal sparstiy pattern\n   size_t nc = internal_pattern.end();\n   //\n   pattern_out.resize(nr * nc);\n   for(size_t ij = 0; ij < nr * nc; ij++)\n      pattern_out[ij] = false;\n   //\n   for(size_t i = 0; i < nr; i++)\n   {  CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() );\n      iterator itr(internal_pattern, internal_index[i]);\n      size_t j = *itr;\n      while( j < nc )\n      {  if( transpose )\n            pattern_out[j * nr + i] = true;\n         else\n            pattern_out[i * nc + j] = true;\n         j = *(++itr);\n      }\n   }\n   return;\n}\ntemplate <class InternalSparsity>\nvoid get_internal_pattern(\n   bool                          transpose         ,\n   const pod_vector<size_t>&     internal_index    ,\n   const InternalSparsity&       internal_pattern  ,\n   vector<bool>&                 pattern_out       )\n{  typedef typename InternalSparsity::const_iterator iterator;\n   // number variables\n   size_t nr = internal_index.size();\n   //\n   // column size of internal sparstiy pattern\n   size_t nc = internal_pattern.end();\n   //\n   pattern_out.resize(nr * nc);\n   for(size_t ij = 0; ij < nr * nc; ij++)\n      pattern_out[ij] = false;\n   //\n   for(size_t i = 0; i < nr; i++)\n   {  CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() );\n      iterator itr(internal_pattern, internal_index[i]);\n      size_t j = *itr;\n      while( j < nc )\n      {  if( transpose )\n            pattern_out[j * nr + i] = true;\n         else\n            pattern_out[i * nc + j] = true;\n         j = *(++itr);\n      }\n   }\n   return;\n}\ntemplate <class InternalSparsity>\nvoid get_internal_pattern(\n   bool                          transpose         ,\n   const pod_vector<size_t>&     internal_index    ,\n   const InternalSparsity&       internal_pattern  ,\n   vector< std::set<size_t> >&   pattern_out       )\n{  typedef typename InternalSparsity::const_iterator iterator;\n   // number variables\n   size_t nr = internal_index.size();\n   //\n   // column size of internal sparstiy pattern\n   size_t nc = internal_pattern.end();\n   //\n   if( transpose )\n      pattern_out.resize(nc);\n   else\n      pattern_out.resize(nr);\n   for(size_t k = 0; k < pattern_out.size(); k++)\n      pattern_out[k].clear();\n   //\n   for(size_t i = 0; i < nr; i++)\n   {  CPPAD_ASSERT_UNKNOWN( internal_index[i] < internal_pattern.n_set() );\n      iterator itr(internal_pattern, internal_index[i]);\n      size_t j = *itr;\n      while( j < nc )\n      {  if( transpose )\n            pattern_out[j].insert(i);\n         else\n            pattern_out[i].insert(j);\n         j = *(++itr);\n      }\n   }\n   return;\n}\n\n\n\n} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sparse/list_setvec.hpp",
    "content": "# ifndef CPPAD_LOCAL_SPARSE_LIST_SETVEC_HPP\n# define CPPAD_LOCAL_SPARSE_LIST_SETVEC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/define.hpp>\n# include <cppad/local/is_pod.hpp>\n# include <cppad/local/sparse/size_setvec.hpp>\n\n// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE\nnamespace CppAD { namespace local { namespace sparse {\n\n/*\n{xrst_begin_parent list_setvec dev}\n{xrst_spell\n   typedef\n}\n\nThe list_setvec Class\n#####################\nThis class is a :ref:`SetVector-title` with elements of type ``size_t``.\nIt is implemented using the template class\n:ref:`size_setvec-name` where the elements any positive integer type.\n{xrst_code cpp} */\ntypedef size_setvec<size_t>                 list_setvec;\ntypedef size_setvec_const_iterator<size_t>  list_setvec_const_iterator;\n/*{xrst_code}\n\n{xrst_toc_table\n   include/cppad/local/sparse/size_setvec.hpp\n}\n\n{xrst_end list_setvec}\n// ----------------------------------------------------------------------------\n{xrst_begin sparsity_user2internal_list_setvec dev}\n{xrst_spell\n   msg\n}\n\nCopy A Vector of Standard Sets To A list_setvec Object\n######################################################\n\nSetVector\n*********\nis a :ref:`simple vector<SimpleVector-name>` type with elements of type\n``std::set<size_t>`` .\n\ninternal\n********\nThe input value of this object does not matter.\nUpon return it contains the same sparsity pattern as *user*\n(or its transpose).\n\nuser\n****\nis the sparsity pattern we are copying to *internal* .\n\nn_set\n*****\nis the number of sets in the output sparsity pattern *internal* .\nIf *transpose* is false, *n_set* is equal to\n*user* . ``size`` () .\n\nend\n***\nis the end value for the output sparsity pattern *internal* .\n``list_setvec`` sparsity pattern *internal* .\nIf *transpose* is true, *end* is equal to\n*user* . ``size`` () .\n\ntranspose\n*********\nIf *transpose* is false,\nelement *j* is in the *i*-th *internal* set if\n*j* is in the *user* [ *i* ] .\nOtherwise,\nelement *j* is in the *i*-th *internal* set if\n*i* is in the *user* [ *j* ] .\n\nerror_msg\n*********\nis the error message to display if some values in the *user*\nsparsity pattern are not valid.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\ntemplate<class SetVector>\nvoid sparsity_user2internal(\n   list_setvec&            internal  ,\n   const SetVector&        user      ,\n   size_t                  n_set     ,\n   size_t                  end       ,\n   bool                    transpose ,\n   const char*             error_msg )\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end sparsity_user2internal_list_setvec}\n**/\n{\n# ifndef NDEBUG\n   if( transpose )\n      CPPAD_ASSERT_KNOWN( end == size_t( user.size() ), error_msg);\n   if( ! transpose )\n      CPPAD_ASSERT_KNOWN( n_set == size_t( user.size() ), error_msg);\n# endif\n\n   // iterator for user set\n   std::set<size_t>::const_iterator itr;\n\n   // size of internal sparsity pattern\n   internal.resize(n_set, end);\n\n   if( transpose )\n   {  // transposed pattern case\n      for(size_t j = 0; j < end; j++)\n      {  itr = user[j].begin();\n         while(itr != user[j].end())\n         {  size_t i = *itr++;\n            CPPAD_ASSERT_KNOWN(i < n_set, error_msg);\n            internal.post_element(i, j);\n         }\n      }\n      for(size_t i = 0; i < n_set; ++i)\n         internal.process_post(i);\n   }\n   else\n   {  for(size_t i = 0; i < n_set; i++)\n      {  itr = user[i].begin();\n         while(itr != user[i].end())\n         {  size_t j = *itr++;\n            CPPAD_ASSERT_KNOWN( j < end, error_msg);\n            internal.post_element(i, j);\n         }\n         internal.process_post(i);\n      }\n   }\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE\n\n// =========================================================================\n// Tell pod_vector class that each pair_size_t is plain old data and hence\n// the corresponding constructor need not be called.\nnamespace CppAD { namespace local {\n   template <> inline bool\n   is_pod<sparse::size_setvec<size_t>::pair_s_type>(void)\n   {  return true; }\n} }\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sparse/pack_setvec.hpp",
    "content": "# ifndef CPPAD_LOCAL_SPARSE_PACK_SETVEC_HPP\n# define CPPAD_LOCAL_SPARSE_PACK_SETVEC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/local/pod_vector.hpp>\n\n// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE\nnamespace CppAD { namespace local { namespace sparse {\n\n// forward declaration of iterator class\nclass pack_setvec_const_iterator;\n\n// ============================================================================\nclass pack_setvec {\n// ============================================================================\n/*\n{xrst_begin pack_setvec_member_data dev}\n\nclass pack_setvec: Private Member Data\n######################################\n\nPack\n****\nType used to pack multiple elements of a set (multiple bits) onto one\n*Pack* value.\n\nn_bit\\_\n*******\nNumber of bits (elements) per *Pack* value.\n\nzero\\_\n******\nThe *Pack* value with all bits zero.\n\none\\_\n*****\nThe *Pack* value with all bits zero, except for the lowest order bit.\n\nn_set\\_\n*******\nNumber of sets that we are representing.\n\nend\\_\n*****\nThe possible elements in each set are ``0`` , ``1`` , ...,\n``end_-1`` .\n\nn_pack\\_\n********\nNumber of Pack values used to represent one set in the vector; i.e.,\nto represent ``end_`` bits.\n\ndata\\_\n******\nData for all of the sets.\n\nSource Code\n***********\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   typedef size_t    Pack;\n   const size_t      n_bit_;\n   const Pack        zero_;\n   const Pack        one_;\n   size_t            n_set_;\n   size_t            end_;\n   size_t            n_pack_;\n   pod_vector<Pack>  data_;\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_member_data}\n-----------------------------------------------------------------------------\n{xrst_begin pack_setvec_vec_memory dev}\n\nclass pack_setvec: Approximate Memory Used by Vector\n####################################################\n\nPublic\n******\nThis function is declared public, but is not part of\n:ref:`SetVector-name` concept.\n\nImplementation\n**************\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   size_t memory(void) const\n   {  return data_.capacity() * sizeof(Pack); }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_vec_memory}\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_vec_print dev}\n\nclass pack_setvec: Print a Vector of Sets\n#########################################\n\nPublic\n******\nThis function is declared public, but is not part of\n:ref:`SetVector-name` concept.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void print(void) const;\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_vec_print}\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_iterators dev}\n{xrst_spell\n   typedef\n}\n\nclass pack_setvec: Iterators\n############################\n\nSetVector Concept\n*****************\n:ref:`SetVector@const_iterator`\n\ntypedef\n*******\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   /// declare a const iterator\n   friend class pack_setvec_const_iterator;\n   typedef pack_setvec_const_iterator const_iterator;\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_iterators}\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_default_ctor dev}\n\nclass pack_setvec: Default Constructor\n######################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@Vector Operations@Constructor`\n\nn_bit\\_\n*******\nThis member variable is set to the number of bits in a *Pack* value.\n\none\\_\n*****\nThis member variable has only its lowest order bit non-zero;\n\ndata\\_\n******\nThis member is initialized as the empty vector; i.e., size zero..\n\nOther\n*****\nAll the other member data are ``size_t`` values\nthat are initialized as zero.\n\nImplementation\n**************\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   pack_setvec(void) :\n   n_bit_( std::numeric_limits<Pack>::digits ),\n   zero_(0), one_(1), n_set_(0), end_(0), n_pack_(0), data_(0)\n   { }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_default_ctor}\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_destructor dev}\n\nclass pack_setvec: Destructor\n#############################\n\nImplementation\n**************\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   ~pack_setvec(void)\n   { }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_destructor}\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_copy_ctor dev}\n\nclass pack_setvec: Copy Constructor\n###################################\n\nv\n*\nThe vector of sets that we are attempting to make a copy of.\n\nImplementation\n**************\nUsing the copy constructor is probably due to a ``pack_setvec``\nbeing passed by value instead of by reference.\nThis is a CppAD programing error (not CppAD user error).\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   pack_setvec(const pack_setvec& v) :\n   n_bit_( std::numeric_limits<Pack>::digits ), zero_(0), one_(1)\n   {  CPPAD_ASSERT_UNKNOWN(0); }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_copy_ctor}\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_vec_resize dev}\n\nclass pack_setvec: Vector resize\n################################\n\nSetVector Concept\n*****************\n:ref:`vector resize<SetVector@Vector Operations@resize>`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void resize(size_t n_set, size_t end)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_vec_resize}\n*/\n   {  n_set_          = n_set;\n      end_            = end;\n      if( n_set_ == 0 )\n      {  CPPAD_ASSERT_UNKNOWN( end == 0 );\n         data_.clear();\n         return;\n      }\n      // now start a new vector with empty sets\n      Pack zero(0);\n      //\n      n_pack_         = ( 1 + (end_ - 1) / n_bit_ );\n      size_t i        = n_set_ * n_pack_;\n      //\n      data_.resize(i);\n      while(i--)\n         data_[i] = zero;\n   }\n/* %$$\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_vec_n_set dev}\n\nclass pack_setvec: Number of Sets\n#################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@Vector Operations@n_set`\n\nImplementation\n**************\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   size_t n_set(void) const\n   {  return n_set_;  }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_vec_n_set}\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_vec_end dev}\n\nclass pack_setvec: End Value\n############################\n\nSetVector Concept\n*****************\n:ref:`SetVector@Vector Operations@end`\n\nImplementation\n**************\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   size_t end(void) const\n   {  return end_; }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_vec_end}\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_vec_assignment dev}\n\nclass pack_setvec: Vector Assignment\n####################################\n\nSetVector Concept\n*****************\n:ref:`vector assignment<SetVector@Vector Operations@Assignment>`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void operator=(const pack_setvec& other)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_vec_assignment}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( n_bit_  == other.n_bit_);\n      CPPAD_ASSERT_UNKNOWN( zero_   == other.zero_);\n      CPPAD_ASSERT_UNKNOWN( one_    == other.one_);\n      n_set_  = other.n_set_;\n      end_    = other.end_;\n      n_pack_ = other.n_pack_;\n      data_   = other.data_;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_vec_swap dev}\n\nclass pack_setvec: Vector Swap\n##############################\n\nSetVector Concept\n*****************\n:ref:`vector swap<SetVector@Vector Operations@swap>`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void swap(pack_setvec& other)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_vec_swap}\n*/\n   {  // size_t objects\n      CPPAD_ASSERT_UNKNOWN( n_bit_  == other.n_bit_);\n      CPPAD_ASSERT_UNKNOWN( zero_   == other.zero_);\n      CPPAD_ASSERT_UNKNOWN( one_    == other.one_);\n      std::swap(n_set_  , other.n_set_);\n      std::swap(end_    , other.end_);\n      std::swap(n_pack_ , other.n_pack_);\n      //\n      // pod_vectors\n      data_.swap(other.data_);\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_number_elements dev}\n\nclass pack_setvec: Number of Elements in a Set\n##############################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@number_elements`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   size_t number_elements(size_t i) const\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_number_elements}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( i < n_set_ );\n      //\n      // special case where data_[i] is 0 or 1\n      if( end_ == 1 )\n      {  CPPAD_ASSERT_UNKNOWN( n_pack_ == 1 );\n         return size_t( data_[i] );\n      }\n      //\n      // initialize count of non-zero bits in this set\n      size_t count = 0;\n      //\n      // mask corresponding to first bit in Pack\n      Pack mask = one_;\n      //\n      // number of bits in last Packing unit\n      size_t n_last = (end_ - 1) % n_bit_ + 1;\n      //\n      // count bits in last unit\n      Pack unit = data_[(i + 1) * n_pack_ - 1];\n      for(size_t bit = 0; bit < n_last; ++bit)\n      {  CPPAD_ASSERT_UNKNOWN( mask >= one_ );\n         if( mask & unit )\n            ++count;\n         mask = mask << 1;\n      }\n      if( n_pack_ == 1 )\n         return count;\n      //\n      // count bits in other units\n      for(size_t bit = 0; bit < n_bit_; ++bit)\n      {  CPPAD_ASSERT_UNKNOWN( mask >= one_ );\n         size_t k = n_pack_;\n         while(--k)\n         {  if( data_[i * n_pack_ + k] & mask )\n               ++count;\n         }\n         mask = mask << 1;\n      }\n      return count;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_add_element dev}\n\nclass pack_setvec: Add an Elements to a Set\n###########################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@add_element`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void add_element(size_t i, size_t element)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_add_element}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( i   < n_set_ );\n      CPPAD_ASSERT_UNKNOWN( element < end_ );\n      if( end_ == 1 )\n         data_[i] |= one_;\n      else\n      {  size_t j  = element / n_bit_;\n         size_t k  = element - j * n_bit_;\n         Pack mask = one_ << k;\n         data_[ i * n_pack_ + j] |= mask;\n      }\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_post_element dev}\n\nclass pack_setvec: Add an Elements to a Set\n###########################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@post_element`\n\nImplementation\n**************\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void post_element(size_t i, size_t element)\n   {  add_element(i, element); }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_post_element}\n*/\n/*\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_process_post dev}\n\nclass pack_setvec: Add Posted Elements to a Set\n###############################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@process_post`\n\nImplementation\n**************\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void process_post(size_t i)\n   {  return; }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_process_post}\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_is_element dev}\n\nclass pack_setvec: Is an Element in a Set\n#########################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@is_element`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   bool is_element(size_t i, size_t element) const\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_is_element}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( i   < n_set_ );\n      CPPAD_ASSERT_UNKNOWN( element < end_ );\n      if( end_ == 1 )\n         return data_[i] != zero_;\n      //\n      size_t j  = element / n_bit_;\n      size_t k  = element - j * n_bit_;\n      Pack mask = one_ << k;\n      return (data_[i * n_pack_ + j] & mask) != zero_;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_clear dev}\n\nclass pack_setvec: Assign a Set to be Empty\n###########################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@clear`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void clear(size_t target)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_clear}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( target < n_set_ );\n      size_t t = target * n_pack_;\n\n      size_t j = n_pack_;\n      while(j--)\n         data_[t++] = zero_;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_assignment dev}\n\nclass pack_setvec: Assign a Set To Equal Another Set\n####################################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@assignment`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void assignment(\n      size_t               this_target  ,\n      size_t               other_value  ,\n      const pack_setvec&   other        )\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_assignment}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( this_target  <   n_set_        );\n      CPPAD_ASSERT_UNKNOWN( other_value  <   other.n_set_  );\n      CPPAD_ASSERT_UNKNOWN( n_pack_      ==  other.n_pack_ );\n      size_t t = this_target * n_pack_;\n      size_t v = other_value * n_pack_;\n\n      size_t j = n_pack_;\n      while(j--)\n         data_[t++] = other.data_[v++];\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_binary_union dev}\n\nclass pack_setvec: Assign a Set To Equal Union of Two Sets\n##########################################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@binary_union`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void binary_union(\n      size_t                  this_target  ,\n      size_t                  this_left    ,\n      size_t                  other_right  ,\n      const pack_setvec&      other        )\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_binary_union}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( this_target < n_set_         );\n      CPPAD_ASSERT_UNKNOWN( this_left   < n_set_         );\n      CPPAD_ASSERT_UNKNOWN( other_right < other.n_set_   );\n      CPPAD_ASSERT_UNKNOWN( n_pack_    ==  other.n_pack_ );\n\n      size_t t  = this_target * n_pack_;\n      size_t l  = this_left  * n_pack_;\n      size_t r  = other_right * n_pack_;\n\n      size_t j = n_pack_;\n      while(j--)\n         data_[t++] = ( data_[l++] | other.data_[r++] );\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_binary_intersection dev}\n\nclass pack_setvec: Assign a Set To Intersection of Two Sets\n###########################################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@binary_intersection`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void binary_intersection(\n      size_t                  this_target  ,\n      size_t                  this_left    ,\n      size_t                  other_right  ,\n      const pack_setvec&      other        )\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_binary_intersection}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( this_target < n_set_         );\n      CPPAD_ASSERT_UNKNOWN( this_left   < n_set_         );\n      CPPAD_ASSERT_UNKNOWN( other_right < other.n_set_   );\n      CPPAD_ASSERT_UNKNOWN( n_pack_    ==  other.n_pack_ );\n\n      size_t t  = this_target * n_pack_;\n      size_t l  = this_left  * n_pack_;\n      size_t r  = other_right * n_pack_;\n\n      size_t j = n_pack_;\n      while(j--)\n         data_[t++] = ( data_[l++] & other.data_[r++] );\n   }\n// ==========================================================================\n}; // END_CLASS_PACK_SETVEC\n// ==========================================================================\n\n\n// =========================================================================\nclass pack_setvec_const_iterator { // BEGIN_CLASS_PACK_SETVEC_CONST_ITERATOR\n// =========================================================================\n\n/*\n{xrst_begin pack_setvec_const_iterator_member_data dev}\n\nclass pack_setvec_const_iterator private: Member Data\n#####################################################\n\nPack\n****\nThis is the same type as\n:ref:`pack_setvec Pack<pack_setvec_member_data@Pack>` .\n\nn_bit\\_\n*******\nThis is a reference to\n:ref:`pack_setvec n_bit_<pack_setvec_member_data@n_bit_>` .\n\none\\_\n*****\nThis is a reference to\n:ref:`pack_setvec one_<pack_setvec_member_data@one_>` .\n\nn_pack\\_\n********\nThis is a reference to\n:ref:`pack_setvec n_pack_<pack_setvec_member_data@n_pack_>` .\n\nend\\_\n*****\nThis is a reference to\n:ref:`pack_setvec end_<pack_setvec_member_data@end_>` .\n\ndata\\_\n******\nThis is a reference to\n:ref:`pack_setvec data_<pack_setvec_member_data@data_>` .\n\ndata_index\\_\n************\nIndex in ``data_`` where the next element is located.\n\nnext_element\n************\nValue of the next element in this set\nIf ``next_element_`` equals ``end_`` ,\nno next element exists; i.e., past end of the set.\n\nSource Code\n***********\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   typedef pack_setvec::Pack Pack;\n   const size_t&             n_bit_;\n   const Pack&               one_;\n   const size_t&             n_pack_;\n   const size_t&             end_;\n   const pod_vector<Pack>&   data_;\n   size_t                    data_index_;\n   size_t                    next_element_;\npublic:\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_const_iterator_member_data}\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_const_iterator_ctor dev}\n\nclass pack_setvec_const_iterator: Constructor\n#############################################\n\nSetVector Concept\n*****************\n:ref:`iterator constructor<SetVector@const_iterator@Constructor>`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   pack_setvec_const_iterator (const pack_setvec& pack, size_t set_index)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_const_iterator_ctor}\n*/\n   :\n   n_bit_         ( pack.n_bit_ )        ,\n   one_           ( pack.one_   )        ,\n   n_pack_        ( pack.n_pack_ )       ,\n   end_           ( pack.end_ )          ,\n   data_          ( pack.data_ )         ,\n   data_index_    ( set_index * n_pack_ )\n   {  CPPAD_ASSERT_UNKNOWN( set_index < pack.n_set_ );\n      CPPAD_ASSERT_UNKNOWN( 0 < end_ );\n      //\n      next_element_ = 0;\n      if( data_[data_index_] & one_ )\n         return;\n      //\n      // element with index zero is not in this set of integers,\n      // advance to first element or end\n      ++(*this);\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_const_iterator_dereference dev}\n\nclass pack_setvec_const_iterator: Dereference\n#############################################\n\nSetVector Concept\n*****************\n:ref:`iterator deference<SetVector@const_iterator@Dereference>`\n\nImplementation\n**************\n{xrst_spell_off}\n{xrst_code hpp} */\n   size_t operator*(void) const\n   {  return next_element_; }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_const_iterator_dereference}\n-------------------------------------------------------------------------------\n{xrst_begin pack_setvec_const_iterator_increment dev}\n\nclass pack_setvec_const_iterator: Increment\n###########################################\n\nSetVector Concept\n*****************\n:ref:`iterator increment<SetVector@const_iterator@Increment>`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   pack_setvec_const_iterator& operator++(void)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end pack_setvec_const_iterator_increment}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( next_element_ <= end_ );\n      if( next_element_ == end_ )\n         return *this;\n      //\n      ++next_element_;\n      if( next_element_ == end_ )\n         return *this;\n      //\n      // bit index corresponding to next element\n      size_t bit = next_element_ % n_bit_;\n      //\n      // check if we have advanced to the next data index\n      if( bit == 0 )\n         ++data_index_;\n      //\n      // initialize mask\n      size_t mask = one_ << bit;\n      //\n      while( next_element_ < end_ )\n      {  // check if this element is in the set\n         if( data_[data_index_] & mask )\n            return *this;\n         //\n         // try next larger element\n         ++next_element_;\n         ++bit;\n         mask <<= 1;\n         //\n         // check if we must go to next packed data index\n         CPPAD_ASSERT_UNKNOWN( bit <= n_bit_ );\n         if( bit == n_bit_ )\n         {  // get next packed value\n            bit   = 0;\n            mask  = one_;\n            ++data_index_;\n         }\n      }\n      CPPAD_ASSERT_UNKNOWN( next_element_ == end_ );\n      return *this;\n   }\n// =========================================================================\n}; // END_CLASS_PACK_SETVEC_CONST_ITERATOR\n// =========================================================================\n\n// Implemented after pack_setvec_const_iterator so can use it\ninline void pack_setvec::print(void) const\n{  std::cout << \"pack_setvec:\\n\";\n   for(size_t i = 0; i < n_set(); i++)\n   {  std::cout << \"set[\" << i << \"] = {\";\n      const_iterator itr(*this, i);\n      while( *itr != end() )\n      {  std::cout << *itr;\n         if( *(++itr) != end() )\n            std::cout << \",\";\n      }\n      std::cout << \"}\\n\";\n   }\n   return;\n}\n\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin sparsity_user2internal_pack_setvec dev}\n{xrst_spell\n   msg\n}\n\nCopy A Boolean Sparsity Pattern To A pack_setvec Object\n#######################################################\n\nSetVector\n*********\nis a :ref:`simple vector<SimpleVector-name>` type with elements of type\n``bool`` containing the input sparsity pattern.\n\ninternal\n********\nThe input value of this object does not matter.\nUpon return it contains the same sparsity pattern as *user*\n(or its transpose).\n\nuser\n****\nis the sparsity pattern we are copying to *internal* .\n\nn_set\n*****\nis the number of sets in the output sparsity pattern *internal* .\n\nend\n***\nis the end value for the output sparsity pattern *internal* .\n\ntranspose\n*********\nIf *transpose* is false,\nelement *j* is in the *i*-th *internal* set if\n\n   *user* [ *i* * *end* + *j*  ]\n\nOtherwise,\nelement *j* is in the *i*-th *internal* set if\n\n   *user* [ *i* * *n_set* + *j*  ]\n\nerror_msg\n*********\nis the error message to display if\n\n   *n_set* * *end* != *user* . ``size`` ()\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\ntemplate<class SetVector>\nvoid sparsity_user2internal(\n   pack_setvec&            internal  ,\n   const SetVector&        user      ,\n   size_t                  n_set     ,\n   size_t                  end       ,\n   bool                    transpose ,\n   const char*             error_msg )\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end sparsity_user2internal_pack_setvec}\n*/\n{  CPPAD_ASSERT_KNOWN(size_t( user.size() ) == n_set * end, error_msg );\n\n   // size of internal sparsity pattern\n   internal.resize(n_set, end);\n\n   if( transpose )\n   {  // transposed pattern case\n      for(size_t j = 0; j < end; j++)\n      {  for(size_t i = 0; i < n_set; i++)\n         {  // no advantage to using post_element for pack_setvec\n            if( user[ j * n_set + i ] )\n               internal.add_element(i, j);\n         }\n      }\n      return;\n   }\n   else\n   {  for(size_t i = 0; i < n_set; i++)\n      {  for(size_t j = 0; j < end; j++)\n         {  // no advantage to using post_element for pack_setvec\n            if( user[ i * end + j ] )\n               internal.add_element(i, j);\n         }\n      }\n   }\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sparse/size_setvec.hpp",
    "content": "# ifndef CPPAD_LOCAL_SPARSE_SIZE_SETVEC_HPP\n# define CPPAD_LOCAL_SPARSE_SIZE_SETVEC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/pod_vector.hpp>\n/*\n{xrst_begin_parent size_setvec dev}\n\nImplement SetVector Using Singly Linked Lists\n#############################################\n\nNamespace\n*********\nThis class is in the ``CppAD::local::sparse`` namespace.\n\nPublic\n******\nThe public member functions for the ``size_setvec`` class implements the\n:ref:`SetVector-name` concept when *s_type* is ``size_t`` .\n\n{xrst_end size_setvec}\n*/\n\n// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE\nnamespace CppAD { namespace local { namespace sparse {\n\n// forward declaration of iterator class\ntemplate <class s_type> class size_setvec_const_iterator;\n\n// =========================================================================\ntemplate <class s_type>\nclass size_setvec { // BEGIN_CLASS_LIST_SETVEC\n// =========================================================================\n\n/*\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_member_data dev}\n{xrst_spell\n   struct\n}\n\nclass size_setvec: Private Member Data\n######################################\n\npair_s_type\n***********\nThis ``struct`` is local to the ``size_setvec`` class.\nIt is the type used for each entry in a singly linked list\nand has the following fields:\n\nvalue\n=====\nThe is the value of an entry in the list\n(for sets, the first entry in the list is a reference count).\n\nnext\n====\nThis is the index in ``data_`` for the next entry in the list.\nIf there are no more entries in the list, this value is zero; i.e.,\n``data_[0]`` is used to represent the end of a list.\n\nend\\_\n*****\nThe possible elements in each set are ``0`` , ``1`` , ...,\n``end_-1``\n\nnumber_not_used\\_\n*****************\nNumber of elements of the ``data_`` vector that are not being used.\n\ndata_not_used\\_\n***************\nIndex in ``data_`` for the start of the linked list of elements\nthat are not being used.\n\ndata\\_\n******\nThe data for all the singly linked lists.\nIf *n_set*  > 0 ,\n``data`` [0]. ``value`` == ``end_`` and\n``data`` [0]. ``next`` == 0 .\n\nstart\\_\n*******\nThe size of this vector is the number of set; i.e.,\n:ref:`SetVector@Vector Operations@n_set` .\nThe starting index for *i*-th set is ``start_`` [ *i* ] .\nIf ``start_`` [ *i* ] == 0 , the i-th set has no elements.\nOtherwise it is the index of the reference count for the list.\n\nReference Count\n===============\nIf ``start_`` [ *i* ] != 0 , ``data_`` [ ``start_`` [ *i* ]]. ``value``\nis the reference count for the *i*-th list\n(not the value of an element in the list).\nThe reference count must be greater than zero.\n\nFirst Element\n=============\nIf ``start_`` [ *i* ] != 0 ,\n\n   *first_index* = ``data_`` [ ``start_`` [ *i* ]]. ``next``\n\nis the index of the first element in the list.\nThis must be non-zero because the list is empty.\n\nNext Element\n============\nStarting with *index* = *first_index* ,\nwhile *index*  != 0 ,\nThe value of the corresponding element in the list is\n``data_`` [ *index* ]. ``value`` (which must be less than ``end_`` ).\nThe *index* for the next element of the list is\n``data_`` [ *index* ]. ``next`` .\n\nLast Element\n============\nAn index *last* corresponds to the last element of a list if\n``data_`` [ *last* ]. ``next`` == 0 .\n(Note that ``data_[0].value == end_`` ).\n\npost\\_\n******\nThe size of this vector is the number of set; i.e.,\n:ref:`SetVector@Vector Operations@n_set` .\nStarting with *index* = ``post_`` [ *i* ] ,\nwhile *index*  != 0 ,\nThe value of the next element posted to the *i*-th list is\n``data_`` [ *index* ]. ``value`` (which must be less than ``end_`` ).\nThe *index* for the next element posted to the *i*-th list is\n``data_`` [ *index* ]. ``next`` .\n\ntemporary\\_\n***********\nA temporary vector, used by member functions, that keeps its capacity\nto avoid re-allocating memory.\nIf a member function calls another,\nno conditions about ``temporary_`` should be assumed during that call.\n\nSource Code\n***********\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   struct pair_s_type {s_type value; s_type next; };\n   friend bool CppAD::local::is_pod<pair_s_type>(void);\n   //\n   s_type                   end_;\n   s_type                   number_not_used_;\n   s_type                   data_not_used_;\n   //\n   pod_vector<pair_s_type> data_;\n   pod_vector<s_type>      start_;\n   pod_vector<s_type>      post_;\n   pod_vector<s_type>      temporary_;\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_member_data}\n------------------------------------------------------------------------------\n{xrst_begin size_setvec_reference_count dev}\n\nclass size_setvec private: Number of References to a Set\n########################################################\n\nSyntax\n******\n| *count* = *vec* . ``reference_count`` ( *i* )\n\nvec\n***\nIs a ``size_setvec`` object and can be ``const`` .\n\ni\n*\nis the index of the set that we are retrieving the references for.\n\ncount\n*****\nis the reference count.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   s_type reference_count(s_type i) const\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_reference_count}\n*/\n   {  // start data index\n      s_type start = start_[i];\n      if( start == 0 )\n         return 0;\n      //\n      // reference count\n      return data_[start].value;\n   }\n/*\n------------------------------------------------------------------------------\n{xrst_begin size_setvec_drop dev}\nclass size_setvec private: Drop a Set No Longer Being Used\n##########################################################\n\nSyntax\n******\n*not_used* = *vec* . ``drop`` ( *i* )\n\ni\n*\nis the index of the set that is dropped.\n\nreference_count\n***************\nif the set is non-empty, the\n:ref:`size_setvec_member_data@start_@Reference Count`\nis decremented.\n\nstart\\_\n*******\nThe value ``start_`` [ *i* ] is set to zero; i.e.,\nthe *i*-th set is empty after the call.\n\npost\\_\n******\nThe value ``post_`` [ *i* ] is set to zero; i.e.,\nany postings to the list are also dropped.\n\ndata_not_used\\_\n***************\nThe elements of ``data_`` were information for the *i*-th set,\nand are no longer being used, are added to the linked list starting at\n``data_not_used`` .\nThis includes both set elements and postings.\n\nnot_used\n********\nis the number of elements of ``data_`` that were begin used for the\n*i*-th set and are no longer being used; i.e., the number of elements\nmoved to ``data_not_used`` .\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   s_type drop(s_type i)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_drop}\n*/\n   {  // initialize count of addition elements not being used.\n      s_type number_drop = 0;\n\n      // the elements in the post list will no longer be used\n      s_type post = post_[i];\n      if( post != 0 )\n      {  // drop this posting\n         post_[i]    = 0;\n         //\n         // count elements in this posting\n         ++number_drop;\n         s_type previous = post;\n         s_type next     = data_[previous].next;\n         while( next != 0 )\n         {  previous = next;\n            next     = data_[previous].next;\n            ++number_drop;\n         }\n         //\n         // add the posting elements to data_not_used_\n         data_[previous].next = data_not_used_;\n         data_not_used_       = post;\n      }\n\n      // check for empty set\n      s_type start = start_[i];\n      if( start == 0 )\n         return number_drop;\n\n      // decrement reference counter\n      CPPAD_ASSERT_UNKNOWN( data_[start].value > 0 );\n      data_[start].value--;\n\n      // set this set to empty\n      start_[i] = 0;\n\n      // If new reference count is positive, the list corresponding to\n      // start is still being used.\n      if( data_[start].value > 0 )\n         return number_drop;\n\n      //\n      // count elements representing this set\n      ++number_drop;\n      s_type previous = start;\n      s_type next     = data_[previous].next;\n      while( next != 0 )\n      {  previous = next;\n         next     = data_[previous].next;\n         ++number_drop;\n      }\n      //\n      // add representing this set to data_not_used_\n      data_[previous].next = data_not_used_;\n      data_not_used_       = start;\n      //\n      return number_drop;\n   }\n/*\n------------------------------------------------------------------------------\n{xrst_begin size_setvec_get_data_index dev}\n\nclass size_setvec private: Get a New List Pair\n##############################################\n\nSyntax\n******\n*index* = *vec* . ``get_data_index`` ()\n\nvec\n***\nIs a ``size_setvec`` object.\n\ndata_not_used\\_\n***************\nIf the input value of ``data_not_used_`` is zero,\nit is not changed.\nOtherwise, the index for the element at the front of that list is returned.\nIn this case,\n``data_not_used`` is advanced to the next element in that list.\n\nnumber_not_used\\_\n*****************\nIf the input value of ``data_not_used_`` is zero,\n``number_not_used_`` is not changed.\nOtherwise it is decremented by one.\n\nindex\n*****\nIf the input value of ``data_not_used_`` is zero,\nthe size of ``data_`` is increased by one and index corresponding\nto the end of ``data_`` is returned.\nOtherwise, the input value for ``data_not_used_`` is returned.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   s_type get_data_index(void)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_get_data_index}\n*/\n   {  s_type index;\n      if( data_not_used_ > 0 )\n      {  CPPAD_ASSERT_UNKNOWN( number_not_used_ > 0 );\n         --number_not_used_;\n         index          = data_not_used_;\n         data_not_used_ = data_[index].next;\n      }\n      else\n      {  index = s_type( data_.extend(1) );\n      }\n      return index;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_check_data_structure dev}\n\nclass size_setvec private: Check Data Structure\n###############################################\n\nSyntax\n******\n*vec* . ``check_data_structure`` ()\n\nvec\n***\nIs a ``size_setvec`` object that is effectively const.\nIt is not declared const because the data structure is modified and\nthen restored.\n\nNDEBUG\n******\nIf ``NDEBUG`` is defined, the routine does nothing.\nOtherwise, if an error is found in the data structure,\na ``CPPAD_ASSERT_UNKNOWN`` is generated.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   void check_data_structure(void)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_check_data_structure}\n*/\n# ifdef NDEBUG\n   {  return; }\n# else\n   {  // number of sets\n      CPPAD_ASSERT_UNKNOWN( s_type( post_.size() ) == s_type( start_.size() ) );\n      s_type n_set = s_type( start_.size() );\n      if( n_set == 0 )\n      {  CPPAD_ASSERT_UNKNOWN( end_ == 0 );\n         CPPAD_ASSERT_UNKNOWN( number_not_used_ == 0 );\n         CPPAD_ASSERT_UNKNOWN( data_not_used_ == 0 );\n         CPPAD_ASSERT_UNKNOWN( s_type( data_.size() ) == 0 );\n         CPPAD_ASSERT_UNKNOWN( s_type( start_.size() ) == 0 );\n         return;\n      }\n      // check data index zero\n      CPPAD_ASSERT_UNKNOWN( data_[0].value == end_ );\n      CPPAD_ASSERT_UNKNOWN( data_[0].next  == 0  );\n      // -----------------------------------------------------------\n      // save a copy of the reference counters in temporary_\n      temporary_.resize( size_t(n_set) );\n      for(s_type i = 0; i < n_set; i++)\n         temporary_[i] = reference_count(i);\n      // -----------------------------------------------------------\n      // Initialize number of entries in data used by sets and posts.\n      // Start with 1 for data_[0].\n      s_type number_used_by_sets = 1;\n      // -----------------------------------------------------------\n      // count the number of entries in data_ that are used by sets\n      for(s_type i = 0; i < n_set; i++)\n      {  s_type start = start_[i];\n         if( start > 0 )\n         {  // check structure for this non-empty set\n            s_type reference_count = data_[start].value;\n            s_type next            = data_[start].next;\n            CPPAD_ASSERT_UNKNOWN( reference_count > 0 );\n            CPPAD_ASSERT_UNKNOWN( next != 0 );\n            CPPAD_ASSERT_UNKNOWN( data_[next].value < end_ );\n            //\n            // decrement the reference counter\n            data_[start].value--;\n            //\n            // count the entries when find last reference\n            if( data_[start].value == 0 )\n            {\n               // restore reference count\n               data_[start].value = temporary_[i];\n\n               // number of data entries used for this set\n               number_used_by_sets += number_elements(i) + 1;\n               /*\n               number of elements checks that value < end_\n               .resizeeach pair in the list except for the start pair\n               and the pair with index zero.\n               */\n            }\n         }\n      }\n      // ------------------------------------------------------------------\n      // count the number of entries in data_ that are used by posts\n      s_type number_used_by_posts = 0;\n      for(s_type i = 0; i < n_set; i++)\n      {  s_type post = post_[i];\n         if( post > 0 )\n         {  s_type value = data_[post].value;\n            s_type next  = data_[post].next;\n            CPPAD_ASSERT_UNKNOWN( value < end_ );\n            //\n            while( value < end_ )\n            {  ++number_used_by_posts;\n               value = data_[next].value;\n               next  = data_[next].next;\n            }\n         }\n      }\n      // ------------------------------------------------------------------\n      // count number of entries in data_not_used_\n      s_type count = 0;\n      s_type next = data_not_used_;\n      while( next != 0 )\n      {  ++count;\n         next = data_[next].next;\n      }\n      CPPAD_ASSERT_UNKNOWN( number_not_used_ == count );\n      // ------------------------------------------------------------------\n      s_type number_used = number_used_by_sets + number_used_by_posts;\n      CPPAD_ASSERT_UNKNOWN(\n         number_used + number_not_used_ == s_type( data_.size() )\n      );\n      return;\n   }\n# endif\n/*\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_vec_memory dev}\n\nclass size_setvec: Approximate Memory Used by Vector\n####################################################\n\nPublic\n******\nThis function is declared public, but is not part of\n:ref:`SetVector-name` concept.\n\nImplementation\n**************\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   s_type memory(void) const\n   {  return data_.capacity() * sizeof(pair_s_type); }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_vec_memory}\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_vec_print dev}\n\nclass size_setvec: Print a Vector of Sets\n#########################################\n\nPublic\n******\nThis function is declared public, but is not part of\n:ref:`SetVector-name` concept.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void print(void) const;\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_vec_print}\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_iterators dev}\n{xrst_spell\n   typedef\n}\n\nclass size_setvec: Iterators\n############################\n\nSetVector Concept\n*****************\n:ref:`SetVector@const_iterator`\n\ntypedef\n*******\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   friend class size_setvec_const_iterator<s_type>;\n   typedef size_setvec_const_iterator<s_type> const_iterator;\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_iterators}\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_default_ctor dev}\n\nclass size_setvec: Default Constructor\n######################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@Vector Operations@Constructor`\n\ns_type Members\n**************\nAll of the ``s_type`` member variables are initialized as zero.\n\npod_vector Members\n******************\nAll of the ``pod_vector`` member variables are initialized\nusing their default constructors.\n\nImplementation\n**************\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   size_setvec(void)\n   : end_(0), number_not_used_(0), data_not_used_(0)\n   { }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_default_ctor}\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_destructor dev}\n\nclass size_setvec: Destructor\n#############################\n\nImplementation\n**************\nIf ``NDEBUG`` is not defined,\n:ref:`check data structure<size_setvec_check_data_structure-name>` .\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   ~size_setvec(void)\n   {  check_data_structure(); }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_destructor}\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_copy_ctor dev}\n\nclass size_setvec: Copy Constructor\n###################################\n\nv\n*\nThe vector of sets that we are attempting to make a copy of.\n\nImplementation\n**************\nUsing the copy constructor is probably due to a ``size_setvec``\nbeing passed by value instead of by reference.\nThis is a CppAD programing error (not CppAD user error).\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   size_setvec(const size_setvec& v)\n   {  CPPAD_ASSERT_UNKNOWN(false); }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_copy_ctor}\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_vec_resize dev}\n\nclass size_setvec: Vector resize\n################################\n\nSetVector Concept\n*****************\n:ref:`vector resize<SetVector@Vector Operations@resize>`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void resize(s_type n_set, s_type end)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_vec_resize}\n*/\n   {  check_data_structure();\n\n      if( n_set == 0 )\n      {  CPPAD_ASSERT_UNKNOWN( end == 0 );\n         //\n         // restore object to start after constructor\n         // (no memory allocated for this object)\n         data_.clear();\n         start_.clear();\n         post_.clear();\n         number_not_used_  = 0;\n         data_not_used_    = 0;\n         end_              = 0;\n         //\n         return;\n      }\n      end_                   = end;\n      //\n      start_.resize( size_t(n_set) );\n      post_.resize(  size_t(n_set) );\n      //\n      for(s_type i = 0; i < n_set; i++)\n      {  start_[i] = 0;\n         post_[i]  = 0;\n      }\n      //\n      // last element, marks the end for all lists\n      data_.resize(1);\n      data_[0].value    = end_;\n      data_[0].next     = 0;\n      //\n      number_not_used_  = 0;\n      data_not_used_    = 0;\n   }\n/* %$$\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_vec_n_set dev}\n\nclass size_setvec: Number of Sets\n#################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@Vector Operations@n_set`\n\nImplementation\n**************\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   s_type n_set(void) const\n   {  return s_type( start_.size() ); }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_vec_n_set}\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_vec_end dev}\n\nclass size_setvec: End Value\n############################\n\nSetVector Concept\n*****************\n:ref:`SetVector@Vector Operations@end`\n\nImplementation\n**************\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   s_type end(void) const\n   {  return end_; }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_vec_end}\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_vec_assignment dev}\n\nclass size_setvec: Vector Assignment\n####################################\n\nSetVector Concept\n*****************\n:ref:`vector assignment<SetVector@Vector Operations@Assignment>`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void operator=(const size_setvec& other)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_vec_assignment}\n*/\n   {  end_             = other.end_;\n      number_not_used_ = other.number_not_used_;\n      data_not_used_   = other.data_not_used_;\n      data_            = other.data_;\n      start_           = other.start_;\n      post_            = other.post_;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_vec_swap dev}\n\nclass size_setvec: Vector Swap\n##############################\n\nSetVector Concept\n*****************\n:ref:`vector swap<SetVector@Vector Operations@swap>`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void swap(size_setvec& other)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_vec_swap}\n*/\n   {  // s_type objects\n      std::swap(end_             , other.end_);\n      std::swap(number_not_used_ , other.number_not_used_);\n      std::swap(data_not_used_   , other.data_not_used_);\n\n      // pod_vectors\n      data_.swap(       other.data_);\n      start_.swap(      other.start_);\n      post_.swap(       other.post_);\n      temporary_.swap(  other.temporary_);\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_number_elements dev}\n\nclass size_setvec: Number of Elements in a Set\n##############################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@number_elements`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   s_type number_elements(s_type i) const\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_number_elements}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( post_[i] == 0 );\n\n      // check if the set is empty\n      s_type start   = start_[i];\n      if( start == 0 )\n         return 0;\n\n      // initialize counter\n      s_type count   = 0;\n\n      // advance to the first element in the set\n      s_type next    = data_[start].next;\n      while( next != 0 )\n      {  CPPAD_ASSERT_UNKNOWN( data_[next].value < end_ );\n         count++;\n         next  = data_[next].next;\n      }\n      CPPAD_ASSERT_UNKNOWN( count > 0 );\n      return count;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_add_element dev}\n\nclass size_setvec: Add an Elements to a Set\n###########################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@add_element`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void add_element(s_type i, s_type element)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_add_element}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( i < s_type( start_.size() ) );\n      CPPAD_ASSERT_UNKNOWN( element < end_ );\n\n      // check for case where starting set is empty\n      s_type start = start_[i];\n      if( start == 0 )\n      {  start              = get_data_index();\n         start_[i]          = start;\n         data_[start].value = 1; // reference count\n         //\n         s_type next        = get_data_index();\n         data_[start].next  = next;\n         //\n         data_[next].value  = element;\n         data_[next].next   = 0;\n         return;\n      }\n      //\n      // start of set with this index\n      s_type previous = start_[i];\n      //\n      // first entry in this set\n      s_type next     = data_[previous].next;\n      s_type value    = data_[next].value;\n      //\n      // locate place to insert this element\n      while( value < element )\n      {  previous = next;\n         next     = data_[next].next;\n         value = data_[next].value;\n      }\n      //\n      // check for case where element is in the set\n      if( value == element )\n         return;\n      //\n      //\n      // check for case where this is the only reference to this set\n      CPPAD_ASSERT_UNKNOWN( element < value );\n      if( data_[start].value == 1 )\n      {  s_type insert         = get_data_index();\n         data_[insert].next    = next;\n         data_[insert].value   = element;\n         data_[previous].next  = insert;\n         //\n         return;\n      }\n      //\n      // must make a separate copy with new element inserted\n      CPPAD_ASSERT_UNKNOWN( data_[start].value > 1 );\n      data_[start].value--;   // reverence counter for old list\n      //\n      s_type start_new       = get_data_index();\n      data_[start_new].value = 1;         // reference counter for new list\n      s_type previous_new    = start_new;\n      //\n      // start of old set with this index\n      previous  = start_[i];\n      //\n      // first entry in old set\n      next    = data_[previous].next;\n      value   = data_[next].value;\n      //\n      // locate place to insert this element\n      while( value < element )\n      {  // copy to new list\n         s_type next_new          = get_data_index();\n         data_[previous_new].next = next_new;\n         data_[next_new].value    = value;\n         previous_new             = next_new;\n         //\n         // get next value\n         previous = next;\n         next     = data_[next].next;\n         value = data_[next].value;\n      }\n      CPPAD_ASSERT_UNKNOWN( element < value );\n      //\n      // insert the element\n      s_type next_new          = get_data_index();\n      data_[previous_new].next = next_new;\n      data_[next_new].value    = element;\n      previous_new             = next_new;\n      //\n      // copy rest of the old set\n      while( value < end_ )\n      {  // copy to new list\n         next_new                 = get_data_index();\n         data_[previous_new].next = next_new;\n         data_[next_new].value    = value;\n         previous_new             = next_new;\n         //\n         // get next value\n         previous = next;\n         next     = data_[next].next;\n         value = data_[next].value;\n      }\n      CPPAD_ASSERT_UNKNOWN( next == 0 );\n      data_[previous_new].next = 0;\n      //\n      // hook up new list\n      start_[i] = start_new;\n      return;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_post_element dev}\n\nclass size_setvec: Post an Elements for Addition to a Set\n#########################################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@post_element`\n\npost\\_\n******\nThe element is added at the front of the linked list\nthat starts at ``post_`` .\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void post_element(s_type i, s_type element)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_post_element}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( i < s_type( start_.size() ) );\n      CPPAD_ASSERT_UNKNOWN( element < end_ );\n\n      // put element at the front of this list\n      s_type next         = post_[i];\n      s_type post         = get_data_index();\n      post_[i]            = post;\n      data_[post].value   = element;\n      data_[post].next    = next;\n\n      return;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_process_post dev}\n\nclass size_setvec: Add Posted Elements to a Set\n###############################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@process_post`\n\npost\\_\n******\nUpon call, ``post_`` [ *i* ] is the linked list of elements to\nbe added to the *i*-th set.\nUpon return, ``post_`` [ *i* ] is zero; i.e., the list is empty.\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void process_post(s_type i)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_process_post}\n*/\n   {  // post\n      s_type post = post_[i];\n      //\n      // check if there are no elements to process\n      if( post == 0 )\n         return;\n      //\n      // check if there is only one element to process\n      s_type next  = data_[post].next;\n      if( next == 0 )\n      {  // done with this posting\n         s_type value     = data_[post].value;\n         post_[i]         = 0;\n         data_[post].next = data_not_used_;\n         data_not_used_   = post;\n         ++number_not_used_;\n         //\n         add_element(i, value);\n         //\n         return;\n      }\n      //\n      // copy posting to temporary_\n      temporary_.resize(0);\n      s_type previous  = post;\n      s_type value     = data_[previous].value;\n      CPPAD_ASSERT_UNKNOWN( value < end_ );\n      temporary_.push_back(value);\n      while( next != 0 )\n      {  previous = next;\n         value    = data_[previous].value;\n         CPPAD_ASSERT_UNKNOWN( value < end_ );\n         temporary_.push_back(value);\n         next     = data_[previous].next;\n      }\n      s_type number_post = s_type( temporary_.size() );\n      //\n      // done with this posting\n      post_[i]              = 0;\n      data_[previous].next  = data_not_used_;\n      data_not_used_        = post;\n      number_not_used_     += number_post;;\n      //\n      // sort temporary_\n      CPPAD_ASSERT_UNKNOWN( number_post > 1 );\n      std::sort( temporary_.data(), temporary_.data() + number_post);\n      // posting is the set { temporary_[0], ... , [number_post-1] }\n      // -------------------------------------------------------------------\n      // put union of posting and set i in\n      // temporary_[number_post], ... , temporary_[ temporary_.size()-1 ]\n      //\n      s_type i_next  = start_[i];\n      s_type i_value = end_;\n      if( i_next > 0 )\n      {  // skip reference count\n         i_next  = data_[i_next].next;\n         i_value = data_[i_next].value;\n      }\n      bool   post_is_subset = true;\n      s_type previous_post = end_;\n      for(s_type j =0; j < number_post; ++j)\n      {  s_type post_value = temporary_[j];\n         CPPAD_ASSERT_UNKNOWN( post_value < end_ );\n         while( i_value < post_value )\n         {  // i_value is in union\n            temporary_.push_back(i_value);\n            i_next  = data_[i_next].next;\n            i_value = data_[i_next].value;\n         }\n         if( i_value == post_value )\n         {  i_next  = data_[i_next].next;\n            i_value = data_[i_next].value;\n         }\n         else\n            post_is_subset = false;\n         //\n         if( previous_post != post_value )\n         {  // post_value is in union\n            temporary_.push_back(post_value);\n         }\n         previous_post = post_value;\n      }\n      // check if posting is a subset of set i\n      if( post_is_subset )\n         return;\n      //\n      // rest of elements in set i\n      while( i_value < end_ )\n      {  temporary_.push_back(i_value);\n         i_next  = data_[i_next].next;\n         i_value = data_[i_next].value;\n      }\n\n      // adjust number_not_used_\n      s_type number_drop = drop(i);\n      number_not_used_  += number_drop;\n\n      // put new set in linked list for set i\n      CPPAD_ASSERT_UNKNOWN( s_type( temporary_.size() ) >= number_post + 1 );\n      s_type index        = get_data_index();\n      start_[i]           = index; // start for the union\n      data_[index].value  = 1;    // reference count for the union\n      for(s_type j = number_post; j < s_type( temporary_.size() ); ++j)\n      {  next              = get_data_index();\n         data_[index].next = next;\n         data_[next].value = temporary_[j]; // next element in union\n         index             = next;\n      }\n      data_[index].next = 0; // end of union\n      //\n      return;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_is_element dev}\n\nclass size_setvec: Is an Element in a Set\n#########################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@is_element`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   bool is_element(s_type i, s_type element) const\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_is_element}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( post_[i] == 0 );\n      CPPAD_ASSERT_UNKNOWN( element < end_ );\n      //\n      s_type start = start_[i];\n      if( start == 0 )\n         return false;\n      //\n      s_type next  = data_[start].next;\n      s_type value = data_[next].value;\n      while( value < element )\n      {  next  = data_[next].next;\n         value = data_[next].value;\n      }\n      return element == value;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_clear dev}\n\nclass size_setvec: Assign a Set to be Empty\n###########################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@clear`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void clear(s_type target)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_clear}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( target < s_type( start_.size() ) );\n\n      // adjust number_not_used_\n      s_type number_drop = drop(target);\n      number_not_used_  += number_drop;\n\n      return;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_assignment dev}\n\nclass size_setvec: Assign a Set To Equal Another Set\n####################################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@assignment`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void assignment(\n      s_type               this_target  ,\n      s_type               other_source ,\n      const size_setvec&   other        )\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_assignment}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( other.post_[ other_source ] == 0 );\n      //\n      CPPAD_ASSERT_UNKNOWN( this_target < s_type( start_.size() )        );\n      CPPAD_ASSERT_UNKNOWN( other_source <   s_type( other.start_.size() )  );\n      CPPAD_ASSERT_UNKNOWN( end_        == other.end_   );\n\n      // check if we are assigning a set to itself\n      if( (this == &other) && (this_target == other_source) )\n         return;\n\n      // set depending on cases below\n      s_type this_start;\n\n      // If this and other are the same, use another reference to same list\n      s_type other_start = other.start_[other_source];\n      if( this == &other )\n      {  this_start = other_start;\n         if( other_start != 0 )\n         {  data_[other_start].value++; // increment reference count\n            CPPAD_ASSERT_UNKNOWN( data_[other_start].value > 1 );\n         }\n      }\n      else if( other_start  == 0 )\n      {  this_start = 0;\n      }\n      else\n      {  // make a copy of the other list in this size_setvec\n         this_start        = get_data_index();\n         s_type this_next  = get_data_index();\n         data_[this_start].value = 1; // reference count\n         data_[this_start].next  = this_next;\n         //\n         s_type next  = other.data_[other_start].next;\n         CPPAD_ASSERT_UNKNOWN( next != 0 );\n         while( next != 0 )\n         {  data_[this_next].value = other.data_[next].value;\n            next                   = other.data_[next].next;\n            if( next == 0 )\n               data_[this_next].next = 0;\n            else\n            {  s_type tmp = get_data_index();\n               data_[this_next].next = tmp;\n               this_next             = tmp;\n            }\n         }\n      }\n\n      // adjust number_not_used_\n      s_type number_drop = drop(this_target);\n      number_not_used_  += number_drop;\n\n      // set the new start value for this_target\n      start_[this_target] = this_start;\n\n      return;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_binary_union dev}\n\nclass size_setvec: Assign a Set To Union of Two Sets\n####################################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@binary_union`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void binary_union(\n      s_type                  this_target  ,\n      s_type                  this_left    ,\n      s_type                  other_right  ,\n      const size_setvec&      other        )\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_binary_union}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( post_[this_left] == 0 );\n      CPPAD_ASSERT_UNKNOWN( other.post_[ other_right ] == 0 );\n      //\n      CPPAD_ASSERT_UNKNOWN( this_target < s_type( start_.size() )         );\n      CPPAD_ASSERT_UNKNOWN( this_left < s_type( start_.size() )         );\n      CPPAD_ASSERT_UNKNOWN( other_right < s_type( other.start_.size() )   );\n      CPPAD_ASSERT_UNKNOWN( end_        == other.end_           );\n\n      // start indices for left and right sets\n      s_type start_left    = start_[this_left];\n      s_type start_right   = other.start_[other_right];\n\n      // if right is empty, the result is the left set\n      if( start_right == 0 )\n      {  assignment(this_target, this_left, *this);\n         return;\n      }\n      // if left is empty, the result is the right set\n      if( start_left == 0 )\n      {  assignment(this_target, other_right, other);\n         return;\n      }\n      // if neither case holds, then both left and right are non-empty\n      CPPAD_ASSERT_UNKNOWN( reference_count(this_left) > 0 );\n      CPPAD_ASSERT_UNKNOWN( other.reference_count(other_right) > 0 );\n\n      // we will use temporary_ for temporary storage of the union\n      temporary_.resize(0);\n\n      // for left next and value\n      s_type next_left   = data_[start_left].next;\n      s_type value_left  = data_[next_left].value;\n\n      // right next and value\n      s_type next_right  = other.data_[start_right].next;\n      s_type value_right = other.data_[next_right].value;\n\n      // both left and right set are non-empty\n      CPPAD_ASSERT_UNKNOWN( value_left < end_ && value_right < end_ );\n\n      // flag that detects if left is or right is a subset of the other\n      bool left_is_subset  = true;\n      bool right_is_subset = true;\n\n      while( (value_left < end_) && (value_right < end_) )\n      {  if( value_left == value_right )\n         {  // value is in both sets\n            temporary_.push_back(value_left);\n            //\n            // advance left\n            next_left  = data_[next_left].next;\n            value_left = data_[next_left].value;\n            //\n            // advance right\n            next_right  = other.data_[next_right].next;\n            value_right = other.data_[next_right].value;\n         }\n         else if( value_left < value_right )\n         {  // need a value from left that is not in right\n            left_is_subset = false;\n            temporary_.push_back(value_left);\n            //\n            // advance left to its next element\n            next_left  = data_[next_left].next;\n            value_left = data_[next_left].value;\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( value_right < value_left )\n            // need a value from right that is not in left\n            right_is_subset = false;\n            temporary_.push_back(value_right);\n            //\n            // advance right to its next element\n            next_right  = other.data_[next_right].next;\n            value_right = other.data_[next_right].value;\n         }\n      }\n      right_is_subset &= value_right == end_;\n      left_is_subset  &= value_left  == end_;\n      //\n      // check right first in case they are equal will do this assignment\n      if( right_is_subset )\n      {  assignment(this_target, this_left, *this);\n         return;\n      }\n      if( left_is_subset )\n      {  assignment(this_target, other_right, other);\n         return;\n      }\n      while( value_left < end_ )\n      {  CPPAD_ASSERT_UNKNOWN( value_right == end_);\n         temporary_.push_back(value_left);\n         next_left  = data_[next_left].next;\n         value_left = data_[next_left].value;\n      }\n      while( value_right < end_ )\n      {  CPPAD_ASSERT_UNKNOWN( value_left == end_);\n         temporary_.push_back(value_right);\n         next_right  = other.data_[next_right].next;\n         value_right = other.data_[next_right].value;\n      }\n\n      // adjust number_not_used_\n      s_type number_drop = drop(this_target);\n      number_not_used_  += number_drop;\n\n      // put new set in linked for this_target\n      CPPAD_ASSERT_UNKNOWN( s_type( temporary_.size() ) >= 2 );\n      s_type index        = get_data_index();\n      start_[this_target] = index; // start for the union\n      data_[index].value  = 1;    // reference count for the union\n      for(s_type i = 0; i < s_type( temporary_.size() ); ++i)\n      {  s_type next       = get_data_index();\n         data_[index].next = next;\n         data_[next].value = temporary_[i]; // next element in union\n         index             = next;\n      }\n      data_[index].next = 0; // end of union\n\n      return;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_binary_intersection dev}\n\nclass size_setvec: Assign a Set To Equal Another Set\n####################################################\n\nSetVector Concept\n*****************\n:ref:`SetVector@binary_intersection`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   void binary_intersection(\n      s_type                  this_target  ,\n      s_type                  this_left    ,\n      s_type                  other_right  ,\n      const size_setvec&      other        )\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_binary_intersection}\n*/\n   {  CPPAD_ASSERT_UNKNOWN( post_[this_left] == 0 );\n      CPPAD_ASSERT_UNKNOWN( other.post_[ other_right ] == 0 );\n      //\n      CPPAD_ASSERT_UNKNOWN( this_target < s_type( start_.size() )         );\n      CPPAD_ASSERT_UNKNOWN( this_left < s_type( start_.size() )         );\n      CPPAD_ASSERT_UNKNOWN( other_right < s_type( other.start_.size() )   );\n      CPPAD_ASSERT_UNKNOWN( end_        == other.end_           );\n\n      // start indices for left and right sets\n      s_type start_left    = start_[this_left];\n      s_type start_right   = other.start_[other_right];\n\n      // if left or right is empty, the result is empty\n      if( (start_left == 0) || (start_right == 0) )\n      {  clear(this_target);\n         return;\n      }\n      // if neither case holds, then both left and right are non-empty\n      CPPAD_ASSERT_UNKNOWN( reference_count(this_left) > 0 );\n      CPPAD_ASSERT_UNKNOWN( other.reference_count(other_right) > 0 );\n\n      // we will use temporary_ for temporary storage of the intersection\n      temporary_.resize(0);\n\n      // left next and value\n      s_type next_left   = data_[start_left].next;\n      s_type value_left  = data_[next_left].value;\n\n      // right next and value\n      s_type next_right  = other.data_[start_right].next;\n      s_type value_right = other.data_[next_right].value;\n\n      // both left and right set are non-empty\n      CPPAD_ASSERT_UNKNOWN( value_left < end_ && value_right < end_ );\n\n      // flag that detects if left is or right is a subset of the other\n      bool left_is_subset  = true;\n      bool right_is_subset = true;\n\n      while( (value_left < end_) && (value_right < end_) )\n      {  if( value_left == value_right )\n         {  // value is in both sets\n            temporary_.push_back(value_left);\n            //\n            // advance left\n            next_left  = data_[next_left].next;\n            value_left = data_[next_left].value;\n            //\n            // advance right\n            next_right  = other.data_[next_right].next;\n            value_right = other.data_[next_right].value;\n         }\n         else if( value_left < value_right )\n         {  // there is a value in left that is not in right\n            left_is_subset = false;\n            //\n            // advance left to its next element\n            next_left  = data_[next_left].next;\n            value_left = data_[next_left].value;\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( value_right < value_left )\n            // there is a value in right that is not in left\n            right_is_subset = false;\n            //\n            // advance right to its next element\n            next_right  = other.data_[next_right].next;\n            value_right = other.data_[next_right].value;\n         }\n      }\n      right_is_subset &= value_right == end_;\n      left_is_subset  &= value_left  == end_;\n      //\n      // check left first in case they are equal will do this assignment\n      if( left_is_subset )\n      {  assignment(this_target, this_left, *this);\n         return;\n      }\n      if( right_is_subset )\n      {  assignment(this_target, other_right, other);\n         return;\n      }\n\n      // adjust number_not_used_\n      s_type number_drop = drop(this_target);\n      number_not_used_  += number_drop;\n\n      // check for empty result\n      if( s_type( temporary_.size() ) == 0 )\n         return;\n\n      // put new set in linked for this_target\n      s_type index        = get_data_index();\n      start_[this_target] = index; // start for the union\n      data_[index].value  = 1;    // reference count for the union\n      for(s_type i = 0; i < s_type( temporary_.size() ); ++i)\n      {  s_type next       = get_data_index();\n         data_[index].next = next;\n         data_[next].value = temporary_[i]; // next element in union\n         index             = next;\n      }\n      data_[index].next = 0; // end of union\n\n      return;\n   }\n// =========================================================================\n}; // END_CLASS_LIST_SETVEC\n// =========================================================================\n\n// =========================================================================\ntemplate <class s_type>\nclass size_setvec_const_iterator { // BEGIN_CLASS_SIZE_SETVEC_CONST_ITERATOR\n// =========================================================================\n\n/*\n{xrst_begin size_setvec_const_iterator_member_data dev}\n\nclass size_setvec_const_iterator private: Member Data\n#####################################################\n\npair_s_type\n***********\nThis type is the same as\n:ref:`size_setvec pair_s_type<size_setvec_member_data@pair_s_type>` .\n\nend\\_\n*****\nThis is\n:ref:`size_setvec_member_data@end_`\nfor the ``size_setvec`` object this iterator refers to.\n\ndata\\_\n******\nThis is\n:ref:`size_setvec_member_data@data_`\nfor the ``size_setvec`` object this iterator refers to.\n\nnext_pair\\_\n***********\nNext element in the set that this iterator refers to.\nIf ``next_pair_.value == end_`` there are no more elements in the set.\n\nSource Code\n***********\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   typedef typename size_setvec<s_type>::pair_s_type pair_s_type;\n   const s_type                     end_;\n   const pod_vector<pair_s_type>&   data_;\n   pair_s_type                      next_pair_;\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_const_iterator_member_data}\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_const_iterator_ctor dev}\n\nclass size_setvec_const_iterator: Constructor\n#############################################\n\nSetVector Concept\n*****************\n:ref:`iterator constructor<SetVector@const_iterator@Constructor>`\n\nPrototype\n*********\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   size_setvec_const_iterator (const size_setvec<s_type>& list, s_type i)\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_const_iterator_ctor}\n*/\n   : end_ ( list.end_ ), data_( list.data_ )\n   {  CPPAD_ASSERT_UNKNOWN( list.post_[i] == 0 );\n      //\n      s_type start = list.start_[i];\n      if( start == 0 )\n      {  next_pair_.next  = 0;\n         next_pair_.value = end_;\n      }\n      else\n      {  // value for this entry is reference count for list\n         CPPAD_ASSERT_UNKNOWN( data_[start].value > 0 );\n\n         // data index where list truly starts\n         s_type next = data_[start].next;\n         CPPAD_ASSERT_UNKNOWN( next != 0 );\n\n         // true first entry in the list\n         next_pair_ = data_[next];\n         CPPAD_ASSERT_UNKNOWN( next_pair_.value < end_ );\n      }\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_const_iterator_dereference dev}\n\nclass size_setvec_const_iterator: Dereference\n#############################################\n\nSetVector Concept\n*****************\n:ref:`iterator deference<SetVector@const_iterator@Dereference>`\n\nImplementation\n**************\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   s_type operator*(void)\n   {  return next_pair_.value; }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_const_iterator_dereference}\n-------------------------------------------------------------------------------\n{xrst_begin size_setvec_const_iterator_increment dev}\n\nclass size_setvec_const_iterator: Increment\n###########################################\n\nSetVector Concept\n*****************\n:ref:`iterator increment<SetVector@const_iterator@Increment>`\n\nImplementation\n**************\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   size_setvec_const_iterator& operator++(void)\n   {  next_pair_  = data_[next_pair_.next];\n      return *this;\n   }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end size_setvec_const_iterator_increment}\n*/\n// ===========================================================================\n}; // END_CLASS_SIZE_SETVEC_CONST_ITERATOR\n// ===========================================================================\n\n// Implemented after size_setvec_const_iterator so can use it\ntemplate <class s_type>\ninline void size_setvec<s_type>::print(void) const\n{  std::cout << \"size_setvec:\\n\";\n   for(s_type i = 0; i < n_set(); i++)\n   {  std::cout << \"set[\" << i << \"] = {\";\n      const_iterator itr(*this, i);\n      while( *itr != end() )\n      {  std::cout << *itr;\n         if( *(++itr) != end() ) std::cout << \",\";\n      }\n      std::cout << \"}\\n\";\n   }\n   return;\n}\n// ----------------------------------------------------------------------------\n\n} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sparse/svec_setvec.hpp",
    "content": "# ifndef CPPAD_LOCAL_SPARSE_SVEC_SETVEC_HPP\n# define CPPAD_LOCAL_SPARSE_SVEC_SETVEC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/define.hpp>\n# include <cppad/local/is_pod.hpp>\n# include <list>\n\n// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE\nnamespace CppAD { namespace local { namespace sparse {\n\n/*!\n\\file svec_setvec.hpp\nVector of sets of positive integers stored as size_t vector\nwith the element values strictly increasing.\n\nTesting indicates this does not work as well as using sparse::list_setvec\n(not currently being used except by test_more/general/local/vector_set.cpp).\n*/\nclass svec_setvec_const_iterator;\n\n// =========================================================================\n/*!\nVector of sets of positive integers, each set stored as a size_t vector.\n\nAll the public members for this class are also in the\nsparse::pack_setvec and sparse::list_setvec classes.\nThis defines the CppAD vector_of_sets concept.\n*/\nclass svec_setvec {\n   friend class svec_setvec_const_iterator;\nprivate:\n   /// Possible elements in each set are 0, 1, ..., end_ - 1;\n   size_t end_;\n\n   /// number of elements in data_ that have been allocated\n   /// and are no longer being used.\n   size_t data_not_used_;\n\n   /// The data for all the singly linked lists.\n   pod_vector<size_t> data_;\n\n   /*!\n   Starting point for i-th set is start_[i].\n\n   \\li\n   If the i-th set has no elements, start_[i] is zero.\n   Othersize the conditions below hold.\n\n   \\li\n   data_[ start_[i] ] is the reference count for this set\n\n   \\li\n   data_[ start_[i] + 1 ] is the first element in this set.\n\n   \\li\n   data_[ start_[i] + 2 ] is the first element in this set.\n\n   \\li\n   data_[ start_[i] + 2 + n ] = end_ where n is the number of\n   elements in this set\n   */\n   pod_vector<size_t> start_;\n\n   /*!\n   Vectors of elements that have not yet been added to corresponding sets.\n\n   \\li\n   If all the post_element calls for the i-th set have been added,\n   post_[i] is zero. Otherwise the conditions below hold.\n\n   \\li\n   data_[ post_[i] ]  the number of elements that have been posted,\n   but not yet added, to set i.\n\n   \\li\n   data_[ post_[i] + 1 ] is the capacity for holding elements\n   which is greater than or equal the number of elements.\n\n   \\li\n   data_[ post_[i] + 2 ] is the first element that has been posted,\n   but not yet added, to set i.\n\n   \\li\n   data_[ post_[i] + 1 + n] is the last element that has been posted,\n   but not yet added, to set i.\n   Here n is the number of elements that are posted and not yet added\n   to set i.\n   */\n   pod_vector<size_t> post_;\n   // -----------------------------------------------------------------\n   /*!\n   Counts references to a set.\n\n   \\param i\n   is the index of the set that we are counting the references to.\n\n   \\return\n   if the set is empty, the return value is zero.\n   Otherwise it is the number of sets that share the same vector.\n   */\n   size_t reference_count(size_t i) const\n   {  // start data index\n      size_t start = start_[i];\n      if( start == 0 )\n         return 0;\n      //\n      // reference count\n      return data_[start];\n   }\n   // -----------------------------------------------------------------\n   /*!\n   drop a set.\n\n   \\param i\n   is the index of the set that will be dropped.\n\n   \\par reference_count\n   if the set is non-empty,\n   the reference count corresponding to index will be decremented.\n\n   \\return\n   is the number of elements of data_ that will be lost when the set is\n   dropped. This is non-zero when the initial reference count is one.\n   */\n   size_t drop(size_t i)\n   {\n      // reference count\n      size_t ref_count = reference_count(i);\n\n      // empty set case\n      if( ref_count == 0 )\n         return 0;\n\n      // start\n      size_t start = start_[i];\n      CPPAD_ASSERT_UNKNOWN( data_[start] == ref_count );\n\n      // decrement reference counter\n      data_[start]--;\n\n      // nothing lost unless new reference count is zero\n      if( ref_count != 1 )\n         return 0;\n\n      // number of elements in the set\n      size_t length = data_[start + 1];\n\n      // reference count, length, end marker, plus elements in set\n      size_t number_lost = 3 + length;\n\n      // number_lost\n      return number_lost;\n   }\n   // -----------------------------------------------------------------\n   /*!\n   Checks data structure\n   (effectively const, but modifies and restores values)\n   */\n# ifdef NDEBUG\n   void check_data_structure(void)\n   {  return; }\n# else\n   void check_data_structure(void)\n   {  // number of sets\n      CPPAD_ASSERT_UNKNOWN( post_.size() == start_.size() );\n      size_t n_set = start_.size();\n      if( n_set == 0 )\n      {  CPPAD_ASSERT_UNKNOWN( end_ == 0 );\n         CPPAD_ASSERT_UNKNOWN( data_not_used_ == 0 );\n         CPPAD_ASSERT_UNKNOWN( data_.size() == 0 );\n         CPPAD_ASSERT_UNKNOWN( start_.size() == 0 );\n         CPPAD_ASSERT_UNKNOWN( post_.size() == 0 );\n         return;\n      }\n      // ------------------------------------------------------------------\n      // save the reference counters\n      pod_vector<size_t> ref_count(n_set);\n      for(size_t i = 0; i < n_set; i++)\n         ref_count[i] = reference_count(i);\n      // ------------------------------------------------------------------\n\n      // ------------------------------------------------------------------\n      // count the number of entries in data_ that are used by sets\n      size_t data_used_by_sets = 0;\n      for(size_t i = 0; i < n_set; i++)\n      {  size_t start = start_[i];\n         if( start > 0 )\n         {  // check structure for this non-empty set\n            size_t reference_count = data_[start + 0];\n            size_t length          = data_[start + 1];\n            size_t first           = data_[start + 2];\n            size_t last            = data_[start + 2 + length];\n            CPPAD_ASSERT_UNKNOWN( reference_count > 0 );\n            CPPAD_ASSERT_UNKNOWN( length          > 0 );\n            CPPAD_ASSERT_UNKNOWN( first < end_);\n            CPPAD_ASSERT_UNKNOWN( last == end_);\n            //\n            // decrement the reference counter\n            data_[start]--;\n            //\n            // count the entries when find last reference\n            if( data_[start] == 0 )\n            {\n               // restore reference count\n               data_[start] = ref_count[i];\n\n               // number of data_ entries used for this set\n               data_used_by_sets += number_elements(i) + 3;\n            }\n         }\n      }\n      // ------------------------------------------------------------------\n      // count the number of entries in data_ that are used by posts\n      size_t data_used_by_posts = 0;\n      for(size_t i = 0; i < n_set; i++)\n      {  size_t post = post_[i];\n         if( post > 0 )\n         {  CPPAD_ASSERT_UNKNOWN( data_[post] > 0 );\n            CPPAD_ASSERT_UNKNOWN( data_[post + 1] > 0 );\n            CPPAD_ASSERT_UNKNOWN( data_[post + 2] < end_ );\n            //\n            size_t capacity     = data_[post + 1];\n            data_used_by_posts += capacity + 2;\n         }\n      }\n      // ------------------------------------------------------------------\n      size_t data_used = data_used_by_sets + data_used_by_posts;\n      CPPAD_ASSERT_UNKNOWN(\n         data_used + data_not_used_ == data_.size()\n      );\n      return;\n   }\n# endif\n   // -----------------------------------------------------------------\n   /*!\n   Check if one of two sets is a subset of the other set\n\n   \\param one_this\n   is the index in this svec_setvec object of the first set.\n\n   \\param two_other\n   is the index in other svec_setvec object of the second set.\n\n   \\param other\n   is the other svec_setvec object which may be the same as this object.\n\n   \\return\n   If zero, neither set is a subset of the other.\n   If one, then one is a subset of two and they are not equal.\n   If two, then two is a subset of one and they are not equal.\n   If three, then the sets are equal.\n   */\n   size_t is_subset(\n      size_t                     one_this    ,\n      size_t                     two_other   ,\n      const svec_setvec&         other       ) const\n   {\n      CPPAD_ASSERT_UNKNOWN( one_this  < start_.size()         );\n      CPPAD_ASSERT_UNKNOWN( two_other < other.start_.size()   );\n      CPPAD_ASSERT_UNKNOWN( end_  == other.end_               );\n      //\n      // start\n      size_t start_one    = start_[one_this];\n      size_t start_two    = other.start_[two_other];\n      //\n      if( start_one == 0 )\n      {  // set one is empty\n         if( start_two == 0 )\n         {  // set two is empty\n            return 3;\n         }\n         // set one is empty and two is not empty\n         return 1;\n      }\n      if( start_two == 0 )\n      {  // set two is empty and one is not empty\n         return 2;\n      }\n      //\n      // data index\n      size_t index_one    = start_one + 2;\n      size_t index_two    = start_two + 2;\n      //\n      // value\n      size_t value_one    = data_[index_one];\n      size_t value_two    = other.data_[index_two];\n      //\n      bool one_subset     = true;\n      bool two_subset     = true;\n      //\n      size_t value_union = std::min(value_one, value_two);\n      while( (one_subset | two_subset) && (value_union < end_) )\n      {  //\n         if( value_one > value_union )\n            two_subset = false;\n         else\n         {  // value_one <= value_two and value_one < end_\n            value_one = data_[++index_one];\n         }\n         //\n         if( value_two > value_union )\n            one_subset = false;\n         else\n         {  // value_two <= value_one and value_two < end_\n            value_two = other.data_[++index_two];\n         }\n         value_union = std::min(value_one, value_two);\n      }\n      if( one_subset )\n      {  if( two_subset )\n         {  // sets are equal\n            return 3;\n         }\n         // one is a subset of two\n         return 1;\n      }\n      if( two_subset )\n      {  // two is a subset of one\n         return 2;\n      }\n      //\n      // neither is a subset\n      return 0;\n   }\n   // -----------------------------------------------------------------\n   /*!\n   Does garbage collection when indicated.\n\n   This routine should be called when more entries are not being used.\n   If a significant proportion are not being used, the data structure\n   will be compacted.\n\n   The size of data_ should equal the number of entries used by the sets\n   plus the number of entries that are not being used data_not_used_.\n   Note that data_[0] never gets used.\n   */\n   void collect_garbage(void)\n   {  if( data_not_used_ < data_.size() / 2 +  100)\n         return;\n      check_data_structure();\n      //\n      // number of sets including empty ones\n      size_t n_set  = start_.size();\n      //\n      // use temporary to hold copy of data_ and start_\n      pod_vector<size_t> data_tmp(1); // data_tmp[0] will not be used\n      pod_vector<size_t> start_tmp(n_set);\n      //\n      for(size_t i = 0; i < n_set; i++)\n      {  size_t start    = start_[i];\n         if( start == 0 )\n            start_tmp[i] = 0;\n         else\n         {  // check if this set has already been copied\n            if( data_[start] == 0 )\n            {  // starting address in data_tmp has been stored here\n               start_tmp[i] = data_[start + 1];\n            }\n            else\n            {  size_t tmp_start          = data_tmp.extend(2);\n               start_tmp[i]              = tmp_start;\n               data_tmp[tmp_start + 0]   = data_[start + 0];\n               data_tmp[tmp_start + 1]   = data_[start + 1];\n               //\n               for(size_t j = 2; data_[start + j] != end_; ++j)\n                  data_tmp.push_back( data_[start + j] );\n               data_tmp.push_back(end_);\n               //\n               // flag that indicates this set already copied\n               data_[start] = 0;\n               //\n               // store the starting address here\n               data_[start + 1] = tmp_start;\n            }\n         }\n      }\n\n      // swap the tmp and old data vectors\n      start_.swap(start_tmp);\n      data_.swap(data_tmp);\n\n      // all of the elements, except the first, are used\n      data_not_used_ = 1;\n   }\n   // -----------------------------------------------------------------\n   /*!\n   Assign a set equal to the union of a set and a vector;\n\n   \\param target\n   is the index in this svec_setvec object of the set being assigned.\n\n   \\param left\n   is the index in this svec_setvec object of the\n   left operand for the union operation.\n   It is OK for target and left to be the same value.\n\n   \\param right\n   is a vector of size_t, sorted in ascending order.\n   right operand for the union operation.\n   Elements can be repeated in right, but are not be repeated in the\n   resulting set.\n   All of the elements must have value less than end();\n   */\n   void binary_union(\n      size_t                    target ,\n      size_t                    left   ,\n      const pod_vector<size_t>& right  )\n   {  CPPAD_ASSERT_UNKNOWN( post_[left] == 0 );\n      //\n      CPPAD_ASSERT_UNKNOWN( target < start_.size() );\n      CPPAD_ASSERT_UNKNOWN( left   < start_.size() );\n\n      size_t start_left   = start_[left];\n      // -------------------------------------------------------------------\n      // Check if right is a subset of left so that we used reference count\n      // and not make copies of identical sets.\n      //\n      // initialize index for left and right sets\n      size_t current_left  = start_left;\n      size_t current_right = 0;\n      //\n      // initialize value_left\n      size_t value_left  = end_;\n      if( current_left > 0 )\n      {  // advance from reference counter to data\n         current_left = current_left + 2;\n         value_left   = data_[current_left];\n         CPPAD_ASSERT_UNKNOWN( value_left < end_);\n      }\n      //\n      // initialize value_right\n      size_t value_right = end_;\n      if( right.size() > 0 )\n         value_right = right[current_right];\n      //\n      bool subset = true;\n      while( subset & (value_right < end_) )\n      {  while( value_left < value_right )\n         {  // advance left\n            value_left = data_[++current_left];\n         }\n         if( value_right < value_left )\n            subset = false;\n         else\n         {  // advance right\n            ++current_right;\n            if( current_right == right.size() )\n               value_right = end_;\n            else\n               value_right = right[current_right];\n         }\n      }\n      //\n      if( subset )\n      {  // target = left will use reference count for identical sets\n         assignment(target, left, *this);\n         return;\n      }\n\n      // -------------------------------------------------------------------\n      // number of elements that will be deleted by removing old version\n      // of target\n      size_t number_lost = drop(target);\n\n      // drop any posting for the target set\n      size_t post = post_[target];\n      if( post > 0 )\n      {  CPPAD_ASSERT_UNKNOWN( target != left );\n         size_t capacity = data_[post + 1];\n         number_lost += capacity + 2;\n         post_[target] = 0;\n      }\n      //\n      // start new version of target\n      size_t start       = data_.extend(2);\n      start_[target]     = start;\n      data_[start]       = 1; // reference count\n      // data_[start + 1] = length is not yet known\n      //\n      // initialize value_left\n      current_left = start_left;\n      value_left   = end_;\n      if( current_left > 0 )\n      {  // advance from reference counter to data\n         current_left = current_left + 2;\n         value_left   = data_[current_left];\n         CPPAD_ASSERT_UNKNOWN( value_left < end_);\n      }\n      //\n      // initialize value_right\n      value_right = end_;\n      if( right.size() > 0 )\n         value_right = right[current_right];\n      //\n      // merge\n      while( (value_left < end_) || (value_right < end_) )\n      {  if( value_left == value_right)\n         {  // advance left so left and right are no longer equal\n            ++current_left;\n            value_left = data_[current_left];\n            CPPAD_ASSERT_UNKNOWN( value_right < value_left );\n         }\n         //\n         if( value_left < value_right )\n         {  // value_left case\n            CPPAD_ASSERT_UNKNOWN( value_left < end_ );\n            data_.push_back( value_left );\n            //\n            // advance left\n            ++current_left;\n            value_left = data_[current_left];\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( value_right < value_left )\n            // value_right case\n            CPPAD_ASSERT_UNKNOWN( value_right < end_);\n            data_.push_back( value_right );\n            //\n            // advance right (skip values equal to this one)\n            size_t previous_value = value_right;\n            while( value_right == previous_value )\n            {  ++current_right;\n               if( current_right == right.size() )\n                  value_right = end_;\n               else\n               {  value_right = right[current_right];\n                  CPPAD_ASSERT_UNKNOWN( value_right < end_ );\n               }\n            }\n         }\n      }\n      // make end of target list\n      data_.push_back( end_ );\n      //\n      // reference count, length, and end_ are not elements of set\n      CPPAD_ASSERT_UNKNOWN( data_.size() > start + 3 );\n      size_t length    = data_.size() - (start + 3);\n      data_[start + 1] = length;\n      //\n\n      // adjust data_not_used_\n      data_not_used_ += number_lost;\n      collect_garbage();\n   }\npublic:\n   /// declare a const iterator\n   typedef svec_setvec_const_iterator const_iterator;\n   // -----------------------------------------------------------------\n   /*!\n   Default constructor (no sets)\n   */\n   svec_setvec(void) :\n   end_(0)            ,\n   data_not_used_(0)  ,\n   data_(0)           ,\n   start_(0)          ,\n   post_(0)\n   { }\n   // -----------------------------------------------------------------\n   /// Destructor\n   ~svec_setvec(void)\n   {  check_data_structure();\n   }\n   // -----------------------------------------------------------------\n   /*!\n   Using copy constructor is a programing (not user) error\n\n   \\param v\n   vector of sets that we are attempting to make a copy of.\n   */\n   svec_setvec(const svec_setvec& v)\n   {  // Error: Probably a svec_setvec argument has been passed by value\n      CPPAD_ASSERT_UNKNOWN(false);\n   }\n   // -----------------------------------------------------------------\n   /*!\n   Assignment operator.\n\n   \\param other\n   this svec_setvec with be set to a deep copy of other.\n   */\n   void operator=(const svec_setvec& other)\n   {  end_           = other.end_;\n      data_not_used_ = other.data_not_used_;\n      data_          = other.data_;\n      start_         = other.start_;\n      post_          = other.post_;\n   }\n   // -----------------------------------------------------------------\n   /*!\n   swap (used by move semantics version of ADFun assignment operator)\n\n   \\param other\n   this sparse::list_setvec with be swapped with other.\n\n   \\par vector_of_sets\n   This public member function is not yet part of\n   the vector_of_sets concept.\n   */\n   void swap(svec_setvec& other)\n   {  // size_t objects\n      std::swap(end_             , other.end_);\n      std::swap(data_not_used_   , other.data_not_used_);\n\n      // pod_vectors\n      data_.swap(       other.data_);\n      start_.swap(      other.start_);\n      post_.swap(       other.post_);\n   }\n   // -----------------------------------------------------------------\n   /*!\n   Start a new vector of sets.\n\n   \\param n_set\n   is the number of sets in this vector of sets.\n   \\li\n   If n_set is zero, any memory currently allocated for this object\n   is freed.\n   \\li\n   If n_set is non-zero, a vector of n_set sets is created and all\n   the sets are initialized as empty.\n\n   \\param end\n   is the maximum element plus one (the minimum element is 0).\n   If n_set is zero, end must also be zero.\n   */\n   void resize(size_t n_set, size_t end)\n   {  check_data_structure();\n\n      if( n_set == 0 )\n      {  CPPAD_ASSERT_UNKNOWN(end == 0 );\n         //\n         // restore object to start after constructor\n         // (no memory allocated for this object)\n         data_.clear();\n         start_.clear();\n         post_.clear();\n         data_not_used_  = 0;\n         end_            = 0;\n         //\n         return;\n      }\n      end_                   = end;\n      //\n      start_.resize(n_set);\n      post_.resize(n_set);\n      for(size_t i = 0; i < n_set; i++)\n      {  start_[i] = 0;\n         post_[i]  = 0;\n      }\n      //\n      data_.resize(1);     // first element is not used\n      data_not_used_  = 1;\n   }\n   // -----------------------------------------------------------------\n   /*!\n   Return number of elements in a set.\n\n   \\param i\n   is the index of the set we are checking number of the elements of.\n   */\n   size_t number_elements(size_t i) const\n   {  CPPAD_ASSERT_UNKNOWN( post_[i] == 0 );\n      //\n      size_t start = start_[i];\n      if( start == 0 )\n         return 0;\n      return data_[start + 1];\n   }\n   // ------------------------------------------------------------------\n   /*!\n   Post an element for delayed addition to a set.\n\n   \\param i\n   is the index for this set in the vector of sets.\n\n   \\param element\n   is the value of the element that we are posting.\n   The same element may be posted multiple times.\n\n   \\par\n   It is faster to post multiple elements to set i and then call\n   process_post(i) then to add each element individually.\n   It is an error to call any member function,\n   that depends on the value of set i,\n   before processing the posts to set i.\n   */\n   void post_element(size_t i, size_t element)\n   {  CPPAD_ASSERT_UNKNOWN( i < start_.size() );\n      CPPAD_ASSERT_UNKNOWN( element < end_ );\n\n      size_t post = post_[i];\n      if( post == 0 )\n      {  // minimum capacity for an post vector\n         size_t min_capacity = 10;\n         size_t post_new = data_.extend(min_capacity + 2);\n         data_[post_new]     = 1;            // length\n         data_[post_new + 1] = min_capacity; // capacity\n         data_[post_new + 2] = element;\n         post_[i]            = post_new;\n      }\n      else\n      {  size_t length   = data_[post];\n         size_t capacity = data_[post + 1];\n         if( length == capacity )\n         {\n            size_t post_new = data_.extend( 2 * capacity );\n            //\n            data_[post_new]     = length + 1;\n            data_[post_new + 1] = 2 * capacity;\n            //\n            for(size_t j = 0; j < length; j++)\n               data_[post_new + 2 + j] = data_[post + 2 + j];\n            data_[post_new + 2 + length] = element;\n            //\n            post_[i]            = post_new;\n            size_t number_lost = length + 2;\n            data_not_used_    += number_lost;\n         }\n         else\n         {  data_[post]              = length + 1;\n            data_[post + 2 + length] = element;\n         }\n      }\n\n      // check amount of data_not_used_\n      collect_garbage();\n\n      return;\n   }\n   // -----------------------------------------------------------------\n   /*!\n   process post entries for a specific set.\n\n   \\param i\n   index of the set for which we are processing the post entries.\n\n   \\par post_\n   Upon call, post_[i] is location in data_ of the elements that get\n   added to the i-th set.  Upon return, post_[i] is zero.\n   */\n   void process_post(size_t i)\n   {  // start\n      size_t start = start_[i];\n      // post\n      size_t post = post_[i];\n      //\n      // check if there are no elements to process\n      if( post == 0 )\n         return;\n      //\n      // sort the elements that need to be processed\n      size_t  length_post   = data_[post];\n      size_t  capacity_post = data_[post + 1];\n      size_t* first_post    = data_.data() + post + 2;\n      size_t* last_post     = first_post + length_post;\n      std::sort(first_post, last_post);\n      // -------------------------------------------------------------------\n      // check if posted elements are a subset of set\n      //\n      // first element of the set\n      size_t current_set = start;\n      size_t value_set   = end_;\n      if( start > 0 )\n      {  current_set = start + 2;\n         value_set   = data_[current_set];\n      }\n      //\n      // first element to post\n      size_t* current_post = first_post;\n      size_t  value_post   = *current_post;\n      //\n      bool subset = true;\n      while( subset & (value_post != end_) )\n      {  while( value_set < value_post )\n            value_set = data_[++current_set];\n         if( value_post < value_set )\n            subset = false;\n         else\n         {  ++current_post;\n            if( current_post == last_post )\n               value_post = end_;\n            else\n               value_post = *current_post;\n         }\n      }\n      //\n      if( subset )\n      {  // drop the post_ elements\n         post_[i] = 0;\n         //\n         size_t number_lost = capacity_post + 2;\n         data_not_used_    += number_lost;\n         collect_garbage();\n         //\n         // nothing else to do\n         return;\n      }\n      // -------------------------------------------------------------------\n      // number of element that will be lost by removing old i-th set\n      size_t number_lost = drop(i);\n\n      // start new version of i-th set\n      size_t start_new  = data_.extend(2);\n      start_[i]         = start_new;\n      data_[start_new]  = 1; // reference count\n      // data[start_new + 1] = length_new is not yet known\n      //\n      // first element of the set\n      current_set = start;\n      value_set   = end_;\n      if( start > 0 )\n      {  current_set = start + 2;\n         value_set   = data_[current_set];\n      }\n      //\n      // first element to process\n      current_post = first_post;\n      value_post   = *current_post;\n      //\n      // merge\n      while( (value_set < end_) || (current_post != last_post ) )\n      {  if( value_set == value_post )\n         {  // advance left so left and right are no longer equal\n            ++current_set;\n            value_set = data_[current_set];\n            CPPAD_ASSERT_UNKNOWN( value_post < value_set );\n         }\n         //\n         if( value_set < value_post )\n         {  // add value_set\n            CPPAD_ASSERT_UNKNOWN( value_set < end_ );\n            data_.push_back( value_set );\n            //\n            // advance set\n            ++current_set;\n            value_set = data_[current_set];\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( value_post < value_set )\n            // add value_post\n            CPPAD_ASSERT_UNKNOWN( value_post < end_);\n            data_.push_back( value_post );\n            //\n            // advance post (skip values equal to this one)\n            size_t value_previous = value_post;\n            while( value_post == value_previous )\n            {  ++current_post;\n               if( current_post == last_post )\n                  value_post = end_;\n               else\n                  value_post = *current_post;\n            }\n         }\n      }\n      // make end of target list\n      data_.push_back( end_ );\n      //\n      // reference count, length, and end_ are not elements of set\n      CPPAD_ASSERT_UNKNOWN( data_.size() > start_new + 3 );\n      size_t length_new    = data_.size() - (start_new + 3);\n      data_[start_new + 1] = length_new;\n      CPPAD_ASSERT_UNKNOWN( data_[start_new + length_new + 2] == end_ );\n      //\n      // drop to post_ elements for this set\n      post_[i] = 0;\n      //\n      number_lost    += capacity_post + 2;\n      data_not_used_ += number_lost;\n      collect_garbage();\n      //\n      return;\n   }\n   // -----------------------------------------------------------------\n   /*!\n   Add one element to a set.\n\n   \\param i\n   is the index for this set in the vector of sets.\n\n   \\param element\n   is the element we are adding to the set.\n   */\n   void add_element(size_t i, size_t element)\n   {  CPPAD_ASSERT_UNKNOWN( i   < start_.size() );\n      CPPAD_ASSERT_UNKNOWN( element < end_ );\n\n      // check if element is already in the set\n      if( is_element(i, element) )\n         return;\n\n      // check for case where old set is empty\n      size_t start = start_[i];\n      if( start == 0 )\n      {  start            = data_.extend(4);\n         start_[i]        = start;\n         data_[start]     = 1;        // reference count\n         data_[start + 1] = 1;        // length\n         data_[start + 2] = element;  // the element\n         data_[start + 3] = end_;     // end marker\n         return;\n      }\n      //\n      size_t number_lost = drop(i);\n      //\n      // start of new set\n      size_t length         = data_[start + 1];\n      size_t new_start      = data_.extend(2);\n      data_[new_start]      = 1;          // reference count\n      data_[new_start + 1]  = length + 1; // new length\n      //\n      size_t count = 0;\n      size_t value     = data_[start + 2 + count];\n      // before new element\n      while( value < element)\n      {  data_.push_back( value );\n         ++count;\n         value   = data_[start + 2 + count];\n      }\n      CPPAD_ASSERT_UNKNOWN( element < value )\n      // new element\n      data_.push_back( element );\n      // after new element\n      while( value < end_ )\n      {  data_.push_back( value );\n         ++count;\n         value   = data_[start + 2 + count];\n      }\n      data_.push_back( end_ );\n\n      //\n      // connect up new set\n      start_[i] = new_start;\n\n      // adjust data_not_used_\n      data_not_used_ += number_lost;\n      collect_garbage();\n      //\n      return;\n   }\n   // -----------------------------------------------------------------\n   /*!\n   Check if an element is in a set.\n\n   \\param i\n   is the index for this set in the vector of sets.\n\n   \\param element\n   is the element we are checking to see if it is in the set.\n   */\n   bool is_element(size_t i, size_t element) const\n   {  CPPAD_ASSERT_UNKNOWN( post_[i] == 0 );\n      CPPAD_ASSERT_UNKNOWN( element < end_ );\n      //\n      size_t start = start_[i];\n      if( start == 0 )\n         return false;\n      //\n      size_t length       = data_[start + 1];\n      const size_t* first = data_.data() + start + 2;\n      const size_t* last  = first + length;\n      if( length < 10 )\n      {  bool result = false;\n         while( last > first )\n            result |= *(--last) == element;\n         return result;\n      }\n      //\n      return std::binary_search(first, last, element);\n   }\n   // -----------------------------------------------------------------\n   /*!\n   Assign the empty set to one of the sets.\n\n   \\param target\n   is the index of the set we are setting to the empty set.\n\n   \\par data_not_used_\n   increments this value by number of data_ elements that are lost\n   (unlinked) by this operation.\n   */\n   void clear(size_t target)\n   {\n      // number of data_ elements used for this set\n      size_t number_lost = drop( target );\n\n      // set target to empty set\n      start_[target] = 0;\n\n      // drop the posted elements\n      if( post_[target] != 0 )\n      {  size_t capacity = post_[target + 1];\n         number_lost    += capacity + 2;\n         //\n         post_[target] = 0;\n      }\n\n      // adjust data_not_used_\n      data_not_used_ += number_lost;\n      collect_garbage();\n   }\n   // -----------------------------------------------------------------\n   /*!\n   Assign one set equal to another set.\n\n   \\param this_target\n   is the index in this svec_setvec object of the set being assigned.\n\n   \\param other_source\n   is the index in the other svec_setvec object of the\n   set that we are using as the value to assign to the target set.\n\n   \\param other\n   is the other svec_setvec object (which may be the same as this\n   svec_setvec object). This must have the same value for end_.\n\n   \\par data_not_used_\n   increments this value by number of elements lost.\n   */\n   void assignment(\n      size_t                  this_target  ,\n      size_t                  other_source ,\n      const svec_setvec&      other        )\n   {  CPPAD_ASSERT_UNKNOWN( other.post_[ other_source ] == 0 );\n      //\n      CPPAD_ASSERT_UNKNOWN( this_target  <   start_.size()        );\n      CPPAD_ASSERT_UNKNOWN( other_source <   other.start_.size()  );\n      CPPAD_ASSERT_UNKNOWN( end_        == other.end_   );\n\n      // check if we are assigning a set to itself\n      if( (this == &other) && (this_target == other_source) )\n         return;\n\n      // number of elements that will be deleted by this operation\n      size_t number_lost = drop(this_target);\n\n      // drop any posting for the target set\n      size_t post = post_[this_target];\n      if( post > 0 )\n      {  // do not need to worry about target being same as source\n         size_t capacity = data_[post + 1];\n         number_lost += capacity + 2;\n         post_[this_target] = 0;\n      }\n\n      // If this and other are the same, use another reference to same list\n      size_t other_start = other.start_[other_source];\n      if( this == &other )\n      {  CPPAD_ASSERT_UNKNOWN( this_target != other_source );\n         start_[this_target] = other_start;\n         if( other_start != 0 )\n         {  // increment reference count\n            data_[other_start]++;\n         }\n      }\n      else if( other_start  == 0 )\n      {  // the target list is empty\n         start_[this_target] = 0;\n      }\n      else\n      {  // make a copy of the other list in this svec_setvec\n         size_t length         = other.data_[other_start + 1];\n         size_t this_start     = data_.extend(2);\n         start_[this_target]   = this_start;\n         data_[this_start]     = 1;      // reference count\n         data_[this_start + 1] = length; // length\n         for(size_t j = 0; j < length; ++j)\n            data_.push_back( other.data_[other_start + 2 + j] );\n         data_.push_back(end_);\n      }\n\n      // adjust data_not_used_\n      data_not_used_ += number_lost;\n      collect_garbage();\n   }\n   // -----------------------------------------------------------------\n   /*!\n   Assign a set equal to the union of two other sets.\n\n   \\param this_target\n   is the index in this svec_setvec object of the set being assigned.\n\n   \\param this_left\n   is the index in this svec_setvec object of the\n   left operand for the union operation.\n   It is OK for this_target and this_left to be the same value.\n\n   \\param other_right\n   is the index in the other svec_setvec object of the\n   right operand for the union operation.\n   It is OK for this_target and other_right to be the same value.\n\n   \\param other\n   is the other svec_setvec object (which may be the same as this\n   svec_setvec object).\n   */\n   void binary_union(\n      size_t                this_target  ,\n      size_t                this_left    ,\n      size_t                other_right  ,\n      const svec_setvec& other        )\n   {  CPPAD_ASSERT_UNKNOWN( post_[this_left] == 0 );\n      CPPAD_ASSERT_UNKNOWN( other.post_[ other_right ] == 0 );\n      //\n      CPPAD_ASSERT_UNKNOWN( this_target < start_.size()         );\n      CPPAD_ASSERT_UNKNOWN( this_left   < start_.size()         );\n      CPPAD_ASSERT_UNKNOWN( other_right < other.start_.size()   );\n      CPPAD_ASSERT_UNKNOWN( end_        == other.end_           );\n\n      // check if one of the two operands is a subset of the the other\n      size_t subset = is_subset(this_left, other_right, other);\n\n      // case where right is a subset of left or right and left are equal\n      if( subset == 2 || subset == 3 )\n      {  assignment(this_target, this_left, *this);\n         return;\n      }\n      // case where the left is a subset of right and they are not equal\n      if( subset == 1 )\n      {  assignment(this_target, other_right, other);\n         return;\n      }\n      // if neither case holds, then both left and right are non-empty\n      CPPAD_ASSERT_UNKNOWN( reference_count(this_left) > 0 );\n      CPPAD_ASSERT_UNKNOWN( other.reference_count(other_right) > 0 );\n\n      // must get all the start indices before modify start_this\n      // (in case start_this is the same as start_left or start_right)\n      size_t start_left    = start_[this_left];\n      size_t start_right   = other.start_[other_right];\n\n      // number of list elements that will be deleted by this operation\n      size_t number_lost = drop(this_target);\n\n      // drop any posting for the target set\n      size_t post = post_[this_target];\n      if( post > 0 )\n      {  // do not need to worry about target being same as left or right\n         size_t capacity = data_[post + 1];\n         number_lost += capacity + 2;\n         post_[this_target] = 0;\n      }\n\n      // start the new list\n      size_t start        = data_.extend(2);\n      start_[this_target] = start;\n      data_[start]        = 1; // reference count\n      // data_[start + 1] = length is not yet known\n\n      // initialize left\n      CPPAD_ASSERT_UNKNOWN( start_left != 0 );\n      size_t current_left = start_left + 2;\n      size_t value_left   = data_[current_left];\n      CPPAD_ASSERT_UNKNOWN( value_left < end_ );\n\n      // initialize right\n      CPPAD_ASSERT_UNKNOWN( start_right != 0 );\n      size_t current_right = start_right + 2;\n      size_t value_right   = other.data_[current_right];\n      CPPAD_ASSERT_UNKNOWN( value_right < end_ );\n\n\n      CPPAD_ASSERT_UNKNOWN( value_left < end_ && value_right < end_ );\n      while( (value_left < end_) || (value_right < end_) )\n      {  if( value_left == value_right )\n         {  // advance right so left and right are no longer equal\n            ++current_right;\n            value_right = other.data_[current_right];\n         }\n         if( value_left < value_right )\n         {  data_.push_back( value_left );\n            // advance left to its next element\n            ++current_left;\n            value_left = data_[current_left];\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( value_right < value_left )\n            data_.push_back( value_right );\n            // advance right to its next element\n            ++current_right;\n            value_right = other.data_[current_right];\n         }\n      }\n      // make end of target list\n      data_.push_back( end_ );\n      //\n      // reference count, length, and end_ are not elements of set\n      CPPAD_ASSERT_UNKNOWN( data_.size() > start + 3 );\n      size_t length = data_.size() - (start + 3);\n      data_[start + 1] = length;\n\n      // adjust data_not_used_\n      data_not_used_ += number_lost;\n      collect_garbage();\n   }\n   // -----------------------------------------------------------------\n   /*!\n   Assign a set equal to the intersection of two other sets.\n\n   \\param this_target\n   is the index in this svec_setvec object of the set being assigned.\n\n   \\param this_left\n   is the index in this svec_setvec object of the\n   left operand for the intersection operation.\n   It is OK for this_target and this_left to be the same value.\n\n   \\param other_right\n   is the index in the other svec_setvec object of the\n   right operand for the intersection operation.\n   It is OK for this_target and other_right to be the same value.\n\n   \\param other\n   is the other svec_setvec object (which may be the same as this\n   svec_setvec object).\n   */\n   void binary_intersection(\n      size_t                  this_target  ,\n      size_t                  this_left    ,\n      size_t                  other_right  ,\n      const svec_setvec&      other        )\n   {  CPPAD_ASSERT_UNKNOWN( post_[this_left] == 0 );\n      CPPAD_ASSERT_UNKNOWN( other.post_[ other_right ] == 0 );\n      //\n      CPPAD_ASSERT_UNKNOWN( this_target < start_.size()         );\n      CPPAD_ASSERT_UNKNOWN( this_left   < start_.size()         );\n      CPPAD_ASSERT_UNKNOWN( other_right < other.start_.size()   );\n      CPPAD_ASSERT_UNKNOWN( end_        == other.end_           );\n      //\n      // check if one of the two operands is a subset of the the other\n      size_t subset = is_subset(this_left, other_right, other);\n\n      // case where left is a subset of right or left and right are equal\n      if( subset == 1 || subset == 3 )\n      {  assignment(this_target, this_left, *this);\n         return;\n      }\n      // case where the right is a subset of left and they are not equal\n      if( subset == 2 )\n      {  assignment(this_target, other_right, other);\n         return;\n      }\n      // if neither case holds, then both left and right are non-empty\n      CPPAD_ASSERT_UNKNOWN( reference_count(this_left) > 0 );\n      CPPAD_ASSERT_UNKNOWN( other.reference_count(other_right) > 0 );\n\n      // must get all the start indices before modify start_this\n      // (in case start_this is the same as start_left or start_right)\n      size_t start_left    = start_[this_left];\n      size_t start_right   = other.start_[other_right];\n\n\n      // number of list elements that will be deleted by this operation\n      size_t number_lost = drop(this_target);\n\n      // drop any posting for the target set\n      size_t post = post_[this_target];\n      if( post > 0 )\n      {  // do not need to worry about target being same as left or right\n         size_t capacity = data_[post + 1];\n         number_lost += capacity + 2;\n         post_[this_target] = 0;\n      }\n\n      // initialize intersection as empty\n      size_t start        = 0;\n      start_[this_target] = start;\n\n      // initialize left\n      CPPAD_ASSERT_UNKNOWN( start_left != 0 );\n      size_t current_left = start_left + 2;\n      size_t value_left   = data_[current_left];\n      CPPAD_ASSERT_UNKNOWN( value_left < end_ );\n\n      // initialize right\n      CPPAD_ASSERT_UNKNOWN( start_right != 0 );\n      size_t current_right = start_right + 2;\n      size_t value_right   = other.data_[current_right];\n      CPPAD_ASSERT_UNKNOWN( value_right < end_ );\n\n      while( (value_left < end_) && (value_right < end_) )\n      {  if( value_left == value_right )\n         {  if( start == 0 )\n            {  // this is the first element in the intersection\n               start               = data_.extend(2);\n               start_[this_target] = start;\n               data_[start]        = 1; // reference count\n               // data_[start + 1] = length is not yet known\n            }\n            data_.push_back( value_left );\n            //\n            // advance left to its next element\n            ++current_left;\n            value_left = data_[current_left];\n         }\n         if( value_left > value_right )\n         {  // advance right\n            ++current_right;\n            value_right = other.data_[current_right];\n         }\n         if( value_right > value_left )\n         {  // advance left\n            ++current_left;\n            value_left = data_[current_left];\n         }\n      }\n      if( start != 0 )\n      {  data_.push_back(end_);\n         CPPAD_ASSERT_UNKNOWN( data_.size() > start + 3 );\n         size_t length = data_.size() - (start + 3);\n         data_[start + 1] = length;\n      }\n\n      // adjust data_not_used_\n      data_not_used_ += number_lost;\n      collect_garbage();\n   }\n   // -----------------------------------------------------------------\n   /*! Fetch n_set for vector of sets object.\n\n   \\return\n   Number of from sets for this vector of sets object\n   */\n   size_t n_set(void) const\n   {  return start_.size(); }\n   // -----------------------------------------------------------------\n   /*! Fetch end for this vector of sets object.\n\n   \\return\n   is the maximum element value plus one (the minimum element value is 0).\n   */\n   size_t end(void) const\n   {  return end_; }\n   // -----------------------------------------------------------------\n   /*! Amount of memory used by this vector of sets\n\n   \\return\n   The amount of memory in units of type unsigned char memory.\n   */\n   size_t memory(void) const\n   {  return data_.capacity() * sizeof(size_t);\n   }\n   /*!\n   Print the vector of sets (used for debugging)\n   */\n   void print(void) const;\n};\n// =========================================================================\n/*!\ncons_iterator for one set of positive integers in a svec_setvec object.\n\nAll the public member functions for this class are also in the\nsparse::pack_setvec_const_iterator and sparse::list_setvec_const_iterator classes.\nThis defines the CppAD vector_of_sets iterator concept.\n*/\nclass svec_setvec_const_iterator {\nprivate:\n   /// data for the entire vector of sets\n   const pod_vector<size_t>& data_;\n\n   /// Possible elements in a list are 0, 1, ..., end_ - 1;\n   const size_t                   end_;\n\n   /// data index of next entry, zero for no more entries\n   size_t                         data_index_;\npublic:\n   /// construct a const_iterator for a set in a svec_setvec object\n   svec_setvec_const_iterator (const svec_setvec& vec_set, size_t i)\n   :\n   data_( vec_set.data_ ) ,\n   end_ ( vec_set.end_ )\n   {  CPPAD_ASSERT_UNKNOWN( vec_set.post_[i] == 0 );\n      //\n      size_t start = vec_set.start_[i];\n      if( start == 0 )\n      {  data_index_ = 0;\n      }\n      else\n      {  // data index of the first element in the set\n         data_index_ = start + 2;\n         CPPAD_ASSERT_UNKNOWN( data_[data_index_] < end_ );\n      }\n   }\n\n   /// advance to next element in this list\n   svec_setvec_const_iterator& operator++(void)\n   {  if( data_index_ != 0 )\n      {  ++data_index_;\n         if( data_[data_index_] == end_ )\n            data_index_ = 0;\n      }\n      return *this;\n   }\n\n   /// obtain value of this element of the set of positive integers\n   /// (end_ for no such element)\n   size_t operator*(void)\n   {  if( data_index_ == 0 )\n         return end_;\n      return data_[data_index_];\n   }\n};\n// =========================================================================\n/*!\nPrint the vector of sets (used for debugging)\n*/\ninline void svec_setvec::print(void) const\n{  std::cout << \"svec_setvec:\\n\";\n   for(size_t i = 0; i < n_set(); i++)\n   {  std::cout << \"set[\" << i << \"] = {\";\n      const_iterator itr(*this, i);\n      while( *itr != end() )\n      {  std::cout << *itr;\n         if( *(++itr) != end() )\n            std::cout << \",\";\n      }\n      std::cout << \"}\\n\";\n   }\n   return;\n}\n\n/*!\nCopy a user vector of sets sparsity pattern to an internal svec_setvec object.\n\n\\tparam SetVector\nis a simple vector with elements of type std::set<size_t>.\n\n\\param internal\nThe input value of sparisty does not matter.\nUpon return it contains the same sparsity pattern as user\n(or the transposed sparsity pattern).\n\n\\param user\nsparsity pattern that we are placing internal.\n\n\\param n_set\nnumber of sets (rows) in the internal sparsity pattern.\n\n\\param end\nend of set value (number of columns) in the internal sparsity pattern.\n\n\\param transpose\nif true, the user sparsity patter is the transposed.\n\n\\param error_msg\nis the error message to display if some values in the user sparstiy\npattern are not valid.\n*/\ntemplate<class SetVector>\nvoid sparsity_user2internal(\n   svec_setvec&            internal  ,\n   const SetVector&        user      ,\n   size_t                  n_set     ,\n   size_t                  end       ,\n   bool                    transpose ,\n   const char*             error_msg )\n{\n# ifndef NDEBUG\n   if( transpose )\n      CPPAD_ASSERT_KNOWN( end == size_t( user.size() ), error_msg);\n   if( ! transpose )\n      CPPAD_ASSERT_KNOWN( n_set == size_t( user.size() ), error_msg);\n# endif\n\n   // iterator for user set\n   std::set<size_t>::const_iterator itr;\n\n   // size of internal sparsity pattern\n   internal.resize(n_set, end);\n\n   if( transpose )\n   {  // transposed pattern case\n      for(size_t j = 0; j < end; j++)\n      {  itr = user[j].begin();\n         while(itr != user[j].end())\n         {  size_t i = *itr++;\n            CPPAD_ASSERT_KNOWN(i < n_set, error_msg);\n            internal.add_element(i, j);\n         }\n      }\n   }\n   else\n   {  for(size_t i = 0; i < n_set; i++)\n      {  itr = user[i].begin();\n         while(itr != user[i].end())\n         {  size_t j = *itr++;\n            CPPAD_ASSERT_KNOWN( j < end, error_msg);\n            internal.add_element(i, j);\n         }\n      }\n   }\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sparse/unary_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_SPARSE_UNARY_OP_HPP\n# define CPPAD_LOCAL_SPARSE_UNARY_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE\nnamespace CppAD { namespace local { namespace sparse {\n/*!\n\\file sparse_unary_op.hpp\nForward and reverse mode sparsity patterns for unary operators.\n*/\n\n\n/*!\nForward mode Jacobian sparsity pattern for all unary operators.\n\nThe C++ source code corresponding to a unary operation has the form\n\\verbatim\n   z = fun(x)\n\\endverbatim\nwhere fun is a C++ unary function, or it has the form\n\\verbatim\n   z = x op q\n\\endverbatim\nwhere op is a C++ binary unary operator and q is a parameter.\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\\param i_z\nvariable index corresponding to the result for this operation;\ni.e., z.\n\n\\param i_x\nvariable index corresponding to the argument for this operator;\ni.e., x.\n\n\n\\param sparsity\n\\b Input: The set with index arg[0] in sparsity\nis the sparsity bit pattern for x.\nThis identifies which of the independent variables the variable x\ndepends on.\n\\n\n\\n\n\\b Output: The set with index i_z in sparsity\nis the sparsity bit pattern for z.\nThis identifies which of the independent variables the variable z\ndepends on.\n\\n\n\n\\par Checked Assertions:\n\\li i_x < i_z\n*/\n\ntemplate <class Vector_set>\nvoid for_jac_unary_op(\n   size_t            i_z           ,\n   size_t            i_x           ,\n   Vector_set&       sparsity      )\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( i_x < i_z );\n\n   sparsity.assignment(i_z, i_x, sparsity);\n}\n/*!\nReverse mode Jacobian sparsity pattern for all unary operators.\n\nThe C++ source code corresponding to a unary operation has the form\n\\verbatim\n   z = fun(x)\n\\endverbatim\nwhere fun is a C++ unary function, or it has the form\n\\verbatim\n   z = x op q\n\\endverbatim\nwhere op is a C++ bianry operator and q is a parameter.\n\nThis routine is given the sparsity patterns\nfor a function G(z, y, ... )\nand it uses them to compute the sparsity patterns for\n\\verbatim\n   H( x , w , u , ... ) = G[ z(x) , x , w , u , ... ]\n\\endverbatim\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\n\\param i_z\nvariable index corresponding to the result for this operation;\ni.e. the row index in sparsity corresponding to z.\n\n\\param i_x\nvariable index corresponding to the argument for this operator;\ni.e. the row index in sparsity corresponding to x.\n\n\\param sparsity\n\\b Input:\nThe set with index i_z in sparsity\nis the sparsity bit pattern for G with respect to the variable z.\n\\n\n\\b Input:\nThe set with index i_x in sparsity\nis the sparsity bit pattern for G with respect to the variable x.\n\\n\n\\b Output:\nThe set with index i_x in sparsity\nis the sparsity bit pattern for H with respect to the variable x.\n\n\\par Checked Assertions:\n\\li i_x < i_z\n*/\n\ntemplate <class Vector_set>\nvoid rev_jac_unary_op(\n   size_t     i_z                     ,\n   size_t     i_x                     ,\n   Vector_set&            sparsity    )\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( i_x < i_z );\n\n   sparsity.binary_union(i_x, i_x, i_z, sparsity);\n\n   return;\n}\n// ---------------------------------------------------------------------------\n/*!\nReverse mode Hessian sparsity pattern for linear unary operators.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n      z = fun(x)\n\\endverbatim\nwhere fun is a linear functions; e.g. abs, or\n\\verbatim\n   z = x op q\n\\endverbatim\nwhere op is a C++ binary operator and q is a parameter.\n\n\\copydetails CppAD::local::reverse_sparse_hessian_unary_op\n*/\ntemplate <class Vector_set>\nvoid rev_hes_lin_unary_op(\n   size_t              i_z               ,\n   size_t              i_x               ,\n   bool*               rev_jacobian      ,\n   const Vector_set&   for_jac_sparsity  ,\n   Vector_set&         rev_hes_sparsity  )\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( i_x < i_z );\n\n   // check for no effect\n   if( ! rev_jacobian[i_z] )\n      return;\n\n   rev_hes_sparsity.binary_union(i_x, i_x, i_z, rev_hes_sparsity);\n\n   rev_jacobian[i_x] = true;\n   return;\n}\n\n/*!\nReverse mode Hessian sparsity pattern for non-linear unary operators.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n      z = fun(x)\n\\endverbatim\nwhere fun is a non-linear functions; e.g. sin. or\n\\verbatim\n   z = q / x\n\\endverbatim\nwhere q is a parameter.\n\n\n\\copydetails CppAD::local::reverse_sparse_hessian_unary_op\n*/\ntemplate <class Vector_set>\nvoid rev_hes_nl_unary_op(\n   size_t              i_z               ,\n   size_t              i_x               ,\n   bool*               rev_jacobian      ,\n   const Vector_set&   for_jac_sparsity  ,\n   Vector_set&         rev_hes_sparsity  )\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( i_x < i_z );\n\n   // check for no effect\n   if( ! rev_jacobian[i_z] )\n      return;\n\n   rev_hes_sparsity.binary_union(i_x, i_x, i_z, rev_hes_sparsity);\n   rev_hes_sparsity.binary_union(i_x, i_x, i_x, for_jac_sparsity);\n\n   rev_jacobian[i_x] = true;\n   return;\n}\n// ---------------------------------------------------------------------------\n/*\n{xrst_begin for_hes_nl_unary_op dev}\n{xrst_spell\n   np\n   numvar\n}\n\nForward Hessian Sparsity for Non-linear Unary Operators\n#######################################################\n\nSyntax\n******\n| ``local::for_hes_nl_unary_op`` (\n| |tab| *np1* , *numvar* , *i_v* , *for_sparsity*\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_for_hes_nl_unary_op\n   // END_for_hes_nl_unary_op\n}\n\nC++ Source\n**********\nThe C++ source code corresponding to this operation is\n\n   *w* = *fun* ( *v*  )\n\nwhere *fun* is a non-linear function.\n\nnp1\n***\nThis is the number of independent variables plus one;\ni.e. size of *x* plus one.\n\nnumvar\n******\nThis is the total number of variables in the tape.\n\ni_w\n***\nis the index of the variable corresponding to the result *w* .\n\ni_v\n***\nis the index of the variable corresponding to the argument *v* .\n\nfor_sparsity\n************\nWe have the conditions *np1* = *for_sparsity* . ``end`` ()\nand *for_sparsity* . ``n_set`` () = *np1* + *numvar* .\n\nInput Jacobian Sparsity\n=======================\nFor *i* = 0, ..., *i_w* ``-1`` ,\nthe *np1* + *i* row of *for_sparsity* is the Jacobian sparsity\nfor the *i*-th variable. These values do not change.\nNote that *i* =0 corresponds to a parameter and\nthe corresponding Jacobian sparsity is empty.\n\nInput Hessian Sparsity\n======================\nFor *j* =1, ..., *n* ,\nthe *j*-th row of *for_sparsity* is the Hessian sparsity\nbefore including the function :math:`w(x)`.\n\nOutput Jacobian Sparsity\n========================\nthe *i_w* row of *for_sparsity* is the Jacobian sparsity\nfor the variable *w* .\n\nOutput Hessian Sparsity\n=======================\nFor *j* =1, ..., *n* ,\nthe *j*-th row of *for_sparsity* is the Hessian sparsity\nafter including the function :math:`w(x)`.\n\n{xrst_end for_hes_nl_unary_op}\n*/\n// BEGIN_for_hes_nl_unary_op\ntemplate <class Vector_set>\nvoid for_hes_nl_unary_op(\n   size_t              np1            ,\n   size_t              numvar         ,\n   size_t              i_w            ,\n   size_t              i_v            ,\n   Vector_set&         for_sparsity   )\n// END_for_hes_nl_unary_op\n{  CPPAD_ASSERT_UNKNOWN( i_v < i_w );\n   CPPAD_ASSERT_UNKNOWN( i_w < numvar );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + numvar );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.number_elements(np1) == 0 );\n\n   // set Jacobian sparsity J(i_w)\n   for_sparsity.assignment(np1 + i_w, np1 + i_v, for_sparsity);\n\n   // set of independent variables that v depends on\n   typename Vector_set::const_iterator itr(for_sparsity, i_v + np1);\n\n   // loop over independent variables with non-zero partial for v\n   size_t i_x = *itr;\n   while( i_x < np1 )\n   {  // N(i_x) = N(i_x) union J(i_v)\n      for_sparsity.binary_union(i_x, i_x, i_v + np1, for_sparsity);\n      i_x = *(++itr);\n   }\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/std_set.hpp",
    "content": "# ifndef CPPAD_LOCAL_STD_SET_HPP\n# define CPPAD_LOCAL_STD_SET_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/define.hpp>\n\n// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n/*!\n\\file std_set.hpp\nTwo constant standard sets (currently used for concept checking).\n*/\n\n/*!\nA standard set with one element.\n*/\ntemplate <class Scalar>\nconst std::set<Scalar>& one_element_std_set(void)\n{  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n   static std::set<Scalar> one;\n   if( one.empty() )\n      one.insert(1);\n   return one;\n}\n/*!\nA standard set with a two elements.\n*/\ntemplate <class Scalar>\nconst std::set<Scalar>& two_element_std_set(void)\n{  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n   static std::set<Scalar> two;\n   if( two.empty() )\n   {  two.insert(1);\n      two.insert(2);\n   }\n   return two;\n}\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/subgraph/arg_variable.hpp",
    "content": "# ifndef CPPAD_LOCAL_SUBGRAPH_ARG_VARIABLE_HPP\n# define CPPAD_LOCAL_SUBGRAPH_ARG_VARIABLE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/pod_vector.hpp>\n\n// BEGIN_CPPAD_LOCAL_SUBGRAPH_NAMESPACE\nnamespace CppAD { namespace local { namespace subgraph {\n/*!\n\\file arg_variable.hpp\nDetermine arguments that are variables.\n*/\n\n/*!\nDetermine the set of arguments, for an operator, that are variables.\n\n\\tparam Addr\nType used for indices in random iterator.\n\n\\param random_itr\nis a random iterator for this operation sequence.\n\n\\param i_op\nis the operator index. If this operator is part of a atomic function call,\nit must be the first AFunOp in the call. (There is a AFunOp at the\nbeginning and end of each call.)\n\n\\param variable\nis the set of argument variables corresponding to this operator.\nIf the operator is a AFunOp, the arguments are the variables\nthat are passed into the function call.\n\n\\param work\nthis is work space used by arg_variable to make subsequent calls\nfaster. It should not be used by the calling routine. In addition,\nit is better if work does not drop out of scope between calls.\n*/\ntemplate <class Addr>\nvoid get_argument_variable(\n   const play::const_random_iterator<Addr>& random_itr  ,\n   size_t                                   i_op        ,\n   pod_vector<size_t>&                      variable    ,\n   pod_vector<bool>&                        work        )\n{\n   // reset to size zero, but keep allocated memory\n   variable.resize(0);\n   //\n   // operator corresponding to i_op\n   op_code_var   op;\n   const addr_t* op_arg;\n   size_t        i_var;\n   random_itr.op_info(i_op, op, op_arg, i_var);\n   //\n   // partial check of assumptions on atomic function calls\n   CPPAD_ASSERT_UNKNOWN(\n      op != FunapOp && op != FunavOp && op != FunrpOp && op != FunrvOp\n   );\n   //\n   // we assume this is the first AFunOp of the call\n   if( op == AFunOp )\n   {  random_itr.op_info(++i_op, op, op_arg, i_var);\n      while( op != AFunOp )\n      {  switch(op)\n         {\n            case FunavOp:\n            {  CPPAD_ASSERT_NARG_NRES(op, 1, 0);\n               size_t j_var = size_t( op_arg[0] );\n               variable.push_back(j_var);\n            }\n            break;\n\n            case FunrvOp:\n            case FunrpOp:\n            case FunapOp:\n            break;\n\n            default:\n            // cannot find second AFunOp in this call\n            CPPAD_ASSERT_UNKNOWN(false);\n            break;\n         }\n         random_itr.op_info(++i_op, op, op_arg, i_var);\n      }\n      CPPAD_ASSERT_UNKNOWN( variable.size() > 0 );\n      return;\n   }\n   // is_variable is a reference to work with a better name\n   pod_vector<bool>& is_variable(work);\n   arg_is_variable(op, op_arg, is_variable);\n   size_t num_arg = is_variable.size();\n   for(size_t j = 0; j < num_arg; ++j)\n   {  if( is_variable[j] )\n      {  size_t j_var = size_t( op_arg[j] );\n         variable.push_back(j_var);\n      }\n   }\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_SUBGRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/subgraph/entire_call.hpp",
    "content": "# ifndef CPPAD_LOCAL_SUBGRAPH_ENTIRE_CALL_HPP\n# define CPPAD_LOCAL_SUBGRAPH_ENTIRE_CALL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/pod_vector.hpp>\n\n// BEGIN_CPPAD_LOCAL_SUBGRAPH_NAMESPACE\nnamespace CppAD { namespace local { namespace subgraph {\n/*!\n\\file entire_call.hpp\ninclude entire function call in a subgraph\n*/\n// ===========================================================================\n/*!\nConvert from just first AFunOp to entire atomic function call in a subgraph.\n\n\\tparam Addr\nType used for indices in the random iterator.\n\n\\param random_itr\nis a random iterator for this operation sequence.\n\n\\param subgraph\nIt a set of operator indices in this recording.\nIf the corresponding operator is a AFunOp, it assumed to be the\nfirst one in the corresponding atomic function call.\nThe other call operators are included in the subgraph.\n*/\ntemplate <class Addr>\nvoid entire_call(\n   const play::const_random_iterator<Addr>& random_itr ,\n   pod_vector<addr_t>&                      subgraph   )\n{\n   // add extra operators corresponding to rest of atomic function calls\n   size_t n_sub = subgraph.size();\n   for(size_t k = 0; k < n_sub; ++k)\n   {  size_t i_op = size_t( subgraph[k] );\n      //\n      if( random_itr.get_op(i_op) == AFunOp )\n      {  // This is the first AFunOp of this atomic function call\n         while( random_itr.get_op(++i_op) != AFunOp )\n         {  switch(random_itr.get_op(i_op))\n            {\n               case FunavOp:\n               case FunrvOp:\n               case FunrpOp:\n               case FunapOp:\n               subgraph.push_back( addr_t(i_op) );\n               break;\n\n               default:\n               // cannot find second AFunOp in this call\n               CPPAD_ASSERT_UNKNOWN(false);\n               break;\n            }\n         }\n         // THis is the second AFunOp of this atomic function call\n         subgraph.push_back( addr_t(i_op) );\n      }\n   }\n\n}\n\n} } } // END_CPPAD_LOCAL_SUBGRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/subgraph/get_rev.hpp",
    "content": "# ifndef CPPAD_LOCAL_SUBGRAPH_GET_REV_HPP\n# define CPPAD_LOCAL_SUBGRAPH_GET_REV_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/pod_vector.hpp>\n# include <cppad/local/subgraph/arg_variable.hpp>\n# include <cppad/local/subgraph/info.hpp>\n\n// BEGIN_CPPAD_LOCAL_SUBGRAPH_NAMESPACE\nnamespace CppAD { namespace local { namespace subgraph {\n/*!\n\\file get_rev.hpp\nGet subgraph corresponding to a dependent variable.\n*/\n\n// ===========================================================================\n/*!\nGet the subgraph corresponding to a dependent variables\n(and a selected set of independent variables).\n\n\\tparam Addr\nType used for indices in the random iterator.\n\n\\param random_itr\nis a random iterator for this operation sequence.\n\n\\param dep_taddr\nis the vector mapping user dependent variable indices\nto the corresponding variable in the recording.\n\n\\param i_dep\nis the user index for his dependent variable;\nthat i_dep < n_dep_.\n\n\\param subgraph\nthe input size and contents of this vector do not matter.\nRepeated calls with the same subgraph vector should reduce\nthe amount of memory allocation.\nUpon return it contains the operator indices for the subgraph\ncorresponding to the dependent and the selected independent variables.\nOnly selected independent variable operators InvOp are included\nin the subgraph.\nFurthermore the operator indices in subgraph are unique; i.e.,\nif i_op != j_op then subgraph[i_op] != subgraph[j_op].\n\n\\par map_user_op_\nThis vector must be set.\n\n\\par in_subgraph_\nhas size equal to the number of operators in play.\nIf in_subgraph[i_op] <= n_dep_,\nthe result for this operator depends on the selected independent variables.\nIn addition, upon input, there is no i_op such that in_subgraph[i_op] == i_dep.\nNote that for atomic function call operators i_op,\n\\code\n   n_dep_ < in_subgraph[i_op]\n\\endcode\nexcept for the first AFunOp in the atomic function call sequence.\nFor the first AFunOp,\n\\code\n   in_subgraph[i_op] <= n_dep_\n\\endcode\nif any result for the atomic function call\ndepends on the selected independent variables.\nExcept for UserOP, only operators with NumRes(op) > 0 are included\nin the dependency; e.g., comparison operators are not included.\nUpon return, some of the i_op for which in_subgraph[i_op] <= n_dep_,\nwill be changed to in_subgraph[i_op] = i_dep.\n\n\\par process_range_\nThe value process_range_[i_dep] is checked to make sure it is false.\nIt is then set to have value true.\n*/\ntemplate <class Addr>\nvoid subgraph_info::get_rev(\n   const play::const_random_iterator<Addr>&   random_itr  ,\n   const pod_vector<size_t>&                  dep_taddr   ,\n   addr_t                                     i_dep       ,\n   pod_vector<addr_t>&                        subgraph    )\n{  // check sizes\n   CPPAD_ASSERT_UNKNOWN( map_user_op_.size()   == n_op_ );\n\n   // process_range_\n   CPPAD_ASSERT_UNKNOWN( process_range_[i_dep] == false );\n   process_range_[i_dep] = true;\n\n   // special value; see init_rev_in_subgraph\n   addr_t depend_yes = addr_t( n_dep_ );\n\n   // assumption on i_dep\n   CPPAD_ASSERT_UNKNOWN( i_dep < depend_yes );\n\n   // start with an empty subgraph for this dependent variable\n   subgraph.resize(0);\n\n   // tape index corresponding to this dependent variable\n   size_t i_var = dep_taddr[i_dep];\n\n   // operator corresponding to this dependent variable\n   size_t i_op = random_itr.var2op(i_var);\n   i_op        = size_t( map_user_op_[i_op] );\n\n   // if this variable depends on the selected independent variables\n   // process its subgraph\n   CPPAD_ASSERT_UNKNOWN( in_subgraph_[i_op] != i_dep )\n   if( in_subgraph_[i_op] <= depend_yes )\n   {  subgraph.push_back( addr_t(i_op) );\n      in_subgraph_[i_op] = i_dep;\n   }\n\n   // space used to return set of arguments that are variables\n   pod_vector<size_t> argument_variable;\n\n   // temporary space used by get_argument_variable\n   pod_vector<bool> work;\n\n   // scan all the operators in this subgraph\n   size_t sub_index = 0;\n   while(sub_index < subgraph.size() )\n   {  // this operator connected to this dependent and selected independent\n      i_op = size_t( subgraph[sub_index] );\n      CPPAD_ASSERT_UNKNOWN( in_subgraph_[i_op] == i_dep );\n      //\n      // There must be a result for this operator\n# ifndef NDEBUG\n      op_code_var op = random_itr.get_op(i_op);\n      CPPAD_ASSERT_UNKNOWN(op == AFunOp || NumRes(op) > 0 );\n# endif\n      //\n      // which variables are connected to this operator\n      get_argument_variable(random_itr, i_op, argument_variable, work);\n      for(size_t j = 0; j < argument_variable.size(); ++j)\n      {  // add the corresponding operators to the subgraph\n         size_t j_var = argument_variable[j];\n         size_t j_op  = random_itr.var2op(j_var);\n         j_op         = size_t( map_user_op_[j_op] );\n         bool add = in_subgraph_[j_op] <= depend_yes;\n         add     &= in_subgraph_[j_op] != i_dep;\n         if( random_itr.get_op(j_op) == InvOp )\n         {  CPPAD_ASSERT_UNKNOWN( j_op == j_var );\n            add &= select_domain_[j_var - 1];\n         }\n         if( add )\n         {  subgraph.push_back( addr_t(j_op) );\n            in_subgraph_[j_op] = i_dep;\n         }\n      }\n      // we are done scanning this subgraph operator\n      ++sub_index;\n   }\n}\n\n} } } // END_CPPAD_LOCAL_SUBGRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/subgraph/info.hpp",
    "content": "# ifndef CPPAD_LOCAL_SUBGRAPH_INFO_HPP\n# define CPPAD_LOCAL_SUBGRAPH_INFO_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/play/random_iterator.hpp>\n# include <cppad/local/pod_vector.hpp>\n# include <cppad/local/subgraph/arg_variable.hpp>\n\n// BEGIN_CPPAD_LOCAL_SUBGRAPH_NAMESPACE\nnamespace CppAD { namespace local { namespace subgraph {\n/*!\n\\file info.hpp\nsubgraph information attached to a operation sequence\n*/\n\n/// class for maintaining subgraph information attached to on ADFun object.\nclass subgraph_info {\nprivate:\n   // -----------------------------------------------------------------------\n   // private member data set by constructor, resize, and assign\n   // -----------------------------------------------------------------------\n   /// number of independent variables for this function\n   size_t  n_ind_;\n\n   /// number of dependent variables for this function\n   size_t  n_dep_;\n\n   /// number of operatros in operation sequence\n   size_t  n_op_;\n\n   /// number of variables in operation sequence\n   size_t n_var_;\n\n   // -----------------------------------------------------------------------\n   // private member data set by set_map_user_op\n   // -----------------------------------------------------------------------\n\n   /// Mapping atomic call operators to AFunOp that begins call sequence,\n   /// other operators are not changed by the map.\n   /// (size zero after constructor or resize)\n   pod_vector<addr_t> map_user_op_;\n\n   // -----------------------------------------------------------------------\n   // other private member data\n   // -----------------------------------------------------------------------\n\n   /// flags which operators are in subgraph\n   /// (size zero or n_op_).\n   pod_vector<addr_t> in_subgraph_;\n\n   /// flags which dependent variables are selected\n   pod_vector<bool> select_domain_;\n\n   /// flags which dependent variables have been processed since\n   /// the previous init_rev\n   pod_vector<bool> process_range_;\n\npublic:\n   // -----------------------------------------------------------------------\n   // const public functions\n   // -----------------------------------------------------------------------\n   /// number of independent variables\n   size_t n_ind(void) const\n   {  return n_ind_; }\n\n   /// number of dependent variables\n   size_t n_dep(void) const\n   {  return n_dep_; }\n\n   /// number of operators\n   size_t n_op(void) const\n   {  return n_op_; }\n\n   // number of variables\n   size_t n_var(void) const\n   {  return n_var_; }\n\n   /// map atomic function calls to first operator in the call\n   const pod_vector<addr_t>& map_user_op(void) const\n   {  return map_user_op_; }\n\n   /// previous select_domain argument to init_rev\n   const pod_vector<bool>& select_domain(void) const\n   {  return select_domain_; }\n\n   /// dependent variables that have been processed since previous init_rev\n   const pod_vector<bool>& process_range(void) const\n   {  return process_range_; }\n\n   /// amount of memory corresponding to this object\n   size_t memory(void) const\n   {  size_t sum = map_user_op_.size()   * sizeof(addr_t);\n      sum       += in_subgraph_.size()   * sizeof(addr_t);\n      sum       += select_domain_.size() * sizeof(bool);\n      sum       += process_range_.size() * sizeof(bool);\n      return sum;\n   }\n\n   /// free memory used for calculating subgraph\n   void clear(void)\n   {  map_user_op_.clear();\n      in_subgraph_.clear();\n      select_domain_.clear();\n      process_range_.clear();\n   }\n   // -----------------------------------------------------------------------\n   /*!\n   check that the value of map_user_op is OK for this operation sequence\n\n   \\param play\n   is the player for this operation sequence.\n\n   \\return\n   is true, if map_user_op has the correct value for this operation sequence\n   (is the same as it would be after a set_map_user_op).\n   */\n   template <class Base>\n   bool check_map_user_op(const player<Base>* play) const\n   {  if( map_user_op_.size() != n_op_ )\n         return false;\n      bool   ok   = true;\n      size_t i_op = 0;\n      while( i_op < n_op_ )\n      {  op_code_var op = play->GetOp(i_op);\n         ok       &= map_user_op_[i_op] == addr_t( i_op );\n         if( op == AFunOp )\n         {  addr_t begin = addr_t( i_op );\n            op           = play->GetOp(++i_op);\n            while( op != AFunOp )\n            {  CPPAD_ASSERT_UNKNOWN(\n               op==FunapOp || op==FunavOp || op==FunrpOp || op==FunrvOp\n               );\n               ok  &= map_user_op_[i_op] == begin;\n               op   = play->GetOp(++i_op);\n            }\n            ok  &= map_user_op_[i_op] == begin;\n         }\n         ++i_op;\n      }\n      return ok;\n   }\n   // -----------------------------------------------------------------------\n   // non const public functions\n   // -----------------------------------------------------------------------\n\n   /// flag which operators that are in the subgraph\n   pod_vector<addr_t>& in_subgraph(void)\n   {  return in_subgraph_; }\n\n\n   /// default constructor (all sizes are zero)\n   subgraph_info(void)\n   : n_ind_(0), n_dep_(0), n_op_(0), n_var_(0)\n   {  CPPAD_ASSERT_UNKNOWN( map_user_op_.size()   == 0 );\n      CPPAD_ASSERT_UNKNOWN( in_subgraph_.size()   == 0 );\n   }\n   // -----------------------------------------------------------------------\n   /// assignment operator\n   void operator=(const subgraph_info& info)\n   {  n_ind_            = info.n_ind_;\n      n_dep_            = info.n_dep_;\n      n_op_             = info.n_op_;\n      n_var_            = info.n_var_;\n      map_user_op_      = info.map_user_op_;\n      in_subgraph_      = info.in_subgraph_;\n      select_domain_    = info.select_domain_;\n      process_range_    = info.process_range_;\n      return;\n   }\n   // -----------------------------------------------------------------------\n   /// swap\n   /// (used for move semantics version of ADFun assignment)\n   void swap(subgraph_info& info)\n   {  // size_t objects\n      std::swap(n_ind_ , info.n_ind_);\n      std::swap(n_dep_ , info.n_dep_);\n      std::swap(n_op_  , info.n_op_);\n      std::swap(n_var_ , info.n_var_);\n      //\n      // pod_vectors\n      map_user_op_.swap(   info.map_user_op_);\n      in_subgraph_.swap(   info.in_subgraph_);\n      select_domain_.swap( info.select_domain_);\n      process_range_.swap( info.process_range_);\n      //\n      return;\n   }\n   // -----------------------------------------------------------------------\n   /*!\n   set sizes for this object (the default sizes are zero)\n\n   \\param n_ind\n   number of independent variables.\n\n   \\param n_dep\n   number of dependent variables.\n\n   \\param n_op\n   number of operators.\n\n   \\param n_var\n   number of variables.\n\n   \\par map_user_op_\n   is resized to zero.\n\n   \\par in_subgraph_\n   is resized to zero.\n   */\n   void resize(size_t n_ind, size_t n_dep, size_t n_op, size_t n_var)\n   {  CPPAD_ASSERT_UNKNOWN(\n         n_op <= size_t( std::numeric_limits<addr_t>::max() )\n      );\n      // n_ind_\n      n_ind_ = n_ind;\n      // n_dep_\n      n_dep_ = n_dep;\n      // n_op_\n      n_op_  = n_op;\n      // n_var_\n      n_var_ = n_var;\n\n      //\n      // map_user_op_\n      map_user_op_.resize(0);\n      //\n      // in_subgraph_\n      in_subgraph_.resize(0);\n      //\n      return;\n   }\n   // -----------------------------------------------------------------------\n   /*!\n   set the value of map_user_op for this operation sequence\n\n   \\param play\n   is the player for this operation sequence. It must same number of\n   operators and variables as this subgraph_info object.\n\n   \\par map_user_op_\n   This size of map_user_op_ must be zero when this function is called\n   (which is true after a resize operation).\n   This function sets its size to the number of operations in play.\n   We use the term user OpCocde for the any one of the following:\n   AFunOp, FunapOp, FunavOp, FunrpOp, or FunrvOp. Suppose\n   \\code\n      OpCodce op_i = play->GetOp(i_op);\n      size_t  j_op = map_user_op[i_op];\n      op_code_var op_j = play->GetOP(j_op);\n   \\endcode\n   If op is a user op_code_var, j_op is the index of the first operator\n   in the corresponding atomic function call and op_j == AFunOp.\n   Otherwise j_op == i_op;\n\n   */\n   template <class Base>\n   void set_map_user_op(const player<Base>* play)\n   {  CPPAD_ASSERT_UNKNOWN( map_user_op_.size()   == 0 );\n      //\n      CPPAD_ASSERT_UNKNOWN( n_op_  == play->num_var_op() );\n      CPPAD_ASSERT_UNKNOWN( n_var_ == play->num_var() );\n      //\n      // resize map_user_op_\n      map_user_op_.resize(n_op_);\n      //\n      // set map_user_op for each operator\n      for(size_t i_op = 0; i_op < n_op_; ++i_op)\n      {  // this operator\n         op_code_var op = play->GetOp(i_op);\n         //\n         // value of map_user_op when op is not in atomic function call)\n         map_user_op_[i_op] = addr_t( i_op );\n         //\n         if( op == AFunOp )\n         {  // first AFunOp in an atomic function call sequence\n            //\n            // All operators in this atomic call sequence will be\n            // mapped to the AFunOp that begins this call.\n            addr_t begin = addr_t( i_op );\n            op           = play->GetOp(++i_op);\n            while( op != AFunOp )\n            {  CPPAD_ASSERT_UNKNOWN(\n               op==FunapOp || op==FunavOp || op==FunrpOp || op==FunrvOp\n               );\n               // map this operator to the beginning of the call\n               map_user_op_[i_op] = begin;\n               op                 = play->GetOp(++i_op);\n            }\n            // map the second AFunOp to the beginning of the call\n            map_user_op_[i_op] = begin;\n         }\n      }\n      return;\n   }\n   // -----------------------------------------------------------------------\n   // see init_rev.hpp\n   template <class Addr, class BoolVector>\n   void init_rev(\n      const play::const_random_iterator<Addr>& random_itr ,\n      const BoolVector&                        select_domain\n   );\n   template <class Addr, class Base, class BoolVector>\n   void init_rev(\n      player<Base>*        play          ,\n      const BoolVector&    select_domain\n   );\n   // -----------------------------------------------------------------------\n   // see get_rev.hpp\n   template <class Addr>\n   void get_rev(\n      const play::const_random_iterator<Addr>&   random_itr   ,\n      const pod_vector<size_t>&                  dep_taddr    ,\n      addr_t                                     i_dep        ,\n      pod_vector<addr_t>&                        subgraph\n   );\n};\n\n} } } // END_CPPAD_LOCAL_SUBGRAPH_NAMESPACE\n\n// routines that operate on in_subgraph\n# include <cppad/local/subgraph/init_rev.hpp>\n# include <cppad/local/subgraph/get_rev.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/subgraph/init_rev.hpp",
    "content": "# ifndef CPPAD_LOCAL_SUBGRAPH_INIT_REV_HPP\n# define CPPAD_LOCAL_SUBGRAPH_INIT_REV_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/subgraph/info.hpp>\n\n// BEGIN_CPPAD_LOCAL_SUBGRAPH_NAMESPACE\nnamespace CppAD { namespace local { namespace subgraph {\n/*!\n\\file init_rev.hpp\ninitialize for a reverse mode subgraph calculation\n*/\n\n// -----------------------------------------------------------------------\n/*!\nInitialize in_subgraph corresponding to a single dependent variable\n(and a selected set of independent variables).\n\n\\tparam Addr\nis the type used for indices in the random iterator.\n\n\\param random_itr\nIs a random iterator for this operation sequence.\n\n\\param select_domain\nis a vector with, size equal to the number of independent variables\nin the recording. It determines the selected independent variables.\n\n\\par in_subgraph_\nWe use depend_yes (depend_no) for the value n_dep_ (n_dep_ + 1).\nThe important properties are that depend_yes < depend_no and\nfor a valid independent variable index i_ind < depend_yes.\nThe input size and elements of in_subgraph_ do not matter.\nIf in_subgraph_[i_op] == depend_yes (depend_no),\nthe result for this operator depends (does not depend)\non the selected independent variables.\nNote that for atomic function call operators i_op,\nin_subgraph[i_op] is depend_no except for the first AFunOp in the\natomic function call sequence. For the first AFunOp,\nit is depend_yes (depend_no) if any of the results for the call sequence\ndepend (do not depend) on the selected independent variables.\nExcept for UserOP, only operators with NumRes(op) > 0 have in_subgraph_\nvalue depend_yes;\ne.g., comparison operators have in_subgraph_ value depend_no.\n\n\\par select_domain_\nThis vector is is set equal to the select_domain argument.\n\n\\par process_range_\nThis vector is to to size n_dep_ and its values are set to false\n*/\ntemplate <class Addr, class BoolVector>\nvoid subgraph_info::init_rev(\n   const local::play::const_random_iterator<Addr>&  random_itr    ,\n   const BoolVector&                                select_domain )\n{\n   // check sizes\n   CPPAD_ASSERT_UNKNOWN( map_user_op_.size()   == n_op_ );\n   CPPAD_ASSERT_UNKNOWN( random_itr.num_op()   == n_op_ );\n   CPPAD_ASSERT_UNKNOWN( size_t( select_domain.size() ) == n_ind_ );\n\n   // depend_yes and depend_no\n   addr_t depend_yes = addr_t( n_dep_ );\n   addr_t depend_no  = addr_t( n_dep_ + 1 );\n\n   // select_domain_\n   select_domain_.resize(n_ind_);\n   for(size_t j = 0; j < n_ind_; ++j)\n      select_domain_[j]  = select_domain[j];\n\n   // process_range_\n   process_range_.resize(n_dep_);\n   for(size_t i = 0; i < n_dep_; ++i)\n      process_range_[i] = false;\n\n   // set in_subgraph to have proper size\n   in_subgraph_.resize(n_op_);\n\n   // space used to return set of arguments that are variables\n   pod_vector<size_t> argument_variable;\n\n   // temporary space used by get_argument_variable\n   pod_vector<bool> work;\n\n# ifndef NDEBUG\n   size_t count_independent = 0;\n# endif\n   bool begin_atomic_call = false;\n   for(size_t i_op = 0; i_op < n_op_; ++i_op)\n   {  op_code_var op = random_itr.get_op(i_op);\n      //\n      // default value for this operator\n      in_subgraph_[i_op] = depend_no;\n      //\n      switch(op)\n      {  case InvOp:\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 );\n         CPPAD_ASSERT_UNKNOWN( i_op > 0 );\n         {  // get user index for this independent variable\n            size_t j = i_op - 1;\n            CPPAD_ASSERT_UNKNOWN( j < n_ind_ );\n            //\n            // set in_subgraph_[i_op]\n            if( select_domain[j] )\n               in_subgraph_[i_op] = depend_yes;\n         }\n# ifndef NDEBUG\n         ++count_independent;\n# endif\n         break;\n\n         // only mark both first AFunOp for each call as depending\n         // on the selected independent variables\n         case AFunOp:\n         begin_atomic_call  = ! begin_atomic_call;\n         if( begin_atomic_call )\n         {  get_argument_variable(random_itr, i_op, argument_variable, work);\n            for(size_t j = 0; j < argument_variable.size(); ++j)\n            {  size_t j_var = argument_variable[j];\n               size_t j_op  = random_itr.var2op(j_var);\n               j_op         = size_t( map_user_op_[j_op] );\n               CPPAD_ASSERT_UNKNOWN( j_op < i_op );\n               if( in_subgraph_[j_op] == depend_yes )\n                  in_subgraph_[i_op] =  depend_yes;\n            }\n         }\n         break;\n\n         // skip FunrvOp (gets mapped to first AFunOp in this call)\n         case FunrvOp:\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 );\n         break;\n\n         default:\n         // Except for AFunOp, only include when NumRes(op) > 0.\n         if( NumRes(op) > 0 )\n         {  get_argument_variable(random_itr, i_op, argument_variable, work);\n            for(size_t j = 0; j < argument_variable.size(); ++j)\n            {  size_t j_var = argument_variable[j];\n               size_t j_op  = random_itr.var2op(j_var);\n               j_op         = size_t( map_user_op_[j_op] );\n               CPPAD_ASSERT_UNKNOWN( j_op < i_op );\n               if( in_subgraph_[j_op] == depend_yes )\n                  in_subgraph_[i_op] =  depend_yes;\n            }\n         }\n         break;\n      }\n   }\n   CPPAD_ASSERT_UNKNOWN(\n      count_independent == size_t(select_domain.size())\n   );\n   //\n   return;\n}\n// -----------------------------------------------------------------------\n/*!\nInitialize in_subgraph corresponding to a single dependent variable\n(and a selected set of independent variables).\n\n\\tparam Addr\nis the type used for indices in the random iterator.\n\n\\tparam Base\nthis recording was made using ADFun<Base>\n\n\\param play\nis a player for this ADFun<Base> object.\n\n\\param select_domain\nis a vector with, size equal to the number of independent variables\nin the recording. It determines the selected independent variables.\n\n\\par in_subgraph_\nWe use depend_yes (depend_no) for the value n_dep_ (n_dep_ + 1).\nThe important properties are that depend_yes < depend_no and\nfor a valid independent variable index i_ind < depend_yes.\nThe input size and elements of in_subgraph_ do not matter.\nIf in_subgraph_[i_op] == depend_yes (depend_no),\nthe result for this operator depends (does not depend)\non the selected independent variables.\nNote that for atomic function call operators i_op,\nin_subgraph[i_op] is depend_no except for the first AFunOp in the\natomic function call sequence. For the first AFunOp,\nit is depend_yes (depend_no) if any of the results for the call sequence\ndepend (do not depend) on the selected independent variables.\nExcept for UserOP, only operators with NumRes(op) > 0 have in_subgraph_\nvalue depend_yes;\ne.g., comparison operators have in_subgraph_ value depend_no.\n\n\\par select_domain_\nThis vector is is set equal to the select_domain argument.\n\n\\par process_range_\nThis vector is to to size n_dep_ and its values are set to false\n*/\ntemplate <class Addr, class Base, class BoolVector>\nvoid subgraph_info::init_rev(\n   player<Base>*       play          ,\n   const BoolVector&   select_domain )\n{\n   // get random access iterator for this player\n   Addr not_used;\n   play->setup_random( not_used );\n   local::play::const_random_iterator<Addr> random_itr =\n      play->get_random( not_used );\n   //\n   init_rev(random_itr, select_domain);\n   //\n   return;\n}\n\n\n} } } // END_CPPAD_LOCAL_SUBGRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/subgraph/sparsity.hpp",
    "content": "# ifndef CPPAD_LOCAL_SUBGRAPH_SPARSITY_HPP\n# define CPPAD_LOCAL_SUBGRAPH_SPARSITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/pod_vector.hpp>\n# include <cppad/local/subgraph/arg_variable.hpp>\n# include <cppad/local/subgraph/info.hpp>\n# include <cppad/local/subgraph/entire_call.hpp>\n\n// BEGIN_CPPAD_LOCAL_SUBGRAPH_NAMESPACE\nnamespace CppAD { namespace local { namespace subgraph {\n/*!\n\\file sparsity.hpp\nCompute dependency sparsity pattern using subgraph technique.\n*/\n// ===========================================================================\n/*!\nCompute dependency sparsity pattern for an ADFun<Base> function.\n\n\\tparam Addr\ntype used for indices in random iterator\n(must correspond to play->addr_type())\n\n\\tparam Base\nthe operation sequence was recorded using AD<Base>.\n\n\\tparam BoolVector\na simple vector class with elements of type bool.\n\n\\param play\nis the operation sequence corresponding to the ADFun<Base> function.\nIt is effectively const except that play->setup_random() is called.\n\n\n\\param sub_info\nis the subgraph information for this ADFun object.\n\n\\param dep_taddr\nmapping from user dependent variable index to variable index in play\n(must have size sub_info.n_dep()).\n\n\\param select_domain\nonly the selected independent variables will be included in the sparsity\npattern (must have size sub_info.n_ind()).\n\n\\param select_range\nonly the selected dependent variables will be included in the sparsity pattern\n(must have size sub_info.n_dep()).\n\n\\param row_out\nThe input size and elements of row_out do not matter.\nWe use number of non-zeros (nnz) to denote the number of elements\nin row_out. For k = 0 , ... , nnz-1, row_out[k] is the row index\nof the k-th no-zero element of the dependency sparsitiy pattern for\nthe function corresponding to the recording.\n\\code\n   0 <= row_out[k] < dep_taddr.size()\n   select_range[ row_out[k] ] == true\n\\endcode\n\n\\param col_out\nThe input size and elements of col_out do not matter.\nUpon return is has the same size as row_out; i.e., nnz.\nFor k = 0 , ... , nnz-1, col_out[k] is the column index\nof the k-th no-zero element of the dependency sparsitiy pattern for\nthe function corresponding to the recording.\n\\code\n   0 <= col_out[k] < sub_info.n_ind()\n   select_domain[ col_out[k] ] == true\n\\endcode\n\n\\par AFunOp\nAll of the inputs and outputs for an atomic function call are considered\nto be connected.\n2DO: It would be good to use the sparsity patters for atomic function calls\nto to make the sparsity pattern more efficient.\n*/\n\ntemplate <class Addr, class Base, class BoolVector>\nvoid subgraph_sparsity(\n   player<Base>*                              play          ,\n   subgraph_info&                             sub_info      ,\n   const pod_vector<size_t>&                  dep_taddr     ,\n   const BoolVector&                          select_domain ,\n   const BoolVector&                          select_range  ,\n   pod_vector<size_t>&                        row_out       ,\n   pod_vector<size_t>&                        col_out       )\n{\n   // get random access iterator for this player\n   Addr not_used;\n   play->setup_random( not_used );\n   local::play::const_random_iterator<Addr> random_itr =\n      play->get_random( not_used );\n\n   // check dimension assumptions\n   CPPAD_ASSERT_UNKNOWN(\n      dep_taddr.size() == sub_info.n_dep()\n   );\n   CPPAD_ASSERT_UNKNOWN(\n      size_t(select_domain.size()) == sub_info.n_ind()\n   );\n   CPPAD_ASSERT_UNKNOWN(\n      size_t(select_range.size()) == sub_info.n_dep()\n   );\n\n   // number of dependent variables\n   size_t n_dep = dep_taddr.size();\n   CPPAD_ASSERT_UNKNOWN( size_t(select_range.size()) == n_dep );\n\n   // start with an empty sparsity pattern\n   row_out.resize(0);\n   col_out.resize(0);\n\n   // map_user_op\n   if( sub_info.map_user_op().size() == 0 )\n      sub_info.set_map_user_op(play);\n   else\n   {  CPPAD_ASSERT_UNKNOWN( sub_info.check_map_user_op(play) );\n   }\n   CPPAD_ASSERT_UNKNOWN(\n         sub_info.map_user_op().size() == play->num_var_op()\n   );\n\n   // subgraph of operators that are are connected to one of the selected\n   // dependent variables and depend on the selected independent variables\n   pod_vector<addr_t> subgraph;\n\n   // initialize a reverse mode subgraph calculation\n   sub_info.init_rev(random_itr, select_domain);\n   CPPAD_ASSERT_UNKNOWN(\n      sub_info.in_subgraph().size() == play->num_var_op()\n   );\n   //\n# ifndef NDEBUG\n   addr_t depend_yes = addr_t( n_dep );\n# endif\n\n   // for each of the selected dependent variables\n# ifndef NDEBUG\n   addr_t depend_no  = addr_t( n_dep + 1 );\n# endif\n   CPPAD_ASSERT_UNKNOWN( depend_yes < depend_no );\n   CPPAD_ASSERT_UNKNOWN( NumRes(BeginOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(InvOp) == 1 );\n   for(size_t i_dep = 0; i_dep < n_dep; ++i_dep) if( select_range[i_dep] )\n   {  CPPAD_ASSERT_UNKNOWN( i_dep < size_t( depend_yes ) );\n      //\n      // subgraph of operators connected to i_dep\n      sub_info.get_rev(\n         random_itr, dep_taddr, addr_t(i_dep), subgraph\n      );\n      //\n      for(size_t k = 0; k < subgraph.size(); k++)\n      {  size_t i_op = size_t( subgraph[k] );\n         //\n         // operator corresponding to this index\n         op_code_var op = play->GetOp(i_op);\n         //\n         // This version of the subgraph only has first AFunOp\n         // for each atomic functionc all.\n         CPPAD_ASSERT_UNKNOWN( NumRes(op) > 0 || op == AFunOp );\n         //\n         // independent variable entries correspond to sparsity pattern\n         if( op == InvOp )\n         {  CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n            // i_var is equal i_op because BeginOp and InvOp have 1 result\n            size_t i_var = i_op;       // tape index for this variable\n            size_t i_ind = i_var - 1;  // user index for this variable\n            CPPAD_ASSERT_UNKNOWN( random_itr.var2op(i_var) == i_op );\n            CPPAD_ASSERT_UNKNOWN( select_domain[i_ind] );\n            //\n            // put this pair in the sparsity pattern\n            row_out.push_back(i_dep);\n            col_out.push_back(i_ind);\n         }\n      }\n   }\n}\n\n} } } // END_CPPAD_LOCAL_SUBGRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sweep/call_atomic.hpp",
    "content": "# ifndef CPPAD_LOCAL_SWEEP_CALL_ATOMIC_HPP\n# define CPPAD_LOCAL_SWEEP_CALL_ATOMIC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/atomic_index.hpp>\n# include <cppad/core/atomic/two/atomic.hpp>\n# include <cppad/core/atomic/three/atomic.hpp>\n# include <cppad/core/atomic/four/atomic.hpp>\n\n// BEGIN_CPAPD_LOCAL_SWEEP_NAMESPACE\nnamespace CppAD { namespace local { namespace sweep {\n\n/*\n// ----------------------------------------------------------------------------\n{xrst_begin_parent call_atomic dev}\n\nAtomic Function Callbacks\n#########################\n\n{xrst_end call_atomic}\n// ----------------------------------------------------------------------------\n{xrst_begin atomic_forward_callback dev}\n\nForward Mode Callback to Atomic Functions\n#########################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_FORWARD\n   // END_FORWARD\n}\n\nBase\n****\nIs the base type corresponding to the atomic function call.\n\nRecBase\n*******\nIs the base type corresponding to this atomic function call.\n\nvector\n******\nis the CppAD::vector template class.\n\nparameter_x\n***********\ncontains the values, in afun(ax, ay), for arguments that are parameters.\n\ntype_x\n******\nwhat is the type, in the call, for each component of x.\n\nneed_y\n******\nspecifies which components of taylor_y are necessary.\nOnly the components of y with the type equal to need_y need\nto be computed. If need_y is greater than variable_enum,\nthen all the components of y must be computed.\n\nselect_y\n********\nspecifies which components of taylor_y are necessary.\n\norder_low\n*********\nlowest order for this forward mode calculation.\n\norder_up\n********\nhighest order for this forward mode calculation.\n\natom_index\n**********\nis the index, in local::atomic_index, corresponding to this atomic function.\n\ncall_id\n*******\nsee the atomic_four :ref:`atomic_four_call@call_id` and\nthe atomic_one :ref:`atomic_one@id` .\n\ntaylor_x\n********\nTaylor coefficients corresponding to x.\n\ntaylor_y\n********\nTaylor coefficient corresponding to y.\n\n{xrst_end atomic_forward_callback}\n*/\n// BEGIN_FORWARD\ntemplate <class Base, class RecBase>\nvoid call_atomic_forward(\n   const vector<Base>&          parameter_x ,\n   const vector<ad_type_enum>&  type_x      ,\n   size_t                       need_y      ,\n   const vector<bool>&          select_y    ,\n   size_t                       order_low   ,\n   size_t                       order_up    ,\n   size_t                       atom_index  ,\n   size_t                       call_id     ,\n   const vector<Base>&          taylor_x    ,\n   vector<Base>&                taylor_y    )\n// END_FORWARD\n{  CPPAD_ASSERT_UNKNOWN( 0 < atom_index );\n   bool         set_null = false;\n   size_t       type     = 0;          // set to avoid warning\n   std::string* name_ptr = nullptr;\n   void*        v_ptr    = nullptr; // set to avoid warning\n   local::atomic_index<RecBase>(set_null, atom_index, type, name_ptr, v_ptr);\n# ifndef NDEBUG\n   bool ok = v_ptr != nullptr;\n   if( ok )\n   {\n      if( type == 2 )\n      {  atomic_base<RecBase>* afun =\n            reinterpret_cast< atomic_base<RecBase>* >(v_ptr);\n         afun->set_old(call_id);\n         vector<ad_type_enum> empty;\n         ok = afun->forward(\n            order_low, order_up, empty, empty, taylor_x, taylor_y\n         );\n      }\n      else if( type == 3 )\n      {  CPPAD_ASSERT_UNKNOWN( type == 3 );\n         atomic_three<RecBase>* afun =\n            reinterpret_cast< atomic_three<RecBase>* >(v_ptr);\n         ok = afun->forward(\n            parameter_x, type_x,\n            need_y, order_low, order_up, taylor_x, taylor_y\n         );\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN( type == 4 );\n         atomic_four<RecBase>* afun =\n            reinterpret_cast< atomic_four<RecBase>* >(v_ptr);\n         ok = afun->forward(\n            call_id, select_y, order_low, order_up, taylor_x, taylor_y\n         );\n      }\n   }\n   if( ! ok )\n   {  // now take the extra time to copy the name\n      std::string name;\n      local::atomic_index<RecBase>(set_null, atom_index, type, &name, v_ptr);\n      std::string msg = name;\n      if( v_ptr == nullptr )\n         msg += \": this atomic function has been deleted\";\n      else\n         msg += \": atomic forward returned false\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# else\n   if( type == 2 )\n   {  atomic_base<RecBase>* afun =\n         reinterpret_cast< atomic_base<RecBase>* >(v_ptr);\n      vector<ad_type_enum> empty;\n      afun->set_old(call_id);\n      afun->forward(\n         order_low, order_up, empty, empty, taylor_x, taylor_y\n      );\n   }\n   else if( type == 3 )\n   {  atomic_three<RecBase>* afun =\n         reinterpret_cast< atomic_three<RecBase>* >(v_ptr);\n      afun->forward(\n         parameter_x, type_x,\n         need_y, order_low, order_up, taylor_x, taylor_y\n      );\n   }\n   else\n   {  atomic_four<RecBase>* afun =\n         reinterpret_cast< atomic_four<RecBase>* >(v_ptr);\n      afun->forward(\n         call_id, select_y, order_low, order_up, taylor_x, taylor_y\n      );\n   }\n# endif\n}\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_reverse_callback dev}\n\nReverse Mode callback to Atomic Functions\n#########################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_REVERSE\n   // END_REVERSE\n}\n\nBase\n****\nIs the base type corresponding to the atomic function call.\n\nRecBase\n*******\nIs the base type corresponding to this atomic function call.\n\nvector\n******\nis the CppAD::vector template class.\n\nparameter_x\n***********\nvalue of the parameter arguments to the atomic function\n(other arguments have the value nan).\n\ntype_x\n******\ntype for each component of x (not used by atomic_two interface).\n\nselect_x\n********\nspecifies which components of partial_x are necessary.\n\norder_up\n********\nhighest order for this reverse mode calculation.\n\natom_index\n**********\nis the index, in local::atomic_index, corresponding to this atomic function.\n\ncall_id\n*******\nsee the atomic_four :ref:`atomic_four_call@call_id` and\nthe atomic_one :ref:`atomic_one@id` .\n\ntaylor_x\n********\nTaylor coefficients corresponding to x.\n\ntaylor_y\n********\nTaylor coefficient corresponding to y.\n\npartial_x\n*********\nPartials w.r.t the x Taylor coefficients.\n\npartial_y\n*********\nPartials w.r.t the y Taylor coefficients.\n\n{xrst_end atomic_reverse_callback}\n*/\n// BEGIN_REVERSE\ntemplate <class Base, class RecBase>\nvoid call_atomic_reverse(\n   const vector<Base>&          parameter_x ,\n   const vector<ad_type_enum>&  type_x      ,\n   const vector<bool>&          select_x    ,\n   size_t                       order_up    ,\n   size_t                       atom_index  ,\n   size_t                       call_id     ,\n   const vector<Base>&          taylor_x    ,\n   const vector<Base>&          taylor_y    ,\n   vector<Base>&                partial_x   ,\n   const vector<Base>&          partial_y   )\n// END_REVERSE\n{  CPPAD_ASSERT_UNKNOWN( 0 < atom_index );\n   bool         set_null = false;\n   size_t       type     = 0;          // set to avoid warning\n   std::string* name_ptr = nullptr;\n   void*        v_ptr    = nullptr; // set to avoid warning\n   local::atomic_index<RecBase>(set_null, atom_index, type, name_ptr, v_ptr);\n# ifndef NDEBUG\n   bool ok = v_ptr != nullptr;\n   if( ok )\n   {\n      if( type == 2 )\n      {  atomic_base<RecBase>* afun =\n            reinterpret_cast< atomic_base<RecBase>* >(v_ptr);\n         afun->set_old(call_id);\n         ok = afun->reverse(\n            order_up, taylor_x, taylor_y, partial_x, partial_y\n         );\n      }\n      else if( type == 3 )\n      {  atomic_three<RecBase>* afun =\n            reinterpret_cast< atomic_three<RecBase>* >(v_ptr);\n         ok = afun->reverse(\n            parameter_x, type_x,\n            order_up, taylor_x, taylor_y, partial_x, partial_y\n         );\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN( type == 4 );\n         atomic_four<RecBase>* afun =\n            reinterpret_cast< atomic_four<RecBase>* >(v_ptr);\n         ok = afun->reverse(\n            call_id, select_x,\n            order_up, taylor_x, taylor_y, partial_x, partial_y\n         );\n      }\n   }\n   if( ! ok )\n   {  // now take the extra time to copy the name\n      std::string name;\n      local::atomic_index<RecBase>(set_null, atom_index, type, &name, v_ptr);\n      std::string msg = name;\n      if( v_ptr == nullptr )\n         msg += \": this atomic function has been deleted\";\n      else\n         msg += \": atomic reverse returned false\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# else\n   if( type == 2 )\n   {  atomic_base<RecBase>* afun =\n         reinterpret_cast< atomic_base<RecBase>* >(v_ptr);\n      afun->set_old(call_id);\n      afun->reverse(\n         order_up, taylor_x, taylor_y, partial_x, partial_y\n      );\n   }\n   else if( type == 3 )\n   {  atomic_three<RecBase>* afun =\n         reinterpret_cast< atomic_three<RecBase>* >(v_ptr);\n      afun->reverse(\n         parameter_x, type_x,\n         order_up, taylor_x, taylor_y, partial_x, partial_y\n      );\n   }\n   else\n   {  atomic_four<RecBase>* afun =\n         reinterpret_cast< atomic_four<RecBase>* >(v_ptr);\n      afun->reverse(\n         call_id, select_x,\n         order_up, taylor_x, taylor_y, partial_x, partial_y\n      );\n   }\n# endif\n}\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_for_jac_sparsity_callback dev}\n{xrst_spell\n   setvec\n}\n\nForward Jacobian Sparsity Callback to Atomic Functions\n######################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_FOR_JAC_SPARSITY\n   // END_FOR_JAC_SPARSITY\n}\n\nBase\n****\nIs the base type corresponding to the atomic function call.\n\nvector\n******\nis the CppAD::vector template class.\n\nInternalSparsity\n****************\nis the internal type used to represent sparsity; i.e.,\nsparse::pack_setvec or sparse::list_setvec.\n\natom_index\n**********\nis the index, in local::atomic_index, corresponding to this atomic function.\n\ncall_id\n*******\nsee the atomic_four :ref:`atomic_four_call@call_id` and\nthe atomic_one :ref:`atomic_one@id` .\n\ndependency\n**********\nis this a dependency or sparsity calculation.\n\nparameter_x\n***********\nvalue of the parameter arguments to the atomic function\n(other arguments have the value nan).\n\ntype_x\n******\ntype for each component of x (not used by atomic_two interface).\n\nx_index\n*******\nis a mapping from the index of an atomic function argument\nto the corresponding variable on the tape.\n\ny_index\n*******\nis a mapping from the index of an atomic function result\nto the corresponding variable on the tape.\n\nvar_sparsity\n************\nOn input, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nis the sparsity for the j-th argument to this atomic function.\nOn output, for i = 0, ... , m-1, the sparsity pattern with index y_index[i],\nis the sparsity for the i-th result for this atomic function.\n\n{xrst_end atomic_for_jac_sparsity_callback}\n*/\n// BEGIN_FOR_JAC_SPARSITY\ntemplate <class Base, class RecBase, class InternalSparsity>\nvoid call_atomic_for_jac_sparsity(\n   size_t                       atom_index    ,\n   size_t                       call_id       ,\n   bool                         dependency    ,\n   const vector<Base>&          parameter_x   ,\n   const vector<ad_type_enum>&  type_x        ,\n   const vector<size_t>&        x_index       ,\n   const vector<size_t>&        y_index       ,\n   InternalSparsity&            var_sparsity  )\n// END_FOR_JAC_SPARSITY\n{  CPPAD_ASSERT_UNKNOWN( 0 < atom_index );\n   bool         set_null = false;\n   size_t       type     = 0;       // set to avoid warning\n   std::string* name_ptr = nullptr;\n   void*        v_ptr    = nullptr; // set to avoid warning\n   local::atomic_index<RecBase>(set_null, atom_index, type, name_ptr, v_ptr);\n   //\n   // ident_zero_x\n   vector<bool> ident_zero_x;\n   if( type == 4 )\n   {  size_t n = x_index.size();\n      ident_zero_x.resize(n);\n      for(size_t j = 0; j < n; ++j)\n      {  if( type_x[j] > constant_enum )\n            ident_zero_x[j] = false;\n         else\n            ident_zero_x[j] = IdenticalZero( parameter_x[j] );\n      }\n   }\n# ifndef NDEBUG\n   bool ok = v_ptr != nullptr;\n   if ( ok )\n   {\n      if( type == 2 )\n      {  atomic_base<RecBase>* afun =\n            reinterpret_cast< atomic_base<RecBase>* >(v_ptr);\n         afun->set_old(call_id);\n         ok = afun->for_sparse_jac(\n            parameter_x, x_index, y_index, var_sparsity\n         );\n      }\n      else if( type == 3 )\n      {  atomic_three<RecBase>* afun =\n            reinterpret_cast< atomic_three<RecBase>* >(v_ptr);\n         ok = afun->for_jac_sparsity(\n         dependency, parameter_x, type_x, x_index, y_index, var_sparsity\n         );\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN( type == 4 );\n         atomic_four<RecBase>* afun =\n            reinterpret_cast< atomic_four<RecBase>* >(v_ptr);\n         ok = afun->for_jac_sparsity( call_id,\n            dependency, ident_zero_x, x_index, y_index, var_sparsity\n         );\n      }\n   }\n   if( ! ok )\n   {  // now take the extra time to copy the name\n      std::string name;\n      local::atomic_index<RecBase>(\n         set_null, atom_index, type, &name, v_ptr\n      );\n      std::string msg = name;\n      if( v_ptr == nullptr )\n         msg += \": this atomic function has been deleted\";\n      else\n         msg += \": atomic jac_sparsity returned false\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# else\n   if( type == 2 )\n   {  atomic_base<RecBase>* afun =\n         reinterpret_cast< atomic_base<RecBase>* >(v_ptr);\n      afun->set_old(call_id);\n      afun->for_sparse_jac(\n         parameter_x, x_index, y_index, var_sparsity\n      );\n   }\n   else if( type == 3 )\n   {  atomic_three<RecBase>* afun =\n         reinterpret_cast< atomic_three<RecBase>* >(v_ptr);\n      afun->for_jac_sparsity(\n         dependency, parameter_x, type_x, x_index, y_index, var_sparsity\n      );\n   }\n   else\n   {  atomic_four<RecBase>* afun =\n         reinterpret_cast< atomic_four<RecBase>* >(v_ptr);\n      afun->for_jac_sparsity( call_id,\n         dependency, ident_zero_x, x_index, y_index, var_sparsity\n      );\n   }\n# endif\n}\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_rev_jac_sparsity_callback dev}\n{xrst_spell\n   setvec\n}\n\nReverse Jacobian sparsity Callback to Atomic Functions\n######################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_REV_JAC_SPARSITY\n   // END_REV_JAC_SPARSITY\n}\n\nBase\n****\nis the type corresponding to parameter_x\nand to this atomic function.\n\nInternalSparsity\n****************\nis the internal type used to represent sparsity; i.e.,\nsparse::pack_setvec or sparse::list_setvec.\n\natom_index\n**********\nis the index, in local::atomic_index, corresponding to this atomic function.\n\ncall_id\n*******\nsee the atomic_four :ref:`atomic_four_call@call_id` and\nthe atomic_one :ref:`atomic_one@id` .\n\ndependency\n**********\nis this a dependency or sparsity calculation.\n\nparameter_x\n***********\nvalue of the parameter arguments to the atomic function\n(other arguments have the value nan).\n\ntype_x\n******\ntype for each component of x (not used by atomic_two interface).\n\nx_index\n*******\nis a mapping from the index of an atomic function argument\nto the corresponding variable on the tape.\n\ny_index\n*******\nis a mapping from the index of an atomic function result\nto the corresponding variable on the tape.\n\nvar_sparsity [in/out]\n*********************\nOn input, for i = 0, ... , m-1, the sparsity pattern with index y_index[i],\nis the sparsity for the i-th argument to this atomic function.\nOn output, for j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nthe sparsity has been updated to remove y as a function of x.\n\n{xrst_end atomic_rev_jac_sparsity_callback}\n*/\n// BEGIN_REV_JAC_SPARSITY\ntemplate <class Base, class RecBase, class InternalSparsity>\nvoid call_atomic_rev_jac_sparsity(\n   size_t                       atom_index    ,\n   size_t                       call_id       ,\n   bool                         dependency    ,\n   const vector<Base>&          parameter_x   ,\n   const vector<ad_type_enum>&  type_x        ,\n   const vector<size_t>&        x_index       ,\n   const vector<size_t>&        y_index       ,\n   InternalSparsity&            var_sparsity  )\n// END_REV_JAC_SPARSITY\n{  CPPAD_ASSERT_UNKNOWN( 0 < atom_index );\n   bool         set_null = false;\n   size_t       type     = 0;          // set to avoid warning\n   std::string* name_ptr = nullptr;\n   void*        v_ptr    = nullptr; // set to avoid warning\n   local::atomic_index<RecBase>(set_null, atom_index, type, name_ptr, v_ptr);\n   //\n   // ident_zero_x\n   vector<bool> ident_zero_x;\n   if( type == 4 )\n   {  size_t n = x_index.size();\n      ident_zero_x.resize(n);\n      for(size_t j = 0; j < n; ++j)\n      {  if( type_x[j] > constant_enum )\n            ident_zero_x[j] = false;\n         else\n            ident_zero_x[j] = IdenticalZero( parameter_x[j] );\n      }\n   }\n# ifndef NDEBUG\n   bool ok = v_ptr != nullptr;\n   if( ok )\n   {\n      if( type == 2 )\n      {  atomic_base<RecBase>* afun =\n            reinterpret_cast< atomic_base<RecBase>* >(v_ptr);\n         afun->set_old(call_id);\n         ok = afun->rev_sparse_jac(\n            parameter_x, x_index, y_index, var_sparsity\n         );\n      }\n      else if( type == 3 )\n      {  atomic_three<RecBase>* afun =\n            reinterpret_cast< atomic_three<RecBase>* >(v_ptr);\n         ok = afun->rev_jac_sparsity(\n         dependency, parameter_x, type_x, x_index, y_index, var_sparsity\n         );\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN( type == 4 );\n         atomic_four<RecBase>* afun =\n            reinterpret_cast< atomic_four<RecBase>* >(v_ptr);\n         ok = afun->rev_jac_sparsity(call_id,\n            dependency, ident_zero_x, x_index, y_index, var_sparsity\n         );\n      }\n   }\n   if( ! ok )\n   {  // now take the extra time to copy the name\n      std::string name;\n      local::atomic_index<RecBase>(\n         set_null, atom_index, type, &name, v_ptr\n      );\n      std::string msg = name;\n      if( v_ptr == nullptr )\n         msg += \": this atomic function has been deleted\";\n      else\n         msg += \": atomic jac_sparsity returned false\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# else\n   if( type == 2 )\n   {  atomic_base<RecBase>* afun =\n         reinterpret_cast< atomic_base<RecBase>* >(v_ptr);\n      afun->set_old(call_id);\n      afun->rev_sparse_jac(\n         parameter_x, x_index, y_index, var_sparsity\n      );\n   }\n   else if( type == 3 )\n   {  atomic_three<RecBase>* afun =\n         reinterpret_cast< atomic_three<RecBase>* >(v_ptr);\n      afun->rev_jac_sparsity(\n         dependency, parameter_x, type_x, x_index, y_index, var_sparsity\n      );\n   }\n   else\n   {  atomic_four<RecBase>* afun =\n         reinterpret_cast< atomic_four<RecBase>* >(v_ptr);\n      afun->rev_jac_sparsity(call_id,\n         dependency, ident_zero_x, x_index, y_index, var_sparsity\n      );\n   }\n# endif\n}\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_for_hes_sparsity_callback dev}\n{xrst_spell\n   setvec\n}\n\nForward Hessian Sparsity Callback to Atomic Functions\n#####################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_FOR_HES_SPARSITY\n   // END_FOR_HES_SPARSITY\n}\n\nBase\n****\nis the type corresponding to *parameter_x*\nand to this atomic function.\n\nInternalSparsity\n****************\nis the internal type used to represent sparsity; i.e.,\n``sparse::pack_setvec`` or ``sparse::list_setvec`` .\n\natom_index\n**********\nis the index, in local::atomic_index, corresponding to this atomic function.\n\ncall_id\n*******\nsee the atomic_four :ref:`atomic_four_call@call_id` and\nthe atomic_one :ref:`atomic_one@id` .\n\nparameter_x\n***********\nvalue of the parameter arguments to the atomic function\n(other arguments have the value nan).\n\ntype_x\n******\ntype for each component of x (not used by atomic_two interface).\n\nx_index\n*******\nis a mapping from the index of an atomic function argument\nto the corresponding variable on the tape.\nWe use *m_x* to denote the maximum value w.r.t *i* of\n*x_index* [ *i* ] .\n\ny_index\n*******\nis a mapping from the index of an atomic function result\nto the corresponding variable on the tape.\nIt should hold that *m_i* < ``y_index`` [ ``i`` ] for all *i* .\n\nnp1\n***\nThis is the number of independent variables plus one;\ni.e. size of *x* plus one.\n\nnum_var\n*******\nThis is the total number of variables in the tape.\n\nrev_jac_sparsity\n****************\nFor i = 0, ... , m-1, the sparsity pattern with index y_index[i],\nis the reverse Jacobian sparsity for the i-th result to this atomic function.\nThis shows which components of the result affect the function we are\ncomputing the Hessian of.\n\nfor_sparsity\n************\nWe have the conditions *np1* = *for_sparsity* . ``end`` ()\nand *for_sparsity* . ``n_set`` () = *np1* + *num_var* .\n\nInput Jacobian Sparsity\n=======================\nFor *i* = 0, ..., *m_x* ,\nthe *np1* + *i* row of *for_sparsity* is the Jacobian sparsity\nfor the *i*-th variable. These values do not change.\nNote that *i* =0 corresponds to a parameter and\nthe corresponding Jacobian sparsity is empty.\n\nInput Hessian Sparsity\n======================\nFor *i* =1, ..., *n* ,\nthe *i*-th row of *for_sparsity* is the Hessian sparsity\nbefore including the function :math:`y = f(x)`.\n\nOutput Jacobian Sparsity\n========================\nFor *i* =0, ..., *y_index* . ``size`` () ,\nrow *np1* + *y_index* [ *i* ]\nof *for_sparsity* is the Jacobian sparsity\nfor the variable with index *y_index* [ *i* ] .\n\nOutput Hessian Sparsity\n=======================\nFor *i* =1, ..., *n* ,\nthe *i*-th row of *for_sparsity* is the Hessian sparsity\nafter including the function :math:`y = f(x)`.\n\n{xrst_end atomic_for_hes_sparsity_callback}\n*/\n// BEGIN_FOR_HES_SPARSITY\ntemplate <class Base, class RecBase, class InternalSparsity>\nvoid call_atomic_for_hes_sparsity(\n   size_t                       atom_index        ,\n   size_t                       call_id           ,\n   const vector<Base>&          parameter_x       ,\n   const vector<ad_type_enum>&  type_x            ,\n   const vector<size_t>&        x_index           ,\n   const vector<size_t>&        y_index           ,\n   size_t                       np1               ,\n   size_t                       num_var           ,\n   const InternalSparsity&      rev_jac_sparsity  ,\n   InternalSparsity&            for_sparsity      )\n// END_FOR_HES_SPARSITY\n{  CPPAD_ASSERT_UNKNOWN( 0 < atom_index );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + num_var );\n\n   bool         set_null = false;\n   size_t       type     = 0;          // set to avoid warning\n   std::string* name_ptr = nullptr;\n   void*        v_ptr    = nullptr; // set to avoid warning\n   local::atomic_index<RecBase>(set_null, atom_index, type, name_ptr, v_ptr);\n   //\n   // ident_zero_x\n   vector<bool> ident_zero_x;\n   if( type == 4 )\n   {  size_t n = x_index.size();\n      ident_zero_x.resize(n);\n      for(size_t j = 0; j < n; ++j)\n      {  if( type_x[j] > constant_enum )\n            ident_zero_x[j] = false;\n         else\n            ident_zero_x[j] = IdenticalZero( parameter_x[j] );\n      }\n   }\n# ifndef NDEBUG\n   bool ok = v_ptr != nullptr;\n   if( ok )\n   {\n      if( type == 2 )\n      {  atomic_base<RecBase>* afun =\n            reinterpret_cast< atomic_base<RecBase>* >(v_ptr);\n         afun->set_old(call_id);\n         ok = afun->for_sparse_hes(\n            parameter_x,\n            x_index,\n            y_index,\n            np1,\n            num_var,\n            rev_jac_sparsity,\n            for_sparsity\n         );\n      }\n      else if( type == 3 )\n      {  atomic_three<RecBase>* afun =\n            reinterpret_cast< atomic_three<RecBase>* >(v_ptr);\n         ok = afun->for_hes_sparsity(\n            parameter_x,\n            type_x,\n            x_index,\n            y_index,\n            np1,\n            num_var,\n            rev_jac_sparsity,\n            for_sparsity\n         );\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN( type == 4 );\n         atomic_four<RecBase>* afun =\n            reinterpret_cast< atomic_four<RecBase>* >(v_ptr);\n         ok = afun->for_hes_sparsity(\n            call_id,\n            ident_zero_x,\n            x_index,\n            y_index,\n            np1,\n            num_var,\n            rev_jac_sparsity,\n            for_sparsity\n         );\n      }\n   }\n   if( ! ok )\n   {  // now take the extra time to copy the name\n      std::string name;\n      local::atomic_index<RecBase>(\n         set_null, atom_index, type, &name, v_ptr\n      );\n      std::string msg = name;\n      if( v_ptr == nullptr )\n         msg += \": this atomic function has been deleted\";\n      else\n         msg += \": atomic hes_sparsity returned false\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# else\n   if( type == 2 )\n   {  atomic_base<RecBase>* afun =\n         reinterpret_cast< atomic_base<RecBase>* >(v_ptr);\n      afun->set_old(call_id);\n      afun->for_sparse_hes(\n         parameter_x,\n         x_index,\n         y_index,\n         np1,\n         num_var,\n         rev_jac_sparsity,\n         for_sparsity\n      );\n   }\n   else if( type == 3 )\n   {  atomic_three<RecBase>* afun =\n         reinterpret_cast< atomic_three<RecBase>* >(v_ptr);\n      afun->for_hes_sparsity(\n         parameter_x,\n         type_x,\n         x_index,\n         y_index,\n         np1,\n         num_var,\n         rev_jac_sparsity,\n         for_sparsity\n      );\n   }\n   else\n   {  atomic_four<RecBase>* afun =\n         reinterpret_cast< atomic_four<RecBase>* >(v_ptr);\n      afun->for_hes_sparsity(\n         call_id,\n         ident_zero_x,\n         x_index,\n         y_index,\n         np1,\n         num_var,\n         rev_jac_sparsity,\n         for_sparsity\n      );\n   }\n# endif\n}\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_rev_hes_sparsity_callback dev}\n{xrst_spell\n   setvec\n}\n\nReverse Hessian Sparsity Callback to Atomic Functions\n#####################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_REV_HES_SPARSITY\n   // END_REV_HES_SPARSITY\n}\n\nBase\n****\nis the type corresponding to parameter_x\nand to this atomic function.\n\nInternalSparsity\n****************\nis the internal type used to represent sparsity; i.e.,\nsparse::pack_setvec or sparse::list_setvec.\n\ncall_id\n*******\nsee the atomic_four :ref:`atomic_four_call@call_id` and\nthe atomic_one :ref:`atomic_one@id` .\n\nparameter_x\n***********\nvalue of the parameter arguments to the atomic function\n(other arguments have the value nan).\n\ntype_x\n******\ntype for each component of x (not used by atomic_two interface).\n\nx_index\n*******\nis a mapping from the index of an atomic function argument\nto the corresponding variable on the tape.\n\ny_index\n*******\nis a mapping from the index of an atomic function result\nto the corresponding variable on the tape.\n\nfor_jac_sparsity\n****************\nFor j = 0, ... , n-1, the sparsity pattern with index x_index[j],\nis the forward Jacobian sparsity for the j-th argument to this atomic function.\n\nrev_jac_flag\n************\nOn input, for i = 0, ... , m-1, rev_jac_flag[ y_index[i] ] is true\nif the function (we are computing the sparsity for)\ndepends on the variable y_index[i].\nUpon return, for j = 0, ..., n-1, rev_jac_flag[ x_index[j] ] has been set to\ntrue any of the y_index variables are flagged depend on x_index[j].\nOtherwise, rev_jac_flag[ x_index[j] ] is not modified.\n\nrev_hes_sparsity\n****************\nThis is the sparsity pattern for the Hessian.\nOn input, for i = 0, ... , m-1, row y_index[i] is the reverse Hessian sparsity\nwith one of the partials with respect to y_index[i].\nUpon return, for j = 0, ..., n-1, the row x_index[j] has been\nmodified to include components that have a non-zero hessian through\nthe atomic function with one of the partials w.r.t. x_index[j].\n\n{xrst_end atomic_rev_hes_sparsity_callback}\n*/\n// BEGIN_REV_HES_SPARSITY\ntemplate <class Base, class RecBase, class InternalSparsity>\nvoid call_atomic_rev_hes_sparsity(\n   size_t                       atom_index        ,\n   size_t                       call_id           ,\n   const vector<Base>&          parameter_x       ,\n   const vector<ad_type_enum>&  type_x            ,\n   const vector<size_t>&        x_index           ,\n   const vector<size_t>&        y_index           ,\n   const InternalSparsity&      for_jac_sparsity  ,\n   bool*                        rev_jac_flag      ,\n   InternalSparsity&            rev_hes_sparsity  )\n// END_REV_HES_SPARSITY\n{  CPPAD_ASSERT_UNKNOWN( 0 < atom_index );\n   bool         set_null = false;\n   size_t       type     = 0;          // set to avoid warning\n   std::string* name_ptr = nullptr;\n   void*        v_ptr    = nullptr; // set to avoid warning\n   local::atomic_index<RecBase>(set_null, atom_index, type, name_ptr, v_ptr);\n   //\n   // ident_zero_x\n   vector<bool> ident_zero_x;\n   if( type == 4 )\n   {  size_t n = x_index.size();\n      ident_zero_x.resize(n);\n      for(size_t j = 0; j < n; ++j)\n      {  if( type_x[j] > constant_enum )\n            ident_zero_x[j] = false;\n         else\n            ident_zero_x[j] = IdenticalZero( parameter_x[j] );\n      }\n   }\n# ifndef NDEBUG\n   bool ok = v_ptr != nullptr;\n   if( ok )\n   {\n      if( type == 2 )\n      {  atomic_base<RecBase>* afun =\n            reinterpret_cast< atomic_base<RecBase>* >(v_ptr);\n         afun->set_old(call_id);\n         ok = afun->rev_sparse_hes(\n            parameter_x,\n            x_index,\n            y_index,\n            for_jac_sparsity,\n            rev_jac_flag,\n            rev_hes_sparsity\n         );\n      }\n      else if( type == 3 )\n      {  atomic_three<RecBase>* afun =\n            reinterpret_cast< atomic_three<RecBase>* >(v_ptr);\n         ok = afun->rev_hes_sparsity(\n            parameter_x,\n            type_x,\n            x_index,\n            y_index,\n            for_jac_sparsity,\n            rev_jac_flag,\n            rev_hes_sparsity\n         );\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN( type == 4 );\n         atomic_four<RecBase>* afun =\n            reinterpret_cast< atomic_four<RecBase>* >(v_ptr);\n         ok = afun->rev_hes_sparsity(\n            call_id,\n            ident_zero_x,\n            x_index,\n            y_index,\n            for_jac_sparsity,\n            rev_jac_flag,\n            rev_hes_sparsity\n         );\n      }\n   }\n   if( ! ok )\n   {  // now take the extra time to copy the name\n      std::string name;\n      local::atomic_index<RecBase>(\n         set_null, atom_index, type, &name, v_ptr\n      );\n      std::string msg = name;\n      if( v_ptr == nullptr )\n         msg += \": this atomic function has been deleted\";\n      else\n         msg += \": atomic hes_sparsity returned false\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# else\n   if( type == 2 )\n   {  atomic_base<RecBase>* afun =\n         reinterpret_cast< atomic_base<RecBase>* >(v_ptr);\n      afun->set_old(call_id);\n      afun->rev_sparse_hes(\n         parameter_x,\n         x_index,\n         y_index,\n         for_jac_sparsity,\n         rev_jac_flag,\n         rev_hes_sparsity\n      );\n   }\n   else if( type == 3 )\n   {  atomic_three<RecBase>* afun =\n         reinterpret_cast< atomic_three<RecBase>* >(v_ptr);\n      afun->rev_hes_sparsity(\n         parameter_x,\n         type_x,\n         x_index,\n         y_index,\n         for_jac_sparsity,\n         rev_jac_flag,\n         rev_hes_sparsity\n      );\n   }\n   else\n   {  atomic_four<RecBase>* afun =\n         reinterpret_cast< atomic_four<RecBase>* >(v_ptr);\n      afun->rev_hes_sparsity(\n         call_id,\n         ident_zero_x,\n         x_index,\n         y_index,\n         for_jac_sparsity,\n         rev_jac_flag,\n         rev_hes_sparsity\n      );\n   }\n# endif\n}\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin atomic_rev_depend_callback dev}\n\nReverse Dependency Callback to Atomic Functions\n###############################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_REV_DEPEND\n   // END_REV_DEPEND\n}\n\natom_index\n**********\nis the index, in local::atomic_index, corresponding to this atomic function.\n\ncall_id\n*******\nsee the atomic_four :ref:`atomic_four_call@call_id` and\nthe atomic_one :ref:`atomic_one@id` .\n\nparameter_x\n***********\nis the value of the parameters in the corresponding atomic function call.\n\ntype_x\n******\nis the type for each x component in the corresponding atomic function call.\n\ndepend_x\n********\nwhich components of x affect values we are interested in.\nThis is the only output for this routine.\n\ndepend_y\n********\nwhich components of y affect values we are interested in.\n\n{xrst_end atomic_rev_depend_callback}\n*/\n// BEGIN_REV_DEPEND\ntemplate <class Base, class RecBase>\nvoid call_atomic_rev_depend(\n   size_t                      atom_index   ,\n   size_t                      call_id      ,\n   const vector<Base>&         parameter_x  ,\n   const vector<ad_type_enum>& type_x       ,\n   vector<bool>&               depend_x     ,\n   const vector<bool>&         depend_y     )\n// END_REV_DEPEND\n{  CPPAD_ASSERT_UNKNOWN( 0 < atom_index );\n   bool         set_null = false;\n   size_t       type     = 0;          // set to avoid warning\n   std::string* name_ptr = nullptr;\n   void*        v_ptr    = nullptr; // set to avoid warning\n   local::atomic_index<RecBase>(set_null, atom_index, type, name_ptr, v_ptr);\n   //\n   // ident_zero_x\n   vector<bool> ident_zero_x;\n   if( type == 4 )\n   {  size_t n = parameter_x.size();\n      ident_zero_x.resize(n);\n      for(size_t j = 0; j < n; ++j)\n      {  if( type_x[j] > constant_enum )\n            ident_zero_x[j] = false;\n         else\n            ident_zero_x[j] = IdenticalZero( parameter_x[j] );\n      }\n   }\n# ifndef NDEBUG\n   bool ok = v_ptr != nullptr;\n   if( ok )\n   {\n      if( type == 2 )\n      {  atomic_base<RecBase>* afun =\n            reinterpret_cast< atomic_base<RecBase>* >(v_ptr);\n         afun->set_old(call_id);\n         vector<ad_type_enum> empty;\n         ok = afun->rev_depend(parameter_x, type_x, depend_x, depend_y);\n      }\n      else if( type == 3 )\n      {  atomic_three<RecBase>* afun =\n            reinterpret_cast< atomic_three<RecBase>* >(v_ptr);\n         ok = afun->rev_depend(parameter_x, type_x, depend_x, depend_y);\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN( type == 4 );\n         atomic_four<RecBase>* afun =\n            reinterpret_cast< atomic_four<RecBase>* >(v_ptr);\n         // rev_depend does not have a wrapper that drops back to\n         // deprecated version of this function.\n         ok = afun->rev_depend(call_id, ident_zero_x, depend_x, depend_y);\n         if( ! ok ) ok = afun->rev_depend(call_id, depend_x, depend_y);\n      }\n   }\n   if( ! ok )\n   {  // now take the extra time to copy the name\n      std::string name;\n      local::atomic_index<RecBase>(set_null, atom_index, type, &name, v_ptr);\n      std::string msg = name;\n      if( v_ptr == nullptr )\n         msg += \": this atomic function has been deleted\";\n      else\n         msg += \": atomic rev_depend returned false\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# else\n   if( type == 2 )\n   {  atomic_base<RecBase>* afun =\n         reinterpret_cast< atomic_base<RecBase>* >(v_ptr);\n      vector<ad_type_enum> empty;\n      afun->set_old(call_id);\n      afun->rev_depend(parameter_x, type_x, depend_x, depend_y);\n   }\n   else if( type == 3 )\n   {  atomic_three<RecBase>* afun =\n         reinterpret_cast< atomic_three<RecBase>* >(v_ptr);\n      afun->rev_depend(parameter_x, type_x, depend_x, depend_y);\n   }\n   else\n   {  atomic_four<RecBase>* afun =\n         reinterpret_cast< atomic_four<RecBase>* >(v_ptr);\n      // rev_depend does not have a wrapper that drops back to\n      // deprecated version of this function.\n      bool ok = afun->rev_depend(call_id, ident_zero_x, depend_x, depend_y);\n      if( ! ok ) afun->rev_depend(call_id, depend_x, depend_y);\n   }\n# endif\n}\n\n\n} } } // END_CPAPD_LOCAL_SWEEP_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sweep/dynamic.hpp",
    "content": "# ifndef CPPAD_LOCAL_SWEEP_DYNAMIC_HPP\n# define CPPAD_LOCAL_SWEEP_DYNAMIC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/play/atom_op_info.hpp>\n\n// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE\nnamespace CppAD { namespace local { namespace sweep {\n/*!\n\\file sweep/dynamic.hpp\nUnder Construction\n*/\n\n/*!\n\\def CPPAD_DYNAMIC_TRACE\nThis value is either zero or one.\nZero is the normal operational value.\nIf it is one, a trace for each dynamic parameter is computation is printed.\nSometimes it is useful to trace f.new_dynamic with the same\ndynamic parameter values as during the recording\n(to debug the recording process).\n*/\n# define CPPAD_DYNAMIC_TRACE 0\n\n/*!\nCompute dynamic parameters.\n\n\\tparam Base\nThe type of the parameters.\n\n\\tparam BaseVector\nis a simple vector class with elements of type Base.\n\n\\param ind_dynamic\nnew value for the independent dynamic parameter vector.\n\n\\param par_all\nis the vector of all the parameters.\nThe constant parameters are inputs and the dynamic parameters are outputs.\n\n\\param par_is_dyn\nis a vector with the same length as par_vec.\nThe i-th parameter is dynamic if and only if par_is_dyn[i] is true.\n\n\\param dyn2par_index\nis a vector with length equal to the number of dynamic parameters.\nThe element dyn2par_index[j] is the index in par_all corresponding\nto the j-th dynamic parameter.\nNote that if par_is_dyn[i] is false, the i-th parameter does not\nappear in this vector.\n\n\\param dyn_par_op\nis a vector with length equal to the number of dynamic parameters.\nThe element dyn_par_op_[j] is the operator for the j-th dynamic parameter.\nNote that if par_is_dyn[i] is false, the i-th parameter does not\nhave a parameter in this list.\n\n\\param dyn_par_arg\nis a vector containing the arguments for the dynamic parameters.\nThe first argument for the j-th dynamic parameter is dyn_par_arg[k]\nwhere\n\\code\n   k = NumArg( dyn_par_op[0] ) + ... + NumArg( dyn_par_op[j-1] )\n\\endcode\nThe arguments for each dynamic parameter have index value\nlower than the index value for the parameter.\n\n\\param not_used_rec_base\nSpecifies RecBase for this call.\n*/\n\ntemplate <class RecBase>\nRecBase discrete_eval(size_t index, const RecBase& x, const RecBase& not_used)\n{  return discrete<RecBase>::eval(index, x); }\ntemplate <class RecBase>\nAD<RecBase> discrete_eval(\n   size_t index, const AD<RecBase>& ax, const RecBase& not_used\n)\n{  return discrete<RecBase>::ad_eval(index, ax); }\n\n\n\ntemplate <class Base, class BaseVector, class RecBase>\nvoid dynamic(\n   pod_vector_maybe<Base>&       par_all            ,\n   const BaseVector&             ind_dynamic        ,\n   const pod_vector<bool>&       par_is_dyn         ,\n   const pod_vector<addr_t>&     dyn2par_index      ,\n   const pod_vector<opcode_t>&   dyn_par_op         ,\n   const pod_vector<addr_t>&     dyn_par_arg        ,\n   const RecBase&                not_used_rec_base  )\n{\n   // number of dynamic parameters\n   size_t num_dynamic_par = dyn2par_index.size();\n\n   // vectors used in call to atomic functions\n   vector<ad_type_enum> type_x;\n   vector<Base>         taylor_x, taylor_y;\n   vector<bool>         select_y;\n# ifndef NDEBUG\n   for(size_t j = 0; j < ind_dynamic.size(); ++j)\n      CPPAD_ASSERT_UNKNOWN(\n         par_is_dyn[j+1] && op_code_dyn( dyn_par_op[j] ) == ind_dyn\n   );\n# endif\n# if CPPAD_DYNAMIC_TRACE\n   const char* cond_exp_name[] = {\n      \"CondExpLt\",\n      \"CondExpLe\",\n      \"CondExpEq\",\n      \"CondExpGe\",\n      \"CondExpGt\",\n      \"CondExpNe\"\n   };\n   std::cout\n   << std::endl\n   << std::setw(10) << std::left << \"index\"\n   << std::setw(10) << std::left << \"old\"\n   << std::setw(10) << std::left << \"new\"\n   << std::setw(11) << std::left << \"op\"\n   << std::setw(26) << std::right << \"dynamic i=, constant v=\"\n   << std::endl;\n# endif\n   // used to hold the first two parameter arguments\n   const Base* par[2];\n   for(size_t j = 0; j < 2; ++j)\n      par[j] = nullptr;\n   //\n   // Initialize index in dyn_par_arg\n   size_t i_arg = 0;\n   //\n   // Loop throubh the dynamic parameters\n   size_t i_dyn = 0;\n   while(i_dyn < num_dynamic_par)\n   {  // number of dynamic parameters created by this operator\n      size_t n_dyn = 1;\n      //\n      // parameter index for this dynamic parameter\n      size_t i_par = size_t( dyn2par_index[i_dyn] );\n      //\n# if CPPAD_DYNAMIC_TRACE\n      Base old_value = par_all[i_par];\n# endif\n      //\n      // operator for this dynamic parameter\n      op_code_dyn op = op_code_dyn( dyn_par_op[i_dyn] );\n      //\n      // number of arguments for this operator\n      size_t n_arg       = num_arg_dyn(op);\n      //\n      // for unary or binary operators\n      bool unary_or_binary = true;\n      unary_or_binary &= op != atom_dyn;\n      unary_or_binary &= op != cond_exp_dyn;\n      unary_or_binary &= op != dis_dyn;\n      unary_or_binary &= op != ind_dyn;\n      unary_or_binary &= op != result_dyn;\n      if( unary_or_binary )\n      {  CPPAD_ASSERT_UNKNOWN( n_arg == 1 || n_arg == 2 );\n           for(size_t j = 0; j < n_arg; ++j)\n            par[j] = & par_all[ dyn_par_arg[i_arg + j] ];\n      }\n      //\n      switch(op)\n      {\n         // ---------------------------------------------------------------\n         // standard_math_98\n         // acos\n         case acos_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = acos( *par[0] );\n         break;\n\n         // asin\n         case asin_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = asin( *par[0] );\n         break;\n\n         // atan\n         case atan_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = atan( *par[0] );\n         break;\n\n         // cos\n         case cos_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = cos( *par[0] );\n         break;\n\n         // cosh\n         case cosh_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = cosh( *par[0] );\n         break;\n\n         // ind\n         case ind_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 0 );\n         CPPAD_ASSERT_UNKNOWN( i_par == i_dyn + 1 );\n         par_all[i_par] = ind_dynamic[i_dyn];\n         break;\n\n         // exp\n         case exp_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = exp( *par[0] );\n         break;\n\n         // fabs\n         case fabs_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = fabs( *par[0] );\n         break;\n\n         // log\n         case log_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = log( *par[0] );\n         break;\n\n         // sin\n         case sin_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = sin( *par[0] );\n         break;\n\n         // sinh\n         case sinh_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = sinh( *par[0] );\n         break;\n\n         // sqrt\n         case sqrt_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = sqrt( *par[0] );\n         break;\n\n         // tan\n         case tan_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = tan( *par[0] );\n         break;\n\n         // tanh\n         case tanh_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = tanh( *par[0] );\n         break;\n\n         // ---------------------------------------------------------------\n         // asinh\n         case asinh_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = asinh( *par[0] );\n         break;\n\n         // acosh\n         case acosh_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = acosh( *par[0] );\n         break;\n\n         // atanh\n         case atanh_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = atanh( *par[0] );\n         break;\n\n         // expm1\n         case expm1_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = expm1( *par[0] );\n         break;\n\n         // erf\n         case erf_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = erf( *par[0] );\n         break;\n\n         // erfc\n         case erfc_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = erfc( *par[0] );\n         break;\n\n         // log1p\n         case log1p_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = log1p( *par[0] );\n         break;\n         // ---------------------------------------------------------------\n         // abs\n         case abs_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = fabs( *par[0] );\n         break;\n\n         // add\n         case add_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 2 );\n         par_all[i_par] = *par[0] + *par[1];\n         break;\n\n         // div\n         case div_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 2 );\n         par_all[i_par] = *par[0] / *par[1];\n         break;\n\n         // mul\n         case mul_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 2 );\n         par_all[i_par] = *par[0] * *par[1];\n         break;\n\n         // neg\n         case neg_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = - *par[0];\n         break;\n\n         // pow\n         case pow_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 2 );\n         par_all[i_par] = pow( *par[0], *par[1] );\n         break;\n\n         // sign\n         case sign_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         par_all[i_par] = sign( *par[0] );\n         break;\n\n         // sub\n         case sub_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 2 );\n         par_all[i_par] = *par[0] - *par[1];\n         break;\n\n         // zmul\n         case zmul_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 2 );\n         par_all[i_par] = azmul( *par[0],  *par[1] );\n         break;\n\n         // ---------------------------------------------------------------\n         // discrete(index, argument)\n         case dis_dyn:\n         par_all[i_par] = discrete_eval(\n               size_t(      dyn_par_arg[i_arg + 0] ) , // index\n               par_all[ dyn_par_arg[i_arg + 1] ] , // argument\n               RecBase(0)                              // not_used\n         );\n# if CPPAD_DYNAMIC_TRACE\n         std::cout\n         << std::setw(10) << std::left << i_par\n         << std::setw(10) << std::left << old_value\n         << std::setw(10) << std::left << par_all[i_par]\n         << \"=\"\n         << std::setw(10) << std::right << op_name_dyn(op)\n         << \"(\"\n         << std::setw(12) << std::right <<\n            discrete<Base>::name( size_t( dyn_par_arg[i_arg + 0] ) );\n         if( par_is_dyn[ dyn_par_arg[i_arg + 1] ] )\n         {  std::cout << \", i=\" << std::setw(10) << std::right\n            << dyn_par_arg[i_arg + 1];\n         }\n         else\n         {  std::cout << \", v=\" << std::setw(10) << std::right\n            << par_all[ dyn_par_arg[i_arg + 1] ];\n         }\n         std::cout << \")\" << std::endl;\n# endif\n         break;\n\n         // ---------------------------------------------------------------\n         // cond_exp(cop, left, right, if_true, if_false)\n         // (not yet implemented)\n         case cond_exp_dyn:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 5 );\n         par_all[i_par] = CondExpOp(\n            CompareOp(   dyn_par_arg[i_arg + 0] ) , // cop\n            par_all[ dyn_par_arg[i_arg + 1] ] , // left\n            par_all[ dyn_par_arg[i_arg + 2] ] , // right\n            par_all[ dyn_par_arg[i_arg + 3] ] , // if_true\n            par_all[ dyn_par_arg[i_arg + 4] ]   // if_false\n         );\n# if CPPAD_DYNAMIC_TRACE\n         std::cout\n         << std::setw(10) << std::left << i_par\n         << std::setw(10) << std::left << old_value\n         << std::setw(10) << std::left << par_all[i_par]\n         << \"=\"\n         << std::setw(10) << std::right\n         << cond_exp_name[ dyn_par_arg[i_arg + 0] ]\n         << \"(\";\n         for(size_t i = 1; i < 5; ++i)\n         {  if( par_is_dyn[ dyn_par_arg[i_arg + i] ] )\n            {  std::cout << \"i=\" << std::setw(10) << std::right\n               << dyn_par_arg[i_arg + i];\n            }\n            else\n            {  std::cout << \"v=\" << std::setw(10) << std::right\n               << par_all[ dyn_par_arg[i_arg + i] ];\n            }\n            if( i < 4 )\n               std::cout << \",\";\n         }\n         std::cout << \")\" << std::endl;\n# endif\n         break;\n         // ---------------------------------------------------------------\n         // atomic function results\n         case result_dyn:\n         break;\n\n         // atomic function call\n         case atom_dyn:\n         {  size_t atom_index = size_t( dyn_par_arg[i_arg + 0] );\n            size_t call_id    = size_t( dyn_par_arg[i_arg + 1] );\n            size_t n          = size_t( dyn_par_arg[i_arg + 2] );\n            size_t m          = size_t( dyn_par_arg[i_arg + 3] );\n            n_dyn             = size_t( dyn_par_arg[i_arg + 4] );\n            n_arg             = 6 + n + m;\n            CPPAD_ASSERT_UNKNOWN(\n               size_t( dyn_par_arg[i_arg + 5 + n + m] ) == n_arg\n            );\n            //\n            size_t need_y    = size_t(dynamic_enum);\n            size_t order_low = 0;\n            size_t order_up  = 0;\n            type_x.resize(n);\n            taylor_x.resize(n);\n            taylor_y.resize(m);\n            select_y.resize(m);\n            //\n            // taylor_x, type_x\n            for(size_t j = 0; j < n; ++j)\n            {  addr_t arg_j = dyn_par_arg[i_arg + 5 + j];\n               taylor_x[j]   = par_all[ arg_j ];\n               if( arg_j == 0 )\n                  type_x[j] = variable_enum;\n               else if ( par_is_dyn[arg_j] )\n                  type_x[j] = dynamic_enum;\n               else\n                  type_x[j] = constant_enum;\n            }\n            // select_y\n            for(size_t i = 0; i < m; ++i)\n            {  i_par = size_t( dyn_par_arg[i_arg + 5 + n + i] );\n               select_y[i] = par_is_dyn[i_par];\n            }\n            call_atomic_forward<Base, RecBase>(\n               taylor_x,\n               type_x,\n               need_y,\n               select_y,\n               order_low,\n               order_up,\n               atom_index,\n               call_id,\n               taylor_x,\n               taylor_y\n            );\n# if CPPAD_DYNAMIC_TRACE\n            // get the name of this atomic function\n            bool         set_null = false;\n            size_t       type     = 0;          // set to avoid warning\n            std::string name;\n            void*        v_ptr    = nullptr; // set to avoid warning\n            atomic_index<RecBase>(\n               set_null, atom_index, type, &name, v_ptr\n            );\n            std::cout << \"atom_dyn \" << name << \" arguments\\n\";\n            for(size_t j = 0; j < n; ++j)\n            {  std::cout << \"index = \" << j\n               << \", value = \" << taylor_x[j] << std::endl;\n            }\n            std::cout << \"atom_dyn \" << name << \" results\\n\";\n# endif\n# ifndef NDEBUG\n            size_t count_dyn = 0;\n# endif\n            for(size_t i = 0; i < m; ++i)\n            {  i_par = size_t( dyn_par_arg[i_arg + 5 + n + i] );\n               if( par_is_dyn[i_par] )\n               {  CPPAD_ASSERT_UNKNOWN( i_par != 0 );\n                  par_all[i_par] = taylor_y[i];\n# ifndef NDEBUG\n                  ++count_dyn;\n# endif\n# if CPPAD_DYNAMIC_TRACE\n                  std::cout\n                  << std::setw(10) << std::left << i_par\n                  << std::setw(10) << std::left << old_value\n                  << std::setw(10) << std::left << par_all[i_par]\n                  << \"= \" << name << \"_\" << i << std::endl;\n# endif\n               }\n            }\n            CPPAD_ASSERT_UNKNOWN( count_dyn == n_dyn );\n# if CPPAD_DYNAMIC_TRACE\n            std::cout << \"end atomic dynamic parameter results\\n\";\n# endif\n         }\n         break;\n\n         // ---------------------------------------------------------------\n         default:\n         std::cerr << \"op_code_dyn = \" << op_name_dyn(op) << std::endl;\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n      }\n# if CPPAD_DYNAMIC_TRACE\n      if(\n         (op != cond_exp_dyn) &\n         (op != dis_dyn )     &\n         (op != atom_dyn )    &\n         (op != result_dyn )  )\n      {\n         std::cout\n         << std::setw(10) << std::left << i_par\n         << std::setw(10) << std::left << old_value\n         << std::setw(10) << std::left << par_all[i_par]\n         << \"=\"\n         << std::setw(10) << std::right << op_name_dyn(op)\n         << \"(\";\n         if( 0 < n_arg )\n         {  if( par_is_dyn[ dyn_par_arg[i_arg + 0] ] )\n            {  std::cout << \"i=\" << std::setw(10) << std::right\n               << dyn_par_arg[i_arg + 0];\n            }\n            else\n            {  std::cout << \"v=\" << std::setw(10) << std::right\n               << par_all[ dyn_par_arg[i_arg + 0] ];\n            }\n         }\n         if( 1 < n_arg )\n         {  if( par_is_dyn[ dyn_par_arg[i_arg + 1] ] )\n            {  std::cout << \", i=\" << std::setw(10) << std::right\n               << dyn_par_arg[i_arg + 1];\n            }\n            else\n            {  std::cout << \", v=\" << std::setw(10) << std::right\n               << par_all[ dyn_par_arg[i_arg + 1] ];\n            }\n         }\n         std::cout << \")\" << std::endl;\n      }\n# endif\n      i_arg += n_arg;\n      i_dyn += n_dyn;\n   }\n   CPPAD_ASSERT_UNKNOWN( i_arg == dyn_par_arg.size() )\n   return;\n}\n\n// preprocessor symbols that are local to this file\n# undef CPPAD_DYNAMIC_TRACE\n\n} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sweep/for_hes.hpp",
    "content": "# ifndef CPPAD_LOCAL_SWEEP_FOR_HES_HPP\n# define CPPAD_LOCAL_SWEEP_FOR_HES_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/play/atom_op_info.hpp>\n# include <cppad/local/var_op/load_op.hpp>\n# include <cppad/local/var_op/store_op.hpp>\n# include <cppad/local/var_op/csum_op.hpp>\n\n/*\n{xrst_begin local_sweep_for_hes dev}\n{xrst_spell\n   inv\n}\n\nForward Mode Hessian Sparsity Patterns\n######################################\n\nSyntax\n******\n| ``local::sweep::for_hes`` (\n| |tab| *play*               ,\n| |tab| *n*                  ,\n| |tab| *num_var*        ,\n| |tab| *select_domain*      ,\n| |tab| *rev_jac_sparse*     ,\n| |tab| *for_hes_sparse*     ,\n| |tab| ``not_used_rec_base``\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN PROTOTYPE\n   // END PROTOTYPE\n}\n\nPurpose\n*******\nGiven the forward Jacobian sparsity pattern for all the variables,\nand the reverse Jacobian sparsity pattern for the dependent variables,\n``for_hes`` computes the Hessian sparsity pattern for all the independent\nvariables.\n\nCPPAD_FOR_HES_TRACE\n*******************\nThis value is either zero or one.  Zero is the normal operational value.\nIf it is one, a trace of Jacobian and Hessian sparsity result for every\noperation for every ``for_hes`` sweep is printed.\nThe sparsity patterns are printed as binary numbers with 1 (0) meaning that\nthe corresponding index is (is not) in the set.\n{xrst_code hpp} */\n# define CPPAD_FOR_HES_TRACE 0\n/* {xrst_code}\n\nBase\n****\nThe operation sequence in *play* was recorded using\n``AD`` < *Base* > .\n\nRecBase\n*******\nIs the base type when this function was recorded.\nThis is different from *Base* if\nthis function object was created by :ref:`base2ad-name` .\n\nSetVector\n*********\nThis is a :ref:`SetVector-name` type.\n\nplay\n****\nThe information stored in play\nis a recording of the operations corresponding to a function\n:math:`F : \\B{R}^n \\rightarrow \\B{R}^m`\nwhere *m* is the number of dependent variables.\n\nn\n*\nis the number of independent variables in the tape.\n\nnum_var\n*******\nis the total number of variables in the tape; i.e.,\n*play* ``->num_var`` () .\nThis is also the number of sets in all the sparsity patterns.\n\nselect_domain\n*************\nis a vector with size *n* that specifies\nwhich components of the domain to include in the Hessian sparsity pattern.\nFor *j* = 0, ..., *n* ``-1`` , the *j*-th independent variable\nwill be included if and only if *select_domain* [ *j* ] is true.\nThis assumes that the order of the independent variables is the same\nas the order of the InvOp operators.\n\nrev_jac_sparse\n**************\nIs a sparsity pattern with size *num_var* by one.\nFor *i* =1, ..., *num_var* ``-1`` ,\nthe if the scalar valued function we are computing the Hessian sparsity for\nhas a non-zero derivative w.r.t. variable with index *i* ,\nthe set with index *i* has the element zero.\nOtherwise it has no elements.\n\nfor_hes_sparse\n**************\nThis is a sparsity pattern with *n* + 1 + *num_var* sets\nand end value *n* + 1 .\nOn input, all of the sets are empty.\nOn output, it contains the two sparsity patterns described below:\n\nHessian Sparsity\n================\nFor *j* equal 1 to *n* ,\nif *i* is in set with index *j* ,\nthe Hessian may have a non-zero partial with respect to the\nindependent variables with indices ( *i* - 1, *j* - 1 ) .\nNote that the index zero is not used because it corresponds to the\nphantom variable on the tape.\n\nJacobian Sparsity\n=================\nFor *k* equal 1 to *num_var* - 1 ,\nif *i* is in the set with index *n* + 1 + *k* ,\nthe variable with index *k* may have a non-zero partial with resect to the\nindependent variable with index *i* - 1 .\n\nMethod\n======\nFor *k* equal 1 to *num_var* - 1,\nthe Jacobian sparsity pattern for variable with index *k* is computed using\nthe previous Jacobian sparsity patterns.\nThe Hessian sparsity pattern is updated using linear and non-linear\ninteractions for the variable with index *k* and the previous Jacobian\nsparsity patterns.\n\nnot_used_rec_base\n*****************\nThis argument is only used to specify the type *RecBase* for this call.\n\n{xrst_end local_sweep_for_hes}\n*/\n\n// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE\nnamespace CppAD { namespace local { namespace sweep {\n\n// BEGIN PROTOTYPE\ntemplate <class Base, class SetVector, class RecBase>\nvoid for_hes(\n   const local::player<Base>* play                ,\n   size_t                     n                   ,\n   size_t                     num_var             ,\n   const pod_vector<bool>&    select_domain       ,\n   const SetVector&           rev_jac_sparse      ,\n   SetVector&                 for_hes_sparse      ,\n   const RecBase&             not_used_rec_base   )\n// END PROTOTYPE\n{\n   // length of the parameter vector (used by CppAD assert macros)\n# ifndef NDEBUG\n   const size_t num_par = play->num_par_all();\n# endif\n\n   // check arguments\n   size_t np1 = n+1;\n   CPPAD_ASSERT_UNKNOWN( select_domain.size()   == n );\n   CPPAD_ASSERT_UNKNOWN( play->num_var()        == num_var );\n   CPPAD_ASSERT_UNKNOWN( rev_jac_sparse.n_set() == num_var );\n   CPPAD_ASSERT_UNKNOWN( for_hes_sparse.n_set() == np1+num_var );\n   //\n   CPPAD_ASSERT_UNKNOWN( rev_jac_sparse.end()   == 1   );\n   CPPAD_ASSERT_UNKNOWN( for_hes_sparse.end()   == np1 );\n   //\n   CPPAD_ASSERT_UNKNOWN( num_var > 0 );\n   //\n   // vecad_sparsity: forward Jacobian sparsity pattern for each VecAD object.\n   // vecad_ind: maps the VecAD index at beginning of the VecAD object\n   //            to the index for the corresponding set in vecad_sparsity.\n   size_t num_vecad_ind   = play->num_var_vec_ind();\n   size_t num_vecad_vec   = play->num_var_vecad();\n   SetVector vecad_sparsity;\n   pod_vector<size_t> vecad_ind;\n   if( num_vecad_vec > 0 )\n   {  size_t length;\n      vecad_sparsity.resize(num_vecad_vec, np1);\n      vecad_ind.extend(num_vecad_ind);\n      size_t j  = 0;\n      for(size_t i = 0; i < num_vecad_vec; i++)\n      {  // length of this VecAD\n         length   = play->GetVecInd(j);\n         // set vecad_ind to proper index for this VecAD\n         vecad_ind[j] = i;\n         // make all other values for this vector invalid\n         for(size_t k = 1; k <= length; k++)\n            vecad_ind[j+k] = num_vecad_vec;\n         // start of next VecAD\n         j       += length + 1;\n      }\n      CPPAD_ASSERT_UNKNOWN( j == play->num_var_vec_ind() );\n   }\n   // ------------------------------------------------------------------------\n   // work space used by atomic functions\n   var_op::atomic_op_work<Base> atom_work;\n   //\n   //\n   // pointer to the beginning of the parameter vector\n   // (used by atomic functions)\n   CPPAD_ASSERT_UNKNOWN( num_par > 0 )\n   const Base* parameter = play->par_ptr();\n   //\n   // skip the BeginOp at the beginning of the recording\n   play::const_sequential_iterator itr = play->begin();\n   // op_info\n   op_code_var   op;\n   size_t        i_var;\n   const addr_t* arg;\n   itr.op_info(op, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op == BeginOp );\n# if CPPAD_FOR_HES_TRACE\n   std::cout << std::endl;\n   bool atom_trace = true;\n# else\n   bool atom_trace = false;\n# endif\n   bool   more_operators = true;\n   size_t count_independent = 0;\n   while(more_operators)\n   {  bool linear[3];\n\n      // next op\n      (++itr).op_info(op, arg, i_var);\n\n      // does the Hessian in question have a non-zero derivative\n      // with respect to this variable\n      bool include = NumRes(op) > 0;\n      if( include )\n         include = rev_jac_sparse.is_element(i_var, 0);\n      switch( op )\n      {\n         // include\n         // operators that must always be included\n         case EndOp:\n         case CSkipOp:\n         case AFunOp:\n         case FunapOp:\n         case FunavOp:\n         case FunrpOp:\n         case FunrvOp:\n         case StppOp:\n         case StpvOp:\n         case StvpOp:\n         case StvvOp:\n         include = true;\n         break;\n\n         // count_independent\n         case InvOp:\n         if( ! include )\n            ++count_independent;\n         break;\n\n         // itr\n         case CSumOp:\n         if( ! include )\n            itr.correct_before_increment();\n         break;\n\n         // default\n         default:\n         break;\n      }\n      //\n      if( include ) switch( op )\n      {  // operators that should not occur\n         // case BeginOp\n\n         // operators that do not affect Jacobian or Hessian\n         // and where with a fixed number of arguments and results\n         case CExpOp:\n         case DisOp:\n         case ParOp:\n         case PriOp:\n         case SignOp:\n         break;\n         // -------------------------------------------------\n\n         // independent variable operator: set J(i_var) = { i_var }\n         case InvOp:\n         CPPAD_ASSERT_UNKNOWN( for_hes_sparse.number_elements(i_var) == 0 );\n         if( select_domain[count_independent] )\n         {  // Not using post_element because only adding one element\n            // per set\n            for_hes_sparse.add_element(np1 + i_var, i_var);\n         }\n         ++count_independent;\n         break;\n\n         // -------------------------------------------------\n         // linear operators where arg[0] is the only variable\n         case AbsOp:\n         case DivvpOp:\n         case SubvpOp:\n         case ZmulvpOp:\n         linear[0] = true;\n         var_op::one_var_for_hes(\n            np1, num_var, i_var, size_t(arg[0]), linear, for_hes_sparse\n         );\n         break;\n\n         // -------------------------------------------------\n         // linear operators where arg[1] is the only variable\n         case AddpvOp:\n         case MulpvOp:\n         case SubpvOp:\n         linear[0] = true;\n         var_op::one_var_for_hes(\n            np1, num_var, i_var, size_t(arg[1]), linear, for_hes_sparse\n         );\n         break;\n\n         // -------------------------------------------------\n         // linear operators where arg[0] and arg[1] are variables\n         case AddvvOp:\n         case SubvvOp:\n         linear[0] = true;\n         linear[1] = true;\n         linear[2] = true;\n         var_op::two_var_for_hes(\n            np1, num_var, i_var, arg, linear, for_hes_sparse\n         );\n         break;\n\n         // ------------------------------------------------------\n         // VecAD load operators\n         case LdvOp:\n         case LdpOp:\n         var_op::load_for_hes(\n            op, arg, num_vecad_ind, i_var, n,\n            vecad_ind, vecad_sparsity, for_hes_sparse\n         );\n         break;\n         //\n         // VecAD store operators\n         case StppOp:\n         case StpvOp:\n         case StvpOp:\n         case StvvOp:\n         var_op::store_for_hes(op,\n            arg, num_vecad_ind, n,\n            vecad_ind, vecad_sparsity, for_hes_sparse\n         );\n         break;\n\n         // ------------------------------------------------------\n         // nonlinear operators where arg[0] is the only variable\n         case AcosOp:\n         case AsinOp:\n         case AtanOp:\n         case CosOp:\n         case CoshOp:\n         case ExpOp:\n         case LogOp:\n         case NegOp:\n         case SinOp:\n         case SinhOp:\n         case SqrtOp:\n         case TanOp:\n         case TanhOp:\n         case AcoshOp:\n         case AsinhOp:\n         case AtanhOp:\n         case Expm1Op:\n         case Log1pOp:\n         case ErfOp:\n         case ErfcOp:\n         CPPAD_ASSERT_UNKNOWN( 0 < NumArg(op) )\n         linear[0] = false;\n         var_op::one_var_for_hes(\n               np1, num_var, i_var, size_t(arg[0]), linear, for_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         case CSkipOp:\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case CSumOp:\n         var_op::csum_for_hes(arg, i_var, n, for_hes_sparse);\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case DivvvOp:\n         linear[0] = true;\n         linear[1] = false;\n         linear[2] = false;\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1)\n         var_op::two_var_for_hes(\n            np1, num_var, i_var, arg, linear, for_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n         // nonlinear operators where arg[1] is the only variable\n         case DivpvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1)\n         linear[0] = false;\n         var_op::one_var_for_hes(\n               np1, num_var, i_var, size_t(arg[1]), linear, for_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         case EndOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 0);\n         more_operators = false;\n         break;\n\n         // -------------------------------------------------\n         // logical comparison operators\n         case EqppOp:\n         case EqpvOp:\n         case EqvvOp:\n         case LtppOp:\n         case LtpvOp:\n         case LtvpOp:\n         case LtvvOp:\n         case LeppOp:\n         case LepvOp:\n         case LevpOp:\n         case LevvOp:\n         case NepvOp:\n         case NeppOp:\n         case NevvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 0);\n         break;\n         // -------------------------------------------------\n\n         case MulvvOp:\n         case ZmulvvOp:\n         linear[0] = true;\n         linear[1] = true;\n         linear[2] = false;\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1)\n         var_op::two_var_for_hes(\n            np1, num_var, i_var, arg, linear, for_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         case PowpvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 3)\n         linear[0] = false;\n         var_op::one_var_for_hes(\n               np1, num_var, i_var, size_t(arg[1]), linear, for_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         case PowvpOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1)\n         linear[0] = false;\n         var_op::one_var_for_hes(\n               np1, num_var, i_var, size_t(arg[0]), linear, for_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         case PowvvOp:\n         linear[0] = false;\n         linear[1] = false;\n         linear[2] = false;\n         CPPAD_ASSERT_NARG_NRES(op, 2, 3)\n         var_op::two_var_for_hes(\n            np1, num_var, i_var, arg, linear, for_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         case AFunOp:\n         var_op::atomic_for_hes<SetVector, Base, RecBase>(\n            itr,\n            play,\n            parameter,\n            atom_trace,\n            atom_work,\n            np1,\n            rev_jac_sparse,\n            for_hes_sparse\n         );\n         break;\n\n         case FunapOp:\n         case FunavOp:\n         case FunrpOp:\n         case FunrvOp:\n         CPPAD_ASSERT_UNKNOWN( false );\n         break;\n         // -------------------------------------------------\n\n         default:\n         CPPAD_ASSERT_UNKNOWN(0);\n      }\n# if CPPAD_FOR_HES_TRACE\n      if( op != AFunOp )\n      {  //\n         printOp<Base, RecBase>(\n            std::cout,\n            play,\n            itr.op_index(),\n            i_var,\n            op,\n            arg\n         );\n         //\n         if( NumRes(op) > 0 )\n         {  typedef typename SetVector::const_iterator itr_sparse_t;\n            CPPAD_ASSERT_UNKNOWN( np1 == for_hes_sparse.end() );\n            CppAD::vectorBool jac_row(np1);\n            for(size_t j = 0; j < np1; ++j)\n               jac_row[j] = false;\n            itr_sparse_t itr_jac(for_hes_sparse, np1 + i_var);\n            {  size_t j = *itr_jac;\n               while( j < np1 )\n               {  jac_row[j] = true;\n                  j = *(++itr_jac);\n               }\n            }\n            printOpResult(\n               std::cout,\n               1,\n               &jac_row,\n               0,\n               (CppAD::vectorBool *) nullptr\n            );\n            std::cout << std::endl;\n            //\n            CppAD::vector< CppAD::vectorBool > hes(np1);\n            for(size_t i = 0; i < np1; ++i)\n            {  hes[i].resize(np1);\n               for(size_t j = 0; j < np1; ++j)\n                  hes[i][j] = false;\n               itr_sparse_t itr_hes(for_hes_sparse, i);\n               size_t j = *itr_hes;\n               while( j < np1 )\n               {  hes[i][j] = true;\n                  j = *(++itr_hes);\n               }\n            }\n            printOpResult(\n               std::cout,\n               np1,\n               hes.data(),\n               0,\n               (CppAD::vectorBool *) nullptr\n            );\n            std::cout << std::endl;\n         }\n      }\n   }\n   std::cout << std::endl;\n# else\n   }\n# endif\n\n   return;\n}\n} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE\n\n// preprocessor symbols that are local to this file\n# undef CPPAD_FOR_HES_TRACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sweep/for_jac.hpp",
    "content": "# ifndef CPPAD_LOCAL_SWEEP_FOR_JAC_HPP\n# define CPPAD_LOCAL_SWEEP_FOR_JAC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <set>\n# include <cppad/local/pod_vector.hpp>\n# include <cppad/local/play/atom_op_info.hpp>\n# include <cppad/local/sweep/call_atomic.hpp>\n\n// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE\nnamespace CppAD { namespace local { namespace sweep {\n/*!\n\\file sweep/for_jac.hpp\nCompute Forward mode Jacobian sparsity patterns.\n*/\n\n/*!\n\\def CPPAD_FOR_JAC_TRACE\nThis value is either zero or one.\nZero is the normal operational value.\nIf it is one, a trace of every for_jac_sweep computation is printed.\n*/\n# define CPPAD_FOR_JAC_TRACE 0\n\n/*!\nGiven the sparsity pattern for the independent variables,\nForJacSweep computes the sparsity pattern for all the other variables.\n\n\\tparam Base\nthis operation sequence was recorded using AD<Base>.\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\\param dependency\nAre the derivatives with respect to left and right of the expression below\nconsidered to be non-zero:\n\\code\n   CondExpRel(left, right, if_true, if_false)\n\\endcode\nThis is used by the optimizer to obtain the correct dependency relations.\n\n\\param n\nis the number of independent variables on the tape.\n\n\\param num_var\nis the total number of variables on the tape; i.e.,\n play->num_var().\n\n\\param play\nThe information stored in play\nis a recording of the operations corresponding to a function\n\\f[\n   F : {\\bf R}^n \\rightarrow {\\bf R}^m\n\\f]\nwhere \\f$ n \\f$ is the number of independent variables\nand \\f$ m \\f$ is the number of dependent variables.\n\n\\param var_sparsity\n\\b Input: For j = 1 , ... , n,\nthe sparsity pattern for the independent variable with index (j-1)\ncorresponds to the set with index j in var_sparsity.\n\\n\n\\n\n\\b Output: For i = n + 1 , ... , num_var - 1,\nthe sparsity pattern for the variable with index i on the tape\ncorresponds to the set with index i in var_sparsity.\n\n\\par Checked Assertions:\n\\li num_var == var_sparsity.n_set()\n\\li num_var == play->num_var()\n\n\\param not_used_rec_base\nSpecifies RecBase for this call.\n*/\n\ntemplate <class Vector_set, class Base, class RecBase>\nvoid for_jac(\n   const local::player<Base>* play,\n   bool                       dependency        ,\n   size_t                     n                 ,\n   size_t                     num_var           ,\n   Vector_set&                var_sparsity,\n   const RecBase&             not_used_rec_base\n)\n{\n   size_t            i, j, k;\n\n   // check num_var argument\n   CPPAD_ASSERT_UNKNOWN( play->num_var()      == num_var );\n   CPPAD_ASSERT_UNKNOWN( var_sparsity.n_set() == num_var );\n\n   // length of the parameter vector (used by CppAD assert macros)\n   const size_t num_par = play->num_par_all();\n\n   // cum_sparsity accumulates sparsity pattern a cumulative sum\n   size_t limit = var_sparsity.end();\n\n   // vecad_sparsity contains a sparsity pattern from each VecAD object\n   // to all the other variables.\n   // vecad_ind maps a VecAD index (the beginning of the\n   // VecAD object) to its from index in vecad_sparsity\n   size_t num_vecad_ind   = play->num_var_vec_ind();\n   size_t num_vecad_vec   = play->num_var_vecad();\n   Vector_set  vecad_sparsity;\n   pod_vector<size_t> vecad_ind;\n   if( num_vecad_vec > 0 )\n   {  size_t length;\n      vecad_sparsity.resize(num_vecad_vec, limit);\n      vecad_ind.extend(num_vecad_ind);\n      j             = 0;\n      for(i = 0; i < num_vecad_vec; i++)\n      {  // length of this VecAD\n         length   = play->GetVecInd(j);\n         // set to proper index for this VecAD\n         vecad_ind[j] = i;\n         for(k = 1; k <= length; k++)\n            vecad_ind[j+k] = num_vecad_vec; // invalid index\n         // start of next VecAD\n         j       += length + 1;\n      }\n      CPPAD_ASSERT_UNKNOWN( j == play->num_var_vec_ind() );\n   }\n\n   // work space used by atomic functions\n   var_op::atomic_op_work<Base> atom_work;\n   //\n   //\n   // pointer to the beginning of the parameter vector\n   // (used by atomic functions)\n   CPPAD_ASSERT_UNKNOWN( num_par > 0 )\n   const Base* parameter = play->par_ptr();\n   //\n# if CPPAD_FOR_JAC_TRACE\n   std::cout << std::endl;\n   CppAD::vectorBool z_value(limit);\n   bool atom_trace = true;\n# else\n   bool atom_trace = false;\n# endif\n\n   // skip the BeginOp at the beginning of the recording\n   play::const_sequential_iterator itr = play->begin();\n   // op_info\n   op_code_var op;\n   size_t i_var;\n   const addr_t*   arg;\n   itr.op_info(op, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op == BeginOp );\n   //\n   bool more_operators = true;\n   while(more_operators)\n   {  //\n      // this op\n      (++itr).op_info(op, arg, i_var);\n      //\n      // rest of information depends on the case\n      switch( op )\n      {  //\n         // operators with one primary result and\n         // where the first argument is the only variable\n         case AbsOp:\n         case AcosOp:\n         case AcoshOp:\n         case AsinOp:\n         case AsinhOp:\n         case AtanOp:\n         case AtanhOp:\n         case CosOp:\n         case CoshOp:\n         case DivvpOp:\n         case ErfOp:\n         case ErfcOp:\n         case ExpOp:\n         case Expm1Op:\n         case LogOp:\n         case NegOp:\n         case Log1pOp:\n         case PowvpOp:\n         case SinOp:\n         case SinhOp:\n         case SqrtOp:\n         case SubvpOp:\n         case TanOp:\n         case TanhOp:\n         case ZmulvpOp:\n         CPPAD_ASSERT_UNKNOWN( 0 < NumArg(op) );\n         var_op::one_var_for_jac(\n            i_var, size_t(arg[0]), var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         // operators with one primary result and\n         // where the second argument is the only variable\n         case AddpvOp:\n         case DivpvOp:\n         case MulpvOp:\n         case PowpvOp:\n         case SubpvOp:\n         case ZmulpvOp:\n         CPPAD_ASSERT_UNKNOWN( 1 < NumArg(op) );\n         var_op::one_var_for_jac(\n            i_var, size_t(arg[1]), var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case AddvvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         var_op::two_var_for_jac(\n            i_var, arg, var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case CSkipOp:\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case CSumOp:\n         var_op::csum_for_jac(\n            i_var, arg, var_sparsity\n         );\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case CExpOp:\n         var_op::cexp_for_jac(\n            dependency, i_var, arg, num_par, var_sparsity\n         );\n         break;\n         // --------------------------------------------------\n\n         case DisOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         // derivative is identically zero but dependency is not\n         if( dependency ) var_op::one_var_for_jac(\n            i_var, size_t(arg[1]), var_sparsity\n         );\n         else\n            var_sparsity.clear(i_var);\n         break;\n         // -------------------------------------------------\n\n         case DivvvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         var_op::two_var_for_jac(\n            i_var, arg, var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case EndOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 0);\n         more_operators = false;\n         break;\n         // -------------------------------------------------\n\n         case InvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         // sparsity pattern is already defined\n         break;\n         // -------------------------------------------------\n\n         case LdpOp:\n         case LdvOp:\n         var_op::load_for_jac(\n            op,\n            num_vecad_ind,\n            i_var,\n            arg,\n            dependency,\n            vecad_ind,\n            var_sparsity,\n            vecad_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case EqppOp:\n         case EqpvOp:\n         case EqvvOp:\n         case LtppOp:\n         case LtpvOp:\n         case LtvpOp:\n         case LtvvOp:\n         case LeppOp:\n         case LepvOp:\n         case LevpOp:\n         case LevvOp:\n         case NeppOp:\n         case NepvOp:\n         case NevvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 0);\n         break;\n         // -------------------------------------------------\n         case MulvvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         var_op::two_var_for_jac(\n            i_var, arg, var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case ParOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1);\n         var_sparsity.clear(i_var);\n         break;\n         // -------------------------------------------------\n\n         case PowvvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 3);\n         var_op::two_var_for_jac(\n            i_var, arg, var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case PriOp:\n         CPPAD_ASSERT_NARG_NRES(op, 5, 0);\n         break;\n         // -------------------------------------------------\n\n         case SignOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1);\n         // derivative is identically zero but dependency is not\n         if( dependency ) var_op::one_var_for_jac(\n            i_var, size_t(arg[0]), var_sparsity\n         );\n         else\n            var_sparsity.clear(i_var);\n         break;\n         // -------------------------------------------------\n\n         case StppOp:\n         case StpvOp:\n         case StvpOp:\n         case StvvOp:\n         var_op::store_for_jac(\n            op,\n            num_vecad_ind,\n            arg,\n            dependency,\n            vecad_ind,\n            var_sparsity,\n            vecad_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case SubvvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         var_op::two_var_for_jac(\n            i_var, arg, var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case AFunOp:\n         var_op:: atomic_for_jac<Vector_set, Base, RecBase>(\n            itr,\n            play,\n            parameter,\n            atom_trace,\n            atom_work,\n            dependency,\n            var_sparsity\n         );\n         break;\n\n         case FunapOp:\n         case FunavOp:\n         case FunrpOp:\n         case FunrvOp:\n         CPPAD_ASSERT_UNKNOWN( false );\n         break;\n         // -------------------------------------------------\n\n         case ZmulvvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         var_op::two_var_for_jac(\n            i_var, arg, var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         default:\n         CPPAD_ASSERT_UNKNOWN(0);\n      }\n# if CPPAD_FOR_JAC_TRACE\n      if( op != AFunOp )\n      {  // value for this variable\n         for(j = 0; j < limit; j++)\n            z_value[j] = false;\n         typename Vector_set::const_iterator sparse_itr(var_sparsity, i_var);\n         j = *sparse_itr;\n         while( j < limit )\n         {  z_value[j] = true;\n            j = *(++sparse_itr);\n         }\n         printOp<Base, RecBase>(\n            std::cout,\n            play,\n            itr.op_index(),\n            i_var,\n            op,\n            arg\n         );\n         if( NumRes(op) > 0 ) printOpResult(\n            std::cout,\n            1,\n            &z_value,\n            0,\n            (CppAD::vectorBool *) nullptr\n         );\n         std::cout << std::endl;\n      }\n# endif\n   }\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE\n\n// preprocessor symbols that are local to this file\n# undef CPPAD_FOR_JAC_TRACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sweep/forward0.hpp",
    "content": "# ifndef CPPAD_LOCAL_SWEEP_FORWARD0_HPP\n# define CPPAD_LOCAL_SWEEP_FORWARD0_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/play/atom_op_info.hpp>\n# include <cppad/local/sweep/call_atomic.hpp>\n# include <cppad/local/var_op/compare.hpp>\n\n// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE\nnamespace CppAD { namespace local { namespace sweep {\n/*!\n\\file sweep/forward0.hpp\nCompute zero order forward mode Taylor coefficients.\n*/\n\n/*\n ------------------------------------------------------------------------------\n{xrst_begin sweep_forward0 dev}\n{xrst_spell\n   cskip\n   numvar\n   pri\n}\nCompute Zero Order Forward Mode Taylor Coefficients\n###################################################\n\nSyntax\n******\n| ``forward0`` (\n| |tab| *play* ,\n| |tab| *s_out* ,\n| |tab| *print* ,\n| |tab| *n* ,\n| |tab| *numvar* ,\n| |tab| *J* ,\n| |tab| *taylor* ,\n| |tab| *cskip_op* ,\n| |tab| *load_op2var* ,\n| |tab| *compare_change_count* ,\n| |tab| *compare_change_number* ,\n| |tab| *compare_change_op_index* ,\n| |tab| *not_used_rec_base*\n| )\n\nCPPAD_FORWARD0_TRACE\n********************\nThis value is either zero or one.\nZero is the normal operational value.\nIf it is one, a trace of every zero order forward mode computation is printed.\n{xrst_spell_off}\n{xrst_code hpp} */\n# define CPPAD_FORWARD0_TRACE 0\n/* {xrst_code}\n{xrst_spell_on}\n\nBase\n****\nThe type used during the forward mode computations; i.e., the corresponding\nrecording of operations used the type ``AD`` < *Base* > .\n\ns_out\n*****\nIs the stream where output corresponding to PriOp operations will\nbe written.\n\nprint\n*****\nIf print is false,\nsuppress the output that is otherwise generated by the PriOp instructions.\n\nn\n*\nis the number of independent variables on the tape.\n\nnumvar\n******\nis the total number of variables on the tape.\nThis is also equal to the number of rows in the matrix taylor; i.e.,\n*play* ``->num_var_rec`` () .\n\nplay\n****\nThe information stored in play\nis a recording of the operations corresponding to a function\n\n.. math::\n\n   f : \\B{R}^n \\rightarrow \\B{R}^m\n\nwhere *n* is the number of independent variables and\n*m* is the number of dependent variables.\n\nJ\n*\nIs the number of columns in the coefficient matrix taylor.\nThis must be greater than or equal one.\n\ntaylor\n******\nIs the matrix of Taylor coefficients.\n\nInput\n=====\nFor *i* = 1 , ... , *n* ,\n*taylor* [% *i* % * % *J* % + 0]%\nis the zero order Taylor coefficient for variable with index\n*j* on the tape (these are the independent variables).\n\nOutput\n======\nFor *i* = *n* +1 , ... , *numvar* ``-1`` ,\n*taylor* [% *i* % * % *J* % + 0]%\nis the zero order Taylor coefficient for the variable with\nindex i on the tape.\n\ncskip_op\n********\nIs a vector with size *play* ``->num_op_rec`` () .\nThe input value of the elements does not matter.\nUpon return, if *cskip_op* [ *i* ] is true,\nthe operator index *i* does not affect any of the dependent variable\n(given the value of the independent variables).\n\nload_op2var\n***********\nIs a vector with size *play* ``->num_var_load_rec`` () .\nThe input value of the elements does not matter.\nUpon return, *load_op2var* [ *i* ]\nis the variable index corresponding to the *i*-th variable VecAD load operator.\nNote that even though the VecAD vector is a variable, the load\ncan correspond to an element that is a parameter in which case\n*load_op2var* [ *i* ] is zero.\n\ncompare_change_count\n********************\nIs the compare change count value at which *compare_change_op_index*\nis returned. If it is zero, the comparison changes are not counted.\n\ncompare_change_number\n*********************\nIf *compare_change_count* is zero, this value is set to zero.\nOtherwise, the return value is the number of comparison operations\nthat have a different result from when the information in\n*play* was recorded.\n\ncompare_change_op_index\n***********************\nIf *compare_change_count* is zero, this value is set to zero.\nOtherwise it is the operator index (see forward_next) for the\ncomparison operation that has a different result from when the information in\nplay was recorded.\nThis is not the first comparison that is different,\nbut rather the *compare_change_count* comparison.\n\nnot_used_rec_base\n*****************\nSpecifies *RecBase* for this call.\n\n{xrst_end sweep_forward0}\n*/\n\ntemplate <class Base, class RecBase>\nvoid forward0(\n   const local::player<Base>* play,\n   std::ostream&              s_out,\n   bool                       print,\n   size_t                     n,\n   size_t                     numvar,\n   size_t                     J,\n   Base*                      taylor,\n   bool*                      cskip_op,\n   pod_vector<addr_t>&        load_op2var,\n   size_t                     compare_change_count,\n   size_t&                    compare_change_number,\n   size_t&                    compare_change_op_index,\n   const RecBase&             not_used_rec_base\n)\n{  CPPAD_ASSERT_UNKNOWN( J >= 1 );\n   CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar );\n\n   // use p, q, r so other forward sweeps can use code defined here\n   size_t p = 0;\n   size_t q = 0;\n   size_t r = 1;\n\n   // initialize the comparison operator counter\n   if( p == 0 )\n   {  compare_change_number   = 0;\n      compare_change_op_index = 0;\n   }\n\n   // If this includes a zero calculation, initialize this information\n   pod_vector<bool>   vec_ad2isvar;\n   pod_vector<size_t> vec_ad2index;\n   if( p == 0 )\n   {  size_t i;\n\n      // this includes order zero calculation, initialize vector indices\n      size_t num = play->num_var_vecad_ind_rec();\n      if( num > 0 )\n      {  vec_ad2isvar.extend(num);\n         vec_ad2index.extend(num);\n         for(i = 0; i < num; i++)\n         {  vec_ad2index[i] = play->GetVecInd(i);\n            vec_ad2isvar[i] = false;\n         }\n      }\n      // includes zero order, so initialize conditional skip flags\n      num = play->num_op_rec();\n      for(i = 0; i < num; i++)\n         cskip_op[i] = false;\n   }\n\n   // information used by atomic function operators\n   const pod_vector<bool>& dyn_par_is( play->dyn_par_is() );\n   const size_t need_y    = size_t( variable_enum );\n   const size_t order_low = p;\n   const size_t order_up  = q;\n\n   // vectors used by atomic function operators\n   vector<Base>         atom_par_x;  // argument parameter values\n   vector<ad_type_enum> atom_type_x; // argument type\n   vector<Base>         atom_tx;     // argument vector Taylor coefficients\n   vector<Base>         atom_ty;     // result vector Taylor coefficients\n   vector<size_t>       atom_iy;     // variable indices for result vector\n   vector<bool>         atom_sy;     // select_y for this atomic function\n   //\n   // information defined by atomic function operators\n   size_t atom_index=0, atom_id=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0;\n   enum_atom_state atom_state = start_atom; // proper initialization\n\n   // length of the parameter vector (used by CppAD assert macros)\n   const size_t num_par = play->num_par_rec();\n\n   // pointer to the beginning of the parameter vector\n   CPPAD_ASSERT_UNKNOWN( num_par > 0 )\n   const Base* parameter = play->GetPar();\n\n   // length of the text vector (used by CppAD assert macros)\n   const size_t num_text = play->num_text_rec();\n\n   // pointer to the beginning of the text vector\n   const char* text = nullptr;\n   if( num_text > 0 )\n      text = play->GetTxt(0);\n\n# if CPPAD_FORWARD0_TRACE\n   // flag as to when to trace atomic function values\n   bool atom_trace            = false;\n# endif\n\n   // skip the BeginOp at the beginning of the recording\n   play::const_sequential_iterator itr = play->begin();\n   // op_info\n   op_code_var op;\n   size_t i_var;\n   const addr_t* arg;\n   itr.op_info(op, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op == BeginOp );\n   //\n# if CPPAD_FORWARD0_TRACE\n   std::cout << std::endl;\n# endif\n   bool flag; // a temporary flag to use in switch cases\n   bool more_operators = true;\n   while(more_operators)\n   {\n      // next op\n      (++itr).op_info(op, arg, i_var);\n      CPPAD_ASSERT_UNKNOWN( itr.op_index() < play->num_op_rec() );\n\n      // check if we are skipping this operation\n      while( cskip_op[itr.op_index()] )\n      {  switch(op)\n         {\n            case AFunOp:\n            {  // get information for this atomic function call\n               CPPAD_ASSERT_UNKNOWN( atom_state == start_atom );\n               play::atom_op_info<Base>(\n                  op, arg, atom_index, atom_id, atom_m, atom_n\n               );\n               //\n               // skip to the second AFunOp\n               for(size_t i = 0; i < atom_m + atom_n + 1; ++i)\n                  ++itr;\n# ifndef NDEBUG\n               itr.op_info(op, arg, i_var);\n               CPPAD_ASSERT_UNKNOWN( op == AFunOp );\n# endif\n            }\n            break;\n\n            case CSkipOp:\n            case CSumOp:\n            itr.correct_before_increment();\n            break;\n\n            default:\n            break;\n         }\n         (++itr).op_info(op, arg, i_var);\n      }\n\n      // action to take depends on the case\n      switch( op )\n      {\n         case EqppOp:\n         case EqpvOp:\n         case EqvvOp:\n         case LeppOp:\n         case LepvOp:\n         case LevpOp:\n         case LevvOp:\n         case LtppOp:\n         case LtpvOp:\n         case LtvpOp:\n         case LtvvOp:\n         case NeppOp:\n         case NepvOp:\n         case NevvOp:\n         var_op::compare(op,\n            arg, parameter, J, taylor, itr.op_index(), compare_change_count,\n            compare_change_number, compare_change_op_index\n         );\n         break;\n         // -------------------------------------------------\n\n         case AbsOp:\n         var_op::forward_abs_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AddvvOp:\n         var_op::forward_addvv_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AddpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_addpv_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AcosOp:\n         // sqrt(1 - x * x), acos(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_acos_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AcoshOp:\n         // sqrt(x * x - 1), acosh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_acosh_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AsinOp:\n         // sqrt(1 - x * x), asin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_asin_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AsinhOp:\n         // sqrt(1 + x * x), asinh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_asinh_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AtanOp:\n         // 1 + x * x, atan(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_atan_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AtanhOp:\n         // 1 - x * x, atanh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_atanh_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case CExpOp:\n         // Use the general case with d == 0\n         // (could create an optimzied version for this case)\n         var_op::forward_cond_op_0(\n            i_var, arg, num_par, parameter, J, taylor\n         );\n         break;\n         // ---------------------------------------------------\n\n         case CosOp:\n         // sin(x), cos(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_cos_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // ---------------------------------------------------\n\n         case CoshOp:\n         // sinh(x), cosh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_cosh_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case CSkipOp:\n         var_op::forward_cskip_op_0(\n            i_var, arg, num_par, parameter, J, taylor, cskip_op\n         );\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case CSumOp:\n         var_op::csum_forward_op(\n            0, 0, i_var, arg, num_par, parameter, J, taylor\n         );\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case DisOp:\n         var_op::forward_dis_op<RecBase>(p, q, r, i_var, arg, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case DivvvOp:\n         var_op::forward_divvv_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case DivpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_divpv_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case DivvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::forward_divvp_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case EndOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 0);\n         more_operators = false;\n         break;\n         // -------------------------------------------------\n\n         case ErfOp:\n         case ErfcOp:\n         var_op::forward_erf_op_0(op, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case ExpOp:\n         var_op::forward_exp_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case Expm1Op:\n         var_op::forward_expm1_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case InvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         break;\n         // ---------------------------------------------------\n\n         case LdpOp:\n         case LdvOp:\n         var_op::load_forward_0(\n            op,\n            i_var,\n            play->num_var_vecad_ind_rec(),\n            arg,\n            numvar,\n            num_par,\n            parameter,\n            J,\n            taylor,\n            vec_ad2isvar,\n            vec_ad2index,\n            load_op2var\n         );\n         break;\n         // -------------------------------------------------\n\n         case LogOp:\n         var_op::forward_log_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case Log1pOp:\n         var_op::forward_log1p_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case MulpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_mulpv_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case MulvvOp:\n         var_op::forward_mulvv_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case NegOp:\n         var_op::forward_neg_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n\n         // -------------------------------------------------\n\n         case ParOp:\n         var_op::forward_par_op_0(\n            i_var, arg, num_par, parameter, J, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case PowvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::forward_powvp_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case PowpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_powpv_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case PowvvOp:\n         var_op::forward_powvv_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case PriOp:\n         if( print ) var_op::forward_pri_0(s_out,\n            arg, num_text, text, num_par, parameter, J, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case SignOp:\n         // cos(x), sin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_sign_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SinOp:\n         // cos(x), sin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_sin_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SinhOp:\n         // cosh(x), sinh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_sinh_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SqrtOp:\n         var_op::forward_sqrt_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case StppOp:\n         case StpvOp:\n         case StvpOp:\n         case StvvOp:\n         var_op::store_forward_0(\n            op,\n            arg,\n            numvar,\n            num_par,\n            parameter,\n            J,\n            taylor,\n            vec_ad2isvar,\n            vec_ad2index\n         );\n         break;\n         // -------------------------------------------------\n\n         case SubvvOp:\n         var_op::forward_subvv_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SubpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_subpv_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SubvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::forward_subvp_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case TanOp:\n         // tan(x)^2, tan(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_tan_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case TanhOp:\n         // tanh(x)^2, tanh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_tanh_op_0(i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AFunOp:\n         // start or end an atomic function call\n         flag = atom_state == start_atom;\n         play::atom_op_info<RecBase>(\n            op, arg, atom_index, atom_id, atom_m, atom_n\n         );\n         if( flag )\n         {  atom_state = arg_atom;\n            atom_i     = 0;\n            atom_j     = 0;\n            //\n            atom_par_x.resize(atom_n);\n            atom_type_x.resize(atom_n);\n            atom_tx.resize(atom_n);\n            atom_ty.resize(atom_m);\n            atom_iy.resize(atom_m);\n            atom_sy.resize(atom_m);\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( atom_i == atom_m );\n            CPPAD_ASSERT_UNKNOWN( atom_j == atom_n );\n            atom_state = start_atom;\n            //\n            for(size_t i = 0; i < atom_m; ++i)\n               atom_sy[i] = atom_iy[i] != 0;\n            //\n            // call atomic function for this operation\n            call_atomic_forward<Base, RecBase>(\n               atom_par_x, atom_type_x, need_y, atom_sy,\n               order_low, order_up, atom_index, atom_id, atom_tx, atom_ty\n            );\n            for(size_t i = 0; i < atom_m; ++i)\n               if( atom_iy[i] > 0 )\n                  taylor[ atom_iy[i] * J + 0 ] = atom_ty[i];\n# if CPPAD_FORWARD0_TRACE\n            atom_trace = true;\n# endif\n         }\n         break;\n\n         case FunapOp:\n         // parameter argument for an atomic function\n         CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );\n         CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom );\n         CPPAD_ASSERT_UNKNOWN( atom_i == 0 );\n         CPPAD_ASSERT_UNKNOWN( atom_j < atom_n );\n         CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par );\n         //\n         if( dyn_par_is[ arg[0] ] )\n            atom_type_x[atom_j] = dynamic_enum;\n         else\n            atom_type_x[atom_j] = constant_enum;\n         atom_par_x[atom_j] = parameter[ arg[0] ];\n         atom_tx[atom_j++]  = parameter[ arg[0] ];\n         //\n         if( atom_j == atom_n )\n         {  // call atomic function for this operation\n            atom_state = ret_atom;\n         }\n         break;\n\n         case FunavOp:\n         // variable argument for an atomic function\n         CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );\n         CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom );\n         CPPAD_ASSERT_UNKNOWN( atom_i == 0 );\n         CPPAD_ASSERT_UNKNOWN( atom_j < atom_n );\n         //\n         atom_type_x[atom_j] = variable_enum;\n         atom_par_x[atom_j]  = CppAD::numeric_limits<Base>::quiet_NaN();\n         atom_tx[atom_j++]   = taylor[ size_t(arg[0]) * J + 0 ];\n         //\n         if( atom_j == atom_n )\n            atom_state = ret_atom;\n         break;\n\n         case FunrpOp:\n         // parameter result for an atomic function\n         CPPAD_ASSERT_NARG_NRES(op, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom );\n         CPPAD_ASSERT_UNKNOWN( atom_i < atom_m );\n         CPPAD_ASSERT_UNKNOWN( atom_j == atom_n );\n         CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par );\n         atom_iy[atom_i++] = 0;\n         if( atom_i == atom_m )\n            atom_state = end_atom;\n         break;\n\n         case FunrvOp:\n         // variable result for an atomic function\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom );\n         CPPAD_ASSERT_UNKNOWN( atom_i < atom_m );\n         CPPAD_ASSERT_UNKNOWN( atom_j == atom_n );\n         atom_iy[atom_i++] = i_var;\n         if( atom_i == atom_m )\n            atom_state = end_atom;\n         break;\n         // -------------------------------------------------\n\n         case ZmulpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_zmulpv_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case ZmulvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::forward_zmulvp_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case ZmulvvOp:\n         var_op::forward_zmulvv_op_0(i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n      }\n# if CPPAD_FORWARD0_TRACE\n      size_t  d  = 0;\n      if( atom_trace )\n      {  atom_trace = false;\n\n         CPPAD_ASSERT_UNKNOWN( op == AFunOp );\n         CPPAD_ASSERT_UNKNOWN( NumArg(FunrvOp) == 0 );\n         for(size_t i = 0; i < atom_m; i++) if( atom_iy[i] > 0 )\n         {  size_t i_tmp   = (itr.op_index() + i) - atom_m;\n            printOp<Base, RecBase>(\n               std::cout,\n               play,\n               i_tmp,\n               atom_iy[i],\n               FunrvOp,\n               nullptr\n            );\n            Base* Z_tmp = taylor + atom_iy[i] * J;\n            printOpResult(\n               std::cout,\n               d + 1,\n               Z_tmp,\n               0,\n               (Base *) nullptr\n            );\n            std::cout << std::endl;\n         }\n      }\n      Base*           Z_tmp   = taylor + i_var * J;\n      if( op != FunrvOp )\n      {\n         printOp<Base, RecBase>(\n            std::cout,\n            play,\n            itr.op_index(),\n            i_var,\n            op,\n            arg\n         );\n         if( NumRes(op) > 0 ) printOpResult(\n            std::cout,\n            d + 1,\n            Z_tmp,\n            0,\n            (Base *) nullptr\n         );\n         std::cout << std::endl;\n      }\n   }\n   std::cout << std::endl;\n# else\n   }\n# endif\n   CPPAD_ASSERT_UNKNOWN( atom_state == start_atom );\n\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE\n\n// preprocessor symbols that are local to this file\n# undef CPPAD_FORWARD0_TRACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sweep/forward1.hpp",
    "content": "# ifndef CPPAD_LOCAL_SWEEP_FORWARD1_HPP\n# define CPPAD_LOCAL_SWEEP_FORWARD1_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/play/atom_op_info.hpp>\n# include <cppad/local/sweep/call_atomic.hpp>\n# include <cppad/local/var_op/compare.hpp>\n\n// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE\nnamespace CppAD { namespace local { namespace sweep {\n/*!\n\\file sweep/forward1.hpp\nCompute one Taylor coefficient for each order requested.\n*/\n\n/*!\n\\def CPPAD_FORWARD1_TRACE\nThis value is either zero or one.\nZero is the normal operational value.\nIf it is one, a trace of every forward1sweep computation is printed.\n*/\n# define CPPAD_FORWARD1_TRACE 0\n\n/*!\nCompute arbitrary order forward mode Taylor coefficients.\n\n<!-- replace forward0_doc_define -->\n\\tparam Base\nThe type used during the forward mode computations; i.e., the corresponding\nrecording of operations used the type AD<Base>.\n\n\\param s_out\nIs the stream where output corresponding to PriOp operations will\nbe written.\n\n\\param print\nIf print is false,\nsuppress the output that is otherwise generated by the c PriOp instructions.\n\n\\param n\nis the number of independent variables on the tape.\n\n\\param numvar\nis the total number of variables on the tape.\nThis is also equal to the number of rows in the matrix taylor; i.e.,\nplay->num_var_rec().\n\n\\param play\nThe information stored in play\nis a recording of the operations corresponding to the function\n\\f[\n   F : {\\bf R}^n \\rightarrow {\\bf R}^m\n\\f]\nwhere \\f$ n \\f$ is the number of independent variables and\n\\f$ m \\f$ is the number of dependent variables.\n\n\\param J\nIs the number of columns in the coefficient matrix taylor.\nThis must be greater than or equal one.\n\n<!-- end forward0_doc_define -->\n\n\\param cskip_op\nIs a vector with size play->num_op_rec().\n\\n\n\\n\n<tt>p = 0</tt>\n\\n\nIn this case,\nthe input value of the elements does not matter.\nUpon return, if cskip_op[i] is true, the operator with index i\ndoes not affect any of the dependent variable\n(given the value of the independent variables).\n\\n\n\\n\n<tt>p > 0</tt>\n\\n\nIn this case cskip_op is not modified and has the same meaning\nas its return value above.\n\n\\param load_op2var\nis a vector with size play->num_var_load_rec().\n\\n\n\\n\n<tt>p == 0</tt>\n\\n\nIn this case,\nThe input value of the elements does not matter.\nUpon return,\nit is the variable index corresponding the result for each load operator.\nIn the case where the index is zero,\nthe load operator results in a parameter (not a variable).\nNote that the is no variable with index zero on the tape.\n\\n\n\\n\n<tt>p > 0</tt>\n\\n\nIn this case load_op2var is not modified and has the meaning\nas its return value above.\n\n\\param p\nis the lowest order of the Taylor coefficients\nthat are computed during this call.\n\n\\param q\nis the highest order of the Taylor coefficients\nthat are computed during this call.\n\n\\param taylor\n\\n\n\\b Input:\nFor <code>i = 1 , ... , numvar-1</code>,\n<code>k = 0 , ... , p-1</code>,\n<code>taylor[ J*i + k]</code>\nis the k-th order Taylor coefficient corresponding to\nthe i-th variable.\n\\n\n\\n\n\\b Input:\nFor <code>i = 1 , ... , n</code>,\n<code>k = p , ... , q</code>,\n<code>taylor[ J*j + k]</code>\nis the k-th order Taylor coefficient corresponding to\nthe i-th variable\n(these are the independent varaibles).\n\\n\n\\n\n\\b Output:\nFor <code>i = n+1 , ... , numvar-1</code>, and\n<code>k = 0 , ... , p-1</code>,\n<code>taylor[ J*i + k]</code>\nis the k-th order Taylor coefficient corresponding to\nthe i-th variable.\n\n\n\\param compare_change_count\nIs the count value for changing number and op_index during\nzero order forward mode.\n\n\\param compare_change_number\nIf p is non-zero, this value is not changed, otherwise:\nIf compare_change_count is zero, this value is set to zero, otherwise:\nthis value is set to the number of comparison operations\nthat have a different result from when the information in\nplay was recorded.\n\n\\param compare_change_op_index\nif p is non-zero, this value is not changed, otherwise:\nIf compare_change_count is zero, this value is set to zero.\nOtherwise it is the operator index (see forward_next) for the count-th\ncomparison operation that has a different result from when the information in\nplay was recorded.\n\n\\param not_used_rec_base\nSpecifies RecBase for this call.\n*/\n\ntemplate <class Base, class RecBase>\nvoid forward1(\n   const local::player<Base>* play,\n   std::ostream&              s_out,\n   const bool                 print,\n   const size_t               p,\n   const size_t               q,\n   const size_t               n,\n   const size_t               numvar,\n   const size_t               J,\n   Base*                      taylor,\n   bool*                      cskip_op,\n   pod_vector<addr_t>&        load_op2var,\n   size_t                     compare_change_count,\n   size_t&                    compare_change_number,\n   size_t&                    compare_change_op_index,\n   const RecBase&             not_used_rec_base\n)\n{\n   // number of directions\n   const size_t r = 1;\n\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n   CPPAD_ASSERT_UNKNOWN( J >= q + 1 );\n   CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar );\n\n   /*\n   <!-- replace forward0sweep_code_define -->\n   */\n\n   // initialize the comparison operator counter\n   if( p == 0 )\n   {  compare_change_number   = 0;\n      compare_change_op_index = 0;\n   }\n\n   // If this includes a zero calculation, initialize this information\n   pod_vector<bool>   vec_ad2isvar;\n   pod_vector<size_t> vec_ad2index;\n   if( p == 0 )\n   {  size_t i;\n\n      // this includes order zero calculation, initialize vector indices\n      size_t num = play->num_var_vecad_ind_rec();\n      if( num > 0 )\n      {  vec_ad2isvar.extend(num);\n         vec_ad2index.extend(num);\n         for(i = 0; i < num; i++)\n         {  vec_ad2index[i] = play->GetVecInd(i);\n            vec_ad2isvar[i] = false;\n         }\n      }\n      // includes zero order, so initialize conditional skip flags\n      num = play->num_op_rec();\n      for(i = 0; i < num; i++)\n         cskip_op[i] = false;\n   }\n\n   // information used by atomic function operators\n   const pod_vector<bool>& dyn_par_is( play->dyn_par_is() );\n   const size_t need_y    = size_t( variable_enum );\n   const size_t order_low = p;\n   const size_t order_up  = q;\n\n   // vectors used by atomic function operators\n   vector<Base>         atom_par_x;  // argument parameter values\n   vector<ad_type_enum> atom_type_x; // argument type\n   vector<Base>         atom_tx;     // argument vector Taylor coefficients\n   vector<Base>         atom_ty;     // result vector Taylor coefficients\n   vector<size_t>       atom_iy;     // variable indices for result vector\n   vector<bool>         atom_sy;     // select_y for this atomic call\n   //\n   // information defined by atomic function operators\n   size_t atom_index=0, atom_id=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0;\n   enum_atom_state atom_state = start_atom; // proper initialization\n\n   // length of the parameter vector (used by CppAD assert macros)\n   const size_t num_par = play->num_par_rec();\n\n   // pointer to the beginning of the parameter vector\n   CPPAD_ASSERT_UNKNOWN( num_par > 0 )\n   const Base* parameter = play->GetPar();\n\n   // length of the text vector (used by CppAD assert macros)\n   const size_t num_text = play->num_text_rec();\n\n   // pointer to the beginning of the text vector\n   const char* text = nullptr;\n   if( num_text > 0 )\n      text = play->GetTxt(0);\n   /*\n   <!-- end forward0sweep_code_define -->\n   */\n   // temporary indices\n   size_t i, k;\n\n   // number of orders for this atomic calculation\n   // (not needed for order zero)\n   const size_t atom_q1 = q+1;\n\n   // skip the BeginOp at the beginning of the recording\n   play::const_sequential_iterator itr = play->begin();\n   // op_info\n   op_code_var op;\n   size_t i_var;\n   const addr_t* arg;\n   itr.op_info(op, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op == BeginOp );\n   //\n# if CPPAD_FORWARD1_TRACE\n   bool atom_trace = false;\n   std::cout << std::endl;\n# endif\n   //\n   bool flag; // a temporary flag to use in switch cases\n   bool more_operators = true;\n   while(more_operators)\n   {\n      // next op\n      (++itr).op_info(op, arg, i_var);\n      CPPAD_ASSERT_UNKNOWN( itr.op_index() < play->num_op_rec() );\n\n      // check if we are skipping this operation\n      while( cskip_op[itr.op_index()] )\n      {  switch(op)\n         {\n            case AFunOp:\n            {  // get information for this atomic function call\n               CPPAD_ASSERT_UNKNOWN( atom_state == start_atom );\n               play::atom_op_info<Base>(\n                  op, arg, atom_index, atom_id, atom_m, atom_n\n               );\n               //\n               // skip to the second AFunOp\n               for(i = 0; i < atom_m + atom_n + 1; ++i)\n                  ++itr;\n# ifndef NDEBUG\n               itr.op_info(op, arg, i_var);\n               CPPAD_ASSERT_UNKNOWN( op == AFunOp );\n# endif\n            }\n            break;\n\n            case CSkipOp:\n            case CSumOp:\n            itr.correct_before_increment();\n            break;\n\n            default:\n            break;\n         }\n         (++itr).op_info(op, arg, i_var);\n      }\n\n      // action depends on the operator\n      switch( op )\n      {\n         case EqppOp:\n         case EqpvOp:\n         case EqvvOp:\n         case LeppOp:\n         case LepvOp:\n         case LevpOp:\n         case LevvOp:\n         case LtppOp:\n         case LtpvOp:\n         case LtvpOp:\n         case LtvvOp:\n         case NeppOp:\n         case NepvOp:\n         case NevvOp:\n         var_op::compare(op,\n            arg, parameter, J, taylor, itr.op_index(), compare_change_count,\n            compare_change_number, compare_change_op_index\n         );\n         break;\n         // -------------------------------------------------\n\n         case AbsOp:\n         var_op::forward_abs_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AddvvOp:\n         var_op::forward_addvv_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AddpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_addpv_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AcosOp:\n         // sqrt(1 - x * x), acos(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_acos_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AcoshOp:\n         // sqrt(x * x - 1), acosh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_acosh_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AsinOp:\n         // sqrt(1 - x * x), asin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_asin_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AsinhOp:\n         // sqrt(1 + x * x), asinh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_asinh_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AtanOp:\n         // 1 + x * x, atan(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_atan_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AtanhOp:\n         // 1 - x * x, atanh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_atanh_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case CExpOp:\n         var_op::forward_cond_op(\n            p, q, i_var, arg, num_par, parameter, J, taylor\n         );\n         break;\n         // ---------------------------------------------------\n\n         case CosOp:\n         // sin(x), cos(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_cos_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // ---------------------------------------------------\n\n         case CoshOp:\n         // sinh(x), cosh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_cosh_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case CSkipOp:\n         if( p == 0 )\n         {  var_op::forward_cskip_op_0(\n               i_var, arg, num_par, parameter, J, taylor, cskip_op\n            );\n         }\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case CSumOp:\n         var_op::csum_forward_op(\n            p, q, i_var, arg, num_par, parameter, J, taylor\n         );\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case DisOp:\n         var_op::forward_dis_op<RecBase>(p, q, r, i_var, arg, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case DivvvOp:\n         var_op::forward_divvv_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case DivpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_divpv_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case DivvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::forward_divvp_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case EndOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 0);\n         more_operators = false;\n         break;\n         // -------------------------------------------------\n\n         case ErfOp:\n         case ErfcOp:\n         var_op::forward_erf_op(op, p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case ExpOp:\n         var_op::forward_exp_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // ---------------------------------------------------\n\n         case Expm1Op:\n         var_op::forward_expm1_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // ---------------------------------------------------\n\n         case InvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         break;\n         // -------------------------------------------------\n\n         case LdpOp:\n         case LdvOp:\n         if( p == 0 )\n         {  var_op::load_forward_0(\n               op,\n               i_var,\n               play->num_var_vecad_ind_rec(),\n               arg,\n               numvar,\n               num_par,\n               parameter,\n               J,\n               taylor,\n               vec_ad2isvar,\n               vec_ad2index,\n               load_op2var\n            );\n            if( p < q ) var_op::load_forward_nonzero(\n               op,\n               i_var,\n               arg,\n               p+1,\n               q,\n               r,\n               J,\n               load_op2var,\n               taylor\n            );\n         }\n         else\n            var_op::load_forward_nonzero(\n            op,\n            i_var,\n            arg,\n            p,\n            q,\n            r,\n            J,\n            load_op2var,\n            taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case LogOp:\n         var_op::forward_log_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case Log1pOp:\n         var_op::forward_log1p_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case MulpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_mulpv_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case MulvvOp:\n         var_op::forward_mulvv_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // --------------------------------------------------\n\n         case NegOp:\n         var_op::forward_neg_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case ParOp:\n         i = p;\n         if( i == 0 )\n         {  var_op::forward_par_op_0(\n               i_var, arg, num_par, parameter, J, taylor\n            );\n            i++;\n         }\n         while(i <= q)\n         {  taylor[ i_var * J + i] = Base(0.0);\n            i++;\n         }\n         break;\n         // -------------------------------------------------\n\n         case PowvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::forward_powvp_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case PowpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_powpv_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case PowvvOp:\n         var_op::forward_powvv_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case PriOp:\n         if( (p == 0) & print ) var_op::forward_pri_0(s_out,\n            arg, num_text, text, num_par, parameter, J, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case SignOp:\n         // sign(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_sign_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SinOp:\n         // cos(x), sin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_sin_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SinhOp:\n         // cosh(x), sinh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_sinh_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SqrtOp:\n         var_op::forward_sqrt_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case StppOp:\n         case StpvOp:\n         case StvpOp:\n         case StvvOp:\n         if( p == 0 )\n         {  var_op::store_forward_0(\n               op,\n               arg,\n               numvar,\n               num_par,\n               parameter,\n               J,\n               taylor,\n               vec_ad2isvar,\n               vec_ad2index\n            );\n         }\n         break;\n         // -------------------------------------------------\n\n         case SubvvOp:\n         var_op::forward_subvv_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SubpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_subpv_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SubvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::forward_subvp_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case TanOp:\n         // tan(x)^2, tan(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_tan_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case TanhOp:\n         // tanh(x)^2, tanh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_tanh_op(p, q, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AFunOp:\n         // start or end an atomic function call\n         flag = atom_state == start_atom;\n         play::atom_op_info<RecBase>(\n            op, arg, atom_index, atom_id, atom_m, atom_n\n         );\n         if( flag )\n         {  atom_state = arg_atom;\n            atom_i     = 0;\n            atom_j     = 0;\n            //\n            atom_par_x.resize(atom_n);\n            atom_type_x.resize(atom_n);\n            atom_tx.resize(atom_n * atom_q1);\n            atom_ty.resize(atom_m * atom_q1);\n            atom_iy.resize(atom_m);\n            atom_sy.resize(atom_m);\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( atom_i == atom_m );\n            CPPAD_ASSERT_UNKNOWN( atom_j == atom_n );\n            atom_state = start_atom;\n            //\n            for(i = 0; i < atom_m; ++i)\n               atom_sy[i] = atom_iy[i] != 0;\n            //\n            // call atomic function for this operation\n            call_atomic_forward<Base, RecBase>(\n               atom_par_x, atom_type_x, need_y, atom_sy,\n               order_low, order_up, atom_index, atom_id, atom_tx, atom_ty\n            );\n            for(i = 0; i < atom_m; i++)\n               if( atom_iy[i] > 0 )\n                  for(k = p; k <= q; k++)\n                     taylor[ atom_iy[i] * J + k ] =\n                        atom_ty[ i * atom_q1 + k ];\n# if CPPAD_FORWARD1_TRACE\n            atom_trace = true;\n# endif\n         }\n         break;\n\n         case FunapOp:\n         // parameter argument for an atomic function\n         CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );\n         CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom );\n         CPPAD_ASSERT_UNKNOWN( atom_i == 0 );\n         CPPAD_ASSERT_UNKNOWN( atom_j < atom_n );\n         CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par );\n         //\n         if( dyn_par_is[ arg[0] ] )\n            atom_type_x[atom_j] = dynamic_enum;\n         else\n            atom_type_x[atom_j] = constant_enum;\n         atom_par_x[atom_j]            = parameter[ arg[0] ];\n         atom_tx[atom_j * atom_q1 + 0] = parameter[ arg[0]];\n         for(k = 1; k < atom_q1; k++)\n            atom_tx[atom_j * atom_q1 + k] = Base(0.0);\n         //\n         ++atom_j;\n         if( atom_j == atom_n )\n            atom_state = ret_atom;\n         break;\n\n         case FunavOp:\n         // variable argument for an atomic function\n         CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );\n         CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom );\n         CPPAD_ASSERT_UNKNOWN( atom_i == 0 );\n         CPPAD_ASSERT_UNKNOWN( atom_j < atom_n );\n         //\n         atom_type_x[atom_j] = variable_enum;\n         atom_par_x[atom_j]  = CppAD::numeric_limits<Base>::quiet_NaN();\n         for(k = 0; k < atom_q1; k++)\n            atom_tx[atom_j * atom_q1 + k] = taylor[ size_t(arg[0]) * J + k];\n         //\n         ++atom_j;\n         if( atom_j == atom_n )\n            atom_state = ret_atom;\n         break;\n\n         case FunrpOp:\n         // parameter result for an atomic function\n         CPPAD_ASSERT_NARG_NRES(op, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom );\n         CPPAD_ASSERT_UNKNOWN( atom_i < atom_m );\n         CPPAD_ASSERT_UNKNOWN( atom_j == atom_n );\n         CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par );\n         //\n         atom_iy[atom_i] = 0;\n         atom_ty[atom_i * atom_q1 + 0] = parameter[ arg[0]];\n         for(k = 1; k < p; k++)\n            atom_ty[atom_i * atom_q1 + k] = Base(0.0);\n         //\n         ++atom_i;\n         if( atom_i == atom_m )\n            atom_state = end_atom;\n         break;\n\n         case FunrvOp:\n         // variable result for an atomic function\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom );\n         CPPAD_ASSERT_UNKNOWN( atom_i < atom_m );\n         CPPAD_ASSERT_UNKNOWN( atom_j == atom_n );\n         //\n         atom_iy[atom_i] = i_var;\n         for(k = 0; k < p; k++)\n            atom_ty[atom_i * atom_q1 + k] = taylor[ i_var * J + k];\n         //\n         ++atom_i;\n         if( atom_i == atom_m )\n            atom_state = end_atom;\n         break;\n         // -------------------------------------------------\n\n         case ZmulpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_zmulpv_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case ZmulvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::forward_zmulvp_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case ZmulvvOp:\n         var_op::forward_zmulvv_op(p, q, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n      }\n# if CPPAD_FORWARD1_TRACE\n      if( atom_trace )\n      {  atom_trace = false;\n\n         CPPAD_ASSERT_UNKNOWN( op == AFunOp );\n         CPPAD_ASSERT_UNKNOWN( NumArg(FunrvOp) == 0 );\n         for(i = 0; i < atom_m; i++) if( atom_iy[i] > 0 )\n         {  size_t i_tmp   = (itr.op_index() + i) - atom_m;\n            printOp<Base, RecBase>(\n               std::cout,\n               play,\n               i_tmp,\n               atom_iy[i],\n               FunrvOp,\n               nullptr\n            );\n            Base* Z_tmp = taylor + atom_iy[i] * J;\n            printOpResult(\n               std::cout,\n               q + 1,\n               Z_tmp,\n               0,\n               (Base *) nullptr\n            );\n            std::cout << std::endl;\n         }\n      }\n      Base*           Z_tmp   = taylor + J * i_var;\n      if( op != FunrvOp )\n      {\n         printOp<Base, RecBase>(\n            std::cout,\n            play,\n            itr.op_index(),\n            i_var,\n            op,\n            arg\n         );\n         if( NumRes(op) > 0 ) printOpResult(\n            std::cout,\n            q + 1,\n            Z_tmp,\n            0,\n            (Base *) nullptr\n         );\n         std::cout << std::endl;\n      }\n   }\n   std::cout << std::endl;\n# else\n   }\n# endif\n   CPPAD_ASSERT_UNKNOWN( atom_state == start_atom );\n\n   if( (p == 0) && (compare_change_count == 0) )\n      compare_change_number = 0;\n   return;\n}\n\n// preprocessor symbols that are local to this file\n# undef CPPAD_FORWARD1_TRACE\n\n} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sweep/forward2.hpp",
    "content": "# ifndef CPPAD_LOCAL_SWEEP_FORWARD2_HPP\n# define CPPAD_LOCAL_SWEEP_FORWARD2_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/play/atom_op_info.hpp>\n# include <cppad/local/sweep/call_atomic.hpp>\n\n// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE\nnamespace CppAD { namespace local { namespace sweep {\n/*!\n\\file sweep/forward2.hpp\nCompute one Taylor coefficient for each direction requested.\n*/\n\n/*!\n\\def CPPAD_FORWARD2_TRACE\nThis value is either zero or one.\nZero is the normal operational value.\nIf it is one, a trace of every forward2sweep computation is printed.\n*/\n# define CPPAD_FORWARD2_TRACE 0\n\n/*!\nCompute multiple directions forward mode Taylor coefficients.\n\n\\tparam Base\nThe type used during the forward mode computations; i.e., the corresponding\nrecording of operations used the type AD<Base>.\n\n\\param q\nis the order of the Taylor coefficients\nthat are computed during this call;\n<code>q > 0</code>.\n\n\\param r\nis the number of Taylor coefficients\nthat are computed during this call.\n\n\\param n\nis the number of independent variables on the tape.\n\n\\param numvar\nis the total number of variables on the tape.\nThis is also equal to the number of rows in the matrix taylor; i.e.,\nplay->num_var_rec().\n\n\\param play\nThe information stored in play\nis a recording of the operations corresponding to the function\n\\f[\n   F : {\\bf R}^n \\rightarrow {\\bf R}^m\n\\f]\nwhere \\f$ n \\f$ is the number of independent variables and\n\\f$ m \\f$ is the number of dependent variables.\n\n\\param J\nIs the number of columns in the coefficient matrix taylor.\nThis must be greater than or equal one.\n\n\\param taylor\n\\n\n\\b Input:\nFor <code>i = 1 , ... , numvar-1</code>,\n<code>taylor[ (J-1)*r*i + i + 0 ]</code>\nis the zero order Taylor coefficient corresponding to\nthe i-th variable and all directions.\nFor <code>i = 1 , ... , numvar-1</code>,\nFor <code>k = 1 , ... , q-1</code>,\n<code>ell = 0 , ... , r-1</code>,\n<code>taylor[ (J-1)*r*i + i + (k-1)*r + ell + 1 ]</code>\nis the k-th order Taylor coefficient corresponding to\nthe i-th variabel and ell-th direction.\n\\n\n\\n\n\\b Input:\nFor <code>i = 1 , ... , n</code>,\n<code>ell = 0 , ... , r-1</code>,\n<code>taylor[ (J-1)*r*i + i + (q-1)*r + ell + 1 ]</code>\nis the q-th order Taylor coefficient corresponding to\nthe i-th variable and ell-th direction\n(these are the independent varaibles).\n\\n\n\\n\n\\b Output:\nFor <code>i = n+1 , ... , numvar-1</code>,\n<code>ell = 0 , ... , r-1</code>,\n<code>taylor[ (J-1)*r*i + i + (q-1)*r + ell + 1 ]</code>\nis the q-th order Taylor coefficient corresponding to\nthe i-th variable and ell-th direction.\n\n\\param cskip_op\nIs a vector with size play->num_op_rec().\nIf cskip_op[i] is true, the operator with index i\ndoes not affect any of the dependent variable (given the value\nof the independent variables).\n\n\\param load_op2var\nis a vector with size play->num_var_load_rec().\nIt is the variable index corresponding to each the\nload instruction.\nIn the case where the index is zero,\nthe instruction corresponds to a parameter (not variable).\n\n\\param not_used_rec_base\nSpecifies RecBase for this call.\n\n*/\n\ntemplate <class Addr, class Base, class RecBase>\nvoid forward2(\n   const local::player<Base>*  play,\n   const size_t                q,\n   const size_t                r,\n   const size_t                n,\n   const size_t                numvar,\n   const size_t                J,\n   Base*                       taylor,\n   const bool*                 cskip_op,\n   const pod_vector<Addr>&     load_op2var,\n   const RecBase&              not_used_rec_base\n)\n{\n   CPPAD_ASSERT_UNKNOWN( q > 0 );\n   CPPAD_ASSERT_UNKNOWN( J >= q + 1 );\n   CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar );\n\n   // only compute one order at a time when using multi-direction forward\n   size_t p = q;\n\n   // information used by atomic function operators\n   const pod_vector<bool>& dyn_par_is( play->dyn_par_is() );\n   const size_t need_y    = size_t( variable_enum );\n   const size_t order_low = p;\n   const size_t order_up  = q;\n\n   // vectors used by atomic function operators\n   vector<Base> atom_par_x;          // argument parameter values\n   vector<ad_type_enum> atom_type_x; // argument type\n   vector<Base> atom_tx_one;         // argument vector Taylor coefficients\n   vector<Base> atom_tx_all;\n   vector<Base> atom_ty_one;         // result vector Taylor coefficients\n   vector<Base> atom_ty_all;\n   //\n   // information defined by atomic function operators\n   size_t atom_index=0, atom_id=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0;\n   enum_atom_state atom_state = start_atom; // proper initialization\n   //\n   // length of the parameter vector (used by CppAD assert macros)\n   const size_t num_par = play->num_par_rec();\n\n   // pointer to the beginning of the parameter vector\n   CPPAD_ASSERT_UNKNOWN( num_par > 0 )\n   const Base* parameter = play->GetPar();\n\n   // temporary indices\n   size_t i, j, k, ell;\n\n   // number of orders for this atomic calculation\n   // (not needed for order zero)\n   const size_t atom_q1 = q+1;\n\n   // variable indices for results vector\n   vector<size_t> atom_iy;\n\n   // select_y for an atomic function call\n   vector<bool> atom_sy;\n\n   // skip the BeginOp at the beginning of the recording\n   play::const_sequential_iterator itr = play->begin();\n   // op_info\n   op_code_var op;\n   size_t i_var;\n   const Addr*   arg;\n   itr.op_info(op, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op == BeginOp );\n# if CPPAD_FORWARD2_TRACE\n   bool atom_trace  = false;\n   std::cout << std::endl;\n   CppAD::vector<Base> Z_vec(q+1);\n# endif\n   bool flag; // a temporary flag to use in switch cases\n   bool more_operators = true;\n   while(more_operators)\n   {\n      // next op\n      (++itr).op_info(op, arg, i_var);\n      CPPAD_ASSERT_UNKNOWN( itr.op_index() < play->num_op_rec() );\n\n      // check if we are skipping this operation\n      while( cskip_op[itr.op_index()] )\n      {  switch(op)\n         {\n            case AFunOp:\n            {  // get information for this atomic function call\n               CPPAD_ASSERT_UNKNOWN( atom_state == start_atom );\n               play::atom_op_info<Base>(\n                  op, arg, atom_index, atom_id, atom_m, atom_n\n               );\n               //\n               // skip to the second AFunOp\n               for(i = 0; i < atom_m + atom_n + 1; ++i)\n                  ++itr;\n# ifndef NDEBUG\n               itr.op_info(op, arg, i_var);\n               CPPAD_ASSERT_UNKNOWN( op == AFunOp );\n# endif\n            }\n            break;\n\n            case CSkipOp:\n            case CSumOp:\n            itr.correct_before_increment();\n            break;\n\n            default:\n            break;\n         }\n         (++itr).op_info(op, arg, i_var);\n      }\n\n      // action depends on the operator\n      switch( op )\n      {\n         case AbsOp:\n         var_op::forward_abs_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AddvvOp:\n         var_op::forward_addvv_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AddpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_addpv_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AcosOp:\n         // sqrt(1 - x * x), acos(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_acos_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AcoshOp:\n         // sqrt(x * x - 1), acosh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_acosh_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AsinOp:\n         // sqrt(1 - x * x), asin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_asin_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AsinhOp:\n         // sqrt(1 + x * x), asinh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_asinh_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AtanOp:\n         // 1 + x * x, atan(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_atan_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AtanhOp:\n         // 1 - x * x, atanh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_atanh_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case CExpOp:\n         var_op::forward_cond_op_dir(\n            q, r, i_var, arg, num_par, parameter, J, taylor\n         );\n         break;\n         // ---------------------------------------------------\n\n         case CosOp:\n         // sin(x), cos(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_cos_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // ---------------------------------------------------\n\n         case CoshOp:\n         // sinh(x), cosh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_cosh_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case CSkipOp:\n         // CSkipOp only does somthing on order zero.\n         CPPAD_ASSERT_UNKNOWN( p > 0 );\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case CSumOp:\n         var_op::csum_forward_dir(\n            q, r, i_var, arg, num_par, parameter, J, taylor\n         );\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case DisOp:\n         var_op::forward_dis_op<RecBase>(p, q, r, i_var, arg, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case DivvvOp:\n         var_op::forward_divvv_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case DivpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_divpv_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case DivvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::forward_divvp_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case EndOp:\n         // needed for sparse_jacobian test\n         CPPAD_ASSERT_NARG_NRES(op, 0, 0);\n         more_operators = false;\n         break;\n         // -------------------------------------------------\n\n         case ErfOp:\n         case ErfcOp:\n         var_op::forward_erf_op_dir(op, q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case ExpOp:\n         var_op::forward_exp_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case Expm1Op:\n         var_op::forward_expm1_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case InvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         break;\n         // -------------------------------------------------\n\n         case LdpOp:\n         case LdvOp:\n         var_op::load_forward_nonzero(\n            op,\n            i_var,\n            arg,\n            p,\n            q,\n            r,\n            J,\n            load_op2var,\n            taylor\n         );\n         break;\n         // ---------------------------------------------------\n\n         case EqppOp:\n         case EqpvOp:\n         case EqvvOp:\n         case LtppOp:\n         case LtpvOp:\n         case LtvpOp:\n         case LtvvOp:\n         case LeppOp:\n         case LepvOp:\n         case LevpOp:\n         case LevvOp:\n         case NeppOp:\n         case NepvOp:\n         case NevvOp:\n         CPPAD_ASSERT_UNKNOWN(q > 0 );\n         break;\n         // -------------------------------------------------\n\n         case LogOp:\n         var_op::forward_log_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // ---------------------------------------------------\n\n         case Log1pOp:\n         var_op::forward_log1p_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // ---------------------------------------------------\n\n         case MulpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_mulpv_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case MulvvOp:\n         var_op::forward_mulvv_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case NegOp:\n         var_op::forward_neg_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case ParOp:\n         k = i_var*(J-1)*r + i_var + (q-1)*r + 1;\n         for(ell = 0; ell < r; ell++)\n            taylor[k + ell] = Base(0.0);\n         break;\n         // -------------------------------------------------\n\n         case PowpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_powpv_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case PowvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::forward_powvp_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case PowvvOp:\n         var_op::forward_powvv_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case PriOp:\n         CPPAD_ASSERT_UNKNOWN(q > 0);\n         break;\n         // -------------------------------------------------\n\n         case SignOp:\n         // sign(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_sign_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SinOp:\n         // cos(x), sin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_sin_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SinhOp:\n         // cosh(x), sinh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_sinh_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SqrtOp:\n         var_op::forward_sqrt_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case StppOp:\n         case StpvOp:\n         case StvpOp:\n         case StvvOp:\n         CPPAD_ASSERT_UNKNOWN(q > 0 );\n         break;\n         // -------------------------------------------------\n\n         case SubvvOp:\n         var_op::forward_subvv_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SubpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_subpv_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SubvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::forward_subvp_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case TanOp:\n         // tan(x)^2, tan(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_tan_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case TanhOp:\n         // tanh(x)^2, tanh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < numvar  );\n         var_op::forward_tanh_op_dir(q, r, i_var, size_t(arg[0]), J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AFunOp:\n         // start or end an atomic function call\n         flag = atom_state == start_atom;\n         play::atom_op_info<RecBase>(\n            op, arg, atom_index, atom_id, atom_m, atom_n\n         );\n         if( flag )\n         {  atom_state = arg_atom;\n            atom_i     = 0;\n            atom_j     = 0;\n            //\n            atom_par_x.resize(atom_n);\n            atom_type_x.resize(atom_n);\n            //\n            atom_tx_one.resize(atom_n * atom_q1);\n            atom_tx_all.resize(atom_n * (q * r + 1));\n            //\n            atom_ty_one.resize(atom_m * atom_q1);\n            atom_ty_all.resize(atom_m * (q * r + 1));\n            //\n            atom_iy.resize(atom_m);\n            atom_sy.resize(atom_m);\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( atom_i == atom_m );\n            CPPAD_ASSERT_UNKNOWN( atom_j == atom_n );\n            atom_state = start_atom;\n            //\n            // call atomic function for this operation\n            for(ell = 0; ell < r; ell++)\n            {  // set atom_tx\n               for(j = 0; j < atom_n; j++)\n               {  size_t j_all     = j * (q * r + 1);\n                  size_t j_one     = j * atom_q1;\n                  atom_tx_one[j_one+0] = atom_tx_all[j_all+0];\n                  for(k = 1; k < atom_q1; k++)\n                  {  size_t k_all       = j_all + (k-1)*r+1+ell;\n                     size_t k_one       = j_one + k;\n                     atom_tx_one[k_one] = atom_tx_all[k_all];\n                  }\n               }\n               // set atom_ty\n               for(i = 0; i < atom_m; i++)\n               {  size_t i_all     = i * (q * r + 1);\n                  size_t i_one     = i * atom_q1;\n                  atom_ty_one[i_one+0] = atom_ty_all[i_all+0];\n                  for(k = 1; k < q; k++)\n                  {  size_t k_all       = i_all + (k-1)*r+1+ell;\n                     size_t k_one       = i_one + k;\n                     atom_ty_one[k_one] = atom_ty_all[k_all];\n                  }\n               }\n               // set atom_sy\n               for(i = 0; i < atom_m; ++i)\n                  atom_sy[i] = atom_iy[i] != 0;\n               call_atomic_forward<Base,RecBase>(\n                  atom_par_x,\n                  atom_type_x,\n                  need_y,\n                  atom_sy,\n                  order_low,\n                  order_up,\n                  atom_index,\n                  atom_id,\n                  atom_tx_one,\n                  atom_ty_one\n               );\n               for(i = 0; i < atom_m; i++)\n               {  if( atom_iy[i] > 0 )\n                  {  size_t i_taylor = atom_iy[i]*((J-1)*r+1);\n                     size_t q_taylor = i_taylor + (q-1)*r+1+ell;\n                     size_t q_one    = i * atom_q1 + q;\n                     taylor[q_taylor] = atom_ty_one[q_one];\n                  }\n               }\n            }\n# if CPPAD_FORWARD2_TRACE\n            atom_trace = true;\n# endif\n         }\n         break;\n\n         case FunapOp:\n         // parameter argument for an atomic function\n         CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );\n         CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom );\n         CPPAD_ASSERT_UNKNOWN( atom_i == 0 );\n         CPPAD_ASSERT_UNKNOWN( atom_j < atom_n );\n         CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par );\n         //\n         if( dyn_par_is[ arg[0] ] )\n            atom_type_x[atom_j] = dynamic_enum;\n         else\n            atom_type_x[atom_j] = constant_enum;\n         atom_par_x[atom_j]      = parameter[ arg[0] ];\n         atom_tx_all[atom_j*(q*r+1) + 0] = parameter[ arg[0]];\n         for(ell = 0; ell < r; ell++)\n            for(k = 1; k < atom_q1; k++)\n               atom_tx_all[atom_j*(q*r+1) + (k-1)*r+1+ell] = Base(0.0);\n         //\n         ++atom_j;\n         if( atom_j == atom_n )\n            atom_state = ret_atom;\n         break;\n\n         case FunavOp:\n         // variable argument for an atomic function\n         CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );\n         CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom );\n         CPPAD_ASSERT_UNKNOWN( atom_i == 0 );\n         CPPAD_ASSERT_UNKNOWN( atom_j < atom_n );\n         //\n         atom_type_x[atom_j] = variable_enum;\n         atom_par_x[atom_j]  = CppAD::numeric_limits<Base>::quiet_NaN();\n         atom_tx_all[atom_j*(q*r+1)+0] =\n            taylor[size_t(arg[0])*((J-1)*r+1)+0];\n         for(ell = 0; ell < r; ell++)\n         {  for(k = 1; k < atom_q1; k++)\n            {  atom_tx_all[atom_j*(q*r+1) + (k-1)*r+1+ell] =\n                  taylor[size_t(arg[0])*((J-1)*r+1) + (k-1)*r+1+ell];\n            }\n         }\n         //\n         ++atom_j;\n         if( atom_j == atom_n )\n            atom_state = ret_atom;\n         break;\n\n         case FunrpOp:\n         // parameter result for an atomic function\n         CPPAD_ASSERT_NARG_NRES(op, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom );\n         CPPAD_ASSERT_UNKNOWN( atom_i < atom_m );\n         CPPAD_ASSERT_UNKNOWN( atom_j == atom_n );\n         //\n         atom_iy[atom_i] = 0;\n         atom_ty_all[atom_i*(q*r+1) + 0] = parameter[ arg[0]];\n         for(ell = 0; ell < r; ell++)\n            for(k = 1; k < atom_q1; k++)\n               atom_ty_all[atom_i*(q*r+1) + (k-1)*r+1+ell] = Base(0.0);\n         //\n         ++atom_i;\n         if( atom_i == atom_m )\n            atom_state = end_atom;\n         break;\n\n         case FunrvOp:\n         // variable result for an atomic function\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom );\n         CPPAD_ASSERT_UNKNOWN( atom_i < atom_m );\n         CPPAD_ASSERT_UNKNOWN( atom_j == atom_n );\n         //\n         atom_iy[atom_i] = i_var;\n         atom_ty_all[atom_i*(q*r+1)+0] = taylor[i_var*((J-1)*r+1)+0];\n         for(ell = 0; ell < r; ell++)\n         {  for(k = 1; k < atom_q1; k++)\n            {  atom_ty_all[atom_i*(q*r+1) + (k-1)*r+1+ell] =\n                  taylor[i_var*((J-1)*r+1) + (k-1)*r+1+ell];\n            }\n         }\n         ++atom_i;\n         if( atom_i == atom_m )\n            atom_state = end_atom;\n         break;\n         // -------------------------------------------------\n\n         case ZmulpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::forward_zmulpv_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case ZmulvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::forward_zmulvp_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         case ZmulvvOp:\n         var_op::forward_zmulvv_op_dir(q, r, i_var, arg, parameter, J, taylor);\n         break;\n         // -------------------------------------------------\n\n         default:\n         CPPAD_ASSERT_UNKNOWN(0);\n      }\n# if CPPAD_FORWARD2_TRACE\n      if( atom_trace )\n      {  atom_trace = false;\n         CPPAD_ASSERT_UNKNOWN( op == AFunOp );\n         CPPAD_ASSERT_UNKNOWN( NumArg(FunrvOp) == 0 );\n         for(i = 0; i < atom_m; i++) if( atom_iy[i] > 0 )\n         {  size_t i_tmp   = (itr.op_index() + i) - atom_m;\n            printOp<Base, RecBase>(\n               std::cout,\n               play,\n               i_tmp,\n               atom_iy[i],\n               FunrvOp,\n               nullptr\n            );\n            Base* Z_tmp = taylor + atom_iy[i]*((J-1) * r + 1);\n            {  Z_vec[0]    = Z_tmp[0];\n               for(ell = 0; ell < r; ell++)\n               {  std::cout << std::endl << \"     \";\n                  for(size_t p_tmp = 1; p_tmp <= q; p_tmp++)\n                     Z_vec[p_tmp] = Z_tmp[(p_tmp-1)*r+ell+1];\n                  printOpResult(\n                     std::cout,\n                     q + 1,\n                     Z_vec.data(),\n                     0,\n                     (Base *) nullptr\n                  );\n               }\n            }\n            std::cout << std::endl;\n         }\n      }\n      if( op != FunrvOp )\n      {  printOp<Base, RecBase>(\n            std::cout,\n            play,\n            itr.op_index(),\n            i_var,\n            op,\n            arg\n         );\n         Base* Z_tmp = nullptr;\n         if( op == FunavOp )\n            Z_tmp = taylor + size_t(arg[0])*((J-1) * r + 1);\n         else if( NumRes(op) > 0 )\n            Z_tmp = taylor + i_var*((J-1)*r + 1);\n         if( Z_tmp != nullptr )\n         {  Z_vec[0]    = Z_tmp[0];\n            for(ell = 0; ell < r; ell++)\n            {  std::cout << std::endl << \"     \";\n               for(size_t p_tmp = 1; p_tmp <= q; p_tmp++)\n                  Z_vec[p_tmp] = Z_tmp[ (p_tmp-1)*r + ell + 1];\n               printOpResult(\n                  std::cout,\n                  q + 1,\n                  Z_vec.data(),\n                  0,\n                  (Base *) nullptr\n               );\n            }\n         }\n         std::cout << std::endl;\n      }\n   }\n   std::cout << std::endl;\n# else\n   }\n# endif\n   CPPAD_ASSERT_UNKNOWN( atom_state == start_atom );\n\n   return;\n}\n\n// preprocessor symbols that are local to this file\n# undef CPPAD_FORWARD2_TRACE\n\n} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sweep/forward_0.hpp",
    "content": "# ifndef CPPAD_LOCAL_SWEEP_FORWARD_0_HPP\n# define CPPAD_LOCAL_SWEEP_FORWARD_0_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/play/atom_op_info.hpp>\n# include <cppad/local/sweep/call_atomic.hpp>\n# include <cppad/local/var_op/compare_op.hpp>\n# include <cppad/local/var_op/atomic_op.hpp>\n\n# define CPPAD_FORWARD_0_TRACE 0\n\n// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE\nnamespace CppAD { namespace local { namespace sweep {\n/*\n ------------------------------------------------------------------------------\n{xrst_begin sweep_forward_0 dev}\n{xrst_spell\n   cskip\n}\n\n{xrst_template ;\n   include/cppad/local/sweep/template/forward_sweep.xrst\n\n   headers all:     CPPAD_@NAME@_TRACE, Portotype, Base, RecBase, play, num_var\n   headers all:     cap_order, cskip, load_op2var, taylor\n   headers 0 & any: change_count, change_number, change_op_index, sout, print\n\n   @title@  The title for this forward sweep\n   @#####@  Underlining for the tilte\n   @NAME@   is one of FORWARD_0, FORWARD_ANY, FORWARD_DIR\n   @****@   Underlining for @NAME@\n\n   @title@ ; Compute Zero Order Forward Mode Taylor Coefficients\n   @#####@ ; ###################################################\n   @NAME@  ; FORWARD_0\n   @****@  ; *********\n}\n\n{xrst_end sweep_forward_0}\n*/\n\n// BEGIN_FORWARD_0\ntemplate <class Base, class RecBase>\nvoid forward_0(\n   const RecBase&             not_used_rec_base,\n   const local::player<Base>* play,\n   size_t                     num_var,\n   size_t                     cap_order,\n   bool*                      cskip_op,\n   pod_vector<addr_t>&        load_op2var,\n   size_t                     change_count,\n   size_t&                    change_number,\n   size_t&                    change_op_index,\n   std::ostream&              s_out,\n   bool                       print,\n   Base*                      taylor\n)\n// END_FORWARD_0\n{  CPPAD_ASSERT_UNKNOWN( cap_order >= 1 );\n   CPPAD_ASSERT_UNKNOWN( play->num_var() == num_var );\n\n   // use p, q, r so other forward sweeps can use code defined here\n   size_t order_low = 0;\n   size_t order_up  = 0;\n   size_t r = 1;\n\n   // initialize the comparison operator counter\n   if( order_low == 0 )\n   {  change_number   = 0;\n      change_op_index = 0;\n   }\n\n   // If this includes a zero calculation, initialize this information\n   pod_vector<bool>   vec_ad2isvar;\n   pod_vector<size_t> vec_ad2index;\n   if( order_low == 0 )\n   {  size_t i;\n\n      // this includes order zero calculation, initialize vector indices\n      size_t num = play->num_var_vec_ind();\n      if( num > 0 )\n      {  vec_ad2isvar.extend(num);\n         vec_ad2index.extend(num);\n         for(i = 0; i < num; i++)\n         {  vec_ad2index[i] = play->GetVecInd(i);\n            vec_ad2isvar[i] = false;\n         }\n      }\n      // includes zero order, so initialize conditional skip flags\n      num = play->num_var_op();\n      for(i = 0; i < num; i++)\n         cskip_op[i] = false;\n   }\n\n   // information used by atomic function operators\n\n   // work space used by atomic functions\n   var_op::atomic_op_work<Base> atom_work;\n\n   // length of the parameter vector (used by CppAD assert macros)\n   const size_t num_par = play->num_par_all();\n\n   // pointer to the beginning of the parameter vector\n   CPPAD_ASSERT_UNKNOWN( num_par > 0 )\n   const Base* parameter = play->par_ptr();\n\n   // length of the text vector (used by CppAD assert macros)\n   const size_t num_text = play->num_var_text();\n\n   // pointer to the beginning of the text vector\n   const char* text = nullptr;\n   if( num_text > 0 )\n      text = play->GetTxt(0);\n\n# if CPPAD_FORWARD_0_TRACE\n   // flag as to when to trace atomic function values\n   bool atom_trace  = true;\n# else\n   bool atom_trace  = false;\n# endif\n\n   // skip the BeginOp at the beginning of the recording\n   play::const_sequential_iterator itr = play->begin();\n   // op_info\n   op_code_var   op;\n   size_t        i_var;\n   const addr_t* arg;\n   itr.op_info(op, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op == BeginOp );\n   //\n# if CPPAD_FORWARD_0_TRACE\n   std::cout << std::endl;\n# endif\n   bool more_operators = true;\n   while(more_operators)\n   {\n      // next op\n      (++itr).op_info(op, arg, i_var);\n      CPPAD_ASSERT_UNKNOWN( itr.op_index() < play->num_var_op() );\n\n      // check if we are skipping this operation\n      while( cskip_op[itr.op_index()] )\n      {  switch(op)\n         {\n            case AFunOp:\n            {  // get information for this atomic function call\n               size_t atom_index, atom_id, atom_m, atom_n;\n               play::atom_op_info<Base>(\n                  op, arg, atom_index, atom_id, atom_m, atom_n\n               );\n               //\n               // skip to the second AFunOp\n               for(size_t i = 0; i < atom_m + atom_n + 1; ++i)\n                  ++itr;\n# ifndef NDEBUG\n               itr.op_info(op, arg, i_var);\n               CPPAD_ASSERT_UNKNOWN( op == AFunOp );\n# endif\n            }\n            break;\n\n            case CSkipOp:\n            case CSumOp:\n            itr.correct_before_increment();\n            break;\n\n            default:\n            break;\n         }\n         (++itr).op_info(op, arg, i_var);\n      }\n\n      // action to take depends on the case\n      switch( op )\n      {\n         case EqppOp:\n         case EqpvOp:\n         case EqvvOp:\n         case LeppOp:\n         case LepvOp:\n         case LevpOp:\n         case LevvOp:\n         case LtppOp:\n         case LtpvOp:\n         case LtvpOp:\n         case LtvvOp:\n         case NeppOp:\n         case NepvOp:\n         case NevvOp:\n         var_op::compare_forward_any(op,\n            arg, parameter, cap_order, taylor, itr.op_index(),\n            change_count, change_number, change_op_index\n         );\n         break;\n         // -------------------------------------------------\n\n         case AbsOp:\n         var_op::abs_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AddvvOp:\n         var_op::addvv_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AddpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::addpv_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AcosOp:\n         // sqrt(1 - x * x), acos(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::acos_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AcoshOp:\n         // sqrt(x * x - 1), acosh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::acosh_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AsinOp:\n         // sqrt(1 - x * x), asin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::asin_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AsinhOp:\n         // sqrt(1 + x * x), asinh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::asinh_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AtanOp:\n         // 1 + x * x, atan(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::atan_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AtanhOp:\n         // 1 - x * x, atanh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::atanh_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case CExpOp:\n         // Use the general case with d == 0\n         // (could create an optimized version for this case)\n         var_op::cexp_forward_0(\n            i_var, arg, num_par, parameter, cap_order, taylor\n         );\n         break;\n         // ---------------------------------------------------\n\n         case CosOp:\n         // sin(x), cos(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::cos_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // ---------------------------------------------------\n\n         case CoshOp:\n         // sinh(x), cosh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::cosh_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case CSkipOp:\n         var_op::cskip_forward_0(\n            i_var, arg, num_par, parameter, cap_order, taylor, cskip_op\n         );\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case CSumOp:\n         var_op::csum_forward_any(\n            0, 0, i_var, arg, num_par, parameter, cap_order, taylor\n         );\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case DisOp:\n         var_op::dis_forward_dir<RecBase>(\n            order_low, order_up, r, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case DivvvOp:\n         var_op::divvv_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case DivpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::divpv_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case DivvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::divvp_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case EndOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 0);\n         more_operators = false;\n         break;\n         // -------------------------------------------------\n\n         case ErfOp:\n         case ErfcOp:\n         var_op::erf_forward_0(op, i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case ExpOp:\n         var_op::exp_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case Expm1Op:\n         var_op::expm1_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case InvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         break;\n         // ---------------------------------------------------\n\n         case LdpOp:\n         case LdvOp:\n         var_op::load_forward_0(\n            op,\n            i_var,\n            play->num_var_vec_ind(),\n            arg,\n            num_var,\n            num_par,\n            parameter,\n            cap_order,\n            taylor,\n            vec_ad2isvar,\n            vec_ad2index,\n            load_op2var\n         );\n         break;\n         // -------------------------------------------------\n\n         case LogOp:\n         var_op::log_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case Log1pOp:\n         var_op::log1p_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case MulpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::mulpv_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case MulvvOp:\n         var_op::mulvv_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case NegOp:\n         var_op::neg_forward_0(i_var, arg, cap_order, taylor);\n         break;\n\n         // -------------------------------------------------\n\n         case ParOp:\n         var_op::par_forward_0(\n            i_var, arg, num_par, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case PowvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::powvp_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case PowpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::powpv_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case PowvvOp:\n         var_op::powvv_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case PriOp:\n         if( print ) var_op::pri_forward_0(s_out,\n            arg, num_text, text, num_par, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case SignOp:\n         // cos(x), sin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::sign_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SinOp:\n         // cos(x), sin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::sin_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SinhOp:\n         // cosh(x), sinh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::sinh_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SqrtOp:\n         var_op::sqrt_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case StppOp:\n         case StpvOp:\n         case StvpOp:\n         case StvvOp:\n         var_op::store_forward_0(\n            op,\n            arg,\n            num_var,\n            num_par,\n            parameter,\n            cap_order,\n            taylor,\n            vec_ad2isvar,\n            vec_ad2index\n         );\n         break;\n         // -------------------------------------------------\n\n         case SubvvOp:\n         var_op::subvv_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SubpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::subpv_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case SubvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::subvp_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case TanOp:\n         // tan(x)^2, tan(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::tan_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case TanhOp:\n         // tanh(x)^2, tanh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::tanh_forward_0(i_var, arg, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case AFunOp:\n         // start of an atomic function call\n         var_op::atomic_forward_any<Base, RecBase>(\n            itr,\n            play,\n            parameter,\n            atom_trace,\n            atom_work,\n            cap_order,\n            order_low,\n            order_up,\n            taylor\n         );\n         break;\n\n         case FunapOp:\n         case FunavOp:\n         case FunrpOp:\n         case FunrvOp:\n         CPPAD_ASSERT_UNKNOWN( false );\n         break;\n         // -------------------------------------------------\n\n         case ZmulpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::zmulpv_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case ZmulvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::zmulvp_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         case ZmulvvOp:\n         var_op::zmulvv_forward_0(i_var, arg, parameter, cap_order, taylor);\n         break;\n         // -------------------------------------------------\n\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n      }\n# if CPPAD_FORWARD_0_TRACE\n      size_t  d  = 0;\n      Base*           Z_tmp   = taylor + i_var * cap_order;\n      if( op != AFunOp )\n      {\n         printOp<Base, RecBase>(\n            std::cout,\n            play,\n            itr.op_index(),\n            i_var,\n            op,\n            arg\n         );\n         if( NumRes(op) > 0 ) printOpResult(\n            std::cout,\n            d + 1,\n            Z_tmp,\n            0,\n            (Base *) nullptr\n         );\n         std::cout << std::endl;\n      }\n   }\n   std::cout << std::endl;\n# else\n   }\n# endif\n\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE\n\n// preprocessor symbols that are local to this file\n# undef CPPAD_FORWARD_0_TRACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sweep/forward_any.hpp",
    "content": "# ifndef CPPAD_LOCAL_SWEEP_FORWARD_ANY_HPP\n# define CPPAD_LOCAL_SWEEP_FORWARD_ANY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/play/atom_op_info.hpp>\n# include <cppad/local/sweep/call_atomic.hpp>\n# include <cppad/local/var_op/compare_op.hpp>\n# include <cppad/local/var_op/atomic_op.hpp>\n\n# define CPPAD_FORWARD_ANY_TRACE 0\n\n// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE\nnamespace CppAD { namespace local { namespace sweep {\n/*\n ------------------------------------------------------------------------------\n{xrst_begin sweep_forward_any dev}\n{xrst_spell\n   cskip\n}\n\n{xrst_template ;\n   include/cppad/local/sweep/template/forward_sweep.xrst\n\n   headers all:     CPPAD_@NAME@_TRACE, Portotype, Base, RecBase, play, num_var\n   headers all:     cap_order, cskip, load_op2var, taylor\n   headers 0 & any: change_count, change_number, change_op_index, sout, print\n   headers any:     order_low, order_up\n\n   @title@  The title for this forward sweep\n   @#####@  Underlining for the tilte\n   @NAME@   is one of FORWARD_0, FORWARD_ANY, FORWARD_DIR\n   @****@   Underlining for @NAME@\n\n   @title@ ; Compute Any Order Forward Mode Taylor Coefficients\n   @#####@ ; ##################################################\n   @NAME@  ; FORWARD_ANY\n   @****@  ; ***********\n}\n\n{xrst_end sweep_forward_any}\n*/\n// BEGIN_FORWARD_ANY\ntemplate <class Base, class RecBase>\nvoid forward_any(\n   const RecBase&             not_used_rec_base,\n   const local::player<Base>* play,\n   const size_t               num_var,\n   const size_t               cap_order,\n   bool*                      cskip_op,\n   pod_vector<addr_t>&        load_op2var,\n   size_t                     change_count,\n   size_t&                    change_number,\n   size_t&                    change_op_index,\n   std::ostream&              s_out,\n   const bool                 print,\n   const size_t               order_low,\n   const size_t               order_up,\n   Base*                      taylor\n)\n// END_FORWARD_ANY\n{\n   // number of directions\n   const size_t r = 1;\n\n   CPPAD_ASSERT_UNKNOWN(order_low <= order_up );\n   CPPAD_ASSERT_UNKNOWN( cap_order >= order_up + 1 );\n   CPPAD_ASSERT_UNKNOWN( play->num_var() == num_var );\n\n   /*\n   <!-- replace forward0sweep_code_define -->\n   */\n\n   // initialize the comparison operator counter\n   if( order_low == 0 )\n   {  change_number   = 0;\n      change_op_index = 0;\n   }\n\n   // If this includes a zero calculation, initialize this information\n   pod_vector<bool>   vec_ad2isvar;\n   pod_vector<size_t> vec_ad2index;\n   if( order_low == 0 )\n   {  size_t i;\n\n      // this includes order zero calculation, initialize vector indices\n      size_t num = play->num_var_vec_ind();\n      if( num > 0 )\n      {  vec_ad2isvar.extend(num);\n         vec_ad2index.extend(num);\n         for(i = 0; i < num; i++)\n         {  vec_ad2index[i] = play->GetVecInd(i);\n            vec_ad2isvar[i] = false;\n         }\n      }\n      // includes zero order, so initialize conditional skip flags\n      num = play->num_var_op();\n      for(i = 0; i < num; i++)\n         cskip_op[i] = false;\n   }\n\n   // information used by atomic function operators\n\n   // work space used by atomic functions\n   var_op::atomic_op_work<Base> atom_work;\n\n   // information defined by atomic function operators\n   size_t atom_index, atom_id, atom_m, atom_n;\n\n   // length of the parameter vector (used by CppAD assert macros)\n   const size_t num_par = play->num_par_all();\n\n   // pointer to the beginning of the parameter vector\n   CPPAD_ASSERT_UNKNOWN( num_par > 0 )\n   const Base* parameter = play->par_ptr();\n\n   // length of the text vector (used by CppAD assert macros)\n   const size_t num_text = play->num_var_text();\n\n   // pointer to the beginning of the text vector\n   const char* text = nullptr;\n   if( num_text > 0 )\n      text = play->GetTxt(0);\n   /*\n   <!-- end forward0sweep_code_define -->\n   */\n   // temporary indices\n   size_t i;\n\n   // skip the BeginOp at the beginning of the recording\n   play::const_sequential_iterator itr = play->begin();\n   // op_info\n   op_code_var   op;\n   size_t        i_var;\n   const addr_t* arg;\n   itr.op_info(op, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op == BeginOp );\n   //\n# if CPPAD_FORWARD_ANY_TRACE\n   // flag as to when to trace atomic function values\n   bool atom_trace  = true;\n# else\n   bool atom_trace  = false;\n# endif\n   //\n   bool more_operators = true;\n   while(more_operators)\n   {\n      // next op\n      (++itr).op_info(op, arg, i_var);\n      CPPAD_ASSERT_UNKNOWN( itr.op_index() < play->num_var_op() );\n\n      // check if we are skipping this operation\n      while( cskip_op[itr.op_index()] )\n      {  switch(op)\n         {\n            case AFunOp:\n            {  // get information for this atomic function call\n               play::atom_op_info<Base>(\n                  op, arg, atom_index, atom_id, atom_m, atom_n\n               );\n               //\n               // skip to the second AFunOp\n               for(i = 0; i < atom_m + atom_n + 1; ++i)\n                  ++itr;\n# ifndef NDEBUG\n               itr.op_info(op, arg, i_var);\n               CPPAD_ASSERT_UNKNOWN( op == AFunOp );\n# endif\n            }\n            break;\n\n            case CSkipOp:\n            case CSumOp:\n            itr.correct_before_increment();\n            break;\n\n            default:\n            break;\n         }\n         (++itr).op_info(op, arg, i_var);\n      }\n\n      // action depends on the operator\n      switch( op )\n      {\n         case EqppOp:\n         case EqpvOp:\n         case EqvvOp:\n         case LeppOp:\n         case LepvOp:\n         case LevpOp:\n         case LevvOp:\n         case LtppOp:\n         case LtpvOp:\n         case LtvpOp:\n         case LtvvOp:\n         case NeppOp:\n         case NepvOp:\n         case NevvOp:\n         var_op::compare_forward_any(op,\n            arg, parameter, cap_order, taylor, itr.op_index(),\n            change_count, change_number, change_op_index\n         );\n         break;\n         // -------------------------------------------------\n\n         case AbsOp:\n         var_op::abs_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AddvvOp:\n         var_op::addvv_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AddpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::addpv_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AcosOp:\n         // sqrt(1 - x * x), acos(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::acos_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AcoshOp:\n         // sqrt(x * x - 1), acosh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::acosh_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AsinOp:\n         // sqrt(1 - x * x), asin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::asin_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AsinhOp:\n         // sqrt(1 + x * x), asinh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::asinh_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AtanOp:\n         // 1 + x * x, atan(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::atan_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AtanhOp:\n         // 1 - x * x, atanh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::atanh_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case CExpOp:\n         var_op::cexp_forward_any(\n            order_low, order_up, i_var, arg, num_par, parameter, cap_order, taylor\n         );\n         break;\n         // ---------------------------------------------------\n\n         case CosOp:\n         // sin(x), cos(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::cos_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // ---------------------------------------------------\n\n         case CoshOp:\n         // sinh(x), cosh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::cosh_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case CSkipOp:\n         if( order_low == 0 )\n         {  var_op::cskip_forward_0(\n               i_var, arg, num_par, parameter, cap_order, taylor, cskip_op\n            );\n         }\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case CSumOp:\n         var_op::csum_forward_any(\n            order_low, order_up, i_var, arg, num_par, parameter, cap_order, taylor\n         );\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case DisOp:\n         var_op::dis_forward_dir<RecBase>(\n            order_low, order_up, r, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case DivvvOp:\n         var_op::divvv_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case DivpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::divpv_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case DivvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::divvp_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case EndOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 0);\n         more_operators = false;\n         break;\n         // -------------------------------------------------\n\n         case ErfOp:\n         case ErfcOp:\n         var_op::erf_forward_any(\n            op, order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case ExpOp:\n         var_op::exp_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // ---------------------------------------------------\n\n         case Expm1Op:\n         var_op::expm1_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // ---------------------------------------------------\n\n         case InvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         break;\n         // -------------------------------------------------\n\n         case LdpOp:\n         case LdvOp:\n         if( order_low == 0 )\n         {  var_op::load_forward_0(\n               op,\n               i_var,\n               play->num_var_vec_ind(),\n               arg,\n               num_var,\n               num_par,\n               parameter,\n               cap_order,\n               taylor,\n               vec_ad2isvar,\n               vec_ad2index,\n               load_op2var\n            );\n            if(order_low < order_up ) var_op::load_forward_nonzero(\n               op,\n               i_var,\n               arg,\n               order_low + 1,\n               order_up,\n               r,\n               cap_order,\n               load_op2var,\n               taylor\n            );\n         }\n         else\n            var_op::load_forward_nonzero(\n            op,\n            i_var,\n            arg,\n            order_low,\n            order_up,\n            r,\n            cap_order,\n            load_op2var,\n            taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case LogOp:\n         var_op::log_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case Log1pOp:\n         var_op::log1p_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case MulpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::mulpv_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case MulvvOp:\n         var_op::mulvv_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // --------------------------------------------------\n\n         case NegOp:\n         var_op::neg_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case ParOp:\n         var_op::par_forward_any(\n            order_low, order_up, i_var, arg, num_par, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case PowvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::powvp_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case PowpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::powpv_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case PowvvOp:\n         var_op::powvv_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case PriOp:\n         if( ( order_low == 0 ) & print ) var_op::pri_forward_0(s_out,\n            arg, num_text, text, num_par, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case SignOp:\n         // sign(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::sign_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case SinOp:\n         // cos(x), sin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::sin_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case SinhOp:\n         // cosh(x), sinh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::sinh_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case SqrtOp:\n         var_op::sqrt_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case StppOp:\n         case StpvOp:\n         case StvpOp:\n         case StvvOp:\n         if( order_low == 0 )\n         {  var_op::store_forward_0(\n               op,\n               arg,\n               num_var,\n               num_par,\n               parameter,\n               cap_order,\n               taylor,\n               vec_ad2isvar,\n               vec_ad2index\n            );\n         }\n         break;\n         // -------------------------------------------------\n\n         case SubvvOp:\n         var_op::subvv_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case SubpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::subpv_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case SubvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::subvp_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case TanOp:\n         // tan(x)^2, tan(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::tan_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case TanhOp:\n         // tanh(x)^2, tanh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::tanh_forward_any(\n            order_low, order_up, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AFunOp:\n         // start of an atomic function call\n         var_op::atomic_forward_any<Base, RecBase>(\n            itr,\n            play,\n            parameter,\n            atom_trace,\n            atom_work,\n            cap_order,\n            order_low,\n            order_up,\n            taylor\n         );\n         break;\n\n         case FunapOp:\n         case FunavOp:\n         case FunrpOp:\n         case FunrvOp:\n         CPPAD_ASSERT_UNKNOWN( false );\n         break;\n         // -------------------------------------------------\n\n         case ZmulpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::zmulpv_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case ZmulvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::zmulvp_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case ZmulvvOp:\n         var_op::zmulvv_forward_any(\n            order_low, order_up, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n      }\n# if CPPAD_FORWARD_ANY_TRACE\n      Base*           Z_tmp   = taylor + cap_order * i_var;\n      if( op != AFunOp )\n      {\n         printOp<Base, RecBase>(\n            std::cout,\n            play,\n            itr.op_index(),\n            i_var,\n            op,\n            arg\n         );\n         if( NumRes(op) > 0 ) printOpResult(\n            std::cout,\n            order_up + 1,\n            Z_tmp,\n            0,\n            (Base *) nullptr\n         );\n         std::cout << std::endl;\n      }\n   }\n   std::cout << std::endl;\n# else\n   }\n# endif\n   if( ( order_low == 0 ) && (change_count == 0) )\n      change_number = 0;\n   return;\n}\n\n// preprocessor symbols that are local to this file\n# undef CPPAD_FORWARD_ANY_TRACE\n\n} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sweep/forward_dir.hpp",
    "content": "# ifndef CPPAD_LOCAL_SWEEP_FORWARD_DIR_HPP\n# define CPPAD_LOCAL_SWEEP_FORWARD_DIR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/play/atom_op_info.hpp>\n# include <cppad/local/sweep/call_atomic.hpp>\n# include <cppad/local/var_op/atomic_op.hpp>\n\n# define CPPAD_FORWARD_DIR_TRACE 0\n\n// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE\nnamespace CppAD { namespace local { namespace sweep {\n/*\n ------------------------------------------------------------------------------\n{xrst_begin sweep_forward_dir dev}\n{xrst_spell\n   cskip\n}\n\n{xrst_template ;\n   include/cppad/local/sweep/template/forward_sweep.xrst\n\n   headers all:     CPPAD_@NAME@_TRACE, Portotype, Base, RecBase, play, num_var\n   headers all:     cap_order, cskip, load_op2var, taylor\n   headers dir:     order_up, n_dir\n\n   @title@  The title for this forward sweep\n   @#####@  Underlining for the tilte\n   @NAME@   is one of FORWARD_0, FORWARD_ANY, FORWARD_DIR\n   @****@   Underlining for @NAME@\n\n   @title@ ; Compute One Order Multiple Directions Forward Taylor Coefficients\n   @#####@ ; #################################################################\n   @NAME@  ; FORWARD_DIR\n   @****@  ; ***********\n}\n\n{xrst_end sweep_forward_dir}\n*/\n// BEGIN_FORWARD_DIR\ntemplate <class Base, class RecBase>\nvoid forward_dir(\n   const RecBase&              not_used_rec_base,\n   const local::player<Base>*  play,\n   const size_t                num_var,\n   const size_t                cap_order,\n   const bool*                 cskip_op,\n   const pod_vector<addr_t>&   load_op2var,\n   const size_t                order_up,\n   const size_t                n_dir,\n   Base*                       taylor\n)\n// END_FORWARD_DIR\n{\n   CPPAD_ASSERT_UNKNOWN( order_up > 0 );\n   CPPAD_ASSERT_UNKNOWN( cap_order >= order_up + 1 );\n   CPPAD_ASSERT_UNKNOWN( play->num_var() == num_var );\n\n   // only compute one order at a time when using multi-direction forward\n   size_t order_low = order_up;\n\n   // information used by atomic function operators\n\n   // work space used by atomic functions\n   var_op::atomic_op_work<Base> atom_work;\n\n   // information defined by atomic function operators\n   size_t atom_index=0, atom_id=0, atom_m=0, atom_n=0;\n   //\n   // length of the parameter vector (used by CppAD assert macros)\n   const size_t num_par = play->num_par_all();\n\n   // pointer to the beginning of the parameter vector\n   CPPAD_ASSERT_UNKNOWN( num_par > 0 )\n   const Base* parameter = play->par_ptr();\n\n   // temporary indices\n   size_t i;\n\n   // skip the BeginOp at the beginning of the recording\n   play::const_sequential_iterator itr = play->begin();\n   // op_info\n   op_code_var     op;\n   size_t          i_var;\n   const addr_t*   arg;\n   itr.op_info(op, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op == BeginOp );\n# if CPPAD_FORWARD_DIR_TRACE\n   bool atom_trace  = true;\n   std::cout << std::endl;\n   CppAD::vector<Base> Z_vec(order_up + 1);\n# else\n   bool atom_trace = false;\n# endif\n   bool more_operators = true;\n   while(more_operators)\n   {\n      // next op\n      (++itr).op_info(op, arg, i_var);\n      CPPAD_ASSERT_UNKNOWN( itr.op_index() < play->num_var_op() );\n\n      // check if we are skipping this operation\n      while( cskip_op[itr.op_index()] )\n      {  switch(op)\n         {\n            case AFunOp:\n            {  // get information for this atomic function call\n               play::atom_op_info<Base>(\n                  op, arg, atom_index, atom_id, atom_m, atom_n\n               );\n               //\n               // skip to the second AFunOp\n               for(i = 0; i < atom_m + atom_n + 1; ++i)\n                  ++itr;\n# ifndef NDEBUG\n               itr.op_info(op, arg, i_var);\n               CPPAD_ASSERT_UNKNOWN( op == AFunOp );\n# endif\n            }\n            break;\n\n            case CSkipOp:\n            case CSumOp:\n            itr.correct_before_increment();\n            break;\n\n            default:\n            break;\n         }\n         (++itr).op_info(op, arg, i_var);\n      }\n\n      // action depends on the operator\n      switch( op )\n      {\n         case AbsOp:\n         var_op::abs_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AddvvOp:\n         var_op::addvv_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AddpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::addpv_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AcosOp:\n         // sqrt(1 - x * x), acos(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::acos_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AcoshOp:\n         // sqrt(x * x - 1), acosh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::acosh_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AsinOp:\n         // sqrt(1 - x * x), asin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::asin_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AsinhOp:\n         // sqrt(1 + x * x), asinh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::asinh_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AtanOp:\n         // 1 + x * x, atan(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::atan_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AtanhOp:\n         // 1 - x * x, atanh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::atanh_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case CExpOp:\n         var_op::cexp_forward_dir(\n            order_up, n_dir, i_var, arg, num_par, parameter, cap_order, taylor\n         );\n         break;\n         // ---------------------------------------------------\n\n         case CosOp:\n         // sin(x), cos(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::cos_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // ---------------------------------------------------\n\n         case CoshOp:\n         // sinh(x), cosh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::cosh_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case CSkipOp:\n         // CSkipOp only does something on order zero.\n         CPPAD_ASSERT_UNKNOWN( order_low > 0 );\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case CSumOp:\n         var_op::csum_forward_dir(\n            order_up, i_var, arg, num_par, parameter, n_dir, cap_order, taylor\n         );\n         itr.correct_before_increment();\n         break;\n         // -------------------------------------------------\n\n         case DisOp:\n         var_op::dis_forward_dir<RecBase>(\n            order_low, order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case DivvvOp:\n         var_op::divvv_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case DivpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::divpv_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case DivvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::divvp_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case EndOp:\n         // needed for sparse_jacobian test\n         CPPAD_ASSERT_NARG_NRES(op, 0, 0);\n         more_operators = false;\n         break;\n         // -------------------------------------------------\n\n         case ErfOp:\n         case ErfcOp:\n         var_op::erf_forward_dir(\n            op, order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case ExpOp:\n         var_op::exp_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case Expm1Op:\n         var_op::expm1_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case InvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         break;\n         // -------------------------------------------------\n\n         case LdpOp:\n         case LdvOp:\n         var_op::load_forward_nonzero(\n            op,\n            i_var,\n            arg,\n            order_low,\n            order_up,\n            n_dir,\n            cap_order,\n            load_op2var,\n            taylor\n         );\n         break;\n         // ---------------------------------------------------\n\n         case EqppOp:\n         case EqpvOp:\n         case EqvvOp:\n         case LtppOp:\n         case LtpvOp:\n         case LtvpOp:\n         case LtvvOp:\n         case LeppOp:\n         case LepvOp:\n         case LevpOp:\n         case LevvOp:\n         case NeppOp:\n         case NepvOp:\n         case NevvOp:\n         CPPAD_ASSERT_UNKNOWN( order_up > 0 );\n         break;\n         // -------------------------------------------------\n\n         case LogOp:\n         var_op::log_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // ---------------------------------------------------\n\n         case Log1pOp:\n         var_op::log1p_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // ---------------------------------------------------\n\n         case MulpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::mulpv_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case MulvvOp:\n         var_op::mulvv_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case NegOp:\n         var_op::neg_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case ParOp:\n         var_op::par_forward_dir(\n            order_up, n_dir, i_var, arg, num_par, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case PowpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::powpv_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case PowvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::powvp_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case PowvvOp:\n         var_op::powvv_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case PriOp:\n         CPPAD_ASSERT_UNKNOWN( order_up > 0 );\n         break;\n         // -------------------------------------------------\n\n         case SignOp:\n         // sign(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::sign_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case SinOp:\n         // cos(x), sin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::sin_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case SinhOp:\n         // cosh(x), sinh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::sinh_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case SqrtOp:\n         var_op::sqrt_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case StppOp:\n         case StpvOp:\n         case StvpOp:\n         case StvvOp:\n         CPPAD_ASSERT_UNKNOWN( order_up > 0 );\n         break;\n         // -------------------------------------------------\n\n         case SubvvOp:\n         var_op::subvv_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case SubpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::subpv_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case SubvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::subvp_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case TanOp:\n         // tan(x)^2, tan(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::tan_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case TanhOp:\n         // tanh(x)^2, tanh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var  );\n         var_op::tanh_forward_dir(\n            order_up, n_dir, i_var, arg, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case AFunOp:\n         var_op::atomic_forward_dir<Base, RecBase>(\n            itr,\n            play,\n            parameter,\n            atom_trace,\n            atom_work,\n            cap_order,\n            order_up,\n            n_dir,\n            taylor\n         );\n         break;\n\n         case FunapOp:\n         case FunavOp:\n         case FunrpOp:\n         case FunrvOp:\n         break;\n         // -------------------------------------------------\n\n         case ZmulpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::zmulpv_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case ZmulvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::zmulvp_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         case ZmulvvOp:\n         var_op::zmulvv_forward_dir(\n            order_up, n_dir, i_var, arg, parameter, cap_order, taylor\n         );\n         break;\n         // -------------------------------------------------\n\n         default:\n         CPPAD_ASSERT_UNKNOWN(0);\n      }\n# if CPPAD_FORWARD_DIR_TRACE\n      if( op != AFunOp )\n      {  printOp<Base, RecBase>(\n            std::cout,\n            play,\n            itr.op_index(),\n            i_var,\n            op,\n            arg\n         );\n         Base* Z_tmp = nullptr;\n         if( op == FunavOp )\n            Z_tmp = taylor + size_t(arg[0])*((cap_order - 1) * n_dir + 1);\n         else if( NumRes(op) > 0 )\n            Z_tmp = taylor + i_var*((cap_order - 1)*n_dir + 1);\n         if( Z_tmp != nullptr )\n         {  Z_vec[0]    = Z_tmp[0];\n            for(size_t ell = 0; ell < n_dir; ell++)\n            {  std::cout << std::endl << \"     \";\n               for(size_t p_tmp = 1; p_tmp <= order_up; p_tmp++)\n                  Z_vec[p_tmp] = Z_tmp[ (p_tmp-1)*n_dir + ell + 1];\n               printOpResult(\n                  std::cout,\n                  order_up + 1,\n                  Z_vec.data(),\n                  0,\n                  (Base *) nullptr\n               );\n            }\n         }\n         std::cout << std::endl;\n      }\n   }\n   std::cout << std::endl;\n# else\n   }\n# endif\n\n   return;\n}\n\n// preprocessor symbols that are local to this file\n# undef CPPAD_FORWARD_DIR_TRACE\n\n} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sweep/rev_hes.hpp",
    "content": "# ifndef CPPAD_LOCAL_SWEEP_REV_HES_HPP\n# define CPPAD_LOCAL_SWEEP_REV_HES_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/play/atom_op_info.hpp>\n# include <cppad/local/sweep/call_atomic.hpp>\n\n// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE\nnamespace CppAD { namespace local { namespace sweep {\n/*!\n\\file sweep/rev_hes.hpp\nCompute Reverse mode Hessian sparsity patterns.\n*/\n\n/*!\n\\def CPPAD_REV_HES_TRACE\nThis value is either zero or one.\nZero is the normal operational value.\nIf it is one, a trace of every rev_hes_sweep computation is printed.\n*/\n# define CPPAD_REV_HES_TRACE 0\n\n/*!\nGiven the forward Jacobian sparsity pattern for all the variables,\nand the reverse Jacobian sparsity pattern for the dependent variables,\nRevHesSweep computes the Hessian sparsity pattern for all the independent\nvariables.\n\n\\tparam Base\nthis operation sequence was recorded using AD<Base>.\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\\param n\nis the number of independent variables on the tape.\n\n\\param num_var\nis the total number of variables on the tape; i.e.,\n play->num_var().\nThis is also the number of rows in the entire sparsity pattern\n rev_hes_sparse.\n\n\\param play\nThe information stored in play\nis a recording of the operations corresponding to a function\n\\f[\n   F : {\\bf R}^n \\rightarrow {\\bf R}^m\n\\f]\nwhere \\f$ n \\f$ is the number of independent variables\nand \\f$ m \\f$ is the number of dependent variables.\n\n\\param for_jac_sparse\nFor i = 0 , ... , num_var - 1,\n(for all the variables on the tape),\nthe forward Jacobian sparsity pattern for the variable with index i\ncorresponds to the set with index i in for_jac_sparse.\n\n\\param RevJac\n\\b Input:\nFor i = 0, ... , num_var - 1\nthe if the variable with index i on the tape is an dependent variable and\nincluded in the Hessian, RevJac[ i ] is equal to true,\notherwise it is equal to false.\n\\n\n\\n\n\\b Output: The values in RevJac upon return are not specified; i.e.,\nit is used for temporary work space.\n\n\\param rev_hes_sparse\nThe reverse Hessian sparsity pattern for the variable with index i\ncorresponds to the set with index i in rev_hes_sparse.\n\\n\n\\n\n\\b Input: For i = 0 , ... , num_var - 1\nthe reverse Hessian sparsity pattern for the variable with index i is empty.\n\\n\n\\n\n\\b Output: For j = 1 , ... , n,\nthe reverse Hessian sparsity pattern for the independent dependent variable\nwith index (j-1) is given by the set with index j\nin rev_hes_sparse.\nThe values in the rest of rev_hes_sparse are not specified; i.e.,\nthey are used for temporary work space.\n\n\\param not_used_rec_base\nSpecifies RecBase for this call.\n*/\n\ntemplate <class Base, class Vector_set, class RecBase>\nvoid rev_hes(\n   const local::player<Base>* play,\n   size_t                     num_var,\n   const Vector_set&          for_jac_sparse,\n   bool*                      RevJac,\n   Vector_set&                rev_hes_sparse,\n   const RecBase&             not_used_rec_base\n)\n{\n   // length of the parameter vector (used by CppAD assert macros)\n   const size_t num_par = play->num_par_all();\n\n   size_t             i, j, k;\n\n   // check num_var argument\n   CPPAD_ASSERT_UNKNOWN( play->num_var()        == num_var );\n   CPPAD_ASSERT_UNKNOWN( for_jac_sparse.n_set() == num_var );\n   CPPAD_ASSERT_UNKNOWN( rev_hes_sparse.n_set() == num_var );\n   CPPAD_ASSERT_UNKNOWN( num_var > 0 );\n\n   // upper limit exclusive for set elements\n   size_t limit   = rev_hes_sparse.end();\n   CPPAD_ASSERT_UNKNOWN( for_jac_sparse.end() == limit );\n\n   // check number of sets match\n   CPPAD_ASSERT_UNKNOWN(\n      for_jac_sparse.n_set() == rev_hes_sparse.n_set()\n   );\n\n   // vecad_sparsity contains a sparsity pattern for each VecAD object.\n   // vecad_ind maps a VecAD index (beginning of the VecAD object)\n   // to the index for the corresponding set in vecad_sparsity.\n   size_t num_vecad_ind   = play->num_var_vec_ind();\n   size_t num_vecad_vec   = play->num_var_vecad();\n   Vector_set vecad_sparse;\n   pod_vector<size_t> vecad_ind;\n   pod_vector<bool>   vecad_jac;\n   if( num_vecad_vec > 0 )\n   {  size_t length;\n      vecad_sparse.resize(num_vecad_vec, limit);\n      vecad_ind.extend(num_vecad_ind);\n      vecad_jac.extend(num_vecad_vec);\n      j             = 0;\n      for(i = 0; i < num_vecad_vec; i++)\n      {  // length of this VecAD\n         length   = play->GetVecInd(j);\n         // set vecad_ind to proper index for this VecAD\n         vecad_ind[j] = i;\n         // make all other values for this vector invalid\n         for(k = 1; k <= length; k++)\n            vecad_ind[j+k] = num_vecad_vec;\n         // start of next VecAD\n         j       += length + 1;\n         // initialize this vector's reverse jacobian value\n         vecad_jac[i] = false;\n      }\n      CPPAD_ASSERT_UNKNOWN( j == play->num_var_vec_ind() );\n   }\n\n   // ----------------------------------------------------------------------\n   //\n   // work space used by atomic functions\n   var_op::atomic_op_work<Base> atom_work;\n   //\n   // pointer to the beginning of the parameter vector\n   // (used by atomic functions\n   CPPAD_ASSERT_UNKNOWN( num_par > 0 )\n   const Base* parameter = play->par_ptr();\n   //\n   // skip the EndOp at the end of the recording\n   play::const_sequential_iterator itr = play->end();\n   // op_info\n   op_code_var   op;\n   size_t        i_var;\n   const addr_t* arg;\n   itr.op_info(op, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op == EndOp );\n# if CPPAD_REV_HES_TRACE\n   std::cout << std::endl;\n   CppAD::vectorBool zf_value(limit);\n   CppAD::vectorBool zh_value(limit);\n   bool atom_trace = true;\n# else\n   bool atom_trace = false;\n# endif\n   bool more_operators = true;\n   while(more_operators)\n   {  bool linear[3];\n      //\n      // next op\n      (--itr).op_info(op, arg, i_var);\n\n      // rest of information depends on the case\n      switch( op )\n      {  //\n         // linear operators with one primary result\n         // and where the first argument is the only variable\n         case AbsOp:\n         case DivvpOp:\n         case NegOp:\n         case SubvpOp:\n         case ZmulvpOp:\n         CPPAD_ASSERT_UNKNOWN( 0 < NumArg(op) );\n         linear[0] = true;\n         var_op::one_var_rev_hes(\n            i_var, size_t(arg[0]), linear,\n            RevJac, for_jac_sparse, rev_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         // non-linear operators with one primary result\n         // and where the first argument is the only variable\n         case AcosOp:\n         case AcoshOp:\n         case AsinOp:\n         case AsinhOp:\n         case AtanOp:\n         case AtanhOp:\n         case CosOp:\n         case CoshOp:\n         case ErfOp:\n         case ErfcOp:\n         case ExpOp:\n         case Expm1Op:\n         case LogOp:\n         case Log1pOp:\n         case PowvpOp:\n         case SinOp:\n         case SinhOp:\n         case SqrtOp:\n         case TanOp:\n         case TanhOp:\n         CPPAD_ASSERT_UNKNOWN( 0 < NumArg(op) );\n         linear[0] = false;\n         var_op::one_var_rev_hes(\n            i_var, size_t(arg[0]), linear,\n            RevJac, for_jac_sparse, rev_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         // linear and non-liner operators with one primary result\n         // and where the second argument is the only variable\n         case AddpvOp:\n         case MulpvOp:\n         case SubpvOp:\n         case ZmulpvOp:\n         CPPAD_ASSERT_UNKNOWN( 1 < NumArg(op) );\n         linear[0] = true;\n         var_op::one_var_rev_hes(\n            i_var, size_t(arg[1]), linear,\n            RevJac, for_jac_sparse, rev_hes_sparse\n         );\n         break;\n\n         case PowpvOp:\n         case DivpvOp:\n         CPPAD_ASSERT_UNKNOWN( 1 < NumArg(op) );\n         linear[0] = false;\n         var_op::one_var_rev_hes(\n            i_var, size_t(arg[1]), linear,\n            RevJac, for_jac_sparse, rev_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         case AddvvOp:\n         case SubvvOp:\n         linear[0] = true;\n         linear[1] = true;\n         linear[2] = true;\n         var_op::two_var_rev_hes(\n            i_var, arg, linear, RevJac, for_jac_sparse, rev_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         case BeginOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1)\n         more_operators = false;\n         break;\n         // -------------------------------------------------\n\n         case CSkipOp:\n         itr.correct_after_decrement(arg);\n         break;\n         // -------------------------------------------------\n\n         case CSumOp:\n         itr.correct_after_decrement(arg);\n         var_op::csum_rev_hes(\n            i_var, arg, RevJac, rev_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         case CExpOp:\n         var_op::cexp_rev_hes(\n            i_var, arg, num_par, RevJac, rev_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         case DisOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1)\n         // derivativve is identically zero\n         break;\n         // -------------------------------------------------\n\n         case DivvvOp:\n         linear[0] = true;\n         linear[1] = false;\n         linear[2] = false;\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1)\n         var_op::two_var_rev_hes(\n            i_var, arg, linear, RevJac, for_jac_sparse, rev_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         case InvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1)\n         // Z is already defined\n         break;\n         // -------------------------------------------------\n\n         case LdpOp:\n         case LdvOp:\n         var_op::load_rev_hes(\n            op,\n            arg,\n            num_vecad_ind,\n            i_var,\n            vecad_ind,\n            rev_hes_sparse,\n            vecad_sparse,\n            RevJac,\n            vecad_jac\n         );\n         break;\n         // -------------------------------------------------\n\n         case EqppOp:\n         case EqpvOp:\n         case EqvvOp:\n         case LtppOp:\n         case LtpvOp:\n         case LtvpOp:\n         case LtvvOp:\n         case LeppOp:\n         case LepvOp:\n         case LevpOp:\n         case LevvOp:\n         case NeppOp:\n         case NepvOp:\n         case NevvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 0);\n         break;\n         // -------------------------------------------------\n\n         case MulvvOp:\n         case ZmulvvOp:\n         linear[0] = true;\n         linear[1] = true;\n         linear[2] = false;\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1)\n         var_op::two_var_rev_hes(\n            i_var, arg, linear, RevJac, for_jac_sparse, rev_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         case ParOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1)\n         break;\n         // -------------------------------------------------\n\n         case PowvvOp:\n         linear[0] = false;\n         linear[1] = false;\n         linear[2] = false;\n         CPPAD_ASSERT_NARG_NRES(op, 2, 3)\n         var_op::two_var_rev_hes(\n            i_var, arg, linear, RevJac, for_jac_sparse, rev_hes_sparse\n         );\n         break;\n         // -------------------------------------------------\n\n         case PriOp:\n         CPPAD_ASSERT_NARG_NRES(op, 5, 0);\n         break;\n         // -------------------------------------------------\n\n         case SignOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1);\n         // Derivative is identiaclly zero\n         break;\n         // -------------------------------------------------\n\n         case StppOp:\n         case StpvOp:\n         case StvpOp:\n         case StvvOp:\n         var_op::store_rev_hes(\n            op,\n            arg,\n            num_vecad_ind,\n            vecad_ind,\n            rev_hes_sparse,\n            vecad_sparse,\n            RevJac,\n            vecad_jac\n         );\n         break;\n         // -------------------------------------------------\n\n         case AFunOp:\n         var_op::atomic_rev_hes<Vector_set, Base, RecBase>(\n            itr,\n            play,\n            parameter,\n            atom_trace,\n            atom_work,\n            for_jac_sparse,\n            RevJac,\n            rev_hes_sparse\n         );\n         break;\n\n         case FunapOp:\n         case FunavOp:\n         case FunrpOp:\n         case FunrvOp:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         // -------------------------------------------------\n\n         default:\n         CPPAD_ASSERT_UNKNOWN(0);\n      }\n# if CPPAD_REV_HES_TRACE\n      if( op != AFunOp )\n      {  for(j = 0; j < limit; j++)\n         {  zf_value[j] = false;\n            zh_value[j] = false;\n         }\n         typename Vector_set::const_iterator itr_jac(for_jac_sparse, i_var);\n         j = *itr_jac;\n         while( j < limit )\n         {  zf_value[j] = true;\n            j = *(++itr_jac);\n         }\n         typename Vector_set::const_iterator itr_hes(rev_hes_sparse, i_var);\n         j = *itr_hes;\n         while( j < limit )\n         {  zh_value[j] = true;\n            j = *(++itr_hes);\n         }\n         printOp<Base, RecBase>(\n            std::cout,\n            play,\n            itr.op_index(),\n            i_var,\n            op,\n            arg\n         );\n         // should also print RevJac[i_var], but printOpResult does not\n         // yet allow for this\n         if( NumRes(op) > 0 && op != BeginOp ) printOpResult(\n            std::cout,\n            1,\n            &zf_value,\n            1,\n            &zh_value\n         );\n         std::cout << std::endl;\n      }\n   }\n   std::cout << std::endl;\n# else\n   }\n# endif\n   // values corresponding to BeginOp\n   CPPAD_ASSERT_UNKNOWN( itr.op_index() == 0 );\n   CPPAD_ASSERT_UNKNOWN( i_var == 0 );\n\n   return;\n}\n} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE\n\n// preprocessor symbols that are local to this file\n# undef CPPAD_REV_HES_TRACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sweep/rev_jac.hpp",
    "content": "# ifndef CPPAD_LOCAL_SWEEP_REV_JAC_HPP\n# define CPPAD_LOCAL_SWEEP_REV_JAC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/play/atom_op_info.hpp>\n# include <cppad/local/sweep/call_atomic.hpp>\n\n// This value is either zero or one.  Zero is the normal operational value.\n// If it is one, a trace of every rev_jac_sweep computation is printed.\n# define CPPAD_REV_JAC_TRACE 0\n\n/*\n{xrst_begin local_sweep_rev_jac dev}\n{xrst_spell\n   setvec\n}\n\nReverse Mode Jacobian Sparsity Patterns\n#######################################\n\nSyntax\n******\n| ``local::sweep::rev_jac`` (\n| |tab| *play*               ,\n| |tab| *dependency*         ,\n| |tab| *n*                  ,\n| |tab| *num_var*        ,\n| |tab| *var_sparsity*       ,\n| |tab| ``not_used_rec_base``\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nBase\n****\nthis operation sequence was recorded using ``AD`` < *Base* > .\n\nVector_set\n**********\nis the type used for vectors of sets. It can be either\n``sparse::pack_setvec`` or ``sparse::list_setvec`` .\n{xrst_comment 2DO: in previous line change code to cref}\n\nRecBase\n*******\nIs the base type when this function was recorded.\nThis is different from *Base* if\nthis function object was created by :ref:`base2ad-name` .\n\nplay\n****\nThe information stored in play\nis a recording of the operations corresponding to a function\n:math:`F : \\B{R}^n \\rightarrow \\B{R}^m`\nwhere *m* is the number of dependent variables.\n\ndependency\n**********\nAre we computing dependency relations, or only concerned with\npossibly non-zero derivatives. For example,\nare the derivatives with respect to\n*left* and *right* of the expression below\nconsidered to be non-zero:\n\n   ``CondExpRel`` ( *left* , *right* , *if_true* , *if_false* )\n\nThis is used by the optimizer to obtain the correct dependency relations.\n\nn\n*\nis the number of independent variables in the tape.\n\nnum_var\n*******\nis the total number of variables in the tape; i.e.,\n*play* ``->num_var`` () .\nThis is also the number of rows in all the sparsity patterns.\n\nvar_sparsity\n************\n\nOn Input\n========\nFor *i* = 0 , ... , *num_var* ``-1`` ,\nif *i* corresponds to a dependent variables,\nthe set with index *i* is an input.\nOtherwise the set with index *i* is empty.\n\nOn Output\n=========\nFor *i* = 0 , ... , *num_var* ``-1`` ,\nthe sparsity pattern for the variable with index *j* ``-1``\nis given by the set with index *j* in *var_sparsity* .\nNote that one dependent variable may depend on the value of another,\nin which case its output sparsity pattern may be different than its\ninput pattern.\n\nnot_used_rec_base\n*****************\nSpecifies *RecBase* for this call.\n\n{xrst_end local_sweep_rev_jac}\n*/\n\n// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE\nnamespace CppAD { namespace local { namespace sweep {\n\n// BEGIN_PROTOTYPE\ntemplate <class Base, class Vector_set, class RecBase>\nvoid rev_jac(\n   const local::player<Base>* play               ,\n   bool                       dependency         ,\n   size_t                     n                  ,\n   size_t                     num_var            ,\n   Vector_set&                var_sparsity       ,\n   const RecBase&             not_used_rec_base  )\n// END_PROTOTYPE\n{\n   size_t            i, j, k;\n\n   // length of the parameter vector (used by CppAD assert macros)\n   const size_t num_par = play->num_par_all();\n\n   // check num_var argument\n   CPPAD_ASSERT_UNKNOWN( num_var > 0 );\n   CPPAD_ASSERT_UNKNOWN( play->num_var()       == num_var );\n   CPPAD_ASSERT_UNKNOWN( var_sparsity.n_set() == num_var );\n\n   // upper limit (exclusive) for elements in the set\n   size_t limit = var_sparsity.end();\n\n   // vecad_sparsity contains a sparsity pattern for each VecAD object.\n   // vecad_ind maps a VecAD index (beginning of the VecAD object)\n   // to the index of the corresponding set in vecad_sparsity.\n   size_t num_vecad_ind   = play->num_var_vec_ind();\n   size_t num_vecad_vec   = play->num_var_vecad();\n   Vector_set  vecad_sparsity;\n   pod_vector<size_t> vecad_ind;\n   if( num_vecad_vec > 0 )\n   {  size_t length;\n      vecad_sparsity.resize(num_vecad_vec, limit);\n      vecad_ind.extend(num_vecad_ind);\n      j             = 0;\n      for(i = 0; i < num_vecad_vec; i++)\n      {  // length of this VecAD\n         length   = play->GetVecInd(j);\n         // set to proper index for this VecAD\n         vecad_ind[j] = i;\n         for(k = 1; k <= length; k++)\n            vecad_ind[j+k] = num_vecad_vec; // invalid index\n         // start of next VecAD\n         j       += length + 1;\n      }\n      CPPAD_ASSERT_UNKNOWN( j == play->num_var_vec_ind() );\n   }\n   // ----------------------------------------------------------------------\n   //\n   // work space used by atomic functions\n   var_op::atomic_op_work<Base> atom_work;\n   //\n   // pointer to the beginning of the parameter vector\n   // (used by atomic functions\n   CPPAD_ASSERT_UNKNOWN( num_par > 0 )\n   const Base* parameter = play->par_ptr();\n   //\n   // skip the EndOp at the end of the recording\n   play::const_sequential_iterator itr = play->end();\n   // op_info\n   op_code_var   op;\n   size_t        i_var;\n   const addr_t* arg;\n   itr.op_info(op, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op == EndOp );\n# if CPPAD_REV_JAC_TRACE\n   std::cout << std::endl;\n   CppAD::vectorBool z_value(limit);\n   bool atom_trace = true;\n# else\n   bool atom_trace = false;\n# endif\n   bool more_operators = true;\n   while(more_operators)\n   {  //\n      // next op\n      (--itr).op_info(op, arg, i_var);\n\n      // rest of information depends on the case\n      switch( op )\n      {  //\n         // operators with one primary result and\n         // where the first argument is the only variable\n         case AbsOp:\n         case AcosOp:\n         case AcoshOp:\n         case AsinOp:\n         case AsinhOp:\n         case AtanOp:\n         case AtanhOp:\n         case CosOp:\n         case CoshOp:\n         case DivvpOp:\n         case ErfOp:\n         case ErfcOp:\n         case ExpOp:\n         case Expm1Op:\n         case LogOp:\n         case NegOp:\n         case Log1pOp:\n         case PowvpOp:\n         case SinOp:\n         case SinhOp:\n         case SqrtOp:\n         case SubvpOp:\n         case TanOp:\n         case TanhOp:\n         case ZmulvpOp:\n         CPPAD_ASSERT_UNKNOWN( 0 < NumArg(op) );\n         var_op::one_var_rev_jac(\n            i_var, size_t(arg[0]), var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         // operators with one primary result and\n         // where the second argument is the only variable\n         case AddpvOp:\n         case DivpvOp:\n         case MulpvOp:\n         case PowpvOp:\n         case SubpvOp:\n         case ZmulpvOp:\n         CPPAD_ASSERT_UNKNOWN( 1 < NumArg(op) );\n         var_op::one_var_rev_jac(\n            i_var, size_t(arg[1]), var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case AddvvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         var_op::two_var_rev_jac(\n            i_var, arg, var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case BeginOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1);\n         more_operators = false;\n         break;\n         // -------------------------------------------------\n\n         case CSkipOp:\n         itr.correct_after_decrement(arg);\n         break;\n         // -------------------------------------------------\n\n         case CSumOp:\n         itr.correct_after_decrement(arg);\n         var_op::csum_rev_jac(\n            i_var, arg, var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case CExpOp:\n         var_op::cexp_rev_jac(\n            dependency, i_var, arg, num_par, var_sparsity\n         );\n         break;\n         // ---------------------------------------------------\n\n         case DisOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         // derivative is identically zero but dependency is not\n         if( dependency ) var_op::one_var_rev_jac(\n            i_var, size_t(arg[1]), var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case DivvvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         var_op::two_var_rev_jac(\n            i_var, arg, var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case InvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 0, 1);\n         break;\n         // -------------------------------------------------\n\n         case LdpOp:\n         case LdvOp:\n         var_op::load_rev_jac(\n            op,\n            num_vecad_ind,\n            i_var,\n            arg,\n            dependency,\n            vecad_ind,\n            var_sparsity,\n            vecad_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case EqppOp:\n         case EqpvOp:\n         case EqvvOp:\n         case LtppOp:\n         case LtpvOp:\n         case LtvpOp:\n         case LtvvOp:\n         case LeppOp:\n         case LepvOp:\n         case LevpOp:\n         case LevvOp:\n         case NeppOp:\n         case NepvOp:\n         case NevvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 0);\n         break;\n         // -------------------------------------------------\n\n         case MulvvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         var_op::two_var_rev_jac(\n            i_var, arg, var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case ParOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1);\n\n         break;\n         // -------------------------------------------------\n\n         case PowvvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 3);\n         var_op::two_var_rev_jac(\n            i_var, arg, var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case PriOp:\n         CPPAD_ASSERT_NARG_NRES(op, 5, 0);\n         break;\n         // -------------------------------------------------\n\n         case SignOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1);\n         // derivative is identically zero but dependency is not\n         if( dependency ) var_op::one_var_rev_jac(\n            i_var, size_t(arg[0]), var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case StppOp:\n         case StpvOp:\n         case StvpOp:\n         case StvvOp:\n         var_op::store_rev_jac(\n            op,\n            num_vecad_ind,\n            arg,\n            dependency,\n            vecad_ind,\n            var_sparsity,\n            vecad_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case SubvvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         var_op::two_var_rev_jac(\n            i_var, arg, var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         case AFunOp:\n         var_op::atomic_rev_jac<Vector_set, Base, RecBase>(\n            itr,\n            play,\n            parameter,\n            atom_trace,\n            atom_work,\n            dependency,\n            var_sparsity\n         );\n         break;\n\n         case FunapOp:\n         case FunavOp:\n         case FunrpOp:\n         case FunrvOp:\n         CPPAD_ASSERT_UNKNOWN( false );\n         break;\n         // -------------------------------------------------\n\n         case ZmulvvOp:\n         CPPAD_ASSERT_NARG_NRES(op, 2, 1);\n         var_op::two_var_rev_jac(\n            i_var, arg, var_sparsity\n         );\n         break;\n         // -------------------------------------------------\n\n         default:\n         CPPAD_ASSERT_UNKNOWN(0);\n      }\n# if CPPAD_REV_JAC_TRACE\n      if( op != AFunOp )\n      {  for(j = 0; j < limit; j++)\n            z_value[j] = false;\n         typename Vector_set::const_iterator itr_sparse(var_sparsity, i_var);\n         j = *itr_sparse;\n         while( j < limit )\n         {  z_value[j] = true;\n            j          = *(++itr_sparse);\n         }\n         printOp<Base, RecBase>(\n            std::cout,\n            play,\n            itr.op_index(),\n            i_var,\n            op,\n            arg\n         );\n         // Note that sparsity for FunrvOp are computed before call to\n         // atomic function so no need to delay printing (as in forward mode)\n         if( NumRes(op) > 0 && op != BeginOp ) printOpResult(\n            std::cout,\n            0,\n            (CppAD::vectorBool *) nullptr,\n            1,\n            &z_value\n         );\n         std::cout << std::endl;\n      }\n   }\n   std::cout << std::endl;\n# else\n   }\n# endif\n   // values corresponding to BeginOp\n   CPPAD_ASSERT_UNKNOWN( itr.op_index() == 0 );\n   CPPAD_ASSERT_UNKNOWN( i_var == 0 );\n\n   return;\n}\n\n// preprocessor symbols that are local to this file\n# undef CPPAD_REV_JAC_TRACE\n\n} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/sweep/reverse.hpp",
    "content": "# ifndef CPPAD_LOCAL_SWEEP_REVERSE_HPP\n# define CPPAD_LOCAL_SWEEP_REVERSE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\n# include <cppad/local/play/atom_op_info.hpp>\n\n// BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE\nnamespace CppAD { namespace local { namespace sweep {\n/*!\n\\file sweep/reverse.hpp\nCompute derivatives of arbitrary order Taylor coefficients.\n*/\n\n/*!\n\\def CPPAD_REVERSE_TRACE\nThis value is either zero or one.\nZero is the normal operational value.\nIf it is one, a trace of every reverse_sweep computation is printed.\n*/\n# define CPPAD_REVERSE_TRACE 0\n\n/*!\nCompute derivative of arbitrary order forward mode Taylor coefficients.\n\n\\tparam Base\nthis operation sequence was recorded using AD<Base>\nand computations by this routine are done using type Base.\n\n\\param n\nis the number of independent variables on the tape.\n\n\\param num_var\nis the total number of variables on the tape.\nThis is also equal to the number of rows in the matrix Taylor; i.e.,\nplay->num_var().\n\n\\param play\nThe information stored in play\nis a recording of the operations corresponding to the function\n\\f[\n   F : {\\bf R}^n \\rightarrow {\\bf R}^m\n\\f]\nwhere \\f$ n \\f$ is the number of independent variables and\n\\f$ m \\f$ is the number of dependent variables.\nWe define \\f$ u^{(k)} \\f$ as the value of <code>x_k</code> in the previous call\nof the form\n<code>\n   f.Forward(k, x_k)\n</code>\nWe define\n\\f$ X : {\\bf R}^{n \\times d} \\rightarrow {\\bf R}^n \\f$ by\n\\f[\n   X(t, u) =  u^{(0)} + u^{(1)} t + \\cdots + u^{(d)} t^d\n\\f]\nWe define\n\\f$ Y : {\\bf R}^{n \\times d} \\rightarrow {\\bf R}^m \\f$ by\n\\f[\n   Y(t, u) =  F[ X(t, u) ]\n\\f]\nWe define the function\n\\f$ W : {\\bf R}^{n \\times d} \\rightarrow {\\bf R} \\f$ by\n\\f[\nW(u)\n=\n\\sum_{k=0}^{d} ( w^{(k)} )^{\\rm T}\n   \\frac{1}{k !} \\frac{\\partial^k}{\\partial t^k} Y(0, u)\n\\f]\n(The matrix \\f$ w \\in {\\bf R}^m \\f$,\nis defined below under the heading Partial.)\nNote that the scale factor  1 / k  converts\nthe k-th partial derivative to the k-th order Taylor coefficient.\nThis routine computes the derivative of \\f$ W(u) \\f$\nwith respect to all the Taylor coefficients\n\\f$ u^{(k)} \\f$ for \\f$ k = 0 , ... , d \\f$.\n\n\\param J\nIs the number of columns in the coefficient matrix Taylor.\nThis must be greater than or equal d + 1.\n\n\\param Taylor\nFor i = 1 , ... , num_var, and for k = 0 , ... , d,\n Taylor [ i * J + k ]\nis the k-th order Taylor coefficient corresponding to\nvariable with index i on the tape.\nThe value \\f$ u \\in {\\bf R}^{n \\times d} \\f$,\nat which the derivative is computed,\nis defined by\n\\f$ u_j^{(k)} \\f$ = Taylor [ j * J + k ]\nfor j = 1 , ... , n, and for k = 0 , ... , d.\n\n\\param K\nIs the number of columns in the partial derivative matrix Partial.\nIt must be greater than or equal d + 1.\n\n\\param Partial\n\\b Input:\nThe last \\f$ m \\f$ rows of Partial are inputs.\nThe matrix \\f$ w \\f$, used to define \\f$ W(u) \\f$,\nis specified by these rows.\nFor i = 0 , ... , m - 1,\nfor k = 0 , ... , d,\n<code>Partial [ (num_var - m + i ) * K + k ] = w[i,k]</code>.\n\\n\n\\n\n\\b Temporary:\nFor i = n+1 , ... , num_var - 1 and for k = 0 , ... , d,\nthe value of Partial [ i * K + k ] is used for temporary work space\nand its output value is not defined.\n\\n\n\\n\n\\b Output:\nFor j = 1 , ... , n and for k = 0 , ... , d,\n Partial [ j * K + k ]\nis the partial derivative of \\f$ W( u ) \\f$ with\nrespect to \\f$ u_j^{(k)} \\f$.\n\n\\param cskip_op\nIs a vector with size play->num_var_op().\nIf cskip_op[i] is true, the operator index i in the recording\ndoes not affect any of the dependent variable (given the value\nof the independent variables).\nNote that all the operators in an atomic function call are skipped as a block,\nso only the last AFunOp fore each call needs to have cskip_op[i] true.\n\n\\param load_op2var\nis a vector with size play->num_var_load().\nIt contains the variable index corresponding to each load instruction.\nIn the case where the index is zero,\nthe instruction corresponds to a parameter (not variable).\n\n\\tparam Iterator\nThis is either player::const_iteratoror player::const_subgraph_iterator.\n\n\\param play_itr\nOn input this is either play->end(), for the entire graph,\nor play->end(subgraph), for a subgraph.\nThis routine mode will use --play_itr to iterate over the graph or subgraph.\nIt is assumes that the iterator starts just past the EndOp and it will\ncontinue until it reaches the BeginOp.\nIf i_var is a variable index, and the corresponding operator\nis not in the subgraph,\nthen the partials with respect to i_var are not modified and need to be\ninitialized as zero. Note that this means the partial for the independent\nvariables, that are not in the subgraph are not calculated.\nIf part of an atomic function call is in the subgraph,\nthe entire atomic function call must be in the subgraph.\n\n\\param not_used_rec_base\nSpecifies RecBase for this call.\n\n\\par Assumptions\nThe first operator on the tape is a BeginOp,\nand the next n operators are InvOp operations for the\ncorresponding independent variables; see play->check_inv_op(n_ind).\n*/\ntemplate <class Base, class Iterator, class RecBase>\nvoid reverse(\n   size_t                      num_var,\n   const local::player<Base>*  play,\n   size_t                      cap_order,\n   const Base*                 Taylor,\n   size_t                      K,\n   Base*                       Partial,\n   bool*                       cskip_op,\n   const pod_vector<addr_t>&   load_op2var,\n   Iterator&                   play_itr,\n   const RecBase&              not_used_rec_base\n)\n{\n   // check num_var argument\n   CPPAD_ASSERT_UNKNOWN( play->num_var() == num_var );\n   CPPAD_ASSERT_UNKNOWN( num_var > 0 );\n\n   // length of the parameter vector (used by CppAD assert macros)\n   const size_t num_par = play->num_par_all();\n\n   // pointer to the beginning of the parameter vector\n   CPPAD_ASSERT_UNKNOWN( num_par > 0 )\n   const Base* parameter = play->par_ptr();\n\n   // work space used by atomic functions\n   var_op::atomic_op_work<Base> atom_work;\n\n   //\n   // information defined by atomic forward\n   size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0;\n\n   // A vector with unspecified contents declared here so that operator\n   // routines do not need to re-allocate it\n   vector<Base> work;\n\n   // Initialize\n# if CPPAD_REVERSE_TRACE\n   std::cout << std::endl;\n   bool atom_trace = true;\n# else\n   bool atom_trace = false;\n# endif\n   op_code_var   op;\n   const addr_t* arg;\n   size_t        i_var;\n   play_itr.op_info(op, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op == EndOp );\n   while(op != BeginOp )\n   {  //\n      // next op\n      (--play_itr).op_info(op, arg, i_var);\n\n      // check if we are skipping this operation\n      size_t i_op = play_itr.op_index();\n      while( cskip_op[i_op] )\n      {  switch(op)\n         {\n            case CSumOp:\n            case CSkipOp:\n            // cases that never happen but the code reads better with them\n            play_itr.correct_after_decrement(arg);\n            break;\n\n            case AFunOp:\n            {  // get information for this atomic function call\n               play::atom_op_info<Base>(\n                  op, arg, atom_index, atom_old, atom_m, atom_n\n               );\n               //\n               // skip to the first AFunOp\n               for(size_t i = 0; i < atom_m + atom_n + 1; ++i)\n                  --play_itr;\n               play_itr.op_info(op, arg, i_var);\n               CPPAD_ASSERT_UNKNOWN( op == AFunOp );\n            }\n            break;\n\n            default:\n            break;\n         }\n         (--play_itr).op_info(op, arg, i_var);\n         i_op = play_itr.op_index();\n      }\n# if CPPAD_REVERSE_TRACE\n      if( op != AFunOp )\n      {\n         size_t       i_tmp  = i_var;\n         const Base*  Z_tmp  = Taylor + i_var * cap_order;\n         const Base*  pZ_tmp = Partial + i_var * K;\n         printOp<Base, RecBase>(\n            std::cout,\n            play,\n            i_op,\n            i_tmp,\n            op,\n            arg\n         );\n         if( NumRes(op) > 0 && op != BeginOp ) printOpResult(\n            std::cout,\n            K,\n            Z_tmp,\n            K,\n            pZ_tmp\n         );\n         std::cout << std::endl;\n      }\n# endif\n      switch( op )\n      {\n         case AbsOp:\n         var_op::abs_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case AcosOp:\n         // sqrt(1 - x * x), acos(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var );\n         var_op::acos_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case AcoshOp:\n         // sqrt(x * x - 1), acosh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var );\n         var_op::acosh_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case AddvvOp:\n         var_op::addvv_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case AddpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::addpv_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case AsinOp:\n         // sqrt(1 - x * x), asin(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var );\n         var_op::asin_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case AsinhOp:\n         // sqrt(1 + x * x), asinh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var );\n         var_op::asinh_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case AtanOp:\n         // 1 + x * x, atan(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var );\n         var_op::atan_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // -------------------------------------------------\n\n         case AtanhOp:\n         // 1 - x * x, atanh(x)\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var );\n         var_op::atanh_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // -------------------------------------------------\n\n         case BeginOp:\n         CPPAD_ASSERT_NARG_NRES(op, 1, 1);\n         CPPAD_ASSERT_UNKNOWN( i_op == 0 );\n         break;\n         // --------------------------------------------------\n\n         case CSkipOp:\n         // CSkipOp has a zero order forward action.\n         play_itr.correct_after_decrement(arg);\n         break;\n         // -------------------------------------------------\n\n         case CSumOp:\n         play_itr.correct_after_decrement(arg);\n         var_op::csum_reverse(\n            i_var, arg, K, Partial\n         );\n         // end of a cumulative summation\n         break;\n         // -------------------------------------------------\n\n         case CExpOp:\n         var_op::cexp_reverse(\n            i_var,\n            arg,\n            num_par,\n            parameter,\n            cap_order,\n            Taylor,\n            K,\n            Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case CosOp:\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var );\n         var_op::cos_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case CoshOp:\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var );\n         var_op::cosh_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case DisOp:\n         // Derivative of discrete operation is zero so no\n         // contribution passes through this operation.\n         break;\n         // --------------------------------------------------\n\n         case DivvvOp:\n         var_op::divvv_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case DivpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::divpv_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case DivvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::divvp_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n         case EndOp:\n         CPPAD_ASSERT_UNKNOWN(\n            i_op == play->num_var_op() - 1\n         );\n         break;\n\n         // --------------------------------------------------\n\n         case ErfOp:\n         case ErfcOp:\n         var_op::erf_reverse(\n            op, i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case ExpOp:\n         var_op::exp_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case Expm1Op:\n         var_op::expm1_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case InvOp:\n         break;\n         // --------------------------------------------------\n\n         case LdpOp:\n         case LdvOp:\n         var_op::load_reverse(\n            op, i_var, arg, load_op2var, cap_order, K, Partial\n         );\n         break;\n         // -------------------------------------------------\n\n         case EqppOp:\n         case EqpvOp:\n         case EqvvOp:\n         case LtppOp:\n         case LtpvOp:\n         case LtvpOp:\n         case LtvvOp:\n         case LeppOp:\n         case LepvOp:\n         case LevpOp:\n         case LevvOp:\n         case NeppOp:\n         case NepvOp:\n         case NevvOp:\n         break;\n         // -------------------------------------------------\n\n         case LogOp:\n         var_op::log_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case Log1pOp:\n         var_op::log1p_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case MulpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::mulpv_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case MulvvOp:\n         var_op::mulvv_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // -------------------------------------------------\n\n         case NegOp:\n         var_op::neg_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case ParOp:\n         break;\n         // --------------------------------------------------\n\n         case PowvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::powvp_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial, work\n         );\n         break;\n         // -------------------------------------------------\n\n         case PowpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::powpv_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // -------------------------------------------------\n\n         case PowvvOp:\n         var_op::powvv_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case PriOp:\n         // no result so nothing to do\n         break;\n         // --------------------------------------------------\n\n         case SignOp:\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var );\n         var_op::sign_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // -------------------------------------------------\n\n         case SinOp:\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var );\n         var_op::sin_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // -------------------------------------------------\n\n         case SinhOp:\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var );\n         var_op::sinh_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case SqrtOp:\n         var_op::sqrt_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case StppOp:\n         break;\n         // --------------------------------------------------\n\n         case StpvOp:\n         break;\n         // -------------------------------------------------\n\n         case StvpOp:\n         break;\n         // -------------------------------------------------\n\n         case StvvOp:\n         break;\n         // --------------------------------------------------\n\n         case SubvvOp:\n         var_op::subvv_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case SubpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::subpv_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case SubvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::subvp_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // -------------------------------------------------\n\n         case TanOp:\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var );\n         var_op::tan_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // -------------------------------------------------\n\n         case TanhOp:\n         CPPAD_ASSERT_UNKNOWN( i_var < num_var );\n         var_op::tanh_reverse(\n            i_var, arg, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case AFunOp:\n         var_op::atomic_reverse<Base, RecBase, Iterator>(\n            play_itr,\n            play,\n            parameter,\n            atom_trace,\n            atom_work,\n            cap_order,\n            K,\n            Taylor,\n            Partial\n         );\n         break;\n\n         case FunapOp:\n         case FunavOp:\n         case FunrpOp:\n         case FunrvOp:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         // ------------------------------------------------------------\n\n         case ZmulpvOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n         var_op::zmulpv_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case ZmulvpOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n         var_op::zmulvp_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         case ZmulvvOp:\n         var_op::zmulvv_reverse(\n            i_var, arg, parameter, cap_order, Taylor, K, Partial\n         );\n         break;\n         // --------------------------------------------------\n\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n      }\n   }\n# if CPPAD_REVERSE_TRACE\n   std::cout << std::endl;\n# endif\n}\n\n} } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE\n\n// preprocessor symbols that are local to this file\n# undef CPPAD_REVERSE_TRACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/temp_file.hpp",
    "content": "# ifndef CPPAD_LOCAL_TEMP_FILE_HPP\n# define CPPAD_LOCAL_TEMP_FILE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <string>\n# include <iostream>\n\nnamespace CppAD { namespace local {\n   std::string temp_file(void);\n} }\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/utility/cppad_vector_itr.hpp",
    "content": "# ifndef CPPAD_LOCAL_UTILITY_CPPAD_VECTOR_ITR_HPP\n# define CPPAD_LOCAL_UTILITY_CPPAD_VECTOR_ITR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cstddef>\n# include <cppad/core/cppad_assert.hpp>\n/*\n------------------------------------------------------------------------------\n{xrst_begin cppad_vector_itr_define dev}\n{xrst_spell\n   undef\n}\n\nVector Class Iterator Preprocessor Definitions\n##############################################\n\nSyntax\n******\n{xrst_code cpp}\n# define CPPAD_CONST 0\n# include <cppad/local/utility/cppad_vector_itr.hpp>\n# undef CPPAD_LOCAL_UTILITY_CPPAD_VECTOR_ITR_HPP\n# define CPPAD_CONST 1\n# include <cppad/local/utility/cppad_vector_itr.hpp>\n{xrst_code}\n\nBeginning of cppad_vector_itr.hpp\n*********************************\nThe following preprocessor definition appears at the beginning of\n``cppad_vector_itr.hpp`` and is used for the class definition in this file:\n::\n\n   # if CPPAD_CONST\n   # define CPPAD_VECTOR_ITR const_cppad_vector_itr\n   # else\n   # define CPPAD_VECTOR_ITR cppad_vector_itr\n   # endif\n\nEnd of cppad_vector_itr.hpp\n***************************\nThe following preprocessor definition appears at the end of\n``cppad_vector_itr.hpp`` so that it can be included with a different\nvalue for ``CPPAD_CONST`` :\n::\n\n   # undef CPPAD_CONST\n   # undef CPPAD_VECTOR_ITR\n\n{xrst_end cppad_vector_itr_define}\n*/\n# if CPPAD_CONST\n# define CPPAD_VECTOR_ITR const_cppad_vector_itr\n# else\n# define CPPAD_VECTOR_ITR cppad_vector_itr\n# endif\n\n\n// BEGIN_CPPAD_LOCAL_UTILITY_NAMESPACE\nnamespace CppAD { namespace local { namespace utility {\n\n// const_cppad_vector_itr\n// declare here can be make it a friend in cppad_vector_itr<Type>\ntemplate <class Type> class const_cppad_vector_itr;\n\n// ==========================================================================\ntemplate <class Type> class CPPAD_VECTOR_ITR {\n// ==========================================================================\n/*\n-----------------------------------------------------------------------------\n{xrst_begin cppad_vector_itr_traits dev}\n\nVector Class Iterator Traits and Friends\n########################################\n\n{xrst_spell_off}\n{xrst_code hpp} */\n# if ! CPPAD_CONST\n   friend class const_cppad_vector_itr<Type>;\n# endif\npublic:\n   typedef std::random_access_iterator_tag    iterator_category;\n   typedef Type                               value_type;\n   typedef std::ptrdiff_t                     difference_type;\n   typedef Type*                              pointer;\n   typedef Type&                              reference;\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cppad_vector_itr_traits}\n-------------------------------------------------------------------------------\n{xrst_begin cppad_vector_itr_ctor dev}\n\nVector Class Iterator Member Data and Constructors\n##################################################\n\nConstructors\n************\n\nConstant\n========\n\n| ``const_cppad_vector_itr`` *itr* ()\n| ``const_cppad_vector_itr`` *itr* ( *data* , *length* , *index* )\n| ``const_cppad_vector_itr`` *itr* ( *other* )\n| ``const_cppad_vector_itr`` *itr* ( *non_const_other* )\n\nNot Constant\n============\n\n| ``cppad_vector_itr`` *itr* ()\n| ``cppad_vector_itr`` *itr* ( *data* , *length* , *index* )\n| ``cppad_vector_itr`` *itr* ( *other* )\n\nNamespace\n*********\nThese definitions are in the ``CppAD::local::utility`` namespace.\n\nIndirection\n***********\nWe use an extra level of indirection in this routine so that\nthe iterator has the same values as the vector even if the vector changes.\n\ndata\\_\n******\nis a pointer to a constant pointer to data for this vector\n(used by operations that are not supported by constant iterators).\n\nlength\\_\n********\nis a pointer to the length of the corresponding vector.\n\nindex\\_\n*******\nis the current vector index corresponding to this iterator.\n\ncheck_element\n*************\ngenerates an assert with a known cause when the ``index_``\ndoes not correspond go a valid element and\n``NDEBUG`` is not defined.\n\ncheck_cop\n*********\nGenerates an assert with a known cause when the ``data_``\nfor this vector is different from the other vector and\n``NDEBUG`` is not defined.\nThis should be used by operators that compare iterators.\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n# if CPPAD_CONST\n   const Type* const* data_;\n# else\n   Type* const*       data_;\n# endif\n   const size_t*      length_;\n   difference_type    index_;\n   void check_element(void) const CPPAD_NDEBUG_NOEXCEPT\n   {  CPPAD_ASSERT_KNOWN( 0 <= index_ && size_t(index_) < *length_,\n         \"CppAD vector iterator: accessing element out of range\"\n      );\n   }\n   void check_cop(const CPPAD_VECTOR_ITR& other) const CPPAD_NDEBUG_NOEXCEPT\n   {  CPPAD_ASSERT_KNOWN( data_ == other.data_,\n         \"CppAD vector iterator: comparing indices from different vectors\"\n      );\n   }\npublic:\n   CPPAD_VECTOR_ITR(void) noexcept\n   : data_(nullptr), length_(nullptr), index_(0)\n   { }\n# if CPPAD_CONST\n   // ctor\n   const_cppad_vector_itr(\n      const Type* const* data, const size_t* length, difference_type index\n   ) noexcept\n   : data_(data), length_(length), index_( difference_type(index) )\n   { }\n   // ctor a const_iterator from an iterator. Here is were we need\n   //  const_cppad_vector_itr to be friend of cppad_vector_itr\n   const_cppad_vector_itr(\n      const cppad_vector_itr<Type>& non_const_other\n   ) noexcept\n   {  data_       = non_const_other.data_;\n      length_     = non_const_other.length_;\n      index_      = non_const_other.index_;\n   }\n# else\n   // ctor\n   cppad_vector_itr(\n      Type* const* data, const size_t* length, difference_type index\n   ) noexcept\n   : data_(data), length_(length), index_( difference_type(index) )\n   { }\n# endif\n   void operator=(const CPPAD_VECTOR_ITR& other) noexcept\n   {  data_       = other.data_;\n      length_     = other.length_;\n      index_      = other.index_;\n   }\n   CPPAD_VECTOR_ITR(const CPPAD_VECTOR_ITR& other) noexcept\n   {  *this = other; }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cppad_vector_itr_ctor}\n-------------------------------------------------------------------------------\n{xrst_begin cppad_vector_itr_inc dev}\n\nVector Class Iterator Increment Operators\n#########################################\n\nSyntax\n******\n\n| ++ *itr*\n| ``--`` *itr*\n| *itr* ++\n| *itr* ``--``\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   CPPAD_VECTOR_ITR& operator++(void) noexcept\n   {  ++index_;\n      return *this;\n   }\n   CPPAD_VECTOR_ITR& operator--(void) noexcept\n   {  --index_;\n      return *this;\n   }\n   CPPAD_VECTOR_ITR operator++(int) noexcept\n   {  CPPAD_VECTOR_ITR ret(*this);\n      ++index_;\n      return ret;\n   }\n   CPPAD_VECTOR_ITR operator--(int) noexcept\n   {  CPPAD_VECTOR_ITR ret(*this);\n      --index_;\n      return ret;\n   }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cppad_vector_itr_inc}\n-------------------------------------------------------------------------------\n{xrst_begin cppad_vector_itr_equal dev}\n\nVector Class Iterator Equality Operators\n########################################\n\nSyntax\n******\n\n| *itr* == *other*\n| *itr* != *other*\n\nRestrictions\n************\nIt is an error to compare iterators corresponding to different\n``data_`` vectors\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   bool operator==(const CPPAD_VECTOR_ITR& other) const CPPAD_NDEBUG_NOEXCEPT\n   {  check_cop(other);\n      return index_ == other.index_;\n   }\n   bool operator!=(const CPPAD_VECTOR_ITR& other) const CPPAD_NDEBUG_NOEXCEPT\n   {  check_cop(other);\n      return index_ != other.index_;\n   }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cppad_vector_itr_equal}\n-------------------------------------------------------------------------------\n{xrst_begin cppad_vector_itr_element dev}\n\nVector Class Iterator Access Elements\n#####################################\n\nSyntax\n******\n\n| *element* = * *itr*\n| * *itr* = *element*\n| *element* = *itr* [ *n* ]\n| *itr* [ *n* ] = *element*\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n# if CPPAD_CONST\n   const Type& operator*(void) const\n   {  check_element();\n      return (*data_)[index_];\n   }\n   const Type& operator[](difference_type n) const\n   {  return *(*this + n);\n   }\n   const Type& operator[](size_t n) const\n   {  return *( *this + difference_type(n) );\n   }\n# else\n   Type& operator*(void) const\n   {  check_element();\n      return (*data_)[index_];\n   }\n   Type& operator[](difference_type n) const\n   {  return *(*this + n);\n   }\n   Type& operator[](size_t n) const\n   {  return *( *this + difference_type(n) );\n   }\n# endif\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cppad_vector_itr_element}\n-------------------------------------------------------------------------------\n{xrst_begin cppad_vector_itr_random dev}\n\nVector Class Iterator Random Access\n###################################\n\nSyntax\n******\n\n| *itr* + *-* = *n*\n| *itr* = *other* + *-* *n*\n| *itr* = *n* + *-* *other*\n| *n* = *itr* ``-`` *other*\n| *b* = *itr* *cop* *other*\n\nPlus or Minus\n*************\nThe notation + *-* above is either ``+`` or ``-`` .\n\ncop\n***\nis one of the following:\n``<`` , ``<=`` ,\n``>`` , ``>=`` .\n\nitr, other\n**********\nare iterators of the same type.\n\nn\n*\nis a ``difference_type`` object.\n\nb\n*\nis a ``bool`` .\n\nRestrictions\n************\nIt is an error to use a *cop* with iterators corresponding to different\n``data_`` vectors\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   // sum and difference operators\n   CPPAD_VECTOR_ITR& operator+=(difference_type n) noexcept\n   {  index_ += n;\n      return *this;\n   }\n   CPPAD_VECTOR_ITR& operator-=(difference_type n) noexcept\n   {  index_ -= n;\n      return *this;\n   }\n   CPPAD_VECTOR_ITR operator+(difference_type n) const noexcept\n   {  return CPPAD_VECTOR_ITR(data_, length_, index_ + n);\n   }\n   CPPAD_VECTOR_ITR operator-(difference_type n) const noexcept\n   {  return CPPAD_VECTOR_ITR(data_, length_, index_ - n);\n   }\n   difference_type  operator-(const CPPAD_VECTOR_ITR& other) const\n   noexcept\n   {  return index_ - other.index_;\n   }\n   // comparison operators\n   bool operator<(const CPPAD_VECTOR_ITR& other) const CPPAD_NDEBUG_NOEXCEPT\n   {  check_cop(other);\n      return index_ < other.index_;\n   }\n   bool operator<=(const CPPAD_VECTOR_ITR& other) const CPPAD_NDEBUG_NOEXCEPT\n   {  check_cop(other);\n      return index_ <= other.index_;\n   }\n   bool operator>(const CPPAD_VECTOR_ITR& other) const CPPAD_NDEBUG_NOEXCEPT\n   {  check_cop(other);\n      return index_ > other.index_;\n   }\n   bool operator>=(const CPPAD_VECTOR_ITR& other) const CPPAD_NDEBUG_NOEXCEPT\n   {  check_cop(other);\n      return index_ >= other.index_;\n   }\n/* {xrst_code}\n{xrst_spell_on}\n{xrst_literal\n   // BEGIN_BINARY_OP\n   // END_BINARY_OP\n}\n\n{xrst_end cppad_vector_itr_random}\n*/\n// ==========================================================================\n}; // END_TEMPLATE_CLASS_CPPAD_VECTOR_ITR\n// ==========================================================================\n\n// BEGIN_BINARY_OP\ntemplate <class Type> CPPAD_VECTOR_ITR<Type> operator+(\n   typename CPPAD_VECTOR_ITR<Type>::difference_type n  ,\n   const CPPAD_VECTOR_ITR<Type>&               other   ) noexcept\n{  return other + n;\n}\n// END_BINARY_OP\n\n} } } // END_CPPAD_LOCAL_UTILITY_NAMESPACE\n\n# undef CPPAD_CONST\n# undef CPPAD_VECTOR_ITR\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/utility/vector_bool.hpp",
    "content": "# ifndef CPPAD_LOCAL_UTILITY_VECTOR_BOOL_HPP\n# define CPPAD_LOCAL_UTILITY_VECTOR_BOOL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cstddef>\n\n// BEGIN_CPPAD_LOCAL_UTILITY_NAMESPACE\nnamespace CppAD { namespace local { namespace utility {\n/*\n{xrst_begin vector_bool_element dev}\n\nvectorBoolElement Class\n#######################\n\nSyntax\n******\n| ``local::utility::vectorBoolElement`` *element* ( *unit* , *mask* )\n| ``local::utility::vectorBoolElement`` *element* ( *other* )\n| *value* = *element*\n| *element* = *value*\n| *element* = *element*\n\nunit_t\n******\nType used to pack multiple boolean (bit) values into one unit.\nLogical operations are preformed one unit at a time.\n\nunit\\_\n******\npointer to the unit that holds the value for this element.\n\nmask\\_\n******\nmask for the bit corresponding to this element; i.e., all the bits\nare zero except for bit that corresponds to this element which is one.\n\nvalue\n*****\nis a ``bool`` .\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\nclass vectorBoolElement {\nprivate:\n   typedef size_t unit_t;\n   unit_t* unit_;\n   unit_t  mask_;\npublic:\n   vectorBoolElement(unit_t* unit, unit_t mask )\n   : unit_(unit) , mask_(mask)\n   { }\n   vectorBoolElement(const vectorBoolElement& other)\n   : unit_(other.unit_) , mask_(other.mask_)\n   { }\n   operator bool() const\n   {  return (*unit_ & mask_) != 0; }\n   vectorBoolElement& operator=(bool value)\n   {  if(value) *unit_ |= mask_;\n      else      *unit_ &= ~mask_;\n      return *this;\n   }\n   vectorBoolElement& operator=(const vectorBoolElement& element)\n   {  if( *(element.unit_) & element.mask_ ) *unit_ |= mask_;\n      else                                   *unit_ &= ~mask_;\n      return *this;\n   }\n};\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end vector_bool_element}\n*/\n} } } // END_CPPAD_LOCAL_UTILITY_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/base_op.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_BASE_OP_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_BASE_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-23 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/val_graph/val_type.hpp>\n# include <cstdio>\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_base_op dev}\n\nThe Value Operator Base Class\n#############################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_BASE_OP_T\n   // END_BASE_OP_T\n}\n\nPurpose\n*******\nThis section describes the value operator base class\n(all the value operators are derived from this class).\n\nMember Variables\n****************\nNone of the value operators have any member variables,\nso their functions are like static functions but cannot be declared as\nsuch because they are virtual or override functions.\n\nValue\n*****\nThis template parameter is the type used for each element of the\n:ref:`val_graph@Value Vector` .\n\nbase_op\n*******\nThis is the base class used for operators.\nAll of its functions are public and pure virtual; i.e.,\nthey all must be defined in order for a derived class object to be used.\n\nop_enum\n*******\nThis member function returns the enum value corresponding to this operator;\nsee :ref:`val_graph_type@op_enum_t` .\n{xrst_literal\n   // BEGIN_OP_ENUM\n   // END_OP_ENUM\n}\n\nn_before\n********\nThis member function returns the number of auxiliary arguments\nthat come before the arguments that are value vector indices.\n{xrst_literal\n   // BEGIN_N_BEFORE\n   // END_N_BEFORE\n}\n\nn_after\n*******\nThis member function returns the number of auxiliary arguments\nthat come after the arguments that are value vector indices.\nThis can only be zero or one.\n{xrst_literal\n   // BEGIN_N_AFTER\n   // END_N_AFTER\n}\n\n\nn_arg\n*****\nThis member function returns the number of arguments for this operator.\n{xrst_literal\n   // BEGIN_N_ARG\n   // END_N_ARG\n}\n\nFixed\n=====\nIf *n_after* returns zero, this operator has a fixed number of arguments.\nIn this case, the *arg_index* and *arg_vec* arguments to this function.\nYou can set *arg_index* to\n*arg_vec*.size() (an invalid value) if you know this is not a call operator.\n\nVariable\n========\nIf *n_after* returns one, this operator has a variable number of arguments.\nIn this case the last argument is an auxiliary argument and is\nequal to the number of arguments for this use of this operator.\n\nn_res\n*****\nThis member function returns the number of results for this operator.\n{xrst_literal\n   // BEGIN_N_RES\n   // END_N_RES\n}\n\neval\n****\nThe values in *val_vec* with index less than *res_index*\nare inputs to this member function.\nThe *n_res* values starting at *res_index* in *val_vec* are\ncomputed by this function.\n{xrst_literal\n   // BEGIN_EVAL\n   // END_EVAL\n}\n\ntape\n====\nThis is a pointer to the tape that the operator is being evaluated for.\nWe use arg_vec to denote tape->arg_vec() below.\n\ntrace\n=====\nif this is true (false) the operator is (is not) printed\nat the end of the eval operation.\n\nind_vec_vec\n===========\nThe size of this vector is equal to the number of dynamic vectors.\nThe size of each element of this vector is equal to the size of the\ncorresponding dynamic vector.\nIf there are no dynamic vectors in the tape this argument must\nbe empty (or not present).\nThis argument is only used by the :ref:`val_vector_op-name` operations.\n\ncompare_false\n=============\nThis is the number of :ref:`val_comp_op-name` that had a false\nresult for their comparisons.\nThis is both an input and output; i.e., each false comparison\nwill add one to this value.\n\nname\n****\nis a short name, 5 or less characters, for this operator.\n\narg_index\n*********\nis the index in *arg_vec* where the *n_arg* arguments to this function start.\n\nres_index\n*********\nis the index in *val_vec* where the results for this operator start.\n\nval_vec\n*******\nis the entire :ref:`val_graph@Value Vector` .\n\narg_vec\n*******\nDuring  the eval function, arg_vec below denotes tape->arg_vec() .\n\nUnary Operators\n===============\nIf this operator is a unary operator\n\n#. arg_vec[arg_index + 0] < res_index\n#. val_vec[ arg_vec[ arg_index + 0 ] ] is the operand\n#. val_vec[ res_index] is the result computed by eval\n\nBinary Operators\n================\nIf this operator is a binary operator\n\n#. arg_vec[arg_index + 0] < res_index\n#. arg_vec[arg_index + 1] < res_index\n#. val_vec[ arg_vec[ arg_index + 1 ] ] is the left operand\n#. val_vec[ arg_vec[ arg_index + 2 ] ] is the right operand\n#. val_vec[ res_index] is the result computed by eval\n\nis_unary\n********\nis true (false) if this is (is not) a unary operator;\nsee :ref:`val_unary_op-name`.\n{xrst_literal\n   // BEGIN_IS_UNARY\n   // END_IS_UNARY\n}\n\nis_binary\n*********\nis true (false) if this is (is not) a binary operator;\nsee :ref:`val_binary_op-name`.\n{xrst_literal\n   // BEGIN_IS_BINARY\n   // END_IS_BINARY\n}\n\n\nOperator Classes\n****************\n{xrst_comment BEGIN_SORT_THIS_LINE_PLUS_2}\n{xrst_toc_table\n   include/cppad/local/val_graph/binary_op.hpp\n   include/cppad/local/val_graph/call_op.hpp\n   include/cppad/local/val_graph/cexp_op.hpp\n   include/cppad/local/val_graph/comp_op.hpp\n   include/cppad/local/val_graph/con_op.hpp\n   include/cppad/local/val_graph/csum_op.hpp\n   include/cppad/local/val_graph/dis_op.hpp\n   include/cppad/local/val_graph/pri_op.hpp\n   include/cppad/local/val_graph/unary_op.hpp\n   include/cppad/local/val_graph/vector_op.hpp\n}\n{xrst_comment END_SORT_THIS_LINE_MINUS_2}\n\n{xrst_end val_base_op}\n*/\n//\n// tape_t\ntemplate<class Value> class tape_t;\n\n// BEGIN_BASE_OP_T\ntemplate <class Value> class base_op_t {\npublic:\n// END_BASE_OP_T\n   // BEGIN_OP_ENUM\n   virtual op_enum_t op_enum(void)  const = 0;\n   // END_OP_ENUM\n   //\n   // BEGIN_N_BEFORE\n   virtual addr_t    n_before(void) const = 0;\n   // END_N_BEFORE\n   //\n   // BEGIN_N_AFTER\n   virtual addr_t    n_after(void)  const = 0;\n   // END_N_AFTER\n   //\n   // BEGIN_N_ARG\n   virtual addr_t n_arg(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const = 0;\n   // END_N_ARG\n   //\n   // BEGIN_N_RES\n   virtual addr_t n_res(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const = 0;\n   // END_N_RES\n   //\n   // BEGIN_EVAL\n   virtual void eval(\n      const tape_t<Value>*       tape          ,\n      bool                       trace         ,\n      addr_t                     arg_index     ,\n      addr_t                     res_index     ,\n      Vector<Value>&             val_vec       ,\n      Vector< Vector<addr_t> >&  ind_vec_vec   ,\n      size_t&                    compare_false ) const = 0;\n   // END_EVAL\n   //\n   // BEGIN_IS_UNARY\n   virtual bool is_unary(void) const\n   // END_IS_UNARY\n   {  return false; }\n   //\n   // BEGIN_IS_BINARY\n   virtual bool is_binary(void) const\n   // END_IS_BINARY\n   {  return false; }\n};\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/binary_op.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_BINARY_OP_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_BINARY_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/val_graph/base_op.hpp>\n# include <cppad/local/val_graph/print_op.hpp>\n# include <cppad/base_require.hpp>\n\nnamespace CppAD { namespace local { namespace val_graph {\n\n# define CPPAD_VAL_GRAPH_BINARY(Name, Op) \\\n   template <class Value> \\\n   class Name##_op_t : public binary_op_t<Value> { \\\n   public: \\\n      /* get_instance */ \\\n      static Name##_op_t* get_instance(void) \\\n      {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; \\\n         static Name##_op_t instance; \\\n         return &instance; \\\n      } \\\n      /* op_enum */ \\\n      op_enum_t op_enum(void) const override \\\n      {  return Name##_op_enum;  \\\n      } \\\n      /* eval */ \\\n      void eval( \\\n         const tape_t<Value>*      tape          , \\\n         bool                      trace         , \\\n         addr_t                    arg_index     , \\\n         addr_t                    res_index     , \\\n         Vector<Value>&            val_vec       , \\\n         Vector< Vector<addr_t> >& ind_vec_vec   , \\\n         size_t&                   compare_false ) const override \\\n      {  const Vector<addr_t>& arg_vec( tape->arg_vec() ); \\\n         const Value& left   = val_vec[ arg_vec[arg_index + 0] ]; \\\n         const Value& right  = val_vec[ arg_vec[arg_index + 1] ]; \\\n         val_vec[res_index]  = left Op right; \\\n         if( trace ) this->print_op( \\\n            #Name , arg_index, tape->arg_vec(), res_index, val_vec \\\n         ); \\\n      } \\\n   }\n\n/*\n------------------------------------------------------------------------------\n{xrst_begin_parent val_binary_op dev}\n\nBinary Value Operators\n######################\n\n{xrst_end val_binary_op}\n------------------------------------------------------------------------------\n{xrst_begin val_binary_base_op dev}\n\nThe Value Operator Binary Class\n###############################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_BINARY_OP_T\n   // END_BINARY_OP_T\n}\n\nPurpose\n*******\nThe class is derived from :ref:`base_op <val_base_op-name>`.\nIt overrides the\n*is_binary*, *n_before*, *n_after*, *n_arg*, *n_res_*, and *print_op*\nmember functions.\nThe *op_enum* and *eval* member functions are still pure virtual.\n\nis_binary\n*********\nThis override of :ref:`val_base_op@is_binary` returns true.\n\nn_before\n********\nThis override of :ref:`val_base_op@n_before` returns 0.\n\nn_after\n*******\nThis override of :ref:`val_base_op@n_after` returns 0.\n\nn_arg\n*****\nThis override of :ref:`val_base_op@n_arg` returns 2.\n\nn_res\n*****\nThis override of :ref:`val_base_op@n_res` returns 1.\n\nprint_op\n********\n{xrst_literal\n   // BEGIN_PRINT_OP\n   // END_PRINT_OP\n}\nThis member function uses :ref:`val_print_op-name`\nto print binary operators.\n\n{xrst_end val_binary_base_op}\n*/\n\n// BEGIN_BINARY_OP_T\ntemplate <class Value>\nclass binary_op_t : public base_op_t<Value> {\n// END_BINARY_OP_T\npublic:\n   // n_before\n   addr_t n_before(void) const override\n   {  return 0; }\n   //\n   // n_after\n   addr_t n_after(void) const override\n   {  return 0; }\n   //\n   // is_binary\n   bool is_binary(void) const override\n   {  return true; }\n   //\n   // n_arg\n   addr_t n_arg(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 2; }\n   //\n   // n_res\n   addr_t n_res(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 1; }\n   //\n   // op_enum\n   virtual op_enum_t op_enum(void) const override = 0;\n   //\n   // eval\n   virtual void eval(\n      const tape_t<Value>*      tape          ,\n      bool                      trace         ,\n      addr_t                    arg_index     ,\n      addr_t                    res_index     ,\n      Vector<Value>&            val_vec       ,\n      Vector< Vector<addr_t> >& ind_vec_vec   ,\n      size_t&                   compare_false ) const override = 0;\n   //\n   // BEGIN_PRINT_OP\n   void print_op(\n      const char*           name         ,\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ,\n      addr_t                res_index    ,\n      Vector<Value>&        val_vec      ) const\n   // END_PRINT_OP\n   {  //\n      addr_t left_index            = arg_vec[ arg_index + 0 ];\n      addr_t right_index           = arg_vec[ arg_index + 1 ];\n      Vector<addr_t> arg_val_index = { left_index, right_index };\n      Vector<Value>  res_value     = { val_vec[res_index] };\n      CppAD::local::val_graph::print_op(\n         name, arg_val_index, res_index, res_value\n      );\n   }\n};\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_binary_op_derived dev}\n\nThe Binary Value Operator Derived Classes\n#########################################\n\nPrototype\n*********\n| |tab| ``template <class Value>``\n| |tab| ``class`` *Name*\\ ``_opt_t : public binary_op_t<Value>``\n\n*Name*\n******\nUnary operators are defined for the following names:\n\n.. csv-table:: Unary Operators\n   :widths: auto\n   :header-rows: 1\n\n   Name,description\n   add,result is the sum of the two operands\n   sub,result is the first operand minus the second\n\nContext\n*******\nThis class is derived from :ref:`val_binary_op-name` .\nIt overrides the *op_enum* and *eval* member functions\nand is a concrete class (it has no pure virtual functions).\n\nget_instance\n************\nThis static member function returns a pointer to a\n*Name*\\ ``_op_t`` object.\n\nop_enum\n*******\nThis override of :ref:`val_base_op@op_enum` returns\n*Name*\\ ``_op_enum`` .\n\neval\n****\nThis override of :ref:`val_base_op@eval` sets\nthe result equal to the binary operator applied to the operands; see\n:ref:`val_base_op@arg_vec@Unary Operators` .\n\n\n{xrst_toc_hidden\n   val_graph/binary_xam.cpp\n}\nExample\n*******\nThe file :ref:`binary_xam.cpp <val_binary_xam.cpp-name>`\nis an example and test that uses a binary operator.\n\n{xrst_end val_binary_op_derived}\n*/\nCPPAD_VAL_GRAPH_BINARY(add, +);\nCPPAD_VAL_GRAPH_BINARY(sub, -);\nCPPAD_VAL_GRAPH_BINARY(mul, *);\nCPPAD_VAL_GRAPH_BINARY(div, /);\n\ntemplate <class Value>\nclass pow_op_t : public binary_op_t<Value> {\npublic:\n   /* get_instance */\n   static pow_op_t* get_instance(void)\n   {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n      static pow_op_t instance;\n      return &instance;\n   }\n   /* op_enum */\n   op_enum_t op_enum(void) const override\n   {  return pow_op_enum;\n   }\n   /* eval */\n   void eval(\n      const tape_t<Value>*      tape          ,\n      bool                      trace         ,\n      addr_t                    arg_index     ,\n      addr_t                    res_index     ,\n      Vector<Value>&            val_vec       ,\n      Vector< Vector<addr_t> >& ind_vec_vec   ,\n      size_t&                   compare_false ) const override\n   {  const Vector<addr_t>& arg_vec( tape->arg_vec() );\n      const Value& left   = val_vec[ arg_vec[arg_index + 0] ];\n      const Value& right  = val_vec[ arg_vec[arg_index + 1] ];\n      // Only the line directly below is different from\n      // CPPAD_VAL_GRAPH_BINARY(pow, pow)\n      val_vec[res_index]  = pow(left, right);\n      if( trace ) this->print_op(\n         \"pow\", arg_index, tape->arg_vec(), res_index, val_vec\n      );\n   }\n};\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# undef CPPAD_VAL_GRAPH_BINARY\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/call_atomic.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAL_GRAPH_CALL_ATOMIC_HPP\n# define CPPAD_LOCAL_VAL_GRAPH_CALL_ATOMIC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-23 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/atomic_index.hpp>\n# include <cppad/core/atomic/two/atomic.hpp>\n# include <cppad/core/atomic/three/atomic.hpp>\n# include <cppad/core/atomic/four/atomic.hpp>\nnamespace CppAD { namespace local { namespace val_graph {\n/*\nThis is similar to the routines in cppad/local/sweep/call_atomic.hpp,\nbut it is used by val_graph instead of the sweeps.\n*/\n/*\n{xrst_begin atomic_for_type_callback dev}\n\nForward Type Callback to Atomic Functions\n#########################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_FORWARD\n   // END_FORWARD\n}\n\nValue\n*****\nis the base type corresponding to the atomic function.\n\nCppAD::vector\n*************\nthis routine uses the CppAD::vector template class\n(and not CppAD::local::val_graph::Vector) because atomic functions expect\nCppAD::vector.\n\nconstant_x\n**********\ncontains the values, in afun(ax, ay), for arguments that are constants.\n\ntype_x\n******\nwhat is the type, in the call, for each component of x.\n\ntype_y\n******\nthe input values in this vector do not matter.\nUpon return it is the type for each component of y.\n\natom_index\n**********\nis the index, in local::atomic_index, corresponding to this atomic function.\n\ncall_id\n*******\nsee the atomic_four :ref:`atomic_four_call@call_id` and\nthe atomic_one :ref:`atomic_one@id` .\n\n{xrst_end atomic_for_type_callback}\n*/\n// BEGIN_FORWARD\ntemplate <class Value>\nvoid call_atomic_for_type(\n   const CppAD::vector<Value>&         constant_x  ,\n   const CppAD::vector<ad_type_enum>&  type_x      ,\n   CppAD::vector<ad_type_enum>&        type_y      ,\n   size_t                              atom_index  ,\n   size_t                              call_id     )\n// END_FORWARD\n{  CPPAD_ASSERT_UNKNOWN( 0 < atom_index );\n   //\n   // type, v_ptr\n   bool         set_null = false;\n   size_t       type     = 0;       // set to avoid warning\n   std::string  name;\n   void*        v_ptr    = nullptr; // set to avoid warning\n   local::atomic_index<Value>(set_null, atom_index, type, &name, v_ptr);\n//\n# ifndef NDEBUG\n   bool ok = v_ptr != nullptr;\n   if( ok )\n   {\n      if( type == 2 )\n      {  size_t p = 0, q = 0, nx = type_x.size(), ny = type_y.size();\n         CppAD::vector<bool> vx(nx), vy(ny);\n         for(size_t i = 0; i < nx; ++i)\n            vx[i] = type_x[i] > constant_enum;\n         const CppAD::vector<Value>& taylor_x = constant_x;\n         CppAD::vector<Value> taylor_y(ny);\n         atomic_base<Value>* afun =\n            reinterpret_cast< atomic_base<Value>* >(v_ptr);\n         afun->set_old(call_id);\n         ok = afun->forward(\n            p, q, vx, vy, taylor_x, taylor_y\n         );\n         for(size_t i = 0; i < ny; ++i)\n         {  if( vy[i] )\n               type_y[i] = variable_enum;\n            else\n               type_y[i] = constant_enum;\n         }\n      }\n      else if( type == 3 )\n      {  CPPAD_ASSERT_UNKNOWN( type == 3 );\n         atomic_three<Value>* afun =\n            reinterpret_cast< atomic_three<Value>* >(v_ptr);\n         ok = afun->for_type(constant_x, type_x, type_y );\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN( type == 4 );\n         atomic_four<Value>* afun =\n            reinterpret_cast< atomic_four<Value>* >(v_ptr);\n         ok = afun->for_type(call_id, type_x, type_y);\n      }\n   }\n   if( ! ok )\n   {  // now take the extra time to copy the name\n      std::string msg = name;\n      if( v_ptr == nullptr )\n         msg += \": this atomic function has been deleted\";\n      else\n         msg += \": atomic for_type returned false\";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n# else\n   if( type == 2 )\n   {  size_t p = 0, q = 0, nx = type_x.size(), ny = type_y.size();\n      CppAD::vector<bool> vx(nx), vy(ny);\n      for(size_t i = 0; i < nx; ++i)\n         vx[i] = type_x[i] > constant_enum;\n      const CppAD::vector<Value>& taylor_x = constant_x;\n      CppAD::vector<Value> taylor_y(ny);\n      atomic_base<Value>* afun =\n         reinterpret_cast< atomic_base<Value>* >(v_ptr);\n      afun->set_old(call_id);\n      afun->forward(\n         p, q, vx, vy, taylor_x, taylor_y\n      );\n      for(size_t i = 0; i < ny; ++i)\n      {  if( vy[i] )\n            type_y[i] = variable_enum;\n         else\n            type_y[i] = constant_enum;\n      }\n   }\n   else if( type == 3 )\n   {  CPPAD_ASSERT_UNKNOWN( type == 3 );\n      atomic_three<Value>* afun =\n         reinterpret_cast< atomic_three<Value>* >(v_ptr);\n      afun->for_type(constant_x, type_x, type_y );\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( type == 4 );\n      atomic_four<Value>* afun =\n         reinterpret_cast< atomic_four<Value>* >(v_ptr);\n      afun->for_type(call_id, type_x, type_y);\n   }\n# endif\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/call_op.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_CALL_OP_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_CALL_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cstdio>\n# include <cppad/local/val_graph/base_op.hpp>\n# include <cppad/local/atomic_index.hpp>\n# include <cppad/core/atomic/four/atomic.hpp>\n# include <cppad/local/sweep/call_atomic.hpp>\n# include <cppad/local/val_graph/print_op.hpp>\n\n// define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_call_op dev}\n\nThe Call Value Operator\n#######################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CALL_OP_T\n   // END_CALL_OP_T\n}\n\nContext\n*******\nThe class is derived from :ref:`val_base_op-name` .\nIt overrides all its base class virtual member functions\nand is a concrete class (it has no pure virtual functions).\n\nget_instance\n************\nThis static member function returns a pointer to a call_op_t object.\n\nop_enum\n*******\nThis override of :ref:`val_base_op@op_enum` returns ``call_op_enum`` .\n\nn_before\n********\nThis override of :ref:`val_base_op@n_before` returns 4.\n{xrst_literal\n   // BEGIN_ARG_BEFORE\n   // END_ARG_BEFORE\n}\n\nn_after\n*******\nThis override of :ref:`val_base_op@n_after` returns 1.\nThis is for a second copy of *n_arg* that can be used to iterate\nthrough the operators in reverse.\n\nn_arg\n*****\nsee base_op :ref:`val_base_op@n_arg` .\n\nn_res\n*****\nsee base_op :ref:`val_base_op@n_res` .\n\natomic_index\n************\nThis member function returns the *atomic_index* for the mapping; see\n:ref:`atomic_index@index_out` in the case where *index_in* is zero.\n\ncall_id\n*******\nThis member function returns the *call_id* for this use of the mapping; see\n:ref:`atomic_four_call@call_id` .\n\neval\n****\nThis override of :ref:`val_base_op@eval` makes the atomic function call\nidentified by *atomic_index* , with the *call_id*,\nto evaluate *n_res* results given *n_arg* - 4 arguments.\n\n#. The arguments for the function call are\n   ::\n\n      val_vec[ arg_vec[ arg_index + 4 ] ] ,\n      val_vec[ arg_vec[ arg_index + 5 ] ] ,\n      ...\n      val_vec[ arg_vec[ arg_index + n_arg - 1 ] ]\n\n#. The results of the function call are placed in\n   ::\n\n      val_vec[res_index + 0] ,\n      val_vec[res_index + 1] ,\n      ...\n      val_vec[res_index + n_res - 1]\n\ntrace\n=====\nIf trace is true, :ref:`val_print_op-name` is called to print this operator.\n\n{xrst_toc_hidden\n   val_graph/call_xam.cpp\n}\nExample\n*******\nThe file :ref:`call_xam.cpp <val_call_xam.cpp-name>`\nis an example and test that uses this operator.\n\n{xrst_end val_call_op}\n*/\n// BEGIN_CALL_OP_T\ntemplate <class Value>\nclass call_op_t : public base_op_t<Value> {\npublic:\n   // n_before\n   addr_t n_before(void) const override\n   {  return 4; }\n   //\n   // n_after\n   addr_t n_after(void) const override\n   {  return 1; }\n   //\n   // get_instance\n   static call_op_t* get_instance(void)\n   {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n      static call_op_t instance;\n      return &instance;\n   }\n   // op_enum\n   // type of this operator\n   op_enum_t op_enum(void) const override\n   {  return call_op_enum; }\n   //\n   // n_arg\n   addr_t n_arg(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return arg_vec[arg_index + 0]; }\n   //\n   // n_res\n   addr_t n_res(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return arg_vec[arg_index + 1]; }\n   //\n   // atomic_index\n   size_t atomic_index(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      )\n   {  return size_t( arg_vec[arg_index + 2] ); }\n   //\n   // call_id\n   size_t call_id(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      )\n   {  return size_t( arg_vec[arg_index + 3] ); }\n   //\n   // eval\n   void eval(\n      const tape_t<Value>*      tape          ,\n      bool                      trace         ,\n      addr_t                    arg_index     ,\n      addr_t                    res_index     ,\n      Vector<Value>&            val_vec       ,\n      Vector< Vector<addr_t> >& ind_vec_vec   ,\n      size_t&                   compare_false\n    ) const override;\n// END_CALL_OP_T\n};\n//\n// eval\ntemplate <class Value>\nvoid call_op_t<Value>::eval(\n   const tape_t<Value>*      tape          ,\n   bool                      trace         ,\n   addr_t                    arg_index     ,\n   addr_t                    res_index     ,\n   Vector<Value>&            val_vec       ,\n   Vector< Vector<addr_t> >& ind_vec_vec   ,\n   size_t&                   compare_false ) const\n{  //\n   // arg_vec\n   const Vector<addr_t>& arg_vec( tape->arg_vec() );\n   //\n   // n_arg, n_res, atomic_index, call_id\n   // BEGIN_ARG_BEFORE\n   addr_t n_arg         =  arg_vec[arg_index + 0] ;\n   addr_t n_res         =  arg_vec[arg_index + 1] ;\n   size_t atomic_index  = size_t( arg_vec[arg_index + 2] );\n   size_t call_id       = size_t( arg_vec[arg_index + 3] );\n   CPPAD_ASSERT_UNKNOWN( atomic_index != 0 );\n   // END_ARG_BEFORE\n   //\n   // n_x\n   addr_t n_x = n_arg - n_before() - n_after();\n   //\n   // x\n   CppAD::vector<Value> x(n_x);\n   for(addr_t i = 0; i < n_x; ++i)\n      x[i] = val_vec[ arg_vec[arg_index + n_before() + i] ];\n   //\n   // type_x\n   CppAD::vector<ad_type_enum> type_x(n_x);\n   for(addr_t i = 0; i < n_x; ++i)\n      type_x[i] = variable_enum;\n   //\n   // need_y\n   size_t need_y = size_t( number_ad_type_enum );\n   //\n   // order_low, order_up\n   size_t order_low = 0, order_up = 0;\n   //\n   // select_y\n   CppAD::vector<bool> select_y(n_res);\n   for(addr_t i = 0; i < n_res; ++i)\n      select_y[i] = true;\n   //\n   // y\n   CppAD::vector<Value> y(n_res);\n   local::sweep::call_atomic_forward<Value,Value>(\n      x, type_x, need_y, select_y, order_low, order_up,\n      atomic_index, call_id, x, y\n   );\n   //\n   // val_vec\n   for(addr_t i = 0; i < n_res; ++i)\n      val_vec[res_index + i] = y[i];\n   //\n   // trace\n   if( ! trace )\n      return;\n   //\n   // v_ptr, name\n   bool         set_null = false;\n   size_t       type     = 0;       // result: set to avoid warning\n   std::string  name;               // result:\n   void*        v_ptr    = nullptr; // result: set to avoid warning\n   local::atomic_index<Value>(set_null, atomic_index, type, &name, v_ptr);\n   //\n   Vector<addr_t> arg_val_index(n_x);\n   for(addr_t i = 0; i < n_x; ++i)\n      arg_val_index[i] = arg_vec[arg_index + n_before() + i];\n   //\n   Vector<Value> res_value(n_res);\n   for(addr_t i = 0; i < n_res; ++i)\n      res_value[i] = val_vec[res_index + i];\n   //\n   print_op(name, arg_val_index, res_index, res_value);\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/cexp_op.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_CEXP_OP_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_CEXP_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/val_graph/base_op.hpp>\n\n// define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_cexp_op dev}\n\nThe Conditional Expression Value Operator\n#########################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CEXP_OP_T\n   // END_CEXP_OP_T\n}\n\nContext\n*******\nThis class computes the result for a\n:ref:`conditional expression <condexp-name>` .\nIt is derived from :ref:`val_base_op-name` .\nIt overrides all its base class virtual member functions\nand is a concrete class (it has no pure virtual functions).\n\nget_instance\n************\nThis static member function returns a pointer to a cexp_op_t object.\n\nop_enum\n*******\nThis override of :ref:`val_base_op@op_enum` returns ``cexp_op_enum`` .\n\nn_before\n********\nThis override of :ref:`val_base_op@n_before` returns 1.\n\nn_after\n*******\nThis override of :ref:`val_base_op@n_after` returns 0.\n\nn_arg\n*****\nThis override of :ref:`val_base_op@n_arg` returns 5.\n\nn_res\n*****\nThis override of :ref:`val_base_op@n_res` returns 1.\n\neval\n****\nThis override of :ref:`val_base_op@eval` .\nIf the comparison is false (true), one (zero) is added to\nthe compare_false argument to eval.\n{xrst_literal\n   // BEGIN_ARGS\n   // END_ARGS\n}\n\ntrace\n=====\nIf trace is true, :ref:`val_print_op-name` is called to print this operator.\n\n{xrst_toc_hidden\n   val_graph/cexp_xam.cpp\n}\nExample\n*******\nThe file :ref:`com_xam.cpp <val_cexp_xam.cpp-name>`\nis an example and test that uses this operator.\n\n{xrst_end val_cexp_op}\n*/\n// BEGIN_CEXP_OP_T\ntemplate <class Value>\nclass cexp_op_t : public base_op_t<Value> {\npublic:\n   // n_before\n   addr_t n_before(void) const override\n   {  return 1; }\n   //\n   // n_after\n   addr_t n_after(void) const override\n   {  return 0; }\n   //\n   // get_instance\n   static cexp_op_t* get_instance(void)\n   {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n      static cexp_op_t instance;\n      return &instance;\n   }\n   // op_enum\n   op_enum_t op_enum(void) const override\n   {  return cexp_op_enum; }\n// END_CEXP_OP_T\n   //\n   // n_arg\n   addr_t n_arg(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 5; }\n   //\n   // n_res\n   addr_t n_res(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 1; }\n   //\n   // eval\n   void eval(\n      const tape_t<Value>*      tape            ,\n      bool                      trace           ,\n      addr_t                    arg_index       ,\n      addr_t                    res_index       ,\n      Vector<Value>&            val_vec         ,\n      Vector< Vector<addr_t> >& ind_vec_vec     ,\n      size_t&                   compare_false   ) const override\n   {  //\n      // arg_vec\n      const Vector<addr_t>& arg_vec( tape->arg_vec() );\n      //\n      // compare_enum, left_index, right_index\n      // BEGIN_ARGS\n      compare_enum_t compare_enum = compare_enum_t( arg_vec[arg_index + 0] );\n      addr_t left_index           = arg_vec[arg_index + 1];\n      addr_t right_index          = arg_vec[arg_index + 2];\n      addr_t if_true_index        = arg_vec[arg_index + 3];\n      addr_t if_false_index       = arg_vec[arg_index + 4];\n      // END_ARGS\n      //\n      // left, right\n      const Value&   left          = val_vec[left_index];\n      const Value&   right         = val_vec[right_index];\n      const Value&   if_true       = val_vec[if_true_index];\n      const Value&   if_false      = val_vec[if_false_index];\n      //\n      // res, name\n      const char* name;\n      switch( compare_enum )\n      {  //\n         // e_eq\n         case compare_eq_enum:\n         val_vec[res_index]  = CondExpEq(left, right, if_true, if_false);\n         name = \"e_eq\";\n         break;\n         //\n         // e_lt\n         case compare_lt_enum:\n         val_vec[res_index]  = CondExpLt(left, right, if_true, if_false);\n         name = \"e_lt\";\n         break;\n         //\n         // e_le\n         case compare_le_enum:\n         val_vec[res_index]  = CondExpLe(left, right, if_true, if_false);\n         name = \"e_le\";\n         break;\n         //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         val_vec[res_index]  = CppAD::numeric_limits<Value>::quiet_NaN();\n         name = \"\";\n      }\n      //\n      // trace\n      if( ! trace )\n         return;\n      //\n      // print_op\n      Vector<addr_t> arg_val_index(4);\n      for(addr_t i = 0; i < 4; ++i)\n         arg_val_index[i] = arg_vec[arg_index + i + 1];\n      Vector<Value>  res_value = { val_vec[res_index] };\n      print_op(name, arg_val_index, res_index, res_value);\n      //\n      return;\n   }\n};\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/comp_op.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_COMP_OP_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_COMP_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/val_graph/base_op.hpp>\n# include <cppad/local/val_graph/print_op.hpp>\n\n// define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_comp_op dev}\n\nThe Compare Value Operator\n##########################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_COMP_OP_T\n   // END_COMP_OP_T\n}\n\nContext\n*******\nThis class checks if the comparison between two values has changed.\nIt is derived from :ref:`val_base_op-name` .\nIt overrides all its base class virtual member functions\nand is a concrete class (it has no pure virtual functions).\n\nget_instance\n************\nThis static member function returns a pointer to a comp_op_t object.\n\nop_enum\n*******\nThis override of :ref:`val_base_op@op_enum` returns ``comp_op_enum`` .\n\nn_before\n********\nThis override of :ref:`val_base_op@n_before` returns 1.\n\nn_after\n*******\nThis override of :ref:`val_base_op@n_after` returns 0.\n\nn_arg\n*****\nThis override of :ref:`val_base_op@n_arg` returns 3.\n\nn_res\n*****\nThis override of :ref:`val_base_op@n_res` returns 1.\n\neval\n****\nThis override of :ref:`val_base_op@eval` .\nIf the comparison is false (true), one (zero) is added to\nthe compare_false argument to eval.\n{xrst_literal\n   // BEGIN_ARGS\n   // END_ARGS\n}\n\ntrace\n=====\nIf trace is true, :ref:`val_print_comp_op-name`\nis called to print this operator.\n\n{xrst_toc_hidden\n   val_graph/comp_xam.cpp\n}\nExample\n*******\nThe file :ref:`com_xam.cpp <val_comp_xam.cpp-name>`\nis an example and test that uses this operator.\n\n{xrst_end val_comp_op}\n*/\n// BEGIN_COMP_OP_T\ntemplate <class Value>\nclass comp_op_t : public base_op_t<Value> {\npublic:\n   // n_before\n   addr_t n_before(void) const override\n   {  return 1; }\n   //\n   // n_after\n   addr_t n_after(void) const override\n   {  return 0; }\n   //\n   // get_instance\n   static comp_op_t* get_instance(void)\n   {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n      static comp_op_t instance;\n      return &instance;\n   }\n   // op_enum\n   op_enum_t op_enum(void) const override\n   {  return comp_op_enum; }\n// END_COMP_OP_T\n   //\n   // n_arg\n   addr_t n_arg(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 3; }\n   //\n   // n_res\n   addr_t n_res(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 0; }\n   //\n   // eval\n   void eval(\n      const tape_t<Value>*      tape            ,\n      bool                      trace           ,\n      addr_t                    arg_index       ,\n      addr_t                    res_index       ,\n      Vector<Value>&            val_vec         ,\n      Vector< Vector<addr_t> >& ind_vec_vec     ,\n      size_t&                   compare_false   ) const override\n   {  //\n      // arg_vec\n      const Vector<addr_t>& arg_vec( tape->arg_vec() );\n      //\n      // compare_enum, left_index, right_index\n      // BEGIN_ARGS\n      compare_enum_t compare_enum = compare_enum_t( arg_vec[arg_index + 0] );\n      addr_t left_index           = arg_vec[arg_index + 1];\n      addr_t right_index          = arg_vec[arg_index + 2];\n      // END_ARGS\n      //\n      // left, right\n      const Value&   left          = val_vec[left_index];\n      const Value&   right         = val_vec[right_index];\n      //\n      // result, comp_name\n      bool result;\n      const char* comp_name;\n      switch( compare_enum )\n      {  //\n         case compare_eq_enum:\n         result    = left == right;\n         comp_name = \"eq\";\n         break;\n         //\n         // ne\n         case compare_ne_enum:\n         result    = left != right;\n         comp_name = \"ne\";\n         break;\n         //\n         // lt\n         case compare_lt_enum:\n         result    = left < right;\n         comp_name = \"lt\";\n         break;\n         //\n         // le\n         case compare_le_enum:\n         result    = left <= right;\n         comp_name = \"le\";\n         break;\n         //\n         // no\n         case compare_no_enum:\n         result    = true;\n         comp_name = \"no\";\n         break;\n         //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         result    = false; // to avoid compiler warning\n         comp_name = \"\";\n      }\n      //\n      // compare_false\n      if( ! result )\n         ++compare_false;\n      //\n      // trace\n      if( ! trace )\n         return;\n      //\n      // print_comp_op\n      print_comp_op(comp_name, left_index, right_index, result);\n   }\n};\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/compress.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_COMPRESS_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_COMPRESS_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-25 Bradley M. Bell\n// ---------------------------------------------------------------------------\n# include <cppad/local/val_graph/tape.hpp>\n# include <cppad/local/val_graph/op_hash_table.hpp>\n# include <cppad/local/val_graph/rev_depend.hpp>\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_tape_compress dev}\n{xrst_spell\n   dep\n}\n\nTape Compression\n################\nThis is :ref:`val_tape_renumber-name` and :ref:`val_tape_dead_code-name`\nin one step. I should be faster, and require more memory,\nthan separate execution. (Testing with :ref:`cppad_det_minor.cpp-name`\nindicates that it is only slightly faster.)\n\nChanges\n*******\nOnly the following values, for this tape, are guaranteed to be same:\n#. The number of independent values :ref:`val_tape@n_ind` .\n#. The size of the dependent vector :ref:`dep_vec.size() <val_tape@dep_vec>` .\n#. The mapping from the independent to the dependent variables.\n\nkeep_compare\n************\nsee :ref:`val_tape_option@keep_compare` .\nIf *keep_compare* is false, no comparison operators are in the new tape.\nOtherwise, if two or more comparison operators are identical,\nonly the first such operator is in the new tape.\n\nkeep_print\n**********\nsee :ref:`val_tape_option@keep_print` .\nIf *keep_print* is false, no print operators are in the new tape.\nOtherwise, if two or more print operators are identical,\nonly the first such operator is in the new tape.\n\nAlgorithm\n*********\n#. The dependent variables are marked as used.\n#. The operators are scanned in reverse and if an operator's result is\n   used, the corresponding arguments are marked as used.\n   The call operator has a more complicated version of this marking.\n#. A forward pass is made though the operators and only the operators that\n   are used ones are considered.\n#. If an operator is equivalent to a previous operator,\n   the previous operator is used in it's place.\n#. An operators result may have a new index\n   because some previous results were left out.\n   A mapping from the old result indices to the new result indices\n   enables subsequent operators to adjust their argument indices.\n#. After the forward pass, the mapping from old indices to new indices\n   is used to adjust the dependent variable indices.\n\n{xrst_toc_hidden\n   val_graph/compress_xam.cpp\n}\nExample\n*******\nThe file :ref:`compress_xam.cpp <val_compress_xam.cpp-name>` is an\nexample and test of tape.compress().\n\n{xrst_end val_tape_compress}\n*/\n\n// BEGIN_COMPRESS\n// new_use_val = compress()\ntemplate <class Value>\nvectorBool tape_t<Value>::compress(void)\n// END_COMPRESS\n{\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // thread, initial_inuse\n   size_t thread        = thread_alloc::thread_num();\n   size_t initial_inuse = thread_alloc::inuse(thread);\n# endif\n   //\n   // val_use_case, vec_last_load\n   Vector<addr_t> val_use_case, vec_last_load;\n   rev_depend(val_use_case, vec_last_load);\n   //\n   // op2arg_index, op2res_index\n   Vector<addr_t> op2arg_index( n_op() ), op2res_index( n_op() );\n   {  op_iterator<Value> op_itr(*this, 0);\n      for(addr_t i_op = 0; i_op < n_op(); ++i_op)\n      {  op2arg_index[i_op] = op_itr.arg_index();\n         op2res_index[i_op] = op_itr.res_index();\n         ++op_itr;\n      }\n   }\n   //\n   // op_hash_table\n   addr_t n_hash_code = 1 + (n_val_ / 2);\n   op_hash_table_t<Value>  op_hash_table(*this, op2arg_index, n_hash_code);\n   //\n   // keep_compare\n   bool keep_compare = option_map_[\"keep_compare\"] == \"true\";\n   //\n   // keep_print\n   bool keep_print = option_map_[\"keep_print\"] == \"true\";\n   //\n   // new_tape\n   tape_t new_tape;\n   new_tape.set_ind(n_ind_);\n   //\n   // new_which_vec\n   // initialize all dynamic vectors as not used\n   Vector<addr_t> new_which_vec( vec_initial_.size() );\n   for(size_t i = 0; i < vec_initial_.size(); ++i)\n      new_which_vec[i] = addr_t( vec_initial_.size() );\n   //\n   // new_val_index\n   // include nan at index n_ind_ in val_vec\n   Vector<addr_t> new_val_index( n_val_ );\n   for(addr_t i = 0; i <= n_ind_; ++i)\n      new_val_index[i] = addr_t(i);\n   for(addr_t i = n_ind_ + 1; i < n_val_; ++i)\n      new_val_index[i] = addr_t( n_val_ );\n   //\n# ifndef NDEBUG\n   // nan at index n_ind_\n   assert( op_enum_t( new_tape.op_enum_vec_[0] ) == con_op_enum );\n   assert( new_tape.var_arg_[0] == 0 );\n   assert( CppAD::isnan( new_tape.con_vec_[0] ) );\n# endif\n   //\n   // new_use_val\n   // Because the call operator can have more than one result, not all the\n   // results for all the needed operators are used. Initialize as all the\n   // independent values and the nan after them are used.\n   vectorBool new_use_val(n_ind_ + 1);\n   for(addr_t i = 0; i <= n_ind_; ++i)\n      new_use_val[i] = true;\n   //\n   // work\n   Vector<addr_t> work;\n   //\n   //\n   // i_op\n   for(addr_t i_op = 1; i_op < n_op(); ++i_op)\n   {  //\n      // op_ptr\n      const base_op_t<Value>* op_ptr   = base_op_ptr(i_op);\n      //\n      // arg_index_i, res_index_i\n      addr_t arg_index_i = op2arg_index[i_op];\n      addr_t res_index_i = op2res_index[i_op];\n      addr_t n_res        = op_ptr->n_res(arg_index_i, var_arg_);\n      //\n      // use_op\n      bool use_op = false;\n      if( n_res == 0 )\n      {  op_enum_t op_enum = op_ptr->op_enum();\n         if( op_enum == vec_op_enum || op_enum == store_op_enum )\n         {  addr_t which_vector = var_arg_[arg_index_i + 0];\n            use_op              = i_op < vec_last_load[which_vector];\n         }\n         else if( op_enum == pri_op_enum )\n            use_op  = keep_print;\n         else\n         {  CPPAD_ASSERT_UNKNOWN( op_enum == comp_op_enum );\n            use_op  = keep_compare;\n         }\n      }\n      else for(addr_t k = 0; k < n_res; ++k)\n         use_op |= 0 != val_use_case[ res_index_i + k];\n      //\n      if(use_op)\n      {  //\n         // j_op\n         addr_t j_op = op_hash_table.match_op(i_op, new_val_index);\n         //\n         if( j_op != i_op )\n         {  // use j_op every where that i_op was used\n            assert( j_op < i_op );\n            //\n            // new_val_index\n            // mapping so use op_j results in place of op_i results.\n            addr_t res_index_j = op2res_index[j_op];\n            for(addr_t k = 0; k < n_res; ++k)\n               new_val_index[res_index_i + k] = res_index_j + k;\n         }\n         else\n         {  // record i_op operator on the new tape\n            addr_t new_res_index = record_new(\n               new_tape        ,\n               new_which_vec   ,\n               work            ,\n               new_val_index   ,\n               val_use_case    ,\n               op_ptr          ,\n               arg_index_i     ,\n               res_index_i\n            );\n            //\n            // new_val_index\n            for(addr_t k = 0; k < n_res; ++k)\n               new_val_index[ res_index_i + k ] = new_res_index + k;\n            //\n            // new_use_val\n            for(addr_t k = 0; k < n_res; ++k)\n            {  bool use_val_k = val_use_case[ res_index_i + k ] != 0;\n               new_use_val.push_back( use_val_k );\n            }\n         }\n      }\n   }\n   //\n   // dep_vec\n   Vector<addr_t> dep_vec( dep_vec_.size() );\n   for(size_t k = 0; k < dep_vec_.size(); ++k)\n      dep_vec[k] = new_val_index[ dep_vec_[k] ];\n   new_tape.set_dep( dep_vec );\n   //\n   // swap\n   swap(new_tape);\n   //\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // inuse\n   size_t final_inuse = thread_alloc::inuse(thread);\n   std::cout << \"dead_code:  inuse = \" << final_inuse - initial_inuse << \"\\n\";\n# endif\n   // BEGIN_RETURN\n   CPPAD_ASSERT_UNKNOWN( size_t( n_val() ) == new_use_val.size() );\n   return new_use_val;\n   // END_RETURN\n}\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/con_op.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_CON_OP_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_CON_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/val_graph/base_op.hpp>\n\n// define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_con_op dev}\n\nThe Constant Value Operator\n###########################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CON_OP_T\n   // END_CON_OP_T\n}\n\nContext\n*******\nThe class is derived from :ref:`val_base_op-name` .\nIt overrides all its base class virtual member functions\nand is a concrete class (it has no pure virtual functions).\nThis is not a unary operator because the operand is in the\nconstant vector and not the value vector.\n\nget_instance\n************\nThis static member function returns a pointer to a con_op_t object.\n\nop_enum\n*******\nThis override of :ref:`val_base_op@op_enum` returns ``con_op_enum`` .\n\nn_before\n********\nThis override of :ref:`val_base_op@n_before` returns 1.\n\nn_after\n*******\nThis override of :ref:`val_base_op@n_after` returns 0.\n\nn_arg\n*****\nThis override of :ref:`val_base_op@n_arg` returns 1.\n\nn_res\n*****\nThis override of :ref:`val_base_op@n_res` returns 1.\n\neval\n****\nThis override of :ref:`val_base_op@eval` sets\nthe result equal to\n::\n\n      con_vec[ arg_vec[ arg_index + 0 ] ]\n\ntrace\n=====\nIf trace is true, :ref:`val_print_con_op-name`\nis called to print this operator.\n\n{xrst_toc_hidden\n   val_graph/con_xam.cpp\n}\nExample\n*******\nThe file :ref:`con_xam.cpp <val_con_xam.cpp-name>`\nis an example and test that uses this operator.\n\n{xrst_end val_con_op}\n*/\n// BEGIN_CON_OP_T\ntemplate <class Value>\nclass con_op_t : public base_op_t<Value> {\npublic:\n   // n_before\n   addr_t n_before(void) const override\n   {  return 1; }\n   //\n   // n_after\n   addr_t n_after(void) const override\n   {  return 0; }\n   // get_instance\n   static con_op_t* get_instance(void)\n   {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n      static con_op_t instance;\n      return &instance;\n   }\n   // op_enum\n   op_enum_t op_enum(void) const override\n   {  return con_op_enum; }\n// END_CON_OP_T\n   //\n   // n_arg\n   addr_t n_arg(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 1; }\n   //\n   // n_res\n   addr_t n_res(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 1; }\n   //\n   // eval\n   void eval(\n      const tape_t<Value>*      tape          ,\n      bool                      trace         ,\n      addr_t                    arg_index     ,\n      addr_t                    res_index     ,\n      Vector<Value>&            val_vec       ,\n      Vector< Vector<addr_t> >& ind_vec_vec   ,\n      size_t&                   compare_false ) const override\n   {  //\n      // arg_vec, con_vec\n      const Vector<addr_t>& arg_vec( tape->arg_vec() );\n      const Vector<Value>&  con_vec( tape->con_vec() );\n      //\n      // val_index, val_vec\n      addr_t val_index    = arg_vec[ arg_index + 0 ];\n      val_vec[res_index]  = con_vec[ val_index ];\n      //\n      // trace\n      if( ! trace )\n         return;\n      //\n      // print_con_op\n      Vector<addr_t> arg = { arg_vec[ arg_index + 0 ] };\n      Vector<Value> res_value = { val_vec[res_index] };\n      print_con_op(arg, res_index, res_value);\n   }\n};\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/csum_op.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_CSUM_OP_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_CSUM_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cstdio>\n# include <cppad/local/val_graph/base_op.hpp>\n# include <cppad/local/atomic_index.hpp>\n# include <cppad/core/atomic/four/atomic.hpp>\n# include <cppad/local/sweep/call_atomic.hpp>\n# include <cppad/local/val_graph/print_op.hpp>\n\n// define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_csum_op dev}\n\nThe Cumulative Summation Value Operator\n#######################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CSUM_OP_T\n   // END_CSUM_OP_T\n}\n\nContext\n*******\nThe class is derived from :ref:`val_base_op-name` .\nIt overrides all its base class virtual member functions\nand is a concrete class (it has no pure virtual functions).\n\nget_instance\n************\nThis static member function returns a pointer to a csum_op_t object.\n\nop_enum\n*******\nThis override of :ref:`val_base_op@op_enum` returns ``csum_op_enum`` .\n\nn_before\n********\nThis override of :ref:`val_base_op@n_before` returns 2.\n{xrst_literal\n   // BEGIN_ARG_BEFORE\n   // END_ARG_BEFORE\n}\n\nn_after\n*******\nThis override of :ref:`val_base_op@n_after` returns 1.\nThis is for a copy of *n_arg* that can be used to iterate\nthrough the operators in reverse.\n\nn_res\n*****\nThis override of :ref:`val_base_op@n_res` returns 1.\n\nn_arg\n*****\nsee base_op :ref:`val_base_op@n_arg` .\n\nn_add\n*****\nThis member function returns the number of additions in the summation.\n\nn_sub\n*****\nThis member function returns the number of subtractions in the summation.\n\neval\n****\nThis override of :ref:`val_base_op@eval` computes the summation.\n\n#. The additions in the summation are\n   ::\n\n      val_vec[ arg_vec[ arg_index + 2 ] ] ,\n      val_vec[ arg_vec[ arg_index + 3 ] ] ,\n      ...\n      val_vec[ arg_vec[ arg_index + 1 + n_add ] ]\n\n#. The subtractions in the summation are\n   ::\n\n      val_vec[ arg_vec[ arg_index + 2 + n_add ] ] ,\n      val_vec[ arg_vec[ arg_index + 3 + n_add ] ] ,\n      ...\n      val_vec[ arg_vec[ arg_index + 1 + n_add + n_sub ] ]\n\ntrace\n=====\nIf trace is true, :ref:`val_print_csum_op-name`\nis called to print this operator.\n\n{xrst_toc_hidden\n   val_graph/csum_xam.cpp\n}\nExample\n*******\nThe file :ref:`csum_xam.cpp <val_csum_xam.cpp-name>`\nis an example and test that uses this operator.\n\n{xrst_end val_csum_op}\n*/\n// BEGIN_CSUM_OP_T\ntemplate <class Value>\nclass csum_op_t : public base_op_t<Value> {\npublic:\n   // n_before\n   addr_t n_before(void) const override\n   {  return 2; }\n   //\n   // n_after\n   addr_t n_after(void) const override\n   {  return 1; }\n   //\n   // get_instance\n   static csum_op_t* get_instance(void)\n   {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n      static csum_op_t instance;\n      return &instance;\n   }\n   // op_enum\n   // type of this operator\n   op_enum_t op_enum(void) const override\n   {  return csum_op_enum; }\n   //\n   // n_arg\n   addr_t n_arg(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  addr_t n_add = arg_vec[arg_index + 0];\n      addr_t n_sub = arg_vec[arg_index + 1];\n      return 3 + n_add + n_sub;\n   }\n   //\n   // n_res\n   addr_t n_res(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 1; }\n   //\n   // n_add\n   addr_t n_add(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const\n   {  return size_t( arg_vec[arg_index + 0] ); }\n   //\n   // n_sub\n   addr_t n_sub(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const\n   {  return size_t( arg_vec[arg_index + 1] ); }\n   //\n   // eval\n   void eval(\n      const tape_t<Value>*      tape          ,\n      bool                      trace         ,\n      addr_t                    arg_index     ,\n      addr_t                    res_index     ,\n      Vector<Value>&            val_vec       ,\n      Vector< Vector<addr_t> >& ind_vec_vec   ,\n      size_t&                   compare_false\n    ) const override;\n// END_CSUM_OP_T\n};\n//\n// eval\ntemplate <class Value>\nvoid csum_op_t<Value>::eval(\n   const tape_t<Value>*      tape          ,\n   bool                      trace         ,\n   addr_t                    arg_index     ,\n   addr_t                    res_index     ,\n   Vector<Value>&            val_vec       ,\n   Vector< Vector<addr_t> >& ind_vec_vec   ,\n   size_t&                   compare_false ) const\n{  //\n   // arg_vec\n   const Vector<addr_t>& arg_vec( tape->arg_vec() );\n   //\n   // n_add, n_sub\n   // BEGIN_ARG_BEFORE\n   addr_t n_add         =  arg_vec[arg_index + 0] ;\n   addr_t n_sub         =  arg_vec[arg_index + 1] ;\n   // END_ARG_BEFORE\n   //\n   // sum\n   Value sum(0.0);\n   for(addr_t i = 0; i < n_add; ++i)\n      sum += val_vec[ arg_vec[arg_index + 2 + i] ];\n   for(addr_t i = 0; i < n_sub; ++i)\n      sum -= val_vec[ arg_vec[arg_index + 2 + n_add + i] ];\n   //\n   // val_vec\n   val_vec[res_index] = sum;\n   //\n   // trace\n   if( ! trace )\n      return;\n   //\n   // print_csum_op\n   Vector<addr_t> arg(3 + n_add + n_sub);\n   for(addr_t i = 0; i < addr_t( arg.size() ); ++i)\n      arg[i] = arg_vec[ arg_index + i ];\n   Vector<Value> res_value = { val_vec[res_index] };\n   print_csum_op(arg, res_index, res_value );\n   //\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/cumulative.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_CUMULATIVE_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_CUMULATIVE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-25 Bradley M. Bell\n// ---------------------------------------------------------------------------\n# include <cppad/local/val_graph/tape.hpp>\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_op2csum dev}\n{xrst_spell\n   neg\n}\n\nConvert Add, Subtract, or Negative to Cumulative Summation\n##########################################################\nThese are ideas under construction for a better way to combine\ncumulative summation operators; i.e., an alternative to the summation.hpp file.\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_OP2CSUM\n   // END_OP2CSUM\n}\n\nReplacement Operator\n********************\nThis will replace an addition, subtraction, or negative value operator\nwith an equivalent cumulative summation operator.\n\nop_index\n********\nIs the operator index in this tape for the operator that is being replaced.\nOn input it must correspond to an\nadd_op_enum, sub_op_enum, or neg_op_enum value operator.\nUpon return it will correspond to a csum_op_enum operator.\n\n{xrst_toc_hidden\n   val_graph/cumulative_xam.cpp\n}\nExample\n*******\nsee :ref:`val_cumulative_xam-name` .\n\n{xrst_end val_op2csum}\n*/\n// BEGIN_OP2CSUM\ntemplate <class Value>\nvoid tape_t<Value>::op2csum(addr_t op_index)\n// END_OP2CSUM\n{\n   // op2arg_index_\n   CPPAD_ASSERT_UNKNOWN( op2arg_index_.size() == size_t( n_op() ) );\n   //\n   // arg_index\n   addr_t arg_index = op2arg_index_[op_index];\n   //\n   // op_ptr\n   const base_op_t< Value>* op_ptr = base_op_ptr(op_index);\n   //\n   // op_enum\n   op_enum_t op_enum = op_ptr->op_enum();\n   //\n   // n_add, n_sub\n   addr_t n_add = 0;\n   addr_t n_sub = 0;\n   //\n   // n_add, n_sub\n   switch( op_enum )\n   {  //\n      default :\n      // op_enum is not add_op, sub_op, or neg_op\n      CPPAD_ASSERT_UNKNOWN( false );\n      break;\n\n      // add_op_enum\n      case add_op_enum:\n      n_add = 2;\n      break;\n\n      // sub_op_enum\n      case sub_op_enum:\n      n_add = 1;\n      n_sub = 1;\n      break;\n\n      // neg_op_enum\n      case neg_op_enum:\n      n_add = 0;\n      n_sub = 1;\n      break;\n   }\n   //\n   // op_enum_vec_\n   op_enum_vec_[op_index] = uint8_t( csum_op_enum );\n   //\n   // op2arg_index_\n   op2arg_index_[op_index] = addr_t( var_arg_.size() );\n   //\n   // var_arg_\n   var_arg_.push_back( n_add );\n   var_arg_.push_back( n_sub );\n   for(addr_t i = 0; i < n_add + n_sub; ++i)\n   {  addr_t arg_i = var_arg_[arg_index + i];\n      var_arg_.push_back( arg_i );\n   }\n   //\n   // var_arg_\n   addr_t n_arg = 3 + n_add + n_sub;\n   var_arg_.push_back( n_arg );\n   //\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/dead_code.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_DEAD_CODE_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_DEAD_CODE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-25 Bradley M. Bell\n// ---------------------------------------------------------------------------\n# include <cppad/local/val_graph/tape.hpp>\n# include <cppad/local/val_graph/rev_depend.hpp>\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_tape_dead_code dev}\n{xrst_spell\n   comp\n   dep\n}\n\nDead Code Elimination\n#####################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_DEAD_CODE\n   // END_DEAD_CODE\n}\n\nkeep_compare\n************\nsee :ref:`val_tape_option@keep_compare`:\n\n#. If this is false, all the :ref`val_comp_op-name` operators will be removed.\n   In this case future calls to eval will not modify\n   :ref:`val_tape@eval@compare_false` .\n#. If this is true, the compare_no_enum compare operators are removed and\n   other comparisons are kept.\n\nkeep_print\n**********\nsee :ref:`val_tape_option@keep_print`:\n\n\nAlgorithm\n*********\n#. The dependent variables are marked as needed.\n#. The operators are scanned in reverse and if an operator's result is\n   needed, the corresponding arguments are marked as needed.\n   The call operator has a more complicated version of this marking.\n#. A forward pass is made though the operators and only the needed\n   ones are included.\n#. An operators result may have a new index\n   because some previous results were left out.\n   A mapping from the old result indices to the new result indices\n   enables subsequent operators to adjust their argument indices.\n#. After the forward pass, the mapping from old indices to new indices\n   is used to adjust the dependent variable indices.\n\n\nChanges\n*******\nOnly the following values, for this tape, are guaranteed to be same:\n#. The number of independent values :ref:`val_tape@n_ind` .\n#. The size of the dependent vector :ref:`dep_vec.size() <val_tape@dep_vec>` .\n#. The mapping from the independent to the dependent variables.\n\nnew_use_val\n***********\nThe i-th element of the return vector *new_use_val* is true (false),\nif and only if\nthe i-th element of the value vector is used to compute the dependent values.\nThere are two exceptions to this rule. One exception is that all the independent\nvalues are marked as used no matter what.\nThe other exception is that the nan, after the independent variables,\nis also marked as used no matter what.\nIf *new_use_val*\\ [i] is false, the i-th value must be the result of a\ncall operator. In addition, at least one result for each call will\nhave a corresponding *new_use_val* of true.\n\nReference\n*********\n`dead-code elimination <https://en.wikipedia.org/wiki/Dead-code_elimination>`_\n\n{xrst_toc_hidden\n   val_graph/dead_xam.cpp\n}\nExample\n*******\nThe file :ref:`dead_xam.cpp <val_dead_xam.cpp-name>` is an\nexample and test of tape.dead_code().\n\n{xrst_end val_tape_dead_code}\n*/\n// BEGIN_DEAD_CODE\n// new_use_val = dead_code()\ntemplate <class Value>\nvectorBool tape_t<Value>::dead_code(void)\n// END_DEAD_CODE\n{  // -----------------------------------------------------------------------\n   // Dead Code Elimination\n   // https://en.wikipedia.org/wiki/Dead-code_elimination\n   // -----------------------------------------------------------------------\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // thread, initial_inuse\n   size_t thread        = thread_alloc::thread_num();\n   size_t initial_inuse = thread_alloc::inuse(thread);\n# endif\n   //\n   // keep_compare\n   bool keep_compare = option_map_[\"keep_compare\"] == \"true\";\n   //\n   // keep_print\n   bool keep_print = option_map_[\"keep_print\"] == \"true\";\n   //\n   // val_use_case, vec_last_load\n   Vector<addr_t> val_use_case, vec_last_load;\n   rev_depend(val_use_case, vec_last_load);\n   //\n   // new_tape\n   tape_t new_tape;\n   new_tape.set_ind(n_ind_);\n   //\n   // new_which_vec\n   // initialize all dynamic vectors as not used\n   Vector<addr_t> new_which_vec( vec_initial_.size() );\n   for(size_t i = 0; i < vec_initial_.size(); ++i)\n      new_which_vec[i] = addr_t( vec_initial_.size() );\n   //\n   // new_val_index\n   // include nan at index n_ind_ in val_vec\n   Vector<addr_t> new_val_index( n_val_ );\n   for(addr_t i = 0; i <= n_ind_; ++i)\n      new_val_index[i] = addr_t(i);\n   for(addr_t i = n_ind_ + 1; i < n_val_; ++i)\n      new_val_index[i] = addr_t( n_val_ );\n   //\n# ifndef NDEBUG\n   // nan at index n_ind_\n   assert( op_enum_t( new_tape.op_enum_vec_[0] ) == con_op_enum );\n   assert( new_tape.var_arg_[0] == 0 );\n   assert( CppAD::isnan( new_tape.con_vec_[0] ) );\n# endif\n   //\n   // new_use_val\n   // Because the call operator can have more than one result, not all the\n   // results for all the needed operators are used. Initialize as all the\n   // independent values and the nan after them are used.\n   vectorBool new_use_val(n_ind_ + 1);\n   for(addr_t i = 0; i <= n_ind_; ++i)\n      new_use_val[i] = true;\n   //\n   // work\n   Vector<addr_t> work;\n   //\n   // op_itr_forward\n   op_iterator<Value> op_itr_forward(*this, 0);\n   //\n   // i_op\n   for(addr_t i_op = 1; i_op < n_op(); ++i_op)\n   {  //\n      // op_itr_forward\n      ++op_itr_forward; // skip index zero\n      //\n      // op_ptr, arg_index, res_index\n      const base_op_t<Value>* op_ptr    = op_itr_forward.op_ptr();\n      addr_t                  res_index = op_itr_forward.res_index();\n      addr_t                  arg_index = op_itr_forward.arg_index();\n      //\n      // op_enum, n_res\n      op_enum_t  op_enum   = op_ptr->op_enum();\n      addr_t     n_res     = op_ptr->n_res(arg_index, var_arg_);\n      //\n      // need_op\n      bool need_op = false;\n      if( n_res == 0 )\n      {  if( op_enum == vec_op_enum || op_enum == store_op_enum )\n         {  addr_t which_vector = var_arg_[arg_index + 0];\n            need_op             = i_op < vec_last_load[which_vector];\n         }\n         else if( op_enum == pri_op_enum )\n         {  need_op  = keep_print;\n            need_op &= var_arg_[arg_index + 2] != this->n_ind();\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( op_enum == comp_op_enum );\n            need_op  = keep_compare;\n            need_op &= var_arg_[arg_index + 0] != addr_t(compare_no_enum);\n         }\n      }\n      else for(addr_t k = 0; k < n_res; ++k)\n         need_op |= 0 != val_use_case[ res_index + k];\n      //\n      if( need_op )\n      {  addr_t new_res_index = record_new(\n            new_tape        ,\n            new_which_vec   ,\n            work            ,\n            new_val_index   ,\n            val_use_case    ,\n            op_ptr          ,\n            arg_index       ,\n            res_index\n         );\n         //\n         // new_val_index\n         for(addr_t k = 0; k < n_res; ++k)\n            new_val_index[ res_index + k ] = new_res_index + k;\n         //\n         // new_use_val\n         for(addr_t k = 0; k < n_res; ++k)\n         {  bool use_val_k = val_use_case[ res_index + k ] != 0;\n            new_use_val.push_back( use_val_k );\n         }\n      }\n   }\n   //\n   // dep_vec\n   Vector<addr_t> dep_vec( dep_vec_.size() );\n   for(size_t k = 0; k < dep_vec_.size(); ++k)\n      dep_vec[k] = new_val_index[ dep_vec_[k] ];\n   new_tape.set_dep( dep_vec );\n   //\n   // swap\n   swap(new_tape);\n   //\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // inuse\n   size_t final_inuse = thread_alloc::inuse(thread);\n   std::cout << \"dead_code:  inuse = \" << final_inuse - initial_inuse << \"\\n\";\n# endif\n   // BEGIN_RETURN\n   CPPAD_ASSERT_UNKNOWN( size_t( n_val() ) == new_use_val.size() );\n   return new_use_val;\n   // END_RETURN\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/dis_op.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_DIS_OP_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_DIS_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/val_graph/base_op.hpp>\n# include <cppad/local/val_graph/print_op.hpp>\n# include <cppad/core/discrete/discrete.hpp>\n\n// define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_dis_op dev}\n\nThe Discrete Value Operator\n###########################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_DIS_OP_T\n   // END_DIS_OP_T\n}\n\nContext\n*******\nThe class is derived from :ref:`val_base_op-name` .\nIt overrides all its base class virtual member functions\nand is a concrete class (it has no pure virtual functions).\n\nget_instance\n************\nThis static member function returns a pointer to a dis_op_t object.\n\nop_enum\n*******\nThis override of :ref:`val_base_op@op_enum` returns ``dis_op_enum`` .\n\nn_before\n********\nThis override of :ref:`val_base_op@n_before` returns 1.\n{xrst_literal\n   // BEGIN_ARG_BEFORE\n   // END_ARG_BEFORE\n}\n\nn_after\n*******\nThis override of :ref:`val_base_op@n_after` returns 0.\n\nn_arg\n*****\nThis override of :ref:`val_base_op@n_arg` returns 2.\n\nn_res\n*****\nThis override of :ref:`val_base_op@n_res` returns 1.\n\neval\n****\nThis override of :ref:`val_base_op@eval` sets\nthe result equal to the discrete function evaluated at\n::\n\n      val_vec[ arg_vec[ arg_index + 1 ] ]\n\ntrace\n=====\nIf trace is true, :ref:`val_print_op-name` is called to print this operator.\n\n{xrst_toc_hidden\n   val_graph/dis_xam.cpp\n}\nExample\n*******\nThe file :ref:`dis_xam.cpp <val_dis_xam.cpp-name>`\nis an example and test that uses this operator.\n\n{xrst_end val_dis_op}\n*/\n// BEGIN_DIS_OP_T\ntemplate <class Value>\nclass dis_op_t : public base_op_t<Value> {\npublic:\n   // n_before\n   addr_t n_before(void) const override\n   {  return 1; }\n   //\n   // n_after\n   addr_t n_after(void) const override\n   {  return 0; }\n   //\n   // get_instance\n   static dis_op_t* get_instance(void)\n   {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n      static dis_op_t instance;\n      return &instance;\n   }\n   // op_enum\n   op_enum_t op_enum(void) const override\n   {  return dis_op_enum; }\n   //\n   // discrete_index\n   size_t discrete_index(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      )\n   {  return size_t( arg_vec[arg_index + 0] ); }\n// END_DIS_OP_T\n   //\n   // n_arg\n   addr_t n_arg(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 2; }\n   //\n   // n_res\n   addr_t n_res(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 1; }\n   //\n   // eval\n   void eval(\n      const tape_t<Value>*      tape          ,\n      bool                      trace         ,\n      addr_t                    arg_index     ,\n      addr_t                    res_index     ,\n      Vector<Value>&            val_vec       ,\n      Vector< Vector<addr_t> >& ind_vec_vec   ,\n      size_t&                   compare_false ) const override\n   {  //\n      // arg_vec\n      const Vector<addr_t>& arg_vec( tape->arg_vec() );\n      //\n      // discrete_index\n      // BEGIN_ARG_BEFORE\n      size_t       discrete_index = size_t( arg_vec[arg_index + 0] );\n      // END_ARG_BEFORE\n      //\n      // val_vec\n      addr_t       val_index      = arg_vec[ arg_index + 1 ];\n      const Value& value          = val_vec[val_index];\n      val_vec[res_index] = discrete<Value>::eval(discrete_index, value);\n      //\n      // trace\n      if( ! trace )\n         return;\n      //\n      std::string name = discrete<Value>::name(discrete_index);\n      Vector<addr_t> arg_val_index = { arg_vec[arg_index + 1] };\n      Vector<Value> res_value      = { val_vec[res_index] };\n      print_op(name, arg_val_index, res_index, res_value);\n      //\n      return;\n   }\n};\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/dyn_type.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_DYN_TYPE_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_DYN_TYPE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-23 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n-------------------------------------------------------------------------------\n{xrst_begin_parent type_dyn_op dev}\n\nTypes of Dynamic Parameter Operators\n####################################\n\n{xrst_end type_dyn_op}\n-------------------------------------------------------------------------------\n{xrst_begin unary_dyn_op dev}\n\nIs This a Binary Dynamic Parameter Operator\n###########################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_UNARY_DYN_OP\n   // END_UNARY_DYN_OP\n}\n\ndyn_op\n******\nis the dynamic parameter operator.\n\nReturn\n******\nThe return is true if this operator has one operands and is recorded by\nspecifying the operator and parameter address of the operand on the tape.\n\n{xrst_end unary_dyn_op}\n*/\nnamespace CppAD { namespace local { namespace val_graph {\n\n// BEGIN_UNARY_DYN_OP\ninline bool unary_dyn_op(op_code_dyn dyn_op)\n// END_UNARY_DYN_OP\n{  bool result;\n   switch(dyn_op)\n   {  default:\n      result = false;\n      break;\n      //\n      case abs_dyn:\n      case acos_dyn:\n      case acosh_dyn:\n      case asin_dyn:\n      case asinh_dyn:\n      case atan_dyn:\n      case atanh_dyn:\n      case cos_dyn:\n      case cosh_dyn:\n      case erf_dyn:\n      case erfc_dyn:\n      case exp_dyn:\n      case expm1_dyn:\n      case fabs_dyn:\n      case log1p_dyn:\n      case log_dyn:\n      case neg_dyn:\n      case sign_dyn:\n      case sin_dyn:\n      case sinh_dyn:\n      case sqrt_dyn:\n      case tan_dyn:\n      case tanh_dyn:\n      result = true;\n      break;\n   }\n   return result;\n}\n/*\n-------------------------------------------------------------------------------\n{xrst_begin binary_dyn_op dev}\n\nIs This a Binary Dynamic Parameter Operator\n###########################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_BINARY_DYN_OP\n   // END_BINARY_DYN_OP\n}\n\ndyn_op\n******\nis the dynamic parameter operator.\n\nReturn\n******\nThe return is true if this operator has two operands and is recorded by\nspecifying the operator and parameter address for each of the operands.\n\n{xrst_end binary_dyn_op}\n*/\n// BEGIN_BINARY_DYN_OP\ninline bool binary_dyn_op(op_code_dyn dyn_op)\n// END_BINARY_DYN_OP\n{  bool result;\n   switch(dyn_op)\n   {  default:\n      result = false;\n      break;\n      case add_dyn:\n      case div_dyn:\n      case mul_dyn:\n      case pow_dyn:\n      case sub_dyn:\n      case zmul_dyn:\n      result = true;\n      break;\n   }\n   return result;\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/enable_parallel.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_ENABLE_PARALLEL_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_ENABLE_PARALLEL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n// BEGIN_SORT_THIS_LINE_PLUS_1\n# include <cppad/local/val_graph/base_op.hpp>\n# include <cppad/local/val_graph/binary_op.hpp>\n# include <cppad/local/val_graph/call_op.hpp>\n# include <cppad/local/val_graph/cexp_op.hpp>\n# include <cppad/local/val_graph/comp_op.hpp>\n# include <cppad/local/val_graph/con_op.hpp>\n# include <cppad/local/val_graph/csum_op.hpp>\n# include <cppad/local/val_graph/dis_op.hpp>\n# include <cppad/local/val_graph/pri_op.hpp>\n# include <cppad/local/val_graph/unary_op.hpp>\n# include <cppad/local/val_graph/vector_op.hpp>\n// END_SORT_THIS_LINE_MINUS_1\n//\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_enable_parallel dev}\n\nEnable val_graph Operators During Parallel Mode\n###############################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ENABLE_PARALLEL\n   // END_ENABLE_PARALLEL\n}\n\nPurpose\n*******\nConvert an operator enum type :ref:`val_graph_type@op_enum_t`\nto a pointer to an operator base class object :ref:`val_base_op-name` .\n\n{xrst_end val_enable_parallel}\n*/\n// ----------------------------------------------------------------------------\n\n// BEGIN_ENABLE_PARALLEL\n// CppAD::local::val_graph enable_parallel()\ntemplate <class Value> void enable_parallel(void)\n// END_ENABLE_PARALLEL\n{  //\n   // BEGIN_SORT_THIS_LINE_PLUS_1\n   abs_op_t<Value>::get_instance();\n   acos_op_t<Value>::get_instance();\n   acosh_op_t<Value>::get_instance();\n   add_op_t<Value>::get_instance();\n   asin_op_t<Value>::get_instance();\n   asinh_op_t<Value>::get_instance();\n   atan_op_t<Value>::get_instance();\n   atanh_op_t<Value>::get_instance();\n   call_op_t<Value>::get_instance();\n   cexp_op_t<Value>::get_instance();\n   comp_op_t<Value>::get_instance();\n   con_op_t<Value>::get_instance();\n   cos_op_t<Value>::get_instance();\n   cosh_op_t<Value>::get_instance();\n   csum_op_t<Value>::get_instance();\n   dis_op_t<Value>::get_instance();\n   div_op_t<Value>::get_instance();\n   erf_op_t<Value>::get_instance();\n   erfc_op_t<Value>::get_instance();\n   exp_op_t<Value>::get_instance();\n   expm1_op_t<Value>::get_instance();\n   load_op_t<Value>::get_instance();\n   log1p_op_t<Value>::get_instance();\n   log_op_t<Value>::get_instance();\n   mul_op_t<Value>::get_instance();\n   neg_op_t<Value>::get_instance();\n   pow_op_t<Value>::get_instance();\n   pri_op_t<Value>::get_instance();\n   sign_op_t<Value>::get_instance();\n   sin_op_t<Value>::get_instance();\n   sinh_op_t<Value>::get_instance();\n   sqrt_op_t<Value>::get_instance();\n   store_op_t<Value>::get_instance();\n   sub_op_t<Value>::get_instance();\n   tan_op_t<Value>::get_instance();\n   tanh_op_t<Value>::get_instance();\n   vec_op_t<Value>::get_instance();\n   // END_SORT_THIS_LINE_MINUS_1\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/fold_con.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_FOLD_CON_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_FOLD_CON_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-25 Bradley M. Bell\n/*\n-------------------------------------------------------------------------------\n{xrst_begin val_tape_fold_con dev}\n{xrst_spell\n   dep\n}\n\nConstant Folding\n################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_FOLD_CON\n   // END_FOLD_CON\n}\n\nDiscussion\n**********\nThis is like :ref:`value numbering <val_tape_renumber-title>` but a major\ndifference is that it adds a new operator for each folded constant.\n\n#. operator results that are constants get replaced by con_op operators.\n   Thus all the constants that are used to compute the dependent values\n   are the result of a con_op operator.\n#. If all the results for an operator get replaced, the operator becomes\n   dead code.\n\nCppAD\n=====\nCppAD functions fold constants before recording but constants\nthat result from an atomic function do not have separate constant operators.\n\n#. Perhaps fun2val could make a separate operator for these constants\n   and it would not be necessary to fold constants here.\n#. On the other hand, folding will be necessary if we allow for creating a new\n   tape where some of the independent values are constants\n#. Currently, this uses more memory than the other optimization steps\n   and is of dubious value in the context of CppAD.\n\n\nChanges\n*******\nOnly the following values, for this tape, are guaranteed to be same:\n#. The number of independent values :ref:`val_tape@n_ind` .\n#. The size of the dependent vector :ref:`dep_vec.size() <val_tape@dep_vec>` .\n\nReference\n*********\n`constant folding <https://en.wikipedia.org/wiki/Constant_folding>`_ .\n\n{xrst_toc_hidden\n   val_graph/fold_con_xam.cpp\n}\nExample\n*******\nThe file :ref:`fold_con_xam.cpp <val_fold_con_xam.cpp-name>`\nis an example and test of tape.fold_con().\n\n{xrst_end val_tape_fold_con}\n-------------------------------------------------------------------------------\n*/\n# include <cppad/local/val_graph/tape.hpp>\n# include <cppad/local/val_graph/call_atomic.hpp>\n\nnamespace CppAD { namespace local { namespace val_graph {\n\n// BEGIN_FOLD_CON\ntemplate <class Value>\nvoid tape_t<Value>::fold_con(void)\n// END_FOLD_CON\n{\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // thread, initial_inuse\n   size_t thread        = thread_alloc::thread_num();\n   size_t initial_inuse = thread_alloc::inuse(thread);\n# endif\n   //\n   // nan\n   Value nan = CppAD::numeric_limits<Value>::quiet_NaN();\n   //\n   // val_index2con\n   Vector<Value> val_index2con(n_val_);\n   for(addr_t i = 0; i < n_ind_; ++i)\n      val_index2con[i] = nan;\n   bool trace           = false;\n   eval(trace, val_index2con);\n   //\n   // is_constant\n   vectorBool is_constant( static_cast<size_t>(n_val_) );\n   for(addr_t i = 0; i < n_val_; ++i)\n      is_constant[i] = false;\n   //\n   // con_x, type_x, type_y\n   // use CppAD::vector because call_atomic_for_type expects it\n   CppAD::vector<Value> con_x;\n   CppAD::vector<ad_type_enum> type_x, type_y;\n   //\n   // op_arg\n   Vector<addr_t> op_arg;\n   //\n   // new_tape\n   tape_t new_tape;\n   new_tape.set_ind(n_ind_);\n   //\n   // old2new_index\n   Vector<addr_t> old2new_index;\n   for(addr_t i = 0; i < n_ind_; ++i)\n      old2new_index.push_back( i );\n   //\n   // we will skip nan at index zero\n   old2new_index.push_back( n_ind_ );\n   is_constant[n_ind_] = true;\n   //\n   // op_itr\n   op_iterator<Value> op_itr(*this, 0);\n   //\n   // i_op\n   for(addr_t i_op = 1; i_op < n_op(); ++i_op)\n   {  //\n      // op_itr\n      ++op_itr; // skip nan at index zero\n      //\n      // op_ptr, arg_index, res_index\n      const base_op_t<Value>* op_ptr    = op_itr.op_ptr();\n      addr_t                  arg_index = op_itr.arg_index();\n      addr_t                  res_index = op_itr.res_index();\n      //\n      // op_enum, n_arg, n_before, n_after, n_res\n      op_enum_t  op_enum   = op_ptr->op_enum();\n      addr_t     n_before  = op_ptr->n_before();\n      addr_t     n_after   = op_ptr->n_after();\n      addr_t     n_arg     = op_ptr->n_arg(arg_index, var_arg_);\n      addr_t     n_res     = op_ptr->n_res(arg_index, var_arg_);\n      //\n      CPPAD_ASSERT_UNKNOWN( size_t( res_index ) == old2new_index.size() );\n      //\n      // new_tape, is_constant, old2new_index\n      if( n_res == 1 && op_enum != con_op_enum )\n      {  bool fold = true;\n         for(addr_t i = n_before; i < n_arg - n_after; ++i)\n            fold &= is_constant[ var_arg_[arg_index + i] ];\n         if( fold )\n         {  is_constant[res_index]  = true;\n            const Value& value      = val_index2con[res_index];\n            addr_t new_res_index    = new_tape.record_con_op(value);\n            old2new_index.push_back( new_res_index );\n         }\n         else\n         {  op_arg.resize(n_arg);\n            for(addr_t k = 0; k < n_before; ++k)\n               op_arg[k] = var_arg_[arg_index + k];\n            for(addr_t k = n_before; k < n_arg - n_after; ++k)\n            {  addr_t old_index = var_arg_[arg_index + k];\n               assert( old_index < res_index );\n               op_arg[k] = old2new_index[old_index];\n            }\n            for(addr_t k = 1; k <= n_after; ++k)\n               op_arg[n_arg - k] = var_arg_[arg_index + n_arg - k];\n            //\n            addr_t new_res_index = new_tape.record_op(op_enum, op_arg);\n            old2new_index.push_back( new_res_index );\n         }\n      }\n      else switch(op_enum)\n      {  //\n         // default\n         default:\n         CPPAD_ASSERT_KNOWN(false,\n            \"val_graph::fold_con: This operator not yet implemented\"\n         );\n         break;\n         // ----------------------------------------------------------------\n         // con_op\n         case con_op_enum:\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1);\n         {  is_constant[res_index] = true;\n            const Value& value   = val_index2con[res_index];\n            addr_t new_res_index = new_tape.record_con_op(value);\n            old2new_index.push_back( new_res_index );\n         }\n         break;\n         // ----------------------------------------------------------------\n         // call_op\n         case call_op_enum:\n         {  //\n            // atomic_index, call_id\n            addr_t atomic_index = var_arg_[arg_index + 2];\n            addr_t call_id      = var_arg_[arg_index + 3];\n            CPPAD_ASSERT_UNKNOWN( atomic_index > 0 );\n            //\n            // n_before, n_x\n            addr_t n_x      = n_arg - n_before - op_ptr->n_after();\n            //\n            // con_x, type_x\n            type_x.resize(n_x);\n            con_x.resize(n_x);\n            for(addr_t i = 0; i < n_x; ++i)\n            {  addr_t val_index =  var_arg_[arg_index + n_before + i];\n               con_x[i] = val_index2con[val_index];\n               if( is_constant[val_index] )\n                  type_x[i] = constant_enum;\n               else\n                  type_x[i] = variable_enum;;\n            }\n            //\n            // type_y\n            type_y.resize(n_res);\n            call_atomic_for_type<Value>(\n               con_x, type_x, type_y, size_t(atomic_index), size_t(call_id)\n            );\n            //\n            // new_tape, new_res_index\n            // record the function call\n            op_arg.resize(n_x);\n            for(addr_t k = 0; k < n_x; ++k)\n            {  addr_t old_index   = var_arg_[arg_index + n_before + k];\n               op_arg[k]      = old2new_index[old_index];\n            }\n            addr_t new_res_index = new_tape.record_call_op(\n               atomic_index, call_id, n_res, op_arg\n            );\n            //\n            // is_constant, new_tape, old2new_index\n            for(addr_t i = 0; i < n_res; ++i)\n            {  is_constant[res_index + i] = type_y[i] <= constant_enum;\n               if( is_constant[res_index + i] )\n               {  const Value& value      = val_index2con[res_index + i];\n                  addr_t con_res_index    = new_tape.record_con_op(value);\n                  old2new_index.push_back( con_res_index );\n               }\n               else\n               {  // if none of these results get used, this call is dead code\n                  old2new_index.push_back(new_res_index + i);\n               }\n            }\n         }\n         break;\n      }\n   }\n   //\n   // dep_vec\n   Vector<addr_t> dep_vec( dep_vec_.size() );\n   for(size_t k = 0; k < dep_vec_.size(); ++k)\n      dep_vec[k] = old2new_index[ dep_vec_[k] ];\n   new_tape.set_dep( dep_vec );\n   //\n   // swap\n   swap(new_tape);\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // inuse\n   size_t final_inuse = thread_alloc::inuse(thread);\n   std::cout << \"fold_con:  inuse = \" << final_inuse - initial_inuse << \"\\n\";\n# endif\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/fun2val.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_FUN2VAL_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_FUN2VAL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// --------------------------------------------------------------------------\n/*\n------------------------------------------------------------------------------\n{xrst_begin fun2val_graph dev}\n\nCreate a Value Graph Corresponding to an ADFun Object\n#####################################################\n\nSyntax\n******\n| |tab| ``ADFun`` < *Base* > *fun*\n| |tab| *fun* . ``fun2val`` ( *val_tape* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nBase\n****\nis the type corresponding to this :ref:`adfun-name` object;\ni.e., its calculations are done using the type *Base* .\nIt is also :ref:`val_tape@Value` type for the tape.\n\nRecBase\n*******\nin the prototype above, *RecBase* is the same type as *Base* .\n\nval_tape\n********\nThis is a :ref:`val_tape-name` object.\nThe input contents of the tape does not matter.\nUpon return it is a\n:ref:`val_graph-name` representation of the function.\nThe independent dynamic parameters have the same order as in\n*fun* and come first (in the value graph independent vector).\nThe independent variables have the same order as in\n*fun* and come after the independent dynamic parameters.\n\nfun\n***\nThis is the function that the value graph will correspond to.\n\nUnder Construction\n******************\nThis routine is under construction and is only implemented\nfor a few of the possible :ref:`ADFun-name` operators.\n\n{xrst_toc_hidden\n   val_graph/fun2val_xam.cpp\n}\nExamples\n********\nThe file :ref:`val_fun2val_xam.cpp-name`\nis an example an test of this conversion.\n\n{xrst_end fun2val_graph}\n*/\n\n# include <cppad/core/ad_fun.hpp>\n# include <cppad/local/op_code_dyn.hpp>\n# include <cppad/local/val_graph/tape.hpp>\n# include <cppad/local/pod_vector.hpp>\n# include <cppad/local/val_graph/var_type.hpp>\n# include <cppad/local/val_graph/dyn_type.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n// BEGIN_PROTOTYPE\ntemplate <class Base, class RecBase>\nvoid ADFun<Base, RecBase>::fun2val(\n   local::val_graph::tape_t<Base>& val_tape  )\n// END_PROTOTYPE\n{  //\n   // Vector, addr_t, op_enum_t\n   using local::val_graph::Vector;\n   using local::val_graph::addr_t;\n   using local::val_graph::op_enum_t;\n   op_enum_t number_op_enum = local::val_graph::number_op_enum;\n   //\n   // op_code_dyn, number_dyn, op_code_var\n   using local::op_code_dyn;\n   op_code_dyn number_dyn = local::number_dyn;\n   using local::op_code_var;\n   //\n   // pod_vector, opcode_t\n   using local::pod_vector;\n   using local::opcode_t;\n   //\n   // invalid_addr_t\n   addr_t invalid_addr_t = std::numeric_limits<addr_t>::max();\n   //\n   // parameter\n   const Base* parameter = play_.par_ptr();\n   //\n   // dyn_op2val_op\n   Vector<op_enum_t> dyn_op2val_op(number_dyn);\n   for(size_t i = 0; i < size_t(number_dyn); ++i)\n      dyn_op2val_op[i] = number_op_enum; // invalid\n   dyn_op2val_op[local::add_dyn] = local::val_graph::add_op_enum;\n   dyn_op2val_op[local::neg_dyn] = local::val_graph::neg_op_enum;\n   dyn_op2val_op[local::sub_dyn] = local::val_graph::sub_op_enum;\n   // ------------------------------------------------------------------------\n   // var_op2val_op\n   Vector<op_enum_t> var_op2val_op(local::NumberOp);\n   for(size_t i = 0; i < size_t(local::NumberOp); ++i)\n      var_op2val_op[i] = number_op_enum; // invalid\n   //\n   // unary operators\n   // BEGIN_SORT_THIS_LINE_PLUS_1\n   var_op2val_op[local::AbsOp]    = local::val_graph::abs_op_enum;\n   var_op2val_op[local::AcosOp]   = local::val_graph::acos_op_enum;\n   var_op2val_op[local::AcoshOp]  = local::val_graph::acosh_op_enum;\n   var_op2val_op[local::AsinOp]   = local::val_graph::asin_op_enum;\n   var_op2val_op[local::AsinhOp]  = local::val_graph::asinh_op_enum;\n   var_op2val_op[local::AtanOp]   = local::val_graph::atan_op_enum;\n   var_op2val_op[local::AtanhOp]  = local::val_graph::atanh_op_enum;\n   var_op2val_op[local::CosOp]    = local::val_graph::cos_op_enum;\n   var_op2val_op[local::CoshOp]   = local::val_graph::cosh_op_enum;\n   var_op2val_op[local::ErfOp]    = local::val_graph::erf_op_enum;\n   var_op2val_op[local::ErfcOp]   = local::val_graph::erfc_op_enum;\n   var_op2val_op[local::ExpOp]    = local::val_graph::exp_op_enum;\n   var_op2val_op[local::Expm1Op]  = local::val_graph::expm1_op_enum;\n   var_op2val_op[local::Log1pOp]  = local::val_graph::log1p_op_enum;\n   var_op2val_op[local::LogOp]    = local::val_graph::log_op_enum;\n   var_op2val_op[local::NegOp]    = local::val_graph::neg_op_enum;\n   var_op2val_op[local::SignOp]   = local::val_graph::sign_op_enum;\n   var_op2val_op[local::SinOp]    = local::val_graph::sin_op_enum;\n   var_op2val_op[local::SinhOp]   = local::val_graph::sinh_op_enum;\n   var_op2val_op[local::SqrtOp]   = local::val_graph::sqrt_op_enum;\n   var_op2val_op[local::TanOp]    = local::val_graph::tan_op_enum;\n   var_op2val_op[local::TanhOp]   = local::val_graph::tanh_op_enum;\n   // END_SORT_THIS_LINE_MINUS_1\n   //\n   // add\n   var_op2val_op[local::AddpvOp] = local::val_graph::add_op_enum;\n   var_op2val_op[local::AddvvOp] = local::val_graph::add_op_enum;\n   //\n   // sub\n   var_op2val_op[local::SubpvOp] = local::val_graph::sub_op_enum;\n   var_op2val_op[local::SubvpOp] = local::val_graph::sub_op_enum;\n   var_op2val_op[local::SubvvOp] = local::val_graph::sub_op_enum;\n   //\n   // mul\n   var_op2val_op[local::MulpvOp] = local::val_graph::mul_op_enum;\n   var_op2val_op[local::MulvvOp] = local::val_graph::mul_op_enum;\n   //\n   // div\n   var_op2val_op[local::DivpvOp] = local::val_graph::div_op_enum;\n   var_op2val_op[local::DivvpOp] = local::val_graph::div_op_enum;\n   var_op2val_op[local::DivvvOp] = local::val_graph::div_op_enum;\n   //\n   // pow\n   var_op2val_op[local::PowpvOp] = local::val_graph::pow_op_enum;\n   var_op2val_op[local::PowvpOp] = local::val_graph::pow_op_enum;\n   var_op2val_op[local::PowvvOp] = local::val_graph::pow_op_enum;\n   // ------------------------------------------------------------------------\n   //\n   // dyn_par_op\n   // mapping from dynamic parameter index to operator\n   const pod_vector<opcode_t>& dyn_par_op ( play_.dyn_par_op()  );\n   //\n   // dyn2par_index\n     // mapping from dynamic parameter index to parameter index\n   const pod_vector<addr_t>& dyn2par_index ( play_.dyn2par_index() );\n   //\n   // dyn_par_arg\n   // vector that contains arguments to all the dynamic parameter operators\n   const pod_vector<addr_t>&  dyn_par_arg( play_.dyn_par_arg() );\n   //\n   // n_parameter\n   // number of parameters\n   size_t n_parameter = play_.num_par_all();\n   //\n   // n_dynamic\n   // number of dynamic parameters\n   size_t n_dynamic = dyn2par_index.size();\n   //\n   // n_dynamic_ind\n   // number of independent dynamic parameters\n   size_t n_dynamic_ind = play_.n_dyn_independent();\n   //\n   // n_variables\n   // number of variables\n   const size_t n_variable = play_.num_var();\n   //\n   // n_variable_ind\n   // number of independent variables\n   size_t n_variable_ind = ind_taddr_.size();\n   //\n   // n_val_ind\n   // number of independent values\n   addr_t n_val_ind = addr_t( n_dynamic_ind + n_variable_ind );\n   //\n# ifndef NDEBUG\n   // nan_val_index\n   // initialize value vector tape\n   addr_t nan_val_index = val_tape.set_ind( n_val_ind );\n   CPPAD_ASSERT_UNKNOWN( nan_val_index == n_val_ind );\n# else\n   val_tape.set_ind( n_val_ind );\n# endif\n   //\n   // val_tape, vec_info_vec\n   // Put dynamic vectors in val_tape and create vec_info_vec\n   struct vec_info_t { size_t size; size_t offset; };\n   Vector<vec_info_t> vec_info_vec;\n   {  size_t n_vecad_ind = play_.num_var_vec_ind();\n      size_t index         = 0;\n      while(index < n_vecad_ind)\n      {  size_t size         = play_.GetVecInd(index++);\n         size_t offset       = index;\n         //\n         Vector<addr_t> initial(size);\n         for(size_t i = 0; i < size; ++i)\n         {  size_t par_index = play_.GetVecInd(index++);\n            addr_t val_index = val_tape.record_con_op( parameter[par_index] );\n            initial[i]       = val_index;\n         }\n# ifdef NDEBUG\n         val_tape.record_vec_op(initial);\n# else\n         addr_t which_vector = val_tape.record_vec_op(initial);\n         CPPAD_ASSERT_UNKNOWN( size_t(which_vector) == vec_info_vec.size() );\n# endif\n         vec_info_t vec_info = {size, offset};\n         vec_info_vec.push_back( vec_info );\n      }\n   }\n   //\n   // vec_offset2index\n   // mapping from vecad offset to index in vec_info_vec\n   auto vec_offset2index = [&vec_info_vec](addr_t offset)\n   {  addr_t index    = 0;\n      size_t offset_s = size_t(offset);\n      while( vec_info_vec[index].offset < offset_s )\n         ++index;\n      CPPAD_ASSERT_UNKNOWN( vec_info_vec[index].offset == offset_s );\n      return index;\n   };\n   //\n   // par2val_index\n   // Initialize mapping from parameter index to index in value vector.\n   Vector<addr_t> par2val_index(n_parameter);\n   for(size_t i = 0; i < n_parameter; ++i)\n      par2val_index[i] = invalid_addr_t;\n   for(addr_t i = 0; i < addr_t( n_dynamic_ind ); ++i)\n      par2val_index[i + 1] = i;\n   //\n   // val_op_arg, var_op_res, res_is_par;\n   Vector<addr_t> val_op_arg, var_op_res;\n   Vector<bool>   res_is_par;\n   //\n   // i_arg\n   // initial index in dyn_par_arg\n   addr_t i_arg = 0;\n   //\n   // ensure_par2val_index\n   // val_tape, par2val_index\n   auto ensure_par2val_index =\n   [&val_tape, &par2val_index, &parameter, invalid_addr_t] (addr_t par_index)\n   {  addr_t result = par2val_index[par_index];\n      if( result == invalid_addr_t )\n      {  Base constant            = parameter[par_index];\n         result                   = val_tape.record_con_op(constant);\n         par2val_index[par_index] = result;\n      }\n      return result;\n   };\n   //\n   // val_tape\n   // record dynamic parameter operations\n   //\n   // val_tape, val_index, par2val_index\n   addr_t val_index = invalid_addr_t;\n   for(size_t i_dyn = n_dynamic_ind; i_dyn < n_dynamic; ++i_dyn)\n   {  //\n      // i_par\n      size_t i_par = size_t( dyn2par_index[i_dyn] );\n      //\n      // dyn_op\n      // operator for this dynamic parameter\n      local::op_code_dyn dyn_op = local::op_code_dyn( dyn_par_op[i_dyn] );\n      //\n      // is_unary, is_binary\n      bool is_unary  = local::val_graph::unary_dyn_op(dyn_op);\n      bool is_binary = local::val_graph::binary_dyn_op(dyn_op);\n      //\n      // n_arg, val_tape, val_index, par2val_index\n      addr_t n_arg;\n      if( is_unary || is_binary )\n      {  //\n         // val_tape, val_index, par2val_index\n         n_arg = addr_t( num_arg_dyn(dyn_op) );\n         val_op_arg.resize(n_arg);\n         for(addr_t i = 0; i < n_arg; ++i)\n         {  addr_t par_index = dyn_par_arg[i_arg + i];\n            val_op_arg[i]    = ensure_par2val_index(par_index);\n         }\n         // val_tape, val_index\n         op_enum_t val_op = dyn_op2val_op[dyn_op];\n         val_index = val_tape.record_op(val_op, val_op_arg);\n      }\n      else switch( dyn_op )\n      {  //\n         default:\n         CPPAD_ASSERT_KNOWN(false,\n            \"val_graph::fun2val: This dynamic operator not yet implemented\"\n         );\n         // -------------------------------------------------------------------\n         // result_dyn\n         // This is a place holder for multiple result operators\n         case local::result_dyn:\n         CPPAD_ASSERT_UNKNOWN( val_index != invalid_addr_t );\n         n_arg      = 0;\n         val_index += 1;\n         break;\n         // -------------------------------------------------------------------\n         // dis_dyn\n         case local::dis_dyn:\n         {  // val_tape, val_index, par2val_index\n            val_op_arg.resize(1);\n            addr_t discrete_index = dyn_par_arg[i_arg + 0];\n            addr_t par_index      = dyn_par_arg[i_arg + 1];\n            val_op_arg[0]         = ensure_par2val_index(par_index);\n            //\n            // n_arg, val_tape, val_index\n            n_arg = 2;\n            val_index = val_tape.record_dis_op(\n               discrete_index, val_op_arg[0]\n            );\n         }\n         break;\n         // -------------------------------------------------------------------\n         // cond_exp\n         case local::cond_exp_dyn:\n         {  CompareOp cop = CompareOp( dyn_par_arg[i_arg + 0] );\n            addr_t left     = ensure_par2val_index( dyn_par_arg[i_arg + 1] );\n            addr_t right    = ensure_par2val_index( dyn_par_arg[i_arg + 2] );\n            addr_t if_true  = ensure_par2val_index( dyn_par_arg[i_arg + 3] );\n            addr_t if_false = ensure_par2val_index( dyn_par_arg[i_arg + 4] );\n            local::val_graph::compare_enum_t compare_enum;\n            switch( cop )\n            {  case CompareLt:\n               compare_enum = local::val_graph::compare_lt_enum;\n               break;\n\n               case CompareLe:\n               compare_enum = local::val_graph::compare_le_enum;\n               break;\n\n               case CompareEq:\n               compare_enum = local::val_graph::compare_eq_enum;\n               break;\n\n               case CompareGe:\n               compare_enum = local::val_graph::compare_lt_enum;\n               std::swap(if_true, if_false);\n               break;\n\n               case CompareGt:\n               compare_enum = local::val_graph::compare_le_enum;\n               std::swap(if_true, if_false);\n               break;\n\n               case CompareNe:\n               compare_enum = local::val_graph::compare_eq_enum;\n               std::swap(if_true, if_false);\n               break;\n\n               default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               // avoid warning about value not set\n               compare_enum = local::val_graph::compare_no_enum;\n               break;\n            }\n            //\n            // n_arg, val_tape, val_index\n            n_arg     = 5;\n            val_index = val_tape.record_cexp_op(\n               compare_enum, left, right, if_true, if_false\n            );\n         }\n         break;\n         // -------------------------------------------------------------------\n         // atom_dyn\n         case local::atom_dyn:\n         {  //\n            // atomic_index, call_id, n_call_arg, n_res\n            addr_t atomic_index = dyn_par_arg[i_arg + 0];\n            addr_t call_id      = dyn_par_arg[i_arg + 1];\n            addr_t n_call_arg   = dyn_par_arg[i_arg + 2];\n            addr_t n_res        =  dyn_par_arg[i_arg + 3] ;\n            // num_dyn          = size_t( dyn_par_arg[i_age + 4] );\n            //\n            // val_op_arg, val_tape, par2val_index\n            val_op_arg.resize( n_call_arg );\n            for(addr_t i = 0; i < n_call_arg; i++)\n            {  addr_t par_index = dyn_par_arg[i_arg + i + 5];\n               val_op_arg[i] = ensure_par2val_index(par_index);\n            }\n            // n_arg, val_tape, val_index\n            n_arg     = n_call_arg + 5;\n            val_index = val_tape.record_call_op(\n               atomic_index, call_id, n_res, val_op_arg\n            );\n         }\n         break;\n      }\n      // par2val_index\n      // Each dyn_op has one result, result_dyn ops are added to make this so\n      par2val_index[i_par] = val_index;\n      //\n      // i_arg\n      i_arg += n_arg;\n   }\n   //\n   // var2val_index\n   // Initialize mapping from variable index to index in value vector.\n   Vector<addr_t> var2val_index(n_variable);\n   for(size_t i = 0; i < n_variable; ++i)\n      var2val_index[i] = invalid_addr_t;\n   for(addr_t i = 0; i < addr_t(n_variable_ind); ++i)\n      var2val_index[i + 1] = addr_t( n_dynamic_ind )  + i;\n   //\n   // itr, is_var, more_operators\n   local::play::const_sequential_iterator itr  = play_.begin();\n   Vector<bool>       is_var(2);\n   bool more_operators = true;\n   bool in_atomic_call = false;\n   //\n   // val_tape, var2val_index, par2val_index\n   while(more_operators)\n   {  //\n      //\n      // itr, var_op, var_op_arg, i_var\n      local::op_code_var var_op;\n      const            addr_t* var_op_arg;\n      size_t           i_var;\n      (++itr).op_info(var_op, var_op_arg, i_var);\n      //\n      // is_unary, is_binary, is_compare\n      // initialize to avoid compiler warning\n      bool is_unary = false, is_binary = false, is_compare = false;\n      local::val_graph::type_var_op(\n         var_op, is_unary, is_binary, is_compare\n      );\n      // ----------------------------------------------------------------------\n      if( is_unary )\n      {  //\n         // val_op\n         op_enum_t val_op = var_op2val_op[var_op];\n         CPPAD_ASSERT_UNKNOWN( val_op < number_op_enum );\n         //\n         // val_tape, val_index\n         val_op_arg.resize(1);\n         val_op_arg[0] = var2val_index[ var_op_arg[0] ];\n         val_index = val_tape.record_op(val_op, val_op_arg);\n         //\n         // var2val_index\n         var2val_index[i_var] = val_index;\n      }\n      // ----------------------------------------------------------------------\n      else if( is_binary )\n      {   switch( var_op )\n         {\n            default:\n            CPPAD_ASSERT_KNOWN(false,\n               \"val_graph::fun2val: This variable operator not yet implemented\"\n            );\n\n            // first argument a parameter, second argument a variable\n            case local::AddpvOp:\n            case local::SubpvOp:\n            case local::MulpvOp:\n            case local::DivpvOp:\n            case local::PowpvOp:\n            is_var[0]   = false;\n            is_var[1]   = true;\n            break;\n\n            // first argument a variable, second argument a parameter\n            case local::SubvpOp:\n            case local::DivvpOp:\n            case local::PowvpOp:\n            is_var[0]   = true;\n            is_var[1]   = false;\n            break;\n\n            // first argument a variable, second argument a variable\n            case local::AddvvOp:\n            case local::SubvvOp:\n            case local::MulvvOp:\n            case local::DivvvOp:\n            case local::PowvvOp:\n            is_var[0]   = true;\n            is_var[1]   = true;\n            break;\n         }\n         //\n         // varl_op_arg, val_tape, par2val_index\n         val_op_arg.resize(2);\n         for(size_t i = 0; i < 2; ++i)\n         {  if( is_var[i] )\n               val_op_arg[i] = var2val_index[ var_op_arg[i] ];\n            else\n               val_op_arg[i] = ensure_par2val_index( var_op_arg[i] );\n         }\n         //\n         // val_op\n         op_enum_t val_op = var_op2val_op[var_op];\n         CPPAD_ASSERT_UNKNOWN( val_op < number_op_enum );\n         //\n         // record_op, val_index\n         val_index = val_tape.record_op(val_op, val_op_arg);\n         //\n         // var2val_index\n         var2val_index[i_var] = val_index;\n      }\n      // ----------------------------------------------------------------------\n      else if( is_compare )\n      {  //\n         // left_index, right_index\n         addr_t left_index, right_index;\n         switch( var_op )\n         {\n            // default\n            default:\n            CPPAD_ASSERT_UNKNOWN(false);\n            left_index  = 0; // to avoid compiler warning\n            right_index = 0;\n            break;\n\n            // both nodes parameters\n            case local::EqppOp:\n            case local::NeppOp:\n            case local::LtppOp:\n            case local::LeppOp:\n            left_index  = par2val_index[ var_op_arg[0] ];\n            right_index = par2val_index[ var_op_arg[1] ];\n            break;\n\n            // first node parameter, second variable\n            case local::EqpvOp:\n            case local::NepvOp:\n            case local::LtpvOp:\n            case local::LepvOp:\n            left_index  = par2val_index[ var_op_arg[0] ];\n            right_index = var2val_index[ var_op_arg[1] ];\n            break;\n\n            // first node variable, second parameter\n            case local::LtvpOp:\n            case local::LevpOp:\n            left_index  = var2val_index[ var_op_arg[0] ];\n            right_index = par2val_index[ var_op_arg[1] ];\n            break;\n\n            // both nodes variables\n            case local::EqvvOp:\n            case local::NevvOp:\n            case local::LtvvOp:\n            case local::LevvOp:\n            left_index  = var2val_index[ var_op_arg[0] ];\n            right_index = var2val_index[ var_op_arg[1] ];\n            break;\n\n         }\n         // compare_enum\n         local::val_graph::compare_enum_t compare_enum;\n         // Set graph_op\n         switch( var_op )\n         {\n            // default\n            default:\n            CPPAD_ASSERT_UNKNOWN(false);\n            // set to avoid compiler warning\n            compare_enum = local::val_graph::number_compare_enum;\n            break;\n\n            case local::EqppOp:\n            case local::EqpvOp:\n            case local::EqvvOp:\n            compare_enum = local::val_graph::compare_eq_enum;\n            break;\n\n            case local::NeppOp:\n            case local::NepvOp:\n            case local::NevvOp:\n            compare_enum = local::val_graph::compare_ne_enum;\n            break;\n\n            case local::LtppOp:\n            case local::LtpvOp:\n            case local::LtvpOp:\n            case local::LtvvOp:\n            compare_enum = local::val_graph::compare_lt_enum;\n            break;\n\n            case local::LeppOp:\n            case local::LepvOp:\n            case local::LevpOp:\n            case local::LevvOp:\n            compare_enum = local::val_graph::compare_le_enum;\n            break;\n\n         }\n         //\n         // tape\n         val_index = val_tape.record_comp_op(\n            compare_enum, left_index, right_index\n         );\n         CPPAD_ASSERT_UNKNOWN(val_index == 0); // no result for this operator\n      }\n      // ----------------------------------------------------------------------\n      else switch(var_op)\n      {\n         default:\n         CPPAD_ASSERT_KNOWN(false,\n            \"val_graph::fun2val: This variable operator not yet implemented\"\n         );\n         break;\n\n         // ParOp:\n         // val_tape, par2val_index, var2val_index\n         case local::ParOp:\n         val_index            = ensure_par2val_index( var_op_arg[0] );\n         var2val_index[i_var] = val_index;\n         break;\n\n         // EndOp:\n         case local::EndOp:\n         more_operators = false;\n         break;\n\n         // InvOp:\n         // The independent variable indices are already assigned\n         case local::InvOp:\n         break;\n         //\n         // DisOp\n         case local::DisOp:\n         {  // val_tape, var2val_index\n            val_op_arg.resize(1);\n            addr_t discrete_index = var_op_arg[0];\n            val_op_arg[0]         = var2val_index[ var_op_arg[1] ];\n            val_index             = val_tape.record_dis_op(\n               discrete_index, val_op_arg[0]\n            );\n            var2val_index[i_var]  = val_index;\n         }\n         break;\n         // --------------------------------------------------------------\n         case local::LdpOp:\n         {  addr_t which_vector = vec_offset2index( var_op_arg[0] );\n            addr_t vector_index = ensure_par2val_index( var_op_arg[1] );\n            //\n            var2val_index[i_var] = val_tape.record_load_op(\n               which_vector, vector_index\n            );\n         }\n         break;\n         //\n         case local::LdvOp:\n         {  addr_t which_vector = vec_offset2index( var_op_arg[0] );\n            addr_t vector_index = var2val_index[ var_op_arg[1] ];\n            //\n            var2val_index[i_var] = val_tape.record_load_op(\n               which_vector, vector_index\n            );\n         }\n         break;\n         //\n         case local::StppOp:\n         {  addr_t which_vector = vec_offset2index( var_op_arg[0] );\n            addr_t vector_index = ensure_par2val_index( var_op_arg[1] );\n            addr_t value_index  = ensure_par2val_index( var_op_arg[2] );\n            //\n            val_tape.record_store_op(\n               which_vector, vector_index, value_index\n            );\n         }\n         break;\n         //\n         case local::StpvOp:\n         {  addr_t which_vector = vec_offset2index( var_op_arg[0] );\n            addr_t vector_index = ensure_par2val_index( var_op_arg[1] );\n            addr_t value_index  = var2val_index[ var_op_arg[2] ];\n            //\n            val_tape.record_store_op(\n               which_vector, vector_index, value_index\n            );\n         }\n         break;\n         //\n         case local::StvpOp:\n         {  addr_t which_vector = vec_offset2index( var_op_arg[0] );\n            addr_t vector_index = var2val_index[ var_op_arg[1] ];\n            addr_t value_index  = ensure_par2val_index( var_op_arg[2] );\n            //\n            val_tape.record_store_op(\n               which_vector, vector_index, value_index\n            );\n         }\n         break;\n         //\n         case local::StvvOp:\n         {  addr_t which_vector = vec_offset2index( var_op_arg[0] );\n            addr_t vector_index = var2val_index[ var_op_arg[1] ];\n            addr_t value_index  = var2val_index[ var_op_arg[2] ];\n            //\n            val_tape.record_store_op(\n               which_vector, vector_index, value_index\n            );\n         }\n         break;\n         // --------------------------------------------------------------\n         case local::PriOp:\n         {  //\n            // before, after\n            std::string before( play_.GetTxt( size_t( var_op_arg[2] ) ) );\n            std::string after(  play_.GetTxt( size_t( var_op_arg[4] ) ) );\n            //\n            // flag_index\n            addr_t flag_index;\n            if( var_op_arg[0] & 1 )\n               flag_index = var2val_index[ var_op_arg[1] ];\n            else\n               flag_index = ensure_par2val_index( var_op_arg[1] );\n            //\n            // value_index\n            addr_t value_index;\n            if( var_op_arg[0] & 1 )\n               value_index = var2val_index[ var_op_arg[3] ];\n            else\n               value_index = ensure_par2val_index( var_op_arg[3] );\n            //\n            val_index = val_tape.record_pri_op(\n               before, after, flag_index, value_index\n            );\n         }\n         CPPAD_ASSERT_UNKNOWN(val_index == 0); // no result for this operator\n         break;\n         // --------------------------------------------------------------\n         case local::CSumOp:\n         {  //\n            // add, sub\n            Vector<addr_t> add, sub;\n            //\n            // add: constant term\n            add.push_back( ensure_par2val_index( var_op_arg[0] ) );\n            //\n            // add: variables\n            for(addr_t i = 5; i < var_op_arg[1]; ++i)\n               add.push_back( var2val_index[ var_op_arg[i] ] );\n            //\n            // sub: variables\n            for(addr_t i = var_op_arg[1]; i < var_op_arg[2]; ++i)\n               sub.push_back( var2val_index[ var_op_arg[i] ] );\n            //\n            // add: dynamic parameters\n            for(addr_t i = var_op_arg[2]; i < var_op_arg[3]; ++i)\n               add.push_back( ensure_par2val_index( var_op_arg[i] ) );\n            //\n            // sub: dynamic parameters\n            for(addr_t i = var_op_arg[3]; i < var_op_arg[4]; ++i)\n               sub.push_back( ensure_par2val_index( var_op_arg[i] ) );\n            //\n            // val_tape, var2val_index\n            var2val_index[i_var] = val_tape.record_csum_op(add, sub);\n         }\n         itr.correct_before_increment();\n         break;\n         // --------------------------------------------------------------\n         case local::CExpOp:\n         {  // cop, left, right, if_true, if_false\n            CompareOp cop = CompareOp( var_op_arg[0] );\n            addr_t left, right, if_true, if_false;\n            if( var_op_arg[1] & 1 )\n               left = var2val_index[ var_op_arg[2] ];\n            else\n               left = ensure_par2val_index( var_op_arg[2] );\n            if( var_op_arg[1] & 2 )\n               right = var2val_index[ var_op_arg[3] ];\n            else\n               right = ensure_par2val_index( var_op_arg[3] );\n            if( var_op_arg[1] & 4 )\n               if_true = var2val_index[ var_op_arg[4] ];\n            else\n               if_true = ensure_par2val_index( var_op_arg[4] );\n            if( var_op_arg[1] & 8 )\n               if_false = var2val_index[ var_op_arg[5] ];\n            else\n               if_false = ensure_par2val_index( var_op_arg[5] );\n            //\n            // compare_enum\n            local::val_graph::compare_enum_t compare_enum;\n            switch( cop )\n            {  case CompareLt:\n               compare_enum = local::val_graph::compare_lt_enum;\n               break;\n\n               case CompareLe:\n               compare_enum = local::val_graph::compare_le_enum;\n               break;\n\n               case CompareEq:\n               compare_enum = local::val_graph::compare_eq_enum;\n               break;\n\n               case CompareGe:\n               compare_enum = local::val_graph::compare_lt_enum;\n               std::swap(if_true, if_false);\n               break;\n\n               case CompareGt:\n               compare_enum = local::val_graph::compare_le_enum;\n               std::swap(if_true, if_false);\n               break;\n\n               case CompareNe:\n               compare_enum = local::val_graph::compare_eq_enum;\n               std::swap(if_true, if_false);\n               break;\n\n               default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               // set to avoid compiler warning\n               compare_enum = local::val_graph::number_compare_enum;\n               break;\n            }\n            val_index = val_tape.record_cexp_op(\n               compare_enum, left, right, if_true, if_false\n            );\n            var2val_index[i_var] = val_index;\n         }\n         break;\n\n         // --------------------------------------------------------------\n         case local::FunapOp:\n         val_op_arg.push_back( ensure_par2val_index( var_op_arg[0] ) );\n         break;\n\n         case local::FunavOp:\n         CPPAD_ASSERT_UNKNOWN( size_t(var_op_arg[0]) <= i_var );\n         val_op_arg.push_back( var2val_index[var_op_arg[0]] );\n         break;\n\n         case local::FunrpOp:\n         var_op_res.push_back( var_op_arg[0] );\n         res_is_par.push_back(true);\n         break;\n\n         case local::FunrvOp:\n         var_op_res.push_back( addr_t(i_var) );\n         res_is_par.push_back(false);\n         break;\n\n         case local::AFunOp:\n         in_atomic_call = ! in_atomic_call;\n         if( in_atomic_call )\n         {  val_op_arg.resize(0);\n            var_op_res.resize(0);\n            res_is_par.resize(0);\n         }\n         else\n         {  // atomic_index, call_id, n_res\n            addr_t atomic_index = var_op_arg[0];\n            addr_t call_id      = var_op_arg[1];\n            addr_t n_res        = var_op_arg[3];\n# ifndef NDEBUG\n            addr_t n_arg        = var_op_arg[2];\n            CPPAD_ASSERT_UNKNOWN( val_op_arg.size() == size_t(n_arg) );\n            CPPAD_ASSERT_UNKNOWN( var_op_res.size() == size_t(n_res) );\n            CPPAD_ASSERT_UNKNOWN( res_is_par.size() == size_t(n_res) );\n# endif\n            // var2val_index\n            addr_t res_index = val_tape.record_call_op(\n               atomic_index, call_id, n_res, val_op_arg\n            );\n            for(addr_t i = 0; i < n_res; ++i)\n            {  if( res_is_par[i] )\n                  par2val_index[ var_op_res[i] ] = res_index + i;\n               else\n                  var2val_index[ var_op_res[i] ] = res_index + i;\n            }\n         }\n         break;\n      }\n   }\n   // dep_vec\n   size_t n_dependent = dep_taddr_.size();\n   Vector<addr_t> dep_vec(n_dependent);\n   for(size_t i = 0; i < n_dependent; ++i)\n      dep_vec[i] = var2val_index[ dep_taddr_[i] ];\n   val_tape.set_dep( dep_vec );\n}\n\n} // END_CPPAD_NAMESPACE\n// --------------------------------------------------------------------------\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/op2arg_index.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_OP2ARG_INDEX_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_OP2ARG_INDEX_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-23 Bradley M. Bell\n// ---------------------------------------------------------------------------\n# include <cppad/local/val_graph/tape.hpp>\n# include <cppad/local/val_graph/rev_depend.hpp>\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n-------------------------------------------------------------------------------\n{xrst_begin val_op2arg_index dev}\n\nSet and Get the op2arg_index Vector\n###################################\nThis vector maps an operator index to the corresponding arg_index; i.e.,\nthe index in arg_vec of the first argument for this operator.\n\nset\n***\nThis ensures that the op2arg_index vector has been set.\n{xrst_literal\n   // BEGIN_SET_OP2ARG_INDEX\n   // END_SET_OP2ARG_INDEX\n}\n\nget\n***\nThis gets th op2arg_index vector.\nIf its size is zero, it has not been set.\n{xrst_literal\n   // BEGIN_OP2ARG_INDEX\n   // END_OP2ARG_INDEX\n}\n\n\n{xrst_end val_op2arg_index}\n*/\n// BEGIN_SET_OP2ARG_INDEX\ntemplate <class Value>\nvoid tape_t<Value>::set_op2arg_index(void)\n// END_SET_OP2ARG_INDEX\n{  if( 0 < op2arg_index_.size() )\n   {  CPPAD_ASSERT_UNKNOWN( op2arg_index_.size() == size_t( n_op() ) );\n      return;\n   }\n   //\n   // op2arg_indeex\n   Vector<addr_t> op2arg_index( n_op() );\n   op_iterator<Value> op_itr(*this, 0);\n   for(addr_t i_op = 0; i_op < n_op(); ++i_op)\n   {   op2arg_index[i_op] = op_itr.arg_index();\n      ++op_itr;\n   }\n   //\n   // op2arg_index_\n   // We needed a complete op2arg_index, before we could set op2arg_index_,\n   // otherwise op_iterator would not work properly.\n   op2arg_index_.swap(op2arg_index);\n}\n//\n// BEGIN_OP2ARG_INDEX\ntemplate <class Value>\nconst Vector<addr_t>& tape_t<Value>::op2arg_index(void) const\n// END_OP2ARG_INDEX\n{  return op2arg_index_; }\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/op_enum2class.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_OP_ENUM2CLASS_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_OP_ENUM2CLASS_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-23 Bradley M. Bell\n// ----------------------------------------------------------------------------\n// BEGIN_SORT_THIS_LINE_PLUS_1\n# include <cppad/local/val_graph/base_op.hpp>\n# include <cppad/local/val_graph/binary_op.hpp>\n# include <cppad/local/val_graph/call_op.hpp>\n# include <cppad/local/val_graph/cexp_op.hpp>\n# include <cppad/local/val_graph/comp_op.hpp>\n# include <cppad/local/val_graph/con_op.hpp>\n# include <cppad/local/val_graph/csum_op.hpp>\n# include <cppad/local/val_graph/dis_op.hpp>\n# include <cppad/local/val_graph/pri_op.hpp>\n# include <cppad/local/val_graph/unary_op.hpp>\n# include <cppad/local/val_graph/vector_op.hpp>\n// END_SORT_THIS_LINE_MINUS_1\n//\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_op_enum2class dev}\n\nMapping From Operator Enum To Class\n###################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_OP_ENUM2CLASS\n   // END_OP_ENUM2CLASS\n}\n\nPurpose\n*******\nConvert an operator enum type :ref:`val_graph_type@op_enum_t`\nto a pointer to an operator base class object :ref:`val_base_op-name` .\n\n{xrst_end val_op_enum2class}\n*/\n// ----------------------------------------------------------------------------\n// BEGIN_OP_ENUM2CLASS\n\n# define CPPAD_VAL_GRAPH_INSTANCE(name) \\\n   case name##_op_enum: \\\n   op_ptr = name##_op_t<Value>::get_instance(); \\\n   break;\n\ntemplate <class Value>\nbase_op_t<Value>* op_enum2class(op_enum_t op_enum)\n// END_OP_ENUM2CLASS\n{  //\n   base_op_t<Value>* op_ptr;\n   switch(op_enum)\n   {\n      default:\n      assert( false );\n      op_ptr = nullptr; // set in this case to avoid compiler warning\n      break;\n\n      // BEGIN_SORT_THIS_LINE_PLUS_1\n      CPPAD_VAL_GRAPH_INSTANCE(abs)\n      CPPAD_VAL_GRAPH_INSTANCE(acos)\n      CPPAD_VAL_GRAPH_INSTANCE(acosh)\n      CPPAD_VAL_GRAPH_INSTANCE(add)\n      CPPAD_VAL_GRAPH_INSTANCE(asin)\n      CPPAD_VAL_GRAPH_INSTANCE(asinh)\n      CPPAD_VAL_GRAPH_INSTANCE(atan)\n      CPPAD_VAL_GRAPH_INSTANCE(atanh)\n      CPPAD_VAL_GRAPH_INSTANCE(call)\n      CPPAD_VAL_GRAPH_INSTANCE(cexp)\n      CPPAD_VAL_GRAPH_INSTANCE(comp)\n      CPPAD_VAL_GRAPH_INSTANCE(con)\n      CPPAD_VAL_GRAPH_INSTANCE(cos)\n      CPPAD_VAL_GRAPH_INSTANCE(cosh)\n      CPPAD_VAL_GRAPH_INSTANCE(csum)\n      CPPAD_VAL_GRAPH_INSTANCE(dis)\n      CPPAD_VAL_GRAPH_INSTANCE(div)\n      CPPAD_VAL_GRAPH_INSTANCE(erf)\n      CPPAD_VAL_GRAPH_INSTANCE(erfc)\n      CPPAD_VAL_GRAPH_INSTANCE(exp)\n      CPPAD_VAL_GRAPH_INSTANCE(expm1)\n      CPPAD_VAL_GRAPH_INSTANCE(load)\n      CPPAD_VAL_GRAPH_INSTANCE(log)\n      CPPAD_VAL_GRAPH_INSTANCE(log1p)\n      CPPAD_VAL_GRAPH_INSTANCE(mul)\n      CPPAD_VAL_GRAPH_INSTANCE(neg)\n      CPPAD_VAL_GRAPH_INSTANCE(pow)\n      CPPAD_VAL_GRAPH_INSTANCE(pri)\n      CPPAD_VAL_GRAPH_INSTANCE(sign)\n      CPPAD_VAL_GRAPH_INSTANCE(sin)\n      CPPAD_VAL_GRAPH_INSTANCE(sinh)\n      CPPAD_VAL_GRAPH_INSTANCE(sqrt)\n      CPPAD_VAL_GRAPH_INSTANCE(store)\n      CPPAD_VAL_GRAPH_INSTANCE(sub)\n      CPPAD_VAL_GRAPH_INSTANCE(tan)\n      CPPAD_VAL_GRAPH_INSTANCE(tanh)\n      CPPAD_VAL_GRAPH_INSTANCE(vec)\n      // END_SORT_THIS_LINE_MINUS_1\n   }\n   return op_ptr;\n}\n\n# undef CPPAD_VAL_GRAPH_INSTANCE\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/op_hash_table.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_OP_HASH_TABLE_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_OP_HASH_TABLE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-25 Bradley M. Bell\n// ---------------------------------------------------------------------------\n# include <cppad/local/sparse/size_setvec.hpp>\n# include <cppad/local/val_graph/tape.hpp>\n# include <cppad/local/is_pod.hpp>\n/*\n{xrst_begin val_op_hash_table dev}\n\nThe Value Operator Hash Table\n#############################\n\nConstructor\n***********\n{xrst_literal\n   // BEGIN_OP_HASH_TABLE_T\n   // END_OP_HASH_TABLE_T\n}\n\nop_hash_table\n=============\nThis is the operator hash table that is constructed\n\ntape\n====\nA reference to *tape* is stored in *op_hash_tale* ; i.e.,\n*tape* must not be destroyed before *op_hash_table* .\n\nop2arg_index\n============\nThis is a mapping from operator index to corresponding offset in the\ntape argument vector *tape*.var_arg_ .\n\nn_hash_code\n===========\nThis is the number of possible hash codes in the operator hash table\n*op_hash_table* .\n\nmatch_op\n********\n{xrst_literal\n   // BEGIN_MATCH_OP\n   // END_MATCH_OP\n}\n\nop_hash_table\n=============\nThis is a hash table for the tape.\n\ni_op\n====\nThis is the index of the operator that we are searching for a match.\n\nnew_val_index\n=============\nThis maps old value indices to new value indices\nfor indices less than the first result for the *i_op* operator.\nNew value indices are the result of using previous operator matches.\nFor arguments that are value indices,\nthe new indices are used when checking to see if operators match.\n\nj_op\n====\nThe return value *j_op* is the lowest operator index that corresponds to a\nmatch for *i_op* . If it is equal to *i_op* , then this operator has been placed\nin the hash table (for future matches).\nOtherwise *j_op* is less than *i_op* and its results are equivalent to *i_op*.\n\nsize_count\n**********\n{xrst_literal\n   // BEGIN_SIZE_COUNT\n   // END_SIZE_COUNT\n}\nFor each valid index *i*, *size_count* ()[ *i* ]\nis the number of hash code values, in the table, that have *i* collisions.\nA collision occurs when two operators that do not match have the same hash code.\n\n{xrst_end val_op_hash_table}\n*/\n\n// Tell pod_vector class that each size_setvec<addr_t>::pair_s_type is\n// plain old data and hence the corresponding constructor need not be called.\nnamespace CppAD { namespace local {\n# if ! CPPAD_IS_SAME_TAPE_ADDR_TYPE_SIZE_T\n   // This pair gets defined in list_setvec.hpp for the type size_t.\n   // Would be better to have conditional compile depending of if defined.\n   template <> inline bool\n   is_pod< sparse::size_setvec<addr_t>::pair_s_type > (void)\n   {  return true; }\n# endif\n} }\n\nnamespace CppAD { namespace local { namespace val_graph {\n\n// hash_value\ntemplate <class Value>\nsize_t hash_value(const Value& value)\n{\n   CPPAD_ASSERT_UNKNOWN( sizeof(unsigned short) == 2 );\n   CPPAD_ASSERT_UNKNOWN( sizeof(value) % 2  == 0 );\n   //\n   // v\n   const unsigned short* v\n             = reinterpret_cast<const unsigned short*>(& value);\n   //\n   // sum\n   size_t i   = sizeof(value) / 2 - 1;\n   size_t sum = v[i];\n   while(i--)\n      sum += v[i];\n   //\n   return sum;\n}\n\n//\n// op_hash_table_t\ntemplate <class Value>\nclass op_hash_table_t {\nprivate:\n   //\n   // tape_\n   const tape_t<Value>& tape_;\n   //\n   // op2arg_index_\n   const Vector<addr_t>& op2arg_index_;\n   //\n   // table\n   CppAD::local::sparse::size_setvec<addr_t> table_;\n   //\n   // hash_code\n   addr_t hash_code(\n      const base_op_t<Value>* op_ptr        ,\n      addr_t                  arg_index     ,\n      const Vector<addr_t>&   new_val_index )\n   {  //\n      // arg_vec, con_vec, op_enum\n      const Vector<addr_t>& arg_vec = tape_.arg_vec();\n      const Vector<Value>&  con_vec = tape_.con_vec();\n      op_enum_t             op_enum = op_ptr->op_enum();\n      //\n      size_t code;\n      if( op_enum == con_op_enum )\n         code = hash_value( con_vec[  arg_vec[arg_index] ] );\n      else\n      {  addr_t n_arg    = op_ptr->n_arg(arg_index, arg_vec);\n         addr_t n_before = op_ptr->n_before();\n         addr_t n_after  = op_ptr->n_after();\n         //\n         // code\n         code = 0;\n         //\n         // These are auxiliary indices\n         for(addr_t i = 0; i < n_before; ++i)\n            code += size_t( arg_vec[arg_index + i] );\n         //\n         // These arguments are indices in the value vector, so check for a\n         // match with the lowest equivalent value vector index.\n         for(addr_t i = n_before; i < n_arg - n_after; ++i)\n            code += size_t( new_val_index[ arg_vec[arg_index + i] ] );\n         //\n         // These are auxiliary indices\n         for(addr_t i = n_arg - n_after; i < n_arg ; ++i)\n            code += size_t( arg_vec[arg_index + i] );\n      }\n      code = code % size_t( table_.n_set() );\n      return addr_t( code );\n   }\npublic:\n   // -------------------------------------------------------------------------\n   // BEGIN_OP_HASH_TABLE_T\n   // op_hash_table_t op_hash_table(tape, op2arg_index, n_hash_code)\n   op_hash_table_t(\n         const tape_t<Value>&     tape         ,\n         const Vector<addr_t>&    op2arg_index ,\n         addr_t                   n_hash_code  )\n   // END_OP_HASH_TABLE_T\n   : tape_( tape ), op2arg_index_(op2arg_index)\n   {  // table_\n      addr_t n_op = tape.n_op();\n      //\n      table_.resize( n_hash_code, n_op );\n   }\n   // -------------------------------------------------------------------------\n   // BEGIN_SIZE_COUNT\n   // size_count = op_hash_table.size_count()\n   Vector<addr_t> size_count(void)\n   // END_SIZE_COUNT\n   {  Vector<addr_t> count;\n      addr_t n_set  = table_.n_set();\n      for(addr_t i = 0; i < n_set; ++i)\n      {  addr_t number_elements = table_.number_elements(i);\n         if( size_t( number_elements ) >= count.size() )\n         {  size_t old_size = count.size();\n            addr_t new_size = number_elements + 1;\n            count.resize(new_size);\n            for(size_t j = old_size; j < new_size; ++j)\n               count[j] = 0;\n         }\n         count[number_elements] += 1;\n      }\n      return count;\n   }\n   // -------------------------------------------------------------------------\n   // BEGIN_MATCH_OP\n   // j_op = op_hash_table.match_op(i_op, new_val_index)\n   addr_t match_op(addr_t i_op, const Vector<addr_t>& new_val_index)\n   // END_MATCH_OP\n   {  assert( i_op < table_.end() );\n      //\n      // arg_vec, con_vec\n      const Vector<addr_t>&    arg_vec     = tape_.arg_vec();\n      const Vector<Value>&     con_vec     = tape_.con_vec();\n      //\n      // op_enum, op_ptr\n      const base_op_t<Value>* op_ptr = tape_.base_op_ptr(i_op);\n      op_enum_t op_enum              = op_ptr->op_enum();\n      //\n      // arg_index, n_arg\n      addr_t arg_index = op2arg_index_[i_op];\n      addr_t n_arg     = op_ptr->n_arg(arg_index, arg_vec);\n      //\n      // nan\n      if( op_enum == con_op_enum )\n      {  if( CppAD::isnan( con_vec[ arg_vec[arg_index] ] ) )\n         {  CPPAD_ASSERT_UNKNOWN( op2arg_index_[0] == 0 );\n            CPPAD_ASSERT_UNKNOWN( arg_vec[0] == 0 );\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( con_vec[0] ) );\n            return 0;\n         }\n      }\n      //\n      // code\n      addr_t code = hash_code(op_ptr, arg_index, new_val_index);\n      //\n      // itr\n      local::sparse::size_setvec_const_iterator<addr_t> itr(table_, code);\n      while( *itr != table_.end() )\n      {  // op_enum_j, arg_index_j\n         addr_t                  j_op = *itr;\n         const base_op_t<Value>* op_ptr_j = tape_.base_op_ptr(j_op);\n         op_enum_t op_enum_j   = op_ptr_j->op_enum();\n         addr_t    arg_index_j = op2arg_index_[j_op];\n         addr_t     n_arg_j    = op_ptr_j->n_arg(arg_index_j, arg_vec);\n         //\n         // match\n         bool match = (op_enum == op_enum_j) && (n_arg == n_arg_j);\n         if( match && op_enum == con_op_enum )\n         {  //\n            const Value& c = con_vec[ arg_vec[arg_index] ];\n            const Value& c_j = con_vec[ arg_vec[arg_index_j] ];\n            match            = IdenticalEqualCon(c, c_j);\n         }\n         else if( match )\n         {  addr_t n_before = op_ptr->n_before();\n            addr_t n_after  = op_ptr->n_after();\n            //\n            for(addr_t k = 0; k < n_before; ++k)\n               match &= arg_vec[arg_index + k] == arg_vec[arg_index_j + k];\n            //\n            for(addr_t k = n_before; k < n_arg - n_after; ++k)\n            {  addr_t val_index   = new_val_index[ arg_vec[arg_index + k] ];\n               addr_t val_index_j = new_val_index[ arg_vec[arg_index_j + k] ];\n               match &= val_index == val_index_j;\n            }\n            //\n            for(addr_t k = n_arg - n_after; k < n_arg; ++k)\n               match &= arg_vec[arg_index + k] == arg_vec[arg_index_j + k];\n            //\n            bool communative = op_enum == add_op_enum;\n            communative     |= op_enum == mul_op_enum;\n            if( communative && ! match )\n            {  addr_t val_index   = new_val_index[ arg_vec[arg_index + 0] ];\n               addr_t val_index_j = new_val_index[ arg_vec[arg_index_j + 1] ];\n               match = val_index == val_index_j;\n               //\n               val_index   = new_val_index[ arg_vec[arg_index + 1] ];\n               val_index_j = new_val_index[ arg_vec[arg_index_j + 0] ];\n               match &= val_index == val_index_j;\n            }\n         }\n         if( match )\n            return j_op;\n         //\n         // itr\n         ++itr;\n      }\n      table_.add_element(code, i_op);\n      return i_op;\n   }\n};\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/op_iterator.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_OP_ITERATOR_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_OP_ITERATOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// --------------------------------------------------------------------------\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_op_iterator dev}\n\nClass For Iterating Over Operators in a Value Tape\n##################################################\n\nSyntax\n******\n| |tab| ``op_iterator`` < *Value* > *op_itr* ( *tape* , *op_index* )\n| |tab| *op_itr* . ``op_ptr`` ()\n| |tab| *op_itr* . ``arg_index`` ()\n| |tab| *op_itr* . ``res_index`` ()\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CTOR\n   // END_CTOR\n}\n{xrst_literal\n   // BEGIN_MEMBER_FUNCTIONS\n   // END_MEMBER_FUNCTIONS\n}\n\nValue\n*****\nis the :ref:`val_tape@Value` type for the tape.\n\n\ntape\n****\nis the :ref:`val_tape-name` containing the operators we are\niterating over.\n\nop_index\n********\nis the operator index where the iterator starts.\nThis must be zero (for the beginning of the tape)\nor the number of operators in the tape (for the end of the tape).\n\nop_itr\n******\nis the operator iterator.\n\n{xrst_end val_op_iterator}\n*/\n# include <cppad/local/val_graph/op_enum2class.hpp>\n# include <cppad/core/cppad_assert.hpp>\n\n// BEGIN_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\nnamespace CppAD { namespace local { namespace val_graph  {\n\n//\n// tape_t;\ntemplate <class Value> class tape_t;\n\ntemplate <class Value>\nclass op_iterator {\n//\nprivate:\n   //\n   // tape_\n   const tape_t<Value>& tape_;\n   //\n   // op_ptr_\n   base_op_t<Value>* op_ptr_;\n   //\n   // op_index_\n   addr_t op_index_;\n   //\n   // arg_index_\n   addr_t arg_index_;\n   //\n   // res_index_\n   addr_t res_index_;\n   //\npublic:\n   //\n   // BEGIN_MEMBER_FUNCTIONS\n   const base_op_t<Value>* op_ptr(void) const\n   {  return op_ptr_; }\n   addr_t arg_index(void) const\n   {  return arg_index_; }\n   addr_t res_index(void) const\n   {  return res_index_; }\n   // END_MEMBER_FUNCTIONS\n   //\n   // BEGIN_CTOR\n   op_iterator(const tape_t<Value>& tape, addr_t op_index)\n   // END_CTOR\n   :\n   tape_ ( tape )         ,\n   op_ptr_(nullptr)       ,\n   op_index_ ( op_index )\n   {  addr_t n_op = tape.n_op();\n      //\n      if( op_index == 0 )\n      {  op_enum_t op_enum = op_enum_t( tape.op_enum_vec()[op_index] );\n         //\n         arg_index_ = 0;\n         res_index_ = tape.n_ind();\n         op_ptr_    = op_enum2class<Value>(op_enum);\n      }\n      else if( op_index == n_op )\n      {  arg_index_ = addr_t( tape.arg_vec().size() );\n         res_index_ = tape.n_val();\n      }\n      else\n      {  CPPAD_ASSERT_KNOWN( false,\n            \"op_iterator: op_index is not zero or number of operators in tape\"\n         );\n      }\n   }\n   //\n   // BEGIN_INCREMENT\n   void operator++(void)\n   // END_INCREMENT\n   {  CPPAD_ASSERT_KNOWN( op_index_ < addr_t( tape_.n_op() ),\n         \"op_iterator: attempt to increment past the end of the tape\"\n      );\n      //\n      // n_arg, n_res\n      addr_t n_arg = op_ptr_->n_arg(arg_index_, tape_.arg_vec());\n      addr_t n_res = op_ptr_->n_res(arg_index_, tape_.arg_vec());\n      //\n      // op_index_, arg_index_, res_index_\n      ++op_index_;\n      res_index_ += n_res;\n      //\n      // op_ptr_\n      if( op_index_ == tape_.n_op() )\n      {  op_ptr_    = nullptr;\n         arg_index_ = addr_t( tape_.arg_vec().size() ); // invalid value\n      }\n      else\n      {  if( tape_.op2arg_index().size() == 0 )\n            arg_index_ += n_arg;\n         else\n            arg_index_ = tape_.op2arg_index()[op_index_];\n         //\n         op_enum_t op_enum = op_enum_t( tape_.op_enum_vec()[op_index_] );\n         op_ptr_           = op_enum2class<Value>(op_enum);\n      }\n   }\n   //\n   // BEGIN_DECREMENT\n   void operator--(void)\n   // END_DECREMENT\n   {  CPPAD_ASSERT_KNOWN( 0 < op_index_,\n         \"op_iterator: attempt to decrement below the beginning of the tape\"\n      );\n      //\n      // op_index_\n      --op_index_;\n      //\n      // op_ptr_\n      op_enum_t op_enum = op_enum_t( tape_.op_enum_vec()[op_index_] );\n      op_ptr_           = op_enum2class<Value>(op_enum);\n      //\n      // n_after\n      addr_t n_after = op_ptr_->n_after();\n      CPPAD_ASSERT_UNKNOWN( n_after == 0 || n_after == 1 );\n      //\n      // arg_index_\n      if( 0 < tape_.op2arg_index().size() )\n         arg_index_ = tape_.op2arg_index()[op_index_];\n      else\n      {  addr_t n_arg;\n         if( n_after )\n            n_arg = tape_.arg_vec()[arg_index_ - 1];\n         else\n         {  // arg_index\n            // set to an invalid value for an index in the arg_vec vector.\n            addr_t arg_index = addr_t( tape_.arg_vec().size() );\n            n_arg = op_ptr_->n_arg(arg_index, tape_.arg_vec());\n         }\n         arg_index_ -= n_arg;\n      }\n      //\n      // res_index_\n      addr_t n_res = op_ptr_->n_res(arg_index_, tape_.arg_vec());\n      res_index_ -= n_res;\n   }\n};\n\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n// --------------------------------------------------------------------------\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/option.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_OPTION_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_OPTION_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-23 Bradley M. Bell\n// ---------------------------------------------------------------------------\n# include <cppad/local/val_graph/tape.hpp>\n\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n-------------------------------------------------------------------------------\n{xrst_begin val_tape_option dev}\n\nSet an Option's Value\n#####################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_SET_OPTION\n   // END_SET_OPTION\n}\n\nkeep_compare\n************\nIf *name* is keep_compare, *value* must be true or false .\nIf it is false (true), :ref:`val_comp_op-name` operators will (will not)\nbe removed during :ref:`val_tape_dead_code-name` optimization.\n\nkeep_print\n**********\nIf *name* is keep_print, *value* must be true or false .\nIf it is false (true), :ref:`val_pri_op-name` operators will (will not)\nbe removed during dead code optimization.\n\n{xrst_end val_tape_option}\n*/\n// ---------------------------------------------------------------------------\n// BEGIN_INITIALIZE_OPTION\ntemplate <class Value>\nvoid tape_t<Value>::initialize_option(void)\n// END_INITIALIZE_OPTION\n{\n   option_map_[\"keep_compare\"] = \"true\";\n   option_map_[\"keep_print\"]   = \"true\";\n   //\n   return;\n}\n// ---------------------------------------------------------------------------\n// BEGIN_SET_OPTION\ntemplate <class Value>\nvoid tape_t<Value>::set_option(\n   const std::string& name  ,\n   const std::string& value )\n// END_SET_OPTION\n{  //\n   if( option_map_.find(name) == option_map_.end() )\n   {  std::string msg = \"value tape: There is no option named \" + name;\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n   if( value != \"true\" && value != \"false\" )\n   {  std::string msg = \"value tape: option [\" + name + \"]\";\n      msg            += \" value is not true or false \";\n      CPPAD_ASSERT_KNOWN(false, msg.c_str() );\n   }\n   option_map_[name] = value;\n   //\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/pri_op.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_PRI_OP_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_PRI_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/val_graph/base_op.hpp>\n\n// define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_pri_op dev}\n{xrst_spell\n   str\n}\n\nThe Print Value Operator\n########################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PRI_OP_T\n   // END_PRI_OP_T\n}\n\nContext\n*******\nThe class is derived from :ref:`val_base_op-name` .\nIt overrides all its base class virtual member functions\nand is a concrete class (it has no pure virtual functions).\n\nget_instance\n************\nThis static member function returns a pointer to a pri_op_t object.\n\nop_enum\n*******\nThis override of :ref:`val_base_op@op_enum` returns ``pri_op_enum`` .\n\nn_before\n********\nThis override of :ref:`val_base_op@n_before` returns 2.\n\nn_after\n*******\nThis override of :ref:`val_base_op@n_after` returns 0.\n\nn_arg\n*****\nThis override of :ref:`val_base_op@n_arg` returns 4.\n\nn_res\n*****\nThis override of :ref:`val_base_op@n_res` returns 0.\n\neval\n****\nThis override of :ref:`val_base_op@eval` defines the following values:\n\n.. csv-table::\n   :header: Type,Name,Definition\n\n   string, *before*  ,  str_vec[ arg_vec[ arg_index + 0 ] ]\n   string, *after*   ,  str_vec[ arg_vec[ arg_index + 1 ] ]\n   Value,    *flag*  ,  val_vec[ arg_vec[ arg_index + 2 ] ]\n   Value,    *value* ,  val_vec[ arg_vec[ arg_index + 3 ] ]\n\nbefore\n======\nThis text is printed before the value.\n\nafter\n=====\nThis text is printed after the value.\n\nflag\n====\nIf *flag* is less than or equal zero, print the output.\nIf *flag* is greater than zero, nothing is printed by this operator.\nIn the special case where\n\n   arg_vec[ arg_index + 2] == tape.n_ind()\n\n*flag* has the value nan and nothing is printed.\nThis fact is used by :ref:`val_tape_renumber-name` to change repeated\nprints of the same value to no-ops.\nThe :ref:`val_tape_dead_code-name` routine will remove this operators.\n\nvalue\n=====\nThis value is printed between *before* and *after*.\n\ntrace\n=====\nIf trace is true, :ref:`val_print_pri_op-name`\nis used to print this operator.\nPrinting the operator is separate from printing the value.\n\n{xrst_toc_hidden\n   val_graph/pri_xam.cpp\n}\nExample\n*******\nThe file :ref:`pri_xam.cpp <val_pri_xam.cpp-name>`\nis an example and test that uses this operator.\n\n{xrst_end val_pri_op}\n*/\n// BEGIN_PRI_OP_T\ntemplate <class Value>\nclass pri_op_t : public base_op_t<Value> {\npublic:\n   // n_before\n   addr_t n_before(void) const override\n   {  return 2; }\n   //\n   // n_after\n   addr_t n_after(void) const override\n   {  return 0; }\n   //\n   // get_instance\n   static pri_op_t* get_instance(void)\n   {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n      static pri_op_t instance;\n      return &instance;\n   }\n   // op_enum\n   op_enum_t op_enum(void) const override\n   {  return pri_op_enum; }\n// END_PRI_OP_T\n   //\n   // n_arg\n   addr_t n_arg(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 4; }\n   //\n   // n_res\n   addr_t n_res(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 0; }\n   //\n   // eval\n   void eval(\n      const tape_t<Value>*      tape          ,\n      bool                      trace         ,\n      addr_t                    arg_index     ,\n      addr_t                    res_index     ,\n      Vector<Value>&            val_vec       ,\n      Vector< Vector<addr_t> >& ind_vec_vec   ,\n      size_t&                   compare_false ) const override\n   {  //\n      // arg_vec, str_vec\n      const Vector<addr_t>&       arg_vec( tape->arg_vec() );\n      const Vector<std::string>&  str_vec( tape->str_vec() );\n      //\n      // Special case where flag is nan and this is a no op.\n      if( arg_vec[ arg_index + 2] == tape->n_ind() )\n         return;\n      //\n      // arg\n      Vector<addr_t> arg(4);\n      for(addr_t i = 0; i < 4; ++i)\n         arg[i] = arg_vec[ arg_index + i ];\n      //\n      if( trace )\n      {  // print_pri_op(before_index, after_index, flag_index, value_index)\n         print_pri_op(arg[0], arg[1], arg[2], arg[3]);\n      }\n      //\n      // before, after, flag, value\n      const std::string& before  = str_vec[ arg[0] ];\n      const std::string& after   = str_vec[ arg[1] ];\n      const Value&       flag    = val_vec[ arg[2] ];\n      const Value&       value   = val_vec[ arg[3] ];\n      if( flag <= Value(0) )\n         std::cout << before << value << after;\n   }\n};\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/print_op.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_PRINT_OP_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_PRINT_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <iostream>\n# include <iomanip>\n/*\n{xrst_begin_parent val_print_op dev}\n\nPrinting Value Operators\n########################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PRINT_OP\n   // END_PRINT_OP\n}\n\nOutput Notation\n***************\n#. The first column is a value index and the second column is the\n   corresponding value.\n#. Values inside of parenthesis are arguments that are result indices\n   for the operator name  that comes before the left parenthesis.\n#. Values inside of brackets are indices for vector name that\n   comes before the left bracket.\n\nname\n****\nIs the name of this operator. In the case of a function call operator,\nit is the name of the function being called.\n\nval_arg\n*******\nis a vector containing the operator arguments that are value indices\n(in order).\n\nres_index\n*********\nis the index of the first result for this operator.\n\nres_value\n*********\nis a non-empty vector of results for this operator.\n\nSpecial Cases\n*************\n{xrst_toc_table\n}\n\n{xrst_end val_print_op}\n*/\n\n// BEGIN_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\nnamespace CppAD { namespace local { namespace val_graph {\n\n// BEGIN_PRINT_OP\ntemplate <class Value>\nvoid print_op(\n   const std::string&    name            ,\n   const Vector<addr_t>& val_arg         ,\n   addr_t                res_index       ,\n   const Vector<Value>&  res_value       )\n// END_PRINT_OP\n{  size_t n_arg = val_arg.size();\n   size_t n_res = res_value.size();\n   using std::setw;\n   using std::right;\n   using std::cout;\n   //\n   // One result\n   if( n_res == 1 )\n   {  cout << right << setw(5) << res_index;\n      cout << \" \" << right << setw(10) << res_value[0];\n      cout << \" = \" << right << setw(5)  << name << \"(\";\n      for(size_t i = 0; i < n_arg; ++i)\n      {  cout << right << setw(5) << std::right << val_arg[i];\n         if( i + 1 < n_arg )\n            cout << \",\";\n      }\n      cout << \")\" << std::endl;\n      return;\n   }\n   //\n   // Multiple results\n   CPPAD_ASSERT_UNKNOWN( n_res > 1 );\n   cout << right << setw(5) << name << \"(\";\n   for(size_t i = 0; i < n_arg; ++i)\n   {  cout << right << setw(5) << val_arg[i];\n      if( i + 1 < n_arg )\n            cout << \",\";\n      else\n            cout << \")\";\n   }\n   for(addr_t i = 0; i < addr_t( n_res ); ++i)\n   {  cout << std::endl;\n      cout << right << setw(5) << res_index + i;\n      cout << \" \" << setw(10) << res_value[i];\n   }\n   cout << std::endl;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_print_con_op dev}\n\nPrinting Constant Operators\n###########################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PRINT_CON_OP\n   // END_PRINT_CON_OP\n}\n\narg\n***\nis a vector containing all the operator arguments (must be length one).\n\nres_index\n*********\nis the index of the result for this operator.\n\nres_value\n*********\nis a vector of results for this operator (must be length one).\n\n{xrst_end val_print_con_op}\n*/\n// BEGIN_PRINT_CON_OP\ntemplate <class Value>\nvoid print_con_op(\n   const Vector<addr_t>& arg             ,\n   addr_t                res_index       ,\n   const Vector<Value>&  res_value       )\n// END_PRINT_CON_OP\n{  CPPAD_ASSERT_UNKNOWN( arg.size() == 1 );\n   CPPAD_ASSERT_UNKNOWN( res_value.size() == 1 );\n   using std::setw;\n   using std::right;\n   using std::cout;\n   {  cout << right << setw(5) << res_index;\n      cout << \" \" << right << setw(10) << res_value[0];\n      cout << \" = \" << right << setw(5)  << \"con\" << \"[\";\n      cout << right << setw(5) << std::right << arg[0] << \"]\";\n      cout << std::endl;\n      return;\n   }\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_print_csum_op dev}\n\nPrinting Cumulative Summation Operators\n#######################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PRINT_CSUM_OP\n   // END_PRINT_CSUM_OP\n}\n\narg\n***\nis a vector containing all the operator arguments (must be length one).\n\nres_index\n*********\nis the index of the result for this operator.\n\nres_value\n*********\nis a vector of results for this operator (must be length one).\n\n{xrst_end val_print_csum_op}\n*/\n// BEGIN_PRINT_CSUM_OP\ntemplate <class Value>\nvoid print_csum_op(\n   const Vector<addr_t>& arg             ,\n   addr_t                res_index       ,\n   const Vector<Value>&  res_value       )\n// END_PRINT_CSUM_OP\n{  CPPAD_ASSERT_UNKNOWN( res_value.size() == 1);\n   //\n   using std::setw;\n   using std::right;\n   using std::cout;\n   //\n   // n_add, n_sub\n   addr_t n_add = arg[0];\n   addr_t n_sub = arg[1];\n   //\n   CPPAD_ASSERT_UNKNOWN( arg.size() == size_t(3 + n_add + n_sub ) );\n   //\n   cout << right << setw(5) << res_index;\n   cout << \" \" << right << setw(10) << res_value[0] << \" = \";\n   if( n_add > 0 )\n   {  cout << right << setw(5)  << \"csum+\" << \"(\";\n      for(addr_t i = 0; i < n_add; ++i)\n      {  cout << right << setw(5) << arg[2 + i];\n         if( i + 1 < n_add )\n            cout << \",\";\n      }\n      cout << \")\" << std::endl;\n      if( n_sub > 0 )\n      {  cout << setw(19) << \"\" << right << setw(5)  << \"csum-\" << \"(\";\n         for(addr_t i = 0; i < n_sub; ++i)\n         {  cout << right << setw(5) << arg[2 + n_add + i];\n            if( i + 1 < n_sub )\n               cout << \",\";\n         }\n         cout << \")\" << std::endl;\n      }\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( n_sub > 0 );\n      cout << right << setw(5)  << \"csum-\" << \"(\";\n      for(addr_t i = 0; i < n_sub; ++i)\n      {  cout << right << setw(5) << arg[2 + n_add + i];\n         if( i + 1 < n_sub )\n            cout << \",\";\n      }\n      cout << \")\" << std::endl;\n   }\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_print_comp_op dev}\n\nPrinting Compare Operators\n##########################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PRINT_COMP_OP\n   // END_PRINT_COMP_OP\n}\n\ncomp_name\n*********\nis the name of the comparison operator; e.g., \"lt\"\n\nleft_index\n**********\nis the value index corresponding to the left operand in the comparison.\n\nright_index\n***********\nis the value index corresponding to the right operand in the comparison.\n\nresult\n******\nis the result of the comparison.\n\n{xrst_end val_print_comp_op}\n*/\n// BEGIN_PRINT_COMP_OP\ninline void print_comp_op(\n   const char* comp_name   ,\n   addr_t      left_index  ,\n   addr_t      right_index ,\n   bool        result      )\n// END_PRINT_COMP_OP\n{  //\n   using std::setw;\n   using std::right;\n   using std::cout;\n   //\n   const char* res_str;\n   if( result )\n      res_str = \"true\";\n   else\n      res_str = \"false\";\n   //\n   cout << setw(19) << \"\" << right << setw(5)  << comp_name << \"(\";\n   cout << right << setw(5) << left_index  << \",\";\n   cout << right << setw(5) << right_index << \") = \";\n   cout << right << setw(5) << res_str << std::endl;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_print_pri_op dev}\n{xrst_spell\n   str\n}\n\nPrinting Print Operators\n########################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PRINT_PRI_OP\n   // END_PRINT_PRI_OP\n}\n\nbefore_index\n************\nis the index in str_vec corresponding to the before text.\n\nafter_index\n***********\nis the index in str_vec corresponding to the after text.\n\nflag_index\n**********\nis the index in the value vector corresponding to the flag.\n\nvalue_index\n***********\nis the index in the value vector corresponding to the value that is printed\nif the flag is positive.\n\n\n{xrst_end val_print_pri_op}\n*/\n// BEGIN_PRINT_PRI_OP\ninline void print_pri_op(\n   addr_t       before_index ,\n   addr_t       after_index  ,\n   addr_t       flag_index   ,\n   addr_t       value_index  )\n// END_PRINT_PRI_OP\n{  //\n   using std::setw;\n   using std::right;\n   using std::cout;\n   //\n   cout << setw(19) << \"\" << right << setw(5)  << \"pri\" << \"[\";\n   cout << right << setw(5) << before_index  << \",\";\n   cout << right << setw(5) << after_index   << \"](\";\n   cout << right << setw(5) << flag_index    << \",\";\n   cout << right << setw(5) << value_index << \")\" << std::endl;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_print_store_op dev}\n\nPrinting Store Operators\n########################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PRINT_STORE_OP\n   // END_PRINT_STORE_OP\n}\n\nwhich_vector\n************\nis the index in val_vec_vec corresponding to this vector.\n\nvector_index\n************\nis the index in val_vec corresponding to the index for this vector element.\n\nvalue_index\n***********\nis the index in val_vec corresponding to the new value for this vector element.\n\n\n{xrst_end val_print_store_op}\n*/\n// BEGIN_PRINT_STORE_OP\ninline void print_store_op(\n   addr_t       which_vector ,\n   addr_t       vector_index ,\n   addr_t       value_index  )\n// END_PRINT_STORE_OP\n{  //\n   using std::setw;\n   using std::right;\n   using std::cout;\n   //\n   cout << setw(19) << \"\" << right << setw(5)  << \"store\" << \"[\";\n   cout << right << setw(5) << which_vector  << \"](\";\n   cout << right << setw(5) << vector_index  << \",\";\n   cout << right << setw(5) << value_index << \")\" << std::endl;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_print_load_op dev}\n\nPrinting Load Operators\n#######################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PRINT_LOAD_OP\n   // END_PRINT_LOAD_OP\n}\n\nwhich_vector\n************\nis the index in val_vec_vec corresponding to this vector.\n\nvector_index\n************\nis the index in val_vec corresponding to the index for this vector element.\n\nres_index\n*********\nin the index in val_vec corresponding to the result for this operator.\n\n{xrst_end val_print_load_op}\n*/\n// BEGIN_PRINT_LOAD_OP\ntemplate <class Value>\ninline void print_load_op(\n   addr_t       which_vector ,\n   addr_t       vector_index ,\n   addr_t       res_index    ,\n   const Value& res_value    )\n// END_PRINT_LOAD_OP\n{  //\n   using std::setw;\n   using std::right;\n   using std::cout;\n   //\n   cout << right << setw(5) << res_index;\n   cout << \" \" << right << setw(10) << res_value;\n   cout << \" = \" << setw(5)  << \"load\" << \"[\";\n   cout << right << setw(5) << which_vector  << \"](\";\n   cout << right << setw(5) << vector_index << \")\" << std::endl;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_print_vec_op dev}\n\nPrinting New Dynamic Vector Operators\n#####################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PRINT_VEC_OP\n   // END_PRINT_VEC_OP\n}\n\nwhich_vector\n************\nis the index in val_vec_vec corresponding to this vector.\n\ninitial\n*******\nis the vector of indices in val_vec (the value vector)\ncorresponding to the initial values for this dynamic vector.\n\n{xrst_end val_print_vec_op}\n*/\n// BEGIN_PRINT_VEC_OP\ninline void print_vec_op(\n   addr_t                which_vector ,\n   const Vector<addr_t>& initial      )\n// END_PRINT_VEC_OP\n{  //\n   using std::setw;\n   using std::right;\n   using std::cout;\n   //\n   cout << setw(19) << \"\" << right << setw(5)  << \"vec\" << \"[\";\n   cout << right << setw(5) << which_vector  << \"](\";\n   for(size_t i = 0; i < initial.size(); ++i)\n   {  cout << right << setw(5) << initial[i];\n      if( i + 1 < initial.size() )\n         cout << \",\";\n   }\n   cout << \")\" << std::endl;\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/record.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_RECORD_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_RECORD_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/val_graph/tape.hpp>\n# include <cppad/local/val_graph/op_enum2class.hpp>\n# include <cppad/core/numeric_limits.hpp>\n//\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin_parent val_record dev}\n\nRecording Value Operations on a Tape\n####################################\n\nPurpose\n*******\nThese operations store a function in the :ref:`val_tape-name`.\n\n{xrst_end val_record}\n------------------------------------------------------------------------------\n{xrst_begin val_set_ind dev}\n{xrst_spell\n   str\n}\n\nSetting Independent Variables\n#############################\n\nset_ind\n*******\n{xrst_literal\n   // BEGIN_SET_IND\n   // END_SET_IND\n}\nThis is the first step in a creating a recording. It does the following:\n\n#. Clear all of the memory that is currently used by the tape except\n   for the options settings.\n#. Set the number of independent values.\n#. The empty string is placed in the string constant vector str_vec\\_.\n   This string has index zero in the string constant vector str_vec\\_.\n#. Place the constant nan directly after the last independent value.\n   This value has index zero in the value constant vector con_vec\\_.\n#. The return value is the index in the value vector where the nan\n   will be placed; i.e., *n_ind* .\n\nDirectly after this operation:\n{xrst_literal\n   // BEGIN_POST_CONDITION\n   // END_POST_CONDITION\n}\n\n{xrst_end val_set_ind}\n*/\n// ----------------------------------------------------------------------------\n// BEGIN_SET_IND\ntemplate <class Value>\naddr_t tape_t<Value>::set_ind(addr_t n_ind)\n// END_SET_IND\n{  Value nan = CppAD::numeric_limits<Value>::quiet_NaN();\n   n_ind_ = n_ind;\n   n_val_ = n_ind;\n   var_arg_.clear();\n   con_vec_.clear();\n   str_vec_.clear();\n   vec_initial_.clear();\n   dep_vec_.clear();\n   op_enum_vec_.clear();\n   op2arg_index_.clear();\n   // option_map_ does not change during this operation.\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // set_ind_inue\n   size_t thread  = thread_alloc::thread_num();\n   set_ind_inuse_ = thread_alloc::inuse(thread);\n# endif\n   //\n   str_vec_.push_back( \"\" );\n   addr_t nan_addr = record_con_op(nan);\n   assert( n_val_ == n_ind + 1 );\n   //\n   // BEGIN_POST_CONDITION\n   CPPAD_ASSERT_UNKNOWN( op_enum_vec_.size() == 1 ); // one operator\n   CPPAD_ASSERT_UNKNOWN( var_arg_.size() == 1 );     // one argument\n   CPPAD_ASSERT_UNKNOWN( con_vec_.size() == 1 );     // one value constant\n   CPPAD_ASSERT_UNKNOWN( str_vec_[0] == \"\" );        // empty string\n   CPPAD_ASSERT_UNKNOWN( vec_initial_.size() == 0 );    // no dynamic vectors\n   CPPAD_ASSERT_UNKNOWN( nan_addr == n_ind );        // return value\n   return nan_addr;\n   // END_POST_CONDITION\n}\n/*\n-------------------------------------------------------------------------------\n{xrst_begin val_set_dep dev}\n\nSetting the Dependent Variables\n###############################\n\nset_dep\n*******\n{xrst_literal\n   // BEGIN_SET_DEP\n   // END_SET_DEP\n}\nThis sets the dependent vector to the corresponding indices\nin the value vector.\nThis is last step in creating a recording.\n\n{xrst_end val_set_dep}\n*/\n// ----------------------------------------------------------------------------\n// BEGIN_SET_DEP\ntemplate <class Value>\nvoid tape_t<Value>::set_dep(const Vector<addr_t>& dep_vec)\n// END_SET_DEP\n{  dep_vec_ = dep_vec;\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // inuse\n   size_t thread        = thread_alloc::thread_num();\n   size_t set_dep_inuse = thread_alloc::inuse(thread);\n   std::cout << \"tape:       inuse = \" << set_dep_inuse-set_ind_inuse_ << \"\\n\";\n# endif\n}\n/*\n-------------------------------------------------------------------------------\n{xrst_begin val_record_op dev}\n\nRecording Operators with One Result\n###################################\n\nrecord_op\n*********\n{xrst_literal\n   // BEGIN_RECORD_OP\n   // END_RECORD_OP\n}\nThis can be used to place any operator that has one result in the tape;\ne.g., the unary and binary operators.\n\nop_enum\n*******\nThe argument identifies the operator.\n\nop_arg\n******\nThe vector contains the arg_vec values for this operator.\nIts size must be equal to :ref:`val_base_op@n_arg` for this operator.\n\nreturn\n******\nThe return value is the index were the result of the operation\nis placed in the value vector.\n\n{xrst_end val_record_op}\n*/\n// ----------------------------------------------------------------------------\n// BEGIN_RECORD_OP\ntemplate <class Value>\naddr_t tape_t<Value>::record_op(op_enum_t op_enum, const Vector<addr_t>& op_arg)\n// END_RECORD_OP\n{  //\n   // res_index\n   addr_t res_index = n_val_;\n# ifndef NDEBUG\n   // arg_index\n   addr_t arg_index = addr_t( var_arg_.size() );\n# endif\n   //\n   // op_enum_vec_\n   op_enum_vec_.push_back( uint8_t( op_enum ) );\n   //\n   // var_arg_\n   for(size_t i = 0; i < op_arg.size(); ++i)\n      var_arg_.push_back( op_arg[i] );\n   //\n   // n_val_\n   ++n_val_;\n   //\n# ifndef NDEBUG\n   base_op_t<Value>* op_ptr = op_enum2class<Value>(op_enum);\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( op_ptr->n_arg(arg_index, var_arg_) ) == op_arg.size()\n   );\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( op_ptr->n_res(arg_index, var_arg_) ) == 1\n   );\n# endif\n   //\n   return res_index;\n}\n/*\n{xrst_betin val_record_con_op dev}\n\nRecording Constants\n###################\n\nrecord_con_op\n*************\n{xrst_literal\n   // BEGIN_RECORD_CON_OP\n   // END_RECORD_CON_OP\n}\nThis places a :ref:`val_con_op-name` operator in the tape.\nThe return value is the index were *constant* will be placed\nin the value vector.\nNote that if *constant* is nan, the return value will always be *n_ind*; i.e,\nonly one nan gets paced in the constant vector.\n\n{xrst_end val_record_con_op}\n*/\n// ----------------------------------------------------------------------------\n// BEGIN_RECORD_CON_OP\ntemplate <class Value>\naddr_t tape_t<Value>::record_con_op(const Value& constant)\n// END_RECORD_CON_OP\n{  //\n   // nan\n   if( op_enum_vec_.size() == 0 )\n   {  CPPAD_ASSERT_UNKNOWN( CppAD::isnan(constant) && n_val_ == n_ind_ );\n   }\n   else if( CppAD::isnan(constant) )\n      return n_ind_;\n   //\n   // con_index\n   addr_t con_index = addr_t( con_vec_.size() );\n   con_vec_.push_back( constant );\n   //\n   // res_index\n   addr_t res_index = n_val_;\n   //\n   // op_enum_vec_\n   op_enum_vec_.push_back( uint8_t( con_op_enum ) );\n   //\n   // var_arg_\n   var_arg_.push_back( con_index );\n   //\n   // n_val_\n   ++n_val_;\n   //\n   return res_index;\n}\n/*\n-------------------------------------------------------------------------------\n{xrst_begin val_record_dis_op dev}\n\nRecording The Discrete Operations\n#################################\n\nrecord_dis_op\n*************\n{xrst_literal\n   // BEGIN_RECORD_DIS_OP\n   // END_RECORD_DIS_OP\n}\nThis places a :ref:`val_dis_op-name` operator in the tape.\nThe argument *discrete_index* identifies which discrete function to use.\nThe argument *val_index* is the index of the operand\nin the value vector.\nThe return value is the index were the result will be placed\nin the value vector.\n{xrst_end val_record_dis_op}\n*/\n// ----------------------------------------------------------------------------\n// BEGIN_RECORD_DIS_OP\ntemplate <class Value>\naddr_t tape_t<Value>::record_dis_op(addr_t discrete_index, addr_t val_index)\n// END_RECORD_DIS_OP\n{  //\n   // res_index\n   addr_t res_index = n_val_;\n   //\n   // op_enum_vec_\n   op_enum_vec_.push_back( uint8_t( dis_op_enum ) );\n   //\n   // var_arg_\n   var_arg_.push_back( discrete_index );\n   var_arg_.push_back( val_index );\n   //\n   // n_val_\n   ++n_val_;\n   //\n   return res_index;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_record_comp_op dev}\n\nRecording Comparison Operations\n###############################\n\nrecord_comp_op\n**************\n{xrst_literal\n   // BEGIN_RECORD_COMP_OP\n   // END_RECORD_COMP_OP\n}\nThis places a :ref:`val_comp_op-name` operator in the tape.\nThe return value is always zero because there is\nno value vector result for this operator.\n\ncompare_enum\n============\nThis identifies which comparison is done by this use of the compare operator.\n\nleft_index\n==========\nThis is the value vector index for the left operand in the comparison.\n\nright_index\n===========\nThis is the value vector index for the right operand in the comparison.\n\nreturn\n======\nThe return value is zero because this operator does not have a result\n(and zero is used for an invalid result value).\n\n{xrst_end val_record_comp_op}\n*/\n// ----------------------------------------------------------------------------\n// BEGIN_RECORD_COMP_OP\ntemplate <class Value>\naddr_t tape_t<Value>::record_comp_op(\n   compare_enum_t compare_enum ,\n   addr_t         left_index   ,\n   addr_t         right_index  )\n// END_RECORD_COMP_OP\n{  // res_index\n   addr_t res_index = 0; // invalid result index\n   //\n   // op_enum_vec_\n   op_enum_vec_.push_back( uint8_t( comp_op_enum ) );\n   //\n   // var_arg_\n   var_arg_.push_back( addr_t(compare_enum) );\n   var_arg_.push_back( left_index );\n   var_arg_.push_back( right_index );\n   //\n   return res_index;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_record_call_op dev}\n\nRecording Call Operations\n#########################\n\nrecord_call_op\n**************\n{xrst_literal\n   // BEGIN_RECORD_CALL_OP\n   // END_RECORD_CALL_OP\n}\nThis places a :ref:`val_call_op-name` operator in the tape.\n\natomic_index\n============\nThis is the *atomic_index* for the atomic function; see\n:ref:`atomic_index@index_out` in the case where *index_in* is zero.\n\ncall_id\n=======\nThis is the *call_id* for this use of the atomic function; see\n:ref:`atomic_four_call@call_id` .\n\nn_res\n=====\nThis is the number of values returned by the atomic function call\nand placed in the value vector.\n\nfun_arg\n=======\nThis vector has size equal to the number of arguments to the atomic function\nfor this *call_id* .\n(The combination of *atomic_index* and *call_id* must specify a function.)\nThe *j*-th element of *fun_arg* is the index on the value vector of\nthe *j*-th argument to the function.\n\nreturn\n======\nThe ``record_con_op`` function returns the index in the value vector where\nthe first result is placed in the value vector.\nA total of *n_res* results are placed in the value vector.\n\n{xrst_end val_record_call_op}\n*/\n// ----------------------------------------------------------------------------\n// BEGIN_RECORD_CALL_OP\ntemplate <class Value>\naddr_t tape_t<Value>::record_call_op(\n   addr_t  atomic_index          ,\n   addr_t  call_id               ,\n   addr_t  n_res                 ,\n   const Vector<addr_t>& fun_arg )\n// END_RECORD_CALL_OP\n{  //\n   // res_index\n   addr_t res_index = n_val_;\n   //\n   // op_enum_vec_\n   op_enum_vec_.push_back( uint8_t( call_op_enum ) );\n   //\n   // var_arg_\n   addr_t n_arg = 5 + addr_t( fun_arg.size() );\n   var_arg_.push_back( n_arg );\n   var_arg_.push_back( n_res );\n   var_arg_.push_back( atomic_index );\n   var_arg_.push_back( call_id );\n   for(size_t i = 0; i < fun_arg.size(); ++i)\n      var_arg_.push_back( fun_arg[i] );\n   var_arg_.push_back( n_arg );\n   //\n   // n_val_\n   n_val_ = n_val_ + addr_t(n_res);\n   //\n   return res_index;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_record_csum_op dev}\n\nRecording Cumulative Summation Operations\n#########################################\n\nrecord_csum_op\n**************\n{xrst_literal\n   // BEGIN_RECORD_CSUM_OP\n   // END_RECORD_CSUM_OP\n}\nThis places a :ref:`val_csum_op-name` operator in the tape.\n\nadd\n===\nThis is the vector of value indices corresponding to the values\nthat are added to the sum.\n\nsub\n===\nThis is the vector of value indices corresponding to the values\nthat are subtracted from the sum.\n\nreturn\n======\nThe ``record_con_op`` function returns the index in the value vector where\nthe sum is placed.\n\n{xrst_end val_record_csum_op}\n*/\n// ----------------------------------------------------------------------------\n// BEGIN_RECORD_CSUM_OP\ntemplate <class Value>\naddr_t tape_t<Value>::record_csum_op(\n   const Vector<addr_t>& add ,\n   const Vector<addr_t>& sub )\n// END_RECORD_CSUM_OP\n{  //\n   // n_add, n_sub, n_arg\n   addr_t n_add = addr_t( add.size() );\n   addr_t n_sub = addr_t( sub.size() );\n   addr_t n_arg = 3 + n_add + n_sub;\n   //\n   // res_index\n   addr_t res_index = n_val_;\n   //\n   // op_enum_vec_\n   op_enum_vec_.push_back( uint8_t( csum_op_enum ) );\n   //\n   // var_arg_\n   var_arg_.push_back( n_add );\n   var_arg_.push_back( n_sub );\n   for(size_t i = 0; i < add.size(); ++i)\n      var_arg_.push_back( add[i] );\n   for(size_t i = 0; i < sub.size(); ++i)\n      var_arg_.push_back( sub[i] );\n   var_arg_.push_back( n_arg );\n   //\n   // n_val_\n   ++n_val_;\n   //\n   return res_index;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_record_cexp_op dev}\n\nRecording Comparison Operations\n###############################\n\nrecord_cexp_op\n**************\n{xrst_literal\n   // BEGIN_RECORD_CEXP_OP\n   // END_RECORD_CEXP_OP\n}\nThis places a :ref:`val_cexp_op-name` operator in the tape.\n\ncompare_enum\n============\nThis identifies which comparison is used by this conditional expression.\n\nleft\n====\nThis is the value vector index for the left operand in the comparison.\n\nright\n=====\nThis is the value vector index for the right operand in the comparison.\n\nif_true\n=======\nThis is the index of the value of the value that is used for the result if\nthe comparison is true.\n\nif_false\n========\nThis is the index of the value of the value that is used for the result if\nthe comparison is false.\n\nreturn\n======\nThe ``record_con_op`` function returns the index in the value vector where\nthe result is placed in the value vector.\n\n{xrst_end val_record_cexp_op}\n*/\n// ----------------------------------------------------------------------------\n// BEGIN_RECORD_CEXP_OP\ntemplate <class Value>\naddr_t tape_t<Value>::record_cexp_op(\n   compare_enum_t comp_enum ,\n   addr_t         left      ,\n   addr_t         right     ,\n   addr_t         if_true   ,\n   addr_t         if_false  )\n// END_RECORD_CEXP_OP\n{  //\n   // res_index\n   addr_t res_index = n_val_;\n   //\n   // op_enum_vec_\n   op_enum_vec_.push_back( uint8_t(cexp_op_enum) );\n   //\n   // var_arg_\n   var_arg_.push_back( addr_t(comp_enum) );\n   var_arg_.push_back( left );\n   var_arg_.push_back( right );\n   var_arg_.push_back( if_true );\n   var_arg_.push_back( if_false );\n   //\n   // n_val_\n   ++n_val_;\n   //\n   return res_index;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_record_pri_op dev}\n{xrst_spell\n   str\n}\n\nRecording Print Operations\n##########################\n\nrecord_pri_op\n*************\n{xrst_literal\n   // BEGIN_RECORD_PRI_OP\n   // END_RECORD_PRI_OP\n}\nThis places a :ref:`val_pri_op-name` operator in the tape.\nThe return value is always zero because there is\nno value vector result for this operator.\n\nbefore\n======\nThis is the text that is printed before the value when *flag* is positive.\nIf a previous str_vec\\_ entry is equal to before, it is used.\nOtherwise a new entry equal to before is added to str_vec\\_.\n\nafter\n=====\nThis is the text that is printed after the value when *flag* is positive.\nIf a previous str_vec\\_ entry is equal to after, it is used.\nOtherwise a new entry equal to after is added to str_vec\\_.\n\nflag_index\n==========\nThis is the value vector index for the flag operand.\n\nvalue_index\n===========\nThis is the value vector index for the value that is printed\nwhen the flag is positive.\n\nreturn\n======\nThe return value is zero because this operator does not have a result\n(and zero is used for an invalid result value).\n\n{xrst_end val_record_pri_op}\n*/\n// ----------------------------------------------------------------------------\n// BEGIN_RECORD_PRI_OP\ntemplate <class Value>\naddr_t tape_t<Value>::record_pri_op(\n   const std::string& before      ,\n   const std::string& after       ,\n   addr_t             flag_index  ,\n   addr_t             value_index )\n// END_RECORD_PRI_OP\n{  //\n   // str_index\n   using std::string;\n   auto str_index = [](const string& str, Vector<string>& str_vec)\n   {  size_t result = str_vec.size();\n      for(size_t i = 0; i < str_vec.size(); ++i)\n      {  if( str == str_vec[i] )\n            result = i;\n      }\n      if( result == str_vec.size() )\n         str_vec.push_back(str);\n      return addr_t( result );\n   };\n   // empty string\n   CPPAD_ASSERT_UNKNOWN( str_vec_[0] == \"\" );\n   //\n   // res_index\n   addr_t res_index = 0; // invalid result index\n   //\n   // op_enum_vec_\n   op_enum_vec_.push_back( uint8_t(pri_op_enum) );\n   //\n   // str_vec_, var_arg_: before_index\n   addr_t before_index = str_index(before, str_vec_);\n   var_arg_.push_back( before_index );\n   //\n   // str_vec_, var_arg_: after_index\n   addr_t after_index = str_index(after, str_vec_);\n   var_arg_.push_back( after_index );\n   //\n   // var_arg_: flag_index, value_index\n   var_arg_.push_back( flag_index );\n   var_arg_.push_back( value_index );\n   //\n   return res_index;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_record_vec_op dev}\n\nRecord Adding a Dynamic Vector\n##############################\n\nrecord_vec_op\n*************\n{xrst_literal\n   // BEGIN_RECORD_VEC_OP\n   // END_RECORD_VEC_OP\n}\nThis creates a new dynamic vector with the specified initial values.\nA dynamic vector must be created before a load or store can be recorded\nfor the corresponding vector.\n\ninitial\n*******\nThe size of this vector is the size of the dynamic vector being created.\nThe initial value for the dynamic vector at index *vector_index* is\nthe value vector at index *initial*[ *vector_index* ]; i.e.,\n\n   *val_vec* [ *initial* [ *vector_index* ] ]\n\nwhere *val_vec* is the value vector.\n\nwhich_vector\n************\nThe return value is an index identifying\nwhich dynamic vector is created.\nThis is the *which_vector* argument for subsequent\n:ref:`load <val_load_op@eval@which_vector>` and\n:ref:`store <val_store_op@eval@which_vector>` operators\nthat use this dynamic vector.\n\n\n{xrst_end val_record_vec_op}\n*/\n// BEGIN_RECORD_VEC_OP\ntemplate <class Value>\naddr_t tape_t<Value>::record_vec_op(const Vector<addr_t>& initial)\n// END_RECORD_VEC_OP\n{  //\n   // which_vector\n   addr_t which_vector = addr_t( vec_initial_.size() );\n   //\n   // vec_initial_\n   vec_initial_.push_back( initial );\n   //\n   // op_enum_vec_\n   op_enum_vec_.push_back( uint8_t(vec_op_enum) );\n   //\n   // var_arg_\n   var_arg_.push_back( which_vector );\n   //\n   return which_vector;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_record_load_op dev}\n\nRecording Load Operations\n#########################\n\nrecord_load_op\n**************\n{xrst_literal\n   // BEGIN_RECORD_LOAD_OP\n   // END_RECORD_LOAD_OP\n}\nThis places a :ref:`val_load_op-name` operator in the tape.\n\nwhich_vector\n============\nThis is the index returned by :ref:`val_vec_op-name`\nwhen it created this dynamic vector.\n\nvector_index\n============\nThis is the index, in the value vector, of the index in the dynamic vector,\nof the element for this load operation.\n\nreturn\n******\nThe return value is the index were the result of the operation\nis placed in the value vector.\n\n{xrst_end val_record_load_op}\n*/\n// ----------------------------------------------------------------------------\n// BEGIN_RECORD_LOAD_OP\ntemplate <class Value>\naddr_t tape_t<Value>::record_load_op(\n   addr_t   which_vector  ,\n   addr_t   vector_index  )\n// END_RECORD_LOAD_OP\n{  //\n   // check that vec_op_enum comes before load_op_enum\n   CPPAD_ASSERT_UNKNOWN( size_t(which_vector) < vec_initial_.size() );\n   //\n   // res_index\n   addr_t res_index = n_val_;\n   //\n   // op_enum_vec_\n   op_enum_vec_.push_back( uint8_t(load_op_enum) );\n   //\n   // var_arg_\n   var_arg_.push_back( which_vector );\n   var_arg_.push_back( vector_index );\n   //\n   // n_val_\n   ++n_val_;\n   //\n   return res_index;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_record_store_op dev}\n\nRecording Store Operations\n##########################\n\nrecord_store_op\n***************\n{xrst_literal\n   // BEGIN_RECORD_STORE_OP\n   // END_RECORD_STORE_OP\n}\nThis places a :ref:`val_store_op-name` operator in the tape.\n\nwhich_vector\n============\nThis is the index returned by :ref:`val_vec_op-name`\nwhen it created this dynamic vector.\n\nvector_index\n============\nThis is the index, in the value vector, of the index in the dynamic vector,\nof the element for this store operation.\n\nreturn\n******\nThe return value is always zero because there is\nno value vector result for this operator.\n\n{xrst_end val_record_store_op}\n*/\n// ----------------------------------------------------------------------------\n// BEGIN_RECORD_STORE_OP\ntemplate <class Value>\naddr_t tape_t<Value>::record_store_op(\n   addr_t   which_vector  ,\n   addr_t   vector_index  ,\n   addr_t   value_index   )\n// END_RECORD_STORE_OP\n{  //\n   // check that vec_op_enum comes before store_op_enum\n   CPPAD_ASSERT_UNKNOWN( size_t(which_vector) < vec_initial_.size() );\n   //\n   // res_index\n   addr_t res_index = 0;\n   //\n   // op_enum_vec_\n   op_enum_vec_.push_back( uint8_t(store_op_enum) );\n   //\n   // var_arg_\n   var_arg_.push_back( which_vector );\n   var_arg_.push_back( vector_index );\n   var_arg_.push_back( value_index  );\n   //\n   return res_index;\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/record_new.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_RECORD_NEW_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_RECORD_NEW_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-25 Bradley M. Bell\n// ---------------------------------------------------------------------------\n# include <cppad/local/val_graph/op_iterator.hpp>\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_record_new dev}\n\nCopy an Old Operator to a New Tape\n##################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_RECORD_NEW\n   // END_RECORD_NEW\n}\n\nOld Tape\n********\nWe refer to ``*this`` as the old tape.\n\nnew_tape\n********\nThe is the new tape that the operator is recorded on.\n\nnew_which_vec\n*************\nThis vector has size ``vec_initial_.size()`` .\nIt is a mapping from each dynamic vector index in the old tape\nto the corresponding dynamic vector index in the new tape.\n\n#. This starts out as the invalid value\n   ``vec_initial_.size()`` for each old dynamic vector index.\n\n#. If the operator being recorded is an ``vec_op_enum`` operator,\n   a dynamic vector is added to the new tape and the corresponding\n   *new_which_vec* entry is modified.\n\n#. If this is a load or store operation, *new_which_vec* is used to map\n   from the dynamic vector index in the old tape to the dynamic vector\n   index in the new tape.\n\nwork\n****\nThis is work space used by record_new and not otherwise specified.\n\nnew_val_index\n*************\nThis vector has size ``n_val()``\nbut it is only defined for indices less than *res_index* (see below).\nIt is a mapping from each value index in the old tape\nto the corresponding value index in the new tape.\n\nval_use_case\n************\nIf *val_use_case* [ *val_index* ] is zero,\nthe value with index *val_index* is not needed to compute\nthe dependent variables.\n\nop_ptr\n******\nThis is a pointer to the :ref:`val_base_op-name` for the operator on this tape.\n\narg_index\n*********\nThis is the value index corresponding to the first argument for the operator\non this tape.\n\nres_index\n*********\nThis is the value index corresponding to the first result for the operator\non this tape.\n\nnew_res_index\n*************\nThis is the value index in the new tape that corresponds to the first result\nfor this operator.\n\n{xrst_end val_record_new}\n*/\n// BEGIN_RECORD_NEW\n// new_res_index = record_new( ... )\ntemplate <class Value>\naddr_t tape_t<Value>::record_new(\n   tape_t&                   new_tape         ,\n   Vector<addr_t>&           new_which_vec    ,\n   Vector<addr_t>&           work             ,\n   const Vector<addr_t>&     new_val_index    ,\n   const Vector<addr_t>&     val_use_case     ,\n   const base_op_t<Value>*   op_ptr           ,\n   addr_t                    arg_index        ,\n   addr_t                    res_index        )\n// END_RECORD_NEW\n{\n   //\n   // op_arg\n   Vector<addr_t>& op_arg(work);\n   //\n   // new_res_index\n   // set to avoid compiler warning\n   addr_t new_res_index = 0;\n   //\n   // op_enum, n_arg, n_before, n_after, n_res\n   op_enum_t  op_enum   = op_ptr->op_enum();\n   addr_t     n_before  = op_ptr->n_before();\n   addr_t     n_after   = op_ptr->n_after();\n   addr_t     n_arg     = op_ptr->n_arg(arg_index, var_arg_);\n   addr_t     n_res     = op_ptr->n_res(arg_index, var_arg_);\n   //\n   // new_tape, new_res_index\n   bool simple = n_res == 1;\n   simple     &= op_enum != con_op_enum;\n   simple     &= op_enum != call_op_enum;\n   simple     &= op_enum != load_op_enum;\n   if( simple )\n   {  op_arg.resize(n_arg);\n      for(addr_t k = 0; k < n_before; ++k)\n         op_arg[k] = var_arg_[arg_index + k];\n      for(addr_t k = n_before; k < n_arg - n_after; ++k)\n      {  addr_t old_index = var_arg_[arg_index + k];\n         assert( old_index < res_index );\n         CPPAD_ASSERT_UNKNOWN( val_use_case[old_index] != 0 );\n         op_arg[k] = new_val_index[old_index];\n      }\n      for(addr_t k = 1; k <= n_after; ++k)\n         op_arg[n_arg - k] = var_arg_[arg_index + n_arg - k];\n      //\n      new_res_index = new_tape.record_op(op_enum, op_arg);\n   }\n   else switch( op_enum )\n   {  //\n      // default\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n      //\n      // new_res_index\n      break;\n      //\n      // load_op_enum\n      // new_val_index\n      case load_op_enum:\n      CPPAD_ASSERT_UNKNOWN( n_res == 1);\n      {  addr_t which_vector = new_which_vec[ var_arg_[arg_index + 0] ];\n         addr_t vector_index = new_val_index[ var_arg_[arg_index + 1] ];\n         //\n         // record_con_op, new_val_index\n         new_res_index = new_tape.record_load_op( which_vector, vector_index);\n      }\n      break;\n      //\n      // con_op_enum\n      // new_val_index\n      case con_op_enum:\n      CPPAD_ASSERT_UNKNOWN( n_res == 1 );\n      {  Value value = con_vec_[ var_arg_[ arg_index ] ];\n         //\n         // record_con_op, new_val_index\n         new_res_index = new_tape.record_con_op(value);\n      }\n      break;\n      //\n      // store_op_enum\n      case store_op_enum:\n      CPPAD_ASSERT_UNKNOWN( n_res == 0 );\n      {  addr_t which_vector = new_which_vec[ var_arg_[arg_index + 0] ];\n         addr_t vector_index = new_val_index[ var_arg_[arg_index + 1] ];\n         addr_t value_index  = new_val_index[ var_arg_[arg_index + 2] ];\n         CPPAD_ASSERT_UNKNOWN( val_use_case[ var_arg_[arg_index + 1] ] != 0 );\n         CPPAD_ASSERT_UNKNOWN( val_use_case[ var_arg_[arg_index + 2] ] != 0 );\n         new_tape.record_store_op(\n            which_vector, vector_index, value_index\n         );\n      }\n      break;\n      //\n      // vec_op_enum\n      case vec_op_enum:\n      CPPAD_ASSERT_UNKNOWN( n_res == 0 );\n      {  addr_t old_which_vector       = var_arg_[arg_index + 0];\n         const Vector<addr_t>& initial = vec_initial_[old_which_vector];\n         addr_t which_vector           = new_tape.record_vec_op(initial);\n         //\n         // new_which_vec\n         new_which_vec[old_which_vector] = which_vector;\n      }\n      break;\n      //\n      // comp_op_enum\n      case comp_op_enum:\n      CPPAD_ASSERT_UNKNOWN( n_res == 0 );\n      {  compare_enum_t compare_enum;\n         compare_enum       = compare_enum_t( var_arg_[arg_index + 0] );\n         addr_t left_index  = new_val_index[ var_arg_[arg_index + 1] ];\n         addr_t right_index = new_val_index[ var_arg_[arg_index + 2] ];\n         CPPAD_ASSERT_UNKNOWN( val_use_case[ var_arg_[arg_index + 1] ] != 0 );\n         CPPAD_ASSERT_UNKNOWN( val_use_case[ var_arg_[arg_index + 2] ] != 0 );\n         new_tape.record_comp_op(\n            compare_enum, left_index, right_index\n         );\n      }\n      break;\n      //\n      // pri_op_enum\n      CPPAD_ASSERT_UNKNOWN( n_res == 0 );\n      case pri_op_enum:\n      {  std::string before = str_vec_[ var_arg_[arg_index + 0] ];\n         std::string after  = str_vec_[ var_arg_[arg_index + 1] ];\n         addr_t left_index  = new_val_index[ var_arg_[arg_index + 2] ];\n         addr_t right_index = new_val_index[ var_arg_[arg_index + 3] ];\n         CPPAD_ASSERT_UNKNOWN( val_use_case[ var_arg_[arg_index + 2] ] != 0 );\n         CPPAD_ASSERT_UNKNOWN( val_use_case[ var_arg_[arg_index + 3] ] != 0 );\n         new_tape.record_pri_op(\n            before, after, left_index, right_index\n         );\n      }\n      break;\n      //\n      // call_op_enum\n      // new_val_index\n      case call_op_enum:\n      {  //\n         // n_x\n         addr_t n_x = n_arg - n_before - op_ptr->n_after();\n# ifndef NDEBUG\n         bool one_arg_needed = false;\n# endif\n         //\n         op_arg.resize(n_x);\n         for(addr_t k = 0; k < n_x; ++k)\n         {  addr_t val_index = var_arg_[arg_index + n_before + k];\n            if( val_use_case[val_index] != 0 )\n            {  op_arg[k] = new_val_index[val_index];\n# ifndef NDEBUG\n               one_arg_needed =  true;\n# endif\n            }\n            else\n            {  // nan in the new tape\n               op_arg[k] = new_tape.n_ind();\n            }\n         }\n         CPPAD_ASSERT_UNKNOWN( one_arg_needed );\n         addr_t atomic_index = var_arg_[arg_index + 2];\n         addr_t call_id      = var_arg_[arg_index + 3];\n         new_res_index       = new_tape.record_call_op(\n            atomic_index, call_id, n_res, op_arg\n         );\n      }\n      break;\n   }\n   return new_res_index;\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/renumber.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_RENUMBER_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_RENUMBER_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-25 Bradley M. Bell\n// ---------------------------------------------------------------------------\n# include <cppad/local/val_graph/op_hash_table.hpp>\n\n/*\n-------------------------------------------------------------------------------\n{xrst_begin val_tape_renumber dev}\n{xrst_spell\n   dep\n}\n\nValue Re-Numbering\n##################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_RENUMBER\n   // END_RENUMBER\n}\n\nDiscussion\n**********\nThis routine uses hash coding to find operators that are equivalent\nto a previous operators in the tape.\nIt changes the use of an operator's results to use of the\nresults for the equivalent previous operator with lowest index.\nThis creates an equivalent tape where replaced operators are not removed,\nbut the are dead code in the new tape.\n\nCompare Operators\n*****************\nIf two or more compare operators are identical, the first will be kept as\nis and the others will be changed to compare_no_enum operators.\nIn this case future calls to eval will on add one to\n:ref:`val_tape@eval@compare_false`,\nfor each unique comparison that is false.\nbe removed.\n\nChanges\n*******\nOnly the following values, for this tape, are guaranteed to be same:\n#. The number of independent values :ref:`val_tape@n_ind` .\n#. The size of the dependent vector :ref:`dep_vec.size() <val_tape@dep_vec>` .\n#. The mapping from the independent to the dependent variables.\n\nReference\n*********\n`value numbering <https://en.wikipedia.org/wiki/Value_numbering>`_ .\n\n{xrst_toc_hidden\n   val_graph/renumber_xam.cpp\n}\nExample\n*******\nThe file :ref:`renumber_xam.cpp <val_renumber_xam.cpp-name>` is an\nexample and test of tape.renumber().\n\n{xrst_end val_tape_renumber}\n-------------------------------------------------------------------------------\n*/\nnamespace CppAD { namespace local { namespace val_graph {\n\n// BEGIN_RENUMBER\ntemplate <class Value>\nvoid tape_t<Value>::renumber(void)\n// END_RENUMBER\n{\n   // -----------------------------------------------------------------------\n   // SAS Global Value Renumbering\n   // https://en.wikipedia.org/wiki/Value_numbering\n   // -----------------------------------------------------------------------\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // thread, initial_inuse\n   size_t thread        = thread_alloc::thread_num();\n   size_t initial_inuse = thread_alloc::inuse(thread);\n# endif\n   //\n   // op2arg_index, op2res_index\n   Vector<addr_t> op2arg_index( n_op() ), op2res_index( n_op() );\n   {  op_iterator<Value> op_itr(*this, 0);\n      for(addr_t i_op = 0; i_op < n_op(); ++i_op)\n      {  op2arg_index[i_op] = op_itr.arg_index();\n         op2res_index[i_op] = op_itr.res_index();\n         ++op_itr;\n      }\n   }\n   //\n   // op_hash_table\n   addr_t n_hash_code = 1 + (n_val_ / 2);\n   op_hash_table_t<Value>  op_hash_table(*this, op2arg_index, n_hash_code);\n   //\n   // new_val_index\n   // value used for operators that are not replaced.\n   Vector<addr_t> new_val_index( n_val_ );\n   for(addr_t i = 0; i < addr_t(n_val_); ++i)\n      new_val_index[i] = i;\n   //\n   // i_op\n   for(addr_t i_op = 0; i_op < n_op(); ++i_op)\n   {  //\n      // op_ptr\n      const base_op_t<Value>* op_ptr   = base_op_ptr(i_op);\n      //\n      // arg_index_i, res_index_i\n      addr_t arg_index_i = op2arg_index[i_op];\n      addr_t res_index_i = op2res_index[i_op];\n      //\n      // j_op\n      addr_t j_op = op_hash_table.match_op(i_op, new_val_index);\n      if( j_op != i_op )\n      {  assert( j_op < i_op );\n         //\n         // new_val_index\n         // mapping so that op_j results will be used instead of op_i results;\n         // i.e., op_i becomes dead code.\n         addr_t res_index_j = op2res_index[j_op];\n         addr_t n_res       = op_ptr->n_res(arg_index_i, var_arg_);\n         if( n_res == 0 )\n         {  //\n            // change the i_op operator to a no op\n            if( op_ptr->op_enum() == pri_op_enum )\n               var_arg_[arg_index_i + 2] = this->n_ind();\n            else\n            {\n               CPPAD_ASSERT_UNKNOWN( op_ptr->op_enum() == comp_op_enum );\n               var_arg_[arg_index_i + 0] = compare_no_enum;\n            }\n         }\n         else for(addr_t k = 0; k < n_res; ++k)\n            new_val_index[res_index_i + k] = res_index_j + k;\n      }\n   }\n   //\n   // var_arg_\n   for(addr_t i_op = 0; i_op < n_op(); ++i_op)\n   {  //\n      // op_ptr\n      const base_op_t<Value>* op_ptr   = base_op_ptr(i_op);\n      //\n      // arg_index, n_arg\n      addr_t    arg_index = op2arg_index[i_op];\n      addr_t    n_arg     = op_ptr->n_arg(arg_index, var_arg_);\n      //\n      // n_before, n_x\n      addr_t n_before = op_ptr->n_before();\n      addr_t n_x = n_arg - n_before - op_ptr->n_after();\n      //\n      for(addr_t i = 0; i < n_x; ++i)\n      {  addr_t val_index = arg_index + n_before + i;\n         var_arg_[val_index] = new_val_index[ var_arg_[val_index] ];\n      }\n   }\n   //\n   // dep_vec_\n   for(size_t i = 0; i < dep_vec_.size(); ++i)\n      dep_vec_[i] = new_val_index[ dep_vec_[i] ];\n\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // A set size more than one represents a collision\n   Vector<addr_t> size_count = op_hash_table.size_count();\n   for(size_t i = 0; i < size_count.size(); ++i)\n      std::cout << \"size = \" << i << \", count = \" << size_count[i] << \"\\n\";\n   //\n   // inuse\n   size_t final_inuse = thread_alloc::inuse(thread);\n   std::cout << \"renumber:   inuse = \" << final_inuse - initial_inuse << \"\\n\";\n# endif\n   return;\n}\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/rev_depend.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_REV_DEPEND_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_REV_DEPEND_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-25 Bradley M. Bell\n// ---------------------------------------------------------------------------\n# include <cppad/local/val_graph/tape.hpp>\n# include <cppad/local/atomic_index.hpp>\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_tape_rev_depend dev}\n\nReverse Dependency Analysis\n###########################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_REV_DEPEND\n   // END_REV_DEPEND\n}\n\ntape\n****\nIs the :ref:`val_tape-name` that we are analyzing.\n\nval_use_case\n************\nThis vector is empty on input.\nUpon return, it has size equal to the number of values; i.e.,\n:ref:`val_tape@n_val` .\n\nZero\n====\nIf *val_use_case* [ *val_index* ] is zero,\nthe value with index *val_index* is not needed\nto compute the dependent variables.\n\nn_op\n====\nIf *val_use_case* [ *val_index* ] is equal to n_op (the number of operators),\nthe value with index *val_index* satisfies one of the following conditions:\n\n#. It is a dependent variable.\n#. It is used by more than one operator.\n#. It is used more than once by one operator and that operator is not a\n   binary operator.\n\nOtherwise\n=========\nIf *val_use_case* [ *val_index* ] is not zero or n_op,\nit is the index of the only operator that\nuses the value with index *val_index* as an argument.\n\nvec_last_load\n*************\nThis vector is empty on input.\nUpon return, it has size equal the number of dynamic vectors; i.e.,\nvec_size\\_.size() .\nThe value\n\n   *i_op* = *vec_last_load* [ *which_vector* ]\n\nis the index of the last load operator,\nthat used the dynamic vector with index *which_vector* ,\nand is needed to compute the dependent variables.\n\nImprovement\n===========\nThis could be done differently as a vector of maps.\n\n   *i_op* = *vec_last_load*[ *which_vector* ] [ *value_index* ]\n\nwould be the operator index of the last load operator with the same\n:ref:`val_load_op@eval@which_vector` and :ref:`val_load_op@eval@vector_index` .\nThen we could avoid two stores to the same vector and index with no\nload in between.\n\n{xrst_end val_tape_rev_depend}\n*/\n// BEGIN_REV_DEPEND\n// tape.rev_depend(val_use_case, vec_last_load)\ntemplate <class Value>\nvoid tape_t<Value>::rev_depend(\n   Vector<addr_t>& val_use_case  ,\n   Vector<addr_t>& vec_last_load )\n// END_REV_DEPEND\n{  CPPAD_ASSERT_UNKNOWN( val_use_case.size() == 0 );\n   CPPAD_ASSERT_UNKNOWN( vec_last_load.size() == 0 );\n   //\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // thread, initial_inuse\n   size_t thread        = thread_alloc::thread_num();\n   size_t initial_inuse = thread_alloc::inuse(thread);\n# endif\n   //\n   // con_x, type_x, depend_x, depend_y\n   // use CppAD::vector because call_atomic_rev_depend expect it\n   CppAD::vector<Value> con_x;\n   CppAD::vector<ad_type_enum> type_x;\n   CppAD::vector<bool> depend_x, depend_y;\n   //\n   // val_index2con\n   Vector< Vector<Value> > val_vec_vec( vec_initial_.size() );\n   for(size_t i = 0; i < vec_initial_.size(); ++i)\n      val_vec_vec[i].resize( vec_initial_[i].size() );\n   Value nan = CppAD::numeric_limits<Value>::quiet_NaN();\n   Vector<Value> val_index2con(n_val_);\n   for(addr_t i = 0; i < n_val_; ++i)\n      val_index2con[i] = nan;\n   bool trace           = false;\n   eval(trace, val_index2con);\n   //\n   // val_use_case\n   // initialize as no operator uses any value\n   val_use_case.resize(n_val_);\n   for(addr_t i = 0; i < n_val_; ++i)\n      val_use_case[i] = 0;\n   //\n   // vec_last_load\n   // initialize as the no operator uses any dynamic vector\n   vec_last_load.resize( vec_initial_.size() );\n   for(size_t i = 0; i < vec_initial_.size(); ++i)\n      vec_last_load[i] = 0;\n   //\n   // val_use_case\n   for(size_t i = 0; i < dep_vec_.size(); ++i)\n      val_use_case[ dep_vec_[i] ] = n_op(); // result is a dependent var\n   //\n   // inc_val_use_case\n   auto inc_val_use_case =\n      [this, &val_use_case](addr_t val_index, addr_t op_index)\n   {  if( val_use_case[val_index] == 0 )\n         val_use_case[val_index] = op_index; // only used by this operator\n      else\n         val_use_case[val_index] = n_op();   // is used multiple times\n   };\n   //\n   // op_itr\n   op_iterator<Value> op_itr(*this, n_op() );\n   //\n   // use_case\n   addr_t i_op = n_op();\n   while( i_op-- )\n   {  //\n      // op_itr\n      --op_itr;\n      //\n      // op_ptr, arg_index, res_index\n      const base_op_t<Value>* op_ptr    = op_itr.op_ptr();\n      addr_t                  res_index = op_itr.res_index();\n      addr_t                  arg_index = op_itr.arg_index();\n      //\n      // op_enum, n_before, n_after, n_arg, n_res, is_binary\n      op_enum_t op_enum   = op_ptr->op_enum();\n      addr_t    n_before  = op_ptr->n_before();\n      addr_t    n_after   = op_ptr->n_after();\n      addr_t    n_arg     = op_ptr->n_arg(arg_index, var_arg_);\n      addr_t    n_res     = op_ptr->n_res(arg_index, var_arg_);\n      bool      is_binary = op_ptr->is_binary();\n      //\n      if( 0 < n_res && op_enum != call_op_enum )\n      {  CPPAD_ASSERT_UNKNOWN( n_res == 1 );\n         //\n         // need_op\n         bool need_op = bool( val_use_case[res_index + 0] );\n         //\n         // val_use_case\n         if( need_op )\n         {  if( is_binary )\n            {  addr_t left_index  = var_arg_[arg_index + 0];\n               addr_t right_index = var_arg_[arg_index + 1];\n               inc_val_use_case(left_index, i_op);\n               if( left_index != right_index )\n                  inc_val_use_case(right_index, i_op);\n            }\n            else if( op_enum == load_op_enum )\n            {  CPPAD_ASSERT_UNKNOWN( i_op != 0 );\n               addr_t which_vector = var_arg_[arg_index + 0];\n               addr_t val_index    = var_arg_[arg_index + 1];\n               if( vec_last_load[which_vector] == 0 )\n                  vec_last_load[which_vector] = i_op;\n               inc_val_use_case(val_index, i_op);\n            }\n            else\n            {  for(addr_t i = n_before; i < n_arg - n_after; ++i)\n               {  addr_t val_index = var_arg_[arg_index + i];\n                  inc_val_use_case(val_index, i_op);\n               }\n            }\n         }\n      }\n      else if( 0 < n_res )\n      {  //\n         // call_op_enum\n         CPPAD_ASSERT_UNKNOWN( op_enum == call_op_enum );\n         //\n         size_t atomic_index  = size_t( var_arg_[arg_index + 2] );\n         size_t call_id       = size_t( var_arg_[arg_index + 3] );\n         //\n         // n_x\n         addr_t n_x = n_arg - n_before - n_after;\n         size_t nx  = size_t(n_x);\n         //\n         // con_x, type_x\n         con_x.resize(nx);\n         type_x.resize(nx);\n         for(addr_t i = 0; i < n_x; ++i)\n         {  con_x[i] = val_index2con[ var_arg_[arg_index + n_before + i] ];\n            if( CppAD::isnan( con_x[i] ) )\n               type_x[i] = variable_enum;\n            else\n               type_x[i] = constant_enum;\n         }\n         //\n         // depend_y\n         depend_y.resize(n_res);\n         for(addr_t i = 0; i < n_res; ++i)\n            depend_y[i] = bool( val_use_case[ res_index + i ] );\n         //\n         // depend_x\n         // only constants (not dynamic parameters) are included in con_x\n         depend_x.resize(nx);\n         local::sweep::call_atomic_rev_depend<Value, Value>(\n            atomic_index, call_id, con_x, type_x, depend_x, depend_y\n         );\n         //\n         // val_use_case\n         for(addr_t k = 0; k < n_x; ++k)\n         {  addr_t val_index = var_arg_[arg_index + n_before + k];\n            if( depend_x[k] )\n               inc_val_use_case(val_index, i_op);\n         }\n      }\n   }\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // inuse\n   size_t final_inuse = thread_alloc::inuse(thread);\n   std::cout << \"rev_depend: inuse = \" << final_inuse - initial_inuse << \"\\n\";\n# endif\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/summation.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_SUMMATION_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_SUMMATION_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-25 Bradley M. Bell\n// ---------------------------------------------------------------------------\n# include <cppad/local/val_graph/tape.hpp>\n# include <cppad/local/val_graph/rev_depend.hpp>\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n------------------------------------------------------------------------------\n{xrst_begin_parent val_summation dev}\n{xrst_spell\n   csum\n   dep\n   neg\n}\n\nCombine Multiple sum Operators into a csum Operator\n###################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_SUMMATION\n   // END_SUMMATION\n}\n\n\nDiscussion\n**********\nWe refer to an add, sub, neg, or csum operator as a sum operation.\nIf the result for one of these operations is only used by a sum operator,\nthe two operations can be replaced by a single csum operator.\nThis process is repeated until the result is used by some other operation\nor the result is a dependent variable.\n\nLimitation\n**********\nThe process above terminates before reaching a csum operator in the\noriginal tape. To get full optimization in this case, csum operators\nshould first be converted to add and sub operations.\n\nChanges\n*******\nOnly the following values, for this tape, are guaranteed to be same:\n#. The number of independent values :ref:`val_tape@n_ind` .\n#. The size of the dependent vector :ref:`dep_vec.size() <val_tape@dep_vec>` .\n\nExample\n*******\nThe file :ref:`val_summation_xam.cpp-name` is an example and test using\ntape.summation().\n\nContents\n********\n{xrst_toc_table\n   val_graph/summation_xam.cpp\n}\n\n{xrst_end val_summation}\n-----------------------------------------------------------------------------\n{xrst_begin val_csum_info dev}\n{xrst_spell\n   ctor\n   struct\n}\n\nInformation for a Cumulative Summation\n######################################\n\n{xrst_code cpp} */\nstruct csum_info_t {\n   bool  first_done;  // is first operator argument included in lists\n   bool  second_done; // is second operator argument included in lists\n   std::list<addr_t> add_list; // list of value indices to add\n   std::list<addr_t> sub_list; // list of value indices to subtract\n   // ctor\n   csum_info_t() : first_done(false), second_done(false) { }\n};\n/* {xrst_code}\n{xrst_end val_csum_info}\n------------------------------------------------------------------------------\n{xrst_begin val_replace_csum_op dev}\n{xrst_spell\n   neg\n}\n\nReplace An Operator with a Cumulative Summation\n###############################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_REPLACE_CSUM_OP\n   // END_REPLACE_CSUM_OP\n}\n\nReplacement Operator Use\n************************\nThis will replace an operator use in the tape.\nThe :ref:`set_op2arg_index <val_op2arg_index@set>` must have been\nexecuted on this tape before a replacement can be done.\n\nres_index\n*********\nis the value index of the result for this operator.\n\nop_index\n********\nis the index of the operator that we are replacing\nThis operator must have just one result with index res_index.\n\ncsum_info\n*********\nIs the cumulative summation information for the operator\nthat we are replacing.\nThe idea here is that there are multiple add, sub, and neg operators\nthat become dead code when this replacement is done.\n\n{xrst_end val_replace_csum_op}\n*/\n//\n// BEGIN_REPLACE_CSUM_OP\ntemplate <class Value>\nvoid tape_t<Value>::replace_csum_op(\n   addr_t       res_index ,\n   addr_t       i_op      ,\n   csum_info_t& csum_info )\n// END_REPLACE_CSUM_OP\n{\n   //\n   // This is a replace\n   //\n   // op_enum_vec_\n   op_enum_vec_[i_op] = uint8_t( csum_op_enum );\n   //\n   // arg_index_vec_\n   op2arg_index_[i_op] = addr_t( var_arg_.size() );\n   //\n   // n_add, var_arg_\n   addr_t n_add  = addr_t( csum_info.add_list.size() );\n   var_arg_.push_back( n_add );\n   //\n   // n_sub, var_arg_\n   addr_t n_sub  = addr_t( csum_info.sub_list.size() );\n   var_arg_.push_back( n_sub );\n   //\n   // itr\n   std::list<addr_t>::const_iterator itr;\n   //\n   // var_arg_: addition variables\n   for(itr = csum_info.add_list.begin(); itr != csum_info.add_list.end(); ++itr)\n   {  CPPAD_ASSERT_UNKNOWN( *itr < res_index );\n      var_arg_.push_back( *itr );\n   }\n   //\n   // var_arg_: subtraction variables\n   for(itr = csum_info.sub_list.begin(); itr != csum_info.sub_list.end(); ++itr)\n   {  CPPAD_ASSERT_UNKNOWN( *itr < res_index );\n      var_arg_.push_back( *itr );\n   }\n   //\n   // n_arg, var_arg_\n   addr_t n_arg = 3 + n_add + n_sub;\n   var_arg_.push_back( n_arg );\n   //\n   return;\n}\n// ---------------------------------------------------------------------------\n// BEGIN_SUMMATION\ntemplate <class Value>\nvoid tape_t<Value>::summation(void)\n// END_SUMMATION\n{  //\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // thread, initial_inuse\n   size_t thread        = thread_alloc::thread_num();\n   size_t initial_inuse = thread_alloc::inuse(thread);\n# endif\n   //\n   // op_arg\n   Vector<addr_t> op_arg;\n   //\n   // csum_map\n   // information for all the cumulative summation operations\n   std::map<addr_t, csum_info_t> csum_map;\n   //\n   // sum_op\n   auto sum_op = [] (op_enum_t op_enum)\n   {  bool result = false;\n      result     |= op_enum == neg_op_enum;\n      result     |= op_enum == add_op_enum;\n      result     |= op_enum == sub_op_enum;\n      return result;\n   };\n   //\n   // splice_list\n   auto splice_list = [] (std::list<addr_t>& des, std::list<addr_t>& src)\n   {  std::list<addr_t>::iterator itr_pos = des.end();\n      des.splice(itr_pos, src);\n      return;\n   };\n   //\n   // cat_list\n   auto cat_list = [] (std::list<addr_t>& des, std::list<addr_t>& src)\n   {  std::list<addr_t>::iterator itr_pos         = des.end();\n      std::list<addr_t>::const_iterator itr_begin = src.begin();\n      std::list<addr_t>::const_iterator itr_end   = src.end();\n      des.insert(itr_pos, itr_begin, itr_end);\n      return;\n   };\n   //\n   // set_op2arg_index\n   // This is necessary before calling replace_csum_op.\n   set_op2arg_index();\n   //\n   // val_use_case, vec_last_load\n   Vector<addr_t> val_use_case, vec_last_load;\n   rev_depend(val_use_case, vec_last_load);\n   //\n   // op_itr\n   op_iterator<Value> op_itr(*this, 0);\n   //\n   // i_op\n   for(addr_t i_op = 1; i_op < n_op(); ++i_op)\n   {  //\n      // op_itr\n      ++op_itr; // skip index zero\n      //\n      // op_ptr, arg_index, res_index\n      const base_op_t<Value>* op_ptr_i    = op_itr.op_ptr();\n      addr_t                  res_index_i = op_itr.res_index();\n      addr_t                  arg_index_i = op_itr.arg_index();\n      //\n      // op_enum_i, n_arg\n      op_enum_t op_enum_i  = op_ptr_i->op_enum();\n      addr_t    n_arg      = op_ptr_i->n_arg(arg_index_i, var_arg_);\n      //\n      // use_i, sum_i\n      bool sum_i   = sum_op( op_enum_i );\n      bool use_i   = false;\n      if( sum_i )\n      {\n# ifndef NDEBUG\n         addr_t n_res = op_ptr_i->n_res(arg_index_i, var_arg_);\n         CPPAD_ASSERT_UNKNOWN( n_res == 1 );\n# endif\n         use_i = 0 != val_use_case[res_index_i];\n      }\n      if( use_i & sum_i )\n      {  // i_op is one of neg, add, or sub\n         //\n         // op_arg\n         op_arg.resize(n_arg);\n         for(addr_t i = 0; i < n_arg; ++i)\n            op_arg[i] = var_arg_[arg_index_i + i];\n         //\n         // op_arg_equal_i\n         bool op_arg_equal_i = false;\n         if( op_ptr_i->is_binary() )\n            op_arg_equal_i = op_arg[0] == op_arg[1];\n         //\n         // is_csum_i, csum_map[i_op]\n         bool is_csum_i  = 0 < csum_map.count(i_op);\n         if( is_csum_i )\n         {  csum_info_t& csum_info_i = csum_map[i_op];\n            switch(op_enum_i)\n            {  //\n               default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               break;\n               //\n               case neg_op_enum:\n               CPPAD_ASSERT_UNKNOWN( csum_info_i.first_done );\n               break;\n               //\n               case add_op_enum:\n               if( ! csum_info_i.first_done )\n               {  CPPAD_ASSERT_UNKNOWN( ! op_arg_equal_i );\n                  csum_info_i.add_list.push_back(op_arg[0]);\n               }\n               if( ! csum_info_i.second_done )\n               {  CPPAD_ASSERT_UNKNOWN( ! op_arg_equal_i );\n                  csum_info_i.add_list.push_back(op_arg[1]);\n               }\n               break;\n               //\n               case sub_op_enum:\n               if( ! csum_info_i.first_done )\n               {  CPPAD_ASSERT_UNKNOWN( ! op_arg_equal_i );\n                  csum_info_i.add_list.push_back(op_arg[0]);\n               }\n               if( ! csum_info_i.second_done )\n               {  CPPAD_ASSERT_UNKNOWN( ! op_arg_equal_i );\n                  csum_info_i.sub_list.push_back(op_arg[1]);\n               }\n               break;\n            }\n            csum_info_i.first_done  = true;\n            csum_info_i.second_done = true;\n         }\n         //\n         if( val_use_case[res_index_i] == n_op() )\n         {  // i_op is a dependent variable or used more than once\n            //\n            if( is_csum_i )\n            {  replace_csum_op(res_index_i, i_op, csum_map[i_op]);\n               csum_map.erase( i_op );\n            }\n         }\n         else\n         {  //\n            // j_op\n            // i_op result is only used by the j_op operator\n            addr_t j_op = val_use_case[res_index_i];\n            //\n            // op_enum_j\n            op_enum_t op_enum_j = op_enum_t( op_enum_vec_[j_op] );\n            //\n            // sum_j\n            bool sum_j = sum_op( op_enum_j );\n            //\n            if( ! sum_j )\n            {  // The only use of i_op is not a summation operator\n               if( is_csum_i )\n               {  replace_csum_op(res_index_i, i_op,  csum_map[i_op]);\n                  csum_map.erase( i_op );\n               }\n            }\n            else\n            {  // The only use of i_op result is in a summation operator\n               //\n               // csum_map[i_op]\n               if( ! is_csum_i )\n               {  csum_info_t csum_info;\n                  switch(op_enum_i)\n                  {  //\n                     default:\n                     CPPAD_ASSERT_UNKNOWN(false);\n                     break;\n                     //\n                     // neg_op_enum\n                     case neg_op_enum:\n                     csum_info.sub_list.push_back(op_arg[0]);\n                     break;\n                     //\n                     // add_op_enum\n                     case add_op_enum:\n                     csum_info.add_list.push_back(op_arg[0]);\n                     csum_info.add_list.push_back(op_arg[1]);\n                     break;\n                     //\n                     // sub_op_enum\n                     // no use is adding and subtracting the same argument\n                     case sub_op_enum:\n                     if( ! op_arg_equal_i )\n                     {  csum_info.add_list.push_back(op_arg[0]);\n                        csum_info.sub_list.push_back(op_arg[1]);\n                     }\n                     break;\n                  }\n                  csum_map[i_op] = csum_info;\n               }\n               //\n               // csum_info_i\n               csum_info_t& csum_info_i = csum_map[i_op];\n               //\n               // second_operand\n               bool second_operand = false;\n               bool op_arg_equal_j = false;\n               if( (op_enum_j == add_op_enum) || (op_enum_j == sub_op_enum) )\n               {  addr_t          arg_index_j = op2arg_index_[j_op];\n                  addr_t          right_index = var_arg_[arg_index_j + 1];\n                  addr_t          left_index  = var_arg_[arg_index_j + 0];\n                  second_operand  = right_index == res_index_i;\n                  op_arg_equal_j  = right_index == left_index;\n                  CPPAD_ASSERT_UNKNOWN(\n                     left_index == res_index_i || right_index == res_index_i\n                  );\n               }\n               //\n               // is_csum_j\n               bool is_csum_j = 0 < csum_map.count(j_op);\n               //\n               // csum_map[j_op]\n               if( ! is_csum_j )\n                  csum_map[j_op] = csum_info_t();\n               csum_info_t& csum_info_j = csum_map[j_op];\n               switch( op_enum_j )\n               {  //\n                  default:\n                  CPPAD_ASSERT_UNKNOWN(false)\n                  break;\n                  //\n                  case neg_op_enum:\n                  splice_list(csum_info_j.add_list, csum_info_i.sub_list);\n                  splice_list(csum_info_j.sub_list, csum_info_i.add_list);\n                  break;\n                  //\n                  case add_op_enum:\n                  if( op_arg_equal_j )\n                  {  cat_list(csum_info_j.add_list, csum_info_i.add_list);\n                     cat_list(csum_info_j.sub_list, csum_info_i.sub_list);\n                  }\n                  splice_list(csum_info_j.add_list, csum_info_i.add_list);\n                  splice_list(csum_info_j.sub_list, csum_info_i.sub_list);\n                  break;\n                  //\n                  case sub_op_enum:\n                  if( second_operand )\n                  {  if( ! op_arg_equal_j )\n                     {  splice_list(csum_info_j.add_list, csum_info_i.sub_list);\n                        splice_list(csum_info_j.sub_list, csum_info_i.add_list);\n                     }\n                  }\n                  else if( op_arg_equal_j )\n                  {  cat_list(csum_info_j.add_list, csum_info_i.add_list);\n                     cat_list(csum_info_j.sub_list, csum_info_i.sub_list);\n                     splice_list(csum_info_j.add_list, csum_info_i.add_list);\n                     splice_list(csum_info_j.sub_list, csum_info_i.sub_list);\n                  }\n                  else\n                  {  splice_list(csum_info_j.add_list, csum_info_i.add_list);\n                     splice_list(csum_info_j.sub_list, csum_info_i.sub_list);\n                  }\n                  break;\n               }\n               if( op_arg_equal_j )\n               {  csum_info_j.first_done  = true;\n                  csum_info_j.second_done = true;\n               }\n               else if( second_operand )\n                  csum_info_j.second_done = true;\n               else\n                  csum_info_j.first_done = true;\n            }\n         }\n      }\n   }\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // inuse\n   size_t final_inuse = thread_alloc::inuse(thread);\n   std::cout << \"summation:  inuse = \" << final_inuse - initial_inuse << \"\\n\";\n# endif\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/tape.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_TAPE_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_TAPE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/val_graph/op_iterator.hpp>\n# include <cppad/local/val_graph/op_enum2class.hpp>\n# include <cppad/local/val_graph/val_type.hpp>\n# include <cppad/local/val_graph/op_iterator.hpp>\n\n# define CPPAD_VAL_GRAPH_TAPE_TRACE 0\n\nnamespace CppAD { namespace local { namespace val_graph {\n\n// csum_info_t: forward declare\nstruct csum_info_t;\n\n/*\n{xrst_begin val_tape dev}\n{xrst_spell\n   dep\n   str\n}\n\nThe Value Operator Tape\n#######################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_TAPE_T\n   // END_TAPE_T\n}\n\nPurpose\n*******\nThis class is used to define a function using a sequence of operators.\n\nValue\n*****\nThis is the type used for evaluations using the tape.\n\nop_ptr\n******\n{xrst_literal\n   // BEGIN_OP_PTR\n   // END_OP_PTR\n}\nThis is the :ref:`base_op <val_base_op-name>` corresponding to\n*op_index* in this tape.\n\nn_val\n*****\n{xrst_literal\n   // BEGIN_N_VAL\n   // END_N_VAL\n}\nThis is the number of elements in the value vector.\n\nn_op\n****\n{xrst_literal\n   // BEGIN_N_OP\n   // END_N_OP\n}\nThis is the number of operators in the tape.\n\nn_ind\n*****\n{xrst_literal\n   // BEGIN_N_IND\n   // END_N_IND\n}\nThis is the size of the independent vector.\n\narg_vec\n*******\n{xrst_literal\n   // BEGIN_ARG_VEC\n   // END_ARG_VEC\n}\nThe elements of this vector at non-negative integers that connect\nwith an operator to make an operator usage.\n\ncon_vec\n*******\n{xrst_literal\n   // BEGIN_CON_VEC\n   // END_CON_VEC\n}\nThis is the vector of value constants.\n\nstr_vec\n*******\n{xrst_literal\n   // BEGIN_STR_VEC\n   // END_STR_VEC\n}\nThis is the vector of string constants.\n\nvec_initial\n***********\n{xrst_literal\n   // BEGIN_VEC_INITIAL\n   // END_VEC_INITIAL\n}\nThis vector has length equal to the number of dynamic vectors.\nThis i-th element of this vector is the vector of initial indices\nfor the i-th dynamic vector; see :ref:`val_vec_op-name` .\n\nop_enum_vec\n***********\n{xrst_literal\n   // BEGIN_OP_ENUM_VEC\n   // END_OP_ENUM_VEC\n}\nEach element of this vector corresponds to an operator usage.\nThe order of the vector is the order of operations.\n\ndep_vec\n*******\n{xrst_literal\n   // BEGIN_DEP_VEC\n   // END_DEP_VEC\n}\nThis is the vector of dependent indices in the value vector.\nThe function corresponding to a tape maps the independent values\nto the dependent values.\n\nswap\n****\n{xrst_literal\n   // BEGIN_SWAP\n   // END_SWAP\n}\nThis swaps the contents of this tape with another tape.\n\neval\n****\n{xrst_literal\n   // BEGIN_EVAL\n   // END_EVAL\n}\nGiven the independent values, this routine execute the operators\nin order to evaluate the rest of the value vector and the compare_false\ncounter.\n\ntrace\n=====\nIf this is true, the :ref:`val_print_op-name` functions are used\nto print the operators.\n\nval_vec\n=======\nThis vector has size equal to *n_val*.\nThe first *n_ind* elements are inputs.\nThe rest of the elements are outputs.\n\ncompare_false\n=============\nThis argument is optional.\nIt is the number of :ref:`val_comp_op-name` that had a false\nresult for their comparisons.\nThis is both an input and output; i.e., each false comparison\nwill add one to this value.\n\nOperations on Tape\n******************\n{xrst_comment BEGIN_SORT_THIS_LINE_PLUS_2}\n{xrst_toc_table\n   include/cppad/local/val_graph/compress.hpp\n   include/cppad/local/val_graph/cumulative.hpp\n   include/cppad/local/val_graph/dead_code.hpp\n   include/cppad/local/val_graph/fold_con.hpp\n   include/cppad/local/val_graph/op2arg_index.hpp\n   include/cppad/local/val_graph/op_hash_table.hpp\n   include/cppad/local/val_graph/op_iterator.hpp\n   include/cppad/local/val_graph/option.hpp\n   include/cppad/local/val_graph/record.hpp\n   include/cppad/local/val_graph/record_new.hpp\n   include/cppad/local/val_graph/renumber.hpp\n   include/cppad/local/val_graph/rev_depend.hpp\n   include/cppad/local/val_graph/summation.hpp\n}\n{xrst_comment END_SORT_THIS_LINE_MINUS_2}\n\n\n{xrst_end val_tape}\n*/\n// BEGIN_TAPE_T\ntemplate <class Value> class tape_t {\n// END_TAPE_T\nprivate :\n   addr_t              n_ind_;       // number of independent values\n   addr_t              n_val_;       // total number of values\n   Vector<addr_t>      var_arg_;     // arguments for all operator uses\n   Vector<Value>       con_vec_;     // value constants\n   Vector<std::string> str_vec_;     // string constants\n   Vector<addr_t>      dep_vec_;     // dependent variable indices in val_vec\n   Vector<uint8_t>     op_enum_vec_; // one byte per operator enum value.\n   //\n   // vec_initial_\n   // initial indices for all the dynamic vectors\n   Vector< Vector<addr_t> > vec_initial_;\n   //\n   // op2arg_index_\n   // Optional vector that changes how op_iterator works; e.g.,\n   // this is necessary is we are using replace_csum_op with this tape.\n   Vector<addr_t> op2arg_index_;\n   //\n   // option_map_\n   std::map< std::string, std::string > option_map_;\n   //\n# if CPPAD_VAL_GRAPH_TAPE_TRACE\n   // set by set_ind, used by set_dep\n   size_t  set_ind_inuse_;\n# endif\n   //\npublic :\n   // default constructor\n   tape_t(void)\n   {  initialize_option(); }\n   //\n   // BEGIN_OP_PTR\n   const base_op_t<Value>* base_op_ptr(addr_t op_index) const\n   {  op_enum_t op_enum = op_enum_t( op_enum_vec_[op_index] );\n      return op_enum2class<Value>(op_enum);\n   }\n   // END_OP_PTR\n   // ------------------------------------------------------------------------\n   // BEGIN_N_VAL\n   addr_t n_val(void) const\n   {  return n_val_; }\n   // END_N_VAL\n   //\n   // BEGIN_N_OP\n   addr_t n_op(void) const\n   {  return addr_t( op_enum_vec_.size() ); }\n   // END_N_OP\n   //\n   // BEGIN_N_IND\n   addr_t n_ind(void) const\n   {  return n_ind_; }\n   // END_N_IND\n   //\n   // BEGIN_ARG_VEC\n   const Vector<addr_t>& arg_vec(void) const\n   {  return var_arg_; }\n   // END_ARG_VEC\n   //\n   // BEGIN_CON_VEC\n   const Vector<Value>& con_vec(void) const\n   {  return con_vec_; }\n   // END_CON_VEC\n   //\n   // BEGIN_STR_VEC\n   const Vector<std::string>& str_vec(void) const\n   {  return str_vec_; }\n   // END_STR_VEC\n   //\n   // BEGIN_VEC_INITIAL\n   const Vector< Vector<addr_t> >& vec_initial(void) const\n   {  return vec_initial_; }\n   // END_VEC_INITIAL\n   //\n   // BEGIN_OP_ENUM_VEC\n   const Vector<uint8_t>& op_enum_vec(void) const\n   {  return op_enum_vec_; }\n   // END_OP_ENUM_VEC\n   //\n   // BEGIN_DEP_VEC\n   const Vector<addr_t>& dep_vec(void) const\n   {  return dep_vec_; }\n   // END_DEP_VEC\n   // ------------------------------------------------------------------------\n   // BEGIN_SWAP\n   void swap(tape_t& other)\n   // END_SWAP\n   {  // same order as declaration of member variables just below private:\n      std::swap( n_ind_, other.n_ind_ );\n      std::swap( n_val_, other.n_val_);\n      var_arg_.swap( other.var_arg_ );\n      con_vec_.swap( other.con_vec_ );\n      str_vec_.swap( other.str_vec_ );\n      dep_vec_.swap( other.dep_vec_ );\n      op_enum_vec_.swap( other.op_enum_vec_ );\n      vec_initial_.swap( other.vec_initial_ );\n      op2arg_index_.swap( other.op2arg_index_ );\n      option_map_.swap( other.option_map_ );\n   }\n   // eval(trace, val_vec)\n   void eval(\n      bool           trace         ,\n      Vector<Value>& val_vec       ) const\n   {  size_t                  compare_false = 0;\n      eval(trace, val_vec, compare_false);\n   }\n   // BEGIN_EVAL\n   // eval(trace, val_vec, compare_false)\n   void eval(\n      bool                      trace         ,\n      Vector<Value>&            val_vec       ,\n      size_t&                   compare_false ) const\n   // END_EVAL\n   {  CPPAD_ASSERT_KNOWN(\n         val_vec.size() == size_t(n_val_),\n         \"eval: size of val_vec not equal to tape.n_val()\"\n      );\n      using std::setw;\n      using std::right;\n      using std::cout;\n      //\n      // ind_vec_vec\n      // Only the vector_op routines use this eval argument\n      Vector< Vector<addr_t> > ind_vec_vec;\n      //\n      // trace\n      if( trace )\n      {  // no operators for independent variables\n         std::cout << \"independent vector\\n\";\n         for(addr_t res_index = 0; res_index < n_ind_; ++res_index)\n         {  Value res = val_vec[res_index];\n            cout << right << setw(5) << res_index;\n            cout << \" \" << right << setw(10) << res << \"\\n\";\n         }\n         std::printf(\"operators\\n\");\n      }\n      //\n      // op_itr, i_op\n      op_iterator<Value> op_itr(*this, 0);\n      for(addr_t i_op = 0; i_op < n_op(); ++i_op)\n      {  //\n         // op_ptr, arg_index, res_index\n         const base_op_t<Value>* op_ptr     = op_itr.op_ptr();\n         addr_t                  arg_index  = op_itr.arg_index();\n         addr_t                  res_index  = op_itr.res_index();\n         //\n         // base_op_t<Value>::eval\n         op_ptr->eval(\n            this,\n            trace,\n            arg_index,\n            res_index,\n            val_vec,\n            ind_vec_vec,\n            compare_false\n         );\n         //\n         // op_itr\n         ++op_itr;\n      }\n      // trace\n      if( trace )\n      {  // no operators for dependent variables\n         std::cout << \"dependent vector\\n\";\n         for(size_t i = 0; i < dep_vec_.size(); ++i)\n         {  addr_t res_index = dep_vec_[i];\n            Value res        = val_vec[res_index];\n            cout << right << setw(5) << res_index;\n            cout << \" \" << right << setw(10) << res << \"\\n\";\n         }\n         // space after end of this tape\n         std::printf(\"\\n\");\n      }\n      return;\n   }\n   // ------------------------------------------------------------------------\n   // functions in record.hpp\n   // ------------------------------------------------------------------------\n   //\n   // set_ind\n   addr_t set_ind(addr_t n_ind);\n   //\n   // record_op\n   addr_t record_op(op_enum_t op_enum, const Vector<addr_t>& op_arg);\n   //\n   // record_con_op\n   addr_t record_con_op(const Value& constant);\n   //\n   // record_dis_op\n   addr_t record_dis_op(addr_t discrete_index, addr_t op_arg);\n   //\n   // record_comp_op\n   addr_t record_comp_op(\n      compare_enum_t compare_enum ,\n      addr_t         left_index   ,\n      addr_t         right_index\n   );\n   //\n   // record_call_op\n   addr_t record_call_op(\n      addr_t atomic_index           ,\n      addr_t call_id                ,\n      addr_t n_res                  ,\n      const Vector<addr_t>& fun_arg\n   );\n   //\n   // record_csum_op\n   addr_t record_csum_op(\n      const Vector<addr_t>& add,\n      const Vector<addr_t>& sub\n   );\n   //\n   // record_cexp_op\n   addr_t record_cexp_op(\n      compare_enum_t compare_enum ,\n      addr_t         left         ,\n      addr_t         right        ,\n      addr_t         if_true      ,\n      addr_t         if_false\n   );\n   //\n   // record_pri_op\n   addr_t record_pri_op(\n      const std::string& before      ,\n      const std::string& after       ,\n      addr_t             flag_index  ,\n      addr_t             value_index\n   );\n   //\n   // record_vec_op\n   addr_t record_vec_op(const Vector<addr_t>& initial);\n   //\n   // record_load_op\n   addr_t record_load_op(\n      addr_t   which_vector  ,\n      addr_t   vector_index\n   );\n   //\n   // record_store_op\n   addr_t record_store_op(\n      addr_t   which_vector  ,\n      addr_t   vector_index  ,\n      addr_t   value_index\n   );\n   //\n   // set_dep\n   void set_dep(const Vector<addr_t>& dep_vec);\n   // ------------------------------------------------------------------------\n   // functions in their own files\n   // ------------------------------------------------------------------------\n   //\n   // fold_con\n   void fold_con(void);\n   //\n   // renumber\n   void renumber(void);\n   //\n   // rev_depend\n   void rev_depend(\n      Vector<addr_t>& val_use_case  ,\n      Vector<addr_t>& vec_last_load\n   );\n   //\n   // dead_code\n   vectorBool dead_code(void);\n   //\n   // compress\n   vectorBool compress(void);\n   //\n   // record_new\n   addr_t record_new(\n      tape_t&                   new_tape         ,\n      Vector<addr_t>&           new_which_vec    ,\n      Vector<addr_t>&           work             ,\n      const Vector<addr_t>&     new_val_index    ,\n      const Vector<addr_t>&     val_use_case     ,\n      const base_op_t<Value>*   op_ptr           ,\n      addr_t                    arg_index        ,\n      addr_t                    res_index\n   );\n   //\n   // ------------------------------------------------------------------------\n   // functions in summation.hpp\n   // ------------------------------------------------------------------------\n   //\n   // summation\n   void summation(void);\n   //\n   // set_op2arg_index\n   void set_op2arg_index();\n   //\n   // op2arg_index\n   const Vector<addr_t>& op2arg_index(void) const;\n   //\n   // replace_csum_op\n   void replace_csum_op(\n      addr_t       res_index ,\n      addr_t       i_op      ,\n      csum_info_t& csum_info\n   );\n   // -----------------------------------------------------------------------\n   // functions in cumulative.hpp\n   // -----------------------------------------------------------------------\n   //\n   // op2csum\n   void op2csum(addr_t op_index);\n   //\n   // ------------------------------------------------------------------------\n   // functions in option.hpp\n   // ------------------------------------------------------------------------\n   //\n   // initialize_option\n   void initialize_option(void);\n   //\n   // set_option\n   void set_option(const std::string& name, const std::string& value);\n};\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n// BEGIN_SORT_THIS_LINE_PLUS_1\n# include <cppad/local/val_graph/compress.hpp>\n# include <cppad/local/val_graph/cumulative.hpp>\n# include <cppad/local/val_graph/dead_code.hpp>\n# include <cppad/local/val_graph/fold_con.hpp>\n# include <cppad/local/val_graph/op2arg_index.hpp>\n# include <cppad/local/val_graph/op_hash_table.hpp>\n# include <cppad/local/val_graph/option.hpp>\n# include <cppad/local/val_graph/record.hpp>\n# include <cppad/local/val_graph/record_new.hpp>\n# include <cppad/local/val_graph/renumber.hpp>\n# include <cppad/local/val_graph/summation.hpp>\n// END_SORT_THIS_LINE_MINUS_1\n\n# undef CPPAD_VAL_GRAPH_TAPE_TRACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/unary_op.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_UNARY_OP_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_UNARY_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/val_graph/base_op.hpp>\n# include <cppad/local/val_graph/print_op.hpp>\n\n# define CPPAD_VAL_GRAPH_UNARY(Name, Op) \\\n   template <class Value> \\\n   class Name##_op_t : public unary_op_t<Value> { \\\n   public: \\\n      /* get_instance */ \\\n      static Name##_op_t* get_instance(void) \\\n      {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; \\\n         static Name##_op_t instance; \\\n         return &instance; \\\n      } \\\n      /* op_enum */ \\\n      op_enum_t op_enum(void) const override \\\n      {  return Name##_op_enum; \\\n      } \\\n      /* eval */ \\\n      void eval( \\\n         const tape_t<Value>*      tape          , \\\n         bool                      trace         , \\\n         addr_t                    arg_index     , \\\n         addr_t                    res_index     , \\\n         Vector<Value>&            val_vec       , \\\n         Vector< Vector<addr_t> >& ind_vec_vec   , \\\n         size_t&                   compare_false ) const override \\\n      {  const Vector<addr_t>& arg_vec( tape->arg_vec() ); \\\n         const Value& value  = val_vec[ arg_vec[arg_index + 0] ]; \\\n         val_vec[res_index]  = Op ( value ); \\\n         if( trace ) this->print_op( \\\n            #Name , arg_index, arg_vec, res_index, val_vec \\\n         ); \\\n      } \\\n   }\n\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n------------------------------------------------------------------------------\n{xrst_begin_parent val_unary_op dev}\n\nUnary Value Operators\n#####################\n\n{xrst_end val_unary_op}\n------------------------------------------------------------------------------\n{xrst_begin val_unary_base_op dev}\n\nThe Unary Value Operator Base Class\n###################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_UNARY_OP_T\n   // END_UNARY_OP_T\n}\n\nPurpose\n*******\nThe class is derived from :ref:`base_op <val_base_op-name>`.\nIt overrides the\n*is_unary*, *n_before*, *n_after*, *n_arg*, *n_res_*, and *print_op*\nmember functions.\nThe *op_enum* and *eval* member functions are still pure virtual.\n\nis_unary\n********\nThis override of :ref:`val_base_op@is_unary` returns true.\n\nn_before\n********\nThis override of :ref:`val_base_op@n_before` returns 0.\n\nn_after\n*******\nThis override of :ref:`val_base_op@n_after` returns 0.\n\nn_arg\n*****\nThis override of :ref:`val_base_op@n_arg` returns 1.\n\nn_res\n*****\nThis override of :ref:`val_base_op@n_res` returns 1.\n\nprint_op\n********\n{xrst_literal\n   // BEGIN_PRINT_OP\n   // END_PRINT_OP\n}\nThis member function uses :ref:`val_print_op-name` to print unary operators.\n\n{xrst_end val_unary_base_op}\n*/\n\n// BEGIN_UNARY_OP_T\ntemplate <class Value>\nclass unary_op_t : public base_op_t<Value> {\n// END_UNARY_OP_T\npublic:\n   // n_before\n   addr_t n_before(void) const override\n   {  return 0; }\n   //\n   // n_after\n   addr_t n_after(void) const override\n   {  return 0; }\n   //\n   // is_unary\n   bool is_unary(void) const override\n   {  return true; }\n   //\n   // n_arg\n   addr_t n_arg(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 1; }\n   //\n   // n_res\n   addr_t n_res(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 1; }\n   //\n   // op_enum\n   virtual op_enum_t op_enum(void) const override = 0;\n   //\n   // eval\n   virtual void eval(\n      const tape_t<Value>*      tape          ,\n      bool                      trace         ,\n      addr_t                    arg_index     ,\n      addr_t                    res_index     ,\n      Vector<Value>&            val_vec       ,\n      Vector< Vector<addr_t> >& ind_vec_vec   ,\n      size_t&                   compare_false ) const override = 0;\n   //\n   // BEGIN_PRINT_OP\n   void print_op(\n      const char*           name         ,\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ,\n      addr_t                res_index    ,\n      Vector<Value>&        val_vec      ) const\n   // END_PRINT_OP\n   {  //\n      Vector<addr_t> arg_val_index  = { arg_vec[ arg_index + 0 ] };\n      Vector<Value>  res_value      = { val_vec[res_index] };\n      CppAD::local::val_graph::print_op(\n         name, arg_val_index, res_index, res_value\n      );\n   }\n};\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_unary_op_derived dev}\n{xrst_spell\n   neg\n}\n\nThe Unary Value Operator Derived Classes\n########################################\n\nPrototype\n*********\n| |tab| ``template <class Value>``\n| |tab| ``class`` *Name*\\ ``_opt_t : public unary_op_t<Value>``\n\n*Name*\n******\nUnary operators are defined for the following names:\n\n.. csv-table:: Unary Operators\n   :widths: auto\n   :header-rows: 1\n\n   Name,description\n   neg,result is negative of operand\n\nContext\n*******\nThis class is derived from :ref:`val_unary_op-name` .\nIt overrides the *op_enum* and *eval* member functions\nand is a concrete class (it has no pure virtual functions).\n\nget_instance\n************\nThis static member function returns a pointer to a\n*Name*\\ ``_op_t`` object.\n\nop_enum\n*******\nThis override of :ref:`val_base_op@op_enum` returns\n*Name*\\ ``_op_enum`` .\n\neval\n****\nThis override of :ref:`val_base_op@eval` sets\nthe result equal to the unary operator applied to the operand; see\n:ref:`val_base_op@arg_vec@Unary Operators` .\n\n\n{xrst_toc_hidden\n   val_graph/unary_xam.cpp\n}\nExample\n*******\nThe file :ref:`unary_xam.cpp <val_unary_xam.cpp-name>`\nis an example and test that uses a unary operator.\n\n{xrst_end val_unary_op_derived}\n*/\n// BEGIN_SORT_THIS_LINE_PLUS_1\nCPPAD_VAL_GRAPH_UNARY(abs,   fabs);\nCPPAD_VAL_GRAPH_UNARY(acos,  acos);\nCPPAD_VAL_GRAPH_UNARY(acosh, acosh);\nCPPAD_VAL_GRAPH_UNARY(asin,  asin);\nCPPAD_VAL_GRAPH_UNARY(asinh, asinh);\nCPPAD_VAL_GRAPH_UNARY(atan,  atan);\nCPPAD_VAL_GRAPH_UNARY(atanh, atanh);\nCPPAD_VAL_GRAPH_UNARY(cos,   cos);\nCPPAD_VAL_GRAPH_UNARY(cosh,  cosh);\nCPPAD_VAL_GRAPH_UNARY(erf,   erf);\nCPPAD_VAL_GRAPH_UNARY(erfc,  erfc);\nCPPAD_VAL_GRAPH_UNARY(exp,   exp);\nCPPAD_VAL_GRAPH_UNARY(expm1, expm1);\nCPPAD_VAL_GRAPH_UNARY(log,   log);\nCPPAD_VAL_GRAPH_UNARY(log1p, log1p);\nCPPAD_VAL_GRAPH_UNARY(neg,   -);\nCPPAD_VAL_GRAPH_UNARY(sign,  sign);\nCPPAD_VAL_GRAPH_UNARY(sin,   sin);\nCPPAD_VAL_GRAPH_UNARY(sinh,  sinh);\nCPPAD_VAL_GRAPH_UNARY(sqrt,  sqrt);\nCPPAD_VAL_GRAPH_UNARY(tan,   tan);\nCPPAD_VAL_GRAPH_UNARY(tanh,  tanh);\n// END_SORT_THIS_LINE_MINUS_1\n\n// ---------------------------------------------------------------------------\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# undef CPPAD_VAL_GRAPH_UNARY\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/val2fun.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_VAL2FUN_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_VAL2FUN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// --------------------------------------------------------------------------\n/*\n{xrst_begin val2fun_graph dev}\n{xrst_spell\n   dyn\n}\n\nCreate an ADFun Object Corresponding to a Value Graph\n#####################################################\n\nSyntax\n******\n| |tab| ``ADFun`` < *Base* > *fun*\n| |tab| *fun* . ``val2fun`` ( *val_tape* , *dyn_ind* , *var_ind* )\n| |tab| *fun* . ``val2fun`` ( *val_tape* , *dyn_ind* , *var_ind* , *use_val* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nBase\n****\nis the type corresponding to this :ref:`adfun-name` object;\ni.e., its calculations are done using the type *Base* .\nIt is also :ref:`val_tape@Value` type for the tape.\n\nRecBase\n*******\nin the prototype above, *RecBase* is the same type as *Base* .\n\nval_tape\n********\nThis is a :ref:`val_tape-name` representation of the function.\n\n*dyn_ind*\n*********\nThe *i*-th element of the vector is the index in the value graph\nof the *i*-th independent dynamic parameter in *fun* .\n\n*var_ind*\n*********\nThe *i*-th element of the vector is the index in *val_tape*\nof the *i*-th independent variable in *fun* .\nNo two elements of *dyn_ind* or *var_ind* can have the same value.\nFurthermore, the total number of elements in these two vectors\nmust be the number of independent variables in *val_tape* .\n\nuse_val\n*******\nIf this vector is present extra detection is done to convert\nvariables to parameters.\nIt has size equal to *val_tape*\\ .n_val().\nFor each value index, that is a result for a\n:ref:`val_call_op-name`, the corresponding *use_val*\\ [i] is true (false)\nif the result is used to compute one of the dependent variables.\n\n*fun*\n*****\nThe input contents of *fun* do not matter.\nUpon return it is an ADFun representation of the function.\n\nUnder Construction\n******************\nThis routine is under construction and is only implemented\nfor a few of the possible :ref:`ADFun-name` operators.\n\n{xrst_toc_hidden\n   val_graph/val2fun_xam.cpp\n}\nExamples\n********\nThe file :ref:`val_val2fun_xam.cpp-name`\nis an example an test of this conversion.\n\n{xrst_end val2fun_graph}\n*/\n\n# include <cppad/core/ad_fun.hpp>\n# include <cppad/local/op_code_dyn.hpp>\n# include <cppad/local/val_graph/tape.hpp>\n# include <cppad/local/val_graph/op_iterator.hpp>\n# include <cppad/local/val_graph/call_atomic.hpp>\n# include <cppad/local/pod_vector.hpp>\n# include <cppad/core/cppad_assert.hpp>\n\n# define CPPAD_VAL2FUN_DYN_UNARY(name)                  \\\n   case local::val_graph::name##_op_enum:               \\\n   tmp_addr = rec.put_dyn_par(                          \\\n      nan, local::name##_dyn, fun_arg[0]                \\\n   );                                                   \\\n   break;\n\n# define CPPAD_VAL2FUN_DYN_BINARY(name)                 \\\n   case local::val_graph::name##_op_enum:               \\\n   tmp_addr = rec.put_dyn_par(                          \\\n      nan, local::name##_dyn, fun_arg[0], fun_arg[1]    \\\n   );                                                   \\\n   break;\n\n# define CPPAD_VAL2FUN_VAR_UNARY(name, Op)              \\\n   case local::val_graph::name##_op_enum:               \\\n   tmp_addr = rec.PutOp(local::Op);                     \\\n   rec.PutArg( fun_arg[0] );                            \\\n   break;\n\n# define CPPAD_VAL2FUN_VAR_BINARY(name, Op)             \\\n   case local::val_graph::name##_op_enum:               \\\n   tmp_addr = rec.PutOp(local::Op);                     \\\n   break;\n\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\ntemplate <class Base, class RecBase>\nvoid ADFun<Base, RecBase>::val2fun(\n   const local::val_graph::tape_t<Base>&                   val_tape  ,\n   const CppAD::local::val_graph::Vector<size_t>&          dyn_ind   ,\n   const CppAD::local::val_graph::Vector<size_t>&          var_ind   )\n{  vectorBool use_val;\n   val2fun(val_tape, dyn_ind, var_ind, use_val);\n}\n\n// BEGIN_PROTOTYPE\ntemplate <class Base, class RecBase>\nvoid ADFun<Base, RecBase>::val2fun(\n   const local::val_graph::tape_t<Base>&                   val_tape  ,\n   const CppAD::local::val_graph::Vector<size_t>&          dyn_ind   ,\n   const CppAD::local::val_graph::Vector<size_t>&          var_ind   ,\n   const CppAD::vectorBool&                                use_val   )\n// END_PROTOTYPE\n{  //\n   // vector\n   using CppAD::local::val_graph::Vector;\n   //\n   // base_op_t, op_enum_t, compare_enum_t\n   using local::val_graph::base_op_t;\n   using local::val_graph::op_enum_t;\n   using local::val_graph::compare_enum_t;\n   //\n   // val_arg_vec, val_con_vec, val_str_vec, val_dep_vec\n   const Vector<addr_t>&      val_arg_vec = val_tape.arg_vec();\n   const Vector<Base>&        val_con_vec = val_tape.con_vec();\n   const Vector<std::string>& val_str_vec = val_tape.str_vec();\n   const Vector<addr_t>&      val_dep_vec = val_tape.dep_vec();\n   //\n   // nan\n   Base nan = CppAD::numeric_limits<Base>::quiet_NaN();\n   //\n   // par_addr\n   // a temporary parameter index\n   addr_t par_addr;\n   //\n   // var_addr\n   // a temporary variable index\n   addr_t var_addr;\n   //\n   // tmp_addr\n   // a parameter or variable temporary index\n   // initialize to zero to avoid compiler warnings\n   addr_t tmp_addr = 0;\n   //\n# ifndef NDEBUG\n   // val_n_ind\n   // size of the independent value vector\n   size_t val_n_ind = size_t( val_tape.n_ind() );\n# endif\n   //\n   // dyn_n_ind\n   // number of independent dynamic parameters\n   size_t dyn_n_ind = dyn_ind.size();\n   //\n   // var_n_ind\n   // number of independent variables\n   size_t var_n_ind = var_ind.size();\n   //\n   // val_n_op\n   addr_t val_n_op = val_tape.n_op();\n   //\n   CPPAD_ASSERT_KNOWN( dyn_n_ind + var_n_ind == val_n_ind,\n      \"val2fun: The number of independent variables and dynamic parameters\\n\"\n      \"is not equal to the size of the independent value vector\"\n   );\n   //\n   // n_val\n   addr_t n_val = val_tape.n_val();\n   //\n   // fun_ad_type\n   Vector<ad_type_enum> fun_ad_type(n_val);\n   for(addr_t i = 0; i < n_val; ++i)\n      fun_ad_type[i] = number_ad_type_enum; // invalid\n   //\n   // val_index2con\n   // After fold_con, all the constants that get used are op_con results.\n   Vector<Base> val_index2con(n_val);\n   for(addr_t i = 0; i < n_val; ++i)\n      val_index2con[i] = nan;\n   bool trace           = false;\n   val_tape.eval(trace, val_index2con);\n   //\n   // val2fun_index\n   // mapping from value index to index in the AD function object.\n   // The meaning of this index depends on its ad_type.\n   Vector<addr_t> val2fun_index(n_val);\n   for(addr_t i = 0; i < n_val; ++i)\n      val2fun_index[i] = std::numeric_limits<addr_t>::max(); // invalid\n   //\n   // rec\n   // start a function recording\n   local::recorder<Base> rec;\n   CPPAD_ASSERT_UNKNOWN( rec.num_var_op() == 0 );\n   rec.set_n_dyn_independent(dyn_n_ind);\n   rec.set_abort_op_index(0);\n   rec.set_record_compare(false);\n   //\n   // parameter\n# ifndef NDEBUG\n   const local::pod_vector_maybe<Base>& parameter( rec.par_all());\n   CPPAD_ASSERT_UNKNOWN( parameter.size() == 0 );\n# endif\n   //\n   // rec\n   // initialize with the value nan at index nan\n   par_addr = rec.put_con_par(nan);\n   CPPAD_ASSERT_UNKNOWN( par_addr == 0 );\n   CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[par_addr] ) );\n   //\n   // rec\n   // Place the variable with index 0 in the tape\n   CPPAD_ASSERT_UNKNOWN( NumArg(local::BeginOp) == 1);\n   CPPAD_ASSERT_UNKNOWN( NumRes(local::BeginOp) == 1);\n   rec.PutOp(local::BeginOp);\n   rec.PutArg(0); // parameter argument is the nan above\n   //\n   // rec, vecad_offset\n   // place the VecAD objects in the recording\n   Vector<addr_t> vecad_offset;\n   addr_t         offset = 1;\n   for(size_t i = 0; i < val_tape.vec_initial().size(); ++i)\n   {  const Vector<addr_t>& val_initial = val_tape.vec_initial()[i];\n      size_t size = val_initial.size();\n      local::pod_vector<addr_t>  fun_initial(size);\n      for(size_t j = 0; j < size; ++j)\n      {  addr_t val_index  = val_initial[j];\n         const Base& value = val_index2con[val_index];\n         CPPAD_ASSERT_KNOWN( ! CppAD::isnan(value),\n            \"val2fun: an initial value for a dynamic array is not constant\"\n         );\n         fun_initial[j] =  rec.put_con_par( value );\n      }\n      rec.put_var_vecad(size, fun_initial);\n      vecad_offset.push_back( offset );\n      offset += addr_t(size + 1);\n   }\n   //\n   // rec, fun_ad_type, val2fun_index\n   // put the independent dynamic parameters in the function recording\n   for(size_t i = 0; i < dyn_n_ind; ++i)\n   {  CPPAD_ASSERT_KNOWN( dyn_ind[i] < val_n_ind,\n         \"val2fun: number of independent values is <= dyn_ind[i]\"\n      );\n      CPPAD_ASSERT_KNOWN( fun_ad_type[ dyn_ind[i] ] == number_ad_type_enum,\n         \"val2fun: dep_ind[i] == dep_ind[j] for some i and j\"\n      );\n      fun_ad_type[ dyn_ind[i] ]  = dynamic_enum;\n      par_addr                    = rec.put_dyn_par(nan, local::ind_dyn);\n      val2fun_index[ dyn_ind[i] ] = par_addr;\n      CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[par_addr] ) );\n   }\n   // put the independent variables in the function recording\n   for(size_t i = 0; i < var_n_ind; ++i)\n   {  CPPAD_ASSERT_KNOWN( var_ind[i] < val_n_ind,\n         \"val2fun: number of independent values is <= var_ind[i]\"\n      );\n      CPPAD_ASSERT_KNOWN( fun_ad_type[ var_ind[i] ] == number_ad_type_enum,\n         \"val2fun: var_ind[i] == dep_ind[j] for some i and j\\n\"\n         \"or var_ind[i] == var_ind[j] for some i and j\"\n      );\n      fun_ad_type[ var_ind[i] ]   = variable_enum;\n      var_addr                    = rec.PutOp( local::InvOp );\n      val2fun_index[ var_ind[i] ] = var_addr;\n   }\n   //\n   // ind_taddr_\n   // address of the independent variables on variable tape\n   ind_taddr_.resize(var_n_ind);\n   for(size_t i = 0; i < var_n_ind; ++i)\n      ind_taddr_[i] = i + 1;\n   //\n   // rec_con_index\n   // First constant in CppAD recording and val_graph is nan\n   Vector<addr_t> rec_con_index( val_con_vec.size() );\n   CPPAD_ASSERT_UNKNOWN( CppAD::isnan( val_con_vec[0] ) );\n   rec_con_index[0] = 0;\n   for(size_t i = 1; i < val_con_vec.size(); ++i)\n      rec_con_index[i] = rec.put_con_par( val_con_vec[i] );\n   //\n   // zero_index\n   addr_t zero_index = rec.put_con_par( Base(0.0) );\n   //\n   // two_sqrt_pi_index: 2 / sqrt(pi)\n   addr_t two_sqrt_pi_index = rec.put_con_par(\n      Base(1.0) / sqrt( atan( Base(1.0) ) )\n   );\n   //\n   // rec_str_index\n   Vector<addr_t> rec_str_index( val_str_vec.size() );\n   for(size_t i = 0; i < val_str_vec.size(); ++i)\n   {  const std::string& str = val_str_vec[i];\n      rec_str_index[i]       = rec.PutTxt( str.c_str() );\n   }\n   //\n   // ad_type_x, ad_type_y, fun_arg, csum_arg, select_y\n   Vector<addr_t>       fun_arg, csum_arg;\n   Vector<bool>         select_y;\n   Vector< AD<Base> >   ax, ay;\n   //\n   // con_x, at_type_x, ad_type_y;\n   // Use CppAD::vector because call_atomic_for_type requires it\n   CppAD::vector<Base>  con_x;\n   CppAD::vector<ad_type_enum> ad_type_x, ad_type_y;\n   //\n   // op_itr\n   local::val_graph::op_iterator<Base> op_itr(val_tape, 0);\n   //\n   // i_op\n   for(addr_t i_op = 0; i_op < val_n_op; ++i_op)\n   {  //\n      // op_itr\n      if( 0 < i_op )\n         ++op_itr;\n      //\n      // op_ptr, arg_index, res_index\n      const base_op_t<Base>* op_ptr    = op_itr.op_ptr();\n      addr_t                 arg_index = op_itr.arg_index();\n      addr_t                 res_index = op_itr.res_index();\n      //\n      // op_enum, is_unary, is_binary, n_arg\n      op_enum_t        op_enum   = op_ptr->op_enum();\n      bool             is_unary  = op_ptr->is_unary();\n      bool             is_binary = op_ptr->is_binary();\n      addr_t           n_before  = op_ptr->n_before();\n      addr_t           n_after   = op_ptr->n_after();\n      addr_t           n_arg     = op_ptr->n_arg(arg_index, val_arg_vec);\n      CPPAD_ASSERT_UNKNOWN( n_before + n_after <= n_arg );\n      //\n      // n_x\n      addr_t n_x = n_arg - n_before - n_after;\n      //\n      // ad_type_x, fun_arg, con_x, max_ad_type\n      ad_type_x.resize(n_x);\n      fun_arg.resize(n_x);\n      con_x.resize(n_x);\n      ad_type_enum max_ad_type = constant_enum;\n      for(addr_t i = 0; i < n_x; ++i)\n      {  addr_t val_index     = val_arg_vec[arg_index + n_before + i];\n         ad_type_x[i] = fun_ad_type[val_index];\n         fun_arg[i]   = val2fun_index[val_index];\n         con_x[i]     = val_index2con[val_index];\n         max_ad_type  = std::max(max_ad_type, ad_type_x[i] );\n      }\n      /*\n      CPPAD_ASSERT_KNOWN(\n         n_x == 0 || constant_enum < max_ad_type,\n         \"val2fun: must first call fold_con\"\n      );\n      */\n      //\n      // rec, fun_ad_type, val2fun_index\n      if( is_unary )\n      {  //\n         fun_ad_type[res_index] = max_ad_type;\n         CPPAD_ASSERT_UNKNOWN( n_arg == 1 );\n         //\n         // rec, val2fun_index\n         if( max_ad_type == dynamic_enum )\n         {  switch( op_enum )\n            {  //\n               // default\n               default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               tmp_addr = 0; // to avoid compiler warning\n               break;\n               //\n               // BEGIN_SORT_THIS_LINE_PLUS_1\n               CPPAD_VAL2FUN_DYN_UNARY(abs);\n               CPPAD_VAL2FUN_DYN_UNARY(acos);\n               CPPAD_VAL2FUN_DYN_UNARY(acosh);\n               CPPAD_VAL2FUN_DYN_UNARY(asin);\n               CPPAD_VAL2FUN_DYN_UNARY(asinh);\n               CPPAD_VAL2FUN_DYN_UNARY(atan);\n               CPPAD_VAL2FUN_DYN_UNARY(atanh);\n               CPPAD_VAL2FUN_DYN_UNARY(cos);\n               CPPAD_VAL2FUN_DYN_UNARY(cosh);\n               CPPAD_VAL2FUN_DYN_UNARY(erf);\n               CPPAD_VAL2FUN_DYN_UNARY(erfc);\n               CPPAD_VAL2FUN_DYN_UNARY(exp);\n               CPPAD_VAL2FUN_DYN_UNARY(expm1);\n               CPPAD_VAL2FUN_DYN_UNARY(log);\n               CPPAD_VAL2FUN_DYN_UNARY(log1p);\n               CPPAD_VAL2FUN_DYN_UNARY(neg);\n               CPPAD_VAL2FUN_DYN_UNARY(sign);\n               CPPAD_VAL2FUN_DYN_UNARY(sin);\n               CPPAD_VAL2FUN_DYN_UNARY(sinh);\n               CPPAD_VAL2FUN_DYN_UNARY(sqrt);\n               CPPAD_VAL2FUN_DYN_UNARY(tan);\n               // END_SORT_THIS_LINE_MINUS_1\n            }\n         }\n         else\n         {  switch( op_enum )\n            {\n               // default\n               default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               tmp_addr = 0; // to avoid compiler warning\n               break;\n               //\n               // BEGIN_SORT_THIS_LINE_PLUS_1\n               CPPAD_VAL2FUN_VAR_UNARY(abs,     AbsOp);\n               CPPAD_VAL2FUN_VAR_UNARY(acos,    AcosOp);\n               CPPAD_VAL2FUN_VAR_UNARY(acosh,   AcoshOp);\n               CPPAD_VAL2FUN_VAR_UNARY(asin,    AsinOp);\n               CPPAD_VAL2FUN_VAR_UNARY(asinh,   AsinhOp);\n               CPPAD_VAL2FUN_VAR_UNARY(atan,    AtanOp);\n               CPPAD_VAL2FUN_VAR_UNARY(atanh,   AtanhOp);\n               CPPAD_VAL2FUN_VAR_UNARY(cos,     CosOp);\n               CPPAD_VAL2FUN_VAR_UNARY(cosh,    CoshOp);\n               CPPAD_VAL2FUN_VAR_UNARY(exp,     ExpOp);\n               CPPAD_VAL2FUN_VAR_UNARY(expm1,   Expm1Op);\n               CPPAD_VAL2FUN_VAR_UNARY(log,     LogOp);\n               CPPAD_VAL2FUN_VAR_UNARY(log1p,   Log1pOp);\n               CPPAD_VAL2FUN_VAR_UNARY(neg,     NegOp);\n               CPPAD_VAL2FUN_VAR_UNARY(sign,    SignOp);\n               CPPAD_VAL2FUN_VAR_UNARY(sin,     SinOp);\n               CPPAD_VAL2FUN_VAR_UNARY(sinh,    SinhOp);\n               CPPAD_VAL2FUN_VAR_UNARY(sqrt,    SqrtOp);\n               CPPAD_VAL2FUN_VAR_UNARY(tan,     TanOp);\n               CPPAD_VAL2FUN_VAR_UNARY(tanh,    TanhOp);\n               // END_SORT_THIS_LINE_MINUS_1\n               //\n               // erf\n               case local::val_graph::erf_op_enum:\n               {  tmp_addr = rec.PutOp(local::ErfOp);\n                  CPPAD_ASSERT_UNKNOWN( NumArg(local::ErfOp) == 3 );\n                  rec.PutArg( fun_arg[0] );\n                  rec.PutArg( zero_index );\n                  rec.PutArg( two_sqrt_pi_index );\n               }\n               break;\n               //\n               // erfc\n               case local::val_graph::erfc_op_enum:\n               {  tmp_addr = rec.PutOp(local::ErfcOp);\n                  CPPAD_ASSERT_UNKNOWN( NumArg(local::ErfcOp) == 3 );\n                  rec.PutArg( fun_arg[0] );\n                  rec.PutArg( zero_index );\n                  rec.PutArg( two_sqrt_pi_index );\n               }\n               break;\n            }\n         }\n         val2fun_index[res_index] = tmp_addr;\n      }\n      else if( is_binary )\n      {  //\n         fun_ad_type[res_index] = max_ad_type;\n         CPPAD_ASSERT_UNKNOWN( n_arg == 2 );\n         //\n         if( max_ad_type == dynamic_enum )\n         {  switch(op_enum)\n            {  default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               break;\n               //\n               CPPAD_VAL2FUN_DYN_BINARY(add);\n               CPPAD_VAL2FUN_DYN_BINARY(sub);\n               CPPAD_VAL2FUN_DYN_BINARY(mul);\n               CPPAD_VAL2FUN_DYN_BINARY(div);\n               CPPAD_VAL2FUN_DYN_BINARY(pow);\n            }\n            CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[tmp_addr] ) );\n         }\n         else if(\n            ad_type_x[0] == variable_enum &&\n            ad_type_x[1] == variable_enum )\n         {  switch(op_enum)\n            {  default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               break;\n               //\n               CPPAD_VAL2FUN_VAR_BINARY(add, AddvvOp);\n               CPPAD_VAL2FUN_VAR_BINARY(sub, SubvvOp);\n               CPPAD_VAL2FUN_VAR_BINARY(mul, MulvvOp);\n               CPPAD_VAL2FUN_VAR_BINARY(div, DivvvOp);\n               CPPAD_VAL2FUN_VAR_BINARY(pow, PowvvOp);\n            }\n            rec.PutArg(fun_arg[0], fun_arg[1]);\n         }\n         else if( ad_type_x[1] == variable_enum )\n         {  switch(op_enum)\n            {  default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               break;\n               //\n               CPPAD_VAL2FUN_VAR_BINARY(add, AddpvOp);\n               CPPAD_VAL2FUN_VAR_BINARY(sub, SubpvOp);\n               CPPAD_VAL2FUN_VAR_BINARY(mul, MulpvOp);\n               CPPAD_VAL2FUN_VAR_BINARY(div, DivpvOp);\n               CPPAD_VAL2FUN_VAR_BINARY(pow, PowpvOp);\n            }\n            rec.PutArg(fun_arg[0], fun_arg[1]);\n         }\n         else\n         {  CPPAD_ASSERT_UNKNOWN( ad_type_x[0] == variable_enum );\n            switch(op_enum)\n            {  default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               break;\n               //\n               // add\n               case local::val_graph::add_op_enum:\n               tmp_addr = rec.PutOp(local::AddpvOp);\n               std::swap(fun_arg[0], fun_arg[1]);\n               break;\n               //\n               // mul\n               case local::val_graph::mul_op_enum:\n               tmp_addr = rec.PutOp(local::MulpvOp);\n               std::swap(fun_arg[0], fun_arg[1]);\n               break;\n               //\n               CPPAD_VAL2FUN_VAR_BINARY(sub, SubvpOp);\n               CPPAD_VAL2FUN_VAR_BINARY(div, DivvpOp);\n               CPPAD_VAL2FUN_VAR_BINARY(pow, PowvpOp);\n            }\n            rec.PutArg(fun_arg[0], fun_arg[1]);\n         }\n         val2fun_index[res_index] = tmp_addr;\n      }\n      else switch( op_enum )\n      {  // ! ( is_unary || is_binary)\n         //\n         // default\n         default:\n         CPPAD_ASSERT_KNOWN( op_enum > local::val_graph::number_op_enum,\n            \"val_graph::val2fun: op_enum is not yet implemented\"\n         );\n         // ------------------------------------------------------------------\n         // dis_op\n         // rec, fun_ad_type, val2fun_index\n         case local::val_graph::dis_op_enum:\n         fun_arg.resize(1);\n         CPPAD_ASSERT_UNKNOWN( n_arg = 2 );\n         {  addr_t dynamic_index  = val_arg_vec[arg_index + 0];\n            if( max_ad_type == dynamic_enum )\n            {  tmp_addr = rec.put_dyn_par(\n                  nan, local::dis_dyn, dynamic_index, fun_arg[0]\n               );\n            }\n            else\n            {  CPPAD_ASSERT_UNKNOWN( max_ad_type == variable_enum );\n               tmp_addr = rec.PutOp(local::DisOp);\n               rec.PutArg( dynamic_index );\n               rec.PutArg( fun_arg[0] );\n            }\n            fun_ad_type[res_index]   = max_ad_type;\n            val2fun_index[res_index] = tmp_addr;\n         }\n         break;\n         // ------------------------------------------------------------------\n         // con_op\n         // rec, fun_ad_type, val2fun_index\n         case local::val_graph::con_op_enum:\n         CPPAD_ASSERT_UNKNOWN( n_arg = 1 );\n         {  par_addr                 = rec_con_index[ val_arg_vec[arg_index] ];\n            fun_ad_type[res_index]   = constant_enum;\n            val2fun_index[res_index] = par_addr;\n# ifndef NDEBUG\n            const Base& constant = val_con_vec[ val_arg_vec[arg_index] ];\n            CPPAD_ASSERT_UNKNOWN(\n               CppAD::isnan(constant) || parameter[par_addr] == constant\n            );\n# endif\n         }\n         break;\n         // -------------------------------------------------------------------\n         // pri_op: rec\n         case local::val_graph::pri_op_enum:\n         {  //\n            // before, after, flag, value\n            addr_t before = rec_str_index[ val_arg_vec[arg_index + 0] ];\n            addr_t after  = rec_str_index[ val_arg_vec[arg_index + 1] ];\n            addr_t flag   = fun_arg[0];\n            addr_t value  = fun_arg[1];\n            //\n            // is_var\n            // base 2 representation of [ is_var(flag), is_var(value) ]\n            addr_t is_var = 0;\n            if( fun_ad_type[flag] == variable_enum )\n               is_var += 1;\n            if( fun_ad_type[value] == variable_enum )\n               is_var += 2;\n            //\n            // rec\n            rec.PutOp(local::PriOp);\n            rec.PutArg(is_var, flag, before, value, after);\n         }\n         break;\n         // -------------------------------------------------------------------\n         // cexp_op\n         case local::val_graph::cexp_op_enum:\n         {  //\n            // compare, compare_enum, cop\n            addr_t         compare       = val_arg_vec[arg_index + 0];\n            compare_enum_t compare_enum = compare_enum_t( compare );\n            CompareOp      cop;\n            if( compare_enum == local::val_graph::compare_eq_enum )\n               cop = CompareEq;\n            else if( compare_enum == local::val_graph::compare_le_enum )\n               cop = CompareLe;\n            else\n            {  CPPAD_ASSERT_UNKNOWN(\n                  compare_enum == local::val_graph::compare_lt_enum\n               );\n               cop = CompareLt;\n            }\n            if( max_ad_type == dynamic_enum )\n            {  tmp_addr = rec.put_dyn_cond_exp(\n                  nan, cop, fun_arg[0], fun_arg[1], fun_arg[2], fun_arg[3]\n               );\n            }\n            else\n            {  addr_t flag = 0;\n               addr_t bit  = 1;\n               for(size_t j = 0; j < 4; ++j)\n               {  if( ad_type_x[j] == variable_enum )\n                     flag |= bit;\n                  bit = 2 * bit;\n               }\n               CPPAD_ASSERT_UNKNOWN( flag != 0 );\n               rec.PutArg(\n                  cop, flag, fun_arg[0], fun_arg[1], fun_arg[2], fun_arg[3]\n               );\n               tmp_addr = rec.PutOp(local::CExpOp);\n            }\n            fun_ad_type[res_index]   = max_ad_type;\n            val2fun_index[res_index] = tmp_addr;\n         }\n         break;\n         // -------------------------------------------------------------------\n         // comp_op\n         // rec\n         case local::val_graph::comp_op_enum:\n         {  //\n            // compare\n            addr_t compare  = val_arg_vec[arg_index + 0];\n            //\n            // var_left, var_right, dyn_left, dyn_right\n            bool var_left  = ad_type_x[0] == variable_enum;\n            bool var_right = ad_type_x[1] == variable_enum;\n            bool dyn_left  = ad_type_x[0] == dynamic_enum;\n            bool dyn_right = ad_type_x[1] == dynamic_enum;\n            //\n            // ax\n            ax.resize(2);\n            //\n            if( var_left | dyn_left )\n               ax[0].taddr_ = fun_arg[0];\n            else\n               ax[0].value_ = con_x[0];\n            //\n            if( var_right | dyn_right )\n               ax[1].taddr_ = fun_arg[1];\n            else\n               ax[1].value_ = con_x[1];\n            //\n            // res, compare_enum\n            compare_enum_t compare_enum = compare_enum_t( compare );\n            bool res;\n            switch(compare_enum)\n            {  //\n               default:\n               CPPAD_ASSERT_UNKNOWN(false);\n               break;\n               //\n               case local::val_graph::compare_eq_enum:\n               res = true;\n               rec.comp_eq(\n                  var_left, var_right, dyn_left, dyn_right, ax[0], ax[1], res\n               );\n               break;\n               //\n               case local::val_graph::compare_le_enum:\n               res = true;\n               rec.comp_le(\n                  var_left, var_right, dyn_left, dyn_right, ax[0], ax[1], res\n               );\n               break;\n               //\n               case local::val_graph::compare_lt_enum:\n               res = true;\n               rec.comp_lt(\n                  var_left, var_right, dyn_left, dyn_right, ax[0], ax[1], res\n               );\n               break;\n               //\n               case local::val_graph::compare_ne_enum:\n               res = false;\n               rec.comp_eq(\n                  var_left, var_right, dyn_left, dyn_right, ax[0], ax[1], res\n               );\n               break;\n               //\n               case local::val_graph::compare_no_enum:\n               break;\n            }\n         }\n         break;\n         // -------------------------------------------------------------------\n         // csum_op\n         // rec, fun_ad_type, val2fun_index\n         case local::val_graph::csum_op_enum:\n         if( dynamic_enum <= max_ad_type )\n         {  //\n            // n_add, n_sub, n_arg\n            addr_t n_add =  val_arg_vec[arg_index + 0];\n            addr_t n_sub =  val_arg_vec[arg_index + 1];\n            CPPAD_ASSERT_UNKNOWN( n_arg == 3 + n_add + n_sub );\n            //\n            // sum_constant\n            Base sum_constant = Base(0.0);\n            for(addr_t i = 0; i < n_add; ++i)\n            {  if( ad_type_x[i] <= constant_enum )\n                  sum_constant += con_x[i];\n            }\n            for(addr_t i = 0; i < n_sub; ++i)\n            {  if( ad_type_x[n_add + i] <= constant_enum )\n                  sum_constant -= con_x[n_add + i];\n            }\n            // rec, sum_constant_addr\n            addr_t sum_constant_addr = rec.put_con_par(sum_constant);\n            CPPAD_ASSERT_UNKNOWN(parameter[sum_constant_addr] == sum_constant);\n            //\n            if( max_ad_type == dynamic_enum )\n            {  tmp_addr = sum_constant_addr;\n               for(addr_t i = 0; i < n_x; ++i)\n               {  tmp_addr = rec.put_dyn_par(\n                     nan, local::add_dyn, tmp_addr, fun_arg[i]\n                  );\n                  CPPAD_ASSERT_UNKNOWN( CppAD::isnan( parameter[tmp_addr] ) );\n               }\n            }\n            else if( max_ad_type == variable_enum )\n            {  //\n               // n_add_var, n_add_dyn\n               addr_t n_add_dyn = 0;\n               addr_t n_add_var = 0;\n               for(addr_t i = 0; i < n_add; ++i)\n               {  if( ad_type_x[i] == dynamic_enum )\n                     ++n_add_dyn;\n                  if( ad_type_x[i] == variable_enum )\n                     ++n_add_var;\n               }\n               //\n               // n_add_var, n_add_dyn\n               addr_t n_sub_dyn = 0;\n               addr_t n_sub_var = 0;\n               for(addr_t i = 0; i < n_sub; ++i)\n               {  if( ad_type_x[n_add + i] == dynamic_enum )\n                     ++n_sub_dyn;\n                  if( ad_type_x[n_add + i] == variable_enum )\n                     ++n_sub_var;\n               }\n               //\n               // csum_arg\n               addr_t n_tot = 6 + n_add_var + n_sub_var + n_add_dyn + n_sub_dyn;\n               csum_arg.resize(n_tot);\n               csum_arg[0] = sum_constant_addr;\n               csum_arg[1] = 5 + n_add_var;\n               csum_arg[2] = csum_arg[1] + n_sub_var;\n               csum_arg[3] = csum_arg[2] + n_add_dyn;\n               csum_arg[4] = csum_arg[3] + n_sub_dyn;\n               //\n               addr_t i_variable = 5;\n               addr_t i_dynamic  = i_variable + n_add_var + n_sub_var;\n               for(addr_t i = 0; i < n_add; ++i)\n               {  if( ad_type_x[i] == dynamic_enum )\n                     csum_arg[i_dynamic++]  = fun_arg[i];\n                  if( ad_type_x[i] == variable_enum )\n                     csum_arg[i_variable++] = fun_arg[i];\n               }\n               for(addr_t i = 0; i < n_sub; ++i)\n               {  if( ad_type_x[n_add + i] == dynamic_enum )\n                     csum_arg[i_dynamic++]  = fun_arg[n_add + i];\n                  if( ad_type_x[n_add + i] == variable_enum )\n                     csum_arg[i_variable++] = fun_arg[n_add + i];\n               }\n               CPPAD_ASSERT_UNKNOWN( i_dynamic == n_tot - 1 );\n               csum_arg[n_tot - 1] = n_tot;\n               //\n               // rec, tmp_addr\n               tmp_addr = rec.PutOp(local::CSumOp);\n               for(addr_t i = 0; i < n_tot; ++i)\n                  rec.PutArg( csum_arg[i] );\n               CPPAD_ASSERT_UNKNOWN( local::NumRes(local::CSumOp) == 1 );\n            }\n            fun_ad_type[res_index]   = max_ad_type;\n            val2fun_index[res_index] = tmp_addr;\n         }\n         break;\n         // -------------------------------------------------------------------\n         // vec_op\n         case local::val_graph::vec_op_enum:\n         // All the VecAD objects have already been initialized\n         break;\n         //\n         // load_op\n         case local::val_graph::load_op_enum:\n         {  addr_t which_vector  = val_arg_vec[arg_index + 0];\n            offset               = vecad_offset[which_vector];\n            addr_t load_op_index = addr_t( rec.num_var_load() );\n            rec.PutArg(offset, fun_arg[0], load_op_index);\n            if( ad_type_x[0] < variable_enum )\n               var_addr = rec.PutLoadOp(local::LdpOp);\n            else\n               var_addr = rec.PutLoadOp(local::LdvOp);\n            //\n            // The result of a load function is always a variable\n            fun_ad_type[res_index]   = variable_enum;\n            val2fun_index[res_index] = var_addr;\n         }\n         break;\n         //\n         // store_op\n         case local::val_graph::store_op_enum:\n         {  addr_t which_vector = val_arg_vec[arg_index + 0];\n            offset              = vecad_offset[which_vector];\n            rec.PutArg(offset, fun_arg[0], fun_arg[1] );\n            if( ad_type_x[0] < variable_enum )\n            {  if( ad_type_x[1] < variable_enum )\n                  rec.PutOp(local::StppOp);\n               else\n                  rec.PutOp(local::StpvOp);\n            }\n            else\n            {  if( ad_type_x[1] < variable_enum )\n                  rec.PutOp(local::StvpOp);\n               else\n                  rec.PutOp(local::StvvOp);\n            }\n         }\n         break;\n         //\n         // -------------------------------------------------------------------\n         // call_op\n         // rec, fun_ad_type, val2fun_index\n         case local::val_graph::call_op_enum:\n         {  //\n            // atomic_index, call_id\n            addr_t n_res        =  val_arg_vec[arg_index + 1];\n            size_t atomic_index = size_t( val_arg_vec[arg_index + 2] );\n            size_t call_id      = size_t( val_arg_vec[arg_index + 3] );\n            //\n            // ad_type_y\n            ad_type_y.resize(n_res);\n            local::val_graph::call_atomic_for_type<Base>(\n               con_x, ad_type_x, ad_type_y, atomic_index, call_id\n            );\n            //\n            // record_dynamic, record_variable\n            bool record_dynamic  = false;\n            bool record_variable = false;\n            for(addr_t i = 0; i < n_res; ++i)\n            {  CPPAD_ASSERT_UNKNOWN( ad_type_y[i] <= variable_enum );\n               record_dynamic  |= ad_type_y[i] == dynamic_enum;\n               record_variable |= ad_type_y[i] == variable_enum;\n            }\n            // tape_id\n            // tape_id is zero because not a true recording\n            tape_id_t tape_id = 0;\n            //\n            // ax, ay\n            if( record_dynamic || record_variable )\n            {  //\n               // ax\n               ax.resize(n_x);\n               for(addr_t j = 0; j < n_x; ++j)\n               {  addr_t val_index = val_arg_vec[arg_index + n_before + j];\n                  ax[j].taddr_   = val2fun_index[val_index];\n                  ax[j].value_   = val_index2con[val_index];\n               }\n               // ay, ad_type_y\n               ay.resize(n_res);\n               for(addr_t j = 0; j < n_res; ++j)\n               {  ay[j].taddr_     = 0; // not used\n                  ay[j].value_     = val_index2con[res_index + j];\n                  if( use_val.size() != 0 )\n                  {  if( ! use_val[res_index + j] )\n                     {  ay[j].value_  = nan;\n                        if( ad_type_y[j] == variable_enum )\n                           ad_type_y[j] = constant_enum;\n                     }\n                  }\n               }\n            }\n            if( record_dynamic ) rec.put_dyn_atomic(\n               tape_id, atomic_index, call_id, ad_type_x, ad_type_y, ax, ay\n            );\n            if( record_variable ) rec.put_var_atomic(\n               tape_id, atomic_index, call_id, ad_type_x, ad_type_y, ax, ay\n            );\n            //\n            // val2fun_index, fun_ad_type\n            for(addr_t i = 0; i < n_res; ++i)\n            {  val2fun_index[res_index + i] = ay[i].taddr_;\n               fun_ad_type[res_index + i]   = ad_type_y[i];\n            }\n         }\n         break;\n      }\n   }\n   // dep_taddr_, dep_parameter, rec\n   // dep_taddr_ is address of the dependent variables on variable tape\n   dep_taddr_.resize( val_dep_vec.size() );\n   dep_parameter_.resize( val_dep_vec.size() );\n   for(size_t i = 0; i < val_dep_vec.size(); ++i)\n   {  addr_t val_index     = val_dep_vec[i];\n      ad_type_enum ad_type = fun_ad_type[val_index];\n      addr_t fun_index     = val2fun_index[val_index];\n      dep_parameter_[i]    = ad_type < variable_enum;\n      if( dep_parameter_[i] )\n      {  // see RecordParOp(const AD<Base>& y)\n         rec.PutArg( fun_index );\n         fun_index = rec.PutOp(local::ParOp);\n      }\n      dep_taddr_[i] = size_t( fun_index );\n   }\n   // rec\n   rec.PutOp(local::EndOp);\n   //\n   //\n   // ----------------------------------------------------------------------\n   // End recording, set private member data except for\n   // ----------------------------------------------------------------------\n   //\n   // bool values in this object except check_for_nan_\n   has_been_optimized_        = false;\n   //\n   // size_t values in this object\n   compare_change_count_      = 1;\n   compare_change_number_     = 0;\n   compare_change_op_index_   = 0;\n   num_order_taylor_          = 0;\n   cap_order_taylor_          = 0;\n   num_direction_taylor_      = 0;\n   num_var_tape_              = rec.num_var();\n   //\n   // taylor_\n   taylor_.resize(0);\n   //\n   // cskip_op_\n   cskip_op_.resize( rec.num_var_op() );\n   //\n   // load_op2var_\n   load_op2var_.resize( rec.num_var_load() );\n   //\n   // play_\n   // Now that each dependent variable has a place in the recording,\n   // and there is a EndOp at the end of the record, we can transfer the\n   // recording to the player and and erase the recording.\n   play_.get_recording(rec, var_n_ind);\n   //\n   // ind_taddr_\n   // Note that play_ has been set, we can use it to check operators\n   CPPAD_ASSERT_UNKNOWN( var_n_ind < num_var_tape_);\n   for(size_t j = 0; j < var_n_ind; j++)\n   {  CPPAD_ASSERT_UNKNOWN( play_.GetOp(j+1) == local::InvOp );\n      CPPAD_ASSERT_UNKNOWN( ind_taddr_[j] = j+1 );\n   }\n   //\n   // for_jac_sparse_pack_, for_jac_sparse_set_\n   for_jac_sparse_pack_.resize(0, 0);\n   for_jac_sparse_set_.resize(0,0);\n   //\n   // resize subgraph_info_\n   subgraph_info_.resize(\n      ind_taddr_.size(),   // n_dep\n      dep_taddr_.size(),   // n_ind\n      play_.num_var_op(),  // n_op\n      play_.num_var()      // n_var\n   );\n   //\n   // set the function name\n   function_name_ = \"\";\n   //\n   //\n   return;\n}\n\n# undef CPPAD_VAL2FUN_DYN_UNARY\n# undef CPPAD_VAL2FUN_DYN_BINARY\n# undef CPPAD_VAL2FUN_VAR_UNARY\n# undef CPPAD_VAL2FUN_VAR_BINARY\n\n} // END_CPPAD_NAMESPACE\n// --------------------------------------------------------------------------\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/val_optimize.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_VAL_OPTIMIZE_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_VAL_OPTIMIZE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-23 Bradley M. Bell\n// --------------------------------------------------------------------------\n/*\n------------------------------------------------------------------------------\n{xrst_begin val_optimize dev}\n\n\nOptimize the Value Graph Corresponding to This Function\n#######################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_VAL_OPTIMIZE\n   // END_VAL_OPTIMIZE\n}\n\noptions\n=======\nSee :ref:`optimize@options` .\n\n{xrst_end val_optimize}\n*/\n\n# include <cppad/core/ad_fun.hpp>\n# include <cppad/local/val_graph/tape.hpp>\n# include <cppad/local/optimize/extract_option.hpp>\n\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n// BEGIN_VAL_OPTIMIZE\ntemplate <class Base, class RecBase>\nvoid ADFun<Base, RecBase>::val_optimize(const std::string& options)\n// END_VAL_OPTIMIZE\n{  //\n   // compare_op, cumulative_sum_op, print_for_op,\n   local::optimize::options_t result = local::optimize::extract_option(options);\n   bool compare_op          = result.compare_op;\n   bool cumulative_sum_op   = result.cumulative_sum_op;\n   bool print_for_op        = result.print_for_op;\n   //\n   CPPAD_ASSERT_UNKNOWN( result.val_graph == true );\n   CPPAD_ASSERT_KNOWN( result.conditional_skip == false,\n      \"optimize options: \"\n      \"val_graph is present and no_conditional_skip is not present\"\n   );\n   // n_dyn_ind, n_var_ind\n   size_t n_dyn_ind = size_dyn_ind();\n   size_t n_var_ind = Domain();\n   //\n   // dyn_ind, var_ind\n   using CppAD::local::val_graph::Vector;\n   Vector<size_t> dyn_ind(n_dyn_ind), var_ind(n_var_ind);\n   for(size_t j = 0; j < n_dyn_ind; ++j)\n      dyn_ind[j] = j;\n   for(size_t j = 0; j < n_var_ind; ++j)\n      var_ind[j] = n_dyn_ind + j;\n   //\n   // val_tape\n   // value operator representation corresponding to this function\n   local::val_graph::tape_t<Base> val_tape;\n   fun2val(val_tape);\n   //\n   //\n   // this\n   // free all the memory associated with this function\n   {  ADFun<Base> g;\n      swap(g);\n   }\n   /*\n   Vector<Base> val_vec( val_tape.n_val() );\n   for(addr_t i = 0; i < val_tape.n_ind(); ++i)\n      val_vec[i] = Base(i + 1);\n   bool   trace = true;\n   val_tape.eval(trace, val_vec);\n   */\n   // val_tape: renumber\n   val_tape.renumber();\n   //\n   // val_tape: fold_con();\n   //\n   // val_tape: summation\n   if( cumulative_sum_op )\n      val_tape.summation();\n   //\n   // val_tape: dead_code, val_use\n   if( compare_op )\n      val_tape.set_option(\"keep_compare\", \"true\");\n   else\n      val_tape.set_option(\"keep_compare\", \"false\");\n   if( print_for_op )\n      val_tape.set_option(\"keep_print\", \"true\");\n   else\n      val_tape.set_option(\"keep_print\", \"false\");\n   vectorBool use_val = val_tape.dead_code();\n   /*\n   val_vec.resize( val_tape.n_val() );\n   val_tape.eval(trace, val_vec);\n   */\n   // this\n   // convert optimized value graph to fun\n   val2fun(val_tape, dyn_ind, var_ind, use_val);\n   //\n   // no collision limit in value graph representation.\n   return;\n}\n\n} // END_CPPAD_NAMESPACE\n// --------------------------------------------------------------------------\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/val_type.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_VAL_TYPE_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_VAL_TYPE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-24 Bradley M. Bell\n// -------------------------------------------------------------\n# include <vector>\n# include <cassert>\n# include <cstddef>\n# include <cppad/utility/vector.hpp>\n# include <cppad/configure.hpp>\n\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin val_graph_type dev}\n{xrst_spell\n   typedef\n}\n\nValue Operator Type Definitions\n###############################\n\naddr_t\n******\nThis type is used to store vectors of non-negative integers.\nIt must be able to support an index equal to the length of the arg_vec vector.\nA signed type can be used for testing, but an unsigned type will support\nmore indices with the same memory usage.\n{xrst_code hpp} */\ntypedef CPPAD_TAPE_ADDR_TYPE addr_t;\n/* {xrst_code}\n\nVector\n******\nThis is a :ref:`SimpleVector-name` template class.\nIn addition, these vectors have the following member functions\n``push_back`` , ``clear`` .\nThese member functions have he same specifications as for std::vector.\nThe std::vector and CppAD::vector are two example template vector\nclasses that can be used.\n{xrst_code hpp} */\ntemplate <class Value> using Vector = CppAD::vector<Value>;\n/* {xrst_code}\n\nop_enum_t\n*********\nA concrete class does not have any pure virtual functions.\nThis enum type is used to identify the concrete operator class types.\n{xrst_spell_off}\n{xrst_comment BEGIN_SORT_THIS_LINE_PLUS_3}\n{xrst_code hpp}*/\nenum op_enum_t {\n   abs_op_enum,      // absolute value\n   acos_op_enum,     // inverse cosine\n   acosh_op_enum,    // inverse hyperbolic cosine\n   add_op_enum,      // addition\n   asin_op_enum,     // inverse sine\n   asinh_op_enum,    // inverse hyperbolic sine\n   atan_op_enum,     // inverse tangent\n   atanh_op_enum,    // inverse hyperbolic tangent\n   call_op_enum,     // atomic functions\n   cexp_op_enum,     // conditional expression\n   comp_op_enum,     // comparison\n   con_op_enum,      // constants\n   cos_op_enum,      // cosine\n   cosh_op_enum,     // hyperbolic cosine\n   csum_op_enum,     // cumulative summation\n   dis_op_enum,      // discrete functions\n   div_op_enum,      // division\n   erf_op_enum,      // error function\n   erfc_op_enum,     // complementary error function\n   exp_op_enum,      // exponential function\n   expm1_op_enum,    // exponential function minus one\n   load_op_enum,     // load an element from a dynamic vector\n   log1p_op_enum,    // one plust natural log\n   log_op_enum,      // natural log function\n   mul_op_enum,      // multiplication\n   neg_op_enum,      // negative\n   pow_op_enum,      // power function\n   pri_op_enum,      // print\n   sign_op_enum,     // sign function (1, 0, -1)\n   sin_op_enum,      // sine function\n   sinh_op_enum,     // hyperbolic sine\n   sqrt_op_enum,     // square root\n   store_op_enum,    // store an element in a dynamic vector\n   sub_op_enum,      // subtraction\n   tan_op_enum,      // tangent\n   tanh_op_enum,     // hyperbolic tangent\n   vec_op_enum,      // create a new dynamic vector\n   number_op_enum\n};\n/* {xrst_code}\n{xrst_comment END_SORT_THIS_LINE_MINUS_4}\n{xrst_spell_on}\nThe ``number_op_enum`` entry is used for the number of concrete\noperator class types (and does not correspond to an operator).\n\ncompare_op_enum_t\n*****************\nThis enum type is used to identify which comparison a :ref:`val_comp_op-name`\ndoes.\n{xrst_code hpp}*/\nenum compare_enum_t {\n   compare_eq_enum,    // equal\n   compare_ne_enum,    // not equal\n   compare_lt_enum,    // less than\n   compare_le_enum,    // less than or equal\n   compare_no_enum,    // no comparison (used during optimization)\n   number_compare_enum\n};\n/*{xrst_code}\n{xrst_end val_graph_type}\n*/\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/var_type.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_VAR_TYPE_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_VAR_TYPE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n-------------------------------------------------------------------------------\n{xrst_begin type_var_op dev}\n\nTypes of Variable Operators\n###########################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_TYPE_VAR_OP\n   // END_TYPE_VAR_OP\n}\n\nvar_op\n******\nis the variable operator.\n\nis_unary\n********\nIf the return value for is_unary is true,\nthis operator has one operand, one result, and is recorded by\nspecifying the operator and variable address of the operand on the tape.\n\nis_binary\n*********\nIf the return value for is_binary is true,\nthis operator has two operands, one result, and is recorded by\nspecifying the operator and variable or parameter address for each operand.\n\nis_compare\n**********\nIf the return value for is_compare is true, this is a compare operator.\nIt has two operands, no result, and is recorded by\nspecifying the operator and variable or parameter address for each operand.\n\n{xrst_end type_var_op}\n*/\nnamespace CppAD { namespace local { namespace val_graph {\n\n// BEGIN_TYPE_VAR_OP\ninline void type_var_op(\n   op_code_var var_op     ,\n   bool& is_unary    ,\n   bool& is_binary   ,\n   bool& is_compare  )\n// END_TYPE_VAR_OP\n{  //\n   switch(var_op)\n   {  //\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n      break;\n      // BEGIN_SORT_THIS_LINE_PLUS_1\n      case AFunOp:\n      case BeginOp:\n      case CExpOp:\n      case CSumOp:\n      case DisOp:\n      case EndOp:\n      case FunapOp:\n      case FunavOp:\n      case FunrpOp:\n      case FunrvOp:\n      case InvOp:\n      case LdpOp:\n      case LdvOp:\n      case ParOp:\n      case PriOp:\n      case StppOp:\n      case StpvOp:\n      case StvpOp:\n      case StvvOp:\n      // END_SORT_THIS_LINE_MINUS_1\n      is_unary   = false;\n      is_binary  = false;\n      is_compare = false;\n      break;\n      //\n      // unary operators\n      // BEGIN_SORT_THIS_LINE_PLUS_1\n      case AbsOp:\n      case AcosOp:\n      case AcoshOp:\n      case AsinOp:\n      case AsinhOp:\n      case AtanOp:\n      case AtanhOp:\n      case CosOp:\n      case CoshOp:\n      case ErfOp:\n      case ErfcOp:\n      case ExpOp:\n      case Expm1Op:\n      case Log1pOp:\n      case LogOp:\n      case NegOp:\n      case SignOp:\n      case SinOp:\n      case SinhOp:\n      case SqrtOp:\n      case TanOp:\n      case TanhOp:\n      // END_SORT_THIS_LINE_MINUS_1\n      is_unary   = true;\n      is_binary  = false;\n      is_compare = false;\n      break;\n      //\n      // binary operators\n      // BEGIN_SORT_THIS_LINE_PLUS_1\n      case AddpvOp:\n      case AddvvOp:\n      case DivpvOp:\n      case DivvpOp:\n      case DivvvOp:\n      case MulpvOp:\n      case MulvvOp:\n      case PowpvOp:\n      case PowvpOp:\n      case PowvvOp:\n      case SubpvOp:\n      case SubvpOp:\n      case SubvvOp:\n      case ZmulpvOp:\n      case ZmulvpOp:\n      case ZmulvvOp:\n      // END_SORT_THIS_LINE_MINUS_1\n      is_unary   = false;\n      is_binary  = true;\n      is_compare = false;\n      break;\n      //\n      // compare operators\n      // BEGIN_SORT_THIS_LINE_PLUS_1\n      case local::EqppOp:\n      case local::EqpvOp:\n      case local::EqvvOp:\n      case local::LeppOp:\n      case local::LepvOp:\n      case local::LevpOp:\n      case local::LevvOp:\n      case local::LtppOp:\n      case local::LtpvOp:\n      case local::LtvpOp:\n      case local::LtvvOp:\n      case local::NeppOp:\n      case local::NepvOp:\n      case local::NevvOp:\n      // END_SORT_THIS_LINE_MINUS_1\n      is_unary   = false;\n      is_binary  = false;\n      is_compare = true;\n      break;\n   }\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/val_graph/vector_op.hpp",
    "content": "# ifndef  CPPAD_LOCAL_VAL_GRAPH_VECTOR_OP_HPP\n# define  CPPAD_LOCAL_VAL_GRAPH_VECTOR_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2023-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/local/val_graph/base_op.hpp>\n# include <cppad/local/val_graph/print_op.hpp>\n\n// define CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { namespace local { namespace val_graph {\n/*\n{xrst_begin_parent val_vector_op dev}\n\nThe Dynamic Vector Value Operators\n##################################\nThese classes implement dynamic vectors; i.e., vector were\nthe indices may depend on the independent values.\n\nind_vec_vec\n***********\nThe size of this vector is equal to the number of dynamic vectors.\nThe size of each element of this vector is equal to the size of the\ncorresponding dynamic vector plus one.\nIt is a vector of value indices mapping dynamic vector indices to the\nindex in the value vector for the current value of the dynamic vector.\nThe last element for each dynamic vector is a flag.\nIf it is nan, an index value for a store operation was nan.\nIn this case, all the subsequent load operation results (for that vector)\nwill be nan.\nIn addition, if the index for a load operation is nan,\nthe corresponding result will be nan.\n\n{xrst_toc_hidden\n   val_graph/vec_xam.cpp\n}\nOperators\n*********\nOnly the following operators use the eval\n:ref:`val_base_op@eval@ind_vec_vec` argument:\n`:ref:val_vec_op-name` ,\n`:ref:val_load_op-name` ,\n`:ref:val_store_op-name` .\n\n\nExample\n*******\nThe file :ref:`com_xam.cpp <val_vec_xam.cpp-name>`\nis an example and test that uses this operator.\n\n{xrst_end val_vector_op}\n// ---------------------------------------------------------------------------\n{xrst_begin val_vec_op dev}\n\nCreate A Dynamic Vector Operator\n################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_VEC_OP_T\n   // END_VEC_OP_T\n}\n\nContext\n*******\nIt is derived from :ref:`val_base_op-name` .\nIt overrides all its base class virtual member functions\nand is a concrete class (it has no pure virtual functions).\n\nget_instance\n************\nThis static member function returns a pointer to a vec_op_t object.\n\nop_enum\n*******\nThis override of :ref:`val_base_op@op_enum` returns ``vec_op_enum`` .\n\nn_before\n********\nThis override of :ref:`val_base_op@n_before` returns 1.\n{xrst_literal\n   // BEGIN_VEC_ARG_BEFORE\n   // END_VEC_ARG_BEFORE\n}\n\nn_after\n*******\nThis override of :ref:`val_base_op@n_after` returns 0.\n\nn_arg\n*****\nThis override of :ref:`val_base_op@n_arg` returns 1.\n\nn_res\n*****\nThis override of :ref:`val_base_op@n_res` return 0.\n\neval\n****\nThis override of :ref:`val_base_op@eval` implement a\ncreate dynamic vector operation.\n\ntrace\n=====\nIf trace is true, :ref:`val_print_vec_op-name`\nis called to print this operator.\n\n{xrst_end val_vec_op}\n*/\n// BEGIN_VEC_OP_T\ntemplate <class Value>\nclass vec_op_t : public base_op_t<Value> {\npublic:\n   // n_before\n   addr_t n_before(void) const override\n   {  return 1; }\n   //\n   // n_after\n   addr_t n_after(void) const override\n   {  return 0; }\n   //\n   // get_instance\n   static vec_op_t* get_instance(void)\n   {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n      static vec_op_t instance;\n      return &instance;\n   }\n   // op_enum\n   op_enum_t op_enum(void) const override\n   {  return vec_op_enum; }\n// END_VEC_OP_T\n   //\n   // n_arg\n   addr_t n_arg(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 1; }\n   //\n   // n_res\n   addr_t n_res(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 0; }\n   //\n   // eval\n   void eval(\n      const tape_t<Value>*      tape           ,\n      bool                      trace          ,\n      addr_t                    arg_index      ,\n      addr_t                    res_index      ,\n      Vector<Value>&            val_vec        ,\n      Vector< Vector<addr_t> >& ind_vec_vec    ,\n      size_t&                   compare_false  ) const override\n   {  //\n      // arg_vec, vec_vec\n      const Vector<addr_t>& arg_vec( tape->arg_vec() );\n      //\n      // which_vector\n      // BEGIN_VEC_ARG_BEFORE\n      addr_t  which_vector = arg_vec[arg_index + 0];\n      // END_VEC_ARG_BEFORE\n      //\n      // initial\n      const Vector<addr_t> initial = tape->vec_initial()[which_vector];\n# ifndef NDEBUG\n      for(size_t i = 0; i < initial.size(); ++i)\n      {  CPPAD_ASSERT_KNOWN(\n            initial[i] < res_index,\n            \"vec_op: initial indices must come before index of next result\"\n         );\n      }\n# endif\n      //\n      // ind_vec_vec\n      CPPAD_ASSERT_UNKNOWN( ind_vec_vec.size() == size_t(which_vector) );\n      ind_vec_vec.push_back(initial);\n      ind_vec_vec[which_vector].resize( initial.size() + 1 );\n      //\n      // ind_vec_vec\n      // Does not point to the nan in the tape which is at index tape->n_ind()\n      CPPAD_ASSERT_UNKNOWN( 0 < tape->n_ind() );\n      ind_vec_vec[which_vector][ initial.size() ] = 0;\n      //\n      if( ! trace )\n         return;\n      //\n      // print_vec_op\n      print_vec_op(which_vector, initial);\n   }\n};\n// ---------------------------------------------------------------------------\n/*\n{xrst_begin val_load_op dev}\n\nDynamic Vector Load Operator\n############################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_LOAD_OP_T\n   // END_LOAD_OP_T\n}\n\nContext\n*******\nIt is derived from :ref:`val_base_op-name` .\nIt overrides all its base class virtual member functions\nand is a concrete class (it has no pure virtual functions).\n\nget_instance\n************\nThis static member function returns a pointer to a load_op_t object.\n\nop_enum\n*******\nThis override of :ref:`val_base_op@op_enum` returns ``load_op_enum`` .\n\nn_before\n********\nThis override of :ref:`val_base_op@n_before` returns 1.\n{xrst_literal\n   // BEGIN_LOAD_ARG_BEFORE\n   // END_LOAD_ARG_BEFORE\n}\n\nn_after\n*******\nThis override of :ref:`val_base_op@n_after` returns 0.\n\nn_arg\n*****\nThis override of :ref:`val_base_op@n_arg` returns 2.\n\nn_res\n*****\nThis override of :ref:`val_base_op@n_res` return 1.\n\neval\n****\nThis override of :ref:`val_base_op@eval` implement a\ndynamic vector load operation.\n\nwhich_vector\n============\nWe use *which_vector* to denote the index corresponding to this\ndynamic vector; i.e.  arg_vec[arg_index + 0].\n\nvector_index\n============\nWe use *vector_index* to denote the index, in the value vector,\nof the index in the dynamic vector, of the element for this load; i.e.\narg_vec[arg_index + 1].\n\ntrace\n=====\nIf trace is true, :ref:`val_print_load_op-name`\nis called to print this operator.\n\n{xrst_end val_load_op}\n*/\n// BEGIN_LOAD_OP_T\ntemplate <class Value>\nclass load_op_t : public base_op_t<Value> {\npublic:\n   // n_before\n   addr_t n_before(void) const override\n   {  return 1; }\n   //\n   // n_after\n   addr_t n_after(void) const override\n   {  return 0; }\n   //\n   // get_instance\n   static load_op_t* get_instance(void)\n   {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n      static load_op_t instance;\n      return &instance;\n   }\n   // op_enum\n   op_enum_t op_enum(void) const override\n   {  return load_op_enum; }\n// END_LOAD_OP_T\n   //\n   // n_arg\n   addr_t n_arg(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 2; }\n   //\n   // n_res\n   addr_t n_res(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 1; }\n   //\n   // eval\n   void eval(\n      const tape_t<Value>*      tape           ,\n      bool                      trace          ,\n      addr_t                    arg_index      ,\n      addr_t                    res_index      ,\n      Vector<Value>&            val_vec        ,\n      Vector< Vector<addr_t> >& ind_vec_vec    ,\n      size_t&                   compare_false  ) const override\n   {  //\n      // arg_vec, vec_vec\n      const Vector<addr_t>& arg_vec( tape->arg_vec() );\n      //\n      // this_vector\n      // BEGIN_LOAD_ARG_BEFORE\n      addr_t          which_vector = arg_vec[arg_index + 0];\n      Vector<addr_t>& this_vector  = ind_vec_vec[which_vector];\n      // END_LOAD_ARG_BEFORE\n      //\n      // vector_index\n      addr_t vector_index = arg_vec[arg_index + 1];\n      //\n      // index\n      Value index          = val_vec[vector_index];\n      //\n      // val_vec\n      addr_t flag = this_vector[ this_vector.size() - 1 ];\n      if( flag == tape->n_ind() || CppAD::isnan(index) )\n      {  val_vec[res_index] = val_vec[ tape->n_ind() ];\n         CPPAD_ASSERT_UNKNOWN( CppAD::isnan( val_vec[res_index] ) );\n      }\n      else\n      {  //\n         // dynamic_index\n         addr_t dynamic_index = addr_t( Integer(index) );\n         CPPAD_ASSERT_KNOWN( size_t(dynamic_index) + 1 < this_vector.size(),\n            \"dynamic vector index is greater than or equal vector size\"\n         );\n         //\n         // val_vec\n         val_vec[res_index] = val_vec[ this_vector[dynamic_index] ];\n      }\n      //\n      // trace\n      if( ! trace )\n         return;\n      //\n      // print_load_op\n      Value res_value = val_vec[res_index];\n      print_load_op(which_vector, vector_index, res_index, res_value);\n   }\n};\n// ---------------------------------------------------------------------------\n/*\n{xrst_begin val_store_op dev}\n\nDynamic Vector Store Operator\n#############################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_STORE_OP_T\n   // END_STORE_OP_T\n}\n\nContext\n*******\nIt is derived from :ref:`val_base_op-name` .\nIt overrides all its base class virtual member functions\nand is a concrete class (it has no pure virtual functions).\n\nget_instance\n************\nThis static member function returns a pointer to a store_op_t object.\n\nop_enum\n*******\nThis override of :ref:`val_base_op@op_enum` returns ``store_op_enum`` .\n\nn_before\n********\nThis override of :ref:`val_base_op@n_before` returns 1.\n{xrst_literal\n   // BEGIN_STORE_ARG_BEFORE\n   // END_STORE_ARG_BEFORE\n}\n\nn_after\n*******\nThis override of :ref:`val_base_op@n_after` returns 0.\n\nn_arg\n*****\nThis override of :ref:`val_base_op@n_arg` returns 3.\n\nn_res\n*****\nThis override of :ref:`val_base_op@n_res` return 0.\n\neval\n****\nThis override of :ref:`val_base_op@eval` implement a\ndynamic vector store operation.\n\nwhich_vector\n============\nWe use *which_vector* to denote the index corresponding to this\ndynamic vector; i.e.  arg_vec[arg_index + 0].\n\nvector_index\n============\nWe use *vector_index* to denote the index, in the value vector,\nof the index in the dynamic vector, of the element for this store; i.e.\narg_vec[arg_index + 1].\n\nvalue_index\n===========\nWe use *value_index* to denote the index,\nin the val_vec vector, of the element for this store; i.e.\narg_vec[arg_index + 2].\n\ntrace\n=====\nIf trace is true, :ref:`val_print_store_op-name`\nis called to print this operator.\n\n{xrst_end val_store_op}\n*/\n// BEGIN_STORE_OP_T\ntemplate <class Value>\nclass store_op_t : public base_op_t<Value> {\npublic:\n   // n_before\n   addr_t n_before(void) const override\n   {  return 1; }\n   //\n   // n_after\n   addr_t n_after(void) const override\n   {  return 0; }\n   //\n   // get_instance\n   static store_op_t* get_instance(void)\n   {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n      static store_op_t instance;\n      return &instance;\n   }\n   // op_enum\n   op_enum_t op_enum(void) const override\n   {  return store_op_enum; }\n// END_STORE_OP_T\n   //\n   // n_arg\n   addr_t n_arg(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 3; }\n   //\n   // n_res\n   addr_t n_res(\n      addr_t                arg_index    ,\n      const Vector<addr_t>& arg_vec      ) const override\n   {  return 0; }\n   //\n   // eval\n   void eval(\n      const tape_t<Value>*      tape           ,\n      bool                      trace          ,\n      addr_t                    arg_index      ,\n      addr_t                    res_index      ,\n      Vector<Value>&            val_vec        ,\n      Vector< Vector<addr_t> >& ind_vec_vec    ,\n      size_t&                   compare_false  ) const override\n   {  //\n      // arg_vec, vec_vec\n      const Vector<addr_t>& arg_vec( tape->arg_vec() );\n      //\n      // this_vector\n      // BEGIN_STORE_ARG_BEFORE\n      addr_t          which_vector = arg_vec[arg_index + 0];\n      Vector<addr_t>& this_vector  = ind_vec_vec[which_vector];\n      // END_STORE_ARG_BEFORE\n      //\n      // vector_index, value_index\n      addr_t vector_index = arg_vec[arg_index + 1];\n      addr_t value_index  = arg_vec[arg_index + 2];\n      //\n      // index\n      Value index          = val_vec[vector_index];\n      if( CppAD::isnan(index) )\n      {  // set flag for this vector\n         this_vector[ this_vector.size() - 1 ] = tape->n_ind();\n      }\n      else\n      {  // dynamic_index\n         addr_t dynamic_index = addr_t( Integer(index) );\n         CPPAD_ASSERT_KNOWN( size_t(dynamic_index) + 1 < this_vector.size(),\n            \"dynamic vector index is greater than or equal vector size\"\n         );\n         //\n         // val_vec_vec\n         this_vector[dynamic_index] = value_index;\n      }\n      //\n      // trace\n      if( ! trace )\n         return;\n      //\n      // print_store_op\n      print_store_op(which_vector, vector_index, value_index);\n   }\n};\n\n} } } // END_CPPAD_LOCAL_VAL_GRAPH_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/abs_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_ABS_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_ABS_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void abs_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   for(size_t j = p; j <= q; j++)\n      z[j] = sign(x[0]) * x[j];\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void abs_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* z = taylor + i_z * num_taylor_per_var;\n\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n      z[m + ell] = sign(x[0]) * x[m + ell];\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void abs_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base x0 = *(taylor + i_x * cap_order);\n   Base* z = taylor + i_z * cap_order;\n\n   z[0] = fabs(x0);\n}\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void abs_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   //\n   size_t j;\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AbsOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AbsOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to result\n   Base* pz       = partial +    i_z * n_order;\n\n   // do not need azmul because sign is either +1, -1, or zero\n   for(j = 0; j < n_order; j++)\n      px[j] += sign(x[0]) * pz[j];\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/acos_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_ACOS_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_ACOS_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void acos_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AcosOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AcosOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n   Base* b = z      -       cap_order;  // called y in documentation\n\n   size_t k;\n   Base uj;\n   if( p == 0 )\n   {  z[0] = acos( x[0] );\n      uj   = Base(1.0) - x[0] * x[0];\n      b[0] = sqrt( uj );\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {  uj = Base(0.0);\n      for(k = 0; k <= j; k++)\n         uj -= x[k] * x[j-k];\n      b[j] = Base(0.0);\n      z[j] = Base(0.0);\n      for(k = 1; k < j; k++)\n      {  b[j] -= Base(double(k)) * b[k] * b[j-k];\n         z[j] -= Base(double(k)) * z[k] * b[j-k];\n      }\n      b[j] /= Base(double(j));\n      z[j] /= Base(double(j));\n      //\n      b[j] += uj / Base(2.0);\n      z[j] -= x[j];\n      //\n      b[j] /= b[0];\n      z[j] /= b[0];\n   }\n}\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void acos_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AcosOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AcosOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* z = taylor + i_z * num_taylor_per_var;\n   Base* b = z - num_taylor_per_var;  // called y in documentation\n\n   size_t k, ell;\n   size_t m = (q-1) * r + 1;\n   for(ell = 0; ell < r; ell ++)\n   {  Base uq = - 2.0 * x[m + ell] * x[0];\n      for(k = 1; k < q; k++)\n         uq -= x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell];\n      b[m+ell] = Base(0.0);\n      z[m+ell] = Base(0.0);\n      for(k = 1; k < q; k++)\n      {  b[m+ell] += Base(double(k)) * b[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell];\n         z[m+ell] += Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell];\n      }\n      b[m+ell] =  ( uq / Base(2.0) - b[m+ell] / Base(double(q)) ) / b[0];\n      z[m+ell] = -( x[m+ell]     + z[m+ell] / Base(double(q)) ) / b[0];\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void acos_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AcosOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AcosOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n   Base* b = z      -       cap_order; // called y in documentation\n\n   z[0] = acos( x[0] );\n   b[0] = sqrt( Base(1.0) - x[0] * x[0] );\n}\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void acos_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AcosOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AcosOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to first result\n   const Base* z  = taylor  + i_z * cap_order;\n   Base* pz       = partial + i_z * n_order;\n\n   // Taylor coefficients and partials corresponding to auxiliary result\n   const Base* b  = z  - cap_order; // called y in documentation\n   Base* pb       = pz - n_order;\n\n   Base inv_b0 = Base(1.0) / b[0];\n\n   // number of indices to access\n   size_t j = d;\n   size_t k;\n   while(j)\n   {\n      // scale partials w.r.t b[j] by 1 / b[0]\n      pb[j]  = azmul(pb[j], inv_b0);\n\n      // scale partials w.r.t z[j] by 1 / b[0]\n      pz[j]  = azmul(pz[j], inv_b0);\n\n      // update partials w.r.t b^0\n      pb[0] -= azmul(pz[j], z[j]) + azmul(pb[j], b[j]);\n\n      // update partial w.r.t. x^0\n      px[0] -= azmul(pb[j], x[j]);\n\n      // update partial w.r.t. x^j\n      px[j] -= pz[j] + azmul(pb[j], x[0]);\n\n      // further scale partial w.r.t. z[j] by 1 / j\n      pz[j] /= Base(double(j));\n\n      for(k = 1; k < j; k++)\n      {  // update partials w.r.t b^(j-k)\n         pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]) + azmul(pb[j], b[k]);\n\n         // update partials w.r.t. x^k\n         px[k]   -= azmul(pb[j], x[j-k]);\n\n         // update partials w.r.t. z^k\n         pz[k]   -= Base(double(k)) * azmul(pz[j], b[j-k]);\n      }\n      --j;\n   }\n\n   // j == 0 case\n   px[0] -= azmul( pz[0] + azmul(pb[0], x[0]), inv_b0);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/acosh_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_ACOSH_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_ACOSH_OP_HPP\n\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void acosh_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AcoshOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AcoshOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n   Base* b = z      -       cap_order;  // called y in documentation\n\n   size_t k;\n   Base uj;\n   if( p == 0 )\n   {  z[0] = acosh( x[0] );\n      uj   = x[0] * x[0] - Base(1.0);\n      b[0] = sqrt( uj );\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {  uj = Base(0.0);\n      for(k = 0; k <= j; k++)\n         uj += x[k] * x[j-k];\n      b[j] = Base(0.0);\n      z[j] = Base(0.0);\n      for(k = 1; k < j; k++)\n      {  b[j] -= Base(double(k)) * b[k] * b[j-k];\n         z[j] -= Base(double(k)) * z[k] * b[j-k];\n      }\n      b[j] /= Base(double(j));\n      z[j] /= Base(double(j));\n      //\n      b[j] += uj / Base(2.0);\n      z[j] += x[j];\n      //\n      b[j] /= b[0];\n      z[j] /= b[0];\n   }\n}\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void acosh_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AcoshOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AcoshOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* z = taylor + i_z * num_taylor_per_var;\n   Base* b = z - num_taylor_per_var;  // called y in documentation\n\n   size_t k, ell;\n   size_t m = (q-1) * r + 1;\n   for(ell = 0; ell < r; ell ++)\n   {  Base uq = 2.0 * x[m + ell] * x[0];\n      for(k = 1; k < q; k++)\n         uq += x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell];\n      b[m+ell] = Base(0.0);\n      z[m+ell] = Base(0.0);\n      for(k = 1; k < q; k++)\n      {  b[m+ell] += Base(double(k)) * b[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell];\n         z[m+ell] += Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell];\n      }\n      b[m+ell] =  ( uq / Base(2.0) - b[m+ell] / Base(double(q)) ) / b[0];\n      z[m+ell] = ( x[m+ell]     - z[m+ell] / Base(double(q)) ) / b[0];\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void acosh_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AcoshOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AcoshOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n   Base* b = z      -       cap_order; // called y in documentation\n\n   z[0] = acosh( x[0] );\n   b[0] = sqrt( x[0] * x[0] - Base(1.0) );\n}\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void acosh_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AcoshOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AcoshOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to first result\n   const Base* z  = taylor  + i_z * cap_order;\n   Base* pz       = partial + i_z * n_order;\n\n   // Taylor coefficients and partials corresponding to auxiliary result\n   const Base* b  = z  - cap_order; // called y in documentation\n   Base* pb       = pz - n_order;\n\n   Base inv_b0 = Base(1.0) / b[0];\n\n   // number of indices to access\n   size_t j = d;\n   size_t k;\n   while(j)\n   {\n      // scale partials w.r.t b[j] by 1 / b[0]\n      pb[j]  = azmul(pb[j], inv_b0);\n\n      // scale partials w.r.t z[j] by 1 / b[0]\n      pz[j]  = azmul(pz[j], inv_b0);\n\n      // update partials w.r.t b^0\n      pb[0] -= azmul(pz[j], z[j]) + azmul(pb[j], b[j]);\n\n      // update partial w.r.t. x^0\n      px[0] += azmul(pb[j], x[j]);\n\n      // update partial w.r.t. x^j\n      px[j] += pz[j] + azmul(pb[j], x[0]);\n\n      // further scale partial w.r.t. z[j] by 1 / j\n      pz[j] /= Base(double(j));\n\n      for(k = 1; k < j; k++)\n      {  // update partials w.r.t b^(j-k)\n         pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]) + azmul(pb[j], b[k]);\n\n         // update partials w.r.t. x^k\n         px[k]   += azmul(pb[j], x[j-k]);\n\n         // update partials w.r.t. z^k\n         pz[k]   -= Base(double(k)) * azmul(pz[j], b[j-k]);\n      }\n      --j;\n   }\n\n   // j == 0 case\n   px[0] += azmul(pz[0] + azmul(pb[0], x[0]),  inv_b0);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/add_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_ADD_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_ADD_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n\n// --------------------------- Addvv -----------------------------------------\n\n// See dev documentation: forward_unary_op\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void addvv_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q  );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   for(size_t j = p; j <= q; j++)\n      z[j] = x[j] + y[j];\n}\n\n// See dev documentation: forward_unary_op\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void addvv_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( 0 < q  );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + size_t(arg[0]) * num_taylor_per_var;\n   Base* y = taylor + size_t(arg[1]) * num_taylor_per_var;\n   Base* z = taylor +    i_z * num_taylor_per_var;\n\n   size_t m = (q-1)*r + 1 ;\n   for(size_t ell = 0; ell < r; ell++)\n      z[m+ell] = x[m+ell] + y[m+ell];\n}\n\n\n// See dev documentation: forward_unary_op\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void addvv_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   z[0] = x[0] + y[0];\n}\n\n\n// See dev documentation: reverse_unary_op\n// See dev documentation: reverse_binary_op\ntemplate <class Base>\ninline void addvv_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Partial derivatives corresponding to arguments and result\n   Base* px = partial + size_t(arg[0]) * n_order;\n   Base* py = partial + size_t(arg[1]) * n_order;\n   Base* pz = partial + i_z    * n_order;\n\n   // number of indices to access\n   size_t i = d + 1;\n   while(i)\n   {  --i;\n      px[i] += pz[i];\n      py[i] += pz[i];\n   }\n}\n\n// --------------------------- Addpv -----------------------------------------\n// See dev documentation: forward_unary_op\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void addpv_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AddpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AddpvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   if( p == 0 )\n   {  // Paraemter value\n      Base x = parameter[ arg[0] ];\n      z[0] = x + y[0];\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n      z[j] = y[j];\n}\n// See dev documentation: forward_unary_op\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void addpv_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AddpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AddpvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   size_t m                  = (q-1) * r + 1;\n   Base* y = taylor + size_t(arg[1]) * num_taylor_per_var + m;\n   Base* z = taylor + i_z    * num_taylor_per_var + m;\n\n   for(size_t ell = 0; ell < r; ell++)\n      z[ell] = y[ell];\n}\n\n// See dev documentation: forward_unary_op\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void addpv_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AddpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AddpvOp) == 1 );\n\n   // Paraemter value\n   Base x = parameter[ arg[0] ];\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   z[0] = x + y[0];\n}\n\n\n// See dev documentation: reverse_unary_op\n// See dev documentation: reverse_binary_op\ntemplate <class Base>\ninline void addpv_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AddvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AddvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Partial derivatives corresponding to arguments and result\n   Base* py = partial + size_t(arg[1]) * n_order;\n   Base* pz = partial + i_z    * n_order;\n\n   // number of indices to access\n   size_t i = d + 1;\n   while(i)\n   {  --i;\n      py[i] += pz[i];\n   }\n}\n\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/asin_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_ASIN_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_ASIN_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void asin_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AsinOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AsinOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n   Base* b = z      -       cap_order;  // called y in documentation\n\n   size_t k;\n   Base uj;\n   if( p == 0 )\n   {  z[0] = asin( x[0] );\n      uj   = Base(1.0) - x[0] * x[0];\n      b[0] = sqrt( uj );\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {  uj = Base(0.0);\n      for(k = 0; k <= j; k++)\n         uj -= x[k] * x[j-k];\n      b[j] = Base(0.0);\n      z[j] = Base(0.0);\n      for(k = 1; k < j; k++)\n      {  b[j] -= Base(double(k)) * b[k] * b[j-k];\n         z[j] -= Base(double(k)) * z[k] * b[j-k];\n      }\n      b[j] /= Base(double(j));\n      z[j] /= Base(double(j));\n      //\n      b[j] += uj / Base(2.0);\n      z[j] += x[j];\n      //\n      b[j] /= b[0];\n      z[j] /= b[0];\n   }\n}\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void asin_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AcosOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AcosOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* z = taylor + i_z * num_taylor_per_var;\n   Base* b = z - num_taylor_per_var;  // called y in documentation\n\n   size_t k, ell;\n   size_t m = (q-1) * r + 1;\n   for(ell = 0; ell < r; ell ++)\n   {  Base uq = - 2.0 * x[m + ell] * x[0];\n      for(k = 1; k < q; k++)\n         uq -= x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell];\n      b[m+ell] = Base(0.0);\n      z[m+ell] = Base(0.0);\n      for(k = 1; k < q; k++)\n      {  b[m+ell] += Base(double(k)) * b[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell];\n         z[m+ell] += Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell];\n      }\n      b[m+ell] = ( uq / Base(2.0) - b[m+ell] / Base(double(q)) ) / b[0];\n      z[m+ell] = ( x[m+ell]     - z[m+ell] / Base(double(q)) ) / b[0];\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void asin_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AsinOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AsinOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n   Base* b = z      -       cap_order; // called y in documentation\n\n   z[0] = asin( x[0] );\n   b[0] = sqrt( Base(1.0) - x[0] * x[0] );\n}\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void asin_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AsinOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AsinOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to first result\n   const Base* z  = taylor  + i_z * cap_order;\n   Base* pz       = partial + i_z * n_order;\n\n   // Taylor coefficients and partials corresponding to auxiliary result\n   const Base* b  = z  - cap_order; // called y in documentation\n   Base* pb       = pz - n_order;\n\n   Base inv_b0 = Base(1.0) / b[0];\n\n   // number of indices to access\n   size_t j = d;\n   size_t k;\n   while(j)\n   {\n      // scale partials w.r.t b[j] by 1 / b[0]\n      pb[j]  = azmul(pb[j], inv_b0);\n\n      // scale partials w.r.t z[j] by 1 / b[0]\n      pz[j]  = azmul(pz[j], inv_b0);\n\n      // update partials w.r.t b^0\n      pb[0] -= azmul(pz[j], z[j]) + azmul(pb[j], b[j]);\n\n      // update partial w.r.t. x^0\n      px[0] -= azmul(pb[j], x[j]);\n\n      // update partial w.r.t. x^j\n      px[j] += pz[j] - azmul(pb[j], x[0]);\n\n      // further scale partial w.r.t. z[j] by 1 / j\n      pz[j] /= Base(double(j));\n\n      for(k = 1; k < j; k++)\n      {  // update partials w.r.t b^(j-k)\n         pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]) + azmul(pb[j], b[k]);\n\n         // update partials w.r.t. x^k\n         px[k]   -= azmul(pb[j], x[j-k]);\n\n         // update partials w.r.t. z^k\n         pz[k]   -= Base(double(k)) * azmul(pz[j], b[j-k]);\n      }\n      --j;\n   }\n\n   // j == 0 case\n   px[0] += azmul(pz[0] - azmul(pb[0], x[0]), inv_b0);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/asinh_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_ASINH_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_ASINH_OP_HPP\n\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void asinh_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AsinhOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AsinhOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n   Base* b = z      -       cap_order;  // called y in documentation\n\n   size_t k;\n   Base uj;\n   if( p == 0 )\n   {  z[0] = asinh( x[0] );\n      uj   = Base(1.0) + x[0] * x[0];\n      b[0] = sqrt( uj );\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {  uj = Base(0.0);\n      for(k = 0; k <= j; k++)\n         uj += x[k] * x[j-k];\n      b[j] = Base(0.0);\n      z[j] = Base(0.0);\n      for(k = 1; k < j; k++)\n      {  b[j] -= Base(double(k)) * b[k] * b[j-k];\n         z[j] -= Base(double(k)) * z[k] * b[j-k];\n      }\n      b[j] /= Base(double(j));\n      z[j] /= Base(double(j));\n      //\n      b[j] += uj / Base(2.0);\n      z[j] += x[j];\n      //\n      b[j] /= b[0];\n      z[j] /= b[0];\n   }\n}\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void asinh_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AcosOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AcosOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* z = taylor + i_z * num_taylor_per_var;\n   Base* b = z - num_taylor_per_var;  // called y in documentation\n\n   size_t k, ell;\n   size_t m = (q-1) * r + 1;\n   for(ell = 0; ell < r; ell ++)\n   {  Base uq = 2.0 * x[m + ell] * x[0];\n      for(k = 1; k < q; k++)\n         uq += x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell];\n      b[m+ell] = Base(0.0);\n      z[m+ell] = Base(0.0);\n      for(k = 1; k < q; k++)\n      {  b[m+ell] += Base(double(k)) * b[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell];\n         z[m+ell] += Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell];\n      }\n      b[m+ell] = ( uq / Base(2.0) - b[m+ell] / Base(double(q)) ) / b[0];\n      z[m+ell] = ( x[m+ell]     - z[m+ell] / Base(double(q)) ) / b[0];\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void asinh_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AsinhOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AsinhOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n   Base* b = z      -       cap_order; // called y in documentation\n\n   z[0] = asinh( x[0] );\n   b[0] = sqrt( Base(1.0) + x[0] * x[0] );\n}\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void asinh_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AsinhOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AsinhOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to first result\n   const Base* z  = taylor  + i_z * cap_order;\n   Base* pz       = partial + i_z * n_order;\n\n   // Taylor coefficients and partials corresponding to auxiliary result\n   const Base* b  = z  - cap_order; // called y in documentation\n   Base* pb       = pz - n_order;\n\n   Base inv_b0 = Base(1.0) / b[0];\n\n   // number of indices to access\n   size_t j = d;\n   size_t k;\n   while(j)\n   {\n      // scale partials w.r.t b[j] by 1 / b[0]\n      pb[j]  = azmul(pb[j], inv_b0);\n\n      // scale partials w.r.t z[j] by 1 / b[0]\n      pz[j]  = azmul(pz[j], inv_b0);\n\n      // update partials w.r.t b^0\n      pb[0] -= azmul(pz[j], z[j]) + azmul(pb[j], b[j]);\n\n      // update partial w.r.t. x^0\n      px[0] += azmul(pb[j], x[j]);\n\n      // update partial w.r.t. x^j\n      px[j] += pz[j] + azmul(pb[j], x[0]);\n\n      // further scale partial w.r.t. z[j] by 1 / j\n      pz[j] /= Base(double(j));\n\n      for(k = 1; k < j; k++)\n      {  // update partials w.r.t b^(j-k)\n         pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]) + azmul(pb[j], b[k]);\n\n         // update partials w.r.t. x^k\n         px[k]   += azmul(pb[j], x[j-k]);\n\n         // update partials w.r.t. z^k\n         pz[k]   -= Base(double(k)) * azmul(pz[j], b[j-k]);\n      }\n      --j;\n   }\n\n   // j == 0 case\n   px[0] += azmul(pz[0] + azmul(pb[0], x[0]), inv_b0);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/atan_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_ATAN_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_ATAN_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void atan_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AtanOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AtanOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n   Base* b = z      -       cap_order;  // called y in documentation\n\n   size_t k;\n   if( p == 0 )\n   {  z[0] = atan( x[0] );\n      b[0] = Base(1.0) + x[0] * x[0];\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {\n      b[j] = Base(2.0) * x[0] * x[j];\n      z[j] = Base(0.0);\n      for(k = 1; k < j; k++)\n      {  b[j] += x[k] * x[j-k];\n         z[j] -= Base(double(k)) * z[k] * b[j-k];\n      }\n      z[j] /= Base(double(j));\n      z[j] += x[j];\n      z[j] /= b[0];\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void atan_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AtanOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AtanOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* z = taylor + i_z * num_taylor_per_var;\n   Base* b = z      -       num_taylor_per_var; // called y in documentation\n\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  b[m+ell] = Base(2.0) * x[m+ell] * x[0];\n      z[m+ell] = Base(double(q)) * x[m+ell];\n      for(size_t k = 1; k < q; k++)\n      {  b[m+ell] += x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell];\n         z[m+ell] -= Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell];\n      }\n      z[m+ell] /= ( Base(double(q)) * b[0] );\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void atan_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AtanOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AtanOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n   Base* b = z      -       cap_order; // called y in documentation\n\n   z[0] = atan( x[0] );\n   b[0] = Base(1.0) + x[0] * x[0];\n}\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void atan_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AtanOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AtanOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to first result\n   const Base* z  = taylor  + i_z * cap_order;\n   Base* pz       = partial + i_z * n_order;\n\n   // Taylor coefficients and partials corresponding to auxiliary result\n   const Base* b  = z  - cap_order; // called y in documentation\n   Base* pb       = pz - n_order;\n\n   Base inv_b0 = Base(1.0) / b[0];\n\n   // number of indices to access\n   size_t j = d;\n   size_t k;\n   while(j)\n   {  // scale partials w.r.t z[j] and b[j]\n      pz[j]  = azmul(pz[j], inv_b0);\n      pb[j] *= Base(2.0);\n\n      pb[0] -= azmul(pz[j], z[j]);\n      px[j] += pz[j] + azmul(pb[j], x[0]);\n      px[0] += azmul(pb[j], x[j]);\n\n      // more scaling of partials w.r.t z[j]\n      pz[j] /= Base(double(j));\n\n      for(k = 1; k < j; k++)\n      {  pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]);\n         pz[k]   -= Base(double(k)) * azmul(pz[j], b[j-k]);\n         px[k]   += azmul(pb[j], x[j-k]);\n      }\n      --j;\n   }\n   px[0] += azmul(pz[0], inv_b0) + Base(2.0) * azmul(pb[0], x[0]);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/atanh_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_ATANH_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_ATANH_OP_HPP\n\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void atanh_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AtanhOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AtanhOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n   Base* b = z      -       cap_order;  // called y in documentation\n\n   size_t k;\n   if( p == 0 )\n   {  z[0] = atanh( x[0] );\n      b[0] = Base(1.0) - x[0] * x[0];\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {\n      b[j] = - Base(2.0) * x[0] * x[j];\n      z[j] = Base(0.0);\n      for(k = 1; k < j; k++)\n      {  b[j] -= x[k] * x[j-k];\n         z[j] -= Base(double(k)) * z[k] * b[j-k];\n      }\n      z[j] /= Base(double(j));\n      z[j] += x[j];\n      z[j] /= b[0];\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void atanh_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AtanhOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AtanhOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* z = taylor + i_z * num_taylor_per_var;\n   Base* b = z      -       num_taylor_per_var; // called y in documentation\n\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  b[m+ell] = - Base(2.0) * x[m+ell] * x[0];\n      z[m+ell] = Base(double(q)) * x[m+ell];\n      for(size_t k = 1; k < q; k++)\n      {  b[m+ell] -= x[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell];\n         z[m+ell] -= Base(double(k)) * z[(k-1)*r+1+ell] * b[(q-k-1)*r+1+ell];\n      }\n      z[m+ell] /= ( Base(double(q)) * b[0] );\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void atanh_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AtanhOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AtanhOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n   Base* b = z      -       cap_order; // called y in documentation\n\n   z[0] = atanh( x[0] );\n   b[0] = Base(1.0) - x[0] * x[0];\n}\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void atanh_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(AtanhOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(AtanhOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to first result\n   const Base* z  = taylor  + i_z * cap_order;\n   Base* pz       = partial + i_z * n_order;\n\n   // Taylor coefficients and partials corresponding to auxiliary result\n   const Base* b  = z  - cap_order; // called y in documentation\n   Base* pb       = pz - n_order;\n\n   Base inv_b0 = Base(1.0) / b[0];\n\n   // number of indices to access\n   size_t j = d;\n   size_t k;\n   while(j)\n   {  // scale partials w.r.t z[j] and b[j]\n      pz[j]  = azmul(pz[j], inv_b0);\n      pb[j] *= Base(2.0);\n\n      pb[0] -= azmul(pz[j], z[j]);\n      px[j] += pz[j] - azmul(pb[j], x[0]);\n      px[0] -= azmul(pb[j], x[j]);\n\n      // more scaling of partials w.r.t z[j]\n      pz[j] /= Base(double(j));\n\n      for(k = 1; k < j; k++)\n      {  pb[j-k] -= Base(double(k)) * azmul(pz[j], z[k]);\n         pz[k]   -= Base(double(k)) * azmul(pz[j], b[j-k]);\n         px[k]   -= azmul(pb[j], x[j-k]);\n      }\n      --j;\n   }\n   px[0] += azmul(pz[0], inv_b0) - Base(2.0) * azmul(pb[0], x[0]);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/atomic_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_ATOMIC_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_ATOMIC_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-25 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// BEGIN_CPPAD_LOCAL_VAR_OP_NAMESPACE\nnamespace CppAD { namespace local { namespace var_op {\n\n// sweep_type\nenum sweep_type {\n   forward_op_sweep,\n   forward_dir_sweep,\n   reverse_op_sweep,\n   for_jac_sweep,\n   rev_jac_sweep,\n   for_hes_sweep,\n   rev_hes_sweep\n};\n\n// atomic_op_work\ntemplate <class Base>\nstruct atomic_op_work {\n   // parameter_x, taylor_x, type_x, taylor_y, index_y, variable_y\n   CppAD::vector<Base>           parameter_x;\n   CppAD::vector<ad_type_enum>   type_x;\n   //\n   CppAD::vector<Base>           taylor_x;\n   CppAD::vector<Base>           taylor_y;\n   //\n   CppAD::vector<Base>           partial_x;\n   CppAD::vector<Base>           partial_y;\n   //\n   CppAD::vector<size_t>         index_x;\n   CppAD::vector<size_t>         index_y;\n   //\n   CppAD::vector<bool>           variable_x;\n   CppAD::vector<bool>           variable_y;\n   //\n   // resize\n   void resize(size_t m, size_t n, size_t n_order, sweep_type sweep)\n   {  //\n      // parameter_x, type_x\n      parameter_x.resize(n);\n      type_x.resize(n);\n      //\n      switch( sweep )\n      {\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         // ------------------------------------------------------------------\n         // forward_op_sweep\n         case forward_op_sweep:\n         taylor_x.resize(n * n_order);\n         taylor_y.resize(m * n_order);\n         //\n         partial_x.resize(0);\n         partial_y.resize(0);\n         //\n         index_x.resize(0);\n         index_y.resize(m);\n         //\n         variable_x.resize(0);\n         variable_y.resize(m);\n         break;\n         // ------------------------------------------------------------------\n         // forward_dir_sweep\n         case forward_dir_sweep:\n         taylor_x.resize(n * n_order);\n         taylor_y.resize(m * n_order);\n         //\n         partial_x.resize(0);\n         partial_y.resize(0);\n         //\n         index_x.resize(n);\n         index_y.resize(m);\n         //\n         variable_x.resize(0);\n         variable_y.resize(m);\n         break;\n         // ------------------------------------------------------------------\n         // reverse_op_sweep\n         case reverse_op_sweep:\n         taylor_x.resize(n * n_order);\n         taylor_y.resize(m * n_order);\n         //\n         partial_x.resize(n * n_order);\n         partial_y.resize(m * n_order);\n         //\n         index_x.resize(n);\n         index_y.resize(0);\n         //\n         variable_x.resize(n);\n         variable_y.resize(0);\n         break;\n         // ------------------------------------------------------------------\n         // for_jac_sweep, rev_jac_sweep\n         // for_hes_sweep, rev_hes_sweep\n         case for_jac_sweep:\n         case rev_jac_sweep:\n         case for_hes_sweep:\n         case rev_hes_sweep:\n         taylor_x.resize(0);\n         taylor_y.resize(0);\n         //\n         partial_x.resize(0);\n         partial_y.resize(0);\n         //\n         index_x.resize(n);\n         index_y.resize(m);\n         //\n         variable_x.resize(0);\n         variable_y.resize(0);\n         break;\n      }\n   }\n};\n/*\n------------------------------------------------------------------------------\n{xrst_begin_parent var_atomic_op dev}\n{xrst_spell\n   funap\n   funav\n   funrp\n   funrv\n}\n\nAtomic Function Call Operators\n##############################\n\nAFunOp\n******\nThis operator appears at the start and end of every atomic function call.\nIt has four arguments and no results.\n\narg[0]\n======\nThis is the :ref:`atomic_index-name` for this function.\n\narg[1]\n======\nIf this is an atomic_four call,\narg[1] is the corresponding :ref:`atomic_four_call@call_id` .\nIf this is an atomic_one call (which has been deprecated)\narg[1] is corresponding :ref:`atomic_one@id`\n\narg[2], n\n=========\nis the number of arguments to this atomic function call.\nWe use the notation *n* = *arg* [2] .\n\narg[3], m\n=========\nis the number of results returned by this atomic function call.\nWe use the notation *m* = *arg* [3] .\n\nFunapOp, FunavOp\n****************\n#. There are *n* of these operators directly after\n   the AFunOp at the start of a function call,\n   one for each argument to the function call.\n#. Each of these operators has one argument and no result.\n#. If the *j*-th argument in the function call is a parameter (variable)\n   the corresponding operator is FunapOp ( FunavOp ).\n#. The operator argument for FunapOp ( FunavOp )\n   is the parameter index (variable index) for the corresponding\n   argument in the function call.\n\nFunrpOp, FunrvOp\n****************\n#. There are *m* of these operators directly after the\n   FunapOp or FunavOp operators for a function call,\n   one for each result returned by the function call.\n#. If the *i*-th result is a parameter (variable)\n   the corresponding operator is FunrpOp ( FunrvOp ).\n#. The FunrpOp operator has one argument and no result\n   (because the corresponding function result is not a variable).\n   The operator argument is the parameter index for the corresponding\n   result of the function call.\n#. The FunrvOp operator has no arguments and one variable result.\n   The new variable, created by this operator, gets its values from\n   the corresponding result of the function.\n\n{xrst_end var_atomic_op}\n-------------------------------------------------------------------------------\n{xrst_begin var_atomic_forward_any dev}\n\nAny Order Forward Atomic Function Call\n######################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ATOMIC_FORWARD_ANY\n   // END_ATOMIC_FORWARD_ANY\n}\n\n{xrst_template ;\n   include/cppad/local/var_op/template/atomic_op.xrst\n   headers: n_res, i_z, itr, play, parameter, trace, work\n\n   @mode@ ; forward\n}\n{xrst_template ;\n   include/cppad/local/var_op/template/forward_op.xrst\n   headers: cap_order, order_low, order_up, taylor\n}\n\n{xrst_end var_atomic_forward_any}\n*/\n\n\n// BEGIN_ATOMIC_FORWARD_ANY\ntemplate <class Base, class RecBase>\nvoid atomic_forward_any(\n   play::const_sequential_iterator& itr        ,\n   const player<Base>*              play       ,\n   const Base*                      parameter  ,\n   bool                             trace      ,\n   atomic_op_work<Base>&            work       ,\n   size_t                           cap_order  ,\n   size_t                           order_low  ,\n   size_t                           order_up   ,\n   Base*                            taylor     )\n// END_ATOMIC_FORWARD_ANY\n{  //\n   // vector\n   using CppAD::vector;\n   //\n   // par_is_dyn\n   const pod_vector<bool>& par_is_dyn( play->par_is_dyn() );\n   //\n   // n_order\n   size_t n_order = order_up + 1;\n   //\n   // op_code, i_var, arg\n   op_code_var   op_code;\n   size_t        i_var;\n   const addr_t* arg;\n   itr.op_info(op_code, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op_code == AFunOp );\n   CPPAD_ASSERT_NARG_NRES(op_code, 4, 0);\n   //\n   if( trace )\n   {  printOp<Base, RecBase>(\n         std::cout, play, itr.op_index(), i_var, op_code, arg\n      );\n      std::cout << std::endl;\n   }\n   //\n   // atom_index, call_id, m, n\n   size_t atom_index, call_id, m, n;\n   play::atom_op_info<RecBase>(op_code, arg, atom_index, call_id, m, n);\n   //\n   // parameter_x, type_x, taylor_x, taylor_y, index_y, variable_y\n   work.resize(m, n, n_order, forward_op_sweep);\n   vector<Base>&         parameter_x( work.parameter_x );\n   vector<ad_type_enum>& type_x( work.type_x );\n   //\n   vector<Base>&         taylor_x( work.taylor_x );\n   vector<Base>&         taylor_y( work.taylor_y );\n   //\n   vector<size_t>&       index_y( work.index_y );\n   vector<bool>&         variable_y( work.variable_y );\n   //\n   // j\n   for(size_t j = 0; j < n; ++j)\n   {  //\n      // op_code, arg, i_var\n      (++itr).op_info(op_code, arg, i_var);\n      if( trace )\n      {  printOp<Base, RecBase>(\n            std::cout, play, itr.op_index(), i_var, op_code, arg\n         );\n         std::cout << std::endl;\n      }\n      //\n      // type_x, parameter_x, taylor_x\n      switch(op_code)\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         //\n         // FunapOp\n         case FunapOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_par_all() );\n         if( par_is_dyn[ arg[0] ] )\n            type_x[j]    = dynamic_enum;\n         else\n            type_x[j]    = constant_enum;\n         parameter_x[j]             = parameter[ arg[0] ];\n         taylor_x[j * n_order + 0]  = parameter[ arg[0] ];\n         for(size_t k = 1; k < n_order; ++k)\n            taylor_x[j * n_order + k] = Base(0.0);\n         break;\n         //\n         // FunavOp\n         case FunavOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_var() );\n         type_x[j]       = variable_enum;\n         parameter_x[j]  = CppAD::numeric_limits<Base>::quiet_NaN();\n         for(size_t k = 0; k < n_order; ++k)\n            taylor_x[j * n_order + k] =\n               taylor[ size_t(arg[0]) * cap_order  + k ];\n         break;\n      }\n   }\n   //\n   // index_y, variable_y\n   for(size_t i = 0; i < m; ++i)\n   {  //\n      // op_code, arg, i_var\n      (++itr).op_info(op_code, arg, i_var);\n      //\n      //\n      switch(op_code)\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         //\n         // FunrpOp\n         case FunrpOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_par_all() );\n         index_y[i]    = std::numeric_limits<size_t>::max();\n         variable_y[i] = false;\n         if( 0 < order_low )\n            taylor_y[i * n_order + 0] = parameter[ arg[0] ];\n         for(size_t k = 1; k < order_low; ++k)\n            taylor_y[i * n_order + k] = Base(0.0);\n         if( trace )\n         {  printOp<Base, RecBase>(\n               std::cout, play, itr.op_index(), i_var, op_code, arg\n            );\n            std::cout << std::endl;\n         }\n         break;\n         //\n         // FunrvOp\n         case FunrvOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 0, 1);\n         CPPAD_ASSERT_UNKNOWN( 0 < i_var );\n         index_y[i]    = i_var;\n         variable_y[i] = true;\n         for(size_t k = 0; k < order_low; ++k)\n            taylor_y[i * n_order + k] = taylor[i_var * cap_order + k];\n         break;\n      }\n   }\n   //\n   // op_code\n   (++itr).op_info(op_code, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op_code == AFunOp );\n   //\n   // taylor_y\n   size_t need_y = size_t(variable_enum);\n   sweep::call_atomic_forward<Base, RecBase>(\n      parameter_x,\n      type_x,\n      need_y,\n      variable_y,\n      order_low,\n      order_up,\n      atom_index,\n      call_id,\n      taylor_x,\n      taylor_y\n   );\n   //\n   // taylor\n   for(size_t i = 0; i < m; ++i)\n   {  if( variable_y[i] )\n      {  for(size_t k = order_low; k < n_order; ++k)\n            taylor[ index_y[i] * cap_order  + k ] = taylor_y[i * n_order + k];\n         if( trace )\n         {  const addr_t* null_addr = static_cast<addr_t*>( nullptr );\n            printOp<Base, RecBase>(\n               std::cout, play, itr.op_index(), index_y[i], FunrvOp, null_addr\n            );\n            Base* yi_ptr          = taylor + index_y[i] * cap_order + 0;\n            const Base* null_base = static_cast<Base*>( nullptr );\n            printOpResult<Base>(\n               std::cout, n_order, yi_ptr, 0, null_base\n            );\n            std::cout << std::endl;\n         }\n      }\n   }\n   //\n   return;\n}\n/*\n-----------------------------------------------------------------------------\n{xrst_begin var_atomic_forward_dir dev}\n\nMultiple Direction Forward Atomic Function Call\n###############################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ATOMIC_FORWARD_DIR\n   // END_ATOMIC_FORWARD_DIR\n}\n\n{xrst_template ;\n   include/cppad/local/var_op/template/atomic_op.xrst\n   headers: n_res, i_z, itr, play, parameter, trace, work\n\n   @mode@ ; forward\n}\n{xrst_template ;\n   include/cppad/local/var_op/template/forward_dir.xrst\n   headers: n_dir, cap_order, order_up, taylor\n}\n\n\n{xrst_end var_atomic_forward_dir}\n*/\n// BEGIN_ATOMIC_FORWARD_DIR\ntemplate <class Base, class RecBase>\nvoid atomic_forward_dir(\n   play::const_sequential_iterator& itr        ,\n   const player<Base>*              play       ,\n   const Base*                      parameter  ,\n   bool                             trace      ,\n   atomic_op_work<Base>&            work       ,\n   size_t                           cap_order  ,\n   size_t                           order_up   ,\n   size_t                           n_dir      ,\n   Base*                            taylor     )\n// END_ATOMIC_FORWARD_DIR\n{  //\n   // order_low\n   size_t order_low = order_up;\n   //\n   // vector\n   using CppAD::vector;\n   //\n   // taylor_index\n   size_t per_variable = (cap_order - 1) * n_dir + 1;\n   auto taylor_index = [per_variable, n_dir]\n      (size_t variable_index, size_t order, size_t dir)\n   {  size_t index = variable_index * per_variable;\n      if( order > 0 )\n         index += (order - 1) * n_dir + 1 + dir;\n      return index;\n   };\n   //\n   // par_is_dyn\n   const pod_vector<bool>& par_is_dyn( play->par_is_dyn() );\n   //\n   // n_order\n   size_t n_order = order_up + 1;\n   //\n   // op_code, i_var, arg\n   op_code_var   op_code;\n   size_t        i_var;\n   const addr_t* arg;\n   itr.op_info(op_code, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op_code == AFunOp );\n   CPPAD_ASSERT_NARG_NRES(op_code, 4, 0);\n   //\n   if( trace )\n   {  printOp<Base, RecBase>(\n         std::cout, play, itr.op_index(), i_var, op_code, arg\n      );\n      std::cout << std::endl;\n   }\n   //\n   // atom_index, call_id, m, n\n   size_t atom_index, call_id, m, n;\n   play::atom_op_info<RecBase>(op_code, arg, atom_index, call_id, m, n);\n   //\n   // parameter_x, type_x, taylor_x, taylor_y, index_x, index_y, variable_y\n   work.resize(m, n, n_order, forward_dir_sweep);\n   vector<Base>&         parameter_x( work.parameter_x );\n   vector<ad_type_enum>& type_x( work.type_x );\n   //\n   vector<Base>&         taylor_x( work.taylor_x );\n   vector<Base>&         taylor_y( work.taylor_y );\n   //\n   vector<size_t>&       index_x( work.index_x );\n   vector<size_t>&       index_y( work.index_y );\n   vector<bool>&         variable_y(work.variable_y );\n\n   //\n   // j\n   for(size_t j = 0; j < n; ++j)\n   {  //\n      // op_code, arg, i_var\n      (++itr).op_info(op_code, arg, i_var);\n      if( trace )\n      {  printOp<Base, RecBase>(\n            std::cout, play, itr.op_index(), i_var, op_code, arg\n         );\n         std::cout << std::endl;\n      }\n      //\n      // index_x, type_x, parameter_x\n      switch(op_code)\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         //\n         // FunapOp\n         case FunapOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_par_all() );\n         index_x[j] = std::numeric_limits<size_t>::max();\n         if( par_is_dyn[ arg[0] ] )\n            type_x[j]    = dynamic_enum;\n         else\n            type_x[j]    = constant_enum;\n         parameter_x[j]  = parameter[ arg[0] ];\n         break;\n         //\n         // FunavOp\n         case FunavOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_var() );\n         index_x[j]      = size_t( arg[0] );\n         type_x[j]       = variable_enum;\n         parameter_x[j]  = CppAD::numeric_limits<Base>::quiet_NaN();\n         break;\n      }\n   }\n   //\n   // index_y, variable_y\n   for(size_t i = 0; i < m; ++i)\n   {  //\n      // op_code, arg, i_var\n      (++itr).op_info(op_code, arg, i_var);\n      //\n      //\n      switch(op_code)\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         //\n         // FunrpOp\n         case FunrpOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_par_all() );\n         index_y[i]    = size_t( arg[0] );\n         variable_y[i] = false;\n         if( trace )\n         {  printOp<Base, RecBase>(\n               std::cout, play, itr.op_index(), i_var, op_code, arg\n            );\n            std::cout << std::endl;\n         }\n         break;\n         //\n         // FunrvOp\n         case FunrvOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 0, 1);\n         CPPAD_ASSERT_UNKNOWN( 0 < i_var );\n         index_y[i]    = i_var;\n         variable_y[i] = true;\n         break;\n      }\n   }\n   //\n   // op_code\n   (++itr).op_info(op_code, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op_code == AFunOp );\n   //\n   // dir\n   for(size_t dir = 0; dir < n_dir; ++dir)\n   {\n      //\n      // taylor_x\n      for(size_t j = 0; j < n; ++j)\n      {  if( type_x[j] != variable_enum )\n         {  taylor_x[j * n_order + 0] = parameter_x[j];\n            for(size_t k = 1; k < n_order; ++k)\n               taylor_x[j * n_order + k] = Base(0.0);\n         }\n         else\n         {  for(size_t k = 0; k < n_order; ++k)\n            {  size_t index              = taylor_index(index_x[j], k, dir);\n               taylor_x[j * n_order + k] = taylor[index];\n            }\n         }\n      }\n      //\n      // taylor_y\n      for(size_t i = 0; i < m; ++i)\n      {  if( ! variable_y[i] )\n         {  if( 0 < order_low )\n               taylor_y[i * n_order + 0] = parameter[ index_y[i] ];\n            for(size_t k = 1; k < order_low; ++k)\n               taylor_y[i * n_order + k] = Base(0.0);\n         }\n         else\n         {  for(size_t k = 0; k < order_low; ++k)\n            {  size_t index              = taylor_index(index_y[i], k, dir);\n               taylor_y[i * n_order + k] = taylor[index];\n            }\n         }\n      }\n      size_t need_y = size_t(variable_enum);\n      sweep::call_atomic_forward<Base, RecBase>(\n         parameter_x,\n         type_x,\n         need_y,\n         variable_y,\n         order_low,\n         order_up,\n         atom_index,\n         call_id,\n         taylor_x,\n         taylor_y\n      );\n      //\n      // taylor\n      for(size_t i = 0; i < m; ++i) if( variable_y[i] )\n      {  for(size_t k = order_low; k < n_order; ++k)\n         {  size_t index  = taylor_index(index_y[i], k, dir);\n            taylor[index] = taylor_y[i * n_order + k];\n         }\n         if( trace )\n         {  const addr_t* null_addr = static_cast<addr_t*>( nullptr );\n            if( dir == 0 )\n            {  printOp<Base, RecBase>(\n               std::cout, play, itr.op_index(), index_y[i], FunrvOp, null_addr\n               );\n               std::cout << std::endl;\n            }\n            Base* yi_ptr          = taylor_y.data() + i * n_order;\n            const Base* null_base = static_cast<Base*>( nullptr );\n            std::cout << \"     \";\n            printOpResult<Base>(\n               std::cout, n_order, yi_ptr, 0, null_base\n            );\n            std::cout << std::endl;\n         }\n      }\n   }\n   //\n   return;\n}\n/*\n-------------------------------------------------------------------------------\n{xrst_begin var_atomic_reverse dev}\n{xrst_spell\n   subgraph\n}\n\nReverse Atomic Function Call\n############################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ATOMIC_REVERSE\n   // END_ATOMIC_REVERSE\n}\n\nIterator\n********\nthis template parameter is either\n``play::subgraph_iterator`` or\n``play::const_sequential_iterator`` .\n\n{xrst_template ;\n   include/cppad/local/var_op/template/atomic_op.xrst\n   headers: n_res, i_z, itr, play, parameter, trace, work\n   headers if @mode@ is reverse: G and H\n\n   @mode@ ; reverse\n}\n\ncap_order\n*********\nsee atomic_forward_any :ref:`var_atomic_forward_any@cap_order`\n\nn_order\n*******\nis the number of Taylor coefficient orders that we are\ncomputing the partial derivatives with respect to.\n\ntaylor\n******\nThe Taylor coefficient for the variable with index j and order k is::\n\n   taylor[ j * cap_order + k ]\n\npartial\n*******\nThe partial derivative with respect to the order *k* Taylor coefficient\nfor the variable with index *j* is::\n\n   partial[ j * n_order + k ]\n\nOn input, *partial* contains the partial derivatives of *G*\nwith respect to the Taylor coefficients of the arguments to *G* .\nOn output, *partial* contains the partial derivatives of *H*\nwith respect to the Taylor coefficients of the arguments to *H* .\nWe only have partials with respect to variables; i.e.,\n*partial* does not included derivatives with respect to\nthe parameters in *x* or *y* .\n~\n\n{xrst_end var_atomic_reverse}\n*/\n// BEGIN_ATOMIC_REVERSE\ntemplate <class Base, class RecBase, class Iterator>\nvoid atomic_reverse(\n   Iterator&                        itr        ,\n   const player<Base>*              play       ,\n   const Base*                      parameter  ,\n   bool                             trace      ,\n   atomic_op_work<Base>&            work       ,\n   size_t                           cap_order  ,\n   size_t                           n_order    ,\n   const Base*                      taylor     ,\n   Base*                            partial    )\n// END_ATOMIC_REVERSE\n{  CPPAD_ASSERT_UNKNOWN( 0 < n_order );\n   //\n   // vector\n   using CppAD::vector;\n   //\n   // par_is_dyn\n   const pod_vector<bool>& par_is_dyn( play->par_is_dyn() );\n   //\n   // n_order\n   size_t order_up = n_order - 1;\n   //\n   // op_code, i_var, arg\n   op_code_var   op_code;\n   size_t        i_var;\n   const addr_t* arg;\n   itr.op_info(op_code, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op_code == AFunOp );\n   CPPAD_ASSERT_NARG_NRES(op_code, 4, 0);\n   //\n   if( trace )\n   {  printOp<Base, RecBase>(\n         std::cout, play, itr.op_index(), i_var, op_code, arg\n      );\n      std::cout << std::endl;\n   }\n   //\n   // atom_index, call_id, m, n\n   size_t atom_index, call_id, m, n;\n   play::atom_op_info<RecBase>(op_code, arg, atom_index, call_id, m, n);\n   //\n   // parameter_x, type_x,\n   // taylor_x, taylor_y, partial_x, partial_y, variable_x, index_x\n   work.resize(m, n, n_order, reverse_op_sweep);\n   vector<Base>&         parameter_x( work.parameter_x );\n   vector<ad_type_enum>& type_x( work.type_x );\n   //\n   vector<Base>&         taylor_x( work.taylor_x );\n   vector<Base>&         taylor_y( work.taylor_y );\n   //\n   vector<Base>&         partial_x( work.partial_x );\n   vector<Base>&         partial_y( work.partial_y );\n   //\n   vector<bool>&         variable_x( work.variable_x );\n   vector<size_t>&       index_x( work.index_x );\n   //\n   // i\n   for(size_t ip1 = m; ip1 > 0; --ip1)\n   {  size_t i = ip1 - 1;\n      //\n      // op_code, arg, i_var\n      (--itr).op_info(op_code, arg, i_var);\n      if( trace )\n      {  printOp<Base, RecBase>(\n            std::cout, play, itr.op_index(), i_var, op_code, arg\n         );\n      }\n      //\n      // taylor_y, partial_y\n      switch(op_code)\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         //\n         // FunrpOp\n         case FunrpOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_par_all() );\n         taylor_y[i * n_order + 0]  = parameter[ arg[0] ];\n         partial_y[i * n_order + 0] = Base(0.0);\n         for(size_t k = 1; k < n_order; ++k)\n         {  partial_y[i * n_order + k] = Base(0.0);\n            taylor_y[ i * n_order + k] = Base(0.0);\n         }\n         break;\n         //\n         // FunrvOp\n         case FunrvOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 0, 1);\n         CPPAD_ASSERT_UNKNOWN( 0 < i_var );\n         for(size_t k = 0; k < n_order; ++k)\n         {  taylor_y[ i * n_order + k] = taylor[i_var * cap_order + k];\n            partial_y[i * n_order + k] = partial[i_var * n_order + k];\n         }\n         if( trace )\n         {  const Base* t_ptr = taylor + i_var * cap_order;\n            const Base* p_ptr = partial + i_var * n_order;\n            printOpResult(\n               std::cout,\n               n_order,\n               t_ptr,\n               n_order,\n               p_ptr\n            );\n         }\n         break;\n      }\n      if( trace )\n         std::cout << std::endl;\n   }\n   //\n   // j\n   for(size_t jp1 = n; jp1 > 0; --jp1)\n   {  size_t j = jp1 - 1;\n      //\n      // op_code, arg, i_var\n      (--itr).op_info(op_code, arg, i_var);\n      if( trace )\n      {  printOp<Base, RecBase>(\n            std::cout, play, itr.op_index(), i_var, op_code, arg\n         );\n         std::cout << std::endl;\n      }\n      //\n      // variable_x, type_x\n      switch(op_code)\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         //\n         // FunapOp\n         case FunapOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_par_all() );\n         variable_x[j] = false;\n         index_x[j]    = size_t( arg[0] );\n         if( par_is_dyn[ arg[0] ] )\n            type_x[j]    = dynamic_enum;\n         else\n            type_x[j]    = constant_enum;\n         parameter_x[j]             = parameter[ arg[0] ];\n         taylor_x[j * n_order + 0]  = parameter[ arg[0] ];\n         for(size_t k = 1; k < n_order; ++k)\n            taylor_x[j * n_order + k] = Base(0.0);\n         break;\n         //\n         // FunavOp\n         case FunavOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_var() );\n         variable_x[j]   = true;\n         index_x[j]      = size_t( arg[0] );\n         type_x[j]       = variable_enum;\n         parameter_x[j]  = CppAD::numeric_limits<Base>::quiet_NaN();\n         for(size_t k = 0; k < n_order; ++k)\n            taylor_x[j * n_order + k] =\n               taylor[ size_t(arg[0]) * cap_order  + k ];\n         break;\n      }\n   }\n   //\n   // op_code\n   (--itr).op_info(op_code, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op_code == AFunOp );\n   //\n   // partial_y\n   sweep::call_atomic_reverse<Base, RecBase>(\n      parameter_x,\n      type_x,\n      variable_x,\n      order_up,\n      atom_index,\n      call_id,\n      taylor_x,\n      taylor_y,\n      partial_x,\n      partial_y\n   );\n   //\n   // taylor\n   for(size_t j = 0; j < n; ++j)\n   {  if( variable_x[j] )\n      {  for(size_t k = 0; k < n_order; ++k)\n         {  size_t index = index_x[j] * n_order + k;\n            partial[index] += partial_x[j * n_order + k];\n         }\n      }\n   }\n   //\n   return;\n}\n/*\n-------------------------------------------------------------------------------\n{xrst_begin var_atomic_for_jac dev}\n\nForward Jacobian Sparsity Atomic Function Call\n##############################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ATOMIC_FOR_JAC\n   // END_ATOMIC_FOR_JAC\n}\n\n{xrst_template ;\n   include/cppad/local/var_op/template/atomic_op.xrst\n   headers: n_res, i_z, itr, play, parameter, trace, work\n\n   @mode@ ; forward\n}\n\nVector_set\n**********\nis the type used for vectors of sets. It must satisfy the\n:ref:`SetVector-name` concept.\n\nvar_sparsity\n************\n\nInput\n=====\n::\n\n   for j = 0, ..., i_z - n_res\n      The set with index j in var_sparsity\n\nOutput\n======\n::\n\n   for j = i_z , ... , i_z - n_res + 1\n      The set with index j in var_sparsity\n\n{xrst_end var_atomic_for_jac}\n*/\n// BEGIN_ATOMIC_FOR_JAC\ntemplate <class Vector_set, class Base, class RecBase>\ninline void atomic_for_jac(\n   play::const_sequential_iterator& itr          ,\n   const player<Base>*              play         ,\n   const Base*                      parameter    ,\n   bool                             trace        ,\n   atomic_op_work<Base>&            work         ,\n   bool                             dependency   ,\n   Vector_set&                      var_sparsity )\n// END_ATOMIC_FOR_JAC\n{  //\n   //\n   // vector\n   using CppAD::vector;\n   //\n   // par_is_dyn\n   const pod_vector<bool>& par_is_dyn( play->par_is_dyn() );\n   //\n   // op_code, i_var, arg\n   op_code_var   op_code;\n   size_t        i_var;\n   const addr_t* arg;\n   itr.op_info(op_code, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op_code == AFunOp );\n   CPPAD_ASSERT_NARG_NRES(op_code, 4, 0);\n   //\n   if( trace )\n   {  printOp<Base, RecBase>(\n         std::cout, play, itr.op_index(), i_var, op_code, arg\n      );\n      std::cout << std::endl;\n   }\n   //\n   // atom_index, call_id, m, n\n   size_t atom_index, call_id, m, n;\n   play::atom_op_info<RecBase>(op_code, arg, atom_index, call_id, m, n);\n   //\n   // parameter_x, type_x, index_x, index_y\n   size_t n_order = 0;\n   work.resize(m, n, n_order, for_jac_sweep);\n   vector<Base>&         parameter_x( work.parameter_x );\n   vector<ad_type_enum>& type_x( work.type_x );\n   vector<size_t>&       index_x( work.index_x );\n   vector<size_t>&       index_y( work.index_y );\n   //\n   // j\n   for(size_t j = 0; j < n; ++j)\n   {  //\n      // op_code, arg, i_var\n      (++itr).op_info(op_code, arg, i_var);\n      if( trace )\n      {  printOp<Base, RecBase>(\n            std::cout, play, itr.op_index(), i_var, op_code, arg\n         );\n         std::cout << std::endl;\n      }\n      //\n      // type_x, parameter_x, index_x\n      switch(op_code)\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         //\n         // FunapOp\n         case FunapOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_par_all() );\n         if( par_is_dyn[ arg[0] ] )\n            type_x[j]    = dynamic_enum;\n         else\n            type_x[j]    = constant_enum;\n         parameter_x[j]  = parameter[ arg[0] ];\n         index_x[j]      = 0; // special variable index used for parameters\n         break;\n         //\n         // FunavOp\n         case FunavOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_var() );\n         type_x[j]       = variable_enum;\n         parameter_x[j]  = CppAD::numeric_limits<Base>::quiet_NaN();\n         index_x[j]      = size_t(arg[0]);\n         break;\n      }\n   }\n   //\n   // i\n   for(size_t i = 0; i < m; ++i)\n   {  //\n      // op_code, arg, i_var\n      (++itr).op_info(op_code, arg, i_var);\n      //\n      // index_y\n      switch(op_code)\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         //\n         // FunrpOp\n         case FunrpOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_par_all() );\n         index_y[i]       = 0;  // special variable index used for parameters\n         break;\n         //\n         // FunrvOp\n         case FunrvOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 0, 1);\n         CPPAD_ASSERT_UNKNOWN( 0 < i_var );\n         index_y[i]    = i_var;\n         break;\n      }\n   }\n   //\n   // op_code\n   (++itr).op_info(op_code, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op_code == AFunOp );\n   //\n   // varsparsity\n   sweep::call_atomic_for_jac_sparsity<Base,RecBase>(\n      atom_index,\n      call_id,\n      dependency,\n      parameter_x,\n      type_x,\n      index_x,\n      index_y,\n      var_sparsity\n   );\n   //\n   if( trace )\n   {  size_t end = var_sparsity.end();\n      CppAD::vectorBool this_row(end);\n      addr_t*  arg_tmp = { 0 };\n      for(size_t i = 0; i < m; ++i)\n      {  size_t j_var = index_y[i];\n         for(size_t j = 0; j < end; ++j)\n            this_row[j] = false;\n         typename Vector_set::const_iterator itr_sparse(var_sparsity, j_var);\n         size_t j = *itr_sparse;\n         while( j < end )\n         {  this_row[j] = true;\n            j = *(++itr_sparse);\n         }\n         if( 0 < j_var )\n         {  printOp<Base, RecBase>(\n               std::cout,\n               play,\n               itr.op_index() - m + i,\n               j_var,\n               FunrvOp,\n               arg_tmp\n            );\n            printOpResult(\n               std::cout,\n               1,\n               &this_row,\n               0,\n               (CppAD::vectorBool *) nullptr\n            );\n            std::cout << std::endl;\n         }\n      }\n   }\n   return;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_atomic_rev_jac dev}\n\nReverse Jacobian Sparsity Atomic Function Call\n##############################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ATOMIC_REV_JAC\n   // END_ATOMIC_REV_JAC\n}\n\n{xrst_template ;\n   include/cppad/local/var_op/template/atomic_op.xrst\n   headers: n_res, i_z, itr, play, parameter, trace, work\n   headers if @mode@ is reverse: G and H\n\n   @mode@ ; reverse\n}\n\nVector_set\n**********\nis the type used for vectors of sets. It must satisfy the\n:ref:`SetVector-name` concept.\n\nvar_sparsity\n************\nOn input, *var_sparsity* contains the sparsity pattern for\n:math:`G [ y, x, \\cdots ]` .\nOn output it contains the sparsity pattern for\n:math:`H ( x, \\cdots )` .\n\n{xrst_end var_atomic_rev_jac}\n*/\n// BEGIN_ATOMIC_REV_JAC\ntemplate <class Vector_set, class Base, class RecBase>\ninline void atomic_rev_jac(\n   play::const_sequential_iterator& itr          ,\n   const player<Base>*              play         ,\n   const Base*                      parameter    ,\n   bool                             trace        ,\n   atomic_op_work<Base>&            work         ,\n   bool                             dependency   ,\n   Vector_set&                      var_sparsity )\n// END_ATOMIC_REV_JAC\n{  //\n   //\n   // vector\n   using CppAD::vector;\n   //\n   // par_is_dyn\n   const pod_vector<bool>& par_is_dyn( play->par_is_dyn() );\n   //\n   // op_code, i_var, arg\n   op_code_var   op_code;\n   size_t        i_var;\n   const addr_t* arg;\n   itr.op_info(op_code, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op_code == AFunOp );\n   CPPAD_ASSERT_NARG_NRES(op_code, 4, 0);\n   //\n   if( trace )\n   {  printOp<Base, RecBase>(\n         std::cout, play, itr.op_index(), i_var, op_code, arg\n      );\n      std::cout << std::endl;\n   }\n   //\n   // atom_index, call_id, m, n\n   size_t atom_index, call_id, m, n;\n   play::atom_op_info<RecBase>(op_code, arg, atom_index, call_id, m, n);\n   //\n   // parameter_x, type_x, index_x, index_y\n   size_t n_order = 0;\n   work.resize(m, n, n_order, rev_jac_sweep);\n   vector<Base>&         parameter_x( work.parameter_x );\n   vector<ad_type_enum>& type_x( work.type_x );\n   vector<size_t>&       index_x( work.index_x );\n   vector<size_t>&       index_y( work.index_y );\n   //\n   // i\n   for(size_t ip1 = m; ip1 > 0; --ip1)\n   {  size_t i = ip1 - 1;\n      //\n      // op_code, arg, i_var\n      (--itr).op_info(op_code, arg, i_var);\n      //\n      // index_y\n      switch(op_code)\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         //\n         // FunrpOp\n         case FunrpOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_par_all() );\n         index_y[i]       = 0;  // special variable index used for parameters\n         break;\n         //\n         // FunrvOp\n         case FunrvOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 0, 1);\n         CPPAD_ASSERT_UNKNOWN( 0 < i_var );\n         index_y[i]    = i_var;\n         break;\n      }\n   }\n   if( trace )\n   {  size_t end = var_sparsity.end();\n      CppAD::vectorBool this_row(end);\n      const addr_t* arg_null = static_cast<addr_t*>(nullptr);\n      for(size_t ip1 = m; ip1 > 0; --ip1)\n      {  size_t i = ip1 - 1;\n         if( index_y[i] > 0 )\n         {  for(size_t j = 0; j < end; ++j)\n               this_row[j] = false;\n            //\n            typedef typename Vector_set::const_iterator itr_sparse_t;\n            itr_sparse_t itr_sparse(var_sparsity, index_y[i]);\n            size_t j = *itr_sparse;\n            while( j < end )\n            {  this_row[j] = true;\n               j = *(++itr_sparse);\n            }\n            printOp<Base, RecBase>(\n               std::cout,\n               play,\n               itr.op_index() + i,\n               index_y[i],\n               FunrvOp,\n               arg_null\n            );\n            printOpResult(\n               std::cout,\n               1,\n               &this_row,\n               0,\n               (CppAD::vectorBool *) nullptr\n            );\n            std::cout << std::endl;\n         }\n      }\n   }\n   //\n   // j\n   for(size_t jp1 = n; jp1 > 0; --jp1)\n   {  size_t j = jp1 - 1;\n      //\n      // op_code, arg, i_var\n      (--itr).op_info(op_code, arg, i_var);\n      if( trace )\n      {  printOp<Base, RecBase>(\n            std::cout, play, itr.op_index(), i_var, op_code, arg\n         );\n         std::cout << std::endl;\n      }\n      //\n      // type_x, parameter_x, index_x\n      switch(op_code)\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         //\n         // FunapOp\n         case FunapOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_par_all() );\n         if( par_is_dyn[ arg[0] ] )\n            type_x[j]    = dynamic_enum;\n         else\n            type_x[j]    = constant_enum;\n         parameter_x[j]  = parameter[ arg[0] ];\n         index_x[j]      = 0; // special variable index used for parameters\n         break;\n         //\n         // FunavOp\n         case FunavOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_var() );\n         type_x[j]       = variable_enum;\n         parameter_x[j]  = CppAD::numeric_limits<Base>::quiet_NaN();\n         index_x[j]      = size_t(arg[0]);\n         break;\n      }\n   }\n   //\n   // op_code\n   (--itr).op_info(op_code, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op_code == AFunOp );\n   //\n   // varsparsity\n   sweep::call_atomic_rev_jac_sparsity<Base,RecBase>(\n      atom_index,\n      call_id,\n      dependency,\n      parameter_x,\n      type_x,\n      index_x,\n      index_y,\n      var_sparsity\n   );\n   return;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_atomic_rev_hes dev}\n\nReverse Hessian Sparsity Atomic Function Call\n#############################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ATOMIC_REV_HES\n   // END_ATOMIC_REV_HES\n}\n\n{xrst_template ;\n   include/cppad/local/var_op/template/atomic_op.xrst\n   headers: n_res, i_z, itr, play, parameter, trace, work\n   headers if @mode@ is reverse: G and H\n\n   @mode@ ; reverse\n}\n\nnum_var\n*******\nWe use the notation *num_var* for the number of variables on the tape\n(including the phantom variable at index zero); i.e.::\n``play->num_var()`` .\n\nfor_jac_sparsity\n****************\nThe set with index *j* is the forward Jacobian sparsity\npattern for the variable with index *j*.\n\nrev_jac_include\n***************\nIf the *j* element of this vector is true,\nthe variable with index *j* is included in the Hessian,\nor affects the value of a variable that is included in the Hessian.\n\nInput\n=====\n::\n\n   for j = num_var, ... , i_z + 1\n      rev_jac_include[j] is an input\n\nOutput\n======\n::\n\n   for j = i_z , ... , i_z - n_res + 1\n      rev_jac_include[j] is an output\n\nrev_hes_sparsity\n****************\nOn input (output), this is the sparsity pattern for *G* ( *H* ).\nFor each variable index *j* ,\n*rev_hes_sparsity* [ *j* ] is the set of indices\nthat may have non-zero cross partials with variable index *j* .\n\nExample\n=======\nIf the indices in the sets correspond to the independent variables,\nthen *rev_hes_sparsity* ``.end()`` is the number of independent variables.\nFor *i* a variable index between 1 and the number of independent variables,\n*i* - 1 is the corresponding independent variable index.\n(The index *i* = 0 corresponds to the phantom variable at the beginning\nof the tape. )\n\n{xrst_end var_atomic_rev_hes}\n*/\n// BEGIN_ATOMIC_REV_HES\ntemplate <class Vector_set, class Base, class RecBase>\ninline void atomic_rev_hes(\n   play::const_sequential_iterator& itr               ,\n   const player<Base>*              play              ,\n   const Base*                      parameter         ,\n   bool                             trace             ,\n   atomic_op_work<Base>&            work              ,\n   const Vector_set&                for_jac_sparsity  ,\n   bool*                            rev_jac_include   ,\n   Vector_set&                      rev_hes_sparsity  )\n// END_ATOMIC_REV_HES\n{  //\n   //\n   CPPAD_ASSERT_UNKNOWN( for_jac_sparsity.n_set() == play->num_var() );\n   CPPAD_ASSERT_UNKNOWN( rev_hes_sparsity.n_set() == play->num_var() );\n   CPPAD_ASSERT_UNKNOWN( for_jac_sparsity.end()   == rev_hes_sparsity.end() );\n   //\n   // vector\n   using CppAD::vector;\n   //\n   // par_is_dyn\n   const pod_vector<bool>& par_is_dyn( play->par_is_dyn() );\n   //\n   // op_code, i_var, arg\n   op_code_var   op_code;\n   size_t        i_var;\n   const addr_t* arg;\n   itr.op_info(op_code, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op_code == AFunOp );\n   CPPAD_ASSERT_NARG_NRES(op_code, 4, 0);\n   //\n   if( trace )\n   {  printOp<Base, RecBase>(\n         std::cout, play, itr.op_index(), i_var, op_code, arg\n      );\n      std::cout << std::endl;\n   }\n   //\n   // atom_index, call_id, m, n\n   size_t atom_index, call_id, m, n;\n   play::atom_op_info<RecBase>(op_code, arg, atom_index, call_id, m, n);\n   //\n   // parameter_x, type_x, index_x, index_y\n   size_t n_order = 0;\n   work.resize(m, n, n_order, rev_hes_sweep);\n   vector<Base>&         parameter_x( work.parameter_x );\n   vector<ad_type_enum>& type_x( work.type_x );\n   vector<size_t>&       index_x( work.index_x );\n   vector<size_t>&       index_y( work.index_y );\n   //\n   // i\n   for(size_t ip1 = m; ip1 > 0; --ip1)\n   {  size_t i = ip1 - 1;\n      //\n      // op_code, arg, i_var\n      (--itr).op_info(op_code, arg, i_var);\n      //\n      // index_y\n      switch(op_code)\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         //\n         // FunrpOp\n         case FunrpOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_par_all() );\n         index_y[i]       = 0;  // special variable index used for parameters\n         break;\n         //\n         // FunrvOp\n         case FunrvOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 0, 1);\n         CPPAD_ASSERT_UNKNOWN( 0 < i_var );\n         index_y[i]    = i_var;\n         break;\n      }\n   }\n   //\n   // j\n   for(size_t jp1 = n; jp1 > 0; --jp1)\n   {  size_t j = jp1 - 1;\n      //\n      // op_code, arg, i_var\n      (--itr).op_info(op_code, arg, i_var);\n      if( trace )\n      {  printOp<Base, RecBase>(\n            std::cout, play, itr.op_index(), i_var, op_code, arg\n         );\n         std::cout << std::endl;\n      }\n      //\n      // type_x, parameter_x, index_x\n      switch(op_code)\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         //\n         // FunapOp\n         case FunapOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_par_all() );\n         if( par_is_dyn[ arg[0] ] )\n            type_x[j]    = dynamic_enum;\n         else\n            type_x[j]    = constant_enum;\n         parameter_x[j]  = parameter[ arg[0] ];\n         index_x[j]      = 0; // special variable index used for parameters\n         break;\n         //\n         // FunavOp\n         case FunavOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_var() );\n         type_x[j]       = variable_enum;\n         parameter_x[j]  = CppAD::numeric_limits<Base>::quiet_NaN();\n         index_x[j]      = size_t(arg[0]);\n         break;\n      }\n   }\n   //\n   // op_code\n   (--itr).op_info(op_code, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op_code == AFunOp );\n   //\n   // rev_jac_include, rev_hes_sparsity\n   sweep::call_atomic_rev_hes_sparsity<Base,RecBase>(\n      atom_index,\n      call_id,\n      parameter_x,\n      type_x,\n      index_x,\n      index_y,\n      for_jac_sparsity,\n      rev_jac_include,\n      rev_hes_sparsity\n   );\n   //\n   if( trace )\n   {  typedef typename Vector_set::const_iterator itr_sparse_t;\n      size_t end = rev_hes_sparsity.end();\n      CppAD::vectorBool jac_row(end), hes_row(end);\n      addr_t*  arg_tmp = { 0 };\n      for(size_t i = 0; i < m; ++i)\n      {  size_t j_var = index_y[i];\n         if( 0 < j_var)\n         {\n            for(size_t j = 0; j < end; ++j)\n            {  jac_row[j]  = false;\n               hes_row[j]  = false;\n            }\n            itr_sparse_t itr_jac(for_jac_sparsity, j_var);\n            size_t j = *itr_jac;\n            while( j < end )\n            {  jac_row[j] = true;\n               j = *(++itr_jac);\n            }\n            itr_sparse_t itr_hes(rev_hes_sparsity, j_var);\n            j = *itr_hes;\n            while( j < end )\n            {  hes_row[j] = true;\n               j = *(++itr_hes);\n            }\n            printOp<Base, RecBase>(\n               std::cout,\n               play,\n               itr.op_index() - m + i,\n               j_var,\n               FunrvOp,\n               arg_tmp\n            );\n            printOpResult(\n               std::cout,\n               1,\n               &jac_row,\n               1,\n               &hes_row\n            );\n            std::cout << std::endl;\n         }\n      }\n   }\n   return;\n}\n/*\n-------------------------------------------------------------------------------\n{xrst_begin var_atomic_for_hes dev}\n\nForward Hessian Sparsity Atomic Function Call\n#############################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ATOMIC_FOR_HES\n   // END_ATOMIC_FOR_HES\n}\n\n{xrst_template ;\n   include/cppad/local/var_op/template/atomic_op.xrst\n   headers: n_res, i_z, itr, play, parameter, trace, work\n\n   @mode@ ; forward\n}\n\nVector_set\n**********\nis the type used for vectors of sets. It must satisfy the\n:ref:`SetVector-name` concept.\n\nn_independent_p1\n****************\nis the number of independent variables (in the tape) plus one.\n\nrev_jac_sparsity\n****************\nis the reverse Jacobian sparsity pattern for the scalar valued\nfunction that the Hessian sparsity is being computed for.\nZero is the only possible element in each set;\ni.e.. *ref_jac_sparsity* .end() == 1 .\nIf the set with index *j* is empty,\nthe derivative of the function w.r.t the variable with index *j* is zero.\n\nfor_hes_sparsity\n****************\nOn input, all the linear and nonlinear interactions up to the\narguments to the atomic function have been take into account.\nUpon return, the linear and nonlinear interactions in\nthe atomic function have been take into account.\n\nHessian Sparsity\n================\nFor *j* equal 1 to *n_independent_p1* - 1,\nif *i* is in set with index *j* ,\nthe Hessian may have a non-zero partial with respect to the\nindependent variables with indices ( *i* - 1, *j* - 1 ) .\nNote that the index zero is not used because it corresponds to the\nphantom variable on the tape.\n\nJacobian Sparsity\n=================\nIf *i* is in the set with index *n_independent_p1* + *j* ,\nthe variable with index *j* may have a non-zero partial with resect to the\nindependent variable with index *i* - 1 .\n\n{xrst_end var_atomic_for_hes}\n*/\n// BEGIN_ATOMIC_FOR_HES\ntemplate <class Vector_set, class Base, class RecBase>\ninline void atomic_for_hes(\n   play::const_sequential_iterator& itr              ,\n   const player<Base>*              play             ,\n   const Base*                      parameter        ,\n   bool                             trace            ,\n   atomic_op_work<Base>&            work             ,\n   size_t                           n_independent_p1 ,\n   const Vector_set&                rev_jac_sparsity ,\n   Vector_set&                      for_hes_sparsity )\n// END_ATOMIC_FOR_HES\n{  CPPAD_ASSERT_UNKNOWN( rev_jac_sparsity.end() == 1 );\n   //\n   CPPAD_ASSERT_UNKNOWN( for_hes_sparsity.end() == n_independent_p1 );\n   //\n   // vector\n   using CppAD::vector;\n   //\n   // par_is_dyn\n   const pod_vector<bool>& par_is_dyn( play->par_is_dyn() );\n   //\n   // op_code, i_var, arg\n   op_code_var   op_code;\n   size_t        i_var;\n   const addr_t* arg;\n   itr.op_info(op_code, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op_code == AFunOp );\n   CPPAD_ASSERT_NARG_NRES(op_code, 4, 0);\n   //\n   if( trace )\n   {  printOp<Base, RecBase>(\n         std::cout, play, itr.op_index(), i_var, op_code, arg\n      );\n      std::cout << std::endl;\n   }\n   //\n   // atom_index, call_id, m, n\n   size_t atom_index, call_id, m, n;\n   play::atom_op_info<RecBase>(op_code, arg, atom_index, call_id, m, n);\n   //\n   // parameter_x, type_x, index_x, index_y\n   size_t n_order = 0;\n   work.resize(m, n, n_order, for_hes_sweep);\n   vector<Base>&         parameter_x( work.parameter_x );\n   vector<ad_type_enum>& type_x( work.type_x );\n   vector<size_t>&       index_x( work.index_x );\n   vector<size_t>&       index_y( work.index_y );\n   //\n   // j\n   for(size_t j = 0; j < n; ++j)\n   {  //\n      // op_code, arg, i_var\n      (++itr).op_info(op_code, arg, i_var);\n      if( trace )\n      {  printOp<Base, RecBase>(\n            std::cout, play, itr.op_index(), i_var, op_code, arg\n         );\n         std::cout << std::endl;\n      }\n      //\n      // type_x, parameter_x, index_x\n      switch(op_code)\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         //\n         // FunapOp\n         case FunapOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_par_all() );\n         if( par_is_dyn[ arg[0] ] )\n            type_x[j]    = dynamic_enum;\n         else\n            type_x[j]    = constant_enum;\n         parameter_x[j]  = parameter[ arg[0] ];\n         index_x[j]      = 0; // special variable index used for parameters\n         break;\n         //\n         // FunavOp\n         case FunavOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_var() );\n         type_x[j]       = variable_enum;\n         parameter_x[j]  = CppAD::numeric_limits<Base>::quiet_NaN();\n         index_x[j]      = size_t(arg[0]);\n         break;\n      }\n   }\n   //\n   // i\n   for(size_t i = 0; i < m; ++i)\n   {  //\n      // op_code, arg, i_var\n      (++itr).op_info(op_code, arg, i_var);\n      //\n      // index_y\n      switch(op_code)\n      {  //\n         default:\n         CPPAD_ASSERT_UNKNOWN(false);\n         break;\n         //\n         // FunrpOp\n         case FunrpOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 1, 0);\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < play->num_par_all() );\n         index_y[i]       = 0;  // special variable index used for parameters\n         break;\n         //\n         // FunrvOp\n         case FunrvOp:\n         CPPAD_ASSERT_NARG_NRES(op_code, 0, 1);\n         CPPAD_ASSERT_UNKNOWN( 0 < i_var );\n         index_y[i]    = i_var;\n         break;\n      }\n   }\n   //\n   // op_code\n   (++itr).op_info(op_code, arg, i_var);\n   CPPAD_ASSERT_UNKNOWN( op_code == AFunOp );\n   //\n   // varsparsity\n   size_t num_var = play->num_var();\n   sweep::call_atomic_for_hes_sparsity<Base,RecBase>(\n      atom_index,\n      call_id,\n      parameter_x,\n      type_x,\n      index_x,\n      index_y,\n      n_independent_p1,\n      num_var,\n      rev_jac_sparsity,\n      for_hes_sparsity\n   );\n   //\n   if( trace )\n   {  typedef typename Vector_set::const_iterator itr_sparse_t;\n      size_t np1 = n_independent_p1;\n      CPPAD_ASSERT_UNKNOWN( np1 == for_hes_sparsity.end() );\n      CppAD::vectorBool jac_row(np1);\n      addr_t*  arg_tmp = { 0 };\n      for(size_t i = 0; i < m; ++i)\n      {  size_t j_var = index_y[i];\n         if( 0 < j_var )\n         {  for(size_t j = 0; j < np1; ++j)\n               jac_row[j] = false;\n            itr_sparse_t itr_jac(for_hes_sparsity, np1 + j_var);\n            size_t j = *itr_jac;\n            while( j < np1 )\n            {  jac_row[j] = true;\n               j = *(++itr_jac);\n            }\n            printOp<Base, RecBase>(\n               std::cout,\n               play,\n               itr.op_index() - m + i,\n               j_var,\n               FunrvOp,\n               arg_tmp\n            );\n            printOpResult(\n               std::cout,\n               1,\n               &jac_row,\n               0,\n               (CppAD::vectorBool *) nullptr\n            );\n            std::cout << std::endl;\n         }\n      }\n      CppAD::vector< CppAD::vectorBool > hes(np1);\n      for(size_t i = 0; i < np1; ++i)\n      {  hes[i].resize(np1);\n         for(size_t j = 0; j < np1; ++j)\n            hes[i][j] = false;\n         itr_sparse_t itr_hes(for_hes_sparsity, i);\n         size_t j = *itr_hes;\n         while( j < np1 )\n         {  hes[i][j] = true;\n            j = *(++itr_hes);\n         }\n      }\n      printOpResult(\n         std::cout,\n         np1,\n         hes.data(),\n         0,\n         (CppAD::vectorBool *) nullptr\n      );\n      std::cout << std::endl;\n   }\n   return;\n}\n\n\n} } } // END_CPPAD_LOCAL_VAR_OP_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/cexp_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_CEXP_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_CEXP_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n/*\n{xrst_begin_parent var_cexp_op dev}\n\nThe Variable Conditional Expression Operator\n############################################\n\nCExpOp\n******\nis the op code for this operator.\n\nUser Syntax\n***********\n| *z* = ``CondExp`` *Rel* ( *left* , *right* , *if_true* , *if_false* )\n\nRel\n***\nis Lt, Le, Eq, Ge, Gt or Ne .\n\nleft\n****\nis the left operand for the comparison.\n\nright\n*****\nis the right operand for the comparison.\n\nif_true\n*******\nis the value assigned to *z* if the comparison result is true.\n\nif_false\n********\nis the value assigned to *z* if the comparison result is false.\n\nz\n*\nis the variable that results from the comparison.\n\narg\n***\n\narg[0]\n======\nis static cast to addr_t from the enum type\n{xrst_literal\n   include/cppad/local/declare_ad.hpp\n   // BEGIN_COMPARE_OP\n   // END_COMPARE_OP\n}\nThe operator corresponding to Ne does not appear because that case\nis converted to the Eq case by switching *if_true* and *if_false* .\nThus it must hold that::\n\n   arg[0] < addr_t(CompareNe)\n\narg[1]\n======\nThe first four bits of this value are used as flags; see below.\n\narg[2]\n======\nIf arg[1] & 1 is zero (is one) ,\narg[2] is the parameter (variable) index corresponding to *left*\n\narg[3]\n======\nIf arg[1] & 2 is zero (is one) ,\narg[3] is the parameter (variable) index corresponding to *right*\n\narg[4]\n======\nIf arg[1] & 4 is zero (is one) ,\narg[4] is the parameter (variable) index corresponding to *if_true*\n\narg[5]\n======\nIf arg[1] & 8 is zero (is one) ,\narg[5] is the parameter (variable) index corresponding to *if_false*\n\n{xrst_end var_cexp_op}\n------------------------------------------------------------------------------\n{xrst_begin var_cexp_forward_any dev}\n\nAny Order Forward Conditional Expression Variable Operator\n##########################################################\n\nz\n*\nsee\n:ref:`var_cexp_op@z`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CEXP_FORWARD_ANY\n   // END_CEXP_FORWARD_ANY\n}\n\narg\n***\nsee\n:ref:`var_cexp_op@arg`\n\nRecBase\n*******\nis the base type use when recording this operator;\ni.e., this operation was recording using AD< *RecBase* > operations.\n\nBase\n****\nis the type used for computations by this operator.\nThis is either *RecBase* or AD< *RecBase* >.\n\ni_z\n***\nis the variable index corresponding to the variable *z* .\n\nnum_par\n*******\nis the total number of values in the *parameter* vector.\n\nparameter\n*********\nmaps parameter indices to parameter values .\n\n{xrst_template ;\n   include/cppad/local/var_op/template/forward_op.xrst\n   headers: cap_order, order_low, order_up, taylor\n}\n\n{xrst_end var_cexp_forward_any}\n*/\n// BEGIN_CEXP_FORWARD_ANY\ntemplate <class Base>\ninline void cexp_forward_any(\n   size_t         order_low   ,\n   size_t         order_up    ,\n   size_t         i_z         ,\n   const addr_t*  arg         ,\n   size_t         num_par     ,\n   const Base*    parameter   ,\n   size_t         cap_order   ,\n   Base*          taylor      )\n// END_CEXP_FORWARD_ANY\n{  Base y_0, y_1, y_2, y_3;\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   Base zero(0);\n   Base* z = taylor + i_z * cap_order;\n\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n\n   if( arg[1] & 1 )\n   {\n      y_0 = taylor[ size_t(arg[2]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );\n      y_0 = parameter[ arg[2] ];\n   }\n   if( arg[1] & 2 )\n   {\n      y_1 = taylor[ size_t(arg[3]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );\n      y_1 = parameter[ arg[3] ];\n   }\n   if( p == 0 )\n   {  if( arg[1] & 4 )\n      {\n         y_2 = taylor[ size_t(arg[4]) * cap_order + 0 ];\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par );\n         y_2 = parameter[ arg[4] ];\n      }\n      if( arg[1] & 8 )\n      {\n         y_3 = taylor[ size_t(arg[5]) * cap_order + 0 ];\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par );\n         y_3 = parameter[ arg[5] ];\n      }\n      z[0] = CondExpOp(\n         CompareOp( arg[0] ),\n         y_0,\n         y_1,\n         y_2,\n         y_3\n      );\n      p++;\n   }\n   for(size_t d = p; d <= q; d++)\n   {  if( arg[1] & 4 )\n      {\n         y_2 = taylor[ size_t(arg[4]) * cap_order + d];\n      }\n      else\n         y_2 = zero;\n      if( arg[1] & 8 )\n      {\n         y_3 = taylor[ size_t(arg[5]) * cap_order + d];\n      }\n      else\n         y_3 = zero;\n      z[d] = CondExpOp(\n         CompareOp( arg[0] ),\n         y_0,\n         y_1,\n         y_2,\n         y_3\n      );\n   }\n   return;\n}\n\n/*!\nMultiple directions forward mode Taylor coefficients for op = CExpOp.\n\n<!-- replace conditional_exp_op -->\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\param parameter\nFor j = 0, 1, 2, 3,\nif y_j is a parameter, parameter [ arg[2 + j] ] is its value.\n\n\\param cap_order\nnumber of columns in the matrix containing the Taylor coefficients.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end conditional_exp_op -->\n\n\\param q\nis order of the Taylor coefficient of z that we are computing.\n\n\\param r\nis the number of Taylor coefficient directions that we are computing.\n\n\\par tpv\nWe use the notation\n<code>tpv = (cap_order-1) * r + 1</code>\nwhich is the number of Taylor coefficients per variable\n\n\\param taylor\n\\b Input:\nFor j = 0, 1, 2, 3, k = 1, ..., q,\nif y_j is a variable then\n<code>taylor [ arg[2+j] * tpv + 0 ]</code>\nis the zero order Taylor coefficient corresponding to y_j and\n<code>taylor [ arg[2+j] * tpv + (k-1)*r+1+ell</code> is its\nk-th order Taylor coefficient in the ell-th direction.\n\\n\n\\b Input:\nFor j = 0, 1, 2, 3, k = 1, ..., q-1,\n<code>taylor [ i_z * tpv + 0 ]</code>\nis the zero order Taylor coefficient corresponding to z and\n<code>taylor [ i_z * tpv + (k-1)*r+1+ell</code> is its\nk-th order Taylor coefficient in the ell-th direction.\n\\n\n\\b Output: <code>taylor [ i_z * tpv + (q-1)*r+1+ell ]</code>\nis the q-th order Taylor coefficient corresponding to z\nin the ell-th direction.\n*/\ntemplate <class Base>\ninline void cexp_forward_dir(\n   size_t         order_up    ,\n   size_t         n_dir       ,\n   size_t         i_z         ,\n   const addr_t*  arg         ,\n   size_t         num_par     ,\n   const Base*    parameter   ,\n   size_t         cap_order   ,\n   Base*          taylor      )\n{  Base y_0, y_1, y_2, y_3;\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   Base zero(0);\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* z = taylor + i_z * num_taylor_per_var;\n\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   if( arg[1] & 1 )\n   {\n      y_0 = taylor[ size_t(arg[2]) * num_taylor_per_var + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );\n      y_0 = parameter[ arg[2] ];\n   }\n   if( arg[1] & 2 )\n   {\n      y_1 = taylor[ size_t(arg[3]) * num_taylor_per_var + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );\n      y_1 = parameter[ arg[3] ];\n   }\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  if( arg[1] & 4 )\n      {\n         y_2 = taylor[ size_t(arg[4]) * num_taylor_per_var + m + ell];\n      }\n      else\n         y_2 = zero;\n      if( arg[1] & 8 )\n      {\n         y_3 = taylor[ size_t(arg[5]) * num_taylor_per_var + m + ell];\n      }\n      else\n         y_3 = zero;\n      z[m+ell] = CondExpOp(\n         CompareOp( arg[0] ),\n         y_0,\n         y_1,\n         y_2,\n         y_3\n      );\n   }\n   return;\n}\n\n/*!\nCompute zero order forward mode Taylor coefficients for op = CExpOp.\n\n<!-- replace conditional_exp_op -->\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\param parameter\nFor j = 0, 1, 2, 3,\nif y_j is a parameter, parameter [ arg[2 + j] ] is its value.\n\n\\param cap_order\nnumber of columns in the matrix containing the Taylor coefficients.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end conditional_exp_op -->\n\n\\param taylor\n\\b Input:\nFor j = 0, 1, 2, 3,\nif y_j is a variable then\n taylor [ arg[2+j] * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to y_j.\n\\n\n\\b Output: taylor [ i_z * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to z.\n*/\ntemplate <class Base>\ninline void cexp_forward_0(\n   size_t         i_z         ,\n   const addr_t*  arg         ,\n   size_t         num_par     ,\n   const Base*    parameter   ,\n   size_t         cap_order   ,\n   Base*          taylor      )\n{  Base y_0, y_1, y_2, y_3;\n   //\n   Base* z;\n\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n\n   if( arg[1] & 1 )\n   {\n      y_0 = taylor[ size_t(arg[2]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );\n      y_0 = parameter[ arg[2] ];\n   }\n   if( arg[1] & 2 )\n   {\n      y_1 = taylor[ size_t(arg[3]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );\n      y_1 = parameter[ arg[3] ];\n   }\n   if( arg[1] & 4 )\n   {\n      y_2 = taylor[ size_t(arg[4]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par );\n      y_2 = parameter[ arg[4] ];\n   }\n   if( arg[1] & 8 )\n   {\n      y_3 = taylor[ size_t(arg[5]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par );\n      y_3 = parameter[ arg[5] ];\n   }\n   z = taylor + i_z * cap_order;\n   z[0] = CondExpOp(\n      CompareOp( arg[0] ),\n      y_0,\n      y_1,\n      y_2,\n      y_3\n   );\n   return;\n}\n\n/*!\nCompute reverse mode Taylor coefficients for op = CExpOp.\n\nThis routine is given the partial derivatives of a function\nG( z , y , x , w , ... )\nand it uses them to compute the partial derivatives of\n\\verbatim\n   H( y , x , w , u , ... ) = G[ z(y) , y , x , w , u , ... ]\n\\endverbatim\nwhere y above represents y_0, y_1, y_2, y_3.\n\n<!-- replace conditional_exp_op -->\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\param parameter\nFor j = 0, 1, 2, 3,\nif y_j is a parameter, parameter [ arg[2 + j] ] is its value.\n\n\\param cap_order\nnumber of columns in the matrix containing the Taylor coefficients.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end conditional_exp_op -->\n\n\\param d\nis the order of the Taylor coefficient of z that we are  computing.\n\n\\param taylor\n\\b Input:\nFor j = 0, 1, 2, 3 and k = 0 , ... , d,\nif y_j is a variable then\n taylor [ arg[2+j] * cap_order + k ]\nis the k-th order Taylor coefficient corresponding to y_j.\n\\n\n taylor [ i_z * cap_order + k ]\nfor k = 0 , ... , d\nis the k-th order Taylor coefficient corresponding to z.\n\n\\param n_order\nnumber of columns in the matrix containing the Taylor coefficients.\n\n\\param partial\n\\b Input:\nFor j = 0, 1, 2, 3 and k = 0 , ... , d,\nif y_j is a variable then\n partial [ arg[2+j] * n_order + k ]\nis the partial derivative of G( z , y , x , w , u , ... )\nwith respect to the k-th order Taylor coefficient corresponding to y_j.\n\\n\n\\b Input: partial [ i_z * cap_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of G( z , y , x , w , u , ... )\nwith respect to the k-th order Taylor coefficient corresponding to z.\n\\n\n\\b Output:\nFor j = 0, 1, 2, 3 and k = 0 , ... , d,\nif y_j is a variable then\n partial [ arg[2+j] * n_order + k ]\nis the partial derivative of H( y , x , w , u , ... )\nwith respect to the k-th order Taylor coefficient corresponding to y_j.\n\n*/\ntemplate <class Base>\ninline void cexp_reverse(\n   size_t         i_z         ,\n   const addr_t*  arg         ,\n   size_t         num_par     ,\n   const Base*    parameter   ,\n   size_t         cap_order   ,\n   const Base*    taylor      ,\n   size_t         n_order     ,\n   Base*          partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   Base y_0, y_1;\n   Base zero(0);\n   Base* pz;\n   Base* py_2;\n   Base* py_3;\n\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n\n   pz = partial + i_z * n_order + 0;\n   if( arg[1] & 1 )\n   {\n      y_0 = taylor[ size_t(arg[2]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );\n      y_0 = parameter[ arg[2] ];\n   }\n   if( arg[1] & 2 )\n   {\n      y_1 = taylor[ size_t(arg[3]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );\n      y_1 = parameter[ arg[3] ];\n   }\n   if( arg[1] & 4 )\n   {\n      py_2 = partial + size_t(arg[4]) * n_order;\n      size_t j = d + 1;\n      while(j--)\n      {  py_2[j] += CondExpOp(\n            CompareOp( arg[0] ),\n            y_0,\n            y_1,\n            pz[j],\n            zero\n         );\n      }\n   }\n   if( arg[1] & 8 )\n   {\n      py_3 = partial + size_t(arg[5]) * n_order;\n      size_t j = d + 1;\n      while(j--)\n      {  py_3[j] += CondExpOp(\n            CompareOp( arg[0] ),\n            y_0,\n            y_1,\n            zero,\n            pz[j]\n         );\n      }\n   }\n   return;\n}\n\n/*!\nCompute forward Jacobian sparsity patterns for op = CExpOp.\n\n<!-- replace sparse_conditional_exp_op -->\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end sparse_conditional_exp_op -->\n\n\\param dependency\nAre the derivatives with respect to left and right of the expression below\nconsidered to be non-zero:\n\\code\n   CondExpRel(left, right, if_true, if_false)\n\\endcode\nThis is used by the optimizer to obtain the correct dependency relations.\n\n\\param sparsity\n\\b Input:\nif y_2 is a variable, the set with index t is\nthe sparsity pattern corresponding to y_2.\nThis identifies which of the independent variables the variable y_2\ndepends on.\n\\n\n\\b Input:\nif y_3 is a variable, the set with index t is\nthe sparsity pattern corresponding to y_3.\nThis identifies which of the independent variables the variable y_3\ndepends on.\n\\n\n\\b Output:\nThe set with index T is\nthe sparsity pattern corresponding to z.\nThis identifies which of the independent variables the variable z\ndepends on.\n*/\ntemplate <class Vector_set>\ninline void cexp_for_jac(\n   bool               dependency    ,\n   size_t             i_z           ,\n   const addr_t*      arg           ,\n   size_t             num_par       ,\n   Vector_set&        sparsity      )\n{  //\n   //\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n# ifndef NDEBUG\n   addr_t k = 1;\n   for( size_t j = 0; j < 4; j++)\n   {  if( ! ( arg[1] & k ) )\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par );\n      k *= 2;\n   }\n# endif\n   sparsity.clear(i_z);\n   if( dependency )\n   {  if( arg[1] & 1 )\n         sparsity.binary_union(i_z, i_z, size_t(arg[2]), sparsity);\n      if( arg[1] & 2 )\n         sparsity.binary_union(i_z, i_z, size_t(arg[3]), sparsity);\n   }\n   if( arg[1] & 4 )\n      sparsity.binary_union(i_z, i_z, size_t(arg[4]), sparsity);\n   if( arg[1] & 8 )\n      sparsity.binary_union(i_z, i_z, size_t(arg[5]), sparsity);\n   return;\n}\n\n/*!\nCompute reverse Jacobian sparsity patterns for op = CExpOp.\n\nThis routine is given the sparsity patterns\nfor a function G(z, y, x, ... )\nand it uses them to compute the sparsity patterns for\n\\verbatim\n   H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ]\n\\endverbatim\nwhere y represents the combination of y_0, y_1, y_2, and y_3.\n\n<!-- replace sparse_conditional_exp_op -->\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end sparse_conditional_exp_op -->\n\n\\param dependency\nAre the derivatives with respect to left and right of the expression below\nconsidered to be non-zero:\n\\code\n   CondExpRel(left, right, if_true, if_false)\n\\endcode\nThis is used by the optimizer to obtain the correct dependency relations.\n\n\n\\param sparsity\nif y_2 is a variable, the set with index t is\nthe sparsity pattern corresponding to y_2.\nThis identifies which of the dependent variables depend on the variable y_2.\nOn input, this pattern corresponds to the function G.\nOn output, it corresponds to the function H.\n\\n\n\\n\nif y_3 is a variable, the set with index t is\nthe sparsity pattern corresponding to y_3.\nThis identifies which of the dependent variables depeond on the variable y_3.\nOn input, this pattern corresponds to the function G.\nOn output, it corresponds to the function H.\n\\n\n\\b Output:\nThe set with index T is\nthe sparsity pattern corresponding to z.\nThis identifies which of the dependent variables depend on the variable z.\nOn input and output, this pattern corresponds to the function G.\n*/\ntemplate <class Vector_set>\ninline void cexp_rev_jac(\n   bool                dependency    ,\n   size_t              i_z           ,\n   const addr_t*       arg           ,\n   size_t              num_par       ,\n   Vector_set&         sparsity      )\n{  //\n   //\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n# ifndef NDEBUG\n   addr_t k = 1;\n   for( size_t j = 0; j < 4; j++)\n   {  if( ! ( arg[1] & k ) )\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par );\n      k *= 2;\n   }\n# endif\n   if( dependency )\n   {  if( arg[1] & 1 )\n         sparsity.binary_union( size_t(arg[2]), size_t(arg[2]), i_z, sparsity);\n      if( arg[1] & 2 )\n         sparsity.binary_union( size_t(arg[3]), size_t(arg[3]), i_z, sparsity);\n   }\n   // --------------------------------------------------------------------\n   if( arg[1] & 4 )\n      sparsity.binary_union( size_t(arg[4]), size_t(arg[4]), i_z, sparsity);\n   if( arg[1] & 8 )\n      sparsity.binary_union( size_t(arg[5]), size_t(arg[5]), i_z, sparsity);\n   return;\n}\n\n/*!\nCompute reverse Hessian sparsity patterns for op = CExpOp.\n\nThis routine is given the sparsity patterns\nfor a function G(z, y, x, ... )\nand it uses them to compute the sparsity patterns for\n\\verbatim\n   H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ]\n\\endverbatim\nwhere y represents the combination of y_0, y_1, y_2, and y_3.\n\n<!-- replace sparse_conditional_exp_op -->\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end sparse_conditional_exp_op -->\n\n\n\\param jac_reverse\n jac_reverse[i_z]\nis false (true) if the Jacobian of G with respect to z is always zero\n(may be non-zero).\n\\n\n\\n\n jac_reverse[ arg[4] ]\nIf y_2 is a variable,\n jac_reverse[ arg[4] ]\nis false (true) if the Jacobian with respect to y_2 is always zero\n(may be non-zero).\nOn input, it corresponds to the function G,\nand on output it corresponds to the function H.\n\\n\n\\n\n jac_reverse[ arg[5] ]\nIf y_3 is a variable,\n jac_reverse[ arg[5] ]\nis false (true) if the Jacobian with respect to y_3 is always zero\n(may be non-zero).\nOn input, it corresponds to the function G,\nand on output it corresponds to the function H.\n\n\\param hes_sparsity\nThe set with index i_z in hes_sparsity\nis the Hessian sparsity pattern for the function G\nwhere one of the partials is with respect to z.\n\\n\n\\n\nIf y_2 is a variable,\nthe set with index arg[4] in hes_sparsity\nis the Hessian sparsity pattern\nwhere one of the partials is with respect to y_2.\nOn input, this pattern corresponds to the function G.\nOn output, this pattern corresponds to the function H.\n\\n\n\\n\nIf y_3 is a variable,\nthe set with index arg[5] in hes_sparsity\nis the Hessian sparsity pattern\nwhere one of the partials is with respect to y_3.\nOn input, this pattern corresponds to the function G.\nOn output, this pattern corresponds to the function H.\n*/\ntemplate <class Vector_set>\ninline void cexp_rev_hes(\n   size_t               i_z           ,\n   const addr_t*        arg           ,\n   size_t               num_par       ,\n   bool*                jac_reverse   ,\n   Vector_set&          hes_sparsity  )\n{  //\n   //\n\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n# ifndef NDEBUG\n   addr_t k = 1;\n   for( size_t j = 0; j < 4; j++)\n   {  if( ! ( arg[1] & k ) )\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par );\n      k *= 2;\n   }\n# endif\n   if( arg[1] & 4 )\n   {\n      hes_sparsity.binary_union( size_t(arg[4]), size_t(arg[4]), i_z, hes_sparsity);\n      jac_reverse[ arg[4] ] |= jac_reverse[i_z];\n   }\n   if( arg[1] & 8 )\n   {\n      hes_sparsity.binary_union( size_t(arg[5]), size_t(arg[5]), i_z, hes_sparsity);\n      jac_reverse[ arg[5] ] |= jac_reverse[i_z];\n   }\n   return;\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/compare.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_COMPARE_HPP\n# define CPPAD_LOCAL_VAR_OP_COMPARE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ---------------------------------------------------------------------------\n/*\n{xrst_begin var_compare dev}\n\nImplement Comparison Operators\n##############################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN PROTOTYPE\n   // END PROTOTYPE\n}\n\nBase\n****\nis the base type for the operator; i.e., this operation was recorded\nusing ``AD`` < *Base* > and computations by these operators are done using\ntype *Base* .\n\nop_code\n*******\nis the enum value for the comparison operator that we are implementing.\n\narg\n***\nis the vector of argument indices for this operator.\nAll the comparison operators have two arguments and the corresponding\nindices are *arg*\\ [0] and *arg*\\ [1] .\n\nparameter\n*********\nmaps parameter indices to parameter values.\n\ncap_order\n*********\nis the maximum number of orders that will fit in *taylor* .\n\ntaylor\n******\nThe Taylor coefficient corresponding to\nvariable index *i* and order zero is\n\n   *taylor* [ *i* * *cap_order* ]\n\nthis_op_index\n*************\nIs the operator index for this compare operation.\n\ncompare_change_count\n********************\nis the compare_change_number at which *this_op_index* is returned\nas *compare_change_op_index*.\nIf it is zero, the comparison changes are not counted.\n\ncompare_change_number\n*********************\nIf *compare_change_count* is zero, this value is not modified.\nOtherwise, if this operator comparison has changed (is no longer true),\n*compare_change_number* is incremented by one.\n\ncompare_change_op_index\n***********************\nIf *compare_change_count* is zero, this value is not modified.\nOtherwise, if this operator comparison has changed (is no longer true), and\nthe new value of *compare_change_number* is equal to *compare_change_count* ,\n*compare_change_op_index* is set equal to *this_op_index* .\n\n{xrst_end var_compare}\n*/\n\n# include <cppad/local/op_code_var.hpp>\n# include <cppad/core/cppad_assert.hpp>\n\nnamespace CppAD { namespace local { namespace var_op { // BEGIN namespace\n\n// BEGIN PROTOTYPE\ntemplate <class Base> void compare(\n   op_code_var   op_code                 ,\n   const addr_t* arg                     ,\n   const Base*   parameter               ,\n   size_t        cap_order               ,\n   const Base*   taylor                  ,\n   size_t        this_op_index           ,\n   size_t        compare_change_count    ,\n   size_t&       compare_change_number   ,\n   size_t&       compare_change_op_index )\n// END PROTOTYPE\n{  //\n   // n_arg, n_res\n   CPPAD_ASSERT_NARG_NRES(op_code, 2, 0);\n   //\n   // special case\n   if( compare_change_count == 0 )\n      return;\n   //\n   // x, y\n   Base x, y;\n   switch(op_code)\n   {  //\n      // pp\n      case EqppOp:\n      case LeppOp:\n      case LtppOp:\n      case NeppOp:\n      x = parameter[ arg[0] ];\n      y = parameter[ arg[1] ];\n      break;\n      //\n      // pv\n      case EqpvOp:\n      case LepvOp:\n      case LtpvOp:\n      case NepvOp:\n      x = parameter[ arg[0] ];\n      y = taylor[ size_t(arg[1]) * cap_order ];\n      break;\n\n      // vp\n      case LevpOp:\n      case LtvpOp:\n      x = taylor[ size_t(arg[0]) * cap_order ];\n      y = parameter[ arg[1] ];\n      break;\n      //\n      // vv\n      case EqvvOp:\n      case LevvOp:\n      case LtvvOp:\n      case NevvOp:\n      x = taylor[ size_t(arg[0]) * cap_order ];\n      y = taylor[ size_t(arg[1]) * cap_order ];\n      break;\n      //\n      default:\n      // assign x and y to avoid compiler warnings\n      CPPAD_ASSERT_UNKNOWN( false );\n      x = CppAD::numeric_limits<Base>::quiet_NaN();\n      y = CppAD::numeric_limits<Base>::quiet_NaN();\n   }\n   bool change;\n   switch(op_code)\n   {  //\n      case EqppOp:\n      case EqpvOp:\n      case EqvvOp:\n      change = x != y;\n      break;\n\n      case LeppOp:\n      case LepvOp:\n      case LevpOp:\n      case LevvOp:\n      change = GreaterThanZero(x - y);\n      break;\n\n      case LtppOp:\n      case LtpvOp:\n      case LtvpOp:\n      case LtvvOp:\n      change = GreaterThanOrZero(x - y);\n      break;\n\n      case NeppOp:\n      case NepvOp:\n      case NevvOp:\n      change = x == y;\n      break;\n\n      default:\n      // assign change to avoid compiler warning\n      CPPAD_ASSERT_UNKNOWN( false );\n      change = true;\n      break;\n   }\n   if( change )\n   {  ++compare_change_number;\n      if( compare_change_number == compare_change_count )\n         compare_change_op_index = this_op_index;\n   }\n}\n}}} // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/compare_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_COMPARE_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_COMPARE_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ---------------------------------------------------------------------------\n/*\n{xrst_begin_parent var_compare_op dev}\n{xrst_spell\n   eqpp\n   eqpv\n   eqvv\n   lepp\n   lepv\n   levp\n   levv\n   ltpp\n   ltpv\n   ltvp\n   ltvv\n   nepp\n   nepv\n   nevv\n}\n\nComparison Operators\n####################\n\nUser Syntax\n***********\n*z* = *x* *op* *y*\n\nx\n*\nis the left operand for this comparison.\n\ny\n*\nis the right operand for this comparison.\n\nz\n*\nis he result for this operator which is a boolean\n(not a variable or parameter).\n\nop\n**\nis one of the following: ==, <=, <, != .\nThe >= and > comparisons are folded into <= and < by switching *x* and *y* .\n\nop_code\n*******\n\nEqppOp, LeppOp, LtppOp, NeppOp\n==============================\nThese operators implement ==. <=, <, and != for the case where\nboth *x* and *y* are parameters.\n\nEqpvOp, LepvOp, LtpvOp, NepvOp\n==============================\nThese operators implement ==. <=, <, and != for the case where\n*x* is a parameter and *y* is a variable.\n\nLevpOp, LtvpOp\n==============\nThese operators implement <= and < for the case where\n*x* is a variable and *y* is a parameter.\nThe == and != operators are folded into EqpvOp and NepvOp by\nswitching *x* and *y* .\n\nEqvvOp, LevvOp, LtvvOp, NevvOp\n==============================\nThese operators implement ==. <=, <, and != for the case where\nboth *x* and *y* are variables.\n\narg\n***\n\narg[0]\n======\nIf *x* is a variable (parameter)\n*arg* [0] is the variable index (parameter index) corresponding to *x* .\n\narg[1]\n======\nIf *y* is a variable (parameter)\n*arg* [1] is the variable index (parameter index) corresponding to *y* .\n\n{xrst_end var_compare_op}\n\n-------------------------------------------------------------------------------\n{xrst_begin var_compare_forward_any dev}\n\nForward Comparison Operators\n############################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_COMPARE_FORWARD_ANY\n   // END_COMPARE_FORWARD_ANY\n}\n\nRecBase\n*******\nis the base type use when recording this operator;\ni.e., this operation was recording using AD< *RecBase* > operations.\n\nBase\n****\nis the type used for computations by this operator.\nThis is either *RecBase* or AD< *RecBase* >.\ntype *Base* .\n\nop_code, arg\n************\nsee :ref:`var_compare_op@op_code`\n\nparameter\n*********\nmaps parameter indices to parameter values.\n\ncap_order\n*********\nis the maximum number of orders that will fit in *taylor* .\n\ntaylor\n******\nThe Taylor coefficient corresponding to\nvariable index *i* and order zero is\n\n   *taylor* [ *i* * *cap_order* ]\n\nthis_op_index\n*************\nIs the operator index for this compare operation.\n\nchange_count\n************\nis the change_number at which *this_op_index* is returned\nas *change_op_index*.\nIf it is zero, the comparison changes are not counted.\n\nchange_number\n*************\nIf *change_count* is zero, this value is not modified.\nOtherwise, if this operator comparison has changed (is no longer true),\n*change_number* is incremented by one.\n\nchange_op_index\n***************\nIf *change_count* is zero, this value is not modified.\nOtherwise, if this operator comparison has changed (is no longer true), and\nthe new value of *change_number* is equal to *change_count* ,\n*change_op_index* is set equal to *this_op_index* .\n\n{xrst_end var_compare_forward_any}\n*/\n\n# include <cppad/local/op_code_var.hpp>\n# include <cppad/core/cppad_assert.hpp>\n\nnamespace CppAD { namespace local { namespace var_op { // BEGIN namespace\n\n// BEGIN_COMPARE_FORWARD_ANY\ntemplate <class Base> void compare_forward_any(\n   op_code_var   op_code                 ,\n   const addr_t* arg                     ,\n   const Base*   parameter               ,\n   size_t        cap_order               ,\n   const Base*   taylor                  ,\n   size_t        this_op_index           ,\n   size_t        change_count            ,\n   size_t&       change_number           ,\n   size_t&       change_op_index         )\n// END_COMPARE_FORWARD_ANY\n{  //\n   // n_arg, n_res\n   CPPAD_ASSERT_NARG_NRES(op_code, 2, 0);\n   //\n   // special case\n   if( change_count == 0 )\n      return;\n   //\n   // x, y\n   Base x, y;\n   switch(op_code)\n   {  //\n      // pp\n      case EqppOp:\n      case LeppOp:\n      case LtppOp:\n      case NeppOp:\n      x = parameter[ arg[0] ];\n      y = parameter[ arg[1] ];\n      break;\n      //\n      // pv\n      case EqpvOp:\n      case LepvOp:\n      case LtpvOp:\n      case NepvOp:\n      x = parameter[ arg[0] ];\n      y = taylor[ size_t(arg[1]) * cap_order ];\n      break;\n\n      // vp\n      case LevpOp:\n      case LtvpOp:\n      x = taylor[ size_t(arg[0]) * cap_order ];\n      y = parameter[ arg[1] ];\n      break;\n      //\n      // vv\n      case EqvvOp:\n      case LevvOp:\n      case LtvvOp:\n      case NevvOp:\n      x = taylor[ size_t(arg[0]) * cap_order ];\n      y = taylor[ size_t(arg[1]) * cap_order ];\n      break;\n      //\n      default:\n      // assign x and y to avoid compiler warnings\n      CPPAD_ASSERT_UNKNOWN( false );\n      x = CppAD::numeric_limits<Base>::quiet_NaN();\n      y = CppAD::numeric_limits<Base>::quiet_NaN();\n   }\n   bool change;\n   switch(op_code)\n   {  //\n      case EqppOp:\n      case EqpvOp:\n      case EqvvOp:\n      change = x != y;\n      break;\n\n      case LeppOp:\n      case LepvOp:\n      case LevpOp:\n      case LevvOp:\n      change = GreaterThanZero(x - y);\n      break;\n\n      case LtppOp:\n      case LtpvOp:\n      case LtvpOp:\n      case LtvvOp:\n      change = GreaterThanOrZero(x - y);\n      break;\n\n      case NeppOp:\n      case NepvOp:\n      case NevvOp:\n      change = x == y;\n      break;\n\n      default:\n      // assign change to avoid compiler warning\n      CPPAD_ASSERT_UNKNOWN( false );\n      change = true;\n      break;\n   }\n   if( change )\n   {  ++change_number;\n      if( change_number == change_count         )\n         change_op_index = this_op_index;\n   }\n}\n}}} // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/cond_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_COND_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_COND_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n/*!\n\\file cond_op.hpp\nForward, reverse, and sparse operations for conditional expressions.\n*/\n\n/*!\nShared documentation for conditional expressions (not called).\n\n<!-- define conditional_exp_op -->\nThe C++ source code coresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\param parameter\nFor j = 0, 1, 2, 3,\nif y_j is a parameter, parameter [ arg[2 + j] ] is its value.\n\n\\param cap_order\nnumber of columns in the matrix containing the Taylor coefficients.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end conditional_exp_op -->\n*/\ntemplate <class Base>\ninline void conditional_exp_op(\n   size_t         i_z         ,\n   const addr_t*  arg         ,\n   size_t         num_par     ,\n   const Base*    parameter   ,\n   size_t         cap_order   )\n{  // This routine is only for documentation, it should never be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n/*!\nShared documentation for conditional expression sparse operations (not called).\n\n<!-- define sparse_conditional_exp_op -->\nThe C++ source code coresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end sparse_conditional_exp_op -->\n*/\ntemplate <class Vector_set>\ninline void sparse_conditional_exp_op(\n   size_t         i_z           ,\n   const addr_t*  arg           ,\n   size_t         num_par       )\n{  // This routine is only for documentation, it should never be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n/*!\nCompute forward mode Taylor coefficients for op = CExpOp.\n\n<!-- replace conditional_exp_op -->\nThe C++ source code coresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\param parameter\nFor j = 0, 1, 2, 3,\nif y_j is a parameter, parameter [ arg[2 + j] ] is its value.\n\n\\param cap_order\nnumber of columns in the matrix containing the Taylor coefficients.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end conditional_exp_op -->\n\n\\param p\nis the lowest order of the Taylor coefficient of z that we are computing.\n\n\\param q\nis the highest order of the Taylor coefficient of z that we are computing.\n\n\\param taylor\n\\b Input:\nFor j = 0, 1, 2, 3 and k = 0 , ... , q,\nif y_j is a variable then\n<code>taylor [ arg[2+j] * cap_order + k ]</code>\nis the k-th order Taylor coefficient corresponding to y_j.\n\\n\n\\b Input: <code>taylor [ i_z * cap_order + k ]</code>\nfor k = 0 , ... , p-1,\nis the k-th order Taylor coefficient corresponding to z.\n\\n\n\\b Output: <code>taylor [ i_z * cap_order + k ]</code>\nfor k = p , ... , q,\nis the k-th order Taylor coefficient corresponding to z.\n\n*/\ntemplate <class Base>\ninline void forward_cond_op(\n   size_t         p           ,\n   size_t         q           ,\n   size_t         i_z         ,\n   const addr_t*  arg         ,\n   size_t         num_par     ,\n   const Base*    parameter   ,\n   size_t         cap_order   ,\n   Base*          taylor      )\n{  Base y_0, y_1, y_2, y_3;\n   Base zero(0);\n   Base* z = taylor + i_z * cap_order;\n\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n\n   if( arg[1] & 1 )\n   {\n      y_0 = taylor[ size_t(arg[2]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );\n      y_0 = parameter[ arg[2] ];\n   }\n   if( arg[1] & 2 )\n   {\n      y_1 = taylor[ size_t(arg[3]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );\n      y_1 = parameter[ arg[3] ];\n   }\n   if( p == 0 )\n   {  if( arg[1] & 4 )\n      {\n         y_2 = taylor[ size_t(arg[4]) * cap_order + 0 ];\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par );\n         y_2 = parameter[ arg[4] ];\n      }\n      if( arg[1] & 8 )\n      {\n         y_3 = taylor[ size_t(arg[5]) * cap_order + 0 ];\n      }\n      else\n      {  CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par );\n         y_3 = parameter[ arg[5] ];\n      }\n      z[0] = CondExpOp(\n         CompareOp( arg[0] ),\n         y_0,\n         y_1,\n         y_2,\n         y_3\n      );\n      p++;\n   }\n   for(size_t d = p; d <= q; d++)\n   {  if( arg[1] & 4 )\n      {\n         y_2 = taylor[ size_t(arg[4]) * cap_order + d];\n      }\n      else\n         y_2 = zero;\n      if( arg[1] & 8 )\n      {\n         y_3 = taylor[ size_t(arg[5]) * cap_order + d];\n      }\n      else\n         y_3 = zero;\n      z[d] = CondExpOp(\n         CompareOp( arg[0] ),\n         y_0,\n         y_1,\n         y_2,\n         y_3\n      );\n   }\n   return;\n}\n\n/*!\nMultiple directions forward mode Taylor coefficients for op = CExpOp.\n\n<!-- replace conditional_exp_op -->\nThe C++ source code coresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\param parameter\nFor j = 0, 1, 2, 3,\nif y_j is a parameter, parameter [ arg[2 + j] ] is its value.\n\n\\param cap_order\nnumber of columns in the matrix containing the Taylor coefficients.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end conditional_exp_op -->\n\n\\param q\nis order of the Taylor coefficient of z that we are computing.\n\n\\param r\nis the number of Taylor coefficient directions that we are computing.\n\n\\par tpv\nWe use the notation\n<code>tpv = (cap_order-1) * r + 1</code>\nwhich is the number of Taylor coefficients per variable\n\n\\param taylor\n\\b Input:\nFor j = 0, 1, 2, 3, k = 1, ..., q,\nif y_j is a variable then\n<code>taylor [ arg[2+j] * tpv + 0 ]</code>\nis the zero order Taylor coefficient corresponding to y_j and\n<code>taylor [ arg[2+j] * tpv + (k-1)*r+1+ell</code> is its\nk-th order Taylor coefficient in the ell-th direction.\n\\n\n\\b Input:\nFor j = 0, 1, 2, 3, k = 1, ..., q-1,\n<code>taylor [ i_z * tpv + 0 ]</code>\nis the zero order Taylor coefficient corresponding to z and\n<code>taylor [ i_z * tpv + (k-1)*r+1+ell</code> is its\nk-th order Taylor coefficient in the ell-th direction.\n\\n\n\\b Output: <code>taylor [ i_z * tpv + (q-1)*r+1+ell ]</code>\nis the q-th order Taylor coefficient corresponding to z\nin the ell-th direction.\n*/\ntemplate <class Base>\ninline void forward_cond_op_dir(\n   size_t         q           ,\n   size_t         r           ,\n   size_t         i_z         ,\n   const addr_t*  arg         ,\n   size_t         num_par     ,\n   const Base*    parameter   ,\n   size_t         cap_order   ,\n   Base*          taylor      )\n{  Base y_0, y_1, y_2, y_3;\n   Base zero(0);\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* z = taylor + i_z * num_taylor_per_var;\n\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   if( arg[1] & 1 )\n   {\n      y_0 = taylor[ size_t(arg[2]) * num_taylor_per_var + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );\n      y_0 = parameter[ arg[2] ];\n   }\n   if( arg[1] & 2 )\n   {\n      y_1 = taylor[ size_t(arg[3]) * num_taylor_per_var + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );\n      y_1 = parameter[ arg[3] ];\n   }\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  if( arg[1] & 4 )\n      {\n         y_2 = taylor[ size_t(arg[4]) * num_taylor_per_var + m + ell];\n      }\n      else\n         y_2 = zero;\n      if( arg[1] & 8 )\n      {\n         y_3 = taylor[ size_t(arg[5]) * num_taylor_per_var + m + ell];\n      }\n      else\n         y_3 = zero;\n      z[m+ell] = CondExpOp(\n         CompareOp( arg[0] ),\n         y_0,\n         y_1,\n         y_2,\n         y_3\n      );\n   }\n   return;\n}\n\n/*!\nCompute zero order forward mode Taylor coefficients for op = CExpOp.\n\n<!-- replace conditional_exp_op -->\nThe C++ source code coresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\param parameter\nFor j = 0, 1, 2, 3,\nif y_j is a parameter, parameter [ arg[2 + j] ] is its value.\n\n\\param cap_order\nnumber of columns in the matrix containing the Taylor coefficients.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end conditional_exp_op -->\n\n\\param taylor\n\\b Input:\nFor j = 0, 1, 2, 3,\nif y_j is a variable then\n taylor [ arg[2+j] * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to y_j.\n\\n\n\\b Output: taylor [ i_z * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to z.\n*/\ntemplate <class Base>\ninline void forward_cond_op_0(\n   size_t         i_z         ,\n   const addr_t*  arg         ,\n   size_t         num_par     ,\n   const Base*    parameter   ,\n   size_t         cap_order   ,\n   Base*          taylor      )\n{  Base y_0, y_1, y_2, y_3;\n   Base* z;\n\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n\n   if( arg[1] & 1 )\n   {\n      y_0 = taylor[ size_t(arg[2]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );\n      y_0 = parameter[ arg[2] ];\n   }\n   if( arg[1] & 2 )\n   {\n      y_1 = taylor[ size_t(arg[3]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );\n      y_1 = parameter[ arg[3] ];\n   }\n   if( arg[1] & 4 )\n   {\n      y_2 = taylor[ size_t(arg[4]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par );\n      y_2 = parameter[ arg[4] ];\n   }\n   if( arg[1] & 8 )\n   {\n      y_3 = taylor[ size_t(arg[5]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par );\n      y_3 = parameter[ arg[5] ];\n   }\n   z = taylor + i_z * cap_order;\n   z[0] = CondExpOp(\n      CompareOp( arg[0] ),\n      y_0,\n      y_1,\n      y_2,\n      y_3\n   );\n   return;\n}\n\n/*!\nCompute reverse mode Taylor coefficients for op = CExpOp.\n\nThis routine is given the partial derivatives of a function\nG( z , y , x , w , ... )\nand it uses them to compute the partial derivatives of\n\\verbatim\n   H( y , x , w , u , ... ) = G[ z(y) , y , x , w , u , ... ]\n\\endverbatim\nwhere y above represents y_0, y_1, y_2, y_3.\n\n<!-- replace conditional_exp_op -->\nThe C++ source code coresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\param parameter\nFor j = 0, 1, 2, 3,\nif y_j is a parameter, parameter [ arg[2 + j] ] is its value.\n\n\\param cap_order\nnumber of columns in the matrix containing the Taylor coefficients.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end conditional_exp_op -->\n\n\\param d\nis the order of the Taylor coefficient of z that we are  computing.\n\n\\param taylor\n\\b Input:\nFor j = 0, 1, 2, 3 and k = 0 , ... , d,\nif y_j is a variable then\n taylor [ arg[2+j] * cap_order + k ]\nis the k-th order Taylor coefficient corresponding to y_j.\n\\n\n taylor [ i_z * cap_order + k ]\nfor k = 0 , ... , d\nis the k-th order Taylor coefficient corresponding to z.\n\n\\param n_order\nnumber of columns in the matrix containing the Taylor coefficients.\n\n\\param partial\n\\b Input:\nFor j = 0, 1, 2, 3 and k = 0 , ... , d,\nif y_j is a variable then\n partial [ arg[2+j] * n_order + k ]\nis the partial derivative of G( z , y , x , w , u , ... )\nwith respect to the k-th order Taylor coefficient corresponding to y_j.\n\\n\n\\b Input: partial [ i_z * cap_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of G( z , y , x , w , u , ... )\nwith respect to the k-th order Taylor coefficient corresponding to z.\n\\n\n\\b Output:\nFor j = 0, 1, 2, 3 and k = 0 , ... , d,\nif y_j is a variable then\n partial [ arg[2+j] * n_order + k ]\nis the partial derivative of H( y , x , w , u , ... )\nwith respect to the k-th order Taylor coefficient corresponding to y_j.\n\n*/\ntemplate <class Base>\ninline void reverse_cond_op(\n   size_t         i_z         ,\n   const addr_t*  arg         ,\n   size_t         num_par     ,\n   const Base*    parameter   ,\n   size_t         cap_order   ,\n   const Base*    taylor      ,\n   size_t         n_order     ,\n   Base*          partial     )\n{  // d\n   size_t d = n_order - 1;\n   //\n   Base y_0, y_1;\n   Base zero(0);\n   Base* pz;\n   Base* py_2;\n   Base* py_3;\n\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n\n   pz = partial + i_z * n_order + 0;\n   if( arg[1] & 1 )\n   {\n      y_0 = taylor[ size_t(arg[2]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );\n      y_0 = parameter[ arg[2] ];\n   }\n   if( arg[1] & 2 )\n   {\n      y_1 = taylor[ size_t(arg[3]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );\n      y_1 = parameter[ arg[3] ];\n   }\n   if( arg[1] & 4 )\n   {\n      py_2 = partial + size_t(arg[4]) * n_order;\n      size_t j = d + 1;\n      while(j--)\n      {  py_2[j] += CondExpOp(\n            CompareOp( arg[0] ),\n            y_0,\n            y_1,\n            pz[j],\n            zero\n         );\n      }\n   }\n   if( arg[1] & 8 )\n   {\n      py_3 = partial + size_t(arg[5]) * n_order;\n      size_t j = d + 1;\n      while(j--)\n      {  py_3[j] += CondExpOp(\n            CompareOp( arg[0] ),\n            y_0,\n            y_1,\n            zero,\n            pz[j]\n         );\n      }\n   }\n   return;\n}\n\n/*!\nCompute forward Jacobian sparsity patterns for op = CExpOp.\n\n<!-- replace sparse_conditional_exp_op -->\nThe C++ source code coresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end sparse_conditional_exp_op -->\n\n\\param dependency\nAre the derivatives with respect to left and right of the expression below\nconsidered to be non-zero:\n\\code\n   CondExpRel(left, right, if_true, if_false)\n\\endcode\nThis is used by the optimizer to obtain the correct dependency relations.\n\n\\param sparsity\n\\b Input:\nif y_2 is a variable, the set with index t is\nthe sparsity pattern corresponding to y_2.\nThis identifies which of the independent variables the variable y_2\ndepends on.\n\\n\n\\b Input:\nif y_3 is a variable, the set with index t is\nthe sparsity pattern corresponding to y_3.\nThis identifies which of the independent variables the variable y_3\ndepends on.\n\\n\n\\b Output:\nThe set with index T is\nthe sparsity pattern corresponding to z.\nThis identifies which of the independent variables the variable z\ndepends on.\n*/\ntemplate <class Vector_set>\ninline void forward_sparse_jacobian_cond_op(\n   bool               dependency    ,\n   size_t             i_z           ,\n   const addr_t*      arg           ,\n   size_t             num_par       ,\n   Vector_set&        sparsity      )\n{\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n# ifndef NDEBUG\n   addr_t k = 1;\n   for( size_t j = 0; j < 4; j++)\n   {  if( ! ( arg[1] & k ) )\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par );\n      k *= 2;\n   }\n# endif\n   sparsity.clear(i_z);\n   if( dependency )\n   {  if( arg[1] & 1 )\n         sparsity.binary_union(i_z, i_z, size_t(arg[2]), sparsity);\n      if( arg[1] & 2 )\n         sparsity.binary_union(i_z, i_z, size_t(arg[3]), sparsity);\n   }\n   if( arg[1] & 4 )\n      sparsity.binary_union(i_z, i_z, size_t(arg[4]), sparsity);\n   if( arg[1] & 8 )\n      sparsity.binary_union(i_z, i_z, size_t(arg[5]), sparsity);\n   return;\n}\n\n/*!\nCompute reverse Jacobian sparsity patterns for op = CExpOp.\n\nThis routine is given the sparsity patterns\nfor a function G(z, y, x, ... )\nand it uses them to compute the sparsity patterns for\n\\verbatim\n   H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ]\n\\endverbatim\nwhere y represents the combination of y_0, y_1, y_2, and y_3.\n\n<!-- replace sparse_conditional_exp_op -->\nThe C++ source code coresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end sparse_conditional_exp_op -->\n\n\\param dependency\nAre the derivatives with respect to left and right of the expression below\nconsidered to be non-zero:\n\\code\n   CondExpRel(left, right, if_true, if_false)\n\\endcode\nThis is used by the optimizer to obtain the correct dependency relations.\n\n\n\\param sparsity\nif y_2 is a variable, the set with index t is\nthe sparsity pattern corresponding to y_2.\nThis identifies which of the dependent variables depend on the variable y_2.\nOn input, this pattern corresponds to the function G.\nOn ouput, it corresponds to the function H.\n\\n\n\\n\nif y_3 is a variable, the set with index t is\nthe sparsity pattern corresponding to y_3.\nThis identifies which of the dependent variables depeond on the variable y_3.\nOn input, this pattern corresponds to the function G.\nOn ouput, it corresponds to the function H.\n\\n\n\\b Output:\nThe set with index T is\nthe sparsity pattern corresponding to z.\nThis identifies which of the dependent variables depend on the variable z.\nOn input and output, this pattern corresponds to the function G.\n*/\ntemplate <class Vector_set>\ninline void reverse_sparse_jacobian_cond_op(\n   bool                dependency    ,\n   size_t              i_z           ,\n   const addr_t*       arg           ,\n   size_t              num_par       ,\n   Vector_set&         sparsity      )\n{\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n# ifndef NDEBUG\n   addr_t k = 1;\n   for( size_t j = 0; j < 4; j++)\n   {  if( ! ( arg[1] & k ) )\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par );\n      k *= 2;\n   }\n# endif\n   if( dependency )\n   {  if( arg[1] & 1 )\n         sparsity.binary_union( size_t(arg[2]), size_t(arg[2]), i_z, sparsity);\n      if( arg[1] & 2 )\n         sparsity.binary_union( size_t(arg[3]), size_t(arg[3]), i_z, sparsity);\n   }\n   // --------------------------------------------------------------------\n   if( arg[1] & 4 )\n      sparsity.binary_union( size_t(arg[4]), size_t(arg[4]), i_z, sparsity);\n   if( arg[1] & 8 )\n      sparsity.binary_union( size_t(arg[5]), size_t(arg[5]), i_z, sparsity);\n   return;\n}\n\n/*!\nCompute reverse Hessian sparsity patterns for op = CExpOp.\n\nThis routine is given the sparsity patterns\nfor a function G(z, y, x, ... )\nand it uses them to compute the sparsity patterns for\n\\verbatim\n   H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ]\n\\endverbatim\nwhere y represents the combination of y_0, y_1, y_2, and y_3.\n\n<!-- replace sparse_conditional_exp_op -->\nThe C++ source code coresponding to this operation is\n\\verbatim\n   z = CondExpRel(y_0, y_1, y_2, y_3)\n\\endverbatim\nwhere Rel is one of the following: Lt, Le, Eq, Ge, Gt.\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\\param i_z\nis the AD variable index corresponding to the variable z.\n\n\\param arg\n\\n\n arg[0]\nis static cast to size_t from the enum type\n\\verbatim\n   enum CompareOp {\n      CompareLt,\n      CompareLe,\n      CompareEq,\n      CompareGe,\n      CompareGt,\n      CompareNe\n   }\n\\endverbatim\nfor this operation.\nNote that arg[0] cannot be equal to CompareNe.\n\\n\n\\n\n arg[1] & 1\n\\n\nIf this is zero, y_0 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 2\n\\n\nIf this is zero, y_1 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 4\n\\n\nIf this is zero, y_2 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1] & 8\n\\n\nIf this is zero, y_3 is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[2 + j ] for j = 0, 1, 2, 3\n\\n\nis the index corresponding to y_j.\n\n\\param num_par\nis the total number of values in the vector parameter.\n\n\\par Checked Assertions\n\\li NumArg(CExpOp) == 6\n\\li NumRes(CExpOp) == 1\n\\li arg[0] < static_cast<size_t> ( CompareNe )\n\\li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.\n\\li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.\n<!-- end sparse_conditional_exp_op -->\n\n\n\\param jac_reverse\n jac_reverse[i_z]\nis false (true) if the Jacobian of G with respect to z is always zero\n(may be non-zero).\n\\n\n\\n\n jac_reverse[ arg[4] ]\nIf y_2 is a variable,\n jac_reverse[ arg[4] ]\nis false (true) if the Jacobian with respect to y_2 is always zero\n(may be non-zero).\nOn input, it corresponds to the function G,\nand on output it corresponds to the function H.\n\\n\n\\n\n jac_reverse[ arg[5] ]\nIf y_3 is a variable,\n jac_reverse[ arg[5] ]\nis false (true) if the Jacobian with respect to y_3 is always zero\n(may be non-zero).\nOn input, it corresponds to the function G,\nand on output it corresponds to the function H.\n\n\\param hes_sparsity\nThe set with index i_z in hes_sparsity\nis the Hessian sparsity pattern for the function G\nwhere one of the partials is with respect to z.\n\\n\n\\n\nIf y_2 is a variable,\nthe set with index arg[4] in hes_sparsity\nis the Hessian sparsity pattern\nwhere one of the partials is with respect to y_2.\nOn input, this pattern corresponds to the function G.\nOn output, this pattern corresponds to the function H.\n\\n\n\\n\nIf y_3 is a variable,\nthe set with index arg[5] in hes_sparsity\nis the Hessian sparsity pattern\nwhere one of the partials is with respect to y_3.\nOn input, this pattern corresponds to the function G.\nOn output, this pattern corresponds to the function H.\n*/\ntemplate <class Vector_set>\ninline void reverse_sparse_hessian_cond_op(\n   size_t               i_z           ,\n   const addr_t*        arg           ,\n   size_t               num_par       ,\n   bool*                jac_reverse   ,\n   Vector_set&          hes_sparsity  )\n{\n\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( NumArg(CExpOp) == 6 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n# ifndef NDEBUG\n   addr_t k = 1;\n   for( size_t j = 0; j < 4; j++)\n   {  if( ! ( arg[1] & k ) )\n         CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par );\n      k *= 2;\n   }\n# endif\n   if( arg[1] & 4 )\n   {\n      hes_sparsity.binary_union( size_t(arg[4]), size_t(arg[4]), i_z, hes_sparsity);\n      jac_reverse[ arg[4] ] |= jac_reverse[i_z];\n   }\n   if( arg[1] & 8 )\n   {\n      hes_sparsity.binary_union( size_t(arg[5]), size_t(arg[5]), i_z, hes_sparsity);\n      jac_reverse[ arg[5] ] |= jac_reverse[i_z];\n   }\n   return;\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/cos_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_COS_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_COS_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void cos_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(CosOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CosOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* c = taylor + i_z * cap_order;\n   Base* s = c      -       cap_order;\n\n\n   // rest of this routine is identical for the following cases:\n   // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op.\n   // (except that there is a sign difference for the hyperbolic case).\n   size_t k;\n   if( p == 0 )\n   {  s[0] = sin( x[0] );\n      c[0] = cos( x[0] );\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {\n      s[j] = Base(0.0);\n      c[j] = Base(0.0);\n      for(k = 1; k <= j; k++)\n      {  s[j] += Base(double(k)) * x[k] * c[j-k];\n         c[j] -= Base(double(k)) * x[k] * s[j-k];\n      }\n      s[j] /= Base(double(j));\n      c[j] /= Base(double(j));\n   }\n}\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void cos_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(CosOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CosOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* c = taylor + i_z * num_taylor_per_var;\n   Base* s = c      -       num_taylor_per_var;\n\n\n   // rest of this routine is identical for the following cases:\n   // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op\n   // (except that there is a sign difference for the hyperbolic case).\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  s[m+ell] =   Base(double(q)) * x[m + ell] * c[0];\n      c[m+ell] = - Base(double(q)) * x[m + ell] * s[0];\n      for(size_t k = 1; k < q; k++)\n      {  s[m+ell] += Base(double(k)) * x[(k-1)*r+1+ell] * c[(q-k-1)*r+1+ell];\n         c[m+ell] -= Base(double(k)) * x[(k-1)*r+1+ell] * s[(q-k-1)*r+1+ell];\n      }\n      s[m+ell] /= Base(double(q));\n      c[m+ell] /= Base(double(q));\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void cos_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(CosOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CosOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* c = taylor + i_z * cap_order;  // called z in documentation\n   Base* s = c      -       cap_order;  // called y in documentation\n\n   c[0] = cos( x[0] );\n   s[0] = sin( x[0] );\n}\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void cos_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(CosOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CosOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to first result\n   const Base* c  = taylor  + i_z * cap_order; // called z in doc\n   Base* pc       = partial + i_z * n_order;\n\n   // Taylor coefficients and partials corresponding to auxiliary result\n   const Base* s  = c  - cap_order; // called y in documentation\n   Base* ps       = pc - n_order;\n\n\n   // rest of this routine is identical for the following cases:\n   // reverse_sin_op, reverse_cos_op, reverse_sinh_op, reverse_cosh_op.\n   size_t j = d;\n   size_t k;\n   while(j)\n   {\n      ps[j]   /= Base(double(j));\n      pc[j]   /= Base(double(j));\n      for(k = 1; k <= j; k++)\n      {\n         px[k]   += Base(double(k)) * azmul(ps[j], c[j-k]);\n         px[k]   -= Base(double(k)) * azmul(pc[j], s[j-k]);\n\n         ps[j-k] -= Base(double(k)) * azmul(pc[j], x[k]);\n         pc[j-k] += Base(double(k)) * azmul(ps[j], x[k]);\n\n      }\n      --j;\n   }\n   px[0] += azmul(ps[0], c[0]);\n   px[0] -= azmul(pc[0], s[0]);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/cosh_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_COSH_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_COSH_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void cosh_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(CoshOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CoshOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* c = taylor + i_z * cap_order;\n   Base* s = c      -       cap_order;\n\n   // rest of this routine is identical for the following cases:\n   // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op.\n   // (except that there is a sign difference for hyperbolic case).\n   size_t k;\n   if( p == 0 )\n   {  s[0] = sinh( x[0] );\n      c[0] = cosh( x[0] );\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {\n      s[j] = Base(0.0);\n      c[j] = Base(0.0);\n      for(k = 1; k <= j; k++)\n      {  s[j] += Base(double(k)) * x[k] * c[j-k];\n         c[j] += Base(double(k)) * x[k] * s[j-k];\n      }\n      s[j] /= Base(double(j));\n      c[j] /= Base(double(j));\n   }\n}\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void cosh_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(CoshOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CoshOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* s = taylor + i_z * num_taylor_per_var;\n   Base* c = s      -       num_taylor_per_var;\n\n\n   // rest of this routine is identical for the following cases:\n   // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op\n   // (except that there is a sign difference for the hyperbolic case).\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  s[m+ell] = Base(double(q)) * x[m + ell] * c[0];\n      c[m+ell] = Base(double(q)) * x[m + ell] * s[0];\n      for(size_t k = 1; k < q; k++)\n      {  s[m+ell] += Base(double(k)) * x[(k-1)*r+1+ell] * c[(q-k-1)*r+1+ell];\n         c[m+ell] += Base(double(k)) * x[(k-1)*r+1+ell] * s[(q-k-1)*r+1+ell];\n      }\n      s[m+ell] /= Base(double(q));\n      c[m+ell] /= Base(double(q));\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void cosh_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(CoshOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CoshOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* c = taylor + i_z * cap_order;  // called z in documentation\n   Base* s = c      -       cap_order;  // called y in documentation\n\n   c[0] = cosh( x[0] );\n   s[0] = sinh( x[0] );\n}\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void cosh_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(CoshOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(CoshOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to first result\n   const Base* c  = taylor  + i_z * cap_order; // called z in doc\n   Base* pc       = partial + i_z * n_order;\n\n   // Taylor coefficients and partials corresponding to auxiliary result\n   const Base* s  = c  - cap_order; // called y in documentation\n   Base* ps       = pc - n_order;\n\n\n   // rest of this routine is identical for the following cases:\n   // reverse_sin_op, reverse_cos_op, reverse_sinh_op, reverse_cosh_op.\n   size_t j = d;\n   size_t k;\n   while(j)\n   {\n      ps[j]   /= Base(double(j));\n      pc[j]   /= Base(double(j));\n      for(k = 1; k <= j; k++)\n      {\n         px[k]   += Base(double(k)) * azmul(ps[j], c[j-k]);\n         px[k]   += Base(double(k)) * azmul(pc[j], s[j-k]);\n\n         ps[j-k] += Base(double(k)) * azmul(pc[j], x[k]);\n         pc[j-k] += Base(double(k)) * azmul(ps[j], x[k]);\n\n      }\n      --j;\n   }\n   px[0] += azmul(ps[0], c[0]);\n   px[0] += azmul(pc[0], s[0]);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/cskip_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_CSKIP_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_CSKIP_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n/*!\n{xrst_begin_parent var_cskip_op dev}\n\nThe Conditional Skip Operator\n#############################\n\nCSkipOp\n*******\nis the op code for this operator.\n\nUser Syntax\n***********\n| *z* = ``CondExp`` *Rel* ( *left* , *right* , *if_true* , *if_false* )\n\nRel\n***\nis Lt, Le, Eq, Ge, or Gt .\n\narg\n***\n\narg[0]\n======\nIs the comparison operator for this conditional skip\nas a static cast from CompareOp to addr_t :\n{xrst_literal\n   include/cppad/local/declare_ad.hpp\n   // BEGIN_COMPARE_OP\n   // END_COMPARE_OP\n}\nNote that arg[0] cannot be equal to CompareNe; i.e.\nthe last enum value CompareNe will not appear.\n\narg[1]\n======\nThe first two bits of this value are used as flags; see below.\n\narg[2]\n======\nIf arg[1] & 1 is zero (is one) ,\narg[2] is the parameter (variable) index corresponding to *left* .\n\narg[3]\n======\nIf arg[1] & 2 is zero (is one) ,\narg[3] is the parameter (variable) index corresponding to *right* .\n\narg[4]\n======\nis the number of operations to skip if the comparison result is true\nand the left and right operands are\n:ref:`base_identical@Identical@IdenticalCon` .\n\narg[5]\n======\nis the number of operations to skip if the comparison result is false\nand the left and right operands are identically constant.\n\narg[6+i]\n========\nFor i = 0 , ... , arg[4] - 1,\narg[6 + i] is the index of an operation to skip if the comparison\nis identically true.\n\narg[6+arg[4]+i]\n===============\nFor i = 0 , ... , arg[5] - 1,\narg[6 + i] is the index of an operation to skip if the comparison\nis identically false.\n\narg[6+arg[4]+arg[5]]\n====================\nThis is equal to 6 + arg[4] + arg[5] + 1,\nwhich is the total number or arguments to this operator.\nHaving this value at the end enables reverse mode to know how far\nto back up to get to the start of this operation.\n\n{xrst_end var_cskip_op}\n------------------------------------------------------------------------------\n{xrst_begin var_cskip_forward_0 dev}\n\nZero Order Forward Conditional Skip Operator\n############################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CSKIP_FORWARD_0\n   // END_CSKIP_FORWARD_0\n}\n\nRecBase\n*******\nis the base type use when recording this operator;\ni.e., this operation was recording using AD< *RecBase* > operations.\n\nBase\n****\nis the type used for computations by this operator.\nThis is either *RecBase* or AD< *RecBase* >.\n\ni_z\n***\nvariable index corresponding to the result of the previous operation.\nThis is only used for error checking. To be specific,\nif the left and right operand for the conditional expression is a variable,\nits index must be less than or equal this value.\n\nnum_par\n*******\nis the total number of values in the *parameter* vector.\n\nparameter\n*********\nmaps parameter indices to parameter values.\n\ncap_order\n*********\nis the maximum number of orders that can fit in *taylor* .\n\ntaylor\n******\nFor *j* <= *i_z* ,\nthe Taylor coefficient corresponding to variable *j* and order zero is\n\n   *taylor* [ *j* * *cap_order* + 0  ]\n\ncskip_op\n********\nis vector specifying which operations are at this point are know to be\nunnecessary and can be skipped. This is both an input and an output; i.e.,\nthe call may add more true values to *cskip_op* .\n\n{xrst_end var_cskip_forward_0}\n*/\n// BEGIN_CSKIP_FORWARD_0\ntemplate <class Base>\ninline void cskip_forward_0(\n   size_t               i_z            ,\n   const addr_t*        arg            ,\n   size_t               num_par        ,\n   const Base*          parameter      ,\n   size_t               cap_order      ,\n   Base*                taylor         ,\n   bool*                cskip_op       )\n// END_CSKIP_FORWARD_0\n{  //\n   //\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < size_t(CompareNe) );\n   CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );\n   //\n   Base left, right;\n   if( arg[1] & 1 )\n   {  // If variable arg[2] <= i_z, it has already been computed,\n      // but it will be skipped for higher orders.\n      CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) <= i_z );\n      left = taylor[ size_t(arg[2]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );\n      left = parameter[ arg[2] ];\n   }\n   if( arg[1] & 2 )\n   {  // If variable arg[3] <= i_z, it has already been computed,\n      // but it will be skipped for higher orders.\n      CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) <= i_z );\n      right = taylor[ size_t(arg[3]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );\n      right = parameter[ arg[3] ];\n   }\n   bool ok_to_skip = IdenticalCon(left) && IdenticalCon(right);\n   if( ! ok_to_skip )\n      return;\n\n   // initialize to avoid compiler warning\n   bool true_case = false;\n   Base diff      = left - right;\n   switch( CompareOp( arg[0] ) )\n   {\n      case CompareLt:\n      true_case = LessThanZero(diff);\n      break;\n\n      case CompareLe:\n      true_case = LessThanOrZero(diff);\n      break;\n\n      case CompareEq:\n      true_case = IdenticalZero(diff);\n      break;\n\n      case CompareGe:\n      true_case = GreaterThanOrZero(diff);\n      break;\n\n      case CompareGt:\n      true_case = GreaterThanZero(diff);\n      break;\n\n      case CompareNe:\n      true_case = ! IdenticalZero(diff);\n      break;\n\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n   }\n   if( true_case )\n   {  for(addr_t i = 0; i < arg[4]; i++)\n         cskip_op[ arg[6+i] ] = true;\n   }\n   else\n   {  for(addr_t i = 0; i < arg[5]; i++)\n         cskip_op[ arg[6+arg[4]+i] ] = true;\n   }\n   return;\n}\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/csum_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_CSUM_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_CSUM_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n/*\n{xrst_begin_parent var_csum_op dev}\n\nVariable Cumulative Summation Operator\n######################################\n\nCSumOp\n******\nis the op code for this operator.\n\nUser Syntax\n***********\n::\n\n   z = s\n       + x[0] + ... + x[ n1 - 1 ]\n       - y[0] - ... - y[ n2 - 1 ]\n       + u[0] + ... + u[ n3 - 1 ]\n       - v[0] - ... - v[ n4 - 1 ]\n\ns\n*\nis the constant parameter that initializes the summation.\n\nx\n*\nis the vector of addition variables that appear in the sum.\n\ny\n*\nis the vector of subtraction variables that appear in the sum.\n\nu\n*\nis the vector of addition dynamic parameters that appear in the sum.\n\nv\n*\nis the vector of subtraction dynamic parameters that appear in the sum.\n\nz\n*\nis the result of the summation.\n\nRecBase\n*******\nis the base type use when recording this operator;\ni.e., this operation was recording using AD< *RecBase* > operations.\n\nBase\n****\nis the type used for computations by this operator.\nThis is either *RecBase* or AD< *RecBase* >.\n\ni_z\n***\nis the variable index corresponding to the result for this operation;\ni.e. the row index in taylor corresponding to *z* .\n\narg\n***\n\narg[0]\n======\nis the index of the constant parameter *s* in the parameter vector.\n\narg[1]\n======\nis the index in arg of the end of the addition variables; i.e.,\n*n1* = arg[1] - 5 .\n\narg[2]\n======\nis the index in arg of the end of the subtraction variables; i.e.,\n*n2* = arg[2] - arg[1] .\n\narg[3]\n======\nis the index in arg of the end of the addition dynamic parameters; i.e.,\n*n3* = arg[3] - arg[2] .\n\narg[4]\n======\nis the index in arg of the end of the subtraction dynamic parameters; i.e.,\n*n4* = arg[4] - arg[3] .\n\narg[5+j]\n========\nfor j = 0 , ... , n1 - 1, arg[5 + j]\nis the index corresponding to the variable x[j] .\n\narg[ arg[1]+j ]\n===============\nfor j = 0 , ... , n2 - 1, arg[ arg[1] + j ]\nis the index corresponding to the variable y[j] .\n\narg[ arg[2]+j ]\n===============\nfor j = 0 , ... , n3 - 1, arg[ arg[2] + j ]\nis the index corresponding to the dynamic parameter u[j] .\n\narg[ arg[3]+j ]\n===============\nfor j = 0 , ... , n4 - 1, arg[ arg[3] + j ]\nis the index corresponding to the dynamic parameter v[j] .\n\narg[ arg[4] ]\n=============\nThis is equal to arg[4] + 1\nwhich is the total number or arguments to this operator.\nHaving this value at the end enables reverse mode to know how far\nto back up to get to the start of this operation.\n\n{xrst_end var_csum_op}\n-----------------------------------------------------------------------------\n{xrst_begin var_csum_forward_any dev}\n\nAny Order Forward Cumulative Summation Operation\n################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CSUM_FORWARD_ANY\n   // END_CSUM_FORWARD_ANY\n}\n\nx, y, u, v, z\n*************\nsee\n:ref:`var_csum_op@x` ,\n:ref:`var_csum_op@y` ,\n:ref:`var_csum_op@u` ,\n:ref:`var_csum_op@v` ,\n:ref:`var_csum_op@z`\n\ni_z, arg\n********\nsee\n:ref:`var_csum_op@i_z` ,\n:ref:`var_csum_op@arg`\n\n{xrst_template ;\n   include/cppad/local/var_op/template/forward_op.xrst\n   headers: cap_order, order_low, order_up, taylor\n}\n\nnum_par\n*******\nis the number of parameters in parameter.\n\nparameter\n*********\nis the parameter vector for this operation sequence.\n\n{xrst_end var_csum_forward_any}\n*/\n// BEGIN_CSUM_FORWARD_ANY\ntemplate <class Base>\ninline void csum_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        num_par     ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n// END_CSUM_FORWARD_ANY\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumRes(CSumOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( order_up < cap_order );\n   CPPAD_ASSERT_UNKNOWN( order_low <= order_up );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n   CPPAD_ASSERT_UNKNOWN( arg[arg[4]] == arg[4] + 1 );\n   //\n   // zero\n   Base zero(0);\n   //\n   // z\n   Base* z = taylor + i_z    * cap_order;\n   for(size_t k = order_low; k <= order_up; k++)\n      z[k] = zero;\n   //\n   if( order_low == 0 )\n   {  // constant parameter\n      z[order_low] = parameter[ arg[0] ];\n      // addition dynamic parameters\n      for(addr_t i = arg[2]; i < arg[3]; ++i)\n         z[order_low] += parameter[ arg[i] ];\n      // subtraction dynamic parameters\n      for(addr_t i = arg[3]; i < arg[4]; ++i)\n         z[order_low] -= parameter[ arg[i] ];\n   }\n   // addition variables\n   for(addr_t i = 5; i < arg[1]; ++i)\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z );\n      Base* x = taylor + size_t(arg[i]) * cap_order;\n      for(size_t k = order_low; k <= order_up; k++)\n         z[k] += x[k];\n   }\n   // subtraction variables\n   for(addr_t i = arg[1]; i < arg[2]; ++i)\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z );\n      Base* x = taylor + size_t(arg[i]) * cap_order;\n      for(size_t k = order_low; k <= order_up; k++)\n         z[k] -= x[k];\n   }\n}\n/*\n{xrst_begin var_csum_forward_dir dev}\n\nMultiple Direction Forward Mode Cumulative Summation Operation\n##############################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CSUM_FORWARD_DIR\n   // END_CSUM_FORWARD_DIR\n}\n\nx, y, u, v, z\n*************\nsee\n:ref:`var_csum_op@x` ,\n:ref:`var_csum_op@y` ,\n:ref:`var_csum_op@u` ,\n:ref:`var_csum_op@v` ,\n:ref:`var_csum_op@z`\n\ni_z, arg\n********\nsee\n:ref:`var_csum_op@i_z` ,\n:ref:`var_csum_op@arg`\n\nnum_par\n*******\nis the number of parameters in parameter.\n\nparameter\n*********\nis the parameter vector for this operation sequence.\n\n{xrst_template ;\n   include/cppad/local/var_op/template/forward_dir.xrst\n   headers: n_dir, cap_order, order_up, taylor\n}\n\n{xrst_end var_csum_forward_dir}\n*/\n// BEGIN_CSUM_FORWARD_DIR\ntemplate <class Base>\ninline void csum_forward_dir(\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        num_par     ,\n   const Base*   parameter   ,\n   size_t        n_dir       ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n// END_CSUM_FORWARD_DIR\n{  //\n   //\n   CPPAD_ASSERT_UNKNOWN( NumRes(CSumOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( order_up < cap_order );\n   CPPAD_ASSERT_UNKNOWN( 0 < order_up );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n   CPPAD_ASSERT_UNKNOWN( arg[arg[4]] == arg[4] + 1 );\n   //\n   // zero\n   Base zero(0);\n   //\n   // per_variable\n   size_t per_variable = (cap_order-1) * n_dir + 1;\n   //\n   // m\n   size_t m = (order_up - 1) * n_dir + 1;\n   //\n   // z\n   Base* z = taylor + i_z * per_variable + m;\n   for(size_t ell = 0; ell < n_dir; ell++)\n      z[ell] = zero;\n   //\n   // addition variables\n   for(addr_t i = 5; i < arg[1]; ++i)\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z );\n      Base* x = taylor + size_t(arg[i]) * per_variable + m;\n      for(size_t ell = 0; ell < n_dir; ell++)\n         z[ell] += x[ell];\n   }\n   //\n   // subtraction variables\n   for(addr_t i = arg[1]; i < arg[2]; ++i)\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z );\n      Base* x = taylor + size_t(arg[i]) * per_variable + m;\n      for(size_t ell = 0; ell < n_dir; ell++)\n         z[ell] -= x[ell];\n   }\n}\n/*\n---------------------------------------------------------------------------\n{xrst_begin var_csum_reverse dev}\n\nReverse Mode Cumulative Summation Operation\n###########################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CSUM_REVERSE\n   // END_CSUM_REVERSE\n}\n\nx, y, u, v, z\n*************\nsee\n:ref:`var_csum_op@x` ,\n:ref:`var_csum_op@y` ,\n:ref:`var_csum_op@u` ,\n:ref:`var_csum_op@v` ,\n:ref:`var_csum_op@z`\n\ni_z, arg\n********\nsee\n:ref:`var_csum_op@i_z` ,\n:ref:`var_csum_op@arg`\n\n{xrst_template ;\n   include/cppad/local/var_op/template/reverse_op.xrst\n   headers: n_order, partial\n\n   @x, y@  ; x, y, u, v\n}\n\n{xrst_end var_csum_reverse}\n*/\n// BEGIN_CSUM_REVERSE\ntemplate <class Base>\ninline void csum_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        n_order     ,\n   Base*         partial     )\n// END_CSUM_REVERSE\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   //\n   CPPAD_ASSERT_UNKNOWN( NumRes(CSumOp) == 1 );\n   //\n   // pz, dp1\n   Base* pz = partial + i_z * n_order;\n   size_t dp1 = d + 1;\n   //\n   // addition variables\n   for(addr_t i = 5; i < arg[1]; ++i)\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z );\n      Base* px = partial + size_t(arg[i]) * n_order;\n      size_t k = dp1;\n      while(k--)\n         px[k] += pz[k];\n   }\n   //\n   // subtraction variables\n   for(addr_t i = arg[1]; i < arg[2]; ++i)\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z );\n      Base* px = partial + size_t(arg[i]) * n_order;\n      size_t k = dp1;\n      while(k--)\n         px[k] -= pz[k];\n   }\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_csum_for_jac dev}\n\nForward Jacobian Sparsity for Cumulative Summation\n##################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CSUM_FOR_JAC\n   // END_CSUM_FOR_JAC\n}\n\nx, y, u, v, z\n*************\nsee\n:ref:`var_csum_op@x` ,\n:ref:`var_csum_op@y` ,\n:ref:`var_csum_op@u` ,\n:ref:`var_csum_op@v` ,\n:ref:`var_csum_op@z`\n\ni_z, arg\n********\nsee\n:ref:`var_csum_op@i_z` ,\n:ref:`var_csum_op@arg`\n\nVector_set\n**********\nis the type used for vectors of sets.\nIt must satisfy the :ref:`SetVector-name` concept.\n\ni_z\n\nsparsity\n********\n\nInput\n=====\nFor k = 0 , ... , i_z - 1,\nthe set with index k in *sparsity*\nidentifies which independent variables the variable with index k depends on.\n\nOutput\n======\nThe set with index i_z in *sparsity*\nidentifies which independent variables the variable *z* depends on.\n\n{xrst_end var_csum_for_jac}\n*/\n// BEGIN_CSUM_FOR_JAC\ntemplate <class Vector_set>\ninline void csum_for_jac(\n   size_t           i_z         ,\n   const addr_t*    arg         ,\n   Vector_set&      sparsity    )\n// END_CSUM_FOR_JAC\n{  //\n   //\n   // sparsity\n   sparsity.clear(i_z);\n   //\n   // addition and subtraction variables\n   for(addr_t i = 5; i < arg[2]; ++i)\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z );\n      sparsity.binary_union(\n         i_z            , // index in sparsity for result\n         i_z            , // index in sparsity for left operand\n         size_t(arg[i]) , // index for right operand\n         sparsity         // sparsity vector for right operand\n      );\n   }\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_csum_rev_jac dev}\n\nReverse Jacobian Sparsity for Cumulative Summation\n##################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CSUM_REV_JAC\n   // END_CSUM_REV_JAC\n}\n\nx, y, u, v, z\n*************\nsee\n:ref:`var_csum_op@x` ,\n:ref:`var_csum_op@y` ,\n:ref:`var_csum_op@u` ,\n:ref:`var_csum_op@v` ,\n:ref:`var_csum_op@z`\n\ni_z, arg\n********\nsee\n:ref:`var_csum_op@i_z` ,\n:ref:`var_csum_op@arg`\n\nVector_set\n**********\nis the type used for vectors of sets.\nIt must satisfy the :ref:`SetVector-name` concept.\n\n\nsparsity\n********\nThe set with index *i_z* is the sparsity pattern for *z* .\nThis sparsity pattern is added th the sparsity pattern for the\nvariables in the vectors *x* and *y* .\n\n{xrst_end var_csum_rev_jac}\n*/\n// BEGIN_CSUM_REV_JAC\ntemplate <class Vector_set>\ninline void csum_rev_jac(\n   size_t           i_z         ,\n   const addr_t*    arg         ,\n   Vector_set&      sparsity    )\n// END_CSUM_REV_JAC\n{  //\n   //\n   // addition and subtraction variables\n   for(addr_t i = 5; i < arg[2]; ++i)\n   {\n      CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z );\n      sparsity.binary_union(\n         size_t(arg[i]), // index in sparsity for result\n         size_t(arg[i]), // index in sparsity for left operand\n         i_z        , // index for right operand\n         sparsity     // sparsity vector for right operand\n      );\n   }\n}\n/*\n{xrst_begin var_csum_rev_hes dev}\n\nReverse Hessian Sparsity for Cumulative Summation\n#################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CSUM_REV_HES\n   // END_CSUM_REV_HES\n}\n\nx, y, u, v, z\n*************\nsee\n:ref:`var_csum_op@x` ,\n:ref:`var_csum_op@y` ,\n:ref:`var_csum_op@u` ,\n:ref:`var_csum_op@v` ,\n:ref:`var_csum_op@z`\n\ni_z, arg\n********\nsee\n:ref:`var_csum_op@i_z` ,\n:ref:`var_csum_op@arg`\n\nG, H\n****\nWe use *G* to denote the scalar function we are computing the\nsparsity pattern for as a function of the variables up to and including *z* .\nWe use *H* for the function with *z* replaced by its operator; i.e.::\n\n   H(x, y, u, v, ...) = G[ z(x, y, u, v) , x, y, u, v, ... ]\n\nVector_set\n**********\nis the type used for vectors of sets.\nIt must satisfy the :ref:`SetVector-name` concept.\n\nrev_jacobian\n************\n#. If rev_jacobian[i_z] is true (false),\n   *G* may depend (does not depend) on *z* .\n\n#. If *j* is the index of an addition variable in the vector *x* or *y* ,\n   and *G* may depend on *z* ,\n   rev_jacobian[j] is set to true.\n\nrev_hes_sparsity\n****************\nOn input, *rev_hes_sparsity*\ncontains the Hessian sparsity pattern for the function *G* .\nOn output, it contains the Hessian sparsity pattern for the function *H* .\n\n{xrst_end var_csum_rev_hes}\n*/\n// BEGIN_CSUM_REV_HES\ntemplate <class Vector_set>\ninline void csum_rev_hes(\n   size_t           i_z                 ,\n   const addr_t*    arg                 ,\n   bool*            rev_jacobian        ,\n   Vector_set&      rev_hes_sparsity    )\n// END_CSUM_REV_HES\n{  //\n   //\n   // addition and subtraction variables\n   for(addr_t i = 5; i < arg[2]; ++i)\n   {\n      CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z );\n      rev_hes_sparsity.binary_union(\n         size_t(arg[i])     , // index in sparsity for result\n         size_t(arg[i])     , // index in sparsity for left operand\n         i_z                , // index for right operand\n         rev_hes_sparsity     // sparsity vector for right operand\n      );\n      rev_jacobian[arg[i]] |= rev_jacobian[i_z];\n   }\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_csum_for_hes dev}\n\nForward Hessian Sparsity for Cumulative Summation\n#################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CSUM_FOR_HES\n   // END_CSUM_FOR_HES\n}\n\nx, y, u, v, z\n*************\nsee\n:ref:`var_csum_op@x` ,\n:ref:`var_csum_op@y` ,\n:ref:`var_csum_op@u` ,\n:ref:`var_csum_op@v` ,\n:ref:`var_csum_op@z`\n\ni_z, arg\n********\nsee\n:ref:`var_csum_op@i_z` ,\n:ref:`var_csum_op@arg`\n\nVector_set\n**********\nis the type used for vectors of sets.\nIt must satisfy the :ref:`SetVector-name` concept.\n\nn\n*\nis the number of independent variables on the tape.\n\nfor_hes_sparse\n**************\nsee :ref:`local_sweep_for_hes@for_hes_sparse` .\n\n{xrst_end var_csum_for_hes}\n*/\n// BEGIN_CSUM_FOR_HES\ntemplate <class Vector_set>\ninline void csum_for_hes(\n   const addr_t*             arg            ,\n   size_t                    i_z            ,\n   size_t                    n              ,\n   Vector_set&               for_hes_sparse )\n// END_CSUM_FOR_HES\n{  //\n   //\n   // np1\n   size_t np1 = n + 1;\n   //\n   // for_hes_sparse\n   for_hes_sparse.clear(np1 + i_z);\n   //\n   // addition and subtraction variables\n   for(addr_t i = 5; i < arg[2]; ++i)\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[i]) < i_z );\n      //\n      // linear functions only modify forward Jacobian sparsity\n      for_hes_sparse.binary_union(\n         np1 + i_z            , // index in sparsity for result\n         np1 + i_z            , // index in sparsity for left operand\n         np1 + size_t(arg[i]) , // index for right operand\n         for_hes_sparse         // sparsity vector for right operand\n      );\n   }\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/dis_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_DIS_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_DIS_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin_parent var_dis_op dev}\n\nVariable Discrete Operator\n##########################\n\nDisOp\n*****\nis the op code for this operator.\n\nUser Syntax\n***********\n| *z* = *name* ( *x* )\n\nname\n****\nis the :ref:`Discrete@name` of he discrete function.\n\nx\n*\nis the argument for this discrete function.\n\nz\n*\nis the new variable created by this function evaluation.\n(Note that this is called :ref:`Discrete@y` is the user documentation\nfor discrete functions.)\n\narg\n***\n\narg[0]\n======\nis the index that identifies this discrete function.\n\narg[1]\n======\nvariable index corresponding to the argument for this function call.\n\n\n{xrst_end var_dis_op}\n------------------------------------------------------------------------------\n{xrst_begin dis_forward_dir dev}\n{xrst_spell\n   ataylor\n   tpv\n}\n\nForward Mode Result for Discrete Functions\n##########################################\n\nname, x, z, arg\n***************\nsee\n:ref:`var_dis_op@name` ,\n:ref:`var_dis_op@x` ,\n:ref:`var_dis_op@z` ,\n:ref:`var_dis_op@arg`\n\nPrototype\n*********\n\nRecBase\n=======\n{xrst_literal\n   // BEGIN_DIS_FORWARD_ANY\n   // END_DIS_FORWARD_ANY\n}\n\nAD<RecBase>\n===========\n{xrst_literal\n   // BEGIN_AD_DIS_FORWARD_ANY\n   // END_AD_DIS_FORWARD_ANY\n}\n\nRecBase\n*******\nIs the Base type when this function was recorded; i.e.,\n:ref:`Discrete@ax` and :ref:`Discrete@ay` have type ``AD`` < *RecBase* > .\n\norder_low\n*********\nis the lowest order Taylor coefficient that will be calculated.\n\norder_up\n********\nis the highest order Taylor coefficient that will be calculated.\n\nn_dir\n*****\nis the number of directions, for each order,\nthat will be calculated (except for order zero which only has one direction).\n\ni_z\n***\nvariable index corresponding to the result for this operation;\ni.e. the row index in *taylor* or *ataylor* corresponding to *z* .\n\ncap_order\n*********\nis the maximum number of orders that can fit in *taylor* or *ataylor* .\n\ntpv\n***\nWe use the notation\n\n   *tpv* = ( *cap_order* - 1 ) * *n_dir*  + 1\n\nwhich is the number of Taylor coefficients per variable\n\ntaylor\n******\n\nInput\n=====\nThe zero order Taylor coefficient corresponding to x::\n\n   taylor[ arg[1] * tpv + 0 ]\n\nOutput\n======\nIf *order_low* is zero::\n\n   taylor[ i_z * tpv + 0 ]\n\nis the zero order Taylor coefficient corresponding to z.\nFor k = max(order_low, 1), ... , order_up,\n\n   taylor[ i_z * tpv + (k-1)*n_dir + 1 + ell ]\n\nis the k-th order Taylor coefficient corresponding to z (which is zero).\n\nataylor\n*******\nThis has the same description as *taylor* except that its type is\n``AD`` < *RecBase* > instead of *RecBase* .\n\n{xrst_end dis_forward_dir}\n*/\nnamespace CppAD { namespace local { namespace var_op {\n\n// ---------------------------------------------------------------------------\n// BEGIN_DIS_FORWARD_ANY\ntemplate <class RecBase>\ninline void dis_forward_dir(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   RecBase*      taylor      )\n// END_DIS_FORWARD_ANY\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DisOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DisOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( 0 < r );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   RecBase* x = taylor + size_t(arg[1]) * num_taylor_per_var;\n   RecBase* z = taylor +    i_z * num_taylor_per_var;\n\n   if( p == 0 )\n   {  z[0]  = discrete<RecBase>::eval(size_t(arg[0]), x[0]);\n      p++;\n   }\n   for(size_t ell = 0; ell < r; ell++)\n      for(size_t k = p; k <= q; k++)\n         z[ (k-1) * r + 1 + ell ] = RecBase(0.0);\n}\n// ---------------------------------------------------------------------------\n// BEGIN_AD_DIS_FORWARD_ANY\ntemplate <class RecBase>\ninline void dis_forward_dir(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   AD<RecBase>*  ataylor     )\n// END_AD_DIS_FORWARD_ANY\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DisOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DisOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( 0 < r );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   AD<RecBase>* ax = ataylor + size_t(arg[1]) * num_taylor_per_var;\n   AD<RecBase>* az = ataylor +    i_z * num_taylor_per_var;\n\n   if( p == 0 )\n   {  az[0]  = discrete<RecBase>::ad_eval(size_t(arg[0]), ax[0]);\n      p++;\n   }\n   for(size_t ell = 0; ell < r; ell++)\n      for(size_t k = p; k <= q; k++)\n         az[ (k-1) * r + 1 + ell ] = AD<RecBase>(0.0);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/discrete_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_DISCRETE_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_DISCRETE_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin discrete_op dev}\n{xrst_spell\n   ataylor\n   az\n   tpv\n}\n\nForward Mode Result for Discrete Functions\n##########################################\n\nSyntax\n******\n| ``forward_dis_op`` (\n| |tab| *p* , *q* , *r* , *i_z* , *arg* , *cap_order* , *taylor*\n| ) ``forward_dis_op`` (\n| |tab| *p* , *q* , *r* , *i_z* , *arg* , *cap_order* , *ataylor*\n| )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nUsage\n*****\nThe C++ source code corresponding to this operation is\n\n   *az* = *f* ( *ax* )\n\nwhere *f* is a piecewise constant function and it's derivative is\nalways calculated as zero.\n\nRecBase\n*******\nIs the Base type when this function was recorded; i.e.,\n*ax* and *az* have type ``AD`` < *RecBase* > .\n\np\n*\nis the lowest order Taylor coefficient that will be calculated.\n\nq\n*\nis the highest order Taylor coefficient that will be calculated.\n\nr\n*\nis the number of directions, for each order,\nthat will be calculated (except for order zero which only has one direction).\n\ni_z\n***\nvariable index corresponding to the result for this operation;\ni.e. the row index in *taylor* or *ataylor* corresponding to\n*z* .\n\narg\n***\n\narg[0]\n======\nis the index, in the order of the discrete functions defined by the user,\nfor this discrete function.\n\narg[1]\n======\nvariable index corresponding to the argument for this operator;\ni.e. the row index in *taylor* or *ataylor* corresponding to x.\n\ncap_order\n*********\nmaximum number of orders that will fit in the taylor array.\n\ntpv\n***\nWe use the notation\n\n   *tpv* = ( *cap_order* ``-1`` ) * *r*  + 1\n\nwhich is the number of Taylor coefficients per variable\n\ntaylor\n******\nThe type of this parameter is *RecBase* .\n\nInput\n=====\nThe value taylor[ arg[1] * tpv + 0 ]\nis the zero order Taylor coefficient corresponding to x.\n\nOutput\n======\nIf *p* is zero,\ntaylor[ i_z * tpv + 0 ]\nis the zero order Taylor coefficient corresponding to z.\nFor k = max(p, 1), ... , q,\ntaylor[ i_z * tpv + (k-1)*r + 1 + ell ]\nis the k-th order Taylor coefficient corresponding to z\n(which is zero).\n\nataylor\n*******\nThe type of this parameter is ``AD`` < *RecBase* > .\nOtherwise, it has the same description as *taylor* .\n\nAsserts\n*******\nNumArg(op) == 2, NumRes(op) == 1,  q < cap_order, 0 < r\n\n{xrst_end discrete_op}\n*/\nnamespace CppAD { namespace local { namespace var_op {\n\n// ---------------------------------------------------------------------------\n// BEGIN_PROTOTYPE\ntemplate <class RecBase>\ninline void forward_dis_op(\n   size_t        p           ,\n   size_t        q           ,\n   size_t        r           ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   RecBase*      taylor      )\n// END_PROTOTYPE\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DisOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DisOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( 0 < r );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   RecBase* x = taylor + size_t(arg[1]) * num_taylor_per_var;\n   RecBase* z = taylor +    i_z * num_taylor_per_var;\n\n   if( p == 0 )\n   {  z[0]  = discrete<RecBase>::eval(size_t(arg[0]), x[0]);\n      p++;\n   }\n   for(size_t ell = 0; ell < r; ell++)\n      for(size_t k = p; k <= q; k++)\n         z[ (k-1) * r + 1 + ell ] = RecBase(0.0);\n}\n// ---------------------------------------------------------------------------\ntemplate <class RecBase>\ninline void forward_dis_op(\n   size_t        p           ,\n   size_t        q           ,\n   size_t        r           ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   AD<RecBase>*  ataylor     )\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DisOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DisOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( 0 < r );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   AD<RecBase>* ax = ataylor + size_t(arg[1]) * num_taylor_per_var;\n   AD<RecBase>* az = ataylor +    i_z * num_taylor_per_var;\n\n   if( p == 0 )\n   {  az[0]  = discrete<RecBase>::ad_eval(size_t(arg[0]), ax[0]);\n      p++;\n   }\n   for(size_t ell = 0; ell < r; ell++)\n      for(size_t k = p; k <= q; k++)\n         az[ (k-1) * r + 1 + ell ] = AD<RecBase>(0.0);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/div_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_DIV_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_DIV_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n\n// --------------------------- Divvv -----------------------------------------\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void divvv_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n\n   // Using CondExp, it can make sense to divide by zero,\n   // so do not make it an error.\n   size_t k;\n   for(size_t d = p; d <= q; d++)\n   {  z[d] = x[d];\n      for(k = 1; k <= d; k++)\n         z[d] -= z[d-k] * y[k];\n      z[d] /= y[0];\n   }\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void divvv_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + size_t(arg[0]) * num_taylor_per_var;\n   Base* y = taylor + size_t(arg[1]) * num_taylor_per_var;\n   Base* z = taylor + i_z    * num_taylor_per_var;\n\n\n   // Using CondExp, it can make sense to divide by zero,\n   // so do not make it an error.\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  z[m+ell] = x[m+ell] - z[0] * y[m+ell];\n      for(size_t k = 1; k < q; k++)\n         z[m+ell] -= z[(q-k-1)*r+1+ell] * y[(k-1)*r+1+ell];\n      z[m+ell] /= y[0];\n   }\n}\n\n\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void divvv_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   z[0] = x[0] / y[0];\n}\n\n\n// See dev documentation: reverse_binary_op\ntemplate <class Base>\ninline void divvv_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Arguments\n   const Base* y  = taylor + size_t(arg[1]) * cap_order;\n   const Base* z  = taylor + i_z    * cap_order;\n\n   // Partial derivatives corresponding to arguments and result\n   Base* px = partial + size_t(arg[0]) * n_order;\n   Base* py = partial + size_t(arg[1]) * n_order;\n   Base* pz = partial + i_z    * n_order;\n\n   // Using CondExp, it can make sense to divide by zero\n   // so do not make it an error.\n   Base inv_y0 = Base(1.0) / y[0];\n\n   size_t k;\n   // number of indices to access\n   size_t j = d + 1;\n   while(j)\n   {  --j;\n      // scale partial w.r.t. z[j]\n      pz[j] = azmul(pz[j], inv_y0);\n\n      px[j] += pz[j];\n      for(k = 1; k <= j; k++)\n      {  pz[j-k] -= azmul(pz[j], y[k]  );\n         py[k]   -= azmul(pz[j], z[j-k]);\n      }\n      py[0] -= azmul(pz[j], z[j]);\n   }\n}\n\n// --------------------------- Divpv -----------------------------------------\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void divpv_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DivpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DivpvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   // Paraemter value\n   Base x = parameter[ arg[0] ];\n\n   // Using CondExp, it can make sense to divide by zero,\n   // so do not make it an error.\n   size_t k;\n   if( p == 0 )\n   {  z[0] = x / y[0];\n      p++;\n   }\n   for(size_t d = p; d <= q; d++)\n   {  z[d] = Base(0.0);\n      for(k = 1; k <= d; k++)\n         z[d] -= z[d-k] * y[k];\n      z[d] /= y[0];\n   }\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void divpv_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DivpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DivpvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* y = taylor + size_t(arg[1]) * num_taylor_per_var;\n   Base* z = taylor + i_z    * num_taylor_per_var;\n\n   // Using CondExp, it can make sense to divide by zero,\n   // so do not make it an error.\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  z[m+ell] = - z[0] * y[m+ell];\n      for(size_t k = 1; k < q; k++)\n         z[m+ell] -= z[(q-k-1)*r+1+ell] * y[(k-1)*r+1+ell];\n      z[m+ell] /= y[0];\n   }\n}\n\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void divpv_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DivpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DivpvOp) == 1 );\n\n   // Paraemter value\n   Base x = parameter[ arg[0] ];\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   z[0] = x / y[0];\n}\n\n\n// See dev documentation: reverse_binary_op\ntemplate <class Base>\ninline void divpv_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DivvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DivvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Arguments\n   const Base* y = taylor + size_t(arg[1]) * cap_order;\n   const Base* z = taylor + i_z    * cap_order;\n\n   // Partial derivatives corresponding to arguments and result\n   Base* py = partial + size_t(arg[1]) * n_order;\n   Base* pz = partial + i_z    * n_order;\n\n   // Using CondExp, it can make sense to divide by zero so do not\n   // make it an error.\n   Base inv_y0 = Base(1.0) / y[0];\n\n   size_t k;\n   // number of indices to access\n   size_t j = d + 1;\n   while(j)\n   {  --j;\n      // scale partial w.r.t z[j]\n      pz[j] = azmul(pz[j], inv_y0);\n\n      for(k = 1; k <= j; k++)\n      {  pz[j-k] -= azmul(pz[j], y[k]  );\n         py[k]   -= azmul(pz[j], z[j-k] );\n      }\n      py[0] -= azmul(pz[j], z[j]);\n   }\n}\n\n\n// --------------------------- Divvp -----------------------------------------\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void divvp_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DivvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DivvpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   // Parameter value\n   Base y = parameter[ arg[1] ];\n\n   // Using CondExp and multiple levels of AD, it can make sense\n   // to divide by zero so do not make it an error.\n   for(size_t d = p; d <= q; d++)\n      z[d] = x[d] / y;\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void divvp_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DivvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DivvpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( 0 < q  );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + size_t(arg[0]) * num_taylor_per_var;\n   Base* z = taylor +    i_z * num_taylor_per_var;\n\n   // Parameter value\n   Base y = parameter[ arg[1] ];\n\n   // Using CondExp and multiple levels of AD, it can make sense\n   // to divide by zero so do not make it an error.\n   size_t m = (q-1)*r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n      z[m + ell] = x[m + ell] / y;\n}\n\n\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void divvp_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DivvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DivvpOp) == 1 );\n\n   // Parameter value\n   Base y = parameter[ arg[1] ];\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   z[0] = x[0] / y;\n}\n\n\n// See dev documentation: reverse_binary_op\ntemplate <class Base>\ninline void divvp_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(DivvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(DivvpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Argument values\n   Base  y = parameter[ arg[1] ];\n\n   // Partial derivatives corresponding to arguments and result\n   Base* px = partial + size_t(arg[0]) * n_order;\n   Base* pz = partial + i_z    * n_order;\n\n   // Using CondExp, it can make sense to divide by zero\n   // so do not make it an error.\n   Base inv_y = Base(1.0) / y;\n\n   // number of indices to access\n   size_t j = d + 1;\n   while(j)\n   {  --j;\n      px[j] += azmul(pz[j], inv_y);\n   }\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/erf_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_ERF_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_ERF_OP_HPP\n\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <cppad/local/var_op/mul_op.hpp>\n# include <cppad/local/var_op/sub_op.hpp>\n# include <cppad/local/var_op/exp_op.hpp>\n\n\nnamespace CppAD { namespace local { namespace var_op {\n/*!\n\\file erf_op.hpp\nForward and reverse mode calculations for z = erf(x) or erfc(x).\n*/\n\n/*!\nForward mode Taylor coefficient for result of op = ErfOp or ErfcOp.\n\nThe C++ source code corresponding to this operation is one of\n\\verbatim\n   z = erf(x)\n   z = erfc(x)\n\\endverbatim\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type Base.\n\n\\param op\nmust be either ErfOp or ErfcOp and indicates if this is\nz = erf(x) or z = erfc(x).\n\n\\param p\nlowest order of the Taylor coefficients that we are computing.\n\n\\param q\nhighest order of the Taylor coefficients that we are computing.\n\n\\param i_z\nvariable index corresponding to the last (primary) result for this operation;\ni.e. the row index in taylor corresponding to z.\nThe auxiliary results are called y_j have index i_z - j.\n\n\\param arg\narg[0]: is the variable index corresponding to x.\n\\n\narg[1]: is the parameter index corresponding to the value zero.\n\\n\narg[2]: is  the parameter index correspodning to the value 2 / sqrt(pi).\n\n\\param parameter\nparameter[ arg[1] ] is the value zero,\nand parameter[ arg[2] ] is the value 2 / sqrt(pi).\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n\\b Input:\ntaylor [ size_t(arg[0]) * cap_order + k ]\nfor k = 0 , ... , q,\nis the k-th order Taylor coefficient corresponding to x.\n\\n\n\\b Input:\ntaylor [ i_z * cap_order + k ]\nfor k = 0 , ... , p - 1,\nis the k-th order Taylor coefficient corresponding to z.\n\\n\n\\b Input:\ntaylor [ ( i_z - j) * cap_order + k ]\nfor k = 0 , ... , p-1,\nand j = 0 , ... , 4,\nis the k-th order Taylor coefficient corresponding to the j-th result for z.\n\\n\n\\b Output:\ntaylor [ (i_z-j) * cap_order + k ],\nfor k = p , ... , q,\nand j = 0 , ... , 4,\nis the k-th order Taylor coefficient corresponding to the j-th result for z.\n\n*/\ntemplate <class Base>\ninline void erf_forward_any(\n   op_code_var   op          ,\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( op == ErfOp || op == ErfcOp );\n   CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(op) == 5 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= i_z + 2\n   );\n\n   // array used to pass parameter values for sub-operations\n   addr_t addr[2];\n\n   // convert from final result to first result\n   i_z -= 4; // 4 = NumRes(ErfOp) - 1;\n\n   // z_0 = x * x\n   addr[0] = arg[0]; // x\n   addr[1] = arg[0]; // x\n   mulvv_forward_any(p, q, i_z+0, addr, parameter, cap_order, taylor);\n\n   // z_1 = - x * x\n   addr[0] = arg[1];           // zero\n   addr[1] = addr_t( i_z );    // z_0\n   subpv_forward_any(p, q, i_z+1, addr, parameter, cap_order, taylor);\n\n   // z_2 = exp( - x * x )\n   addr[0] = addr_t(i_z+1);\n   exp_forward_any(p, q, i_z+2, addr, cap_order, taylor);\n\n   // z_3 = (2 / sqrt(pi)) * exp( - x * x )\n   addr[0] = arg[2];            // 2 / sqrt(pi)\n   addr[1] = addr_t( i_z + 2 ); // z_2\n   mulpv_forward_any(p, q, i_z+3, addr, parameter, cap_order, taylor);\n\n   // pointers to taylor coefficients for x , z_3, and z_4\n   Base* x    = taylor + size_t(arg[0]) * cap_order;\n   Base* z_3  = taylor + (i_z+3) * cap_order;\n   Base* z_4  = taylor + (i_z+4) * cap_order;\n\n   // calculate z_4 coefficients\n   if( p == 0 )\n   {  // z4 (t) = erf[x(t)]\n      if( op == ErfOp )\n         z_4[0] = erf(x[0]);\n      else\n         z_4[0] = erfc(x[0]);\n      p++;\n   }\n   // sign\n   Base sign(1.0);\n   if( op == ErfcOp )\n      sign = Base(-1.0);\n   //\n   for(size_t j = p; j <= q; j++)\n   {  // erf:  z_4' (t) =   erf'[x(t)] * x'(t) = z3(t) * x'(t)\n      // erfc: z_4' (t) = - erf'[x(t)] * x'(t) = - z3(t) * x'(t)\n      // z_4[1] + 2 * z_4[2] * t +  ... =\n      // sign * (z_3[0] + z_3[1] * t +  ...) * (x[1] + 2 * x[2] * t +  ...)\n      Base base_j = static_cast<Base>(double(j));\n      z_4[j]      = static_cast<Base>(0);\n      for(size_t k = 1; k <= j; k++)\n         z_4[j] += sign * (Base(double(k)) / base_j) * x[k] * z_3[j-k];\n   }\n}\n\n/*!\nZero order Forward mode Taylor coefficient for result of op = ErfOp or ErfcOp.\n\nThe C++ source code corresponding to this operation one of\n\\verbatim\n   z = erf(x)\n   z = erfc(x)\n\\endverbatim\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type Base.\n\n\\param op\nmust be either ErfOp or ErfcOp and indicates if this is\nz = erf(x) or z = erfc(x).\n\n\\param i_z\nvariable index corresponding to the last (primary) result for this operation;\ni.e. the row index in taylor corresponding to z.\nThe auxiliary results are called y_j have index i_z - j.\n\n\\param arg\narg[0]: is the variable index corresponding to x.\n\\n\narg[1]: is the parameter index corresponding to the value zero.\n\\n\narg[2]: is  the parameter index correspodning to the value 2 / sqrt(pi).\n\n\\param parameter\nparameter[ arg[1] ] is the value zero,\nand parameter[ arg[2] ] is the value 2 / sqrt(pi).\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n\\b Input:\ntaylor [ size_t(arg[0]) * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to x.\n\\n\n\\b Input:\ntaylor [ i_z * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to z.\n\\n\n\\b Output:\ntaylor [ (i_z-j) * cap_order + 0 ],\nfor j = 0 , ... , 4,\nis the zero order Taylor coefficient for j-th result corresponding to z.\n\n*/\ntemplate <class Base>\ninline void erf_forward_0(\n   op_code_var   op          ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( op == ErfOp || op == ErfcOp );\n   CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(op) == 5 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= i_z + 2\n   );\n\n   // array used to pass parameter values for sub-operations\n   addr_t addr[2];\n\n   // convert from final result to first result\n   i_z -= 4; // 4 = NumRes(ErfOp) - 1;\n\n   // z_0 = x * x\n   addr[0] = arg[0]; // x\n   addr[1] = arg[0]; // x\n   mulvv_forward_0(i_z+0, addr, parameter, cap_order, taylor);\n\n   // z_1 = - x * x\n   addr[0] = arg[1];       // zero\n   addr[1] = addr_t(i_z);  // z_0\n   subpv_forward_0(i_z+1, addr, parameter, cap_order, taylor);\n\n   // z_2 = exp( - x * x )\n   addr[0] = addr_t(i_z+1);\n   exp_forward_0(i_z+2, addr, cap_order, taylor);\n\n   // z_3 = (2 / sqrt(pi)) * exp( - x * x )\n   addr[0] = arg[2];          // 2 / sqrt(pi)\n   addr[1] = addr_t(i_z + 2); // z_2\n   mulpv_forward_0(i_z+3, addr, parameter, cap_order, taylor);\n\n   // zero order Taylor coefficient for z_4\n   Base* x    = taylor + size_t(arg[0]) * cap_order;\n   Base* z_4  = taylor + (i_z + 4) * cap_order;\n   if( op == ErfOp )\n      z_4[0] = erf(x[0]);\n   else\n      z_4[0] = erfc(x[0]);\n}\n/*!\nForward mode Taylor coefficient for result of op = ErfOp or ErfcOp.\n\nThe C++ source code corresponding to this operation is one of\n\\verbatim\n   z = erf(x)\n   z = erfc(x)\n\\endverbatim\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type Base.\n\n\\param op\nmust be either ErfOp or ErfcOp and indicates if this is\nz = erf(x) or z = erfc(x).\n\n\\param q\norder of the Taylor coefficients that we are computing.\n\n\\param r\nnumber of directions for the Taylor coefficients that we afre computing.\n\n\\param i_z\nvariable index corresponding to the last (primary) result for this operation;\ni.e. the row index in taylor corresponding to z.\nThe auxiliary results have index i_z - j for j = 0 , ... , 4\n(and include z).\n\n\\param arg\narg[0]: is the variable index corresponding to x.\n\\n\narg[1]: is the parameter index corresponding to the value zero.\n\\n\narg[2]: is  the parameter index correspodning to the value 2 / sqrt(pi).\n\n\\param parameter\nparameter[ arg[1] ] is the value zero,\nand parameter[ arg[2] ] is the value 2 / sqrt(pi).\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\par tpv\nWe use the notation\n<code>tpv = (cap_order-1) * r + 1</code>\nwhich is the number of Taylor coefficients per variable\n\n\\param taylor\n\\b Input: If x is a variable,\n<code>taylor [ arg[0] * tpv + 0 ]</code>,\nis the zero order Taylor coefficient for all directions and\n<code>taylor [ arg[0] * tpv + (k-1)*r + ell + 1 ]</code>,\nfor k = 1 , ... , q,\nell = 0, ..., r-1,\nis the k-th order Taylor coefficient\ncorresponding to x and the ell-th direction.\n\\n\n\\b Input:\ntaylor [ (i_z - j) * tpv + 0 ]\nis the zero order Taylor coefficient for all directions and the\nj-th result for z.\nfor k = 1 , ... , q-1,\nell = 0, ... , r-1,\n<code>\ntaylor[ (i_z - j) * tpv + (k-1)*r + ell + 1]\n</code>\nis the Taylor coefficient for the k-th order, ell-th direction,\nand j-th auzillary result.\n\\n\n\\b Output:\ntaylor [ (i_z-j) * tpv + (q-1)*r + ell + 1 ],\nfor ell = 0 , ... , r-1,\nis the Taylor coefficient for the q-th order, ell-th direction,\nand j-th auzillary result.\n\n*/\ntemplate <class Base>\ninline void erf_forward_dir(\n   op_code_var   op          ,\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( op == ErfOp || op == ErfcOp );\n   CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(op) == 5 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= i_z + 2\n   );\n\n   // array used to pass parameter values for sub-operations\n   addr_t addr[2];\n\n   // convert from final result to first result\n   i_z -= 4; // 4 = NumRes(ErfOp) - 1;\n\n   // z_0 = x * x\n   addr[0] = arg[0]; // x\n   addr[1] = arg[0]; // x\n   mulvv_forward_dir(q, r, i_z+0, addr, parameter, cap_order, taylor);\n\n   // z_1 = - x * x\n   addr[0] = arg[1];         // zero\n   addr[1] = addr_t( i_z );  // z_0\n   subpv_forward_dir(q, r, i_z+1, addr, parameter, cap_order, taylor);\n\n   // z_2 = exp( - x * x )\n   addr[0] = addr_t(i_z+1);\n   exp_forward_dir(q, r, i_z+2, addr, cap_order, taylor);\n\n   // z_3 = (2 / sqrt(pi)) * exp( - x * x )\n   addr[0] = arg[2];            // 2 / sqrt(pi)\n   addr[1] = addr_t( i_z + 2 ); // z_2\n   mulpv_forward_dir(q, r, i_z+3, addr, parameter, cap_order, taylor);\n\n   // pointers to taylor coefficients for x , z_3, and z_4\n   size_t num_taylor_per_var = (cap_order - 1) * r + 1;\n   Base* x    = taylor + size_t(arg[0]) * num_taylor_per_var;\n   Base* z_3  = taylor + (i_z+3) * num_taylor_per_var;\n   Base* z_4  = taylor + (i_z+4) * num_taylor_per_var;\n\n   // sign\n   Base sign(1.0);\n   if( op == ErfcOp )\n      sign = Base(-1.0);\n\n   // erf:  z_4' (t) =   erf'[x(t)] * x'(t) = z3(t) * x'(t)\n   // erfc: z_4' (t) = - erf'[x(t)] * x'(t) = z3(t) * x'(t)\n   // z_4[1] + 2 * z_4[2] * t +  ... =\n   // sign * (z_3[0] + z_3[1] * t +  ...) * (x[1] + 2 * x[2] * t +  ...)\n   Base base_q = static_cast<Base>(double(q));\n   for(size_t ell = 0; ell < r; ell++)\n   {  // index in z_4 and x for q-th order term\n      size_t m = (q-1)*r + ell + 1;\n      // initialize q-th order term summation\n      z_4[m] = sign * z_3[0] * x[m];\n      for(size_t k = 1; k < q; k++)\n      {  size_t x_index  = (k-1)*r + ell + 1;\n         size_t z3_index = (q-k-1)*r + ell + 1;\n         Base bk = Base(double(k));\n         z_4[m] += sign * (bk / base_q) * x[x_index] * z_3[z3_index];\n      }\n   }\n}\n\n/*!\nCompute reverse mode partial derivatives for result of op = ErfOp or ErfcOp.\n\nThe C++ source code corresponding to this operation is one of\n\\verbatim\n   z = erf(x)\n   z = erfc(x)\n\\endverbatim\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type Base.\n\n\\param op\nmust be either ErfOp or ErfcOp and indicates if this is\nz = erf(x) or z = erfc(x).\n\n\\param d\nhighest order Taylor of the Taylor coefficients that we are computing\nthe partial derivatives with respect to.\n\n\\param i_z\nvariable index corresponding to the last (primary) result for this operation;\ni.e. the row index in taylor corresponding to z.\nThe auxiliary results are called y_j have index i_z - j.\n\n\\param arg\narg[0]: is the variable index corresponding to x.\n\\n\narg[1]: is the parameter index corresponding to the value zero.\n\\n\narg[2]: is  the parameter index correspodning to the value 2 / sqrt(pi).\n\n\\param parameter\nparameter[ arg[1] ] is the value zero,\nand parameter[ arg[2] ] is the value 2 / sqrt(pi).\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n\\b Input:\ntaylor [ size_t(arg[0]) * cap_order + k ]\nfor k = 0 , ... , d,\nis the k-th order Taylor coefficient corresponding to x.\n\\n\ntaylor [ (i_z - j) * cap_order + k ]\nfor k = 0 , ... , d,\nand for j = 0 , ... , 4,\nis the k-th order Taylor coefficient corresponding to the j-th result\nfor this operation.\n\n\\param n_order\nnumber of columns in the matrix containing all the partial derivatives\n\n\\param partial\n\\b Input:\npartial [ size_t(arg[0]) * n_order + k ]\nfor k = 0 , ... , d,\nis the partial derivative of G( z , x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for x.\n\\n\n\\b Input:\npartial [ (i_z - j) * n_order + k ]\nfor k = 0 , ... , d,\nand for j = 0 , ... , 4,\nis the partial derivative of G( z , x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for the j-th result of this operation.\n\\n\n\\b Output:\npartial [ size_t(arg[0]) * n_order + k ]\nfor k = 0 , ... , d,\nis the partial derivative of H( x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for x.\n\\n\n\\b Output:\npartial [ (i_z-j) * n_order + k ]\nfor k = 0 , ... , d,\nand for j = 0 , ... , 4,\nmay be used as work space; i.e., may change in an unspecified manner.\n\n*/\ntemplate <class Base>\ninline void erf_reverse(\n   op_code_var   op          ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( op == ErfOp || op == ErfcOp );\n   CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(op) == 5 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= i_z + 2\n   );\n\n   // array used to pass parameter values for sub-operations\n   addr_t addr[2];\n\n   // If pz is zero, make sure this operation has no effect\n   // (zero times infinity or nan would be non-zero).\n   Base* pz  = partial + i_z * n_order;\n   bool skip(true);\n   for(size_t i_d = 0; i_d <= d; i_d++)\n      skip &= IdenticalZero(pz[i_d]);\n   if( skip )\n      return;\n\n   // convert from final result to first result\n   i_z -= 4; // 4 = NumRes(ErfOp) - 1;\n\n   // Taylor coefficients and partials corresponding to x\n   const Base* x  = taylor  + size_t(arg[0]) * cap_order;\n   Base* px       = partial + size_t(arg[0]) * n_order;\n\n   // Taylor coefficients and partials corresponding to z_3\n   const Base* z_3  = taylor  + (i_z+3) * cap_order;\n   Base* pz_3       = partial + (i_z+3) * n_order;\n\n   // Taylor coefficients and partials corresponding to z_4\n   Base* pz_4 = partial + (i_z+4) * n_order;\n\n   // sign\n   Base sign(1.0);\n   if( op == ErfcOp )\n      sign = Base(-1.0);\n\n   // Reverse z_4\n   size_t j = d;\n   while(j)\n   {  pz_4[j] /= Base(double(j));\n      for(size_t k = 1; k <= j; k++)\n      {  px[k]     += sign * azmul(pz_4[j], z_3[j-k]) * Base(double(k));\n         pz_3[j-k] += sign * azmul(pz_4[j], x[k]) * Base(double(k));\n      }\n      j--;\n   }\n   px[0] += sign * azmul(pz_4[0], z_3[0]);\n\n   // z_3 = (2 / sqrt(pi)) * exp( - x * x )\n   addr[0] = arg[2];            // 2 / sqrt(pi)\n   addr[1] = addr_t( i_z + 2 ); // z_2\n   mulpv_reverse(\n      i_z+3, addr, parameter, cap_order, taylor, n_order, partial\n   );\n\n   // z_2 = exp( - x * x )\n   addr[0] = addr_t(i_z + 1);\n   exp_reverse(\n      i_z+2, addr, cap_order, taylor, n_order, partial\n   );\n\n   // z_1 = - x * x\n   addr[0] = arg[1];           // zero\n   addr[1] = addr_t( i_z );    // z_0\n   subpv_reverse(\n      i_z+1, addr, parameter, cap_order, taylor, n_order, partial\n   );\n\n   // z_0 = x * x\n   addr[0] = arg[0]; // x\n   addr[1] = arg[0]; // x\n   mulvv_reverse(\n      i_z+0, addr, parameter, cap_order, taylor, n_order, partial\n   );\n\n}\n\n\n} } } // END namespace\n# endif // CPPAD_ERF_OP_INCLUDED\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/exp_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_EXP_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_EXP_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void exp_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   size_t k;\n   if( p == 0 )\n   {  z[0] = exp( x[0] );\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {\n      z[j] = x[1] * z[j-1];\n      for(k = 2; k <= j; k++)\n         z[j] += Base(double(k)) * x[k] * z[j-k];\n      z[j] /= Base(double(j));\n   }\n}\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void exp_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* z = taylor + i_z * num_taylor_per_var;\n\n   size_t m = (q-1)*r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  z[m+ell] = Base(double(q)) * x[m+ell] * z[0];\n      for(size_t k = 1; k < q; k++)\n         z[m+ell] += Base(double(k)) * x[(k-1)*r+ell+1] * z[(q-k-1)*r+ell+1];\n      z[m+ell] /= Base(double(q));\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void exp_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   z[0] = exp( x[0] );\n}\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void exp_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ExpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to result\n   const Base* z  = taylor  + i_z * cap_order;\n   Base* pz       = partial + i_z * n_order;\n\n   // If pz is zero, make sure this operation has no effect\n   // (zero times infinity or nan would be non-zero).\n   bool skip(true);\n   for(size_t i_d = 0; i_d <= d; i_d++)\n      skip &= IdenticalZero(pz[i_d]);\n   if( skip )\n      return;\n\n   // loop through orders in reverse\n   size_t j, k;\n   j = d;\n   while(j)\n   {  // scale partial w.r.t z[j]\n      pz[j] /= Base(double(j));\n\n      for(k = 1; k <= j; k++)\n      {  px[k]   += Base(double(k)) * azmul(pz[j], z[j-k]);\n         pz[j-k] += Base(double(k)) * azmul(pz[j], x[k]);\n      }\n      --j;\n   }\n   px[0] += azmul(pz[0], z[0]);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/expm1_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_EXPM1_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_EXPM1_OP_HPP\n\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\ntemplate <class Base>\ninline void expm1_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(Expm1Op) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(Expm1Op) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   size_t k;\n   if( p == 0 )\n   {  z[0] = expm1( x[0] );\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {\n      z[j] = x[1] * z[j-1];\n      for(k = 2; k <= j; k++)\n         z[j] += Base(double(k)) * x[k] * z[j-k];\n      z[j] /= Base(double(j));\n      z[j] += x[j];\n   }\n}\n\n\ntemplate <class Base>\ninline void expm1_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(Expm1Op) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(Expm1Op) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* z = taylor + i_z * num_taylor_per_var;\n\n   size_t m = (q-1)*r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  z[m+ell] = Base(double(q)) * x[m+ell] * z[0];\n      for(size_t k = 1; k < q; k++)\n         z[m+ell] += Base(double(k)) * x[(k-1)*r+ell+1] * z[(q-k-1)*r+ell+1];\n      z[m+ell] /= Base(double(q));\n      z[m+ell] += x[m+ell];\n   }\n}\n\ntemplate <class Base>\ninline void expm1_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(Expm1Op) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(Expm1Op) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   z[0] = expm1( x[0] );\n}\n\ntemplate <class Base>\ninline void expm1_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(Expm1Op) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(Expm1Op) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to result\n   const Base* z  = taylor  + i_z * cap_order;\n   Base* pz       = partial + i_z * n_order;\n\n   // If pz is zero, make sure this operation has no effect\n   // (zero times infinity or nan would be non-zero).\n   bool skip(true);\n   for(size_t i_d = 0; i_d <= d; i_d++)\n      skip &= IdenticalZero(pz[i_d]);\n   if( skip )\n      return;\n\n   // loop through orders in reverse\n   size_t j, k;\n   j = d;\n   while(j)\n   {  px[j] += pz[j];\n\n      // scale partial w.r.t z[j]\n      pz[j] /= Base(double(j));\n\n      for(k = 1; k <= j; k++)\n      {  px[k]   += Base(double(k)) * azmul(pz[j], z[j-k]);\n         pz[j-k] += Base(double(k)) * azmul(pz[j], x[k]);\n      }\n      --j;\n   }\n   px[0] += pz[0] + azmul(pz[0], z[0]);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/load_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_LOAD_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_LOAD_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n/*\n ------------------------------------------------------------------------------\n{xrst_begin_parent var_load_op dev}\n{xrst_spell\n   ldp\n   ldv\n}\n\nAccess an Element in a Variable VecAD Vector\n############################################\n\nLdpOp, LdvOp\n************\nare the op codes for these operators.\n\nUser Syntax\n***********\n| *z* = *v* [ *x* ]\n\n\nv\n*\nis the :ref:`VecAD-name` vector for this load operation.\nIf this vector is a constant before the load,\nthe index *x* is a variable and it is a variable after the load.\n\nx\n*\nis the index for this load.\n\ny\n*\nis the value that was stored in *v* [ *x* ] prior to this load;\nsee :ref:`var_store_op@y` .\n\nz\n*\nis the new variable created by this load.\n(This new variable is like a copy of *y* .)\n\nRecBase\n*******\nis the base type use when recording this operator;\ni.e., this operation was recording using AD< *RecBase* > operations.\n\nBase\n****\nis the type used for computations by this operator.\nThis is either *RecBase* or AD< *RecBase* >.\n\nop_code\n*******\n\n.. csv-table::\n   :widths: auto\n   :header-rows: 1\n\n   op_code, x, z\n   LdpOp, parameter, variable\n   LdvOp, variable, variable\n\ni_z\n***\nis the variable index corresponding to *z* .\n\nnum_vecad_ind\n*************\nis the size of the single array that includes\nall the VecAD vectors together with the size of each vector.\n\narg\n***\n\narg[0]\n======\nthis argument is the offset of the vector *v*\nrelative to the beginning of the single array\nthat contains all VecAD elements and sizes.\nThis offset corresponds to the first element of *v* and not its size\nwhich comes just before the first element.\n\narg[1]\n======\nIf *x* is a parameter (variable), arg[1] is the parameter index\n(variable index) to *x* .\n\narg[2]\n======\nIs the number of this VecAD load instruction that came before this one.\n\n{xrst_end var_load_op}\n-------------------------------------------------------------------------------\n{xrst_begin var_load_forward_0 dev}\n{xrst_spell\n   isvar\n}\n\nZero Order Forward Load an Element of a VecAD Vector\n####################################################\n\nv, x, y, z\n**********\nsee\n:ref:`var_load_op@v` ,\n:ref:`var_load_op@x` ,\n:ref:`var_load_op@y` ,\n:ref:`var_load_op@z`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_LOAD_FORWARD_0\n   // END_LOAD_FORWARD_0\n}\n\n\nBase, op_code, i_z, num_vecad_ind, arg\n**************************************\nsee\n:ref:`var_load_op@Base` ,\n:ref:`var_load_op@op_code` ,\nref:`var_load_op@i_z` ,\n:ref:`var_load_op@num_vecad_ind` ,\n:ref:`var_load_op@arg` .\n\nnum_var\n*******\nis the number of variables in this recording.\n\nnum_par\n*******\nis the number of parameters in this recording.\n\nparameter\n*********\nThis is the vector of parameters for this recording which has size *num_par* .\n\ncap_order\n*********\nis the maximum number of orders that can fit in *taylor* .\n\ntaylor\n******\nIs the matrix of Taylor coefficients for all the variables.\n\n\nper_variable\n============\nFor each variable there is one Taylor coefficient of order zero\nand *n_dir* coefficients for orders greater than zero.\nThe taylor coefficients capacity per variable is::\n\n   per_variable = (cap_order - 1) * n_dir + 1\n\nInput\n=====\nFor j = 0, ..., i_z - 1,  taylor[ j * per_variable + 0 ] is an input.\n\nOutput\n======\ntaylor[ i_z * per_variable + 0 ] is an output.\n\ni_vec\n*****\nWe use *i_vec* to denote the ``size_t`` value corresponding to\n:ref:`var_load_op@x` .\nIf *x* is a parameter (variable) this is a parameter (variable) index.\n\n\nvec_ad2isvar\n************\nThis vector has size :ref:`var_load_op@num_vecad_ind` .\nIf *y* is a parameter (variable),\n*vec_ad2isvar* [ *arg* [0] + *i_vec*  ] is false (true).\n\nvec_ad2index\n************\nThis vector has size *num_vecad_ind* .\nIf *y* a parameter (variable),\n*vec_ad2index* [ *arg* [0] + *i_vec*  ]\nis the parameter (variable) index\ncorresponding to the value being loaded.\n\n{xrst_end var_load_forward_0}\n*/\n// BEGIN_LOAD_FORWARD_0\ntemplate <class Base>\ninline void load_forward_0(\n   op_code_var                op_code          ,\n   size_t                     i_z              ,\n   size_t                     num_vec_ind      ,\n   const addr_t*              arg              ,\n   size_t                     num_var          ,\n   size_t                     num_par          ,\n   const Base*                parameter        ,\n   size_t                     cap_order        ,\n   Base*                      taylor           ,\n   const pod_vector<bool>&    vec_ad2isvar     ,\n   const pod_vector<size_t>&  vec_ad2index     ,\n   pod_vector<addr_t>&        load_op2var      )\n// END_LOAD_FORWARD_0\n{  CPPAD_ASSERT_NARG_NRES(op_code, 3, 1);\n   //\n   CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );\n   CPPAD_ASSERT_UNKNOWN( vec_ad2isvar.size() == num_vec_ind );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < load_op2var.size() );\n   //\n   // i_vec\n   // assign here to avoid compiler warning for default case\n   addr_t i_vec = std::numeric_limits<addr_t>::max();\n   switch(op_code)\n   {  //\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n      break;\n      //\n      case LdpOp:\n      CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n      i_vec = addr_t( Integer( parameter[ arg[1] ] ) );\n      break;\n      //\n      case LdvOp:\n      CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_var );\n      i_vec = addr_t(Integer( taylor[ size_t(arg[1]) * cap_order + 0 ] ));\n      break;\n   }\n   //\n   CPPAD_ASSERT_KNOWN(\n      size_t(i_vec) < vec_ad2index[ arg[0] - 1 ] ,\n      \"VecAD: dynamic parameter index out or range during zero order forward\"\n   );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0] + i_vec) < num_vec_ind );\n   //\n   // i_y, isvar\n   size_t i_y    = vec_ad2index[ arg[0] + i_vec ];\n   bool   isvar  = vec_ad2isvar[ arg[0] + i_vec ];\n   //\n   // z\n   Base* z       = taylor + i_z * cap_order;\n   //\n   // z, load_op2var\n   if( isvar )\n   {  CPPAD_ASSERT_UNKNOWN( i_y < i_z );\n      load_op2var[ arg[2] ] = addr_t( i_y );\n      Base* y = taylor + i_y * cap_order;\n      z[0]      = y[0];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( i_y < num_par  );\n      load_op2var[ arg[2] ] = 0;\n      Base y    = parameter[i_y];\n      z[0]      = y;\n   }\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_load_forward_nonzero dev}\n\nNonzero Order Forward Load an Element of a VecAD Vector\n#######################################################\n\nv, x, y, z\n**********\nsee\n:ref:`var_load_op@v` ,\n:ref:`var_load_op@x` ,\n:ref:`var_load_op@y` ,\n:ref:`var_load_op@z`\n\nn_res\n*****\nThe number of results that are variables, *n_res* , is one for\nthis operation.\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_LOAD_FORWARD_NONZERO\n   // END_LOAD_FORWARD_NONZERO\n}\n\n\nBase, op_code, i_z, arg\n***********************\nsee\n:ref:`var_load_op@Base` ,\n:ref:`var_load_op@op_code` ,\n:ref:`var_load_op@i_z` ,\n:ref:`var_load_op@arg` .\n\norder_low\n*********\nis the lowest order Taylor coefficient that we are computing.\n\n{xrst_template ;\n   include/cppad/local/var_op/template/forward_dir.xrst\n   headers: n_dir, cap_order, order_up, taylor\n}\n\n\nload_op2var\n***********\nmaps the load operator index *arg* [2] to the\nindex corresponding to *y* for this load operation.\nIf the case where the index is zero,\n*y* is a parameter; i.e., *y* is not a variable.\n\n{xrst_end var_load_forward_nonzero}\n*/\n// BEGIN_LOAD_FORWARD_NONZERO\ntemplate <class Base>\ninline void load_forward_nonzero(\n   op_code_var                   op_code     ,\n   size_t                        i_z         ,\n   const addr_t*                 arg         ,\n   size_t                        order_low   ,\n   size_t                        order_up    ,\n   size_t                        n_dir       ,\n   size_t                        cap_order   ,\n   const pod_vector<addr_t>&     load_op2var ,\n   Base*                         taylor      )\n// END_LOAD_FORWARD_NONZERO\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   CPPAD_ASSERT_NARG_NRES(op_code, 3, 1);\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( 0 < r);\n   CPPAD_ASSERT_UNKNOWN( 0 < p);\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < load_op2var.size() );\n   //\n   // i_y\n   size_t i_y = size_t( load_op2var[ arg[2] ] );\n   CPPAD_ASSERT_UNKNOWN( i_y < i_z );\n   //\n   // num_taylor_per_var\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   //\n   // z\n   Base* z  = taylor + i_z * num_taylor_per_var;\n   //\n   // z\n   if( i_y > 0 )\n   {  Base* y = taylor + i_y * num_taylor_per_var;\n      for(size_t ell = 0; ell < r; ell++)\n      {  for(size_t k = p; k <= q; k++)\n         {  size_t m = (k-1) * r + 1 + ell;\n            z[m]     = y[m];\n         }\n      }\n   }\n   else\n   {  for(size_t ell = 0; ell < r; ell++)\n      {  for(size_t k = p; k <= q; k++)\n         {  size_t m = (k-1) * r + 1 + ell;\n            z[m]     = Base(0.0);\n         }\n      }\n   }\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_load_reverse dev}\n\nReverse Mode Load an Element of a VecAD Vector\n##############################################\n\nv, x, y, z\n**********\nsee\n:ref:`var_load_op@v` ,\n:ref:`var_load_op@x` ,\n:ref:`var_load_op@y` ,\n:ref:`var_load_op@z`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_LOAD_REVERSE\n   // END_LOAD_REVERSE\n}\n\nBase, op_code, i_z, arg\n***********************\nsee\n:ref:`var_load_op@Base` ,\n:ref:`var_load_op@op_code` ,\n:ref:`var_load_op@i_z` ,\n:ref:`var_load_op@arg` .\n\ncap_order\n*********\nis the maximum number of orders that can fit in *taylor* .\n\nload_op2var\n***********\nThis vector maps the load instruction index *arg* [2] to the corresponding\n*y* variable index.\nIf this index is zero, *y* is a parameter (not a variable).\n\n{xrst_template ;\n   include/cppad/local/var_op/template/reverse_op.xrst\n   headers: n_order, partial\n\n   @x, y@  ; y\n}\n\nIf *y* is a parameter,\nnothing is modified by this call to ``reverse_load_op`` .\nOtherwise, let *i_y* be the variable index corresponding to *y*; i.e.\n\n| |tab| *i_y* = *load_op2var* [ *arg* [2] ]\n\nFor k = 0 , ... , d the k-th order Taylor coefficient for *z*\nis added to the k-th order Taylor coefficient for *y*; i.e.,\n\n|tab|\n*partial* [ *i_y* * *n_order* + *k* ] +=\n*partial* [ *i_z* * *n_order* + *k* ]\n\n{xrst_end var_load_reverse}\n*/\n// BEGIN_LOAD_REVERSE\ntemplate <class Base>\ninline void load_reverse(\n   op_code_var               op_code     ,\n   size_t                    i_z         ,\n   const addr_t*             arg         ,\n   const pod_vector<addr_t>& load_op2var ,\n   size_t                    cap_order   ,\n   size_t                    n_order     ,\n   Base*                     partial     )\n// END_LOAD_REVERSE\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   //\n   CPPAD_ASSERT_NARG_NRES(op_code, 3, 1);\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n   // i_y\n   size_t i_y = size_t( load_op2var[ arg[2] ] );\n   CPPAD_ASSERT_UNKNOWN( i_y < i_z );\n   //\n   // py\n   if( i_y > 0 )\n   {\n      Base* pz   = partial + i_z * n_order;\n      Base* py   = partial + i_y * n_order;\n      size_t j = d + 1;\n      while(j--)\n         py[j]   += pz[j];\n   }\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_load_for_jac dev}\n\nForward Jacobian Sparsity for Store a VecAD Element\n###################################################\n\nv, x, y, z\n**********\nsee\n:ref:`var_load_op@v` ,\n:ref:`var_load_op@x` ,\n:ref:`var_load_op@y` ,\n:ref:`var_load_op@z`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_LOAD_FOR_JAC\n   // END_LOAD_FOR_JAC\n}\n\nop_code, num_vecad_ind, arg\n***************************\nsee :ref:`var_load_op@op_code` ,\n:ref:`var_load_op@num_vecad_ind` ,\n:ref:`var_load_op@arg` .\n\nVector_set\n**********\nis the type used for vectors of sets. It must satisfy the\n:ref:`SetVector-name` concept.\n\ndependency\n**********\nIf true (false) we are including (are not including)\ndependencies that have derivative zero in the sparsity pattern.\nFor example, the :ref:`Discrete-name` functions have derivative zero,\nbut the value depends on its argument.\n\nvecad_ind\n*********\nis a vector with size *num_vec_ind* .\nWe use the notation *i_v* defined by\n\n|tab| *i_v* = vecad_ind[ arg[0] - 1 ]\n\nThis is the index of the VecAD vector and is less than the number of\nVecAD vectors in the recording.\n\nvar_sparsity\n************\nThe sparsity pattern for *z*\nis set equal to the sparsity pattern for *v.\nIf *dependency* is true, and *x* is a variable,\nthe sparsity pattern for *x* is added to the sparsity pattern for *z*.\n\nvecad_sparsity\n**************\nThe set with index *i_v* in *vecad_sparsity\nis the sparsity pattern for the vector *v*.\n\n{xrst_end var_load_for_jac}\n*/\n// BEGIN_LOAD_FOR_JAC\ntemplate <class Vector_set>\ninline void load_for_jac(\n   op_code_var               op_code        ,\n   size_t                    num_vecad_ind  ,\n   size_t                    i_z            ,\n   const addr_t*             arg            ,\n   bool                      dependency     ,\n   const pod_vector<size_t>& vecad_ind      ,\n   Vector_set&               var_sparsity   ,\n   const Vector_set&         vecad_sparsity )\n// END_LOAD_FOR_JAC\n{  //\n   //\n   CPPAD_ASSERT_NARG_NRES(op_code, 3, 1);\n   CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );\n   CPPAD_ASSERT_UNKNOWN( num_vecad_ind == vecad_ind.size() );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_vecad_ind );\n   //\n   // i_v\n   size_t i_v = vecad_ind[ arg[0] - 1 ];\n   CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() );\n   //\n   // var_sparsity[i_z]\n   var_sparsity.assignment(i_z, i_v, vecad_sparsity);\n   //\n   // var_sparsity[i_z]\n   if( dependency & (op_code == LdvOp) )\n   {  size_t i_x = size_t( arg[1] );\n      var_sparsity.binary_union(i_z, i_z, i_x, var_sparsity);\n   }\n   return;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_load_rev_jac dev}\n\nReverse Jacobian Sparsity for Load a VecAD Element\n##################################################\n\nv, x, y, z\n**********\nsee\n:ref:`var_load_op@v` ,\n:ref:`var_load_op@x` ,\n:ref:`var_load_op@y` ,\n:ref:`var_load_op@z`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_LOAD_REV_JAC\n   // END_LOAD_REV_JAC\n}\n\nop_code, num_vecad_ind, arg\n***************************\nsee :ref:`var_load_op@op_code` ,\n:ref:`var_load_op@num_vecad_ind` ,\n:ref:`var_load_op@arg` .\n\nVector_set\n**********\nis the type used for vectors of sets. It must satisfy the\n:ref:`SetVector-name` concept.\n\ndependency\n**********\nIf true (false) we are including (are not including)\ndependencies that have derivative zero in the sparsity pattern.\nFor example, the :ref:`Discrete-name` functions have derivative zero,\nbut the value depends on its argument.\n\nvecad_ind\n*********\nis a vector with size *num_vec_ind* .\nWe use the notation *i_v* defined by\n\n|tab| *i_v* = vecad_ind[ arg[0] - 1 ]\n\nThis is the index of the VecAD vector and is less than the number of\nVecAD vectors in the recording.\n\nvar_sparsity\n************\nThe set with index *i_z* in *vecad_sparsity\nis the sparsity pattern for the variable *z*.\nIf *dependency* is true and *x* is a variable,\nthe sparsity pattern for *z* is added to the sparsity pattern *x* .\n\nvecad_sparsity\n**************\nThe sparsity pattern for *z* is added to the sparsity pattern\nwith index *i_v* in *vecad_sparsity ( the sparsity pattern for *v* ).\n\n\n{xrst_end var_load_rev_jac}\n*/\n// BEGIN_LOAD_REV_JAC\ntemplate <class Vector_set>\ninline void load_rev_jac(\n   op_code_var               op_code        ,\n   size_t                    num_vecad_ind  ,\n   size_t                    i_z            ,\n   const addr_t*             arg            ,\n   bool                      dependency     ,\n   const pod_vector<size_t>& vecad_ind      ,\n   Vector_set&               var_sparsity   ,\n   Vector_set&               vecad_sparsity )\n// END_LOAD_REV_JAC\n{  //\n   //\n   CPPAD_ASSERT_NARG_NRES(op_code, 3, 1);\n   CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_vecad_ind );\n   //\n   // i_v\n   size_t i_v = vecad_ind[ arg[0] - 1 ];\n   CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() );\n   //\n   // vecad_sparsity[i_v]\n   vecad_sparsity.binary_union(i_v, i_v, i_z, var_sparsity);\n   if( dependency & (op_code == LdvOp) )\n   {  size_t i_x = size_t( arg[1] );\n      var_sparsity.binary_union(i_x, i_x, i_z, var_sparsity);\n   }\n   return;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_load_rev_hes dev}\n\nReverse Hessian Sparsity for Load a VecAD Element\n#################################################\n\nv, x, y, z\n**********\nsee\n:ref:`var_load_op@v` ,\n:ref:`var_load_op@x` ,\n:ref:`var_load_op@y` ,\n:ref:`var_load_op@z`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_LOAD_REV_HES\n   // END_LOAD_REV_HES\n}\n\nop_code, num_vecad_ind, i_z, arg\n********************************\nsee :ref:`var_load_op@op_code` ,\n:ref:`var_load_op@num_vecad_ind` ,\n:ref:`var_load_op@i_z` ,\n:ref:`var_load_op@arg` .\n\nVector_set\n**********\nis the type used for vectors of sets. It must satisfy the\n:ref:`SetVector-name` concept.\n\nvecad_ind\n*********\nis a vector with size *num_vec_ind* .\nWe use the notation *i_v* defined by\n\n|tab| *i_v* = vecad_ind[ arg[0] - 1 ]\n\nThis is the index of the VecAD vector and is less than the number of\nVecAD vectors in the recording.\nIt is also the index of the hessian\nsparsity pattern for *v* in *vecad_sparsity*.\n\nvar_sparsity\n************\nThe set with index *i_z* in *var_sparsity\nis the hessian sparsity pattern for the variable *z*.\n\nvecad_sparsity\n**************\nThe set with index *i_v* in *vecad_sparsity\nis the hessian sparsity pattern for the vector *v*.\nThe sparsity pattern for *z* is added to the sparsity pattern for *v* .\n\nvar_rev_jac\n***********\nIf the scalar function has non-zero partial w.r.t *z* ,\nthe *i_z* component of this vector is true.\n\nvecad_rev_jac\n*************\nIf the scalar function has non-zero partial w.r.t *z* ,\nthe *i_v* component of *vecad_rev_jac* is set to true.\n\n{xrst_end var_load_rev_hes}\n*/\n// BEGIN_LOAD_REV_HES\ntemplate <class Vector_set>\ninline void load_rev_hes(\n   op_code_var               op_code        ,\n   const addr_t*             arg            ,\n   size_t                    num_vecad_ind  ,\n   size_t                    i_z            ,\n   const pod_vector<size_t>& vecad_ind      ,\n   const Vector_set&         var_sparsity   ,\n   Vector_set&               vecad_sparsity ,\n   const bool*               var_rev_jac    ,\n   pod_vector<bool>&         vecad_rev_jac  )\n// END_LOAD_REV_HES\n{  //\n   //\n   CPPAD_ASSERT_NARG_NRES(op_code, 3, 1);\n   CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_vecad_ind );\n   CPPAD_ASSERT_UNKNOWN( vecad_ind.size() == num_vecad_ind );\n   //\n   // i_v\n   size_t i_v = vecad_ind[ arg[0] - 1 ];\n   CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() );\n   //\n   // vecad_sparsity[i_v]\n   vecad_sparsity.binary_union(i_v, i_v, i_z, var_sparsity);\n   //\n   // vecad_rev_jac[iv]\n   vecad_rev_jac[i_v] |= var_rev_jac[i_z];\n   //\n   return;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_load_for_hes dev}\n\nForward Hessian Sparsity for Load a VecAD Element\n#################################################\n\nv, x, y, z\n**********\nsee\n:ref:`var_load_op@v` ,\n:ref:`var_load_op@x` ,\n:ref:`var_load_op@y` ,\n:ref:`var_load_op@z`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_LOAD_FOR_HES\n   // END_LOAD_FOR_HES\n}\n\nop_code, num_vecad_ind, i_z, arg\n********************************\nsee :ref:`var_load_op@op_code` ,\n:ref:`var_load_op@num_vecad_ind` ,\n:ref:`var_load_op@i_z` ,\n:ref:`var_load_op@arg` .\n\nVector_set\n**********\nis the type used for vectors of sets. It must satisfy the\n:ref:`SetVector-name` concept.\n\nn\n*\nis the number of independent variables on the tape.\n\nvecad_ind\n*********\nis a vector with size *num_vec_ind* .\nWe use the notation *i_v* defined by\n\n|tab| *i_v* = vecad_ind[ arg[0] - 1 ]\n\nThis is the index of the VecAD vector and is less than the number of\nVecAD vectors in the recording.\nIt is also the index of the hessian\nsparsity pattern for *v* in *vecad_sparsity*.\n\nvecad_sparsity\n**************\nThe set with index *i_v* in *vecad_sparsity\nis the forward Jacobian sparsity pattern for the vector *v*.\n\nfor_hes_sparse\n**************\nsee :ref:`local_sweep_for_hes@for_hes_sparse` .\n\n{xrst_end var_load_for_hes}\n*/\n// BEGIN_LOAD_FOR_HES\ntemplate <class Vector_set>\ninline void load_for_hes(\n   op_code_var               op_code        ,\n   const addr_t*             arg            ,\n   size_t                    num_vecad_ind  ,\n   size_t                    i_z            ,\n   size_t                    n              ,\n   const pod_vector<size_t>& vecad_ind      ,\n   const Vector_set&         vecad_sparsity ,\n   Vector_set&               for_hes_sparse )\n// END_LOAD_FOR_HES\n{  //\n   //\n   CPPAD_ASSERT_NARG_NRES(op_code, 3, 1);\n   CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_vecad_ind );\n   CPPAD_ASSERT_UNKNOWN( vecad_ind.size() == num_vecad_ind );\n   //\n   // np1\n   size_t np1 = n + 1;\n   CPPAD_ASSERT_UNKNOWN( for_hes_sparse.end() == np1 );\n   //\n   // i_v\n   size_t i_v = vecad_ind[ arg[0] - 1 ];\n   CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() );\n   //\n   // for_hes_sparse\n   // set Jacobian sparsity for variable with index i_z\n   for_hes_sparse.assignment(np1 + i_z, i_v, vecad_sparsity);\n   //\n   return;\n}\n\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/log1p_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_LOG1P_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_LOG1P_OP_HPP\n\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n\ntemplate <class Base>\ninline void log1p_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t k;\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(Log1pOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(Log1pOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   if( p == 0 )\n   {  z[0] = log1p( x[0] );\n      p++;\n      if( q == 0 )\n         return;\n   }\n   if ( p == 1 )\n   {  z[1] = x[1] / (Base(1.0) + x[0]);\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {\n      z[j] = -z[1] * x[j-1];\n      for(k = 2; k < j; k++)\n         z[j] -= Base(double(k)) * z[k] * x[j-k];\n      z[j] /= Base(double(j));\n      z[j] += x[j];\n      z[j] /= (Base(1.0) + x[0]);\n   }\n}\n\ntemplate <class Base>\ninline void log1p_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(Log1pOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(Log1pOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* z = taylor + i_z * num_taylor_per_var;\n\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  z[m+ell] = Base(double(q)) * x[m+ell];\n      for(size_t k = 1; k < q; k++)\n         z[m+ell] -= Base(double(k)) * z[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell];\n      z[m+ell] /= (Base(double(q)) + Base(q) * x[0]);\n   }\n}\n\ntemplate <class Base>\ninline void log1p_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(Log1pOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(Log1pOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   z[0] = log1p( x[0] );\n}\n\n\ntemplate <class Base>\ninline void log1p_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   size_t j, k;\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(Log1pOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(Log1pOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to result\n   const Base* z  = taylor  + i_z * cap_order;\n   Base* pz       = partial + i_z * n_order;\n\n   Base inv_1px0 = Base(1.0) / (Base(1) + x[0]);\n\n   j = d;\n   while(j)\n   {  // scale partial w.r.t z[j]\n      pz[j]   = azmul(pz[j]   , inv_1px0);\n\n      px[0]   -= azmul(pz[j], z[j]);\n      px[j]   += pz[j];\n\n      // further scale partial w.r.t. z[j]\n      pz[j]   /= Base(double(j));\n\n      for(k = 1; k < j; k++)\n      {  pz[k]   -= Base(double(k)) * azmul(pz[j], x[j-k]);\n         px[j-k] -= Base(double(k)) * azmul(pz[j], z[k]);\n      }\n      --j;\n   }\n   px[0] += azmul(pz[0], inv_1px0);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/log_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_LOG_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_LOG_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void log_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t k;\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(LogOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(LogOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   if( p == 0 )\n   {  z[0] = log( x[0] );\n      p++;\n      if( q == 0 )\n         return;\n   }\n   if ( p == 1 )\n   {  z[1] = x[1] / x[0];\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {\n      z[j] = -z[1] * x[j-1];\n      for(k = 2; k < j; k++)\n         z[j] -= Base(double(k)) * z[k] * x[j-k];\n      z[j] /= Base(double(j));\n      z[j] += x[j];\n      z[j] /= x[0];\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void log_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(LogOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(LogOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* z = taylor + i_z * num_taylor_per_var;\n\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  z[m+ell] = Base(double(q)) * x[m+ell];\n      for(size_t k = 1; k < q; k++)\n         z[m+ell] -= Base(double(k)) * z[(k-1)*r+1+ell] * x[(q-k-1)*r+1+ell];\n      z[m+ell] /= (Base(double(q)) * x[0]);\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void log_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(LogOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(LogOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   z[0] = log( x[0] );\n}\n\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void log_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   size_t j, k;\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(LogOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(LogOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to result\n   const Base* z  = taylor  + i_z * cap_order;\n   Base* pz       = partial + i_z * n_order;\n\n   Base inv_x0 = Base(1.0) / x[0];\n\n   j = d;\n   while(j)\n   {  // scale partial w.r.t z[j]\n      pz[j]   = azmul(pz[j]   , inv_x0);\n\n      px[0]   -= azmul(pz[j], z[j]);\n      px[j]   += pz[j];\n\n      // further scale partial w.r.t. z[j]\n      pz[j]   /= Base(double(j));\n\n      for(k = 1; k < j; k++)\n      {  pz[k]   -= Base(double(k)) * azmul(pz[j], x[j-k]);\n         px[j-k] -= Base(double(k)) * azmul(pz[j], z[k]);\n      }\n      --j;\n   }\n   px[0] += azmul(pz[0], inv_x0);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/mul_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_MUL_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_MUL_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n\n// --------------------------- Mulvv -----------------------------------------\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void mulvv_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   size_t k;\n   for(size_t d = p; d <= q; d++)\n   {  z[d] = Base(0.0);\n      for(k = 0; k <= d; k++)\n         z[d] += x[d-k] * y[k];\n   }\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void mulvv_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + size_t(arg[0]) * num_taylor_per_var;\n   Base* y = taylor + size_t(arg[1]) * num_taylor_per_var;\n   Base* z = taylor +    i_z * num_taylor_per_var;\n\n   size_t k, ell, m;\n   for(ell = 0; ell < r; ell++)\n   {  m = (q-1)*r + ell + 1;\n      z[m] = x[0] * y[m] + x[m] * y[0];\n      for(k = 1; k < q; k++)\n         z[m] += x[(q-k-1)*r + ell + 1] * y[(k-1)*r + ell + 1];\n   }\n}\n\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void mulvv_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   z[0] = x[0] * y[0];\n}\n\n\n// See dev documentation: reverse_binary_op\ntemplate <class Base>\ninline void mulvv_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Arguments\n   const Base* x  = taylor + size_t(arg[0]) * cap_order;\n   const Base* y  = taylor + size_t(arg[1]) * cap_order;\n\n   // Partial derivatives corresponding to arguments and result\n   Base* px = partial + size_t(arg[0]) * n_order;\n   Base* py = partial + size_t(arg[1]) * n_order;\n   Base* pz = partial + i_z    * n_order;\n\n\n   // number of indices to access\n   size_t j = d + 1;\n   size_t k;\n   while(j)\n   {  --j;\n      for(k = 0; k <= j; k++)\n      {\n         // must use azmul because pz[j] = 0 may mean that this\n         // component of the function was not selected.\n         px[j-k] += azmul(pz[j], y[k]);\n         py[k]   += azmul(pz[j], x[j-k]);\n      }\n   }\n}\n// --------------------------- Mulpv -----------------------------------------\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void mulpv_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   // Paraemter value\n   Base x = parameter[ arg[0] ];\n\n   for(size_t d = p; d <= q; d++)\n      z[d] = x * y[d];\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void mulpv_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   size_t m                  = (q-1) * r + 1;\n   Base* y = taylor + size_t(arg[1]) * num_taylor_per_var + m;\n   Base* z = taylor + i_z    * num_taylor_per_var + m;\n\n   // Paraemter value\n   Base x = parameter[ arg[0] ];\n\n   for(size_t ell = 0; ell < r; ell++)\n      z[ell] = x * y[ell];\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void mulpv_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 );\n\n   // Paraemter value\n   Base x = parameter[ arg[0] ];\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   z[0] = x * y[0];\n}\n\n\n// See dev documentation: reverse_binary_op\ntemplate <class Base>\ninline void mulpv_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Arguments\n   Base x  = parameter[ arg[0] ];\n\n   // Partial derivatives corresponding to arguments and result\n   Base* py = partial + size_t(arg[1]) * n_order;\n   Base* pz = partial + i_z    * n_order;\n\n   // number of indices to access\n   size_t j = d + 1;\n   while(j)\n   {  --j;\n      // must use azmul because pz[j] = 0 may mean that this\n      // component of the function was not selected.\n      py[j] += azmul(pz[j], x);\n   }\n}\n\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/neg_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_NEG_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_NEG_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\ntemplate <class Base>\n\n// See forward_unary1_op in developer documentation\ninline void neg_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_NARG_NRES( NegOp, 1, 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   for(size_t k = p; k <= q; k++)\n      z[k] = - x[k];\n}\n\n// See forward_unary1_op_dir in  developer documentation\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void neg_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n\n   // check assumptions\n   CPPAD_ASSERT_NARG_NRES( NegOp, 1, 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* z = taylor + i_z * num_taylor_per_var;\n\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n      z[m+ell] = - x[m+ell];\n}\n\n// See forward_unary1_op_0 in developer documentation\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void neg_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n\n   // check assumptions\n   CPPAD_ASSERT_NARG_NRES( NegOp, 1, 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   z[0] = - x[0];\n}\n\n// See reverse_unary1_op in developer documentation\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void neg_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_NARG_NRES( NegOp, 1, 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to result\n   Base* pz       = partial + i_z * n_order;\n\n   Base neg_one   = Base(-1.0);\n   for(size_t k = 0; k <= d; ++k)\n      px[k]  += azmul(pz[k], neg_one);\n\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/one_var.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_ONE_VAR_HPP\n# define CPPAD_LOCAL_VAR_OP_ONE_VAR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE\nnamespace CppAD { namespace local { namespace var_op {\n\n/*\n{xrst_begin_parent var_one_var dev}\n\nSparsity Calculations for Operators With One Variable\n#####################################################\n\nUnary Operators\n***************\n| *z* = *Fun* ( *x* )\n\nSee :ref:`var_unary_op@Fun` for unary operators\nfor some of the possible values of *Fun* and the corresponding operators.\n\nBinary Operators\n****************\n| *z* = *fun* ( *x* , *y* )\n| *z* = *x*  *Op* *y*\n\n\nSee :ref:`var_binary_op@Fun` for binary operators,\nrestricted to the case where just *x* or just *y* is a variable,\nfor some of the possible values of *Fun* and the corresponding operators.\n\nx\n*\nis the first operand for this operator .\n\ny\n*\nis the second operand for this operator\n\nz\n*\nis the primary result for this operator.\n\nVector_set\n**********\nis the type used for vectors of sets. It must satisfy the\n:ref:`SetVector-name` concept.\n\ni_z\n***\nis the variable index corresponding to *z* .\n\ni_v\n***\nis the variable index corresponding to the argument that is a variable.\n\n{xrst_end var_one_var}\n------------------------------------------------------------------------------\n{xrst_begin var_one_var_for_jac dev}\n\nForward Jacobian Sparsity for One Variable Argument Operators\n#############################################################\n\nx, y, z\n*******\nsee\n:ref:`var_one_var@x` ,\n:ref:`var_one_var@y` ,\n:ref:`var_one_var@z`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ONE_VAR_FOR_JAC\n   // END_ONE_VAR_FOR_JAC\n}\n\nVector_set, i_z, i_v\n********************\nsee\n:ref:`var_one_var@Vector_set` ,\n:ref:`var_one_var@i_z` ,\n:ref:`var_one_var@i_v`\n\nsparsity\n********\n\nInput\n=====\nfor *j* < *i_z*  and *j* not an auxiliary result,\nthe set with index *j* in *sparsity* is\nthe Jacobian sparsity for the variable with index *j* .\n\nOutput\n======\nThe set with index *i_z* in *sparsity* is\nthe Jacobian sparsity for the variable *z* .\n\n{xrst_end var_one_var_for_jac}\n*/\n// BEGIN_ONE_VAR_FOR_JAC\ntemplate <class Vector_set>\nvoid one_var_for_jac(\n   size_t            i_z           ,\n   size_t            i_v           ,\n   Vector_set&       sparsity      )\n// END_ONE_VAR_FOR_JAC\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( i_v < i_z );\n\n   sparsity.assignment(i_z, i_v, sparsity);\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_one_var_rev_jac dev}\n\nReverse Jacobian Sparsity for One Variable Argument Operators\n#############################################################\n\nx, y, z\n*******\nsee\n:ref:`var_one_var@x` ,\n:ref:`var_one_var@y` ,\n:ref:`var_one_var@z`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ONE_VAR_REV_JAC\n   // END_ONE_VAR_REV_JAC\n}\n\nVector_set, i_z, i_v\n********************\nsee\n:ref:`var_one_var@Vector_set` ,\n:ref:`var_one_var@i_z` ,\n:ref:`var_one_var@i_v`\n\nsparsity\n********\nUse z(v) to denote the variable *z* as a function of the variable *v*\nand define H in terms of G by::\n\n   H( v , u , ... ) = G[ z(v) , u , ... ]\n\nOn input, *sparsity* is a sparsity pattern for the Jacobian of *G* .\nUpon return, *sparsity* is a sparsity pattern for the Jacobian of *H* .\n\n{xrst_end var_one_var_rev_jac}\n*/\n// BEGIN_ONE_VAR_REV_JAC\ntemplate <class Vector_set>\nvoid one_var_rev_jac(\n   size_t            i_z         ,\n   size_t            i_v         ,\n   Vector_set&       sparsity    )\n// END_ONE_VAR_REV_JAC\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( i_v < i_z );\n\n   sparsity.binary_union(i_v, i_v, i_z, sparsity);\n\n   return;\n}\n// ---------------------------------------------------------------------------\n/*\n{xrst_begin var_one_var_rev_hes dev}\n\nReverse Jacobian Sparsity for One Variable Argument Operators\n#############################################################\n\nx, y, z\n*******\nsee\n:ref:`var_one_var@x` ,\n:ref:`var_one_var@y` ,\n:ref:`var_one_var@z`\n\nG and H\n*******\nUse :math:`z(v)` to denote the variable *z* as a function of the variable *v* .\nWe use :math:`G( z, v, \\ldots )` to denote a function of the variables\nup to and including *z* .\nWe define :math:`H(v, \\ldost)` by\n\n.. math::\n\n   H(v, \\cdots ) = G [ z(v) , v , \\cdots ]\n\nnum_var\n*******\nWe use the notation *num_var* for the number of variables on the tape\n(including the phantom variable at index zero).\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ONE_VAR_REV_HES\n   // END_ONE_VAR_REV_HES\n}\n\nVector_set, i_z, i_v\n********************\nsee\n:ref:`var_one_var@Vector_set` ,\n:ref:`var_one_var@i_z` ,\n:ref:`var_one_var@i_v`\n\nlinear[0]\n*********\nThis value is true (false) if the :math:`z(v)`\nmust have zero second derivative (may have non-zero second derivative).\n\nfor_jac_sparsity\n****************\nThe set with index *j* is the forward Jacobian sparsity\npattern for the variable with index *j*.\n\nrev_jac_include\n***************\nIf the *j* element of this vector is true,\nthe variable with index *j* is included in the Hessian,\nor affects the value of a variable that is included in the Hessian.\n\nInput\n=====\n::\n\n   for j = num_var, ... , i_z + 1\n      rev_jac_include[j] is an input\n\nOutput\n======\nrev_jac_include[i_z] is an output\n\nrev_hes_sparsity\n****************\nOn input (output), this is the sparsity pattern for *G* ( *H* ).\nFor each variable index *j* ,\n*rev_hes_sparsity* [ *j* ] is the set of indices\nthat may have non-zero cross partials with variable index *j* .\n\nExample\n=======\nIf the indices in the sets correspond to the independent variables,\nthen *rev_hes_sparsity* ``.end()`` is the number of independent variables.\nFor *i* a variable index between 1 and the number of independent variables,\n*i* - 1 is the corresponding independent variable index.\n(The index *i* = 0 corresponds to the phantom variable at the beginning\nof the tape. )\n{xrst_end var_one_var_rev_hes}\n*/\n// BEGIN_ONE_VAR_REV_HES\ntemplate <class Vector_set>\nvoid one_var_rev_hes(\n   size_t              i_z               ,\n   size_t              i_v               ,\n   bool*               linear            ,\n   bool*               rev_jacobian      ,\n   const Vector_set&   for_jac_sparsity  ,\n   Vector_set&         rev_hes_sparsity  )\n// END_ONE_VAR_REV_HES\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( i_v < i_z );\n\n   // check for no effect\n   if( ! rev_jacobian[i_z] )\n      return;\n\n   rev_hes_sparsity.binary_union(i_v, i_v, i_z, rev_hes_sparsity);\n   if( ! linear[0] )\n      rev_hes_sparsity.binary_union(i_v, i_v, i_v, for_jac_sparsity);\n\n   rev_jacobian[i_v] = true;\n   return;\n}\n// ---------------------------------------------------------------------------\n/*\n{xrst_begin var_one_var_for_hes dev}\n\nForward Hessian Sparsity for One Variable Argument Operators\n############################################################\n\nx, y, z\n*******\nsee\n:ref:`var_one_var@x` ,\n:ref:`var_one_var@y` ,\n:ref:`var_one_var@z`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_ONE_VAR_FOR_HES\n   // END_ONE_VAR_FOR_HES\n}\n\nVector_set, i_z, i_v\n********************\nsee\n:ref:`var_one_var@Vector_set` ,\n:ref:`var_one_var@i_z` ,\n:ref:`var_one_var@i_v`\n\n\nlinear[0]\n*********\nThis value is true (false) if the :math:`z(v)`\nmust have zero second derivative (may have non-zero second derivative).\n\n\nn_independent_p1\n****************\nis the number of independent variables (in the tape) plus one.\n\nnum_var\n*******\nThis is the total number of variables in the tape\n(counting the phantom variable at index zero).\n\nfor_sparsity\n************\nOn input, all the linear and nonlinear interactions up to the\narguments to the atomic function have been take into account.\nUpon return, the linear and nonlinear interactions in\nthe atomic function have been take into account.\n\nHessian Sparsity\n================\nFor *j* equal 1 to *n_independent_p1* - 1,\nif *i* is in set with index *j* ,\nthe Hessian may have a non-zero partial with respect to the\nindependent variables with indices ( *i* - 1, *j* - 1 ) .\nNote that the index zero is not used because it corresponds to the\nphantom variable on the tape.\n\nJacobian Sparsity\n=================\nIf *i* is in the set with index *n_independent_p1* + *j* ,\nthe variable with index *j* may have a non-zero partial with resect to the\nindependent variable with index *i* - 1 .\n\n{xrst_end var_one_var_for_hes}\n*/\n// BEGIN_ONE_VAR_FOR_HES\ntemplate <class Vector_set>\nvoid one_var_for_hes(\n   size_t              n_independent_p1 ,\n   size_t              num_var          ,\n   size_t              i_z              ,\n   size_t              i_v              ,\n   bool*               linear           ,\n   Vector_set&         for_sparsity     )\n// END_ONE_VAR_FOR_HES\n{  // np1\n   size_t np1 = n_independent_p1;\n   //\n   CPPAD_ASSERT_UNKNOWN( i_v < i_z );\n   CPPAD_ASSERT_UNKNOWN( i_v < num_var );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + num_var );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.number_elements(np1) == 0 );\n\n   // for_sparsity\n   // set Jacobian sparsity for z\n   for_sparsity.assignment(np1 + i_z, np1 + i_v, for_sparsity);\n\n   //\n   if( ! linear[0] )\n   {  // itr\n      // set of independent variables that v depends on\n      typename Vector_set::const_iterator itr(for_sparsity, i_v + np1);\n      //\n      // i_x\n      // loop over independent variables that v has non-zero partials w.r.t.\n      size_t i_x = *itr;\n      while( i_x < np1 )\n      {  // for_sparsity\n         // union of Hessian sparsity for x and Jacobian sparsity for v\n         for_sparsity.binary_union(i_x, i_x, i_v + np1, for_sparsity);\n         i_x = *(++itr);\n      }\n   }\n   return;\n}\n\n} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/par_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_PAR_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_PAR_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n/*\n{xrst_begin_parent var_par_op dev}\n\nCreate a Variable From a Parameter Operator\n###########################################\n\nParOp\n*****\nis the op code for this operator.\n\nPurpose\n*******\nIf one of the :ref:`dependent@y` components in an ADFun object is a parameter,\nit is converted to a variable using this operator.\n\nn_res\n*****\nThis operator has one variable result (the variable that is created).\n\ni_z\n***\nis the variable index corresponding the result of this operator.\n\narg\n***\n\narg[0]\n======\nis the index of the parameter that is converted to a variable\n\n{xrst_end var_par_op}\n------------------------------------------------------------------------------\n{xrst_begin var_par_forward_0 dev}\n\nZero Order Forward Create a Variable From a Parameter\n#####################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PAR_FORWARD_0\n   // END_PAR_FORWARD_0\n}\n\ni_z, arg\n********\nsee\nref:`var_par_op@i_z` ,\nref:`var_par_op@arg`\n\nnum_par\n*******\nis the total number of values in the *parameter* vector.\n\nparameter\n*********\nmaps parameter indices to parameter values .\n\ntaylor\n******\nThe Taylor coefficient corresponding to variable *i* and order *k* is\n\n   *taylor* [ *i* * *cap_order* + *k*  ]\n\nInput\n=====\nThe zero order Taylor coefficients\nfor variables with index *i* less than or equal *i_z* .\n\nOutput\n======\nThe zero order Taylor coefficients for variables with index *i_z* ; i.e.,\nthe value of the parameter.\n\n{xrst_end var_par_forward_0}\n*/\n// BEGIN_PAR_FORWARD_0\ntemplate <class Base>\ninline void par_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        num_par     ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n// END_PAR_FORWARD_0\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_NARG_NRES(ParOp, 1, 1);\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   Base* z = taylor + i_z * cap_order;\n\n   z[0]  = parameter[ arg[0] ];\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_par_forward_any dev}\n\nAny Order Forward Create a Variable From a Parameter\n####################################################\n\nn_res\n*****\nsee\n:ref:`var_par_op@n_res` .\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PAR_FORWARD_ANY\n   // END_PAR_FORWARD_ANY\n}\n\ni_z, arg\n********\nsee\nref:`var_par_op@i_z` ,\nref:`var_par_op@arg`\n\nnum_par\n*******\nis the total number of values in the *parameter* vector.\n\nparameter\n*********\nmaps parameter indices to parameter values .\n\n{xrst_template ;\n   include/cppad/local/var_op/template/forward_op.xrst\n   headers: cap_order, order_low, order_up, taylor\n}\n\n{xrst_end var_par_forward_any}\n*/\n// BEGIN_PAR_FORWARD_ANY\ntemplate <class Base>\ninline void par_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        num_par     ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n// END_PAR_FORWARD_ANY\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_NARG_NRES(ParOp, 1, 1);\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n   CPPAD_ASSERT_UNKNOWN( order_low <= order_up );\n\n   Base* z = taylor + i_z * cap_order;\n   if( order_low == 0 )\n   {  z[0]  = parameter[ arg[0] ];\n      ++order_low;\n   }\n   for(size_t k = order_low; k <= order_up; ++k)\n      z[k] = Base(0.0);\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_par_forward_dir dev}\n\nMultiple Direction Forward Create a Variable From a Parameter\n#############################################################\n\nn_res\n*****\nsee\n:ref:`var_par_op@n_res` .\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PAR_FORWARD_DIR\n   // END_PAR_FORWARD_DIR\n}\n\ni_z, arg\n********\nsee\nref:`var_par_op@i_z` ,\nref:`var_par_op@arg`\n\nnum_par\n*******\nis the total number of values in the *parameter* vector.\n\nparameter\n*********\nmaps parameter indices to parameter values .\n\n{xrst_template ;\n   include/cppad/local/var_op/template/forward_dir.xrst\n   headers: n_dir, cap_order, order_up, taylor\n}\n\n{xrst_end var_par_forward_dir}\n*/\n// BEGIN_PAR_FORWARD_DIR\ntemplate <class Base>\ninline void par_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        num_par     ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n// END_PAR_FORWARD_DIR\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_NARG_NRES(ParOp, 1, 1);\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n   CPPAD_ASSERT_UNKNOWN( 0 < order_up );\n\n   // per_variable\n   size_t per_variable = (cap_order - 1) * n_dir + 1;\n   //\n   // z\n   Base* z  = taylor + i_z * per_variable;\n   //\n   // m\n   size_t m = (order_up - 1) * n_dir + 1;\n   //\n   // taylor\n   for(size_t ell = 0; ell < n_dir; ++ell)\n      z[m + ell]   = Base(0.0);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/parameter_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_PARAMETER_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_PARAMETER_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void forward_par_op_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        num_par     ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ParOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ParOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   Base* z = taylor + i_z * cap_order;\n\n   z[0]  = parameter[ arg[0] ];\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/pow_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_POW_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_POW_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n/*!\n\\file pow_op.hpp\nForward and reverse mode calculations for z = pow(x, y).\n*/\n\n// --------------------------- Powvv -----------------------------------------\n/*!\nCompute forward mode Taylor coefficients for result of op = PowvvOp.\n\nIn the documentation below,\nthis operations is for the case where both x and y are variables\nand the argument parameter is not used.\n\n\\copydetails CppAD::local::forward_pow_op\n*/\n\ntemplate <class Base>\ninline void powvv_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // convert from final result to first result\n   i_z -= 2; // 2 = NumRes(PowvvOp) - 1;\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(PowvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(PowvvOp) == 3 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= i_z\n   );\n\n   // z_0 = log(x)\n   log_forward_any(p, q, i_z, arg, cap_order, taylor);\n\n   // z_1 = z_0 * y\n   addr_t addr[2];\n   addr[0] = addr_t( i_z );\n   addr[1] = arg[1];\n   mulvv_forward_any(p, q, i_z+1, addr,  parameter, cap_order, taylor);\n\n   // z_2 = exp(z_1)\n   // final result for zero order case is exactly the same as for Base\n   if( p == 0 )\n   {  // Taylor coefficients corresponding to arguments and result\n      Base* x   = taylor + size_t(arg[0]) * cap_order;\n      Base* y   = taylor + size_t(arg[1]) * cap_order;\n      Base* z_2 = taylor + (i_z+2) * cap_order;\n\n      z_2[0] = pow(x[0], y[0]);\n      p++;\n   }\n   if( p <= q )\n   {  addr[0] = addr_t(i_z+1);\n      exp_forward_any(p, q, i_z+2, addr, cap_order, taylor);\n   }\n}\n/*!\nMultiple directions forward mode Taylor coefficients for op = PowvvOp.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = pow(x, y)\n\\endverbatim\nIn the documentation below,\nthis operations is for the case where x is a variable and y is a parameter.\n\n\\copydetails CppAD::local::forward_pow_op_dir\n*/\n\ntemplate <class Base>\ninline void powvv_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // convert from final result to first result\n   i_z -= 2; // 2 = NumRes(PowvvOp) - 1\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(PowvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(PowvvOp) == 3 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= i_z\n   );\n\n   // z_0 = log(x)\n   log_forward_dir(q, r, i_z, arg, cap_order, taylor);\n\n   // z_1 = y * z_0\n   addr_t addr[2];\n   addr[0] = addr_t( i_z );\n   addr[1] = arg[1];\n   mulvv_forward_dir(q, r, i_z+1, addr,  parameter, cap_order, taylor);\n\n   // z_2 = exp(z_1)\n   addr[0] = addr_t(i_z+1);\n   exp_forward_dir(q, r, i_z+2, addr, cap_order, taylor);\n}\n/*!\nCompute zero order forward mode Taylor coefficients for result of op = PowvvOp.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = pow(x, y)\n\\endverbatim\nIn the documentation below,\nthis operations is for the case where both x and y are variables\nand the argument parameter is not used.\n\n\\copydetails CppAD::local::forward_pow_op_0\n*/\n\ntemplate <class Base>\ninline void powvv_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // convert from final result to first result\n   i_z -= 2; // NumRes(PowvvOp) - 1;\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(PowvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(PowvvOp) == 3 );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x   = taylor + size_t(arg[0]) * cap_order;\n   Base* y   = taylor + size_t(arg[1]) * cap_order;\n   Base* z_0 = taylor + i_z    * cap_order;\n   Base* z_1 = z_0    +          cap_order;\n   Base* z_2 = z_1    +          cap_order;\n\n   z_0[0] = log( x[0] );\n   z_1[0] = z_0[0] * y[0];\n   z_2[0] = pow(x[0], y[0]);\n\n}\n\n/*!\nCompute reverse mode partial derivatives for result of op = PowvvOp.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = pow(x, y)\n\\endverbatim\nIn the documentation below,\nthis operations is for the case where both x and y are variables\nand the argument parameter is not used.\n\n\\copydetails CppAD::local::reverse_pow_op\n*/\n\ntemplate <class Base>\ninline void powvv_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  //\n   //\n   //\n   // convert from final result to first result\n   i_z -= 2; // NumRes(PowvvOp) - 1;\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(PowvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(PowvvOp) == 3 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= i_z\n   );\n\n   // z_2 = exp(z_1)\n   addr_t addr[2];\n   addr[0] = addr_t(i_z + 1);\n   exp_reverse(\n      i_z+2, addr, cap_order, taylor, n_order, partial\n   );\n\n   // z_1 = z_0 * y\n   addr[0] = addr_t( i_z );\n   addr[1] = arg[1];\n   mulvv_reverse(\n   i_z+1, addr,  parameter, cap_order, taylor, n_order, partial\n   );\n\n   // z_0 = log(x)\n   log_reverse(\n      i_z, arg, cap_order, taylor, n_order, partial\n   );\n}\n\n// --------------------------- Powpv -----------------------------------------\n/*!\nCompute forward mode Taylor coefficients for result of op = PowpvOp.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = pow(x, y)\n\\endverbatim\nIn the documentation below,\nthis operations is for the case where x is a parameter and y is a variable.\n\n\\copydetails CppAD::local::forward_pow_op\n*/\n\ntemplate <class Base>\ninline void powpv_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // convert from final result to first result\n   i_z -= 2; // 2 = NumRes(PowpvOp) - 1;\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(PowpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(PowpvOp) == 3 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* z_0 = taylor + i_z    * cap_order;\n\n   // z_0 = log(x)\n   Base x    = parameter[ arg[0] ];\n   size_t d;\n   for(d = p; d <= q; d++)\n   {  if( d == 0 )\n         z_0[d] = log(x);\n      else\n         z_0[d] = Base(0.0);\n   }\n\n   // 2DO: remove requirement that i_z * cap_order <= max addr_t value\n   CPPAD_ASSERT_KNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= i_z * cap_order,\n      \"cppad_tape_addr_type maximum value has been exceeded\\n\"\n      \"This is due to a kludge in the pow operation and should be fixed.\"\n   );\n\n   // z_1 = z_0 * y\n   addr_t addr[2];\n   // offset of z_i in taylor (as if it were a parameter); i.e., log(x)\n   addr[0] = addr_t( i_z * cap_order );\n   // offset of y in taylor (as a variable)\n   addr[1] = arg[1];\n\n   // Trick: use taylor both for the parameter vector and variable values\n   mulpv_forward_any(p, q, i_z+1, addr,  taylor, cap_order, taylor);\n\n   // z_2 = exp(z_1)\n   // zero order case exactly same as Base type operation\n   if( p == 0 )\n   {  Base* y   = taylor + size_t(arg[1]) * cap_order;\n      Base* z_2 = taylor + (i_z+2) * cap_order;\n      z_2[0] = pow(x, y[0]);\n      p++;\n   }\n   if( p <= q )\n   {  addr[0] = addr_t(i_z+1);\n      exp_forward_any(p, q, i_z+2, addr, cap_order, taylor);\n   }\n}\n/*!\nMultiple directions forward mode Taylor coefficients for op = PowpvOp.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = pow(x, y)\n\\endverbatim\nIn the documentation below,\nthis operations is for the case where x is a parameter and y is a variable.\n\n\\copydetails CppAD::local::forward_pow_op_dir\n*/\n\ntemplate <class Base>\ninline void powpv_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // convert from final result to first result\n   i_z -= 2; // 2 = NumRes(PowpvOp) - 1;\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(PowpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(PowpvOp) == 3 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* z_0 = taylor + i_z * num_taylor_per_var;\n\n   // z_0 = log(x)\n   size_t m  = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n      z_0[m+ell] = Base(0.0);\n\n   // 2DO: remove requirement i_z * num_taylor_per_var <= max addr_t value\n   CPPAD_ASSERT_KNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= i_z * num_taylor_per_var,\n      \"cppad_tape_addr_type maximum value has been exceeded\\n\"\n      \"This is due to a kludge in the pow operation and should be fixed.\"\n   );\n\n   // z_1 = z_0 * y\n   addr_t addr[2];\n   // offset of z_0 in taylor (as if it were a parameter); i.e., log(x)\n   addr[0] = addr_t( i_z * num_taylor_per_var );\n   // offset of y in taylor (as a variable)\n   addr[1] = arg[1];\n\n   // Trick: use taylor both for the parameter vector and variable values\n   mulpv_forward_dir(q, r, i_z+1, addr,  taylor, cap_order, taylor);\n\n   // z_2 = exp(z_1)\n   addr[0] = addr_t(i_z+1);\n   exp_forward_dir(q, r, i_z+2, addr, cap_order, taylor);\n}\n/*!\nCompute zero order forward mode Taylor coefficient for result of op = PowpvOp.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = pow(x, y)\n\\endverbatim\nIn the documentation below,\nthis operations is for the case where x is a parameter and y is a variable.\n\n\\copydetails CppAD::local::forward_pow_op_0\n*/\n\ntemplate <class Base>\ninline void powpv_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // convert from final result to first result\n   i_z -= 2; // NumRes(PowpvOp) - 1;\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(PowpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(PowpvOp) == 3 );\n\n   // Paraemter value\n   Base x = parameter[ arg[0] ];\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* y   = taylor + size_t(arg[1]) * cap_order;\n   Base* z_0 = taylor + i_z    * cap_order;\n   Base* z_1 = z_0    +          cap_order;\n   Base* z_2 = z_1    +          cap_order;\n\n   // z_0 = log(x)\n   z_0[0] = log(x);\n\n   // z_1 = z_0 * y\n   z_1[0] = z_0[0] * y[0];\n\n   // z_2 = exp(z_1)\n   // zero order case exactly same as Base type operation\n   z_2[0] = pow(x, y[0]);\n}\n\n/*!\nCompute reverse mode partial derivative for result of op = PowpvOp.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = pow(x, y)\n\\endverbatim\nIn the documentation below,\nthis operations is for the case where x is a parameter and y is a variable.\n\n\\copydetails CppAD::local::reverse_pow_op\n*/\n\ntemplate <class Base>\ninline void powpv_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  //\n   //\n   //\n   // convert from final result to first result\n   i_z -= 2; // NumRes(PowpvOp) - 1;\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(PowvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(PowvvOp) == 3 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // z_2 = exp(z_1)\n   addr_t addr[2];\n   addr[0] = addr_t(i_z + 1);\n   exp_reverse(\n      i_z+2, addr, cap_order, taylor, n_order, partial\n   );\n\n   // 2DO: remove requirement that i_z * cap_order <= max addr_t value\n   CPPAD_ASSERT_KNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= i_z * cap_order,\n      \"cppad_tape_addr_type maximum value has been exceeded\\n\"\n      \"This is due to a kludge in the pow operation and should be fixed.\"\n   );\n\n   // z_1 = z_0 * y\n   addr[0] = addr_t( i_z * cap_order ); // offset of z_0[0] in taylor\n   addr[1] = arg[1];                    // index of y in taylor and partial\n   // use taylor both for parameter and variable values\n   mulpv_reverse(\n      i_z+1, addr,  taylor, cap_order, taylor, n_order, partial\n   );\n\n   // z_0 = log(x)\n   // x is a parameter\n}\n\n// --------------------------- Powvp -----------------------------------------\n/*!\nCompute forward mode Taylor coefficients for result of op = PowvpOp.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = pow(x, y)\n\\endverbatim\nIn the documentation below,\nthis operations is for the case where x is a variable and y is a parameter.\n\n\\copydetails CppAD::local::forward_pow_op\n*/\n\ntemplate <class Base>\ninline void powvp_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(PowvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(PowvpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= i_z\n   );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   // Paraemter value\n   Base y = parameter[ arg[1] ];\n\n   // Special solution when x[0] is zero\n   Base b0 = Base( 0.0 );\n\n   // special case zero order\n   if( p == 0 )\n   {  z[0] = pow(x[0], y);\n      p++;\n   }\n   for(size_t j = p; j <= q; ++j)\n   {  Base sum = Base(0);\n      for(size_t k = 1; k < j; ++k)\n      {  Base bk = Base( double(k) );\n         sum += bk * (y * x[k] * z[j-k] - z[k] * x[j-k]);\n      }\n      Base bj = Base( double(j) );\n      Base zj = ( y * z[0] * x[j] + sum / bj ) / x[0];\n      z[j] = CondExpEq(x[0], b0, b0, zj);\n   }\n}\n/*!\nMultiple directions forward mode Taylor coefficients for op = PowvpOp.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = pow(x, y)\n\\endverbatim\nIn the documentation below,\nthis operations is for the case where x is a variable and y is a parameter.\n\n\\copydetails CppAD::local::forward_pow_op_dir\n*/\n\ntemplate <class Base>\ninline void powvp_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(PowvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(PowvpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= i_z\n   );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + size_t(arg[0]) * num_taylor_per_var;\n   Base* z = taylor +    i_z * num_taylor_per_var;\n\n   // Parameter value\n   Base y = parameter[ arg[1] ];\n\n   // special solution when x[0] is zero\n   Base b0 = Base( 0.0 );\n\n   // index in Taylor coefficients where multiple directions start\n   size_t m = (q-1)*r + 1;\n   //\n   // loop over directions\n   for(size_t ell = 0; ell < r; ell++)\n   {  Base sum = Base(0);\n      for(size_t k = 1; k < q; ++k)\n      {  Base xk   = x[(k-1)*r   + ell + 1];\n         Base zk   = z[(k-1)*r   + ell + 1];\n         Base xqk  = x[(q-k-1)*r + ell + 1];\n         Base zqk  = z[(q-k-1)*r + ell + 1];\n         Base bk   = Base( double(k) );\n         sum += bk * (y * xk * zqk - zk * xqk);\n      }\n      Base xq  = x[(q-1)*r + ell + 1];\n      Base bq   = Base( double(q) );\n      Base zell = ( y * z[0] * xq + sum / bq ) / x[0];\n      z[m+ell]  = CondExpEq(x[0], b0, b0, zell);\n   }\n}\n\n/*!\nCompute zero order forward mode Taylor coefficients for result of op = PowvpOp.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = pow(x, y)\n\\endverbatim\nIn the documentation below,\nthis operations is for the case where x is a variable and y is a parameter.\n\n\\copydetails CppAD::local::forward_pow_op_0\n*/\n\ntemplate <class Base>\ninline void powvp_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(PowvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(PowvpOp) == 1 );\n\n   // Paraemter value\n   Base y = parameter[ arg[1] ];\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   z[0] = pow(x[0], y);\n}\n\n/*!\nCompute reverse mode partial derivative for result of op = PowvpOp.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   z = pow(x, y)\n\\endverbatim\nIn the documentation below,\nthis operations is for the case where x is a variable and y is a parameter.\n\n\\copydetails CppAD::local::reverse_pow_op\n*/\n\ntemplate <class Base>\ninline void powvp_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     ,\n   CppAD::vector<Base>& work )\n{  //\n   //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(PowvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(PowvpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n   CPPAD_ASSERT_UNKNOWN(\n      size_t( std::numeric_limits<addr_t>::max() ) >= i_z\n   );\n\n   // Taylor coefficients\n   const Base* x = taylor + size_t( arg[0] ) * cap_order;\n   const Base* z = taylor + i_z * cap_order;\n\n   // parameter value\n   const Base  y = parameter[ arg[1] ];\n\n   // Partial derivatives corresponding to arguments and result\n   Base* px = partial + size_t(arg[0]) * n_order;\n   Base* pz = partial + i_z * n_order;\n\n   // Special solution when x[0] is zero\n   Base b0 = Base( 0.0 );\n\n   // Place to hold px for this operator until conditional assignment at end\n   work.resize(n_order);\n   for(size_t j = 0; j < n_order; ++j)\n      work[j] = px[j];\n\n   // reverse z^j for j = d, ..., 1\n   size_t j = n_order - 1;\n   while(j)\n   {  // j\n      Base bj = Base( double(j) );\n      //\n      // x^j term\n      work[j] += azmul(pz[j], y * z[0] / x[0]);\n      //\n      // x^k terms\n      for(size_t k = 1; k < j; ++k)\n      {  Base bk   = Base( double(k) );\n         Base term = (bk * y - Base(j-k) ) * z[j-k] / (bj * x[0]);\n         work[k] += azmul(pz[j], term);\n      }\n      //\n      // z^k terms\n      for(size_t k = 1; k < j; ++k)\n      {  Base bk   = Base( double(k) );\n         Base term = (Base(j-k) * y - bk) * x[j-k] / (bj * x[0]);\n         pz[k] += azmul(pz[j], term);\n      }\n      //\n      // x^0 term\n      work[0] -= azmul(pz[j], z[j] / x[0]);\n      //\n      // z^0 term\n      pz[0] += azmul(pz[j], y * x[j] / x[0] );\n      //\n      // next j\n      --j;\n   }\n   // reverse z^0\n   work[0] += azmul(pz[0], y * z[0] / x[0]);\n   //\n   for(j = 0; j < n_order; ++j)\n      px[j] = CondExpEq(x[0], b0, b0, work[j]);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/pri_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_PRI_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_PRI_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n/*\n{xrst_begin_parent var_pri_op dev}\n{xrst_spell\n   pos\n}\n\nPrint A Variable or Parameter Operator\n######################################\n\nPriOp\n*****\nis the op code for this operator.\n\nUser Syntax\n***********\n| ``PrintFor`` ( *pos* , *before* , *value* , *after* )\n\npos\n***\nThis value is expected to be positive and\n*value* is printed if *pos* is not positive.\n\nbefore\n******\nis the text printed before the value.\n\nvalue\n*****\nis the value that is printed.\n\nafter\n*****\nis the text printed after the value.\n\nRecBase\n*******\nis the base type use when recording this operator;\ni.e., this operation was recording using AD< *RecBase* > operations.\n\nBase\n****\nis the type used for computations by this operator.\nThis is either *RecBase* or AD< *RecBase* >.\n\narg\n***\n\narg[0]\n******\nThe first two bits of this value are used a flags; see below.\n\narg[1]\n******\nIf arg[0] & 1 is zero (is one), arg[1] is the parameter (variable) index\ncorresponding to *pos* .\n\narg[2]\n******\nis the text index corresponding to *before* .\n\narg[3]\n******\nIf arg[0] & 2 is zero (is one), arg[3] is the parameter (variable) index\ncorresponding to *value* .\n\narg[4]\n******\nis the text index corresponding to *after* .\n\n{xrst_end var_pri_op}\n------------------------------------------------------------------------------\n{xrst_begin var_pri_forward_0 dev}\n\nZero Order Forward Print A Variable or Parameter\n################################################\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PRI_FORWARD_0\n   // END_PRI_FORWARD_0\n}\n\ns_out\n*****\nthe results are printed on this output stream.\n\nnum_text\n********\nis the total number of text characters on the tape\n(only used for error checking).\n\ntext\n****\nis the tape text vector.\nThe value *before* ( *after* ) is stored in this vector\nas a null terminated string start at index arg[2] ( arg[4] ).\n\nnum_par\n*******\nis the total number of values in the parameter vector .\n\nparameter\n*********\nmaps parameter indices to parameter values.\n\ncap_order\n*********\nis the maximum number of orders that can fit in taylor .\n\ntaylor\n******\nThe zero order Taylor coefficient corresponding to the variable with\nindex j* is taylor[ j * cap_order + 0] .\n\n{xrst_end var_pri_forward_0}\n*/\n// BEGIN_PRI_FORWARD_0\ntemplate <class Base>\ninline void pri_forward_0(\n   std::ostream& s_out       ,\n   const addr_t* arg         ,\n   size_t        num_text    ,\n   const char*   text        ,\n   size_t        num_par     ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      )\n// END_PRI_FORWARD_0\n{  Base pos, value;\n   //\n   const char* before;\n   const char* after;\n   CPPAD_ASSERT_NARG_NRES(PriOp, 5, 0);\n\n   // pos\n   if( arg[0] & 1 )\n   {  pos = taylor[ size_t(arg[1]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n      pos = parameter[ arg[1] ];\n   }\n\n   // before\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_text );\n   before = text + arg[2];\n\n   // value\n   if( arg[0] & 2 )\n   {  value = taylor[ size_t(arg[3]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );\n      value = parameter[ arg[3] ];\n   }\n\n   // after\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_text );\n   after = text + arg[4];\n\n   if( ! GreaterThanZero( pos ) )\n      s_out << before << value << after;\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/print_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_PRINT_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_PRINT_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n/*!\nPrint operation for parameters; i.e., op = PriOp.\n\nThe C++ source code corresponding to this operation is\n\\verbatim\n   f.Forward(0, x)\n   PrintFor(before, var)\n   PrintFor(pos, before, var, after)\n\\endverbatim\nThe PrintFor call puts the print operation on the tape\nand the print occurs during the zero order forward mode computation.\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base .\n\n\\param s_out\nthe results are printed on this output stream.\n\n\\param arg\n arg[0] & 1\n\\n\nIf this is zero, pos is a parameter. Otherwise it is a variable.\n\\n\n arg[0] & 2\n\\n\nIf this is zero, var is a parameter. Otherwise it is a variable.\n\\n\n\\n\n arg[1]\n\\n\nIf pos is a parameter, <code>parameter[arg[1]]</code> is its value.\nOthwise <code>taylor[ size_t(arg[1]) * cap_order + 0 ]</code> is the zero\norder Taylor coefficient for pos.\n\\n\n\\n\n arg[2]\n\\n\nindex of the text to be printed before var\nif pos is not a positive value.\n\\n\n\\n\n arg[3]\n\\n\nIf var is a parameter, <code>parameter[arg[3]]</code> is its value.\nOthwise <code>taylor[ size_t(arg[3]) * cap_order + 0 ]</code> is the zero\norder Taylor coefficient for var.\n\\n\n\\n\n arg[4]\n\\n\nindex of the text to be printed after var\nif pos is not a positive value.\n\n\\param num_text\nis the total number of text characters on the tape\n(only used for error checking).\n\n\\param text\n\\b Input: <code>text[arg[1]]</code> is the first character of the text\nthat will be printed. All the characters from there to (but not including)\nthe first '\\\\0' are printed.\n\n\\param num_par\nis the total number of values in the parameter vector\n\n\\param parameter\nContains the value of parameters.\n\n\\param cap_order\nnumber of colums in the matrix containing all the Taylor coefficients.\n\n\\param taylor\nContains the value of variables.\n\n\\par Checked Assertions:\n\\li NumArg(PriOp)  == 5\n\\li NumRes(PriOp)  == 0\n\\li text          !=  nullptr\n\\li arg[1]         <  num_text\n\\li if pos is a parameter, arg[1] < num_par\n\\li if var is a parameter, arg[3] < num_par\n*/\ntemplate <class Base>\ninline void forward_pri_0(\n   std::ostream& s_out       ,\n   const addr_t* arg         ,\n   size_t        num_text    ,\n   const char*   text        ,\n   size_t        num_par     ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      )\n{  Base pos, var;\n   const char* before;\n   const char* after;\n   CPPAD_ASSERT_NARG_NRES(PriOp, 5, 0);\n\n   // pos\n   if( arg[0] & 1 )\n   {  pos = taylor[ size_t(arg[1]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );\n      pos = parameter[ arg[1] ];\n   }\n\n   // before\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_text );\n   before = text + arg[2];\n\n   // var\n   if( arg[0] & 2 )\n   {  var = taylor[ size_t(arg[3]) * cap_order + 0 ];\n   }\n   else\n   {  CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );\n      var = parameter[ arg[3] ];\n   }\n\n   // after\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_text );\n   after = text + arg[4];\n\n   if( ! GreaterThanZero( pos ) )\n      s_out << before << var << after;\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/prototype_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_PROTOTYPE_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_PROTOTYPE_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n/*!\n\\file prototype_op.hpp\nDocumentation for generic cases (these generic cases are never used).\n*/\n\n// ==================== Unary operators with one result ====================\n\n\n/*!\nPrototype for forward mode unary operator with one result (not used).\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param p\nlowest order of the Taylor coefficient that we are computing.\n\n\\param q\nhighest order of the Taylor coefficient that we are computing.\n\n\\param i_z\nvariable index corresponding to the result for this operation;\ni.e. the row index in taylor corresponding to z.\n\n\\param i_x\nvariable index corresponding to the argument for this operator;\ni.e. the row index in taylor corresponding to x.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n\\b Input: <code>taylor [ i_x * cap_order + k ]</code>,\nfor k = 0 , ... , q,\nis the k-th order Taylor coefficient corresponding to x.\n\\n\n\\b Input: <code>taylor [ i_z * cap_order + k ]</code>,\nfor k = 0 , ... , p-1,\nis the k-th order Taylor coefficient corresponding to z.\n\\n\n\\b Output: <code>taylor [ i_z * cap_order + k ]</code>,\nfor k = p , ... , q,\nis the k-th order Taylor coefficient corresponding to z.\n\n\\par Checked Assertions\n\\li NumArg(op) == 1\n\\li NumRes(op) == 1\n\\li q < cap_order\n\\li p <= q\n*/\ntemplate <class Base>\ninline void unary1_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n/*!\nPrototype for multiple direction forward mode unary operator with one result\n(not used).\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param q\norder of the Taylor coefficients that we are computing.\n\n\\param r\nnumber of directions for Taylor coefficients that we are computing.\n\n\\param i_z\nvariable index corresponding to the last (primary) result for this operation;\ni.e. the row index in taylor corresponding to z.\n\n\\param i_x\nvariable index corresponding to the argument for this operator;\ni.e. the row index in taylor corresponding to x.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\par tpv\nWe use the notation\n<code>tpv = (cap_order-1) * r + 1</code>\nwhich is the number of Taylor coefficients per variable\n\n\\param taylor\n\\b Input: If x is a variable,\n<code>taylor [ arg[0] * tpv + 0 ]</code>,\nis the zero order Taylor coefficient for all directions and\n<code>taylor [ arg[0] * tpv + (k-1)*r + ell + 1 ]</code>,\nfor k = 1 , ... , q,\nell = 0, ..., r-1,\nis the k-th order Taylor coefficient\ncorresponding to x and the ell-th direction.\n\\n\n\\b Input: <code>taylor [ i_z * tpv + 0 ]</code>,\nis the zero order Taylor coefficient for all directions and\n<code>taylor [ i_z * tpv + (k-1)*r + ell + 1 ]</code>,\nfor k = 1 , ... , q-1,\nell = 0, ..., r-1,\nis the k-th order Taylor coefficient\ncorresponding to z and the ell-th direction.\n\\n\n\\b Output:\n<code>taylor [ i_z * tpv + (q-1)*r + ell + 1]</code>,\nell = 0, ..., r-1,\nis the q-th order Taylor coefficient\ncorresponding to z and the ell-th direction.\n\n\\par Checked Assertions\n\\li NumArg(op) == 1\n\\li NumRes(op) == 2\n\\li i_x < i_z\n\\li 0 < q\n\\li q < cap_order\n*/\ntemplate <class Base>\ninline void unary1_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n/*!\nPrototype for zero order forward mode unary operator with one result (not used).\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base .\n\n\\param i_z\nvariable index corresponding to the result for this operation;\ni.e. the row index in taylor corresponding to z.\n\n\\param i_x\nvariable index corresponding to the argument for this operator;\ni.e. the row index in taylor corresponding to x.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n\\b Input: taylor [ i_x * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to x.\n\\n\n\\b Output: taylor [ i_z * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to z.\n\n\\par Checked Assertions\n\\li NumArg(op) == 1\n\\li NumRes(op) == 1\n\\li i_x < i_z\n\\li 0 < cap_order\n*/\ntemplate <class Base>\ninline void unary1_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n/*!\nPrototype for reverse mode unary operator with one result (not used).\n\nThis routine is given the partial derivatives of a function\nG(z , x , w, u ... )\nand it uses them to compute the partial derivatives of\n\\verbatim\n   H( x , w , u , ... ) = G[ z(x) , x , w , u , ... ]\n\\endverbatim\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base .\n\n\\param d\nhighest order Taylor coefficient that\nwe are computing the partial derivatives with respect to.\n\n\\param i_z\nvariable index corresponding to the result for this operation;\ni.e. the row index in taylor to z.\n\n\\param i_x\nvariable index corresponding to the argument for this operation;\ni.e. the row index in taylor corresponding to x.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n taylor [ i_x * cap_order + k ]\nfor k = 0 , ... , d\nis the k-th order Taylor coefficient corresponding to x.\n\\n\n taylor [ i_z * cap_order + k ]\nfor k = 0 , ... , d\nis the k-th order Taylor coefficient corresponding to z.\n\n\\param n_order\nnumber of columns in the matrix containing all the partial derivatives.\n\n\\param partial\n\\b Input: partial [ i_x * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of G( z , x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for x.\n\\n\n\\b Input: partial [ i_z * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of G( z , x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for z.\n\\n\n\\b Output: partial [ i_x * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of H( x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for x.\n\\n\n\\b Output: partial [ i_z * n_order + k ]\nfor k = 0 , ... , d\nmay be used as work space; i.e., may change in an unspecified manner.\n\n\n\\par Checked Assumptions\n\\li NumArg(op) == 1\n\\li NumRes(op) == 1\n\\li i_x < i_z\n\\li d < cap_order\n\\li d < n_order\n*/\ntemplate <class Base>\ninline void unary1_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n// ==================== Unary operators with two results ====================\n\n/*!\nPrototype for forward mode unary operator with two results (not used).\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param p\nlowest order of the Taylor coefficients that we are computing.\n\n\\param q\nhighest order of the Taylor coefficients that we are computing.\n\n\\param i_z\nvariable index corresponding to the last (primary) result for this operation;\ni.e. the row index in taylor corresponding to z.\nThe auxiliary result is called y has index i_z - 1.\n\n\\param i_x\nvariable index corresponding to the argument for this operator;\ni.e. the row index in taylor corresponding to x.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n\\b Input: <code>taylor [ i_x * cap_order + k ]</code>\nfor k = 0 , ... , q,\nis the k-th order Taylor coefficient corresponding to x.\n\\n\n\\b Input: <code>taylor [ i_z * cap_order + k ]</code>\nfor k = 0 , ... , p - 1,\nis the k-th order Taylor coefficient corresponding to z.\n\\n\n\\b Input: <code>taylor [ ( i_z - 1) * cap_order + k ]</code>\nfor k = 0 , ... , p-1,\nis the k-th order Taylor coefficient corresponding to the auxiliary result y.\n\\n\n\\b Output: <code>taylor [ i_z * cap_order + k ]</code>,\nfor k = p , ... , q,\nis the k-th order Taylor coefficient corresponding to z.\n\\n\n\\b Output: <code>taylor [ ( i_z - 1 ) * cap_order + k ]</code>,\nfor k = p , ... , q,\nis the k-th order Taylor coefficient corresponding to\nthe autillary result y.\n\n\\par Checked Assertions\n\\li NumArg(op) == 1\n\\li NumRes(op) == 2\n\\li i_x + 1 < i_z\n\\li q < cap_order\n\\li p <= q\n*/\ntemplate <class Base>\ninline void unary2_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n/*!\nPrototype for multiple direction forward mode unary operator with two results\n(not used).\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param q\norder of the Taylor coefficients that we are computing.\n\n\\param r\nnumber of directions for Taylor coefficients that we are computing.\n\n\\param i_z\nvariable index corresponding to the last (primary) result for this operation;\ni.e. the row index in taylor corresponding to z.\nThe auxiliary result is called y has index i_z - 1.\n\n\\param i_x\nvariable index corresponding to the argument for this operator;\ni.e. the row index in taylor corresponding to x.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\par tpv\nWe use the notation\n<code>tpv = (cap_order-1) * r + 1</code>\nwhich is the number of Taylor coefficients per variable\n\n\\param taylor\n\\b Input: <code>taylor [ i_x * tpv + 0 ]</code>\nis the zero order Taylor coefficient for all directions and\n<code>taylor [ i_x * tpv + (k-1)*r + ell + 1</code>\nfor k = 1 , ... , q,\nell = 0 , ..., r-1,\nis the k-th order Taylor coefficient\ncorresponding to x and the ell-th direction.\n\\n\n\\b Input: <code>taylor [ i_z * tpv + 0 ]</code>,\nis the zero order Taylor coefficient for all directions and\n<code>taylor [ i_z * tpv + (k-1)*r + ell + 1 ]</code>,\nfor k = 1 , ... , q-1,\nell = 0, ..., r-1,\nis the k-th order Taylor coefficient\ncorresponding to z and the ell-th direction.\n\\n\n\\b Input: <code>taylor [ (i_z-1) * tpv + 0 ]</code>,\nis the zero order Taylor coefficient for all directions and\n<code>taylor [ (i_z-1) * tpv + (k-1)*r + ell + 1 ]</code>,\nfor k = 1 , ... , q-1,\nell = 0, ..., r-1,\nis the k-th order Taylor coefficient\ncorresponding to the auxiliary result y and the ell-th direction.\n\\n\n\\b Output:\n<code>taylor [ i_z * tpv + (q-1)*r + ell + 1]</code>,\nell = 0, ..., r-1,\nis the q-th order Taylor coefficient\ncorresponding to z and the ell-th direction.\n\n\\par Checked Assertions\n\\li NumArg(op) == 1\n\\li NumRes(op) == 2\n\\li i_x + 1 < i_z\n\\li 0 < q\n\\li q < cap_order\n*/\ntemplate <class Base>\ninline void unary2_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n/*!\nPrototype for zero order forward mode unary operator with two results (not used).\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base .\n\n\\param i_z\nvariable index corresponding to the last (primary) result for this operation;\ni.e. the row index in taylor corresponding to z.\nThe auxiliary result is called y and has index i_z - 1.\n\n\\param i_x\nvariable index corresponding to the argument for this operator;\ni.e. the row index in taylor corresponding to x.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n\\b Input: taylor [ i_x * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to x.\n\\n\n\\b Output: taylor [ i_z * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to z.\n\\n\n\\b Output: taylor [ ( i_z - 1 ) * cap_order + j ]\nis the j-th order Taylor coefficient corresponding to\nthe autillary result y.\n\n\\par Checked Assertions\n\\li NumArg(op) == 1\n\\li NumRes(op) == 2\n\\li i_x + 1 < i_z\n\\li j < cap_order\n*/\ntemplate <class Base>\ninline void unary2_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n/*!\nPrototype for reverse mode unary operator with two results (not used).\n\nThis routine is given the partial derivatives of a function\nG( z , y , x , w , ... )\nand it uses them to compute the partial derivatives of\n\\verbatim\n   H( x , w , u , ... ) = G[ z(x) , y(x), x , w , u , ... ]\n\\endverbatim\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base .\n\n\\param d\nhighest order Taylor coefficient that\nwe are computing the partial derivatives with respect to.\n\n\\param i_z\nvariable index corresponding to the last (primary) result for this operation;\ni.e. the row index in taylor to z.\nThe auxiliary result is called y and has index i_z - 1.\n\n\\param i_x\nvariable index corresponding to the argument for this operation;\ni.e. the row index in taylor corresponding to x.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n taylor [ i_x * cap_order + k ]\nfor k = 0 , ... , d\nis the k-th order Taylor coefficient corresponding to x.\n\\n\n taylor [ i_z * cap_order + k ]\nfor k = 0 , ... , d\nis the k-th order Taylor coefficient corresponding to z.\n\\n\n taylor [ ( i_z - 1) * cap_order + k ]\nfor k = 0 , ... , d\nis the k-th order Taylor coefficient corresponding to\nthe auxiliary variable y.\n\n\\param n_order\nnumber of columns in the matrix containing all the partial derivatives.\n\n\\param partial\n\\b Input: partial [ i_x * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of\nG( z , y , x , w , u , ... )\nwith respect to the k-th order Taylor coefficient for x.\n\\n\n\\b Input: partial [ i_z * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of G( z , y , x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for z.\n\\n\n\\b Input: partial [ ( i_z - 1) * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of G( z , x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for the auxiliary variable y.\n\\n\n\\b Output: partial [ i_x * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of H( x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for x.\n\\n\n\\b Output: partial [ ( i_z - j ) * n_order + k ]\nfor j = 0 , 1 , and for k = 0 , ... , d\nmay be used as work space; i.e., may change in an unspecified manner.\n\n\n\\par Checked Assumptions\n\\li NumArg(op) == 1\n\\li NumRes(op) == 2\n\\li i_x + 1 < i_z\n\\li d < cap_order\n\\li d < n_order\n*/\ntemplate <class Base>\ninline void unary2_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n// =================== Binary operators with one result ====================\n\n/*!\nPrototype forward mode x op y (not used)\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param p\nlowest order of the Taylor coefficient that we are computing.\n\n\\param q\nhighest order of the Taylor coefficient that we are computing.\n\n\\param i_z\nvariable index corresponding to the result for this operation;\ni.e. the row index in taylor corresponding to z.\n\n\\param arg\n arg[0]\nindex corresponding to the left operand for this operator;\ni.e. the index corresponding to x.\n\\n\n arg[1]\nindex corresponding to the right operand for this operator;\ni.e. the index corresponding to y.\n\n\\param parameter\nIf x is a parameter, parameter [ arg[0] ]\nis the value corresponding to x.\n\\n\nIf y is a parameter, parameter [ arg[1] ]\nis the value corresponding to y.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n\\b Input: If x is a variable,\n<code>taylor [ size_t(arg[0]) * cap_order + k ]</code>,\nfor k = 0 , ... , q,\nis the k-th order Taylor coefficient corresponding to x.\n\\n\n\\b Input: If y is a variable,\n<code>taylor [ size_t(arg[1]) * cap_order + k ]</code>,\nfor k = 0 , ... , q,\nis the k-th order Taylor coefficient corresponding to y.\n\\n\n\\b Input: <code>taylor [ i_z * cap_order + k ]</code>,\nfor k = 0 , ... , p-1,\nis the k-th order Taylor coefficient corresponding to z.\n\\n\n\\b Output: <code>taylor [ i_z * cap_order + k ]</code>,\nfor k = p, ... , q,\nis the k-th order Taylor coefficient corresponding to z.\n\n\\par Checked Assertions\n\\li NumArg(op) == 2\n\\li NumRes(op) == 1\n\\li q <  cap_order\n\\li p <=  q\n*/\ntemplate <class Base>\ninline void binary_forward_any(\n   size_t        order_low  ,\n   size_t        order_up   ,\n   size_t        i_z        ,\n   const addr_t* arg        ,\n   const Base*   parameter  ,\n   size_t        cap_order  ,\n   Base*         taylor     )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n/*!\nPrototype multiple direction forward mode x op y (not used)\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param q\nis the order of the Taylor coefficients that we are computing.\n\n\\param r\nnumber of directions for Taylor coefficients that we are computing\n\n\\param i_z\nvariable index corresponding to the result for this operation;\ni.e. the row index in taylor corresponding to z.\n\n\\param arg\n arg[0]\nindex corresponding to the left operand for this operator;\ni.e. the index corresponding to x.\n\\n\n arg[1]\nindex corresponding to the right operand for this operator;\ni.e. the index corresponding to y.\n\n\\param parameter\nIf x is a parameter, parameter [ arg[0] ]\nis the value corresponding to x.\n\\n\nIf y is a parameter, parameter [ arg[1] ]\nis the value corresponding to y.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\par tpv\nWe use the notation\n<code>tpv = (cap_order-1) * r + 1</code>\nwhich is the number of Taylor coefficients per variable\n\n\\param taylor\n\\b Input: If x is a variable,\n<code>taylor [ arg[0] * tpv + 0 ]</code>,\nis the zero order Taylor coefficient for all directions and\n<code>taylor [ arg[0] * tpv + (k-1)*r + ell + 1 ]</code>,\nfor k = 1 , ... , q,\nell = 0, ..., r-1,\nis the k-th order Taylor coefficient\ncorresponding to x and the ell-th direction.\n\\n\n\\b Input: If y is a variable,\n<code>taylor [ arg[1] * tpv + 0 ]</code>,\nis the zero order Taylor coefficient for all directions and\n<code>taylor [ arg[1] * tpv + (k-1)*r + ell + 1 ]</code>,\nfor k = 1 , ... , q,\nell = 0, ..., r-1,\nis the k-th order Taylor coefficient\ncorresponding to y and the ell-th direction.\n\\n\n\\b Input: <code>taylor [ i_z * tpv + 0 ]</code>,\nis the zero order Taylor coefficient for all directions and\n<code>taylor [ i_z * tpv + (k-1)*r + ell + 1 ]</code>,\nfor k = 1 , ... , q-1,\nell = 0, ..., r-1,\nis the k-th order Taylor coefficient\ncorresponding to z and the ell-th direction.\n\\n\n\\b Output:\n<code>taylor [ i_z * tpv + (q-1)*r + ell + 1]</code>,\nell = 0, ..., r-1,\nis the q-th order Taylor coefficient\ncorresponding to z and the ell-th direction.\n\n\\par Checked Assertions\n\\li NumArg(op) == 2\n\\li NumRes(op) == 1\n\\li 0 < q <  cap_order\n*/\ntemplate <class Base>\ninline void binary_forward_dir(\n   size_t        order_up   ,\n   size_t        n_dir      ,\n   size_t        i_z        ,\n   const addr_t* arg        ,\n   const Base*   parameter  ,\n   size_t        cap_order  ,\n   Base*         taylor     )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n\n/*!\nPrototype zero order forward mode x op y (not used)\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param i_z\nvariable index corresponding to the result for this operation;\ni.e. the row index in taylor corresponding to z.\n\n\\param arg\n arg[0]\nindex corresponding to the left operand for this operator;\ni.e. the index corresponding to x.\n\\n\n arg[1]\nindex corresponding to the right operand for this operator;\ni.e. the index corresponding to y.\n\n\\param parameter\nIf x is a parameter, parameter [ arg[0] ]\nis the value corresponding to x.\n\\n\nIf y is a parameter, parameter [ arg[1] ]\nis the value corresponding to y.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n\\b Input: If x is a variable, taylor [ arg[0] * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to x.\n\\n\n\\b Input: If y is a variable, taylor [ arg[1] * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to y.\n\\n\n\\b Output: taylor [ i_z * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to z.\n\n\\par Checked Assertions\n\\li NumArg(op) == 2\n\\li NumRes(op) == 1\n*/\ntemplate <class Base>\ninline void binary_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n/*!\nPrototype for reverse mode binary operator x op y (not used).\n\nThis routine is given the partial derivatives of a function\nG( z , y , x , w , ... )\nand it uses them to compute the partial derivatives of\n\\verbatim\n   H( y , x , w , u , ... ) = G[ z(x , y) , y , x , w , u , ... ]\n\\endverbatim\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base .\n\n\\param d\nhighest order Taylor coefficient that\nwe are computing the partial derivatives with respect to.\n\n\\param i_z\nvariable index corresponding to the result for this operation;\ni.e. the row index in taylor corresponding to z.\n\n\\param arg\n arg[0]\nindex corresponding to the left operand for this operator;\ni.e. the index corresponding to x.\n\\n\n arg[1]\nindex corresponding to the right operand for this operator;\ni.e. the index corresponding to y.\n\n\\param parameter\nIf x is a parameter, parameter [ arg[0] ]\nis the value corresponding to x.\n\\n\nIf y is a parameter, parameter [ arg[1] ]\nis the value corresponding to y.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n taylor [ i_z * cap_order + k ]\nfor k = 0 , ... , d\nis the k-th order Taylor coefficient corresponding to z.\n\\n\nIf x is a variable, taylor [ arg[0] * cap_order + k ]\nfor k = 0 , ... , d\nis the k-th order Taylor coefficient corresponding to x.\n\\n\nIf y is a variable, taylor [ arg[1] * cap_order + k ]\nfor k = 0 , ... , d\nis the k-th order Taylor coefficient corresponding to y.\n\n\\param n_order\nnumber of columns in the matrix containing all the partial derivatives.\n\n\\param partial\n\\b Input: partial [ i_z * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of\nG( z , y , x , w , u , ... )\nwith respect to the k-th order Taylor coefficient for z.\n\\n\n\\b Input: If x is a variable, partial [ arg[0] * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of G( z , y , x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for x.\n\\n\n\\b Input: If y is a variable, partial [ arg[1] * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of G( z , x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for the auxiliary variable y.\n\\n\n\\b Output: If x is a variable, partial [ arg[0] * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of H( y , x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for x.\n\\n\n\\b Output: If y is a variable, partial [ arg[1] * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of H( y , x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for y.\n\\n\n\\b Output: partial [ i_z * n_order + k ]\nfor k = 0 , ... , d\nmay be used as work space; i.e., may change in an unspecified manner.\n\n\\par Checked Assumptions\n\\li NumArg(op) == 2\n\\li NumRes(op) == 1\n\\li If x is a variable, arg[0] < i_z\n\\li If y is a variable, arg[1] < i_z\n\\li d < cap_order\n\\li d < n_order\n*/\ntemplate <class Base>\ninline void binary_reverse(\n   size_t      i_z          ,\n   addr_t*     arg          ,\n   const Base* parameter    ,\n   size_t      cap_order    ,\n   const Base* taylor       ,\n   size_t      n_order      ,\n   Base*       partial      )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n// ======================= Pow Function ===================================\n/*!\nPrototype for forward mode z = pow(x, y) (not used).\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param p\nlowest order of the Taylor coefficient that we are computing.\n\n\\param q\nhighest order of the Taylor coefficient that we are computing.\n\n\\param i_z\nvariable index corresponding to the last (primary) result for this operation;\ni.e. the row index in taylor corresponding to z.\nNote that there are three results for this operation,\nbelow they are referred to as z_0, z_1, z_2 and correspond to\n\\verbatim\n   z_0 = log(x)\n   z_1 = z0 * y\n   z_2 = exp(z1)\n\\endverbatim\nIt follows that the final result is equal to z; i.e., z = z_2 = pow(x, y).\n\n\\param arg\n arg[0]\nindex corresponding to the left operand for this operator;\ni.e. the index corresponding to x.\n\\n\n arg[1]\nindex corresponding to the right operand for this operator;\ni.e. the index corresponding to y.\n\n\\param parameter\nIf x is a parameter, parameter [ arg[0] ]\nis the value corresponding to x.\n\\n\nIf y is a parameter, parameter [ arg[1] ]\nis the value corresponding to y.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n\\b Input: If x is a variable,\n<code>taylor [ size_t(arg[0]) * cap_order + k ]</code>\nfor k = 0 , ... , q,\nis the k-th order Taylor coefficient corresponding to x.\n\\n\n\\b Input: If y is a variable,\n<code>taylor [ size_t(arg[1]) * cap_order + k ]</code>\nfor k = 0 , ... , q\nis the k-th order Taylor coefficient corresponding to y.\n\\n\n\\b Input: <code>taylor [ (i_z-2+j) * cap_order + k ]</code>,\nfor j = 0, 1, 2 , for k = 0 , ... , p-1,\nis the k-th order Taylor coefficient corresponding to z_j.\n\\n\n\\b Output: <code>taylor [ (i_z-2+j) * cap_order + k ]</code>,\nis the k-th order Taylor coefficient corresponding to z_j.\n\n\\par Checked Assertions\n\\li NumArg(op) == 2\n\\li NumRes(op) == 3\n\\li If x is a variable, arg[0] < i_z - 2\n\\li If y is a variable, arg[1] < i_z - 2\n\\li q < cap_order\n\\li p <= q\n*/\ntemplate <class Base>\ninline void pow_forward_any(\n   size_t        order_low  ,\n   size_t        order_up   ,\n   size_t        i_z        ,\n   const addr_t* arg        ,\n   const Base*   parameter  ,\n   size_t        cap_order  ,\n   Base*         taylor     )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n/*!\nPrototype for multiple direction forward mode z = pow(x, y) (not used).\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param q\norder of the Taylor coefficient that we are computing.\n\n\\param r\nis the number of Taylor coefficient directions that we are computing\n\n\\param i_z\nvariable index corresponding to the last (primary) result for this operation;\ni.e. the row index in taylor corresponding to z.\nNote that there are three results for this operation,\nbelow they are referred to as z_0, z_1, z_2 and correspond to\n\\verbatim\n   z_0 = log(x)\n   z_1 = z0 * y\n   z_2 = exp(z1)\n\\endverbatim\nIt follows that the final result is equal to z; i.e., z = z_2 = pow(x, y).\n\n\\param arg\n arg[0]\nindex corresponding to the left operand for this operator;\ni.e. the index corresponding to x.\n\\n\n arg[1]\nindex corresponding to the right operand for this operator;\ni.e. the index corresponding to y.\n\n\\param parameter\nIf x is a parameter, parameter [ arg[0] ]\nis the value corresponding to x.\n\\n\nIf y is a parameter, parameter [ arg[1] ]\nis the value corresponding to y.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\par tpv\nWe use the notation\n<code>tpv = (cap_order-1) * r + 1</code>\nwhich is the number of Taylor coefficients per variable\n\n\\param taylor\n\\b Input: If x is a variable,\n<code>taylor [ arg[0] * tpv + 0 ]</code>\nis the zero order coefficient corresponding to x and\n<code>taylor [ arg[0] * tpv + (k-1)*r+1+ell ]</code>\nfor k = 1 , ... , q,\nell = 0 , ... , r-1,\nis the k-th order Taylor coefficient corresponding to x\nfor the ell-th direction.\n\\n\n\\n\n\\b Input: If y is a variable,\n<code>taylor [ arg[1] * tpv + 0 ]</code>\nis the zero order coefficient corresponding to y and\n<code>taylor [ arg[1] * tpv + (k-1)*r+1+ell ]</code>\nfor k = 1 , ... , q,\nell = 0 , ... , r-1,\nis the k-th order Taylor coefficient corresponding to y\nfor the ell-th direction.\n\\n\n\\n\n\\b Input:\n<code>taylor [ (i_z-2+j) * tpv + 0 ]</code>,\nis the zero order coefficient corresponding to z_j and\n<code>taylor [ (i_z-2+j) * tpv + (k-1)*r+1+ell ]</code>,\nfor j = 0, 1, 2 , k = 0 , ... , q-1, ell = 0, ... , r-1,\nis the k-th order Taylor coefficient corresponding to z_j\nfor the ell-th direction.\n\\n\n\\n\n\\b Output:\n<code>taylor [ (i_z-2+j) * tpv + (q-1)*r+1+ell ]</code>,\nfor j = 0, 1, 2 , ell = 0, ... , r-1,\nis the q-th order Taylor coefficient corresponding to z_j\nfor the ell-th direction.\n\n\\par Checked Assertions\n\\li NumArg(op) == 2\n\\li NumRes(op) == 3\n\\li If x is a variable, arg[0] < i_z - 2\n\\li If y is a variable, arg[1] < i_z - 2\n\\li 0 < q\n\\li q < cap_order\n*/\ntemplate <class Base>\ninline void pow_forward_dir(\n   size_t        order_up   ,\n   size_t        n_dir      ,\n   size_t        i_z        ,\n   const addr_t* arg        ,\n   const Base*   parameter  ,\n   size_t        cap_order  ,\n   Base*         taylor     )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n/*!\nPrototype for zero order forward mode z = pow(x, y) (not used).\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base.\n\n\\param i_z\nvariable index corresponding to the last (primary) result for this operation;\ni.e. the row index in taylor corresponding to z.\nNote that there are three results for this operation,\nbelow they are referred to as z_0, z_1, z_2 and correspond to\n\\verbatim\n   z_0 = log(x)\n   z_1 = z0 * y\n   z_2 = exp(z1)\n\\endverbatim\nIt follows that the final result is equal to z; i.e., z = z_2 = pow(x, y).\n\n\\param arg\n arg[0]\nindex corresponding to the left operand for this operator;\ni.e. the index corresponding to x.\n\\n\n arg[1]\nindex corresponding to the right operand for this operator;\ni.e. the index corresponding to y.\n\n\\param parameter\nIf x is a parameter, parameter [ arg[0] ]\nis the value corresponding to x.\n\\n\nIf y is a parameter, parameter [ arg[1] ]\nis the value corresponding to y.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n\\b Input: If x is a variable, taylor [ arg[0] * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to x.\n\\n\n\\b Input: If y is a variable, taylor [ arg[1] * cap_order + 0 ]\nis the k-th order Taylor coefficient corresponding to y.\n\\n\n\\b Output: taylor [ (i_z - 2 + j) * cap_order + 0 ]\nis the zero order Taylor coefficient corresponding to z_j.\n\n\\par Checked Assertions\n\\li NumArg(op) == 2\n\\li NumRes(op) == 3\n\\li If x is a variable, arg[0] < i_z - 2\n\\li If y is a variable, arg[1] < i_z - 2\n*/\ntemplate <class Base>\ninline void pow_forward_0(\n   size_t        i_z        ,\n   const addr_t* arg        ,\n   const Base*   parameter  ,\n   size_t        cap_order  ,\n   Base*         taylor     )\n{  //\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n/*!\nPrototype for reverse mode z = pow(x, y) (not used).\n\nThis routine is given the partial derivatives of a function\nG( z , y , x , w , ... )\nand it uses them to compute the partial derivatives of\n\\verbatim\n   H( y , x , w , u , ... ) = G[ pow(x , y) , y , x , w , u , ... ]\n\\endverbatim\n\n\\tparam Base\nbase type for the operator; i.e., this operation was recorded\nusing AD< Base > and computations by this routine are done using type\n Base .\n\n\\param d\nhighest order Taylor coefficient that\nwe are computing the partial derivatives with respect to.\n\n\\param i_z\nvariable index corresponding to the last (primary) result for this operation;\ni.e. the row index in taylor corresponding to z.\nNote that there are three results for this operation,\nbelow they are referred to as z_0, z_1, z_2 and correspond to\n\\verbatim\n   z_0 = log(x)\n   z_1 = z0 * y\n   z_2 = exp(z1)\n\\endverbatim\nIt follows that the final result is equal to z; i.e., z = z_2 = pow(x, y).\n\n\\param arg\n arg[0]\nindex corresponding to the left operand for this operator;\ni.e. the index corresponding to x.\n\\n\n arg[1]\nindex corresponding to the right operand for this operator;\ni.e. the index corresponding to y.\n\n\\param parameter\nIf x is a parameter, parameter [ arg[0] ]\nis the value corresponding to x.\n\\n\nIf y is a parameter, parameter [ arg[1] ]\nis the value corresponding to y.\n\n\\param cap_order\nmaximum number of orders that will fit in the taylor array.\n\n\\param taylor\n taylor [ (i_z - 2 + j) * cap_order + k ]\nfor j = 0, 1, 2 and k = 0 , ... , d\nis the k-th order Taylor coefficient corresponding to z_j.\n\\n\nIf x is a variable, taylor [ arg[0] * cap_order + k ]\nfor k = 0 , ... , d\nis the k-th order Taylor coefficient corresponding to x.\n\\n\nIf y is a variable, taylor [ arg[1] * cap_order + k ]\nfor k = 0 , ... , d\nis the k-th order Taylor coefficient corresponding to y.\n\n\\param n_order\nnumber of columns in the matrix containing all the partial derivatives.\n\n\\param partial\n\\b Input: partial [ (i_z - 2 + j) * n_order + k ]\nfor j = 0, 1, 2, and k = 0 , ... , d\nis the partial derivative of\nG( z , y , x , w , u , ... )\nwith respect to the k-th order Taylor coefficient for z_j.\n\\n\n\\b Input: If x is a variable, partial [ arg[0] * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of G( z , y , x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for x.\n\\n\n\\b Input: If y is a variable, partial [ arg[1] * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of G( z , x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for the auxiliary variable y.\n\\n\n\\b Output: If x is a variable, partial [ arg[0] * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of H( y , x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for x.\n\\n\n\\b Output: If y is a variable, partial [ arg[1] * n_order + k ]\nfor k = 0 , ... , d\nis the partial derivative of H( y , x , w , u , ... ) with respect to\nthe k-th order Taylor coefficient for y.\n\\n\n\\b Output: partial [ ( i_z - j ) * n_order + k ]\nfor j = 0 , 1 , 2 and for k = 0 , ... , d\nmay be used as work space; i.e., may change in an unspecified manner.\n\n\\par Checked Assumptions\n\\li NumArg(op) == 2\n\\li NumRes(op) == 3\n\\li If x is a variable, arg[0] < i_z - 2\n\\li If y is a variable, arg[1] < i_z - 2\n\\li d < cap_order\n\\li d < n_order\n*/\ntemplate <class Base>\ninline void pow_reverse(\n   size_t      i_z          ,\n   addr_t*     arg          ,\n   const Base* parameter    ,\n   size_t      cap_order    ,\n   const Base* taylor       ,\n   size_t      n_order      ,\n   Base*       partial      )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n// ==================== Sparsity Calculations ==============================\n/*!\nPrototype for reverse mode Hessian sparsity unary operators.\n\nThis routine is given the forward mode Jacobian sparsity patterns for x.\nIt is also given the reverse mode dependence of G on z.\nIn addition, it is given the reverse mode Hessian sparsity\nfor the quantity of interest G(z , y , ... )\nand it uses them to compute the sparsity patterns for\n\\verbatim\n   H( x , w , u , ... ) = G[ z(x) , x , w , u , ... ]\n\\endverbatim\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\\param i_z\nvariable index corresponding to the result for this operation;\ni.e. the row index in sparsity corresponding to z.\n\n\\param i_x\nvariable index corresponding to the argument for this operator;\ni.e. the row index in sparsity corresponding to x.\n\n\\param rev_jacobian\n rev_jacobian[i_z]\nis all false (true) if the Jacobian of G with respect to z must be zero\n(may be non-zero).\n\\n\n\\n\n rev_jacobian[i_x]\nis all false (true) if the Jacobian with respect to x must be zero\n(may be non-zero).\nOn input, it corresponds to the function G,\nand on output it corresponds to the function H.\n\n\\param for_jac_sparsity\nThe set with index i_x in for_jac_sparsity\nis the forward mode Jacobian sparsity pattern for the variable x.\n\n\\param rev_hes_sparsity\nThe set with index i_z in in rev_hes_sparsity\nis the Hessian sparsity pattern for the function G\nwhere one of the partials derivative is with respect to z.\n\\n\n\\n\nThe set with index i_x in rev_hes_sparsity\nis the Hessian sparsity pattern\nwhere one of the partials derivative is with respect to x.\nOn input, it corresponds to the function G,\nand on output it corresponds to the function H.\n\n\\par Checked Assertions:\n\\li i_x < i_z\n*/\n\ntemplate <class Vector_set>\ninline void reverse_sparse_hessian_unary_op(\n   size_t              i_z               ,\n   size_t              i_x               ,\n   bool*               rev_jacobian      ,\n   Vector_set&         for_jac_sparsity  ,\n   Vector_set&         rev_hes_sparsity  )\n{  //\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n/*!\nPrototype for reverse mode Hessian sparsity binary operators.\n\nThis routine is given the sparsity patterns the Hessian\nof a function G(z, y, x, ... )\nand it uses them to compute the sparsity patterns for the Hessian of\n\\verbatim\n   H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ]\n\\endverbatim\n\n\\tparam Vector_set\nis the type used for vectors of sets. It can be either\nsparse::pack_setvec or sparse::list_setvec.\n\n\\param i_z\nvariable index corresponding to the result for this operation;\ni.e. the row index in sparsity corresponding to z.\n\n\\param arg\n arg[0]\nvariable index corresponding to the left operand for this operator;\ni.e. the set with index arg[0] in var_sparsity\nis the spasity pattern corresponding to x.\n\\n\n\\n arg[1]\nvariable index corresponding to the right operand for this operator;\ni.e. the row index in sparsity patterns corresponding to y.\n\n\\param jac_reverse\n jac_reverse[i_z]\nis false (true) if the Jacobian of G with respect to z is always zero\n(may be non-zero).\n\\n\n\\n\n jac_reverse[ arg[0] ]\nis false (true) if the Jacobian with respect to x is always zero\n(may be non-zero).\nOn input, it corresponds to the function G,\nand on output it corresponds to the function H.\n\\n\n\\n\n jac_reverse[ arg[1] ]\nis false (true) if the Jacobian with respect to y is always zero\n(may be non-zero).\nOn input, it corresponds to the function G,\nand on output it corresponds to the function H.\n\n\\param for_jac_sparsity\nThe set with index arg[0] in for_jac_sparsity for the\nis the forward Jacobian sparsity pattern for x.\n\\n\n\\n\nThe set with index arg[1] in for_jac_sparsity\nis the forward sparsity pattern for y.\n\n\\param rev_hes_sparsity\nThe set with index i_x in rev_hes_sparsity\nis the Hessian sparsity pattern for the function G\nwhere one of the partial derivatives is with respect to z.\n\\n\n\\n\nThe set with index arg[0] in  rev_hes_sparsity\nis the Hessian sparsity pattern where one of the\npartial derivatives is with respect to x.\nOn input, it corresponds to the function G,\nand on output it correspondst to H.\n\\n\n\\n\nThe set with index arg[1] in rev_hes_sparsity\nis the Hessian sparsity pattern where one of the\npartial derivatives is with respect to y.\nOn input, it corresponds to the function G,\nand on output it correspondst to H.\n\n\\par Checked Assertions:\n\\li arg[0] < i_z\n\\li arg[1] < i_z\n*/\ntemplate <class Vector_set>\ninline void reverse_sparse_hessian_binary_op(\n   size_t            i_z                ,\n   const addr_t*     arg                ,\n   bool*             jac_reverse        ,\n   Vector_set&       for_jac_sparsity   ,\n   Vector_set&       rev_hes_sparsity   )\n{  //\n   //\n   // This routine is only for documentation, it should not be used\n   CPPAD_ASSERT_UNKNOWN( false );\n}\n\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/sign_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_SIGN_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_SIGN_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void sign_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SignOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SignOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   if( p == 0 )\n   {  z[0] = sign(x[0]);\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n      z[j] = Base(0.);\n}\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void sign_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SignOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SignOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   size_t m = (q - 1) * r + 1;\n   Base* z = taylor + i_z * num_taylor_per_var;\n\n   for(size_t ell = 0; ell < r; ell++)\n      z[m+ell] = Base(0.);\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void sign_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SignOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SignOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base x0 = *(taylor + i_x * cap_order);\n   Base* z = taylor + i_z * cap_order;\n\n   z[0] = sign(x0);\n}\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void sign_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SignOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SignOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // nothing to do because partials of sign are zero\n   return;\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/sin_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_SIN_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_SIN_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void sin_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SinOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SinOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* s = taylor + i_z * cap_order;\n   Base* c = s      -       cap_order;\n\n   // rest of this routine is identical for the following cases:\n   // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op.\n   // (except that there is a sign difference for the hyperbolic case).\n   size_t k;\n   if( p == 0 )\n   {  s[0] = sin( x[0] );\n      c[0] = cos( x[0] );\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {\n      s[j] = Base(0.0);\n      c[j] = Base(0.0);\n      for(k = 1; k <= j; k++)\n      {  s[j] += Base(double(k)) * x[k] * c[j-k];\n         c[j] -= Base(double(k)) * x[k] * s[j-k];\n      }\n      s[j] /= Base(double(j));\n      c[j] /= Base(double(j));\n   }\n}\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void sin_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SinOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SinOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* s = taylor + i_z * num_taylor_per_var;\n   Base* c = s      -       num_taylor_per_var;\n\n\n   // rest of this routine is identical for the following cases:\n   // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op\n   // (except that there is a sign difference for the hyperbolic case).\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  s[m+ell] =   Base(double(q)) * x[m + ell] * c[0];\n      c[m+ell] = - Base(double(q)) * x[m + ell] * s[0];\n      for(size_t k = 1; k < q; k++)\n      {  s[m+ell] += Base(double(k)) * x[(k-1)*r+1+ell] * c[(q-k-1)*r+1+ell];\n         c[m+ell] -= Base(double(k)) * x[(k-1)*r+1+ell] * s[(q-k-1)*r+1+ell];\n      }\n      s[m+ell] /= Base(double(q));\n      c[m+ell] /= Base(double(q));\n   }\n}\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void sin_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SinOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SinOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* s = taylor + i_z * cap_order;  // called z in documentation\n   Base* c = s      -       cap_order;  // called y in documentation\n\n   s[0] = sin( x[0] );\n   c[0] = cos( x[0] );\n}\n\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void sin_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SinOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SinOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to first result\n   const Base* s  = taylor  + i_z * cap_order; // called z in doc\n   Base* ps       = partial + i_z * n_order;\n\n   // Taylor coefficients and partials corresponding to auxiliary result\n   const Base* c  = s  - cap_order; // called y in documentation\n   Base* pc       = ps - n_order;\n\n\n   // rest of this routine is identical for the following cases:\n   // reverse_sin_op, reverse_cos_op, reverse_sinh_op, reverse_cosh_op.\n   size_t j = d;\n   size_t k;\n   while(j)\n   {\n      ps[j]   /= Base(double(j));\n      pc[j]   /= Base(double(j));\n      for(k = 1; k <= j; k++)\n      {\n         px[k]   += Base(double(k)) * azmul(ps[j], c[j-k]);\n         px[k]   -= Base(double(k)) * azmul(pc[j], s[j-k]);\n\n         ps[j-k] -= Base(double(k)) * azmul(pc[j], x[k]);\n         pc[j-k] += Base(double(k)) * azmul(ps[j], x[k]);\n\n      }\n      --j;\n   }\n   px[0] += azmul(ps[0], c[0]);\n   px[0] -= azmul(pc[0], s[0]);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/sinh_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_SINH_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_SINH_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void sinh_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SinhOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* s = taylor + i_z * cap_order;\n   Base* c = s      -       cap_order;\n\n\n   // rest of this routine is identical for the following cases:\n   // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op\n   // (except that there is a sign difference for hyperbolic case).\n   size_t k;\n   if( p == 0 )\n   {  s[0] = sinh( x[0] );\n      c[0] = cosh( x[0] );\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {\n      s[j] = Base(0.0);\n      c[j] = Base(0.0);\n      for(k = 1; k <= j; k++)\n      {  s[j] += Base(double(k)) * x[k] * c[j-k];\n         c[j] += Base(double(k)) * x[k] * s[j-k];\n      }\n      s[j] /= Base(double(j));\n      c[j] /= Base(double(j));\n   }\n}\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void sinh_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SinhOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* s = taylor + i_z * num_taylor_per_var;\n   Base* c = s      -       num_taylor_per_var;\n\n\n   // rest of this routine is identical for the following cases:\n   // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op\n   // (except that there is a sign difference for the hyperbolic case).\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  s[m+ell] = Base(double(q)) * x[m + ell] * c[0];\n      c[m+ell] = Base(double(q)) * x[m + ell] * s[0];\n      for(size_t k = 1; k < q; k++)\n      {  s[m+ell] += Base(double(k)) * x[(k-1)*r+1+ell] * c[(q-k-1)*r+1+ell];\n         c[m+ell] += Base(double(k)) * x[(k-1)*r+1+ell] * s[(q-k-1)*r+1+ell];\n      }\n      s[m+ell] /= Base(double(q));\n      c[m+ell] /= Base(double(q));\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void sinh_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SinhOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* s = taylor + i_z * cap_order;  // called z in documentation\n   Base* c = s      -       cap_order;  // called y in documentation\n\n   s[0] = sinh( x[0] );\n   c[0] = cosh( x[0] );\n}\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void sinh_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SinhOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to first result\n   const Base* s  = taylor  + i_z * cap_order; // called z in doc\n   Base* ps       = partial + i_z * n_order;\n\n   // Taylor coefficients and partials corresponding to auxiliary result\n   const Base* c  = s  - cap_order; // called y in documentation\n   Base* pc       = ps - n_order;\n\n\n   // rest of this routine is identical for the following cases:\n   // reverse_sin_op, reverse_cos_op, reverse_sinh_op, reverse_cosh_op.\n   size_t j = d;\n   size_t k;\n   while(j)\n   {\n      ps[j]   /= Base(double(j));\n      pc[j]   /= Base(double(j));\n      for(k = 1; k <= j; k++)\n      {\n         px[k]   += Base(double(k)) * azmul(ps[j], c[j-k]);\n         px[k]   += Base(double(k)) * azmul(pc[j], s[j-k]);\n\n         ps[j-k] += Base(double(k)) * azmul(pc[j], x[k]);\n         pc[j-k] += Base(double(k)) * azmul(ps[j], x[k]);\n\n      }\n      --j;\n   }\n   px[0] += azmul(ps[0], c[0]);\n   px[0] += azmul(pc[0], s[0]);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/sqrt_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_SQRT_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_SQRT_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void sqrt_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SqrtOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SqrtOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   size_t k;\n   if( p == 0 )\n   {  z[0] = sqrt( x[0] );\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {\n      z[j] = Base(0.0);\n      for(k = 1; k < j; k++)\n         z[j] -= Base(double(k)) * z[k] * z[j-k];\n      z[j] /= Base(double(j));\n      z[j] += x[j] / Base(2.0);\n      z[j] /= z[0];\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void sqrt_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SqrtOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SqrtOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* z = taylor + i_z * num_taylor_per_var;\n   Base* x = taylor + i_x * num_taylor_per_var;\n\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  z[m+ell] = Base(0.0);\n      for(size_t k = 1; k < q; k++)\n         z[m+ell] -= Base(double(k)) * z[(k-1)*r+1+ell] * z[(q-k-1)*r+1+ell];\n      z[m+ell] /= Base(double(q));\n      z[m+ell] += x[m+ell] / Base(2.0);\n      z[m+ell] /= z[0];\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void sqrt_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SqrtOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SqrtOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n\n   z[0] = sqrt( x[0] );\n}\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void sqrt_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SqrtOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SqrtOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to result\n   const Base* z  = taylor  + i_z * cap_order;\n   Base* pz       = partial + i_z * n_order;\n\n\n   Base inv_z0 = Base(1.0) / z[0];\n\n   // number of indices to access\n   size_t j = d;\n   size_t k;\n   while(j)\n   {\n\n      // scale partial w.r.t. z[j]\n      pz[j]    = azmul(pz[j], inv_z0);\n\n      pz[0]   -= azmul(pz[j], z[j]);\n      px[j]   += pz[j] / Base(2.0);\n      for(k = 1; k < j; k++)\n         pz[k]   -= azmul(pz[j], z[j-k]);\n      --j;\n   }\n   px[0] += azmul(pz[0], inv_z0) / Base(2.0);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/store_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_STORE_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_STORE_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n/*\n{xrst_begin_parent var_store_op dev}\n{xrst_spell\n   stpp\n   stpv\n   stvp\n   stvv\n}\n\nStore an Element of a Variable VecAD Vector\n###########################################\n\nStppOp, StpvOp, StvpOp, StvvOp\n******************************\nare the op codes for these operators.\n\nUser Syntax\n***********\n| *v* [ *x* ] = *y*\n\nv\n*\nis the :ref:`VecAD-name` vector for this store operation.\nThis vector is a variable after the store.\nif this is a StppOp operation, *v* is a variable before the store.\n\nx\n*\nis the index for this store.\n\ny\n*\nis the value being stored.\n\nRecBase\n*******\nis the base type use when recording this operator;\ni.e., this operation was recording using AD< *RecBase* > operations.\n\nBase\n****\nis the type used for computations by this operator.\nThis is either *RecBase* or AD< *RecBase* >.\n\nop_code\n*******\n\n.. csv-table::\n   :widths: auto\n   :header-rows: 1\n\n   op_code, x, y\n   StppOp, parameter, parameter\n   StpvOp, parameter, variable\n   StvpOp, variable,  parameter\n   StvvOp, variable,  variable\n\nnum_vecad_ind\n*************\nis the size of the single array that includes\nall the VecAD vectors together with the size of each vector.\n\narg\n***\n\narg[0]\n======\nthis argument is the offset of the vector *v*\nrelative to the beginning of the single array\nthat contains all VecAD elements and sizes.\nThis offset corresponds to the first element of *v* and not its size\nwhich comes just before the first element.\n\narg[1]\n======\nIf *x* is a parameter (variable), arg[1] is the parameter index\n(variable index) to *x* .\n\narg[2]\n======\nIf *y* is a parameter (variable), arg[2] is the parameter index\n(variable index) to *y* .\n\n{xrst_end var_store_op}\n------------------------------------------------------------------------------\n{xrst_begin var_store_forward_0 dev}\n{xrst_spell\n   isvar\n}\n\nZero Order Forward Store an Element of a VecAD Vector\n#####################################################\n\nv, x, y\n*******\nsee\n:ref:`var_store_op@v` ,\n:ref:`var_store_op@x` ,\n:ref:`var_store_op@y`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_STORE_FORWARD_0\n   // END_STORE_FORWARD_0\n}\n\nBase, op_code, num_vecad_ind, arg\n*********************************\nsee\n:ref:`var_store_op@Base` ,\n:ref:`var_store_op@op_code` ,\n:ref:`var_store_op@num_vecad_ind` ,\n:ref:`var_store_op@arg` .\n\nnum_var\n*******\nis the number of variables in this recording.\n\nnum_par\n*******\nis the number of parameters in this recording.\n\nparameter\n*********\nThis is the vector of parameters for this recording which has size *num_par* .\n\ncap_order\n*********\nis the maximum number of orders that can fit in *taylor* .\n\ntaylor\n******\nIs the matrix of Taylor coefficients for all the variables.\n\ni_vec\n*****\nWe use *i_vec* to denote the ``size_t`` value corresponding to\n:ref:`var_store_op@x` .\nIf *x* is a parameter (variable) this is a parameter (variable) index.\n\nvec_ad2isvar\n************\nThis vector has size :ref:`var_store_op@num_vecad_ind` .\nThe input values of its elements does not matter.\nIf the value being stored is a parameter (variable),\n*vec_ad2isvar* [ *arg* [0] + *i_vec*  ] is set to false (true).\n\nvec_ad2index\n************\nThis vector has size *num_vecad_ind* .\nThe input value of its elements does not matter.\nIf the value being stored is a parameter (variable),\n*vec_ad2index* [ *arg* [0] + *i_vec*  ]\nis set to the parameter (variable) index\ncorresponding to the value being stored.\n\n{xrst_end var_store_forward_0}\n*/\n// BEGIN_STORE_FORWARD_0\ntemplate <class Base>\ninline void store_forward_0(\n   op_code_var          op_code        ,\n   const addr_t*        arg            ,\n   size_t               num_var        ,\n   size_t               num_par        ,\n   const Base*          parameter      ,\n   size_t               cap_order      ,\n   const Base*          taylor         ,\n   pod_vector<bool>&    vec_ad2isvar   ,\n   pod_vector<size_t>&  vec_ad2index   )\n// END_STORE_FORWARD_0\n{  //\n   //\n   CPPAD_ASSERT_NARG_NRES(op_code, 3, 0);\n   CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );\n   CPPAD_ASSERT_UNKNOWN( vec_ad2isvar.size() == vec_ad2index.size() )\n   //\n   // i_y\n   size_t i_y = size_t( arg[2] );\n   //\n   // i_vec, isvar\n   // assign here to avoid compiler warning for default case\n   addr_t i_vec = std::numeric_limits<addr_t>::max();\n   bool   isvar = false;\n   switch(op_code)\n   {  //\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n      break;\n      //\n      case StppOp:\n      i_vec = addr_t( Integer( parameter[ arg[1] ] ) );\n      isvar = false;\n      CPPAD_ASSERT_UNKNOWN( i_y < num_par );\n      break;\n      //\n      case StpvOp:\n      i_vec = addr_t( Integer( parameter[ arg[1] ] ) );\n      isvar = true;\n      CPPAD_ASSERT_UNKNOWN( i_y < num_var );\n      break;\n      //\n      case StvpOp:\n      i_vec = addr_t(Integer( taylor[ size_t(arg[1]) * cap_order + 0 ] ));\n      isvar = false;\n      CPPAD_ASSERT_UNKNOWN( i_y < num_par );\n      break;\n      //\n      case StvvOp:\n      i_vec = addr_t(Integer( taylor[ size_t(arg[1]) * cap_order + 0 ] ));\n      isvar = true;\n      CPPAD_ASSERT_UNKNOWN( i_y < num_var );\n      break;\n   }\n   //\n   CPPAD_ASSERT_KNOWN(\n      size_t(i_vec) < vec_ad2index[ arg[0] - 1 ] ,\n      \"VecAD: zero order forward index out of range\"\n   );\n   //\n   // vec_ad2isvar, vec_ad2index\n   vec_ad2isvar[ arg[0] + i_vec ]  = isvar;\n   vec_ad2index[ arg[0] + i_vec ]  = i_y;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_store_for_jac dev}\n\nForward Jacobian Sparsity for Store a VecAD Element\n###################################################\n\nv, x, y\n*******\nsee\n:ref:`var_store_op@v` ,\n:ref:`var_store_op@x` ,\n:ref:`var_store_op@y`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_STORE_FOR_JAC\n   // END_STORE_FOR_JAC\n}\n\nop_code, num_vecad_ind, arg\n***************************\nsee :ref:`var_store_op@op_code` ,\n:ref:`var_store_op@num_vecad_ind` ,\n:ref:`var_store_op@arg` .\n\nVector_set\n**********\nis the type used for vectors of sets. It must satisfy the\n:ref:`SetVector-name` concept.\n\ndependency\n**********\nIf true (false) we are including (are not including)\ndependencies that have derivative zero in the sparsity pattern.\nFor example, the :ref:`Discrete-name` functions have derivative zero,\nbut the value depends on its argument.\n\nvecad_ind\n*********\nis a vector with size *num_vec_ind* .\nWe use the notation *i_v* defined by\n\n|tab| *i_v* = vecad_ind[ arg[0] - 1 ]\n\nThis is the index of the VecAD vector and is less than the number of\nVecAD vectors in the recording.\n\nvar_sparsity\n************\nIf :ref:`var_store_op@y` is a variable,\nthe sets with index arg[2] in *var_sparsity* is the sparsity pattern for *y* .\nOtherwise, *y* is a parameter and its sparsity pattern for *y* is empty\n\n\nvecad_sparsity\n**************\nThe set with index *i_v* in *vecad_sparsity\nis the sparsity pattern for the vector *v*.\nThe sparsity pattern for *y* is added\nto the sparsity pattern for *v* .\nIf *dependency* is true and *x* is a variable,\nthe sparsity pattern for *x* is also added to the sparsity pattern for *v*.\n\n{xrst_end var_store_for_jac}\n*/\n// BEGIN_STORE_FOR_JAC\ntemplate <class Vector_set>\ninline void store_for_jac(\n   op_code_var               op_code        ,\n   size_t                    num_vecad_ind  ,\n   const addr_t*             arg            ,\n   bool                      dependency     ,\n   const pod_vector<size_t>& vecad_ind      ,\n   const Vector_set&         var_sparsity   ,\n   Vector_set&               vecad_sparsity )\n// END_STORE_FOR_JAC\n{  //\n   //\n   CPPAD_ASSERT_NARG_NRES(op_code, 3, 0);\n   CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );\n   CPPAD_ASSERT_UNKNOWN( num_vecad_ind == vecad_ind.size() );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_vecad_ind );\n   //\n   // i_v\n   size_t i_v = vecad_ind[ arg[0] - 1 ];\n   CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() );\n   //\n   // i_x, i_y\n   size_t i_x = size_t( arg[1] );\n   size_t i_y = size_t( arg[2] );\n   //\n   switch(op_code)\n   {  //\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n      break;\n      //\n      case StppOp:\n      break;\n      //\n      case StpvOp:\n      vecad_sparsity.binary_union(i_v, i_v, i_y, var_sparsity);\n      break;\n      //\n      case StvpOp:\n      if( dependency )\n         vecad_sparsity.binary_union(i_v, i_v, i_x, var_sparsity);\n      break;\n      //\n      case StvvOp:\n      if( dependency )\n         vecad_sparsity.binary_union(i_v, i_v, i_x, var_sparsity);\n      vecad_sparsity.binary_union(i_v, i_v, i_y, var_sparsity);\n      break;\n   }\n   return;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_store_rev_jac dev}\n\nReverse Jacobian Sparsity for Store a VecAD Element\n###################################################\n\nv, x, y\n*******\nsee\n:ref:`var_store_op@v` ,\n:ref:`var_store_op@x` ,\n:ref:`var_store_op@y`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_STORE_REV_JAC\n   // END_STORE_REV_JAC\n}\n\nop_code, num_vecad_ind, arg\n***************************\nsee :ref:`var_store_op@op_code` ,\n:ref:`var_store_op@num_vecad_ind` ,\n:ref:`var_store_op@arg` .\n\nVector_set\n**********\nis the type used for vectors of sets. It must satisfy the\n:ref:`SetVector-name` concept.\n\ndependency\n**********\nIf true (false) we are including (are not including)\ndependencies that have derivative zero in the sparsity pattern.\nFor example, the :ref:`Discrete-name` functions have derivative zero,\nbut the value depends on its argument.\n\nvecad_ind\n*********\nis a vector with size *num_vec_ind* .\nWe use the notation *i_v* defined by\n\n|tab| *i_v* = vecad_ind[ arg[0] - 1 ]\n\nThis is the index of the VecAD vector and is less than the number of\nVecAD vectors in the recording.\n\nvar_sparsity\n************\nIf :ref:`var_store_op@y` is a variable,\nthe sparsity pattern for *v* is added to the sparsity pattern for *y*.\nIf *dependency* is true and *x* is a variable,\nthe sparsity pattern for *v* is also added to the sparsity pattern for *x*.\n\nvecad_sparsity\n**************\nThe set with index *i_v* in *vecad_sparsity\nis the sparsity pattern for the vector *v*.\n\n{xrst_end var_store_rev_jac}\n*/\n// BEGIN_STORE_REV_JAC\ntemplate <class Vector_set>\ninline void store_rev_jac(\n   op_code_var               op_code        ,\n   size_t                    num_vecad_ind  ,\n   const addr_t*             arg            ,\n   bool                      dependency     ,\n   const pod_vector<size_t>& vecad_ind      ,\n   Vector_set&               var_sparsity   ,\n   const Vector_set&         vecad_sparsity )\n// END_STORE_REV_JAC\n{  //\n   //\n   CPPAD_ASSERT_NARG_NRES(op_code, 3, 0);\n   CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );\n   CPPAD_ASSERT_UNKNOWN( num_vecad_ind == vecad_ind.size() );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_vecad_ind );\n   //\n   // i_v\n   size_t i_v = vecad_ind[ arg[0] - 1 ];\n   CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() );\n   //\n   // i_x, i_y\n   size_t i_x = size_t( arg[1] );\n   size_t i_y = size_t( arg[2] );\n   //\n   switch(op_code)\n   {  //\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n      break;\n      //\n      case StppOp:\n      break;\n      //\n      case StpvOp:\n      var_sparsity.binary_union(i_y, i_y, i_v, vecad_sparsity);\n      break;\n      //\n      case StvpOp:\n      if( dependency )\n         var_sparsity.binary_union(i_x, i_x, i_v, vecad_sparsity);\n      break;\n      //\n      case StvvOp:\n      if( dependency )\n         var_sparsity.binary_union(i_x, i_x, i_v, vecad_sparsity);\n      var_sparsity.binary_union(i_y, i_y, i_v, vecad_sparsity);\n      break;\n   }\n   return;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_store_rev_hes dev}\n\nReverse Hessian Sparsity for Store a VecAD Element\n##################################################\n\nv, x, y\n*******\nsee\n:ref:`var_store_op@v` ,\n:ref:`var_store_op@x` ,\n:ref:`var_store_op@y`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_STORE_REV_HES\n   // END_STORE_REV_HES\n}\n\nop_code, num_vecad_ind, arg\n***************************\nsee :ref:`var_store_op@op_code` ,\n:ref:`var_store_op@num_vecad_ind` ,\n:ref:`var_store_op@arg` .\n\nVector_set\n**********\nis the type used for vectors of sets. It must satisfy the\n:ref:`SetVector-name` concept.\n\nvecad_ind\n*********\nis a vector with size *num_vec_ind* .\nWe use the notation *i_v* defined by\n\n|tab| *i_v* = vecad_ind[ arg[0] - 1 ]\n\nThis is the index of the VecAD vector and is less than the number of\nVecAD vectors in the recording.\nIt is also the index of the hessian\nsparsity pattern for *v* in *vecad_sparsity*.\n\nvar_sparsity\n************\nIf :ref:`var_store_op@y` is a variable,\nthe hessian sparsity pattern for *v* is added to the\nhessian sparsity pattern for *y*.\n\nvecad_sparsity\n**************\nThe set with index *i_v* in *vecad_sparsity\nis the hessian sparsity pattern for the vector *v*.\n\nvar_rev_jac\n***********\nIf the scalar function we are computing the Hessian sparsity of\nhas a non-zero partial w.r.t. *v*,\nand *y* is a variable, *var_rev_jac* [ *i_y* ] is set to true.\nThis is because the scalar function has non-zero partial w.r.t. *y* .\n\nvecad_rev_jac\n*************\nthe *i_v* component of this vector is true ,\nif the scalar function has non-zero partial w.r.t *v*.\n\n{xrst_end var_store_rev_hes}\n*/\n// BEGIN_STORE_REV_HES\ntemplate <class Vector_set>\ninline void store_rev_hes(\n   op_code_var               op_code        ,\n   const addr_t*             arg            ,\n   size_t                    num_vecad_ind  ,\n   const pod_vector<size_t>& vecad_ind      ,\n   Vector_set&               var_sparsity   ,\n   const Vector_set&         vecad_sparsity ,\n   bool*                     var_rev_jac    ,\n   const pod_vector<bool>&   vecad_rev_jac  )\n// END_STORE_REV_HES\n{  //\n   //\n   CPPAD_ASSERT_NARG_NRES(op_code, 3, 0);\n   CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_vecad_ind );\n   CPPAD_ASSERT_UNKNOWN( vecad_ind.size() == num_vecad_ind );\n   //\n   // i_v\n   size_t i_v = vecad_ind[ arg[0] - 1 ];\n   CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() );\n   //\n   // i_y\n   size_t i_y = size_t( arg[2] );\n   //\n   switch(op_code)\n   {  //\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n      break;\n      //\n      case StpvOp:\n      case StvvOp:\n      var_sparsity.binary_union(i_y, i_y, i_v, vecad_sparsity);\n      var_rev_jac[i_y] |= vecad_rev_jac[i_v];\n      break;\n      //\n      case StppOp:\n      case StvpOp:\n      break;\n   }\n   //\n   return;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_store_for_hes dev}\n\nForward Hessian Sparsity for Store a VecAD Element\n##################################################\n\nv, x, y\n*******\nsee\n:ref:`var_store_op@v` ,\n:ref:`var_store_op@x` ,\n:ref:`var_store_op@y`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_STORE_FOR_HES\n   // END_STORE_FOR_HES\n}\n\nop_code, num_vecad_ind, arg\n***************************\nsee :ref:`var_store_op@op_code` ,\n:ref:`var_store_op@num_vecad_ind` ,\n:ref:`var_store_op@arg` .\n\nVector_set\n**********\nis the type used for vectors of sets. It must satisfy the\n:ref:`SetVector-name` concept.\n\nvecad_ind\n*********\nis a vector with size *num_vec_ind* .\nWe use the notation *i_v* defined by\n\n|tab| *i_v* = vecad_ind[ arg[0] - 1 ]\n\nThis is the index of the VecAD vector and is less than the number of\nVecAD vectors in the recording.\nIt is also the index of the hessian\nsparsity pattern for *v* in *vecad_sparsity*.\n\nvar_sparsity\n************\nIf :ref:`var_store_op@y` is a variable,\nthe hessian sparsity pattern for *v* is added to the\nhessian sparsity pattern for *y*.\n\nvecad_sparsity\n**************\nThe set with index *i_v* in *vecad_sparsity\nis the hessian sparsity pattern for the vector *v*.\n\nvar_rev_jac\n***********\nIf the scalar function we are computing the Hessian sparsity of\nhas a non-zero partial w.r.t. *v*,\nand *y* is a variable, *var_rev_jac* [ *i_y* ] is set to true.\nThis is because the scalar function has non-zero partial w.r.t. *y* .\n\nvecad_rev_jac\n*************\nthe *i_v* component of this vector is true ,\nif the scalar function has non-zero partial w.r.t *v*.\n\n{xrst_end var_store_for_hes}\n*/\n// BEGIN_STORE_FOR_HES\ntemplate <class Vector_set>\ninline void store_for_hes(\n   op_code_var               op_code        ,\n   const addr_t*             arg            ,\n   size_t                    num_vecad_ind  ,\n   size_t                    n              ,\n   const pod_vector<size_t>& vecad_ind      ,\n   Vector_set&               vecad_sparsity ,\n   const Vector_set&         for_hes_sparse )\n// END_STORE_FOR_HES\n{  //\n   //\n   CPPAD_ASSERT_NARG_NRES(op_code, 3, 0);\n   CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_vecad_ind );\n   CPPAD_ASSERT_UNKNOWN( vecad_ind.size() == num_vecad_ind );\n   //\n   // np1\n   size_t np1 = n + 1;\n   CPPAD_ASSERT_UNKNOWN( for_hes_sparse.end() == np1 );\n   //\n   // i_v\n   size_t i_v = vecad_ind[ arg[0] - 1 ];\n   CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() );\n   //\n   // i_y\n   size_t i_y = size_t( arg[2] );\n   //\n   switch(op_code)\n   {  //\n      default:\n      CPPAD_ASSERT_UNKNOWN(false);\n      break;\n      //\n      // vecad_sparsity\n      // set Jacobian sparsity for vector with index i_v\n      case StpvOp:\n      case StvvOp:\n      vecad_sparsity.binary_union(i_v, i_v, np1 + i_y, for_hes_sparse);\n      break;\n      //\n      case StppOp:\n      case StvpOp:\n      break;\n   }\n   //\n   return;\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/sub_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_SUB_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_SUB_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n\n// --------------------------- Subvv -----------------------------------------\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void subvv_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SubvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SubvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   for(size_t d = p; d <= q; d++)\n      z[d] = x[d] - y[d];\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void subvv_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SubvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SubvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   size_t m                  = (q-1) * r + 1;\n   Base* x = taylor + size_t(arg[0]) * num_taylor_per_var + m;\n   Base* y = taylor + size_t(arg[1]) * num_taylor_per_var + m;\n   Base* z = taylor + i_z    * num_taylor_per_var + m;\n\n   for(size_t ell = 0; ell < r; ell++)\n      z[ell] = x[ell] - y[ell];\n}\n\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void subvv_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SubvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SubvvOp) == 1 );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   z[0] = x[0] - y[0];\n}\n\n\n// See dev documentation: reverse_binary_op\ntemplate <class Base>\ninline void subvv_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SubvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SubvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Partial derivatives corresponding to arguments and result\n   Base* px = partial + size_t(arg[0]) * n_order;\n   Base* py = partial + size_t(arg[1]) * n_order;\n   Base* pz = partial + i_z    * n_order;\n\n   // number of indices to access\n   size_t i = d + 1;\n   while(i)\n   {  --i;\n      px[i] += pz[i];\n      py[i] -= pz[i];\n   }\n}\n\n// --------------------------- Subpv -----------------------------------------\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void subpv_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SubpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SubpvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   // Paraemter value\n   Base x = parameter[ arg[0] ];\n   if( p == 0 )\n   {  z[0] = x - y[0];\n      p++;\n   }\n   for(size_t d = p; d <= q; d++)\n      z[d] = - y[d];\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void subpv_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SubpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SubpvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   size_t m                  = (q-1) * r + 1;\n   Base* y = taylor + size_t(arg[1]) * num_taylor_per_var + m;\n   Base* z = taylor + i_z    * num_taylor_per_var + m;\n\n   // Paraemter value\n   for(size_t ell = 0; ell < r; ell++)\n      z[ell] = - y[ell];\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void subpv_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SubpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SubpvOp) == 1 );\n\n   // Paraemter value\n   Base x = parameter[ arg[0] ];\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   z[0] = x - y[0];\n}\n\n\n// See dev documentation: reverse_binary_op\ntemplate <class Base>\ninline void subpv_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SubvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SubvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Partial derivatives corresponding to arguments and result\n   Base* py = partial + size_t(arg[1]) * n_order;\n   Base* pz = partial + i_z    * n_order;\n\n   // number of indices to access\n   size_t i = d + 1;\n   while(i)\n   {  --i;\n      py[i] -= pz[i];\n   }\n}\n\n// --------------------------- Subvp -----------------------------------------\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void subvp_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SubvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SubvpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   // Parameter value\n   Base y = parameter[ arg[1] ];\n   if( p == 0 )\n   {  z[0] = x[0] - y;\n      p++;\n   }\n   for(size_t d = p; d <= q; d++)\n      z[d] = x[d];\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void subvp_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SubvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SubvpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + size_t(arg[0]) * num_taylor_per_var;\n   Base* z = taylor + i_z    * num_taylor_per_var;\n\n   // Parameter value\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n      z[m+ell] = x[m+ell];\n}\n\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void subvp_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SubvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SubvpOp) == 1 );\n\n   // Parameter value\n   Base y = parameter[ arg[1] ];\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   z[0] = x[0] - y;\n}\n\n\n// See dev documentation: reverse_binary_op\ntemplate <class Base>\ninline void subvp_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(SubvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(SubvpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Partial derivatives corresponding to arguments and result\n   Base* px = partial + size_t(arg[0]) * n_order;\n   Base* pz = partial + i_z    * n_order;\n\n   // number of indices to access\n   size_t i = d + 1;\n   while(i)\n   {  --i;\n      px[i] += pz[i];\n   }\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/tan_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_TAN_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_TAN_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void tan_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n   Base* y = z      -       cap_order;\n\n   size_t k;\n   if( p == 0 )\n   {  z[0] = tan( x[0] );\n      y[0] = z[0] * z[0];\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {  Base base_j = static_cast<Base>(double(j));\n\n      z[j] = x[j];\n      for(k = 1; k <= j; k++)\n         z[j] += Base(double(k)) * x[k] * y[j-k] / base_j;\n\n      y[j] = z[0] * z[j];\n      for(k = 1; k <= j; k++)\n         y[j] += z[k] * z[j-k];\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void tan_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* z = taylor + i_z * num_taylor_per_var;\n   Base* y = z      -       num_taylor_per_var;\n\n   size_t k;\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  z[m+ell] = Base(double(q)) * ( x[m+ell] + x[m+ell] * y[0]);\n      for(k = 1; k < q; k++)\n         z[m+ell] +=  Base(double(k)) * x[(k-1)*r+1+ell] * y[(q-k-1)*r+1+ell];\n      z[m+ell] /= Base(double(q));\n      //\n      y[m+ell] = Base(2.0) * z[m+ell] * z[0];\n      for(k = 1; k < q; k++)\n         y[m+ell] += z[(k-1)*r+1+ell] * z[(q-k-1)*r+1+ell];\n   }\n}\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void tan_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;  // called z in documentation\n   Base* y = z      -       cap_order;  // called y in documentation\n\n   z[0] = tan( x[0] );\n   y[0] = z[0] * z[0];\n}\n\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void tan_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to first result\n   const Base* z  = taylor  + i_z * cap_order; // called z in doc\n   Base* pz       = partial + i_z * n_order;\n\n   // Taylor coefficients and partials corresponding to auxiliary result\n   const Base* y  = z  - cap_order; // called y in documentation\n   Base* py       = pz - n_order;\n\n\n   size_t j = d;\n   size_t k;\n   Base base_two(2);\n   while(j)\n   {\n      px[j]   += pz[j];\n      pz[j]   /= Base(double(j));\n      for(k = 1; k <= j; k++)\n      {  px[k]   += azmul(pz[j], y[j-k]) * Base(double(k));\n         py[j-k] += azmul(pz[j], x[k]) * Base(double(k));\n      }\n      for(k = 0; k < j; k++)\n         pz[k] += azmul(py[j-1], z[j-k-1]) * base_two;\n\n      --j;\n   }\n   px[0] += azmul(pz[0], Base(1.0) + y[0]);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/tanh_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_TANH_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_TANH_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\nnamespace CppAD { namespace local { namespace var_op {\n\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void tanh_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;\n   Base* y = z      -       cap_order;\n\n   size_t k;\n   if( p == 0 )\n   {  z[0] = tanh( x[0] );\n      y[0] = z[0] * z[0];\n      p++;\n   }\n   for(size_t j = p; j <= q; j++)\n   {  Base base_j = static_cast<Base>(double(j));\n\n      z[j] = x[j];\n      for(k = 1; k <= j; k++)\n         z[j] -= Base(double(k)) * x[k] * y[j-k] / base_j;\n\n      y[j] = z[0] * z[j];\n      for(k = 1; k <= j; k++)\n         y[j] += z[k] * z[j-k];\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void tanh_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + i_x * num_taylor_per_var;\n   Base* z = taylor + i_z * num_taylor_per_var;\n   Base* y = z      -       num_taylor_per_var;\n\n   size_t k;\n   size_t m = (q-1) * r + 1;\n   for(size_t ell = 0; ell < r; ell++)\n   {  z[m+ell] = Base(double(q)) * ( x[m+ell] - x[m+ell] * y[0] );\n      for(k = 1; k < q; k++)\n         z[m+ell] -= Base(double(k)) * x[(k-1)*r+1+ell] * y[(q-k-1)*r+1+ell];\n      z[m+ell] /= Base(double(q));\n      //\n      y[m+ell] = Base(2.0) * z[m+ell] * z[0];\n      for(k = 1; k < q; k++)\n         y[m+ell] += z[(k-1)*r+1+ell] * z[(q-k-1)*r+1+ell];\n   }\n}\n\n// See dev documentation: forward_unary_op\ntemplate <class Base>\ninline void tanh_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( 0 < cap_order );\n\n   // Taylor coefficients corresponding to argument and result\n   Base* x = taylor + i_x * cap_order;\n   Base* z = taylor + i_z * cap_order;  // called z in documentation\n   Base* y = z      -       cap_order;  // called y in documentation\n\n   z[0] = tanh( x[0] );\n   y[0] = z[0] * z[0];\n}\n\n\n// See dev documentation: reverse_unary_op\ntemplate <class Base>\ninline void tanh_reverse(\n   size_t        i_z          ,\n   const addr_t* arg          ,\n   size_t        cap_order    ,\n   const Base*   taylor       ,\n   size_t        n_order      ,\n   Base*         partial      )\n{  // d  //\n   //\n   // i_x\n   size_t i_x = size_t(arg[0]);\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Taylor coefficients and partials corresponding to argument\n   const Base* x  = taylor  + i_x * cap_order;\n   Base* px       = partial + i_x * n_order;\n\n   // Taylor coefficients and partials corresponding to first result\n   const Base* z  = taylor  + i_z * cap_order; // called z in doc\n   Base* pz       = partial + i_z * n_order;\n\n   // Taylor coefficients and partials corresponding to auxiliary result\n   const Base* y  = z  - cap_order; // called y in documentation\n   Base* py       = pz - n_order;\n\n\n   size_t j = d;\n   size_t k;\n   Base base_two(2);\n   while(j)\n   {\n      px[j]   += pz[j];\n      pz[j]   /= Base(double(j));\n      for(k = 1; k <= j; k++)\n      {  px[k]   -= azmul(pz[j], y[j-k]) * Base(double(k));\n         py[j-k] -= azmul(pz[j], x[k]) * Base(double(k));\n      }\n      for(k = 0; k < j; k++)\n         pz[k] += azmul(py[j-1], z[j-k-1]) * base_two;\n\n      --j;\n   }\n   px[0] += azmul(pz[0], Base(1.0) - y[0]);\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/two_var.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_TWO_VAR_HPP\n# define CPPAD_LOCAL_VAR_OP_TWO_VAR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// BEGIN_CPPAD_LOCAL_SPARSE_NAMESPACE\nnamespace CppAD { namespace local { namespace var_op {\n// END_DECLARE_NAMESPACE\n\n/*\n{xrst_begin_parent var_two_var dev}\n\nSparsity Calculations for Operators With Two Variables\n######################################################\n\nBinary Operators\n****************\n| *z* = *fun* ( *x* , *y* )\n| *z* = *x*  *Op* *y*\n\nSee :ref:`var_binary_op@Fun` for binary operators,\nrestricted to the case where both *x* and *y* are variables,\nfor some of the possible values of *Fun* and the corresponding operators.\n\nx\n*\nis the first operand for this operator .\n\ny\n*\nis the second operand for this operator\n\nz\n*\nis the primary result for this operator.\n\nVector_set\n**********\nis the type used for vectors of sets. It must satisfy the\n:ref:`SetVector-name` concept.\n\ni_z\n***\nis the variable index corresponding to *z* .\n\narg\n***\n\narg[0]\n======\nis the variable index corresponding to x.\n\narg[1]\n======\nis the variable index corresponding to y.\n\n{xrst_end var_two_var}\n------------------------------------------------------------------------------\n{xrst_begin var_two_var_for_jac dev}\n\nForward Jacobian Sparsity for Two Variable Argument Operators\n#############################################################\n\nx, y, z\n*******\nsee\n:ref:`var_two_var@x` ,\n:ref:`var_two_var@y` ,\n:ref:`var_two_var@z`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_TWO_VAR_FOR_JAC\n   // END_TWO_VAR_FOR_JAC\n}\n\nVector_set, i_z, arg\n********************\nsee\n:ref:`var_two_var@Vector_set` ,\n:ref:`var_two_var@i_z` ,\n:ref:`var_two_var@arg`\n\nsparsity\n********\n\nInput\n=====\nfor *j* < *i_z*  and *j* not an auxiliary result,\nthe set with index *j* in *sparsity* is\nthe Jacobian sparsity for the variable with index *j* .\n\nOutput\n======\nThe set with index *i_z* in *sparsity* is\nthe Jacobian sparsity for the variable *z* .\n\n{xrst_end var_two_var_for_jac}\n*/\n// BEGIN_TWO_VAR_FOR_JAC\ntemplate <class Vector_set>\nvoid two_var_for_jac(\n   size_t            i_z           ,\n   const addr_t*     arg           ,\n   Vector_set&       sparsity      )\n// END_TWO_VAR_FOR_JAC\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );\n\n   sparsity.binary_union(i_z, size_t(arg[0]), size_t(arg[1]), sparsity);\n\n   return;\n}\n/*\n------------------------------------------------------------------------------\n{xrst_begin var_two_var_rev_jac dev}\n\nReverse Jacobian Sparsity for Two Variable Argument Operators\n#############################################################\n\nx, y, z\n*******\nsee\n:ref:`var_two_var@x` ,\n:ref:`var_two_var@y` ,\n:ref:`var_two_var@z`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_TWO_VAR_REV_JAC\n   // END_TWO_VAR_REV_JAC\n}\n\nVector_set, i_z, arg\n********************\nsee\n:ref:`var_two_var@Vector_set` ,\n:ref:`var_two_var@i_z` ,\n:ref:`var_two_var@arg`\n\nsparsity\n********\nUse z(x, y) to denote the variable *z* as a function of the variables\n*x* , *y* , and define H in terms of G by::\n\n   H( x, y, ... ) = G[ z(x, y) , x, y, ... ]\n\nOn input, *sparsity* is a sparsity pattern for the Jacobian of *G* .\nUpon return, *sparsity* is a sparsity pattern for the Jacobian of *H* .\n\n{xrst_end var_two_var_rev_jac}\n*/\n// BEGIN_TWO_VAR_REV_JAC\ntemplate <class Vector_set>\nvoid two_var_rev_jac(\n   size_t              i_z           ,\n   const addr_t*       arg           ,\n   Vector_set&         sparsity      )\n// END_TWO_VAR_REV_JAC\n{\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );\n   CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );\n\n   sparsity.binary_union( size_t(arg[0]), size_t(arg[0]), i_z, sparsity);\n   sparsity.binary_union( size_t(arg[1]), size_t(arg[1]), i_z, sparsity);\n\n   return;\n}\n// ---------------------------------------------------------------------------\n/*\n{xrst_begin var_two_var_for_hes dev}\n\nForward Hessian Sparsity for Two Variable Argument Operators\n############################################################\n\nx, y, z\n*******\nsee\n:ref:`var_two_var@x` ,\n:ref:`var_two_var@y` ,\n:ref:`var_two_var@z`\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_TWO_VAR_FOR_HES\n   // END_TWO_VAR_FOR_HES\n}\n\nVector_set, i_z, arg\n********************\nsee\n:ref:`var_two_var@Vector_set` ,\n:ref:`var_two_var@i_z` ,\n:ref:`var_two_var@arg`\n\n\nlinear\n******\n\nlinear[0]\n=========\nThis value is true (false) if the :math:`z(x, y)`\nmust have zero second partial derivative with respect to *x*\n(may have non-zero second partial).\n\nlinear[1]\n=========\nThis value is true (false) if the :math:`z(x, y)`\nmust have zero second partial derivative with respect to *y*\n(may have non-zero second partial).\n\nlinear[2]\n=========\nThis value is true (false) if the :math:`z(x, y)`\nmust have zero cross partial derivative\n(may have non-zero cross partial).\n\nn_independent_p1\n****************\nis the number of independent variables (in the tape) plus one.\n\nnum_var\n*******\nThis is the total number of variables in the tape\n(counting the phantom variable at index zero).\n\nfor_sparsity\n************\nOn input, all the linear and nonlinear interactions up to the\narguments to the atomic function have been take into account.\nUpon return, the linear and nonlinear interactions in\nthe atomic function have been take into account.\n\nHessian Sparsity\n================\nFor *j* equal 1 to *n_independent_p1* - 1,\nif *i* is in set with index *j* ,\nthe Hessian may have a non-zero partial with respect to the\nindependent variables with indices ( *i* - 1, *j* - 1 ) .\nNote that the index zero is not used because it corresponds to the\nphantom variable on the tape.\n\nJacobian Sparsity\n=================\nIf *i* is in the set with index *n_independent_p1* + *j* ,\nthe variable with index *j* may have a non-zero partial with resect to the\nindependent variable with index *i* - 1 .\n\n{xrst_end var_two_var_for_hes}\n*/\n// BEGIN_TWO_VAR_FOR_HES\ntemplate <class Vector_set>\nvoid two_var_for_hes(\n   size_t        n_independent_p1    ,\n   size_t        num_var             ,\n   size_t        i_z                 ,\n   const addr_t* arg                 ,\n   bool*         linear              ,\n   Vector_set&   for_sparsity        )\n// END_TWO_VAR_FOR_HES\n{  //\n   // np1, i_x, i_y, linear_x, linear_y, linear_xy\n   size_t np1 = n_independent_p1;\n   size_t i_x = size_t( arg[0] );\n   size_t i_y = size_t( arg[1] );\n   bool linear_x  = linear[0];\n   bool linear_y  = linear[1];\n   bool linear_xy = linear[2];\n   //\n   CPPAD_ASSERT_UNKNOWN( i_x < i_z  && i_y < i_z );\n   CPPAD_ASSERT_UNKNOWN( i_z < num_var );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.end() == np1 );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.n_set() == np1 + num_var );\n   CPPAD_ASSERT_UNKNOWN( for_sparsity.number_elements(np1) == 0 );\n   //\n   //\n   // for_sparsity\n   // Jacobian sparsity for z\n   for_sparsity.binary_union(np1 + i_z, np1 + i_x, np1 + i_y, for_sparsity);\n   //\n   //\n   if( ! linear_x )\n   {  //\n      // itr_x, i_u\n      typename Vector_set::const_iterator itr_x(for_sparsity, i_x + np1);\n      size_t i_u = *itr_x;\n      while( i_u < np1 )\n      {  // x depends on the independent variable u\n         //\n         // for_sparsity\n         // update Hessian term with one partial w.r.t u\n         if( ! linear_xy )\n         {  // other independent variables that z depends on\n            for_sparsity.binary_union(i_u, i_u, i_z + np1, for_sparsity);\n         }\n         else\n         {  // other independent variables that x depends on\n            for_sparsity.binary_union(i_u, i_u, i_x + np1, for_sparsity);\n         }\n         //\n         // i_u\n         i_u = *(++itr_x);\n      }\n   }\n   if( ! linear_y )\n   {  //\n      // itr_y, i_u\n      typename Vector_set::const_iterator itr_y(for_sparsity, i_y + np1);\n      size_t i_u = *itr_y;\n      while( i_u < np1 )\n      {  // y depends on the independent variable u\n         //\n         // for_sparsity\n         // update Hessian term with one partial w.r.t u\n         if( ! linear_xy )\n         {  // other independent variables that z depends on\n            for_sparsity.binary_union(i_u, i_u, i_z + np1, for_sparsity);\n         }\n         else\n         {  // other independent variables that y depends on\n            for_sparsity.binary_union(i_u, i_u, i_y + np1, for_sparsity);\n         }\n         //\n         // i_u\n         i_u = *(++itr_y);\n      }\n   }\n   if( (! linear_xy) && linear_x )\n   {  //\n      // itr_x, i_u\n      typename Vector_set::const_iterator itr_x(for_sparsity, i_x + np1);\n      size_t i_u = *itr_x;\n      while( i_u < np1 )\n      {  // x depends on the independent variable u\n         //\n         // for_sparsity\n         // update Hessian term with one partial w.r.t u other w.r.t\n         // independent variables that y depends on\n         for_sparsity.binary_union(i_u, i_u, i_y + np1, for_sparsity);\n         //\n         // i_u\n         i_u = *(++itr_x);\n      }\n   }\n   if( (! linear_xy) && linear_y )\n   {  //\n      // itr_y, i_u\n      typename Vector_set::const_iterator itr_y(for_sparsity, i_y + np1);\n      size_t i_u = *itr_y;\n      while( i_u < np1 )\n      {  // y depends on the independent variable u\n         //\n         // for_sparsity\n         // update Hessian term with one partial w.r.t u other w.r.t\n         // independent variables that x depends on\n         for_sparsity.binary_union(i_u, i_u, i_x + np1, for_sparsity);\n         //\n         // i_u\n         i_u = *(++itr_y);\n      }\n   }\n}\n// ---------------------------------------------------------------------------\n/*\n{xrst_begin var_two_var_rev_hes dev}\n\nReverse Jacobian Sparsity for Two Variable Argument Operators\n#############################################################\n\nx, y, z\n*******\nsee\n:ref:`var_two_var@x` ,\n:ref:`var_two_var@y` ,\n:ref:`var_two_var@z`\n\nG and H\n*******\nUse z(x, y) to denote the variable *z* as a function of the variables\n*x* , *y* , and define H in terms of G by::\n\n   H( x, y, ... ) = G[ z(x, y) , x, y, ... ]\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_TWO_VAR_REV_HES\n   // END_TWO_VAR_REV_HES\n}\n\nVector_set, i_z, arg\n********************\nsee\n:ref:`var_two_var@Vector_set` ,\n:ref:`var_two_var@i_z` ,\n:ref:`var_two_var@arg`\n\nlinear\n******\n\nlinear[0]\n=========\nThis value is true (false) if the :math:`z(x, y)`\nmust have zero second partial derivative with respect to *x*\n(may have non-zero second partial).\n\nlinear[1]\n=========\nThis value is true (false) if the :math:`z(x, y)`\nmust have zero second partial derivative with respect to *y*\n(may have non-zero second partial).\n\nlinear[2]\n=========\nThis value is true (false) if the :math:`z(x, y)`\nmust have zero cross partial derivative\n(may have non-zero cross partial).\n\nn_independent_p1\n****************\nis the number of independent variables (in the tape) plus one.\n\nnum_var\n*******\nThis is the total number of variables in the tape\n(counting the phantom variable at index zero).\n\nfor_jac_sparsity\n****************\nThe set with index *j* is the forward Jacobian sparsity\npattern for the variable with index *j*.\n\nrev_jac_include\n***************\nIf the *j* element of this vector is true,\nthe variable with index *j* is included in the Hessian,\nor affects the value of a variable that is included in the Hessian.\n\nInput\n=====\n::\n\n   for j = num_var, ... , i_z + 1\n      rev_jac_include[j] is an input\n\nOutput\n======\nrev_jac_include[i_z] is an output\n\nrev_hes_sparsity\n****************\nOn input (output), this is the sparsity pattern for *G* ( *H* ).\nFor each variable index *j* ,\n*rev_hes_sparsity* [ *j* ] is the set of indices\nthat may have non-zero cross partials with variable index *j* .\n\nExample\n=======\nIf the indices in the sets correspond to the independent variables,\nthen *rev_hes_sparsity* ``.end()`` is the number of independent variables.\nFor *i* a variable index between 1 and the number of independent variables,\n*i* - 1 is the corresponding independent variable index.\n(The index *i* = 0 corresponds to the phantom variable at the beginning\nof the tape. )\n{xrst_end var_two_var_rev_hes}\n*/\n// BEGIN_TWO_VAR_REV_HES\ntemplate <class Vector_set>\nvoid two_var_rev_hes(\n   size_t              i_z               ,\n   const addr_t*       arg               ,\n   bool*               linear            ,\n   bool*               rev_jacobian      ,\n   const Vector_set&   for_jac_sparsity  ,\n   Vector_set&         rev_hes_sparsity  )\n// END_TWO_VAR_REV_HES\n{  //\n   // check for nothing to do\n   if( ! rev_jacobian[i_z] )\n      return;\n   //\n   // i_x, i_y, linear_x, linear_y, linear_xy\n   size_t i_x = size_t( arg[0] );\n   size_t i_y = size_t( arg[1] );\n   bool linear_x  = linear[0];\n   bool linear_y  = linear[1];\n   bool linear_xy = linear[2];\n   //\n   CPPAD_ASSERT_UNKNOWN( i_x < i_z );\n   CPPAD_ASSERT_UNKNOWN( i_y < i_z );\n   //\n   // rev_hes_sparsity\n   // propagate form z to x and y\n   rev_hes_sparsity.binary_union(i_x, i_x, i_z, rev_hes_sparsity);\n   rev_hes_sparsity.binary_union(i_y, i_y, i_z, rev_hes_sparsity);\n   //\n   if( ! linear_x )\n   {  rev_hes_sparsity.binary_union(i_x, i_x, i_x, for_jac_sparsity);\n      rev_hes_sparsity.binary_union(i_y, i_y, i_x, for_jac_sparsity);\n   }\n   if( ! linear_y )\n   {  rev_hes_sparsity.binary_union(i_x, i_x, i_y, for_jac_sparsity);\n      rev_hes_sparsity.binary_union(i_y, i_y, i_y, for_jac_sparsity);\n   }\n   if( ! linear_xy )\n   {  rev_hes_sparsity.binary_union(i_x, i_x, i_y, for_jac_sparsity);\n      rev_hes_sparsity.binary_union(i_y, i_y, i_x, for_jac_sparsity);\n   }\n   //\n   // rev_jacobian\n   rev_jacobian[i_x] = true;\n   rev_jacobian[i_y] = true;\n}\n// ---------------------------------------------------------------------------\n} } } // END_CPPAD_LOCAL_SPARSE_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/var_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_VAR_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_VAR_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n// used by the sparse operators\n# include <cppad/local/sparse/internal.hpp>\n\n// operations\n# include <cppad/core/std_math_11.hpp>\n# include <cppad/local/var_op/abs_op.hpp>\n# include <cppad/local/var_op/add_op.hpp>\n# include <cppad/local/var_op/acos_op.hpp>\n# include <cppad/local/var_op/acosh_op.hpp>\n# include <cppad/local/var_op/asin_op.hpp>\n# include <cppad/local/var_op/asinh_op.hpp>\n# include <cppad/local/var_op/atan_op.hpp>\n# include <cppad/local/var_op/atanh_op.hpp>\n# include <cppad/local/var_op/cexp_op.hpp>\n# include <cppad/local/var_op/cos_op.hpp>\n# include <cppad/local/var_op/cosh_op.hpp>\n# include <cppad/local/var_op/cskip_op.hpp>\n# include <cppad/local/var_op/csum_op.hpp>\n# include <cppad/local/var_op/dis_op.hpp>\n# include <cppad/local/var_op/div_op.hpp>\n# include <cppad/local/var_op/erf_op.hpp>\n# include <cppad/local/var_op/exp_op.hpp>\n# include <cppad/local/var_op/expm1_op.hpp>\n# include <cppad/local/var_op/load_op.hpp>\n# include <cppad/local/var_op/log_op.hpp>\n# include <cppad/local/var_op/log1p_op.hpp>\n# include <cppad/local/var_op/mul_op.hpp>\n# include <cppad/local/var_op/neg_op.hpp>\n# include <cppad/local/var_op/par_op.hpp>\n# include <cppad/local/var_op/pow_op.hpp>\n# include <cppad/local/var_op/pri_op.hpp>\n# include <cppad/local/var_op/sign_op.hpp>\n# include <cppad/local/var_op/sin_op.hpp>\n# include <cppad/local/var_op/sinh_op.hpp>\n# include <cppad/local/var_op/sqrt_op.hpp>\n# include <cppad/local/var_op/sub_op.hpp>\n# include <cppad/local/var_op/two_var.hpp>\n# include <cppad/local/var_op/one_var.hpp>\n# include <cppad/local/var_op/store_op.hpp>\n# include <cppad/local/var_op/tan_op.hpp>\n# include <cppad/local/var_op/tanh_op.hpp>\n# include <cppad/local/var_op/zmul_op.hpp>\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/local/var_op/zmul_op.hpp",
    "content": "# ifndef CPPAD_LOCAL_VAR_OP_ZMUL_OP_HPP\n# define CPPAD_LOCAL_VAR_OP_ZMUL_OP_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\nnamespace CppAD { namespace local { namespace var_op {\n\n// --------------------------- Zmulvv -----------------------------------------\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void zmulvv_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   size_t k;\n   for(size_t d = p; d <= q; d++)\n   {  z[d] = Base(0.0);\n      for(k = 0; k <= d; k++)\n         z[d] += azmul(x[d-k], y[k]);\n   }\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void zmulvv_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   Base* x = taylor + size_t(arg[0]) * num_taylor_per_var;\n   Base* y = taylor + size_t(arg[1]) * num_taylor_per_var;\n   Base* z = taylor +    i_z * num_taylor_per_var;\n\n   size_t k, ell, m;\n   for(ell = 0; ell < r; ell++)\n   {  m = (q-1)*r + ell + 1;\n      z[m] = azmul(x[0], y[m]) + azmul(x[m],  y[0]);\n      for(k = 1; k < q; k++)\n         z[m] += azmul(x[(q-k-1)*r + ell + 1], y[(k-1)*r + ell + 1]);\n   }\n}\n\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void zmulvv_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   z[0] = azmul(x[0], y[0]);\n}\n\n\n// See dev documentation: reverse_binary_op\ntemplate <class Base>\ninline void zmulvv_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Arguments\n   const Base* x  = taylor + size_t(arg[0]) * cap_order;\n   const Base* y  = taylor + size_t(arg[1]) * cap_order;\n\n   // Partial derivatives corresponding to arguments and result\n   Base* px = partial + size_t(arg[0]) * n_order;\n   Base* py = partial + size_t(arg[1]) * n_order;\n   Base* pz = partial + i_z    * n_order;\n\n   // number of indices to access\n   size_t j = d + 1;\n   size_t k;\n   while(j)\n   {  --j;\n      for(k = 0; k <= j; k++)\n      {\n         px[j-k] += azmul(pz[j], y[k]);\n         py[k]   += azmul(pz[j], x[j-k]);\n      }\n   }\n}\n// --------------------------- Zmulpv -----------------------------------------\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void zmulpv_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ZmulpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ZmulpvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   // Paraemter value\n   Base x = parameter[ arg[0] ];\n\n   for(size_t d = p; d <= q; d++)\n      z[d] = azmul(x, y[d]);\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void zmulpv_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ZmulpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ZmulpvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   size_t m                  = (q-1) * r + 1;\n   Base* y = taylor + size_t(arg[1]) * num_taylor_per_var + m;\n   Base* z = taylor + i_z    * num_taylor_per_var + m;\n\n   // Paraemter value\n   Base x = parameter[ arg[0] ];\n\n   for(size_t ell = 0; ell < r; ell++)\n      z[ell] = azmul(x, y[ell]);\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void zmulpv_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ZmulpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ZmulpvOp) == 1 );\n\n   // Paraemter value\n   Base x = parameter[ arg[0] ];\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* y = taylor + size_t(arg[1]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   z[0] = azmul(x, y[0]);\n}\n\n\n// See dev documentation: reverse_binary_op\ntemplate <class Base>\ninline void zmulpv_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ZmulpvOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ZmulpvOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Arguments\n   Base x  = parameter[ arg[0] ];\n\n   // Partial derivatives corresponding to arguments and result\n   Base* py = partial + size_t(arg[1]) * n_order;\n   Base* pz = partial + i_z    * n_order;\n\n   // number of indices to access\n   size_t j = d + 1;\n   while(j)\n   {  --j;\n      py[j] += azmul(pz[j], x);\n   }\n}\n// --------------------------- Zmulvp -----------------------------------------\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void zmulvp_forward_any(\n   size_t        order_low   ,\n   size_t        order_up    ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // p, q\n   size_t p = order_low;\n   size_t q = order_up;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n   CPPAD_ASSERT_UNKNOWN( p <= q );\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   // Paraemter value\n   Base y = parameter[ arg[1] ];\n\n   for(size_t d = p; d <= q; d++)\n      z[d] = azmul(x[d], y);\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void zmulvp_forward_dir(\n   size_t        order_up    ,\n   size_t        n_dir       ,\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{   // q, r\n   size_t q = order_up;\n   size_t r = n_dir;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( 0 < q );\n   CPPAD_ASSERT_UNKNOWN( q < cap_order );\n\n   // Taylor coefficients corresponding to arguments and result\n   size_t num_taylor_per_var = (cap_order-1) * r + 1;\n   size_t m                  = (q-1) * r + 1;\n   Base* x = taylor + size_t(arg[0]) * num_taylor_per_var + m;\n   Base* z = taylor + i_z    * num_taylor_per_var + m;\n\n   // Paraemter value\n   Base y = parameter[ arg[1] ];\n\n   for(size_t ell = 0; ell < r; ell++)\n      z[ell] = azmul(x[ell], y);\n}\n\n// See dev documentation: forward_binary_op\ntemplate <class Base>\ninline void zmulvp_forward_0(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   Base*         taylor      )\n{  //\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 );\n\n   // Paraemter value\n   Base y = parameter[ arg[1] ];\n\n   // Taylor coefficients corresponding to arguments and result\n   Base* x = taylor + size_t(arg[0]) * cap_order;\n   Base* z = taylor + i_z    * cap_order;\n\n   z[0] = azmul(x[0], y);\n}\n\n\n// See dev documentation: reverse_binary_op\ntemplate <class Base>\ninline void zmulvp_reverse(\n   size_t        i_z         ,\n   const addr_t* arg         ,\n   const Base*   parameter   ,\n   size_t        cap_order   ,\n   const Base*   taylor      ,\n   size_t        n_order     ,\n   Base*         partial     )\n{  // d\n   //\n   size_t d = n_order - 1;\n   //\n   // check assumptions\n   CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvpOp) == 2 );\n   CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 );\n   CPPAD_ASSERT_UNKNOWN( n_order <= cap_order );\n\n   // Arguments\n   Base y  = parameter[ arg[1] ];\n\n   // Partial derivatives corresponding to arguments and result\n   Base* px = partial + size_t(arg[0]) * n_order;\n   Base* pz = partial + i_z    * n_order;\n\n   // number of indices to access\n   size_t j = d + 1;\n   while(j)\n   {  --j;\n      px[j] += azmul(pz[j], y);\n   }\n}\n\n} } } // END namespace\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/check_numeric_type.hpp",
    "content": "# ifndef CPPAD_UTILITY_CHECK_NUMERIC_TYPE_HPP\n# define CPPAD_UTILITY_CHECK_NUMERIC_TYPE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin CheckNumericType}\n\nCheck NumericType Class Concept\n###############################\n\nSyntax\n******\n| # ``include <cppad/utility/check_numeric_type.hpp>``\n| ``CheckNumericType`` < *NumericType* >()\n\nPurpose\n*******\nThe syntax\n\n   ``CheckNumericType`` < *NumericType* >()\n\npreforms compile and run time checks that the type specified\nby *NumericType* satisfies all the requirements for\na :ref:`NumericType-name` class.\nIf a requirement is not satisfied,\na an error message makes it clear what condition is not satisfied.\n\nInclude\n*******\nThe file ``cppad/utility/check_numeric_type.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest\nif the CppAD include files.\n\nParallel Mode\n*************\nThe routine :ref:`thread_alloc::parallel_setup<ta_parallel_setup-name>`\nmust be called before it\ncan be used in :ref:`parallel<ta_in_parallel-name>` mode.\n\nExample\n*******\n{xrst_toc_hidden\n   example/utility/check_numeric_type.cpp\n}\nThe file :ref:`check_numeric_type.cpp-name`\ncontains an example and test of this function.\nThe comments in this example suggest a way to change the example\nso an error message occurs.\n\n{xrst_end CheckNumericType}\n---------------------------------------------------------------------------\n*/\n\n# include <cstddef>\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD {\n\n# ifdef NDEBUG\n   template <class NumericType>\n   void CheckNumericType(void)\n   { }\n# else\n   template <class NumericType>\n   NumericType CheckNumericType(void)\n   {  // Section 3.6.2 of ISO/IEC 14882:1998(E) states: \"The storage for\n      // objects with static storage duration (3.7.1) shall be zero-\n      // initialized (8.5) before any other initialization takes place.\"\n      static size_t count[CPPAD_MAX_NUM_THREADS];\n      size_t thread = thread_alloc::thread_num();\n      if( count[thread] > 0  )\n         return NumericType(0);\n      count[thread]++;\n      /*\n      constructors\n      */\n      NumericType check_NumericType_default_constructor;\n      NumericType check_NumericType_constructor_from_int(1);\n\n      const NumericType x(1);\n\n      NumericType check_NumericType_copy_constructor(x);\n\n      // assignment\n      NumericType check_NumericType_assignment;\n      check_NumericType_assignment = x;\n\n      /*\n      unary operators\n      */\n      const NumericType check_NumericType_unary_plus(1);\n      NumericType check_NumericType_unary_plus_result =\n         + check_NumericType_unary_plus;\n\n      const NumericType check_NumericType_unary_minus(1);\n      NumericType check_NumericType_unary_minus_result =\n         - check_NumericType_unary_minus;\n\n      /*\n      binary operators\n      */\n      const NumericType check_NumericType_binary_addition(1);\n      NumericType check_NumericType_binary_addition_result =\n         check_NumericType_binary_addition + x;\n\n      const NumericType check_NumericType_binary_subtraction(1);\n      NumericType check_NumericType_binary_subtraction_result =\n         check_NumericType_binary_subtraction - x;\n\n      const NumericType check_NumericType_binary_multiplication(1);\n      NumericType check_NumericType_binary_multiplication_result =\n         check_NumericType_binary_multiplication * x;\n\n      const NumericType check_NumericType_binary_division(1);\n      NumericType check_NumericType_binary_division_result =\n         check_NumericType_binary_division / x;\n\n      /*\n      compound assignment operators\n      */\n      NumericType\n      check_NumericType_computed_assignment_addition(1);\n      check_NumericType_computed_assignment_addition += x;\n\n      NumericType\n      check_NumericType_computed_assignment_subtraction(1);\n      check_NumericType_computed_assignment_subtraction -= x;\n\n      NumericType\n      check_NumericType_computed_assignment_multiplication(1);\n      check_NumericType_computed_assignment_multiplication *= x;\n\n      NumericType\n      check_NumericType_computed_assignment_division(1);\n      check_NumericType_computed_assignment_division /= x;\n\n      /*\n      use all values so as to avoid warnings\n      */\n      check_NumericType_default_constructor = x;\n      return\n         + check_NumericType_default_constructor\n         + check_NumericType_constructor_from_int\n         + check_NumericType_copy_constructor\n         + check_NumericType_assignment\n         + check_NumericType_unary_plus_result\n         + check_NumericType_unary_minus_result\n         + check_NumericType_binary_addition_result\n         + check_NumericType_binary_subtraction_result\n         + check_NumericType_binary_multiplication_result\n         + check_NumericType_binary_division_result\n         + check_NumericType_computed_assignment_addition\n         + check_NumericType_computed_assignment_subtraction\n         + check_NumericType_computed_assignment_multiplication\n         + check_NumericType_computed_assignment_division\n      ;\n   }\n# endif\n\n} // end namespace CppAD\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/check_simple_vector.hpp",
    "content": "# ifndef CPPAD_UTILITY_CHECK_SIMPLE_VECTOR_HPP\n# define CPPAD_UTILITY_CHECK_SIMPLE_VECTOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin CheckSimpleVector}\n\nCheck Simple Vector Concept\n###########################\n\nSyntax\n******\n| # ``include <cppad/utility/check_simple_vector.hpp>``\n| ``CheckSimpleVector`` < *Scalar* , *Vector* >()\n| ``CheckSimpleVector`` < *Scalar* , *Vector* >( *x* , *y* )\n\nPurpose\n*******\nPreforms compile and run time checks that the type specified\nby *Vector* satisfies all the requirements for\na :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n*Scalar* .\nIf a requirement is not satisfied,\na an error message makes it clear what condition is not satisfied.\n\nVector\n******\nis the vector type we are checking.\n\nScalar\n******\nis the type corresponding to the elements of an *Vector* .\n\nx, y\n****\nIf the arguments *x* and *y* are present,\nthey have prototype\n\n| |tab| ``const`` *Scalar* & *x*\n| |tab| ``const`` *Scalar* & *y*\n\nIn addition, the check\n\n   *x* == *x*\n\nwill return the boolean value ``true`` , and\n\n   *x* == *y*\n\nwill return ``false`` .\n\nRestrictions\n************\nIf the arguments *x* and *y* are not present,\nthe following extra assumption is made by ``CheckSimpleVector`` :\nIf *x* is a *Scalar* object\n\n| |tab| *x*  = 0\n| |tab| *y*  = 1\n\nassigns values to the objects *x* and *y* .\nIn addition,\n*x* == *x* would return the boolean value ``true`` and\n*x* == *y* would return ``false`` .\n\nInclude\n*******\nThe file ``cppad/utility/check_simple_vector.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest\nif the CppAD include files.\n\nParallel Mode\n*************\nThis routine must be called before entering parallel mode\nbecause it has static variables that must be initialized.\nIf it's first call is not in  parallel mode, and NDEBUG is not defined,\nyou will get an assertion. Running in the debugger and going to the\nstack frame where CheckSimpleVector is called may help you determine\nwhat the value of *Scalar* and *Vector* need to be initialized.\n\nExample\n*******\n{xrst_toc_hidden\n   example/utility/check_simple_vector.cpp\n}\nThe file :ref:`check_simple_vector.cpp-name`\ncontains an example and test of this function where *S*\nis the same as *T* .\nThe comments in this example suggest a way to change the example\nso *S* is not the same as *T* .\n\n{xrst_end CheckSimpleVector}\n---------------------------------------------------------------------------\n*/\n\n# include <cstddef>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/local/define.hpp>\n# include <cppad/utility/thread_alloc.hpp>\n\n// CPPAD_CHECK_SIMPLE_VECTOR\n# ifndef NDEBUG\n# define CPPAD_CHECK_SIMPLE_VECTOR 1\n# elif CPPAD_DEBUG_AND_RELEASE\n# define CPPAD_CHECK_SIMPLE_VECTOR 1\n# else\n# define CPPAD_CHECK_SIMPLE_VECTOR 0\n# endif\n\nnamespace CppAD {\n\n# if ! CPPAD_CHECK_SIMPLE_VECTOR\n   template <class Scalar, class Vector>\n   inline void CheckSimpleVector(const Scalar& x, const Scalar& y)\n   { }\n   template <class Scalar, class Vector>\n   inline void CheckSimpleVector(void)\n   { }\n# else\n   template <class S, class T>\n   struct ok_if_S_same_as_T { };\n\n   template <class T>\n   struct ok_if_S_same_as_T<T,T> { T value; };\n\n   template <class Scalar, class Vector>\n   inline void CheckSimpleVector(const Scalar& x, const Scalar& y)\n   {  //\n      // count\n      static size_t count = 0;\n      if( count > 0  )\n         return;\n      CPPAD_ASSERT_KNOWN(\n         ! CppAD::thread_alloc::in_parallel() ,\n         \"In parallel mode and CheckSimpleVector was not previously called\\n\"\n         \"with this Scalar and Vector type; see the heading\\n\"\n         \"Parallel Mode in the CheckSimpleVector documentation.\"\n      );\n      count++;\n\n      // value_type must be type of elements of Vector\n      typedef typename Vector::value_type value_type;\n\n      // check that elements of Vector have type Scalar\n      struct ok_if_S_same_as_T<Scalar, value_type> x_copy;\n      x_copy.value = x;\n\n      // check default constructor\n      Vector d;\n\n      // size member function\n      CPPAD_ASSERT_KNOWN(\n         d.size() == 0,\n         \"default constructor result does not have size zero\"\n      );\n\n      // resize to same size as other vectors in test\n      d.resize(1);\n\n      // check sizing constructor\n      Vector s(1);\n\n      // check element assignment\n      s[0] = y;\n      CPPAD_ASSERT_KNOWN(\n         s[0] == y,\n         \"element assignment failed\"\n      );\n\n      // check copy constructor\n      s[0] = x_copy.value;\n      const Vector c(s);\n      s[0] = y;\n      CPPAD_ASSERT_KNOWN(\n         c[0] == x,\n         \"copy constructor is shallow\"\n      );\n\n      // vector assignment operator\n      d[0] = x;\n      s    = d;\n      s[0] = y;\n      CPPAD_ASSERT_KNOWN(\n         d[0] == x,\n         \"assignment operator is shallow\"\n      );\n\n      // element access, right side const\n      // element assignment, left side not const\n      d[0] = c[0];\n      CPPAD_ASSERT_KNOWN(\n         d[0] == x,\n         \"element assignment from const failed\"\n      );\n   }\n   template <class Scalar, class Vector>\n   void CheckSimpleVector(void)\n   {  Scalar x;\n      Scalar y;\n\n      // use assignment and not constructor\n      x = Scalar(0);\n      y = Scalar(1);\n\n      CheckSimpleVector<Scalar, Vector>(x, y);\n   }\n\n# endif\n\n} // end namespace CppAD\n\n# undef CPPAD_CHECK_SIMPLE_VECTOR\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/create_dll_lib.hpp",
    "content": "# ifndef CPPAD_UTILITY_CREATE_DLL_LIB_HPP\n# define CPPAD_UTILITY_CREATE_DLL_LIB_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin create_dll_lib}\n{xrst_spell\n   cmd\n   csrc\n   hc\n   hs\n   msg\n}\n\nCreate a Dynamic Link Library\n#############################\n\nSyntax\n******\n| # ``include <cppad/utility/create_dll_lib.hpp>``\n| *err_msg* = ``create_dll_lib`` ( *dll_file* , *csrc_files* , *options* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_CREATE_DLL_LIB\n   // END_CREATE_DLL_LIB\n}\n\ninclude\n*******\nAs with all the CppAD utilities, ``create_dll_lib.hpp`` is included\nby ``<cppad/cppad.hpp>`` , and can also be included separately.\n\ndll_file\n********\nThis is the file where the dynamic link library file named *dll_file* .\nThis file name must have the proper extension for a dynamic link library\n(``.so`` on unix and ``.dll`` on windows).\n\nStringVector\n************\nThe type *StringVector* is a simple vector with elements\nof type ``std::string`` .\n\ncsrc_files\n**********\nThe vector *csrc_files* contains the names of the C source\nfiles that are compiled and linked to the library.\nThese files do not have to have a specific extension.\n\noptions\n*******\nThe possible keys in this map are documented below.\nThe default value for each key is used when the key\ndoes not appear in *options* .\n\ncompile\n=======\nThis is an abbreviated version of the compile command.\nIt does not include the output file flag or output file name.\nIf :ref:`cmake-name` detects that this is the MSVC compiler,\nthe default value for this option is\n\n   `cl /EHs /EHc /c /TC``\n\nIf cmake detects that this is the Clang or GNU compiler,\nthe default value for this option is\n\n   *cppad_c_compiler_cmd* ``-c -fPIC``\n\nHere and below *cppad_c_compiler_cmd* is the command used to run\nthe C compiler (which is determined by cmake) .\n\n\nlink\n====\nThis is an abbreviated version of the link command.\nIt does not include the output file flag or output file name.\nIn the MSVC case, the default for this option is\n\n   ``link /DLL``\n\nIn the Clang or GNU case, the default for this option is\n\n   *cppad_c_compiler_cmd* ``-shared`` .\n\n\nerr_msg\n*******\nIf this string is empty, no error occurred.\nOtherwise the processing aborted and *err_msg* is the corresponding\nerror message.\n\nExample\n*******\nThe file :ref:`dll_lib.cpp-name` contains an example and test of\n``create_dll_lib`` .\n\n{xrst_end create_dll_lib}\n*/\n# include <map>\n# include <cppad/local/temp_file.hpp>\n# include <cppad/configure.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n//\n// create\n// BEGIN_CREATE_DLL_LIB\ntemplate <class StringVector>\nstd::string create_dll_lib(\n   const std::string&                        dll_file   ,\n   const StringVector&                       csrc_files ,\n   const std::map<std::string, std::string>& options    )\n// END_CREATE_DLL_LIB\n{  using std::string;\n   //\n   // err_msg\n   string err_msg = \"\";\n   //\n   // compile, link\n   string compile = \"\";\n   string  link   = \"\";\n# if CPPAD_C_COMPILER_MSVC_FLAGS\n   compile = CPPAD_C_COMPILER_CMD \" /EHs /EHc /c /TC\";\n   link    = \"link /DLL\";\n# endif\n# if CPPAD_C_COMPILER_GNU_FLAGS\n   compile = CPPAD_C_COMPILER_CMD \" -c -fPIC\";\n   link    = CPPAD_C_COMPILER_CMD \" -shared\";\n# endif\n   for( const auto& pair : options )\n   {  const string& key = pair.first;\n      if( key == \"compile\" )\n         compile = pair.second;\n      else if( key == \"link\" )\n         link = pair.second;\n      else\n      {  err_msg = \"options contains following invalid key: \" + key;\n         return err_msg;\n      }\n   }\n   //\n   // check if we know how to create a dll with this compiler\n   if( compile == \"\" )\n   {  err_msg  = \"Do not know how to create a dll using this C compiler\\n\";\n      err_msg += CPPAD_C_COMPILER_CMD;\n      return err_msg;\n   }\n   //\n   // check the std::system function exists\n   int flag = std::system(nullptr);\n   if( flag == 0 )\n   {  err_msg = \"C++ std::system function not available\\n\";\n      return err_msg;\n   }\n   //\n   // check the file extensions\n# ifdef _WIN32\n   string dll_ext = \".dll\";\n# else\n   string dll_ext = \".so\";\n# endif\n   size_t last_match = dll_file.rfind(dll_ext);\n   size_t expected   = dll_file.size() - dll_ext.size();\n   if( last_match != expected )\n   {  err_msg += \"dll_file = \" + dll_file + \"\\ndoes not end with \" + dll_ext;\n      return err_msg;\n   }\n   //\n   // o_file_list, o_file_vec;\n   string       o_file_list;\n   StringVector o_file_vec( csrc_files.size() );\n   //\n   // i_csrc\n   for(size_t i_csrc = 0; i_csrc < csrc_files.size(); ++i_csrc)\n   {  //\n      // c_file\n      string c_file = csrc_files[i_csrc];\n      //\n      // o_file\n      string o_file = local::temp_file();\n      //\n      // cmd\n      string cmd = compile + \" \" + c_file;\n# ifdef _MSC_VER\n      cmd += \" /Fo\\\"\" + o_file + \"\\\" 1> nul 2> nul\";\n# else\n      cmd += \" -o \" + o_file;\n# endif\n      //\n      // o_file\n      // compile c_file and put result in o_file\n      flag = std::system( cmd.c_str() );\n      if(  flag != 0 )\n      {  err_msg = \"create_dll_lib: following system command failed\\n\";\n         err_msg += cmd;\n         return err_msg;\n      }\n      //\n      // o_file_list\n      o_file_list += \" \" + o_file;\n      //\n      // o_file_vec\n      o_file_vec[i_csrc] = o_file;\n   }\n   string cmd = link + \" \" + o_file_list;\n# ifdef _MSC_VER\n   cmd += \" /OUT:\" + dll_file + \" 1> nul 2> nul\";\n# else\n   cmd += \" -o \"   + dll_file;;\n# endif\n   flag = std::system( cmd.c_str() );\n   if(  flag != 0 )\n   {  err_msg = \"create_dll_lib: following system command failed\\n\";\n      err_msg += cmd;\n      return err_msg;\n   }\n   //\n   // remove o_file\n   for(size_t i = 0; i < o_file_vec.size(); ++i)\n   {  flag = std::remove( o_file_vec[i].c_str() );\n      if(  flag != 0 )\n      {  err_msg = \"create_dll_lib: following system command failed\\n\";\n         err_msg += cmd;\n         return err_msg;\n      }\n   }\n   return err_msg;\n}\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/elapsed_seconds.hpp",
    "content": "# ifndef CPPAD_UTILITY_ELAPSED_SECONDS_HPP\n# define CPPAD_UTILITY_ELAPSED_SECONDS_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin elapsed_seconds}\n{xrst_spell\n   chrono\n}\n\nReturns Elapsed Number of Seconds\n#################################\n\nSyntax\n******\n| # ``include <cppad/utility/elapsed_seconds.hpp>``\n| *s* = ``elapsed_seconds`` ()\n\nAccuracy\n********\nThis routine uses ``std::chrono::steady_clock`` to do its timing.\n\ns\n*\nis a ``double`` equal to the\nnumber of seconds since the first call to ``elapsed_seconds`` .\n{xrst_toc_hidden\n   speed/example/elapsed_seconds.cpp\n}\nExample\n*******\nThe routine :ref:`elapsed_seconds.cpp-name` is\nan example and test of this routine.\n\n{xrst_end elapsed_seconds}\n-----------------------------------------------------------------------\n*/\n\n# include <cppad/core/cppad_assert.hpp>\n\n// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\n// c++11 time function\n# include <chrono>\n\n\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\ninline double elapsed_seconds(void)\n// --------------------------------------------------------------------------\n{  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n   static bool first_ = true;\n   static std::chrono::time_point<std::chrono::steady_clock> start_;\n   if( first_ )\n   {  start_ = std::chrono::steady_clock::now();\n      first_ = false;\n      return 0.0;\n   }\n   std::chrono::time_point<std::chrono::steady_clock> now;\n   now   = std::chrono::steady_clock::now();\n   std::chrono::duration<double> difference = now - start_;\n   return difference.count();\n}\n// --------------------------------------------------------------------------\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/error_handler.hpp",
    "content": "# ifndef CPPAD_UTILITY_ERROR_HANDLER_HPP\n# define CPPAD_UTILITY_ERROR_HANDLER_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin ErrorHandler}\n{xrst_spell\n   msg\n   test test\n}\n\nReplacing the CppAD Error Handler\n#################################\n\nSyntax\n******\n| # ``include <cppad/utility/error_handler.hpp>``\n| ``ErrorHandler`` *info* ( *handler* )\n| ``ErrorHandler::Call`` ( *known* , *line* , *file* , *exp* , *msg* )\n\nConstructor\n***********\nWhen you construct a ``ErrorHandler`` object,\nthe current CppAD error handler is replaced by *handler* .\nWhen the object is destructed, the previous CppAD error handler is restored.\n\nParallel Mode\n=============\nThe ``ErrorHandler`` constructor and destructor cannot be called in\n:ref:`parallel<ta_in_parallel-name>` execution mode.\nIf this rule is not abided by, a raw C++ ``assert`` ,\ninstead of one that uses this error handler, will be generated.\n\nCall\n****\nWhen ``ErrorHandler::Call`` is called,\nthe current CppAD error handler is used to report an error.\nThis starts out as a default error handler and can be replaced\nusing the ``ErrorHandler`` constructor.\n\ninfo\n****\nThe object *info* is used to store information\nthat is necessary to restore the previous CppAD error handler.\nThis restoration is done when the destructor for *info* is called.\n\nhandler\n*******\nThe argument *handler* has prototype\n\n| |tab| ``void`` (* *handler* )\n| |tab| |tab| ( ``bool`` , ``int`` , ``const char`` * , ``const char`` * , ``const char`` * );\n\nWhen an error is detected,\nit is called with the syntax\n\n   *handler* ( *known* , *line* , *file* , *exp* , *msg* )\n\nThis routine should not return; i.e., upon detection of the error,\nthe routine calling *handler* does not know how to proceed.\n\nknown\n*****\nThe *handler* argument *known* has prototype\n\n   ``bool`` *known*\n\nIf it is true, the error being reported is from a know problem.\n\nline\n****\nThe *handler* argument *line* has prototype\n\n   ``int`` *line*\n\nIt reports the source code line number where the error is detected.\n\nfile\n****\nThe *handler* argument *file* has prototype\n\n   ``const char`` * *file*\n\nand is a ``'\\0'`` terminated character vector.\nIt reports the source code file where the error is detected.\n\nexp\n***\nThe *handler* argument *exp* has prototype\n\n   ``const char`` * *exp*\n\nand is a ``'\\0'`` terminated character vector.\nIt is a source code boolean expression that should have been true,\nbut is false,\nand thereby causes this call to *handler* .\n\nmsg\n***\nThe *handler* argument *msg* has prototype\n\n   ``const char`` * *msg*\n\nand is a ``'\\0'`` terminated character vector.\nIt reports the meaning of the error from the C++ programmers point of view.\n{xrst_toc_hidden\n   example/utility/error_handler.cpp\n   include/cppad/core/cppad_assert.hpp\n}\nExample\n*******\nThe file\n:ref:`error_handler.cpp-name`\ncontains an example and test a test of using this routine.\n\n{xrst_end ErrorHandler}\n---------------------------------------------------------------------------\n*/\n\n# include <iostream>\n\n# include <cppad/configure.hpp>\n# include <cppad/local/set_get_in_parallel.hpp>\n# include <cassert>\n# include <cstdlib>\n\nnamespace CppAD { // BEGIN CppAD namespace\n\nclass ErrorHandler {\n   template <class Base>\n   friend void parallel_ad(void);\npublic:\n   typedef void (*Handler)\n      (bool, int, const char *, const char *, const char *);\n\n   // construct a new handler\n   ErrorHandler(Handler handler) : previous( Current() )\n   {  if( local::set_get_in_parallel() )\n      {  bool known       = true;\n         int  line        = __LINE__;\n         const char* file = __FILE__;\n         const char* exp  = \"! local::set_get_in_parallel()\";\n         const char* msg  =\n            \"Using ErrorHandler constructor in parallel mode.\";\n         Call(known, line, file, exp, msg);\n      }\n      Current() = handler;\n   }\n\n   // destructor for an error handler\n   ~ErrorHandler(void)\n   {  if( local::set_get_in_parallel() )\n      {  bool known       = true;\n         int  line        = __LINE__;\n         const char* file = __FILE__;\n         const char* exp  = \"! local::set_get_in_parallel()\";\n         const char* msg  =\n            \"Using ErrorHandler destructor in parallel mode.\";\n         Call(known, line, file, exp, msg);\n      }\n      Current() = previous;\n   }\n\n   // report an error\n   static void Call(\n      bool        known,\n      int         line ,\n      const char *file ,\n      const char *exp  ,\n      const char *msg  )\n   {  Handler handler = Current();\n      handler(known, line, file, exp, msg);\n   }\n\nprivate:\n   const Handler previous;\n\n   // The default error handler\n   static void Default(\n      bool        known,\n      int         line ,\n      const char *file ,\n      const char *exp  ,\n      const char *msg  )\n   {  using std::cerr;\n      using std::endl;\n\n      cerr << CPPAD_PACKAGE_STRING;\n      if( known )\n         cerr << \" error from a known source:\" << endl;\n      else\n         cerr << \" error from unknown source\"  << endl;\n      if( msg[0] != '\\0' )\n         cerr << msg << endl;\n      cerr << \"Error detected by false result for\"  << endl;\n      cerr << \"    \"     << exp                     << endl;\n      cerr << \"at line \" << line << \" in the file \" << endl;\n      cerr << \"    \"     << file                    << endl;\n\n      // terminate program execution\n      assert(false);\n\n      // termination when NDEBUG is defined\n      std::exit(1);\n   }\n\n   // current error handler\n   static Handler &Current(void)\n   {  static bool first_call = true;\n      static Handler current = Default;\n      // CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n      // code below is like macro above but works when NDEBUG defined\n      if( first_call )\n      {  if( local::set_get_in_parallel() )\n         {  bool known       = false;\n            int  line        = __LINE__;\n            const char* file = __FILE__;\n            const char* exp  = \"\";\n            const char* msg  = \"\";\n            Call(known, line, file, exp, msg);\n         }\n         first_call = false;\n      }\n      return current;\n   }\n};\n\n} // END CppAD namespace\n\n\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/index_sort.hpp",
    "content": "# ifndef CPPAD_UTILITY_INDEX_SORT_HPP\n# define CPPAD_UTILITY_INDEX_SORT_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin index_sort}\n\nReturns Indices that Sort a Vector\n##################################\n\nSyntax\n******\n| # ``include <cppad/utility/index_sort.hpp>``\n| ``index_sort`` ( *keys* , *ind* )\n\nkeys\n****\nThe argument *keys* has prototype\n\n   ``const`` *KeyVector* & *keys*\n\nwhere *KeyVector* is\na :ref:`SimpleVector-name` class with elements that support the ``<``\noperation.\n\nind\n***\nThe argument *ind* has prototype\n\n   *SizeVector* & *ind*\n\nwhere *SizeVector* is\na :ref:`SimpleVector-name` class with elements of type *Size_t* ,\nwhere *Size_t* is an integral type.\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nInput\n=====\nThe size of *ind* must be the same as the size of *keys*\nand the value of its input elements does not matter.\n\nReturn\n======\nUpon return, *ind* is a permutation of the set of indices\nthat yields increasing order for *keys* .\nIn other words, for all *i* != *j* ,\n\n   *ind* [ *i* ] != *ind* [ *j* ]\n\nand for *i* = 0 , ... , *size* ``-2`` ,\n\n   ( *keys* [ *ind* [ *i* +1] ] < *keys* [ *ind* [ *i* ] ] ) == ``false``\n\nExample\n*******\n{xrst_toc_hidden\n   example/utility/index_sort.cpp\n}\nThe file :ref:`index_sort.cpp-name` contains an example\nand test of this routine.\nIt return true if it succeeds and false otherwise.\n\n{xrst_end index_sort}\n*/\n# include <algorithm>\n# include <cppad/utility/thread_alloc.hpp>\n# include <cppad/utility/check_simple_vector.hpp>\n# include <cppad/local/define.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file index_sort.hpp\nFile used to implement the CppAD index sort utility\n*/\n\n/*!\nHelper class used by index_sort\n*/\ntemplate <class Compare, class Size_t>\nclass index_sort_element {\nprivate:\n   /// key used to determine position of this element\n   Compare key_;\n   /// index value corresponding to this key\n   Size_t  index_;\npublic:\n   /// operator required by std::sort\n   bool operator<(const index_sort_element& other) const\n   {  return key_ < other.key_; }\n   /// set the key for this element\n   void set_key(const Compare& value)\n   {  key_ = value; }\n   /// set the index for this element\n   void set_index(const Size_t& index)\n   {  index_ = index; }\n   /// get the key for this element\n   Compare get_key(void) const\n   {  return key_; }\n   /// get the index for this element\n   Size_t get_index(void) const\n   {  return index_; }\n};\n\n/*!\nCompute the indices that sort a vector of keys\n\n\\tparam KeyVector\nSimple vector type that deterimene the sorting order by < operator\non its elements.\n\n\\tparam SizeVector\nSimple vector type with elements of size_t\nthat is used to return index values.\n\n\\param keys [in]\nvalues that determine the sorting order.\n\n\\param ind [out]\nmust have the same size as keys.\nThe input value of its elements does not matter.\nThe output value of its elements satisfy\n\\code\n( keys[ ind[i] ] < keys[ ind[i+1] ] ) == false\n\\endcode\n*/\ntemplate <class KeyVector, class SizeVector>\nvoid index_sort(const KeyVector& keys, SizeVector& ind)\n{  typedef typename KeyVector::value_type      Compare;\n   typedef typename SizeVector::value_type     Size_t;\n   typedef index_sort_element<Compare, Size_t> Element;\n   //\n   CheckSimpleVector<Size_t, SizeVector>();\n   //\n   CPPAD_ASSERT_KNOWN(\n      keys.size() == ind.size(),\n      \"index_sort: vector sizes do not match\"\n   );\n\n   size_t size_work = keys.size();\n   size_t size_out;\n   Element* work =\n      thread_alloc::create_array<Element>(size_work, size_out);\n\n   // copy initial order into work\n   size_t i;\n   for(i = 0; i < size_work; i++)\n   {  work[i].set_key( keys[i] );\n      work[i].set_index( Size_t(i) );\n   }\n\n   // sort the work array\n   std::sort(work, work+size_work);\n\n   // copy the indices to the output vector\n   for(i = 0; i < size_work; i++)\n      ind[i] = work[i].get_index();\n\n   // we are done with this work array\n   thread_alloc::delete_array(work);\n\n   return;\n}\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/link_dll_lib.hpp",
    "content": "# ifndef CPPAD_UTILITY_LINK_DLL_LIB_HPP\n# define CPPAD_UTILITY_LINK_DLL_LIB_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin link_dll_lib}\n{xrst_spell\n   msg\n}\n\nLink a Dynamic Link Library\n###########################\n\nSyntax\n******\n| # ``include <cppad/utility/link_dll_lib.hpp>``\n| ``link_dll_lib`` *dll_linker* ( *dll_file* , *err_msg* )\n| *fun_ptr* = *dll_linker* ( *function_name* , *err_msg* )\n|\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\ndll_linker\n**********\nIs the dynamic link object that holds an in memory version of the library,\n\nerr_msg\n*******\nIf *err_msg* is non-empty, it contains an error message\nfor the corresponding operation.\n\ndll_file\n********\nIs the file containing the dynamic link library.\n\nfunction_name\n*************\nIs the name of an external entry point in the dll.\n\nfun_ptr\n*******\nIs a ``void*`` version of a pointer the function corresponding to\n*function_name* .\n\nWarning !!\n==========\n*fun_ptr* becomes invalid when the *dll_linker* destructor is called.\n\n{xrst_toc_hidden\n   example/utility/dll_lib.cpp\n}\nExample\n*******\nThe file :ref:`dll_lib.cpp-name` contains an example and test of\n``link_dll_lib`` .\n\n{xrst_end link_dll_lib}\n*/\n\n# include <string>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\nclass link_dll_lib {\nprivate:\n   // pointer to the dll object\n   void* handle_;\n   //\n   // error message during constructor\n   std::string ctor_err_msg_;\n   //\n# ifdef _WIN32\n   static void*       dlopen(const char *filename, int flag);\n   static void*       dlsym(void* handle, const char* symbol);\n   static int         dlclose(void* handle);\n   static const char* dlerror(void);\n# endif\n   //\npublic:\n   // BEGIN_PROTOTYPE\n   link_dll_lib(const std::string& dll_file, std::string& err_msg);\n   ~link_dll_lib(void);\n   void* operator()\n   (const std::string& function_name, std::string& err_msg) const;\n   // END_PROTOTYPE\n};\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/lu_factor.hpp",
    "content": "# ifndef CPPAD_UTILITY_LU_FACTOR_HPP\n# define CPPAD_UTILITY_LU_FACTOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin LuFactor}\n{xrst_spell\n   geq\n   ip\n   jp\n}\n\nLU Factorization of A Square Matrix\n###################################\n\nSyntax\n******\n| # ``include <cppad/utility/lu_factor.hpp>``\n| *sign* = ``LuFactor`` ( *ip* , *jp* , *LU* )\n\nDescription\n***********\nComputes an LU factorization of the matrix *A*\nwhere *A* is a square matrix.\n\nInclude\n*******\nThe file ``cppad/utility/lu_factor.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\nMatrix Storage\n**************\nAll matrices are stored in row major order.\nTo be specific, if :math:`Y` is a vector\nthat contains a :math:`p` by :math:`q` matrix,\nthe size of :math:`Y` must be equal to :math:`p * q` and for\n:math:`i = 0 , \\ldots , p-1`,\n:math:`j = 0 , \\ldots , q-1`,\n\n.. math::\n\n   Y_{i,j} = Y[ i * q + j ]\n\nsign\n****\nThe return value *sign* has prototype\n\n   ``int`` *sign*\n\nIf *A* is invertible, *sign* is plus or minus one\nand is the sign of the permutation corresponding to the row ordering\n*ip* and column ordering *jp* .\nIf *A* is not invertible, *sign* is zero.\n\nip\n**\nThe argument *ip* has prototype\n\n   *SizeVector* & *ip*\n\n(see description of :ref:`LuFactor@SizeVector` below).\nThe size of *ip* is referred to as *n* in the\nspecifications below.\nThe input value of the elements of *ip* does not matter.\nThe output value of the elements of *ip* determine\nthe order of the rows in the permuted matrix.\n\njp\n**\nThe argument *jp* has prototype\n\n   *SizeVector* & *jp*\n\n(see description of :ref:`LuFactor@SizeVector` below).\nThe size of *jp* must be equal to *n* .\nThe input value of the elements of *jp* does not matter.\nThe output value of the elements of *jp* determine\nthe order of the columns in the permuted matrix.\n\nLU\n**\nThe argument *LU* has the prototype\n\n   *FloatVector* & *LU*\n\nand the size of *LU* must equal :math:`n * n`\n(see description of :ref:`LuFactor@FloatVector` below).\n\nA\n=\nWe define *A* as the matrix corresponding to the input\nvalue of *LU* .\n\nP\n=\nWe define the permuted matrix *P* in terms of *A* by\n\n   *P* ( *i* , *j* ) = *A* [ *ip* [ *i* ] * *n* + *jp* [ *j* ] ]\n\nL\n=\nWe define the lower triangular matrix *L* in terms of the\noutput value of *LU* .\nThe matrix *L* is zero above the diagonal\nand the rest of the elements are defined by\n\n   *L* ( *i* , *j* ) = *LU* [ *ip* [ *i* ] * *n* + *jp* [ *j* ] ]\n\nfor :math:`i = 0 , \\ldots , n-1` and :math:`j = 0 , \\ldots , i`.\n\nU\n=\nWe define the upper triangular matrix *U* in terms of the\noutput value of *LU* .\nThe matrix *U* is zero below the diagonal,\none on the diagonal,\nand the rest of the elements are defined by\n\n   *U* ( *i* , *j* ) = *LU* [ *ip* [ *i* ] * *n* + *jp* [ *j* ] ]\n\nfor :math:`i = 0 , \\ldots , n-2` and :math:`j = i+1 , \\ldots , n-1`.\n\nFactor\n======\nIf the return value *sign* is non-zero,\n\n   *L* * *U* = *P*\n\nIf the return value of *sign* is zero,\nthe contents of *L* and *U* are not defined.\n\nDeterminant\n===========\nIf the return value *sign* is zero,\nthe determinant of *A* is zero.\nIf *sign* is non-zero,\nusing the output value of *LU*\nthe determinant of the matrix *A* is equal to\n\n   *sign* * *LU* [ *ip* [0], *jp* [0]] * ... * *LU* [ *ip* [ *n* ``-1`` ], *jp* [ *n* ``-1`` ]]\n\nSizeVector\n**********\nThe type *SizeVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type size_t<SimpleVector@Elements of Specified Type>` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nFloatVector\n***********\nThe type *FloatVector* must be a\n:ref:`simple vector class<SimpleVector-name>` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nFloat\n*****\nThis notation is used to denote the type corresponding\nto the elements of a *FloatVector* .\nThe type *Float* must satisfy the conditions\nfor a :ref:`NumericType-name` .\nThe routine :ref:`CheckNumericType-name` will generate an error message\nif this is not the case.\nIn addition, the following operations must be defined for any pair\nof *Float* objects *x* and *y* :\n\n.. list-table::\n   :widths: auto\n\n   * - **Operation**\n     - **Description**\n   * - ``log`` ( *x* )\n     - returns the logarithm of *x* as a *Float* object\n\nAbsGeq\n******\nIncluding the file ``lu_factor.hpp`` defines the template function\n\n| |tab| ``template <class`` *Float* >\n| |tab| ``bool AbsGeq`` < *Float* >( ``const`` *Float* & *x* , ``const`` *Float* & *y* )\n\nin the ``CppAD`` namespace.\nThis function returns true if the absolute value of\n*x* is greater than or equal the absolute value of *y* .\nIt is used by ``LuFactor`` to choose the pivot elements.\nThis template function definition uses the operator\n``<=`` to obtain the absolute value for *Float* objects.\nIf this operator is not defined for your use of *Float* ,\nyou will need to specialize this template so that it works for your\nuse of ``LuFactor`` .\n\nComplex numbers do not have the operation ``<=`` defined.\nThe specializations\n\n| ``bool AbsGeq< std::complex<float> >``\n| |tab| ( ``const std::complex<float> &`` *x* , ``const std::complex<float> &`` *y* )\n| ``bool AbsGeq< std::complex<double> >``\n| |tab| ( ``const std::complex<double> &`` *x* , ``const std::complex<double> &`` *y* )\n\nare define by including ``lu_factor.hpp``\nThese return true if the sum of the square of the real and imaginary parts\nof *x* is greater than or equal the\nsum of the square of the real and imaginary parts of *y* .\n{xrst_toc_hidden\n   example/utility/lu_factor.cpp\n   xrst/lu_factor_hpp.xrst\n}\nExample\n*******\nThe file\n:ref:`lu_factor.cpp-name`\ncontains an example and test of using ``LuFactor`` by itself.\n\nThe file :ref:`lu_solve.hpp-name` provides a useful example usage of\n``LuFactor`` with ``LuInvert`` .\n\nSource\n******\nThe file :ref:`lu_factor.hpp-name` contains the\ncurrent source code that implements these specifications.\n\n{xrst_end LuFactor}\n--------------------------------------------------------------------------\n*/\n// BEGIN C++\n\n# include <complex>\n# include <vector>\n\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/utility/check_simple_vector.hpp>\n# include <cppad/utility/check_numeric_type.hpp>\n\nnamespace CppAD { // BEGIN CppAD namespace\n\n// AbsGeq\ntemplate <class Float>\nbool AbsGeq(const Float &x, const Float &y)\n{  Float xabs = x;\n   if( xabs <= Float(0) )\n      xabs = - xabs;\n   Float yabs = y;\n   if( yabs <= Float(0) )\n      yabs = - yabs;\n   return xabs >= yabs;\n}\ninline bool AbsGeq(\n   const std::complex<double> &x,\n   const std::complex<double> &y)\n{  double xsq = x.real() * x.real() + x.imag() * x.imag();\n   double ysq = y.real() * y.real() + y.imag() * y.imag();\n\n   return xsq >= ysq;\n}\ninline bool AbsGeq(\n   const std::complex<float> &x,\n   const std::complex<float> &y)\n{  float xsq = x.real() * x.real() + x.imag() * x.imag();\n   float ysq = y.real() * y.real() + y.imag() * y.imag();\n\n   return xsq >= ysq;\n}\n\n// Lines that are different from code in cppad/core/lu_ratio.hpp end with //\ntemplate <class SizeVector, class FloatVector>                          //\nint LuFactor(SizeVector &ip, SizeVector &jp, FloatVector &LU)           //\n{\n   // type of the elements of LU                                   //\n   typedef typename FloatVector::value_type Float;                 //\n\n   // check numeric type specifications\n   CheckNumericType<Float>();\n\n   // check simple vector class specifications\n   CheckSimpleVector<Float, FloatVector>();\n   CheckSimpleVector<size_t, SizeVector>();\n\n   size_t  i, j;          // some temporary indices\n   const Float zero( 0 ); // the value zero as a Float object\n   size_t  imax;          // row index of maximum element\n   size_t  jmax;          // column index of maximum element\n   Float    emax;         // maximum absolute value\n   size_t  p;             // count pivots\n   int     sign;          // sign of the permutation\n   Float   etmp;          // temporary element\n   Float   pivot;         // pivot element\n\n   // -------------------------------------------------------\n   size_t n = ip.size();\n   CPPAD_ASSERT_KNOWN(\n      size_t(jp.size()) == n,\n      \"Error in LuFactor: jp must have size equal to n\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(LU.size()) == n * n,\n      \"Error in LuFactor: LU must have size equal to n * m\"\n   );\n   // -------------------------------------------------------\n\n   // initialize row and column order in matrix not yet pivoted\n   for(i = 0; i < n; i++)\n   {  ip[i] = i;\n      jp[i] = i;\n   }\n   // initialize the sign of the permutation\n   sign = 1;\n   // ---------------------------------------------------------\n\n   // Reduce the matrix P to L * U using n pivots\n   for(p = 0; p < n; p++)\n   {  // determine row and column corresponding to element of\n      // maximum absolute value in remaining part of P\n      imax = jmax = n;\n      emax = zero;\n      for(i = p; i < n; i++)\n      {  for(j = p; j < n; j++)\n         {  CPPAD_ASSERT_UNKNOWN(\n               (ip[i] < n) && (jp[j] < n)\n            );\n            etmp = LU[ ip[i] * n + jp[j] ];\n\n            // check if maximum absolute value so far\n            if( AbsGeq (etmp, emax) )\n            {  imax = i;\n               jmax = j;\n               emax = etmp;\n            }\n         }\n      }\n      CPPAD_ASSERT_KNOWN(\n      (imax < n) && (jmax < n) ,\n      \"LuFactor can't determine an element with \"\n      \"maximum absolute value.\\n\"\n      \"Perhaps original matrix contains not a number or infinity.\\n\"\n      \"Perhaps your specialization of AbsGeq is not correct.\"\n      );\n      if( imax != p )\n      {  // switch rows so max absolute element is in row p\n         i        = ip[p];\n         ip[p]    = ip[imax];\n         ip[imax] = i;\n         sign     = -sign;\n      }\n      if( jmax != p )\n      {  // switch columns so max absolute element is in column p\n         j        = jp[p];\n         jp[p]    = jp[jmax];\n         jp[jmax] = j;\n         sign     = -sign;\n      }\n      // pivot using the max absolute element\n      pivot   = LU[ ip[p] * n + jp[p] ];\n\n      // check for determinant equal to zero\n      if( pivot == zero )\n      {  // abort the mission\n         return   0;\n      }\n\n      // Reduce U by the elementary transformations that maps\n      // LU( ip[p], jp[p] ) to one.  Only need transform elements\n      // above the diagonal in U and LU( ip[p] , jp[p] ) is\n      // corresponding value below diagonal in L.\n      for(j = p+1; j < n; j++)\n         LU[ ip[p] * n + jp[j] ] /= pivot;\n\n      // Reduce U by the elementary transformations that maps\n      // LU( ip[i], jp[p] ) to zero. Only need transform elements\n      // above the diagonal in U and LU( ip[i], jp[p] ) is\n      // corresponding value below diagonal in L.\n      for(i = p+1; i < n; i++ )\n      {  etmp = LU[ ip[i] * n + jp[p] ];\n         for(j = p+1; j < n; j++)\n         {  LU[ ip[i] * n + jp[j] ] -=\n               etmp * LU[ ip[p] * n + jp[j] ];\n         }\n      }\n   }\n   return sign;\n}\n} // END CppAD namespace\n// END C++\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/lu_invert.hpp",
    "content": "# ifndef CPPAD_UTILITY_LU_INVERT_HPP\n# define CPPAD_UTILITY_LU_INVERT_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin LuInvert}\n{xrst_spell\n   ip\n   jp\n}\n\nInvert an LU Factored Equation\n##############################\n\nSyntax\n******\n| # ``include <cppad/utility/lu_invert.hpp>``\n| ``LuInvert`` ( *ip* , *jp* , *LU* , *X* )\n\nDescription\n***********\nSolves the matrix equation *A* * *X* = *B*\nusing an LU factorization computed by :ref:`LuFactor-name` .\n\nInclude\n*******\nThe file ``cppad/utility/lu_invert.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\nMatrix Storage\n**************\nAll matrices are stored in row major order.\nTo be specific, if :math:`Y` is a vector\nthat contains a :math:`p` by :math:`q` matrix,\nthe size of :math:`Y` must be equal to :math:`p * q` and for\n:math:`i = 0 , \\ldots , p-1`,\n:math:`j = 0 , \\ldots , q-1`,\n\n.. math::\n\n   Y_{i,j} = Y[ i * q + j ]\n\nip\n**\nThe argument *ip* has prototype\n\n   ``const`` *SizeVector* & *ip*\n\n(see description for *SizeVector* in\n:ref:`LuFactor<LuFactor@SizeVector>` specifications).\nThe size of *ip* is referred to as *n* in the\nspecifications below.\nThe elements of *ip* determine\nthe order of the rows in the permuted matrix.\n\njp\n**\nThe argument *jp* has prototype\n\n   ``const`` *SizeVector* & *jp*\n\n(see description for *SizeVector* in\n:ref:`LuFactor<LuFactor@SizeVector>` specifications).\nThe size of *jp* must be equal to *n* .\nThe elements of *jp* determine\nthe order of the columns in the permuted matrix.\n\nLU\n**\nThe argument *LU* has the prototype\n\n   ``const`` *FloatVector* & *LU*\n\nand the size of *LU* must equal :math:`n * n`\n(see description for *FloatVector* in\n:ref:`LuFactor<LuFactor@FloatVector>` specifications).\n\nL\n=\nWe define the lower triangular matrix *L* in terms of *LU* .\nThe matrix *L* is zero above the diagonal\nand the rest of the elements are defined by\n\n   *L* ( *i* , *j* ) = *LU* [ *ip* [ *i* ] * *n* + *jp* [ *j* ] ]\n\nfor :math:`i = 0 , \\ldots , n-1` and :math:`j = 0 , \\ldots , i`.\n\nU\n=\nWe define the upper triangular matrix *U* in terms of *LU* .\nThe matrix *U* is zero below the diagonal,\none on the diagonal,\nand the rest of the elements are defined by\n\n   *U* ( *i* , *j* ) = *LU* [ *ip* [ *i* ] * *n* + *jp* [ *j* ] ]\n\nfor :math:`i = 0 , \\ldots , n-2` and :math:`j = i+1 , \\ldots , n-1`.\n\nP\n=\nWe define the permuted matrix *P* in terms of\nthe matrix *L* and the matrix *U*\nby *P* = *L* * *U* .\n\nA\n=\nThe matrix *A* ,\nwhich defines the linear equations that we are solving, is given by\n\n   *P* ( *i* , *j* ) = *A* [ *ip* [ *i* ] * *n* + *jp* [ *j* ] ]\n\n(Hence\n*LU* contains a permuted factorization of the matrix *A* .)\n\nX\n*\nThe argument *X* has prototype\n\n   *FloatVector* & *X*\n\n(see description for *FloatVector* in\n:ref:`LuFactor<LuFactor@FloatVector>` specifications).\nThe matrix *X*\nmust have the same number of rows as the matrix *A* .\nThe input value of *X* is the matrix *B* and the\noutput value solves the matrix equation *A* * *X* = *B* .\n{xrst_toc_hidden\n   example/utility/lu_invert.cpp\n   xrst/lu_invert_hpp.xrst\n}\nExample\n*******\nThe file :ref:`lu_solve.hpp-name` is a good example usage of\n``LuFactor`` with ``LuInvert`` .\nThe file\n:ref:`lu_invert.cpp-name`\ncontains an example and test of using ``LuInvert`` by itself.\n\nSource\n******\nThe file :ref:`lu_invert.hpp-name` contains the\ncurrent source code that implements these specifications.\n\n{xrst_end LuInvert}\n--------------------------------------------------------------------------\n*/\n// BEGIN C++\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/utility/check_simple_vector.hpp>\n# include <cppad/utility/check_numeric_type.hpp>\n\nnamespace CppAD { // BEGIN CppAD namespace\n\n// LuInvert\ntemplate <class SizeVector, class FloatVector>\nvoid LuInvert(\n   const SizeVector  &ip,\n   const SizeVector  &jp,\n   const FloatVector &LU,\n   FloatVector       &B )\n{  size_t k; // column index in X\n   size_t p; // index along diagonal in LU\n   size_t i; // row index in LU and X\n\n   typedef typename FloatVector::value_type Float;\n\n   // check numeric type specifications\n   CheckNumericType<Float>();\n\n   // check simple vector class specifications\n   CheckSimpleVector<Float, FloatVector>();\n   CheckSimpleVector<size_t, SizeVector>();\n\n   Float etmp;\n\n   size_t n = ip.size();\n   CPPAD_ASSERT_KNOWN(\n      size_t(jp.size()) == n,\n      \"Error in LuInvert: jp must have size equal to n * n\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(LU.size()) == n * n,\n      \"Error in LuInvert: Lu must have size equal to n * m\"\n   );\n   size_t m = size_t(B.size()) / n;\n   CPPAD_ASSERT_KNOWN(\n      size_t(B.size()) == n * m,\n      \"Error in LuSolve: B must have size equal to a multiple of n\"\n   );\n\n   // temporary storage for reordered solution\n   FloatVector x(n);\n\n   // loop over equations\n   for(k = 0; k < m; k++)\n   {  // invert the equation c = L * b\n      for(p = 0; p < n; p++)\n      {  // solve for c[p]\n         etmp = B[ ip[p] * m + k ] / LU[ ip[p] * n + jp[p] ];\n         B[ ip[p] * m + k ] = etmp;\n         // subtract off effect on other variables\n         for(i = p+1; i < n; i++)\n            B[ ip[i] * m + k ] -=\n               etmp * LU[ ip[i] * n + jp[p] ];\n      }\n\n      // invert the equation x = U * c\n      p = n;\n      while( p > 0 )\n      {  --p;\n         etmp       = B[ ip[p] * m + k ];\n         x[ jp[p] ] = etmp;\n         for(i = 0; i < p; i++ )\n            B[ ip[i] * m + k ] -=\n               etmp * LU[ ip[i] * n + jp[p] ];\n      }\n\n      // copy reordered solution into B\n      for(i = 0; i < n; i++)\n         B[i * m + k] = x[i];\n   }\n   return;\n}\n} // END CppAD namespace\n// END C++\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/lu_solve.hpp",
    "content": "# ifndef CPPAD_UTILITY_LU_SOLVE_HPP\n# define CPPAD_UTILITY_LU_SOLVE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin LuSolve}\n{xrst_spell\n   geq\n   leq\n   logdet\n   signdet\n}\n\nCompute Determinant and Solve Linear Equations\n##############################################\n\nSyntax\n******\n| # ``include <cppad/utility/lu_solve.hpp>``\n| *signdet* = ``LuSolve`` ( *n* , *m* , *A* , *B* , *X* , *logdet* )\n\nDescription\n***********\nUse an LU factorization of the matrix *A* to\ncompute its determinant\nand solve for *X* in the linear of equation\n\n.. math::\n\n   A * X = B\n\nwhere *A* is an\n*n* by *n* matrix,\n*X* is an\n*n* by *m* matrix, and\n*B* is an :math:`n x m` matrix.\n\nInclude\n*******\nThe file ``cppad/utility/lu_solve.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\nFactor and Invert\n*****************\nThis routine is an easy to user interface to\n:ref:`LuFactor-name` and :ref:`LuInvert-name` for computing determinants and\nsolutions of linear equations.\nThese separate routines should be used if\none right hand side *B*\ndepends on the solution corresponding to another\nright hand side (with the same value of *A* ).\nIn this case only one call to ``LuFactor`` is required\nbut there will be multiple calls to ``LuInvert`` .\n\nMatrix Storage\n**************\nAll matrices are stored in row major order.\nTo be specific, if :math:`Y` is a vector\nthat contains a :math:`p` by :math:`q` matrix,\nthe size of :math:`Y` must be equal to :math:`p * q` and for\n:math:`i = 0 , \\ldots , p-1`,\n:math:`j = 0 , \\ldots , q-1`,\n\n.. math::\n\n   Y_{i,j} = Y[ i * q + j ]\n\nsigndet\n*******\nThe return value *signdet* is a ``int`` value\nthat specifies the sign factor for the determinant of *A* .\nThis determinant of *A* is zero if and only if *signdet*\nis zero.\n\nn\n*\nThe argument *n* has type ``size_t``\nand specifies the number of rows in the matrices\n*A* ,\n*X* ,\nand *B* .\nThe number of columns in *A* is also equal to *n* .\n\nm\n*\nThe argument *m* has type ``size_t``\nand specifies the number of columns in the matrices\n*X*\nand *B* .\nIf *m* is zero,\nonly the determinant of *A* is computed and\nthe matrices *X* and *B* are not used.\n\nA\n*\nThe argument *A* has the prototype\n\n   ``const`` *FloatVector* & *A*\n\nand the size of *A* must equal :math:`n * n`\n(see description of :ref:`LuSolve@FloatVector` below).\nThis is the :math:`n` by *n* matrix that\nwe are computing the determinant of\nand that defines the linear equation.\n\nB\n*\nThe argument *B* has the prototype\n\n   ``const`` *FloatVector* & *B*\n\nand the size of *B* must equal :math:`n * m`\n(see description of :ref:`LuSolve@FloatVector` below).\nThis is the :math:`n` by *m* matrix that\ndefines the right hand side of the linear equations.\nIf *m* is zero, *B* is not used.\n\nX\n*\nThe argument *X* has the prototype\n\n   *FloatVector* & *X*\n\nand the size of *X* must equal :math:`n * m`\n(see description of :ref:`LuSolve@FloatVector` below).\nThe input value of *X* does not matter.\nOn output, the elements of *X* contain the solution\nof the equation we wish to solve\n(unless *signdet* is equal to zero).\nIf *m* is zero, *X* is not used.\n\nlogdet\n******\nThe argument *logdet* has prototype\n\n   *Float* & *logdet*\n\nOn input, the value of *logdet* does not matter.\nOn output, it has been set to the\nlog of the determinant of *A*\n(but not quite).\nTo be more specific,\nthe determinant of *A* is given by the formula\n\n   *det* = *signdet* * ``exp`` ( *logdet*  )\n\nThis enables ``LuSolve`` to use logs of absolute values\nin the case where *Float* corresponds to a real number.\n\nFloat\n*****\nThe type *Float* must satisfy the conditions\nfor a :ref:`NumericType-name` .\nThe routine :ref:`CheckNumericType-name` will generate an error message\nif this is not the case.\nIn addition, the following operations must be defined for any pair\nof *Float* objects *x* and *y* :\n\n.. list-table::\n   :widths: auto\n\n   * - **Operation**\n     - **Description**\n   * - ``log`` ( *x* )\n     - returns the logarithm of *x* as a *Float* object\n\nFloatVector\n***********\nThe type *FloatVector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type Float<SimpleVector@Elements of Specified Type>` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nLeqZero\n*******\nIncluding the file ``lu_solve.hpp`` defines the template function\n\n| |tab| ``template <class`` *Float* >\n| |tab| ``bool LeqZero`` < *Float* >( ``const`` *Float* & *x* )\n\nin the ``CppAD`` namespace.\nThis function returns true if *x* is less than or equal to zero\nand false otherwise.\nIt is used by ``LuSolve`` to avoid taking the log of\nzero (or a negative number if *Float* corresponds to real numbers).\nThis template function definition assumes that the operator\n``<=`` is defined for *Float* objects.\nIf this operator is not defined for your use of *Float* ,\nyou will need to specialize this template so that it works for your\nuse of ``LuSolve`` .\n\nComplex numbers do not have the operation or ``<=`` defined.\nIn addition, in the complex case,\none can take the log of a negative number.\nThe specializations\n\n| |tab| ``bool LeqZero< std::complex<float> >`` ( ``const std::complex<float> &`` *x* )\n| |tab| ``bool LeqZero< std::complex<double> >`` ( ``const std::complex<double> &`` *x* )\n\nare defined by including ``lu_solve.hpp`` .\nThese return true if *x* is zero and false otherwise.\n\nAbsGeq\n******\nIncluding the file ``lu_solve.hpp`` defines the template function\n\n| |tab| ``template <class`` *Float* >\n| |tab| ``bool AbsGeq`` < *Float* >( ``const`` *Float* & *x* , ``const`` *Float* & *y* )\n\nIf the type *Float* does not support the ``<=`` operation\nand it is not ``std::complex<float>`` or ``std::complex<double>`` ,\nsee the documentation for ``AbsGeq`` in :ref:`LuFactor<LuFactor@AbsGeq>` .\n{xrst_toc_hidden\n   example/utility/lu_solve.cpp\n   xrst/lu_solve_hpp.xrst\n}\nExample\n*******\nThe file\n:ref:`lu_solve.cpp-name`\ncontains an example and test of using this routine.\n\nSource\n******\nThe file :ref:`lu_solve.hpp-name` contains the\ncurrent source code that implements these specifications.\n\n{xrst_end LuSolve}\n--------------------------------------------------------------------------\n*/\n// BEGIN C++\n# include <complex>\n# include <vector>\n\n// link exp for float and double cases\n# include <cppad/base_require.hpp>\n\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/utility/check_simple_vector.hpp>\n# include <cppad/utility/check_numeric_type.hpp>\n# include <cppad/utility/lu_factor.hpp>\n# include <cppad/utility/lu_invert.hpp>\n\nnamespace CppAD { // BEGIN CppAD namespace\n\n// LeqZero\ntemplate <class Float>\nbool LeqZero(const Float &x)\n{  return x <= Float(0); }\ninline bool LeqZero( const std::complex<double> &x )\n{  return x == std::complex<double>(0); }\ninline bool LeqZero( const std::complex<float> &x )\n{  return x == std::complex<float>(0); }\n\n// LuSolve\ntemplate <class Float, class FloatVector>\nint LuSolve(\n   size_t             n      ,\n   size_t             m      ,\n   const FloatVector &A      ,\n   const FloatVector &B      ,\n   FloatVector       &X      ,\n   Float        &logdet      )\n{\n   // check numeric type specifications\n   CheckNumericType<Float>();\n\n   // check simple vector class specifications\n   CheckSimpleVector<Float, FloatVector>();\n\n   size_t        p;       // index of pivot element (diagonal of L)\n   int     signdet;       // sign of the determinant\n   Float     pivot;       // pivot element\n\n   // the value zero\n   const Float zero(0);\n\n   // pivot row and column order in the matrix\n   std::vector<size_t> ip(n);\n   std::vector<size_t> jp(n);\n\n   // -------------------------------------------------------\n   CPPAD_ASSERT_KNOWN(\n      size_t(A.size()) == n * n,\n      \"Error in LuSolve: A must have size equal to n * n\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(B.size()) == n * m,\n      \"Error in LuSolve: B must have size equal to n * m\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(X.size()) == n * m,\n      \"Error in LuSolve: X must have size equal to n * m\"\n   );\n   // -------------------------------------------------------\n\n   // copy A so that it does not change\n   FloatVector Lu(A);\n\n   // copy B so that it does not change\n   X = B;\n\n   // Lu factor the matrix A\n   signdet = LuFactor(ip, jp, Lu);\n\n   // compute the log of the determinant\n   logdet  = Float(0);\n   for(p = 0; p < n; p++)\n   {  // pivot using the max absolute element\n      pivot   = Lu[ ip[p] * n + jp[p] ];\n\n      // check for determinant equal to zero\n      if( pivot == zero )\n      {  // abort the mission\n         logdet = Float(0);\n         return   0;\n      }\n\n      // update the determinant\n      if( LeqZero ( pivot ) )\n      {  logdet += log( - pivot );\n         signdet = - signdet;\n      }\n      else\n         logdet += log( pivot );\n\n   }\n\n   // solve the linear equations\n   LuInvert(ip, jp, Lu, X);\n\n   // return the sign factor for the determinant\n   return signdet;\n}\n} // END CppAD namespace\n// END C++\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/memory_leak.hpp",
    "content": "# ifndef CPPAD_UTILITY_MEMORY_LEAK_HPP\n# define CPPAD_UTILITY_MEMORY_LEAK_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin memory_leak app}\n\nMemory Leak Detection\n#####################\n\nDeprecated 2012-04-06\n*********************\nThis routine has been deprecated.\nYou should instead use the routine :ref:`ta_free_all-name` .\n\nSyntax\n******\n| # ``include <cppad/utility/memory_leak.hpp>``\n| ``flag`` = ``memory_leak`` ()\n| *flag* = *memory_leak* ( *add_static* )\n\nPurpose\n*******\nThis routine checks that the are no memory leaks\ncaused by improper use of :ref:`thread_alloc-name` memory allocator.\nThe deprecated memory allocator :ref:`track_new_del-name` is also checked.\nMemory errors in the deprecated :ref:`omp_alloc-name` allocator are\nreported as being in ``thread_alloc`` .\n\nthread\n******\nIt is assumed that :ref:`in_parallel()<ta_in_parallel-name>` is false\nand :ref:`thread_num<ta_thread_num-name>` is zero when\n``memory_leak`` is called.\n\nadd_static\n**********\nThis argument has prototype\n\n   ``size_t`` *add_static*\n\nand its default value is zero.\nStatic variables hold onto memory forever.\nIf the argument *add_static* is present (and non-zero),\n``memory_leak`` adds this amount of memory to the\n:ref:`inuse<ta_inuse-name>` sum that corresponds to\nstatic variables in the program.\nA call with *add_static* should be make after\na routine that has static variables which\nuse :ref:`get_memory<ta_get_memory-name>` to allocate memory.\nThe value of *add_static* should be the difference of\n\n   ``thread_alloc::inuse`` (0)\n\nbefore and after the call.\nSince multiple statics may be allocated in different places in the program,\nit is expected that there will be multiple calls\nthat use this option.\n\nflag\n****\nThe return value *flag* has prototype\n\n   ``bool`` *flag*\n\nIf *add_static* is non-zero,\nthe return value for ``memory_leak`` is false.\nOtherwise, the return value for ``memory_leak`` should be false\n(indicating that the only allocated memory corresponds to static variables).\n\ninuse\n*****\nIt is assumed that, when ``memory_leak`` is called,\nthere should not be any memory\n:ref:`inuse<ta_inuse-name>` or :ref:`omp_inuse-name` for any thread\n(except for inuse memory corresponding to static variables).\nIf there is, a message is printed and ``memory_leak`` returns false.\n\navailable\n*********\nIt is assumed that, when ``memory_leak`` is called,\nthere should not be any memory\n:ref:`available<ta_available-name>` or :ref:`omp_available-name` for any thread;\ni.e., it all has been returned to the system.\nIf there is memory still available for any thread,\n``memory_leak`` returns false.\n\nTRACK_COUNT\n***********\nIt is assumed that, when ``memory_leak`` is called,\n:ref:`track_new_del@TrackCount` will return a zero value.\nIf it returns a non-zero value,\n``memory_leak`` returns false.\n\nError Message\n*************\nIf this is the first call to ``memory_leak`` , no message is printed.\nOtherwise, if it returns true, an error message is printed\nto standard output describing the memory leak that was detected.\n\n{xrst_end memory_leak}\n*/\n# include <iostream>\n# include <cppad/local/define.hpp>\n# include <cppad/utility/omp_alloc.hpp>\n# include <cppad/utility/thread_alloc.hpp>\n# include <cppad/utility/track_new_del.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file memory_leak.hpp\nFile that implements a memory check at end of a CppAD program\n*/\n\n/*!\nFunction that checks\nallocator thread_alloc for misuse that results in memory leaks.\nDeprecated routines in track_new_del.hpp and omp_alloc.hpp are also checked.\n\n\\param add_static [in]\nThe amount specified by add_static is added to the amount\nof memory that is expected to be used by thread zero for static variables.\n\n\\return\nIf add_static is non-zero, the return value is false.\nOtherwise, if one of the following errors is detected,\nthe return value is true:\n\n\\li\nThread zero does not have the expected amount of inuse memory\n(for static variables).\n\\li\nA thread, other than thread zero, has any inuse memory.\n\\li\nAny thread has available memory.\n\n\\par\nIf an error is detected, diagnostic information is printed to standard\noutput.\n*/\ninline bool memory_leak(size_t add_static = 0)\n{  // CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL not necessary given asserts below\n   static size_t thread_zero_static_inuse     = 0;\n   using std::cout;\n   using std::endl;\n   using CppAD::thread_alloc;\n   using CppAD::omp_alloc;\n   // --------------------------------------------------------------------\n   CPPAD_ASSERT_KNOWN(\n      ! thread_alloc::in_parallel(),\n      \"memory_leak: in_parallel() is true.\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      thread_alloc::thread_num() == 0,\n      \"memory_leak: thread_num() is not zero.\"\n   );\n   if( add_static != 0 )\n   {  thread_zero_static_inuse += add_static;\n      return false;\n   }\n   bool leak                 = false;\n   size_t thread             = 0;\n\n   // check that memory in use for thread zero corresponds to statics\n   size_t num_bytes = thread_alloc::inuse(thread);\n   if( num_bytes != thread_zero_static_inuse )\n   {  leak = true;\n      cout << \"thread zero: static inuse = \" << thread_zero_static_inuse;\n      cout << \", current inuse(0)= \" << num_bytes << endl;\n   }\n   // check that no memory is currently available for this thread\n   num_bytes = thread_alloc::available(thread);\n   if( num_bytes != 0 )\n   {  leak = true;\n      cout << \"thread zero: available    = \";\n      cout << num_bytes << endl;\n   }\n   for(thread = 1; thread < CPPAD_MAX_NUM_THREADS; thread++)\n   {\n      // check that no memory is currently in use for this thread\n      num_bytes = thread_alloc::inuse(thread);\n      if( num_bytes != 0 )\n      {  leak = true;\n         cout << \"thread \" << thread << \": inuse(thread) = \";\n         cout << num_bytes << endl;\n      }\n      // check that no memory is currently available for this thread\n      num_bytes = thread_alloc::available(thread);\n      if( num_bytes != 0 )\n      {  leak = true;\n         cout << \"thread \" << thread << \": available(thread) = \";\n         cout << num_bytes << endl;\n      }\n   }\n   // ----------------------------------------------------------------------\n   // check track_new_del\n   if( CPPAD_TRACK_COUNT() != 0 )\n   {  leak = true;\n      CppAD::TrackElement::Print();\n   }\n   return leak;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/nan.hpp",
    "content": "# ifndef CPPAD_UTILITY_NAN_HPP\n# define CPPAD_UTILITY_NAN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin nan}\n{xrst_spell\n   hasnan\n   isnan\n}\n\nObtain Nan or Determine if a Value is Nan\n#########################################\n\nSyntax\n******\n| # ``include <cppad/utility/nan.hpp>``\n| *b* = ``CppAD::isnan`` ( *s* )\n| *b* = ``hasnan`` ( *v* )\n\nPurpose\n*******\nCheck for the value not a number ``nan`` .\nThe IEEE standard specifies that a floating point value *a*\nis ``nan`` if and only if the following returns true\n\n   *a* != *a*\n\nstd::isnan\n**********\nSome compilers; e.g. Visual Studio, result in an ambiguous error\nbetween ``CppAD::isnan`` and ``std::isnan`` unless you include the ``CppAD``\nbefore ``isnan`` (even when inside the CppAD namespace).\n\nInclude\n*******\nThe file ``cppad/utility/nan.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\nMacros\n======\nSome C++ compilers use preprocessor symbols called ``nan``\nand ``isnan`` .\nThese preprocessor symbols will no longer be defined after\nthis file is included.\n\nisnan\n*****\nThis routine determines if a scalar value is ``nan`` .\n\ns\n=\nThe argument *s* has prototype\n\n   ``const`` *Scalar* *s*\n\nb\n=\nThe return value *b* has prototype\n\n   ``bool`` *b*\n\nIt is true if the value *s* is ``nan`` .\n\nhasnan\n******\nThis routine determines if a\n:ref:`SimpleVector-name` has an element that is ``nan`` .\n\nv\n=\nThe argument *v* has prototype\n\n   ``const`` *Vector* & *v*\n\n(see :ref:`nan@Vector` for the definition of *Vector* ).\n\nb\n=\nThe return value *b* has prototype\n\n   ``bool`` *b*\n\nIt is true if the vector *v* has a ``nan`` .\n\nnan(zero)\n*********\n\nDeprecated 2015-10-04\n=====================\nThis routine has been deprecated, use CppAD numeric limits\n:ref:`numeric_limits@quiet_NaN` in its place.\n\nSyntax\n======\n\n   *s* = ``nan`` ( *z* )\n\nz\n=\nThe argument *z* has prototype\n\n   ``const`` *Scalar* & *z*\n\nand its value is zero\n(see :ref:`nan@Scalar` for the definition of *Scalar* ).\n\ns\n=\nThe return value *s* has prototype\n\n   *Scalar* *s*\n\nIt is the value ``nan`` for this floating point type.\n\nScalar\n******\nThe type *Scalar* must support the following operations;\n\n.. list-table::\n   :widths: auto\n\n   * - **Operation**\n     - **Description**\n   * - *a* / *b*\n     - division operator (returns a *Scalar* object)\n   * - *a* == *b*\n     - equality operator (returns a ``bool`` object)\n   * - *a* != *b*\n     - not equality operator (returns a ``bool`` object)\n\nNote that the division operator will be used with *a* and *b*\nequal to zero. For some types (e.g. ``int`` ) this may generate\nan exception. No attempt is made to catch any such exception.\n\nVector\n******\nThe type *Vector* must be a :ref:`SimpleVector-name` class with\nelements of type *Scalar* .\n{xrst_toc_hidden\n   example/utility/nan.cpp\n}\nExample\n*******\nThe file :ref:`nan.cpp-name`\ncontains an example and test of this routine.\n\n{xrst_end nan}\n*/\n\n# include <cstddef>\n# include <cppad/core/cppad_assert.hpp>\n\n/*\n# define nan There must be a define for every CppAD undef\n*/\n# ifdef nan\n# undef nan\n# endif\n\n/*\n# define isnan There must be a define for every CppAD undef\n*/\n# ifdef isnan\n# undef isnan\n# endif\n\nnamespace CppAD { // BEGIN CppAD namespace\n\ntemplate <class Scalar>\nbool isnan(const Scalar &s)\n{  return (s != s);\n}\n\ntemplate <class Vector>\nbool hasnan(const Vector &v)\n{\n   bool found_nan;\n   size_t i;\n   i   = v.size();\n   found_nan = false;\n   // on MS Visual Studio 2012, CppAD required in front of isnan ?\n   while(i--)\n      found_nan |= CppAD::isnan(v[i]);\n   return found_nan;\n}\n\ntemplate <class Scalar>\nScalar nan(const Scalar &zero)\n{  return zero / zero;\n}\n\n} // End CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/near_equal.hpp",
    "content": "# ifndef CPPAD_UTILITY_NEAR_EQUAL_HPP\n# define CPPAD_UTILITY_NEAR_EQUAL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin NearEqual}\n{xrst_spell\n   cout\n   endl\n}\n\nDetermine if Two Values Are Nearly Equal\n########################################\n\nSyntax\n******\n| # ``include <cppad/utility/near_equal.hpp>``\n| *b* = ``NearEqual`` ( *x* , *y* , *r* , *a* )\n\nPurpose\n*******\nReturns true,\nif *x* and *y* are nearly equal,\nand false otherwise.\n\nx\n*\nThe argument *x*\nhas one of the following possible prototypes\n\n| |tab| ``const`` *Type* & *x* ,\n| |tab| ``const std::complex<`` *Type* > & *x* ,\n\ny\n*\nThe argument *y*\nhas one of the following possible prototypes\n\n| |tab| ``const`` *Type* & *y* ,\n| |tab| ``const std::complex<`` *Type* > & *y* ,\n\nr\n*\nThe relative error criteria *r* has prototype\n\n   ``const`` *Type* & *r*\n\nIt must be greater than or equal to zero.\nThe relative error condition is defined as:\n\n.. math::\n\n   | x - y | \\leq r ( |x| + |y| )\n\na\n*\nThe absolute error criteria *a* has prototype\n\n   ``const`` *Type* & *a*\n\nIt must be greater than or equal to zero.\nThe absolute error condition is defined as:\n\n.. math::\n\n   | x - y | \\leq a\n\nb\n*\nThe return value *b* has prototype\n\n   ``bool`` *b*\n\nIf either *x* or *y* is infinite or not a number,\nthe return value is false.\nOtherwise, if either the relative or absolute error\ncondition (defined above) is satisfied, the return value is true.\nOtherwise, the return value is false.\n\nType\n****\nThe type *Type* must be a\n:ref:`NumericType-name` .\nThe routine :ref:`CheckNumericType-name` will generate\nan error message if this is not the case.\nIn addition, the following operations must be defined objects\n*a* and *b* of type *Type* :\n\n.. list-table::\n   :widths: auto\n\n   * - **Operation**\n     - **Description**\n   * - *a* <= *b*\n     - less that or equal operator (returns a ``bool`` object)\n\nInclude Files\n*************\nThe file ``cppad/utility/near_equal.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\nExample\n*******\n{xrst_toc_hidden\n   example/utility/near_equal.cpp\n}\nThe file :ref:`near_equal.cpp-name` contains an example\nand test of ``NearEqual`` .\nIt return true if it succeeds and false otherwise.\n\nExercise\n********\nCreate and run a program that contains the following code:\n::\n\n   using std::complex;\n   using std::cout;\n   using std::endl;\n\n   complex<double> one(1., 0), i(0., 1);\n   complex<double> x = one / i;\n   complex<double> y = - i;\n   double          r = 1e-12;\n   double          a = 0;\n   bool           ok = CppAD::NearEqual(x, y, r, a);\n   if( ok )\n   cout << \"Ok\"    << endl;\n   else\n   cout << \"Error\" << endl;\n\n{xrst_end NearEqual}\n\n*/\n\n# include <limits>\n# include <complex>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/utility/check_numeric_type.hpp>\n\nnamespace CppAD { // Begin CppAD namespace\n\n// determine if both x and y are finite values\ntemplate <class Type>\nbool near_equal_isfinite(const Type &x , const Type &y)\n{  Type infinity = Type( std::numeric_limits<double>::infinity() );\n\n   // handle bug where some compilers return true for nan == nan\n   bool xNan = x != x;\n   bool yNan = y != y;\n\n   // infinite cases\n   bool xInf = (x == infinity   || x == - infinity);\n   bool yInf = (x == infinity   || x == - infinity);\n\n   return ! (xNan | yNan | xInf | yInf);\n}\n\ntemplate <class Type>\nbool NearEqual(const Type &x, const Type &y, const Type &r, const Type &a)\n{\n   CheckNumericType<Type>();\n   Type zero(0);\n\n   CPPAD_ASSERT_KNOWN(\n      zero <= r,\n      \"Error in NearEqual: relative error is less than zero\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      zero <= a,\n      \"Error in NearEqual: absolute error is less than zero\"\n   );\n\n   // check for special cases\n   if( ! CppAD::near_equal_isfinite(x, y) )\n      return false;\n\n   Type ax = x;\n   if( ax <= zero )\n      ax = - ax;\n\n   Type ay = y;\n   if( ay <= zero )\n      ay = - ay;\n\n   Type ad = x - y;\n   if( ad <= zero )\n      ad = - ad;\n\n   if( ad <= a )\n      return true;\n\n   if( ad <= r * (ax + ay) )\n      return true;\n\n   return false;\n}\n\ntemplate <class Type>\nbool NearEqual(\n   const std::complex<Type> &x ,\n   const std::complex<Type> &y ,\n   const              Type  &r ,\n   const              Type  & a )\n{\n   CheckNumericType<Type>();\n# ifndef NDEBUG\n   Type zero(0);\n# endif\n\n   CPPAD_ASSERT_KNOWN(\n      zero <= r,\n      \"Error in NearEqual: relative error is less than zero\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      zero <= a,\n      \"Error in NearEqual: absolute error is less than zero\"\n   );\n\n   // check for special cases\n   if( ! CppAD::near_equal_isfinite(x.real(), x.imag()) )\n      return false;\n   if( ! CppAD::near_equal_isfinite(y.real(), y.imag()) )\n      return false;\n\n   std::complex<Type> d = x - y;\n\n   Type ad = std::abs(d);\n   if( ad <= a )\n      return true;\n\n   Type ax = std::abs(x);\n   Type ay = std::abs(y);\n   if( ad <= r * (ax + ay) )\n      return true;\n\n   return false;\n}\n\ntemplate <class Type>\nbool NearEqual(\n   const std::complex<Type> &x ,\n   const              Type  &y ,\n   const              Type  &r ,\n   const              Type  & a )\n{\n   return NearEqual(x, std::complex<Type>(y, Type(0)), r, a);\n}\n\ntemplate <class Type>\nbool NearEqual(\n   const              Type  &x ,\n   const std::complex<Type> &y ,\n   const              Type  &r ,\n   const              Type  & a )\n{\n   return NearEqual(std::complex<Type>(x, Type(0)), y, r, a);\n}\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/ode_err_control.hpp",
    "content": "# ifndef CPPAD_UTILITY_ODE_ERR_CONTROL_HPP\n# define CPPAD_UTILITY_ODE_ERR_CONTROL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin OdeErrControl}\n{xrst_spell\n   eabs\n   eb\n   ef\n   erel\n   nstep\n   scur\n   smax\n   smin\n   tf\n   xa\n   xb\n   xf\n}\n\nAn Error Controller for ODE Solvers\n###################################\n\nSyntax\n******\n| # ``include <cppad/utility/ode_err_control.hpp>``\n| *xf* = ``OdeErrControl`` ( *method* , *ti* , *tf* , *xi* ,\n| |tab| ``smin`` , ``smax`` , ``scur`` , ``eabs`` , ``erel`` , ``ef`` , ``maxabs`` , ``nstep``  )\n\nDescription\n***********\nLet :math:`\\B{R}` denote the real numbers\nand let :math:`F : \\B{R} \\times \\B{R}^n \\rightarrow \\B{R}^n` be a smooth function.\nWe define :math:`X : [ti , tf] \\rightarrow \\B{R}^n` by\nthe following initial value problem:\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      X(ti)  & = & xi    \\\\\n      X'(t)  & = & F[t , X(t)]\n   \\end{eqnarray}\n\nThe routine ``OdeErrControl`` can be used to adjust the step size\nused an arbitrary integration methods in order to be as fast as possible\nand still with in a requested error bound.\n\nInclude\n*******\nThe file ``cppad/utility/ode_err_control.hpp`` is included by\n``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\nNotation\n********\nThe template parameter types :ref:`OdeErrControl@Scalar` and\n:ref:`OdeErrControl@Vector` are documented below.\n\nxf\n**\nThe return value *xf* has the prototype\n\n   *Vector* *xf*\n\n(see description of :ref:`OdeErrControl@Vector` below).\nand the size of *xf* is equal to *n* .\nIf *xf* contains not a number :ref:`nan-name` ,\nsee the discussion of :ref:`step<OdeErrControl@Method@Nan>` .\n\nMethod\n******\nThe class *Method*\nand the object *method* satisfy the following syntax\n\n   *Method* & *method*\n\nThe object *method* must support ``step`` and\n``order`` member functions defined below:\n\nstep\n====\nThe syntax\n\n   *method* . ``step`` ( *ta* , *tb* , *xa* , *xb* , *eb* )\n\nexecutes one step of the integration method.\n\n   *ta*\n\nThe argument *ta* has prototype\n\n   ``const`` *Scalar* & *ta*\n\nIt specifies the initial time for this step in the\nODE integration.\n(see description of :ref:`OdeErrControl@Scalar` below).\n\n   *tb*\n\nThe argument *tb* has prototype\n\n   ``const`` *Scalar* & *tb*\n\nIt specifies the final time for this step in the\nODE integration.\n\n   *xa*\n\nThe argument *xa* has prototype\n\n   ``const`` *Vector* & *xa*\n\nand size *n* .\nIt specifies the value of :math:`X(ta)`.\n(see description of :ref:`OdeErrControl@Vector` below).\n\n   *xb*\n\nThe argument value *xb* has prototype\n\n   *Vector* & *xb*\n\nand size *n* .\nThe input value of its elements does not matter.\nOn output,\nit contains the approximation for :math:`X(tb)` that the method obtains.\n\n   *eb*\n\nThe argument value *eb* has prototype\n\n   *Vector* & *eb*\n\nand size *n* .\nThe input value of its elements does not matter.\nOn output,\nit contains an estimate for the error in the approximation *xb* .\nIt is assumed (locally) that the error bound in this approximation\nnearly equal to :math:`K (tb - ta)^m`\nwhere *K* is a fixed constant and *m*\nis the corresponding argument to ``CodeControl`` .\n\nNan\n===\nIf any element of the vector *eb* or *xb* are\nnot a number ``nan`` ,\nthe current step is considered to large.\nIf this happens with the current step size equal to *smin* ,\n``OdeErrControl`` returns with *xf* and *ef* as vectors\nof ``nan`` .\n\norder\n=====\nIf *m* is ``size_t`` ,\nthe object *method* must also support the following syntax\n\n   *m* = *method* . ``order`` ()\n\nThe return value *m* is the order of the error estimate;\ni.e., there is a constant K such that if :math:`ti \\leq ta \\leq tb \\leq tf`,\n\n.. math::\n\n   | eb(tb) | \\leq K | tb - ta |^m\n\nwhere *ta* , *tb* , and *eb* are as in\n*method* . ``step`` ( *ta* , *tb* , *xa* , *xb* , *eb* )\n\nti\n**\nThe argument *ti* has prototype\n\n   ``const`` *Scalar* & *ti*\n\nIt specifies the initial time for the integration of\nthe differential equation.\n\ntf\n**\nThe argument *tf* has prototype\n\n   ``const`` *Scalar* & *tf*\n\nIt specifies the final time for the integration of\nthe differential equation.\n\nxi\n**\nThe argument *xi* has prototype\n\n   ``const`` *Vector* & *xi*\n\nand size *n* .\nIt specifies value of :math:`X(ti)`.\n\nsmin\n****\nThe argument *smin* has prototype\n\n   ``const`` *Scalar* & *smin*\n\nThe step size during a call to *method* is defined as\nthe corresponding value of :math:`tb - ta`.\nIf :math:`tf - ti \\leq smin`,\nthe integration will be done in one step of size *tf - ti* .\nOtherwise,\nthe minimum value of *tb - ta* will be :math:`smin`\nexcept for the last two calls to *method* where it may be\nas small as :math:`smin / 2`.\n\nsmax\n****\nThe argument *smax* has prototype\n\n   ``const`` *Scalar* & *smax*\n\nIt specifies the maximum step size to use during the integration;\ni.e., the maximum value for :math:`tb - ta` in a call to *method* .\nThe value of *smax* must be greater than or equal *smin* .\n\nscur\n****\nThe argument *scur* has prototype\n\n   *Scalar* & *scur*\n\nThe value of *scur* is the suggested next step size,\nbased on error criteria, to try in the next call to *method* .\nOn input it corresponds to the first call to *method* ,\nin this call to ``OdeErrControl`` (where :math:`ta = ti`).\nOn output it corresponds to the next call to *method* ,\nin a subsequent call to ``OdeErrControl`` (where *ta* = *tf* ).\n\neabs\n****\nThe argument *eabs* has prototype\n\n   ``const`` *Vector* & *eabs*\n\nand size *n* .\nEach of the elements of *eabs* must be\ngreater than or equal zero.\nIt specifies a bound for the absolute\nerror in the return value *xf* as an approximation for :math:`X(tf)`.\n(see the\n:ref:`OdeErrControl@Error Criteria Discussion`\nbelow).\n\nerel\n****\nThe argument *erel* has prototype\n\n   ``const`` *Scalar* & *erel*\n\nand is greater than or equal zero.\nIt specifies a bound for the relative\nerror in the return value *xf* as an approximation for :math:`X(tf)`\n(see the\n:ref:`OdeErrControl@Error Criteria Discussion`\nbelow).\n\nef\n**\nThe argument value *ef* has prototype\n\n   *Vector* & *ef*\n\nand size *n* .\nThe input value of its elements does not matter.\nOn output,\nit contains an estimated bound for the\nabsolute error in the approximation *xf* ; i.e.,\n\n.. math::\n\n   ef_i > | X( tf )_i - xf_i |\n\nIf on output *ef* contains not a number ``nan`` ,\nsee the discussion of :ref:`step<OdeErrControl@Method@Nan>` .\n\nmaxabs\n******\nThe argument *maxabs* is optional in the call to ``OdeErrControl`` .\nIf it is present, it has the prototype\n\n   *Vector* & *maxabs*\n\nand size *n* .\nThe input value of its elements does not matter.\nOn output,\nit contains an estimate for the\nmaximum absolute value of :math:`X(t)`; i.e.,\n\n.. math::\n\n   maxabs[i] \\approx \\max \\left\\{\n      | X( t )_i | \\; : \\;  t \\in [ti, tf]\n   \\right\\}\n\nnstep\n*****\nThe argument *nstep* is optional in the call to ``OdeErrControl`` .\nIf it is present, it has the prototype\n\n   *size_t* & *nstep*\n\nIts input value does not matter and its output value\nis the number of calls to *method* . ``step``\nused by ``OdeErrControl`` .\n\nError Criteria Discussion\n*************************\nThe relative error criteria *erel* and\nabsolute error criteria *eabs* are enforced during each step of the\nintegration of the ordinary differential equations.\nIn addition, they are inversely scaled by the step size so that\nthe total error bound is less than the sum of the error bounds.\nTo be specific, if :math:`\\tilde{X} (t)` is the approximate solution\nat time :math:`t`,\n*ta* is the initial step time,\nand *tb* is the final step time,\n\n.. math::\n\n   \\left| \\tilde{X} (tb)_j  - X (tb)_j \\right|\n   \\leq\n   \\frac{tf - ti}{tb - ta}\n   \\left[ eabs[j] + erel \\;  | \\tilde{X} (tb)_j | \\right]\n\nIf :math:`X(tb)_j` is near zero for some :math:`tb \\in [ti , tf]`,\nand one uses an absolute error criteria :math:`eabs[j]` of zero,\nthe error criteria above will force ``OdeErrControl``\nto use step sizes equal to\n:ref:`OdeErrControl@smin`\nfor steps ending near :math:`tb`.\nIn this case, the error relative to *maxabs* can be judged after\n``OdeErrControl`` returns.\nIf *ef* is to large relative to *maxabs* ,\n``OdeErrControl`` can be called again\nwith a smaller value of *smin* .\n\nScalar\n******\nThe type *Scalar* must satisfy the conditions\nfor a :ref:`NumericType-name` .\nThe routine :ref:`CheckNumericType-name` will generate an error message\nif this is not the case.\nIn addition, the following operations must be defined for\n*Scalar* objects *a* and *b* :\n\n.. list-table::\n   :widths: auto\n\n   * - **Operation**\n     - **Description**\n   * - *a* <= *b*\n     - returns true (false) if *a* is less than or equal\n       (greater than) *b* .\n   * - *a* == *b*\n     - returns true (false) if *a* is equal to *b* .\n   * - ``log`` ( *a* )\n     - returns a *Scalar* equal to the logarithm of *a*\n   * - ``exp`` ( *a* )\n     - returns a *Scalar* equal to the exponential of *a*\n\nVector\n******\nThe type *Vector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type Scalar<SimpleVector@Elements of Specified Type>` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nExample\n*******\n{xrst_toc_hidden\n   example/utility/ode_err_control.cpp\n   example/utility/ode_err_maxabs.cpp\n}\nThe files\n:ref:`ode_err_control.cpp-name`\nand\n:ref:`ode_err_maxabs.cpp-name`\ncontain examples and tests of using this routine.\nThey return true if they succeed and false otherwise.\n\nTheory\n******\nLet :math:`e(s)` be the error as a function of the\nstep size :math:`s` and suppose that there is a constant\n:math:`K` such that :math:`e(s) = K s^m`.\nLet :math:`a` be our error bound.\nGiven the value of :math:`e(s)`, a step of size :math:`\\lambda s`\nwould be ok provided that\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      a  & \\geq & e( \\lambda s ) (tf - ti) / ( \\lambda s ) \\\\\n      a  & \\geq & K \\lambda^m s^m (tf - ti) / ( \\lambda s ) \\\\\n      a  & \\geq & \\lambda^{m-1} s^{m-1} (tf - ti) e(s) / s^m \\\\\n      a  & \\geq & \\lambda^{m-1} (tf - ti) e(s) / s           \\\\\n      \\lambda^{m-1} & \\leq & \\frac{a}{e(s)} \\frac{s}{tf - ti}\n   \\end{eqnarray}\n\nThus if the right hand side of the last inequality is greater\nthan or equal to one, the step of size :math:`s` is ok.\n\nSource Code\n***********\nThe source code for this routine is in the file\n``cppad/ode_err_control.hpp`` .\n\n{xrst_end OdeErrControl}\n--------------------------------------------------------------------------\n*/\n\n// link exp and log for float and double\n# include <cppad/base_require.hpp>\n\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/utility/check_simple_vector.hpp>\n# include <cppad/utility/nan.hpp>\n\nnamespace CppAD { // Begin CppAD namespace\n\ntemplate <class Scalar, class Vector, class Method>\nVector OdeErrControl(\n   Method          &method,\n   const Scalar    &ti    ,\n   const Scalar    &tf    ,\n   const Vector    &xi    ,\n   const Scalar    &smin  ,\n   const Scalar    &smax  ,\n   Scalar          &scur  ,\n   const Vector    &eabs  ,\n   const Scalar    &erel  ,\n   Vector          &ef    ,\n   Vector          &maxabs,\n   size_t          &nstep )\n{\n   // check simple vector class specifications\n   CheckSimpleVector<Scalar, Vector>();\n\n   size_t n = size_t(xi.size());\n\n   CPPAD_ASSERT_KNOWN(\n      smin <= smax,\n      \"Error in OdeErrControl: smin > smax\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(eabs.size()) == n,\n      \"Error in OdeErrControl: size of eabs is not equal to n\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(maxabs.size()) == n,\n      \"Error in OdeErrControl: size of maxabs is not equal to n\"\n   );\n   size_t m = method.order();\n   CPPAD_ASSERT_KNOWN(\n      m > 1,\n      \"Error in OdeErrControl: m is less than or equal one\"\n   );\n\n   bool    ok;\n   bool    minimum_step;\n   size_t  i;\n   Vector xa(n), xb(n), eb(n), nan_vec(n);\n\n   // initialization\n   Scalar zero(0.0);\n   Scalar one(1.0);\n   Scalar two(2.0);\n   Scalar three(3.0);\n   Scalar m1(double(m-1));\n   Scalar ta = ti;\n   for(i = 0; i < n; i++)\n   {  nan_vec[i] = nan(zero);\n      ef[i]      = zero;\n      xa[i]      = xi[i];\n      if( zero <= xi[i] )\n         maxabs[i] = xi[i];\n      else\n         maxabs[i] = - xi[i];\n\n   }\n   nstep = 0;\n\n   Scalar tb, step, lambda, axbi, a, r, root;\n   while( ! (ta == tf) )\n   {  // start with value suggested by error criteria\n      step = scur;\n\n      // check maximum\n      if( smax <= step )\n         step = smax;\n\n      // check minimum\n      minimum_step = step <= smin;\n      if( minimum_step )\n         step = smin;\n\n      // check if near the end\n      if( tf <= ta + step * three / two )\n         tb = tf;\n      else\n         tb = ta + step;\n\n      // try using this step size\n      nstep++;\n      method.step(ta, tb, xa, xb, eb);\n      step = tb - ta;\n\n      // check if this steps error estimate is ok\n      ok = ! (hasnan(xb) || hasnan(eb));\n      if( (! ok) && minimum_step )\n      {  ef = nan_vec;\n         return nan_vec;\n      }\n\n      // compute value of lambda for this step\n      lambda = Scalar(10) * scur / step;\n      for(i = 0; i < n; i++)\n      {  if( zero <= xb[i] )\n            axbi = xb[i];\n         else\n            axbi = - xb[i];\n         a    = eabs[i] + erel * axbi;\n         if( ! (eb[i] == zero) )\n         {  r = ( a / eb[i] ) * step / (tf - ti);\n            root = exp( log(r) / m1 );\n            if( root <= lambda )\n               lambda = root;\n         }\n      }\n      if( ok && ( one <= lambda || step <= smin * three / two) )\n      {  // this step is within error limits or\n         // close to the minimum size\n         ta = tb;\n         for(i = 0; i < n; i++)\n         {  xa[i] = xb[i];\n            ef[i] = ef[i] + eb[i];\n            if( zero <= xb[i] )\n               axbi = xb[i];\n            else\n               axbi = - xb[i];\n            if( axbi > maxabs[i] )\n               maxabs[i] = axbi;\n         }\n      }\n      if( ! ok )\n      {  // decrease step an see if method will work this time\n         scur = step / two;\n      }\n      else if( ! (ta == tf) )\n      {  // step suggested by the error criteria is not used\n         // on the last step because it may be very small.\n         scur = lambda * step / two;\n      }\n   }\n   return xa;\n}\n\ntemplate <class Scalar, class Vector, class Method>\nVector OdeErrControl(\n   Method          &method,\n   const Scalar    &ti    ,\n   const Scalar    &tf    ,\n   const Vector    &xi    ,\n   const Scalar    &smin  ,\n   const Scalar    &smax  ,\n   Scalar          &scur  ,\n   const Vector    &eabs  ,\n   const Scalar    &erel  ,\n   Vector          &ef    )\n{  Vector maxabs(xi.size());\n   size_t nstep;\n   return OdeErrControl(\n   method, ti, tf, xi, smin, smax, scur, eabs, erel, ef, maxabs, nstep\n   );\n}\n\ntemplate <class Scalar, class Vector, class Method>\nVector OdeErrControl(\n   Method          &method,\n   const Scalar    &ti    ,\n   const Scalar    &tf    ,\n   const Vector    &xi    ,\n   const Scalar    &smin  ,\n   const Scalar    &smax  ,\n   Scalar          &scur  ,\n   const Vector    &eabs  ,\n   const Scalar    &erel  ,\n   Vector          &ef    ,\n   Vector          &maxabs)\n{  size_t nstep;\n   return OdeErrControl(\n   method, ti, tf, xi, smin, smax, scur, eabs, erel, ef, maxabs, nstep\n   );\n}\n\n} // End CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/ode_gear.hpp",
    "content": "# ifndef CPPAD_UTILITY_ODE_GEAR_HPP\n# define CPPAD_UTILITY_ODE_GEAR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin OdeGear}\n{xrst_spell\n   dep\n   pp\n   test test\n   vol\n}\n\nAn Arbitrary Order Gear Method\n##############################\n\nSyntax\n******\n| # ``include <cppad/utility/ode_gear.hpp>``\n| ``OdeGear`` ( *F* , *m* , *n* , *T* , *X* , *e* )\n\nPurpose\n*******\nThis routine applies\n:ref:`OdeGear@Gear's Method`\nto solve an explicit set of ordinary differential equations.\nWe are given\n:math:`f : \\B{R} \\times \\B{R}^n \\rightarrow \\B{R}^n` be a smooth function.\nThis routine solves the following initial value problem\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      x( t_{m-1} )  & = & x^0    \\\\\n      x^\\prime (t)  & = & f[t , x(t)]\n   \\end{eqnarray}\n\nfor the value of :math:`x( t_m )`.\nIf your set of  ordinary differential equations are not stiff\nan explicit method may be better (perhaps :ref:`Runge45-name` .)\n\nInclude\n*******\nThe file ``cppad/utility/ode_gear.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\nFun\n***\nThe class *Fun*\nand the object *F* satisfy the prototype\n\n   *Fun* & *F*\n\nThis must support the following set of calls\n\n| |tab| *F* . ``Ode`` ( *t* , *x* , *f* )\n| |tab| *F* . ``Ode_dep`` ( *t* , *x* , *f_x* )\n\nt\n=\nThe argument *t* has prototype\n\n   ``const`` *Scalar* & *t*\n\n(see description of :ref:`OdeGear@Scalar` below).\n\nx\n=\nThe argument *x* has prototype\n\n   ``const`` *Vector* & *x*\n\nand has size *n*\n(see description of :ref:`OdeGear@Vector` below).\n\nf\n=\nThe argument *f* to *F* . ``Ode`` has prototype\n\n   *Vector* & *f*\n\nOn input and output, *f* is a vector of size *n*\nand the input values of the elements of *f* do not matter.\nOn output,\n*f* is set equal to :math:`f(t, x)`\n(see *f* ( *t* , *x* ) in :ref:`OdeGear@Purpose` ).\n\nf_x\n===\nThe argument *f_x* has prototype\n\n   *Vector* & *f_x*\n\nOn input and output, *f_x* is a vector of size :math:`n * n`\nand the input values of the elements of *f_x* do not matter.\nOn output,\n\n.. math::\n\n   f\\_x [i * n + j] = \\partial_{x(j)} f_i ( t , x )\n\nWarning\n=======\nThe arguments *f* , and *f_x*\nmust have a call by reference in their prototypes; i.e.,\ndo not forget the ``&`` in the prototype for\n*f* and *f_x* .\n\nm\n*\nThe argument *m* has prototype\n\n   ``size_t`` *m*\n\nIt specifies the order (highest power of :math:`t`)\nused to represent the function :math:`x(t)` in the multi-step method.\nUpon return from ``OdeGear`` ,\nthe *i*-th component of the polynomial is defined by\n\n.. math::\n\n   p_i ( t_j ) = X[ j * n + i ]\n\nfor :math:`j = 0 , \\ldots , m` (where :math:`0 \\leq i < n`).\nThe value of :math:`m` must be greater than or equal one.\n\nn\n*\nThe argument *n* has prototype\n\n   ``size_t`` *n*\n\nIt specifies the range space dimension of the\nvector valued function :math:`x(t)`.\n\nT\n*\nThe argument *T* has prototype\n\n   ``const`` *Vector* & *T*\n\nand size greater than or equal to :math:`m+1`.\nFor :math:`j = 0 , \\ldots m`, :math:`T[j]` is the time\ncorresponding to time corresponding\nto a previous point in the multi-step method.\nThe value :math:`T[m]` is the time\nof the next point in the multi-step method.\nThe array :math:`T` must be monotone increasing; i.e.,\n:math:`T[j] < T[j+1]`.\nAbove and below we often use the shorthand :math:`t_j` for :math:`T[j]`.\n\nX\n*\nThe argument *X* has the prototype\n\n   *Vector* & *X*\n\nand size greater than or equal to :math:`(m+1) * n`.\nOn input to ``OdeGear`` ,\nfor :math:`j = 0 , \\ldots , m-1`, and\n:math:`i = 0 , \\ldots , n-1`\n\n.. math::\n\n   X[ j * n + i ] = x_i ( t_j )\n\nUpon return from ``OdeGear`` ,\nfor :math:`i = 0 , \\ldots , n-1`\n\n.. math::\n\n   X[ m * n + i ] \\approx x_i ( t_m )\n\ne\n*\nThe vector *e* is an approximate error bound for the result; i.e.,\n\n.. math::\n\n   e[i] \\geq | X[ m * n + i ] - x_i ( t_m ) |\n\nThe order of this approximation is one less than the order of\nthe solution; i.e.,\n\n.. math::\n\n   e = O ( h^m )\n\nwhere :math:`h` is the maximum of :math:`t_{j+1} - t_j`.\n\nScalar\n******\nThe type *Scalar* must satisfy the conditions\nfor a :ref:`NumericType-name` .\nThe routine :ref:`CheckNumericType-name` will generate an error message\nif this is not the case.\nIn addition, the following operations must be defined for\n*Scalar* objects *a* and *b* :\n\n.. list-table::\n   :widths: auto\n\n   * - **Operation**\n     - **Description**\n   * - *a* < *b*\n     - less than operator (returns a ``bool`` object)\n\nVector\n******\nThe type *Vector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type Scalar<SimpleVector@Elements of Specified Type>` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nExample\n*******\n{xrst_toc_hidden\n   example/utility/ode_gear.cpp\n}\nThe file\n:ref:`ode_gear.cpp-name`\ncontains an example and test a test of using this routine.\n\nSource Code\n***********\nThe source code for this routine is in the file\n``cppad/ode_gear.hpp`` .\n\nTheory\n******\nFor this discussion we use the shorthand :math:`x_j`\nfor the value :math:`x ( t_j ) \\in \\B{R}^n` which is not to be confused\nwith :math:`x_i (t) \\in \\B{R}` in the notation above.\nThe interpolating polynomial :math:`p(t)` is given by\n\n.. math::\n\n   p(t) =\n   \\sum_{j=0}^m\n   x_j\n   \\frac{\n      \\prod_{i \\neq j} ( t - t_i )\n   }{\n      \\prod_{i \\neq j} ( t_j - t_i )\n   }\n\nThe derivative :math:`p^\\prime (t)` is given by\n\n.. math::\n\n   p^\\prime (t) =\n   \\sum_{j=0}^m\n   x_j\n   \\frac{\n      \\sum_{i \\neq j} \\prod_{k \\neq i,j} ( t - t_k )\n   }{\n      \\prod_{k \\neq j} ( t_j - t_k )\n   }\n\nEvaluating the derivative at the point :math:`t_\\ell` we have\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   p^\\prime ( t_\\ell ) & = &\n   x_\\ell\n   \\frac{\n      \\sum_{i \\neq \\ell} \\prod_{k \\neq i,\\ell} ( t_\\ell - t_k )\n   }{\n      \\prod_{k \\neq \\ell} ( t_\\ell - t_k )\n   }\n   +\n   \\sum_{j \\neq \\ell}\n   x_j\n   \\frac{\n      \\sum_{i \\neq j} \\prod_{k \\neq i,j} ( t_\\ell - t_k )\n   }{\n      \\prod_{k \\neq j} ( t_j - t_k )\n   }\n   \\\\\n   & = &\n   x_\\ell\n   \\sum_{i \\neq \\ell}\n   \\frac{ 1 }{ t_\\ell - t_i }\n   +\n   \\sum_{j \\neq \\ell}\n   x_j\n   \\frac{\n      \\prod_{k \\neq \\ell,j} ( t_\\ell - t_k )\n   }{\n      \\prod_{k \\neq j} ( t_j - t_k )\n   }\n   \\\\\n   & = &\n   x_\\ell\n   \\sum_{k \\neq \\ell} ( t_\\ell - t_k )^{-1}\n   +\n   \\sum_{j \\neq \\ell}\n   x_j\n   ( t_j - t_\\ell )^{-1}\n   \\prod_{k \\neq \\ell ,j} ( t_\\ell - t_k ) / ( t_j - t_k )\n   \\end{eqnarray}\n\nWe define the vector :math:`\\alpha \\in \\B{R}^{m+1}` by\n\n.. math::\n\n   \\alpha_j = \\left\\{ \\begin{array}{ll}\n   \\sum_{k \\neq m} ( t_m - t_k )^{-1}\n      & {\\rm if} \\; j = m\n   \\\\\n   ( t_j - t_m )^{-1}\n   \\prod_{k \\neq m,j} ( t_m - t_k ) / ( t_j - t_k )\n      & {\\rm otherwise}\n   \\end{array} \\right.\n\nIt follows that\n\n.. math::\n\n   p^\\prime ( t_m ) = \\alpha_0 x_0 + \\cdots + \\alpha_m x_m\n\nGear's method determines :math:`x_m` by solving the following\nnonlinear equation\n\n.. math::\n\n   f( t_m , x_m ) = \\alpha_0 x_0 + \\cdots + \\alpha_m x_m\n\nNewton's method for solving this equation determines iterates,\nwhich we denote by :math:`x_m^k`, by solving the following affine\napproximation of the equation above\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n   f( t_m , x_m^{k-1} ) + \\partial_x f( t_m , x_m^{k-1} ) ( x_m^k - x_m^{k-1} )\n   & = &\n   \\alpha_0 x_0^k + \\alpha_1 x_1 + \\cdots + \\alpha_m x_m\n   \\\\\n   \\left[ \\alpha_m I - \\partial_x f( t_m , x_m^{k-1} ) \\right]  x_m\n   & = &\n   \\left[\n   f( t_m , x_m^{k-1} ) - \\partial_x f( t_m , x_m^{k-1} ) x_m^{k-1}\n   - \\alpha_0 x_0 - \\cdots - \\alpha_{m-1} x_{m-1}\n   \\right]\n   \\end{eqnarray}\n\nIn order to initialize Newton's method; i.e. choose :math:`x_m^0`\nwe define the vector :math:`\\beta \\in \\B{R}^{m+1}` by\n\n.. math::\n\n   \\beta_j = \\left\\{ \\begin{array}{ll}\n   \\sum_{k \\neq m-1} ( t_{m-1} - t_k )^{-1}\n      & {\\rm if} \\; j = m-1\n   \\\\\n   ( t_j - t_{m-1} )^{-1}\n   \\prod_{k \\neq m-1,j} ( t_{m-1} - t_k ) / ( t_j - t_k )\n      & {\\rm otherwise}\n   \\end{array} \\right.\n\nIt follows that\n\n.. math::\n\n   p^\\prime ( t_{m-1} ) = \\beta_0 x_0 + \\cdots + \\beta_m x_m\n\nWe solve the following approximation of the equation above to determine\n:math:`x_m^0`:\n\n.. math::\n\n   f( t_{m-1} , x_{m-1} ) =\n   \\beta_0 x_0 + \\cdots + \\beta_{m-1} x_{m-1} + \\beta_m x_m^0\n\nGear's Method\n*************\nC. W. Gear,\n*Simultaneous Numerical Solution of Differential-Algebraic Equations* ,\nIEEE Transactions on Circuit Theory,\nvol. 18, no. 1, pp. 89-95, Jan. 1971.\n\n{xrst_end OdeGear}\n--------------------------------------------------------------------------\n*/\n\n# include <cstddef>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/utility/check_simple_vector.hpp>\n# include <cppad/utility/check_numeric_type.hpp>\n# include <cppad/utility/vector.hpp>\n# include <cppad/utility/lu_factor.hpp>\n# include <cppad/utility/lu_invert.hpp>\n\nnamespace CppAD { // BEGIN CppAD namespace\n\ntemplate <class Vector, class Fun>\nvoid OdeGear(\n   Fun          &F  ,\n   size_t        m  ,\n   size_t        n  ,\n   const Vector &T  ,\n   Vector       &X  ,\n   Vector       &e  )\n{\n   // temporary indices\n   size_t i, j, k;\n\n   typedef typename Vector::value_type Scalar;\n\n   // check numeric type specifications\n   CheckNumericType<Scalar>();\n\n   // check simple vector class specifications\n   CheckSimpleVector<Scalar, Vector>();\n\n   CPPAD_ASSERT_KNOWN(\n      m >= 1,\n      \"OdeGear: m is less than one\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      n > 0,\n      \"OdeGear: n is equal to zero\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(T.size()) >= (m+1),\n      \"OdeGear: size of T is not greater than or equal (m+1)\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(X.size()) >= (m+1) * n,\n      \"OdeGear: size of X is not greater than or equal (m+1) * n\"\n   );\n   for(j = 0; j < m; j++) CPPAD_ASSERT_KNOWN(\n      T[j] < T[j+1],\n      \"OdeGear: the array T is not monotone increasing\"\n   );\n\n   // some constants\n   Scalar zero(0);\n   Scalar one(1);\n\n   // vectors required by method\n   Vector alpha(m + 1);\n   Vector beta(m + 1);\n   Vector f(n);\n   Vector f_x(n * n);\n   Vector x_m0(n);\n   Vector x_m(n);\n   Vector b(n);\n   Vector A(n * n);\n\n   // compute alpha[m]\n   alpha[m] = zero;\n   for(k = 0; k < m; k++)\n      alpha[m] += one / (T[m] - T[k]);\n\n   // compute beta[m-1]\n   beta[m-1] = one / (T[m-1] - T[m]);\n   for(k = 0; k < m-1; k++)\n      beta[m-1] += one / (T[m-1] - T[k]);\n\n\n   // compute other components of alpha\n   for(j = 0; j < m; j++)\n   {  // compute alpha[j]\n      alpha[j] = one / (T[j] - T[m]);\n      for(k = 0; k < m; k++)\n      {  if( k != j )\n         {  alpha[j] *= (T[m] - T[k]);\n            alpha[j] /= (T[j] - T[k]);\n         }\n      }\n   }\n\n   // compute other components of beta\n   for(j = 0; j <= m; j++)\n   {  if( j != m-1 )\n      {  // compute beta[j]\n         beta[j] = one / (T[j] - T[m-1]);\n         for(k = 0; k <= m; k++)\n         {  if( k != j && k != m-1 )\n            {  beta[j] *= (T[m-1] - T[k]);\n               beta[j] /= (T[j] - T[k]);\n            }\n         }\n      }\n   }\n\n   // evaluate f(T[m-1], x_{m-1} )\n   for(i = 0; i < n; i++)\n      x_m[i] = X[(m-1) * n + i];\n   F.Ode(T[m-1], x_m, f);\n\n   // solve for x_m^0\n   for(i = 0; i < n; i++)\n   {  x_m[i] =  f[i];\n      for(j = 0; j < m; j++)\n         x_m[i] -= beta[j] * X[j * n + i];\n      x_m[i] /= beta[m];\n   }\n   x_m0 = x_m;\n\n   // evaluate partial w.r.t x of f(T[m], x_m^0)\n   F.Ode_dep(T[m], x_m, f_x);\n\n   // compute the matrix A = ( alpha[m] * I - f_x )\n   for(i = 0; i < n; i++)\n   {  for(j = 0; j < n; j++)\n         A[i * n + j]  = - f_x[i * n + j];\n      A[i * n + i] += alpha[m];\n   }\n\n   // LU factor (and overwrite) the matrix A\n   CppAD::vector<size_t> ip(n) , jp(n);\n# ifndef NDEBUG\n   int sign =\n# endif\n   LuFactor(ip, jp, A);\n   CPPAD_ASSERT_KNOWN(\n      sign != 0,\n      \"OdeGear: step size is to large\"\n   );\n\n   // Iterations of Newton's method\n   for(k = 0; k < 3; k++)\n   {\n      // only evaluate f( T[m] , x_m ) keep f_x during iteration\n      F.Ode(T[m], x_m, f);\n\n      // b = f + f_x x_m - alpha[0] x_0 - ... - alpha[m-1] x_{m-1}\n      for(i = 0; i < n; i++)\n      {  b[i]         = f[i];\n         for(j = 0; j < n; j++)\n            b[i]         -= f_x[i * n + j] * x_m[j];\n         for(j = 0; j < m; j++)\n            b[i] -= alpha[j] * X[ j * n + i ];\n      }\n      LuInvert(ip, jp, A, b);\n      x_m = b;\n   }\n\n   // return estimate for x( t[k] ) and the estimated error bound\n   for(i = 0; i < n; i++)\n   {  X[m * n + i] = x_m[i];\n      e[i]         = x_m[i] - x_m0[i];\n      if( e[i] < zero )\n         e[i] = - e[i];\n   }\n}\n\n} // End CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/ode_gear_control.hpp",
    "content": "# ifndef CPPAD_UTILITY_ODE_GEAR_CONTROL_HPP\n# define CPPAD_UTILITY_ODE_GEAR_CONTROL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin OdeGearControl}\n{xrst_spell\n   dep\n   eabs\n   ef\n   erel\n   maxabs\n   nstep\n   sini\n   smax\n   smin\n   test test\n   tf\n   xf\n}\n\nAn Error Controller for Gear's Ode Solvers\n##########################################\n\nSyntax\n******\n| # ``include <cppad/utility/ode_gear_control.hpp>``\n| *xf* = ``OdeGearControl`` ( *F* , *M* , *ti* , *tf* , *xi* ,\n| |tab| ``smin`` , ``smax`` , ``sini`` , ``eabs`` , ``erel`` , ``ef`` , ``maxabs`` , ``nstep``  )\n\nPurpose\n*******\nLet :math:`\\B{R}` denote the real numbers\nand let :math:`f : \\B{R} \\times \\B{R}^n \\rightarrow \\B{R}^n` be a smooth function.\nWe define :math:`X : [ti , tf] \\rightarrow \\B{R}^n` by\nthe following initial value problem:\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      X(ti)  & = & xi    \\\\\n      X'(t)  & = & f[t , X(t)]\n   \\end{eqnarray}\n\nThe routine :ref:`OdeGear-name` is a stiff multi-step method that\ncan be used to approximate the solution to this equation.\nThe routine ``OdeGearControl`` sets up this multi-step method\nand controls the error during such an approximation.\n\nInclude\n*******\nThe file ``cppad/utility/ode_gear_control.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\nNotation\n********\nThe template parameter types :ref:`OdeGearControl@Scalar` and\n:ref:`OdeGearControl@Vector` are documented below.\n\nxf\n**\nThe return value *xf* has the prototype\n\n   *Vector* *xf*\n\nand the size of *xf* is equal to *n*\n(see description of :ref:`OdeGear@Vector` below).\nIt is the approximation for :math:`X(tf)`.\n\nFun\n***\nThe class *Fun*\nand the object *F* satisfy the prototype\n\n   *Fun* & *F*\n\nThis must support the following set of calls\n\n| |tab| *F* . ``Ode`` ( *t* , *x* , *f* )\n| |tab| *F* . ``Ode_dep`` ( *t* , *x* , *f_x* )\n\nt\n=\nThe argument *t* has prototype\n\n   ``const`` *Scalar* & *t*\n\n(see description of :ref:`OdeGear@Scalar` below).\n\nx\n=\nThe argument *x* has prototype\n\n   ``const`` *Vector* & *x*\n\nand has size *N*\n(see description of :ref:`OdeGear@Vector` below).\n\nf\n=\nThe argument *f* to *F* . ``Ode`` has prototype\n\n   *Vector* & *f*\n\nOn input and output, *f* is a vector of size *N*\nand the input values of the elements of *f* do not matter.\nOn output,\n*f* is set equal to :math:`f(t, x)`\n(see *f* ( *t* , *x* ) in :ref:`OdeGear@Purpose` ).\n\nf_x\n===\nThe argument *f_x* has prototype\n\n   *Vector* & *f_x*\n\nOn input and output, *f_x* is a vector of size :math:`N * N`\nand the input values of the elements of *f_x* do not matter.\nOn output,\n\n.. math::\n\n   f\\_x [i * n + j] = \\partial_{x(j)} f_i ( t , x )\n\nWarning\n=======\nThe arguments *f* , and *f_x*\nmust have a call by reference in their prototypes; i.e.,\ndo not forget the ``&`` in the prototype for\n*f* and *f_x* .\n\nM\n*\nThe argument *M* has prototype\n\n   ``size_t`` *M*\n\nIt specifies the order of the multi-step method; i.e.,\nthe order of the approximating polynomial\n(after the initialization process).\nThe argument *M* must greater than or equal one.\n\nti\n**\nThe argument *ti* has prototype\n\n   ``const`` *Scalar* & *ti*\n\nIt specifies the initial time for the integration of\nthe differential equation.\n\ntf\n**\nThe argument *tf* has prototype\n\n   ``const`` *Scalar* & *tf*\n\nIt specifies the final time for the integration of\nthe differential equation.\n\nxi\n**\nThe argument *xi* has prototype\n\n   ``const`` *Vector* & *xi*\n\nand size *n* .\nIt specifies value of :math:`X(ti)`.\n\nsmin\n****\nThe argument *smin* has prototype\n\n   ``const`` *Scalar* & *smin*\n\nThe minimum value of :math:`T[M] -  T[M-1]` in a call to ``OdeGear``\nwill be :math:`smin` except for the last two calls where it may be\nas small as :math:`smin / 2`.\nThe value of *smin* must be less than or equal *smax* .\n\nsmax\n****\nThe argument *smax* has prototype\n\n   ``const`` *Scalar* & *smax*\n\nIt specifies the maximum step size to use during the integration;\ni.e., the maximum value for :math:`T[M] - T[M-1]`\nin a call to ``OdeGear`` .\n\nsini\n****\nThe argument *sini* has prototype\n\n   *Scalar* & *sini*\n\nThe value of *sini* is the minimum\nstep size to use during initialization of the multi-step method; i.e.,\nfor calls to ``OdeGear`` where :math:`m < M`.\nThe value of *sini* must be less than or equal *smax*\n(and can also be less than *smin* ).\n\neabs\n****\nThe argument *eabs* has prototype\n\n   ``const`` *Vector* & *eabs*\n\nand size *n* .\nEach of the elements of *eabs* must be\ngreater than or equal zero.\nIt specifies a bound for the absolute\nerror in the return value *xf* as an approximation for :math:`X(tf)`.\n(see the\n:ref:`OdeGearControl@Error Criteria Discussion`\nbelow).\n\nerel\n****\nThe argument *erel* has prototype\n\n   ``const`` *Scalar* & *erel*\n\nand is greater than or equal zero.\nIt specifies a bound for the relative\nerror in the return value *xf* as an approximation for :math:`X(tf)`\n(see the\n:ref:`OdeGearControl@Error Criteria Discussion`\nbelow).\n\nef\n**\nThe argument value *ef* has prototype\n\n   *Vector* & *ef*\n\nand size *n* .\nThe input value of its elements does not matter.\nOn output,\nit contains an estimated bound for the\nabsolute error in the approximation *xf* ; i.e.,\n\n.. math::\n\n   ef_i > | X( tf )_i - xf_i |\n\nmaxabs\n******\nThe argument *maxabs* is optional in the call to ``OdeGearControl`` .\nIf it is present, it has the prototype\n\n   *Vector* & *maxabs*\n\nand size *n* .\nThe input value of its elements does not matter.\nOn output,\nit contains an estimate for the\nmaximum absolute value of :math:`X(t)`; i.e.,\n\n.. math::\n\n   maxabs[i] \\approx \\max \\left\\{\n      | X( t )_i | \\; : \\;  t \\in [ti, tf]\n   \\right\\}\n\nnstep\n*****\nThe argument *nstep* has the prototype\n\n   *size_t* & *nstep*\n\nIts input value does not matter and its output value\nis the number of calls to :ref:`OdeGear-name`\nused by ``OdeGearControl`` .\n\nError Criteria Discussion\n*************************\nThe relative error criteria *erel* and\nabsolute error criteria *eabs* are enforced during each step of the\nintegration of the ordinary differential equations.\nIn addition, they are inversely scaled by the step size so that\nthe total error bound is less than the sum of the error bounds.\nTo be specific, if :math:`\\tilde{X} (t)` is the approximate solution\nat time :math:`t`,\n*ta* is the initial step time,\nand *tb* is the final step time,\n\n.. math::\n\n   \\left| \\tilde{X} (tb)_j  - X (tb)_j \\right|\n   \\leq\n   \\frac{tf - ti}{tb - ta}\n   \\left[ eabs[j] + erel \\;  | \\tilde{X} (tb)_j | \\right]\n\nIf :math:`X(tb)_j` is near zero for some :math:`tb \\in [ti , tf]`,\nand one uses an absolute error criteria :math:`eabs[j]` of zero,\nthe error criteria above will force ``OdeGearControl``\nto use step sizes equal to\n:ref:`OdeGearControl@smin`\nfor steps ending near :math:`tb`.\nIn this case, the error relative to *maxabs* can be judged after\n``OdeGearControl`` returns.\nIf *ef* is to large relative to *maxabs* ,\n``OdeGearControl`` can be called again\nwith a smaller value of *smin* .\n\nScalar\n******\nThe type *Scalar* must satisfy the conditions\nfor a :ref:`NumericType-name` .\nThe routine :ref:`CheckNumericType-name` will generate an error message\nif this is not the case.\nIn addition, the following operations must be defined for\n*Scalar* objects *a* and *b* :\n\n.. list-table::\n   :widths: auto\n\n   * - **Operation**\n     - **Description**\n   * - *a* <= *b*\n     - returns true (false) if *a* is less than or equal\n       (greater than) *b* .\n   * - *a* == *b*\n     - returns true (false) if *a* is equal to *b* .\n   * - ``log`` ( *a* )\n     - returns a *Scalar* equal to the logarithm of *a*\n   * - ``exp`` ( *a* )\n     - returns a *Scalar* equal to the exponential of *a*\n\nVector\n******\nThe type *Vector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type Scalar<SimpleVector@Elements of Specified Type>` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nExample\n*******\n{xrst_toc_hidden\n   example/utility/ode_gear_control.cpp\n}\nThe file\n:ref:`ode_gear_control.cpp-name`\ncontains an example and test a test of using this routine.\n\nTheory\n******\nLet :math:`e(s)` be the error as a function of the\nstep size :math:`s` and suppose that there is a constant\n:math:`K` such that :math:`e(s) = K s^m`.\nLet :math:`a` be our error bound.\nGiven the value of :math:`e(s)`, a step of size :math:`\\lambda s`\nwould be ok provided that\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      a  & \\geq & e( \\lambda s ) (tf - ti) / ( \\lambda s ) \\\\\n      a  & \\geq & K \\lambda^m s^m (tf - ti) / ( \\lambda s ) \\\\\n      a  & \\geq & \\lambda^{m-1} s^{m-1} (tf - ti) e(s) / s^m \\\\\n      a  & \\geq & \\lambda^{m-1} (tf - ti) e(s) / s           \\\\\n      \\lambda^{m-1} & \\leq & \\frac{a}{e(s)} \\frac{s}{tf - ti}\n   \\end{eqnarray}\n\nThus if the right hand side of the last inequality is greater\nthan or equal to one, the step of size :math:`s` is ok.\n\nSource Code\n***********\nThe source code for this routine is in the file\n``cppad/ode_gear_control.hpp`` .\n\n{xrst_end OdeGearControl}\n--------------------------------------------------------------------------\n*/\n\n// link exp and log for float and double\n# include <cppad/base_require.hpp>\n\n# include <cppad/utility/ode_gear.hpp>\n\nnamespace CppAD { // Begin CppAD namespace\n\ntemplate <class Scalar, class Vector, class Fun>\nVector OdeGearControl(\n   Fun             &F     ,\n   size_t           M     ,\n   const Scalar    &ti    ,\n   const Scalar    &tf    ,\n   const Vector    &xi    ,\n   const Scalar    &smin  ,\n   const Scalar    &smax  ,\n   Scalar          &sini  ,\n   const Vector    &eabs  ,\n   const Scalar    &erel  ,\n   Vector          &ef    ,\n   Vector          &maxabs,\n   size_t          &nstep )\n{\n   // check simple vector class specifications\n   CheckSimpleVector<Scalar, Vector>();\n\n   // dimension of the state space\n   size_t n = size_t(xi.size());\n\n   CPPAD_ASSERT_KNOWN(\n      M >= 1,\n      \"Error in OdeGearControl: M is less than one\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      smin <= smax,\n      \"Error in OdeGearControl: smin is greater than smax\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      sini <= smax,\n      \"Error in OdeGearControl: sini is greater than smax\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(eabs.size()) == n,\n      \"Error in OdeGearControl: size of eabs is not equal to n\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      size_t(maxabs.size()) == n,\n      \"Error in OdeGearControl: size of maxabs is not equal to n\"\n   );\n\n   // some constants\n   const Scalar zero(0);\n   const Scalar one(1);\n   const Scalar one_plus( Scalar(3) / Scalar(2) );\n   const Scalar two(2);\n   const Scalar ten(10);\n\n   // temporary indices\n   size_t i, k;\n\n   // temporary Scalars\n   Scalar step, sprevious, lambda, axi, a, root, r;\n\n   // vectors of Scalars\n   Vector T  (M + 1);\n   Vector X( (M + 1) * n );\n   Vector e(n);\n   Vector xf(n);\n\n   // initial integer values\n   size_t m = 1;\n   nstep    = 0;\n\n   // initialize T\n   T[0] = ti;\n\n   // initialize X, ef, maxabs\n   for(i = 0; i < n; i++)\n   for(i = 0; i < n; i++)\n   {  X[i] = xi[i];\n      ef[i] = zero;\n      X[i]  = xi[i];\n      if( zero <= xi[i] )\n         maxabs[i] = xi[i];\n      else\n         maxabs[i] = - xi[i];\n\n   }\n\n   // initial step size\n   step = smin;\n\n   while( T[m-1] < tf )\n   {  sprevious = step;\n\n      // check maximum\n      if( smax <= step )\n         step = smax;\n\n      // check minimum\n      if( m < M )\n      {  if( step <= sini )\n            step = sini;\n      }\n      else\n         if( step <= smin )\n            step = smin;\n\n      // check if near the end\n      if( tf <= T[m-1] + one_plus * step )\n         T[m] = tf;\n      else\n         T[m] = T[m-1] + step;\n\n      // try using this step size\n      nstep++;\n      OdeGear(F, m, n, T, X, e);\n      step = T[m] - T[m-1];\n\n      // compute value of lambda for this step\n      lambda = Scalar(10) *  sprevious / step;\n      for(i = 0; i < n; i++)\n      {  axi = X[m * n + i];\n         if( axi <= zero )\n            axi = - axi;\n         a  = eabs[i] + erel * axi;\n         if( e[i] > zero )\n         {  if( m == 1 )\n               root = (a / e[i]) / ten;\n            else\n            {  r = ( a / e[i] ) * step / (tf - ti);\n               root = exp( log(r) / Scalar(m-1) );\n            }\n            if( root <= lambda )\n               lambda = root;\n         }\n      }\n\n      bool advance;\n      if( m == M )\n         advance = one <= lambda || step <= one_plus * smin;\n      else\n         advance = one <= lambda || step <= one_plus * sini;\n\n\n      if( advance )\n      {  // accept the results of this time step\n         CPPAD_ASSERT_UNKNOWN( m <= M );\n         if( m == M )\n         {  // shift for next step\n            for(k = 0; k < m; k++)\n            {  T[k] = T[k+1];\n               for(i = 0; i < n; i++)\n                  X[k*n + i] = X[(k+1)*n + i];\n            }\n         }\n         // update ef and maxabs\n         for(i = 0; i < n; i++)\n         {  ef[i] = ef[i] + e[i];\n            axi = X[m * n + i];\n            if( axi <= zero )\n               axi = - axi;\n            if( axi > maxabs[i] )\n               maxabs[i] = axi;\n         }\n         if( m != M )\n            m++;  // all we need do in this case\n      }\n\n      // new step suggested by error criteria\n      step = std::min(lambda , ten) * step / two;\n   }\n   for(i = 0; i < n; i++)\n      xf[i] = X[(m-1) * n + i];\n\n   return xf;\n}\n\n} // End CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/omp_alloc.hpp",
    "content": "# ifndef CPPAD_UTILITY_OMP_ALLOC_HPP\n# define CPPAD_UTILITY_OMP_ALLOC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/utility/thread_alloc.hpp>\n# ifdef _OPENMP\n# include <omp.h>\n# endif\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\nclass omp_alloc{\n// ============================================================================\npublic:\n/*\n{xrst_begin omp_max_num_threads app}\nSet and Get Maximum Number of Threads for omp_alloc Allocator\n#############################################################\n\nDeprecated 2011-08-31\n*********************\nUse the functions :ref:`thread_alloc::parallel_setup<ta_parallel_setup-name>`\nand :ref:`thread_alloc:num_threads<ta_num_threads-name>` instead.\n\nSyntax\n******\n| # ``include <cppad/utility/omp_alloc.hpp>``\n| ``omp_alloc::set_max_num_threads`` ( *number* )\n| *number* = ``omp_alloc::get_max_num_threads`` ()\n\nPurpose\n*******\nBy default there is only one thread and all execution is in sequential mode\n(not :ref:`parallel<omp_in_parallel-name>` ).\n\nnumber\n******\nThe argument and return value *number* has prototype\n\n   ``size_t`` *number*\n\nand must be greater than zero.\n\nset_max_num_threads\n*******************\nInforms :ref:`omp_alloc-name` of the maximum number of OpenMP threads.\n\nget_max_num_threads\n*******************\nReturns the valued used in the previous call to ``set_max_num_threads`` .\nIf there was no such previous call, the value one is returned\n(and only thread number zero can use :ref:`omp_alloc-name` ).\n\nRestrictions\n************\nThe function ``set_max_num_threads`` must be called before\nthe program enters :ref:`parallel<omp_in_parallel-name>` execution mode.\nIn addition, this function cannot be called while in parallel mode.\n\n{xrst_end omp_max_num_threads}\n*/\n   /*!\n   Inform omp_alloc of the maximum number of OpenMP threads and enable\n   parallel execution mode by initializing all statics in this file.\n\n   \\param number [in]\n   maximum number of OpenMP threads.\n   */\n   static void set_max_num_threads(size_t number)\n   {  thread_alloc::parallel_setup(\n         number, omp_alloc::in_parallel, omp_alloc::get_thread_num\n      );\n      thread_alloc::hold_memory(number > 1);\n   }\n   /*!\n   Get the current maximum number of OpenMP threads that omp_alloc can use.\n\n   \\return\n   maximum number of OpenMP threads.\n   */\n   static size_t get_max_num_threads(void)\n   {  return thread_alloc::num_threads(); }\n\n/* -----------------------------------------------------------------------\n{xrst_begin omp_in_parallel app}\n\nIs The Current Execution in OpenMP Parallel Mode\n################################################\n\nDeprecated 2011-08-31\n*********************\nUse the function :ref:`thread_alloc::in_parallel<ta_in_parallel-name>` instead.\n\nSyntax\n******\n\n   # ``include <cppad/utility/omp_alloc.hpp>``\n\n*flag* = ``omp_alloc::in_parallel`` ()\n\nPurpose\n*******\nSome of the :ref:`omp_alloc-name` allocation routines have different\nspecifications for parallel (not sequential) execution mode.\nThis routine enables you to determine if the current execution mode\nis sequential or parallel.\n\nflag\n****\nThe return value has prototype\n\n   ``bool`` *flag*\n\nIt is true if the current execution is in parallel mode\n(possibly multi-threaded) and false otherwise (sequential mode).\n\n{xrst_end omp_in_parallel}\n*/\n   /// Are we in a parallel execution state; i.e., is it possible that\n   /// other threads are currently executing.\n   static bool in_parallel(void)\n   {\n# ifdef _OPENMP\n      return omp_in_parallel() != 0;\n# else\n      return false;\n# endif\n   }\n\n/* -----------------------------------------------------------------------\n{xrst_begin omp_get_thread_num app}\n\nGet the Current OpenMP Thread Number\n####################################\n\nDeprecated 2011-08-31\n*********************\nUse the function :ref:`thread_alloc::thread_num<ta_thread_num-name>` instead.\n\nSyntax\n******\n\n   # ``include <cppad/utility/omp_alloc.hpp>``\n\n*thread* = ``omp_alloc::get_thread_num`` ()\n\nPurpose\n*******\nSome of the :ref:`omp_alloc-name` allocation routines have a thread number.\nThis routine enables you to determine the current thread.\n\nthread\n******\nThe return value *thread* has prototype\n\n   ``size_t`` *thread*\n\nand is the currently executing thread number.\nIf ``_OPENMP`` is not defined, *thread* is zero.\n\n{xrst_end omp_get_thread_num}\n*/\n   /// Get current OpenMP thread number (zero if _OpenMP not defined).\n   static size_t get_thread_num(void)\n   {\n# ifdef _OPENMP\n      size_t thread = static_cast<size_t>( omp_get_thread_num() );\n      return thread;\n# else\n      return 0;\n# endif\n   }\n/* -----------------------------------------------------------------------\n{xrst_begin omp_get_memory app}\n\nGet At Least A Specified Amount of Memory\n#########################################\n\nDeprecated 2011-08-31\n*********************\nUse the function :ref:`thread_alloc::get_memory<ta_get_memory-name>` instead.\n\nSyntax\n******\n\n   # ``include <cppad/utility/omp_alloc.hpp>``\n\n*v_ptr* = ``omp_alloc::get_memory`` ( *min_bytes* , *cap_bytes* )\n\nPurpose\n*******\nUse :ref:`omp_alloc-name` to obtain a minimum number of bytes of memory\n(for use by the :ref:`current thread<omp_get_thread_num-name>` ).\n\nmin_bytes\n*********\nThis argument has prototype\n\n   ``size_t`` *min_bytes*\n\nIt specifies the minimum number of bytes to allocate.\n\ncap_bytes\n*********\nThis argument has prototype\n\n   ``size_t&`` *cap_bytes*\n\nIt's input value does not matter.\nUpon return, it is the actual number of bytes (capacity)\nthat have been allocated for use,\n\n   *min_bytes* <= *cap_bytes*\n\nv_ptr\n*****\nThe return value *v_ptr* has prototype\n\n   ``void`` * *v_ptr*\n\nIt is the location where the *cap_bytes* of memory\nthat have been allocated for use begins.\n\nAllocation Speed\n****************\nThis allocation should be faster if the following conditions hold:\n\n#. The memory allocated by a previous call to ``get_memory``\n   is currently available for use.\n#. The current *min_bytes* is between\n   the previous *min_bytes* and previous *cap_bytes* .\n\n{xrst_end omp_get_memory}\n*/\n   /*!\n   Use omp_alloc to get a specified amount of memory.\n\n   If the memory allocated by a previous call to get_memory is now\n   available, and min_bytes is between its previous value\n   and the previous cap_bytes, this memory allocation will have\n   optimal speed. Otherwise, the memory allocation is more complicated and\n   may have to wait for other threads to complete an allocation.\n\n   \\param min_bytes [in]\n   The minimum number of bytes of memory to be obtained for use.\n\n   \\param cap_bytes [out]\n   The actual number of bytes of memory obtained for use.\n\n   \\return\n   pointer to the beginning of the memory allocated for use.\n   */\n   static void* get_memory(size_t min_bytes, size_t& cap_bytes)\n   {  return thread_alloc::get_memory(min_bytes, cap_bytes); }\n\n/* -----------------------------------------------------------------------\n{xrst_begin omp_return_memory app}\n\nReturn Memory to omp_alloc\n##########################\n\nDeprecated 2011-08-31\n*********************\nUse the function :ref:`thread_alloc::return_memory<ta_return_memory-name>` instead.\n\nSyntax\n******\n\n   # ``include <cppad/utility/omp_alloc.hpp>``\n\n``omp_alloc::return_memory`` ( *v_ptr* )\n\nPurpose\n*******\nIf :ref:`omp_max_num_threads-name` is one,\nthe memory is returned to the system.\nOtherwise, the memory is retained by :ref:`omp_alloc-name` for quick future use\nby the thread that allocated to memory.\n\nv_ptr\n*****\nThis argument has prototype\n\n   ``void`` * *v_ptr*\n\n.\nIt must be a pointer to memory that is currently in use; i.e.\nobtained by a previous call to :ref:`omp_get_memory-name` and not yet returned.\n\nThread\n******\nEither the :ref:`current thread<omp_get_thread_num-name>` must be the same as during\nthe corresponding call to :ref:`omp_get_memory-name` ,\nor the current execution mode must be sequential\n(not :ref:`parallel<omp_in_parallel-name>` ).\n\nNDEBUG\n******\nIf ``NDEBUG`` is defined, *v_ptr* is not checked (this is faster).\nOtherwise, a list of in use pointers is searched to make sure\nthat *v_ptr* is in the list.\n\n{xrst_end omp_return_memory}\n*/\n   /*!\n   Return memory that was obtained by get_memory.\n   If  <code>max_num_threads(0) == 1</code>,\n   the memory is returned to the system.\n   Otherwise, it is retained by omp_alloc and available for use by\n   get_memory for this thread.\n\n   \\param v_ptr [in]\n   Value of the pointer returned by get_memory and still in use.\n   After this call, this pointer will available (and not in use).\n\n   \\par\n   We must either be in sequential (not parallel) execution mode,\n   or the current thread must be the same as for the corresponding call\n   to get_memory.\n   */\n   static void return_memory(void* v_ptr)\n   {  thread_alloc::return_memory(v_ptr); }\n/* -----------------------------------------------------------------------\n{xrst_begin omp_free_available app}\n\nFree Memory Currently Available for Quick Use by a Thread\n#########################################################\n\nDeprecated 2011-08-31\n*********************\nUse the function :ref:`thread_alloc::free_available<ta_free_available-name>`\ninstead.\n\nSyntax\n******\n\n   # ``include <cppad/utility/omp_alloc.hpp>``\n\n``omp_alloc::free_available`` ( *thread* )\n\nPurpose\n*******\nFree memory, currently available for quick use by a specific thread,\nfor general future use.\n\nthread\n******\nThis argument has prototype\n\n   ``size_t`` *thread*\n\nEither :ref:`omp_get_thread_num-name` must be the same as *thread* ,\nor the current execution mode must be sequential\n(not :ref:`parallel<omp_in_parallel-name>` ).\n\n{xrst_end omp_free_available}\n*/\n   /*!\n   Return all the memory being held as available for a thread to the system.\n\n   \\param thread [in]\n   this thread that will no longer have any available memory after this call.\n   This must either be the thread currently executing, or we must be\n   in sequential (not parallel) execution mode.\n   */\n   static void free_available(size_t thread)\n   {  thread_alloc::free_available(thread); }\n/* -----------------------------------------------------------------------\n{xrst_begin omp_inuse app}\n\nAmount of Memory a Thread is Currently Using\n############################################\n\nDeprecated 2011-08-31\n*********************\n\nSyntax\n******\n\n   # ``include <cppad/utility/omp_alloc.hpp>``\n\n*num_bytes* = ``omp_alloc::inuse`` ( *thread* )\nUse the function :ref:`thread_alloc::inuse<ta_inuse-name>` instead.\n\nPurpose\n*******\nMemory being managed by :ref:`omp_alloc-name` has two states,\ncurrently in use by the specified thread,\nand quickly available for future use by the specified thread.\nThis function informs the program how much memory is in use.\n\nthread\n******\nThis argument has prototype\n\n   ``size_t`` *thread*\n\nEither :ref:`omp_get_thread_num-name` must be the same as *thread* ,\nor the current execution mode must be sequential\n(not :ref:`parallel<omp_in_parallel-name>` ).\n\nnum_bytes\n*********\nThe return value has prototype\n\n   ``size_t`` *num_bytes*\n\nIt is the number of bytes currently in use by the specified thread.\n\n{xrst_end omp_inuse}\n*/\n   /*!\n   Determine the amount of memory that is currently inuse.\n\n   \\param thread [in]\n   Thread for which we are determining the amount of memory\n   (must be < CPPAD_MAX_NUM_THREADS).\n   During parallel execution, this must be the thread\n   that is currently executing.\n\n   \\return\n   The amount of memory in bytes.\n   */\n   static size_t inuse(size_t thread)\n   {  return thread_alloc::inuse(thread); }\n/* -----------------------------------------------------------------------\n{xrst_begin omp_available app}\n\nAmount of Memory Available for Quick Use by a Thread\n####################################################\n\nDeprecated 2011-08-31\n*********************\nUse the function :ref:`thread_alloc::available<ta_available-name>` instead.\n\nSyntax\n******\n\n   # ``include <cppad/utility/omp_alloc.hpp>``\n\n*num_bytes* = ``omp_alloc::available`` ( *thread* )\n\nPurpose\n*******\nMemory being managed by :ref:`omp_alloc-name` has two states,\ncurrently in use by the specified thread,\nand quickly available for future use by the specified thread.\nThis function informs the program how much memory is available.\n\nthread\n******\nThis argument has prototype\n\n   ``size_t`` *thread*\n\nEither :ref:`omp_get_thread_num-name` must be the same as *thread* ,\nor the current execution mode must be sequential\n(not :ref:`parallel<omp_in_parallel-name>` ).\n\nnum_bytes\n*********\nThe return value has prototype\n\n   ``size_t`` *num_bytes*\n\nIt is the number of bytes currently available for use by the specified thread.\n\n{xrst_end omp_available}\n*/\n   /*!\n   Determine the amount of memory that is currently available for use.\n\n   \\copydetails inuse\n   */\n   static size_t available(size_t thread)\n   {  return thread_alloc::available(thread); }\n/* -----------------------------------------------------------------------\n{xrst_begin omp_create_array app}\n\nAllocate Memory and Create A Raw Array\n######################################\n\nDeprecated 2011-08-31\n*********************\nUse the function :ref:`thread_alloc::create_array<ta_create_array-name>` instead.\n\nSyntax\n******\n\n   # ``include <cppad/utility/omp_alloc.hpp>``\n\n*array* = ``omp_alloc::create_array<`` *Type* >( *size_min* , *size_out* ) .\n\nPurpose\n*******\nCreate a new raw array using :ref:`omp_alloc-name` a fast memory allocator\nthat works well in a multi-threading OpenMP environment.\n\nType\n****\nThe type of the elements of the array.\n\nsize_min\n********\nThis argument has prototype\n\n   ``size_t`` *size_min*\n\nThis is the minimum number of elements that there can be\nin the resulting *array* .\n\nsize_out\n********\nThis argument has prototype\n\n   ``size_t&`` *size_out*\n\nThe input value of this argument does not matter.\nUpon return, it is the actual number of elements\nin *array*\n( *size_min* <= *size_out* ).\n\narray\n*****\nThe return value *array* has prototype\n\n   *Type* * *array*\n\nIt is array with *size_out* elements.\nThe default constructor for *Type* is used to initialize the\nelements of *array* .\nNote that :ref:`omp_delete_array-name`\nshould be used to destroy the array when it is no longer needed.\n\nDelta\n*****\nThe amount of memory :ref:`omp_inuse-name` by the current thread,\nwill increase *delta* where\n\n   ``sizeof`` ( *Type* ) * ( *size_out* + 1) > *delta* >= ``sizeof`` ( *Type* ) * *size_out*\n\nThe :ref:`omp_available-name` memory will decrease by *delta* ,\n(and the allocation will be faster)\nif a previous allocation with *size_min* between its current value\nand *size_out* is available.\n\n{xrst_end omp_create_array}\n*/\n   /*!\n   Use omp_alloc to Create a Raw Array.\n\n   \\tparam Type\n   The type of the elements of the array.\n\n   \\param size_min [in]\n   The minimum number of elements in the array.\n\n   \\param size_out [out]\n   The actual number of elements in the array.\n\n   \\return\n   pointer to the first element of the array.\n   The default constructor is used to initialize\n   all the elements of the array.\n\n   \\par\n   The extra_ field, in the omp_alloc node before the return value,\n   is set to size_out.\n   */\n   template <class Type>\n   static Type* create_array(size_t size_min, size_t& size_out)\n   {  return thread_alloc::create_array<Type>(size_min, size_out); }\n/* -----------------------------------------------------------------------\n{xrst_begin omp_delete_array app}\n\nReturn A Raw Array to The Available Memory for a Thread\n#######################################################\n\nDeprecated 2011-08-31\n*********************\nUse the function :ref:`thread_alloc::delete_array<ta_delete_array-name>` instead.\n\nSyntax\n******\n\n   # ``include <cppad/utility/omp_alloc.hpp>``\n\n``omp_alloc::delete_array`` ( *array* ) .\n\nPurpose\n*******\nReturns memory corresponding to a raw array\n(create by :ref:`omp_create_array-name` ) to the\n:ref:`omp_available-name` memory pool for the current thread.\n\nType\n****\nThe type of the elements of the array.\n\narray\n*****\nThe argument *array* has prototype\n\n   *Type* * *array*\n\nIt is a value returned by :ref:`omp_create_array-name` and not yet deleted.\nThe *Type* destructor is called for each element in the array.\n\nThread\n******\nThe :ref:`current thread<omp_get_thread_num-name>` must be the\nsame as when :ref:`omp_create_array-name` returned the value *array* .\nThere is an exception to this rule:\nwhen the current execution mode is sequential\n(not :ref:`parallel<omp_in_parallel-name>` ) the current thread number does not matter.\n\nDelta\n*****\nThe amount of memory :ref:`omp_inuse-name` will decrease by *delta* ,\nand the :ref:`omp_available-name` memory will increase by *delta* ,\nwhere :ref:`omp_create_array@Delta`\nis the same as for the corresponding call to ``create_array`` .\n\n{xrst_end omp_delete_array}\n*/\n   /*!\n   Return Memory Used for a Raw Array to the Available Pool.\n\n   \\tparam Type\n   The type of the elements of the array.\n\n   \\param array [in]\n   A value returned by create_array that has not yet been deleted.\n   The Type destructor is used to destroy each of the elements\n   of the array.\n\n   \\par\n   During parallel execution, the current thread must be the same\n   as during the corresponding call to create_array.\n   */\n   template <class Type>\n   static void delete_array(Type* array)\n   {  thread_alloc::delete_array(array); }\n};\n/* --------------------------------------------------------------------------\n{xrst_begin omp_efficient app}\n\nCheck If A Memory Allocation is Efficient for Another Use\n#########################################################\n\nRemoved\n*******\nThis function has been removed because speed tests seem to indicate\nit is just as fast, or faster, to free and then reallocate the memory.\n\nSyntax\n******\n\n   # ``include <cppad/utility/omp_alloc.hpp>``\n\n*flag* = ``omp_alloc::efficient`` ( *v_ptr* , *num_bytes* )\n\nPurpose\n*******\nCheck if memory that is currently in use is an efficient\nallocation for a specified number of bytes.\n\nv_ptr\n*****\nThis argument has prototype\n\n   ``const void`` * *v_ptr*\n\n.\nIt must be a pointer to memory that is currently in use; i.e.\nobtained by a previous call to :ref:`omp_get_memory-name` and not yet returned.\n\nnum_bytes\n*********\nThis argument has prototype\n\n   ``size_t`` *num_bytes*\n\nIt specifies the number of bytes of the memory allocated by *v_ptr*\nthat we want to use.\n\nflag\n****\nThe return value has prototype\n\n   ``bool`` *flag*\n\nIt is true,\na call to ``get_memory`` with\n:ref:`omp_get_memory@min_bytes`\nequal to *num_bytes* would result in a value for\n:ref:`omp_get_memory@cap_bytes` that is the same as when ``v_ptr``\nwas returned by ``get_memory`` ; i.e.,\n*v_ptr* is an efficient memory block for *num_bytes*\nbytes of information.\n\nThread\n******\nEither the :ref:`current thread<omp_get_thread_num-name>` must be the same as during\nthe corresponding call to :ref:`omp_get_memory-name` ,\nor the current execution mode must be sequential\n(not :ref:`parallel<omp_in_parallel-name>` ).\n\nNDEBUG\n******\nIf ``NDEBUG`` is defined, *v_ptr* is not checked (this is faster).\nOtherwise, a list of in use pointers is searched to make sure\nthat *v_ptr* is in the list.\n\n{xrst_end omp_efficient}\n---------------------------------------------------------------------------\n{xrst_begin old_max_num_threads app}\nSet Maximum Number of Threads for omp_alloc Allocator\n#####################################################\n\nRemoved\n*******\nThis function has been removed from the CppAD API.\nUse the function :ref:`thread_alloc::parallel_setup<ta_parallel_setup-name>`\nin its place.\n\nSyntax\n******\n\n   # ``include <cppad/utility/omp_alloc.hpp>``\n\n``omp_alloc::max_num_threads`` ( *number* )\n\nPurpose\n*******\nBy default there is only one thread and all execution is in sequential mode\n(not :ref:`parallel<omp_in_parallel-name>` ).\n\nnumber\n******\nThe argument *number* has prototype\n\n   ``size_t`` *number*\n\nIt must be greater than zero and specifies the maximum number of\nOpenMP threads that will be active at one time.\n\nRestrictions\n************\nThis function must be called before the program enters\n:ref:`parallel<omp_in_parallel-name>` execution mode.\n\n{xrst_end old_max_num_threads}\n-------------------------------------------------------------------------------\n*/\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/poly.hpp",
    "content": "# ifndef CPPAD_UTILITY_POLY_HPP\n# define CPPAD_UTILITY_POLY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin Poly}\n\nEvaluate a Polynomial or its Derivative\n#######################################\n\nSyntax\n******\n| # ``include <cppad/utility/poly.hpp>``\n| *p* = ``Poly`` ( *k* , *a* , *z* )\n\nDescription\n***********\nComputes the *k*-th derivative of the polynomial\n\n.. math::\n\n   P(z) = a_0 + a_1 z^1 + \\cdots + a_d z^d\n\nIf *k* is equal to zero, the return value is :math:`P(z)`.\n\nInclude\n*******\nThe file ``cppad/utility/poly.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\nIncluding this file defines\n``Poly`` within the ``CppAD`` namespace.\n\nk\n*\nThe argument *k* has prototype\n\n   ``size_t`` *k*\n\nIt specifies the order of the derivative to calculate.\n\na\n*\nThe argument *a* has prototype\n\n   ``const`` *Vector* & *a*\n\n(see :ref:`Poly@Vector` below).\nIt specifies the vector corresponding to the polynomial :math:`P(z)`.\n\nz\n*\nThe argument *z* has prototype\n\n   ``const`` *Type* & *z*\n\n(see *Type* below).\nIt specifies the point at which to evaluate the polynomial\n\np\n*\nThe result *p*  has prototype\n\n   *Type* *p*\n\n(see :ref:`Poly@Type` below)\nand it is equal to the *k*-th derivative of :math:`P(z)`; i.e.,\n\n.. math::\n\n   p = \\frac{k !}{0 !} a_k\n     + \\frac{(k+1) !}{1 !} a_{k+1} z^1\n     + \\ldots\n     + \\frac{d !}{(d - k) !} a_d z^{d - k}\n\nIf :math:`k > d`, *p* = *Type* (0) .\n\nType\n****\nThe type *Type* is determined by the argument *z* .\nIt is assumed that\nmultiplication and addition of *Type* objects\nare commutative.\n\nOperations\n==========\nThe following operations must be supported where\n*x* and *y* are objects of type *Type*\nand *i* is an ``int`` :\n\n.. list-table::\n   :widths: auto\n\n   * - *x* = *i*\n     - assignment\n   * - *x* = *y*\n     - assignment\n   * - *x* \\\\* = *y*\n     - multiplication compound assignment\n   * - *x* += *y*\n     - addition compound assignment\n\nVector\n******\nThe type *Vector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type<SimpleVector@Elements of Specified Type>`\n*Type* .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nOperation Sequence\n******************\nThe *Type* operation sequence used to calculate *p* is\n:ref:`glossary@Operation@Independent`\nof *z* and the elements of *a*\n(it does depend on the size of the vector *a* ).\n{xrst_toc_hidden\n   example/utility/poly.cpp\n   xrst/poly_hpp.xrst\n}\n\nExample\n*******\nThe file\n:ref:`poly.cpp-name`\ncontains an example and test of this routine.\n\nSource\n******\nThe file :ref:`poly.hpp-name` contains the\ncurrent source code that implements these specifications.\n\n{xrst_end Poly}\n------------------------------------------------------------------------------\n*/\n// BEGIN C++\n# include <cstddef>  // used to defined size_t\n# include <cppad/utility/check_simple_vector.hpp>\n\nnamespace CppAD {    // BEGIN CppAD namespace\n\ntemplate <class Type, class Vector>\nType Poly(size_t k, const Vector &a, const Type &z)\n{  size_t i;\n   size_t d = a.size() - 1;\n\n   Type tmp;\n\n   // check Vector is Simple Vector class with Type elements\n   CheckSimpleVector<Type, Vector>();\n\n   // case where derivative order greater than degree of polynomial\n   if( k > d )\n   {  tmp = 0;\n      return tmp;\n   }\n   // case where we are evaluating a derivative\n   if( k > 0 )\n   {  // initialize factor as (k-1) !\n      size_t factor = 1;\n      for(i = 2; i < k; i++)\n         factor *= i;\n\n      // set b to coefficient vector corresponding to derivative\n      Vector b(d - k + 1);\n      for(i = k; i <= d; i++)\n      {  factor   *= i;\n         tmp       = double( factor );\n         b[i - k]  = a[i] * tmp;\n         factor   /= (i - k + 1);\n      }\n      // value of derivative polynomial\n      return Poly(0, b, z);\n   }\n   // case where we are evaluating the original polynomial\n   Type sum = a[d];\n   i        = d;\n   while(i > 0)\n   {  sum *= z;\n      sum += a[--i];\n   }\n   return sum;\n}\n} // END CppAD namespace\n// END C++\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/pow_int.hpp",
    "content": "# ifndef CPPAD_UTILITY_POW_INT_HPP\n# define CPPAD_UTILITY_POW_INT_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n-------------------------------------------------------------------------------\n{xrst_begin pow_int}\n\nThe Integer Power Function\n##########################\n\nSyntax\n******\n| # ``include <cppad/utility/pow_int.hpp>``\n| *z* = ``pow`` ( *x* , *y* )\n\nSee Also\n********\n:ref:`pow-name`\n\nPurpose\n*******\nDetermines the value of the power function\n\n.. math::\n\n   {\\rm pow} (x, y) = x^y\n\nfor integer exponents *n*\nusing multiplication and possibly division to compute the value.\nThe other CppAD :ref:`pow-name` function may use logarithms and exponentiation\nto compute derivatives of the same value\n(which will not work if *x* is less than or equal zero).\n\nInclude\n*******\nThe file ``cppad/utility/pow_int.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\nIncluding this file defines\nthis version of the ``pow`` within the ``CppAD`` namespace.\n\nx\n*\nThe argument *x* has prototype\n\n   ``const`` *Type* & *x*\n\ny\n*\nThe argument *y* has prototype\n\n   ``const int&`` *y*\n\nz\n*\nThe result *z* has prototype\n\n   *Type* *z*\n\nType\n****\nThe type *Type* must support the following operations\nwhere *a* and *b* are *Type* objects\nand *i* is an ``int`` :\n\n.. csv-table::\n   :widths: auto\n\n   **Operation**,**Description**,**Result Type**\n   *Type* *a* ( *i* ),construction of a *Type* object from an ``int``,*Type*\n   *a* * *b*,binary multiplication of *Type* objects,*Type*\n   *a* / *b*,binary division of *Type* objects,*Type*\n\nOperation Sequence\n******************\nThe *Type* operation sequence used to calculate *z* is\n:ref:`glossary@Operation@Independent`\nof *x* .\n\nExample\n*******\n{xrst_toc_hidden\n   example/utility/pow_int.cpp\n}\nThe file :ref:`pow_int.cpp-name`\nis an example and test of this function.\n\n{xrst_end pow_int}\n-------------------------------------------------------------------------------\n*/\n\nnamespace CppAD {\n\n   template <class Type>\n   inline Type pow (const Type& x, const int& n)\n   {\n      Type p(1);\n      int n2 = n / 2;\n\n      if( n == 0 )\n         return p;\n      if( n < 0 )\n         return p / pow(x, -n);\n      if( n == 1 )\n         return x;\n\n      // p = (x^2)^(n/2)\n      p = pow( x * x , n2 );\n\n      // n is even case\n      if( n % 2 == 0 )\n         return p;\n\n      // n is odd case\n      return p * x;\n   }\n\n}\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/romberg_mul.hpp",
    "content": "# ifndef CPPAD_UTILITY_ROMBERG_MUL_HPP\n# define CPPAD_UTILITY_ROMBERG_MUL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin RombergMul}\n{xrst_spell\n   test test\n}\n\nMulti-dimensional Romberg Integration\n#####################################\n\nSyntax\n******\n| # ``include <cppad/utility/romberg_mul.hpp>``\n| ``RombergMul`` < *Fun* , *SizeVector* , *FloatVector* , *m* > *R*\n| *r* = *R* ( *F* , *a* , *b* , *n* , *p* , *e* )\n\nDescription\n***********\nReturns the Romberg integration estimate\n:math:`r` for the multi-dimensional integral\n\n.. math::\n\n   r =\n   \\int_{a[0]}^{b[0]} \\cdots \\int_{a[m-1]}^{b[m-1]}\n   \\; F(x) \\;\n   {\\bf d} x_0 \\cdots {\\bf d} x_{m-1}\n   \\; + \\;\n   \\sum_{i=0}^{m-1}\n   O \\left[ ( b[i] - a[i] ) / 2^{n[i]-1} \\right]^{2(p[i]+1)}\n\nInclude\n*******\nThe file ``cppad/utility/romberg_mul.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\nm\n*\nThe template parameter *m* must be convertible to a ``size_t``\nobject with a value that can be determined at compile time; for example\n``2`` .\nIt determines the dimension of the domain space for the integration.\n\nr\n*\nThe return value *r* has prototype\n\n   *Float* *r*\n\nIt is the estimate computed by ``RombergMul`` for the integral above\n(see description of :ref:`RombergMul@Float` below).\n\nF\n*\nThe object *F* has the prototype\n\n   *Fun* & *F*\n\nIt must support the operation\n\n   *F* ( *x* )\n\nThe argument *x* to *F* has prototype\n\n   ``const`` *Float* & *x*\n\nThe return value of *F* is a *Float* object\n\na\n*\nThe argument *a* has prototype\n\n   ``const`` *FloatVector* & *a*\n\nIt specifies the lower limit for the integration\n(see description of :ref:`RombergMul@FloatVector` below).\n\nb\n*\nThe argument *b* has prototype\n\n   ``const`` *FloatVector* & *b*\n\nIt specifies the upper limit for the integration.\n\nn\n*\nThe argument *n* has prototype\n\n   ``const`` *SizeVector* & *n*\n\nA total number of :math:`2^{n[i]-1} + 1`\nevaluations of *F* ( *x* ) are used to estimate the integral\nwith respect to :math:`{\\bf d} x_i`.\n\np\n*\nThe argument *p* has prototype\n\n   ``const`` *SizeVector* & *p*\n\nFor :math:`i = 0 , \\ldots , m-1`,\n:math:`n[i]` determines the accuracy order in the\napproximation for the integral\nthat is returned by ``RombergMul`` .\nThe values in *p* must be less than or equal *n* ; i.e.,\n*p* [ *i* ] <= *n* [ *i* ] .\n\ne\n*\nThe argument *e* has prototype\n\n   *Float* & *e*\n\nThe input value of *e* does not matter\nand its output value is an approximation for the absolute error in\nthe integral estimate.\n\nFloat\n*****\nThe type *Float* is defined as the type of the elements of\n:ref:`RombergMul@FloatVector` .\nThe type *Float* must satisfy the conditions\nfor a :ref:`NumericType-name` .\nThe routine :ref:`CheckNumericType-name` will generate an error message\nif this is not the case.\nIn addition, if *x* and *y* are *Float* objects,\n\n   *x* < *y*\n\nreturns the ``bool`` value true if *x* is less than\n*y* and false otherwise.\n\nFloatVector\n***********\nThe type *FloatVector* must be a :ref:`SimpleVector-name` class.\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n{xrst_toc_hidden\n   example/utility/romberg_mul.cpp\n}\nExample\n*******\nThe file :ref:`romberg_mul.cpp-name`\ncontains an example and test a test of using this routine.\n\nSource Code\n***********\nThe source code for this routine is in the file\n``cppad/romberg_mul.hpp`` .\n\n{xrst_end RombergMul}\n*/\n\n# include <cppad/utility/romberg_one.hpp>\n# include <cppad/utility/check_numeric_type.hpp>\n# include <cppad/utility/check_simple_vector.hpp>\n\nnamespace CppAD { // BEGIN CppAD namespace\n\ntemplate <class Fun, class FloatVector>\nclass SliceLast {\n   typedef typename FloatVector::value_type Float;\nprivate:\n   Fun        *F;\n   size_t      last;\n   FloatVector x;\npublic:\n   SliceLast( Fun *F_, size_t last_, const FloatVector &x_ )\n   : F(F_) , last(last_), x(last + 1)\n   {  size_t i;\n      for(i = 0; i < last; i++)\n         x[i] = x_[i];\n   }\n   double operator()(const Float &xlast)\n   {  x[last] = xlast;\n      return (*F)(x);\n   }\n};\n\ntemplate <class Fun, class SizeVector, class FloatVector, class Float>\nclass IntegrateLast {\nprivate:\n   Fun                 *F;\n   const size_t        last;\n   const FloatVector   a;\n   const FloatVector   b;\n   const SizeVector    n;\n   const SizeVector    p;\n   Float               esum;\n   size_t              ecount;\n\npublic:\n   IntegrateLast(\n      Fun                *F_    ,\n      size_t              last_ ,\n      const FloatVector  &a_    ,\n      const FloatVector  &b_    ,\n      const SizeVector   &n_    ,\n      const SizeVector   &p_    )\n   : F(F_) , last(last_), a(a_) , b(b_) , n(n_) , p(p_)\n   { }\n   Float operator()(const FloatVector           &x)\n   {  Float r, e;\n      SliceLast<Fun, FloatVector           > S(F, last, x);\n      r     = CppAD::RombergOne(\n         S, a[last], b[last], n[last], p[last], e\n      );\n      esum = esum + e;\n      ecount++;\n      return r;\n   }\n   void ClearEsum(void)\n   {  esum   = 0.; }\n   Float GetEsum(void)\n   {  return esum; }\n\n   void ClearEcount(void)\n   {  ecount   = 0; }\n   size_t GetEcount(void)\n   {  return ecount; }\n};\n\ntemplate <class Fun, class SizeVector, class FloatVector, size_t m>\nclass RombergMul {\n   typedef typename FloatVector::value_type Float;\npublic:\n   RombergMul(void)\n   {  }\n   Float operator() (\n      Fun                 &F  ,\n      const FloatVector   &a  ,\n      const FloatVector   &b  ,\n      const SizeVector    &n  ,\n      const SizeVector    &p  ,\n      Float               &e  )\n   {  Float r;\n\n      typedef IntegrateLast<\n         Fun         ,\n         SizeVector  ,\n         FloatVector ,\n         Float       > IntegrateOne;\n\n      IntegrateOne Fm1(&F, m-1, a, b, n, p);\n      RombergMul<\n         IntegrateOne,\n         SizeVector  ,\n         FloatVector ,\n         m-1         > RombergMulM1;\n\n      Fm1.ClearEsum();\n      Fm1.ClearEcount();\n\n      r  = RombergMulM1(Fm1, a, b, n, p, e);\n\n      Float prod = 1;\n      for(size_t i = 0; i < m-1; i++)\n         prod *= (b[i] - a[i]);\n\n# ifndef NDEBUG\n      size_t pow2 = 1;\n      for(size_t i = 0; i < m-1; i++)\n         for(size_t j = 0; j < (n[i] - 1); j++)\n            pow2 *= 2;\n      assert( Fm1.GetEcount() == (pow2+1) );\n# endif\n\n      e = e + Fm1.GetEsum() * prod / Float( double(Fm1.GetEcount()) );\n\n      return r;\n   }\n};\n\ntemplate <class Fun, class SizeVector, class FloatVector>\nclass RombergMul <Fun, SizeVector, FloatVector, 1> {\n   typedef typename FloatVector::value_type Float;\npublic:\n   Float operator() (\n      Fun                 &F  ,\n      const FloatVector   &a  ,\n      const FloatVector   &b  ,\n      const SizeVector    &n  ,\n      const SizeVector    &p  ,\n      Float               &e  )\n   {  Float r;\n      typedef IntegrateLast<\n         Fun         ,\n         SizeVector  ,\n         FloatVector ,\n         Float       > IntegrateOne;\n\n      // check simple vector class specifications\n      CheckSimpleVector<Float, FloatVector>();\n\n      // check numeric type specifications\n      CheckNumericType<Float>();\n\n      IntegrateOne F0(&F, 0, a, b, n, p);\n\n      F0.ClearEsum();\n      F0.ClearEcount();\n\n      r  = F0(a);\n\n      assert( F0.GetEcount() == 1 );\n      e = F0.GetEsum();\n\n      return r;\n   }\n};\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/romberg_one.hpp",
    "content": "# ifndef CPPAD_UTILITY_ROMBERG_ONE_HPP\n# define CPPAD_UTILITY_ROMBERG_ONE_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin RombergOne}\n{xrst_spell\n   test test\n}\n\nOne DimensionalRomberg Integration\n##################################\n\nSyntax\n******\n| # ``include <cppad/utility/romberg_one.hpp>``\n| *r* = ``RombergOne`` ( *F* , *a* , *b* , *n* , *e* )\n\nDescription\n***********\nReturns the Romberg integration estimate\n:math:`r` for a one dimensional integral\n\n.. math::\n\n   r = \\int_a^b F(x) {\\bf d} x + O \\left[ (b - a) / 2^{n-1} \\right]^{2(p+1)}\n\nInclude\n*******\nThe file ``cppad/utility/romberg_one.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\nr\n*\nThe return value *r* has prototype\n\n   *Float* *r*\n\nIt is the estimate computed by ``RombergOne`` for the integral above.\n\nF\n*\nThe object *F* can be of any type, but it must support\nthe operation\n\n   *F* ( *x* )\n\nThe argument *x* to *F* has prototype\n\n   ``const`` *Float* & *x*\n\nThe return value of *F* is a *Float* object\n(see description of :ref:`RombergOne@Float` below).\n\na\n*\nThe argument *a* has prototype\n\n   ``const`` *Float* & *a*\n\nIt specifies the lower limit for the integration.\n\nb\n*\nThe argument *b* has prototype\n\n   ``const`` *Float* & *b*\n\nIt specifies the upper limit for the integration.\n\nn\n*\nThe argument *n* has prototype\n\n   ``size_t`` *n*\n\nA total number of :math:`2^{n-1} + 1` evaluations of *F* ( *x* )\nare used to estimate the integral.\n\np\n*\nThe argument *p* has prototype\n\n   ``size_t`` *p*\n\nIt must be less than or equal :math:`n`\nand determines the accuracy order in the approximation for the integral\nthat is returned by ``RombergOne`` .\nTo be specific\n\n.. math::\n\n   r = \\int_a^b F(x) {\\bf d} x + O \\left[ (b - a) / 2^{n-1} \\right]^{2(p+1)}\n\ne\n*\nThe argument *e* has prototype\n\n   *Float* & *e*\n\nThe input value of *e* does not matter\nand its output value is an approximation for the error in\nthe integral estimates; i.e.,\n\n.. math::\n\n   e \\approx \\left| r - \\int_a^b F(x) {\\bf d} x \\right|\n\nFloat\n*****\nThe type *Float* must satisfy the conditions\nfor a :ref:`NumericType-name` .\nThe routine :ref:`CheckNumericType-name` will generate an error message\nif this is not the case.\nIn addition, if *x* and *y* are *Float* objects,\n\n   *x* < *y*\n\nreturns the ``bool`` value true if *x* is less than\n*y* and false otherwise.\n{xrst_toc_hidden\n   example/utility/romberg_one.cpp\n}\nExample\n*******\nThe file\n:ref:`romberg_one.cpp-name`\ncontains an example and test a test of using this routine.\n\nSource Code\n***********\nThe source code for this routine is in the file\n``cppad/romberg_one.hpp`` .\n\n{xrst_end RombergOne}\n*/\n\n# include <cppad/utility/check_numeric_type.hpp>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/utility/vector.hpp>\n\nnamespace CppAD { // BEGIN CppAD namespace\n\ntemplate <class Fun, class Float>\nFloat RombergOne(\n   Fun           &F ,\n   const Float   &a ,\n   const Float   &b ,\n   size_t         n ,\n   size_t         p ,\n   Float         &e )\n{\n   size_t ipow2 = 1;\n   size_t k, i;\n   Float pow2, sum, x;\n\n   Float  zero  = Float(0);\n   Float  two   = Float(2);\n\n   // check specifications for a NumericType\n   CheckNumericType<Float>();\n\n   CPPAD_ASSERT_KNOWN(\n      n >= 2,\n      \"RombergOne: n must be greater than or equal 2\"\n   );\n   CppAD::vector<Float> r(n);\n\n   //  set r[i] = trapazoidal rule with 2^i intervals in [a, b]\n   r[0]  = ( F(a) + F(b) ) * (b - a) / two;\n   for(i = 1; i < n; i++)\n   {  ipow2 *= 2;\n      // there must be a conversion from int to any numeric type\n      pow2   = Float(int(ipow2));\n      sum    = zero;\n      for(k = 1; k < ipow2; k += 2)\n      {  // start = a + (b-a)/pow2, increment = 2*(b-a)/pow2\n         x    = ( (pow2 - Float(double(k))) * a + double(k) * b ) / pow2;\n         sum  = sum + F(x);\n      }\n      // combine function evaluations in sum with those in T[i-1]\n      r[i] = r[i-1] / two + sum * (b - a) / pow2;\n   }\n\n   // now compute the higher order estimates\n   size_t ipow4    = 1;   // order of accuract for previous estimate\n   Float pow4, pow4minus;\n   for(i = 0; i < p; i++)\n   {  // compute estimate accurate to O[ step^(2*(i+1)) ]\n      // put results in r[n-1], r[n-2], ... , r[n-i+1]\n      ipow4    *= 4;\n      pow4      = Float(int(ipow4));\n      pow4minus = Float(ipow4-1);\n      for(k = n-1; k > i; k--)\n         r[k] = ( pow4 * r[k] - r[k-1] ) / pow4minus;\n   }\n\n   // error estimate for r[n]\n   e = r[n-1] - r[n-2];\n   if( e < zero )\n      e = - e;\n   return r[n-1];\n}\n\n} // END CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/rosen_34.hpp",
    "content": "# ifndef CPPAD_UTILITY_ROSEN_34_HPP\n# define CPPAD_UTILITY_ROSEN_34_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin Rosen34}\n{xrst_spell\n   dep\n   rosenbrock\n   test test\n   tf\n   xf\n}\n\nA 3rd and 4th Order Rosenbrock ODE Solver\n#########################################\n\nSyntax\n******\n| # ``include <cppad/utility/rosen_34.hpp>``\n| *xf* = ``Rosen34`` ( *F* , *M* , *ti* , *tf* , *xi* )\n| *xf* = ``Rosen34`` ( *F* , *M* , *ti* , *tf* , *xi* , *e* )\n\nDescription\n***********\nThis is an embedded 3rd and 4th order Rosenbrock ODE solver\n(see Section 16.6 of :ref:`Bib@Numerical Recipes`\nfor a description of Rosenbrock ODE solvers).\nIn particular, we use the formulas taken from page 100 of\n:ref:`Bib@Shampine, L.F.`\n(except that the fraction 98/108 has been correction to be 97/108).\n\nWe use :math:`n` for the size of the vector *xi* .\nLet :math:`\\B{R}` denote the real numbers\nand let :math:`F : \\B{R} \\times \\B{R}^n \\rightarrow \\B{R}^n` be a smooth function.\nThe return value *xf* contains a 5th order\napproximation for the value :math:`X(tf)` where\n:math:`X : [ti , tf] \\rightarrow \\B{R}^n` is defined by\nthe following initial value problem:\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      X(ti)  & = & xi    \\\\\n      X'(t)  & = & F[t , X(t)]\n   \\end{eqnarray}\n\nIf your set of  ordinary differential equations are not stiff\nan explicit method may be better (perhaps :ref:`Runge45-name` .)\n\nInclude\n*******\nThe file ``cppad/utility/rosen_34.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\nxf\n**\nThe return value *xf* has the prototype\n\n   *Vector* *xf*\n\nand the size of *xf* is equal to *n*\n(see description of :ref:`Rosen34@Vector` below).\n\n.. math::\n\n   X(tf) = xf + O( h^5 )\n\nwhere :math:`h = (tf - ti) / M` is the step size.\nIf *xf* contains not a number :ref:`nan-name` ,\nsee the discussion of :ref:`f<Rosen34@Fun@Nan>` .\n\nFun\n***\nThe class *Fun*\nand the object *F* satisfy the prototype\n\n   *Fun* & *F*\n\nThis must support the following set of calls\n\n| |tab| *F* . ``Ode`` ( *t* , *x* , *f* )\n| |tab| *F* . ``Ode_ind`` ( *t* , *x* , *f_t* )\n| |tab| *F* . ``Ode_dep`` ( *t* , *x* , *f_x* )\n\nt\n=\nIn all three cases,\nthe argument *t* has prototype\n\n   ``const`` *Scalar* & *t*\n\n(see description of :ref:`Rosen34@Scalar` below).\n\nx\n=\nIn all three cases,\nthe argument *x* has prototype\n\n   ``const`` *Vector* & *x*\n\nand has size *n*\n(see description of :ref:`Rosen34@Vector` below).\n\nf\n=\nThe argument *f* to *F* . ``Ode`` has prototype\n\n   *Vector* & *f*\n\nOn input and output, *f* is a vector of size *n*\nand the input values of the elements of *f* do not matter.\nOn output,\n*f* is set equal to :math:`F(t, x)`\n(see *F* ( *t* , *x* ) in :ref:`Rosen34@Description` ).\n\nf_t\n===\nThe argument *f_t* to *F* . ``Ode_ind`` has prototype\n\n   *Vector* & *f_t*\n\nOn input and output, *f_t* is a vector of size *n*\nand the input values of the elements of *f_t* do not matter.\nOn output, the *i*-th element of\n*f_t* is set equal to :math:`\\partial_t F_i (t, x)`\n(see *F* ( *t* , *x* ) in :ref:`Rosen34@Description` ).\n\nf_x\n===\nThe argument *f_x* to *F* . ``Ode_dep`` has prototype\n\n   *Vector* & *f_x*\n\nOn input and output, *f_x* is a vector of size *n* * *n*\nand the input values of the elements of *f_x* do not matter.\nOn output, the [ *i* * *n* + *j* ] element of\n*f_x* is set equal to :math:`\\partial_{x(j)} F_i (t, x)`\n(see *F* ( *t* , *x* ) in :ref:`Rosen34@Description` ).\n\nNan\n===\nIf any of the elements of *f* , *f_t* , or *f_x*\nhave the value not a number ``nan`` ,\nthe routine ``Rosen34`` returns with all the\nelements of *xf* and *e* equal to ``nan`` .\n\nWarning\n=======\nThe arguments *f* , *f_t* , and *f_x*\nmust have a call by reference in their prototypes; i.e.,\ndo not forget the ``&`` in the prototype for\n*f* , *f_t* and *f_x* .\n\nOptimization\n============\nEvery call of the form\n\n   *F* . ``Ode_ind`` ( *t* , *x* , *f_t* )\n\nis directly followed by a call of the form\n\n   *F* . ``Ode_dep`` ( *t* , *x* , *f_x* )\n\nwhere the arguments *t* and *x* have not changed between calls.\nIn many cases it is faster to compute the values of *f_t*\nand *f_x* together and then pass them back one at a time.\n\nM\n*\nThe argument *M* has prototype\n\n   ``size_t`` *M*\n\nIt specifies the number of steps\nto use when solving the differential equation.\nThis must be greater than or equal one.\nThe step size is given by :math:`h = (tf - ti) / M`, thus\nthe larger *M* , the more accurate the\nreturn value *xf* is as an approximation\nfor :math:`X(tf)`.\n\nti\n**\nThe argument *ti* has prototype\n\n   ``const`` *Scalar* & *ti*\n\n(see description of :ref:`Rosen34@Scalar` below).\nIt specifies the initial time for *t* in the\ndifferential equation; i.e.,\nthe time corresponding to the value *xi* .\n\ntf\n**\nThe argument *tf* has prototype\n\n   ``const`` *Scalar* & *tf*\n\nIt specifies the final time for *t* in the\ndifferential equation; i.e.,\nthe time corresponding to the value *xf* .\n\nxi\n**\nThe argument *xi* has the prototype\n\n   ``const`` *Vector* & *xi*\n\nand the size of *xi* is equal to *n* .\nIt specifies the value of :math:`X(ti)`\n\ne\n*\nThe argument *e* is optional and has the prototype\n\n   *Vector* & *e*\n\nIf *e* is present,\nthe size of *e* must be equal to *n* .\nThe input value of the elements of *e* does not matter.\nOn output\nit contains an element by element\nestimated bound for the absolute value of the error in *xf*\n\n.. math::\n\n   e = O( h^4 )\n\nwhere :math:`h = (tf - ti) / M` is the step size.\n\nScalar\n******\nThe type *Scalar* must satisfy the conditions\nfor a :ref:`NumericType-name` .\nThe routine :ref:`CheckNumericType-name` will generate an error message\nif this is not the case.\nIn addition, the following operations must be defined for\n*Scalar* objects *a* and *b* :\n\n.. list-table::\n   :widths: auto\n\n   * - **Operation**\n     - **Description**\n   * - *a* < *b*\n     - less than operator (returns a ``bool`` object)\n\nVector\n******\nThe type *Vector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type Scalar<SimpleVector@Elements of Specified Type>` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nParallel Mode\n*************\nFor each set of types\n:ref:`Rosen34@Scalar` ,\n:ref:`Rosen34@Vector` , and\n:ref:`Rosen34@Fun` ,\nthe first call to ``Rosen34``\nmust not be :ref:`parallel<ta_in_parallel-name>` execution mode.\n\nExample\n*******\n{xrst_toc_hidden\n   example/utility/rosen_34.cpp\n}\nThe file\n:ref:`rosen_34.cpp-name`\ncontains an example and test a test of using this routine.\n\nSource Code\n***********\nThe source code for this routine is in the file\n``cppad/rosen_34.hpp`` .\n\n{xrst_end Rosen34}\n--------------------------------------------------------------------------\n*/\n\n# include <cstddef>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/utility/check_simple_vector.hpp>\n# include <cppad/utility/check_numeric_type.hpp>\n# include <cppad/utility/vector.hpp>\n# include <cppad/utility/lu_factor.hpp>\n# include <cppad/utility/lu_invert.hpp>\n\n// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { // BEGIN CppAD namespace\n\ntemplate <class Scalar, class Vector, class Fun>\nVector Rosen34(\n   Fun           &F ,\n   size_t         M ,\n   const Scalar &ti ,\n   const Scalar &tf ,\n   const Vector &xi )\n{  Vector e( xi.size() );\n   return Rosen34(F, M, ti, tf, xi, e);\n}\n\ntemplate <class Scalar, class Vector, class Fun>\nVector Rosen34(\n   Fun           &F ,\n   size_t         M ,\n   const Scalar &ti ,\n   const Scalar &tf ,\n   const Vector &xi ,\n   Vector       &e )\n{\n   CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n\n   // check numeric type specifications\n   CheckNumericType<Scalar>();\n\n   // check simple vector class specifications\n   CheckSimpleVector<Scalar, Vector>();\n\n   // Parameters for Shampine's Rosenbrock method\n   // are static to avoid recalculation on each call and\n   // do not use Vector to avoid possible memory leak\n   static Scalar a[3] = {\n      Scalar(0),\n      Scalar(1),\n      Scalar(3)   / Scalar(5)\n   };\n   static Scalar b[2 * 2] = {\n      Scalar(1),\n      Scalar(0),\n      Scalar(24)  / Scalar(25),\n      Scalar(3)   / Scalar(25)\n   };\n   static Scalar ct[4] = {\n      Scalar(1)   / Scalar(2),\n      - Scalar(3) / Scalar(2),\n      Scalar(121) / Scalar(50),\n      Scalar(29)  / Scalar(250)\n   };\n   static Scalar cg[3 * 3] = {\n      - Scalar(4),\n      Scalar(0),\n      Scalar(0),\n      Scalar(186) / Scalar(25),\n      Scalar(6)   / Scalar(5),\n      Scalar(0),\n      - Scalar(56) / Scalar(125),\n      - Scalar(27) / Scalar(125),\n      - Scalar(1)  / Scalar(5)\n   };\n   static Scalar d3[3] = {\n      Scalar(97) / Scalar(108),\n      Scalar(11) / Scalar(72),\n      Scalar(25) / Scalar(216)\n   };\n   static Scalar d4[4] = {\n      Scalar(19)  / Scalar(18),\n      Scalar(1)   / Scalar(4),\n      Scalar(25)  / Scalar(216),\n      Scalar(125) / Scalar(216)\n   };\n   CPPAD_ASSERT_KNOWN(\n      M >= 1,\n      \"Error in Rosen34: the number of steps is less than one\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      e.size() == xi.size(),\n      \"Error in Rosen34: size of e not equal to size of xi\"\n   );\n   size_t i, j, k, l, m;             // indices\n\n   size_t  n    = xi.size();         // number of components in X(t)\n   Scalar  ns   = Scalar(double(M)); // number of steps as Scalar object\n   Scalar  h    = (tf - ti) / ns;    // step size\n   Scalar  zero = Scalar(0);         // some constants\n   Scalar  one  = Scalar(1);\n   Scalar  two  = Scalar(2);\n\n   // permutation vectors needed for LU factorization routine\n   CppAD::vector<size_t> ip(n), jp(n);\n\n   // vectors used to store values returned by F\n   Vector E(n * n), Eg(n), f_t(n);\n   Vector g(n * 3), x3(n), x4(n), xf(n), ftmp(n), xtmp(n), nan_vec(n);\n\n   // initialize e = 0, nan_vec = nan\n   for(i = 0; i < n; i++)\n   {  e[i]       = zero;\n      nan_vec[i] = nan(zero);\n   }\n\n   xf = xi;           // initialize solution\n   for(m = 0; m < M; m++)\n   {  // time at beginning of this interval\n      Scalar t = ti * (Scalar(int(M - m)) / ns)\n                 + tf * (Scalar(int(m)) / ns);\n\n      // value of x at beginning of this interval\n      x3 = x4 = xf;\n\n      // evaluate partial derivatives at beginning of this interval\n      F.Ode_ind(t, xf, f_t);\n      F.Ode_dep(t, xf, E);    // E = f_x\n      if( hasnan(f_t) || hasnan(E) )\n      {  e = nan_vec;\n         return nan_vec;\n      }\n\n      // E = I - f_x * h / 2\n      for(i = 0; i < n; i++)\n      {  for(j = 0; j < n; j++)\n            E[i * n + j] = - E[i * n + j] * h / two;\n         E[i * n + i] += one;\n      }\n\n      // LU factor the matrix E\n# ifndef NDEBUG\n      int sign = LuFactor(ip, jp, E);\n# else\n      LuFactor(ip, jp, E);\n# endif\n      CPPAD_ASSERT_KNOWN(\n         sign != 0,\n         \"Error in Rosen34: I - f_x * h / 2 not invertible\"\n      );\n\n      // loop over integration steps\n      for(k = 0; k < 3; k++)\n      {  // set location for next function evaluation\n         xtmp = xf;\n         for(l = 0; l < k; l++)\n         {  // loop over previous function evaluations\n            Scalar bkl = b[(k-1)*2 + l];\n            for(i = 0; i < n; i++)\n            {  // loop over elements of x\n               xtmp[i] += bkl * g[i*3 + l] * h;\n            }\n         }\n         // ftmp = F(t + a[k] * h, xtmp)\n         F.Ode(t + a[k] * h, xtmp, ftmp);\n         if( hasnan(ftmp) )\n         {  e = nan_vec;\n            return nan_vec;\n         }\n\n         // Form Eg for this integration step\n         for(i = 0; i < n; i++)\n            Eg[i] = ftmp[i] + ct[k] * f_t[i] * h;\n         for(l = 0; l < k; l++)\n         {  for(i = 0; i < n; i++)\n               Eg[i] += cg[(k-1)*3 + l] * g[i*3 + l];\n         }\n\n         // Solve the equation E * g = Eg\n         LuInvert(ip, jp, E, Eg);\n\n         // save solution and advance x3, x4\n         for(i = 0; i < n; i++)\n         {  g[i*3 + k]  = Eg[i];\n            x3[i]      += h * d3[k] * Eg[i];\n            x4[i]      += h * d4[k] * Eg[i];\n         }\n      }\n      // Form Eg for last update to x4 only\n      for(i = 0; i < n; i++)\n         Eg[i] = ftmp[i] + ct[3] * f_t[i] * h;\n      for(l = 0; l < 3; l++)\n      {  for(i = 0; i < n; i++)\n            Eg[i] += cg[2*3 + l] * g[i*3 + l];\n      }\n\n      // Solve the equation E * g = Eg\n      LuInvert(ip, jp, E, Eg);\n\n      // advance x4 and accumulate error bound\n      for(i = 0; i < n; i++)\n      {  x4[i] += h * d4[3] * Eg[i];\n\n         // cant use abs because cppad.hpp may not be included\n         Scalar diff = x4[i] - x3[i];\n         if( diff < zero )\n            e[i] -= diff;\n         else\n            e[i] += diff;\n      }\n\n      // advance xf for this step using x4\n      xf = x4;\n   }\n   return xf;\n}\n\n} // End CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/runge_45.hpp",
    "content": "# ifndef CPPAD_UTILITY_RUNGE_45_HPP\n# define CPPAD_UTILITY_RUNGE_45_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin Runge45}\n{xrst_spell\n   karp\n   kutta\n   tf\n   xf\n}\n\nAn Embedded 4th and 5th Order Runge-Kutta ODE Solver\n####################################################\n\nSyntax\n******\n| # ``include <cppad/utility/runge_45.hpp>``\n| *xf* = ``Runge45`` ( *F* , *M* , *ti* , *tf* , *xi* )\n| *xf* = ``Runge45`` ( *F* , *M* , *ti* , *tf* , *xi* , *e* )\n\nPurpose\n*******\nThis is an implementation of the\nCash-Karp embedded 4th and 5th order Runge-Kutta ODE solver\ndescribed in Section 16.2 of :ref:`Bib@Numerical Recipes` .\nWe use :math:`n` for the size of the vector *xi* .\nLet :math:`\\B{R}` denote the real numbers\nand let :math:`F : \\B{R} \\times \\B{R}^n \\rightarrow \\B{R}^n`\nbe a smooth function.\nThe return value *xf* contains a 5th order\napproximation for the value :math:`X(tf)` where\n:math:`X : [ti , tf] \\rightarrow \\B{R}^n` is defined by\nthe following initial value problem:\n\n.. math::\n   :nowrap:\n\n   \\begin{eqnarray}\n      X(ti)  & = & xi    \\\\\n      X'(t)  & = & F[t , X(t)]\n   \\end{eqnarray}\n\nIf your set of ordinary differential equations\nare stiff, an implicit method may be better\n(perhaps :ref:`Rosen34-name` .)\n\nOperation Sequence\n******************\nThe :ref:`operation sequence<glossary@Operation@Sequence>` for *Runge*\ndoes not depend on any of its *Scalar* input values provided that\nthe operation sequence for\n\n   *F* . ``Ode`` ( *t* , *x* , *f* )\n\ndoes not on any of its *Scalar* inputs (see below).\n\nInclude\n*******\nThe file ``cppad/utility/runge_45.hpp``\nis included by ``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\nxf\n**\nThe return value *xf* has the prototype\n\n   *Vector* *xf*\n\nand the size of *xf* is equal to *n*\n(see description of :ref:`Runge45@Vector` below).\n\n.. math::\n\n   X(tf) = xf + O( h^6 )\n\nwhere :math:`h = (tf - ti) / M` is the step size.\nIf *xf* contains not a number :ref:`nan-name` ,\nsee the discussion for :ref:`Runge45@Fun@f` .\n\nFun\n***\nThe class *Fun*\nand the object *F* satisfy the prototype\n\n   *Fun* & *F*\n\nThe object *F* (and the class *Fun* )\nmust have a member function named ``Ode``\nthat supports the syntax\n\n   *F* . ``Ode`` ( *t* , *x* , *f* )\n\nt\n=\nThe argument *t* to *F* . ``Ode`` has prototype\n\n   ``const`` *Scalar* & *t*\n\n(see description of :ref:`Runge45@Scalar` below).\n\nx\n=\nThe argument *x* to *F* . ``Ode`` has prototype\n\n   ``const`` *Vector* & *x*\n\nand has size *n*\n(see description of :ref:`Runge45@Vector` below).\n\nf\n=\nThe argument *f* to *F* . ``Ode`` has prototype\n\n   *Vector* & *f*\n\nOn input and output, *f* is a vector of size *n*\nand the input values of the elements of *f* do not matter.\nOn output,\n*f* is set equal to :math:`F(t, x)` in the differential equation.\nIf any of the elements of *f* have the value not a number ``nan``\nthe routine ``Runge45`` returns with all the\nelements of *xf* and *e* equal to ``nan`` .\n\nWarning\n=======\nThe argument *f* to *F* . ``Ode``\nmust have a call by reference in its prototype; i.e.,\ndo not forget the ``&`` in the prototype for *f* .\n\nM\n*\nThe argument *M* has prototype\n\n   ``size_t`` *M*\n\nIt specifies the number of steps\nto use when solving the differential equation.\nThis must be greater than or equal one.\nThe step size is given by :math:`h = (tf - ti) / M`, thus\nthe larger *M* , the more accurate the\nreturn value *xf* is as an approximation\nfor :math:`X(tf)`.\n\nti\n**\nThe argument *ti* has prototype\n\n   ``const`` *Scalar* & *ti*\n\n(see description of :ref:`Runge45@Scalar` below).\nIt specifies the initial time for *t* in the\ndifferential equation; i.e.,\nthe time corresponding to the value *xi* .\n\ntf\n**\nThe argument *tf* has prototype\n\n   ``const`` *Scalar* & *tf*\n\nIt specifies the final time for *t* in the\ndifferential equation; i.e.,\nthe time corresponding to the value *xf* .\n\nxi\n**\nThe argument *xi* has the prototype\n\n   ``const`` *Vector* & *xi*\n\nand the size of *xi* is equal to *n* .\nIt specifies the value of :math:`X(ti)`\n\ne\n*\nThe argument *e* is optional and has the prototype\n\n   *Vector* & *e*\n\nIf *e* is present,\nthe size of *e* must be equal to *n* .\nThe input value of the elements of *e* does not matter.\nOn output\nit contains an element by element\nestimated bound for the absolute value of the error in *xf*\n\n.. math::\n\n   e = O( h^5 )\n\nwhere :math:`h = (tf - ti) / M` is the step size.\nIf on output, *e* contains not a number ``nan`` ,\nsee the discussion for :ref:`Runge45@Fun@f` .\n\nScalar\n******\nThe type *Scalar* must satisfy the conditions\nfor a :ref:`NumericType-name` .\nThe routine :ref:`CheckNumericType-name` will generate an error message\nif this is not the case.\n\nfabs\n====\nIn addition, the following function must be defined for\n*Scalar* objects *a* and *b*\n\n   *a* = ``fabs`` ( *b* )\n\nNote that this operation is only used for computing *e* ; hence\nthe operation sequence for *xf* can still be independent of\nthe arguments to ``Runge45`` even if\n\n   ``fabs`` ( *b* ) = ``std::max`` ( ``-`` *b* , *b* )\n\n.\n\nVector\n******\nThe type *Vector* must be a :ref:`SimpleVector-name` class with\n:ref:`elements of type Scalar<SimpleVector@Elements of Specified Type>` .\nThe routine :ref:`CheckSimpleVector-name` will generate an error message\nif this is not the case.\n\nParallel Mode\n*************\nFor each set of types\n:ref:`Runge45@Scalar` ,\n:ref:`Runge45@Vector` , and\n:ref:`Runge45@Fun` ,\nthe first call to ``Runge45``\nmust not be :ref:`parallel<ta_in_parallel-name>` execution mode.\n\nExample\n*******\n{xrst_toc_hidden\n   example/utility/runge45_1.cpp\n   example/utility/runge_45.cpp\n}\nThe file\n:ref:`runge45_1.cpp-name`\ncontains a simple example and test of ``Runge45`` .\n\nThe file\n:ref:`runge_45.cpp-name` contains an example using ``Runge45``\nin the context of algorithmic differentiation.\nIt also returns true if it succeeds and false otherwise.\n\nSource Code\n***********\nThe source code for this routine is in the file\n``cppad/runge_45.hpp`` .\n\n{xrst_end Runge45}\n--------------------------------------------------------------------------\n*/\n# include <cstddef>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/utility/check_simple_vector.hpp>\n# include <cppad/utility/check_numeric_type.hpp>\n# include <cppad/utility/nan.hpp>\n\n// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL\n# include <cppad/utility/thread_alloc.hpp>\n\nnamespace CppAD { // BEGIN CppAD namespace\n\ntemplate <class Scalar, class Vector, class Fun>\nVector Runge45(\n   Fun           &F ,\n   size_t         M ,\n   const Scalar &ti ,\n   const Scalar &tf ,\n   const Vector &xi )\n{  Vector e( xi.size() );\n   return Runge45(F, M, ti, tf, xi, e);\n}\n\ntemplate <class Scalar, class Vector, class Fun>\nVector Runge45(\n   Fun           &F ,\n   size_t         M ,\n   const Scalar &ti ,\n   const Scalar &tf ,\n   const Vector &xi ,\n   Vector       &e )\n{\n   CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n\n   // check numeric type specifications\n   CheckNumericType<Scalar>();\n\n   // check simple vector class specifications\n   CheckSimpleVector<Scalar, Vector>();\n\n   // Cash-Karp parameters for embedded Runge-Kutta method\n   // are static to avoid recalculation on each call and\n   // do not use Vector to avoid possible memory leak\n   static Scalar a[6] = {\n      Scalar(0),\n      Scalar(1) / Scalar(5),\n      Scalar(3) / Scalar(10),\n      Scalar(3) / Scalar(5),\n      Scalar(1),\n      Scalar(7) / Scalar(8)\n   };\n   static Scalar b[5 * 5] = {\n      Scalar(1) / Scalar(5),\n      Scalar(0),\n      Scalar(0),\n      Scalar(0),\n      Scalar(0),\n\n      Scalar(3) / Scalar(40),\n      Scalar(9) / Scalar(40),\n      Scalar(0),\n      Scalar(0),\n      Scalar(0),\n\n      Scalar(3) / Scalar(10),\n      -Scalar(9) / Scalar(10),\n      Scalar(6) / Scalar(5),\n      Scalar(0),\n      Scalar(0),\n\n      -Scalar(11) / Scalar(54),\n      Scalar(5) / Scalar(2),\n      -Scalar(70) / Scalar(27),\n      Scalar(35) / Scalar(27),\n      Scalar(0),\n\n      Scalar(1631) / Scalar(55296),\n      Scalar(175) / Scalar(512),\n      Scalar(575) / Scalar(13824),\n      Scalar(44275) / Scalar(110592),\n      Scalar(253) / Scalar(4096)\n   };\n   static Scalar c4[6] = {\n      Scalar(2825) / Scalar(27648),\n      Scalar(0),\n      Scalar(18575) / Scalar(48384),\n      Scalar(13525) / Scalar(55296),\n      Scalar(277) / Scalar(14336),\n      Scalar(1) / Scalar(4),\n   };\n   static Scalar c5[6] = {\n      Scalar(37) / Scalar(378),\n      Scalar(0),\n      Scalar(250) / Scalar(621),\n      Scalar(125) / Scalar(594),\n      Scalar(0),\n      Scalar(512) / Scalar(1771)\n   };\n\n   CPPAD_ASSERT_KNOWN(\n      M >= 1,\n      \"Error in Runge45: the number of steps is less than one\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      e.size() == xi.size(),\n      \"Error in Runge45: size of e not equal to size of xi\"\n   );\n   size_t i, j, k, m;              // indices\n\n   size_t  n = xi.size();           // number of components in X(t)\n   Scalar  ns = Scalar(int(M));     // number of steps as Scalar object\n   Scalar  h = (tf - ti) / ns;      // step size\n   Scalar  zero_or_nan = Scalar(0); // zero (nan if Ode returns has a nan)\n   for(i = 0; i < n; i++)           // initialize e = 0\n      e[i] = zero_or_nan;\n\n   // vectors used to store values returned by F\n   Vector fh(6 * n), xtmp(n), ftmp(n), x4(n), x5(n), xf(n);\n\n   xf = xi;           // initialize solution\n   for(m = 0; m < M; m++)\n   {  // time at beginning of this interval\n      // (convert to int to avoid MS compiler warning)\n      Scalar t = ti * (Scalar(int(M - m)) / ns)\n                 + tf * (Scalar(int(m)) / ns);\n\n      // loop over integration steps\n      x4 = x5 = xf;   // start x4 and x5 at same point for each step\n      for(j = 0; j < 6; j++)\n      {  // loop over function evaluations for this step\n         xtmp = xf;  // location for next function evaluation\n         for(k = 0; k < j; k++)\n         {  // loop over previous function evaluations\n            Scalar bjk = b[ (j-1) * 5 + k ];\n            for(i = 0; i < n; i++)\n            {  // loop over elements of x\n               xtmp[i] += bjk * fh[i * 6 + k];\n            }\n         }\n         // ftmp = F(t + a[j] * h, xtmp)\n         F.Ode(t + a[j] * h, xtmp, ftmp);\n\n         // if ftmp has a nan, set zero_or_nan to nan\n         for(i = 0; i < n; i++)\n            zero_or_nan *= ftmp[i];\n\n         for(i = 0; i < n; i++)\n         {  // loop over elements of x\n            Scalar fhi    = ftmp[i] * h;\n            fh[i * 6 + j] = fhi;\n            x4[i]        += c4[j] * fhi;\n            x5[i]        += c5[j] * fhi;\n            x5[i]        += zero_or_nan;\n         }\n      }\n      // accumulate error bound\n      for(i = 0; i < n; i++)\n      {  // cant use abs because cppad.hpp may not be included\n         Scalar diff = x5[i] - x4[i];\n         e[i] += fabs(diff);\n         e[i] += zero_or_nan;\n      }\n\n      // advance xf for this step using x5\n      xf = x5;\n   }\n   return xf;\n}\n\n} // End CppAD namespace\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/set_union.hpp",
    "content": "# ifndef CPPAD_UTILITY_SET_UNION_HPP\n# define CPPAD_UTILITY_SET_UNION_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin set_union}\n\nUnion of Standard Sets\n######################\n\nSyntax\n******\n| # ``include <cppad/utility/set_union.hpp>``\n| *result* = ``set_union`` ( *left* , *right* )\n\nPurpose\n*******\nThis is a simplified (and restricted) interface to\nthe ``std::union`` operation.\n\nElement\n*******\nThis is the type of the elements of the sets.\n\nleft\n****\nThis argument has prototype\n\n   ``const std::set<`` *Element* >& *left*\n\nright\n*****\nThis argument has prototype\n\n   ``const std::set<`` *Element* >& *right*\n\nresult\n******\nThe return value has prototype\n\n   ``std::set<`` *Element* >& *result*\n\nIt contains the union of *left* and *right* .\nNote that C++11 detects that the return value is a temporary\nand uses it for the result instead of making a separate copy.\n{xrst_toc_hidden\n   example/utility/set_union.cpp\n}\nExample\n*******\nThe file :ref:`set_union.cpp-name` contains an example and test of this\n\n{xrst_end set_union}\n*/\n\n# include <set>\n# include <algorithm>\n# include <iterator>\n\nnamespace CppAD {\n   template <class Element>\n   std::set<Element> set_union(\n      const std::set<Element>&     left   ,\n      const std::set<Element>&     right  )\n   {  std::set<Element> result;\n      std::set_union(\n         left.begin()              ,\n         left.end()                ,\n         right.begin()             ,\n         right.end()               ,\n         std::inserter(result, result.begin())\n      );\n      return result;\n   }\n}\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/sparse2eigen.hpp",
    "content": "# ifndef CPPAD_UTILITY_SPARSE2EIGEN_HPP\n# define CPPAD_UTILITY_SPARSE2EIGEN_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin sparse2eigen}\n{xrst_spell\n   nnz\n}\n\nConvert A CppAD Sparse Matrix to an Eigen Sparse Matrix\n#######################################################\n\nSyntax\n******\n| # ``include <cppad/utility/sparse2eigen.hpp>``\n| ``sparse2eigen`` ( *source* , *destination* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PROTOTYPE\n   // END_PROTOTYPE\n}\n\nInclude\n*******\nIf :ref:`cmake@Eigen` is found (and c++14 is supported),\nthe file ``cppad/utility/sparse2eigen.hpp``\nis included by ``cppad/cppad.hpp`` .\nIn any case,\nit can also be included separately with out the rest of\nthe ``CppAD`` routines.\nIncluding this file defines\nthis version of the ``sparse2eigen`` within the ``CppAD`` namespace.\n\nSizeVector\n**********\nWe use :ref:`sparse_rc@SizeVector` to denote a\n:ref:`SimpleVector-name` class with elements of ``size_t`` .\n\nValueVector\n***********\nWe use *ValueVector* to denote a\n:ref:`SimpleVector-name` class with elements of type *value_type* .\n\nOptions\n*******\nWe use *Options* to denote either\n``Eigen::RowMajor`` of ``Eigen::ColMajor`` .\n\nvalue_type\n**********\nThe type of elements of elements in *source* and *destination*\nmust be the same. We use *value_type* to denote this type.\n\nsource\n******\nThis is the CppAD sparse matrix that is being converted to eigen format.\n\ndestination\n***********\nThis is the Eigen sparse matrix that is the result of the conversion.\n\nCompressed\n**********\nThe result matrix *destination*\nis in compressed format. For example, let\n\n| |tab| ``size_t`` *nnz* = *source* . ``nnz`` ();\n| |tab| ``const`` *s_vector* & *s_value* = *source* . ``val`` ();\n| |tab| ``const`` *value_type* * *d_value* = *destination* . ``valuePtr`` ();\n| |tab| ``const`` *s_vector* & *row_major* = *source* . ``row_major`` ();\n| |tab| ``const`` *s_vector* & *col_major* = *source* . ``col_major`` ();\n\nIt follows that, for *k* = 0 , ..., *nnz* :\nIf *Options* is ``Eigen::RowMajor`` ,\n\n   *d_value* [ *k* ] == *s_value* [ *row_major* [ *k* ] ]\n\nIf *Options* is ``Eigen::ColMajor`` ,\n\n   *d_value* [ *k* ] == *s_value* [ *col_major* [ *k* ] ]\n\n{xrst_toc_hidden\n   example/sparse/sparse2eigen.cpp\n}\n\nExample\n*******\nThe file :ref:`sparse2eigen.cpp-name` contains an example and test\nof ``sparse2eigen.cpp`` It return true if the test passes\nand false otherwise.\n\n{xrst_end sparse2eigen}\n*/\n# include <cppad/configure.hpp>\n# include <Eigen/Sparse>\n# include <cppad/utility/sparse_rcv.hpp>\n# include <cppad/utility/vector.hpp>\n\nnamespace CppAD { // BEGIN CPPAD_NAMESPACE\n\n// BEGIN_PROTOTYPE\ntemplate <class SizeVector, class ValueVector, int Options>\nvoid sparse2eigen(\nconst CppAD::sparse_rcv<SizeVector, ValueVector>&               source       ,\nEigen::SparseMatrix<typename ValueVector::value_type, Options>& destination  )\n// END_PROTOTYPE\n{  using Eigen::Index;\n   typedef typename ValueVector::value_type value_type;\n   typedef Eigen::Triplet<value_type>       triplet;\n   std::vector<triplet> vec( source.nnz() );\n   //\n   const SizeVector&  row = source.row();\n   const SizeVector&  col = source.col();\n   const ValueVector& val = source.val();\n   //\n   for(size_t k = 0; k < source.nnz(); k++)\n      vec[k] = triplet( int(row[k]), int(col[k]), val[k] );\n   //\n   size_t nr = source.nr();\n   size_t nc = source.nc();\n   destination.resize( Index(nr), Index(nc) );\n   destination.setFromTriplets(vec.begin(), vec.end());\n   //\n   CPPAD_ASSERT_UNKNOWN( destination.isCompressed() );\n   //\n   return;\n}\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/sparse_rc.hpp",
    "content": "# ifndef CPPAD_UTILITY_SPARSE_RC_HPP\n# define CPPAD_UTILITY_SPARSE_RC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin sparse_rc}\n{xrst_spell\n   nnz\n   nr\n   ostream\n}\nRow and Column Index Sparsity Patterns\n######################################\n\nSyntax\n******\n\ninclude\n=======\n\n   # ``include <cppad/utility/sparse_rc.hpp>``\n\nConstructor\n===========\n\n| ``sparse_rc`` < *SizeVector* > *empty*\n| ``sparse_rc`` < *SizeVector* > *pattern* ( *nr* , *nc* , *nnz* )\n| ``sparse_rc`` < *SizeVector* > *pattern* ( *other* )\n\nAssignment\n==========\n\n| *pattern* = *other*\n| *pattern* . ``swap`` ( *other* )\n\nEquality\n========\n\n   *equal* = *pattern* == *other*\n\n.\n\nSetting\n=======\n\n| *resize* ( *nr* , *nc* , *nnz* )\n| *pattern* . ``set`` ( *k* , *r* , *c* )\n| *pattern* . ``push_back`` ( *r* , *c* )\n| *pattern* . ``set_row_major`` ()\n| *pattern* . ``set_col_major`` ()\n\nScalars\n=======\n\n| *pattern* . ``nr`` ()\n| *pattern* . ``nc`` ()\n| *pattern* . ``nnz`` ()\n\nVectors\n=======\n\n| ``const`` *SizeVector* & *row* ( *pattern* . ``row`` () )\n| ``const`` *SizeVector* & *col* ( *pattern* . ``col`` () )\n| ``const`` *SizeVector* & *row_major* ( *pattern* . ``get_row_major`` () )\n| ``const`` *SizeVector* & *col_major* ( *pattern* . ``get_col_major`` () )\n| *row_major* = *pattern* . ``row_major`` ()\n| *col_major* = *pattern* . ``col_major`` ()\n\nOutput\n======\n\n   *os* << *pattern*\n\nSizeVector\n**********\nWe use *SizeVector* to denote :ref:`SimpleVector-name` class\n:ref:`with elements of type<SimpleVector@Elements of Specified Type>`\n``size_t`` .\nIn addition, *SimpleVector* must support the ``swap`` operation\nbetween two of its vectors.\n\nempty\n*****\nThis is an empty sparsity pattern. To be specific,\nthe corresponding number of rows *nr* ,\nnumber of columns *nc* ,\nand number of possibly non-zero values *nnz* ,\nare all zero.\n\npattern\n*******\nThis object is used to hold a sparsity pattern for a matrix.\nThe sparsity *pattern* is ``const``\nexcept during its constructor, ``resize`` , and ``set`` .\n\nother\n*****\n\nAssignment and Constructor\n==========================\nIn the assignment and constructor, *other* has prototype\n\n   ``const sparse_rc`` < *SizeVector* >& *other*\n\nAfter the assignment and constructor, *pattern* is an independent copy\nof *other* ; i.e. it has all the same values as *other*\nand changes to *pattern* do not affect *other* .\n\nMove Semantics Assignment and Constructor\n=========================================\nIn the assignment and constructor, if *other* has prototype\n\n   ``sparse_rc`` < *SizeVector* >&& *other*\n\nA move semantics version of the assignment or constructor is used; e.g.,\nwhen *other* is a function return value.\n\nswap\n====\nIn the swap operation, *other* has prototype\n\n   ``sparse_rc`` < *SizeVector* >& *other*\n\nAfter the swap operation *other* ( *pattern* ) is equivalent\nto *pattern* ( *other* ) before the operation.\n\nEquality\n========\nIn the equality operation, *other* has prototype\n\n   ``const sparse_rc`` < *SizeVector* >& *other*\n\nThe two sparsity patterns are equal if the following conditions hold:\n\n#. The number of rows\n   *pattern* . ``nr`` () and *other* . ``nr`` () are equal.\n#. The number of columns\n   *pattern* . ``nc`` () and *other* . ``nc`` () are equal.\n#. The number of non-zero values\n   *pattern* . ``nnz`` () and *other* . ``nnz`` () are equal.\n#. The set of (row, column) pairs corresponding to\n   *pattern* and *other* , are equal.\n\nDetermining equality requires sorting both patterns\n\nnr\n**\nThis argument has prototype\n\n   ``size_t`` *nr*\n\nIt specifies the number of rows in the sparsity pattern.\nThe function call ``nr()`` returns the value of *nr* .\n\nnc\n**\nThis argument has prototype\n\n   ``size_t`` *nc*\n\nIt specifies the number of columns in the sparsity pattern.\nThe function call ``nc()`` returns the value of *nc* .\n\nnnz\n***\nThis argument has prototype\n\n   ``size_t`` *nnz*\n\nIt specifies the number of possibly non-zero\nindex pairs in the sparsity pattern.\nThe function call ``nnz()`` returns the value of *nnz* .\n\nresize\n******\nThe current sparsity pattern is lost and a new one is started\nwith the specified parameters. The elements in the *row*\nand *col* vectors should be assigned using ``set`` .\n\nset\n***\nThis function sets the values\n\n| |tab| *row* [ *k* ] = *r*\n| |tab| *col* [ *k* ] = *c*\n\npush_back\n*********\nThis function  the value *r* to the back of *row* ,\nthe value *c* to the back of *col* ,\nand increases *nnz* by one.\nThis operation requires *SizeVector* to support the\n``push_back`` operation\n(which is not part of the SimpleVector requirements).\n\nk\n=\nThis argument has type\n\n   ``size_t`` *k*\n\nand must be less than *nnz* .\n\nr\n=\nThis argument has type\n\n   ``size_t`` *r*\n\nIt specifies the value assigned to *row* [ *k* ] and must\nbe less than *nr* .\n\nc\n=\nThis argument has type\n\n   ``size_t`` *c*\n\nIt specifies the value assigned to *col* [ *k* ] and must\nbe less than *nc* .\n\nrow\n***\nThis vector has size *nnz* and\n*row* [ *k* ]\nis the row index of the *k*-th possibly non-zero\nindex pair in the sparsity pattern.\n\ncol\n***\nThis vector has size *nnz* and\n*col* [ *k* ] is the column index of the *k*-th possibly non-zero\nindex pair in the sparsity pattern.\n\nrow_major\n*********\nThis vector has prototype\n\n   *SizeVector* *row_major*\n\nand its size *nnz* .\nIt sorts the sparsity pattern in row-major order.\nTo be specific,\n\n   *col* [ *row_major* [ *k* ] ] <= *col* [ *row_major* [ *k* +1] ]\n\nand if *col* [ *row_major* [ *k* ] ] == *col* [ *row_major* [ *k* +1] ] ,\n\n   *row* [ *row_major* [ *k* ] ] < *row* [ *row_major* [ *k* +1] ]\n\nThis routine generates an assert if there are two entries with the same\nrow and column values (if ``NDEBUG`` is not defined).\n\nset_row_major\n*************\nStore the current row major order in *pattern* .\nThis can be used by the row_major function and the equality function\nto avoid re-sorting the pattern each time.\n\nget_row_major\n*************\nRetrieve the row major order stored in *pattern*\nby the previous ``set_row_major`` .\nIf this order is no longer valid, the return value\n*row_major* has size zero.\n\ncol_major\n*********\nThis vector has prototype\n\n   *SizeVector* *col_major*\n\nand its size *nnz* .\nIt sorts the sparsity pattern in column-major order.\nTo be specific,\n\n   *row* [ *col_major* [ *k* ] ] <= *row* [ *col_major* [ *k* +1] ]\n\nand if *row* [ *col_major* [ *k* ] ] == *row* [ *col_major* [ *k* +1] ] ,\n\n   *col* [ *col_major* [ *k* ] ] < *col* [ *col_major* [ *k* +1] ]\n\nThis routine generates an assert if there are two entries with the same\nrow and column values (if ``NDEBUG`` is not defined).\n\nset_col_major\n*************\nStore the current row major order in *pattern* .\nThis can be used by the col_major function and the equality function\nto avoid re-sorting the pattern each time.\n\nget_col_major\n*************\nRetrieve the row major order stored in *pattern*\nby the previous ``set_col_major`` .\nIf this order is no longer valid, the return value\n*col_major* has size zero.\n{xrst_toc_hidden\n   example/utility/sparse_rc.cpp\n}\nExample\n*******\nThe file :ref:`sparse_rc.cpp-name`\ncontains an example and test of this class.\n\nos\n**\nIf *os* is an ``std::ostream`` , the operation\n\n   *os* << *pattern*\n\noutputs *pattern* to the *os* stream.\nThe output begins with a left brace ``{``\nand ends with a right brace ``}`` .\nThe output is in row major order and has one line for each row.\nThe row index is output at the beginning of a line\nand the column indices follow.\n\n{xrst_end sparse_rc}\n*/\n# include <cstddef> // for size_t\n# include <cppad/core/cppad_assert.hpp>  // for CPPAD_ASSERT\n# include <cppad/utility/index_sort.hpp> // for row and column major ordering\n\nnamespace CppAD { // BEGIN CPPAD_NAMESPACE\n\n// sparsity pattern for a matrix with indices of type size_t\ntemplate <class SizeVector>\nclass sparse_rc {\nprivate:\n   // number of rows in the sparsity pattern\n   size_t nr_;\n   //\n   // number of columns in the sparsity pattern\n   size_t nc_;\n   //\n   // number of possibly non-zero index pairs\n   size_t nnz_;\n   //\n   // row_[k] is the row index for the k-th possibly non-zero entry\n   SizeVector row_;\n   //\n   // col_[k] is the column index for the k-th possibly non-zero entry\n   SizeVector col_;\n   //\n   // if row_major_.size() != 0, row_major_[k] is index of k-th non-zero\n   // entry in row major order.\n   SizeVector row_major_;\n   //\n   // if col_major_.size() != 0, col_major_[k] is index of k-th non-zero\n   // entry in column major order.\n   SizeVector col_major_;\n   //\n   // simple_vector_assign\n   static void simple_vector_assign(\n      SizeVector& destination, const SizeVector& source\n   )\n   {  // resize to zero first so do not copy any values\n      destination.resize(0);\n      // size agreement required for simple vector\n      destination.resize( source.size() );\n      // assignment\n      destination = source;\n   }\npublic:\n   // default constructor\n   // Eigen vector is ambiguous for row_(0), col_(0) so use default ctor\n   sparse_rc(void)\n   : nr_(0), nc_(0), nnz_(0)\n   { }\n   //\n   // move semantics constructor\n   // (none of the default constructor values are used by destructor)\n   sparse_rc(sparse_rc&& other)\n   {  swap(other); }\n   //\n   // destructor\n   ~sparse_rc(void)\n   { }\n   //\n   // sizing constructor\n   // Eigen vector is ambiguous for row_(0), col_(0) so use default ctor\n   sparse_rc(size_t nr, size_t nc, size_t nnz)\n   : nr_(nr), nc_(nc), nnz_(nnz)\n   {  row_.resize(nnz);\n      col_.resize(nnz);\n   }\n   //\n   // copy constructor\n   sparse_rc(const sparse_rc& other)\n   :\n   nr_(other.nr_)   ,\n   nc_(other.nc_)   ,\n   nnz_(other.nnz_) ,\n   row_(other.row_) ,\n   col_(other.col_) ,\n   row_major_(other.row_major_) ,\n   col_major_(other.col_major_)\n   { }\n   //\n   // assignment\n   void operator=(const sparse_rc& other)\n   {  nr_  = other.nr_;\n      nc_  = other.nc_;\n      nnz_ = other.nnz_;\n      //\n      simple_vector_assign(row_, other.row_);\n      simple_vector_assign(col_, other.col_);\n      simple_vector_assign(row_major_, other.row_major_);\n      simple_vector_assign(col_major_, other.col_major_);\n   }\n   //\n   // swap\n   void swap(sparse_rc& other)\n   {  std::swap( nr_ , other.nr_ );\n      std::swap( nc_ , other.nc_ );\n      std::swap( nnz_ , other.nnz_ );\n      //\n      row_.swap( other.row_ );\n      col_.swap( other.col_ );\n      row_major_.swap( other.row_major_ );\n      col_major_.swap( other.col_major_ );\n   }\n   //\n   // move semantics assignment\n   void operator=(sparse_rc&& other)\n   {  swap(other); }\n   //\n   // equality\n   bool operator==(const sparse_rc& other) const\n   {  // result\n      bool result = true;\n      result &= nr_  == other.nr_;\n      result &= nc_  == other.nc_;\n      result &= nnz_ == other.nnz_;\n      if( ! result )\n         return result;\n      //\n      // this_order, other_order, this_order_ptr, other_order_ptr\n      SizeVector        this_order;\n      SizeVector        other_order;\n      const SizeVector* this_order_ptr = &this_order;\n      const SizeVector* other_order_ptr = &other_order;\n      bool this_row_ok  = row_major_.size() > 0;\n      bool this_col_ok  = col_major_.size() > 0;\n      bool other_row_ok = other.row_major_.size() > 0;\n      bool other_col_ok = other.col_major_.size() > 0;\n      if( this_row_ok && this_row_ok )\n      {  this_order_ptr  = &row_major_;\n         other_order_ptr = &(other.row_major_);\n      }\n      else if( this_col_ok && this_col_ok )\n      {  this_order_ptr  = &col_major_;\n         other_order_ptr = &(other.col_major_);\n      }\n      else if( this_row_ok )\n      {  this_order_ptr = &row_major_;\n         other_order    = other.row_major();\n      }\n      else if( this_col_ok )\n      {  this_order_ptr = &col_major_;\n         other_order    = other.col_major();\n      }\n      else if( other_row_ok )\n      {  other_order_ptr = &(other.row_major_);\n         this_order      = row_major();\n      }\n      else if( other_col_ok )\n      {  other_order_ptr = &(other.col_major_);\n         this_order      = col_major();\n      }\n      else\n      {  this_order  = row_major();\n         other_order = other.row_major();\n      }\n      //\n      // result\n      for(size_t k = 0; k < nnz_; ++k)\n      {  size_t this_k  = (*this_order_ptr)[k];\n         size_t other_k = (*other_order_ptr)[k];\n         result &= row_[this_k] == other.row_[other_k];\n         result &= col_[this_k] == other.col_[other_k];\n      }\n      return result;\n   }\n   //\n   // resize\n   void resize(size_t nr, size_t nc, size_t nnz)\n   {  nr_ = nr;\n      nc_ = nc;\n      nnz_ = nnz;\n      row_.resize(nnz);\n      col_.resize(nnz);\n      row_major_.resize(0);\n      col_major_.resize(0);\n   }\n   //\n   // set row and column for a possibly non-zero element\n   void set(size_t k, size_t r, size_t c)\n   {  CPPAD_ASSERT_KNOWN(\n         k < nnz_,\n         \"The index k is not less than nnz in sparse_rc::set\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         r < nr_,\n         \"The index r is not less than nr in sparse_rc::set\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         c < nc_,\n         \"The index c is to not less than nc in sparse_rc::set\"\n      );\n      row_[k] = r;\n      col_[k] = c;\n      //\n      row_major_.resize(0);\n      col_major_.resize(0);\n   }\n   //\n   // push_back\n   void push_back(size_t r, size_t c)\n   {  CPPAD_ASSERT_KNOWN(\n         r < nr_,\n         \"The index r is not less than nr in sparse_rc::push_back\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         c < nc_,\n         \"The index c is to not less than nc in sparse_rc::push_back\"\n      );\n      row_.push_back(r);\n      col_.push_back(c);\n      ++nnz_;\n      CPPAD_ASSERT_UNKNOWN( row_.size() == nnz_ );\n      CPPAD_ASSERT_UNKNOWN( col_.size() == nnz_ );\n      //\n      row_major_.resize(0);\n      col_major_.resize(0);\n   }\n   //\n   // number of rows in matrix\n   size_t nr(void) const\n   {  return nr_; }\n   //\n   // number of columns in matrix\n   size_t nc(void) const\n   {  return nc_; }\n   //\n   // number of possibly non-zero elements in matrix\n   size_t nnz(void) const\n   {  return nnz_; }\n   //\n   // row indices\n   const SizeVector& row(void) const\n   {  return row_; }\n   //\n   // column indices\n   const SizeVector& col(void) const\n   {  return col_; }\n   //\n   // row-major order\n   SizeVector row_major(void) const\n   {  if( row_major_.size() > 0 )\n         return row_major_;\n      //\n      SizeVector keys(nnz_), row_major(nnz_);\n      for(size_t k = 0; k < nnz_; k++)\n      {  CPPAD_ASSERT_UNKNOWN( row_[k] < nr_ );\n         keys[k] = row_[k] * nc_ + col_[k];\n      }\n      index_sort(keys, row_major);\n# ifndef NDEBUG\n      for(size_t ell = 0; ell + 1 < nnz_; ell++)\n      {  size_t k  = row_major[ ell ];\n         size_t kp = row_major[ ell + 1 ];\n         CPPAD_ASSERT_KNOWN(\n            row_[k] != row_[kp] || col_[k] != col_[kp],\n            \"sparse_rc: row_major: duplicate entry in this pattern\"\n         );\n         CPPAD_ASSERT_UNKNOWN(\n            row_[k]<row_[kp] || (row_[k]==row_[kp] && col_[k]<col_[kp])\n         );\n      }\n# endif\n      return row_major;\n   }\n   //\n   // column-major indices\n   SizeVector col_major(void) const\n   {  if( col_major_.size() > 0 )\n         return col_major_;\n      SizeVector keys(nnz_), col_major(nnz_);\n      for(size_t k = 0; k < nnz_; k++)\n      {  CPPAD_ASSERT_UNKNOWN( col_[k] < nc_ );\n         keys[k] = col_[k] * nr_ + row_[k];\n      }\n      index_sort(keys, col_major);\n# ifndef NDEBUG\n      for(size_t ell = 0; ell + 1 < nnz_; ell++)\n      {  size_t k  = col_major[ ell ];\n         size_t kp = col_major[ ell + 1 ];\n         CPPAD_ASSERT_KNOWN(\n            col_[k] != col_[kp] || row_[k] != row_[kp],\n            \"sparse_rc: col_major: duplicate entry in this pattern\"\n         );\n         CPPAD_ASSERT_UNKNOWN(\n            col_[k]<col_[kp] || (col_[k]==col_[kp] && row_[k]<row_[kp])\n         );\n      }\n# endif\n      return col_major;\n   }\n   //\n   void set_row_major(void)\n   {  row_major_ = row_major();\n   }\n   const SizeVector& get_row_major(void) const\n   {  return row_major_;\n   }\n   //\n   void set_col_major(void)\n   {  col_major_ = col_major();\n   }\n   const SizeVector& get_col_major(void) const\n   {  return col_major_;\n   }\n};\n//\n// output\ntemplate <class SizeVector>\nstd::ostream& operator << (\n   std::ostream&                       os      ,\n   const CppAD::sparse_rc<SizeVector>& pattern )\n{  size_t nnz = pattern.nnz();\n   if( nnz == 0 )\n   {  os << \"{ }\";\n      return os;\n   }\n   const SizeVector& row       = pattern.row();\n   const SizeVector& col       = pattern.col();\n   SizeVector        row_major = pattern.row_major();\n   //\n   // k, r, c\n   size_t k = 0;\n   size_t r = row[ row_major[k] ];\n   size_t c = col[ row_major[k] ];\n   //\n   // os\n   os << \"{\\nrow = \" << r << \", col = \" << c;\n   while(++k < nnz )\n   {  bool new_row = r != row[ row_major[k] ];\n      r = row[ row_major[k] ];\n      c = col[ row_major[k] ];\n      if( new_row )\n         os << \"\\nrow = \" << r << \", col = \" << c;\n      else\n         os << \", \" << c;\n   }\n   os << \"\\n}\";\n   //\n   return os;\n}\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/sparse_rcv.hpp",
    "content": "# ifndef CPPAD_UTILITY_SPARSE_RCV_HPP\n# define CPPAD_UTILITY_SPARSE_RCV_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n------------------------------------------------------------------------------\n{xrst_begin sparse_rcv}\n{xrst_spell\n   nnz\n   nr\n   rc\n}\nSparse Matrix Row, Column, Value Representation\n###############################################\n\nSyntax\n******\n| # ``include <cppad/utility/sparse_rcv.hpp>``\n| ``sparse_rcv`` < *SizeVector* , *ValueVector* > *empty*\n| ``sparse_rcv`` < *SizeVector* , *ValueVector* > *matrix* ( *pattern* )\n| *matrix* = *other*\n| *matrix* . ``swap`` ( *other*  )\n| *matrix* . ``set`` ( *k* , *v* )\n| *nr* = *matrix* . ``nr`` ()\n| *nc* = *matrix* . ``nc`` ()\n| *nnz* = *matrix* . ``nnz`` ()\n| ``const`` *SizeVector* & *row* ( *matrix* . ``row`` () )\n| ``const`` *SizeVector* & *col* ( *matrix* . ``col`` () )\n| ``const`` *ValueVector* & *val* ( *matrix* . ``val`` () )\n| ``const sparse_rc`` < *SizeVector* >& *pat* ( *matrix* . ``pat`` () )\n| *row_major* = *matrix* . ``row_major`` ()\n| *col_major* = *matrix* . ``col_major`` ()\n\nSizeVector\n**********\nWe use :ref:`sparse_rc@SizeVector` to denote the\n:ref:`SimpleVector-name` class corresponding to *pattern* .\n\nValueVector\n***********\nWe use *ValueVector* to denote the\n:ref:`SimpleVector-name` class corresponding to *val* .\n\nempty\n*****\nThis is an empty sparse matrix object. To be specific,\nthe corresponding number of rows *nr* ,\nnumber of columns *nc* ,\nand number of possibly non-zero values *nnz* ,\nare all zero.\n\npattern\n*******\nThis constructor argument has prototype\n\n   ``const sparse_rc`` < *SizeVector* >& *pattern*\n\nIt specifies the number of rows, number of columns and\nthe possibly non-zero entries in the *matrix* .\n\nmatrix\n******\nThis is a sparse matrix object with the sparsity specified by *pattern* .\nOnly the *val* vector can be changed. All other values returned by\n*matrix* are fixed during the constructor and constant there after.\nThe *val* vector is only changed by the constructor\nand the ``set`` function.\nThere are two exceptions to this rule, where *other* appears in the\nassignment and swap syntax.\n\nother\n*****\n\nAssignment and Constructor\n==========================\nIn the assignment and constructor, *other* has prototype\n\n   ``const sparse_rcv`` < *SizeVector* , *ValueVector* >& *other*\n\nAfter this assignment and constructor, *other* is an independent copy\nof *matrix* ; i.e. it has all the same values as *matrix*\nand changes to *matrix* do not affect *other* .\n\nMove Semantics Assignment and Constructor\n=========================================\nIn the assignment and constructor, if *other* has prototype\n\n   ``sparse_rcv`` < *SizeVector* , *ValueVector* >&& *other*\n\nA move semantics version of the assignment operator is used; e.g.,\nwhen *other* is a function return value;\n\nswap\n====\nAfter the swap operation *other* ( *matrix* ) is equivalent\nto *matrix* ( *other* ) before the operation.\n\nnr\n**\nThis return value has prototype\n\n   ``size_t`` *nr*\n\nand is the number of rows in *matrix* .\n\nnc\n**\nThis argument and return value has prototype\n\n   ``size_t`` *nc*\n\nand is the number of columns in *matrix* .\n\nnnz\n***\nWe use the notation *nnz* to denote the number of\npossibly non-zero entries in *matrix* .\n\nset\n***\nThis function sets the value\n\n   *val* [ *k* ] = *v*\n\nk\n=\nThis argument has type\n\n   ``size_t`` *k*\n\nand must be less than *nnz* .\n\nv\n=\nThis argument has type\n\n   ``const`` *ValueVector* :: ``value_type&`` *v*\n\nIt specifies the value assigned to *val* [ *k* ] .\n\nrow\n***\nThis vector has size *nnz* and\n*row* [ *k* ]\nis the row index of the *k*-th possibly non-zero\nelement in *matrix* .\n\ncol\n***\nThis vector has size *nnz* and\n*col* [ ``k`` ] is the column index of the *k*-th possibly non-zero\nelement in *matrix*\n\nval\n***\nThis vector has size *nnz* and\n*val* [ ``k`` ] is value of the *k*-th possibly non-zero entry\nin the sparse matrix (the value may be zero).\n\npat\n***\nThis is equal to the sparsity pattern; i.e.,\n*pattern* in the constructor.\n\nrow_major\n*********\nThis vector has prototype\n\n   *SizeVector* *row_major*\n\nand its size *nnz* .\nIt sorts the sparsity pattern in row-major order.\nTo be specific,\n\n   *col* [ *row_major* [ *k* ] ] <= *col* [ *row_major* [ *k* +1] ]\n\nand if *col* [ *row_major* [ *k* ] ] == *col* [ *row_major* [ *k* +1] ] ,\n\n   *row* [ *row_major* [ *k* ] ] < *row* [ *row_major* [ *k* +1] ]\n\nThis routine generates an assert if there are two entries with the same\nrow and column values (if ``NDEBUG`` is not defined).\n\ncol_major\n*********\nThis vector has prototype\n\n   *SizeVector* *col_major*\n\nand its size *nnz* .\nIt sorts the sparsity pattern in column-major order.\nTo be specific,\n\n   *row* [ *col_major* [ *k* ] ] <= *row* [ *col_major* [ *k* +1] ]\n\nand if *row* [ *col_major* [ *k* ] ] == *row* [ *col_major* [ *k* +1] ] ,\n\n   *col* [ *col_major* [ *k* ] ] < *col* [ *col_major* [ *k* +1] ]\n\nThis routine generates an assert if there are two entries with the same\nrow and column values (if ``NDEBUG`` is not defined).\n\nEigen Matrix\n************\nIf you have the :ref:`eigen package<eigen-name>` in your include path,\nyou can use :ref:`sparse2eigen-name` to convert a sparse matrix to eigen format.\n{xrst_toc_hidden\n   example/utility/sparse_rcv.cpp\n}\nExample\n*******\nThe file :ref:`sparse_rcv.cpp-name`\ncontains an example and test of this class.\n\n{xrst_end sparse_rcv}\n*/\n/*!\n\\file sparse_rcv.hpp\nA sparse matrix class.\n*/\n# include <cppad/utility/sparse_rc.hpp>\n\nnamespace CppAD { // BEGIN CPPAD_NAMESPACE\n\n/// Sparse matrices with elements of type Scalar\ntemplate <class SizeVector, class ValueVector>\nclass sparse_rcv {\nprivate:\n   /// sparsity pattern\n   sparse_rc<SizeVector> pattern_;\n   /// value_type\n   typedef typename ValueVector::value_type value_type;\n   /// val_[k] is the value for the k-th possibly non-zero entry in the matrix\n   ValueVector    val_;\npublic:\n   // ------------------------------------------------------------------------\n   /// default constructor\n   sparse_rcv(void)\n   : pattern_(0, 0, 0)\n   { }\n   /// copy constructor\n   sparse_rcv(const sparse_rcv& other)\n   :\n   pattern_( other.pat() ) ,\n   val_( other.val() )\n   { }\n   /// move semantics constructor\n   /// (none of the default constructor values are used by destructor)\n   sparse_rcv(sparse_rcv&& other)\n   {  swap(other); }\n   /// destructor\n   ~sparse_rcv(void)\n   { }\n   /// constructor\n   sparse_rcv(const sparse_rc<SizeVector>& pattern )\n   :\n   pattern_(pattern)    ,\n   val_(pattern_.nnz())\n   { }\n   /// assignment\n   void operator=(const sparse_rcv& other)\n   {  pattern_ = other.pattern_;\n      // simple vector assignment requires vectors to have same size\n      val_.resize( other.nnz() );\n      val_ = other.val();\n   }\n   /// swap\n   void swap(sparse_rcv& other)\n   {  pattern_.swap( other.pattern_ );\n      val_.swap( other.val_ );\n   }\n   /// move semantics assignment\n   void operator=(sparse_rcv&& other)\n   {  swap(other); }\n   // ------------------------------------------------------------------------\n   void set(size_t k, const value_type& v)\n   {  CPPAD_ASSERT_KNOWN(\n         pattern_.nnz(),\n         \"The index k is not less than nnz in sparse_rcv::set\"\n      );\n      val_[k] = v;\n   }\n   /// number of rows in matrix\n   size_t nr(void) const\n   {  return pattern_.nr(); }\n   /// number of columns in matrix\n   size_t nc(void) const\n   {  return pattern_.nc(); }\n   /// number of possibly non-zero elements in matrix\n   size_t nnz(void) const\n   {  return pattern_.nnz(); }\n   /// row indices\n   const SizeVector& row(void) const\n   {  return pattern_.row(); }\n   /// column indices\n   const SizeVector& col(void) const\n   {  return pattern_.col(); }\n   /// value for possibly non-zero elements\n   const ValueVector& val(void) const\n   {  return val_; }\n   /// sparsity pattern\n   const sparse_rc<SizeVector>& pat(void) const\n   {  return pattern_; }\n   /// row-major order\n   SizeVector row_major(void) const\n   {  return pattern_.row_major(); }\n   /// column-major indices\n   SizeVector col_major(void) const\n   {  return pattern_.col_major(); }\n};\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/speed_test.hpp",
    "content": "# ifndef CPPAD_UTILITY_SPEED_TEST_HPP\n# define CPPAD_UTILITY_SPEED_TEST_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin speed_test}\n{xrst_spell\n   ctime\n   gettimeofday\n}\n\nRun One Speed Test and Return Results\n#####################################\n\nSyntax\n******\n| # ``include <cppad/utility/speed_test.hpp>``\n| *rate_vec* = ``speed_test`` ( *test* , *size_vec* , *time_min* )\n\nSee Also\n********\n:ref:`time_test-name`\n\nPurpose\n*******\nThe ``speed_test`` function executes a speed test\nfor various sized problems\nand reports the rate of execution.\n\nMotivation\n**********\nIt is important to separate small calculation units\nand test them individually.\nThis way individual changes can be tested in the context of the\nroutine that they are in.\nOn many machines, accurate timing of a very short execution\nsequences is not possible.\nIn addition,\nthere may be set up and tear down time for a test that\nwe do not really want included in the timing.\nFor this reason ``speed_test``\nautomatically determines how many times to\nrepeat the section of the test that we wish to time.\n\nInclude\n*******\nThe file ``cppad/utility/speed_test.hpp`` defines the\n``speed_test`` function.\nThis file is included by ``cppad/cppad.hpp``\nand it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\nVector\n******\nWe use *Vector* to denote a\n:ref:`simple vector class<SimpleVector-name>` with elements\nof type ``size_t`` .\n\ntest\n****\nThe ``speed_test`` argument *test* is a function with the syntax\n\n   *test* ( *size* , *repeat* )\n\nand its return value is ``void`` .\n\nsize\n====\nThe *test* argument *size* has prototype\n\n   ``size_t`` *size*\n\nIt specifies the size for this test.\n\nrepeat\n======\nThe *test* argument *repeat* has prototype\n\n   ``size_t`` *repeat*\n\nIt specifies the number of times to repeat the test.\n\nsize_vec\n********\nThe ``speed_test`` argument *size_vec* has prototype\n\n   ``const`` *Vector* & *size_vec*\n\nThis vector determines the size for each of the tests problems.\n\ntime_min\n********\nThe argument *time_min* has prototype\n\n   ``double`` *time_min*\n\nIt specifies the minimum amount of time in seconds\nthat the *test* routine should take.\nThe *repeat* argument to *test* is increased\nuntil this amount of execution time is reached.\n\nrate_vec\n********\nThe return value *rate_vec* has prototype\n\n   *Vector* & *rate_vec*\n\nWe use :math:`n` to denote its size which is the same as\nthe vector *size_vec* .\nFor :math:`i = 0 , \\ldots , n-1`,\n\n   *rate_vec* [ *i* ]\n\nis the ratio of *repeat* divided by time in seconds\nfor the problem with size *size_vec* [ *i* ] .\n\nTiming\n******\nIf your system supports the unix ``gettimeofday`` function,\nit will be used to measure time.\nOtherwise,\ntime is measured by the difference in\n::\n\n   (double) clock() / (double) CLOCKS_PER_SEC\n\nin the context of the standard ``<ctime>`` definitions.\n{xrst_toc_hidden\n   speed/example/speed_test.cpp\n}\nExample\n*******\nThe routine :ref:`speed_test.cpp-name` is an example and test\nof ``speed_test`` .\n\n{xrst_end speed_test}\n-----------------------------------------------------------------------\n*/\n\n# include <cstddef>\n# include <cmath>\n\n# include <cppad/utility/check_simple_vector.hpp>\n# include <cppad/utility/elapsed_seconds.hpp>\n\n\nnamespace CppAD { // BEGIN CppAD namespace\n\n// implemented as an inline so that can include in multiple link modules\n// with this same file\ntemplate <class Vector>\nVector speed_test(\n   void test(size_t size, size_t repeat),\n   const Vector& size_vec               ,\n   double time_min                      )\n{\n   // check that size_vec is a simple vector with size_t elements\n   CheckSimpleVector<size_t, Vector>();\n\n   size_t   n = size_vec.size();\n   Vector rate_vec(n);\n   size_t i;\n   for(i = 0; i < n; i++)\n   {  size_t size   = size_vec[i];\n      size_t repeat = 1;\n      double s0     = elapsed_seconds();\n      double s1     = elapsed_seconds();\n      while( s1 - s0 < time_min )\n      {  if( 2 * repeat < repeat )\n         {  // Can't use an assert here because this happens\n            // in release mode first.\n            std::cerr << \"speed_test: test function is too fast to time\\n\";\n            std::exit(1);\n         }\n         repeat = 2 * repeat;\n         s0     = elapsed_seconds();\n         test(size, repeat);\n         s1     = elapsed_seconds();\n      }\n      double rate = .5 + double(repeat) / (s1 - s0);\n      // first convert to float to avoid warning with g++ -Wconversion\n      rate_vec[i] = static_cast<size_t>( static_cast<float>(rate) );\n   }\n   return rate_vec;\n}\n\n} // END CppAD namespace\n\n/*\n{xrst_begin SpeedTest}\n{xrst_spell\n   cout\n   ctime\n}\n\nRun One Speed Test and Print Results\n####################################\n\nSyntax\n******\n\n   # ``include <cppad/utility/speed_test.hpp>``\n\n``SpeedTest`` ( *Test* , *first* , *inc* , *last* )\n\nSee Also\n********\n:ref:`time_test-name`\n\nPurpose\n*******\nThe ``SpeedTest`` function executes a speed test\nfor various sized problems\nand reports the results on standard output; i.e. ``std::cout`` .\nThe size of each test problem is included in its report\n(unless *first* is equal to *last* ).\n\nMotivation\n**********\nIt is important to separate small calculation units\nand test them individually.\nThis way individual changes can be tested in the context of the\nroutine that they are in.\nOn many machines, accurate timing of a very short execution\nsequences is not possible.\nIn addition,\nthere may be set up time for a test that\nwe do not really want included in the timing.\nFor this reason ``SpeedTest``\nautomatically determines how many times to\nrepeat the section of the test that we wish to time.\n\nInclude\n*******\nThe file ``speed_test.hpp`` contains the\n``SpeedTest`` function.\nThis file is included by ``cppad/utility/cppad.hpp``\nbut it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\nTest\n****\nThe ``SpeedTest`` argument *Test* is a function with the syntax\n\n   *name* = *Test* ( *size* , *repeat* )\n\nsize\n====\nThe *Test* argument *size* has prototype\n\n   ``size_t`` *size*\n\nIt specifies the size for this test.\n\nrepeat\n======\nThe *Test* argument *repeat* has prototype\n\n   ``size_t`` *repeat*\n\nIt specifies the number of times to repeat the test.\n\nname\n====\nThe *Test* result *name* has prototype\n\n   ``std::string`` *name*\n\nThe results for this test are reported on ``std::cout``\nwith *name* as an identifier for the test.\nIt is assumed that,\nfor the duration of this call to ``SpeedTest`` ,\n*Test* will always return\nthe same value for *name* .\nIf *name* is the empty string,\nno test name is reported by ``SpeedTest`` .\n\nfirst\n*****\nThe ``SpeedTest`` argument *first* has prototype\n\n   ``size_t`` *first*\n\nIt specifies the size of the first test problem reported by this call to\n``SpeedTest`` .\n\nlast\n****\nThe ``SpeedTest`` argument *last* has prototype\n\n   ``size_t`` *last*\n\nIt specifies the size of the last test problem reported by this call to\n``SpeedTest`` .\n\ninc\n***\nThe ``SpeedTest`` argument *inc* has prototype\n\n   ``int`` *inc*\n\nIt specifies the increment between problem sizes; i.e.,\nall values of *size* in calls to *Test* are given by\n\n   *size* = *first* + *j* * *inc*\n\nwhere *j* is a positive integer.\nThe increment can be positive or negative but it cannot be zero.\nThe values *first* , *last* and *inc* must\nsatisfy the relation\n\n.. math::\n\n   inc * ( last - first ) \\geq 0\n\nrate\n****\nThe value displayed in the ``rate`` column on ``std::cout``\nis defined as the value of *repeat* divided by the\ncorresponding elapsed execution time in seconds.\nThe elapsed execution time is measured by the difference in\n::\n\n   (double) clock() / (double) CLOCKS_PER_SEC\n\nin the context of the standard ``<ctime>`` definitions.\n\nErrors\n******\nIf one of the restrictions above is violated,\nthe CppAD error handler is used to report the error.\nYou can redefine this action using the instructions in\n:ref:`ErrorHandler-name`\n\nExample\n*******\n{xrst_toc_hidden\n   speed/example/speed_program.cpp\n}\nThe program :ref:`speed_program.cpp-name` is an example usage\nof ``SpeedTest`` .\n\n{xrst_end SpeedTest}\n-----------------------------------------------------------------------\n*/\n// BEGIN C++\n\n\n# include <string>\n# include <iostream>\n# include <iomanip>\n# include <cppad/core/cppad_assert.hpp>\n\nnamespace CppAD { // BEGIN CppAD namespace\n\ninline void SpeedTestNdigit(size_t value, size_t &ndigit, size_t &pow10)\n{  pow10 = 10;\n   ndigit       = 1;\n   while( pow10 <= value )\n   {  pow10  *= 10;\n      ndigit += 1;\n   }\n}\n\n// implemented as an inline so that can include in multiple link modules\n// with this same file\ninline void SpeedTest(\n   std::string Test(size_t size, size_t repeat),\n   size_t first,\n   int    inc,\n   size_t last\n)\n{\n\n   using std::cout;\n   using std::endl;\n\n   size_t    size;\n   size_t    repeat;\n   size_t    rate;\n   size_t    digit;\n   size_t    ndigit;\n   size_t    pow10;\n   size_t    maxSize;\n   size_t    maxSizeDigit;\n\n   double    s0;\n   double    s1;\n\n   std::string name;\n\n   CPPAD_ASSERT_KNOWN(\n      inc != 0 && first != 0 && last != 0,\n      \"inc, first, or last is zero in call to SpeedTest\"\n   );\n   CPPAD_ASSERT_KNOWN(\n      (inc > 0 && first <= last) || (inc < 0 && first >= last),\n      \"SpeedTest: increment is positive and first > last or \"\n      \"increment is negative and first < last\"\n   );\n\n   // compute maxSize\n   maxSize = size = first;\n   while(  (inc > 0 && size <= last) || (inc < 0 && size >= last) )\n   {\n      if( size > maxSize )\n         maxSize = size;\n\n      // next size\n      if( int(size) + inc > 0 )\n         size = size_t( int(size) + inc );\n      else\n         size  = 0;\n   }\n   SpeedTestNdigit(maxSize, maxSizeDigit, pow10);\n\n   size = first;\n   while(  (inc > 0 && size <= last) || (inc < 0 && size >= last) )\n   {\n      repeat = 1;\n      s0     = elapsed_seconds();\n      s1     = elapsed_seconds();\n      while( s1 - s0 < 1. )\n      {  if( 2 * repeat < repeat )\n         {  // Can't use an assert here because this happens\n            // in release mode first.\n            std::cerr << \"SpeedTest: test function is too fast to time\\n\";\n            std::exit(1);\n         }\n         repeat = 2 * repeat;\n         s0     = elapsed_seconds();\n         name   = Test(size, repeat);\n         s1     = elapsed_seconds();\n      }\n      double r = .5 + double(repeat) / (s1 - s0);\n      // first convert to float to avoid warning with g++ -Wconversion\n      rate     = static_cast<size_t>( static_cast<float>( r ) );\n\n      if( size == first && name != \"\" )\n         cout << name << endl;\n\n      if( first != last )\n      {\n         // convert int(size_t) to avoid warning on _MSC_VER sys\n         std::cout << \"size = \"  << int(size);\n\n         SpeedTestNdigit(size, ndigit, pow10);\n         while( ndigit < maxSizeDigit )\n         {  cout << \" \";\n            ndigit++;\n         }\n         cout << \" \";\n      }\n\n      cout << \"rate = \";\n      SpeedTestNdigit(rate, ndigit, pow10);\n      while( ndigit > 0 )\n      {\n         pow10 /= 10;\n         digit  = rate / pow10;\n\n         // convert int(size_t) to avoid warning on _MSC_VER sys\n         std::cout << int(digit);\n\n         rate    = rate % pow10;\n         ndigit -= 1;\n\n         if( (ndigit > 0) && (ndigit % 3 == 0) )\n            cout << \",\";\n      }\n      cout << endl;\n\n      // next size\n      if( int(size) + inc > 0 )\n         size = size_t( int(size) + inc );\n      else\n         size  = 0;\n   }\n   return;\n}\n\n} // END CppAD namespace\n\n// END C++\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/test_boolofvoid.hpp",
    "content": "# ifndef CPPAD_UTILITY_TEST_BOOLOFVOID_HPP\n# define CPPAD_UTILITY_TEST_BOOLOFVOID_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin test_boolofvoid}\n{xrst_spell\n   ipopt\n}\n\nObject that Runs a Group of Tests\n#################################\n\nSyntax\n******\n| # ``include <cppad/utility/test_boolofvoid.hpp>``\n| ``test_boolofvoid`` *Run* ( *group* , *width* )\n| *Run* ( *test* , *name* )\n| *ok* = *Run* . ``summary`` ( *memory_ok* )\n\nPurpose\n*******\nThe object *Run* is used to run a group of tests functions\nand report the results on standard output.\n\ngroup\n*****\nThe argument has prototype\n\n   ``const std::string&`` *group*\n\nIt is the name for this group of tests.\n\nwidth\n*****\nThe argument has prototype\n\n   ``size_t`` *width*\n\nIt is the number of columns used to display the name of each test.\nIt must be greater than the maximum number of characters in a test name.\n\ntest\n****\nThe argument has prototype\n\n   ``bool`` *test* ( ``void`` )\n\nIt is a function that returns true (when the test passes) and false\notherwise.\n\nname\n****\nThe argument has prototype\n\n   ``const std::string&`` *name*\n\nIt is the name for the corresponding *test* .\n\nmemory_ok\n*********\nThe argument has prototype\n\n   ``bool`` *memory_ok*\n\nIt is false if a memory leak is detected (and true otherwise).\n\nok\n**\nThis is true if all of the tests pass (including the memory leak test),\notherwise it is false.\n\nExample\n*******\nSee any of the main programs in the example directory; e.g.,\n``example/ipopt_solve.cpp`` .\n\n{xrst_end test_boolofvoid}\n*/\n\n# include <cppad/core/cppad_assert.hpp>\n# include <string>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n/// One class object is used to run a group of tests\nclass test_boolofvoid {\nprivate:\n   /// name for the group of test this object will run\n   const std::string group_;\n   /// number of characters used to display the name for each individual test\n   /// (must be larger than the number of characters in name for each test)\n   const size_t      width_;\n   /// number of tests that have passed\n   size_t            n_ok_;\n   /// number of tests that have failed\n   size_t            n_error_;\n\npublic:\n   /// ctor\n   test_boolofvoid(const std::string& group, size_t width) :\n   group_(group) ,\n   width_(width) ,\n   n_ok_(0)      ,\n   n_error_(0)\n   {  std::cout << \"Begin test group \" << group_ << std::endl; }\n   /// destructor\n   ~test_boolofvoid(void)\n   {  std::cout << \"End test group \" << group_ << std::endl; }\n   /// run one test\n   bool operator()(bool test(void), const std::string& name)\n   {  CPPAD_ASSERT_KNOWN(\n         name.size() < width_ ,\n         \"test_boolofvoid: name does not have less characters than width\"\n      );\n      std::cout.width( int(width_) );\n      std::cout.setf( std::ios_base::left );\n      std::cout << name;\n      //\n      bool ok = test();\n      if( ok )\n      {  std::cout << \"OK\" << std::endl;\n         n_ok_++;\n      }\n      else\n      {  std::cout << \"Error\" << std::endl;\n         n_error_++;\n      }\n      return ok;\n   }\n   /// number of tests that passed\n   size_t n_ok(void) const\n   {  return n_ok_; }\n   /// number of tests that failed\n   size_t n_error(void) const\n   {  return n_error_; }\n   /// summary\n   bool summary(bool memory_ok )\n   {\n      std::cout.width( int(width_) );\n      std::cout.setf( std::ios_base::left );\n      std::cout << \"memory_leak\";\n      //\n      if( memory_ok  )\n      {  std::cout << \"OK\" << std::endl;\n         n_ok_++;\n      }\n      else\n      {  std::cout << \"Error\" << std::endl;\n         n_error_++;\n      }\n      if( n_error_ == 0 )\n         std::cout << \"All \" << n_ok_ << \" tests passed.\" << std::endl;\n      else\n         std::cout << n_error_ << \" tests failed.\" << std::endl;\n      //\n      return n_error_ == 0;\n   }\n};\n\n} // END_CPPAD_NAMESPACE\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/thread_alloc.hpp",
    "content": "# ifndef CPPAD_UTILITY_THREAD_ALLOC_HPP\n# define CPPAD_UTILITY_THREAD_ALLOC_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n# include <sstream>\n# include <limits>\n# include <memory>\n# include <cstdint>\n\n\n# ifdef _MSC_VER\n// Suppress warning that Microsoft compiler changed its behavior and is now\n// doing the correct thing at the statement:\n//            new(array + i) Type();\n# pragma warning(disable:4345)\n# endif\n\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/local/define.hpp>\n# include <cppad/local/set_get_in_parallel.hpp>\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file thread_alloc.hpp\nFile used to define the CppAD multi-threading allocator class\n*/\n\n/*!\n\\def CPPAD_MAX_NUM_CAPACITY\nMaximum number of different capacities the allocator will attempt.\nThis must be larger than the log base two of numeric_limit<size_t>::max().\n*/\n# define CPPAD_MAX_NUM_CAPACITY 100\n\n/*!\n\\def CPPAD_MIN_DOUBLE_CAPACITY\nMinimum number of double values that will fit in an allocation.\n*/\n# define CPPAD_MIN_DOUBLE_CAPACITY 16\n\n/*!\n\\def CPPAD_TRACE_CAPACITY\nIf NDEBUG is not defined, print all calls to get_memory and return_memory\nthat correspond to this capacity and thread CPPAD_TRACE_THREAD.\n(Note that if CPPAD_TRACE_CAPACITY is zero, or any other value not in the list\nof capacities, no tracing will be done.)\n*/\n# define CPPAD_TRACE_CAPACITY 0\n\n/*!\n\\def CPPAD_TRACE_THREAD\nIf NDEBUG is not defined, print all calls to get_memory and return_memory\nthat correspond to this thead and capacity CPPAD_TRACE_CAPACITY.\n*/\n# define CPPAD_TRACE_THREAD 0\n\n/*\nNote that Section 3.6.2 of ISO/IEC 14882:1998(E) states: \"The storage for\nobjects with static storage duration (3.7.1) shall be zero-initialized\n(8.5) before any other initialization takes place.\"\n*/\n\n/*!\nCapacity vector for memory allocation block sizes.\n\nOnly one of these objects should be created and used as a\nstatic variable inside of the thread_alloc::capacity_info function.\n*/\n\n/*!\nAllocator class that works well with an multi-threading environment.\n*/\nclass thread_alloc{\n// ============================================================================\nprivate:\n\n   class capacity_t {\n   public:\n      /// number of capacity values actually used\n      size_t number;\n      /// the different capacity values\n      size_t value[CPPAD_MAX_NUM_CAPACITY];\n      /// ctor\n      capacity_t(void)\n      {  // Cannot figure out how to call thread_alloc::in_parallel here.\n         // CPPAD_ASSERT_UNKNOWN(\n         //    ! thread_alloc::in_parallel() , \"thread_alloc: \"\n         //    \"parallel mode and parallel_setup not yet called.\"\n         // );\n         number           = 0;\n         size_t capacity  = CPPAD_MIN_DOUBLE_CAPACITY * sizeof(double);\n         while( capacity < std::numeric_limits<size_t>::max() / 2 )\n         {  CPPAD_ASSERT_UNKNOWN( number < CPPAD_MAX_NUM_CAPACITY );\n            value[number++] = capacity;\n            // next capactiy is 3/2 times the current one\n            capacity        = 3 * ( (capacity + 1) / 2 );\n         }\n         CPPAD_ASSERT_UNKNOWN( number > 0 );\n      }\n   };\n\n   class block_t {\n   public:\n      /// extra information (currently used by create and delete array)\n      size_t             extra_;\n      /// an index that uniquely identifies both thread and capacity\n      size_t             tc_index_;\n      /// pointer to the next memory allocation with the same tc_index_\n      void*              next_;\n      ///\n      /// Calculated by include/cppad/CMakeLists.txt\n      CPPAD_PADDING_BLOCK_T\n      // -----------------------------------------------------------------\n      /// make default constructor private. It is only used by constructor\n      /// for `root arrays below.\n      block_t(void) : extra_(0), tc_index_(0), next_(nullptr)\n      { }\n   };\n\n   // ---------------------------------------------------------------------\n   /// Vector of fixed capacity values for this allocator\n   static const capacity_t* capacity_info(void)\n   {  CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n      static const capacity_t capacity;\n      return &capacity;\n   }\n   // ---------------------------------------------------------------------\n   /// Structure of information for each thread\n   struct thread_alloc_info {\n      /// count of available bytes for this thread\n      size_t  count_inuse_;\n      /// count of inuse bytes for this thread\n      size_t  count_available_;\n      /// root of available list for this thread and each capacity\n      block_t root_available_[CPPAD_MAX_NUM_CAPACITY];\n      /*!\n      root of inuse list for this thread and each capacity\n      If NDEBUG is defined or CPPAD_DEBUG_AND_RELEASE is true,\n      this memory is not used, but it still helps to separate\n      this structure from the structure for the next thread.\n      */\n      block_t root_inuse_[CPPAD_MAX_NUM_CAPACITY];\n   };\n   // ---------------------------------------------------------------------\n   /*!\n   Set and Get hold available memory flag.\n\n   \\param set [in]\n   if true, the value returned by this return is changed.\n\n   \\param new_value [in]\n   if set is true, this is the new value returned by this routine.\n   Otherwise, new_value is ignored.\n\n   \\return\n   the current setting for this routine (which is initially false).\n   */\n   static bool set_get_hold_memory(bool set, bool new_value = false)\n   {  static bool value = false;\n      if( set )\n         value = new_value;\n      return value;\n   }\n   // ---------------------------------------------------------------------\n   /*!\n   Get pointer to the information for this thread.\n\n   \\param thread [in]\n   Is the thread number for this information pointer.\n\n   \\param clear\n   If clear is true, then the information pointer for this thread\n   is deleted and the nullptr pointer is returned.\n   There must be no memory currently in either the inuse or available\n   lists when this routine is called.\n\n   \\return\n   is the current information pointer for this thread.\n   If clear is false, and the current pointer is nullptr,\n   a new information record is allocated and its pointer returned.\n   In this case, if info is the returned pointer,\n   <code>info->count_inuse == 0</code> and\n   <code>info->count_available == 0</code>.\n   In addition,\n   for <code>c = 0 , ... , CPPAD_MAX_NUM_CAPACITY-1</code>\n   <code>info->root_inuse_[c].next_ == nullptr</code> and\n   <code>info->root_available_[c].next_ == nullptr</code>.\n   */\n   static thread_alloc_info* thread_info(\n      size_t             thread          ,\n      bool               clear = false   )\n   {  static thread_alloc_info* all_info[CPPAD_MAX_NUM_THREADS];\n      static thread_alloc_info  zero_info;\n\n      CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n\n      CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS );\n\n      thread_alloc_info* info = all_info[thread];\n      if( clear )\n      {  if( info != nullptr )\n         {\n# ifndef NDEBUG\n            CPPAD_ASSERT_UNKNOWN(\n               info->count_inuse_     == 0 &&\n               info->count_available_ == 0\n            );\n            for(size_t c = 0; c < CPPAD_MAX_NUM_CAPACITY; c++)\n            {  CPPAD_ASSERT_UNKNOWN(\n                  info->root_inuse_[c].next_     == nullptr &&\n                  info->root_available_[c].next_ == nullptr\n               );\n            }\n# endif\n            if( thread != 0 )\n               ::operator delete( reinterpret_cast<void*>(info) );\n            info             = nullptr;\n            all_info[thread] = info;\n         }\n      }\n      else if( info == nullptr )\n      {  if( thread == 0 )\n            info = &zero_info;\n         else\n         {  size_t size = sizeof(thread_alloc_info);\n            void* v_ptr = ::operator new(size);\n            info        = reinterpret_cast<thread_alloc_info*>(v_ptr);\n         }\n         all_info[thread] = info;\n\n         // initialize the information record\n         for(size_t c = 0; c < CPPAD_MAX_NUM_CAPACITY; c++)\n         {  info->root_inuse_[c].next_       = nullptr;\n            info->root_available_[c].next_   = nullptr;\n         }\n         info->count_inuse_     = 0;\n         info->count_available_ = 0;\n      }\n      return info;\n   }\n   // -----------------------------------------------------------------------\n   /*!\n   Increase the number of bytes of memory that are currently in use; i.e.,\n   that been obtained with get_memory and not yet returned.\n\n   \\param inc [in]\n   amount to increase memory in use.\n\n   \\param thread [in]\n   Thread for which we are increasing the number of bytes in use\n   (must be less than num_threads).\n   During parallel execution, this must be the thread\n   that is currently executing.\n   */\n   static void inc_inuse(size_t inc, size_t thread)\n   {\n      CPPAD_ASSERT_UNKNOWN( thread < num_threads() );\n      CPPAD_ASSERT_UNKNOWN(\n         thread == thread_num() || (! in_parallel())\n      );\n      thread_alloc_info* info = thread_info(thread);\n\n      // do the addition\n      size_t result = info->count_inuse_ + inc;\n      CPPAD_ASSERT_UNKNOWN( result >= info->count_inuse_ );\n\n      info->count_inuse_ = result;\n   }\n   // -----------------------------------------------------------------------\n   /*!\n   Increase the number of bytes of memory that are currently available; i.e.,\n   have been obtained obtained from the system and are being held future use.\n\n   \\copydetails inc_inuse\n   */\n   static void inc_available(size_t inc, size_t thread)\n   {\n      CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);\n      CPPAD_ASSERT_UNKNOWN(\n         thread == thread_num() || (! in_parallel())\n      );\n      thread_alloc_info* info = thread_info(thread);\n      // do the addition\n      size_t result = info->count_available_ + inc;\n      CPPAD_ASSERT_UNKNOWN( result >= info->count_available_ );\n\n      info->count_available_ = result;\n   }\n   // -----------------------------------------------------------------------\n   /*!\n   Decrease the number of bytes of memory that are currently in use; i.e.,\n   that been obtained with get_memory and not yet returned.\n\n   \\param dec [in]\n   amount to decrease number of bytes in use.\n\n   \\param thread [in]\n   Thread for which we are decreasing the number of bytes in use\n   (must be less than num_threads).\n   During parallel execution, this must be the thread\n   that is currently executing.\n   */\n   static void dec_inuse(size_t dec, size_t thread)\n   {\n      CPPAD_ASSERT_UNKNOWN(\n         thread < num_threads() || (! in_parallel())\n      );\n      CPPAD_ASSERT_UNKNOWN(\n         thread == thread_num() || (! in_parallel())\n      );\n      thread_alloc_info* info = thread_info(thread);\n\n      // do the subtraction\n      CPPAD_ASSERT_UNKNOWN( info->count_inuse_ >= dec );\n      info->count_inuse_ = info->count_inuse_ - dec;\n   }\n   // -----------------------------------------------------------------------\n   /*!\n   Decrease the number of bytes of memory that are currently available; i.e.,\n   have been obtained obtained from the system and are being held future use.\n\n   \\copydetails dec_inuse\n   */\n   static void dec_available(size_t dec, size_t thread)\n   {\n      CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);\n      CPPAD_ASSERT_UNKNOWN(\n         thread == thread_num() || (! in_parallel())\n      );\n      thread_alloc_info* info = thread_info(thread);\n      // do the subtraction\n      CPPAD_ASSERT_UNKNOWN( info->count_available_ >= dec );\n      info->count_available_ =  info->count_available_ - dec;\n   }\n\n   // ----------------------------------------------------------------------\n   /*!\n   Set and get the number of threads that are sharing memory.\n\n   \\param number_new\n   If number is zero, we are only retrieving the current maximum\n   number of threads. Otherwise, we are setting and retrieving\n   maximum number of threads.\n\n   \\return\n   the number of threads that are sharing memory.\n   If number_new is non-zero, the return value is equal to\n   number_new.\n   */\n   static size_t set_get_num_threads(size_t number_new)\n   {  static size_t number_user = 1;\n\n      CPPAD_ASSERT_UNKNOWN( number_new <= CPPAD_MAX_NUM_THREADS );\n      CPPAD_ASSERT_UNKNOWN( ! in_parallel() || (number_new == 0) );\n\n      // case where we are changing the number of threads\n      if( number_new != 0 )\n         number_user = number_new;\n\n      return number_user;\n   }\n   /*!\n   Set and call the routine that determine the current thread number.\n\n   \\return\n   returns value for the most recent setting for thread_num_new.\n   If set is true,\n   or the most recent setting is nullptr (its initial value),\n   the return value is zero.\n   Otherwise the routine corresponding to the most recent setting\n   is called and its value returned by set_get_thread_num.\n\n   \\param thread_num_new [in]\n   If set is false, thread_num_new it is not used.\n   Otherwise, the current value of thread_num_new becomes the\n   most recent setting for thread_num.\n\n   \\param set\n   If set is true, then thread_num_new is becomes the most\n   recent setting for this set_get_thread_num.\n   */\n   static size_t set_get_thread_num(\n      size_t (*thread_num_new)(void)  ,\n      bool set = false                )\n   {  static size_t (*thread_num_user)(void) = nullptr;\n\n      if( set )\n      {  thread_num_user = thread_num_new;\n         return 0;\n      }\n\n      if( thread_num_user == nullptr )\n         return 0;\n\n      size_t thread = thread_num_user();\n      CPPAD_ASSERT_KNOWN(\n         thread < set_get_num_threads(0) ,\n         \"parallel_setup: thread_num() >= num_threads\"\n      );\n      return thread;\n   }\n// ============================================================================\npublic:\n/*\n{xrst_begin ta_parallel_setup}\nSetup thread_alloc For Use in Multi-Threading Environment\n#########################################################\n\nSyntax\n******\n| ``thread_alloc::parallel_setup`` ( *num_threads* , *in_parallel* , *thread_num* )\n\nPurpose\n*******\nBy default there is only one thread and all execution is in sequential mode,\ni.e., multiple threads are not sharing the same memory; i.e.\nnot in parallel mode.\n\nSpeed\n*****\nIt should be faster, even when *num_thread* is equal to one,\nfor ``thread_alloc`` to hold onto memory.\nThis can be accomplished using the function call\n\n   ``thread_alloc::hold_memory`` ( ``true`` )\n\nsee :ref:`hold_memory<ta_hold_memory-name>` .\n\nnum_threads\n***********\nThis argument has prototype\n\n   ``size_t`` *num_threads*\n\nand must be greater than zero.\nIt specifies the number of threads that are sharing memory.\nThe case *num_threads*  == 1 is a special case that is\nused to terminate a multi-threading environment.\n\nin_parallel\n***********\nThis function has prototype\n\n   ``bool`` *in_parallel* ( ``void`` )\n\nIt must return ``true`` if there is more than one thread\ncurrently executing.\nOtherwise it can return false.\n\nIn the special case where *num_threads*  == 1 ,\nthe routine *in_parallel* is not used.\n\nthread_num\n**********\nThis function has prototype\n\n   ``size_t`` *thread_num* ( ``void`` )\n\nIt must return a thread number that uniquely identifies the\ncurrently executing thread.\nFurthermore\n\n   0 <= *thread_num* () < *num_threads*\n\n.\nIn the special case where *num_threads*  == 1 ,\nthe routine *thread_num* is not used.\n\nNote that this function is called by other routines so,\nas soon as a new thread is executing,\none must be certain that *thread_num* () will\nwork for that thread.\n\nRestrictions\n************\nThe function ``parallel_setup`` must be called before\nthe program enters :ref:`parallel<ta_in_parallel-name>` execution mode.\nIn addition, this function cannot be called while in parallel mode.\n\nExample\n*******\nThe files\n:ref:`openmp_get_started.cpp-name` ,\n:ref:`bthread_get_started.cpp-name` , and\n:ref:`pthread_get_started.cpp-name` ,\ncontain examples and tests that use this function.\n\n{xrst_end ta_parallel_setup}\n*/\n   /*!\n   Set thread_alloc up for parallel mode usage.\n\n   \\param num_threads [in]\n   Is the number of thread that may be executing at the same time.\n\n   \\param in_parallel [in]\n   Is the routine that determines if we are in parallel mode or not.\n\n   \\param thread_num [in]\n   Is the routine that determines the current thread number\n   (between zero and num_threads minus one).\n   */\n   static void parallel_setup(\n      size_t num_threads         ,\n      bool (*in_parallel)(void)  ,\n      size_t (*thread_num)(void) )\n   {\n      // Special case where we go back to single thread mode right away\n      // (previous settings may no longer be valid)\n      if( num_threads == 1 )\n      {  bool set = true;\n         set_get_num_threads(num_threads);\n         // emphasize that this routine is outside thread_alloc class\n         CppAD::local::set_get_in_parallel(set, nullptr);\n         set_get_thread_num(nullptr, set);\n         return;\n      }\n\n      CPPAD_ASSERT_KNOWN(\n         num_threads <= CPPAD_MAX_NUM_THREADS ,\n         \"parallel_setup: num_threads is too large\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         num_threads != 0 ,\n         \"parallel_setup: num_threads == zero\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         in_parallel != nullptr ,\n         \"parallel_setup: num_threads != 1 and in_parallel == nullptr\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         thread_num != nullptr ,\n         \"parallel_setup: num_threads != 1 and thread_num == nullptr\"\n      );\n\n      // Make sure that constructors for all static variables in this file\n      // are called in sequential mode.\n      for(size_t thread = 0; thread < num_threads; thread++)\n         thread_info(thread);\n      capacity_info();\n      size_t cap_bytes;\n      void* v_ptr = get_memory(0, cap_bytes);\n\n      // free memory allocated by call to get_memory above\n      return_memory(v_ptr);\n      free_available( set_get_thread_num(nullptr) );\n\n      // delay this so thread_num() call above is in previous mode\n      // (current settings may not yet be valid)\n      if( num_threads > 1 )\n      {  bool set = true;\n         set_get_num_threads(num_threads);\n         // emphasize that this routine is outside thread_alloc class\n         CppAD::local::set_get_in_parallel(set, in_parallel);\n         set_get_thread_num(thread_num, set);\n      }\n   }\n/*\n{xrst_begin ta_num_threads}\nGet Number of Threads\n#####################\n\nSyntax\n******\n*number* = ``thread_alloc::num_threads`` ()\n\nPurpose\n*******\nDetermine the number of threads as set during :ref:`parallel_setup<ta_parallel_setup-name>` .\n\nnumber\n******\nThe return value *number* has prototype\n\n   ``size_t`` *number*\n\nand is equal to the value of\n:ref:`ta_parallel_setup@num_threads`\nin the previous call to *parallel_setup* .\nIf there was no such previous call, the value one is returned.\n\nExample\n*******\nThe example and test :ref:`thread_alloc.cpp-name` uses this routine.\n\n{xrst_end ta_num_threads}\n*/\n   /*!\n   Get the current number of threads that thread_alloc can use.\n   */\n   static size_t num_threads(void)\n   {  return set_get_num_threads(0); }\n/* -----------------------------------------------------------------------\n{xrst_begin ta_in_parallel}\n\nIs The Current Execution in Parallel Mode\n#########################################\n\nSyntax\n******\n*flag* = ``thread_alloc::in_parallel`` ()\n\nPurpose\n*******\nSome of the :ref:`thread_alloc-name` allocation routines have different\nspecifications for parallel (not sequential) execution mode.\nThis routine enables you to determine if the current execution mode\nis sequential or parallel.\n\nflag\n****\nThe return value has prototype\n\n   ``bool`` *flag*\n\nIt is true if the current execution is in parallel mode\n(possibly multi-threaded) and false otherwise (sequential mode).\n\nExample\n*******\n:ref:`thread_alloc.cpp-name`\n\n{xrst_end ta_in_parallel}\n*/\n   /// Are we in a parallel execution state; i.e., is it possible that\n   /// other threads are currently executing.\n   static bool in_parallel(void)\n   {  // emphasize that this routine is outside thread_alloc class\n      return CppAD::local::set_get_in_parallel();\n   }\n/* -----------------------------------------------------------------------\n{xrst_begin ta_thread_num}\n\nGet the Current Thread Number\n#############################\n\nSyntax\n******\n*thread* = ``thread_alloc::thread_num`` ()\n\nPurpose\n*******\nSome of the :ref:`thread_alloc-name` allocation routines have a thread number.\nThis routine enables you to determine the current thread.\n\nthread\n******\nThe return value *thread* has prototype\n\n   ``size_t`` *thread*\n\nand is the currently executing thread number.\n\nExample\n*******\n:ref:`thread_alloc.cpp-name`\n\n{xrst_end ta_thread_num}\n*/\n   /// Get current thread number\n   static size_t thread_num(void)\n   {  return set_get_thread_num(nullptr); }\n/* -----------------------------------------------------------------------\n{xrst_begin ta_get_memory}\n\nGet At Least A Specified Amount of Memory\n#########################################\n\nSyntax\n******\n*v_ptr* = ``thread_alloc::get_memory`` ( *min_bytes* , *cap_bytes* )\n\nPurpose\n*******\nUse :ref:`thread_alloc-name` to obtain a minimum number of bytes of memory\n(for use by the :ref:`current thread<ta_thread_num-name>` ).\n\nmin_bytes\n*********\nThis argument has prototype\n\n   ``size_t`` *min_bytes*\n\nIt specifies the minimum number of bytes to allocate.\nThis value must be less than\n::\n\n   std::numeric_limits<size_t>::max() / 2\n\ncap_bytes\n*********\nThis argument has prototype\n\n   ``size_t&`` *cap_bytes*\n\nIt's input value does not matter.\nUpon return, it is the actual number of bytes (capacity)\nthat have been allocated for use,\n\n   *min_bytes* <= *cap_bytes*\n\nv_ptr\n*****\nThe return value *v_ptr* has prototype\n\n   ``void`` * *v_ptr*\n\nIt is the location where the *cap_bytes* of memory\nthat have been allocated for use begins.\n\nAllocation Speed\n****************\nThis allocation should be faster if the following conditions hold:\n\n#. The memory allocated by a previous call to ``get_memory``\n   is currently available for use.\n#. The current *min_bytes* is between\n   the previous *min_bytes* and previous *cap_bytes* .\n\nAlignment\n*********\nWe call a memory allocation aligned if the address is a multiple\nof the number of bytes in a ``size_t`` value.\nIf the system ``new`` allocator is aligned, then *v_ptr*\npointer is also aligned.\n\nExample\n*******\n:ref:`thread_alloc.cpp-name`\n\n{xrst_end ta_get_memory}\n*/\n   /*!\n   Use thread_alloc to get a specified amount of memory.\n\n   If the memory allocated by a previous call to get_memory is now\n   available, and min_bytes is between its previous value\n   and the previous cap_bytes, this memory allocation will have\n   optimal speed. Otherwise, the memory allocation is more complicated and\n   may have to wait for other threads to complete an allocation.\n\n   \\param min_bytes [in]\n   The minimum number of bytes of memory to be obtained for use.\n\n   \\param cap_bytes [out]\n   The actual number of bytes of memory obtained for use.\n\n   \\return\n   pointer to the beginning of the memory allocated for use.\n   */\n   static void* get_memory(size_t min_bytes, size_t& cap_bytes)\n   {  // see first_trace below\n      CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;\n\n      // check that number of requested bytes is not to large\n      CPPAD_ASSERT_KNOWN(\n         min_bytes < std::numeric_limits<size_t>::max() / 2 ,\n         \"get_memory(min_bytes, cap_bytes): min_bytes is too large\"\n      );\n\n      size_t num_cap = capacity_info()->number;\n      using std::cout;\n      using std::endl;\n\n      // determine the capacity for this request\n      size_t c_index   = 0;\n      const size_t* capacity_vec = capacity_info()->value;\n      while( capacity_vec[c_index] < min_bytes )\n      {  ++c_index;\n         CPPAD_ASSERT_UNKNOWN(c_index < num_cap );\n      }\n      cap_bytes = capacity_vec[c_index];\n\n      // determine the thread, capacity, and info for this thread\n      size_t thread            = thread_num();\n      size_t tc_index          = thread * num_cap + c_index;\n      thread_alloc_info* info  = thread_info(thread);\n\n# ifndef NDEBUG\n      // trace allocation\n      static bool first_trace = true;\n      if( cap_bytes == CPPAD_TRACE_CAPACITY &&\n             thread    ==  CPPAD_TRACE_THREAD  && first_trace )\n      {  cout << endl;\n         cout << \"thread_alloc: Trace for Thread = \" << thread;\n         cout << \" and capacity = \" << cap_bytes << endl;\n         if( first_trace )\n            first_trace = false;\n      }\n\n# if ! CPPAD_DEBUG_AND_RELEASE\n      // Root nodes for both lists. Note these are different for different\n      // threads because tc_index is different for different threads.\n      block_t* inuse_root     = info->root_inuse_ + c_index;\n# endif\n# endif\n      block_t* available_root = info->root_available_ + c_index;\n\n      // check if we already have a node we can use\n      void* v_node              = available_root->next_;\n      block_t* node             = reinterpret_cast<block_t*>(v_node);\n      if( node != nullptr )\n      {  CPPAD_ASSERT_UNKNOWN( node->tc_index_ == tc_index );\n\n         // remove node from available list\n         available_root->next_ = node->next_;\n\n         // return value for get_memory\n         void* v_ptr = reinterpret_cast<void*>(node + 1);\n# ifndef NDEBUG\n# if ! CPPAD_DEBUG_AND_RELEASE\n         // add node to inuse list\n         node->next_           = inuse_root->next_;\n         inuse_root->next_     = v_node;\n# endif\n\n         // trace allocation\n         if( cap_bytes == CPPAD_TRACE_CAPACITY &&\n                 thread    ==  CPPAD_TRACE_THREAD   )\n         {  cout << \"get_memory:    v_ptr = \" << v_ptr << endl; }\n# endif\n\n         // adjust counts\n         inc_inuse(cap_bytes, thread);\n         dec_available(cap_bytes, thread);\n\n# ifndef NDEBUG\n         // check that pointers and doubles are aligned\n         std::uintptr_t i_ptr = reinterpret_cast<std::uintptr_t>(v_ptr);\n         CPPAD_ASSERT_UNKNOWN( i_ptr % sizeof(v_ptr) == 0 );\n         CPPAD_ASSERT_UNKNOWN( i_ptr % sizeof(double) == 0 );\n# endif\n         // return pointer to memory, do not include block_t at beginning\n         return v_ptr;\n      }\n\n      // Create a new node with thread_alloc information at front.\n      // This uses the system allocator, which is thread safe, but slower,\n      // because the thread might wait for a lock on the allocator.\n      v_node          = ::operator new(sizeof(block_t) + cap_bytes);\n      CPPAD_ASSERT_UNKNOWN( v_node != nullptr );\n      node            = reinterpret_cast<block_t*>(v_node);\n      node->tc_index_ = tc_index;\n      void* v_ptr     = reinterpret_cast<void*>(node + 1);\n\n# ifndef NDEBUG\n# if ! CPPAD_DEBUG_AND_RELEASE\n      // add node to inuse list\n      node->next_       = inuse_root->next_;\n      inuse_root->next_ = v_node;\n# endif\n\n      // trace allocation\n      if( cap_bytes == CPPAD_TRACE_CAPACITY &&\n         thread    == CPPAD_TRACE_THREAD    )\n      {  cout << \"get_memory:    v_ptr = \" << v_ptr << endl; }\n# endif\n\n      // adjust counts\n      inc_inuse(cap_bytes, thread);\n\n      return v_ptr;\n   }\n\n/* -----------------------------------------------------------------------\n{xrst_begin ta_return_memory}\n\nReturn Memory to thread_alloc\n#############################\n\nSyntax\n******\n``thread_alloc::return_memory`` ( *v_ptr* )\n\nPurpose\n*******\nIf :ref:`hold_memory<ta_hold_memory-name>` is false,\nthe memory is returned to the system.\nOtherwise, the memory is retained by :ref:`thread_alloc-name` for quick future use\nby the thread that allocated to memory.\n\nv_ptr\n*****\nThis argument has prototype\n\n   ``void`` * *v_ptr*\n\n.\nIt must be a pointer to memory that is currently in use; i.e.\nobtained by a previous call to\n:ref:`get_memory<ta_get_memory-name>` and not yet returned.\n\nThread\n******\nEither the :ref:`current thread<ta_thread_num-name>` must be the same as during\nthe corresponding call to :ref:`get_memory<ta_get_memory-name>` ,\nor the current execution mode must be sequential\n(not :ref:`parallel<ta_in_parallel-name>` ).\n\nNDEBUG\n******\nIf ``NDEBUG`` is defined, *v_ptr* is not checked (this is faster).\nOtherwise, a list of in use pointers is searched to make sure\nthat *v_ptr* is in the list.\n\nExample\n*******\n:ref:`thread_alloc.cpp-name`\n\n{xrst_end ta_return_memory}\n*/\n   /*!\n   Return memory that was obtained by get_memory.\n   If  <code>num_threads() == 1</code>,\n   the memory is returned to the system.\n   Otherwise, it is retained by thread_alloc and available for use by\n   get_memory for this thread.\n\n   \\param v_ptr [in]\n   Value of the pointer returned by get_memory and still in use.\n   After this call, this pointer will available (and not in use).\n\n   \\par\n   We must either be in sequential (not parallel) execution mode,\n   or the current thread must be the same as for the corresponding call\n   to get_memory.\n   */\n   static void return_memory(void* v_ptr)\n   {  size_t num_cap   = capacity_info()->number;\n\n      block_t* node    = reinterpret_cast<block_t*>(v_ptr) - 1;\n      size_t tc_index  = node->tc_index_;\n      size_t thread    = tc_index / num_cap;\n      size_t c_index   = tc_index % num_cap;\n      size_t capacity  = capacity_info()->value[c_index];\n\n      CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS );\n      CPPAD_ASSERT_KNOWN(\n         thread == thread_num() || (! in_parallel()),\n         \"Attempt to return memory for a different thread \"\n         \"while in parallel mode\"\n      );\n\n      thread_alloc_info* info = thread_info(thread);\n# ifndef NDEBUG\n# if ! CPPAD_DEBUG_AND_RELEASE\n      // remove node from inuse list\n      void* v_node         = reinterpret_cast<void*>(node);\n      block_t* inuse_root  = info->root_inuse_ + c_index;\n      block_t* previous    = inuse_root;\n      while( (previous->next_ != nullptr) && (previous->next_ != v_node) )\n         previous = reinterpret_cast<block_t*>(previous->next_);\n\n      // check that v_ptr is valid\n      if( previous->next_ != v_node )\n      {  using std::endl;\n         std::ostringstream oss;\n         oss << \"return_memory: attempt to return memory not in use\";\n         oss << endl;\n         oss << \"v_ptr    = \" << v_ptr    << endl;\n         oss << \"thread   = \" << thread   << endl;\n         oss << \"capacity = \" << capacity << endl;\n         oss << \"See CPPAD_TRACE_THREAD & CPPAD_TRACE_CAPACITY in\";\n         oss << endl << \"# include <cppad/utility/thread_alloc.hpp>\" << endl;\n         // oss.str() returns a string object with a copy of the current\n         // contents in the stream buffer.\n         std::string msg_str       = oss.str();\n         // msg_str.c_str() returns a pointer to the c-string\n         // representation of the string object's value.\n         const char* msg_char_star = msg_str.c_str();\n         CPPAD_ASSERT_KNOWN(false, msg_char_star );\n      }\n      // remove v_ptr from inuse list\n      previous->next_  = node->next_;\n# endif\n      // trace option\n      if( capacity==CPPAD_TRACE_CAPACITY && thread==CPPAD_TRACE_THREAD )\n      {  std::cout << \"return_memory: v_ptr = \" << v_ptr << std::endl; }\n\n# endif\n      // capacity bytes are removed from the inuse pool\n      dec_inuse(capacity, thread);\n\n      // check for case where we just return the memory to the system\n      if( ! set_get_hold_memory(false) )\n      {  ::operator delete( reinterpret_cast<void*>(node) );\n         return;\n      }\n\n      // add this node to available list for this thread and capacity\n      block_t* available_root = info->root_available_ + c_index;\n      node->next_             = available_root->next_;\n      available_root->next_   = reinterpret_cast<void*>(node);\n\n      // capacity bytes are added to the available pool\n      inc_available(capacity, thread);\n   }\n/* -----------------------------------------------------------------------\n{xrst_begin ta_free_available}\n{xrst_spell\n   inuse\n}\n\nFree Memory Currently Available for Quick Use by a Thread\n#########################################################\n\nSyntax\n******\n``thread_alloc::free_available`` ( *thread* )\n\nPurpose\n*******\nReturn to the system all the memory that is currently being\n:ref:`held<ta_hold_memory-name>` for quick use by the specified thread.\n\nExtra Memory\n============\nIn the case where *thread*  > 0 ,\nsome extra memory is used to track allocations by the specified thread.\nIf\n\n   ``thread_alloc::inuse`` ( *thread* ) == 0\n\nthe extra memory is also returned to the system.\n\nthread\n******\nThis argument has prototype\n\n   ``size_t`` *thread*\n\nEither :ref:`thread_num<ta_thread_num-name>` must be the same as *thread* ,\nor the current execution mode must be sequential\n(not :ref:`parallel<ta_in_parallel-name>` ).\n\nExample\n*******\n:ref:`thread_alloc.cpp-name`\n\n{xrst_end ta_free_available}\n*/\n   /*!\n   Return all the memory being held as available for a thread to the system.\n\n   \\param thread [in]\n   this thread that will no longer have any available memory after this call.\n   This must either be the thread currently executing, or we must be\n   in sequential (not parallel) execution mode.\n   */\n   static void free_available(size_t thread)\n   {  CPPAD_ASSERT_KNOWN(\n         thread < CPPAD_MAX_NUM_THREADS,\n         \"Attempt to free memory for a thread >= CPPAD_MAX_NUM_THREADS\"\n      );\n      CPPAD_ASSERT_KNOWN(\n         thread == thread_num() || (! in_parallel()),\n         \"Attempt to free memory for a different thread \"\n         \"while in parallel mode\"\n      );\n\n      size_t num_cap = capacity_info()->number;\n      if( num_cap == 0 )\n         return;\n      const size_t*     capacity_vec  = capacity_info()->value;\n      size_t c_index;\n      thread_alloc_info* info = thread_info(thread);\n      for(c_index = 0; c_index < num_cap; c_index++)\n      {  size_t capacity = capacity_vec[c_index];\n         block_t* available_root = info->root_available_ + c_index;\n         void* v_ptr             = available_root->next_;\n         while( v_ptr != nullptr )\n         {  block_t* node = reinterpret_cast<block_t*>(v_ptr);\n            void* next    = node->next_;\n            ::operator delete(v_ptr);\n            v_ptr         = next;\n\n            dec_available(capacity, thread);\n         }\n         available_root->next_ = nullptr;\n      }\n      CPPAD_ASSERT_UNKNOWN( available(thread) == 0 );\n      if( inuse(thread) == 0 )\n      {  // clear the information for this thread\n         thread_info(thread, true);\n      }\n   }\n/* -----------------------------------------------------------------------\n{xrst_begin ta_hold_memory}\n\nControl When Thread Alloc Retains Memory For Future Use\n#######################################################\n\nSyntax\n******\n``thread_alloc::hold_memory`` ( *value* )\n\nPurpose\n*******\nIt should be faster, even when *num_thread* is equal to one,\nfor ``thread_alloc`` to hold onto memory.\nCalling *hold_memory* with *value* equal to true,\ninstructs ``thread_alloc`` to hold onto memory,\nand put it in the :ref:`available<ta_available-name>` pool,\nafter each call to :ref:`return_memory<ta_return_memory-name>` .\n\nvalue\n*****\nIf *value* is true,\n``thread_alloc`` with hold onto memory for future quick use.\nIf it is false, future calls to :ref:`return_memory<ta_return_memory-name>`\nwill return the corresponding memory to the system.\nBy default (when ``hold_memory`` has not been called)\n``thread_alloc`` does not hold onto memory.\n\nfree_available\n**************\nMemory that is being held by ``thread_alloc`` can be returned\nto the system using :ref:`free_available<ta_free_available-name>` .\n\n{xrst_end ta_hold_memory}\n*/\n   /*!\n   Change the thread_alloc hold memory setting.\n\n   \\param value [in]\n   New value for the thread_alloc hold memory setting.\n   */\n   static void hold_memory(bool value)\n   {  bool set = true;\n      set_get_hold_memory(set, value);\n   }\n\n/* -----------------------------------------------------------------------\n{xrst_begin ta_inuse}\n\nAmount of Memory a Thread is Currently Using\n############################################\n\nSyntax\n******\n*num_bytes* = ``thread_alloc::inuse`` ( *thread* )\n\nPurpose\n*******\nMemory being managed by :ref:`thread_alloc-name` has two states,\ncurrently in use by the specified thread,\nand quickly available for future use by the specified thread.\nThis function informs the program how much memory is in use.\n\nthread\n******\nThis argument has prototype\n\n   ``size_t`` *thread*\n\nEither :ref:`thread_num<ta_thread_num-name>` must be the same as *thread* ,\nor the current execution mode must be sequential\n(not :ref:`parallel<ta_in_parallel-name>` ).\n\nnum_bytes\n*********\nThe return value has prototype\n\n   ``size_t`` *num_bytes*\n\nIt is the number of bytes currently in use by the specified thread.\n\nExample\n*******\n:ref:`thread_alloc.cpp-name`\n\n{xrst_end ta_inuse}\n*/\n   /*!\n   Determine the amount of memory that is currently inuse.\n\n   \\param thread [in]\n   Thread for which we are determining the amount of memory\n   (must be < CPPAD_MAX_NUM_THREADS).\n   During parallel execution, this must be the thread\n   that is currently executing.\n\n   \\return\n   The amount of memory in bytes.\n   */\n   static size_t inuse(size_t thread)\n   {\n      CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);\n      CPPAD_ASSERT_UNKNOWN(\n         thread == thread_num() || (! in_parallel())\n      );\n      thread_alloc_info* info = thread_info(thread);\n      return info->count_inuse_;\n   }\n/* -----------------------------------------------------------------------\n{xrst_begin ta_available}\n\nAmount of Memory Available for Quick Use by a Thread\n####################################################\n\nSyntax\n******\n*num_bytes* = ``thread_alloc::available`` ( *thread* )\n\nPurpose\n*******\nMemory being managed by :ref:`thread_alloc-name` has two states,\ncurrently in use by the specified thread,\nand quickly available for future use by the specified thread.\nThis function informs the program how much memory is available.\n\nthread\n******\nThis argument has prototype\n\n   ``size_t`` *thread*\n\nEither :ref:`thread_num<ta_thread_num-name>` must be the same as *thread* ,\nor the current execution mode must be sequential\n(not :ref:`parallel<ta_in_parallel-name>` ).\n\nnum_bytes\n*********\nThe return value has prototype\n\n   ``size_t`` *num_bytes*\n\nIt is the number of bytes currently available for use by the specified thread.\n\nExample\n*******\n:ref:`thread_alloc.cpp-name`\n\n{xrst_end ta_available}\n*/\n   /*!\n   Determine the amount of memory that is currently available for use.\n\n   \\copydetails inuse\n   */\n   static size_t available(size_t thread)\n   {\n      CPPAD_ASSERT_UNKNOWN( thread < CPPAD_MAX_NUM_THREADS);\n      CPPAD_ASSERT_UNKNOWN(\n         thread == thread_num() || (! in_parallel())\n      );\n      thread_alloc_info* info = thread_info(thread);\n      return info->count_available_;\n   }\n/* -----------------------------------------------------------------------\n{xrst_begin ta_create_array}\n\nAllocate An Array and Call Default Constructor for its Elements\n###############################################################\n\nSyntax\n******\n*array* = ``thread_alloc::create_array<`` *Type* >( *size_min* , *size_out* ) .\n\nPurpose\n*******\nCreate a new raw array using :ref:`thread_alloc-name` memory allocator\n(works well in a multi-threading environment)\nand call default constructor for each element.\n\nType\n****\nThe type of the elements of the array.\n\nsize_min\n********\nThis argument has prototype\n\n   ``size_t`` *size_min*\n\nThis is the minimum number of elements that there can be\nin the resulting *array* .\n\nsize_out\n********\nThis argument has prototype\n\n   ``size_t&`` *size_out*\n\nThe input value of this argument does not matter.\nUpon return, it is the actual number of elements\nin *array*\n( *size_min* <= *size_out* ).\n\narray\n*****\nThe return value *array* has prototype\n\n   *Type* * *array*\n\nIt is array with *size_out* elements.\nThe default constructor for *Type* is used to initialize the\nelements of *array* .\nNote that :ref:`delete_array<ta_delete_array-name>`\nshould be used to destroy the array when it is no longer needed.\n\nDelta\n*****\nThe amount of memory :ref:`inuse<ta_inuse-name>` by the current thread,\nwill increase *delta* where\n\n   ``sizeof`` ( *Type* ) * ( *size_out* + 1) > *delta* >= ``sizeof`` ( *Type* ) * *size_out*\n\nThe :ref:`available<ta_available-name>` memory will decrease by *delta* ,\n(and the allocation will be faster)\nif a previous allocation with *size_min* between its current value\nand *size_out* is available.\n\nAlignment\n*********\nWe call a memory allocation aligned if the address is a multiple\nof the number of bytes in a ``size_t`` value.\nIf the system ``new`` allocator is aligned, then *array*\npointer is also aligned.\n\nExample\n*******\n:ref:`thread_alloc.cpp-name`\n\n{xrst_end ta_create_array}\n*/\n   /*!\n   Use thread_alloc to allocate an array, then call default constructor\n   for each element.\n\n   \\tparam Type\n   The type of the elements of the array.\n\n   \\param size_min [in]\n   The minimum number of elements in the array.\n\n   \\param size_out [out]\n   The actual number of elements in the array.\n\n   \\return\n   pointer to the first element of the array.\n   The default constructor is used to initialize\n   all the elements of the array.\n\n   \\par\n   The extra_ field, in the thread_alloc node before the return value,\n   is set to size_out.\n   */\n   template <class Type>\n   static Type* create_array(size_t size_min, size_t& size_out)\n   {  // minimum number of bytes to allocate\n      size_t min_bytes = size_min * sizeof(Type);\n      // do the allocation\n      size_t num_bytes;\n      void*  v_ptr     = get_memory(min_bytes, num_bytes);\n      // This is where the array starts\n      Type*  array     = reinterpret_cast<Type*>(v_ptr);\n      // number of Type values in the allocation\n      size_out         = num_bytes / sizeof(Type);\n      // store this number in the extra field\n      block_t* node    = reinterpret_cast<block_t*>(v_ptr) - 1;\n      node->extra_     = size_out;\n\n      // call default constructor for each element\n      size_t i;\n      for(i = 0; i < size_out; i++)\n         new(array + i) Type();\n\n      return array;\n   }\n/* -----------------------------------------------------------------------\n{xrst_begin ta_delete_array}\n{xrst_spell\n   deallocate\n}\n\nDeallocate An Array and Call Destructor for its Elements\n########################################################\n\nSyntax\n******\n``thread_alloc::delete_array`` ( *array* ) .\n\nPurpose\n*******\nReturns memory corresponding to an array created by\n(create by :ref:`create_array<ta_create_array-name>` ) to the\n:ref:`available<ta_available-name>` memory pool for the current thread.\n\nType\n****\nThe type of the elements of the array.\n\narray\n*****\nThe argument *array* has prototype\n\n   *Type* * *array*\n\nIt is a value returned by :ref:`create_array<ta_create_array-name>` and not yet deleted.\nThe *Type* destructor is called for each element in the array.\n\nThread\n******\nThe :ref:`current thread<ta_thread_num-name>` must be the\nsame as when :ref:`create_array<ta_create_array-name>` returned the value *array* .\nThere is an exception to this rule:\nwhen the current execution mode is sequential\n(not :ref:`parallel<ta_in_parallel-name>` ) the current thread number does not matter.\n\nDelta\n*****\nThe amount of memory :ref:`inuse<ta_inuse-name>` will decrease by *delta* ,\nand the :ref:`available<ta_available-name>` memory will increase by *delta* ,\nwhere :ref:`ta_create_array@Delta`\nis the same as for the corresponding call to ``create_array`` .\n\nExample\n*******\n:ref:`thread_alloc.cpp-name`\n\n{xrst_end ta_delete_array}\n*/\n   /*!\n   Return Memory Used for an Array to the Available Pool\n   (include destructor call for each element).\n\n   \\tparam Type\n   The type of the elements of the array.\n\n   \\param array [in]\n   A value returned by create_array that has not yet been deleted.\n   The Type destructor is used to destroy each of the elements\n   of the array.\n\n   \\par\n   During parallel execution, the current thread must be the same\n   as during the corresponding call to create_array.\n   */\n   template <class Type>\n   static void delete_array(Type* array)\n   {  // determine the number of values in the array\n      block_t* node = reinterpret_cast<block_t*>(array) - 1;\n      size_t size     = node->extra_;\n\n      // call destructor for each element\n      size_t i;\n      for(i = 0; i < size; i++)\n         (array + i)->~Type();\n\n      // return the memory to the available pool for this thread\n      thread_alloc::return_memory( reinterpret_cast<void*>(array) );\n   }\n/* -----------------------------------------------------------------------\n{xrst_begin ta_free_all}\n\nFree All Memory That Was Allocated for Use by thread_alloc\n##########################################################\n\nSyntax\n******\n*ok* = ``thread_alloc::free_all`` () .\n\nPurpose\n*******\nReturns all memory that was used by ``thread_alloc`` to the system.\n\nok\n**\nThe return value *ok* has prototype\n\n   ``bool`` *ok*\n\nIts value will be ``true`` if all the memory can be freed.\nThis requires that for all *thread* indices, there is no memory\n:ref:`inuse<ta_inuse-name>` ; i.e.,\n\n   0 == ``thread_alloc::inuse`` ( *thread* )\n\nOtherwise, the return value will be false.\n\nRestrictions\n************\nThis function cannot be called while in parallel mode.\n\nExample\n*******\n:ref:`thread_alloc.cpp-name`\n\n{xrst_end ta_free_all}\n*/\n   /*!\n   Return to the system all thread_alloc memory that is not currently inuse.\n\n   \\return\n   If no thread_alloc memory is currently inuse,\n   all memory is returned to the system and the return value is true.\n   Otherwise the return value is false.\n   */\n   static bool free_all(void)\n   {  CPPAD_ASSERT_KNOWN(\n         ! in_parallel(),\n         \"free_all cannot be used while in parallel execution\"\n      );\n      bool ok = true;\n      size_t thread = CPPAD_MAX_NUM_THREADS;\n      while(thread--)\n      {  ok &= inuse(thread) == 0;\n         free_available(thread);\n      }\n      return ok;\n   }\n};\n\n\n} // END_CPPAD_NAMESPACE\n\n// preprocessor symbols local to this file\n# undef CPPAD_MAX_NUM_CAPACITY\n# undef CPPAD_MIN_DOUBLE_CAPACITY\n# undef CPPAD_TRACE_CAPACITY\n# undef CPPAD_TRACE_THREAD\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/time_test.hpp",
    "content": "# ifndef CPPAD_UTILITY_TIME_TEST_HPP\n# define CPPAD_UTILITY_TIME_TEST_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin time_test}\n\nDetermine Amount of Time to Execute a Test\n##########################################\n\nSyntax\n******\n| # ``include <cppad/utility/time_test.hpp>``\n| *time* = ``time_test`` ( *test_fun* , *time_min* )\n| *time* = ``time_test`` ( *test_fun* , *time_min* , *test_size* )\n| *time* = ``time_test`` ( *test_fun* , *time_min* , *test_size* , *repeat_out* )\n\nPurpose\n*******\nThe ``time_test`` function executes a timing test\nand reports the amount of wall clock time for execution.\n\nMotivation\n**********\nIt is important to separate small calculation units\nand test them individually.\nThis way individual changes can be tested in the context of the\nroutine that they are in.\nOn many machines, accurate timing of a very short execution\nsequences is not possible.\nIn addition,\nthere may be set up and tear down time for a test that\nwe do not really want included in the timing.\nFor this reason ``time_test``\nautomatically determines how many times to\nrepeat the section of the test that we wish to time.\n\nInclude\n*******\nThe file ``cppad/utility/time_test.hpp`` defines the\n``time_test`` function.\nThis file is included by ``cppad/cppad.hpp``\nand it can also be included separately with out the rest of\nthe ``CppAD`` routines.\n\ntest_fun\n********\nThe ``time_test`` argument *test_fun* is a function,\nor function object.\nIn the case where *test_size* is not present,\n*test_fun* supports the syntax\n\n   *test_fun* ( *repeat* )\n\nIn the case where *test_size* is present,\n*test_fun* supports the syntax\n\n   *test_fun* ( *size* , *repeat* )\n\nIn either case, the return value for *test_fun* is ``void`` .\n\nsize\n====\nIf the argument *size* is present,\nit has prototype\n\n   ``size_t`` *size*\n\nand is equal to the *test_size* argument to ``time_test`` .\n\nrepeat\n======\nThe *test_fun* argument *repeat* has prototype\n\n   ``size_t`` *repeat*\n\nIt specifies the number of times to repeat the test.\n\ntime_min\n********\nThe argument *time_min* has prototype\n\n   ``double`` *time_min*\n\nIt specifies the minimum amount of time in seconds\nthat the repeats of *test_fun* routine should take.\nThe *repeat* argument to *test_fun* is increased\nuntil this amount of execution time (or more) is reached.\n\ntest_size\n*********\nIf this argument is present, it argument has prototype\n\n   ``size_t`` *test_size*\n\nIn this case *test_size* will be present, and have the same value,\nin each call to *test_fun* .\n\nrepeat_out\n**********\nIf this argument is present, it has prototype\n\n   ``size_t&`` *repeat_out*\n\nThis input value of this argument does not matter.\nUpon return, it is the value of :ref:`time_test@test_fun@repeat`\nthat corresponds to the return value *time* ; i.e.,\nthe total time for the repeats of the test is\n\n   *total_time* = *repeat_out* * *time*\n\ntime\n****\nThe return value *time* has prototype\n\n   ``double`` *time*\n\nand is the number of wall clock seconds that it took\nto execute the repeats of *test_fun*\ndivided by the value used for *repeat* .\n\nTiming\n******\nThe routine :ref:`elapsed_seconds-name` will be used to determine the\namount of time it took to execute the test.\n{xrst_toc_hidden\n   include/cppad/utility/elapsed_seconds.hpp\n   speed/example/time_test.cpp\n}\nExample\n*******\nThe routine :ref:`time_test.cpp-name` is an example and test\nof ``time_test`` .\n\n{xrst_end time_test}\n-----------------------------------------------------------------------\n*/\n\n# include <algorithm>\n# include <cstddef>\n# include <cmath>\n# include <cppad/utility/elapsed_seconds.hpp>\n# include <cppad/local/define.hpp>\n\n# define CPPAD_EXTRA_RUN_BEFORE_TIMING 0\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n/*!\n\\file time_test.hpp\n\\brief Function that preforms one timing test (for speed of execution).\n*/\n\n/*!\nPreform one wall clock execution timing test.\n\n\\tparam Test\nEither the type void (*)(size_t)\nor a function object type that supports the same syntax.\n\n\\param test\nThe function, or function object, that supports the operation\ntest(repeat) where repeat is the number of times\nto repeat the tests operation that is being timed.\n\n\\param time_min\nis the minimum amount of time that test should take to preform\nthe repetitions of the operation being timed.\n\n\\return\nis the time for each execution of the test.\n*/\ntemplate <class Test>\ndouble time_test(Test test, double time_min )\n{\n# if CPPAD_EXTRA_RUN_BEFORE_TIMING\n   test(1);\n# endif\n   size_t repeat = 0;\n   double s0     = elapsed_seconds();\n   double s1     = s0;\n   while( s1 - s0 < time_min )\n   {  repeat = std::max(size_t(1), 2 * repeat);\n      s0     = elapsed_seconds();\n      test(repeat);\n      s1     = elapsed_seconds();\n   }\n   double time = (s1 - s0) / double(repeat);\n   return time;\n}\n/*!\nPreform one wall clock execution timing test.\n\n\\tparam Test\nEither the type void (*)(size_t, size_t)\nor a function object type that supports the same syntax.\n\n\\param test\nThe function, or function object, that supports the operation\ntest(size, repeat) where size\nis the size for this test and repeat is the number of times\nto repeat the tests operation that is being timed.\n\n\\param time_min\nis the minimum amount of time that test should take to preform\nthe repetitions of the operation being timed.\n\n\\param test_size\nwill be used for the value of size in the call to test.\n\n\\return\nis the time for each execution of the test.\n*/\ntemplate <class Test>\ndouble time_test(Test test, double time_min, size_t test_size)\n{\n# if CPPAD_EXTRA_RUN_BEFORE_TIMING\n   test(test_size, 1);\n# endif\n   size_t repeat = 0;\n   double s0     = elapsed_seconds();\n   double s1     = s0;\n   while( s1 - s0 < time_min )\n   {  repeat = std::max(size_t(1), 2 * repeat);\n      s0     = elapsed_seconds();\n      test(test_size, repeat);\n      s1     = elapsed_seconds();\n   }\n   double time = (s1 - s0) / double(repeat);\n   return time;\n}\n/*!\nPreform one wall clock execution timing test.\n\n\\tparam Test\nEither the type void (*)(size_t, size_t)\nor a function object type that supports the same syntax.\n\n\\param test\nThe function, or function object, that supports the operation\ntest(size, repeat) where size\nis the size for this test and repeat is the number of times\nto repeat the tests operation that is being timed.\n\n\\param time_min\nis the minimum amount of time that test should take to preform\nthe repetitions of the operation being timed.\n\n\\param test_size\nwill be used for the value of size in the call to test.\n\n\\param repeat_out\nthe return value is the number of times the test was repeated;\ni.e., the return value is the total time divided by repeat.\n\n\\return\nis the time for each execution of the test.\n*/\ntemplate <class Test>\ndouble time_test(\n   Test test, double time_min, size_t test_size, size_t& repeat_out\n)\n{\n# if CPPAD_EXTRA_RUN_BEFORE_TIMING\n   test(test_size, 1);\n# endif\n   repeat_out    = 0;\n   double s0     = elapsed_seconds();\n   double s1     = s0;\n   while( s1 - s0 < time_min )\n   {  repeat_out = std::max(size_t(1), 2 * repeat_out);\n      s0         = elapsed_seconds();\n      test(test_size, repeat_out);\n      s1         = elapsed_seconds();\n   }\n   double time = (s1 - s0) / double(repeat_out);\n   return time;\n}\n\n} // END_CPPAD_NAMESPACE\n\n# undef CPPAD_EXTRA_RUN_BEFORE_TIMING\n// END PROGRAM\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/to_string.hpp",
    "content": "# ifndef CPPAD_UTILITY_TO_STRING_HPP\n# define CPPAD_UTILITY_TO_STRING_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin to_string}\n{xrst_spell\n   long long\n   ostringstream\n}\n\nConvert Certain Types to a String\n#################################\n\nSyntax\n******\n| # ``include <cppad/utility/to_string.hpp>``\n| *s* = ``to_string`` ( *value* ) .\n\nSee Also\n********\n:ref:`base_to_string-name` , :ref:`ad_to_string-name`\n\nPurpose\n*******\nThis routine is similar to the C++11 routine ``std::to_string``\nwith the following differences:\n\n#. It works with C++98.\n#. It has been extended to the fundamental floating point types.\n#. It has specifications for extending to an arbitrary type; see\n   :ref:`base_to_string-name` .\n#. If ``<cppad/cppad.hpp>`` is included,\n   and it has been extended to a *Base* type,\n   it automatically extends to the\n   :ref:`AD types above Base<glossary@AD Type Above Base>` .\n#. For integer types, conversion to a string is exact.\n   For floating point types, conversion to a string yields a value\n   that has relative error within machine epsilon.\n\nvalue\n*****\n\nInteger\n=======\nThe argument *value* can have the following prototype\n\n   ``const`` *Integer* & *value*\n\nwhere *Integer* is any of the fundamental integer types; e.g.,\n``short int`` and ``unsigned long`` .\nNote that if C++11 is supported by this compilation,\n``unsigned long long`` is also a fundamental integer type.\n\nFloat\n=====\nThe argument *value* can have the following prototype\n\n   ``const`` *Float* & *value*\n\nwhere *Float* is any of the fundamental floating point types; i.e.,\n``float`` , ``double`` , and ``long double`` .\n\ns\n*\nThe return value has prototype\n\n   ``std::string`` *s*\n\nand contains a representation of the specified *value* .\n\nInteger\n=======\nIf *value* is an ``Integer`` ,\nthe representation is equivalent to ``os`` << ``value``\nwhere *os* is an ``std::ostringstream`` .\n\nFloat\n=====\nIf *value* is a ``Float`` ,\nenough digits are used in the representation so that\nthe result is accurate to within round off error.\n{xrst_toc_hidden\n   example/utility/to_string.cpp\n}\nExample\n*******\nThe file :ref:`to_string.cpp-name`\ncontains an example and test of this routine.\n\n{xrst_end to_string}\n*/\n# include <limits>\n# include <cmath>\n# include <iomanip>\n# include <sstream>\n# include <cppad/core/cppad_assert.hpp>\n\n# define CPPAD_SPECIALIZE_TO_STRING_INTEGER(Type) \\\ntemplate <> struct to_string_struct<Type>\\\n{  std::string operator()(const Type& value) \\\n   {  std::stringstream os;\\\n      os << value;\\\n      return os.str();\\\n   }\\\n};\n\n# define CPPAD_SPECIALIZE_TO_STRING_FLOAT(Float) \\\ntemplate <> struct to_string_struct<Float>\\\n{  std::string operator()(const Float& value) \\\n   {  std::stringstream os;\\\n      int n_digits = 1 + std::numeric_limits<Float>::digits10;\\\n      os << std::setprecision(n_digits);\\\n      os << value;\\\n      return os.str();\\\n   }\\\n};\n\nnamespace CppAD {\n\n   // Default implementation,\n   // each type must define its own specialization.\n   template <class Type>\n   struct to_string_struct\n   {  std::string operator()(const Type& value)\n      {  CPPAD_ASSERT_KNOWN(\n            false,\n            \"to_string is not implemented for this type\"\n         );\n         // return empty string\n         return std::string(\"\");\n      }\n   };\n\n   // specialization for the fundamental integer types\n   CPPAD_SPECIALIZE_TO_STRING_INTEGER(signed short)\n   CPPAD_SPECIALIZE_TO_STRING_INTEGER(unsigned short)\n   //\n   CPPAD_SPECIALIZE_TO_STRING_INTEGER(signed int)\n   CPPAD_SPECIALIZE_TO_STRING_INTEGER(unsigned int)\n   //\n   CPPAD_SPECIALIZE_TO_STRING_INTEGER(signed long)\n   CPPAD_SPECIALIZE_TO_STRING_INTEGER(unsigned long)\n   //\n   CPPAD_SPECIALIZE_TO_STRING_INTEGER(signed long long)\n   CPPAD_SPECIALIZE_TO_STRING_INTEGER(unsigned long long)\n\n   // specialization for the fundamental floating point types\n   CPPAD_SPECIALIZE_TO_STRING_FLOAT(float)\n   CPPAD_SPECIALIZE_TO_STRING_FLOAT(double)\n   CPPAD_SPECIALIZE_TO_STRING_FLOAT(long double)\n\n   // link from function to function object in structure\n   template<class Type>\n   std::string to_string(const Type& value)\n   {  to_string_struct<Type> to_str;\n      return to_str(value);\n   }\n}\n\n# undef CPPAD_SPECIALIZE_TO_STRING_FLOAT\n# undef CPPAD_SPECIALIZE_TO_STRING_INTEGER\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/track_new_del.hpp",
    "content": "# ifndef CPPAD_UTILITY_TRACK_NEW_DEL_HPP\n# define CPPAD_UTILITY_TRACK_NEW_DEL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin track_new_del app}\n{xrst_spell\n   ncopy\n   newlen\n   newptr\n   oldptr\n}\n\nRoutines That Track Use of New and Delete\n#########################################\n\nDeprecated 2007-07-23\n*********************\nAll these routines have been deprecated.\nYou should use the :ref:`thread_alloc-name` memory allocator instead\n(which works better in both a single thread and\nproperly in multi-threading environment).\n\nSyntax\n******\n| # ``include <cppad/utility/track_new_del.hpp>``\n| *newptr* = ``TrackNewVec`` ( *file* , *line* , *newlen* , *oldptr* )\n| ``TrackDelVec`` ( *file* , *line* , *oldptr* )\n| *newptr* = ``TrackExtend`` ( *file* , *line* , *newlen* , *ncopy* , *oldptr* )\n| *count* = ``TrackCount`` ( *file* , *line* )\n\nPurpose\n*******\nThese routines\naid in the use of ``new[]`` and  ``delete[]``\nduring the execution of a C++ program.\n\nInclude\n*******\nThe file ``cppad/utility/track_new_del.hpp`` is included by\n``cppad/cppad.hpp``\nbut it can also be included separately with out the rest of the\nCppAD include files.\n\nfile\n****\nThe argument *file* has prototype\n\n   ``const char`` * *file*\n\nIt should be the source code file name\nwhere the call to ``TrackNew`` is located.\nThe best way to accomplish this is the use the preprocessor symbol\n``__FILE__`` for this argument.\n\nline\n****\nThe argument *line* has prototype\n\n   ``int`` *line*\n\nIt should be the source code file line number\nwhere the call to ``TrackNew`` is located.\nThe best way to accomplish this is the use the preprocessor symbol\n``__LINE__`` for this argument.\n\noldptr\n******\nThe argument *oldptr* has prototype\n\n   *Type* * *oldptr*\n\nThis argument is used to identify the type *Type* .\n\nnewlen\n******\nThe argument *newlen* has prototype\n\n   ``size_t`` *newlen*\n\nhead newptr\n***********\nThe return value *newptr* has prototype\n\n   *Type* * *newptr*\n\nIt points to the newly allocated vector of objects\nthat were allocated using\n\n   ``new Type`` [ *newlen* ]\n\nncopy\n*****\nThe argument *ncopy* has prototype\n\n   ``size_t`` *ncopy*\n\nThis specifies the number of elements that are copied from\nthe old array to the new array.\nThe value of *ncopy*\nmust be less than or equal *newlen* .\n\nTrackNewVec\n***********\nIf ``NDEBUG`` is defined, this routine only sets\n\n   *newptr* = *Type* ``new`` [ *newlen* ]\n\nThe value of *oldptr* does not matter\n(except that it is used to identify *Type* ).\nIf ``NDEBUG`` is not defined, ``TrackNewVec`` also\ntracks the this memory allocation.\nIn this case, if memory cannot be allocated\n:ref:`ErrorHandler-name` is used to generate a message\nstating that there was not sufficient memory.\n\nMacro\n=====\nThe preprocessor macro call\n\n   ``CPPAD_TRACK_NEW_VEC`` ( *newlen* , *oldptr* )\n\nexpands to\n\n   ``CppAD::TrackNewVec`` (__ ``FILE__`` , __ ``LINE__`` , *newlen* , *oldptr* )\n\nPreviously Deprecated\n=====================\nThe preprocessor macro ``CppADTrackNewVec`` is the\nsame as ``CPPAD_TRACK_NEW_VEC`` and was previously deprecated.\n\nTrackDelVec\n***********\nThis routine is used to a vector of objects\nthat have been allocated using ``TrackNew`` or ``TrackExtend`` .\nIf ``NDEBUG`` is defined, this routine only frees memory with\n\n   ``delete`` [] *oldptr*\n\nIf ``NDEBUG`` is not defined, ``TrackDelete`` also checks that\n*oldptr* was allocated by ``TrackNew`` or ``TrackExtend``\nand has not yet been freed.\nIf this is not the case,\n:ref:`ErrorHandler-name` is used to generate an error message.\n\nMacro\n=====\nThe preprocessor macro call\n\n   ``CPPAD_TRACK_DEL_VEC`` ( *oldptr* )\n\nexpands to\n\n   ``CppAD::TrackDelVec`` (__ ``FILE__`` , __ ``LINE__`` , *oldptr* )\n\nPreviously Deprecated\n=====================\nThe preprocessor macro ``CppADTrackDelVec`` is the\nsame as ``CPPAD_TRACK_DEL_VEC`` was previously deprecated.\n\nTrackExtend\n***********\nThis routine is used to\nallocate a new vector (using ``TrackNewVec`` ),\ncopy *ncopy* elements from the old vector to the new vector.\nIf *ncopy* is greater than zero, *oldptr*\nmust have been allocated using ``TrackNewVec`` or ``TrackExtend`` .\nIn this case, the vector pointed to by *oldptr*\nmust be have at least *ncopy* elements\nand it will be deleted (using ``TrackDelVec`` ).\nNote that the dependence of ``TrackExtend`` on ``NDEBUG``\nis indirectly through the routines ``TrackNewVec`` and\n``TrackDelVec`` .\n\nMacro\n=====\nThe preprocessor macro call\n\n   ``CPPAD_TRACK_EXTEND`` ( *newlen* , *ncopy* , *oldptr* )\n\nexpands to\n\n   ``CppAD::TrackExtend`` (__ ``FILE__`` , __ ``LINE__`` , *newlen* , *ncopy* , *oldptr* )\n\nPreviously Deprecated\n=====================\nThe preprocessor macro ``CppADTrackExtend`` is the\nsame as ``CPPAD_TRACK_EXTEND`` and was previously deprecated.\n\nTrackCount\n**********\nThe return value *count* has prototype\n\n   ``size_t`` *count*\n\nIf ``NDEBUG`` is defined, *count* will be zero.\nOtherwise, it will be\nthe number of vectors that\nhave been allocated\n(by ``TrackNewVec`` or ``TrackExtend`` )\nand not yet freed\n(by ``TrackDelete`` ).\n\nMacro\n=====\nThe preprocessor macro call\n\n   ``CPPAD_TRACK_COUNT`` ()\n\nexpands to\n\n   ``CppAD::TrackCount`` (__ ``FILE__`` , __ ``LINE__`` )\n\nPreviously Deprecated\n=====================\nThe preprocessor macro ``CppADTrackCount`` is the\nsame as ``CPPAD_TRACK_COUNT`` and was previously deprecated.\n\nMulti-Threading\n***************\nThese routines cannot be used :ref:`in_parallel<ta_in_parallel-name>`\nexecution mode.\nUse the :ref:`thread_alloc-name` routines instead.\n\n{xrst_end track_new_del}\n------------------------------------------------------------------------------\n*/\n# include <cppad/local/define.hpp>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/utility/thread_alloc.hpp>\n# include <sstream>\n# include <string>\n\n# ifndef CPPAD_TRACK_DEBUG\n# define CPPAD_TRACK_DEBUG 0\n# endif\n\n// -------------------------------------------------------------------------\n# define CPPAD_TRACK_NEW_VEC(newlen, oldptr) \\\n   CppAD::TrackNewVec(__FILE__, __LINE__, newlen, oldptr)\n\n# define CPPAD_TRACK_DEL_VEC(oldptr) \\\n   CppAD::TrackDelVec(__FILE__, __LINE__, oldptr)\n\n# define CPPAD_TRACK_EXTEND(newlen, ncopy, oldptr) \\\n   CppAD::TrackExtend(__FILE__, __LINE__, newlen, ncopy, oldptr)\n\n# define CPPAD_TRACK_COUNT() \\\n   CppAD::TrackCount(__FILE__, __LINE__)\n// -------------------------------------------------------------------------\n# define CppADTrackNewVec CPPAD_TRACK_NEW_VEC\n# define CppADTrackDelVec CPPAD_TRACK_DEL_VEC\n# define CppADTrackExtend CPPAD_TRACK_EXTEND\n# define CppADTrackCount  CPPAD_TRACK_COUNT\n// -------------------------------------------------------------------------\nnamespace CppAD { // Begin CppAD namespace\n\n// TrackElement ------------------------------------------------------------\nclass TrackElement {\n\npublic:\n   std::string   file;   // corresponding file name\n   int           line;   // corresponding line number\n   void          *ptr;   // value returned by TrackNew\n   TrackElement *next;   // next element in linked list\n\n   // default constructor (used to initialize root)\n   TrackElement(void)\n   : file(\"\"), line(0), ptr(nullptr), next(nullptr)\n   { }\n\n   TrackElement(const char *f, int l, void *p)\n   : file(f), line(l), ptr(p), next(nullptr)\n   {  CPPAD_ASSERT_UNKNOWN( p != nullptr);\n   }\n\n   // There is only one tracking list and it starts it here\n   static TrackElement *Root(void)\n   {  CPPAD_ASSERT_UNKNOWN( ! thread_alloc::in_parallel() );\n      static TrackElement root;\n      return &root;\n   }\n\n   // Print one tracking element\n   static void Print(TrackElement* E)\n   {\n      CPPAD_ASSERT_UNKNOWN( ! thread_alloc::in_parallel() );\n      using std::cout;\n      cout << \"E = \"         << E;\n      cout << \", E->next = \" << E->next;\n      cout << \", E->ptr  = \" << E->ptr;\n      cout << \", E->line = \" << E->line;\n      cout << \", E->file = \" << E->file;\n      cout << std::endl;\n   }\n\n   // Print the linked list for a thread\n   static void Print(void)\n   {\n      CPPAD_ASSERT_UNKNOWN( ! thread_alloc::in_parallel() );\n      using std::cout;\n      using std::endl;\n      TrackElement *E = Root();\n      // convert int(size_t) to avoid warning on _MSC_VER systems\n      cout << \"Begin Track List\" << endl;\n      while( E->next != nullptr )\n      {  E = E->next;\n         Print(E);\n      }\n      cout << \"End Track List:\" << endl;\n      cout << endl;\n   }\n};\n\n\n// TrackError ----------------------------------------------------------------\ninline void TrackError(\n   const char *routine,\n   const char *file,\n   int         line,\n   const char *msg )\n{\n   CPPAD_ASSERT_UNKNOWN( ! thread_alloc::in_parallel() );\n   std::ostringstream buf;\n   buf << routine\n      << \": at line \"\n      << line\n      << \" in file \"\n      << file\n      << std::endl\n      << msg;\n   std::string str = buf.str();\n   size_t      n   = str.size();\n   size_t i;\n   char *message = new char[n + 1];\n   for(i = 0; i < n; i++)\n      message[i] = str[i];\n   message[n] = '\\0';\n   CPPAD_ASSERT_KNOWN( false , message);\n}\n\n// TrackNewVec ---------------------------------------------------------------\n# ifdef NDEBUG\ntemplate <class Type>\nType *TrackNewVec(\n   const char *file, int line, size_t len, Type * /* oldptr */ )\n{\n# if CPPAD_TRACK_DEBUG\n   static bool first = true;\n   if( first )\n   {  std::cout << \"NDEBUG is defined for TrackNewVec\" << std::endl;\n      first = false;\n   }\n# endif\n   return (new Type[len]);\n}\n\n# else\n\ntemplate <class Type>\nType *TrackNewVec(\n   const char *file          ,\n   int         line          ,\n   size_t      len           ,\n   Type       * /* oldptr */ )\n{\n   CPPAD_ASSERT_KNOWN(\n      ! thread_alloc::in_parallel() ,\n      \"attempt to use TrackNewVec in parallel execution mode.\"\n   );\n   // try to allocate the new memrory\n   Type *newptr = nullptr;\n   try\n   {  newptr = new Type[len];\n   }\n   catch(...)\n   {  TrackError(\"TrackNewVec\", file, line,\n         \"Cannot allocate sufficient memory\"\n      );\n   }\n   // create tracking element\n   void *vptr = static_cast<void *>(newptr);\n   TrackElement *E = new TrackElement(file, line, vptr);\n\n   // get the root\n   TrackElement *root = TrackElement::Root();\n\n   // put this element at the front of linked list\n   E->next    = root->next;\n   root->next = E;\n\n# if CPPAD_TRACK_DEBUG\n   std::cout << \"TrackNewVec: \";\n   TrackElement::Print(E);\n# endif\n\n   return newptr;\n}\n\n# endif\n\n// TrackDelVec --------------------------------------------------------------\n# ifdef NDEBUG\ntemplate <class Type>\nvoid TrackDelVec(const char *file, int line, Type *oldptr)\n{\n# if CPPAD_TRACK_DEBUG\n   static bool first = true;\n   if( first )\n   {  std::cout << \"NDEBUG is defined in TrackDelVec\" << std::endl;\n      first = false;\n   }\n# endif\n     delete [] oldptr;\n}\n\n# else\n\ntemplate <class Type>\nvoid TrackDelVec(\n   const char *file    ,\n   int         line    ,\n   Type       *oldptr  )\n{\n   CPPAD_ASSERT_KNOWN(\n      ! thread_alloc::in_parallel() ,\n      \"attempt to use TrackDelVec in parallel execution mode.\"\n   );\n   TrackElement        *P;\n   TrackElement        *E;\n\n   // search list for pointer\n   P          = TrackElement::Root();\n   E          = P->next;\n   void *vptr = static_cast<void *>(oldptr);\n   while(E != nullptr && E->ptr != vptr)\n   {  P = E;\n      E = E->next;\n   }\n\n   // check if pointer was not in list\n   if( E == nullptr || E->ptr != vptr ) TrackError(\n      \"TrackDelVec\", file, line,\n      \"Invalid value for the argument oldptr.\\n\"\n      \"Possible linking of debug and NDEBUG compilations of CppAD.\"\n   );\n\n# if CPPAD_TRACK_DEBUG\n   std::cout << \"TrackDelVec: \";\n   TrackElement::Print(E);\n# endif\n\n   // remove tracking element from list\n   P->next = E->next;\n\n   // delete allocated pointer\n   delete [] oldptr;\n\n   // delete tracking element\n   delete E;\n\n   return;\n}\n\n# endif\n\n// TrackExtend --------------------------------------------------------------\ntemplate <class Type>\nType *TrackExtend(\n   const char *file    ,\n   int         line    ,\n   size_t      newlen  ,\n   size_t      ncopy   ,\n   Type       *oldptr  )\n{\n   CPPAD_ASSERT_KNOWN(\n      ! thread_alloc::in_parallel() ,\n      \"attempt to use TrackExtend in parallel execution mode.\"\n   );\n\n# if CPPAD_TRACK_DEBUG\n   using std::cout;\n   cout << \"TrackExtend: file = \" << file;\n   cout << \", line = \" << line;\n   cout << \", newlen = \" << newlen;\n   cout << \", ncopy = \" << ncopy;\n   cout << \", oldptr = \" << oldptr;\n   cout << std::endl;\n# endif\n   CPPAD_ASSERT_KNOWN(\n      ncopy <= newlen,\n      \"TrackExtend: ncopy is greater than newlen.\"\n   );\n\n   // allocate the new memrory\n   Type *newptr = TrackNewVec(file, line, newlen, oldptr);\n\n   // copy the data\n   size_t i;\n   for(i = 0; i < ncopy; i++)\n      newptr[i] = oldptr[i];\n\n   // delete the old vector\n   if( ncopy > 0 )\n      TrackDelVec(file, line, oldptr);\n\n   return newptr;\n}\n\n// TrackCount --------------------------------------------------------------\ninline size_t TrackCount(const char *file, int line)\n{\n   CPPAD_ASSERT_KNOWN(\n      ! thread_alloc::in_parallel() ,\n      \"attempt to use TrackCount in parallel execution mode.\"\n   );\n   size_t count = 0;\n   TrackElement *E = TrackElement::Root();\n   while( E->next != nullptr )\n   {  ++count;\n      E = E->next;\n   }\n   return count;\n}\n// ---------------------------------------------------------------------------\n\n} // End CppAD namespace\n\n// preprocessor symbols local to this file\n# undef CPPAD_TRACK_DEBUG\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/vector.hpp",
    "content": "# ifndef CPPAD_UTILITY_VECTOR_HPP\n# define CPPAD_UTILITY_VECTOR_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\n# include <cstddef>\n# include <iostream>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/utility/check_simple_vector.hpp>\n# include <cppad/utility/thread_alloc.hpp>\n\n// Note that CPPAD_CONST is undefined by cppad_vector_itr.hpp\n# define CPPAD_CONST 0\n# include <cppad/local/utility/cppad_vector_itr.hpp>\n# undef  CPPAD_LOCAL_UTILITY_CPPAD_VECTOR_ITR_HPP\n# define CPPAD_CONST 1\n# include <cppad/local/utility/cppad_vector_itr.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n// ==========================================================================\ntemplate <class Type> class vector {\n// ==========================================================================\n/*\n{xrst_begin cppad_vector_member dev}\n\nVector Class: Member Data\n#########################\n\nSyntax\n******\n| *vec* . ``capacity`` ()\n| *vec* . ``size`` ()\n| *vec* . ``data`` ()\n\nType\n****\nis the type of the elements in the array.\n\ncapacity\\_\n**********\nNumber of *Type* elements in ``data_`` that have been allocated\n(and constructor has been called).\n\nlength\\_\n********\nNumber of *Type* elements currently in this vector.\n\ndata\\_\n******\nPointer to the first element of the vector\n(not defined and should not be used when ``capacity_`` is  0).\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   size_t capacity_;\n   size_t length_;\n   Type*  data_;\npublic:\n   size_t capacity(void) const noexcept\n   {  return capacity_; }\n   size_t size(void) const noexcept\n   {  return length_; }\n   const Type* data(void) const noexcept\n   {  return data_; }\n   Type* data(void) noexcept\n   {  return data_; }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cppad_vector_member}\n-----------------------------------------------------------------------------\n{xrst_begin cppad_vector_typedef dev}\n\nVector Class: Type Definitions\n##############################\n\nvalue_type\n**********\ntype corresponding to an element of a vector.\n\niterator\n********\ntype corresponding to an iterator for a vector.\n\nconst_iterator\n**************\ntype corresponding to an iterator for a vector when\nthe vector is ``const`` .\n\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   typedef Type                                         value_type;\n   typedef local::utility::cppad_vector_itr<Type>       iterator;\n   typedef local::utility::const_cppad_vector_itr<Type> const_iterator;\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cppad_vector_typedef}\n-----------------------------------------------------------------------------\n{xrst_begin cppad_vector_ctor dev}\n{xrst_spell\n   initializer\n}\n\nVector Class: Constructors and Destructor\n#########################################\n\nDefault\n*******\n\n   ``vector`` < *Type* > *vec*\n\ncreates an empty vector no elements and capacity zero.\n\nSizing\n******\n\n|  ``vector`` < *Type* > *vec* ( *n* )\n|  ``vector`` < *Type* > *vec* ( *n* , *value* )\n\nwhere *n* is a ``size_t`` , ``unsigned int`` , or ``int`` .\nThis creates the vector *vec* with *n* elements and capacity\ngreater than or equal *n* .\n\nValue\n=====\nIf *value* is present, it is a *Type* object and all of the\nelements of the vector are given this value.\n\nInitializer List\n****************\n\n   ``vector`` < *Type > *vec* ( { *e_1* , ... , *e_n* } )\n\nCopy\n****\n\n   ``vector`` < *Type* > *vec* ( *other* )\n\nwhere *other* is a ``vector`` < *Type* > ,\ncreates the vector *vec*\nwith *n* = *other* . ``size`` () elements and capacity\ngreater than or equal *n* .\n\nMove Semantics\n**************\nA move semantics version of the copy operator\nis implemented using ``swap`` .\n\nDestructor\n**********\nIf ``capacity_`` is non-zero, call the destructor\nfor all the corresponding elements and then frees the corresponding memory.\n\ndelete_data\n***********\nCall destructor and free all the allocated elements\n(there are ``capacity_`` such elements).\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   // default\n   vector(void) noexcept\n   : capacity_(0), length_(0), data_(nullptr)\n   { }\n   //\n   // sizing\n   vector(size_t n) : capacity_(0), length_(0), data_(nullptr)\n   {  resize(n); }\n# if ! CPPAD_IS_SAME_UNSIGNED_INT_SIZE_T\n   vector(unsigned int n) : capacity_(0), length_(0), data_(nullptr)\n   {  resize(n); }\n# endif\n   vector(int n) : capacity_(0), length_(0), data_(nullptr)\n   {  resize(n); }\n   //\n   // sizing with value\n   vector(size_t n, const Type& value)\n   : capacity_(0), length_(0), data_(nullptr)\n   {  resize(n);\n      for(size_t i = 0; i < length_; ++i)\n         data_[i] = value;\n   }\n# if ! CPPAD_IS_SAME_UNSIGNED_INT_SIZE_T\n   vector(unsigned int n, const Type& value)\n   : capacity_(0), length_(0), data_(nullptr)\n   {  resize(n);\n      for(size_t i = 0; i < length_; ++i)\n         data_[i] = value;\n   }\n# endif\n   vector(int n, const Type& value)\n   : capacity_(0), length_(0), data_(nullptr)\n   {  resize(n);\n      for(size_t i = 0; i < length_; ++i)\n         data_[i] = value;\n   }\n   //\n   // initializer list\n   vector(std::initializer_list<Type> list) :\n   capacity_(0), length_(0), data_(nullptr)\n   {  for(auto itr = list.begin(); itr != list.end(); ++itr)\n         this->push_back(*itr);\n   }\n   //\n   // copy\n   vector(const vector& other) : capacity_(0), length_(0), data_(nullptr)\n   {  resize(other.length_);\n      for(size_t i = 0; i < length_; i++)\n         data_[i] = other.data_[i];\n   }\n   // capacity_ is only value required to make destructor work for other\n   // after this move semantics constructor\n   vector(vector&& other) : capacity_(0), length_(0), data_(nullptr)\n   {  swap(other); }\n   ~vector(void)\n   {  if( capacity_ > 0 ) delete_data(data_); }\nprivate:\n   void delete_data(Type* data_ptr)\n   {  thread_alloc::delete_array(data_ptr); }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cppad_vector_ctor}\n-----------------------------------------------------------------------------\n{xrst_begin cppad_vector_size dev}\n\nVector Class: Change Size\n#########################\n\nSyntax\n******\n\n| |tab|  *vec* . ``resize`` ( *n* )\n| |tab| *vec* . ``clear`` ()\n\nn\n*\nis a ``size_t`` , ``unsigned int`` , or ``int`` specifying\nthe number of elements in the new version of the vector.\n\nresize\n******\nIf *n* is less than or equal the input value of\n*vec* . ``capacity_`` ,\nthe only change is that *vec* . ``length_`` is set to *n* .\nOtherwise, new memory is allocated for the vector and\n*vec* . ``length_`` elements are copied from the old vector\nto the new one. I you do not need the old elements, you can first resize\nto zero and then the *n* to avoid copying the elements.\n\nclear\n*****\nThe destructor is called for all the elements of *vec*\nand then *vec.length_* and *vec* . ``capacity_`` are set to zero.\n\n{xrst_end cppad_vector_size}\n------------------------------------------------------------------------------\n*/\npublic:\n# if ! CPPAD_IS_SAME_UNSIGNED_INT_SIZE_T\n   void resize(unsigned int n)\n   {  resize( size_t(n) ); }\n# endif\n   void resize(int n)\n   {  CPPAD_ASSERT_KNOWN(\n         n >= 0,\n         \"CppAD::vector: attempt to create a vector with a negative size.\"\n      );\n      resize( size_t(n) );\n   }\n   void resize(size_t n)\n   {  if( capacity_ < n )\n      {  if( capacity_ == 0 )\n         {  // get new memory and set capacity\n            data_ = thread_alloc::create_array<Type>(n, capacity_);\n         }\n         else\n         {  // save old information\n            Type*  old_data     = data_;\n\n            // get new memory and set capacity\n            data_ = thread_alloc::create_array<Type>(n, capacity_);\n\n            // copy old data\n            for(size_t i = 0; i < length_; ++i)\n               data_[i] = old_data[i];\n\n            // free old memory\n            thread_alloc::delete_array(old_data);\n         }\n      }\n      length_ = n;\n   }\n   void clear(void)\n   {  length_ = 0;\n      // check if there is old memory to be freed\n      if( capacity_ > 0 )\n         delete_data(data_);\n      capacity_ = 0;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin cppad_vector_assign dev}\n\nVector Class: Assignment Operators\n##################################\n\nSyntax\n******\n\n   *vec* . ``swap`` ( *other* )\n\n*vec* = *other*\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_SWAP\n   // END_SWAP\n}\n{xrst_literal\n   // BEGIN_MOVE_ASSIGN\n   // END_MOVE_ASSIGN\n}\n{xrst_literal\n   // BEGIN_ASSIGN\n   // END_ASSIGN\n}\n\nswap\n****\nSwaps ``length_`` , ``capacity_`` and ``data_``\nbetween *vec* and *other* .\n\nAssignment\n**********\nsee :ref:`user API assignment<CppAD_vector@Assignment>`\n\nMove Semantics\n**************\nThe move semantics version of the assignment operator\nis implemented using ``swap`` .\n\n{xrst_end cppad_vector_assign}\n-------------------------------------------------------------------------------\n*/\n// BEGIN_SWAP\npublic:\n   // swap does not do any allocation and hence is declared noexcept\n   void swap(vector& other) noexcept\n// END_SWAP\n   {  // special case where vec and other are the same vector\n       if( this == &other )\n         return;\n      //\n      std::swap(length_,   other.length_   );\n      std::swap(capacity_, other.capacity_ );\n      std::swap(data_,     other.data_     );\n      return;\n   }\n\n// BEGIN_MOVE_ASSIGN\n   // move assignment does not doe any allocation and hence is declared noexcept\n   vector& operator=(vector&& other) noexcept\n// END_MOVE_ASSIGN\n   {  swap(other);\n      return *this;\n   }\n\n// BEGIN_ASSIGN\n   vector& operator=(const vector& other)\n// END_ASSIGN\n   {  // avoid copying old elements\n      resize(0);\n      // new size for this vector\n      resize( other.length_ );\n      // copy elements from other\n      for(size_t i = 0; i < length_; i++)\n         data_[i] = other.data_[i];\n      return *this;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin cppad_vector_compare dev}\n{xrst_spell\n}\n\nVector Class: Comparison Operators\n##################################\n\nSyntax\n******\n\n|  *result* = *vec* *op* *other*\n\nwhere *op* is one of the following: == , != , < , <= , > , >= .\n\nPrototype\n*********\n{xrst_literal ,\n   // BEGIN_EQUAL, // END_EQUAL\n   // BEGIN_NOT_EQUAL, // END_NOT_EQUAL\n   // BEGIN_LESS_THAN, // END_LESS_THAN\n   // BEGIN_LESS_OR_EQUAL, // END_LESS_OR_EQUAL\n   // BEGIN_GREATER_THAN, // END_GREATER_THAN\n   // BEGIN_GREATER_OR_EQUAL, // END_GREATER_OR_EQUAL\n}\n\nvec\n***\nis the left side for the comparison operation.\n\nother\n*****\nis the right side for the comparison operation.\nThis vector must have the same size as *vec* .\n\nresult\n******\nThe *result* is true if the comparison\n\n|  *vec* [ *i* ] *op* *other [ *i* ]\n\ntrue for all valid indices *i* .  Otherwise, the *result* is false\n\n{xrst_end cppad_vector_compare}\n-------------------------------------------------------------------------------\n*/\n// BEGIN_EQUAL\npublic:\n   bool operator==(const vector& other) const\n// END_EQUAL\n   {  bool result = true;\n      CPPAD_ASSERT_KNOWN(\n         length_ == other.length_ ,\n         \"CppAD::vector: vec == other: size of vectors is different\"\n      );\n      for(size_t i = 0; i < length_; ++i)\n         result &= data_[i] == other.data_[i];\n      return result;\n   }\n// BEGIN_NOT_EQUAL\n   bool operator!=(const vector& other) const\n// END_NOT_EQUAL\n   {  bool result = true;\n      CPPAD_ASSERT_KNOWN(\n         length_ == other.length_ ,\n         \"CppAD::vector: vec == other: size of vectors is different\"\n      );\n      for(size_t i = 0; i < length_; ++i)\n         result &= data_[i] != other.data_[i];\n      return result;\n   }\n// BEGIN_LESS_THAN\n   bool operator<(const vector& other) const\n// END_LESS_THAN\n   {  bool result = true;\n      CPPAD_ASSERT_KNOWN(\n         length_ == other.length_ ,\n         \"CppAD::vector: vec == other: size of vectors is different\"\n      );\n      for(size_t i = 0; i < length_; ++i)\n         result &= data_[i] < other.data_[i];\n      return result;\n   }\n// BEGIN_LESS_OR_EQUAL\n   bool operator<=(const vector& other) const\n// END_LESS_OR_EQUAL\n   {  bool result = true;\n      CPPAD_ASSERT_KNOWN(\n         length_ == other.length_ ,\n         \"CppAD::vector: vec == other: size of vectors is different\"\n      );\n      for(size_t i = 0; i < length_; ++i)\n         result &= data_[i] <= other.data_[i];\n      return result;\n   }\n// BEGIN_GREATER_THAN\n   bool operator>(const vector& other) const\n// END_GREATER_THAN\n   {  bool result = true;\n      CPPAD_ASSERT_KNOWN(\n         length_ == other.length_ ,\n         \"CppAD::vector: vec == other: size of vectors is different\"\n      );\n      for(size_t i = 0; i < length_; ++i)\n         result &= data_[i] > other.data_[i];\n      return result;\n   }\n// BEGIN_GREATER_OR_EQUAL\n   bool operator>=(const vector& other) const\n// END_GREATER_OR_EQUAL\n   {  bool result = true;\n      CPPAD_ASSERT_KNOWN(\n         length_ == other.length_ ,\n         \"CppAD::vector: vec == other: size of vectors is different\"\n      );\n      for(size_t i = 0; i < length_; ++i)\n         result &= data_[i] >= other.data_[i];\n      return result;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin cppad_vector_subscript dev}\n\nVector Class: Subscript Operator\n################################\n\nSyntax\n******\n\n| *element* = *vec* [ *i* ]\n| *vec* [ *i* ] = *element*\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\n   const Type& operator[]( size_t i) const\n   {  CPPAD_ASSERT_KNOWN( i < length_,\n         \"vector: index greater than or equal vector size\"\n      );\n      return data_[i];\n   }\n   Type& operator[](size_t i)\n   {  CPPAD_ASSERT_KNOWN(i < length_,\n         \"vector: index greater than or equal vector size\"\n      );\n      return data_[i];\n   }\n   template <class Index> const Type& operator[]( Index i) const\n   {  return (*this)[size_t(i)]; }\n   template <class Index> Type& operator[](Index i)\n   {  return (*this)[size_t(i)]; }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cppad_vector_subscript}\n-------------------------------------------------------------------------------\n{xrst_begin cppad_vector_push_back dev}\n\nVector Class: push_back\n#######################\n\nSyntax\n******\n*vec* . ``push_back`` ( *element* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PUSH_BACK\n   // END_PUSH_BACK\n}\n\nDocumentation\n*************\nsee :ref:`use API push_back<cppad_vector_push_back-name>`\n\n{xrst_end cppad_vector_push_back}\n*/\n// BEGIN_PUSH_BACK\n   void push_back(const Type& element)\n// END_PUSH_BACK\n   {  // case where no allocation is necessary\n      if( length_ < capacity_ )\n      {  data_[length_++] = element;\n         return;\n      }\n      CPPAD_ASSERT_UNKNOWN( length_ == capacity_ );\n\n      // create new vector with required size\n      vector vec(length_ + 1);\n\n      // copy old data values\n      for(size_t i = 0; i < length_; ++i)\n         vec.data_[i] = data_[i];\n\n      // put the new element in the new vector\n      CPPAD_ASSERT_UNKNOWN( vec.length_ == length_ + 1);\n      vec.data_[length_] = element;\n\n      // swap old and new vectors\n      swap(vec);\n   }\n/* %$$\n-------------------------------------------------------------------------------\n{xrst_begin cppad_vector_push_vector dev}\n\nVector Class: push_vector\n#########################\n\nSyntax\n******\n*vec* . ``push_vector`` ( *other* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PUSH_VECTOR\n   // END_PUSH_VECTOR\n}\n\nDocumentation\n*************\nsee :ref:`use API push_vector<cppad_vector_push_vector-name>`\n\n{xrst_end cppad_vector_push_vector}\n*/\n// BEGIN_PUSH_VECTOR\n   template <class Vector> void push_vector(const Vector& other)\n// END_PUSH_VECTOR\n   {  // can not use push_back because MS V++ 7.1 did not resolve\n      // to non-template member function when scalar is used.\n      //\n      CheckSimpleVector<Type, Vector>();\n      size_t m = other.size();\n\n      // case where no allocation is necessary\n      if( length_ + m <= capacity_ )\n      {  for(size_t i = 0; i < m; i++)\n            data_[length_++] = other[i];\n         return;\n      }\n\n      // create new vector with required size\n      vector vec(length_ + m);\n\n      // copy old data values\n      for(size_t i = 0; i < length_; ++i)\n         vec.data_[i] = data_[i];\n\n      // put the new elements in the new vector\n      CPPAD_ASSERT_UNKNOWN( vec.length_ == length_ + m );\n      for(size_t i = 0; i < m; i++)\n         vec.data_[length_ + i] = other[i];\n\n      // swap old and new vectors\n      swap(vec);\n   }\n/*\n------------------------------------------------------------------------------\n{xrst_begin cppad_vector_itr_fun dev}\n\nVector Class: Iterator Functions\n################################\n\nSyntax\n******\n\n| ``os`` *vec* . ``begin`` ()\n| *os* ``vec`` . *end* ()\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\n   const_iterator begin(void) const noexcept\n   {    return const_iterator(&data_, &length_, 0); }\n   const_iterator end(void) const noexcept\n   {  typedef typename const_iterator::difference_type difference_type;\n      difference_type index = static_cast<difference_type>(length_);\n      return const_iterator(&data_, &length_, index);\n   }\n   //\n   iterator begin(void) noexcept\n   {    return iterator(&data_, &length_, 0); }\n   iterator end(void) noexcept\n   {  typedef typename iterator::difference_type difference_type;\n      difference_type index = static_cast<difference_type>(length_);\n      return iterator(&data_, &length_, index);\n   }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cppad_vector_itr_fun}\n*/\n\n// =========================================================================\n};  // END_TEMPLATE_CLASS_VECTOR\n// =========================================================================\n\n/*\n{xrst_begin cppad_vector_output dev}\n\nVector Class: Output\n####################\n\nSyntax\n******\n*os* << ``vec``\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\ntemplate <class Type>\nstd::ostream& operator << (std::ostream&  os , const CppAD::vector<Type>& vec )\n{  os << \"{ \";\n   for(size_t i = 0; i < vec.size(); ++i)\n   {  os << vec[i];\n      if( i + 1 < vec.size() )\n         os << \", \";\n   }\n   os << \" }\";\n   return os;\n}\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end cppad_vector_output}\n*/\n\n} // END_CPPAD_NAMESPACE\n\n// user API specifies that vector_bool.hpp is included by vector.hpp\n# include <cppad/utility/vector_bool.hpp>\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility/vector_bool.hpp",
    "content": "# ifndef CPPAD_UTILITY_VECTOR_BOOL_HPP\n# define CPPAD_UTILITY_VECTOR_BOOL_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n\n# include <cstddef>\n# include <iostream>\n# include <limits>\n# include <cppad/core/cppad_assert.hpp>\n# include <cppad/utility/check_simple_vector.hpp>\n# include <cppad/utility/thread_alloc.hpp>\n# include <cppad/local/utility/vector_bool.hpp>\n\nnamespace CppAD { // BEGIN_CPPAD_NAMESPACE\n\n// ============================================================================\nclass vectorBool {\n// ============================================================================\n/*\n{xrst_begin vector_bool_member dev}\n\nvectorBool: Member Data\n#######################\n\nSyntax\n******\n| *vec* . ``unit_min`` ()\n| *vec* . ``bit_per_unit`` ()\n\nunit_t\n******\nType used to pack multiple boolean (bit) values into one unit.\nLogical operations are preformed one unit at a time.\n\nbit_per_unit\\_\n**************\nnumber of bits packed into each unit value in ``data_`` .\n\nn_unit\\_\n********\nNumber of unit values in ``data_`` .\n\nlength\\_\n********\nnumber of bits currently stored in this vector.\n\ndata\\_\n******\npointer to where the bits are stored.\n\nunit_min\n********\nminimum number of ``unit_t`` values that can store ``length_`` bits.\nNote that this is really a function of ``length_`` .\n\nsize\n****\nis the number of boolean elements in the vector.\n\ncapacity\n********\nis the maximum number of boolean elements that will fit in the\ncurrent allocation for ``data_`` .\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\nprivate:\n   typedef size_t unit_t;\n   static const size_t bit_per_unit_ = std::numeric_limits<unit_t>::digits;\n   size_t    n_unit_;\n   size_t    length_;\n   unit_t    *data_;\n   //\n   size_t unit_min(void) const\n   {  if( length_ == 0 )\n         return 0;\n      return (length_ - 1) / bit_per_unit_ + 1;\n   }\npublic:\n   static size_t bit_per_unit(void)\n   {  return bit_per_unit_; }\n   size_t size(void) const\n   {  return length_; }\n   size_t capacity(void) const\n   {  return n_unit_ * bit_per_unit_; }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end vector_bool_member}\n-------------------------------------------------------------------------------\n{xrst_begin vector_bool_typedef dev}\n\nvectorBool Type Definitions\n###########################\n\nvalue_type\n**********\ntype corresponding to the elements of this vector\n(note that non-const elements actually use\n:ref:`vectorBoolElement<vector_bool_element-name>` ).\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\npublic:\n   typedef bool value_type;\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end vector_bool_typedef}\n----------------------------------------------------------------------------\n{xrst_begin vector_bool_ctor dev}\n{xrst_spell\n   initializer\n}\nvectorBool: Constructors and Destructor\n#######################################\n\nDefault\n*******\n\n   ``vectorBool`` *vec*\n\ncreates an empty vector with no elements and ``n_unit_`` zero.\n\nSizing\n******\n\n   ``vectorBool`` *vec* ( *n* )\n\nwhere *n* is a ``size_t`` ,\ncreates the vector *vec* with *n* elements and ``n_unit_``\ngreater than or equal ``unit_min()`` .\n\nInitializer\n***********\n\n   ``vectorBool`` *vec* ( { *b_1* , ... , *b_n* } )\n\n\nCopy\n****\n\n   ``vector`` < *Type* > *vec* ( *other* )\n\nwhere *other* is a ``vector`` < *Type* > ,\ncreates the vector *vec*\nwith *n* = *other* . ``size`` () elements and ``n_unit_``\ngreater than or equal ``unit_min()`` .\n\nDestructor\n**********\nIf ``n_unit_`` is non-zero, the memory corresponding to ``data_``\nis returned to thread_alloc.\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp}:\n*/\n   // default\n   vectorBool(void) : n_unit_(0), length_(0), data_(nullptr)\n   { }\n   //\n   // sizing\n   vectorBool(size_t n) : n_unit_(0), length_(0), data_(nullptr)\n   {  resize(n); }\n   vectorBool(int n) : n_unit_(0), length_(0), data_(nullptr)\n   {  resize( size_t(n) ); }\n# if ! CPPAD_IS_SAME_UNSIGNED_INT_SIZE_T\n   vectorBool(unsigned int n) : n_unit_(0), length_(0), data_(nullptr)\n   {  resize( size_t(n) ); }\n# endif\n   //\n   // copy\n   vectorBool(const vectorBool& other)\n   : n_unit_(0), length_(0), data_(nullptr)\n   {  resize(other.length_);\n      size_t n_used = unit_min();\n      CPPAD_ASSERT_UNKNOWN( n_used <= n_unit_ );\n      for(size_t i = 0; i < n_used; ++i)\n         data_[i] = other.data_[i];\n   }\n   vectorBool(std::initializer_list<bool> list)\n   : n_unit_(0), length_(0), data_(nullptr)\n   {  for(auto itr = list.begin(); itr != list.end(); ++itr)\n         this->push_back(*itr);\n   }\n   // n_unit_ is the only value necessary to make destructor work\n   // for other after this move semantics constructor\n   vectorBool(vectorBool&& other)\n   : n_unit_(0), length_(0), data_(nullptr)\n   {  swap(other); }\n   ~vectorBool(void)\n   {  clear(); }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end vector_bool_ctor}\n-----------------------------------------------------------------------------\n{xrst_begin vector_bool_size dev}\n\nvectorBool: Change Size\n#######################\n\nSyntax\n******\n\n| |tab| *vec* . ``resize`` ( *n* )\n| |tab| *vec* . ``clear`` ()\n\nn\n*\nis a ``size_t`` or ``int`` specifying\nthe number of elements in the new version of the vector.\n\nresize\n******\nIf *n* is less than or equal the input value of\n*vec* . ``n_unit_`` times *vec* . ``bit_per_unit_`` ,\nthe only change is that *vec* . ``length_`` is set to *n* .\nOtherwise the old elements are freed and a new vector is created\nwith *vec* . ``length_`` equal to *n* .\n\nclear\n*****\nthe memory allocated for this vector is freed and\n*vec.length_* and *vec* . ``n_unit_`` are set to zero.\n\n{xrst_end vector_bool_size}\n------------------------------------------------------------------------------\n*/\n// BEGIN_RESIZE\npublic:\n# if ! CPPAD_IS_SAME_UNSIGNED_INT_SIZE_T\n   void resize(unsigned int n)\n   {  resize( size_t(n) );\n   }\n# endif\n   void resize(int n)\n   {  CPPAD_ASSERT_KNOWN(\n         n >= 0,\n         \"CppAD::vector: attempt to create a vector with a negative size.\"\n      );\n      resize( size_t(n) );\n   }\n   void resize(size_t n)\n// END_RESIZE\n   {  length_ = n;\n      // check if we can use the current memory\n      size_t min_unit = unit_min();\n      if( n_unit_ >= min_unit )\n         return;\n      // check if there is old memory to be freed\n      if( n_unit_ > 0 )\n      {  void* v_ptr = reinterpret_cast<void*>(data_);\n         thread_alloc::return_memory(v_ptr);\n      }\n      // get new memory and set n_unit\n      size_t min_bytes = min_unit * sizeof(unit_t);\n      size_t cap_bytes;\n      void* v_ptr = thread_alloc::get_memory(min_bytes, cap_bytes);\n      data_       = reinterpret_cast<unit_t*>(v_ptr);\n      n_unit_     = cap_bytes / sizeof(unit_t);\n      CPPAD_ASSERT_UNKNOWN( n_unit_ >= min_unit );\n   }\n// BEGIN_CLEAR\n   void clear(void)\n// END_CLEAR\n   {\n      // check if there is old memory to be freed\n      if( n_unit_ > 0 )\n      {  void* v_ptr = reinterpret_cast<void*>(data_);\n         thread_alloc::return_memory(v_ptr);\n      }\n      length_ = 0;\n      n_unit_ = 0;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin vector_bool_assign dev}\n\nvectorBool: Assignment Operators\n################################\n\nSyntax\n******\n\n| |tab| *vec* . ``swap`` ( *other* )\n| |tab| *vec* = *other*\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_SWAP\n   // END_SWAP\n}\n{xrst_literal\n   // BEGIN_ASSIGN\n   // END_ASSIGN\n}\n{xrst_literal\n   // BEGIN_MOVE_SEMANTICS\n   // END_MOVE_SEMANTICS\n}\n\nswap\n****\nSwaps ``n_unit_`` , ``length_`` and ``data_``\nbetween *vec* and *other* .\n\nAssignment\n**********\nIf the input value of *vec* . ``length_`` is zero,\n:ref:`vector_bool_size@resize` is used to change its size to\nbe the same as other.\nThe size of *vec* and *other* are then compared and if\ndifferent, an assert with a know cause is generated.\nThe elements of *vec* are then individually assigned\nto have the value of the corresponding elements of *other* .\n\nMove Semantics\n**************\nA move semantics version of the assignment operator, implemented using\n``swap`` , is defined.\n\n{xrst_end vector_bool_assign}\n-------------------------------------------------------------------------------\n*/\n// BEGIN_SWAP\n   void swap(vectorBool& other)\n// END_SWAP\n   {  // swap with self case\n       if( this == &other )\n         return;\n      std::swap(n_unit_,   other.n_unit_   );\n      std::swap(length_,   other.length_   );\n      std::swap(data_,     other.data_     );\n      return;\n   }\n// BEGIN_ASSIGN\n   vectorBool& operator=(const vectorBool& other)\n// END_ASSIGN\n   {  // If original length is zero, then resize it to other.\n      // Otherwise a length mismatch is an error.\n      if( length_ == 0 )\n         resize( other.length_ );\n      CPPAD_ASSERT_KNOWN(\n         length_ == other.length_ ,\n         \"vectorBool: size miss match in assignment operation\"\n      );\n      size_t n_used = unit_min();\n      CPPAD_ASSERT_UNKNOWN( n_used <= n_unit_ );\n      for(size_t i = 0; i < n_used; i++)\n         data_[i] = other.data_[i];\n      return *this;\n   }\n// BEGIN_MOVE_SEMANTICS\n   vectorBool& operator=(vectorBool&& other)\n// END_MOVE_SEMANTICS\n   {  CPPAD_ASSERT_KNOWN(\n         length_ == other.length_ || (length_ == 0),\n         \"vectorBool: size miss match in assignment operation\"\n      );\n      swap(other);\n      return *this;\n   }\n/*\n-------------------------------------------------------------------------------\n{xrst_begin vector_bool_subscript dev}\n\nvectorBool: Subscript Operator\n##############################\n\nSyntax\n******\n\n| *target* = *vec* [ *i* ]\n| *vec* [ *i* ] = *source*\n\ntarget\n******\nIn this syntax *vec* is ``const``\nand the value *vec* [ *i* ] is a ``bool`` .\n\nsource\n******\nIn this syntax *vec* is not ``const``\nand the value *vec* [ *i* ] is a\n:ref:`vectorBoolElement<vector_bool_element-name>` .\n\nSource Code\n***********\n{xrst_spell_off}\n{xrst_code hpp} */\n   bool operator[](size_t i) const\n   {  CPPAD_ASSERT_KNOWN( i < length_,\n         \"vectorBool: index greater than or equal vector size\"\n      );\n      size_t unit_index   = i / bit_per_unit_;\n      size_t bit_index    = i - unit_index * bit_per_unit_;\n      unit_t unit         = data_[unit_index];\n      unit_t mask         = unit_t(1) << bit_index;\n      return (unit & mask) != 0;\n   }\n   local::utility::vectorBoolElement operator[](size_t i)\n   {  CPPAD_ASSERT_KNOWN( i < length_,\n         \"vectorBool: index greater than or equal vector size\"\n      );\n      size_t unit_index   = i / bit_per_unit_;\n      size_t bit_index    = i - unit_index * bit_per_unit_;\n      unit_t mask         = unit_t(1) << bit_index;\n      return local::utility::vectorBoolElement(data_ + unit_index , mask);\n   }\n   template <class Index> bool operator[]( Index i) const\n   {  return (*this)[size_t(i)]; }\n   template <class Index>\n   local::utility::vectorBoolElement operator[](Index i)\n   {  return (*this)[size_t(i)]; }\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end vector_bool_subscript}\n-------------------------------------------------------------------------------\n{xrst_begin vector_bool_push_back dev}\n\nvectorBool: push_back\n#####################\n\nSyntax\n******\n*vec* . ``push_back`` ( *element* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PUSH_BACK\n   // END_PUSH_BACK\n}\n\nDocumentation\n*************\nsee :ref:`use API push_back<cppad_vector_push_back-name>`\n\n{xrst_end vector_bool_push_back}\n*/\n// BEGIN_PUSH_BACK\n   void push_back(bool element)\n// END_PUSH_BACK\n   {  CPPAD_ASSERT_UNKNOWN( unit_min() <= n_unit_ );\n      size_t old_length = length_;\n      if( length_ + 1 > n_unit_ * bit_per_unit_ )\n      {  CPPAD_ASSERT_UNKNOWN( unit_min() == n_unit_ );\n\n         // create new vector with requuired size\n         vectorBool vec(length_ + 1);\n\n         // copy old data values\n         size_t n_used = unit_min();\n         CPPAD_ASSERT_UNKNOWN( n_used <= n_unit_ );\n         for(size_t i = 0; i < n_used; ++i)\n            vec.data_[i] = data_[i];\n\n         // swap old and new vectors\n         swap(vec);\n      }\n      else\n         ++length_;\n      CPPAD_ASSERT_UNKNOWN( length_ <= n_unit_ * bit_per_unit_ )\n      size_t   unit_index = old_length / bit_per_unit_;\n      size_t   bit_index  = old_length - unit_index * bit_per_unit_;\n      unit_t mask         = unit_t(1) << bit_index;\n      if( element )\n         data_[unit_index] |= mask;\n      else\n         data_[unit_index] &= ~mask;\n   }\n/* %$$\n-------------------------------------------------------------------------------\n{xrst_begin vector_bool_push_vector dev}\n\nvectorBool: push_vector\n#######################\n\nSyntax\n******\n*vec* . ``push_vector`` ( *other* )\n\nPrototype\n*********\n{xrst_literal\n   // BEGIN_PUSH_VECTOR\n   // END_PUSH_VECTOR\n}\n\nDocumentation\n*************\nsee :ref:`use API push_vector<cppad_vector_push_vector-name>`\n\n{xrst_end vector_bool_push_vector}\n*/\n// BEGIN_PUSH_VECTOR\n   template <class Vector> void push_vector(const Vector& other)\n// END_PUSH_VECTOR\n   {  CPPAD_ASSERT_UNKNOWN( unit_min() <= n_unit_ );\n      CheckSimpleVector<bool, Vector>();\n      size_t old_length = length_;\n      size_t m           = other.size();\n      if( length_ + m > n_unit_ * bit_per_unit_ )\n      {\n         // create new vector with requuired size\n         vectorBool vec(length_ + m);\n\n         // copy old data values\n         size_t n_used = unit_min();\n         CPPAD_ASSERT_UNKNOWN( n_used <= n_unit_ );\n         for(size_t i = 0; i < n_used; ++i)\n            vec.data_[i] = data_[i];\n\n         // swap old and new vectors\n         swap(vec);\n      }\n      else\n         length_ += m;\n      //\n      // put the new elements in this vector\n      CPPAD_ASSERT_UNKNOWN( length_ <= n_unit_ * bit_per_unit_ )\n      for(size_t k = 0; k < m; k++)\n      {  size_t unit_index = (old_length + k) / bit_per_unit_;\n         size_t bit_index  = (old_length + k) - unit_index * bit_per_unit_;\n         unit_t mask       = unit_t(1) << bit_index;\n         if( other[k] )\n            data_[unit_index] |= mask;\n         else\n            data_[unit_index] &= ~mask;\n      }\n   }\n};\n\n/*\n{xrst_begin vector_bool_output dev}\n\nvectorBool: Output\n##################\n\nSyntax\n******\n*os* << ``vec``\n\nSource\n******\n{xrst_spell_off}\n{xrst_code hpp} */\ninline std::ostream& operator << (std::ostream&  os , const vectorBool& vec )\n{  for(size_t i = 0; i < vec.size(); ++i)\n      os << vec[i];\n   return os;\n}\n/* {xrst_code}\n{xrst_spell_on}\n\n{xrst_end vector_bool_output}\n*/\n\n} // END_CPPAD_NAMESPACE\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/utility.hpp",
    "content": "# ifndef CPPAD_UTILITY_HPP\n# define CPPAD_UTILITY_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n// BEGIN_SORT_THIS_LINE_PLUS_1\n# include <cppad/utility/check_numeric_type.hpp>\n# include <cppad/utility/check_simple_vector.hpp>\n# include <cppad/utility/create_dll_lib.hpp>\n# include <cppad/utility/elapsed_seconds.hpp>\n# include <cppad/utility/error_handler.hpp>\n# include <cppad/utility/index_sort.hpp>\n# include <cppad/utility/link_dll_lib.hpp>\n# include <cppad/utility/lu_factor.hpp>\n# include <cppad/utility/lu_invert.hpp>\n# include <cppad/utility/lu_solve.hpp>\n# include <cppad/utility/memory_leak.hpp>\n# include <cppad/utility/nan.hpp>\n# include <cppad/utility/near_equal.hpp>\n# include <cppad/utility/ode_err_control.hpp>\n# include <cppad/utility/ode_gear.hpp>\n# include <cppad/utility/ode_gear_control.hpp>\n# include <cppad/utility/omp_alloc.hpp>\n# include <cppad/utility/poly.hpp>\n# include <cppad/utility/pow_int.hpp>\n# include <cppad/utility/romberg_mul.hpp>\n# include <cppad/utility/romberg_one.hpp>\n# include <cppad/utility/rosen_34.hpp>\n# include <cppad/utility/runge_45.hpp>\n# include <cppad/utility/set_union.hpp>\n# include <cppad/utility/sparse_rc.hpp>\n# include <cppad/utility/sparse_rcv.hpp>\n# include <cppad/utility/speed_test.hpp>\n# include <cppad/utility/test_boolofvoid.hpp>\n# include <cppad/utility/thread_alloc.hpp>\n# include <cppad/utility/time_test.hpp>\n# include <cppad/utility/to_string.hpp>\n# include <cppad/utility/track_new_del.hpp>\n# include <cppad/utility/vector.hpp>\n// END_SORT_THIS_LINE_MINUS_1\n\n# if CPPAD_HAS_EIGEN\n# include <cppad/utility/sparse2eigen.hpp>\n# endif\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/include/cppad/wno_conversion.hpp",
    "content": "# ifndef CPPAD_WNO_CONVERSION_HPP\n# define CPPAD_WNO_CONVERSION_HPP\n// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n\n/*\n{xrst_begin wno_conversion}\n\nSuppress Suspect Implicit Conversion Warnings\n#############################################\n\nSyntax\n******\n| # ``include <cppad/wno_conversion.hpp>``\n\nPurpose\n*******\nIn many cases it is good to have warnings for implicit conversions\nthat may loose range or precision.\nThe include command above, before any other includes, suppresses\nthese warning for a particular compilation unit (which usually corresponds\nto a * . ``cpp`` file).\n\n{xrst_end wno_conversion}\n*/\n\n# include <cppad/configure.hpp>\n# if CPPAD_COMPILER_HAS_CONVERSION_WARN\n# pragma GCC diagnostic ignored \"-Wfloat-conversion\"\n# pragma GCC diagnostic ignored \"-Wconversion\"\n# endif\n\n# endif\n"
  },
  {
    "path": "thirdparty/cppad/src/cpp_graph_op.cpp",
    "content": "// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-22 Bradley M. Bell\n// ----------------------------------------------------------------------------\n# include <cppad/core/cppad_assert.hpp>\n# include <utility>\n\n// documentations for this routintes are in the file below\n# include <cppad/local/graph/cpp_graph_op.hpp>\n\n// BEGIN_CPPAD_LOCAL_GRAPH_NAMESPACE\nnamespace CppAD { namespace local { namespace graph {\n\n// mapping from operator name to graph_op_enum value\nstd::map<std::string, graph_op_enum> op_name2enum;\n\n// map from operator enum to name\nconst char* op_enum2name[n_graph_op];\n\n// map from operator enum to n_arg (when fixed number of arguments)\nsize_t op_enum2fixed_n_arg[n_graph_op];\n\n// This routine is called by the first use of the cpp_graph constructor\n// see cpp_graph.hpp.\nvoid set_operator_info(void)\n{  // This routine cannot be called in parallel mode\n   CPPAD_ASSERT_UNKNOWN( ! ( CppAD::thread_alloc::in_parallel() ));\n   //\n   typedef std::pair<std::string, graph_op_enum> pair;\n   struct op_info {\n      graph_op_enum code;\n      const char*  name;\n      size_t       n_arg;\n   };\n   /*\n   If n_arg is zero in the table below, the table contains a comment as to\n   the heading in graph_op_enum.hpp below which you can find the\n   specifications for n_arg, n_result for the corresponding operator.\n   */\n   // BEGIN_SORT_THIS_LINE_PLUS_2\n   op_info op_info_vec[] = {\n      { abs_graph_op,      \"abs\",      1 }, // 1 result\n      { acos_graph_op,     \"acos\",     1 }, // 1 result\n      { acosh_graph_op,    \"acosh\",    1 }, // 1 result\n      { add_graph_op,      \"add\",      2 }, // 1 result\n      { asin_graph_op,     \"asin\",     1 }, // 1 result\n      { asinh_graph_op,    \"asinh\",    1 }, // 1 result\n      { atan_graph_op,     \"atan\",     1 }, // 1 result\n      { atanh_graph_op,    \"atanh\",    1 }, // 1 result\n      { atom4_graph_op,    \"atom4\",    0 }, // See Atomic Function\n      { atom_graph_op,     \"atom\",     0 }, // See Atomic Function\n      { azmul_graph_op,    \"azmul\",    2 }, // 1 result\n      { cexp_eq_graph_op,  \"cexp_eq\",  4 }, // 1 result\n      { cexp_le_graph_op,  \"cexp_le\",  4 }, // 1 result\n      { cexp_lt_graph_op,  \"cexp_lt\",  4 }, // 1 result\n      { comp_eq_graph_op,  \"comp_eq\",  0 }, // See Comparisons\n      { comp_le_graph_op,  \"comp_le\",  0 }, // ...\n      { comp_lt_graph_op,  \"comp_lt\",  0 }, // ...\n      { comp_ne_graph_op,  \"comp_ne\",  0 }, // ...\n      { cos_graph_op,      \"cos\",      1 }, // 1 result\n      { cosh_graph_op,     \"cosh\",     1 }, // 1 result\n      { discrete_graph_op, \"discrete\", 0 }, // See Discrete Function\n      { div_graph_op,      \"div\",      2 }, // 1 result\n      { erf_graph_op,      \"erf\",      1 }, // 1 result\n      { erfc_graph_op,     \"erfc\",     1 }, // 1 result\n      { exp_graph_op,      \"exp\",      1 }, // 1 result\n      { expm1_graph_op,    \"expm1\",    1 }, // 1 result\n      { log1p_graph_op,    \"log1p\",    1 }, // 1 result\n      { log_graph_op,      \"log\",      1 }, // 1 result\n      { mul_graph_op,      \"mul\",      2 }, // 1 result\n      { neg_graph_op,      \"neg\",      1 }, // 1 result\n      { pow_graph_op,      \"pow\",      2 }, // 1 result\n      { print_graph_op,    \"print\",    0 }, // See Print\n      { sign_graph_op,     \"sign\",     1 }, // 1 result\n      { sin_graph_op,      \"sin\",      1 }, // 1 result\n      { sinh_graph_op,     \"sinh\",     1 }, // 1 result\n      { sqrt_graph_op,     \"sqrt\",     1 }, // 1 result\n      { sub_graph_op,      \"sub\",      2 }, // 1 result\n      { sum_graph_op,      \"sum\",      0 }, // See Summation\n      { tan_graph_op,      \"tan\",      1 }, // 1 result\n      { tanh_graph_op,     \"tanh\",     1 }  // 1 result\n   };\n   // END_SORT_THIS_LINE_MINUS_2\n   CPPAD_ASSERT_UNKNOWN(\n      size_t(n_graph_op) == sizeof(op_info_vec) / sizeof(op_info_vec[0])\n   );\n   for(size_t i = 0; i < size_t(n_graph_op); ++i)\n   {  graph_op_enum code              = op_info_vec[i].code;\n      const char*  name              = op_info_vec[i].name;\n      size_t       n_arg             = op_info_vec[i].n_arg;\n      CPPAD_ASSERT_UNKNOWN( size_t(code) == i );\n      //\n      op_enum2name[code]        = name;\n      op_enum2fixed_n_arg[code] = n_arg;\n      op_name2enum.insert( pair(name, code) );\n   }\n}\n\n} } } // END_CPPAD_LOCAL_GRAPH_NAMESPACE\n"
  },
  {
    "path": "thirdparty/cppad/src/temp_file.cpp",
    "content": "// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>\n// SPDX-FileContributor: 2003-24 Bradley M. Bell\n// ----------------------------------------------------------------------------\n/*\n{xrst_begin temp_file dev}\n{xrst_spell\n   mkstemp\n}\n\nCreate a New Empty Temporary File\n#################################\n\nSyntax\n******\n| *file_name* = ``temp_file`` ()\n\nfile_name\n*********\nIs the name of a new temporary file.\nThis file did not exist when ``temp_file`` was called.\nIt has been created and is empty upon return.\n\nEmpty\n=====\nThis routine failed if the return value *file_name* is empty.\n\nThread Safe\n***********\nThis routine is thread safe when C++17 and ``mkstemp`` are available\nto CppAD.\n\n{xrst_end temp_file}\n*/\n# include <vector>\n# include <stdio.h>\n# include <cppad/configure.hpp>\n# include <cppad/local/temp_file.hpp>\n\n# if CPPAD_HAS_MKSTEMP && CPPAD_USE_CPLUSPLUS_2017\n# include <filesystem>\n# else\n# include <stdio.h>\n# endif\n\n# if _MSC_VER\n# include <io.h>\n# else\n# include <unistd.h>\n# endif\n\n# ifdef _WIN32\n# define DIR_SEP '\\\\'\n# else\n# define DIR_SEP '/'\n# endif\n\nnamespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE\n\nstd::string temp_file(void)\n# if CPPAD_HAS_MKSTEMP && CPPAD_USE_CPLUSPLUS_2017\n{  // path\n   using std::filesystem::path;\n   //\n   // tmp_dir_path\n   path tmp_dir_path = std::filesystem::temp_directory_path();\n   //\n   // tmp_dir_str\n   std::string tmp_dir_str = tmp_dir_path.string();\n   if( tmp_dir_str.back() != DIR_SEP )\n      tmp_dir_str += DIR_SEP;\n   //\n   // pattern_str\n   std::string pattern_str = tmp_dir_str;\n   pattern_str            += \"fileXXXXXX\";\n   //\n   // pattern_vec\n   std::vector<char> pattern_vec( pattern_str.size() + 1 );\n   for(size_t i = 0; i < pattern_str.size(); ++i)\n      pattern_vec[i] = pattern_str[i];\n   pattern_vec[ pattern_str.size() ] = '\\0';\n   //\n   // fd, pattrern_vec\n   int fd = mkstemp( pattern_vec.data() );\n   if( fd < 0 )\n      return \"\";\n   close(fd);\n   //\n   // file_name\n   std::string file_name = pattern_vec.data();\n   return file_name;\n}\n# else // CPPAD_HAS_MKSTEMP && CPPAD_USE_CPLUSPLUS_2017\n{\n# if CPPAD_HAS_TMPNAM_S\n   char c_str[L_tmpnam_s];\n   tmpnam_s(c_str, L_tmpnam_s );\n# else\n   char c_str[L_tmpnam];\n   tmpnam(c_str);\n# endif\n# ifdef __MINGW32__\n   // https://stackoverflow.com/questions/38868858/\n   // fopen-of-file-name-created-by-tmpnam-fails-on-mingw\n   std::string file_name = c_str + 1;\n# else\n   std::string file_name = c_str;\n# endif\n   FILE* fp = fopen(file_name.c_str(), \"r\");\n   if( fp != NULL )\n      return \"\";\n   fp = fopen(file_name.c_str(), \"w\");\n   if( fp == NULL )\n      return \"\";\n   fclose(fp);\n   return file_name;\n}\n# endif // CPPAD_HAS_MKSTEMP && CPPAD_USE_CPLUSPLUS_2017\n\n} } // END_CPPAD_LOCAL_NAMESPACE\n"
  },
  {
    "path": "thirdparty/fmt/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.8...3.26)\n\nproject(FMT CXX)\n\nfile(GLOB FMT_HEADERS include/fmt/*.h)\nset(FMT_SOURCES src/format.cc src/os.cc)\n\nadd_library(fmt STATIC)\ntarget_sources(fmt PRIVATE\n  ${FMT_HEADERS}\n  ${FMT_SOURCES}\n)\ntarget_include_directories(fmt PUBLIC include)\n"
  },
  {
    "path": "thirdparty/fmt/include/fmt/args.h",
    "content": "// Formatting library for C++ - dynamic argument lists\n//\n// Copyright (c) 2012 - present, Victor Zverovich\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\n#ifndef FMT_ARGS_H_\n#define FMT_ARGS_H_\n\n#ifndef FMT_MODULE\n#  include <functional>  // std::reference_wrapper\n#  include <memory>      // std::unique_ptr\n#  include <vector>\n#endif\n\n#include \"format.h\"  // std_string_view\n\nFMT_BEGIN_NAMESPACE\nnamespace detail {\n\ntemplate <typename T> struct is_reference_wrapper : std::false_type {};\ntemplate <typename T>\nstruct is_reference_wrapper<std::reference_wrapper<T>> : std::true_type {};\n\ntemplate <typename T> auto unwrap(const T& v) -> const T& { return v; }\ntemplate <typename T>\nauto unwrap(const std::reference_wrapper<T>& v) -> const T& {\n  return static_cast<const T&>(v);\n}\n\n// node is defined outside dynamic_arg_list to workaround a C2504 bug in MSVC\n// 2022 (v17.10.0).\n//\n// Workaround for clang's -Wweak-vtables. Unlike for regular classes, for\n// templates it doesn't complain about inability to deduce single translation\n// unit for placing vtable. So node is made a fake template.\ntemplate <typename = void> struct node {\n  virtual ~node() = default;\n  std::unique_ptr<node<>> next;\n};\n\nclass dynamic_arg_list {\n  template <typename T> struct typed_node : node<> {\n    T value;\n\n    template <typename Arg>\n    FMT_CONSTEXPR typed_node(const Arg& arg) : value(arg) {}\n\n    template <typename Char>\n    FMT_CONSTEXPR typed_node(const basic_string_view<Char>& arg)\n        : value(arg.data(), arg.size()) {}\n  };\n\n  std::unique_ptr<node<>> head_;\n\n public:\n  template <typename T, typename Arg> auto push(const Arg& arg) -> const T& {\n    auto new_node = std::unique_ptr<typed_node<T>>(new typed_node<T>(arg));\n    auto& value = new_node->value;\n    new_node->next = std::move(head_);\n    head_ = std::move(new_node);\n    return value;\n  }\n};\n}  // namespace detail\n\n/**\n * A dynamic list of formatting arguments with storage.\n *\n * It can be implicitly converted into `fmt::basic_format_args` for passing\n * into type-erased formatting functions such as `fmt::vformat`.\n */\nFMT_EXPORT template <typename Context> class dynamic_format_arg_store {\n private:\n  using char_type = typename Context::char_type;\n\n  template <typename T> struct need_copy {\n    static constexpr detail::type mapped_type =\n        detail::mapped_type_constant<T, char_type>::value;\n\n    enum {\n      value = !(detail::is_reference_wrapper<T>::value ||\n                std::is_same<T, basic_string_view<char_type>>::value ||\n                std::is_same<T, detail::std_string_view<char_type>>::value ||\n                (mapped_type != detail::type::cstring_type &&\n                 mapped_type != detail::type::string_type &&\n                 mapped_type != detail::type::custom_type))\n    };\n  };\n\n  template <typename T>\n  using stored_t = conditional_t<\n      std::is_convertible<T, std::basic_string<char_type>>::value &&\n          !detail::is_reference_wrapper<T>::value,\n      std::basic_string<char_type>, T>;\n\n  // Storage of basic_format_arg must be contiguous.\n  std::vector<basic_format_arg<Context>> data_;\n  std::vector<detail::named_arg_info<char_type>> named_info_;\n\n  // Storage of arguments not fitting into basic_format_arg must grow\n  // without relocation because items in data_ refer to it.\n  detail::dynamic_arg_list dynamic_args_;\n\n  friend class basic_format_args<Context>;\n\n  auto data() const -> const basic_format_arg<Context>* {\n    return named_info_.empty() ? data_.data() : data_.data() + 1;\n  }\n\n  template <typename T> void emplace_arg(const T& arg) {\n    data_.emplace_back(arg);\n  }\n\n  template <typename T>\n  void emplace_arg(const detail::named_arg<char_type, T>& arg) {\n    if (named_info_.empty())\n      data_.insert(data_.begin(), basic_format_arg<Context>(nullptr, 0));\n    data_.emplace_back(detail::unwrap(arg.value));\n    auto pop_one = [](std::vector<basic_format_arg<Context>>* data) {\n      data->pop_back();\n    };\n    std::unique_ptr<std::vector<basic_format_arg<Context>>, decltype(pop_one)>\n        guard{&data_, pop_one};\n    named_info_.push_back({arg.name, static_cast<int>(data_.size() - 2u)});\n    data_[0] = {named_info_.data(), named_info_.size()};\n    guard.release();\n  }\n\n public:\n  constexpr dynamic_format_arg_store() = default;\n\n  operator basic_format_args<Context>() const {\n    return basic_format_args<Context>(data(), static_cast<int>(data_.size()),\n                                      !named_info_.empty());\n  }\n\n  /**\n   * Adds an argument into the dynamic store for later passing to a formatting\n   * function.\n   *\n   * Note that custom types and string types (but not string views) are copied\n   * into the store dynamically allocating memory if necessary.\n   *\n   * **Example**:\n   *\n   *     fmt::dynamic_format_arg_store<fmt::format_context> store;\n   *     store.push_back(42);\n   *     store.push_back(\"abc\");\n   *     store.push_back(1.5f);\n   *     std::string result = fmt::vformat(\"{} and {} and {}\", store);\n   */\n  template <typename T> void push_back(const T& arg) {\n    if (detail::const_check(need_copy<T>::value))\n      emplace_arg(dynamic_args_.push<stored_t<T>>(arg));\n    else\n      emplace_arg(detail::unwrap(arg));\n  }\n\n  /**\n   * Adds a reference to the argument into the dynamic store for later passing\n   * to a formatting function.\n   *\n   * **Example**:\n   *\n   *     fmt::dynamic_format_arg_store<fmt::format_context> store;\n   *     char band[] = \"Rolling Stones\";\n   *     store.push_back(std::cref(band));\n   *     band[9] = 'c'; // Changing str affects the output.\n   *     std::string result = fmt::vformat(\"{}\", store);\n   *     // result == \"Rolling Scones\"\n   */\n  template <typename T> void push_back(std::reference_wrapper<T> arg) {\n    static_assert(\n        need_copy<T>::value,\n        \"objects of built-in types and string views are always copied\");\n    emplace_arg(arg.get());\n  }\n\n  /**\n   * Adds named argument into the dynamic store for later passing to a\n   * formatting function. `std::reference_wrapper` is supported to avoid\n   * copying of the argument. The name is always copied into the store.\n   */\n  template <typename T>\n  void push_back(const detail::named_arg<char_type, T>& arg) {\n    const char_type* arg_name =\n        dynamic_args_.push<std::basic_string<char_type>>(arg.name).c_str();\n    if (detail::const_check(need_copy<T>::value)) {\n      emplace_arg(\n          fmt::arg(arg_name, dynamic_args_.push<stored_t<T>>(arg.value)));\n    } else {\n      emplace_arg(fmt::arg(arg_name, arg.value));\n    }\n  }\n\n  /// Erase all elements from the store.\n  void clear() {\n    data_.clear();\n    named_info_.clear();\n    dynamic_args_ = {};\n  }\n\n  /// Reserves space to store at least `new_cap` arguments including\n  /// `new_cap_named` named arguments.\n  void reserve(size_t new_cap, size_t new_cap_named) {\n    FMT_ASSERT(new_cap >= new_cap_named,\n               \"set of arguments includes set of named arguments\");\n    data_.reserve(new_cap);\n    named_info_.reserve(new_cap_named);\n  }\n\n  /// Returns the number of elements in the store.\n  auto size() const noexcept -> size_t { return data_.size(); }\n};\n\nFMT_END_NAMESPACE\n\n#endif  // FMT_ARGS_H_\n"
  },
  {
    "path": "thirdparty/fmt/include/fmt/base.h",
    "content": "// Formatting library for C++ - the base API for char/UTF-8\n//\n// Copyright (c) 2012 - present, Victor Zverovich\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\n#ifndef FMT_BASE_H_\n#define FMT_BASE_H_\n\n#if defined(FMT_IMPORT_STD) && !defined(FMT_MODULE)\n#  define FMT_MODULE\n#endif\n\n#ifndef FMT_MODULE\n#  include <limits.h>  // CHAR_BIT\n#  include <stdio.h>   // FILE\n#  include <string.h>  // memcmp\n\n#  include <type_traits>  // std::enable_if\n#endif\n\n// The fmt library version in the form major * 10000 + minor * 100 + patch.\n#define FMT_VERSION 120100\n\n// Detect compiler versions.\n#if defined(__clang__) && !defined(__ibmxl__)\n#  define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)\n#else\n#  define FMT_CLANG_VERSION 0\n#endif\n#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)\n#  define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)\n#else\n#  define FMT_GCC_VERSION 0\n#endif\n#if defined(__ICL)\n#  define FMT_ICC_VERSION __ICL\n#elif defined(__INTEL_COMPILER)\n#  define FMT_ICC_VERSION __INTEL_COMPILER\n#else\n#  define FMT_ICC_VERSION 0\n#endif\n#if defined(_MSC_VER)\n#  define FMT_MSC_VERSION _MSC_VER\n#else\n#  define FMT_MSC_VERSION 0\n#endif\n\n// Detect standard library versions.\n#ifdef _GLIBCXX_RELEASE\n#  define FMT_GLIBCXX_RELEASE _GLIBCXX_RELEASE\n#else\n#  define FMT_GLIBCXX_RELEASE 0\n#endif\n#ifdef _LIBCPP_VERSION\n#  define FMT_LIBCPP_VERSION _LIBCPP_VERSION\n#else\n#  define FMT_LIBCPP_VERSION 0\n#endif\n\n#ifdef _MSVC_LANG\n#  define FMT_CPLUSPLUS _MSVC_LANG\n#else\n#  define FMT_CPLUSPLUS __cplusplus\n#endif\n\n// Detect __has_*.\n#ifdef __has_feature\n#  define FMT_HAS_FEATURE(x) __has_feature(x)\n#else\n#  define FMT_HAS_FEATURE(x) 0\n#endif\n#ifdef __has_include\n#  define FMT_HAS_INCLUDE(x) __has_include(x)\n#else\n#  define FMT_HAS_INCLUDE(x) 0\n#endif\n#ifdef __has_builtin\n#  define FMT_HAS_BUILTIN(x) __has_builtin(x)\n#else\n#  define FMT_HAS_BUILTIN(x) 0\n#endif\n#ifdef __has_cpp_attribute\n#  define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)\n#else\n#  define FMT_HAS_CPP_ATTRIBUTE(x) 0\n#endif\n\n#define FMT_HAS_CPP14_ATTRIBUTE(attribute) \\\n  (FMT_CPLUSPLUS >= 201402L && FMT_HAS_CPP_ATTRIBUTE(attribute))\n\n#define FMT_HAS_CPP17_ATTRIBUTE(attribute) \\\n  (FMT_CPLUSPLUS >= 201703L && FMT_HAS_CPP_ATTRIBUTE(attribute))\n\n// Detect C++14 relaxed constexpr.\n#ifdef FMT_USE_CONSTEXPR\n// Use the provided definition.\n#elif FMT_GCC_VERSION >= 702 && FMT_CPLUSPLUS >= 201402L\n// GCC only allows constexpr member functions in non-literal types since 7.2:\n// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66297.\n#  define FMT_USE_CONSTEXPR 1\n#elif FMT_ICC_VERSION\n#  define FMT_USE_CONSTEXPR 0  // https://github.com/fmtlib/fmt/issues/1628\n#elif FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VERSION >= 1912\n#  define FMT_USE_CONSTEXPR 1\n#else\n#  define FMT_USE_CONSTEXPR 0\n#endif\n#if FMT_USE_CONSTEXPR\n#  define FMT_CONSTEXPR constexpr\n#else\n#  define FMT_CONSTEXPR\n#endif\n\n// Detect consteval, C++20 constexpr extensions and std::is_constant_evaluated.\n#ifdef FMT_USE_CONSTEVAL\n// Use the provided definition.\n#elif !defined(__cpp_lib_is_constant_evaluated)\n#  define FMT_USE_CONSTEVAL 0\n#elif FMT_CPLUSPLUS < 201709L\n#  define FMT_USE_CONSTEVAL 0\n#elif FMT_GLIBCXX_RELEASE && FMT_GLIBCXX_RELEASE < 10\n#  define FMT_USE_CONSTEVAL 0\n#elif FMT_LIBCPP_VERSION && FMT_LIBCPP_VERSION < 10000\n#  define FMT_USE_CONSTEVAL 0\n#elif defined(__apple_build_version__) && __apple_build_version__ < 14000029L\n#  define FMT_USE_CONSTEVAL 0  // consteval is broken in Apple clang < 14.\n#elif FMT_MSC_VERSION && FMT_MSC_VERSION < 1929\n#  define FMT_USE_CONSTEVAL 0  // consteval is broken in MSVC VS2019 < 16.10.\n#elif defined(__cpp_consteval)\n#  define FMT_USE_CONSTEVAL 1\n#elif FMT_GCC_VERSION >= 1002 || FMT_CLANG_VERSION >= 1101\n#  define FMT_USE_CONSTEVAL 1\n#else\n#  define FMT_USE_CONSTEVAL 0\n#endif\n#if FMT_USE_CONSTEVAL\n#  define FMT_CONSTEVAL consteval\n#  define FMT_CONSTEXPR20 constexpr\n#else\n#  define FMT_CONSTEVAL\n#  define FMT_CONSTEXPR20\n#endif\n\n// Check if exceptions are disabled.\n#ifdef FMT_USE_EXCEPTIONS\n// Use the provided definition.\n#elif defined(__GNUC__) && !defined(__EXCEPTIONS)\n#  define FMT_USE_EXCEPTIONS 0\n#elif defined(__clang__) && !defined(__cpp_exceptions)\n#  define FMT_USE_EXCEPTIONS 0\n#elif FMT_MSC_VERSION && !_HAS_EXCEPTIONS\n#  define FMT_USE_EXCEPTIONS 0\n#else\n#  define FMT_USE_EXCEPTIONS 1\n#endif\n#if FMT_USE_EXCEPTIONS\n#  define FMT_TRY try\n#  define FMT_CATCH(x) catch (x)\n#else\n#  define FMT_TRY if (true)\n#  define FMT_CATCH(x) if (false)\n#endif\n\n#ifdef FMT_NO_UNIQUE_ADDRESS\n// Use the provided definition.\n#elif FMT_CPLUSPLUS < 202002L\n// Not supported.\n#elif FMT_HAS_CPP_ATTRIBUTE(no_unique_address)\n#  define FMT_NO_UNIQUE_ADDRESS [[no_unique_address]]\n// VS2019 v16.10 and later except clang-cl (https://reviews.llvm.org/D110485).\n#elif FMT_MSC_VERSION >= 1929 && !FMT_CLANG_VERSION\n#  define FMT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]\n#endif\n#ifndef FMT_NO_UNIQUE_ADDRESS\n#  define FMT_NO_UNIQUE_ADDRESS\n#endif\n\n#if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)\n#  define FMT_FALLTHROUGH [[fallthrough]]\n#elif defined(__clang__)\n#  define FMT_FALLTHROUGH [[clang::fallthrough]]\n#elif FMT_GCC_VERSION >= 700 && \\\n    (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520)\n#  define FMT_FALLTHROUGH [[gnu::fallthrough]]\n#else\n#  define FMT_FALLTHROUGH\n#endif\n\n// Disable [[noreturn]] on MSVC/NVCC because of bogus unreachable code warnings.\n#if FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VERSION && !defined(__NVCC__)\n#  define FMT_NORETURN [[noreturn]]\n#else\n#  define FMT_NORETURN\n#endif\n\n#ifdef FMT_NODISCARD\n// Use the provided definition.\n#elif FMT_HAS_CPP17_ATTRIBUTE(nodiscard)\n#  define FMT_NODISCARD [[nodiscard]]\n#else\n#  define FMT_NODISCARD\n#endif\n\n#if FMT_GCC_VERSION || FMT_CLANG_VERSION\n#  define FMT_VISIBILITY(value) __attribute__((visibility(value)))\n#else\n#  define FMT_VISIBILITY(value)\n#endif\n\n// Detect pragmas.\n#define FMT_PRAGMA_IMPL(x) _Pragma(#x)\n#if FMT_GCC_VERSION >= 504 && !defined(__NVCOMPILER)\n// Workaround a _Pragma bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59884\n// and an nvhpc warning: https://github.com/fmtlib/fmt/pull/2582.\n#  define FMT_PRAGMA_GCC(x) FMT_PRAGMA_IMPL(GCC x)\n#else\n#  define FMT_PRAGMA_GCC(x)\n#endif\n#if FMT_CLANG_VERSION\n#  define FMT_PRAGMA_CLANG(x) FMT_PRAGMA_IMPL(clang x)\n#else\n#  define FMT_PRAGMA_CLANG(x)\n#endif\n#if FMT_MSC_VERSION\n#  define FMT_MSC_WARNING(...) __pragma(warning(__VA_ARGS__))\n#else\n#  define FMT_MSC_WARNING(...)\n#endif\n\n// Enable minimal optimizations for more compact code in debug mode.\nFMT_PRAGMA_GCC(push_options)\n#if !defined(__OPTIMIZE__) && !defined(__CUDACC__) && !defined(FMT_MODULE)\nFMT_PRAGMA_GCC(optimize(\"Og\"))\n#  define FMT_GCC_OPTIMIZED\n#endif\nFMT_PRAGMA_CLANG(diagnostic push)\nFMT_PRAGMA_GCC(diagnostic push)\n\n#ifdef FMT_ALWAYS_INLINE\n// Use the provided definition.\n#elif FMT_GCC_VERSION || FMT_CLANG_VERSION\n#  define FMT_ALWAYS_INLINE inline __attribute__((always_inline))\n#else\n#  define FMT_ALWAYS_INLINE inline\n#endif\n// A version of FMT_ALWAYS_INLINE to prevent code bloat in debug mode.\n#if defined(NDEBUG) || defined(FMT_GCC_OPTIMIZED)\n#  define FMT_INLINE FMT_ALWAYS_INLINE\n#else\n#  define FMT_INLINE inline\n#endif\n\n#ifndef FMT_BEGIN_NAMESPACE\n#  define FMT_BEGIN_NAMESPACE \\\n    namespace fmt {           \\\n    inline namespace v12 {\n#  define FMT_END_NAMESPACE \\\n    }                       \\\n    }\n#endif\n\n#ifndef FMT_EXPORT\n#  define FMT_EXPORT\n#  define FMT_BEGIN_EXPORT\n#  define FMT_END_EXPORT\n#endif\n\n#ifdef _WIN32\n#  define FMT_WIN32 1\n#else\n#  define FMT_WIN32 0\n#endif\n\n#if !defined(FMT_HEADER_ONLY) && FMT_WIN32\n#  if defined(FMT_LIB_EXPORT)\n#    define FMT_API __declspec(dllexport)\n#  elif defined(FMT_SHARED)\n#    define FMT_API __declspec(dllimport)\n#  endif\n#elif defined(FMT_LIB_EXPORT) || defined(FMT_SHARED)\n#  define FMT_API FMT_VISIBILITY(\"default\")\n#endif\n#ifndef FMT_API\n#  define FMT_API\n#endif\n\n#ifndef FMT_OPTIMIZE_SIZE\n#  define FMT_OPTIMIZE_SIZE 0\n#endif\n\n// FMT_BUILTIN_TYPE=0 may result in smaller library size at the cost of higher\n// per-call binary size by passing built-in types through the extension API.\n#ifndef FMT_BUILTIN_TYPES\n#  define FMT_BUILTIN_TYPES 1\n#endif\n\n#define FMT_APPLY_VARIADIC(expr) \\\n  using unused = int[];          \\\n  (void)unused { 0, (expr, 0)... }\n\nFMT_BEGIN_NAMESPACE\n\n// Implementations of enable_if_t and other metafunctions for older systems.\ntemplate <bool B, typename T = void>\nusing enable_if_t = typename std::enable_if<B, T>::type;\ntemplate <bool B, typename T, typename F>\nusing conditional_t = typename std::conditional<B, T, F>::type;\ntemplate <bool B> using bool_constant = std::integral_constant<bool, B>;\ntemplate <typename T>\nusing remove_reference_t = typename std::remove_reference<T>::type;\ntemplate <typename T>\nusing remove_const_t = typename std::remove_const<T>::type;\ntemplate <typename T>\nusing remove_cvref_t = typename std::remove_cv<remove_reference_t<T>>::type;\ntemplate <typename T>\nusing make_unsigned_t = typename std::make_unsigned<T>::type;\ntemplate <typename T>\nusing underlying_t = typename std::underlying_type<T>::type;\ntemplate <typename T> using decay_t = typename std::decay<T>::type;\nusing nullptr_t = decltype(nullptr);\n\n#if (FMT_GCC_VERSION && FMT_GCC_VERSION < 500) || FMT_MSC_VERSION\n// A workaround for gcc 4.9 & MSVC v141 to make void_t work in a SFINAE context.\ntemplate <typename...> struct void_t_impl {\n  using type = void;\n};\ntemplate <typename... T> using void_t = typename void_t_impl<T...>::type;\n#else\ntemplate <typename...> using void_t = void;\n#endif\n\nstruct monostate {\n  constexpr monostate() {}\n};\n\n// An enable_if helper to be used in template parameters which results in much\n// shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed\n// to workaround a bug in MSVC 2019 (see #1140 and #1186).\n#ifdef FMT_DOC\n#  define FMT_ENABLE_IF(...)\n#else\n#  define FMT_ENABLE_IF(...) fmt::enable_if_t<(__VA_ARGS__), int> = 0\n#endif\n\ntemplate <typename T> constexpr auto min_of(T a, T b) -> T {\n  return a < b ? a : b;\n}\ntemplate <typename T> constexpr auto max_of(T a, T b) -> T {\n  return a > b ? a : b;\n}\n\nFMT_NORETURN FMT_API void assert_fail(const char* file, int line,\n                                      const char* message);\n\nnamespace detail {\n// Suppresses \"unused variable\" warnings with the method described in\n// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/.\n// (void)var does not work on many Intel compilers.\ntemplate <typename... T> FMT_CONSTEXPR void ignore_unused(const T&...) {}\n\nconstexpr auto is_constant_evaluated(bool default_value = false) noexcept\n    -> bool {\n// Workaround for incompatibility between clang 14 and libstdc++ consteval-based\n// std::is_constant_evaluated: https://github.com/fmtlib/fmt/issues/3247.\n#if FMT_CPLUSPLUS >= 202002L && FMT_GLIBCXX_RELEASE >= 12 && \\\n    (FMT_CLANG_VERSION >= 1400 && FMT_CLANG_VERSION < 1500)\n  ignore_unused(default_value);\n  return __builtin_is_constant_evaluated();\n#elif defined(__cpp_lib_is_constant_evaluated)\n  ignore_unused(default_value);\n  return std::is_constant_evaluated();\n#else\n  return default_value;\n#endif\n}\n\n// Suppresses \"conditional expression is constant\" warnings.\ntemplate <typename T> FMT_ALWAYS_INLINE constexpr auto const_check(T val) -> T {\n  return val;\n}\n\nFMT_NORETURN FMT_API void assert_fail(const char* file, int line,\n                                      const char* message);\n\n#if defined(FMT_ASSERT)\n// Use the provided definition.\n#elif defined(NDEBUG)\n// FMT_ASSERT is not empty to avoid -Wempty-body.\n#  define FMT_ASSERT(condition, message) \\\n    fmt::detail::ignore_unused((condition), (message))\n#else\n#  define FMT_ASSERT(condition, message)                                    \\\n    ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \\\n         ? (void)0                                                          \\\n         : ::fmt::assert_fail(__FILE__, __LINE__, (message)))\n#endif\n\n#ifdef FMT_USE_INT128\n// Use the provided definition.\n#elif defined(__SIZEOF_INT128__) && !defined(__NVCC__) && \\\n    !(FMT_CLANG_VERSION && FMT_MSC_VERSION)\n#  define FMT_USE_INT128 1\nusing int128_opt = __int128_t;  // An optional native 128-bit integer.\nusing uint128_opt = __uint128_t;\ninline auto map(int128_opt x) -> int128_opt { return x; }\ninline auto map(uint128_opt x) -> uint128_opt { return x; }\n#else\n#  define FMT_USE_INT128 0\n#endif\n#if !FMT_USE_INT128\nenum class int128_opt {};\nenum class uint128_opt {};\n// Reduce template instantiations.\ninline auto map(int128_opt) -> monostate { return {}; }\ninline auto map(uint128_opt) -> monostate { return {}; }\n#endif\n\n#ifdef FMT_USE_BITINT\n// Use the provided definition.\n#elif FMT_CLANG_VERSION >= 1500 && !defined(__CUDACC__)\n#  define FMT_USE_BITINT 1\n#else\n#  define FMT_USE_BITINT 0\n#endif\n\n#if FMT_USE_BITINT\nFMT_PRAGMA_CLANG(diagnostic ignored \"-Wbit-int-extension\")\ntemplate <int N> using bitint = _BitInt(N);\ntemplate <int N> using ubitint = unsigned _BitInt(N);\n#else\ntemplate <int N> struct bitint {};\ntemplate <int N> struct ubitint {};\n#endif  // FMT_USE_BITINT\n\n// Casts a nonnegative integer to unsigned.\ntemplate <typename Int>\nFMT_CONSTEXPR auto to_unsigned(Int value) -> make_unsigned_t<Int> {\n  FMT_ASSERT(std::is_unsigned<Int>::value || value >= 0, \"negative value\");\n  return static_cast<make_unsigned_t<Int>>(value);\n}\n\ntemplate <typename Char>\nusing unsigned_char = conditional_t<sizeof(Char) == 1, unsigned char, unsigned>;\n\n// A heuristic to detect std::string and std::[experimental::]string_view.\n// It is mainly used to avoid dependency on <[experimental/]string_view>.\ntemplate <typename T, typename Enable = void>\nstruct is_std_string_like : std::false_type {};\ntemplate <typename T>\nstruct is_std_string_like<T, void_t<decltype(std::declval<T>().find_first_of(\n                                 typename T::value_type(), 0))>>\n    : std::is_convertible<decltype(std::declval<T>().data()),\n                          const typename T::value_type*> {};\n\n// Check if the literal encoding is UTF-8.\nenum { is_utf8_enabled = \"\\u00A7\"[1] == '\\xA7' };\nenum { use_utf8 = !FMT_WIN32 || is_utf8_enabled };\n\n#ifndef FMT_UNICODE\n#  define FMT_UNICODE 1\n#endif\n\nstatic_assert(!FMT_UNICODE || use_utf8,\n              \"Unicode support requires compiling with /utf-8\");\n\ntemplate <typename T> constexpr auto narrow(T*) -> char* { return nullptr; }\nconstexpr FMT_ALWAYS_INLINE auto narrow(const char* s) -> const char* {\n  return s;\n}\n\ntemplate <typename Char>\nFMT_CONSTEXPR auto compare(const Char* s1, const Char* s2, size_t n) -> int {\n  if (!is_constant_evaluated() && sizeof(Char) == 1) return memcmp(s1, s2, n);\n  for (; n != 0; ++s1, ++s2, --n) {\n    if (*s1 < *s2) return -1;\n    if (*s1 > *s2) return 1;\n  }\n  return 0;\n}\n\nnamespace adl {\nusing namespace std;\n\ntemplate <typename Container>\nauto invoke_back_inserter()\n    -> decltype(back_inserter(std::declval<Container&>()));\n}  // namespace adl\n\ntemplate <typename It, typename Enable = std::true_type>\nstruct is_back_insert_iterator : std::false_type {};\n\ntemplate <typename It>\nstruct is_back_insert_iterator<\n    It, bool_constant<std::is_same<\n            decltype(adl::invoke_back_inserter<typename It::container_type>()),\n            It>::value>> : std::true_type {};\n\n// Extracts a reference to the container from *insert_iterator.\ntemplate <typename OutputIt>\ninline FMT_CONSTEXPR20 auto get_container(OutputIt it) ->\n    typename OutputIt::container_type& {\n  struct accessor : OutputIt {\n    FMT_CONSTEXPR20 accessor(OutputIt base) : OutputIt(base) {}\n    using OutputIt::container;\n  };\n  return *accessor(it).container;\n}\n}  // namespace detail\n\n// Parsing-related public API and forward declarations.\nFMT_BEGIN_EXPORT\n\n/**\n * An implementation of `std::basic_string_view` for pre-C++17. It provides a\n * subset of the API. `fmt::basic_string_view` is used for format strings even\n * if `std::basic_string_view` is available to prevent issues when a library is\n * compiled with a different `-std` option than the client code (which is not\n * recommended).\n */\ntemplate <typename Char> class basic_string_view {\n private:\n  const Char* data_;\n  size_t size_;\n\n public:\n  using value_type = Char;\n  using iterator = const Char*;\n\n  constexpr basic_string_view() noexcept : data_(nullptr), size_(0) {}\n\n  /// Constructs a string view object from a C string and a size.\n  constexpr basic_string_view(const Char* s, size_t count) noexcept\n      : data_(s), size_(count) {}\n\n  constexpr basic_string_view(nullptr_t) = delete;\n\n  /// Constructs a string view object from a C string.\n#if FMT_GCC_VERSION\n  FMT_ALWAYS_INLINE\n#endif\n  FMT_CONSTEXPR20 basic_string_view(const Char* s) : data_(s) {\n#if FMT_HAS_BUILTIN(__builtin_strlen) || FMT_GCC_VERSION || FMT_CLANG_VERSION\n    if (std::is_same<Char, char>::value && !detail::is_constant_evaluated()) {\n      size_ = __builtin_strlen(detail::narrow(s));  // strlen is not constexpr.\n      return;\n    }\n#endif\n    size_t len = 0;\n    while (*s++) ++len;\n    size_ = len;\n  }\n\n  /// Constructs a string view from a `std::basic_string` or a\n  /// `std::basic_string_view` object.\n  template <typename S,\n            FMT_ENABLE_IF(detail::is_std_string_like<S>::value&& std::is_same<\n                          typename S::value_type, Char>::value)>\n  FMT_CONSTEXPR basic_string_view(const S& s) noexcept\n      : data_(s.data()), size_(s.size()) {}\n\n  /// Returns a pointer to the string data.\n  constexpr auto data() const noexcept -> const Char* { return data_; }\n\n  /// Returns the string size.\n  constexpr auto size() const noexcept -> size_t { return size_; }\n\n  constexpr auto begin() const noexcept -> iterator { return data_; }\n  constexpr auto end() const noexcept -> iterator { return data_ + size_; }\n\n  constexpr auto operator[](size_t pos) const noexcept -> const Char& {\n    return data_[pos];\n  }\n\n  FMT_CONSTEXPR void remove_prefix(size_t n) noexcept {\n    data_ += n;\n    size_ -= n;\n  }\n\n  FMT_CONSTEXPR auto starts_with(basic_string_view<Char> sv) const noexcept\n      -> bool {\n    return size_ >= sv.size_ && detail::compare(data_, sv.data_, sv.size_) == 0;\n  }\n  FMT_CONSTEXPR auto starts_with(Char c) const noexcept -> bool {\n    return size_ >= 1 && *data_ == c;\n  }\n  FMT_CONSTEXPR auto starts_with(const Char* s) const -> bool {\n    return starts_with(basic_string_view<Char>(s));\n  }\n\n  FMT_CONSTEXPR auto compare(basic_string_view other) const -> int {\n    int result =\n        detail::compare(data_, other.data_, min_of(size_, other.size_));\n    if (result != 0) return result;\n    return size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);\n  }\n\n  FMT_CONSTEXPR friend auto operator==(basic_string_view lhs,\n                                       basic_string_view rhs) -> bool {\n    return lhs.compare(rhs) == 0;\n  }\n  friend auto operator!=(basic_string_view lhs, basic_string_view rhs) -> bool {\n    return lhs.compare(rhs) != 0;\n  }\n  friend auto operator<(basic_string_view lhs, basic_string_view rhs) -> bool {\n    return lhs.compare(rhs) < 0;\n  }\n  friend auto operator<=(basic_string_view lhs, basic_string_view rhs) -> bool {\n    return lhs.compare(rhs) <= 0;\n  }\n  friend auto operator>(basic_string_view lhs, basic_string_view rhs) -> bool {\n    return lhs.compare(rhs) > 0;\n  }\n  friend auto operator>=(basic_string_view lhs, basic_string_view rhs) -> bool {\n    return lhs.compare(rhs) >= 0;\n  }\n};\n\nusing string_view = basic_string_view<char>;\n\ntemplate <typename T> class basic_appender;\nusing appender = basic_appender<char>;\n\n// Checks whether T is a container with contiguous storage.\ntemplate <typename T> struct is_contiguous : std::false_type {};\n\nclass context;\ntemplate <typename OutputIt, typename Char> class generic_context;\ntemplate <typename Char> class parse_context;\n\n// Longer aliases for C++20 compatibility.\ntemplate <typename Char> using basic_format_parse_context = parse_context<Char>;\nusing format_parse_context = parse_context<char>;\ntemplate <typename OutputIt, typename Char>\nusing basic_format_context =\n    conditional_t<std::is_same<OutputIt, appender>::value, context,\n                  generic_context<OutputIt, Char>>;\nusing format_context = context;\n\ntemplate <typename Char>\nusing buffered_context =\n    conditional_t<std::is_same<Char, char>::value, context,\n                  generic_context<basic_appender<Char>, Char>>;\n\ntemplate <typename Context> class basic_format_arg;\ntemplate <typename Context> class basic_format_args;\n\n// A separate type would result in shorter symbols but break ABI compatibility\n// between clang and gcc on ARM (#1919).\nusing format_args = basic_format_args<context>;\n\n// A formatter for objects of type T.\ntemplate <typename T, typename Char = char, typename Enable = void>\nstruct formatter {\n  // A deleted default constructor indicates a disabled formatter.\n  formatter() = delete;\n};\n\n/// Reports a format error at compile time or, via a `format_error` exception,\n/// at runtime.\n// This function is intentionally not constexpr to give a compile-time error.\nFMT_NORETURN FMT_API void report_error(const char* message);\n\nenum class presentation_type : unsigned char {\n  // Common specifiers:\n  none = 0,\n  debug = 1,   // '?'\n  string = 2,  // 's' (string, bool)\n\n  // Integral, bool and character specifiers:\n  dec = 3,  // 'd'\n  hex,      // 'x' or 'X'\n  oct,      // 'o'\n  bin,      // 'b' or 'B'\n  chr,      // 'c'\n\n  // String and pointer specifiers:\n  pointer = 3,  // 'p'\n\n  // Floating-point specifiers:\n  exp = 1,  // 'e' or 'E' (1 since there is no FP debug presentation)\n  fixed,    // 'f' or 'F'\n  general,  // 'g' or 'G'\n  hexfloat  // 'a' or 'A'\n};\n\nenum class align { none, left, right, center, numeric };\nenum class sign { none, minus, plus, space };\nenum class arg_id_kind { none, index, name };\n\n// Basic format specifiers for built-in and string types.\nclass basic_specs {\n private:\n  // Data is arranged as follows:\n  //\n  //  0                   1                   2                   3\n  //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1\n  // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n  // |type |align| w | p | s |u|#|L|  f  |          unused           |\n  // +-----+-----+---+---+---+-+-+-+-----+---------------------------+\n  //\n  //   w - dynamic width info\n  //   p - dynamic precision info\n  //   s - sign\n  //   u - uppercase (e.g. 'X' for 'x')\n  //   # - alternate form ('#')\n  //   L - localized\n  //   f - fill size\n  //\n  // Bitfields are not used because of compiler bugs such as gcc bug 61414.\n  enum : unsigned {\n    type_mask = 0x00007,\n    align_mask = 0x00038,\n    width_mask = 0x000C0,\n    precision_mask = 0x00300,\n    sign_mask = 0x00C00,\n    uppercase_mask = 0x01000,\n    alternate_mask = 0x02000,\n    localized_mask = 0x04000,\n    fill_size_mask = 0x38000,\n\n    align_shift = 3,\n    width_shift = 6,\n    precision_shift = 8,\n    sign_shift = 10,\n    fill_size_shift = 15,\n\n    max_fill_size = 4\n  };\n\n  unsigned data_ = 1 << fill_size_shift;\n  static_assert(sizeof(basic_specs::data_) * CHAR_BIT >= 18, \"\");\n\n  // Character (code unit) type is erased to prevent template bloat.\n  char fill_data_[max_fill_size] = {' '};\n\n  FMT_CONSTEXPR void set_fill_size(size_t size) {\n    data_ = (data_ & ~fill_size_mask) |\n            (static_cast<unsigned>(size) << fill_size_shift);\n  }\n\n public:\n  constexpr auto type() const -> presentation_type {\n    return static_cast<presentation_type>(data_ & type_mask);\n  }\n  FMT_CONSTEXPR void set_type(presentation_type t) {\n    data_ = (data_ & ~type_mask) | static_cast<unsigned>(t);\n  }\n\n  constexpr auto align() const -> align {\n    return static_cast<fmt::align>((data_ & align_mask) >> align_shift);\n  }\n  FMT_CONSTEXPR void set_align(fmt::align a) {\n    data_ = (data_ & ~align_mask) | (static_cast<unsigned>(a) << align_shift);\n  }\n\n  constexpr auto dynamic_width() const -> arg_id_kind {\n    return static_cast<arg_id_kind>((data_ & width_mask) >> width_shift);\n  }\n  FMT_CONSTEXPR void set_dynamic_width(arg_id_kind w) {\n    data_ = (data_ & ~width_mask) | (static_cast<unsigned>(w) << width_shift);\n  }\n\n  FMT_CONSTEXPR auto dynamic_precision() const -> arg_id_kind {\n    return static_cast<arg_id_kind>((data_ & precision_mask) >>\n                                    precision_shift);\n  }\n  FMT_CONSTEXPR void set_dynamic_precision(arg_id_kind p) {\n    data_ = (data_ & ~precision_mask) |\n            (static_cast<unsigned>(p) << precision_shift);\n  }\n\n  constexpr auto dynamic() const -> bool {\n    return (data_ & (width_mask | precision_mask)) != 0;\n  }\n\n  constexpr auto sign() const -> sign {\n    return static_cast<fmt::sign>((data_ & sign_mask) >> sign_shift);\n  }\n  FMT_CONSTEXPR void set_sign(fmt::sign s) {\n    data_ = (data_ & ~sign_mask) | (static_cast<unsigned>(s) << sign_shift);\n  }\n\n  constexpr auto upper() const -> bool { return (data_ & uppercase_mask) != 0; }\n  FMT_CONSTEXPR void set_upper() { data_ |= uppercase_mask; }\n\n  constexpr auto alt() const -> bool { return (data_ & alternate_mask) != 0; }\n  FMT_CONSTEXPR void set_alt() { data_ |= alternate_mask; }\n  FMT_CONSTEXPR void clear_alt() { data_ &= ~alternate_mask; }\n\n  constexpr auto localized() const -> bool {\n    return (data_ & localized_mask) != 0;\n  }\n  FMT_CONSTEXPR void set_localized() { data_ |= localized_mask; }\n\n  constexpr auto fill_size() const -> size_t {\n    return (data_ & fill_size_mask) >> fill_size_shift;\n  }\n\n  template <typename Char, FMT_ENABLE_IF(std::is_same<Char, char>::value)>\n  constexpr auto fill() const -> const Char* {\n    return fill_data_;\n  }\n  template <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>\n  constexpr auto fill() const -> const Char* {\n    return nullptr;\n  }\n\n  template <typename Char> constexpr auto fill_unit() const -> Char {\n    using uchar = unsigned char;\n    return static_cast<Char>(static_cast<uchar>(fill_data_[0]) |\n                             (static_cast<uchar>(fill_data_[1]) << 8) |\n                             (static_cast<uchar>(fill_data_[2]) << 16));\n  }\n\n  FMT_CONSTEXPR void set_fill(char c) {\n    fill_data_[0] = c;\n    set_fill_size(1);\n  }\n\n  template <typename Char>\n  FMT_CONSTEXPR void set_fill(basic_string_view<Char> s) {\n    auto size = s.size();\n    set_fill_size(size);\n    if (size == 1) {\n      unsigned uchar = static_cast<detail::unsigned_char<Char>>(s[0]);\n      fill_data_[0] = static_cast<char>(uchar);\n      fill_data_[1] = static_cast<char>(uchar >> 8);\n      fill_data_[2] = static_cast<char>(uchar >> 16);\n      return;\n    }\n    FMT_ASSERT(size <= max_fill_size, \"invalid fill\");\n    for (size_t i = 0; i < size; ++i)\n      fill_data_[i & 3] = static_cast<char>(s[i]);\n  }\n\n  FMT_CONSTEXPR void copy_fill_from(const basic_specs& specs) {\n    set_fill_size(specs.fill_size());\n    for (size_t i = 0; i < max_fill_size; ++i)\n      fill_data_[i] = specs.fill_data_[i];\n  }\n};\n\n// Format specifiers for built-in and string types.\nstruct format_specs : basic_specs {\n  int width;\n  int precision;\n\n  constexpr format_specs() : width(0), precision(-1) {}\n};\n\n/**\n * Parsing context consisting of a format string range being parsed and an\n * argument counter for automatic indexing.\n */\ntemplate <typename Char = char> class parse_context {\n private:\n  basic_string_view<Char> fmt_;\n  int next_arg_id_;\n\n  enum { use_constexpr_cast = !FMT_GCC_VERSION || FMT_GCC_VERSION >= 1200 };\n\n  FMT_CONSTEXPR void do_check_arg_id(int arg_id);\n\n public:\n  using char_type = Char;\n  using iterator = const Char*;\n\n  constexpr explicit parse_context(basic_string_view<Char> fmt,\n                                   int next_arg_id = 0)\n      : fmt_(fmt), next_arg_id_(next_arg_id) {}\n\n  /// Returns an iterator to the beginning of the format string range being\n  /// parsed.\n  constexpr auto begin() const noexcept -> iterator { return fmt_.begin(); }\n\n  /// Returns an iterator past the end of the format string range being parsed.\n  constexpr auto end() const noexcept -> iterator { return fmt_.end(); }\n\n  /// Advances the begin iterator to `it`.\n  FMT_CONSTEXPR void advance_to(iterator it) {\n    fmt_.remove_prefix(detail::to_unsigned(it - begin()));\n  }\n\n  /// Reports an error if using the manual argument indexing; otherwise returns\n  /// the next argument index and switches to the automatic indexing.\n  FMT_CONSTEXPR auto next_arg_id() -> int {\n    if (next_arg_id_ < 0) {\n      report_error(\"cannot switch from manual to automatic argument indexing\");\n      return 0;\n    }\n    int id = next_arg_id_++;\n    do_check_arg_id(id);\n    return id;\n  }\n\n  /// Reports an error if using the automatic argument indexing; otherwise\n  /// switches to the manual indexing.\n  FMT_CONSTEXPR void check_arg_id(int id) {\n    if (next_arg_id_ > 0) {\n      report_error(\"cannot switch from automatic to manual argument indexing\");\n      return;\n    }\n    next_arg_id_ = -1;\n    do_check_arg_id(id);\n  }\n  FMT_CONSTEXPR void check_arg_id(basic_string_view<Char>) {\n    next_arg_id_ = -1;\n  }\n  FMT_CONSTEXPR void check_dynamic_spec(int arg_id);\n};\n\n#ifndef FMT_USE_LOCALE\n#  define FMT_USE_LOCALE (FMT_OPTIMIZE_SIZE <= 1)\n#endif\n\n// A type-erased reference to std::locale to avoid the heavy <locale> include.\nclass locale_ref {\n#if FMT_USE_LOCALE\n private:\n  const void* locale_;  // A type-erased pointer to std::locale.\n\n public:\n  constexpr locale_ref() : locale_(nullptr) {}\n\n  template <typename Locale, FMT_ENABLE_IF(sizeof(Locale::collate) != 0)>\n  locale_ref(const Locale& loc) : locale_(&loc) {\n    // Check if std::isalpha is found via ADL to reduce the chance of misuse.\n    isalpha('x', loc);\n  }\n\n  inline explicit operator bool() const noexcept { return locale_ != nullptr; }\n#endif  // FMT_USE_LOCALE\n\n public:\n  template <typename Locale> auto get() const -> Locale;\n};\n\nFMT_END_EXPORT\n\nnamespace detail {\n\n// Specifies if `T` is a code unit type.\ntemplate <typename T> struct is_code_unit : std::false_type {};\ntemplate <> struct is_code_unit<char> : std::true_type {};\ntemplate <> struct is_code_unit<wchar_t> : std::true_type {};\ntemplate <> struct is_code_unit<char16_t> : std::true_type {};\ntemplate <> struct is_code_unit<char32_t> : std::true_type {};\n#ifdef __cpp_char8_t\ntemplate <> struct is_code_unit<char8_t> : bool_constant<is_utf8_enabled> {};\n#endif\n\n// Constructs fmt::basic_string_view<Char> from types implicitly convertible\n// to it, deducing Char. Explicitly convertible types such as the ones returned\n// from FMT_STRING are intentionally excluded.\ntemplate <typename Char, FMT_ENABLE_IF(is_code_unit<Char>::value)>\nconstexpr auto to_string_view(const Char* s) -> basic_string_view<Char> {\n  return s;\n}\ntemplate <typename T, FMT_ENABLE_IF(is_std_string_like<T>::value)>\nconstexpr auto to_string_view(const T& s)\n    -> basic_string_view<typename T::value_type> {\n  return s;\n}\ntemplate <typename Char>\nconstexpr auto to_string_view(basic_string_view<Char> s)\n    -> basic_string_view<Char> {\n  return s;\n}\n\ntemplate <typename T, typename Enable = void>\nstruct has_to_string_view : std::false_type {};\n// detail:: is intentional since to_string_view is not an extension point.\ntemplate <typename T>\nstruct has_to_string_view<\n    T, void_t<decltype(detail::to_string_view(std::declval<T>()))>>\n    : std::true_type {};\n\n/// String's character (code unit) type. detail:: is intentional to prevent ADL.\ntemplate <typename S,\n          typename V = decltype(detail::to_string_view(std::declval<S>()))>\nusing char_t = typename V::value_type;\n\nenum class type {\n  none_type,\n  // Integer types should go first,\n  int_type,\n  uint_type,\n  long_long_type,\n  ulong_long_type,\n  int128_type,\n  uint128_type,\n  bool_type,\n  char_type,\n  last_integer_type = char_type,\n  // followed by floating-point types.\n  float_type,\n  double_type,\n  long_double_type,\n  last_numeric_type = long_double_type,\n  cstring_type,\n  string_type,\n  pointer_type,\n  custom_type\n};\n\n// Maps core type T to the corresponding type enum constant.\ntemplate <typename T, typename Char>\nstruct type_constant : std::integral_constant<type, type::custom_type> {};\n\n#define FMT_TYPE_CONSTANT(Type, constant) \\\n  template <typename Char>                \\\n  struct type_constant<Type, Char>        \\\n      : std::integral_constant<type, type::constant> {}\n\nFMT_TYPE_CONSTANT(int, int_type);\nFMT_TYPE_CONSTANT(unsigned, uint_type);\nFMT_TYPE_CONSTANT(long long, long_long_type);\nFMT_TYPE_CONSTANT(unsigned long long, ulong_long_type);\nFMT_TYPE_CONSTANT(int128_opt, int128_type);\nFMT_TYPE_CONSTANT(uint128_opt, uint128_type);\nFMT_TYPE_CONSTANT(bool, bool_type);\nFMT_TYPE_CONSTANT(Char, char_type);\nFMT_TYPE_CONSTANT(float, float_type);\nFMT_TYPE_CONSTANT(double, double_type);\nFMT_TYPE_CONSTANT(long double, long_double_type);\nFMT_TYPE_CONSTANT(const Char*, cstring_type);\nFMT_TYPE_CONSTANT(basic_string_view<Char>, string_type);\nFMT_TYPE_CONSTANT(const void*, pointer_type);\n\nconstexpr auto is_integral_type(type t) -> bool {\n  return t > type::none_type && t <= type::last_integer_type;\n}\nconstexpr auto is_arithmetic_type(type t) -> bool {\n  return t > type::none_type && t <= type::last_numeric_type;\n}\n\nconstexpr auto set(type rhs) -> int { return 1 << static_cast<int>(rhs); }\nconstexpr auto in(type t, int set) -> bool {\n  return ((set >> static_cast<int>(t)) & 1) != 0;\n}\n\n// Bitsets of types.\nenum {\n  sint_set =\n      set(type::int_type) | set(type::long_long_type) | set(type::int128_type),\n  uint_set = set(type::uint_type) | set(type::ulong_long_type) |\n             set(type::uint128_type),\n  bool_set = set(type::bool_type),\n  char_set = set(type::char_type),\n  float_set = set(type::float_type) | set(type::double_type) |\n              set(type::long_double_type),\n  string_set = set(type::string_type),\n  cstring_set = set(type::cstring_type),\n  pointer_set = set(type::pointer_type)\n};\n\nstruct view {};\n\ntemplate <typename T, typename Enable = std::true_type>\nstruct is_view : std::false_type {};\ntemplate <typename T>\nstruct is_view<T, bool_constant<sizeof(T) != 0>> : std::is_base_of<view, T> {};\n\ntemplate <typename Char, typename T> struct named_arg;\ntemplate <typename T> struct is_named_arg : std::false_type {};\ntemplate <typename T> struct is_static_named_arg : std::false_type {};\n\ntemplate <typename Char, typename T>\nstruct is_named_arg<named_arg<Char, T>> : std::true_type {};\n\ntemplate <typename Char, typename T> struct named_arg : view {\n  const Char* name;\n  const T& value;\n\n  named_arg(const Char* n, const T& v) : name(n), value(v) {}\n  static_assert(!is_named_arg<T>::value, \"nested named arguments\");\n};\n\ntemplate <bool B = false> constexpr auto count() -> int { return B ? 1 : 0; }\ntemplate <bool B1, bool B2, bool... Tail> constexpr auto count() -> int {\n  return (B1 ? 1 : 0) + count<B2, Tail...>();\n}\n\ntemplate <typename... T> constexpr auto count_named_args() -> int {\n  return count<is_named_arg<T>::value...>();\n}\ntemplate <typename... T> constexpr auto count_static_named_args() -> int {\n  return count<is_static_named_arg<T>::value...>();\n}\n\ntemplate <typename Char> struct named_arg_info {\n  const Char* name;\n  int id;\n};\n\n// named_args is non-const to suppress a bogus -Wmaybe-uninitialized in gcc 13.\ntemplate <typename Char>\nFMT_CONSTEXPR void check_for_duplicate(named_arg_info<Char>* named_args,\n                                       int named_arg_index,\n                                       basic_string_view<Char> arg_name) {\n  for (int i = 0; i < named_arg_index; ++i) {\n    if (named_args[i].name == arg_name) report_error(\"duplicate named arg\");\n  }\n}\n\ntemplate <typename Char, typename T, FMT_ENABLE_IF(!is_named_arg<T>::value)>\nvoid init_named_arg(named_arg_info<Char>*, int& arg_index, int&, const T&) {\n  ++arg_index;\n}\ntemplate <typename Char, typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>\nvoid init_named_arg(named_arg_info<Char>* named_args, int& arg_index,\n                    int& named_arg_index, const T& arg) {\n  check_for_duplicate<Char>(named_args, named_arg_index, arg.name);\n  named_args[named_arg_index++] = {arg.name, arg_index++};\n}\n\ntemplate <typename T, typename Char,\n          FMT_ENABLE_IF(!is_static_named_arg<T>::value)>\nFMT_CONSTEXPR void init_static_named_arg(named_arg_info<Char>*, int& arg_index,\n                                         int&) {\n  ++arg_index;\n}\ntemplate <typename T, typename Char,\n          FMT_ENABLE_IF(is_static_named_arg<T>::value)>\nFMT_CONSTEXPR void init_static_named_arg(named_arg_info<Char>* named_args,\n                                         int& arg_index, int& named_arg_index) {\n  check_for_duplicate<Char>(named_args, named_arg_index, T::name);\n  named_args[named_arg_index++] = {T::name, arg_index++};\n}\n\n// To minimize the number of types we need to deal with, long is translated\n// either to int or to long long depending on its size.\nenum { long_short = sizeof(long) == sizeof(int) && FMT_BUILTIN_TYPES };\nusing long_type = conditional_t<long_short, int, long long>;\nusing ulong_type = conditional_t<long_short, unsigned, unsigned long long>;\n\ntemplate <typename T>\nusing format_as_result =\n    remove_cvref_t<decltype(format_as(std::declval<const T&>()))>;\ntemplate <typename T>\nusing format_as_member_result =\n    remove_cvref_t<decltype(formatter<T>::format_as(std::declval<const T&>()))>;\n\ntemplate <typename T, typename Enable = std::true_type>\nstruct use_format_as : std::false_type {};\n// format_as member is only used to avoid injection into the std namespace.\ntemplate <typename T, typename Enable = std::true_type>\nstruct use_format_as_member : std::false_type {};\n\n// Only map owning types because mapping views can be unsafe.\ntemplate <typename T>\nstruct use_format_as<\n    T, bool_constant<std::is_arithmetic<format_as_result<T>>::value>>\n    : std::true_type {};\ntemplate <typename T>\nstruct use_format_as_member<\n    T, bool_constant<std::is_arithmetic<format_as_member_result<T>>::value>>\n    : std::true_type {};\n\ntemplate <typename T, typename U = remove_const_t<T>>\nusing use_formatter =\n    bool_constant<(std::is_class<T>::value || std::is_enum<T>::value ||\n                   std::is_union<T>::value || std::is_array<T>::value) &&\n                  !has_to_string_view<T>::value && !is_named_arg<T>::value &&\n                  !use_format_as<T>::value && !use_format_as_member<U>::value>;\n\ntemplate <typename Char, typename T, typename U = remove_const_t<T>>\nauto has_formatter_impl(T* p, buffered_context<Char>* ctx = nullptr)\n    -> decltype(formatter<U, Char>().format(*p, *ctx), std::true_type());\ntemplate <typename Char> auto has_formatter_impl(...) -> std::false_type;\n\n// T can be const-qualified to check if it is const-formattable.\ntemplate <typename T, typename Char> constexpr auto has_formatter() -> bool {\n  return decltype(has_formatter_impl<Char>(static_cast<T*>(nullptr)))::value;\n}\n\n// Maps formatting argument types to natively supported types or user-defined\n// types with formatters. Returns void on errors to be SFINAE-friendly.\ntemplate <typename Char> struct type_mapper {\n  static auto map(signed char) -> int;\n  static auto map(unsigned char) -> unsigned;\n  static auto map(short) -> int;\n  static auto map(unsigned short) -> unsigned;\n  static auto map(int) -> int;\n  static auto map(unsigned) -> unsigned;\n  static auto map(long) -> long_type;\n  static auto map(unsigned long) -> ulong_type;\n  static auto map(long long) -> long long;\n  static auto map(unsigned long long) -> unsigned long long;\n  static auto map(int128_opt) -> int128_opt;\n  static auto map(uint128_opt) -> uint128_opt;\n  static auto map(bool) -> bool;\n\n  template <int N>\n  static auto map(bitint<N>) -> conditional_t<N <= 64, long long, void>;\n  template <int N>\n  static auto map(ubitint<N>)\n      -> conditional_t<N <= 64, unsigned long long, void>;\n\n  template <typename T, FMT_ENABLE_IF(is_code_unit<T>::value)>\n  static auto map(T) -> conditional_t<\n      std::is_same<T, char>::value || std::is_same<T, Char>::value, Char, void>;\n\n  static auto map(float) -> float;\n  static auto map(double) -> double;\n  static auto map(long double) -> long double;\n\n  static auto map(Char*) -> const Char*;\n  static auto map(const Char*) -> const Char*;\n  template <typename T, typename C = char_t<T>,\n            FMT_ENABLE_IF(!std::is_pointer<T>::value)>\n  static auto map(const T&) -> conditional_t<std::is_same<C, Char>::value,\n                                             basic_string_view<C>, void>;\n\n  static auto map(void*) -> const void*;\n  static auto map(const void*) -> const void*;\n  static auto map(volatile void*) -> const void*;\n  static auto map(const volatile void*) -> const void*;\n  static auto map(nullptr_t) -> const void*;\n  template <typename T, FMT_ENABLE_IF(std::is_pointer<T>::value ||\n                                      std::is_member_pointer<T>::value)>\n  static auto map(const T&) -> void;\n\n  template <typename T, FMT_ENABLE_IF(use_format_as<T>::value)>\n  static auto map(const T& x) -> decltype(map(format_as(x)));\n  template <typename T, FMT_ENABLE_IF(use_format_as_member<T>::value)>\n  static auto map(const T& x) -> decltype(map(formatter<T>::format_as(x)));\n\n  template <typename T, FMT_ENABLE_IF(use_formatter<T>::value)>\n  static auto map(T&) -> conditional_t<has_formatter<T, Char>(), T&, void>;\n\n  template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>\n  static auto map(const T& named_arg) -> decltype(map(named_arg.value));\n};\n\n// detail:: is used to workaround a bug in MSVC 2017.\ntemplate <typename T, typename Char>\nusing mapped_t = decltype(detail::type_mapper<Char>::map(std::declval<T&>()));\n\n// A type constant after applying type_mapper.\ntemplate <typename T, typename Char = char>\nusing mapped_type_constant = type_constant<mapped_t<T, Char>, Char>;\n\ntemplate <typename T, typename Context,\n          type TYPE =\n              mapped_type_constant<T, typename Context::char_type>::value>\nusing stored_type_constant = std::integral_constant<\n    type, Context::builtin_types || TYPE == type::int_type ? TYPE\n                                                           : type::custom_type>;\n// A parse context with extra data used only in compile-time checks.\ntemplate <typename Char>\nclass compile_parse_context : public parse_context<Char> {\n private:\n  int num_args_;\n  const type* types_;\n  using base = parse_context<Char>;\n\n public:\n  FMT_CONSTEXPR explicit compile_parse_context(basic_string_view<Char> fmt,\n                                               int num_args, const type* types,\n                                               int next_arg_id = 0)\n      : base(fmt, next_arg_id), num_args_(num_args), types_(types) {}\n\n  constexpr auto num_args() const -> int { return num_args_; }\n  constexpr auto arg_type(int id) const -> type { return types_[id]; }\n\n  FMT_CONSTEXPR auto next_arg_id() -> int {\n    int id = base::next_arg_id();\n    if (id >= num_args_) report_error(\"argument not found\");\n    return id;\n  }\n\n  FMT_CONSTEXPR void check_arg_id(int id) {\n    base::check_arg_id(id);\n    if (id >= num_args_) report_error(\"argument not found\");\n  }\n  using base::check_arg_id;\n\n  FMT_CONSTEXPR void check_dynamic_spec(int arg_id) {\n    ignore_unused(arg_id);\n    if (arg_id < num_args_ && types_ && !is_integral_type(types_[arg_id]))\n      report_error(\"width/precision is not integer\");\n  }\n};\n\n// An argument reference.\ntemplate <typename Char> union arg_ref {\n  FMT_CONSTEXPR arg_ref(int idx = 0) : index(idx) {}\n  FMT_CONSTEXPR arg_ref(basic_string_view<Char> n) : name(n) {}\n\n  int index;\n  basic_string_view<Char> name;\n};\n\n// Format specifiers with width and precision resolved at formatting rather\n// than parsing time to allow reusing the same parsed specifiers with\n// different sets of arguments (precompilation of format strings).\ntemplate <typename Char = char> struct dynamic_format_specs : format_specs {\n  arg_ref<Char> width_ref;\n  arg_ref<Char> precision_ref;\n};\n\n// Converts a character to ASCII. Returns '\\0' on conversion failure.\ntemplate <typename Char, FMT_ENABLE_IF(std::is_integral<Char>::value)>\nconstexpr auto to_ascii(Char c) -> char {\n  return c <= 0xff ? static_cast<char>(c) : '\\0';\n}\n\n// Returns the number of code units in a code point or 1 on error.\ntemplate <typename Char>\nFMT_CONSTEXPR auto code_point_length(const Char* begin) -> int {\n  if (const_check(sizeof(Char) != 1)) return 1;\n  auto c = static_cast<unsigned char>(*begin);\n  return static_cast<int>((0x3a55000000000000ull >> (2 * (c >> 3))) & 3) + 1;\n}\n\n// Parses the range [begin, end) as an unsigned integer. This function assumes\n// that the range is non-empty and the first character is a digit.\ntemplate <typename Char>\nFMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end,\n                                         int error_value) noexcept -> int {\n  FMT_ASSERT(begin != end && '0' <= *begin && *begin <= '9', \"\");\n  unsigned value = 0, prev = 0;\n  auto p = begin;\n  do {\n    prev = value;\n    value = value * 10 + unsigned(*p - '0');\n    ++p;\n  } while (p != end && '0' <= *p && *p <= '9');\n  auto num_digits = p - begin;\n  begin = p;\n  int digits10 = static_cast<int>(sizeof(int) * CHAR_BIT * 3 / 10);\n  if (num_digits <= digits10) return static_cast<int>(value);\n  // Check for overflow.\n  unsigned max = INT_MAX;\n  return num_digits == digits10 + 1 &&\n                 prev * 10ull + unsigned(p[-1] - '0') <= max\n             ? static_cast<int>(value)\n             : error_value;\n}\n\nFMT_CONSTEXPR inline auto parse_align(char c) -> align {\n  switch (c) {\n  case '<': return align::left;\n  case '>': return align::right;\n  case '^': return align::center;\n  }\n  return align::none;\n}\n\ntemplate <typename Char> constexpr auto is_name_start(Char c) -> bool {\n  return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '_';\n}\n\ntemplate <typename Char, typename Handler>\nFMT_CONSTEXPR auto parse_arg_id(const Char* begin, const Char* end,\n                                Handler&& handler) -> const Char* {\n  Char c = *begin;\n  if (c >= '0' && c <= '9') {\n    int index = 0;\n    if (c != '0')\n      index = parse_nonnegative_int(begin, end, INT_MAX);\n    else\n      ++begin;\n    if (begin == end || (*begin != '}' && *begin != ':'))\n      report_error(\"invalid format string\");\n    else\n      handler.on_index(index);\n    return begin;\n  }\n  if (FMT_OPTIMIZE_SIZE > 1 || !is_name_start(c)) {\n    report_error(\"invalid format string\");\n    return begin;\n  }\n  auto it = begin;\n  do {\n    ++it;\n  } while (it != end && (is_name_start(*it) || ('0' <= *it && *it <= '9')));\n  handler.on_name({begin, to_unsigned(it - begin)});\n  return it;\n}\n\ntemplate <typename Char> struct dynamic_spec_handler {\n  parse_context<Char>& ctx;\n  arg_ref<Char>& ref;\n  arg_id_kind& kind;\n\n  FMT_CONSTEXPR void on_index(int id) {\n    ref = id;\n    kind = arg_id_kind::index;\n    ctx.check_arg_id(id);\n    ctx.check_dynamic_spec(id);\n  }\n  FMT_CONSTEXPR void on_name(basic_string_view<Char> id) {\n    ref = id;\n    kind = arg_id_kind::name;\n    ctx.check_arg_id(id);\n  }\n};\n\ntemplate <typename Char> struct parse_dynamic_spec_result {\n  const Char* end;\n  arg_id_kind kind;\n};\n\n// Parses integer | \"{\" [arg_id] \"}\".\ntemplate <typename Char>\nFMT_CONSTEXPR auto parse_dynamic_spec(const Char* begin, const Char* end,\n                                      int& value, arg_ref<Char>& ref,\n                                      parse_context<Char>& ctx)\n    -> parse_dynamic_spec_result<Char> {\n  FMT_ASSERT(begin != end, \"\");\n  auto kind = arg_id_kind::none;\n  if ('0' <= *begin && *begin <= '9') {\n    int val = parse_nonnegative_int(begin, end, -1);\n    if (val == -1) report_error(\"number is too big\");\n    value = val;\n  } else {\n    if (*begin == '{') {\n      ++begin;\n      if (begin != end) {\n        Char c = *begin;\n        if (c == '}' || c == ':') {\n          int id = ctx.next_arg_id();\n          ref = id;\n          kind = arg_id_kind::index;\n          ctx.check_dynamic_spec(id);\n        } else {\n          begin = parse_arg_id(begin, end,\n                               dynamic_spec_handler<Char>{ctx, ref, kind});\n        }\n      }\n      if (begin != end && *begin == '}') return {++begin, kind};\n    }\n    report_error(\"invalid format string\");\n  }\n  return {begin, kind};\n}\n\ntemplate <typename Char>\nFMT_CONSTEXPR auto parse_width(const Char* begin, const Char* end,\n                               format_specs& specs, arg_ref<Char>& width_ref,\n                               parse_context<Char>& ctx) -> const Char* {\n  auto result = parse_dynamic_spec(begin, end, specs.width, width_ref, ctx);\n  specs.set_dynamic_width(result.kind);\n  return result.end;\n}\n\ntemplate <typename Char>\nFMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end,\n                                   format_specs& specs,\n                                   arg_ref<Char>& precision_ref,\n                                   parse_context<Char>& ctx) -> const Char* {\n  ++begin;\n  if (begin == end) {\n    report_error(\"invalid precision\");\n    return begin;\n  }\n  auto result =\n      parse_dynamic_spec(begin, end, specs.precision, precision_ref, ctx);\n  specs.set_dynamic_precision(result.kind);\n  return result.end;\n}\n\nenum class state { start, align, sign, hash, zero, width, precision, locale };\n\n// Parses standard format specifiers.\ntemplate <typename Char>\nFMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end,\n                                      dynamic_format_specs<Char>& specs,\n                                      parse_context<Char>& ctx, type arg_type)\n    -> const Char* {\n  auto c = '\\0';\n  if (end - begin > 1) {\n    auto next = to_ascii(begin[1]);\n    c = parse_align(next) == align::none ? to_ascii(*begin) : '\\0';\n  } else {\n    if (begin == end) return begin;\n    c = to_ascii(*begin);\n  }\n\n  struct {\n    state current_state = state::start;\n    FMT_CONSTEXPR void operator()(state s, bool valid = true) {\n      if (current_state >= s || !valid)\n        report_error(\"invalid format specifier\");\n      current_state = s;\n    }\n  } enter_state;\n\n  using pres = presentation_type;\n  constexpr auto integral_set = sint_set | uint_set | bool_set | char_set;\n  struct {\n    const Char*& begin;\n    format_specs& specs;\n    type arg_type;\n\n    FMT_CONSTEXPR auto operator()(pres pres_type, int set) -> const Char* {\n      if (!in(arg_type, set)) report_error(\"invalid format specifier\");\n      specs.set_type(pres_type);\n      return begin + 1;\n    }\n  } parse_presentation_type{begin, specs, arg_type};\n\n  for (;;) {\n    switch (c) {\n    case '<':\n    case '>':\n    case '^':\n      enter_state(state::align);\n      specs.set_align(parse_align(c));\n      ++begin;\n      break;\n    case '+':\n    case ' ':\n      specs.set_sign(c == ' ' ? sign::space : sign::plus);\n      FMT_FALLTHROUGH;\n    case '-':\n      enter_state(state::sign, in(arg_type, sint_set | float_set));\n      ++begin;\n      break;\n    case '#':\n      enter_state(state::hash, is_arithmetic_type(arg_type));\n      specs.set_alt();\n      ++begin;\n      break;\n    case '0':\n      enter_state(state::zero);\n      if (!is_arithmetic_type(arg_type))\n        report_error(\"format specifier requires numeric argument\");\n      if (specs.align() == align::none) {\n        // Ignore 0 if align is specified for compatibility with std::format.\n        specs.set_align(align::numeric);\n        specs.set_fill('0');\n      }\n      ++begin;\n      break;\n      // clang-format off\n    case '1': case '2': case '3': case '4': case '5':\n    case '6': case '7': case '8': case '9': case '{':\n      // clang-format on\n      enter_state(state::width);\n      begin = parse_width(begin, end, specs, specs.width_ref, ctx);\n      break;\n    case '.':\n      enter_state(state::precision,\n                  in(arg_type, float_set | string_set | cstring_set));\n      begin = parse_precision(begin, end, specs, specs.precision_ref, ctx);\n      break;\n    case 'L':\n      enter_state(state::locale, is_arithmetic_type(arg_type));\n      specs.set_localized();\n      ++begin;\n      break;\n    case 'd': return parse_presentation_type(pres::dec, integral_set);\n    case 'X': specs.set_upper(); FMT_FALLTHROUGH;\n    case 'x': return parse_presentation_type(pres::hex, integral_set);\n    case 'o': return parse_presentation_type(pres::oct, integral_set);\n    case 'B': specs.set_upper(); FMT_FALLTHROUGH;\n    case 'b': return parse_presentation_type(pres::bin, integral_set);\n    case 'E': specs.set_upper(); FMT_FALLTHROUGH;\n    case 'e': return parse_presentation_type(pres::exp, float_set);\n    case 'F': specs.set_upper(); FMT_FALLTHROUGH;\n    case 'f': return parse_presentation_type(pres::fixed, float_set);\n    case 'G': specs.set_upper(); FMT_FALLTHROUGH;\n    case 'g': return parse_presentation_type(pres::general, float_set);\n    case 'A': specs.set_upper(); FMT_FALLTHROUGH;\n    case 'a': return parse_presentation_type(pres::hexfloat, float_set);\n    case 'c':\n      if (arg_type == type::bool_type) report_error(\"invalid format specifier\");\n      return parse_presentation_type(pres::chr, integral_set);\n    case 's':\n      return parse_presentation_type(pres::string,\n                                     bool_set | string_set | cstring_set);\n    case 'p':\n      return parse_presentation_type(pres::pointer, pointer_set | cstring_set);\n    case '?':\n      return parse_presentation_type(pres::debug,\n                                     char_set | string_set | cstring_set);\n    case '}': return begin;\n    default:  {\n      if (*begin == '}') return begin;\n      // Parse fill and alignment.\n      auto fill_end = begin + code_point_length(begin);\n      if (end - fill_end <= 0) {\n        report_error(\"invalid format specifier\");\n        return begin;\n      }\n      if (*begin == '{') {\n        report_error(\"invalid fill character '{'\");\n        return begin;\n      }\n      auto alignment = parse_align(to_ascii(*fill_end));\n      enter_state(state::align, alignment != align::none);\n      specs.set_fill(\n          basic_string_view<Char>(begin, to_unsigned(fill_end - begin)));\n      specs.set_align(alignment);\n      begin = fill_end + 1;\n    }\n    }\n    if (begin == end) return begin;\n    c = to_ascii(*begin);\n  }\n}\n\ntemplate <typename Char, typename Handler>\nFMT_CONSTEXPR FMT_INLINE auto parse_replacement_field(const Char* begin,\n                                                      const Char* end,\n                                                      Handler&& handler)\n    -> const Char* {\n  ++begin;\n  if (begin == end) {\n    handler.on_error(\"invalid format string\");\n    return end;\n  }\n  int arg_id = 0;\n  switch (*begin) {\n  case '}':\n    handler.on_replacement_field(handler.on_arg_id(), begin);\n    return begin + 1;\n  case '{': handler.on_text(begin, begin + 1); return begin + 1;\n  case ':': arg_id = handler.on_arg_id(); break;\n  default:  {\n    struct id_adapter {\n      Handler& handler;\n      int arg_id;\n\n      FMT_CONSTEXPR void on_index(int id) { arg_id = handler.on_arg_id(id); }\n      FMT_CONSTEXPR void on_name(basic_string_view<Char> id) {\n        arg_id = handler.on_arg_id(id);\n      }\n    } adapter = {handler, 0};\n    begin = parse_arg_id(begin, end, adapter);\n    arg_id = adapter.arg_id;\n    Char c = begin != end ? *begin : Char();\n    if (c == '}') {\n      handler.on_replacement_field(arg_id, begin);\n      return begin + 1;\n    }\n    if (c != ':') {\n      handler.on_error(\"missing '}' in format string\");\n      return end;\n    }\n    break;\n  }\n  }\n  begin = handler.on_format_specs(arg_id, begin + 1, end);\n  if (begin == end || *begin != '}')\n    return handler.on_error(\"unknown format specifier\"), end;\n  return begin + 1;\n}\n\ntemplate <typename Char, typename Handler>\nFMT_CONSTEXPR void parse_format_string(basic_string_view<Char> fmt,\n                                       Handler&& handler) {\n  auto begin = fmt.data(), end = begin + fmt.size();\n  auto p = begin;\n  while (p != end) {\n    auto c = *p++;\n    if (c == '{') {\n      handler.on_text(begin, p - 1);\n      begin = p = parse_replacement_field(p - 1, end, handler);\n    } else if (c == '}') {\n      if (p == end || *p != '}')\n        return handler.on_error(\"unmatched '}' in format string\");\n      handler.on_text(begin, p);\n      begin = ++p;\n    }\n  }\n  handler.on_text(begin, end);\n}\n\n// Checks char specs and returns true iff the presentation type is char-like.\nFMT_CONSTEXPR inline auto check_char_specs(const format_specs& specs) -> bool {\n  auto type = specs.type();\n  if (type != presentation_type::none && type != presentation_type::chr &&\n      type != presentation_type::debug) {\n    return false;\n  }\n  if (specs.align() == align::numeric || specs.sign() != sign::none ||\n      specs.alt()) {\n    report_error(\"invalid format specifier for char\");\n  }\n  return true;\n}\n\n// A base class for compile-time strings.\nstruct compile_string {};\n\ntemplate <typename T, typename Char>\nFMT_VISIBILITY(\"hidden\")  // Suppress an ld warning on macOS (#3769).\nFMT_CONSTEXPR auto invoke_parse(parse_context<Char>& ctx) -> const Char* {\n  using mapped_type = remove_cvref_t<mapped_t<T, Char>>;\n  constexpr bool formattable =\n      std::is_constructible<formatter<mapped_type, Char>>::value;\n  if (!formattable) return ctx.begin();  // Error is reported in the value ctor.\n  using formatted_type = conditional_t<formattable, mapped_type, int>;\n  return formatter<formatted_type, Char>().parse(ctx);\n}\n\ntemplate <typename... T> struct arg_pack {};\n\ntemplate <typename Char, int NUM_ARGS, int NUM_NAMED_ARGS, bool DYNAMIC_NAMES>\nclass format_string_checker {\n private:\n  type types_[max_of<size_t>(1, NUM_ARGS)];\n  named_arg_info<Char> named_args_[max_of<size_t>(1, NUM_NAMED_ARGS)];\n  compile_parse_context<Char> context_;\n\n  using parse_func = auto (*)(parse_context<Char>&) -> const Char*;\n  parse_func parse_funcs_[max_of<size_t>(1, NUM_ARGS)];\n\n public:\n  template <typename... T>\n  FMT_CONSTEXPR explicit format_string_checker(basic_string_view<Char> fmt,\n                                               arg_pack<T...>)\n      : types_{mapped_type_constant<T, Char>::value...},\n        named_args_{},\n        context_(fmt, NUM_ARGS, types_),\n        parse_funcs_{&invoke_parse<T, Char>...} {\n    int arg_index = 0, named_arg_index = 0;\n    FMT_APPLY_VARIADIC(\n        init_static_named_arg<T>(named_args_, arg_index, named_arg_index));\n    ignore_unused(arg_index, named_arg_index);\n  }\n\n  FMT_CONSTEXPR void on_text(const Char*, const Char*) {}\n\n  FMT_CONSTEXPR auto on_arg_id() -> int { return context_.next_arg_id(); }\n  FMT_CONSTEXPR auto on_arg_id(int id) -> int {\n    context_.check_arg_id(id);\n    return id;\n  }\n  FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {\n    for (int i = 0; i < NUM_NAMED_ARGS; ++i) {\n      if (named_args_[i].name == id) return named_args_[i].id;\n    }\n    if (!DYNAMIC_NAMES) on_error(\"argument not found\");\n    return -1;\n  }\n\n  FMT_CONSTEXPR void on_replacement_field(int id, const Char* begin) {\n    on_format_specs(id, begin, begin);  // Call parse() on empty specs.\n  }\n\n  FMT_CONSTEXPR auto on_format_specs(int id, const Char* begin, const Char* end)\n      -> const Char* {\n    context_.advance_to(begin);\n    if (id >= 0 && id < NUM_ARGS) return parse_funcs_[id](context_);\n\n    // If id is out of range, it means we do not know the type and cannot parse\n    // the format at compile time. Instead, skip over content until we finish\n    // the format spec, accounting for any nested replacements.\n    for (int bracket_count = 0;\n         begin != end && (bracket_count > 0 || *begin != '}'); ++begin) {\n      if (*begin == '{')\n        ++bracket_count;\n      else if (*begin == '}')\n        --bracket_count;\n    }\n    return begin;\n  }\n\n  FMT_NORETURN FMT_CONSTEXPR void on_error(const char* message) {\n    report_error(message);\n  }\n};\n\n/// A contiguous memory buffer with an optional growing ability. It is an\n/// internal class and shouldn't be used directly, only via `memory_buffer`.\ntemplate <typename T> class buffer {\n private:\n  T* ptr_;\n  size_t size_;\n  size_t capacity_;\n\n  using grow_fun = void (*)(buffer& buf, size_t capacity);\n  grow_fun grow_;\n\n protected:\n  // Don't initialize ptr_ since it is not accessed to save a few cycles.\n  FMT_MSC_WARNING(suppress : 26495)\n  FMT_CONSTEXPR buffer(grow_fun grow, size_t sz) noexcept\n      : size_(sz), capacity_(sz), grow_(grow) {}\n\n  constexpr buffer(grow_fun grow, T* p = nullptr, size_t sz = 0,\n                   size_t cap = 0) noexcept\n      : ptr_(p), size_(sz), capacity_(cap), grow_(grow) {}\n\n  FMT_CONSTEXPR20 ~buffer() = default;\n  buffer(buffer&&) = default;\n\n  /// Sets the buffer data and capacity.\n  FMT_CONSTEXPR void set(T* buf_data, size_t buf_capacity) noexcept {\n    ptr_ = buf_data;\n    capacity_ = buf_capacity;\n  }\n\n public:\n  using value_type = T;\n  using const_reference = const T&;\n\n  buffer(const buffer&) = delete;\n  void operator=(const buffer&) = delete;\n\n  auto begin() noexcept -> T* { return ptr_; }\n  auto end() noexcept -> T* { return ptr_ + size_; }\n\n  auto begin() const noexcept -> const T* { return ptr_; }\n  auto end() const noexcept -> const T* { return ptr_ + size_; }\n\n  /// Returns the size of this buffer.\n  constexpr auto size() const noexcept -> size_t { return size_; }\n\n  /// Returns the capacity of this buffer.\n  constexpr auto capacity() const noexcept -> size_t { return capacity_; }\n\n  /// Returns a pointer to the buffer data (not null-terminated).\n  FMT_CONSTEXPR auto data() noexcept -> T* { return ptr_; }\n  FMT_CONSTEXPR auto data() const noexcept -> const T* { return ptr_; }\n\n  /// Clears this buffer.\n  FMT_CONSTEXPR void clear() { size_ = 0; }\n\n  // Tries resizing the buffer to contain `count` elements. If T is a POD type\n  // the new elements may not be initialized.\n  FMT_CONSTEXPR void try_resize(size_t count) {\n    try_reserve(count);\n    size_ = min_of(count, capacity_);\n  }\n\n  // Tries increasing the buffer capacity to `new_capacity`. It can increase the\n  // capacity by a smaller amount than requested but guarantees there is space\n  // for at least one additional element either by increasing the capacity or by\n  // flushing the buffer if it is full.\n  FMT_CONSTEXPR void try_reserve(size_t new_capacity) {\n    if (new_capacity > capacity_) grow_(*this, new_capacity);\n  }\n\n  FMT_CONSTEXPR void push_back(const T& value) {\n    try_reserve(size_ + 1);\n    ptr_[size_++] = value;\n  }\n\n  /// Appends data to the end of the buffer.\n  template <typename U>\n// Workaround for MSVC2019 to fix error C2893: Failed to specialize function\n// template 'void fmt::v11::detail::buffer<T>::append(const U *,const U *)'.\n#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1940\n  FMT_CONSTEXPR20\n#endif\n      void\n      append(const U* begin, const U* end) {\n    while (begin != end) {\n      auto size = size_;\n      auto free_cap = capacity_ - size;\n      auto count = to_unsigned(end - begin);\n      if (free_cap < count) {\n        grow_(*this, size + count);\n        size = size_;\n        free_cap = capacity_ - size;\n        count = count < free_cap ? count : free_cap;\n      }\n      // A loop is faster than memcpy on small sizes.\n      T* out = ptr_ + size;\n      for (size_t i = 0; i < count; ++i) out[i] = begin[i];\n      size_ += count;\n      begin += count;\n    }\n  }\n\n  template <typename Idx> FMT_CONSTEXPR auto operator[](Idx index) -> T& {\n    return ptr_[index];\n  }\n  template <typename Idx>\n  FMT_CONSTEXPR auto operator[](Idx index) const -> const T& {\n    return ptr_[index];\n  }\n};\n\nstruct buffer_traits {\n  constexpr explicit buffer_traits(size_t) {}\n  constexpr auto count() const -> size_t { return 0; }\n  constexpr auto limit(size_t size) const -> size_t { return size; }\n};\n\nclass fixed_buffer_traits {\n private:\n  size_t count_ = 0;\n  size_t limit_;\n\n public:\n  constexpr explicit fixed_buffer_traits(size_t limit) : limit_(limit) {}\n  constexpr auto count() const -> size_t { return count_; }\n  FMT_CONSTEXPR auto limit(size_t size) -> size_t {\n    size_t n = limit_ > count_ ? limit_ - count_ : 0;\n    count_ += size;\n    return min_of(size, n);\n  }\n};\n\n// A buffer that writes to an output iterator when flushed.\ntemplate <typename OutputIt, typename T, typename Traits = buffer_traits>\nclass iterator_buffer : public Traits, public buffer<T> {\n private:\n  OutputIt out_;\n  enum { buffer_size = 256 };\n  T data_[buffer_size];\n\n  static FMT_CONSTEXPR void grow(buffer<T>& buf, size_t) {\n    if (buf.size() == buffer_size) static_cast<iterator_buffer&>(buf).flush();\n  }\n\n  void flush() {\n    auto size = this->size();\n    this->clear();\n    const T* begin = data_;\n    const T* end = begin + this->limit(size);\n    while (begin != end) *out_++ = *begin++;\n  }\n\n public:\n  explicit iterator_buffer(OutputIt out, size_t n = buffer_size)\n      : Traits(n), buffer<T>(grow, data_, 0, buffer_size), out_(out) {}\n  iterator_buffer(iterator_buffer&& other) noexcept\n      : Traits(other),\n        buffer<T>(grow, data_, 0, buffer_size),\n        out_(other.out_) {}\n  ~iterator_buffer() {\n    // Don't crash if flush fails during unwinding.\n    FMT_TRY { flush(); }\n    FMT_CATCH(...) {}\n  }\n\n  auto out() -> OutputIt {\n    flush();\n    return out_;\n  }\n  auto count() const -> size_t { return Traits::count() + this->size(); }\n};\n\ntemplate <typename T>\nclass iterator_buffer<T*, T, fixed_buffer_traits> : public fixed_buffer_traits,\n                                                    public buffer<T> {\n private:\n  T* out_;\n  enum { buffer_size = 256 };\n  T data_[buffer_size];\n\n  static FMT_CONSTEXPR void grow(buffer<T>& buf, size_t) {\n    if (buf.size() == buf.capacity())\n      static_cast<iterator_buffer&>(buf).flush();\n  }\n\n  void flush() {\n    size_t n = this->limit(this->size());\n    if (this->data() == out_) {\n      out_ += n;\n      this->set(data_, buffer_size);\n    }\n    this->clear();\n  }\n\n public:\n  explicit iterator_buffer(T* out, size_t n = buffer_size)\n      : fixed_buffer_traits(n), buffer<T>(grow, out, 0, n), out_(out) {}\n  iterator_buffer(iterator_buffer&& other) noexcept\n      : fixed_buffer_traits(other),\n        buffer<T>(static_cast<iterator_buffer&&>(other)),\n        out_(other.out_) {\n    if (this->data() != out_) {\n      this->set(data_, buffer_size);\n      this->clear();\n    }\n  }\n  ~iterator_buffer() { flush(); }\n\n  auto out() -> T* {\n    flush();\n    return out_;\n  }\n  auto count() const -> size_t {\n    return fixed_buffer_traits::count() + this->size();\n  }\n};\n\ntemplate <typename T> class iterator_buffer<T*, T> : public buffer<T> {\n public:\n  explicit iterator_buffer(T* out, size_t = 0)\n      : buffer<T>([](buffer<T>&, size_t) {}, out, 0, ~size_t()) {}\n\n  auto out() -> T* { return &*this->end(); }\n};\n\ntemplate <typename Container>\nclass container_buffer : public buffer<typename Container::value_type> {\n private:\n  using value_type = typename Container::value_type;\n\n  static FMT_CONSTEXPR void grow(buffer<value_type>& buf, size_t capacity) {\n    auto& self = static_cast<container_buffer&>(buf);\n    self.container.resize(capacity);\n    self.set(&self.container[0], capacity);\n  }\n\n public:\n  Container& container;\n\n  explicit container_buffer(Container& c)\n      : buffer<value_type>(grow, c.size()), container(c) {}\n};\n\n// A buffer that writes to a container with the contiguous storage.\ntemplate <typename OutputIt>\nclass iterator_buffer<\n    OutputIt,\n    enable_if_t<is_back_insert_iterator<OutputIt>::value &&\n                    is_contiguous<typename OutputIt::container_type>::value,\n                typename OutputIt::container_type::value_type>>\n    : public container_buffer<typename OutputIt::container_type> {\n private:\n  using base = container_buffer<typename OutputIt::container_type>;\n\n public:\n  explicit iterator_buffer(typename OutputIt::container_type& c) : base(c) {}\n  explicit iterator_buffer(OutputIt out, size_t = 0)\n      : base(get_container(out)) {}\n\n  auto out() -> OutputIt { return OutputIt(this->container); }\n};\n\n// A buffer that counts the number of code units written discarding the output.\ntemplate <typename T = char> class counting_buffer : public buffer<T> {\n private:\n  enum { buffer_size = 256 };\n  T data_[buffer_size];\n  size_t count_ = 0;\n\n  static FMT_CONSTEXPR void grow(buffer<T>& buf, size_t) {\n    if (buf.size() != buffer_size) return;\n    static_cast<counting_buffer&>(buf).count_ += buf.size();\n    buf.clear();\n  }\n\n public:\n  FMT_CONSTEXPR counting_buffer() : buffer<T>(grow, data_, 0, buffer_size) {}\n\n  constexpr auto count() const noexcept -> size_t {\n    return count_ + this->size();\n  }\n};\n\ntemplate <typename T>\nstruct is_back_insert_iterator<basic_appender<T>> : std::true_type {};\n\ntemplate <typename OutputIt, typename InputIt, typename = void>\nstruct has_back_insert_iterator_container_append : std::false_type {};\ntemplate <typename OutputIt, typename InputIt>\nstruct has_back_insert_iterator_container_append<\n    OutputIt, InputIt,\n    void_t<decltype(get_container(std::declval<OutputIt>())\n                        .append(std::declval<InputIt>(),\n                                std::declval<InputIt>()))>> : std::true_type {};\n\ntemplate <typename OutputIt, typename InputIt, typename = void>\nstruct has_back_insert_iterator_container_insert_at_end : std::false_type {};\n\ntemplate <typename OutputIt, typename InputIt>\nstruct has_back_insert_iterator_container_insert_at_end<\n    OutputIt, InputIt,\n    void_t<decltype(get_container(std::declval<OutputIt>())\n                        .insert(get_container(std::declval<OutputIt>()).end(),\n                                std::declval<InputIt>(),\n                                std::declval<InputIt>()))>> : std::true_type {};\n\n// An optimized version of std::copy with the output value type (T).\ntemplate <typename T, typename InputIt, typename OutputIt,\n          FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value&&\n                            has_back_insert_iterator_container_append<\n                                OutputIt, InputIt>::value)>\nFMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)\n    -> OutputIt {\n  get_container(out).append(begin, end);\n  return out;\n}\n\ntemplate <typename T, typename InputIt, typename OutputIt,\n          FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value &&\n                        !has_back_insert_iterator_container_append<\n                            OutputIt, InputIt>::value &&\n                        has_back_insert_iterator_container_insert_at_end<\n                            OutputIt, InputIt>::value)>\nFMT_CONSTEXPR20 auto copy(InputIt begin, InputIt end, OutputIt out)\n    -> OutputIt {\n  auto& c = get_container(out);\n  c.insert(c.end(), begin, end);\n  return out;\n}\n\ntemplate <typename T, typename InputIt, typename OutputIt,\n          FMT_ENABLE_IF(!(is_back_insert_iterator<OutputIt>::value &&\n                          (has_back_insert_iterator_container_append<\n                               OutputIt, InputIt>::value ||\n                           has_back_insert_iterator_container_insert_at_end<\n                               OutputIt, InputIt>::value)))>\nFMT_CONSTEXPR auto copy(InputIt begin, InputIt end, OutputIt out) -> OutputIt {\n  while (begin != end) *out++ = static_cast<T>(*begin++);\n  return out;\n}\n\ntemplate <typename T, typename V, typename OutputIt>\nFMT_CONSTEXPR auto copy(basic_string_view<V> s, OutputIt out) -> OutputIt {\n  return copy<T>(s.begin(), s.end(), out);\n}\n\ntemplate <typename It, typename Enable = std::true_type>\nstruct is_buffer_appender : std::false_type {};\ntemplate <typename It>\nstruct is_buffer_appender<\n    It, bool_constant<\n            is_back_insert_iterator<It>::value &&\n            std::is_base_of<buffer<typename It::container_type::value_type>,\n                            typename It::container_type>::value>>\n    : std::true_type {};\n\n// Maps an output iterator to a buffer.\ntemplate <typename T, typename OutputIt,\n          FMT_ENABLE_IF(!is_buffer_appender<OutputIt>::value)>\nauto get_buffer(OutputIt out) -> iterator_buffer<OutputIt, T> {\n  return iterator_buffer<OutputIt, T>(out);\n}\ntemplate <typename T, typename OutputIt,\n          FMT_ENABLE_IF(is_buffer_appender<OutputIt>::value)>\nauto get_buffer(OutputIt out) -> buffer<T>& {\n  return get_container(out);\n}\n\ntemplate <typename Buf, typename OutputIt>\nauto get_iterator(Buf& buf, OutputIt) -> decltype(buf.out()) {\n  return buf.out();\n}\ntemplate <typename T, typename OutputIt>\nauto get_iterator(buffer<T>&, OutputIt out) -> OutputIt {\n  return out;\n}\n\n// This type is intentionally undefined, only used for errors.\ntemplate <typename T, typename Char> struct type_is_unformattable_for;\n\ntemplate <typename Char> struct string_value {\n  const Char* data;\n  size_t size;\n  auto str() const -> basic_string_view<Char> { return {data, size}; }\n};\n\ntemplate <typename Context> struct custom_value {\n  using char_type = typename Context::char_type;\n  void* value;\n  void (*format)(void* arg, parse_context<char_type>& parse_ctx, Context& ctx);\n};\n\ntemplate <typename Char> struct named_arg_value {\n  const named_arg_info<Char>* data;\n  size_t size;\n};\n\nstruct custom_tag {};\n\n#if !FMT_BUILTIN_TYPES\n#  define FMT_BUILTIN , monostate\n#else\n#  define FMT_BUILTIN\n#endif\n\n// A formatting argument value.\ntemplate <typename Context> class value {\n public:\n  using char_type = typename Context::char_type;\n\n  union {\n    monostate no_value;\n    int int_value;\n    unsigned uint_value;\n    long long long_long_value;\n    unsigned long long ulong_long_value;\n    int128_opt int128_value;\n    uint128_opt uint128_value;\n    bool bool_value;\n    char_type char_value;\n    float float_value;\n    double double_value;\n    long double long_double_value;\n    const void* pointer;\n    string_value<char_type> string;\n    custom_value<Context> custom;\n    named_arg_value<char_type> named_args;\n  };\n\n  constexpr FMT_INLINE value() : no_value() {}\n  constexpr FMT_INLINE value(signed char x) : int_value(x) {}\n  constexpr FMT_INLINE value(unsigned char x FMT_BUILTIN) : uint_value(x) {}\n  constexpr FMT_INLINE value(signed short x) : int_value(x) {}\n  constexpr FMT_INLINE value(unsigned short x FMT_BUILTIN) : uint_value(x) {}\n  constexpr FMT_INLINE value(int x) : int_value(x) {}\n  constexpr FMT_INLINE value(unsigned x FMT_BUILTIN) : uint_value(x) {}\n  FMT_CONSTEXPR FMT_INLINE value(long x FMT_BUILTIN) : value(long_type(x)) {}\n  FMT_CONSTEXPR FMT_INLINE value(unsigned long x FMT_BUILTIN)\n      : value(ulong_type(x)) {}\n  constexpr FMT_INLINE value(long long x FMT_BUILTIN) : long_long_value(x) {}\n  constexpr FMT_INLINE value(unsigned long long x FMT_BUILTIN)\n      : ulong_long_value(x) {}\n  FMT_INLINE value(int128_opt x FMT_BUILTIN) : int128_value(x) {}\n  FMT_INLINE value(uint128_opt x FMT_BUILTIN) : uint128_value(x) {}\n  constexpr FMT_INLINE value(bool x FMT_BUILTIN) : bool_value(x) {}\n\n  template <int N>\n  constexpr FMT_INLINE value(bitint<N> x FMT_BUILTIN) : long_long_value(x) {\n    static_assert(N <= 64, \"unsupported _BitInt\");\n  }\n  template <int N>\n  constexpr FMT_INLINE value(ubitint<N> x FMT_BUILTIN) : ulong_long_value(x) {\n    static_assert(N <= 64, \"unsupported _BitInt\");\n  }\n\n  template <typename T, FMT_ENABLE_IF(is_code_unit<T>::value)>\n  constexpr FMT_INLINE value(T x FMT_BUILTIN) : char_value(x) {\n    static_assert(\n        std::is_same<T, char>::value || std::is_same<T, char_type>::value,\n        \"mixing character types is disallowed\");\n  }\n\n  constexpr FMT_INLINE value(float x FMT_BUILTIN) : float_value(x) {}\n  constexpr FMT_INLINE value(double x FMT_BUILTIN) : double_value(x) {}\n  FMT_INLINE value(long double x FMT_BUILTIN) : long_double_value(x) {}\n\n  FMT_CONSTEXPR FMT_INLINE value(char_type* x FMT_BUILTIN) {\n    string.data = x;\n    if (is_constant_evaluated()) string.size = 0;\n  }\n  FMT_CONSTEXPR FMT_INLINE value(const char_type* x FMT_BUILTIN) {\n    string.data = x;\n    if (is_constant_evaluated()) string.size = 0;\n  }\n  template <typename T, typename C = char_t<T>,\n            FMT_ENABLE_IF(!std::is_pointer<T>::value)>\n  FMT_CONSTEXPR value(const T& x FMT_BUILTIN) {\n    static_assert(std::is_same<C, char_type>::value,\n                  \"mixing character types is disallowed\");\n    auto sv = to_string_view(x);\n    string.data = sv.data();\n    string.size = sv.size();\n  }\n  FMT_INLINE value(void* x FMT_BUILTIN) : pointer(x) {}\n  FMT_INLINE value(const void* x FMT_BUILTIN) : pointer(x) {}\n  FMT_INLINE value(volatile void* x FMT_BUILTIN)\n      : pointer(const_cast<const void*>(x)) {}\n  FMT_INLINE value(const volatile void* x FMT_BUILTIN)\n      : pointer(const_cast<const void*>(x)) {}\n  FMT_INLINE value(nullptr_t) : pointer(nullptr) {}\n\n  template <typename T, FMT_ENABLE_IF(std::is_pointer<T>::value ||\n                                      std::is_member_pointer<T>::value)>\n  value(const T&) {\n    // Formatting of arbitrary pointers is disallowed. If you want to format a\n    // pointer cast it to `void*` or `const void*`. In particular, this forbids\n    // formatting of `[const] volatile char*` printed as bool by iostreams.\n    static_assert(sizeof(T) == 0,\n                  \"formatting of non-void pointers is disallowed\");\n  }\n\n  template <typename T, FMT_ENABLE_IF(use_format_as<T>::value)>\n  value(const T& x) : value(format_as(x)) {}\n  template <typename T, FMT_ENABLE_IF(use_format_as_member<T>::value)>\n  value(const T& x) : value(formatter<T>::format_as(x)) {}\n\n  template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>\n  value(const T& named_arg) : value(named_arg.value) {}\n\n  template <typename T,\n            FMT_ENABLE_IF(use_formatter<T>::value || !FMT_BUILTIN_TYPES)>\n  FMT_CONSTEXPR20 FMT_INLINE value(T& x) : value(x, custom_tag()) {}\n\n  FMT_ALWAYS_INLINE value(const named_arg_info<char_type>* args, size_t size)\n      : named_args{args, size} {}\n\n private:\n  template <typename T, FMT_ENABLE_IF(has_formatter<T, char_type>())>\n  FMT_CONSTEXPR value(T& x, custom_tag) {\n    using value_type = remove_const_t<T>;\n    // T may overload operator& e.g. std::vector<bool>::reference in libc++.\n    if (!is_constant_evaluated()) {\n      custom.value =\n          const_cast<char*>(&reinterpret_cast<const volatile char&>(x));\n    } else {\n      custom.value = nullptr;\n#if defined(__cpp_if_constexpr)\n      if constexpr (std::is_same<decltype(&x), remove_reference_t<T>*>::value)\n        custom.value = const_cast<value_type*>(&x);\n#endif\n    }\n    custom.format = format_custom<value_type>;\n  }\n\n  template <typename T, FMT_ENABLE_IF(!has_formatter<T, char_type>())>\n  FMT_CONSTEXPR value(const T&, custom_tag) {\n    // Cannot format an argument; to make type T formattable provide a\n    // formatter<T> specialization: https://fmt.dev/latest/api.html#udt.\n    type_is_unformattable_for<T, char_type> _;\n  }\n\n  // Formats an argument of a custom type, such as a user-defined class.\n  template <typename T>\n  static void format_custom(void* arg, parse_context<char_type>& parse_ctx,\n                            Context& ctx) {\n    auto f = formatter<T, char_type>();\n    parse_ctx.advance_to(f.parse(parse_ctx));\n    using qualified_type =\n        conditional_t<has_formatter<const T, char_type>(), const T, T>;\n    // format must be const for compatibility with std::format and compilation.\n    const auto& cf = f;\n    ctx.advance_to(cf.format(*static_cast<qualified_type*>(arg), ctx));\n  }\n};\n\nenum { packed_arg_bits = 4 };\n// Maximum number of arguments with packed types.\nenum { max_packed_args = 62 / packed_arg_bits };\nenum : unsigned long long { is_unpacked_bit = 1ULL << 63 };\nenum : unsigned long long { has_named_args_bit = 1ULL << 62 };\n\ntemplate <typename It, typename T, typename Enable = void>\nstruct is_output_iterator : std::false_type {};\n\ntemplate <> struct is_output_iterator<appender, char> : std::true_type {};\n\ntemplate <typename It, typename T>\nstruct is_output_iterator<\n    It, T,\n    enable_if_t<std::is_assignable<decltype(*std::declval<decay_t<It>&>()++),\n                                   T>::value>> : std::true_type {};\n\ntemplate <typename> constexpr auto encode_types() -> unsigned long long {\n  return 0;\n}\n\ntemplate <typename Context, typename First, typename... T>\nconstexpr auto encode_types() -> unsigned long long {\n  return static_cast<unsigned>(stored_type_constant<First, Context>::value) |\n         (encode_types<Context, T...>() << packed_arg_bits);\n}\n\ntemplate <typename Context, typename... T, size_t NUM_ARGS = sizeof...(T)>\nconstexpr auto make_descriptor() -> unsigned long long {\n  return NUM_ARGS <= max_packed_args ? encode_types<Context, T...>()\n                                     : is_unpacked_bit | NUM_ARGS;\n}\n\ntemplate <typename Context, int NUM_ARGS>\nusing arg_t = conditional_t<NUM_ARGS <= max_packed_args, value<Context>,\n                            basic_format_arg<Context>>;\n\ntemplate <typename Context, int NUM_ARGS, int NUM_NAMED_ARGS,\n          unsigned long long DESC>\nstruct named_arg_store {\n  // args_[0].named_args points to named_args to avoid bloating format_args.\n  arg_t<Context, NUM_ARGS> args[1u + NUM_ARGS];\n  named_arg_info<typename Context::char_type>\n      named_args[static_cast<size_t>(NUM_NAMED_ARGS)];\n\n  template <typename... T>\n  FMT_CONSTEXPR FMT_ALWAYS_INLINE named_arg_store(T&... values)\n      : args{{named_args, NUM_NAMED_ARGS}, values...} {\n    int arg_index = 0, named_arg_index = 0;\n    FMT_APPLY_VARIADIC(\n        init_named_arg(named_args, arg_index, named_arg_index, values));\n  }\n\n  named_arg_store(named_arg_store&& rhs) {\n    args[0] = {named_args, NUM_NAMED_ARGS};\n    for (size_t i = 1; i < sizeof(args) / sizeof(*args); ++i)\n      args[i] = rhs.args[i];\n    for (size_t i = 0; i < NUM_NAMED_ARGS; ++i)\n      named_args[i] = rhs.named_args[i];\n  }\n\n  named_arg_store(const named_arg_store& rhs) = delete;\n  auto operator=(const named_arg_store& rhs) -> named_arg_store& = delete;\n  auto operator=(named_arg_store&& rhs) -> named_arg_store& = delete;\n  operator const arg_t<Context, NUM_ARGS>*() const { return args + 1; }\n};\n\n// An array of references to arguments. It can be implicitly converted to\n// `basic_format_args` for passing into type-erased formatting functions\n// such as `vformat`. It is a plain struct to reduce binary size in debug mode.\ntemplate <typename Context, int NUM_ARGS, int NUM_NAMED_ARGS,\n          unsigned long long DESC>\nstruct format_arg_store {\n  // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.\n  using type =\n      conditional_t<NUM_NAMED_ARGS == 0,\n                    arg_t<Context, NUM_ARGS>[max_of<size_t>(1, NUM_ARGS)],\n                    named_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>>;\n  type args;\n};\n\n// TYPE can be different from type_constant<T>, e.g. for __float128.\ntemplate <typename T, typename Char, type TYPE> struct native_formatter {\n private:\n  dynamic_format_specs<Char> specs_;\n\n public:\n  using nonlocking = void;\n\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin();\n    auto end = parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, TYPE);\n    if (const_check(TYPE == type::char_type)) check_char_specs(specs_);\n    return end;\n  }\n\n  template <type U = TYPE,\n            FMT_ENABLE_IF(U == type::string_type || U == type::cstring_type ||\n                          U == type::char_type)>\n  FMT_CONSTEXPR void set_debug_format(bool set = true) {\n    specs_.set_type(set ? presentation_type::debug : presentation_type::none);\n  }\n\n  FMT_PRAGMA_CLANG(diagnostic ignored \"-Wundefined-inline\")\n  template <typename FormatContext>\n  FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const\n      -> decltype(ctx.out());\n};\n\ntemplate <typename T, typename Enable = void>\nstruct locking\n    : bool_constant<mapped_type_constant<T>::value == type::custom_type> {};\ntemplate <typename T>\nstruct locking<T, void_t<typename formatter<remove_cvref_t<T>>::nonlocking>>\n    : std::false_type {};\n\ntemplate <typename T = int> FMT_CONSTEXPR inline auto is_locking() -> bool {\n  return locking<T>::value;\n}\ntemplate <typename T1, typename T2, typename... Tail>\nFMT_CONSTEXPR inline auto is_locking() -> bool {\n  return locking<T1>::value || is_locking<T2, Tail...>();\n}\n\nFMT_API void vformat_to(buffer<char>& buf, string_view fmt, format_args args,\n                        locale_ref loc = {});\n\n#if FMT_WIN32\nFMT_API void vprint_mojibake(FILE*, string_view, format_args, bool);\n#else  // format_args is passed by reference since it is defined later.\ninline void vprint_mojibake(FILE*, string_view, const format_args&, bool) {}\n#endif\n}  // namespace detail\n\n// The main public API.\n\ntemplate <typename Char>\nFMT_CONSTEXPR void parse_context<Char>::do_check_arg_id(int arg_id) {\n  // Argument id is only checked at compile time during parsing because\n  // formatting has its own validation.\n  if (detail::is_constant_evaluated() && use_constexpr_cast) {\n    auto ctx = static_cast<detail::compile_parse_context<Char>*>(this);\n    if (arg_id >= ctx->num_args()) report_error(\"argument not found\");\n  }\n}\n\ntemplate <typename Char>\nFMT_CONSTEXPR void parse_context<Char>::check_dynamic_spec(int arg_id) {\n  using detail::compile_parse_context;\n  if (detail::is_constant_evaluated() && use_constexpr_cast)\n    static_cast<compile_parse_context<Char>*>(this)->check_dynamic_spec(arg_id);\n}\n\nFMT_BEGIN_EXPORT\n\n// An output iterator that appends to a buffer. It is used instead of\n// back_insert_iterator to reduce symbol sizes and avoid <iterator> dependency.\ntemplate <typename T> class basic_appender {\n protected:\n  detail::buffer<T>* container;\n\n public:\n  using container_type = detail::buffer<T>;\n\n  FMT_CONSTEXPR basic_appender(detail::buffer<T>& buf) : container(&buf) {}\n\n  FMT_CONSTEXPR20 auto operator=(T c) -> basic_appender& {\n    container->push_back(c);\n    return *this;\n  }\n  FMT_CONSTEXPR20 auto operator*() -> basic_appender& { return *this; }\n  FMT_CONSTEXPR20 auto operator++() -> basic_appender& { return *this; }\n  FMT_CONSTEXPR20 auto operator++(int) -> basic_appender { return *this; }\n};\n\n// A formatting argument. Context is a template parameter for the compiled API\n// where output can be unbuffered.\ntemplate <typename Context> class basic_format_arg {\n private:\n  detail::value<Context> value_;\n  detail::type type_;\n\n  friend class basic_format_args<Context>;\n\n  using char_type = typename Context::char_type;\n\n public:\n  class handle {\n   private:\n    detail::custom_value<Context> custom_;\n\n   public:\n    explicit handle(detail::custom_value<Context> custom) : custom_(custom) {}\n\n    void format(parse_context<char_type>& parse_ctx, Context& ctx) const {\n      custom_.format(custom_.value, parse_ctx, ctx);\n    }\n  };\n\n  constexpr basic_format_arg() : type_(detail::type::none_type) {}\n  basic_format_arg(const detail::named_arg_info<char_type>* args, size_t size)\n      : value_(args, size) {}\n  template <typename T>\n  basic_format_arg(T&& val)\n      : value_(val), type_(detail::stored_type_constant<T, Context>::value) {}\n\n  constexpr explicit operator bool() const noexcept {\n    return type_ != detail::type::none_type;\n  }\n  auto type() const -> detail::type { return type_; }\n\n  /**\n   * Visits an argument dispatching to the appropriate visit method based on\n   * the argument type. For example, if the argument type is `double` then\n   * `vis(value)` will be called with the value of type `double`.\n   */\n  template <typename Visitor>\n  FMT_CONSTEXPR FMT_INLINE auto visit(Visitor&& vis) const -> decltype(vis(0)) {\n    using detail::map;\n    switch (type_) {\n    case detail::type::none_type:        break;\n    case detail::type::int_type:         return vis(value_.int_value);\n    case detail::type::uint_type:        return vis(value_.uint_value);\n    case detail::type::long_long_type:   return vis(value_.long_long_value);\n    case detail::type::ulong_long_type:  return vis(value_.ulong_long_value);\n    case detail::type::int128_type:      return vis(map(value_.int128_value));\n    case detail::type::uint128_type:     return vis(map(value_.uint128_value));\n    case detail::type::bool_type:        return vis(value_.bool_value);\n    case detail::type::char_type:        return vis(value_.char_value);\n    case detail::type::float_type:       return vis(value_.float_value);\n    case detail::type::double_type:      return vis(value_.double_value);\n    case detail::type::long_double_type: return vis(value_.long_double_value);\n    case detail::type::cstring_type:     return vis(value_.string.data);\n    case detail::type::string_type:      return vis(value_.string.str());\n    case detail::type::pointer_type:     return vis(value_.pointer);\n    case detail::type::custom_type:      return vis(handle(value_.custom));\n    }\n    return vis(monostate());\n  }\n\n  auto format_custom(const char_type* parse_begin,\n                     parse_context<char_type>& parse_ctx, Context& ctx)\n      -> bool {\n    if (type_ != detail::type::custom_type) return false;\n    parse_ctx.advance_to(parse_begin);\n    value_.custom.format(value_.custom.value, parse_ctx, ctx);\n    return true;\n  }\n};\n\n/**\n * A view of a collection of formatting arguments. To avoid lifetime issues it\n * should only be used as a parameter type in type-erased functions such as\n * `vformat`:\n *\n *     void vlog(fmt::string_view fmt, fmt::format_args args);  // OK\n *     fmt::format_args args = fmt::make_format_args();  // Dangling reference\n */\ntemplate <typename Context> class basic_format_args {\n private:\n  // A descriptor that contains information about formatting arguments.\n  // If the number of arguments is less or equal to max_packed_args then\n  // argument types are passed in the descriptor. This reduces binary code size\n  // per formatting function call.\n  unsigned long long desc_;\n  union {\n    // If is_packed() returns true then argument values are stored in values_;\n    // otherwise they are stored in args_. This is done to improve cache\n    // locality and reduce compiled code size since storing larger objects\n    // may require more code (at least on x86-64) even if the same amount of\n    // data is actually copied to stack. It saves ~10% on the bloat test.\n    const detail::value<Context>* values_;\n    const basic_format_arg<Context>* args_;\n  };\n\n  constexpr auto is_packed() const -> bool {\n    return (desc_ & detail::is_unpacked_bit) == 0;\n  }\n  constexpr auto has_named_args() const -> bool {\n    return (desc_ & detail::has_named_args_bit) != 0;\n  }\n\n  FMT_CONSTEXPR auto type(int index) const -> detail::type {\n    int shift = index * detail::packed_arg_bits;\n    unsigned mask = (1 << detail::packed_arg_bits) - 1;\n    return static_cast<detail::type>((desc_ >> shift) & mask);\n  }\n\n  template <int NUM_ARGS, int NUM_NAMED_ARGS, unsigned long long DESC>\n  using store =\n      detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC>;\n\n public:\n  using format_arg = basic_format_arg<Context>;\n\n  constexpr basic_format_args() : desc_(0), args_(nullptr) {}\n\n  /// Constructs a `basic_format_args` object from `format_arg_store`.\n  template <int NUM_ARGS, int NUM_NAMED_ARGS, unsigned long long DESC,\n            FMT_ENABLE_IF(NUM_ARGS <= detail::max_packed_args)>\n  constexpr FMT_ALWAYS_INLINE basic_format_args(\n      const store<NUM_ARGS, NUM_NAMED_ARGS, DESC>& s)\n      : desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)),\n        values_(s.args) {}\n\n  template <int NUM_ARGS, int NUM_NAMED_ARGS, unsigned long long DESC,\n            FMT_ENABLE_IF(NUM_ARGS > detail::max_packed_args)>\n  constexpr basic_format_args(const store<NUM_ARGS, NUM_NAMED_ARGS, DESC>& s)\n      : desc_(DESC | (NUM_NAMED_ARGS != 0 ? +detail::has_named_args_bit : 0)),\n        args_(s.args) {}\n\n  /// Constructs a `basic_format_args` object from a dynamic list of arguments.\n  constexpr basic_format_args(const format_arg* args, int count,\n                              bool has_named = false)\n      : desc_(detail::is_unpacked_bit | detail::to_unsigned(count) |\n              (has_named ? +detail::has_named_args_bit : 0)),\n        args_(args) {}\n\n  /// Returns the argument with the specified id.\n  FMT_CONSTEXPR auto get(int id) const -> format_arg {\n    auto arg = format_arg();\n    if (!is_packed()) {\n      if (id < max_size()) arg = args_[id];\n      return arg;\n    }\n    if (static_cast<unsigned>(id) >= detail::max_packed_args) return arg;\n    arg.type_ = type(id);\n    if (arg.type_ != detail::type::none_type) arg.value_ = values_[id];\n    return arg;\n  }\n\n  template <typename Char>\n  auto get(basic_string_view<Char> name) const -> format_arg {\n    int id = get_id(name);\n    return id >= 0 ? get(id) : format_arg();\n  }\n\n  template <typename Char>\n  FMT_CONSTEXPR auto get_id(basic_string_view<Char> name) const -> int {\n    if (!has_named_args()) return -1;\n    const auto& named_args =\n        (is_packed() ? values_[-1] : args_[-1].value_).named_args;\n    for (size_t i = 0; i < named_args.size; ++i) {\n      if (named_args.data[i].name == name) return named_args.data[i].id;\n    }\n    return -1;\n  }\n\n  auto max_size() const -> int {\n    unsigned long long max_packed = detail::max_packed_args;\n    return static_cast<int>(is_packed() ? max_packed\n                                        : desc_ & ~detail::is_unpacked_bit);\n  }\n};\n\n// A formatting context.\nclass context {\n private:\n  appender out_;\n  format_args args_;\n  FMT_NO_UNIQUE_ADDRESS locale_ref loc_;\n\n public:\n  using char_type = char;  ///< The character type for the output.\n  using iterator = appender;\n  using format_arg = basic_format_arg<context>;\n  enum { builtin_types = FMT_BUILTIN_TYPES };\n\n  /// Constructs a `context` object. References to the arguments are stored\n  /// in the object so make sure they have appropriate lifetimes.\n  FMT_CONSTEXPR context(iterator out, format_args args, locale_ref loc = {})\n      : out_(out), args_(args), loc_(loc) {}\n  context(context&&) = default;\n  context(const context&) = delete;\n  void operator=(const context&) = delete;\n\n  FMT_CONSTEXPR auto arg(int id) const -> format_arg { return args_.get(id); }\n  inline auto arg(string_view name) const -> format_arg {\n    return args_.get(name);\n  }\n  FMT_CONSTEXPR auto arg_id(string_view name) const -> int {\n    return args_.get_id(name);\n  }\n  auto args() const -> const format_args& { return args_; }\n\n  // Returns an iterator to the beginning of the output range.\n  FMT_CONSTEXPR auto out() const -> iterator { return out_; }\n\n  // Advances the begin iterator to `it`.\n  FMT_CONSTEXPR void advance_to(iterator) {}\n\n  FMT_CONSTEXPR auto locale() const -> locale_ref { return loc_; }\n};\n\ntemplate <typename Char = char> struct runtime_format_string {\n  basic_string_view<Char> str;\n};\n\n/**\n * Creates a runtime format string.\n *\n * **Example**:\n *\n *     // Check format string at runtime instead of compile-time.\n *     fmt::print(fmt::runtime(\"{:d}\"), \"I am not a number\");\n */\ninline auto runtime(string_view s) -> runtime_format_string<> { return {{s}}; }\n\n/// A compile-time format string. Use `format_string` in the public API to\n/// prevent type deduction.\ntemplate <typename... T> struct fstring {\n private:\n  static constexpr int num_static_named_args =\n      detail::count_static_named_args<T...>();\n\n  using checker = detail::format_string_checker<\n      char, static_cast<int>(sizeof...(T)), num_static_named_args,\n      num_static_named_args != detail::count_named_args<T...>()>;\n\n  using arg_pack = detail::arg_pack<T...>;\n\n public:\n  string_view str;\n  using t = fstring;\n\n  // Reports a compile-time error if S is not a valid format string for T.\n  template <size_t N>\n  FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const char (&s)[N]) : str(s, N - 1) {\n    using namespace detail;\n    static_assert(count<(is_view<remove_cvref_t<T>>::value &&\n                         std::is_reference<T>::value)...>() == 0,\n                  \"passing views as lvalues is disallowed\");\n    if (FMT_USE_CONSTEVAL) parse_format_string<char>(s, checker(s, arg_pack()));\n#ifdef FMT_ENFORCE_COMPILE_STRING\n    static_assert(\n        FMT_USE_CONSTEVAL && sizeof(s) != 0,\n        \"FMT_ENFORCE_COMPILE_STRING requires format strings to use FMT_STRING\");\n#endif\n  }\n  template <typename S,\n            FMT_ENABLE_IF(std::is_convertible<const S&, string_view>::value)>\n  FMT_CONSTEVAL FMT_ALWAYS_INLINE fstring(const S& s) : str(s) {\n    auto sv = string_view(str);\n    if (FMT_USE_CONSTEVAL)\n      detail::parse_format_string<char>(sv, checker(sv, arg_pack()));\n#ifdef FMT_ENFORCE_COMPILE_STRING\n    static_assert(\n        FMT_USE_CONSTEVAL && sizeof(s) != 0,\n        \"FMT_ENFORCE_COMPILE_STRING requires format strings to use FMT_STRING\");\n#endif\n  }\n  template <typename S,\n            FMT_ENABLE_IF(std::is_base_of<detail::compile_string, S>::value&&\n                              std::is_same<typename S::char_type, char>::value)>\n  FMT_ALWAYS_INLINE fstring(const S&) : str(S()) {\n    FMT_CONSTEXPR auto sv = string_view(S());\n    FMT_CONSTEXPR int unused =\n        (parse_format_string(sv, checker(sv, arg_pack())), 0);\n    detail::ignore_unused(unused);\n  }\n  fstring(runtime_format_string<> fmt) : str(fmt.str) {}\n\n  // Returning by reference generates better code in debug mode.\n  FMT_ALWAYS_INLINE operator const string_view&() const { return str; }\n  auto get() const -> string_view { return str; }\n};\n\ntemplate <typename... T> using format_string = typename fstring<T...>::t;\n\ntemplate <typename T, typename Char = char>\nusing is_formattable = bool_constant<!std::is_same<\n    detail::mapped_t<conditional_t<std::is_void<T>::value, int*, T>, Char>,\n    void>::value>;\n#ifdef __cpp_concepts\ntemplate <typename T, typename Char = char>\nconcept formattable = is_formattable<remove_reference_t<T>, Char>::value;\n#endif\n\n// A formatter specialization for natively supported types.\ntemplate <typename T, typename Char>\nstruct formatter<T, Char,\n                 enable_if_t<detail::type_constant<T, Char>::value !=\n                             detail::type::custom_type>>\n    : detail::native_formatter<T, Char, detail::type_constant<T, Char>::value> {\n};\n\n/**\n * Constructs an object that stores references to arguments and can be\n * implicitly converted to `format_args`. `Context` can be omitted in which case\n * it defaults to `context`. See `arg` for lifetime considerations.\n */\n// Take arguments by lvalue references to avoid some lifetime issues, e.g.\n//   auto args = make_format_args(std::string());\ntemplate <typename Context = context, typename... T,\n          int NUM_ARGS = sizeof...(T),\n          int NUM_NAMED_ARGS = detail::count_named_args<T...>(),\n          unsigned long long DESC = detail::make_descriptor<Context, T...>()>\nconstexpr FMT_ALWAYS_INLINE auto make_format_args(T&... args)\n    -> detail::format_arg_store<Context, NUM_ARGS, NUM_NAMED_ARGS, DESC> {\n  // Suppress warnings for pathological types convertible to detail::value.\n  FMT_PRAGMA_GCC(diagnostic ignored \"-Wconversion\")\n  return {{args...}};\n}\n\ntemplate <typename... T>\nusing vargs =\n    detail::format_arg_store<context, sizeof...(T),\n                             detail::count_named_args<T...>(),\n                             detail::make_descriptor<context, T...>()>;\n\n/**\n * Returns a named argument to be used in a formatting function.\n * It should only be used in a call to a formatting function.\n *\n * **Example**:\n *\n *     fmt::print(\"The answer is {answer}.\", fmt::arg(\"answer\", 42));\n */\ntemplate <typename Char, typename T>\ninline auto arg(const Char* name, const T& arg) -> detail::named_arg<Char, T> {\n  return {name, arg};\n}\n\n/// Formats a string and writes the output to `out`.\ntemplate <typename OutputIt,\n          FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,\n                                                   char>::value)>\nauto vformat_to(OutputIt&& out, string_view fmt, format_args args)\n    -> remove_cvref_t<OutputIt> {\n  auto&& buf = detail::get_buffer<char>(out);\n  detail::vformat_to(buf, fmt, args, {});\n  return detail::get_iterator(buf, out);\n}\n\n/**\n * Formats `args` according to specifications in `fmt`, writes the result to\n * the output iterator `out` and returns the iterator past the end of the output\n * range. `format_to` does not append a terminating null character.\n *\n * **Example**:\n *\n *     auto out = std::vector<char>();\n *     fmt::format_to(std::back_inserter(out), \"{}\", 42);\n */\ntemplate <typename OutputIt, typename... T,\n          FMT_ENABLE_IF(detail::is_output_iterator<remove_cvref_t<OutputIt>,\n                                                   char>::value)>\nFMT_INLINE auto format_to(OutputIt&& out, format_string<T...> fmt, T&&... args)\n    -> remove_cvref_t<OutputIt> {\n  return vformat_to(out, fmt.str, vargs<T...>{{args...}});\n}\n\ntemplate <typename OutputIt> struct format_to_n_result {\n  /// Iterator past the end of the output range.\n  OutputIt out;\n  /// Total (not truncated) output size.\n  size_t size;\n};\n\ntemplate <typename OutputIt, typename... T,\n          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>\nauto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args)\n    -> format_to_n_result<OutputIt> {\n  using traits = detail::fixed_buffer_traits;\n  auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n);\n  detail::vformat_to(buf, fmt, args, {});\n  return {buf.out(), buf.count()};\n}\n\n/**\n * Formats `args` according to specifications in `fmt`, writes up to `n`\n * characters of the result to the output iterator `out` and returns the total\n * (not truncated) output size and the iterator past the end of the output\n * range. `format_to_n` does not append a terminating null character.\n */\ntemplate <typename OutputIt, typename... T,\n          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>\nFMT_INLINE auto format_to_n(OutputIt out, size_t n, format_string<T...> fmt,\n                            T&&... args) -> format_to_n_result<OutputIt> {\n  return vformat_to_n(out, n, fmt.str, vargs<T...>{{args...}});\n}\n\nstruct format_to_result {\n  /// Pointer to just after the last successful write in the array.\n  char* out;\n  /// Specifies if the output was truncated.\n  bool truncated;\n\n  FMT_CONSTEXPR operator char*() const {\n    // Report truncation to prevent silent data loss.\n    if (truncated) report_error(\"output is truncated\");\n    return out;\n  }\n};\n\ntemplate <size_t N>\nauto vformat_to(char (&out)[N], string_view fmt, format_args args)\n    -> format_to_result {\n  auto result = vformat_to_n(out, N, fmt, args);\n  return {result.out, result.size > N};\n}\n\ntemplate <size_t N, typename... T>\nFMT_INLINE auto format_to(char (&out)[N], format_string<T...> fmt, T&&... args)\n    -> format_to_result {\n  auto result = vformat_to_n(out, N, fmt.str, vargs<T...>{{args...}});\n  return {result.out, result.size > N};\n}\n\n/// Returns the number of chars in the output of `format(fmt, args...)`.\ntemplate <typename... T>\nFMT_NODISCARD FMT_INLINE auto formatted_size(format_string<T...> fmt,\n                                             T&&... args) -> size_t {\n  auto buf = detail::counting_buffer<>();\n  detail::vformat_to(buf, fmt.str, vargs<T...>{{args...}}, {});\n  return buf.count();\n}\n\nFMT_API void vprint(string_view fmt, format_args args);\nFMT_API void vprint(FILE* f, string_view fmt, format_args args);\nFMT_API void vprintln(FILE* f, string_view fmt, format_args args);\nFMT_API void vprint_buffered(FILE* f, string_view fmt, format_args args);\n\n/**\n * Formats `args` according to specifications in `fmt` and writes the output\n * to `stdout`.\n *\n * **Example**:\n *\n *     fmt::print(\"The answer is {}.\", 42);\n */\ntemplate <typename... T>\nFMT_INLINE void print(format_string<T...> fmt, T&&... args) {\n  vargs<T...> va = {{args...}};\n  if (detail::const_check(!detail::use_utf8))\n    return detail::vprint_mojibake(stdout, fmt.str, va, false);\n  return detail::is_locking<T...>() ? vprint_buffered(stdout, fmt.str, va)\n                                    : vprint(fmt.str, va);\n}\n\n/**\n * Formats `args` according to specifications in `fmt` and writes the\n * output to the file `f`.\n *\n * **Example**:\n *\n *     fmt::print(stderr, \"Don't {}!\", \"panic\");\n */\ntemplate <typename... T>\nFMT_INLINE void print(FILE* f, format_string<T...> fmt, T&&... args) {\n  vargs<T...> va = {{args...}};\n  if (detail::const_check(!detail::use_utf8))\n    return detail::vprint_mojibake(f, fmt.str, va, false);\n  return detail::is_locking<T...>() ? vprint_buffered(f, fmt.str, va)\n                                    : vprint(f, fmt.str, va);\n}\n\n/// Formats `args` according to specifications in `fmt` and writes the output\n/// to the file `f` followed by a newline.\ntemplate <typename... T>\nFMT_INLINE void println(FILE* f, format_string<T...> fmt, T&&... args) {\n  vargs<T...> va = {{args...}};\n  return detail::const_check(detail::use_utf8)\n             ? vprintln(f, fmt.str, va)\n             : detail::vprint_mojibake(f, fmt.str, va, true);\n}\n\n/// Formats `args` according to specifications in `fmt` and writes the output\n/// to `stdout` followed by a newline.\ntemplate <typename... T>\nFMT_INLINE void println(format_string<T...> fmt, T&&... args) {\n  return fmt::println(stdout, fmt, static_cast<T&&>(args)...);\n}\n\nFMT_PRAGMA_GCC(diagnostic pop)\nFMT_PRAGMA_CLANG(diagnostic pop)\nFMT_PRAGMA_GCC(pop_options)\nFMT_END_EXPORT\nFMT_END_NAMESPACE\n\n#ifdef FMT_HEADER_ONLY\n#  include \"format.h\"\n#endif\n#endif  // FMT_BASE_H_\n"
  },
  {
    "path": "thirdparty/fmt/include/fmt/chrono.h",
    "content": "// Formatting library for C++ - chrono support\n//\n// Copyright (c) 2012 - present, Victor Zverovich\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\n#ifndef FMT_CHRONO_H_\n#define FMT_CHRONO_H_\n\n#ifndef FMT_MODULE\n#  include <algorithm>\n#  include <chrono>\n#  include <cmath>    // std::isfinite\n#  include <cstring>  // std::memcpy\n#  include <ctime>\n#  include <iterator>\n#  include <locale>\n#  include <ostream>\n#  include <type_traits>\n#endif\n\n#include \"format.h\"\n\nFMT_BEGIN_NAMESPACE\n\n// Enable safe chrono durations, unless explicitly disabled.\n#ifndef FMT_SAFE_DURATION_CAST\n#  define FMT_SAFE_DURATION_CAST 1\n#endif\n#if FMT_SAFE_DURATION_CAST\n\n// For conversion between std::chrono::durations without undefined\n// behaviour or erroneous results.\n// This is a stripped down version of duration_cast, for inclusion in fmt.\n// See https://github.com/pauldreik/safe_duration_cast\n//\n// Copyright Paul Dreik 2019\nnamespace safe_duration_cast {\n\n// DEPRECATED!\ntemplate <typename To, typename From,\n          FMT_ENABLE_IF(!std::is_same<From, To>::value &&\n                        std::numeric_limits<From>::is_signed ==\n                            std::numeric_limits<To>::is_signed)>\nFMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec)\n    -> To {\n  ec = 0;\n  using F = std::numeric_limits<From>;\n  using T = std::numeric_limits<To>;\n  static_assert(F::is_integer, \"From must be integral\");\n  static_assert(T::is_integer, \"To must be integral\");\n\n  // A and B are both signed, or both unsigned.\n  if (detail::const_check(F::digits <= T::digits)) {\n    // From fits in To without any problem.\n  } else {\n    // From does not always fit in To, resort to a dynamic check.\n    if (from < (T::min)() || from > (T::max)()) {\n      // outside range.\n      ec = 1;\n      return {};\n    }\n  }\n  return static_cast<To>(from);\n}\n\n/// Converts From to To, without loss. If the dynamic value of from\n/// can't be converted to To without loss, ec is set.\ntemplate <typename To, typename From,\n          FMT_ENABLE_IF(!std::is_same<From, To>::value &&\n                        std::numeric_limits<From>::is_signed !=\n                            std::numeric_limits<To>::is_signed)>\nFMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec)\n    -> To {\n  ec = 0;\n  using F = std::numeric_limits<From>;\n  using T = std::numeric_limits<To>;\n  static_assert(F::is_integer, \"From must be integral\");\n  static_assert(T::is_integer, \"To must be integral\");\n\n  if (detail::const_check(F::is_signed && !T::is_signed)) {\n    // From may be negative, not allowed!\n    if (fmt::detail::is_negative(from)) {\n      ec = 1;\n      return {};\n    }\n    // From is positive. Can it always fit in To?\n    if (detail::const_check(F::digits > T::digits) &&\n        from > static_cast<From>(detail::max_value<To>())) {\n      ec = 1;\n      return {};\n    }\n  }\n\n  if (detail::const_check(!F::is_signed && T::is_signed &&\n                          F::digits >= T::digits) &&\n      from > static_cast<From>(detail::max_value<To>())) {\n    ec = 1;\n    return {};\n  }\n  return static_cast<To>(from);  // Lossless conversion.\n}\n\ntemplate <typename To, typename From,\n          FMT_ENABLE_IF(std::is_same<From, To>::value)>\nFMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec)\n    -> To {\n  ec = 0;\n  return from;\n}  // function\n\n// clang-format off\n/**\n * converts From to To if possible, otherwise ec is set.\n *\n * input                            |    output\n * ---------------------------------|---------------\n * NaN                              | NaN\n * Inf                              | Inf\n * normal, fits in output           | converted (possibly lossy)\n * normal, does not fit in output   | ec is set\n * subnormal                        | best effort\n * -Inf                             | -Inf\n */\n// clang-format on\ntemplate <typename To, typename From,\n          FMT_ENABLE_IF(!std::is_same<From, To>::value)>\nFMT_CONSTEXPR auto safe_float_conversion(const From from, int& ec) -> To {\n  ec = 0;\n  using T = std::numeric_limits<To>;\n  static_assert(std::is_floating_point<From>::value, \"From must be floating\");\n  static_assert(std::is_floating_point<To>::value, \"To must be floating\");\n\n  // catch the only happy case\n  if (std::isfinite(from)) {\n    if (from >= T::lowest() && from <= (T::max)()) {\n      return static_cast<To>(from);\n    }\n    // not within range.\n    ec = 1;\n    return {};\n  }\n\n  // nan and inf will be preserved\n  return static_cast<To>(from);\n}  // function\n\ntemplate <typename To, typename From,\n          FMT_ENABLE_IF(std::is_same<From, To>::value)>\nFMT_CONSTEXPR auto safe_float_conversion(const From from, int& ec) -> To {\n  ec = 0;\n  static_assert(std::is_floating_point<From>::value, \"From must be floating\");\n  return from;\n}\n\n/// Safe duration_cast between floating point durations\ntemplate <typename To, typename FromRep, typename FromPeriod,\n          FMT_ENABLE_IF(std::is_floating_point<FromRep>::value),\n          FMT_ENABLE_IF(std::is_floating_point<typename To::rep>::value)>\nauto safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,\n                        int& ec) -> To {\n  using From = std::chrono::duration<FromRep, FromPeriod>;\n  ec = 0;\n\n  // the basic idea is that we need to convert from count() in the from type\n  // to count() in the To type, by multiplying it with this:\n  struct Factor\n      : std::ratio_divide<typename From::period, typename To::period> {};\n\n  static_assert(Factor::num > 0, \"num must be positive\");\n  static_assert(Factor::den > 0, \"den must be positive\");\n\n  // the conversion is like this: multiply from.count() with Factor::num\n  // /Factor::den and convert it to To::rep, all this without\n  // overflow/underflow. let's start by finding a suitable type that can hold\n  // both To, From and Factor::num\n  using IntermediateRep =\n      typename std::common_type<typename From::rep, typename To::rep,\n                                decltype(Factor::num)>::type;\n\n  // force conversion of From::rep -> IntermediateRep to be safe,\n  // even if it will never happen be narrowing in this context.\n  IntermediateRep count =\n      safe_float_conversion<IntermediateRep>(from.count(), ec);\n  if (ec) {\n    return {};\n  }\n\n  // multiply with Factor::num without overflow or underflow\n  if (detail::const_check(Factor::num != 1)) {\n    constexpr auto max1 = detail::max_value<IntermediateRep>() /\n                          static_cast<IntermediateRep>(Factor::num);\n    if (count > max1) {\n      ec = 1;\n      return {};\n    }\n    constexpr auto min1 = std::numeric_limits<IntermediateRep>::lowest() /\n                          static_cast<IntermediateRep>(Factor::num);\n    if (count < min1) {\n      ec = 1;\n      return {};\n    }\n    count *= static_cast<IntermediateRep>(Factor::num);\n  }\n\n  // this can't go wrong, right? den>0 is checked earlier.\n  if (detail::const_check(Factor::den != 1)) {\n    using common_t = typename std::common_type<IntermediateRep, intmax_t>::type;\n    count /= static_cast<common_t>(Factor::den);\n  }\n\n  // convert to the to type, safely\n  using ToRep = typename To::rep;\n\n  const ToRep tocount = safe_float_conversion<ToRep>(count, ec);\n  if (ec) {\n    return {};\n  }\n  return To{tocount};\n}\n}  // namespace safe_duration_cast\n#endif\n\nnamespace detail {\n\n// Check if std::chrono::utc_time is available.\n#ifdef FMT_USE_UTC_TIME\n// Use the provided definition.\n#elif defined(__cpp_lib_chrono)\n#  define FMT_USE_UTC_TIME (__cpp_lib_chrono >= 201907L)\n#else\n#  define FMT_USE_UTC_TIME 0\n#endif\n#if FMT_USE_UTC_TIME\nusing utc_clock = std::chrono::utc_clock;\n#else\nstruct utc_clock {\n  template <typename T> void to_sys(T);\n};\n#endif\n\n// Check if std::chrono::local_time is available.\n#ifdef FMT_USE_LOCAL_TIME\n// Use the provided definition.\n#elif defined(__cpp_lib_chrono)\n#  define FMT_USE_LOCAL_TIME (__cpp_lib_chrono >= 201907L)\n#else\n#  define FMT_USE_LOCAL_TIME 0\n#endif\n#if FMT_USE_LOCAL_TIME\nusing local_t = std::chrono::local_t;\n#else\nstruct local_t {};\n#endif\n\n}  // namespace detail\n\ntemplate <typename Duration>\nusing sys_time = std::chrono::time_point<std::chrono::system_clock, Duration>;\n\ntemplate <typename Duration>\nusing utc_time = std::chrono::time_point<detail::utc_clock, Duration>;\n\ntemplate <class Duration>\nusing local_time = std::chrono::time_point<detail::local_t, Duration>;\n\nnamespace detail {\n\n// Prevents expansion of a preceding token as a function-style macro.\n// Usage: f FMT_NOMACRO()\n#define FMT_NOMACRO\n\ntemplate <typename T = void> struct null {};\ninline auto gmtime_r(...) -> null<> { return null<>(); }\ninline auto gmtime_s(...) -> null<> { return null<>(); }\n\n// It is defined here and not in ostream.h because the latter has expensive\n// includes.\ntemplate <typename StreamBuf> class formatbuf : public StreamBuf {\n private:\n  using char_type = typename StreamBuf::char_type;\n  using streamsize = decltype(std::declval<StreamBuf>().sputn(nullptr, 0));\n  using int_type = typename StreamBuf::int_type;\n  using traits_type = typename StreamBuf::traits_type;\n\n  buffer<char_type>& buffer_;\n\n public:\n  explicit formatbuf(buffer<char_type>& buf) : buffer_(buf) {}\n\n protected:\n  // The put area is always empty. This makes the implementation simpler and has\n  // the advantage that the streambuf and the buffer are always in sync and\n  // sputc never writes into uninitialized memory. A disadvantage is that each\n  // call to sputc always results in a (virtual) call to overflow. There is no\n  // disadvantage here for sputn since this always results in a call to xsputn.\n\n  auto overflow(int_type ch) -> int_type override {\n    if (!traits_type::eq_int_type(ch, traits_type::eof()))\n      buffer_.push_back(static_cast<char_type>(ch));\n    return ch;\n  }\n\n  auto xsputn(const char_type* s, streamsize count) -> streamsize override {\n    buffer_.append(s, s + count);\n    return count;\n  }\n};\n\ninline auto get_classic_locale() -> const std::locale& {\n  static const auto& locale = std::locale::classic();\n  return locale;\n}\n\ntemplate <typename CodeUnit> struct codecvt_result {\n  static constexpr size_t max_size = 32;\n  CodeUnit buf[max_size];\n  CodeUnit* end;\n};\n\ntemplate <typename CodeUnit>\nvoid write_codecvt(codecvt_result<CodeUnit>& out, string_view in,\n                   const std::locale& loc) {\n  FMT_PRAGMA_CLANG(diagnostic push)\n  FMT_PRAGMA_CLANG(diagnostic ignored \"-Wdeprecated\")\n  auto& f = std::use_facet<std::codecvt<CodeUnit, char, std::mbstate_t>>(loc);\n  FMT_PRAGMA_CLANG(diagnostic pop)\n  auto mb = std::mbstate_t();\n  const char* from_next = nullptr;\n  auto result = f.in(mb, in.begin(), in.end(), from_next, std::begin(out.buf),\n                     std::end(out.buf), out.end);\n  if (result != std::codecvt_base::ok)\n    FMT_THROW(format_error(\"failed to format time\"));\n}\n\ntemplate <typename OutputIt>\nauto write_encoded_tm_str(OutputIt out, string_view in, const std::locale& loc)\n    -> OutputIt {\n  if (const_check(detail::use_utf8) && loc != get_classic_locale()) {\n    // char16_t and char32_t codecvts are broken in MSVC (linkage errors) and\n    // gcc-4.\n#if FMT_MSC_VERSION != 0 ||  \\\n    (defined(__GLIBCXX__) && \\\n     (!defined(_GLIBCXX_USE_DUAL_ABI) || _GLIBCXX_USE_DUAL_ABI == 0))\n    // The _GLIBCXX_USE_DUAL_ABI macro is always defined in libstdc++ from gcc-5\n    // and newer.\n    using code_unit = wchar_t;\n#else\n    using code_unit = char32_t;\n#endif\n\n    using unit_t = codecvt_result<code_unit>;\n    unit_t unit;\n    write_codecvt(unit, in, loc);\n    // In UTF-8 is used one to four one-byte code units.\n    auto u =\n        to_utf8<code_unit, basic_memory_buffer<char, unit_t::max_size * 4>>();\n    if (!u.convert({unit.buf, to_unsigned(unit.end - unit.buf)}))\n      FMT_THROW(format_error(\"failed to format time\"));\n    return copy<char>(u.c_str(), u.c_str() + u.size(), out);\n  }\n  return copy<char>(in.data(), in.data() + in.size(), out);\n}\n\ntemplate <typename Char, typename OutputIt,\n          FMT_ENABLE_IF(!std::is_same<Char, char>::value)>\nauto write_tm_str(OutputIt out, string_view sv, const std::locale& loc)\n    -> OutputIt {\n  codecvt_result<Char> unit;\n  write_codecvt(unit, sv, loc);\n  return copy<Char>(unit.buf, unit.end, out);\n}\n\ntemplate <typename Char, typename OutputIt,\n          FMT_ENABLE_IF(std::is_same<Char, char>::value)>\nauto write_tm_str(OutputIt out, string_view sv, const std::locale& loc)\n    -> OutputIt {\n  return write_encoded_tm_str(out, sv, loc);\n}\n\ntemplate <typename Char>\ninline void do_write(buffer<Char>& buf, const std::tm& time,\n                     const std::locale& loc, char format, char modifier) {\n  auto&& format_buf = formatbuf<std::basic_streambuf<Char>>(buf);\n  auto&& os = std::basic_ostream<Char>(&format_buf);\n  os.imbue(loc);\n  const auto& facet = std::use_facet<std::time_put<Char>>(loc);\n  auto end = facet.put(os, os, Char(' '), &time, format, modifier);\n  if (end.failed()) FMT_THROW(format_error(\"failed to format time\"));\n}\n\ntemplate <typename Char, typename OutputIt,\n          FMT_ENABLE_IF(!std::is_same<Char, char>::value)>\nauto write(OutputIt out, const std::tm& time, const std::locale& loc,\n           char format, char modifier = 0) -> OutputIt {\n  auto&& buf = get_buffer<Char>(out);\n  do_write<Char>(buf, time, loc, format, modifier);\n  return get_iterator(buf, out);\n}\n\ntemplate <typename Char, typename OutputIt,\n          FMT_ENABLE_IF(std::is_same<Char, char>::value)>\nauto write(OutputIt out, const std::tm& time, const std::locale& loc,\n           char format, char modifier = 0) -> OutputIt {\n  auto&& buf = basic_memory_buffer<Char>();\n  do_write<char>(buf, time, loc, format, modifier);\n  return write_encoded_tm_str(out, string_view(buf.data(), buf.size()), loc);\n}\n\ntemplate <typename T, typename U>\nusing is_similar_arithmetic_type =\n    bool_constant<(std::is_integral<T>::value && std::is_integral<U>::value) ||\n                  (std::is_floating_point<T>::value &&\n                   std::is_floating_point<U>::value)>;\n\nFMT_NORETURN inline void throw_duration_error() {\n  FMT_THROW(format_error(\"cannot format duration\"));\n}\n\n// Cast one integral duration to another with an overflow check.\ntemplate <typename To, typename FromRep, typename FromPeriod,\n          FMT_ENABLE_IF(std::is_integral<FromRep>::value&&\n                            std::is_integral<typename To::rep>::value)>\nauto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {\n#if !FMT_SAFE_DURATION_CAST\n  return std::chrono::duration_cast<To>(from);\n#else\n  // The conversion factor: to.count() == factor * from.count().\n  using factor = std::ratio_divide<FromPeriod, typename To::period>;\n\n  using common_rep = typename std::common_type<FromRep, typename To::rep,\n                                               decltype(factor::num)>::type;\n  common_rep count = from.count();  // This conversion is lossless.\n\n  // Multiply from.count() by factor and check for overflow.\n  if (const_check(factor::num != 1)) {\n    if (count > max_value<common_rep>() / factor::num) throw_duration_error();\n    const auto min = (std::numeric_limits<common_rep>::min)() / factor::num;\n    if (const_check(!std::is_unsigned<common_rep>::value) && count < min)\n      throw_duration_error();\n    count *= factor::num;\n  }\n  if (const_check(factor::den != 1)) count /= factor::den;\n  int ec = 0;\n  auto to =\n      To(safe_duration_cast::lossless_integral_conversion<typename To::rep>(\n          count, ec));\n  if (ec) throw_duration_error();\n  return to;\n#endif\n}\n\ntemplate <typename To, typename FromRep, typename FromPeriod,\n          FMT_ENABLE_IF(std::is_floating_point<FromRep>::value&&\n                            std::is_floating_point<typename To::rep>::value)>\nauto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {\n#if FMT_SAFE_DURATION_CAST\n  // Preserve infinity and NaN.\n  if (!isfinite(from.count())) return static_cast<To>(from.count());\n  // Throwing version of safe_duration_cast is only available for\n  // integer to integer or float to float casts.\n  int ec;\n  To to = safe_duration_cast::safe_duration_cast<To>(from, ec);\n  if (ec) throw_duration_error();\n  return to;\n#else\n  // Standard duration cast, may overflow.\n  return std::chrono::duration_cast<To>(from);\n#endif\n}\n\ntemplate <typename To, typename FromRep, typename FromPeriod,\n          FMT_ENABLE_IF(\n              !is_similar_arithmetic_type<FromRep, typename To::rep>::value)>\nauto duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {\n  // Mixed integer <-> float cast is not supported by safe duration_cast.\n  return std::chrono::duration_cast<To>(from);\n}\n\ntemplate <typename Duration>\nauto to_time_t(sys_time<Duration> time_point) -> std::time_t {\n  // Cannot use std::chrono::system_clock::to_time_t since this would first\n  // require a cast to std::chrono::system_clock::time_point, which could\n  // overflow.\n  return detail::duration_cast<std::chrono::duration<std::time_t>>(\n             time_point.time_since_epoch())\n      .count();\n}\n\n}  // namespace detail\n\nFMT_BEGIN_EXPORT\n\n/**\n * Converts given time since epoch as `std::time_t` value into calendar time,\n * expressed in Coordinated Universal Time (UTC). Unlike `std::gmtime`, this\n * function is thread-safe on most platforms.\n */\ninline auto gmtime(std::time_t time) -> std::tm {\n  struct dispatcher {\n    std::time_t time_;\n    std::tm tm_;\n\n    inline dispatcher(std::time_t t) : time_(t) {}\n\n    inline auto run() -> bool {\n      using namespace fmt::detail;\n      return handle(gmtime_r(&time_, &tm_));\n    }\n\n    inline auto handle(std::tm* tm) -> bool { return tm != nullptr; }\n\n    inline auto handle(detail::null<>) -> bool {\n      using namespace fmt::detail;\n      return fallback(gmtime_s(&tm_, &time_));\n    }\n\n    inline auto fallback(int res) -> bool { return res == 0; }\n\n#if !FMT_MSC_VERSION\n    inline auto fallback(detail::null<>) -> bool {\n      std::tm* tm = std::gmtime(&time_);\n      if (tm) tm_ = *tm;\n      return tm != nullptr;\n    }\n#endif\n  };\n  auto gt = dispatcher(time);\n  // Too big time values may be unsupported.\n  if (!gt.run()) FMT_THROW(format_error(\"time_t value out of range\"));\n  return gt.tm_;\n}\n\ntemplate <typename Duration>\ninline auto gmtime(sys_time<Duration> time_point) -> std::tm {\n  return gmtime(detail::to_time_t(time_point));\n}\n\nnamespace detail {\n\n// Writes two-digit numbers a, b and c separated by sep to buf.\n// The method by Pavel Novikov based on\n// https://johnnylee-sde.github.io/Fast-unsigned-integer-to-time-string/.\ninline void write_digit2_separated(char* buf, unsigned a, unsigned b,\n                                   unsigned c, char sep) {\n  unsigned long long digits =\n      a | (b << 24) | (static_cast<unsigned long long>(c) << 48);\n  // Convert each value to BCD.\n  // We have x = a * 10 + b and we want to convert it to BCD y = a * 16 + b.\n  // The difference is\n  //   y - x = a * 6\n  // a can be found from x:\n  //   a = floor(x / 10)\n  // then\n  //   y = x + a * 6 = x + floor(x / 10) * 6\n  // floor(x / 10) is (x * 205) >> 11 (needs 16 bits).\n  digits += (((digits * 205) >> 11) & 0x000f00000f00000f) * 6;\n  // Put low nibbles to high bytes and high nibbles to low bytes.\n  digits = ((digits & 0x00f00000f00000f0) >> 4) |\n           ((digits & 0x000f00000f00000f) << 8);\n  auto usep = static_cast<unsigned long long>(sep);\n  // Add ASCII '0' to each digit byte and insert separators.\n  digits |= 0x3030003030003030 | (usep << 16) | (usep << 40);\n\n  constexpr size_t len = 8;\n  if (const_check(is_big_endian())) {\n    char tmp[len];\n    std::memcpy(tmp, &digits, len);\n    std::reverse_copy(tmp, tmp + len, buf);\n  } else {\n    std::memcpy(buf, &digits, len);\n  }\n}\n\ntemplate <typename Period>\nFMT_CONSTEXPR inline auto get_units() -> const char* {\n  if (std::is_same<Period, std::atto>::value) return \"as\";\n  if (std::is_same<Period, std::femto>::value) return \"fs\";\n  if (std::is_same<Period, std::pico>::value) return \"ps\";\n  if (std::is_same<Period, std::nano>::value) return \"ns\";\n  if (std::is_same<Period, std::micro>::value)\n    return detail::use_utf8 ? \"µs\" : \"us\";\n  if (std::is_same<Period, std::milli>::value) return \"ms\";\n  if (std::is_same<Period, std::centi>::value) return \"cs\";\n  if (std::is_same<Period, std::deci>::value) return \"ds\";\n  if (std::is_same<Period, std::ratio<1>>::value) return \"s\";\n  if (std::is_same<Period, std::deca>::value) return \"das\";\n  if (std::is_same<Period, std::hecto>::value) return \"hs\";\n  if (std::is_same<Period, std::kilo>::value) return \"ks\";\n  if (std::is_same<Period, std::mega>::value) return \"Ms\";\n  if (std::is_same<Period, std::giga>::value) return \"Gs\";\n  if (std::is_same<Period, std::tera>::value) return \"Ts\";\n  if (std::is_same<Period, std::peta>::value) return \"Ps\";\n  if (std::is_same<Period, std::exa>::value) return \"Es\";\n  if (std::is_same<Period, std::ratio<60>>::value) return \"min\";\n  if (std::is_same<Period, std::ratio<3600>>::value) return \"h\";\n  if (std::is_same<Period, std::ratio<86400>>::value) return \"d\";\n  return nullptr;\n}\n\nenum class numeric_system {\n  standard,\n  // Alternative numeric system, e.g. 十二 instead of 12 in ja_JP locale.\n  alternative\n};\n\n// Glibc extensions for formatting numeric values.\nenum class pad_type {\n  // Pad a numeric result string with zeros (the default).\n  zero,\n  // Do not pad a numeric result string.\n  none,\n  // Pad a numeric result string with spaces.\n  space,\n};\n\ntemplate <typename OutputIt>\nauto write_padding(OutputIt out, pad_type pad, int width) -> OutputIt {\n  if (pad == pad_type::none) return out;\n  return detail::fill_n(out, width, pad == pad_type::space ? ' ' : '0');\n}\n\ntemplate <typename OutputIt>\nauto write_padding(OutputIt out, pad_type pad) -> OutputIt {\n  if (pad != pad_type::none) *out++ = pad == pad_type::space ? ' ' : '0';\n  return out;\n}\n\n// Parses a put_time-like format string and invokes handler actions.\ntemplate <typename Char, typename Handler>\nFMT_CONSTEXPR auto parse_chrono_format(const Char* begin, const Char* end,\n                                       Handler&& handler) -> const Char* {\n  if (begin == end || *begin == '}') return begin;\n  if (*begin != '%') FMT_THROW(format_error(\"invalid format\"));\n  auto ptr = begin;\n  while (ptr != end) {\n    pad_type pad = pad_type::zero;\n    auto c = *ptr;\n    if (c == '}') break;\n    if (c != '%') {\n      ++ptr;\n      continue;\n    }\n    if (begin != ptr) handler.on_text(begin, ptr);\n    ++ptr;  // consume '%'\n    if (ptr == end) FMT_THROW(format_error(\"invalid format\"));\n    c = *ptr;\n    switch (c) {\n    case '_':\n      pad = pad_type::space;\n      ++ptr;\n      break;\n    case '-':\n      pad = pad_type::none;\n      ++ptr;\n      break;\n    }\n    if (ptr == end) FMT_THROW(format_error(\"invalid format\"));\n    c = *ptr++;\n    switch (c) {\n    case '%': handler.on_text(ptr - 1, ptr); break;\n    case 'n': {\n      const Char newline[] = {'\\n'};\n      handler.on_text(newline, newline + 1);\n      break;\n    }\n    case 't': {\n      const Char tab[] = {'\\t'};\n      handler.on_text(tab, tab + 1);\n      break;\n    }\n    // Year:\n    case 'Y': handler.on_year(numeric_system::standard, pad); break;\n    case 'y': handler.on_short_year(numeric_system::standard); break;\n    case 'C': handler.on_century(numeric_system::standard); break;\n    case 'G': handler.on_iso_week_based_year(); break;\n    case 'g': handler.on_iso_week_based_short_year(); break;\n    // Day of the week:\n    case 'a': handler.on_abbr_weekday(); break;\n    case 'A': handler.on_full_weekday(); break;\n    case 'w': handler.on_dec0_weekday(numeric_system::standard); break;\n    case 'u': handler.on_dec1_weekday(numeric_system::standard); break;\n    // Month:\n    case 'b':\n    case 'h': handler.on_abbr_month(); break;\n    case 'B': handler.on_full_month(); break;\n    case 'm': handler.on_dec_month(numeric_system::standard, pad); break;\n    // Day of the year/month:\n    case 'U':\n      handler.on_dec0_week_of_year(numeric_system::standard, pad);\n      break;\n    case 'W':\n      handler.on_dec1_week_of_year(numeric_system::standard, pad);\n      break;\n    case 'V': handler.on_iso_week_of_year(numeric_system::standard, pad); break;\n    case 'j': handler.on_day_of_year(pad); break;\n    case 'd': handler.on_day_of_month(numeric_system::standard, pad); break;\n    case 'e':\n      handler.on_day_of_month(numeric_system::standard, pad_type::space);\n      break;\n    // Hour, minute, second:\n    case 'H': handler.on_24_hour(numeric_system::standard, pad); break;\n    case 'I': handler.on_12_hour(numeric_system::standard, pad); break;\n    case 'M': handler.on_minute(numeric_system::standard, pad); break;\n    case 'S': handler.on_second(numeric_system::standard, pad); break;\n    // Other:\n    case 'c': handler.on_datetime(numeric_system::standard); break;\n    case 'x': handler.on_loc_date(numeric_system::standard); break;\n    case 'X': handler.on_loc_time(numeric_system::standard); break;\n    case 'D': handler.on_us_date(); break;\n    case 'F': handler.on_iso_date(); break;\n    case 'r': handler.on_12_hour_time(); break;\n    case 'R': handler.on_24_hour_time(); break;\n    case 'T': handler.on_iso_time(); break;\n    case 'p': handler.on_am_pm(); break;\n    case 'Q': handler.on_duration_value(); break;\n    case 'q': handler.on_duration_unit(); break;\n    case 'z': handler.on_utc_offset(numeric_system::standard); break;\n    case 'Z': handler.on_tz_name(); break;\n    // Alternative representation:\n    case 'E': {\n      if (ptr == end) FMT_THROW(format_error(\"invalid format\"));\n      c = *ptr++;\n      switch (c) {\n      case 'Y': handler.on_year(numeric_system::alternative, pad); break;\n      case 'y': handler.on_offset_year(); break;\n      case 'C': handler.on_century(numeric_system::alternative); break;\n      case 'c': handler.on_datetime(numeric_system::alternative); break;\n      case 'x': handler.on_loc_date(numeric_system::alternative); break;\n      case 'X': handler.on_loc_time(numeric_system::alternative); break;\n      case 'z': handler.on_utc_offset(numeric_system::alternative); break;\n      default:  FMT_THROW(format_error(\"invalid format\"));\n      }\n      break;\n    }\n    case 'O':\n      if (ptr == end) FMT_THROW(format_error(\"invalid format\"));\n      c = *ptr++;\n      switch (c) {\n      case 'y': handler.on_short_year(numeric_system::alternative); break;\n      case 'm': handler.on_dec_month(numeric_system::alternative, pad); break;\n      case 'U':\n        handler.on_dec0_week_of_year(numeric_system::alternative, pad);\n        break;\n      case 'W':\n        handler.on_dec1_week_of_year(numeric_system::alternative, pad);\n        break;\n      case 'V':\n        handler.on_iso_week_of_year(numeric_system::alternative, pad);\n        break;\n      case 'd':\n        handler.on_day_of_month(numeric_system::alternative, pad);\n        break;\n      case 'e':\n        handler.on_day_of_month(numeric_system::alternative, pad_type::space);\n        break;\n      case 'w': handler.on_dec0_weekday(numeric_system::alternative); break;\n      case 'u': handler.on_dec1_weekday(numeric_system::alternative); break;\n      case 'H': handler.on_24_hour(numeric_system::alternative, pad); break;\n      case 'I': handler.on_12_hour(numeric_system::alternative, pad); break;\n      case 'M': handler.on_minute(numeric_system::alternative, pad); break;\n      case 'S': handler.on_second(numeric_system::alternative, pad); break;\n      case 'z': handler.on_utc_offset(numeric_system::alternative); break;\n      default:  FMT_THROW(format_error(\"invalid format\"));\n      }\n      break;\n    default: FMT_THROW(format_error(\"invalid format\"));\n    }\n    begin = ptr;\n  }\n  if (begin != ptr) handler.on_text(begin, ptr);\n  return ptr;\n}\n\ntemplate <typename Derived> struct null_chrono_spec_handler {\n  FMT_CONSTEXPR void unsupported() {\n    static_cast<Derived*>(this)->unsupported();\n  }\n  FMT_CONSTEXPR void on_year(numeric_system, pad_type) { unsupported(); }\n  FMT_CONSTEXPR void on_short_year(numeric_system) { unsupported(); }\n  FMT_CONSTEXPR void on_offset_year() { unsupported(); }\n  FMT_CONSTEXPR void on_century(numeric_system) { unsupported(); }\n  FMT_CONSTEXPR void on_iso_week_based_year() { unsupported(); }\n  FMT_CONSTEXPR void on_iso_week_based_short_year() { unsupported(); }\n  FMT_CONSTEXPR void on_abbr_weekday() { unsupported(); }\n  FMT_CONSTEXPR void on_full_weekday() { unsupported(); }\n  FMT_CONSTEXPR void on_dec0_weekday(numeric_system) { unsupported(); }\n  FMT_CONSTEXPR void on_dec1_weekday(numeric_system) { unsupported(); }\n  FMT_CONSTEXPR void on_abbr_month() { unsupported(); }\n  FMT_CONSTEXPR void on_full_month() { unsupported(); }\n  FMT_CONSTEXPR void on_dec_month(numeric_system, pad_type) { unsupported(); }\n  FMT_CONSTEXPR void on_dec0_week_of_year(numeric_system, pad_type) {\n    unsupported();\n  }\n  FMT_CONSTEXPR void on_dec1_week_of_year(numeric_system, pad_type) {\n    unsupported();\n  }\n  FMT_CONSTEXPR void on_iso_week_of_year(numeric_system, pad_type) {\n    unsupported();\n  }\n  FMT_CONSTEXPR void on_day_of_year(pad_type) { unsupported(); }\n  FMT_CONSTEXPR void on_day_of_month(numeric_system, pad_type) {\n    unsupported();\n  }\n  FMT_CONSTEXPR void on_24_hour(numeric_system) { unsupported(); }\n  FMT_CONSTEXPR void on_12_hour(numeric_system) { unsupported(); }\n  FMT_CONSTEXPR void on_minute(numeric_system) { unsupported(); }\n  FMT_CONSTEXPR void on_second(numeric_system) { unsupported(); }\n  FMT_CONSTEXPR void on_datetime(numeric_system) { unsupported(); }\n  FMT_CONSTEXPR void on_loc_date(numeric_system) { unsupported(); }\n  FMT_CONSTEXPR void on_loc_time(numeric_system) { unsupported(); }\n  FMT_CONSTEXPR void on_us_date() { unsupported(); }\n  FMT_CONSTEXPR void on_iso_date() { unsupported(); }\n  FMT_CONSTEXPR void on_12_hour_time() { unsupported(); }\n  FMT_CONSTEXPR void on_24_hour_time() { unsupported(); }\n  FMT_CONSTEXPR void on_iso_time() { unsupported(); }\n  FMT_CONSTEXPR void on_am_pm() { unsupported(); }\n  FMT_CONSTEXPR void on_duration_value() { unsupported(); }\n  FMT_CONSTEXPR void on_duration_unit() { unsupported(); }\n  FMT_CONSTEXPR void on_utc_offset(numeric_system) { unsupported(); }\n  FMT_CONSTEXPR void on_tz_name() { unsupported(); }\n};\n\nclass tm_format_checker : public null_chrono_spec_handler<tm_format_checker> {\n private:\n  bool has_timezone_ = false;\n\n public:\n  constexpr explicit tm_format_checker(bool has_timezone)\n      : has_timezone_(has_timezone) {}\n\n  FMT_NORETURN inline void unsupported() {\n    FMT_THROW(format_error(\"no format\"));\n  }\n\n  template <typename Char>\n  FMT_CONSTEXPR void on_text(const Char*, const Char*) {}\n  FMT_CONSTEXPR void on_year(numeric_system, pad_type) {}\n  FMT_CONSTEXPR void on_short_year(numeric_system) {}\n  FMT_CONSTEXPR void on_offset_year() {}\n  FMT_CONSTEXPR void on_century(numeric_system) {}\n  FMT_CONSTEXPR void on_iso_week_based_year() {}\n  FMT_CONSTEXPR void on_iso_week_based_short_year() {}\n  FMT_CONSTEXPR void on_abbr_weekday() {}\n  FMT_CONSTEXPR void on_full_weekday() {}\n  FMT_CONSTEXPR void on_dec0_weekday(numeric_system) {}\n  FMT_CONSTEXPR void on_dec1_weekday(numeric_system) {}\n  FMT_CONSTEXPR void on_abbr_month() {}\n  FMT_CONSTEXPR void on_full_month() {}\n  FMT_CONSTEXPR void on_dec_month(numeric_system, pad_type) {}\n  FMT_CONSTEXPR void on_dec0_week_of_year(numeric_system, pad_type) {}\n  FMT_CONSTEXPR void on_dec1_week_of_year(numeric_system, pad_type) {}\n  FMT_CONSTEXPR void on_iso_week_of_year(numeric_system, pad_type) {}\n  FMT_CONSTEXPR void on_day_of_year(pad_type) {}\n  FMT_CONSTEXPR void on_day_of_month(numeric_system, pad_type) {}\n  FMT_CONSTEXPR void on_24_hour(numeric_system, pad_type) {}\n  FMT_CONSTEXPR void on_12_hour(numeric_system, pad_type) {}\n  FMT_CONSTEXPR void on_minute(numeric_system, pad_type) {}\n  FMT_CONSTEXPR void on_second(numeric_system, pad_type) {}\n  FMT_CONSTEXPR void on_datetime(numeric_system) {}\n  FMT_CONSTEXPR void on_loc_date(numeric_system) {}\n  FMT_CONSTEXPR void on_loc_time(numeric_system) {}\n  FMT_CONSTEXPR void on_us_date() {}\n  FMT_CONSTEXPR void on_iso_date() {}\n  FMT_CONSTEXPR void on_12_hour_time() {}\n  FMT_CONSTEXPR void on_24_hour_time() {}\n  FMT_CONSTEXPR void on_iso_time() {}\n  FMT_CONSTEXPR void on_am_pm() {}\n  FMT_CONSTEXPR void on_utc_offset(numeric_system) {\n    if (!has_timezone_) FMT_THROW(format_error(\"no timezone\"));\n  }\n  FMT_CONSTEXPR void on_tz_name() {\n    if (!has_timezone_) FMT_THROW(format_error(\"no timezone\"));\n  }\n};\n\ninline auto tm_wday_full_name(int wday) -> const char* {\n  static constexpr const char* full_name_list[] = {\n      \"Sunday\",   \"Monday\", \"Tuesday\", \"Wednesday\",\n      \"Thursday\", \"Friday\", \"Saturday\"};\n  return wday >= 0 && wday <= 6 ? full_name_list[wday] : \"?\";\n}\ninline auto tm_wday_short_name(int wday) -> const char* {\n  static constexpr const char* short_name_list[] = {\"Sun\", \"Mon\", \"Tue\", \"Wed\",\n                                                    \"Thu\", \"Fri\", \"Sat\"};\n  return wday >= 0 && wday <= 6 ? short_name_list[wday] : \"???\";\n}\n\ninline auto tm_mon_full_name(int mon) -> const char* {\n  static constexpr const char* full_name_list[] = {\n      \"January\", \"February\", \"March\",     \"April\",   \"May\",      \"June\",\n      \"July\",    \"August\",   \"September\", \"October\", \"November\", \"December\"};\n  return mon >= 0 && mon <= 11 ? full_name_list[mon] : \"?\";\n}\ninline auto tm_mon_short_name(int mon) -> const char* {\n  static constexpr const char* short_name_list[] = {\n      \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\n      \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\",\n  };\n  return mon >= 0 && mon <= 11 ? short_name_list[mon] : \"???\";\n}\n\ntemplate <typename T, typename = void>\nstruct has_tm_gmtoff : std::false_type {};\ntemplate <typename T>\nstruct has_tm_gmtoff<T, void_t<decltype(T::tm_gmtoff)>> : std::true_type {};\n\ntemplate <typename T, typename = void> struct has_tm_zone : std::false_type {};\ntemplate <typename T>\nstruct has_tm_zone<T, void_t<decltype(T::tm_zone)>> : std::true_type {};\n\ntemplate <typename T, FMT_ENABLE_IF(has_tm_zone<T>::value)>\nauto set_tm_zone(T& time, char* tz) -> bool {\n  time.tm_zone = tz;\n  return true;\n}\ntemplate <typename T, FMT_ENABLE_IF(!has_tm_zone<T>::value)>\nauto set_tm_zone(T&, char*) -> bool {\n  return false;\n}\n\ninline auto utc() -> char* {\n  static char tz[] = \"UTC\";\n  return tz;\n}\n\n// Converts value to Int and checks that it's in the range [0, upper).\ntemplate <typename T, typename Int, FMT_ENABLE_IF(std::is_integral<T>::value)>\ninline auto to_nonnegative_int(T value, Int upper) -> Int {\n  if (!std::is_unsigned<Int>::value &&\n      (value < 0 || to_unsigned(value) > to_unsigned(upper))) {\n    FMT_THROW(format_error(\"chrono value is out of range\"));\n  }\n  return static_cast<Int>(value);\n}\ntemplate <typename T, typename Int, FMT_ENABLE_IF(!std::is_integral<T>::value)>\ninline auto to_nonnegative_int(T value, Int upper) -> Int {\n  auto int_value = static_cast<Int>(value);\n  if (int_value < 0 || value > static_cast<T>(upper))\n    FMT_THROW(format_error(\"invalid value\"));\n  return int_value;\n}\n\nconstexpr auto pow10(std::uint32_t n) -> long long {\n  return n == 0 ? 1 : 10 * pow10(n - 1);\n}\n\n// Counts the number of fractional digits in the range [0, 18] according to the\n// C++20 spec. If more than 18 fractional digits are required then returns 6 for\n// microseconds precision.\ntemplate <long long Num, long long Den, int N = 0,\n          bool Enabled = (N < 19) && (Num <= max_value<long long>() / 10)>\nstruct count_fractional_digits {\n  static constexpr int value =\n      Num % Den == 0 ? N : count_fractional_digits<Num * 10, Den, N + 1>::value;\n};\n\n// Base case that doesn't instantiate any more templates\n// in order to avoid overflow.\ntemplate <long long Num, long long Den, int N>\nstruct count_fractional_digits<Num, Den, N, false> {\n  static constexpr int value = (Num % Den == 0) ? N : 6;\n};\n\n// Format subseconds which are given as an integer type with an appropriate\n// number of digits.\ntemplate <typename Char, typename OutputIt, typename Duration>\nvoid write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) {\n  constexpr auto num_fractional_digits =\n      count_fractional_digits<Duration::period::num,\n                              Duration::period::den>::value;\n\n  using subsecond_precision = std::chrono::duration<\n      typename std::common_type<typename Duration::rep,\n                                std::chrono::seconds::rep>::type,\n      std::ratio<1, pow10(num_fractional_digits)>>;\n\n  const auto fractional = d - detail::duration_cast<std::chrono::seconds>(d);\n  const auto subseconds =\n      std::chrono::treat_as_floating_point<\n          typename subsecond_precision::rep>::value\n          ? fractional.count()\n          : detail::duration_cast<subsecond_precision>(fractional).count();\n  auto n = static_cast<uint32_or_64_or_128_t<long long>>(subseconds);\n  const int num_digits = count_digits(n);\n\n  int leading_zeroes = (std::max)(0, num_fractional_digits - num_digits);\n  if (precision < 0) {\n    FMT_ASSERT(!std::is_floating_point<typename Duration::rep>::value, \"\");\n    if (std::ratio_less<typename subsecond_precision::period,\n                        std::chrono::seconds::period>::value) {\n      *out++ = '.';\n      out = detail::fill_n(out, leading_zeroes, '0');\n      out = format_decimal<Char>(out, n, num_digits);\n    }\n  } else if (precision > 0) {\n    *out++ = '.';\n    leading_zeroes = min_of(leading_zeroes, precision);\n    int remaining = precision - leading_zeroes;\n    out = detail::fill_n(out, leading_zeroes, '0');\n    if (remaining < num_digits) {\n      int num_truncated_digits = num_digits - remaining;\n      n /= to_unsigned(pow10(to_unsigned(num_truncated_digits)));\n      if (n != 0) out = format_decimal<Char>(out, n, remaining);\n      return;\n    }\n    if (n != 0) {\n      out = format_decimal<Char>(out, n, num_digits);\n      remaining -= num_digits;\n    }\n    out = detail::fill_n(out, remaining, '0');\n  }\n}\n\n// Format subseconds which are given as a floating point type with an\n// appropriate number of digits. We cannot pass the Duration here, as we\n// explicitly need to pass the Rep value in the duration_formatter.\ntemplate <typename Duration>\nvoid write_floating_seconds(memory_buffer& buf, Duration duration,\n                            int num_fractional_digits = -1) {\n  using rep = typename Duration::rep;\n  FMT_ASSERT(std::is_floating_point<rep>::value, \"\");\n\n  auto val = duration.count();\n\n  if (num_fractional_digits < 0) {\n    // For `std::round` with fallback to `round`:\n    // On some toolchains `std::round` is not available (e.g. GCC 6).\n    using namespace std;\n    num_fractional_digits =\n        count_fractional_digits<Duration::period::num,\n                                Duration::period::den>::value;\n    if (num_fractional_digits < 6 && static_cast<rep>(round(val)) != val)\n      num_fractional_digits = 6;\n  }\n\n  fmt::format_to(std::back_inserter(buf), FMT_STRING(\"{:.{}f}\"),\n                 std::fmod(val * static_cast<rep>(Duration::period::num) /\n                               static_cast<rep>(Duration::period::den),\n                           static_cast<rep>(60)),\n                 num_fractional_digits);\n}\n\ntemplate <typename OutputIt, typename Char,\n          typename Duration = std::chrono::seconds>\nclass tm_writer {\n private:\n  static constexpr int days_per_week = 7;\n\n  const std::locale& loc_;\n  bool is_classic_;\n  OutputIt out_;\n  const Duration* subsecs_;\n  const std::tm& tm_;\n\n  auto tm_sec() const noexcept -> int {\n    FMT_ASSERT(tm_.tm_sec >= 0 && tm_.tm_sec <= 61, \"\");\n    return tm_.tm_sec;\n  }\n  auto tm_min() const noexcept -> int {\n    FMT_ASSERT(tm_.tm_min >= 0 && tm_.tm_min <= 59, \"\");\n    return tm_.tm_min;\n  }\n  auto tm_hour() const noexcept -> int {\n    FMT_ASSERT(tm_.tm_hour >= 0 && tm_.tm_hour <= 23, \"\");\n    return tm_.tm_hour;\n  }\n  auto tm_mday() const noexcept -> int {\n    FMT_ASSERT(tm_.tm_mday >= 1 && tm_.tm_mday <= 31, \"\");\n    return tm_.tm_mday;\n  }\n  auto tm_mon() const noexcept -> int {\n    FMT_ASSERT(tm_.tm_mon >= 0 && tm_.tm_mon <= 11, \"\");\n    return tm_.tm_mon;\n  }\n  auto tm_year() const noexcept -> long long { return 1900ll + tm_.tm_year; }\n  auto tm_wday() const noexcept -> int {\n    FMT_ASSERT(tm_.tm_wday >= 0 && tm_.tm_wday <= 6, \"\");\n    return tm_.tm_wday;\n  }\n  auto tm_yday() const noexcept -> int {\n    FMT_ASSERT(tm_.tm_yday >= 0 && tm_.tm_yday <= 365, \"\");\n    return tm_.tm_yday;\n  }\n\n  auto tm_hour12() const noexcept -> int {\n    auto h = tm_hour();\n    auto z = h < 12 ? h : h - 12;\n    return z == 0 ? 12 : z;\n  }\n\n  // POSIX and the C Standard are unclear or inconsistent about what %C and %y\n  // do if the year is negative or exceeds 9999. Use the convention that %C\n  // concatenated with %y yields the same output as %Y, and that %Y contains at\n  // least 4 characters, with more only if necessary.\n  auto split_year_lower(long long year) const noexcept -> int {\n    auto l = year % 100;\n    if (l < 0) l = -l;  // l in [0, 99]\n    return static_cast<int>(l);\n  }\n\n  // Algorithm: https://en.wikipedia.org/wiki/ISO_week_date.\n  auto iso_year_weeks(long long curr_year) const noexcept -> int {\n    auto prev_year = curr_year - 1;\n    auto curr_p =\n        (curr_year + curr_year / 4 - curr_year / 100 + curr_year / 400) %\n        days_per_week;\n    auto prev_p =\n        (prev_year + prev_year / 4 - prev_year / 100 + prev_year / 400) %\n        days_per_week;\n    return 52 + ((curr_p == 4 || prev_p == 3) ? 1 : 0);\n  }\n  auto iso_week_num(int tm_yday, int tm_wday) const noexcept -> int {\n    return (tm_yday + 11 - (tm_wday == 0 ? days_per_week : tm_wday)) /\n           days_per_week;\n  }\n  auto tm_iso_week_year() const noexcept -> long long {\n    auto year = tm_year();\n    auto w = iso_week_num(tm_yday(), tm_wday());\n    if (w < 1) return year - 1;\n    if (w > iso_year_weeks(year)) return year + 1;\n    return year;\n  }\n  auto tm_iso_week_of_year() const noexcept -> int {\n    auto year = tm_year();\n    auto w = iso_week_num(tm_yday(), tm_wday());\n    if (w < 1) return iso_year_weeks(year - 1);\n    if (w > iso_year_weeks(year)) return 1;\n    return w;\n  }\n\n  void write1(int value) {\n    *out_++ = static_cast<char>('0' + to_unsigned(value) % 10);\n  }\n  void write2(int value) {\n    const char* d = digits2(to_unsigned(value) % 100);\n    *out_++ = *d++;\n    *out_++ = *d;\n  }\n  void write2(int value, pad_type pad) {\n    unsigned int v = to_unsigned(value) % 100;\n    if (v >= 10) {\n      const char* d = digits2(v);\n      *out_++ = *d++;\n      *out_++ = *d;\n    } else {\n      out_ = detail::write_padding(out_, pad);\n      *out_++ = static_cast<char>('0' + v);\n    }\n  }\n\n  void write_year_extended(long long year, pad_type pad) {\n    // At least 4 characters.\n    int width = 4;\n    bool negative = year < 0;\n    if (negative) {\n      year = 0 - year;\n      --width;\n    }\n    uint32_or_64_or_128_t<long long> n = to_unsigned(year);\n    const int num_digits = count_digits(n);\n    if (negative && pad == pad_type::zero) *out_++ = '-';\n    if (width > num_digits)\n      out_ = detail::write_padding(out_, pad, width - num_digits);\n    if (negative && pad != pad_type::zero) *out_++ = '-';\n    out_ = format_decimal<Char>(out_, n, num_digits);\n  }\n  void write_year(long long year, pad_type pad) {\n    write_year_extended(year, pad);\n  }\n\n  void write_utc_offset(long long offset, numeric_system ns) {\n    if (offset < 0) {\n      *out_++ = '-';\n      offset = -offset;\n    } else {\n      *out_++ = '+';\n    }\n    offset /= 60;\n    write2(static_cast<int>(offset / 60));\n    if (ns != numeric_system::standard) *out_++ = ':';\n    write2(static_cast<int>(offset % 60));\n  }\n\n  template <typename T, FMT_ENABLE_IF(has_tm_gmtoff<T>::value)>\n  void format_utc_offset(const T& tm, numeric_system ns) {\n    write_utc_offset(tm.tm_gmtoff, ns);\n  }\n  template <typename T, FMT_ENABLE_IF(!has_tm_gmtoff<T>::value)>\n  void format_utc_offset(const T&, numeric_system ns) {\n    write_utc_offset(0, ns);\n  }\n\n  template <typename T, FMT_ENABLE_IF(has_tm_zone<T>::value)>\n  void format_tz_name(const T& tm) {\n    out_ = write_tm_str<Char>(out_, tm.tm_zone, loc_);\n  }\n  template <typename T, FMT_ENABLE_IF(!has_tm_zone<T>::value)>\n  void format_tz_name(const T&) {\n    out_ = std::copy_n(utc(), 3, out_);\n  }\n\n  void format_localized(char format, char modifier = 0) {\n    out_ = write<Char>(out_, tm_, loc_, format, modifier);\n  }\n\n public:\n  tm_writer(const std::locale& loc, OutputIt out, const std::tm& tm,\n            const Duration* subsecs = nullptr)\n      : loc_(loc),\n        is_classic_(loc_ == get_classic_locale()),\n        out_(out),\n        subsecs_(subsecs),\n        tm_(tm) {}\n\n  auto out() const -> OutputIt { return out_; }\n\n  FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) {\n    out_ = copy<Char>(begin, end, out_);\n  }\n\n  void on_abbr_weekday() {\n    if (is_classic_)\n      out_ = write(out_, tm_wday_short_name(tm_wday()));\n    else\n      format_localized('a');\n  }\n  void on_full_weekday() {\n    if (is_classic_)\n      out_ = write(out_, tm_wday_full_name(tm_wday()));\n    else\n      format_localized('A');\n  }\n  void on_dec0_weekday(numeric_system ns) {\n    if (is_classic_ || ns == numeric_system::standard) return write1(tm_wday());\n    format_localized('w', 'O');\n  }\n  void on_dec1_weekday(numeric_system ns) {\n    if (is_classic_ || ns == numeric_system::standard) {\n      auto wday = tm_wday();\n      write1(wday == 0 ? days_per_week : wday);\n    } else {\n      format_localized('u', 'O');\n    }\n  }\n\n  void on_abbr_month() {\n    if (is_classic_)\n      out_ = write(out_, tm_mon_short_name(tm_mon()));\n    else\n      format_localized('b');\n  }\n  void on_full_month() {\n    if (is_classic_)\n      out_ = write(out_, tm_mon_full_name(tm_mon()));\n    else\n      format_localized('B');\n  }\n\n  void on_datetime(numeric_system ns) {\n    if (is_classic_) {\n      on_abbr_weekday();\n      *out_++ = ' ';\n      on_abbr_month();\n      *out_++ = ' ';\n      on_day_of_month(numeric_system::standard, pad_type::space);\n      *out_++ = ' ';\n      on_iso_time();\n      *out_++ = ' ';\n      on_year(numeric_system::standard, pad_type::space);\n    } else {\n      format_localized('c', ns == numeric_system::standard ? '\\0' : 'E');\n    }\n  }\n  void on_loc_date(numeric_system ns) {\n    if (is_classic_)\n      on_us_date();\n    else\n      format_localized('x', ns == numeric_system::standard ? '\\0' : 'E');\n  }\n  void on_loc_time(numeric_system ns) {\n    if (is_classic_)\n      on_iso_time();\n    else\n      format_localized('X', ns == numeric_system::standard ? '\\0' : 'E');\n  }\n  void on_us_date() {\n    char buf[8];\n    write_digit2_separated(buf, to_unsigned(tm_mon() + 1),\n                           to_unsigned(tm_mday()),\n                           to_unsigned(split_year_lower(tm_year())), '/');\n    out_ = copy<Char>(std::begin(buf), std::end(buf), out_);\n  }\n  void on_iso_date() {\n    auto year = tm_year();\n    char buf[10];\n    size_t offset = 0;\n    if (year >= 0 && year < 10000) {\n      write2digits(buf, static_cast<size_t>(year / 100));\n    } else {\n      offset = 4;\n      write_year_extended(year, pad_type::zero);\n      year = 0;\n    }\n    write_digit2_separated(buf + 2, static_cast<unsigned>(year % 100),\n                           to_unsigned(tm_mon() + 1), to_unsigned(tm_mday()),\n                           '-');\n    out_ = copy<Char>(std::begin(buf) + offset, std::end(buf), out_);\n  }\n\n  void on_utc_offset(numeric_system ns) { format_utc_offset(tm_, ns); }\n  void on_tz_name() { format_tz_name(tm_); }\n\n  void on_year(numeric_system ns, pad_type pad) {\n    if (is_classic_ || ns == numeric_system::standard)\n      return write_year(tm_year(), pad);\n    format_localized('Y', 'E');\n  }\n  void on_short_year(numeric_system ns) {\n    if (is_classic_ || ns == numeric_system::standard)\n      return write2(split_year_lower(tm_year()));\n    format_localized('y', 'O');\n  }\n  void on_offset_year() {\n    if (is_classic_) return write2(split_year_lower(tm_year()));\n    format_localized('y', 'E');\n  }\n\n  void on_century(numeric_system ns) {\n    if (is_classic_ || ns == numeric_system::standard) {\n      auto year = tm_year();\n      auto upper = year / 100;\n      if (year >= -99 && year < 0) {\n        // Zero upper on negative year.\n        *out_++ = '-';\n        *out_++ = '0';\n      } else if (upper >= 0 && upper < 100) {\n        write2(static_cast<int>(upper));\n      } else {\n        out_ = write<Char>(out_, upper);\n      }\n    } else {\n      format_localized('C', 'E');\n    }\n  }\n\n  void on_dec_month(numeric_system ns, pad_type pad) {\n    if (is_classic_ || ns == numeric_system::standard)\n      return write2(tm_mon() + 1, pad);\n    format_localized('m', 'O');\n  }\n\n  void on_dec0_week_of_year(numeric_system ns, pad_type pad) {\n    if (is_classic_ || ns == numeric_system::standard)\n      return write2((tm_yday() + days_per_week - tm_wday()) / days_per_week,\n                    pad);\n    format_localized('U', 'O');\n  }\n  void on_dec1_week_of_year(numeric_system ns, pad_type pad) {\n    if (is_classic_ || ns == numeric_system::standard) {\n      auto wday = tm_wday();\n      write2((tm_yday() + days_per_week -\n              (wday == 0 ? (days_per_week - 1) : (wday - 1))) /\n                 days_per_week,\n             pad);\n    } else {\n      format_localized('W', 'O');\n    }\n  }\n  void on_iso_week_of_year(numeric_system ns, pad_type pad) {\n    if (is_classic_ || ns == numeric_system::standard)\n      return write2(tm_iso_week_of_year(), pad);\n    format_localized('V', 'O');\n  }\n\n  void on_iso_week_based_year() {\n    write_year(tm_iso_week_year(), pad_type::zero);\n  }\n  void on_iso_week_based_short_year() {\n    write2(split_year_lower(tm_iso_week_year()));\n  }\n\n  void on_day_of_year(pad_type pad) {\n    auto yday = tm_yday() + 1;\n    auto digit1 = yday / 100;\n    if (digit1 != 0)\n      write1(digit1);\n    else\n      out_ = detail::write_padding(out_, pad);\n    write2(yday % 100, pad);\n  }\n\n  void on_day_of_month(numeric_system ns, pad_type pad) {\n    if (is_classic_ || ns == numeric_system::standard)\n      return write2(tm_mday(), pad);\n    format_localized('d', 'O');\n  }\n\n  void on_24_hour(numeric_system ns, pad_type pad) {\n    if (is_classic_ || ns == numeric_system::standard)\n      return write2(tm_hour(), pad);\n    format_localized('H', 'O');\n  }\n  void on_12_hour(numeric_system ns, pad_type pad) {\n    if (is_classic_ || ns == numeric_system::standard)\n      return write2(tm_hour12(), pad);\n    format_localized('I', 'O');\n  }\n  void on_minute(numeric_system ns, pad_type pad) {\n    if (is_classic_ || ns == numeric_system::standard)\n      return write2(tm_min(), pad);\n    format_localized('M', 'O');\n  }\n\n  void on_second(numeric_system ns, pad_type pad) {\n    if (is_classic_ || ns == numeric_system::standard) {\n      write2(tm_sec(), pad);\n      if (subsecs_) {\n        if (std::is_floating_point<typename Duration::rep>::value) {\n          auto buf = memory_buffer();\n          write_floating_seconds(buf, *subsecs_);\n          if (buf.size() > 1) {\n            // Remove the leading \"0\", write something like \".123\".\n            out_ = copy<Char>(buf.begin() + 1, buf.end(), out_);\n          }\n        } else {\n          write_fractional_seconds<Char>(out_, *subsecs_);\n        }\n      }\n    } else {\n      // Currently no formatting of subseconds when a locale is set.\n      format_localized('S', 'O');\n    }\n  }\n\n  void on_12_hour_time() {\n    if (is_classic_) {\n      char buf[8];\n      write_digit2_separated(buf, to_unsigned(tm_hour12()),\n                             to_unsigned(tm_min()), to_unsigned(tm_sec()), ':');\n      out_ = copy<Char>(std::begin(buf), std::end(buf), out_);\n      *out_++ = ' ';\n      on_am_pm();\n    } else {\n      format_localized('r');\n    }\n  }\n  void on_24_hour_time() {\n    write2(tm_hour());\n    *out_++ = ':';\n    write2(tm_min());\n  }\n  void on_iso_time() {\n    on_24_hour_time();\n    *out_++ = ':';\n    on_second(numeric_system::standard, pad_type::zero);\n  }\n\n  void on_am_pm() {\n    if (is_classic_) {\n      *out_++ = tm_hour() < 12 ? 'A' : 'P';\n      *out_++ = 'M';\n    } else {\n      format_localized('p');\n    }\n  }\n\n  // These apply to chrono durations but not tm.\n  void on_duration_value() {}\n  void on_duration_unit() {}\n};\n\nstruct chrono_format_checker : null_chrono_spec_handler<chrono_format_checker> {\n  bool has_precision_integral = false;\n\n  FMT_NORETURN inline void unsupported() { FMT_THROW(format_error(\"no date\")); }\n\n  template <typename Char>\n  FMT_CONSTEXPR void on_text(const Char*, const Char*) {}\n  FMT_CONSTEXPR void on_day_of_year(pad_type) {}\n  FMT_CONSTEXPR void on_24_hour(numeric_system, pad_type) {}\n  FMT_CONSTEXPR void on_12_hour(numeric_system, pad_type) {}\n  FMT_CONSTEXPR void on_minute(numeric_system, pad_type) {}\n  FMT_CONSTEXPR void on_second(numeric_system, pad_type) {}\n  FMT_CONSTEXPR void on_12_hour_time() {}\n  FMT_CONSTEXPR void on_24_hour_time() {}\n  FMT_CONSTEXPR void on_iso_time() {}\n  FMT_CONSTEXPR void on_am_pm() {}\n  FMT_CONSTEXPR void on_duration_value() const {\n    if (has_precision_integral)\n      FMT_THROW(format_error(\"precision not allowed for this argument type\"));\n  }\n  FMT_CONSTEXPR void on_duration_unit() {}\n};\n\ntemplate <typename T,\n          FMT_ENABLE_IF(std::is_integral<T>::value&& has_isfinite<T>::value)>\ninline auto isfinite(T) -> bool {\n  return true;\n}\n\ntemplate <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>\ninline auto mod(T x, int y) -> T {\n  return x % static_cast<T>(y);\n}\ntemplate <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>\ninline auto mod(T x, int y) -> T {\n  return std::fmod(x, static_cast<T>(y));\n}\n\n// If T is an integral type, maps T to its unsigned counterpart, otherwise\n// leaves it unchanged (unlike std::make_unsigned).\ntemplate <typename T, bool INTEGRAL = std::is_integral<T>::value>\nstruct make_unsigned_or_unchanged {\n  using type = T;\n};\n\ntemplate <typename T> struct make_unsigned_or_unchanged<T, true> {\n  using type = typename std::make_unsigned<T>::type;\n};\n\ntemplate <typename Rep, typename Period,\n          FMT_ENABLE_IF(std::is_integral<Rep>::value)>\ninline auto get_milliseconds(std::chrono::duration<Rep, Period> d)\n    -> std::chrono::duration<Rep, std::milli> {\n  // This may overflow and/or the result may not fit in the target type.\n#if FMT_SAFE_DURATION_CAST\n  using common_seconds_type =\n      typename std::common_type<decltype(d), std::chrono::seconds>::type;\n  auto d_as_common = detail::duration_cast<common_seconds_type>(d);\n  auto d_as_whole_seconds =\n      detail::duration_cast<std::chrono::seconds>(d_as_common);\n  // This conversion should be nonproblematic.\n  auto diff = d_as_common - d_as_whole_seconds;\n  auto ms = detail::duration_cast<std::chrono::duration<Rep, std::milli>>(diff);\n  return ms;\n#else\n  auto s = detail::duration_cast<std::chrono::seconds>(d);\n  return detail::duration_cast<std::chrono::milliseconds>(d - s);\n#endif\n}\n\ntemplate <typename Char, typename Rep, typename OutputIt,\n          FMT_ENABLE_IF(std::is_integral<Rep>::value)>\nauto format_duration_value(OutputIt out, Rep val, int) -> OutputIt {\n  return write<Char>(out, val);\n}\n\ntemplate <typename Char, typename Rep, typename OutputIt,\n          FMT_ENABLE_IF(std::is_floating_point<Rep>::value)>\nauto format_duration_value(OutputIt out, Rep val, int precision) -> OutputIt {\n  auto specs = format_specs();\n  specs.precision = precision;\n  specs.set_type(precision >= 0 ? presentation_type::fixed\n                                : presentation_type::general);\n  return write<Char>(out, val, specs);\n}\n\ntemplate <typename Char, typename OutputIt>\nauto copy_unit(string_view unit, OutputIt out, Char) -> OutputIt {\n  return copy<Char>(unit.begin(), unit.end(), out);\n}\n\ntemplate <typename OutputIt>\nauto copy_unit(string_view unit, OutputIt out, wchar_t) -> OutputIt {\n  // This works when wchar_t is UTF-32 because units only contain characters\n  // that have the same representation in UTF-16 and UTF-32.\n  utf8_to_utf16 u(unit);\n  return copy<wchar_t>(u.c_str(), u.c_str() + u.size(), out);\n}\n\ntemplate <typename Char, typename Period, typename OutputIt>\nauto format_duration_unit(OutputIt out) -> OutputIt {\n  if (const char* unit = get_units<Period>())\n    return copy_unit(string_view(unit), out, Char());\n  *out++ = '[';\n  out = write<Char>(out, Period::num);\n  if (const_check(Period::den != 1)) {\n    *out++ = '/';\n    out = write<Char>(out, Period::den);\n  }\n  *out++ = ']';\n  *out++ = 's';\n  return out;\n}\n\nclass get_locale {\n private:\n  union {\n    std::locale locale_;\n  };\n  bool has_locale_ = false;\n\n public:\n  inline get_locale(bool localized, locale_ref loc) : has_locale_(localized) {\n    if (!localized) return;\n    ignore_unused(loc);\n    ::new (&locale_) std::locale(\n#if FMT_USE_LOCALE\n        loc.template get<std::locale>()\n#endif\n    );\n  }\n  inline ~get_locale() {\n    if (has_locale_) locale_.~locale();\n  }\n  inline operator const std::locale&() const {\n    return has_locale_ ? locale_ : get_classic_locale();\n  }\n};\n\ntemplate <typename Char, typename Rep, typename Period>\nstruct duration_formatter {\n  using iterator = basic_appender<Char>;\n  iterator out;\n  // rep is unsigned to avoid overflow.\n  using rep =\n      conditional_t<std::is_integral<Rep>::value && sizeof(Rep) < sizeof(int),\n                    unsigned, typename make_unsigned_or_unchanged<Rep>::type>;\n  rep val;\n  int precision;\n  locale_ref locale;\n  bool localized = false;\n  using seconds = std::chrono::duration<rep>;\n  seconds s;\n  using milliseconds = std::chrono::duration<rep, std::milli>;\n  bool negative;\n\n  using tm_writer_type = tm_writer<iterator, Char>;\n\n  duration_formatter(iterator o, std::chrono::duration<Rep, Period> d,\n                     locale_ref loc)\n      : out(o), val(static_cast<rep>(d.count())), locale(loc), negative(false) {\n    if (d.count() < 0) {\n      val = 0 - val;\n      negative = true;\n    }\n\n    // this may overflow and/or the result may not fit in the\n    // target type.\n    // might need checked conversion (rep!=Rep)\n    s = detail::duration_cast<seconds>(std::chrono::duration<rep, Period>(val));\n  }\n\n  // returns true if nan or inf, writes to out.\n  auto handle_nan_inf() -> bool {\n    if (isfinite(val)) return false;\n    if (isnan(val)) {\n      write_nan();\n      return true;\n    }\n    // must be +-inf\n    if (val > 0)\n      std::copy_n(\"inf\", 3, out);\n    else\n      std::copy_n(\"-inf\", 4, out);\n    return true;\n  }\n\n  auto days() const -> Rep { return static_cast<Rep>(s.count() / 86400); }\n  auto hour() const -> Rep {\n    return static_cast<Rep>(mod((s.count() / 3600), 24));\n  }\n\n  auto hour12() const -> Rep {\n    Rep hour = static_cast<Rep>(mod((s.count() / 3600), 12));\n    return hour <= 0 ? 12 : hour;\n  }\n\n  auto minute() const -> Rep {\n    return static_cast<Rep>(mod((s.count() / 60), 60));\n  }\n  auto second() const -> Rep { return static_cast<Rep>(mod(s.count(), 60)); }\n\n  auto time() const -> std::tm {\n    auto time = std::tm();\n    time.tm_hour = to_nonnegative_int(hour(), 24);\n    time.tm_min = to_nonnegative_int(minute(), 60);\n    time.tm_sec = to_nonnegative_int(second(), 60);\n    return time;\n  }\n\n  void write_sign() {\n    if (!negative) return;\n    *out++ = '-';\n    negative = false;\n  }\n\n  void write(Rep value, int width, pad_type pad = pad_type::zero) {\n    write_sign();\n    if (isnan(value)) return write_nan();\n    uint32_or_64_or_128_t<int> n =\n        to_unsigned(to_nonnegative_int(value, max_value<int>()));\n    int num_digits = detail::count_digits(n);\n    if (width > num_digits) {\n      out = detail::write_padding(out, pad, width - num_digits);\n    }\n    out = format_decimal<Char>(out, n, num_digits);\n  }\n\n  void write_nan() { std::copy_n(\"nan\", 3, out); }\n\n  template <typename Callback, typename... Args>\n  void format_tm(const tm& time, Callback cb, Args... args) {\n    if (isnan(val)) return write_nan();\n    get_locale loc(localized, locale);\n    auto w = tm_writer_type(loc, out, time);\n    (w.*cb)(args...);\n    out = w.out();\n  }\n\n  void on_text(const Char* begin, const Char* end) {\n    copy<Char>(begin, end, out);\n  }\n\n  // These are not implemented because durations don't have date information.\n  void on_abbr_weekday() {}\n  void on_full_weekday() {}\n  void on_dec0_weekday(numeric_system) {}\n  void on_dec1_weekday(numeric_system) {}\n  void on_abbr_month() {}\n  void on_full_month() {}\n  void on_datetime(numeric_system) {}\n  void on_loc_date(numeric_system) {}\n  void on_loc_time(numeric_system) {}\n  void on_us_date() {}\n  void on_iso_date() {}\n  void on_utc_offset(numeric_system) {}\n  void on_tz_name() {}\n  void on_year(numeric_system, pad_type) {}\n  void on_short_year(numeric_system) {}\n  void on_offset_year() {}\n  void on_century(numeric_system) {}\n  void on_iso_week_based_year() {}\n  void on_iso_week_based_short_year() {}\n  void on_dec_month(numeric_system, pad_type) {}\n  void on_dec0_week_of_year(numeric_system, pad_type) {}\n  void on_dec1_week_of_year(numeric_system, pad_type) {}\n  void on_iso_week_of_year(numeric_system, pad_type) {}\n  void on_day_of_month(numeric_system, pad_type) {}\n\n  void on_day_of_year(pad_type) {\n    if (handle_nan_inf()) return;\n    write(days(), 0);\n  }\n\n  void on_24_hour(numeric_system ns, pad_type pad) {\n    if (handle_nan_inf()) return;\n\n    if (ns == numeric_system::standard) return write(hour(), 2, pad);\n    auto time = tm();\n    time.tm_hour = to_nonnegative_int(hour(), 24);\n    format_tm(time, &tm_writer_type::on_24_hour, ns, pad);\n  }\n\n  void on_12_hour(numeric_system ns, pad_type pad) {\n    if (handle_nan_inf()) return;\n\n    if (ns == numeric_system::standard) return write(hour12(), 2, pad);\n    auto time = tm();\n    time.tm_hour = to_nonnegative_int(hour12(), 12);\n    format_tm(time, &tm_writer_type::on_12_hour, ns, pad);\n  }\n\n  void on_minute(numeric_system ns, pad_type pad) {\n    if (handle_nan_inf()) return;\n\n    if (ns == numeric_system::standard) return write(minute(), 2, pad);\n    auto time = tm();\n    time.tm_min = to_nonnegative_int(minute(), 60);\n    format_tm(time, &tm_writer_type::on_minute, ns, pad);\n  }\n\n  void on_second(numeric_system ns, pad_type pad) {\n    if (handle_nan_inf()) return;\n\n    if (ns == numeric_system::standard) {\n      if (std::is_floating_point<rep>::value) {\n        auto buf = memory_buffer();\n        write_floating_seconds(buf, std::chrono::duration<rep, Period>(val),\n                               precision);\n        if (negative) *out++ = '-';\n        if (buf.size() < 2 || buf[1] == '.')\n          out = detail::write_padding(out, pad);\n        out = copy<Char>(buf.begin(), buf.end(), out);\n      } else {\n        write(second(), 2, pad);\n        write_fractional_seconds<Char>(\n            out, std::chrono::duration<rep, Period>(val), precision);\n      }\n      return;\n    }\n    auto time = tm();\n    time.tm_sec = to_nonnegative_int(second(), 60);\n    format_tm(time, &tm_writer_type::on_second, ns, pad);\n  }\n\n  void on_12_hour_time() {\n    if (handle_nan_inf()) return;\n    format_tm(time(), &tm_writer_type::on_12_hour_time);\n  }\n\n  void on_24_hour_time() {\n    if (handle_nan_inf()) {\n      *out++ = ':';\n      handle_nan_inf();\n      return;\n    }\n\n    write(hour(), 2);\n    *out++ = ':';\n    write(minute(), 2);\n  }\n\n  void on_iso_time() {\n    on_24_hour_time();\n    *out++ = ':';\n    if (handle_nan_inf()) return;\n    on_second(numeric_system::standard, pad_type::zero);\n  }\n\n  void on_am_pm() {\n    if (handle_nan_inf()) return;\n    format_tm(time(), &tm_writer_type::on_am_pm);\n  }\n\n  void on_duration_value() {\n    if (handle_nan_inf()) return;\n    write_sign();\n    out = format_duration_value<Char>(out, val, precision);\n  }\n\n  void on_duration_unit() { out = format_duration_unit<Char, Period>(out); }\n};\n\n}  // namespace detail\n\n#if defined(__cpp_lib_chrono) && __cpp_lib_chrono >= 201907\nusing weekday = std::chrono::weekday;\nusing day = std::chrono::day;\nusing month = std::chrono::month;\nusing year = std::chrono::year;\nusing year_month_day = std::chrono::year_month_day;\n#else\n// A fallback version of weekday.\nclass weekday {\n private:\n  unsigned char value_;\n\n public:\n  weekday() = default;\n  constexpr explicit weekday(unsigned wd) noexcept\n      : value_(static_cast<unsigned char>(wd != 7 ? wd : 0)) {}\n  constexpr auto c_encoding() const noexcept -> unsigned { return value_; }\n};\n\nclass day {\n private:\n  unsigned char value_;\n\n public:\n  day() = default;\n  constexpr explicit day(unsigned d) noexcept\n      : value_(static_cast<unsigned char>(d)) {}\n  constexpr explicit operator unsigned() const noexcept { return value_; }\n};\n\nclass month {\n private:\n  unsigned char value_;\n\n public:\n  month() = default;\n  constexpr explicit month(unsigned m) noexcept\n      : value_(static_cast<unsigned char>(m)) {}\n  constexpr explicit operator unsigned() const noexcept { return value_; }\n};\n\nclass year {\n private:\n  int value_;\n\n public:\n  year() = default;\n  constexpr explicit year(int y) noexcept : value_(y) {}\n  constexpr explicit operator int() const noexcept { return value_; }\n};\n\nclass year_month_day {\n private:\n  fmt::year year_;\n  fmt::month month_;\n  fmt::day day_;\n\n public:\n  year_month_day() = default;\n  constexpr year_month_day(const year& y, const month& m, const day& d) noexcept\n      : year_(y), month_(m), day_(d) {}\n  constexpr auto year() const noexcept -> fmt::year { return year_; }\n  constexpr auto month() const noexcept -> fmt::month { return month_; }\n  constexpr auto day() const noexcept -> fmt::day { return day_; }\n};\n#endif  // __cpp_lib_chrono >= 201907\n\ntemplate <typename Char>\nstruct formatter<weekday, Char> : private formatter<std::tm, Char> {\n private:\n  bool use_tm_formatter_ = false;\n\n public:\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    auto it = ctx.begin(), end = ctx.end();\n    if (it != end && *it == 'L') {\n      ++it;\n      this->set_localized();\n    }\n    use_tm_formatter_ = it != end && *it != '}';\n    return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;\n  }\n\n  template <typename FormatContext>\n  auto format(weekday wd, FormatContext& ctx) const -> decltype(ctx.out()) {\n    auto time = std::tm();\n    time.tm_wday = static_cast<int>(wd.c_encoding());\n    if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx);\n    detail::get_locale loc(this->localized(), ctx.locale());\n    auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);\n    w.on_abbr_weekday();\n    return w.out();\n  }\n};\n\ntemplate <typename Char>\nstruct formatter<day, Char> : private formatter<std::tm, Char> {\n private:\n  bool use_tm_formatter_ = false;\n\n public:\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    auto it = ctx.begin(), end = ctx.end();\n    use_tm_formatter_ = it != end && *it != '}';\n    return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;\n  }\n\n  template <typename FormatContext>\n  auto format(day d, FormatContext& ctx) const -> decltype(ctx.out()) {\n    auto time = std::tm();\n    time.tm_mday = static_cast<int>(static_cast<unsigned>(d));\n    if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx);\n    detail::get_locale loc(false, ctx.locale());\n    auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);\n    w.on_day_of_month(detail::numeric_system::standard, detail::pad_type::zero);\n    return w.out();\n  }\n};\n\ntemplate <typename Char>\nstruct formatter<month, Char> : private formatter<std::tm, Char> {\n private:\n  bool use_tm_formatter_ = false;\n\n public:\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    auto it = ctx.begin(), end = ctx.end();\n    if (it != end && *it == 'L') {\n      ++it;\n      this->set_localized();\n    }\n    use_tm_formatter_ = it != end && *it != '}';\n    return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;\n  }\n\n  template <typename FormatContext>\n  auto format(month m, FormatContext& ctx) const -> decltype(ctx.out()) {\n    auto time = std::tm();\n    time.tm_mon = static_cast<int>(static_cast<unsigned>(m)) - 1;\n    if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx);\n    detail::get_locale loc(this->localized(), ctx.locale());\n    auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);\n    w.on_abbr_month();\n    return w.out();\n  }\n};\n\ntemplate <typename Char>\nstruct formatter<year, Char> : private formatter<std::tm, Char> {\n private:\n  bool use_tm_formatter_ = false;\n\n public:\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    auto it = ctx.begin(), end = ctx.end();\n    use_tm_formatter_ = it != end && *it != '}';\n    return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;\n  }\n\n  template <typename FormatContext>\n  auto format(year y, FormatContext& ctx) const -> decltype(ctx.out()) {\n    auto time = std::tm();\n    time.tm_year = static_cast<int>(y) - 1900;\n    if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx);\n    detail::get_locale loc(false, ctx.locale());\n    auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);\n    w.on_year(detail::numeric_system::standard, detail::pad_type::zero);\n    return w.out();\n  }\n};\n\ntemplate <typename Char>\nstruct formatter<year_month_day, Char> : private formatter<std::tm, Char> {\n private:\n  bool use_tm_formatter_ = false;\n\n public:\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    auto it = ctx.begin(), end = ctx.end();\n    use_tm_formatter_ = it != end && *it != '}';\n    return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;\n  }\n\n  template <typename FormatContext>\n  auto format(year_month_day val, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    auto time = std::tm();\n    time.tm_year = static_cast<int>(val.year()) - 1900;\n    time.tm_mon = static_cast<int>(static_cast<unsigned>(val.month())) - 1;\n    time.tm_mday = static_cast<int>(static_cast<unsigned>(val.day()));\n    if (use_tm_formatter_) return formatter<std::tm, Char>::format(time, ctx);\n    detail::get_locale loc(true, ctx.locale());\n    auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);\n    w.on_iso_date();\n    return w.out();\n  }\n};\n\ntemplate <typename Rep, typename Period, typename Char>\nstruct formatter<std::chrono::duration<Rep, Period>, Char> {\n private:\n  format_specs specs_;\n  detail::arg_ref<Char> width_ref_;\n  detail::arg_ref<Char> precision_ref_;\n  basic_string_view<Char> fmt_;\n\n public:\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    auto it = ctx.begin(), end = ctx.end();\n    if (it == end || *it == '}') return it;\n\n    it = detail::parse_align(it, end, specs_);\n    if (it == end) return it;\n\n    Char c = *it;\n    if ((c >= '0' && c <= '9') || c == '{') {\n      it = detail::parse_width(it, end, specs_, width_ref_, ctx);\n      if (it == end) return it;\n    }\n\n    auto checker = detail::chrono_format_checker();\n    if (*it == '.') {\n      checker.has_precision_integral = !std::is_floating_point<Rep>::value;\n      it = detail::parse_precision(it, end, specs_, precision_ref_, ctx);\n    }\n    if (it != end && *it == 'L') {\n      specs_.set_localized();\n      ++it;\n    }\n    end = detail::parse_chrono_format(it, end, checker);\n    fmt_ = {it, detail::to_unsigned(end - it)};\n    return end;\n  }\n\n  template <typename FormatContext>\n  auto format(std::chrono::duration<Rep, Period> d, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    auto specs = specs_;\n    auto precision = specs.precision;\n    specs.precision = -1;\n    auto begin = fmt_.begin(), end = fmt_.end();\n    // As a possible future optimization, we could avoid extra copying if width\n    // is not specified.\n    auto buf = basic_memory_buffer<Char>();\n    auto out = basic_appender<Char>(buf);\n    detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,\n                                ctx);\n    detail::handle_dynamic_spec(specs.dynamic_precision(), precision,\n                                precision_ref_, ctx);\n    if (begin == end || *begin == '}') {\n      out = detail::format_duration_value<Char>(out, d.count(), precision);\n      detail::format_duration_unit<Char, Period>(out);\n    } else {\n      auto f =\n          detail::duration_formatter<Char, Rep, Period>(out, d, ctx.locale());\n      f.precision = precision;\n      f.localized = specs_.localized();\n      detail::parse_chrono_format(begin, end, f);\n    }\n    return detail::write(\n        ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs);\n  }\n};\n\ntemplate <typename Char> struct formatter<std::tm, Char> {\n private:\n  format_specs specs_;\n  detail::arg_ref<Char> width_ref_;\n  basic_string_view<Char> fmt_ =\n      detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>();\n\n protected:\n  auto localized() const -> bool { return specs_.localized(); }\n  FMT_CONSTEXPR void set_localized() { specs_.set_localized(); }\n\n  FMT_CONSTEXPR auto do_parse(parse_context<Char>& ctx, bool has_timezone)\n      -> const Char* {\n    auto it = ctx.begin(), end = ctx.end();\n    if (it == end || *it == '}') return it;\n\n    it = detail::parse_align(it, end, specs_);\n    if (it == end) return it;\n\n    Char c = *it;\n    if ((c >= '0' && c <= '9') || c == '{') {\n      it = detail::parse_width(it, end, specs_, width_ref_, ctx);\n      if (it == end) return it;\n    }\n\n    if (*it == 'L') {\n      specs_.set_localized();\n      ++it;\n    }\n\n    end = detail::parse_chrono_format(it, end,\n                                      detail::tm_format_checker(has_timezone));\n    // Replace the default format string only if the new spec is not empty.\n    if (end != it) fmt_ = {it, detail::to_unsigned(end - it)};\n    return end;\n  }\n\n  template <typename Duration, typename FormatContext>\n  auto do_format(const std::tm& tm, FormatContext& ctx,\n                 const Duration* subsecs) const -> decltype(ctx.out()) {\n    auto specs = specs_;\n    auto buf = basic_memory_buffer<Char>();\n    auto out = basic_appender<Char>(buf);\n    detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,\n                                ctx);\n\n    auto loc_ref = specs.localized() ? ctx.locale() : locale_ref();\n    detail::get_locale loc(static_cast<bool>(loc_ref), loc_ref);\n    auto w = detail::tm_writer<basic_appender<Char>, Char, Duration>(\n        loc, out, tm, subsecs);\n    detail::parse_chrono_format(fmt_.begin(), fmt_.end(), w);\n    return detail::write(\n        ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs);\n  }\n\n public:\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    return do_parse(ctx, detail::has_tm_gmtoff<std::tm>::value);\n  }\n\n  template <typename FormatContext>\n  auto format(const std::tm& tm, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    return do_format<std::chrono::seconds>(tm, ctx, nullptr);\n  }\n};\n\n// DEPRECATED! Reversed order of template parameters.\ntemplate <typename Char, typename Duration>\nstruct formatter<sys_time<Duration>, Char> : private formatter<std::tm, Char> {\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    return this->do_parse(ctx, true);\n  }\n\n  template <typename FormatContext>\n  auto format(sys_time<Duration> val, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    std::tm tm = gmtime(val);\n    using period = typename Duration::period;\n    if (detail::const_check(\n            period::num == 1 && period::den == 1 &&\n            !std::is_floating_point<typename Duration::rep>::value)) {\n      detail::set_tm_zone(tm, detail::utc());\n      return formatter<std::tm, Char>::format(tm, ctx);\n    }\n    Duration epoch = val.time_since_epoch();\n    Duration subsecs = detail::duration_cast<Duration>(\n        epoch - detail::duration_cast<std::chrono::seconds>(epoch));\n    if (subsecs.count() < 0) {\n      auto second = detail::duration_cast<Duration>(std::chrono::seconds(1));\n      if (tm.tm_sec != 0) {\n        --tm.tm_sec;\n      } else {\n        tm = gmtime(val - second);\n        detail::set_tm_zone(tm, detail::utc());\n      }\n      subsecs += second;\n    }\n    return formatter<std::tm, Char>::do_format(tm, ctx, &subsecs);\n  }\n};\n\ntemplate <typename Duration, typename Char>\nstruct formatter<utc_time<Duration>, Char>\n    : formatter<sys_time<Duration>, Char> {\n  template <typename FormatContext>\n  auto format(utc_time<Duration> val, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    return formatter<sys_time<Duration>, Char>::format(\n        detail::utc_clock::to_sys(val), ctx);\n  }\n};\n\ntemplate <typename Duration, typename Char>\nstruct formatter<local_time<Duration>, Char>\n    : private formatter<std::tm, Char> {\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    return this->do_parse(ctx, false);\n  }\n\n  template <typename FormatContext>\n  auto format(local_time<Duration> val, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    auto time_since_epoch = val.time_since_epoch();\n    auto seconds_since_epoch =\n        detail::duration_cast<std::chrono::seconds>(time_since_epoch);\n    // Use gmtime to prevent time zone conversion since local_time has an\n    // unspecified time zone.\n    std::tm t = gmtime(seconds_since_epoch.count());\n    using period = typename Duration::period;\n    if (period::num == 1 && period::den == 1 &&\n        !std::is_floating_point<typename Duration::rep>::value) {\n      return formatter<std::tm, Char>::format(t, ctx);\n    }\n    auto subsecs =\n        detail::duration_cast<Duration>(time_since_epoch - seconds_since_epoch);\n    return formatter<std::tm, Char>::do_format(t, ctx, &subsecs);\n  }\n};\n\nFMT_END_EXPORT\nFMT_END_NAMESPACE\n\n#endif  // FMT_CHRONO_H_\n"
  },
  {
    "path": "thirdparty/fmt/include/fmt/color.h",
    "content": "// Formatting library for C++ - color support\n//\n// Copyright (c) 2018 - present, Victor Zverovich and fmt contributors\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\n#ifndef FMT_COLOR_H_\n#define FMT_COLOR_H_\n\n#include \"format.h\"\n\nFMT_BEGIN_NAMESPACE\nFMT_BEGIN_EXPORT\n\nenum class color : uint32_t {\n  alice_blue = 0xF0F8FF,               // rgb(240,248,255)\n  antique_white = 0xFAEBD7,            // rgb(250,235,215)\n  aqua = 0x00FFFF,                     // rgb(0,255,255)\n  aquamarine = 0x7FFFD4,               // rgb(127,255,212)\n  azure = 0xF0FFFF,                    // rgb(240,255,255)\n  beige = 0xF5F5DC,                    // rgb(245,245,220)\n  bisque = 0xFFE4C4,                   // rgb(255,228,196)\n  black = 0x000000,                    // rgb(0,0,0)\n  blanched_almond = 0xFFEBCD,          // rgb(255,235,205)\n  blue = 0x0000FF,                     // rgb(0,0,255)\n  blue_violet = 0x8A2BE2,              // rgb(138,43,226)\n  brown = 0xA52A2A,                    // rgb(165,42,42)\n  burly_wood = 0xDEB887,               // rgb(222,184,135)\n  cadet_blue = 0x5F9EA0,               // rgb(95,158,160)\n  chartreuse = 0x7FFF00,               // rgb(127,255,0)\n  chocolate = 0xD2691E,                // rgb(210,105,30)\n  coral = 0xFF7F50,                    // rgb(255,127,80)\n  cornflower_blue = 0x6495ED,          // rgb(100,149,237)\n  cornsilk = 0xFFF8DC,                 // rgb(255,248,220)\n  crimson = 0xDC143C,                  // rgb(220,20,60)\n  cyan = 0x00FFFF,                     // rgb(0,255,255)\n  dark_blue = 0x00008B,                // rgb(0,0,139)\n  dark_cyan = 0x008B8B,                // rgb(0,139,139)\n  dark_golden_rod = 0xB8860B,          // rgb(184,134,11)\n  dark_gray = 0xA9A9A9,                // rgb(169,169,169)\n  dark_green = 0x006400,               // rgb(0,100,0)\n  dark_khaki = 0xBDB76B,               // rgb(189,183,107)\n  dark_magenta = 0x8B008B,             // rgb(139,0,139)\n  dark_olive_green = 0x556B2F,         // rgb(85,107,47)\n  dark_orange = 0xFF8C00,              // rgb(255,140,0)\n  dark_orchid = 0x9932CC,              // rgb(153,50,204)\n  dark_red = 0x8B0000,                 // rgb(139,0,0)\n  dark_salmon = 0xE9967A,              // rgb(233,150,122)\n  dark_sea_green = 0x8FBC8F,           // rgb(143,188,143)\n  dark_slate_blue = 0x483D8B,          // rgb(72,61,139)\n  dark_slate_gray = 0x2F4F4F,          // rgb(47,79,79)\n  dark_turquoise = 0x00CED1,           // rgb(0,206,209)\n  dark_violet = 0x9400D3,              // rgb(148,0,211)\n  deep_pink = 0xFF1493,                // rgb(255,20,147)\n  deep_sky_blue = 0x00BFFF,            // rgb(0,191,255)\n  dim_gray = 0x696969,                 // rgb(105,105,105)\n  dodger_blue = 0x1E90FF,              // rgb(30,144,255)\n  fire_brick = 0xB22222,               // rgb(178,34,34)\n  floral_white = 0xFFFAF0,             // rgb(255,250,240)\n  forest_green = 0x228B22,             // rgb(34,139,34)\n  fuchsia = 0xFF00FF,                  // rgb(255,0,255)\n  gainsboro = 0xDCDCDC,                // rgb(220,220,220)\n  ghost_white = 0xF8F8FF,              // rgb(248,248,255)\n  gold = 0xFFD700,                     // rgb(255,215,0)\n  golden_rod = 0xDAA520,               // rgb(218,165,32)\n  gray = 0x808080,                     // rgb(128,128,128)\n  green = 0x008000,                    // rgb(0,128,0)\n  green_yellow = 0xADFF2F,             // rgb(173,255,47)\n  honey_dew = 0xF0FFF0,                // rgb(240,255,240)\n  hot_pink = 0xFF69B4,                 // rgb(255,105,180)\n  indian_red = 0xCD5C5C,               // rgb(205,92,92)\n  indigo = 0x4B0082,                   // rgb(75,0,130)\n  ivory = 0xFFFFF0,                    // rgb(255,255,240)\n  khaki = 0xF0E68C,                    // rgb(240,230,140)\n  lavender = 0xE6E6FA,                 // rgb(230,230,250)\n  lavender_blush = 0xFFF0F5,           // rgb(255,240,245)\n  lawn_green = 0x7CFC00,               // rgb(124,252,0)\n  lemon_chiffon = 0xFFFACD,            // rgb(255,250,205)\n  light_blue = 0xADD8E6,               // rgb(173,216,230)\n  light_coral = 0xF08080,              // rgb(240,128,128)\n  light_cyan = 0xE0FFFF,               // rgb(224,255,255)\n  light_golden_rod_yellow = 0xFAFAD2,  // rgb(250,250,210)\n  light_gray = 0xD3D3D3,               // rgb(211,211,211)\n  light_green = 0x90EE90,              // rgb(144,238,144)\n  light_pink = 0xFFB6C1,               // rgb(255,182,193)\n  light_salmon = 0xFFA07A,             // rgb(255,160,122)\n  light_sea_green = 0x20B2AA,          // rgb(32,178,170)\n  light_sky_blue = 0x87CEFA,           // rgb(135,206,250)\n  light_slate_gray = 0x778899,         // rgb(119,136,153)\n  light_steel_blue = 0xB0C4DE,         // rgb(176,196,222)\n  light_yellow = 0xFFFFE0,             // rgb(255,255,224)\n  lime = 0x00FF00,                     // rgb(0,255,0)\n  lime_green = 0x32CD32,               // rgb(50,205,50)\n  linen = 0xFAF0E6,                    // rgb(250,240,230)\n  magenta = 0xFF00FF,                  // rgb(255,0,255)\n  maroon = 0x800000,                   // rgb(128,0,0)\n  medium_aquamarine = 0x66CDAA,        // rgb(102,205,170)\n  medium_blue = 0x0000CD,              // rgb(0,0,205)\n  medium_orchid = 0xBA55D3,            // rgb(186,85,211)\n  medium_purple = 0x9370DB,            // rgb(147,112,219)\n  medium_sea_green = 0x3CB371,         // rgb(60,179,113)\n  medium_slate_blue = 0x7B68EE,        // rgb(123,104,238)\n  medium_spring_green = 0x00FA9A,      // rgb(0,250,154)\n  medium_turquoise = 0x48D1CC,         // rgb(72,209,204)\n  medium_violet_red = 0xC71585,        // rgb(199,21,133)\n  midnight_blue = 0x191970,            // rgb(25,25,112)\n  mint_cream = 0xF5FFFA,               // rgb(245,255,250)\n  misty_rose = 0xFFE4E1,               // rgb(255,228,225)\n  moccasin = 0xFFE4B5,                 // rgb(255,228,181)\n  navajo_white = 0xFFDEAD,             // rgb(255,222,173)\n  navy = 0x000080,                     // rgb(0,0,128)\n  old_lace = 0xFDF5E6,                 // rgb(253,245,230)\n  olive = 0x808000,                    // rgb(128,128,0)\n  olive_drab = 0x6B8E23,               // rgb(107,142,35)\n  orange = 0xFFA500,                   // rgb(255,165,0)\n  orange_red = 0xFF4500,               // rgb(255,69,0)\n  orchid = 0xDA70D6,                   // rgb(218,112,214)\n  pale_golden_rod = 0xEEE8AA,          // rgb(238,232,170)\n  pale_green = 0x98FB98,               // rgb(152,251,152)\n  pale_turquoise = 0xAFEEEE,           // rgb(175,238,238)\n  pale_violet_red = 0xDB7093,          // rgb(219,112,147)\n  papaya_whip = 0xFFEFD5,              // rgb(255,239,213)\n  peach_puff = 0xFFDAB9,               // rgb(255,218,185)\n  peru = 0xCD853F,                     // rgb(205,133,63)\n  pink = 0xFFC0CB,                     // rgb(255,192,203)\n  plum = 0xDDA0DD,                     // rgb(221,160,221)\n  powder_blue = 0xB0E0E6,              // rgb(176,224,230)\n  purple = 0x800080,                   // rgb(128,0,128)\n  rebecca_purple = 0x663399,           // rgb(102,51,153)\n  red = 0xFF0000,                      // rgb(255,0,0)\n  rosy_brown = 0xBC8F8F,               // rgb(188,143,143)\n  royal_blue = 0x4169E1,               // rgb(65,105,225)\n  saddle_brown = 0x8B4513,             // rgb(139,69,19)\n  salmon = 0xFA8072,                   // rgb(250,128,114)\n  sandy_brown = 0xF4A460,              // rgb(244,164,96)\n  sea_green = 0x2E8B57,                // rgb(46,139,87)\n  sea_shell = 0xFFF5EE,                // rgb(255,245,238)\n  sienna = 0xA0522D,                   // rgb(160,82,45)\n  silver = 0xC0C0C0,                   // rgb(192,192,192)\n  sky_blue = 0x87CEEB,                 // rgb(135,206,235)\n  slate_blue = 0x6A5ACD,               // rgb(106,90,205)\n  slate_gray = 0x708090,               // rgb(112,128,144)\n  snow = 0xFFFAFA,                     // rgb(255,250,250)\n  spring_green = 0x00FF7F,             // rgb(0,255,127)\n  steel_blue = 0x4682B4,               // rgb(70,130,180)\n  tan = 0xD2B48C,                      // rgb(210,180,140)\n  teal = 0x008080,                     // rgb(0,128,128)\n  thistle = 0xD8BFD8,                  // rgb(216,191,216)\n  tomato = 0xFF6347,                   // rgb(255,99,71)\n  turquoise = 0x40E0D0,                // rgb(64,224,208)\n  violet = 0xEE82EE,                   // rgb(238,130,238)\n  wheat = 0xF5DEB3,                    // rgb(245,222,179)\n  white = 0xFFFFFF,                    // rgb(255,255,255)\n  white_smoke = 0xF5F5F5,              // rgb(245,245,245)\n  yellow = 0xFFFF00,                   // rgb(255,255,0)\n  yellow_green = 0x9ACD32              // rgb(154,205,50)\n};                                     // enum class color\n\nenum class terminal_color : uint8_t {\n  black = 30,\n  red,\n  green,\n  yellow,\n  blue,\n  magenta,\n  cyan,\n  white,\n  bright_black = 90,\n  bright_red,\n  bright_green,\n  bright_yellow,\n  bright_blue,\n  bright_magenta,\n  bright_cyan,\n  bright_white\n};\n\nenum class emphasis : uint8_t {\n  bold = 1,\n  faint = 1 << 1,\n  italic = 1 << 2,\n  underline = 1 << 3,\n  blink = 1 << 4,\n  reverse = 1 << 5,\n  conceal = 1 << 6,\n  strikethrough = 1 << 7,\n};\n\n// rgb is a struct for red, green and blue colors.\n// Using the name \"rgb\" makes some editors show the color in a tooltip.\nstruct rgb {\n  constexpr rgb() : r(0), g(0), b(0) {}\n  constexpr rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {}\n  constexpr rgb(uint32_t hex)\n      : r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {}\n  constexpr rgb(color hex)\n      : r((uint32_t(hex) >> 16) & 0xFF),\n        g((uint32_t(hex) >> 8) & 0xFF),\n        b(uint32_t(hex) & 0xFF) {}\n  uint8_t r;\n  uint8_t g;\n  uint8_t b;\n};\n\nnamespace detail {\n\n// A bit-packed variant of an RGB color, a terminal color, or unset color.\n// see text_style for the bit-packing scheme.\nstruct color_type {\n  constexpr color_type() noexcept = default;\n  constexpr color_type(color rgb_color) noexcept\n      : value_(static_cast<uint32_t>(rgb_color) | (1 << 24)) {}\n  constexpr color_type(rgb rgb_color) noexcept\n      : color_type(static_cast<color>(\n            (static_cast<uint32_t>(rgb_color.r) << 16) |\n            (static_cast<uint32_t>(rgb_color.g) << 8) | rgb_color.b)) {}\n  constexpr color_type(terminal_color term_color) noexcept\n      : value_(static_cast<uint32_t>(term_color) | (3 << 24)) {}\n\n  constexpr auto is_terminal_color() const noexcept -> bool {\n    return (value_ & (1 << 25)) != 0;\n  }\n\n  constexpr auto value() const noexcept -> uint32_t {\n    return value_ & 0xFFFFFF;\n  }\n\n  constexpr color_type(uint32_t value) noexcept : value_(value) {}\n\n  uint32_t value_ = 0;\n};\n}  // namespace detail\n\n/// A text style consisting of foreground and background colors and emphasis.\nclass text_style {\n  // The information is packed as follows:\n  // ┌──┐\n  // │ 0│─┐\n  // │..│ ├── foreground color value\n  // │23│─┘\n  // ├──┤\n  // │24│─┬── discriminator for the above value. 00 if unset, 01 if it's\n  // │25│─┘   an RGB color, or 11 if it's a terminal color (10 is unused)\n  // ├──┤\n  // │26│──── overflow bit, always zero (see below)\n  // ├──┤\n  // │27│─┐\n  // │..│ │\n  // │50│ │\n  // ├──┤ │\n  // │51│ ├── background color (same format as the foreground color)\n  // │52│ │\n  // ├──┤ │\n  // │53│─┘\n  // ├──┤\n  // │54│─┐\n  // │..│ ├── emphases\n  // │61│─┘\n  // ├──┤\n  // │62│─┬── unused\n  // │63│─┘\n  // └──┘\n  // The overflow bits are there to make operator|= efficient.\n  // When ORing, we must throw if, for either the foreground or background,\n  // one style specifies a terminal color and the other specifies any color\n  // (terminal or RGB); in other words, if one discriminator is 11 and the\n  // other is 11 or 01.\n  //\n  // We do that check by adding the styles. Consider what adding does to each\n  // possible pair of discriminators:\n  //    00 + 00 = 000\n  //    01 + 00 = 001\n  //    11 + 00 = 011\n  //    01 + 01 = 010\n  //    11 + 01 = 100 (!!)\n  //    11 + 11 = 110 (!!)\n  // In the last two cases, the ones we want to catch, the third bit——the\n  // overflow bit——is set. Bingo.\n  //\n  // We must take into account the possible carry bit from the bits\n  // before the discriminator. The only potentially problematic case is\n  // 11 + 00 = 011 (a carry bit would make it 100, not good!), but a carry\n  // bit is impossible in that case, because 00 (unset color) means the\n  // 24 bits that precede the discriminator are all zero.\n  //\n  // This test can be applied to both colors simultaneously.\n\n public:\n  FMT_CONSTEXPR text_style(emphasis em = emphasis()) noexcept\n      : style_(static_cast<uint64_t>(em) << 54) {}\n\n  FMT_CONSTEXPR auto operator|=(text_style rhs) -> text_style& {\n    if (((style_ + rhs.style_) & ((1ULL << 26) | (1ULL << 53))) != 0)\n      report_error(\"can't OR a terminal color\");\n    style_ |= rhs.style_;\n    return *this;\n  }\n\n  friend FMT_CONSTEXPR auto operator|(text_style lhs, text_style rhs)\n      -> text_style {\n    return lhs |= rhs;\n  }\n\n  FMT_CONSTEXPR auto operator==(text_style rhs) const noexcept -> bool {\n    return style_ == rhs.style_;\n  }\n\n  FMT_CONSTEXPR auto operator!=(text_style rhs) const noexcept -> bool {\n    return !(*this == rhs);\n  }\n\n  FMT_CONSTEXPR auto has_foreground() const noexcept -> bool {\n    return (style_ & (1 << 24)) != 0;\n  }\n  FMT_CONSTEXPR auto has_background() const noexcept -> bool {\n    return (style_ & (1ULL << 51)) != 0;\n  }\n  FMT_CONSTEXPR auto has_emphasis() const noexcept -> bool {\n    return (style_ >> 54) != 0;\n  }\n  FMT_CONSTEXPR auto get_foreground() const noexcept -> detail::color_type {\n    FMT_ASSERT(has_foreground(), \"no foreground specified for this style\");\n    return style_ & 0x3FFFFFF;\n  }\n  FMT_CONSTEXPR auto get_background() const noexcept -> detail::color_type {\n    FMT_ASSERT(has_background(), \"no background specified for this style\");\n    return (style_ >> 27) & 0x3FFFFFF;\n  }\n  FMT_CONSTEXPR auto get_emphasis() const noexcept -> emphasis {\n    FMT_ASSERT(has_emphasis(), \"no emphasis specified for this style\");\n    return static_cast<emphasis>(style_ >> 54);\n  }\n\n private:\n  FMT_CONSTEXPR text_style(uint64_t style) noexcept : style_(style) {}\n\n  friend FMT_CONSTEXPR auto fg(detail::color_type foreground) noexcept\n      -> text_style;\n\n  friend FMT_CONSTEXPR auto bg(detail::color_type background) noexcept\n      -> text_style;\n\n  uint64_t style_ = 0;\n};\n\n/// Creates a text style from the foreground (text) color.\nFMT_CONSTEXPR inline auto fg(detail::color_type foreground) noexcept\n    -> text_style {\n  return foreground.value_;\n}\n\n/// Creates a text style from the background color.\nFMT_CONSTEXPR inline auto bg(detail::color_type background) noexcept\n    -> text_style {\n  return static_cast<uint64_t>(background.value_) << 27;\n}\n\nFMT_CONSTEXPR inline auto operator|(emphasis lhs, emphasis rhs) noexcept\n    -> text_style {\n  return text_style(lhs) | rhs;\n}\n\nnamespace detail {\n\ntemplate <typename Char> struct ansi_color_escape {\n  FMT_CONSTEXPR ansi_color_escape(color_type text_color,\n                                  const char* esc) noexcept {\n    // If we have a terminal color, we need to output another escape code\n    // sequence.\n    if (text_color.is_terminal_color()) {\n      bool is_background = esc == string_view(\"\\x1b[48;2;\");\n      uint32_t value = text_color.value();\n      // Background ASCII codes are the same as the foreground ones but with\n      // 10 more.\n      if (is_background) value += 10u;\n\n      buffer[size++] = static_cast<Char>('\\x1b');\n      buffer[size++] = static_cast<Char>('[');\n\n      if (value >= 100u) {\n        buffer[size++] = static_cast<Char>('1');\n        value %= 100u;\n      }\n      buffer[size++] = static_cast<Char>('0' + value / 10u);\n      buffer[size++] = static_cast<Char>('0' + value % 10u);\n\n      buffer[size++] = static_cast<Char>('m');\n      return;\n    }\n\n    for (int i = 0; i < 7; i++) {\n      buffer[i] = static_cast<Char>(esc[i]);\n    }\n    rgb color(text_color.value());\n    to_esc(color.r, buffer + 7, ';');\n    to_esc(color.g, buffer + 11, ';');\n    to_esc(color.b, buffer + 15, 'm');\n    size = 19;\n  }\n  FMT_CONSTEXPR ansi_color_escape(emphasis em) noexcept {\n    uint8_t em_codes[num_emphases] = {};\n    if (has_emphasis(em, emphasis::bold)) em_codes[0] = 1;\n    if (has_emphasis(em, emphasis::faint)) em_codes[1] = 2;\n    if (has_emphasis(em, emphasis::italic)) em_codes[2] = 3;\n    if (has_emphasis(em, emphasis::underline)) em_codes[3] = 4;\n    if (has_emphasis(em, emphasis::blink)) em_codes[4] = 5;\n    if (has_emphasis(em, emphasis::reverse)) em_codes[5] = 7;\n    if (has_emphasis(em, emphasis::conceal)) em_codes[6] = 8;\n    if (has_emphasis(em, emphasis::strikethrough)) em_codes[7] = 9;\n\n    buffer[size++] = static_cast<Char>('\\x1b');\n    buffer[size++] = static_cast<Char>('[');\n\n    for (size_t i = 0; i < num_emphases; ++i) {\n      if (!em_codes[i]) continue;\n      buffer[size++] = static_cast<Char>('0' + em_codes[i]);\n      buffer[size++] = static_cast<Char>(';');\n    }\n\n    buffer[size - 1] = static_cast<Char>('m');\n  }\n  FMT_CONSTEXPR operator const Char*() const noexcept { return buffer; }\n\n  FMT_CONSTEXPR auto begin() const noexcept -> const Char* { return buffer; }\n  FMT_CONSTEXPR auto end() const noexcept -> const Char* {\n    return buffer + size;\n  }\n\n private:\n  static constexpr size_t num_emphases = 8;\n  Char buffer[7u + 4u * num_emphases] = {};\n  size_t size = 0;\n\n  static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out,\n                                   char delimiter) noexcept {\n    out[0] = static_cast<Char>('0' + c / 100);\n    out[1] = static_cast<Char>('0' + c / 10 % 10);\n    out[2] = static_cast<Char>('0' + c % 10);\n    out[3] = static_cast<Char>(delimiter);\n  }\n  static FMT_CONSTEXPR auto has_emphasis(emphasis em, emphasis mask) noexcept\n      -> bool {\n    return static_cast<uint8_t>(em) & static_cast<uint8_t>(mask);\n  }\n};\n\ntemplate <typename Char>\nFMT_CONSTEXPR auto make_foreground_color(color_type foreground) noexcept\n    -> ansi_color_escape<Char> {\n  return ansi_color_escape<Char>(foreground, \"\\x1b[38;2;\");\n}\n\ntemplate <typename Char>\nFMT_CONSTEXPR auto make_background_color(color_type background) noexcept\n    -> ansi_color_escape<Char> {\n  return ansi_color_escape<Char>(background, \"\\x1b[48;2;\");\n}\n\ntemplate <typename Char>\nFMT_CONSTEXPR auto make_emphasis(emphasis em) noexcept\n    -> ansi_color_escape<Char> {\n  return ansi_color_escape<Char>(em);\n}\n\ntemplate <typename Char> inline void reset_color(buffer<Char>& buffer) {\n  auto reset_color = string_view(\"\\x1b[0m\");\n  buffer.append(reset_color.begin(), reset_color.end());\n}\n\ntemplate <typename T> struct styled_arg : view {\n  const T& value;\n  text_style style;\n  styled_arg(const T& v, text_style s) : value(v), style(s) {}\n};\n\ntemplate <typename Char>\nvoid vformat_to(buffer<Char>& buf, text_style ts, basic_string_view<Char> fmt,\n                basic_format_args<buffered_context<Char>> args) {\n  if (ts.has_emphasis()) {\n    auto emphasis = make_emphasis<Char>(ts.get_emphasis());\n    buf.append(emphasis.begin(), emphasis.end());\n  }\n  if (ts.has_foreground()) {\n    auto foreground = make_foreground_color<Char>(ts.get_foreground());\n    buf.append(foreground.begin(), foreground.end());\n  }\n  if (ts.has_background()) {\n    auto background = make_background_color<Char>(ts.get_background());\n    buf.append(background.begin(), background.end());\n  }\n  vformat_to(buf, fmt, args);\n  if (ts != text_style()) reset_color<Char>(buf);\n}\n}  // namespace detail\n\ninline void vprint(FILE* f, text_style ts, string_view fmt, format_args args) {\n  auto buf = memory_buffer();\n  detail::vformat_to(buf, ts, fmt, args);\n  print(f, FMT_STRING(\"{}\"), string_view(buf.begin(), buf.size()));\n}\n\n/**\n * Formats a string and prints it to the specified file stream using ANSI\n * escape sequences to specify text formatting.\n *\n * **Example**:\n *\n *     fmt::print(fmt::emphasis::bold | fg(fmt::color::red),\n *                \"Elapsed time: {0:.2f} seconds\", 1.23);\n */\ntemplate <typename... T>\nvoid print(FILE* f, text_style ts, format_string<T...> fmt, T&&... args) {\n  vprint(f, ts, fmt.str, vargs<T...>{{args...}});\n}\n\n/**\n * Formats a string and prints it to stdout using ANSI escape sequences to\n * specify text formatting.\n *\n * **Example**:\n *\n *     fmt::print(fmt::emphasis::bold | fg(fmt::color::red),\n *                \"Elapsed time: {0:.2f} seconds\", 1.23);\n */\ntemplate <typename... T>\nvoid print(text_style ts, format_string<T...> fmt, T&&... args) {\n  return print(stdout, ts, fmt, std::forward<T>(args)...);\n}\n\ninline auto vformat(text_style ts, string_view fmt, format_args args)\n    -> std::string {\n  auto buf = memory_buffer();\n  detail::vformat_to(buf, ts, fmt, args);\n  return fmt::to_string(buf);\n}\n\n/**\n * Formats arguments and returns the result as a string using ANSI escape\n * sequences to specify text formatting.\n *\n * **Example**:\n *\n * ```\n * #include <fmt/color.h>\n * std::string message = fmt::format(fmt::emphasis::bold | fg(fmt::color::red),\n *                                   \"The answer is {}\", 42);\n * ```\n */\ntemplate <typename... T>\ninline auto format(text_style ts, format_string<T...> fmt, T&&... args)\n    -> std::string {\n  return fmt::vformat(ts, fmt.str, vargs<T...>{{args...}});\n}\n\n/// Formats a string with the given text_style and writes the output to `out`.\ntemplate <typename OutputIt,\n          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>\nauto vformat_to(OutputIt out, text_style ts, string_view fmt, format_args args)\n    -> OutputIt {\n  auto&& buf = detail::get_buffer<char>(out);\n  detail::vformat_to(buf, ts, fmt, args);\n  return detail::get_iterator(buf, out);\n}\n\n/**\n * Formats arguments with the given text style, writes the result to the output\n * iterator `out` and returns the iterator past the end of the output range.\n *\n * **Example**:\n *\n *     std::vector<char> out;\n *     fmt::format_to(std::back_inserter(out),\n *                    fmt::emphasis::bold | fg(fmt::color::red), \"{}\", 42);\n */\ntemplate <typename OutputIt, typename... T,\n          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>\ninline auto format_to(OutputIt out, text_style ts, format_string<T...> fmt,\n                      T&&... args) -> OutputIt {\n  return vformat_to(out, ts, fmt.str, vargs<T...>{{args...}});\n}\n\ntemplate <typename T, typename Char>\nstruct formatter<detail::styled_arg<T>, Char> : formatter<T, Char> {\n  template <typename FormatContext>\n  auto format(const detail::styled_arg<T>& arg, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    const auto& ts = arg.style;\n    auto out = ctx.out();\n\n    bool has_style = false;\n    if (ts.has_emphasis()) {\n      has_style = true;\n      auto emphasis = detail::make_emphasis<Char>(ts.get_emphasis());\n      out = detail::copy<Char>(emphasis.begin(), emphasis.end(), out);\n    }\n    if (ts.has_foreground()) {\n      has_style = true;\n      auto foreground =\n          detail::make_foreground_color<Char>(ts.get_foreground());\n      out = detail::copy<Char>(foreground.begin(), foreground.end(), out);\n    }\n    if (ts.has_background()) {\n      has_style = true;\n      auto background =\n          detail::make_background_color<Char>(ts.get_background());\n      out = detail::copy<Char>(background.begin(), background.end(), out);\n    }\n    out = formatter<T, Char>::format(arg.value, ctx);\n    if (has_style) {\n      auto reset_color = string_view(\"\\x1b[0m\");\n      out = detail::copy<Char>(reset_color.begin(), reset_color.end(), out);\n    }\n    return out;\n  }\n};\n\n/**\n * Returns an argument that will be formatted using ANSI escape sequences,\n * to be used in a formatting function.\n *\n * **Example**:\n *\n *     fmt::print(\"Elapsed time: {0:.2f} seconds\",\n *                fmt::styled(1.23, fmt::fg(fmt::color::green) |\n *                                  fmt::bg(fmt::color::blue)));\n */\ntemplate <typename T>\nFMT_CONSTEXPR auto styled(const T& value, text_style ts)\n    -> detail::styled_arg<remove_cvref_t<T>> {\n  return detail::styled_arg<remove_cvref_t<T>>{value, ts};\n}\n\nFMT_END_EXPORT\nFMT_END_NAMESPACE\n\n#endif  // FMT_COLOR_H_\n"
  },
  {
    "path": "thirdparty/fmt/include/fmt/compile.h",
    "content": "// Formatting library for C++ - experimental format string compilation\n//\n// Copyright (c) 2012 - present, Victor Zverovich and fmt contributors\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\n#ifndef FMT_COMPILE_H_\n#define FMT_COMPILE_H_\n\n#ifndef FMT_MODULE\n#  include <iterator>  // std::back_inserter\n#endif\n\n#include \"format.h\"\n\nFMT_BEGIN_NAMESPACE\nFMT_BEGIN_EXPORT\n\n// A compile-time string which is compiled into fast formatting code.\nclass compiled_string {};\n\ntemplate <typename S>\nstruct is_compiled_string : std::is_base_of<compiled_string, S> {};\n\n/**\n * Converts a string literal `s` into a format string that will be parsed at\n * compile time and converted into efficient formatting code. Requires C++17\n * `constexpr if` compiler support.\n *\n * **Example**:\n *\n *     // Converts 42 into std::string using the most efficient method and no\n *     // runtime format string processing.\n *     std::string s = fmt::format(FMT_COMPILE(\"{}\"), 42);\n */\n#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)\n#  define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::compiled_string)\n#else\n#  define FMT_COMPILE(s) FMT_STRING(s)\n#endif\n\n/**\n * Converts a string literal into a format string that will be parsed at\n * compile time and converted into efficient formatting code. Requires support\n * for class types in constant template parameters (a C++20 feature).\n *\n *  **Example**:\n *\n *     // Converts 42 into std::string using the most efficient method and no\n *     // runtime format string processing.\n *     using namespace fmt::literals;\n *     std::string s = fmt::format(\"{}\"_cf, 42);\n */\n#if FMT_USE_NONTYPE_TEMPLATE_ARGS\ninline namespace literals {\ntemplate <detail::fixed_string Str> constexpr auto operator\"\"_cf() {\n  return FMT_COMPILE(Str.data);\n}\n}  // namespace literals\n#endif\n\nFMT_END_EXPORT\n\nnamespace detail {\n\ntemplate <typename T, typename... Tail>\nconstexpr auto first(const T& value, const Tail&...) -> const T& {\n  return value;\n}\n\n#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)\ntemplate <typename... T> struct type_list {};\n\n// Returns a reference to the argument at index N from [first, rest...].\ntemplate <int N, typename T, typename... Args>\nconstexpr auto get([[maybe_unused]] const T& first,\n                   [[maybe_unused]] const Args&... rest) -> const auto& {\n  static_assert(N < 1 + sizeof...(Args), \"index is out of bounds\");\n  if constexpr (N == 0)\n    return first;\n  else\n    return detail::get<N - 1>(rest...);\n}\n\n#  if FMT_USE_NONTYPE_TEMPLATE_ARGS\ntemplate <int N, typename T, typename... Args, typename Char>\nconstexpr auto get_arg_index_by_name(basic_string_view<Char> name) -> int {\n  if constexpr (is_static_named_arg<T>()) {\n    if (name == T::name) return N;\n  }\n  if constexpr (sizeof...(Args) > 0)\n    return get_arg_index_by_name<N + 1, Args...>(name);\n  (void)name;  // Workaround an MSVC bug about \"unused\" parameter.\n  return -1;\n}\n#  endif\n\ntemplate <typename... Args, typename Char>\nFMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view<Char> name) -> int {\n#  if FMT_USE_NONTYPE_TEMPLATE_ARGS\n  if constexpr (sizeof...(Args) > 0)\n    return get_arg_index_by_name<0, Args...>(name);\n#  endif\n  (void)name;\n  return -1;\n}\n\ntemplate <typename Char, typename... Args>\nconstexpr auto get_arg_index_by_name(basic_string_view<Char> name,\n                                     type_list<Args...>) -> int {\n  return get_arg_index_by_name<Args...>(name);\n}\n\ntemplate <int N, typename> struct get_type_impl;\n\ntemplate <int N, typename... Args> struct get_type_impl<N, type_list<Args...>> {\n  using type =\n      remove_cvref_t<decltype(detail::get<N>(std::declval<Args>()...))>;\n};\n\ntemplate <int N, typename T>\nusing get_type = typename get_type_impl<N, T>::type;\n\ntemplate <typename T> struct is_compiled_format : std::false_type {};\n\ntemplate <typename Char> struct text {\n  basic_string_view<Char> data;\n  using char_type = Char;\n\n  template <typename OutputIt, typename... T>\n  constexpr auto format(OutputIt out, const T&...) const -> OutputIt {\n    return write<Char>(out, data);\n  }\n};\n\ntemplate <typename Char>\nstruct is_compiled_format<text<Char>> : std::true_type {};\n\ntemplate <typename Char>\nconstexpr auto make_text(basic_string_view<Char> s, size_t pos, size_t size)\n    -> text<Char> {\n  return {{&s[pos], size}};\n}\n\ntemplate <typename Char> struct code_unit {\n  Char value;\n  using char_type = Char;\n\n  template <typename OutputIt, typename... T>\n  constexpr auto format(OutputIt out, const T&...) const -> OutputIt {\n    *out++ = value;\n    return out;\n  }\n};\n\n// This ensures that the argument type is convertible to `const T&`.\ntemplate <typename T, int N, typename... Args>\nconstexpr auto get_arg_checked(const Args&... args) -> const T& {\n  const auto& arg = detail::get<N>(args...);\n  if constexpr (detail::is_named_arg<remove_cvref_t<decltype(arg)>>()) {\n    return arg.value;\n  } else {\n    return arg;\n  }\n}\n\ntemplate <typename Char>\nstruct is_compiled_format<code_unit<Char>> : std::true_type {};\n\n// A replacement field that refers to argument N.\ntemplate <typename Char, typename V, int N> struct field {\n  using char_type = Char;\n\n  template <typename OutputIt, typename... T>\n  constexpr auto format(OutputIt out, const T&... args) const -> OutputIt {\n    const V& arg = get_arg_checked<V, N>(args...);\n    if constexpr (std::is_convertible<V, basic_string_view<Char>>::value) {\n      auto s = basic_string_view<Char>(arg);\n      return copy<Char>(s.begin(), s.end(), out);\n    } else {\n      return write<Char>(out, arg);\n    }\n  }\n};\n\ntemplate <typename Char, typename T, int N>\nstruct is_compiled_format<field<Char, T, N>> : std::true_type {};\n\n// A replacement field that refers to argument with name.\ntemplate <typename Char> struct runtime_named_field {\n  using char_type = Char;\n  basic_string_view<Char> name;\n\n  template <typename OutputIt, typename T>\n  constexpr static auto try_format_argument(\n      OutputIt& out,\n      // [[maybe_unused]] due to unused-but-set-parameter warning in GCC 7,8,9\n      [[maybe_unused]] basic_string_view<Char> arg_name, const T& arg) -> bool {\n    if constexpr (is_named_arg<typename std::remove_cv<T>::type>::value) {\n      if (arg_name == arg.name) {\n        out = write<Char>(out, arg.value);\n        return true;\n      }\n    }\n    return false;\n  }\n\n  template <typename OutputIt, typename... T>\n  constexpr auto format(OutputIt out, const T&... args) const -> OutputIt {\n    bool found = (try_format_argument(out, name, args) || ...);\n    if (!found) {\n      FMT_THROW(format_error(\"argument with specified name is not found\"));\n    }\n    return out;\n  }\n};\n\ntemplate <typename Char>\nstruct is_compiled_format<runtime_named_field<Char>> : std::true_type {};\n\n// A replacement field that refers to argument N and has format specifiers.\ntemplate <typename Char, typename V, int N> struct spec_field {\n  using char_type = Char;\n  formatter<V, Char> fmt;\n\n  template <typename OutputIt, typename... T>\n  constexpr FMT_INLINE auto format(OutputIt out, const T&... args) const\n      -> OutputIt {\n    const auto& vargs =\n        fmt::make_format_args<basic_format_context<OutputIt, Char>>(args...);\n    basic_format_context<OutputIt, Char> ctx(out, vargs);\n    return fmt.format(get_arg_checked<V, N>(args...), ctx);\n  }\n};\n\ntemplate <typename Char, typename T, int N>\nstruct is_compiled_format<spec_field<Char, T, N>> : std::true_type {};\n\ntemplate <typename L, typename R> struct concat {\n  L lhs;\n  R rhs;\n  using char_type = typename L::char_type;\n\n  template <typename OutputIt, typename... T>\n  constexpr auto format(OutputIt out, const T&... args) const -> OutputIt {\n    out = lhs.format(out, args...);\n    return rhs.format(out, args...);\n  }\n};\n\ntemplate <typename L, typename R>\nstruct is_compiled_format<concat<L, R>> : std::true_type {};\n\ntemplate <typename L, typename R>\nconstexpr auto make_concat(L lhs, R rhs) -> concat<L, R> {\n  return {lhs, rhs};\n}\n\nstruct unknown_format {};\n\ntemplate <typename Char>\nconstexpr auto parse_text(basic_string_view<Char> str, size_t pos) -> size_t {\n  for (size_t size = str.size(); pos != size; ++pos) {\n    if (str[pos] == '{' || str[pos] == '}') break;\n  }\n  return pos;\n}\n\ntemplate <typename Args, size_t POS, int ID, typename S>\nconstexpr auto compile_format_string(S fmt);\n\ntemplate <typename Args, size_t POS, int ID, typename T, typename S>\nconstexpr auto parse_tail(T head, S fmt) {\n  if constexpr (POS != basic_string_view<typename S::char_type>(fmt).size()) {\n    constexpr auto tail = compile_format_string<Args, POS, ID>(fmt);\n    if constexpr (std::is_same<remove_cvref_t<decltype(tail)>,\n                               unknown_format>())\n      return tail;\n    else\n      return make_concat(head, tail);\n  } else {\n    return head;\n  }\n}\n\ntemplate <typename T, typename Char> struct parse_specs_result {\n  formatter<T, Char> fmt;\n  size_t end;\n  int next_arg_id;\n};\n\nenum { manual_indexing_id = -1 };\n\ntemplate <typename T, typename Char>\nconstexpr auto parse_specs(basic_string_view<Char> str, size_t pos,\n                           int next_arg_id) -> parse_specs_result<T, Char> {\n  str.remove_prefix(pos);\n  auto ctx =\n      compile_parse_context<Char>(str, max_value<int>(), nullptr, next_arg_id);\n  auto f = formatter<T, Char>();\n  auto end = f.parse(ctx);\n  return {f, pos + fmt::detail::to_unsigned(end - str.data()),\n          next_arg_id == 0 ? manual_indexing_id : ctx.next_arg_id()};\n}\n\ntemplate <typename Char> struct arg_id_handler {\n  arg_id_kind kind;\n  arg_ref<Char> arg_id;\n\n  constexpr auto on_auto() -> int {\n    FMT_ASSERT(false, \"handler cannot be used with automatic indexing\");\n    return 0;\n  }\n  constexpr auto on_index(int id) -> int {\n    kind = arg_id_kind::index;\n    arg_id = arg_ref<Char>(id);\n    return 0;\n  }\n  constexpr auto on_name(basic_string_view<Char> id) -> int {\n    kind = arg_id_kind::name;\n    arg_id = arg_ref<Char>(id);\n    return 0;\n  }\n};\n\ntemplate <typename Char> struct parse_arg_id_result {\n  arg_id_kind kind;\n  arg_ref<Char> arg_id;\n  const Char* arg_id_end;\n};\n\ntemplate <int ID, typename Char>\nconstexpr auto parse_arg_id(const Char* begin, const Char* end) {\n  auto handler = arg_id_handler<Char>{arg_id_kind::none, arg_ref<Char>{}};\n  auto arg_id_end = parse_arg_id(begin, end, handler);\n  return parse_arg_id_result<Char>{handler.kind, handler.arg_id, arg_id_end};\n}\n\ntemplate <typename T, typename Enable = void> struct field_type {\n  using type = remove_cvref_t<T>;\n};\n\ntemplate <typename T>\nstruct field_type<T, enable_if_t<detail::is_named_arg<T>::value>> {\n  using type = remove_cvref_t<decltype(T::value)>;\n};\n\ntemplate <typename T, typename Args, size_t END_POS, int ARG_INDEX, int NEXT_ID,\n          typename S>\nconstexpr auto parse_replacement_field_then_tail(S fmt) {\n  using char_type = typename S::char_type;\n  constexpr auto str = basic_string_view<char_type>(fmt);\n  constexpr char_type c = END_POS != str.size() ? str[END_POS] : char_type();\n  if constexpr (c == '}') {\n    return parse_tail<Args, END_POS + 1, NEXT_ID>(\n        field<char_type, typename field_type<T>::type, ARG_INDEX>(), fmt);\n  } else if constexpr (c != ':') {\n    FMT_THROW(format_error(\"expected ':'\"));\n  } else {\n    constexpr auto result = parse_specs<typename field_type<T>::type>(\n        str, END_POS + 1, NEXT_ID == manual_indexing_id ? 0 : NEXT_ID);\n    if constexpr (result.end >= str.size() || str[result.end] != '}') {\n      FMT_THROW(format_error(\"expected '}'\"));\n      return 0;\n    } else {\n      return parse_tail<Args, result.end + 1, result.next_arg_id>(\n          spec_field<char_type, typename field_type<T>::type, ARG_INDEX>{\n              result.fmt},\n          fmt);\n    }\n  }\n}\n\n// Compiles a non-empty format string and returns the compiled representation\n// or unknown_format() on unrecognized input.\ntemplate <typename Args, size_t POS, int ID, typename S>\nconstexpr auto compile_format_string(S fmt) {\n  using char_type = typename S::char_type;\n  constexpr auto str = basic_string_view<char_type>(fmt);\n  if constexpr (str[POS] == '{') {\n    if constexpr (POS + 1 == str.size())\n      FMT_THROW(format_error(\"unmatched '{' in format string\"));\n    if constexpr (str[POS + 1] == '{') {\n      return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), fmt);\n    } else if constexpr (str[POS + 1] == '}' || str[POS + 1] == ':') {\n      static_assert(ID != manual_indexing_id,\n                    \"cannot switch from manual to automatic argument indexing\");\n      constexpr auto next_id =\n          ID != manual_indexing_id ? ID + 1 : manual_indexing_id;\n      return parse_replacement_field_then_tail<get_type<ID, Args>, Args,\n                                               POS + 1, ID, next_id>(fmt);\n    } else {\n      constexpr auto arg_id_result =\n          parse_arg_id<ID>(str.data() + POS + 1, str.data() + str.size());\n      constexpr auto arg_id_end_pos = arg_id_result.arg_id_end - str.data();\n      constexpr char_type c =\n          arg_id_end_pos != str.size() ? str[arg_id_end_pos] : char_type();\n      static_assert(c == '}' || c == ':', \"missing '}' in format string\");\n      if constexpr (arg_id_result.kind == arg_id_kind::index) {\n        static_assert(\n            ID == manual_indexing_id || ID == 0,\n            \"cannot switch from automatic to manual argument indexing\");\n        constexpr auto arg_index = arg_id_result.arg_id.index;\n        return parse_replacement_field_then_tail<get_type<arg_index, Args>,\n                                                 Args, arg_id_end_pos,\n                                                 arg_index, manual_indexing_id>(\n            fmt);\n      } else if constexpr (arg_id_result.kind == arg_id_kind::name) {\n        constexpr auto arg_index =\n            get_arg_index_by_name(arg_id_result.arg_id.name, Args{});\n        if constexpr (arg_index >= 0) {\n          constexpr auto next_id =\n              ID != manual_indexing_id ? ID + 1 : manual_indexing_id;\n          return parse_replacement_field_then_tail<\n              decltype(get_type<arg_index, Args>::value), Args, arg_id_end_pos,\n              arg_index, next_id>(fmt);\n        } else if constexpr (c == '}') {\n          return parse_tail<Args, arg_id_end_pos + 1, ID>(\n              runtime_named_field<char_type>{arg_id_result.arg_id.name}, fmt);\n        } else if constexpr (c == ':') {\n          return unknown_format();  // no type info for specs parsing\n        }\n      }\n    }\n  } else if constexpr (str[POS] == '}') {\n    if constexpr (POS + 1 == str.size())\n      FMT_THROW(format_error(\"unmatched '}' in format string\"));\n    return parse_tail<Args, POS + 2, ID>(make_text(str, POS, 1), fmt);\n  } else {\n    constexpr auto end = parse_text(str, POS + 1);\n    if constexpr (end - POS > 1) {\n      return parse_tail<Args, end, ID>(make_text(str, POS, end - POS), fmt);\n    } else {\n      return parse_tail<Args, end, ID>(code_unit<char_type>{str[POS]}, fmt);\n    }\n  }\n}\n\ntemplate <typename... Args, typename S,\n          FMT_ENABLE_IF(is_compiled_string<S>::value)>\nconstexpr auto compile(S fmt) {\n  constexpr auto str = basic_string_view<typename S::char_type>(fmt);\n  if constexpr (str.size() == 0) {\n    return detail::make_text(str, 0, 0);\n  } else {\n    constexpr auto result =\n        detail::compile_format_string<detail::type_list<Args...>, 0, 0>(fmt);\n    return result;\n  }\n}\n#endif  // defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)\n}  // namespace detail\n\nFMT_BEGIN_EXPORT\n\n#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction)\n\ntemplate <typename CompiledFormat, typename... T,\n          typename Char = typename CompiledFormat::char_type,\n          FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>\nFMT_INLINE FMT_CONSTEXPR_STRING auto format(const CompiledFormat& cf,\n                                            const T&... args)\n    -> std::basic_string<Char> {\n  auto s = std::basic_string<Char>();\n  cf.format(std::back_inserter(s), args...);\n  return s;\n}\n\ntemplate <typename OutputIt, typename CompiledFormat, typename... T,\n          FMT_ENABLE_IF(detail::is_compiled_format<CompiledFormat>::value)>\nconstexpr FMT_INLINE auto format_to(OutputIt out, const CompiledFormat& cf,\n                                    const T&... args) -> OutputIt {\n  return cf.format(out, args...);\n}\n\ntemplate <typename S, typename... T,\n          FMT_ENABLE_IF(is_compiled_string<S>::value)>\nFMT_INLINE FMT_CONSTEXPR_STRING auto format(const S&, T&&... args)\n    -> std::basic_string<typename S::char_type> {\n  if constexpr (std::is_same<typename S::char_type, char>::value) {\n    constexpr auto str = basic_string_view<typename S::char_type>(S());\n    if constexpr (str.size() == 2 && str[0] == '{' && str[1] == '}') {\n      const auto& first = detail::first(args...);\n      if constexpr (detail::is_named_arg<\n                        remove_cvref_t<decltype(first)>>::value) {\n        return fmt::to_string(first.value);\n      } else {\n        return fmt::to_string(first);\n      }\n    }\n  }\n  constexpr auto compiled = detail::compile<T...>(S());\n  if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,\n                             detail::unknown_format>()) {\n    return fmt::format(\n        static_cast<basic_string_view<typename S::char_type>>(S()),\n        std::forward<T>(args)...);\n  } else {\n    return fmt::format(compiled, std::forward<T>(args)...);\n  }\n}\n\ntemplate <typename OutputIt, typename S, typename... T,\n          FMT_ENABLE_IF(is_compiled_string<S>::value)>\nFMT_CONSTEXPR auto format_to(OutputIt out, const S&, T&&... args) -> OutputIt {\n  constexpr auto compiled = detail::compile<T...>(S());\n  if constexpr (std::is_same<remove_cvref_t<decltype(compiled)>,\n                             detail::unknown_format>()) {\n    return fmt::format_to(\n        out, static_cast<basic_string_view<typename S::char_type>>(S()),\n        std::forward<T>(args)...);\n  } else {\n    return fmt::format_to(out, compiled, std::forward<T>(args)...);\n  }\n}\n#endif\n\ntemplate <typename OutputIt, typename S, typename... T,\n          FMT_ENABLE_IF(is_compiled_string<S>::value)>\nauto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args)\n    -> format_to_n_result<OutputIt> {\n  using traits = detail::fixed_buffer_traits;\n  auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n);\n  fmt::format_to(std::back_inserter(buf), fmt, std::forward<T>(args)...);\n  return {buf.out(), buf.count()};\n}\n\ntemplate <typename S, typename... T,\n          FMT_ENABLE_IF(is_compiled_string<S>::value)>\nFMT_CONSTEXPR20 auto formatted_size(const S& fmt, T&&... args) -> size_t {\n  auto buf = detail::counting_buffer<>();\n  fmt::format_to(appender(buf), fmt, std::forward<T>(args)...);\n  return buf.count();\n}\n\ntemplate <typename S, typename... T,\n          FMT_ENABLE_IF(is_compiled_string<S>::value)>\nvoid print(std::FILE* f, const S& fmt, T&&... args) {\n  auto buf = memory_buffer();\n  fmt::format_to(appender(buf), fmt, std::forward<T>(args)...);\n  detail::print(f, {buf.data(), buf.size()});\n}\n\ntemplate <typename S, typename... T,\n          FMT_ENABLE_IF(is_compiled_string<S>::value)>\nvoid print(const S& fmt, T&&... args) {\n  print(stdout, fmt, std::forward<T>(args)...);\n}\n\ntemplate <size_t N> class static_format_result {\n private:\n  char data[N];\n\n public:\n  template <typename S, typename... T,\n            FMT_ENABLE_IF(is_compiled_string<S>::value)>\n  explicit FMT_CONSTEXPR static_format_result(const S& fmt, T&&... args) {\n    *fmt::format_to(data, fmt, std::forward<T>(args)...) = '\\0';\n  }\n\n  auto str() const -> fmt::string_view { return {data, N - 1}; }\n  auto c_str() const -> const char* { return data; }\n};\n\n/**\n * Formats arguments according to the format string `fmt_str` and produces\n * a string of the exact required size at compile time. Both the format string\n * and the arguments must be compile-time expressions.\n *\n * The resulting string can be accessed as a C string via `c_str()` or as\n * a `fmt::string_view` via `str()`.\n *\n * **Example**:\n *\n *     // Produces the static string \"42\" at compile time.\n *     static constexpr auto result = FMT_STATIC_FORMAT(\"{}\", 42);\n *     const char* s = result.c_str();\n */\n#define FMT_STATIC_FORMAT(fmt_str, ...)                            \\\n  fmt::static_format_result<                                       \\\n      fmt::formatted_size(FMT_COMPILE(fmt_str), __VA_ARGS__) + 1>( \\\n      FMT_COMPILE(fmt_str), __VA_ARGS__)\n\nFMT_END_EXPORT\nFMT_END_NAMESPACE\n\n#endif  // FMT_COMPILE_H_\n"
  },
  {
    "path": "thirdparty/fmt/include/fmt/core.h",
    "content": "// This file is only provided for compatibility and may be removed in future\n// versions. Use fmt/base.h if you don't need fmt::format and fmt/format.h\n// otherwise.\n\n#include \"format.h\"\n"
  },
  {
    "path": "thirdparty/fmt/include/fmt/format-inl.h",
    "content": "// Formatting library for C++ - implementation\n//\n// Copyright (c) 2012 - 2016, Victor Zverovich\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\n#ifndef FMT_FORMAT_INL_H_\n#define FMT_FORMAT_INL_H_\n\n#ifndef FMT_MODULE\n#  include <algorithm>\n#  include <cerrno>  // errno\n#  include <climits>\n#  include <cmath>\n#  include <exception>\n#endif\n\n#if defined(_WIN32) && !defined(FMT_USE_WRITE_CONSOLE)\n#  include <io.h>  // _isatty\n#endif\n\n#include \"format.h\"\n\n#if FMT_USE_LOCALE && !defined(FMT_MODULE)\n#  include <locale>\n#endif\n\n#ifndef FMT_FUNC\n#  define FMT_FUNC\n#endif\n\nFMT_BEGIN_NAMESPACE\n\n#ifndef FMT_CUSTOM_ASSERT_FAIL\nFMT_FUNC void assert_fail(const char* file, int line, const char* message) {\n  // Use unchecked std::fprintf to avoid triggering another assertion when\n  // writing to stderr fails.\n  std::fprintf(stderr, \"%s:%d: assertion failed: %s\", file, line, message);\n  abort();\n}\n#endif\n\n#if FMT_USE_LOCALE\nnamespace detail {\nusing std::locale;\nusing std::numpunct;\nusing std::use_facet;\n}  // namespace detail\n#else\nnamespace detail {\nstruct locale {};\ntemplate <typename Char> struct numpunct {\n  auto grouping() const -> std::string { return \"\\03\"; }\n  auto thousands_sep() const -> Char { return ','; }\n  auto decimal_point() const -> Char { return '.'; }\n};\ntemplate <typename Facet> Facet use_facet(locale) { return {}; }\n}  // namespace detail\n#endif  // FMT_USE_LOCALE\n\ntemplate <typename Locale> auto locale_ref::get() const -> Locale {\n  using namespace detail;\n  static_assert(std::is_same<Locale, locale>::value, \"\");\n#if FMT_USE_LOCALE\n  if (locale_) return *static_cast<const locale*>(locale_);\n#endif\n  return locale();\n}\n\nnamespace detail {\n\nFMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,\n                                string_view message) noexcept {\n  // Report error code making sure that the output fits into\n  // inline_buffer_size to avoid dynamic memory allocation and potential\n  // bad_alloc.\n  out.try_resize(0);\n  static const char SEP[] = \": \";\n  static const char ERROR_STR[] = \"error \";\n  // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.\n  size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;\n  auto abs_value = static_cast<uint32_or_64_or_128_t<int>>(error_code);\n  if (detail::is_negative(error_code)) {\n    abs_value = 0 - abs_value;\n    ++error_code_size;\n  }\n  error_code_size += detail::to_unsigned(detail::count_digits(abs_value));\n  auto it = appender(out);\n  if (message.size() <= inline_buffer_size - error_code_size)\n    fmt::format_to(it, FMT_STRING(\"{}{}\"), message, SEP);\n  fmt::format_to(it, FMT_STRING(\"{}{}\"), ERROR_STR, error_code);\n  FMT_ASSERT(out.size() <= inline_buffer_size, \"\");\n}\n\nFMT_FUNC void do_report_error(format_func func, int error_code,\n                              const char* message) noexcept {\n  memory_buffer full_message;\n  func(full_message, error_code, message);\n  // Don't use fwrite_all because the latter may throw.\n  if (std::fwrite(full_message.data(), full_message.size(), 1, stderr) > 0)\n    std::fputc('\\n', stderr);\n}\n\n// A wrapper around fwrite that throws on error.\ninline void fwrite_all(const void* ptr, size_t count, FILE* stream) {\n  size_t written = std::fwrite(ptr, 1, count, stream);\n  if (written < count)\n    FMT_THROW(system_error(errno, FMT_STRING(\"cannot write to file\")));\n}\n\ntemplate <typename Char>\nFMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char> {\n  auto&& facet = use_facet<numpunct<Char>>(loc.get<locale>());\n  auto grouping = facet.grouping();\n  auto thousands_sep = grouping.empty() ? Char() : facet.thousands_sep();\n  return {std::move(grouping), thousands_sep};\n}\ntemplate <typename Char>\nFMT_FUNC auto decimal_point_impl(locale_ref loc) -> Char {\n  return use_facet<numpunct<Char>>(loc.get<locale>()).decimal_point();\n}\n\n#if FMT_USE_LOCALE\nFMT_FUNC auto write_loc(appender out, loc_value value,\n                        const format_specs& specs, locale_ref loc) -> bool {\n  auto locale = loc.get<std::locale>();\n  // We cannot use the num_put<char> facet because it may produce output in\n  // a wrong encoding.\n  using facet = format_facet<std::locale>;\n  if (std::has_facet<facet>(locale))\n    return use_facet<facet>(locale).put(out, value, specs);\n  return facet(locale).put(out, value, specs);\n}\n#endif\n}  // namespace detail\n\nFMT_FUNC void report_error(const char* message) {\n#if FMT_MSC_VERSION || defined(__NVCC__)\n  // Silence unreachable code warnings in MSVC and NVCC because these\n  // are nearly impossible to fix in a generic code.\n  volatile bool b = true;\n  if (!b) return;\n#endif\n  FMT_THROW(format_error(message));\n}\n\ntemplate <typename Locale> typename Locale::id format_facet<Locale>::id;\n\ntemplate <typename Locale> format_facet<Locale>::format_facet(Locale& loc) {\n  auto& np = detail::use_facet<detail::numpunct<char>>(loc);\n  grouping_ = np.grouping();\n  if (!grouping_.empty()) separator_ = std::string(1, np.thousands_sep());\n}\n\n#if FMT_USE_LOCALE\ntemplate <>\nFMT_API FMT_FUNC auto format_facet<std::locale>::do_put(\n    appender out, loc_value val, const format_specs& specs) const -> bool {\n  return val.visit(\n      detail::loc_writer<>{out, specs, separator_, grouping_, decimal_point_});\n}\n#endif\n\nFMT_FUNC auto vsystem_error(int error_code, string_view fmt, format_args args)\n    -> std::system_error {\n  auto ec = std::error_code(error_code, std::generic_category());\n  return std::system_error(ec, vformat(fmt, args));\n}\n\nnamespace detail {\n\ntemplate <typename F>\ninline auto operator==(basic_fp<F> x, basic_fp<F> y) -> bool {\n  return x.f == y.f && x.e == y.e;\n}\n\n// Compilers should be able to optimize this into the ror instruction.\nFMT_INLINE auto rotr(uint32_t n, uint32_t r) noexcept -> uint32_t {\n  r &= 31;\n  return (n >> r) | (n << (32 - r));\n}\nFMT_INLINE auto rotr(uint64_t n, uint32_t r) noexcept -> uint64_t {\n  r &= 63;\n  return (n >> r) | (n << (64 - r));\n}\n\n// Implementation of Dragonbox algorithm: https://github.com/jk-jeon/dragonbox.\nnamespace dragonbox {\n// Computes upper 64 bits of multiplication of a 32-bit unsigned integer and a\n// 64-bit unsigned integer.\ninline auto umul96_upper64(uint32_t x, uint64_t y) noexcept -> uint64_t {\n  return umul128_upper64(static_cast<uint64_t>(x) << 32, y);\n}\n\n// Computes lower 128 bits of multiplication of a 64-bit unsigned integer and a\n// 128-bit unsigned integer.\ninline auto umul192_lower128(uint64_t x, uint128_fallback y) noexcept\n    -> uint128_fallback {\n  uint64_t high = x * y.high();\n  uint128_fallback high_low = umul128(x, y.low());\n  return {high + high_low.high(), high_low.low()};\n}\n\n// Computes lower 64 bits of multiplication of a 32-bit unsigned integer and a\n// 64-bit unsigned integer.\ninline auto umul96_lower64(uint32_t x, uint64_t y) noexcept -> uint64_t {\n  return x * y;\n}\n\n// Various fast log computations.\ninline auto floor_log10_pow2_minus_log10_4_over_3(int e) noexcept -> int {\n  FMT_ASSERT(e <= 2936 && e >= -2985, \"too large exponent\");\n  return (e * 631305 - 261663) >> 21;\n}\n\nFMT_INLINE_VARIABLE constexpr struct div_small_pow10_infos_struct {\n  uint32_t divisor;\n  int shift_amount;\n} div_small_pow10_infos[] = {{10, 16}, {100, 16}};\n\n// Replaces n by floor(n / pow(10, N)) returning true if and only if n is\n// divisible by pow(10, N).\n// Precondition: n <= pow(10, N + 1).\ntemplate <int N>\nauto check_divisibility_and_divide_by_pow10(uint32_t& n) noexcept -> bool {\n  // The numbers below are chosen such that:\n  //   1. floor(n/d) = floor(nm / 2^k) where d=10 or d=100,\n  //   2. nm mod 2^k < m if and only if n is divisible by d,\n  // where m is magic_number, k is shift_amount\n  // and d is divisor.\n  //\n  // Item 1 is a common technique of replacing division by a constant with\n  // multiplication, see e.g. \"Division by Invariant Integers Using\n  // Multiplication\" by Granlund and Montgomery (1994). magic_number (m) is set\n  // to ceil(2^k/d) for large enough k.\n  // The idea for item 2 originates from Schubfach.\n  constexpr auto info = div_small_pow10_infos[N - 1];\n  FMT_ASSERT(n <= info.divisor * 10, \"n is too large\");\n  constexpr uint32_t magic_number =\n      (1u << info.shift_amount) / info.divisor + 1;\n  n *= magic_number;\n  const uint32_t comparison_mask = (1u << info.shift_amount) - 1;\n  bool result = (n & comparison_mask) < magic_number;\n  n >>= info.shift_amount;\n  return result;\n}\n\n// Computes floor(n / pow(10, N)) for small n and N.\n// Precondition: n <= pow(10, N + 1).\ntemplate <int N> auto small_division_by_pow10(uint32_t n) noexcept -> uint32_t {\n  constexpr auto info = div_small_pow10_infos[N - 1];\n  FMT_ASSERT(n <= info.divisor * 10, \"n is too large\");\n  constexpr uint32_t magic_number =\n      (1u << info.shift_amount) / info.divisor + 1;\n  return (n * magic_number) >> info.shift_amount;\n}\n\n// Computes floor(n / 10^(kappa + 1)) (float)\ninline auto divide_by_10_to_kappa_plus_1(uint32_t n) noexcept -> uint32_t {\n  // 1374389535 = ceil(2^37/100)\n  return static_cast<uint32_t>((static_cast<uint64_t>(n) * 1374389535) >> 37);\n}\n// Computes floor(n / 10^(kappa + 1)) (double)\ninline auto divide_by_10_to_kappa_plus_1(uint64_t n) noexcept -> uint64_t {\n  // 2361183241434822607 = ceil(2^(64+7)/1000)\n  return umul128_upper64(n, 2361183241434822607ull) >> 7;\n}\n\n// Various subroutines using pow10 cache\ntemplate <typename T> struct cache_accessor;\n\ntemplate <> struct cache_accessor<float> {\n  using carrier_uint = float_info<float>::carrier_uint;\n  using cache_entry_type = uint64_t;\n\n  static auto get_cached_power(int k) noexcept -> uint64_t {\n    FMT_ASSERT(k >= float_info<float>::min_k && k <= float_info<float>::max_k,\n               \"k is out of range\");\n    static constexpr uint64_t pow10_significands[] = {\n        0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f,\n        0xfd87b5f28300ca0e, 0x9e74d1b791e07e49, 0xc612062576589ddb,\n        0xf79687aed3eec552, 0x9abe14cd44753b53, 0xc16d9a0095928a28,\n        0xf1c90080baf72cb2, 0x971da05074da7bef, 0xbce5086492111aeb,\n        0xec1e4a7db69561a6, 0x9392ee8e921d5d08, 0xb877aa3236a4b44a,\n        0xe69594bec44de15c, 0x901d7cf73ab0acda, 0xb424dc35095cd810,\n        0xe12e13424bb40e14, 0x8cbccc096f5088cc, 0xafebff0bcb24aaff,\n        0xdbe6fecebdedd5bf, 0x89705f4136b4a598, 0xabcc77118461cefd,\n        0xd6bf94d5e57a42bd, 0x8637bd05af6c69b6, 0xa7c5ac471b478424,\n        0xd1b71758e219652c, 0x83126e978d4fdf3c, 0xa3d70a3d70a3d70b,\n        0xcccccccccccccccd, 0x8000000000000000, 0xa000000000000000,\n        0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000,\n        0xc350000000000000, 0xf424000000000000, 0x9896800000000000,\n        0xbebc200000000000, 0xee6b280000000000, 0x9502f90000000000,\n        0xba43b74000000000, 0xe8d4a51000000000, 0x9184e72a00000000,\n        0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000,\n        0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000,\n        0xad78ebc5ac620000, 0xd8d726b7177a8000, 0x878678326eac9000,\n        0xa968163f0a57b400, 0xd3c21bcecceda100, 0x84595161401484a0,\n        0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940985,\n        0xa18f07d736b90be6, 0xc9f2c9cd04674edf, 0xfc6f7c4045812297,\n        0x9dc5ada82b70b59e, 0xc5371912364ce306, 0xf684df56c3e01bc7,\n        0x9a130b963a6c115d, 0xc097ce7bc90715b4, 0xf0bdc21abb48db21,\n        0x96769950b50d88f5, 0xbc143fa4e250eb32, 0xeb194f8e1ae525fe,\n        0x92efd1b8d0cf37bf, 0xb7abc627050305ae, 0xe596b7b0c643c71a,\n        0x8f7e32ce7bea5c70, 0xb35dbf821ae4f38c, 0xe0352f62a19e306f};\n    return pow10_significands[k - float_info<float>::min_k];\n  }\n\n  struct compute_mul_result {\n    carrier_uint result;\n    bool is_integer;\n  };\n  struct compute_mul_parity_result {\n    bool parity;\n    bool is_integer;\n  };\n\n  static auto compute_mul(carrier_uint u,\n                          const cache_entry_type& cache) noexcept\n      -> compute_mul_result {\n    auto r = umul96_upper64(u, cache);\n    return {static_cast<carrier_uint>(r >> 32),\n            static_cast<carrier_uint>(r) == 0};\n  }\n\n  static auto compute_delta(const cache_entry_type& cache, int beta) noexcept\n      -> uint32_t {\n    return static_cast<uint32_t>(cache >> (64 - 1 - beta));\n  }\n\n  static auto compute_mul_parity(carrier_uint two_f,\n                                 const cache_entry_type& cache,\n                                 int beta) noexcept\n      -> compute_mul_parity_result {\n    FMT_ASSERT(beta >= 1, \"\");\n    FMT_ASSERT(beta < 64, \"\");\n\n    auto r = umul96_lower64(two_f, cache);\n    return {((r >> (64 - beta)) & 1) != 0,\n            static_cast<uint32_t>(r >> (32 - beta)) == 0};\n  }\n\n  static auto compute_left_endpoint_for_shorter_interval_case(\n      const cache_entry_type& cache, int beta) noexcept -> carrier_uint {\n    return static_cast<carrier_uint>(\n        (cache - (cache >> (num_significand_bits<float>() + 2))) >>\n        (64 - num_significand_bits<float>() - 1 - beta));\n  }\n\n  static auto compute_right_endpoint_for_shorter_interval_case(\n      const cache_entry_type& cache, int beta) noexcept -> carrier_uint {\n    return static_cast<carrier_uint>(\n        (cache + (cache >> (num_significand_bits<float>() + 1))) >>\n        (64 - num_significand_bits<float>() - 1 - beta));\n  }\n\n  static auto compute_round_up_for_shorter_interval_case(\n      const cache_entry_type& cache, int beta) noexcept -> carrier_uint {\n    return (static_cast<carrier_uint>(\n                cache >> (64 - num_significand_bits<float>() - 2 - beta)) +\n            1) /\n           2;\n  }\n};\n\ntemplate <> struct cache_accessor<double> {\n  using carrier_uint = float_info<double>::carrier_uint;\n  using cache_entry_type = uint128_fallback;\n\n  static auto get_cached_power(int k) noexcept -> uint128_fallback {\n    FMT_ASSERT(k >= float_info<double>::min_k && k <= float_info<double>::max_k,\n               \"k is out of range\");\n\n    static constexpr uint128_fallback pow10_significands[] = {\n#if FMT_USE_FULL_CACHE_DRAGONBOX\n      {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b},\n      {0x9faacf3df73609b1, 0x77b191618c54e9ad},\n      {0xc795830d75038c1d, 0xd59df5b9ef6a2418},\n      {0xf97ae3d0d2446f25, 0x4b0573286b44ad1e},\n      {0x9becce62836ac577, 0x4ee367f9430aec33},\n      {0xc2e801fb244576d5, 0x229c41f793cda740},\n      {0xf3a20279ed56d48a, 0x6b43527578c11110},\n      {0x9845418c345644d6, 0x830a13896b78aaaa},\n      {0xbe5691ef416bd60c, 0x23cc986bc656d554},\n      {0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa9},\n      {0x94b3a202eb1c3f39, 0x7bf7d71432f3d6aa},\n      {0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc54},\n      {0xe858ad248f5c22c9, 0xd1b3400f8f9cff69},\n      {0x91376c36d99995be, 0x23100809b9c21fa2},\n      {0xb58547448ffffb2d, 0xabd40a0c2832a78b},\n      {0xe2e69915b3fff9f9, 0x16c90c8f323f516d},\n      {0x8dd01fad907ffc3b, 0xae3da7d97f6792e4},\n      {0xb1442798f49ffb4a, 0x99cd11cfdf41779d},\n      {0xdd95317f31c7fa1d, 0x40405643d711d584},\n      {0x8a7d3eef7f1cfc52, 0x482835ea666b2573},\n      {0xad1c8eab5ee43b66, 0xda3243650005eed0},\n      {0xd863b256369d4a40, 0x90bed43e40076a83},\n      {0x873e4f75e2224e68, 0x5a7744a6e804a292},\n      {0xa90de3535aaae202, 0x711515d0a205cb37},\n      {0xd3515c2831559a83, 0x0d5a5b44ca873e04},\n      {0x8412d9991ed58091, 0xe858790afe9486c3},\n      {0xa5178fff668ae0b6, 0x626e974dbe39a873},\n      {0xce5d73ff402d98e3, 0xfb0a3d212dc81290},\n      {0x80fa687f881c7f8e, 0x7ce66634bc9d0b9a},\n      {0xa139029f6a239f72, 0x1c1fffc1ebc44e81},\n      {0xc987434744ac874e, 0xa327ffb266b56221},\n      {0xfbe9141915d7a922, 0x4bf1ff9f0062baa9},\n      {0x9d71ac8fada6c9b5, 0x6f773fc3603db4aa},\n      {0xc4ce17b399107c22, 0xcb550fb4384d21d4},\n      {0xf6019da07f549b2b, 0x7e2a53a146606a49},\n      {0x99c102844f94e0fb, 0x2eda7444cbfc426e},\n      {0xc0314325637a1939, 0xfa911155fefb5309},\n      {0xf03d93eebc589f88, 0x793555ab7eba27cb},\n      {0x96267c7535b763b5, 0x4bc1558b2f3458df},\n      {0xbbb01b9283253ca2, 0x9eb1aaedfb016f17},\n      {0xea9c227723ee8bcb, 0x465e15a979c1cadd},\n      {0x92a1958a7675175f, 0x0bfacd89ec191eca},\n      {0xb749faed14125d36, 0xcef980ec671f667c},\n      {0xe51c79a85916f484, 0x82b7e12780e7401b},\n      {0x8f31cc0937ae58d2, 0xd1b2ecb8b0908811},\n      {0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa16},\n      {0xdfbdcece67006ac9, 0x67a791e093e1d49b},\n      {0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e1},\n      {0xaecc49914078536d, 0x58fae9f773886e19},\n      {0xda7f5bf590966848, 0xaf39a475506a899f},\n      {0x888f99797a5e012d, 0x6d8406c952429604},\n      {0xaab37fd7d8f58178, 0xc8e5087ba6d33b84},\n      {0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a65},\n      {0x855c3be0a17fcd26, 0x5cf2eea09a550680},\n      {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f},\n      {0xd0601d8efc57b08b, 0xf13b94daf124da27},\n      {0x823c12795db6ce57, 0x76c53d08d6b70859},\n      {0xa2cb1717b52481ed, 0x54768c4b0c64ca6f},\n      {0xcb7ddcdda26da268, 0xa9942f5dcf7dfd0a},\n      {0xfe5d54150b090b02, 0xd3f93b35435d7c4d},\n      {0x9efa548d26e5a6e1, 0xc47bc5014a1a6db0},\n      {0xc6b8e9b0709f109a, 0x359ab6419ca1091c},\n      {0xf867241c8cc6d4c0, 0xc30163d203c94b63},\n      {0x9b407691d7fc44f8, 0x79e0de63425dcf1e},\n      {0xc21094364dfb5636, 0x985915fc12f542e5},\n      {0xf294b943e17a2bc4, 0x3e6f5b7b17b2939e},\n      {0x979cf3ca6cec5b5a, 0xa705992ceecf9c43},\n      {0xbd8430bd08277231, 0x50c6ff782a838354},\n      {0xece53cec4a314ebd, 0xa4f8bf5635246429},\n      {0x940f4613ae5ed136, 0x871b7795e136be9a},\n      {0xb913179899f68584, 0x28e2557b59846e40},\n      {0xe757dd7ec07426e5, 0x331aeada2fe589d0},\n      {0x9096ea6f3848984f, 0x3ff0d2c85def7622},\n      {0xb4bca50b065abe63, 0x0fed077a756b53aa},\n      {0xe1ebce4dc7f16dfb, 0xd3e8495912c62895},\n      {0x8d3360f09cf6e4bd, 0x64712dd7abbbd95d},\n      {0xb080392cc4349dec, 0xbd8d794d96aacfb4},\n      {0xdca04777f541c567, 0xecf0d7a0fc5583a1},\n      {0x89e42caaf9491b60, 0xf41686c49db57245},\n      {0xac5d37d5b79b6239, 0x311c2875c522ced6},\n      {0xd77485cb25823ac7, 0x7d633293366b828c},\n      {0x86a8d39ef77164bc, 0xae5dff9c02033198},\n      {0xa8530886b54dbdeb, 0xd9f57f830283fdfd},\n      {0xd267caa862a12d66, 0xd072df63c324fd7c},\n      {0x8380dea93da4bc60, 0x4247cb9e59f71e6e},\n      {0xa46116538d0deb78, 0x52d9be85f074e609},\n      {0xcd795be870516656, 0x67902e276c921f8c},\n      {0x806bd9714632dff6, 0x00ba1cd8a3db53b7},\n      {0xa086cfcd97bf97f3, 0x80e8a40eccd228a5},\n      {0xc8a883c0fdaf7df0, 0x6122cd128006b2ce},\n      {0xfad2a4b13d1b5d6c, 0x796b805720085f82},\n      {0x9cc3a6eec6311a63, 0xcbe3303674053bb1},\n      {0xc3f490aa77bd60fc, 0xbedbfc4411068a9d},\n      {0xf4f1b4d515acb93b, 0xee92fb5515482d45},\n      {0x991711052d8bf3c5, 0x751bdd152d4d1c4b},\n      {0xbf5cd54678eef0b6, 0xd262d45a78a0635e},\n      {0xef340a98172aace4, 0x86fb897116c87c35},\n      {0x9580869f0e7aac0e, 0xd45d35e6ae3d4da1},\n      {0xbae0a846d2195712, 0x8974836059cca10a},\n      {0xe998d258869facd7, 0x2bd1a438703fc94c},\n      {0x91ff83775423cc06, 0x7b6306a34627ddd0},\n      {0xb67f6455292cbf08, 0x1a3bc84c17b1d543},\n      {0xe41f3d6a7377eeca, 0x20caba5f1d9e4a94},\n      {0x8e938662882af53e, 0x547eb47b7282ee9d},\n      {0xb23867fb2a35b28d, 0xe99e619a4f23aa44},\n      {0xdec681f9f4c31f31, 0x6405fa00e2ec94d5},\n      {0x8b3c113c38f9f37e, 0xde83bc408dd3dd05},\n      {0xae0b158b4738705e, 0x9624ab50b148d446},\n      {0xd98ddaee19068c76, 0x3badd624dd9b0958},\n      {0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d7},\n      {0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4d},\n      {0xd47487cc8470652b, 0x7647c32000696720},\n      {0x84c8d4dfd2c63f3b, 0x29ecd9f40041e074},\n      {0xa5fb0a17c777cf09, 0xf468107100525891},\n      {0xcf79cc9db955c2cc, 0x7182148d4066eeb5},\n      {0x81ac1fe293d599bf, 0xc6f14cd848405531},\n      {0xa21727db38cb002f, 0xb8ada00e5a506a7d},\n      {0xca9cf1d206fdc03b, 0xa6d90811f0e4851d},\n      {0xfd442e4688bd304a, 0x908f4a166d1da664},\n      {0x9e4a9cec15763e2e, 0x9a598e4e043287ff},\n      {0xc5dd44271ad3cdba, 0x40eff1e1853f29fe},\n      {0xf7549530e188c128, 0xd12bee59e68ef47d},\n      {0x9a94dd3e8cf578b9, 0x82bb74f8301958cf},\n      {0xc13a148e3032d6e7, 0xe36a52363c1faf02},\n      {0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac2},\n      {0x96f5600f15a7b7e5, 0x29ab103a5ef8c0ba},\n      {0xbcb2b812db11a5de, 0x7415d448f6b6f0e8},\n      {0xebdf661791d60f56, 0x111b495b3464ad22},\n      {0x936b9fcebb25c995, 0xcab10dd900beec35},\n      {0xb84687c269ef3bfb, 0x3d5d514f40eea743},\n      {0xe65829b3046b0afa, 0x0cb4a5a3112a5113},\n      {0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ac},\n      {0xb3f4e093db73a093, 0x59ed216765690f57},\n      {0xe0f218b8d25088b8, 0x306869c13ec3532d},\n      {0x8c974f7383725573, 0x1e414218c73a13fc},\n      {0xafbd2350644eeacf, 0xe5d1929ef90898fb},\n      {0xdbac6c247d62a583, 0xdf45f746b74abf3a},\n      {0x894bc396ce5da772, 0x6b8bba8c328eb784},\n      {0xab9eb47c81f5114f, 0x066ea92f3f326565},\n      {0xd686619ba27255a2, 0xc80a537b0efefebe},\n      {0x8613fd0145877585, 0xbd06742ce95f5f37},\n      {0xa798fc4196e952e7, 0x2c48113823b73705},\n      {0xd17f3b51fca3a7a0, 0xf75a15862ca504c6},\n      {0x82ef85133de648c4, 0x9a984d73dbe722fc},\n      {0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebbb},\n      {0xcc963fee10b7d1b3, 0x318df905079926a9},\n      {0xffbbcfe994e5c61f, 0xfdf17746497f7053},\n      {0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa634},\n      {0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc1},\n      {0xf9bd690a1b68637b, 0x3dfdce7aa3c673b1},\n      {0x9c1661a651213e2d, 0x06bea10ca65c084f},\n      {0xc31bfa0fe5698db8, 0x486e494fcff30a63},\n      {0xf3e2f893dec3f126, 0x5a89dba3c3efccfb},\n      {0x986ddb5c6b3a76b7, 0xf89629465a75e01d},\n      {0xbe89523386091465, 0xf6bbb397f1135824},\n      {0xee2ba6c0678b597f, 0x746aa07ded582e2d},\n      {0x94db483840b717ef, 0xa8c2a44eb4571cdd},\n      {0xba121a4650e4ddeb, 0x92f34d62616ce414},\n      {0xe896a0d7e51e1566, 0x77b020baf9c81d18},\n      {0x915e2486ef32cd60, 0x0ace1474dc1d122f},\n      {0xb5b5ada8aaff80b8, 0x0d819992132456bb},\n      {0xe3231912d5bf60e6, 0x10e1fff697ed6c6a},\n      {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2},\n      {0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb3},\n      {0xddd0467c64bce4a0, 0xac7cb3f6d05ddbdf},\n      {0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96c},\n      {0xad4ab7112eb3929d, 0x86c16c98d2c953c7},\n      {0xd89d64d57a607744, 0xe871c7bf077ba8b8},\n      {0x87625f056c7c4a8b, 0x11471cd764ad4973},\n      {0xa93af6c6c79b5d2d, 0xd598e40d3dd89bd0},\n      {0xd389b47879823479, 0x4aff1d108d4ec2c4},\n      {0x843610cb4bf160cb, 0xcedf722a585139bb},\n      {0xa54394fe1eedb8fe, 0xc2974eb4ee658829},\n      {0xce947a3da6a9273e, 0x733d226229feea33},\n      {0x811ccc668829b887, 0x0806357d5a3f5260},\n      {0xa163ff802a3426a8, 0xca07c2dcb0cf26f8},\n      {0xc9bcff6034c13052, 0xfc89b393dd02f0b6},\n      {0xfc2c3f3841f17c67, 0xbbac2078d443ace3},\n      {0x9d9ba7832936edc0, 0xd54b944b84aa4c0e},\n      {0xc5029163f384a931, 0x0a9e795e65d4df12},\n      {0xf64335bcf065d37d, 0x4d4617b5ff4a16d6},\n      {0x99ea0196163fa42e, 0x504bced1bf8e4e46},\n      {0xc06481fb9bcf8d39, 0xe45ec2862f71e1d7},\n      {0xf07da27a82c37088, 0x5d767327bb4e5a4d},\n      {0x964e858c91ba2655, 0x3a6a07f8d510f870},\n      {0xbbe226efb628afea, 0x890489f70a55368c},\n      {0xeadab0aba3b2dbe5, 0x2b45ac74ccea842f},\n      {0x92c8ae6b464fc96f, 0x3b0b8bc90012929e},\n      {0xb77ada0617e3bbcb, 0x09ce6ebb40173745},\n      {0xe55990879ddcaabd, 0xcc420a6a101d0516},\n      {0x8f57fa54c2a9eab6, 0x9fa946824a12232e},\n      {0xb32df8e9f3546564, 0x47939822dc96abfa},\n      {0xdff9772470297ebd, 0x59787e2b93bc56f8},\n      {0x8bfbea76c619ef36, 0x57eb4edb3c55b65b},\n      {0xaefae51477a06b03, 0xede622920b6b23f2},\n      {0xdab99e59958885c4, 0xe95fab368e45ecee},\n      {0x88b402f7fd75539b, 0x11dbcb0218ebb415},\n      {0xaae103b5fcd2a881, 0xd652bdc29f26a11a},\n      {0xd59944a37c0752a2, 0x4be76d3346f04960},\n      {0x857fcae62d8493a5, 0x6f70a4400c562ddc},\n      {0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb953},\n      {0xd097ad07a71f26b2, 0x7e2000a41346a7a8},\n      {0x825ecc24c873782f, 0x8ed400668c0c28c9},\n      {0xa2f67f2dfa90563b, 0x728900802f0f32fb},\n      {0xcbb41ef979346bca, 0x4f2b40a03ad2ffba},\n      {0xfea126b7d78186bc, 0xe2f610c84987bfa9},\n      {0x9f24b832e6b0f436, 0x0dd9ca7d2df4d7ca},\n      {0xc6ede63fa05d3143, 0x91503d1c79720dbc},\n      {0xf8a95fcf88747d94, 0x75a44c6397ce912b},\n      {0x9b69dbe1b548ce7c, 0xc986afbe3ee11abb},\n      {0xc24452da229b021b, 0xfbe85badce996169},\n      {0xf2d56790ab41c2a2, 0xfae27299423fb9c4},\n      {0x97c560ba6b0919a5, 0xdccd879fc967d41b},\n      {0xbdb6b8e905cb600f, 0x5400e987bbc1c921},\n      {0xed246723473e3813, 0x290123e9aab23b69},\n      {0x9436c0760c86e30b, 0xf9a0b6720aaf6522},\n      {0xb94470938fa89bce, 0xf808e40e8d5b3e6a},\n      {0xe7958cb87392c2c2, 0xb60b1d1230b20e05},\n      {0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c3},\n      {0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af4},\n      {0xe2280b6c20dd5232, 0x25c6da63c38de1b1},\n      {0x8d590723948a535f, 0x579c487e5a38ad0f},\n      {0xb0af48ec79ace837, 0x2d835a9df0c6d852},\n      {0xdcdb1b2798182244, 0xf8e431456cf88e66},\n      {0x8a08f0f8bf0f156b, 0x1b8e9ecb641b5900},\n      {0xac8b2d36eed2dac5, 0xe272467e3d222f40},\n      {0xd7adf884aa879177, 0x5b0ed81dcc6abb10},\n      {0x86ccbb52ea94baea, 0x98e947129fc2b4ea},\n      {0xa87fea27a539e9a5, 0x3f2398d747b36225},\n      {0xd29fe4b18e88640e, 0x8eec7f0d19a03aae},\n      {0x83a3eeeef9153e89, 0x1953cf68300424ad},\n      {0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd8},\n      {0xcdb02555653131b6, 0x3792f412cb06794e},\n      {0x808e17555f3ebf11, 0xe2bbd88bbee40bd1},\n      {0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec5},\n      {0xc8de047564d20a8b, 0xf245825a5a445276},\n      {0xfb158592be068d2e, 0xeed6e2f0f0d56713},\n      {0x9ced737bb6c4183d, 0x55464dd69685606c},\n      {0xc428d05aa4751e4c, 0xaa97e14c3c26b887},\n      {0xf53304714d9265df, 0xd53dd99f4b3066a9},\n      {0x993fe2c6d07b7fab, 0xe546a8038efe402a},\n      {0xbf8fdb78849a5f96, 0xde98520472bdd034},\n      {0xef73d256a5c0f77c, 0x963e66858f6d4441},\n      {0x95a8637627989aad, 0xdde7001379a44aa9},\n      {0xbb127c53b17ec159, 0x5560c018580d5d53},\n      {0xe9d71b689dde71af, 0xaab8f01e6e10b4a7},\n      {0x9226712162ab070d, 0xcab3961304ca70e9},\n      {0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d23},\n      {0xe45c10c42a2b3b05, 0x8cb89a7db77c506b},\n      {0x8eb98a7a9a5b04e3, 0x77f3608e92adb243},\n      {0xb267ed1940f1c61c, 0x55f038b237591ed4},\n      {0xdf01e85f912e37a3, 0x6b6c46dec52f6689},\n      {0x8b61313bbabce2c6, 0x2323ac4b3b3da016},\n      {0xae397d8aa96c1b77, 0xabec975e0a0d081b},\n      {0xd9c7dced53c72255, 0x96e7bd358c904a22},\n      {0x881cea14545c7575, 0x7e50d64177da2e55},\n      {0xaa242499697392d2, 0xdde50bd1d5d0b9ea},\n      {0xd4ad2dbfc3d07787, 0x955e4ec64b44e865},\n      {0x84ec3c97da624ab4, 0xbd5af13bef0b113f},\n      {0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58f},\n      {0xcfb11ead453994ba, 0x67de18eda5814af3},\n      {0x81ceb32c4b43fcf4, 0x80eacf948770ced8},\n      {0xa2425ff75e14fc31, 0xa1258379a94d028e},\n      {0xcad2f7f5359a3b3e, 0x096ee45813a04331},\n      {0xfd87b5f28300ca0d, 0x8bca9d6e188853fd},\n      {0x9e74d1b791e07e48, 0x775ea264cf55347e},\n      {0xc612062576589dda, 0x95364afe032a819e},\n      {0xf79687aed3eec551, 0x3a83ddbd83f52205},\n      {0x9abe14cd44753b52, 0xc4926a9672793543},\n      {0xc16d9a0095928a27, 0x75b7053c0f178294},\n      {0xf1c90080baf72cb1, 0x5324c68b12dd6339},\n      {0x971da05074da7bee, 0xd3f6fc16ebca5e04},\n      {0xbce5086492111aea, 0x88f4bb1ca6bcf585},\n      {0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6},\n      {0x9392ee8e921d5d07, 0x3aff322e62439fd0},\n      {0xb877aa3236a4b449, 0x09befeb9fad487c3},\n      {0xe69594bec44de15b, 0x4c2ebe687989a9b4},\n      {0x901d7cf73ab0acd9, 0x0f9d37014bf60a11},\n      {0xb424dc35095cd80f, 0x538484c19ef38c95},\n      {0xe12e13424bb40e13, 0x2865a5f206b06fba},\n      {0x8cbccc096f5088cb, 0xf93f87b7442e45d4},\n      {0xafebff0bcb24aafe, 0xf78f69a51539d749},\n      {0xdbe6fecebdedd5be, 0xb573440e5a884d1c},\n      {0x89705f4136b4a597, 0x31680a88f8953031},\n      {0xabcc77118461cefc, 0xfdc20d2b36ba7c3e},\n      {0xd6bf94d5e57a42bc, 0x3d32907604691b4d},\n      {0x8637bd05af6c69b5, 0xa63f9a49c2c1b110},\n      {0xa7c5ac471b478423, 0x0fcf80dc33721d54},\n      {0xd1b71758e219652b, 0xd3c36113404ea4a9},\n      {0x83126e978d4fdf3b, 0x645a1cac083126ea},\n      {0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4},\n      {0xcccccccccccccccc, 0xcccccccccccccccd},\n      {0x8000000000000000, 0x0000000000000000},\n      {0xa000000000000000, 0x0000000000000000},\n      {0xc800000000000000, 0x0000000000000000},\n      {0xfa00000000000000, 0x0000000000000000},\n      {0x9c40000000000000, 0x0000000000000000},\n      {0xc350000000000000, 0x0000000000000000},\n      {0xf424000000000000, 0x0000000000000000},\n      {0x9896800000000000, 0x0000000000000000},\n      {0xbebc200000000000, 0x0000000000000000},\n      {0xee6b280000000000, 0x0000000000000000},\n      {0x9502f90000000000, 0x0000000000000000},\n      {0xba43b74000000000, 0x0000000000000000},\n      {0xe8d4a51000000000, 0x0000000000000000},\n      {0x9184e72a00000000, 0x0000000000000000},\n      {0xb5e620f480000000, 0x0000000000000000},\n      {0xe35fa931a0000000, 0x0000000000000000},\n      {0x8e1bc9bf04000000, 0x0000000000000000},\n      {0xb1a2bc2ec5000000, 0x0000000000000000},\n      {0xde0b6b3a76400000, 0x0000000000000000},\n      {0x8ac7230489e80000, 0x0000000000000000},\n      {0xad78ebc5ac620000, 0x0000000000000000},\n      {0xd8d726b7177a8000, 0x0000000000000000},\n      {0x878678326eac9000, 0x0000000000000000},\n      {0xa968163f0a57b400, 0x0000000000000000},\n      {0xd3c21bcecceda100, 0x0000000000000000},\n      {0x84595161401484a0, 0x0000000000000000},\n      {0xa56fa5b99019a5c8, 0x0000000000000000},\n      {0xcecb8f27f4200f3a, 0x0000000000000000},\n      {0x813f3978f8940984, 0x4000000000000000},\n      {0xa18f07d736b90be5, 0x5000000000000000},\n      {0xc9f2c9cd04674ede, 0xa400000000000000},\n      {0xfc6f7c4045812296, 0x4d00000000000000},\n      {0x9dc5ada82b70b59d, 0xf020000000000000},\n      {0xc5371912364ce305, 0x6c28000000000000},\n      {0xf684df56c3e01bc6, 0xc732000000000000},\n      {0x9a130b963a6c115c, 0x3c7f400000000000},\n      {0xc097ce7bc90715b3, 0x4b9f100000000000},\n      {0xf0bdc21abb48db20, 0x1e86d40000000000},\n      {0x96769950b50d88f4, 0x1314448000000000},\n      {0xbc143fa4e250eb31, 0x17d955a000000000},\n      {0xeb194f8e1ae525fd, 0x5dcfab0800000000},\n      {0x92efd1b8d0cf37be, 0x5aa1cae500000000},\n      {0xb7abc627050305ad, 0xf14a3d9e40000000},\n      {0xe596b7b0c643c719, 0x6d9ccd05d0000000},\n      {0x8f7e32ce7bea5c6f, 0xe4820023a2000000},\n      {0xb35dbf821ae4f38b, 0xdda2802c8a800000},\n      {0xe0352f62a19e306e, 0xd50b2037ad200000},\n      {0x8c213d9da502de45, 0x4526f422cc340000},\n      {0xaf298d050e4395d6, 0x9670b12b7f410000},\n      {0xdaf3f04651d47b4c, 0x3c0cdd765f114000},\n      {0x88d8762bf324cd0f, 0xa5880a69fb6ac800},\n      {0xab0e93b6efee0053, 0x8eea0d047a457a00},\n      {0xd5d238a4abe98068, 0x72a4904598d6d880},\n      {0x85a36366eb71f041, 0x47a6da2b7f864750},\n      {0xa70c3c40a64e6c51, 0x999090b65f67d924},\n      {0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d},\n      {0x82818f1281ed449f, 0xbff8f10e7a8921a5},\n      {0xa321f2d7226895c7, 0xaff72d52192b6a0e},\n      {0xcbea6f8ceb02bb39, 0x9bf4f8a69f764491},\n      {0xfee50b7025c36a08, 0x02f236d04753d5b5},\n      {0x9f4f2726179a2245, 0x01d762422c946591},\n      {0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef6},\n      {0xf8ebad2b84e0d58b, 0xd2e0898765a7deb3},\n      {0x9b934c3b330c8577, 0x63cc55f49f88eb30},\n      {0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fc},\n      {0xf316271c7fc3908a, 0x8bef464e3945ef7b},\n      {0x97edd871cfda3a56, 0x97758bf0e3cbb5ad},\n      {0xbde94e8e43d0c8ec, 0x3d52eeed1cbea318},\n      {0xed63a231d4c4fb27, 0x4ca7aaa863ee4bde},\n      {0x945e455f24fb1cf8, 0x8fe8caa93e74ef6b},\n      {0xb975d6b6ee39e436, 0xb3e2fd538e122b45},\n      {0xe7d34c64a9c85d44, 0x60dbbca87196b617},\n      {0x90e40fbeea1d3a4a, 0xbc8955e946fe31ce},\n      {0xb51d13aea4a488dd, 0x6babab6398bdbe42},\n      {0xe264589a4dcdab14, 0xc696963c7eed2dd2},\n      {0x8d7eb76070a08aec, 0xfc1e1de5cf543ca3},\n      {0xb0de65388cc8ada8, 0x3b25a55f43294bcc},\n      {0xdd15fe86affad912, 0x49ef0eb713f39ebf},\n      {0x8a2dbf142dfcc7ab, 0x6e3569326c784338},\n      {0xacb92ed9397bf996, 0x49c2c37f07965405},\n      {0xd7e77a8f87daf7fb, 0xdc33745ec97be907},\n      {0x86f0ac99b4e8dafd, 0x69a028bb3ded71a4},\n      {0xa8acd7c0222311bc, 0xc40832ea0d68ce0d},\n      {0xd2d80db02aabd62b, 0xf50a3fa490c30191},\n      {0x83c7088e1aab65db, 0x792667c6da79e0fb},\n      {0xa4b8cab1a1563f52, 0x577001b891185939},\n      {0xcde6fd5e09abcf26, 0xed4c0226b55e6f87},\n      {0x80b05e5ac60b6178, 0x544f8158315b05b5},\n      {0xa0dc75f1778e39d6, 0x696361ae3db1c722},\n      {0xc913936dd571c84c, 0x03bc3a19cd1e38ea},\n      {0xfb5878494ace3a5f, 0x04ab48a04065c724},\n      {0x9d174b2dcec0e47b, 0x62eb0d64283f9c77},\n      {0xc45d1df942711d9a, 0x3ba5d0bd324f8395},\n      {0xf5746577930d6500, 0xca8f44ec7ee3647a},\n      {0x9968bf6abbe85f20, 0x7e998b13cf4e1ecc},\n      {0xbfc2ef456ae276e8, 0x9e3fedd8c321a67f},\n      {0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101f},\n      {0x95d04aee3b80ece5, 0xbba1f1d158724a13},\n      {0xbb445da9ca61281f, 0x2a8a6e45ae8edc98},\n      {0xea1575143cf97226, 0xf52d09d71a3293be},\n      {0x924d692ca61be758, 0x593c2626705f9c57},\n      {0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836d},\n      {0xe498f455c38b997a, 0x0b6dfb9c0f956448},\n      {0x8edf98b59a373fec, 0x4724bd4189bd5ead},\n      {0xb2977ee300c50fe7, 0x58edec91ec2cb658},\n      {0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ee},\n      {0x8b865b215899f46c, 0xbd79e0d20082ee75},\n      {0xae67f1e9aec07187, 0xecd8590680a3aa12},\n      {0xda01ee641a708de9, 0xe80e6f4820cc9496},\n      {0x884134fe908658b2, 0x3109058d147fdcde},\n      {0xaa51823e34a7eede, 0xbd4b46f0599fd416},\n      {0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91b},\n      {0x850fadc09923329e, 0x03e2cf6bc604ddb1},\n      {0xa6539930bf6bff45, 0x84db8346b786151d},\n      {0xcfe87f7cef46ff16, 0xe612641865679a64},\n      {0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07f},\n      {0xa26da3999aef7749, 0xe3be5e330f38f09e},\n      {0xcb090c8001ab551c, 0x5cadf5bfd3072cc6},\n      {0xfdcb4fa002162a63, 0x73d9732fc7c8f7f7},\n      {0x9e9f11c4014dda7e, 0x2867e7fddcdd9afb},\n      {0xc646d63501a1511d, 0xb281e1fd541501b9},\n      {0xf7d88bc24209a565, 0x1f225a7ca91a4227},\n      {0x9ae757596946075f, 0x3375788de9b06959},\n      {0xc1a12d2fc3978937, 0x0052d6b1641c83af},\n      {0xf209787bb47d6b84, 0xc0678c5dbd23a49b},\n      {0x9745eb4d50ce6332, 0xf840b7ba963646e1},\n      {0xbd176620a501fbff, 0xb650e5a93bc3d899},\n      {0xec5d3fa8ce427aff, 0xa3e51f138ab4cebf},\n      {0x93ba47c980e98cdf, 0xc66f336c36b10138},\n      {0xb8a8d9bbe123f017, 0xb80b0047445d4185},\n      {0xe6d3102ad96cec1d, 0xa60dc059157491e6},\n      {0x9043ea1ac7e41392, 0x87c89837ad68db30},\n      {0xb454e4a179dd1877, 0x29babe4598c311fc},\n      {0xe16a1dc9d8545e94, 0xf4296dd6fef3d67b},\n      {0x8ce2529e2734bb1d, 0x1899e4a65f58660d},\n      {0xb01ae745b101e9e4, 0x5ec05dcff72e7f90},\n      {0xdc21a1171d42645d, 0x76707543f4fa1f74},\n      {0x899504ae72497eba, 0x6a06494a791c53a9},\n      {0xabfa45da0edbde69, 0x0487db9d17636893},\n      {0xd6f8d7509292d603, 0x45a9d2845d3c42b7},\n      {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b3},\n      {0xa7f26836f282b732, 0x8e6cac7768d7141f},\n      {0xd1ef0244af2364ff, 0x3207d795430cd927},\n      {0x8335616aed761f1f, 0x7f44e6bd49e807b9},\n      {0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a7},\n      {0xcd036837130890a1, 0x36dba887c37a8c10},\n      {0x802221226be55a64, 0xc2494954da2c978a},\n      {0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6d},\n      {0xc83553c5c8965d3d, 0x6f92829494e5acc8},\n      {0xfa42a8b73abbf48c, 0xcb772339ba1f17fa},\n      {0x9c69a97284b578d7, 0xff2a760414536efc},\n      {0xc38413cf25e2d70d, 0xfef5138519684abb},\n      {0xf46518c2ef5b8cd1, 0x7eb258665fc25d6a},\n      {0x98bf2f79d5993802, 0xef2f773ffbd97a62},\n      {0xbeeefb584aff8603, 0xaafb550ffacfd8fb},\n      {0xeeaaba2e5dbf6784, 0x95ba2a53f983cf39},\n      {0x952ab45cfa97a0b2, 0xdd945a747bf26184},\n      {0xba756174393d88df, 0x94f971119aeef9e5},\n      {0xe912b9d1478ceb17, 0x7a37cd5601aab85e},\n      {0x91abb422ccb812ee, 0xac62e055c10ab33b},\n      {0xb616a12b7fe617aa, 0x577b986b314d600a},\n      {0xe39c49765fdf9d94, 0xed5a7e85fda0b80c},\n      {0x8e41ade9fbebc27d, 0x14588f13be847308},\n      {0xb1d219647ae6b31c, 0x596eb2d8ae258fc9},\n      {0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bc},\n      {0x8aec23d680043bee, 0x25de7bb9480d5855},\n      {0xada72ccc20054ae9, 0xaf561aa79a10ae6b},\n      {0xd910f7ff28069da4, 0x1b2ba1518094da05},\n      {0x87aa9aff79042286, 0x90fb44d2f05d0843},\n      {0xa99541bf57452b28, 0x353a1607ac744a54},\n      {0xd3fa922f2d1675f2, 0x42889b8997915ce9},\n      {0x847c9b5d7c2e09b7, 0x69956135febada12},\n      {0xa59bc234db398c25, 0x43fab9837e699096},\n      {0xcf02b2c21207ef2e, 0x94f967e45e03f4bc},\n      {0x8161afb94b44f57d, 0x1d1be0eebac278f6},\n      {0xa1ba1ba79e1632dc, 0x6462d92a69731733},\n      {0xca28a291859bbf93, 0x7d7b8f7503cfdcff},\n      {0xfcb2cb35e702af78, 0x5cda735244c3d43f},\n      {0x9defbf01b061adab, 0x3a0888136afa64a8},\n      {0xc56baec21c7a1916, 0x088aaa1845b8fdd1},\n      {0xf6c69a72a3989f5b, 0x8aad549e57273d46},\n      {0x9a3c2087a63f6399, 0x36ac54e2f678864c},\n      {0xc0cb28a98fcf3c7f, 0x84576a1bb416a7de},\n      {0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d6},\n      {0x969eb7c47859e743, 0x9f644ae5a4b1b326},\n      {0xbc4665b596706114, 0x873d5d9f0dde1fef},\n      {0xeb57ff22fc0c7959, 0xa90cb506d155a7eb},\n      {0x9316ff75dd87cbd8, 0x09a7f12442d588f3},\n      {0xb7dcbf5354e9bece, 0x0c11ed6d538aeb30},\n      {0xe5d3ef282a242e81, 0x8f1668c8a86da5fb},\n      {0x8fa475791a569d10, 0xf96e017d694487bd},\n      {0xb38d92d760ec4455, 0x37c981dcc395a9ad},\n      {0xe070f78d3927556a, 0x85bbe253f47b1418},\n      {0x8c469ab843b89562, 0x93956d7478ccec8f},\n      {0xaf58416654a6babb, 0x387ac8d1970027b3},\n      {0xdb2e51bfe9d0696a, 0x06997b05fcc0319f},\n      {0x88fcf317f22241e2, 0x441fece3bdf81f04},\n      {0xab3c2fddeeaad25a, 0xd527e81cad7626c4},\n      {0xd60b3bd56a5586f1, 0x8a71e223d8d3b075},\n      {0x85c7056562757456, 0xf6872d5667844e4a},\n      {0xa738c6bebb12d16c, 0xb428f8ac016561dc},\n      {0xd106f86e69d785c7, 0xe13336d701beba53},\n      {0x82a45b450226b39c, 0xecc0024661173474},\n      {0xa34d721642b06084, 0x27f002d7f95d0191},\n      {0xcc20ce9bd35c78a5, 0x31ec038df7b441f5},\n      {0xff290242c83396ce, 0x7e67047175a15272},\n      {0x9f79a169bd203e41, 0x0f0062c6e984d387},\n      {0xc75809c42c684dd1, 0x52c07b78a3e60869},\n      {0xf92e0c3537826145, 0xa7709a56ccdf8a83},\n      {0x9bbcc7a142b17ccb, 0x88a66076400bb692},\n      {0xc2abf989935ddbfe, 0x6acff893d00ea436},\n      {0xf356f7ebf83552fe, 0x0583f6b8c4124d44},\n      {0x98165af37b2153de, 0xc3727a337a8b704b},\n      {0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5d},\n      {0xeda2ee1c7064130c, 0x1162def06f79df74},\n      {0x9485d4d1c63e8be7, 0x8addcb5645ac2ba9},\n      {0xb9a74a0637ce2ee1, 0x6d953e2bd7173693},\n      {0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0438},\n      {0x910ab1d4db9914a0, 0x1d9c9892400a22a3},\n      {0xb54d5e4a127f59c8, 0x2503beb6d00cab4c},\n      {0xe2a0b5dc971f303a, 0x2e44ae64840fd61e},\n      {0x8da471a9de737e24, 0x5ceaecfed289e5d3},\n      {0xb10d8e1456105dad, 0x7425a83e872c5f48},\n      {0xdd50f1996b947518, 0xd12f124e28f7771a},\n      {0x8a5296ffe33cc92f, 0x82bd6b70d99aaa70},\n      {0xace73cbfdc0bfb7b, 0x636cc64d1001550c},\n      {0xd8210befd30efa5a, 0x3c47f7e05401aa4f},\n      {0x8714a775e3e95c78, 0x65acfaec34810a72},\n      {0xa8d9d1535ce3b396, 0x7f1839a741a14d0e},\n      {0xd31045a8341ca07c, 0x1ede48111209a051},\n      {0x83ea2b892091e44d, 0x934aed0aab460433},\n      {0xa4e4b66b68b65d60, 0xf81da84d56178540},\n      {0xce1de40642e3f4b9, 0x36251260ab9d668f},\n      {0x80d2ae83e9ce78f3, 0xc1d72b7c6b42601a},\n      {0xa1075a24e4421730, 0xb24cf65b8612f820},\n      {0xc94930ae1d529cfc, 0xdee033f26797b628},\n      {0xfb9b7cd9a4a7443c, 0x169840ef017da3b2},\n      {0x9d412e0806e88aa5, 0x8e1f289560ee864f},\n      {0xc491798a08a2ad4e, 0xf1a6f2bab92a27e3},\n      {0xf5b5d7ec8acb58a2, 0xae10af696774b1dc},\n      {0x9991a6f3d6bf1765, 0xacca6da1e0a8ef2a},\n      {0xbff610b0cc6edd3f, 0x17fd090a58d32af4},\n      {0xeff394dcff8a948e, 0xddfc4b4cef07f5b1},\n      {0x95f83d0a1fb69cd9, 0x4abdaf101564f98f},\n      {0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f2},\n      {0xea53df5fd18d5513, 0x84c86189216dc5ee},\n      {0x92746b9be2f8552c, 0x32fd3cf5b4e49bb5},\n      {0xb7118682dbb66a77, 0x3fbc8c33221dc2a2},\n      {0xe4d5e82392a40515, 0x0fabaf3feaa5334b},\n      {0x8f05b1163ba6832d, 0x29cb4d87f2a7400f},\n      {0xb2c71d5bca9023f8, 0x743e20e9ef511013},\n      {0xdf78e4b2bd342cf6, 0x914da9246b255417},\n      {0x8bab8eefb6409c1a, 0x1ad089b6c2f7548f},\n      {0xae9672aba3d0c320, 0xa184ac2473b529b2},\n      {0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741f},\n      {0x8865899617fb1871, 0x7e2fa67c7a658893},\n      {0xaa7eebfb9df9de8d, 0xddbb901b98feeab8},\n      {0xd51ea6fa85785631, 0x552a74227f3ea566},\n      {0x8533285c936b35de, 0xd53a88958f872760},\n      {0xa67ff273b8460356, 0x8a892abaf368f138},\n      {0xd01fef10a657842c, 0x2d2b7569b0432d86},\n      {0x8213f56a67f6b29b, 0x9c3b29620e29fc74},\n      {0xa298f2c501f45f42, 0x8349f3ba91b47b90},\n      {0xcb3f2f7642717713, 0x241c70a936219a74},\n      {0xfe0efb53d30dd4d7, 0xed238cd383aa0111},\n      {0x9ec95d1463e8a506, 0xf4363804324a40ab},\n      {0xc67bb4597ce2ce48, 0xb143c6053edcd0d6},\n      {0xf81aa16fdc1b81da, 0xdd94b7868e94050b},\n      {0x9b10a4e5e9913128, 0xca7cf2b4191c8327},\n      {0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f1},\n      {0xf24a01a73cf2dccf, 0xbc633b39673c8ced},\n      {0x976e41088617ca01, 0xd5be0503e085d814},\n      {0xbd49d14aa79dbc82, 0x4b2d8644d8a74e19},\n      {0xec9c459d51852ba2, 0xddf8e7d60ed1219f},\n      {0x93e1ab8252f33b45, 0xcabb90e5c942b504},\n      {0xb8da1662e7b00a17, 0x3d6a751f3b936244},\n      {0xe7109bfba19c0c9d, 0x0cc512670a783ad5},\n      {0x906a617d450187e2, 0x27fb2b80668b24c6},\n      {0xb484f9dc9641e9da, 0xb1f9f660802dedf7},\n      {0xe1a63853bbd26451, 0x5e7873f8a0396974},\n      {0x8d07e33455637eb2, 0xdb0b487b6423e1e9},\n      {0xb049dc016abc5e5f, 0x91ce1a9a3d2cda63},\n      {0xdc5c5301c56b75f7, 0x7641a140cc7810fc},\n      {0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9e},\n      {0xac2820d9623bf429, 0x546345fa9fbdcd45},\n      {0xd732290fbacaf133, 0xa97c177947ad4096},\n      {0x867f59a9d4bed6c0, 0x49ed8eabcccc485e},\n      {0xa81f301449ee8c70, 0x5c68f256bfff5a75},\n      {0xd226fc195c6a2f8c, 0x73832eec6fff3112},\n      {0x83585d8fd9c25db7, 0xc831fd53c5ff7eac},\n      {0xa42e74f3d032f525, 0xba3e7ca8b77f5e56},\n      {0xcd3a1230c43fb26f, 0x28ce1bd2e55f35ec},\n      {0x80444b5e7aa7cf85, 0x7980d163cf5b81b4},\n      {0xa0555e361951c366, 0xd7e105bcc3326220},\n      {0xc86ab5c39fa63440, 0x8dd9472bf3fefaa8},\n      {0xfa856334878fc150, 0xb14f98f6f0feb952},\n      {0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d4},\n      {0xc3b8358109e84f07, 0x0a862f80ec4700c9},\n      {0xf4a642e14c6262c8, 0xcd27bb612758c0fb},\n      {0x98e7e9cccfbd7dbd, 0x8038d51cb897789d},\n      {0xbf21e44003acdd2c, 0xe0470a63e6bd56c4},\n      {0xeeea5d5004981478, 0x1858ccfce06cac75},\n      {0x95527a5202df0ccb, 0x0f37801e0c43ebc9},\n      {0xbaa718e68396cffd, 0xd30560258f54e6bb},\n      {0xe950df20247c83fd, 0x47c6b82ef32a206a},\n      {0x91d28b7416cdd27e, 0x4cdc331d57fa5442},\n      {0xb6472e511c81471d, 0xe0133fe4adf8e953},\n      {0xe3d8f9e563a198e5, 0x58180fddd97723a7},\n      {0x8e679c2f5e44ff8f, 0x570f09eaa7ea7649},\n      {0xb201833b35d63f73, 0x2cd2cc6551e513db},\n      {0xde81e40a034bcf4f, 0xf8077f7ea65e58d2},\n      {0x8b112e86420f6191, 0xfb04afaf27faf783},\n      {0xadd57a27d29339f6, 0x79c5db9af1f9b564},\n      {0xd94ad8b1c7380874, 0x18375281ae7822bd},\n      {0x87cec76f1c830548, 0x8f2293910d0b15b6},\n      {0xa9c2794ae3a3c69a, 0xb2eb3875504ddb23},\n      {0xd433179d9c8cb841, 0x5fa60692a46151ec},\n      {0x849feec281d7f328, 0xdbc7c41ba6bcd334},\n      {0xa5c7ea73224deff3, 0x12b9b522906c0801},\n      {0xcf39e50feae16bef, 0xd768226b34870a01},\n      {0x81842f29f2cce375, 0xe6a1158300d46641},\n      {0xa1e53af46f801c53, 0x60495ae3c1097fd1},\n      {0xca5e89b18b602368, 0x385bb19cb14bdfc5},\n      {0xfcf62c1dee382c42, 0x46729e03dd9ed7b6},\n      {0x9e19db92b4e31ba9, 0x6c07a2c26a8346d2},\n      {0xc5a05277621be293, 0xc7098b7305241886},\n      {0xf70867153aa2db38, 0xb8cbee4fc66d1ea8},\n      {0x9a65406d44a5c903, 0x737f74f1dc043329},\n      {0xc0fe908895cf3b44, 0x505f522e53053ff3},\n      {0xf13e34aabb430a15, 0x647726b9e7c68ff0},\n      {0x96c6e0eab509e64d, 0x5eca783430dc19f6},\n      {0xbc789925624c5fe0, 0xb67d16413d132073},\n      {0xeb96bf6ebadf77d8, 0xe41c5bd18c57e890},\n      {0x933e37a534cbaae7, 0x8e91b962f7b6f15a},\n      {0xb80dc58e81fe95a1, 0x723627bbb5a4adb1},\n      {0xe61136f2227e3b09, 0xcec3b1aaa30dd91d},\n      {0x8fcac257558ee4e6, 0x213a4f0aa5e8a7b2},\n      {0xb3bd72ed2af29e1f, 0xa988e2cd4f62d19e},\n      {0xe0accfa875af45a7, 0x93eb1b80a33b8606},\n      {0x8c6c01c9498d8b88, 0xbc72f130660533c4},\n      {0xaf87023b9bf0ee6a, 0xeb8fad7c7f8680b5},\n      {0xdb68c2ca82ed2a05, 0xa67398db9f6820e2},\n#else\n      {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b},\n      {0xce5d73ff402d98e3, 0xfb0a3d212dc81290},\n      {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f},\n      {0x86a8d39ef77164bc, 0xae5dff9c02033198},\n      {0xd98ddaee19068c76, 0x3badd624dd9b0958},\n      {0xafbd2350644eeacf, 0xe5d1929ef90898fb},\n      {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2},\n      {0xe55990879ddcaabd, 0xcc420a6a101d0516},\n      {0xb94470938fa89bce, 0xf808e40e8d5b3e6a},\n      {0x95a8637627989aad, 0xdde7001379a44aa9},\n      {0xf1c90080baf72cb1, 0x5324c68b12dd6339},\n      {0xc350000000000000, 0x0000000000000000},\n      {0x9dc5ada82b70b59d, 0xf020000000000000},\n      {0xfee50b7025c36a08, 0x02f236d04753d5b5},\n      {0xcde6fd5e09abcf26, 0xed4c0226b55e6f87},\n      {0xa6539930bf6bff45, 0x84db8346b786151d},\n      {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b3},\n      {0xd910f7ff28069da4, 0x1b2ba1518094da05},\n      {0xaf58416654a6babb, 0x387ac8d1970027b3},\n      {0x8da471a9de737e24, 0x5ceaecfed289e5d3},\n      {0xe4d5e82392a40515, 0x0fabaf3feaa5334b},\n      {0xb8da1662e7b00a17, 0x3d6a751f3b936244},\n      {0x95527a5202df0ccb, 0x0f37801e0c43ebc9},\n      {0xf13e34aabb430a15, 0x647726b9e7c68ff0}\n#endif\n    };\n\n#if FMT_USE_FULL_CACHE_DRAGONBOX\n    return pow10_significands[k - float_info<double>::min_k];\n#else\n    static constexpr uint64_t powers_of_5_64[] = {\n        0x0000000000000001, 0x0000000000000005, 0x0000000000000019,\n        0x000000000000007d, 0x0000000000000271, 0x0000000000000c35,\n        0x0000000000003d09, 0x000000000001312d, 0x000000000005f5e1,\n        0x00000000001dcd65, 0x00000000009502f9, 0x0000000002e90edd,\n        0x000000000e8d4a51, 0x0000000048c27395, 0x000000016bcc41e9,\n        0x000000071afd498d, 0x0000002386f26fc1, 0x000000b1a2bc2ec5,\n        0x000003782dace9d9, 0x00001158e460913d, 0x000056bc75e2d631,\n        0x0001b1ae4d6e2ef5, 0x000878678326eac9, 0x002a5a058fc295ed,\n        0x00d3c21bcecceda1, 0x0422ca8b0a00a425, 0x14adf4b7320334b9};\n\n    static const int compression_ratio = 27;\n\n    // Compute base index.\n    int cache_index = (k - float_info<double>::min_k) / compression_ratio;\n    int kb = cache_index * compression_ratio + float_info<double>::min_k;\n    int offset = k - kb;\n\n    // Get base cache.\n    uint128_fallback base_cache = pow10_significands[cache_index];\n    if (offset == 0) return base_cache;\n\n    // Compute the required amount of bit-shift.\n    int alpha = floor_log2_pow10(kb + offset) - floor_log2_pow10(kb) - offset;\n    FMT_ASSERT(alpha > 0 && alpha < 64, \"shifting error detected\");\n\n    // Try to recover the real cache.\n    uint64_t pow5 = powers_of_5_64[offset];\n    uint128_fallback recovered_cache = umul128(base_cache.high(), pow5);\n    uint128_fallback middle_low = umul128(base_cache.low(), pow5);\n\n    recovered_cache += middle_low.high();\n\n    uint64_t high_to_middle = recovered_cache.high() << (64 - alpha);\n    uint64_t middle_to_low = recovered_cache.low() << (64 - alpha);\n\n    recovered_cache =\n        uint128_fallback{(recovered_cache.low() >> alpha) | high_to_middle,\n                         ((middle_low.low() >> alpha) | middle_to_low)};\n    FMT_ASSERT(recovered_cache.low() + 1 != 0, \"\");\n    return {recovered_cache.high(), recovered_cache.low() + 1};\n#endif\n  }\n\n  struct compute_mul_result {\n    carrier_uint result;\n    bool is_integer;\n  };\n  struct compute_mul_parity_result {\n    bool parity;\n    bool is_integer;\n  };\n\n  static auto compute_mul(carrier_uint u,\n                          const cache_entry_type& cache) noexcept\n      -> compute_mul_result {\n    auto r = umul192_upper128(u, cache);\n    return {r.high(), r.low() == 0};\n  }\n\n  static auto compute_delta(const cache_entry_type& cache, int beta) noexcept\n      -> uint32_t {\n    return static_cast<uint32_t>(cache.high() >> (64 - 1 - beta));\n  }\n\n  static auto compute_mul_parity(carrier_uint two_f,\n                                 const cache_entry_type& cache,\n                                 int beta) noexcept\n      -> compute_mul_parity_result {\n    FMT_ASSERT(beta >= 1, \"\");\n    FMT_ASSERT(beta < 64, \"\");\n\n    auto r = umul192_lower128(two_f, cache);\n    return {((r.high() >> (64 - beta)) & 1) != 0,\n            ((r.high() << beta) | (r.low() >> (64 - beta))) == 0};\n  }\n\n  static auto compute_left_endpoint_for_shorter_interval_case(\n      const cache_entry_type& cache, int beta) noexcept -> carrier_uint {\n    return (cache.high() -\n            (cache.high() >> (num_significand_bits<double>() + 2))) >>\n           (64 - num_significand_bits<double>() - 1 - beta);\n  }\n\n  static auto compute_right_endpoint_for_shorter_interval_case(\n      const cache_entry_type& cache, int beta) noexcept -> carrier_uint {\n    return (cache.high() +\n            (cache.high() >> (num_significand_bits<double>() + 1))) >>\n           (64 - num_significand_bits<double>() - 1 - beta);\n  }\n\n  static auto compute_round_up_for_shorter_interval_case(\n      const cache_entry_type& cache, int beta) noexcept -> carrier_uint {\n    return ((cache.high() >> (64 - num_significand_bits<double>() - 2 - beta)) +\n            1) /\n           2;\n  }\n};\n\nFMT_FUNC auto get_cached_power(int k) noexcept -> uint128_fallback {\n  return cache_accessor<double>::get_cached_power(k);\n}\n\n// Various integer checks\ntemplate <typename T>\nauto is_left_endpoint_integer_shorter_interval(int exponent) noexcept -> bool {\n  const int case_shorter_interval_left_endpoint_lower_threshold = 2;\n  const int case_shorter_interval_left_endpoint_upper_threshold = 3;\n  return exponent >= case_shorter_interval_left_endpoint_lower_threshold &&\n         exponent <= case_shorter_interval_left_endpoint_upper_threshold;\n}\n\n// Remove trailing zeros from n and return the number of zeros removed (float).\nFMT_INLINE auto remove_trailing_zeros(uint32_t& n, int s = 0) noexcept -> int {\n  FMT_ASSERT(n != 0, \"\");\n  // Modular inverse of 5 (mod 2^32): (mod_inv_5 * 5) mod 2^32 = 1.\n  constexpr uint32_t mod_inv_5 = 0xcccccccd;\n  constexpr uint32_t mod_inv_25 = 0xc28f5c29;  // = mod_inv_5 * mod_inv_5\n\n  while (true) {\n    auto q = rotr(n * mod_inv_25, 2);\n    if (q > max_value<uint32_t>() / 100) break;\n    n = q;\n    s += 2;\n  }\n  auto q = rotr(n * mod_inv_5, 1);\n  if (q <= max_value<uint32_t>() / 10) {\n    n = q;\n    s |= 1;\n  }\n  return s;\n}\n\n// Removes trailing zeros and returns the number of zeros removed (double).\nFMT_INLINE auto remove_trailing_zeros(uint64_t& n) noexcept -> int {\n  FMT_ASSERT(n != 0, \"\");\n\n  // Is n is divisible by 10^8?\n  constexpr uint32_t ten_pow_8 = 100000000u;\n  if ((n % ten_pow_8) == 0) {\n    // If yes, work with the quotient...\n    auto n32 = static_cast<uint32_t>(n / ten_pow_8);\n    // ... and use the 32 bit variant of the function\n    int num_zeros = remove_trailing_zeros(n32, 8);\n    n = n32;\n    return num_zeros;\n  }\n\n  // If n is not divisible by 10^8, work with n itself.\n  constexpr uint64_t mod_inv_5 = 0xcccccccccccccccd;\n  constexpr uint64_t mod_inv_25 = 0x8f5c28f5c28f5c29;  // mod_inv_5 * mod_inv_5\n\n  int s = 0;\n  while (true) {\n    auto q = rotr(n * mod_inv_25, 2);\n    if (q > max_value<uint64_t>() / 100) break;\n    n = q;\n    s += 2;\n  }\n  auto q = rotr(n * mod_inv_5, 1);\n  if (q <= max_value<uint64_t>() / 10) {\n    n = q;\n    s |= 1;\n  }\n\n  return s;\n}\n\n// The main algorithm for shorter interval case\ntemplate <typename T>\nFMT_INLINE auto shorter_interval_case(int exponent) noexcept -> decimal_fp<T> {\n  decimal_fp<T> ret_value;\n  // Compute k and beta\n  const int minus_k = floor_log10_pow2_minus_log10_4_over_3(exponent);\n  const int beta = exponent + floor_log2_pow10(-minus_k);\n\n  // Compute xi and zi\n  using cache_entry_type = typename cache_accessor<T>::cache_entry_type;\n  const cache_entry_type cache = cache_accessor<T>::get_cached_power(-minus_k);\n\n  auto xi = cache_accessor<T>::compute_left_endpoint_for_shorter_interval_case(\n      cache, beta);\n  auto zi = cache_accessor<T>::compute_right_endpoint_for_shorter_interval_case(\n      cache, beta);\n\n  // If the left endpoint is not an integer, increase it\n  if (!is_left_endpoint_integer_shorter_interval<T>(exponent)) ++xi;\n\n  // Try bigger divisor\n  ret_value.significand = zi / 10;\n\n  // If succeed, remove trailing zeros if necessary and return\n  if (ret_value.significand * 10 >= xi) {\n    ret_value.exponent = minus_k + 1;\n    ret_value.exponent += remove_trailing_zeros(ret_value.significand);\n    return ret_value;\n  }\n\n  // Otherwise, compute the round-up of y\n  ret_value.significand =\n      cache_accessor<T>::compute_round_up_for_shorter_interval_case(cache,\n                                                                    beta);\n  ret_value.exponent = minus_k;\n\n  // When tie occurs, choose one of them according to the rule\n  if (exponent >= float_info<T>::shorter_interval_tie_lower_threshold &&\n      exponent <= float_info<T>::shorter_interval_tie_upper_threshold) {\n    ret_value.significand = ret_value.significand % 2 == 0\n                                ? ret_value.significand\n                                : ret_value.significand - 1;\n  } else if (ret_value.significand < xi) {\n    ++ret_value.significand;\n  }\n  return ret_value;\n}\n\ntemplate <typename T> auto to_decimal(T x) noexcept -> decimal_fp<T> {\n  // Step 1: integer promotion & Schubfach multiplier calculation.\n\n  using carrier_uint = typename float_info<T>::carrier_uint;\n  using cache_entry_type = typename cache_accessor<T>::cache_entry_type;\n  auto br = bit_cast<carrier_uint>(x);\n\n  // Extract significand bits and exponent bits.\n  const carrier_uint significand_mask =\n      (static_cast<carrier_uint>(1) << num_significand_bits<T>()) - 1;\n  carrier_uint significand = (br & significand_mask);\n  int exponent =\n      static_cast<int>((br & exponent_mask<T>()) >> num_significand_bits<T>());\n\n  if (exponent != 0) {  // Check if normal.\n    exponent -= exponent_bias<T>() + num_significand_bits<T>();\n\n    // Shorter interval case; proceed like Schubfach.\n    // In fact, when exponent == 1 and significand == 0, the interval is\n    // regular. However, it can be shown that the end-results are anyway same.\n    if (significand == 0) return shorter_interval_case<T>(exponent);\n\n    significand |= (static_cast<carrier_uint>(1) << num_significand_bits<T>());\n  } else {\n    // Subnormal case; the interval is always regular.\n    if (significand == 0) return {0, 0};\n    exponent =\n        std::numeric_limits<T>::min_exponent - num_significand_bits<T>() - 1;\n  }\n\n  const bool include_left_endpoint = (significand % 2 == 0);\n  const bool include_right_endpoint = include_left_endpoint;\n\n  // Compute k and beta.\n  const int minus_k = floor_log10_pow2(exponent) - float_info<T>::kappa;\n  const cache_entry_type cache = cache_accessor<T>::get_cached_power(-minus_k);\n  const int beta = exponent + floor_log2_pow10(-minus_k);\n\n  // Compute zi and deltai.\n  // 10^kappa <= deltai < 10^(kappa + 1)\n  const uint32_t deltai = cache_accessor<T>::compute_delta(cache, beta);\n  const carrier_uint two_fc = significand << 1;\n\n  // For the case of binary32, the result of integer check is not correct for\n  // 29711844 * 2^-82\n  // = 6.1442653300000000008655037797566933477355632930994033813476... * 10^-18\n  // and 29711844 * 2^-81\n  // = 1.2288530660000000001731007559513386695471126586198806762695... * 10^-17,\n  // and they are the unique counterexamples. However, since 29711844 is even,\n  // this does not cause any problem for the endpoints calculations; it can only\n  // cause a problem when we need to perform integer check for the center.\n  // Fortunately, with these inputs, that branch is never executed, so we are\n  // fine.\n  const typename cache_accessor<T>::compute_mul_result z_mul =\n      cache_accessor<T>::compute_mul((two_fc | 1) << beta, cache);\n\n  // Step 2: Try larger divisor; remove trailing zeros if necessary.\n\n  // Using an upper bound on zi, we might be able to optimize the division\n  // better than the compiler; we are computing zi / big_divisor here.\n  decimal_fp<T> ret_value;\n  ret_value.significand = divide_by_10_to_kappa_plus_1(z_mul.result);\n  uint32_t r = static_cast<uint32_t>(z_mul.result - float_info<T>::big_divisor *\n                                                        ret_value.significand);\n\n  if (r < deltai) {\n    // Exclude the right endpoint if necessary.\n    if (r == 0 && (z_mul.is_integer & !include_right_endpoint)) {\n      --ret_value.significand;\n      r = float_info<T>::big_divisor;\n      goto small_divisor_case_label;\n    }\n  } else if (r > deltai) {\n    goto small_divisor_case_label;\n  } else {\n    // r == deltai; compare fractional parts.\n    const typename cache_accessor<T>::compute_mul_parity_result x_mul =\n        cache_accessor<T>::compute_mul_parity(two_fc - 1, cache, beta);\n\n    if (!(x_mul.parity | (x_mul.is_integer & include_left_endpoint)))\n      goto small_divisor_case_label;\n  }\n  ret_value.exponent = minus_k + float_info<T>::kappa + 1;\n\n  // We may need to remove trailing zeros.\n  ret_value.exponent += remove_trailing_zeros(ret_value.significand);\n  return ret_value;\n\n  // Step 3: Find the significand with the smaller divisor.\n\nsmall_divisor_case_label:\n  ret_value.significand *= 10;\n  ret_value.exponent = minus_k + float_info<T>::kappa;\n\n  uint32_t dist = r - (deltai / 2) + (float_info<T>::small_divisor / 2);\n  const bool approx_y_parity =\n      ((dist ^ (float_info<T>::small_divisor / 2)) & 1) != 0;\n\n  // Is dist divisible by 10^kappa?\n  const bool divisible_by_small_divisor =\n      check_divisibility_and_divide_by_pow10<float_info<T>::kappa>(dist);\n\n  // Add dist / 10^kappa to the significand.\n  ret_value.significand += dist;\n\n  if (!divisible_by_small_divisor) return ret_value;\n\n  // Check z^(f) >= epsilon^(f).\n  // We have either yi == zi - epsiloni or yi == (zi - epsiloni) - 1,\n  // where yi == zi - epsiloni if and only if z^(f) >= epsilon^(f).\n  // Since there are only 2 possibilities, we only need to care about the\n  // parity. Also, zi and r should have the same parity since the divisor\n  // is an even number.\n  const auto y_mul = cache_accessor<T>::compute_mul_parity(two_fc, cache, beta);\n\n  // If z^(f) >= epsilon^(f), we might have a tie when z^(f) == epsilon^(f),\n  // or equivalently, when y is an integer.\n  if (y_mul.parity != approx_y_parity)\n    --ret_value.significand;\n  else if (y_mul.is_integer & (ret_value.significand % 2 != 0))\n    --ret_value.significand;\n  return ret_value;\n}\n}  // namespace dragonbox\n}  // namespace detail\n\ntemplate <> struct formatter<detail::bigint> {\n  FMT_CONSTEXPR auto parse(format_parse_context& ctx)\n      -> format_parse_context::iterator {\n    return ctx.begin();\n  }\n\n  auto format(const detail::bigint& n, format_context& ctx) const\n      -> format_context::iterator {\n    auto out = ctx.out();\n    bool first = true;\n    for (auto i = n.bigits_.size(); i > 0; --i) {\n      auto value = n.bigits_[i - 1u];\n      if (first) {\n        out = fmt::format_to(out, FMT_STRING(\"{:x}\"), value);\n        first = false;\n        continue;\n      }\n      out = fmt::format_to(out, FMT_STRING(\"{:08x}\"), value);\n    }\n    if (n.exp_ > 0)\n      out = fmt::format_to(out, FMT_STRING(\"p{}\"),\n                           n.exp_ * detail::bigint::bigit_bits);\n    return out;\n  }\n};\n\nFMT_FUNC detail::utf8_to_utf16::utf8_to_utf16(string_view s) {\n  for_each_codepoint(s, [this](uint32_t cp, string_view) {\n    if (cp == invalid_code_point) FMT_THROW(std::runtime_error(\"invalid utf8\"));\n    if (cp <= 0xFFFF) {\n      buffer_.push_back(static_cast<wchar_t>(cp));\n    } else {\n      cp -= 0x10000;\n      buffer_.push_back(static_cast<wchar_t>(0xD800 + (cp >> 10)));\n      buffer_.push_back(static_cast<wchar_t>(0xDC00 + (cp & 0x3FF)));\n    }\n    return true;\n  });\n  buffer_.push_back(0);\n}\n\nFMT_FUNC void format_system_error(detail::buffer<char>& out, int error_code,\n                                  const char* message) noexcept {\n  FMT_TRY {\n    auto ec = std::error_code(error_code, std::generic_category());\n    detail::write(appender(out), std::system_error(ec, message).what());\n    return;\n  }\n  FMT_CATCH(...) {}\n  format_error_code(out, error_code, message);\n}\n\nFMT_FUNC void report_system_error(int error_code,\n                                  const char* message) noexcept {\n  do_report_error(format_system_error, error_code, message);\n}\n\nFMT_FUNC auto vformat(string_view fmt, format_args args) -> std::string {\n  // Don't optimize the \"{}\" case to keep the binary size small and because it\n  // can be better optimized in fmt::format anyway.\n  auto buffer = memory_buffer();\n  detail::vformat_to(buffer, fmt, args);\n  return to_string(buffer);\n}\n\nnamespace detail {\n\nFMT_FUNC void vformat_to(buffer<char>& buf, string_view fmt, format_args args,\n                         locale_ref loc) {\n  auto out = appender(buf);\n  if (fmt.size() == 2 && equal2(fmt.data(), \"{}\"))\n    return args.get(0).visit(default_arg_formatter<char>{out});\n  parse_format_string(fmt,\n                      format_handler<>{parse_context<>(fmt), {out, args, loc}});\n}\n\ntemplate <typename T> struct span {\n  T* data;\n  size_t size;\n};\n\ntemplate <typename F> auto flockfile(F* f) -> decltype(_lock_file(f)) {\n  _lock_file(f);\n}\ntemplate <typename F> auto funlockfile(F* f) -> decltype(_unlock_file(f)) {\n  _unlock_file(f);\n}\n\n#ifndef getc_unlocked\ntemplate <typename F> auto getc_unlocked(F* f) -> decltype(_fgetc_nolock(f)) {\n  return _fgetc_nolock(f);\n}\n#endif\n\ntemplate <typename F = FILE, typename Enable = void>\nstruct has_flockfile : std::false_type {};\n\ntemplate <typename F>\nstruct has_flockfile<F, void_t<decltype(flockfile(&std::declval<F&>()))>>\n    : std::true_type {};\n\n// A FILE wrapper. F is FILE defined as a template parameter to make system API\n// detection work.\ntemplate <typename F> class file_base {\n public:\n  F* file_;\n\n public:\n  file_base(F* file) : file_(file) {}\n  operator F*() const { return file_; }\n\n  // Reads a code unit from the stream.\n  auto get() -> int {\n    int result = getc_unlocked(file_);\n    if (result == EOF && ferror(file_) != 0)\n      FMT_THROW(system_error(errno, FMT_STRING(\"getc failed\")));\n    return result;\n  }\n\n  // Puts the code unit back into the stream buffer.\n  void unget(char c) {\n    if (ungetc(c, file_) == EOF)\n      FMT_THROW(system_error(errno, FMT_STRING(\"ungetc failed\")));\n  }\n\n  void flush() { fflush(this->file_); }\n};\n\n// A FILE wrapper for glibc.\ntemplate <typename F> class glibc_file : public file_base<F> {\n private:\n  enum {\n    line_buffered = 0x200,  // _IO_LINE_BUF\n    unbuffered = 2          // _IO_UNBUFFERED\n  };\n\n public:\n  using file_base<F>::file_base;\n\n  auto is_buffered() const -> bool {\n    return (this->file_->_flags & unbuffered) == 0;\n  }\n\n  void init_buffer() {\n    if (this->file_->_IO_write_ptr < this->file_->_IO_write_end) return;\n    // Force buffer initialization by placing and removing a char in a buffer.\n    putc_unlocked(0, this->file_);\n    --this->file_->_IO_write_ptr;\n  }\n\n  // Returns the file's read buffer.\n  auto get_read_buffer() const -> span<const char> {\n    auto ptr = this->file_->_IO_read_ptr;\n    return {ptr, to_unsigned(this->file_->_IO_read_end - ptr)};\n  }\n\n  // Returns the file's write buffer.\n  auto get_write_buffer() const -> span<char> {\n    auto ptr = this->file_->_IO_write_ptr;\n    return {ptr, to_unsigned(this->file_->_IO_buf_end - ptr)};\n  }\n\n  void advance_write_buffer(size_t size) { this->file_->_IO_write_ptr += size; }\n\n  auto needs_flush() const -> bool {\n    if ((this->file_->_flags & line_buffered) == 0) return false;\n    char* end = this->file_->_IO_write_end;\n    auto size = max_of<ptrdiff_t>(this->file_->_IO_write_ptr - end, 0);\n    return memchr(end, '\\n', static_cast<size_t>(size));\n  }\n\n  void flush() { fflush_unlocked(this->file_); }\n};\n\n// A FILE wrapper for Apple's libc.\ntemplate <typename F> class apple_file : public file_base<F> {\n private:\n  enum {\n    line_buffered = 1,  // __SNBF\n    unbuffered = 2      // __SLBF\n  };\n\n public:\n  using file_base<F>::file_base;\n\n  auto is_buffered() const -> bool {\n    return (this->file_->_flags & unbuffered) == 0;\n  }\n\n  void init_buffer() {\n    if (this->file_->_p) return;\n    // Force buffer initialization by placing and removing a char in a buffer.\n    if (!FMT_CLANG_ANALYZER) putc_unlocked(0, this->file_);\n    --this->file_->_p;\n    ++this->file_->_w;\n  }\n\n  auto get_read_buffer() const -> span<const char> {\n    return {reinterpret_cast<char*>(this->file_->_p),\n            to_unsigned(this->file_->_r)};\n  }\n\n  auto get_write_buffer() const -> span<char> {\n    return {reinterpret_cast<char*>(this->file_->_p),\n            to_unsigned(this->file_->_bf._base + this->file_->_bf._size -\n                        this->file_->_p)};\n  }\n\n  void advance_write_buffer(size_t size) {\n    this->file_->_p += size;\n    this->file_->_w -= size;\n  }\n\n  auto needs_flush() const -> bool {\n    if ((this->file_->_flags & line_buffered) == 0) return false;\n    return memchr(this->file_->_p + this->file_->_w, '\\n',\n                  to_unsigned(-this->file_->_w));\n  }\n};\n\n// A fallback FILE wrapper.\ntemplate <typename F> class fallback_file : public file_base<F> {\n private:\n  char next_;  // The next unconsumed character in the buffer.\n  bool has_next_ = false;\n\n public:\n  using file_base<F>::file_base;\n\n  auto is_buffered() const -> bool { return false; }\n  auto needs_flush() const -> bool { return false; }\n  void init_buffer() {}\n\n  auto get_read_buffer() const -> span<const char> {\n    return {&next_, has_next_ ? 1u : 0u};\n  }\n\n  auto get_write_buffer() const -> span<char> { return {nullptr, 0}; }\n\n  void advance_write_buffer(size_t) {}\n\n  auto get() -> int {\n    has_next_ = false;\n    return file_base<F>::get();\n  }\n\n  void unget(char c) {\n    file_base<F>::unget(c);\n    next_ = c;\n    has_next_ = true;\n  }\n};\n\n#ifndef FMT_USE_FALLBACK_FILE\n#  define FMT_USE_FALLBACK_FILE 0\n#endif\n\ntemplate <typename F,\n          FMT_ENABLE_IF(sizeof(F::_p) != 0 && !FMT_USE_FALLBACK_FILE)>\nauto get_file(F* f, int) -> apple_file<F> {\n  return f;\n}\ntemplate <typename F,\n          FMT_ENABLE_IF(sizeof(F::_IO_read_ptr) != 0 && !FMT_USE_FALLBACK_FILE)>\ninline auto get_file(F* f, int) -> glibc_file<F> {\n  return f;\n}\n\ninline auto get_file(FILE* f, ...) -> fallback_file<FILE> { return f; }\n\nusing file_ref = decltype(get_file(static_cast<FILE*>(nullptr), 0));\n\ntemplate <typename F = FILE, typename Enable = void>\nclass file_print_buffer : public buffer<char> {\n public:\n  explicit file_print_buffer(F*) : buffer(nullptr, size_t()) {}\n};\n\ntemplate <typename F>\nclass file_print_buffer<F, enable_if_t<has_flockfile<F>::value>>\n    : public buffer<char> {\n private:\n  file_ref file_;\n\n  static void grow(buffer<char>& base, size_t) {\n    auto& self = static_cast<file_print_buffer&>(base);\n    self.file_.advance_write_buffer(self.size());\n    if (self.file_.get_write_buffer().size == 0) self.file_.flush();\n    auto buf = self.file_.get_write_buffer();\n    FMT_ASSERT(buf.size > 0, \"\");\n    self.set(buf.data, buf.size);\n    self.clear();\n  }\n\n public:\n  explicit file_print_buffer(F* f) : buffer(grow, size_t()), file_(f) {\n    flockfile(f);\n    file_.init_buffer();\n    auto buf = file_.get_write_buffer();\n    set(buf.data, buf.size);\n  }\n  ~file_print_buffer() {\n    file_.advance_write_buffer(size());\n    bool flush = file_.needs_flush();\n    F* f = file_;    // Make funlockfile depend on the template parameter F\n    funlockfile(f);  // for the system API detection to work.\n    if (flush) fflush(file_);\n  }\n};\n\n#if !defined(_WIN32) || defined(FMT_USE_WRITE_CONSOLE)\nFMT_FUNC auto write_console(int, string_view) -> bool { return false; }\n#else\nusing dword = conditional_t<sizeof(long) == 4, unsigned long, unsigned>;\nextern \"C\" __declspec(dllimport) int __stdcall WriteConsoleW(  //\n    void*, const void*, dword, dword*, void*);\n\nFMT_FUNC bool write_console(int fd, string_view text) {\n  auto u16 = utf8_to_utf16(text);\n  return WriteConsoleW(reinterpret_cast<void*>(_get_osfhandle(fd)), u16.c_str(),\n                       static_cast<dword>(u16.size()), nullptr, nullptr) != 0;\n}\n#endif\n\n#ifdef _WIN32\n// Print assuming legacy (non-Unicode) encoding.\nFMT_FUNC void vprint_mojibake(std::FILE* f, string_view fmt, format_args args,\n                              bool newline) {\n  auto buffer = memory_buffer();\n  detail::vformat_to(buffer, fmt, args);\n  if (newline) buffer.push_back('\\n');\n  fwrite_all(buffer.data(), buffer.size(), f);\n}\n#endif\n\nFMT_FUNC void print(std::FILE* f, string_view text) {\n#if defined(_WIN32) && !defined(FMT_USE_WRITE_CONSOLE)\n  int fd = _fileno(f);\n  if (_isatty(fd)) {\n    std::fflush(f);\n    if (write_console(fd, text)) return;\n  }\n#endif\n  fwrite_all(text.data(), text.size(), f);\n}\n}  // namespace detail\n\nFMT_FUNC void vprint_buffered(std::FILE* f, string_view fmt, format_args args) {\n  auto buffer = memory_buffer();\n  detail::vformat_to(buffer, fmt, args);\n  detail::print(f, {buffer.data(), buffer.size()});\n}\n\nFMT_FUNC void vprint(std::FILE* f, string_view fmt, format_args args) {\n  if (!detail::file_ref(f).is_buffered() || !detail::has_flockfile<>())\n    return vprint_buffered(f, fmt, args);\n  auto&& buffer = detail::file_print_buffer<>(f);\n  return detail::vformat_to(buffer, fmt, args);\n}\n\nFMT_FUNC void vprintln(std::FILE* f, string_view fmt, format_args args) {\n  auto buffer = memory_buffer();\n  detail::vformat_to(buffer, fmt, args);\n  buffer.push_back('\\n');\n  detail::print(f, {buffer.data(), buffer.size()});\n}\n\nFMT_FUNC void vprint(string_view fmt, format_args args) {\n  vprint(stdout, fmt, args);\n}\n\nnamespace detail {\n\nstruct singleton {\n  unsigned char upper;\n  unsigned char lower_count;\n};\n\ninline auto is_printable(uint16_t x, const singleton* singletons,\n                         size_t singletons_size,\n                         const unsigned char* singleton_lowers,\n                         const unsigned char* normal, size_t normal_size)\n    -> bool {\n  auto upper = x >> 8;\n  auto lower_start = 0;\n  for (size_t i = 0; i < singletons_size; ++i) {\n    auto s = singletons[i];\n    auto lower_end = lower_start + s.lower_count;\n    if (upper < s.upper) break;\n    if (upper == s.upper) {\n      for (auto j = lower_start; j < lower_end; ++j) {\n        if (singleton_lowers[j] == (x & 0xff)) return false;\n      }\n    }\n    lower_start = lower_end;\n  }\n\n  auto xsigned = static_cast<int>(x);\n  auto current = true;\n  for (size_t i = 0; i < normal_size; ++i) {\n    auto v = static_cast<int>(normal[i]);\n    auto len = (v & 0x80) != 0 ? (v & 0x7f) << 8 | normal[++i] : v;\n    xsigned -= len;\n    if (xsigned < 0) break;\n    current = !current;\n  }\n  return current;\n}\n\n// This code is generated by support/printable.py.\nFMT_FUNC auto is_printable(uint32_t cp) -> bool {\n  static constexpr singleton singletons0[] = {\n      {0x00, 1},  {0x03, 5},  {0x05, 6},  {0x06, 3},  {0x07, 6},  {0x08, 8},\n      {0x09, 17}, {0x0a, 28}, {0x0b, 25}, {0x0c, 20}, {0x0d, 16}, {0x0e, 13},\n      {0x0f, 4},  {0x10, 3},  {0x12, 18}, {0x13, 9},  {0x16, 1},  {0x17, 5},\n      {0x18, 2},  {0x19, 3},  {0x1a, 7},  {0x1c, 2},  {0x1d, 1},  {0x1f, 22},\n      {0x20, 3},  {0x2b, 3},  {0x2c, 2},  {0x2d, 11}, {0x2e, 1},  {0x30, 3},\n      {0x31, 2},  {0x32, 1},  {0xa7, 2},  {0xa9, 2},  {0xaa, 4},  {0xab, 8},\n      {0xfa, 2},  {0xfb, 5},  {0xfd, 4},  {0xfe, 3},  {0xff, 9},\n  };\n  static constexpr unsigned char singletons0_lower[] = {\n      0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57, 0x58, 0x8b, 0x8c, 0x90,\n      0x1c, 0x1d, 0xdd, 0x0e, 0x0f, 0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f,\n      0x5c, 0x5d, 0x5f, 0xb5, 0xe2, 0x84, 0x8d, 0x8e, 0x91, 0x92, 0xa9, 0xb1,\n      0xba, 0xbb, 0xc5, 0xc6, 0xc9, 0xca, 0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04,\n      0x11, 0x12, 0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49, 0x4a, 0x5d,\n      0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4, 0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf,\n      0xe4, 0xe5, 0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a,\n      0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e, 0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d,\n      0xc9, 0xce, 0xcf, 0x0d, 0x11, 0x29, 0x45, 0x49, 0x57, 0x64, 0x65, 0x8d,\n      0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x0d,\n      0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5,\n      0xd7, 0xf0, 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6, 0xbe, 0xbf, 0xc5, 0xc7,\n      0xce, 0xcf, 0xda, 0xdb, 0x48, 0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49,\n      0x4e, 0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1, 0xb6, 0xb7,\n      0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7,\n      0xfe, 0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x0f, 0x1f, 0x6e,\n      0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e, 0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16,\n      0x17, 0x1e, 0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e, 0x7e,\n      0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f,\n      0x74, 0x75, 0x96, 0x2f, 0x5f, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf,\n      0xc7, 0xcf, 0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98, 0x30, 0x8f, 0x1f, 0xc0,\n      0xc1, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27,\n      0x2f, 0xee, 0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90, 0x91,\n      0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7,\n      0xfe, 0xff,\n  };\n  static constexpr singleton singletons1[] = {\n      {0x00, 6},  {0x01, 1}, {0x03, 1},  {0x04, 2}, {0x08, 8},  {0x09, 2},\n      {0x0a, 5},  {0x0b, 2}, {0x0e, 4},  {0x10, 1}, {0x11, 2},  {0x12, 5},\n      {0x13, 17}, {0x14, 1}, {0x15, 2},  {0x17, 2}, {0x19, 13}, {0x1c, 5},\n      {0x1d, 8},  {0x24, 1}, {0x6a, 3},  {0x6b, 2}, {0xbc, 2},  {0xd1, 2},\n      {0xd4, 12}, {0xd5, 9}, {0xd6, 2},  {0xd7, 2}, {0xda, 1},  {0xe0, 5},\n      {0xe1, 2},  {0xe8, 2}, {0xee, 32}, {0xf0, 4}, {0xf8, 2},  {0xf9, 2},\n      {0xfa, 2},  {0xfb, 1},\n  };\n  static constexpr unsigned char singletons1_lower[] = {\n      0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e, 0x9e, 0x9f, 0x06, 0x07,\n      0x09, 0x36, 0x3d, 0x3e, 0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x36,\n      0x37, 0x56, 0x57, 0x7f, 0xaa, 0xae, 0xaf, 0xbd, 0x35, 0xe0, 0x12, 0x87,\n      0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a,\n      0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5c, 0xb6, 0xb7, 0x1b,\n      0x1c, 0x07, 0x08, 0x0a, 0x0b, 0x14, 0x17, 0x36, 0x39, 0x3a, 0xa8, 0xa9,\n      0xd8, 0xd9, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x66,\n      0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27,\n      0x28, 0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad, 0xba, 0xbc,\n      0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7,\n      0xcc, 0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e, 0x3f, 0xc5, 0xc6,\n      0x04, 0x20, 0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a, 0x48, 0x4a, 0x4c,\n      0x50, 0x53, 0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66,\n      0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0,\n      0xae, 0xaf, 0x79, 0xcc, 0x6e, 0x6f, 0x93,\n  };\n  static constexpr unsigned char normal0[] = {\n      0x00, 0x20, 0x5f, 0x22, 0x82, 0xdf, 0x04, 0x82, 0x44, 0x08, 0x1b, 0x04,\n      0x06, 0x11, 0x81, 0xac, 0x0e, 0x80, 0xab, 0x35, 0x28, 0x0b, 0x80, 0xe0,\n      0x03, 0x19, 0x08, 0x01, 0x04, 0x2f, 0x04, 0x34, 0x04, 0x07, 0x03, 0x01,\n      0x07, 0x06, 0x07, 0x11, 0x0a, 0x50, 0x0f, 0x12, 0x07, 0x55, 0x07, 0x03,\n      0x04, 0x1c, 0x0a, 0x09, 0x03, 0x08, 0x03, 0x07, 0x03, 0x02, 0x03, 0x03,\n      0x03, 0x0c, 0x04, 0x05, 0x03, 0x0b, 0x06, 0x01, 0x0e, 0x15, 0x05, 0x3a,\n      0x03, 0x11, 0x07, 0x06, 0x05, 0x10, 0x07, 0x57, 0x07, 0x02, 0x07, 0x15,\n      0x0d, 0x50, 0x04, 0x43, 0x03, 0x2d, 0x03, 0x01, 0x04, 0x11, 0x06, 0x0f,\n      0x0c, 0x3a, 0x04, 0x1d, 0x25, 0x5f, 0x20, 0x6d, 0x04, 0x6a, 0x25, 0x80,\n      0xc8, 0x05, 0x82, 0xb0, 0x03, 0x1a, 0x06, 0x82, 0xfd, 0x03, 0x59, 0x07,\n      0x15, 0x0b, 0x17, 0x09, 0x14, 0x0c, 0x14, 0x0c, 0x6a, 0x06, 0x0a, 0x06,\n      0x1a, 0x06, 0x59, 0x07, 0x2b, 0x05, 0x46, 0x0a, 0x2c, 0x04, 0x0c, 0x04,\n      0x01, 0x03, 0x31, 0x0b, 0x2c, 0x04, 0x1a, 0x06, 0x0b, 0x03, 0x80, 0xac,\n      0x06, 0x0a, 0x06, 0x21, 0x3f, 0x4c, 0x04, 0x2d, 0x03, 0x74, 0x08, 0x3c,\n      0x03, 0x0f, 0x03, 0x3c, 0x07, 0x38, 0x08, 0x2b, 0x05, 0x82, 0xff, 0x11,\n      0x18, 0x08, 0x2f, 0x11, 0x2d, 0x03, 0x20, 0x10, 0x21, 0x0f, 0x80, 0x8c,\n      0x04, 0x82, 0x97, 0x19, 0x0b, 0x15, 0x88, 0x94, 0x05, 0x2f, 0x05, 0x3b,\n      0x07, 0x02, 0x0e, 0x18, 0x09, 0x80, 0xb3, 0x2d, 0x74, 0x0c, 0x80, 0xd6,\n      0x1a, 0x0c, 0x05, 0x80, 0xff, 0x05, 0x80, 0xdf, 0x0c, 0xee, 0x0d, 0x03,\n      0x84, 0x8d, 0x03, 0x37, 0x09, 0x81, 0x5c, 0x14, 0x80, 0xb8, 0x08, 0x80,\n      0xcb, 0x2a, 0x38, 0x03, 0x0a, 0x06, 0x38, 0x08, 0x46, 0x08, 0x0c, 0x06,\n      0x74, 0x0b, 0x1e, 0x03, 0x5a, 0x04, 0x59, 0x09, 0x80, 0x83, 0x18, 0x1c,\n      0x0a, 0x16, 0x09, 0x4c, 0x04, 0x80, 0x8a, 0x06, 0xab, 0xa4, 0x0c, 0x17,\n      0x04, 0x31, 0xa1, 0x04, 0x81, 0xda, 0x26, 0x07, 0x0c, 0x05, 0x05, 0x80,\n      0xa5, 0x11, 0x81, 0x6d, 0x10, 0x78, 0x28, 0x2a, 0x06, 0x4c, 0x04, 0x80,\n      0x8d, 0x04, 0x80, 0xbe, 0x03, 0x1b, 0x03, 0x0f, 0x0d,\n  };\n  static constexpr unsigned char normal1[] = {\n      0x5e, 0x22, 0x7b, 0x05, 0x03, 0x04, 0x2d, 0x03, 0x66, 0x03, 0x01, 0x2f,\n      0x2e, 0x80, 0x82, 0x1d, 0x03, 0x31, 0x0f, 0x1c, 0x04, 0x24, 0x09, 0x1e,\n      0x05, 0x2b, 0x05, 0x44, 0x04, 0x0e, 0x2a, 0x80, 0xaa, 0x06, 0x24, 0x04,\n      0x24, 0x04, 0x28, 0x08, 0x34, 0x0b, 0x01, 0x80, 0x90, 0x81, 0x37, 0x09,\n      0x16, 0x0a, 0x08, 0x80, 0x98, 0x39, 0x03, 0x63, 0x08, 0x09, 0x30, 0x16,\n      0x05, 0x21, 0x03, 0x1b, 0x05, 0x01, 0x40, 0x38, 0x04, 0x4b, 0x05, 0x2f,\n      0x04, 0x0a, 0x07, 0x09, 0x07, 0x40, 0x20, 0x27, 0x04, 0x0c, 0x09, 0x36,\n      0x03, 0x3a, 0x05, 0x1a, 0x07, 0x04, 0x0c, 0x07, 0x50, 0x49, 0x37, 0x33,\n      0x0d, 0x33, 0x07, 0x2e, 0x08, 0x0a, 0x81, 0x26, 0x52, 0x4e, 0x28, 0x08,\n      0x2a, 0x56, 0x1c, 0x14, 0x17, 0x09, 0x4e, 0x04, 0x1e, 0x0f, 0x43, 0x0e,\n      0x19, 0x07, 0x0a, 0x06, 0x48, 0x08, 0x27, 0x09, 0x75, 0x0b, 0x3f, 0x41,\n      0x2a, 0x06, 0x3b, 0x05, 0x0a, 0x06, 0x51, 0x06, 0x01, 0x05, 0x10, 0x03,\n      0x05, 0x80, 0x8b, 0x62, 0x1e, 0x48, 0x08, 0x0a, 0x80, 0xa6, 0x5e, 0x22,\n      0x45, 0x0b, 0x0a, 0x06, 0x0d, 0x13, 0x39, 0x07, 0x0a, 0x36, 0x2c, 0x04,\n      0x10, 0x80, 0xc0, 0x3c, 0x64, 0x53, 0x0c, 0x48, 0x09, 0x0a, 0x46, 0x45,\n      0x1b, 0x48, 0x08, 0x53, 0x1d, 0x39, 0x81, 0x07, 0x46, 0x0a, 0x1d, 0x03,\n      0x47, 0x49, 0x37, 0x03, 0x0e, 0x08, 0x0a, 0x06, 0x39, 0x07, 0x0a, 0x81,\n      0x36, 0x19, 0x80, 0xb7, 0x01, 0x0f, 0x32, 0x0d, 0x83, 0x9b, 0x66, 0x75,\n      0x0b, 0x80, 0xc4, 0x8a, 0xbc, 0x84, 0x2f, 0x8f, 0xd1, 0x82, 0x47, 0xa1,\n      0xb9, 0x82, 0x39, 0x07, 0x2a, 0x04, 0x02, 0x60, 0x26, 0x0a, 0x46, 0x0a,\n      0x28, 0x05, 0x13, 0x82, 0xb0, 0x5b, 0x65, 0x4b, 0x04, 0x39, 0x07, 0x11,\n      0x40, 0x05, 0x0b, 0x02, 0x0e, 0x97, 0xf8, 0x08, 0x84, 0xd6, 0x2a, 0x09,\n      0xa2, 0xf7, 0x81, 0x1f, 0x31, 0x03, 0x11, 0x04, 0x08, 0x81, 0x8c, 0x89,\n      0x04, 0x6b, 0x05, 0x0d, 0x03, 0x09, 0x07, 0x10, 0x93, 0x60, 0x80, 0xf6,\n      0x0a, 0x73, 0x08, 0x6e, 0x17, 0x46, 0x80, 0x9a, 0x14, 0x0c, 0x57, 0x09,\n      0x19, 0x80, 0x87, 0x81, 0x47, 0x03, 0x85, 0x42, 0x0f, 0x15, 0x85, 0x50,\n      0x2b, 0x80, 0xd5, 0x2d, 0x03, 0x1a, 0x04, 0x02, 0x81, 0x70, 0x3a, 0x05,\n      0x01, 0x85, 0x00, 0x80, 0xd7, 0x29, 0x4c, 0x04, 0x0a, 0x04, 0x02, 0x83,\n      0x11, 0x44, 0x4c, 0x3d, 0x80, 0xc2, 0x3c, 0x06, 0x01, 0x04, 0x55, 0x05,\n      0x1b, 0x34, 0x02, 0x81, 0x0e, 0x2c, 0x04, 0x64, 0x0c, 0x56, 0x0a, 0x80,\n      0xae, 0x38, 0x1d, 0x0d, 0x2c, 0x04, 0x09, 0x07, 0x02, 0x0e, 0x06, 0x80,\n      0x9a, 0x83, 0xd8, 0x08, 0x0d, 0x03, 0x0d, 0x03, 0x74, 0x0c, 0x59, 0x07,\n      0x0c, 0x14, 0x0c, 0x04, 0x38, 0x08, 0x0a, 0x06, 0x28, 0x08, 0x22, 0x4e,\n      0x81, 0x54, 0x0c, 0x15, 0x03, 0x03, 0x05, 0x07, 0x09, 0x19, 0x07, 0x07,\n      0x09, 0x03, 0x0d, 0x07, 0x29, 0x80, 0xcb, 0x25, 0x0a, 0x84, 0x06,\n  };\n  auto lower = static_cast<uint16_t>(cp);\n  if (cp < 0x10000) {\n    return is_printable(lower, singletons0,\n                        sizeof(singletons0) / sizeof(*singletons0),\n                        singletons0_lower, normal0, sizeof(normal0));\n  }\n  if (cp < 0x20000) {\n    return is_printable(lower, singletons1,\n                        sizeof(singletons1) / sizeof(*singletons1),\n                        singletons1_lower, normal1, sizeof(normal1));\n  }\n  if (0x2a6de <= cp && cp < 0x2a700) return false;\n  if (0x2b735 <= cp && cp < 0x2b740) return false;\n  if (0x2b81e <= cp && cp < 0x2b820) return false;\n  if (0x2cea2 <= cp && cp < 0x2ceb0) return false;\n  if (0x2ebe1 <= cp && cp < 0x2f800) return false;\n  if (0x2fa1e <= cp && cp < 0x30000) return false;\n  if (0x3134b <= cp && cp < 0xe0100) return false;\n  if (0xe01f0 <= cp && cp < 0x110000) return false;\n  return cp < 0x110000;\n}\n\n}  // namespace detail\n\nFMT_END_NAMESPACE\n\n#endif  // FMT_FORMAT_INL_H_\n"
  },
  {
    "path": "thirdparty/fmt/include/fmt/format.h",
    "content": "/*\n  Formatting library for C++\n\n  Copyright (c) 2012 - present, Victor Zverovich\n\n  Permission is hereby granted, free of charge, to any person obtaining\n  a copy of this software and associated documentation files (the\n  \"Software\"), to deal in the Software without restriction, including\n  without limitation the rights to use, copy, modify, merge, publish,\n  distribute, sublicense, and/or sell copies of the Software, and to\n  permit persons to whom the Software is furnished to do so, subject to\n  the following conditions:\n\n  The above copyright notice and this permission notice shall be\n  included in all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n  --- Optional exception to the license ---\n\n  As an exception, if, as a result of your compiling your source code, portions\n  of this Software are embedded into a machine-executable object form of such\n  source code, you may redistribute such embedded portions in such object form\n  without including the above copyright and permission notices.\n */\n\n#ifndef FMT_FORMAT_H_\n#define FMT_FORMAT_H_\n\n#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES\n#  define _LIBCPP_REMOVE_TRANSITIVE_INCLUDES\n#  define FMT_REMOVE_TRANSITIVE_INCLUDES\n#endif\n\n#include \"base.h\"\n\n// libc++ supports string_view in pre-c++17.\n#if FMT_HAS_INCLUDE(<string_view>) && \\\n    (FMT_CPLUSPLUS >= 201703L || defined(_LIBCPP_VERSION))\n#  define FMT_USE_STRING_VIEW\n#endif\n\n#ifndef FMT_MODULE\n#  include <stdlib.h>  // malloc, free\n\n#  include <cmath>    // std::signbit\n#  include <cstddef>  // std::byte\n#  include <cstdint>  // uint32_t\n#  include <cstring>  // std::memcpy\n#  include <limits>   // std::numeric_limits\n#  include <new>      // std::bad_alloc\n#  if defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_DUAL_ABI)\n// Workaround for pre gcc 5 libstdc++.\n#    include <memory>  // std::allocator_traits\n#  endif\n#  include <stdexcept>     // std::runtime_error\n#  include <string>        // std::string\n#  include <system_error>  // std::system_error\n\n// Check FMT_CPLUSPLUS to avoid a warning in MSVC.\n#  if FMT_HAS_INCLUDE(<bit>) && FMT_CPLUSPLUS > 201703L\n#    include <bit>  // std::bit_cast\n#  endif\n\n#  if defined(FMT_USE_STRING_VIEW)\n#    include <string_view>\n#  endif\n\n#  if FMT_MSC_VERSION\n#    include <intrin.h>  // _BitScanReverse[64], _umul128\n#  endif\n#endif  // FMT_MODULE\n\n#if defined(FMT_USE_NONTYPE_TEMPLATE_ARGS)\n// Use the provided definition.\n#elif defined(__NVCOMPILER)\n#  define FMT_USE_NONTYPE_TEMPLATE_ARGS 0\n#elif FMT_GCC_VERSION >= 903 && FMT_CPLUSPLUS >= 201709L\n#  define FMT_USE_NONTYPE_TEMPLATE_ARGS 1\n#elif defined(__cpp_nontype_template_args) && \\\n    __cpp_nontype_template_args >= 201911L\n#  define FMT_USE_NONTYPE_TEMPLATE_ARGS 1\n#elif FMT_CLANG_VERSION >= 1200 && FMT_CPLUSPLUS >= 202002L\n#  define FMT_USE_NONTYPE_TEMPLATE_ARGS 1\n#else\n#  define FMT_USE_NONTYPE_TEMPLATE_ARGS 0\n#endif\n\n#if defined __cpp_inline_variables && __cpp_inline_variables >= 201606L\n#  define FMT_INLINE_VARIABLE inline\n#else\n#  define FMT_INLINE_VARIABLE\n#endif\n\n// Check if RTTI is disabled.\n#ifdef FMT_USE_RTTI\n// Use the provided definition.\n#elif defined(__GXX_RTTI) || FMT_HAS_FEATURE(cxx_rtti) || defined(_CPPRTTI) || \\\n    defined(__INTEL_RTTI__) || defined(__RTTI)\n// __RTTI is for EDG compilers. _CPPRTTI is for MSVC.\n#  define FMT_USE_RTTI 1\n#else\n#  define FMT_USE_RTTI 0\n#endif\n\n// Visibility when compiled as a shared library/object.\n#if defined(FMT_LIB_EXPORT) || defined(FMT_SHARED)\n#  define FMT_SO_VISIBILITY(value) FMT_VISIBILITY(value)\n#else\n#  define FMT_SO_VISIBILITY(value)\n#endif\n\n#if FMT_GCC_VERSION || FMT_CLANG_VERSION\n#  define FMT_NOINLINE __attribute__((noinline))\n#else\n#  define FMT_NOINLINE\n#endif\n\n#ifdef FMT_DEPRECATED\n// Use the provided definition.\n#elif FMT_HAS_CPP14_ATTRIBUTE(deprecated)\n#  define FMT_DEPRECATED [[deprecated]]\n#else\n#  define FMT_DEPRECATED /* deprecated */\n#endif\n\n// Detect constexpr std::string.\n#if !FMT_USE_CONSTEVAL\n#  define FMT_USE_CONSTEXPR_STRING 0\n#elif defined(__cpp_lib_constexpr_string) && \\\n    __cpp_lib_constexpr_string >= 201907L\n#  if FMT_CLANG_VERSION && FMT_GLIBCXX_RELEASE\n// clang + libstdc++ are able to work only starting with gcc13.3\n// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113294\n#    if FMT_GLIBCXX_RELEASE < 13\n#      define FMT_USE_CONSTEXPR_STRING 0\n#    elif FMT_GLIBCXX_RELEASE == 13 && __GLIBCXX__ < 20240521\n#      define FMT_USE_CONSTEXPR_STRING 0\n#    else\n#      define FMT_USE_CONSTEXPR_STRING 1\n#    endif\n#  else\n#    define FMT_USE_CONSTEXPR_STRING 1\n#  endif\n#else\n#  define FMT_USE_CONSTEXPR_STRING 0\n#endif\n#if FMT_USE_CONSTEXPR_STRING\n#  define FMT_CONSTEXPR_STRING constexpr\n#else\n#  define FMT_CONSTEXPR_STRING\n#endif\n\n// GCC 4.9 doesn't support qualified names in specializations.\nnamespace std {\ntemplate <typename T> struct iterator_traits<fmt::basic_appender<T>> {\n  using iterator_category = output_iterator_tag;\n  using value_type = T;\n  using difference_type =\n      decltype(static_cast<int*>(nullptr) - static_cast<int*>(nullptr));\n  using pointer = void;\n  using reference = void;\n};\n}  // namespace std\n\n#ifdef FMT_THROW\n// Use the provided definition.\n#elif FMT_USE_EXCEPTIONS\n#  define FMT_THROW(x) throw x\n#else\n#  define FMT_THROW(x) ::fmt::assert_fail(__FILE__, __LINE__, (x).what())\n#endif\n\n#ifdef __clang_analyzer__\n#  define FMT_CLANG_ANALYZER 1\n#else\n#  define FMT_CLANG_ANALYZER 0\n#endif\n\n// Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of\n// integer formatter template instantiations to just one by only using the\n// largest integer type. This results in a reduction in binary size but will\n// cause a decrease in integer formatting performance.\n#if !defined(FMT_REDUCE_INT_INSTANTIATIONS)\n#  define FMT_REDUCE_INT_INSTANTIATIONS 0\n#endif\n\nFMT_BEGIN_NAMESPACE\n\ntemplate <typename Char, typename Traits, typename Allocator>\nstruct is_contiguous<std::basic_string<Char, Traits, Allocator>>\n    : std::true_type {};\n\nnamespace detail {\n\n// __builtin_clz is broken in clang with Microsoft codegen:\n// https://github.com/fmtlib/fmt/issues/519.\n#if !FMT_MSC_VERSION\n#  if FMT_HAS_BUILTIN(__builtin_clz) || FMT_GCC_VERSION || FMT_ICC_VERSION\n#    define FMT_BUILTIN_CLZ(n) __builtin_clz(n)\n#  endif\n#  if FMT_HAS_BUILTIN(__builtin_clzll) || FMT_GCC_VERSION || FMT_ICC_VERSION\n#    define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)\n#  endif\n#endif\n\n// Some compilers masquerade as both MSVC and GCC but otherwise support\n// __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the\n// MSVC intrinsics if the clz and clzll builtins are not available.\n#if FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL)\n// Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.\n#  ifndef __clang__\n#    pragma intrinsic(_BitScanReverse)\n#    ifdef _WIN64\n#      pragma intrinsic(_BitScanReverse64)\n#    endif\n#  endif\n\ninline auto clz(uint32_t x) -> int {\n  FMT_ASSERT(x != 0, \"\");\n  FMT_MSC_WARNING(suppress : 6102)  // Suppress a bogus static analysis warning.\n  unsigned long r = 0;\n  _BitScanReverse(&r, x);\n  return 31 ^ static_cast<int>(r);\n}\n#  define FMT_BUILTIN_CLZ(n) detail::clz(n)\n\ninline auto clzll(uint64_t x) -> int {\n  FMT_ASSERT(x != 0, \"\");\n  FMT_MSC_WARNING(suppress : 6102)  // Suppress a bogus static analysis warning.\n  unsigned long r = 0;\n#  ifdef _WIN64\n  _BitScanReverse64(&r, x);\n#  else\n  // Scan the high 32 bits.\n  if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32)))\n    return 63 ^ static_cast<int>(r + 32);\n  // Scan the low 32 bits.\n  _BitScanReverse(&r, static_cast<uint32_t>(x));\n#  endif\n  return 63 ^ static_cast<int>(r);\n}\n#  define FMT_BUILTIN_CLZLL(n) detail::clzll(n)\n#endif  // FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL)\n\nFMT_CONSTEXPR inline void abort_fuzzing_if(bool condition) {\n  ignore_unused(condition);\n#ifdef FMT_FUZZ\n  if (condition) throw std::runtime_error(\"fuzzing limit reached\");\n#endif\n}\n\n#if defined(FMT_USE_STRING_VIEW)\ntemplate <typename Char> using std_string_view = std::basic_string_view<Char>;\n#else\ntemplate <typename Char> struct std_string_view {\n  operator basic_string_view<Char>() const;\n};\n#endif\n\ntemplate <typename Char, Char... C> struct string_literal {\n  static constexpr Char value[sizeof...(C)] = {C...};\n  constexpr operator basic_string_view<Char>() const {\n    return {value, sizeof...(C)};\n  }\n};\n#if FMT_CPLUSPLUS < 201703L\ntemplate <typename Char, Char... C>\nconstexpr Char string_literal<Char, C...>::value[sizeof...(C)];\n#endif\n\n// Implementation of std::bit_cast for pre-C++20.\ntemplate <typename To, typename From, FMT_ENABLE_IF(sizeof(To) == sizeof(From))>\nFMT_CONSTEXPR20 auto bit_cast(const From& from) -> To {\n#ifdef __cpp_lib_bit_cast\n  if (is_constant_evaluated()) return std::bit_cast<To>(from);\n#endif\n  auto to = To();\n  // The cast suppresses a bogus -Wclass-memaccess on GCC.\n  std::memcpy(static_cast<void*>(&to), &from, sizeof(to));\n  return to;\n}\n\ninline auto is_big_endian() -> bool {\n#ifdef _WIN32\n  return false;\n#elif defined(__BIG_ENDIAN__)\n  return true;\n#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)\n  return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__;\n#else\n  struct bytes {\n    char data[sizeof(int)];\n  };\n  return bit_cast<bytes>(1).data[0] == 0;\n#endif\n}\n\nclass uint128_fallback {\n private:\n  uint64_t lo_, hi_;\n\n public:\n  constexpr uint128_fallback(uint64_t hi, uint64_t lo) : lo_(lo), hi_(hi) {}\n  constexpr uint128_fallback(uint64_t value = 0) : lo_(value), hi_(0) {}\n\n  constexpr auto high() const noexcept -> uint64_t { return hi_; }\n  constexpr auto low() const noexcept -> uint64_t { return lo_; }\n\n  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>\n  constexpr explicit operator T() const {\n    return static_cast<T>(lo_);\n  }\n\n  friend constexpr auto operator==(const uint128_fallback& lhs,\n                                   const uint128_fallback& rhs) -> bool {\n    return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_;\n  }\n  friend constexpr auto operator!=(const uint128_fallback& lhs,\n                                   const uint128_fallback& rhs) -> bool {\n    return !(lhs == rhs);\n  }\n  friend constexpr auto operator>(const uint128_fallback& lhs,\n                                  const uint128_fallback& rhs) -> bool {\n    return lhs.hi_ != rhs.hi_ ? lhs.hi_ > rhs.hi_ : lhs.lo_ > rhs.lo_;\n  }\n  friend constexpr auto operator|(const uint128_fallback& lhs,\n                                  const uint128_fallback& rhs)\n      -> uint128_fallback {\n    return {lhs.hi_ | rhs.hi_, lhs.lo_ | rhs.lo_};\n  }\n  friend constexpr auto operator&(const uint128_fallback& lhs,\n                                  const uint128_fallback& rhs)\n      -> uint128_fallback {\n    return {lhs.hi_ & rhs.hi_, lhs.lo_ & rhs.lo_};\n  }\n  friend constexpr auto operator~(const uint128_fallback& n)\n      -> uint128_fallback {\n    return {~n.hi_, ~n.lo_};\n  }\n  friend FMT_CONSTEXPR auto operator+(const uint128_fallback& lhs,\n                                      const uint128_fallback& rhs)\n      -> uint128_fallback {\n    auto result = uint128_fallback(lhs);\n    result += rhs;\n    return result;\n  }\n  friend FMT_CONSTEXPR auto operator*(const uint128_fallback& lhs, uint32_t rhs)\n      -> uint128_fallback {\n    FMT_ASSERT(lhs.hi_ == 0, \"\");\n    uint64_t hi = (lhs.lo_ >> 32) * rhs;\n    uint64_t lo = (lhs.lo_ & ~uint32_t()) * rhs;\n    uint64_t new_lo = (hi << 32) + lo;\n    return {(hi >> 32) + (new_lo < lo ? 1 : 0), new_lo};\n  }\n  friend constexpr auto operator-(const uint128_fallback& lhs, uint64_t rhs)\n      -> uint128_fallback {\n    return {lhs.hi_ - (lhs.lo_ < rhs ? 1 : 0), lhs.lo_ - rhs};\n  }\n  FMT_CONSTEXPR auto operator>>(int shift) const -> uint128_fallback {\n    if (shift == 64) return {0, hi_};\n    if (shift > 64) return uint128_fallback(0, hi_) >> (shift - 64);\n    return {hi_ >> shift, (hi_ << (64 - shift)) | (lo_ >> shift)};\n  }\n  FMT_CONSTEXPR auto operator<<(int shift) const -> uint128_fallback {\n    if (shift == 64) return {lo_, 0};\n    if (shift > 64) return uint128_fallback(lo_, 0) << (shift - 64);\n    return {hi_ << shift | (lo_ >> (64 - shift)), (lo_ << shift)};\n  }\n  FMT_CONSTEXPR auto operator>>=(int shift) -> uint128_fallback& {\n    return *this = *this >> shift;\n  }\n  FMT_CONSTEXPR void operator+=(uint128_fallback n) {\n    uint64_t new_lo = lo_ + n.lo_;\n    uint64_t new_hi = hi_ + n.hi_ + (new_lo < lo_ ? 1 : 0);\n    FMT_ASSERT(new_hi >= hi_, \"\");\n    lo_ = new_lo;\n    hi_ = new_hi;\n  }\n  FMT_CONSTEXPR void operator&=(uint128_fallback n) {\n    lo_ &= n.lo_;\n    hi_ &= n.hi_;\n  }\n\n  FMT_CONSTEXPR20 auto operator+=(uint64_t n) noexcept -> uint128_fallback& {\n    if (is_constant_evaluated()) {\n      lo_ += n;\n      hi_ += (lo_ < n ? 1 : 0);\n      return *this;\n    }\n#if FMT_HAS_BUILTIN(__builtin_addcll) && !defined(__ibmxl__)\n    unsigned long long carry;\n    lo_ = __builtin_addcll(lo_, n, 0, &carry);\n    hi_ += carry;\n#elif FMT_HAS_BUILTIN(__builtin_ia32_addcarryx_u64) && !defined(__ibmxl__)\n    unsigned long long result;\n    auto carry = __builtin_ia32_addcarryx_u64(0, lo_, n, &result);\n    lo_ = result;\n    hi_ += carry;\n#elif defined(_MSC_VER) && defined(_M_X64)\n    auto carry = _addcarry_u64(0, lo_, n, &lo_);\n    _addcarry_u64(carry, hi_, 0, &hi_);\n#else\n    lo_ += n;\n    hi_ += (lo_ < n ? 1 : 0);\n#endif\n    return *this;\n  }\n};\n\nusing uint128_t = conditional_t<FMT_USE_INT128, uint128_opt, uint128_fallback>;\n\n#ifdef UINTPTR_MAX\nusing uintptr_t = ::uintptr_t;\n#else\nusing uintptr_t = uint128_t;\n#endif\n\n// Returns the largest possible value for type T. Same as\n// std::numeric_limits<T>::max() but shorter and not affected by the max macro.\ntemplate <typename T> constexpr auto max_value() -> T {\n  return (std::numeric_limits<T>::max)();\n}\ntemplate <typename T> constexpr auto num_bits() -> int {\n  return std::numeric_limits<T>::digits;\n}\n// std::numeric_limits<T>::digits may return 0 for 128-bit ints.\ntemplate <> constexpr auto num_bits<int128_opt>() -> int { return 128; }\ntemplate <> constexpr auto num_bits<uint128_opt>() -> int { return 128; }\ntemplate <> constexpr auto num_bits<uint128_fallback>() -> int { return 128; }\n\n// A heterogeneous bit_cast used for converting 96-bit long double to uint128_t\n// and 128-bit pointers to uint128_fallback.\ntemplate <typename To, typename From, FMT_ENABLE_IF(sizeof(To) > sizeof(From))>\ninline auto bit_cast(const From& from) -> To {\n  constexpr auto size = static_cast<int>(sizeof(From) / sizeof(unsigned short));\n  struct data_t {\n    unsigned short value[static_cast<unsigned>(size)];\n  } data = bit_cast<data_t>(from);\n  auto result = To();\n  if (const_check(is_big_endian())) {\n    for (int i = 0; i < size; ++i)\n      result = (result << num_bits<unsigned short>()) | data.value[i];\n  } else {\n    for (int i = size - 1; i >= 0; --i)\n      result = (result << num_bits<unsigned short>()) | data.value[i];\n  }\n  return result;\n}\n\ntemplate <typename UInt>\nFMT_CONSTEXPR20 inline auto countl_zero_fallback(UInt n) -> int {\n  int lz = 0;\n  constexpr UInt msb_mask = static_cast<UInt>(1) << (num_bits<UInt>() - 1);\n  for (; (n & msb_mask) == 0; n <<= 1) lz++;\n  return lz;\n}\n\nFMT_CONSTEXPR20 inline auto countl_zero(uint32_t n) -> int {\n#ifdef FMT_BUILTIN_CLZ\n  if (!is_constant_evaluated()) return FMT_BUILTIN_CLZ(n);\n#endif\n  return countl_zero_fallback(n);\n}\n\nFMT_CONSTEXPR20 inline auto countl_zero(uint64_t n) -> int {\n#ifdef FMT_BUILTIN_CLZLL\n  if (!is_constant_evaluated()) return FMT_BUILTIN_CLZLL(n);\n#endif\n  return countl_zero_fallback(n);\n}\n\nFMT_INLINE void assume(bool condition) {\n  (void)condition;\n#if FMT_HAS_BUILTIN(__builtin_assume) && !FMT_ICC_VERSION\n  __builtin_assume(condition);\n#elif FMT_GCC_VERSION\n  if (!condition) __builtin_unreachable();\n#endif\n}\n\n// Attempts to reserve space for n extra characters in the output range.\n// Returns a pointer to the reserved range or a reference to it.\ntemplate <typename OutputIt,\n          FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value&&\n                            is_contiguous<typename OutputIt::container>::value)>\n#if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION\n__attribute__((no_sanitize(\"undefined\")))\n#endif\nFMT_CONSTEXPR20 inline auto\nreserve(OutputIt it, size_t n) -> typename OutputIt::value_type* {\n  auto& c = get_container(it);\n  size_t size = c.size();\n  c.resize(size + n);\n  return &c[size];\n}\n\ntemplate <typename T>\nFMT_CONSTEXPR20 inline auto reserve(basic_appender<T> it, size_t n)\n    -> basic_appender<T> {\n  buffer<T>& buf = get_container(it);\n  buf.try_reserve(buf.size() + n);\n  return it;\n}\n\ntemplate <typename Iterator>\nconstexpr auto reserve(Iterator& it, size_t) -> Iterator& {\n  return it;\n}\n\ntemplate <typename OutputIt>\nusing reserve_iterator =\n    remove_reference_t<decltype(reserve(std::declval<OutputIt&>(), 0))>;\n\ntemplate <typename T, typename OutputIt>\nconstexpr auto to_pointer(OutputIt, size_t) -> T* {\n  return nullptr;\n}\ntemplate <typename T> FMT_CONSTEXPR auto to_pointer(T*& ptr, size_t n) -> T* {\n  T* begin = ptr;\n  ptr += n;\n  return begin;\n}\ntemplate <typename T>\nFMT_CONSTEXPR20 auto to_pointer(basic_appender<T> it, size_t n) -> T* {\n  buffer<T>& buf = get_container(it);\n  buf.try_reserve(buf.size() + n);\n  auto size = buf.size();\n  if (buf.capacity() < size + n) return nullptr;\n  buf.try_resize(size + n);\n  return buf.data() + size;\n}\n\ntemplate <typename OutputIt,\n          FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value&&\n                            is_contiguous<typename OutputIt::container>::value)>\ninline auto base_iterator(OutputIt it,\n                          typename OutputIt::container_type::value_type*)\n    -> OutputIt {\n  return it;\n}\n\ntemplate <typename Iterator>\nconstexpr auto base_iterator(Iterator, Iterator it) -> Iterator {\n  return it;\n}\n\n// <algorithm> is spectacularly slow to compile in C++20 so use a simple fill_n\n// instead (#1998).\ntemplate <typename OutputIt, typename Size, typename T>\nFMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value)\n    -> OutputIt {\n  for (Size i = 0; i < count; ++i) *out++ = value;\n  return out;\n}\ntemplate <typename T, typename Size>\nFMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* {\n  if (is_constant_evaluated()) return fill_n<T*, Size, T>(out, count, value);\n  static_assert(sizeof(T) == 1,\n                \"sizeof(T) must be 1 to use char for initialization\");\n  std::memset(out, value, to_unsigned(count));\n  return out + count;\n}\n\ntemplate <typename OutChar, typename InputIt, typename OutputIt>\nFMT_CONSTEXPR FMT_NOINLINE auto copy_noinline(InputIt begin, InputIt end,\n                                              OutputIt out) -> OutputIt {\n  return copy<OutChar>(begin, end, out);\n}\n\n// A public domain branchless UTF-8 decoder by Christopher Wellons:\n// https://github.com/skeeto/branchless-utf8\n/* Decode the next character, c, from s, reporting errors in e.\n *\n * Since this is a branchless decoder, four bytes will be read from the\n * buffer regardless of the actual length of the next character. This\n * means the buffer _must_ have at least three bytes of zero padding\n * following the end of the data stream.\n *\n * Errors are reported in e, which will be non-zero if the parsed\n * character was somehow invalid: invalid byte sequence, non-canonical\n * encoding, or a surrogate half.\n *\n * The function returns a pointer to the next character. When an error\n * occurs, this pointer will be a guess that depends on the particular\n * error, but it will always advance at least one byte.\n */\nFMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e)\n    -> const char* {\n  constexpr int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};\n  constexpr uint32_t mins[] = {4194304, 0, 128, 2048, 65536};\n  constexpr int shiftc[] = {0, 18, 12, 6, 0};\n  constexpr int shifte[] = {0, 6, 4, 2, 0};\n\n  int len = \"\\1\\1\\1\\1\\1\\1\\1\\1\\1\\1\\1\\1\\1\\1\\1\\1\\0\\0\\0\\0\\0\\0\\0\\0\\2\\2\\2\\2\\3\\3\\4\"\n      [static_cast<unsigned char>(*s) >> 3];\n  // Compute the pointer to the next character early so that the next\n  // iteration can start working on the next character. Neither Clang\n  // nor GCC figure out this reordering on their own.\n  const char* next = s + len + !len;\n\n  using uchar = unsigned char;\n\n  // Assume a four-byte character and load four bytes. Unused bits are\n  // shifted out.\n  *c = uint32_t(uchar(s[0]) & masks[len]) << 18;\n  *c |= uint32_t(uchar(s[1]) & 0x3f) << 12;\n  *c |= uint32_t(uchar(s[2]) & 0x3f) << 6;\n  *c |= uint32_t(uchar(s[3]) & 0x3f) << 0;\n  *c >>= shiftc[len];\n\n  // Accumulate the various error conditions.\n  *e = (*c < mins[len]) << 6;       // non-canonical encoding\n  *e |= ((*c >> 11) == 0x1b) << 7;  // surrogate half?\n  *e |= (*c > 0x10FFFF) << 8;       // out of range?\n  *e |= (uchar(s[1]) & 0xc0) >> 2;\n  *e |= (uchar(s[2]) & 0xc0) >> 4;\n  *e |= uchar(s[3]) >> 6;\n  *e ^= 0x2a;  // top two bits of each tail byte correct?\n  *e >>= shifte[len];\n\n  return next;\n}\n\nconstexpr FMT_INLINE_VARIABLE uint32_t invalid_code_point = ~uint32_t();\n\n// Invokes f(cp, sv) for every code point cp in s with sv being the string view\n// corresponding to the code point. cp is invalid_code_point on error.\ntemplate <typename F>\nFMT_CONSTEXPR void for_each_codepoint(string_view s, F f) {\n  auto decode = [f](const char* buf_ptr, const char* ptr) {\n    auto cp = uint32_t();\n    auto error = 0;\n    auto end = utf8_decode(buf_ptr, &cp, &error);\n    bool result = f(error ? invalid_code_point : cp,\n                    string_view(ptr, error ? 1 : to_unsigned(end - buf_ptr)));\n    return result ? (error ? buf_ptr + 1 : end) : nullptr;\n  };\n\n  auto p = s.data();\n  const size_t block_size = 4;  // utf8_decode always reads blocks of 4 chars.\n  if (s.size() >= block_size) {\n    for (auto end = p + s.size() - block_size + 1; p < end;) {\n      p = decode(p, p);\n      if (!p) return;\n    }\n  }\n  auto num_chars_left = to_unsigned(s.data() + s.size() - p);\n  if (num_chars_left == 0) return;\n\n  // Suppress bogus -Wstringop-overflow.\n  if (FMT_GCC_VERSION) num_chars_left &= 3;\n  char buf[2 * block_size - 1] = {};\n  copy<char>(p, p + num_chars_left, buf);\n  const char* buf_ptr = buf;\n  do {\n    auto end = decode(buf_ptr, p);\n    if (!end) return;\n    p += end - buf_ptr;\n    buf_ptr = end;\n  } while (buf_ptr < buf + num_chars_left);\n}\n\nFMT_CONSTEXPR inline auto display_width_of(uint32_t cp) noexcept -> size_t {\n  return to_unsigned(\n      1 + (cp >= 0x1100 &&\n           (cp <= 0x115f ||  // Hangul Jamo init. consonants\n            cp == 0x2329 ||  // LEFT-POINTING ANGLE BRACKET\n            cp == 0x232a ||  // RIGHT-POINTING ANGLE BRACKET\n            // CJK ... Yi except IDEOGRAPHIC HALF FILL SPACE:\n            (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) ||\n            (cp >= 0xac00 && cp <= 0xd7a3) ||    // Hangul Syllables\n            (cp >= 0xf900 && cp <= 0xfaff) ||    // CJK Compatibility Ideographs\n            (cp >= 0xfe10 && cp <= 0xfe19) ||    // Vertical Forms\n            (cp >= 0xfe30 && cp <= 0xfe6f) ||    // CJK Compatibility Forms\n            (cp >= 0xff00 && cp <= 0xff60) ||    // Fullwidth Forms\n            (cp >= 0xffe0 && cp <= 0xffe6) ||    // Fullwidth Forms\n            (cp >= 0x20000 && cp <= 0x2fffd) ||  // CJK\n            (cp >= 0x30000 && cp <= 0x3fffd) ||\n            // Miscellaneous Symbols and Pictographs + Emoticons:\n            (cp >= 0x1f300 && cp <= 0x1f64f) ||\n            // Supplemental Symbols and Pictographs:\n            (cp >= 0x1f900 && cp <= 0x1f9ff))));\n}\n\ntemplate <typename T> struct is_integral : std::is_integral<T> {};\ntemplate <> struct is_integral<int128_opt> : std::true_type {};\ntemplate <> struct is_integral<uint128_t> : std::true_type {};\n\ntemplate <typename T>\nusing is_signed =\n    std::integral_constant<bool, std::numeric_limits<T>::is_signed ||\n                                     std::is_same<T, int128_opt>::value>;\n\ntemplate <typename T>\nusing is_integer =\n    bool_constant<is_integral<T>::value && !std::is_same<T, bool>::value &&\n                  !std::is_same<T, char>::value &&\n                  !std::is_same<T, wchar_t>::value>;\n\n#if defined(FMT_USE_FLOAT128)\n// Use the provided definition.\n#elif FMT_CLANG_VERSION >= 309 && FMT_HAS_INCLUDE(<quadmath.h>)\n#  define FMT_USE_FLOAT128 1\n#elif FMT_GCC_VERSION && defined(_GLIBCXX_USE_FLOAT128) && \\\n    !defined(__STRICT_ANSI__)\n#  define FMT_USE_FLOAT128 1\n#else\n#  define FMT_USE_FLOAT128 0\n#endif\n#if FMT_USE_FLOAT128\nusing float128 = __float128;\n#else\nstruct float128 {};\n#endif\n\ntemplate <typename T> using is_float128 = std::is_same<T, float128>;\n\ntemplate <typename T> struct is_floating_point : std::is_floating_point<T> {};\ntemplate <> struct is_floating_point<float128> : std::true_type {};\n\ntemplate <typename T, bool = is_floating_point<T>::value>\nstruct is_fast_float : bool_constant<std::numeric_limits<T>::is_iec559 &&\n                                     sizeof(T) <= sizeof(double)> {};\ntemplate <typename T> struct is_fast_float<T, false> : std::false_type {};\n\ntemplate <typename T>\nusing fast_float_t = conditional_t<sizeof(T) == sizeof(double), double, float>;\n\ntemplate <typename T>\nusing is_double_double = bool_constant<std::numeric_limits<T>::digits == 106>;\n\n#ifndef FMT_USE_FULL_CACHE_DRAGONBOX\n#  define FMT_USE_FULL_CACHE_DRAGONBOX 0\n#endif\n\n// An allocator that uses malloc/free to allow removing dependency on the C++\n// standard libary runtime. std::decay is used for back_inserter to be found by\n// ADL when applied to memory_buffer.\ntemplate <typename T> struct allocator : private std::decay<void> {\n  using value_type = T;\n\n  auto allocate(size_t n) -> T* {\n    FMT_ASSERT(n <= max_value<size_t>() / sizeof(T), \"\");\n    T* p = static_cast<T*>(malloc(n * sizeof(T)));\n    if (!p) FMT_THROW(std::bad_alloc());\n    return p;\n  }\n\n  void deallocate(T* p, size_t) { free(p); }\n\n  constexpr friend auto operator==(allocator, allocator) noexcept -> bool {\n    return true;  // All instances of this allocator are equivalent.\n  }\n  constexpr friend auto operator!=(allocator, allocator) noexcept -> bool {\n    return false;\n  }\n};\n\ntemplate <typename Formatter>\nFMT_CONSTEXPR auto maybe_set_debug_format(Formatter& f, bool set)\n    -> decltype(f.set_debug_format(set)) {\n  f.set_debug_format(set);\n}\ntemplate <typename Formatter>\nFMT_CONSTEXPR void maybe_set_debug_format(Formatter&, ...) {}\n\n}  // namespace detail\n\nFMT_BEGIN_EXPORT\n\n// The number of characters to store in the basic_memory_buffer object itself\n// to avoid dynamic memory allocation.\nenum { inline_buffer_size = 500 };\n\n/**\n * A dynamically growing memory buffer for trivially copyable/constructible\n * types with the first `SIZE` elements stored in the object itself. Most\n * commonly used via the `memory_buffer` alias for `char`.\n *\n * **Example**:\n *\n *     auto out = fmt::memory_buffer();\n *     fmt::format_to(std::back_inserter(out), \"The answer is {}.\", 42);\n *\n * This will append \"The answer is 42.\" to `out`. The buffer content can be\n * converted to `std::string` with `to_string(out)`.\n */\ntemplate <typename T, size_t SIZE = inline_buffer_size,\n          typename Allocator = detail::allocator<T>>\nclass basic_memory_buffer : public detail::buffer<T> {\n private:\n  T store_[SIZE];\n\n  // Don't inherit from Allocator to avoid generating type_info for it.\n  FMT_NO_UNIQUE_ADDRESS Allocator alloc_;\n\n  // Deallocate memory allocated by the buffer.\n  FMT_CONSTEXPR20 void deallocate() {\n    T* data = this->data();\n    if (data != store_) alloc_.deallocate(data, this->capacity());\n  }\n\n  static FMT_CONSTEXPR20 void grow(detail::buffer<T>& buf, size_t size) {\n    detail::abort_fuzzing_if(size > 5000);\n    auto& self = static_cast<basic_memory_buffer&>(buf);\n    const size_t max_size =\n        std::allocator_traits<Allocator>::max_size(self.alloc_);\n    size_t old_capacity = buf.capacity();\n    size_t new_capacity = old_capacity + old_capacity / 2;\n    if (size > new_capacity)\n      new_capacity = size;\n    else if (new_capacity > max_size)\n      new_capacity = max_of(size, max_size);\n    T* old_data = buf.data();\n    T* new_data = self.alloc_.allocate(new_capacity);\n    // Suppress a bogus -Wstringop-overflow in gcc 13.1 (#3481).\n    detail::assume(buf.size() <= new_capacity);\n    // The following code doesn't throw, so the raw pointer above doesn't leak.\n    memcpy(new_data, old_data, buf.size() * sizeof(T));\n    self.set(new_data, new_capacity);\n    // deallocate must not throw according to the standard, but even if it does,\n    // the buffer already uses the new storage and will deallocate it in\n    // destructor.\n    if (old_data != self.store_) self.alloc_.deallocate(old_data, old_capacity);\n  }\n\n public:\n  using value_type = T;\n  using const_reference = const T&;\n\n  FMT_CONSTEXPR explicit basic_memory_buffer(\n      const Allocator& alloc = Allocator())\n      : detail::buffer<T>(grow), alloc_(alloc) {\n    this->set(store_, SIZE);\n    if (detail::is_constant_evaluated()) detail::fill_n(store_, SIZE, T());\n  }\n  FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); }\n\n private:\n  template <typename Alloc = Allocator,\n            FMT_ENABLE_IF(std::allocator_traits<Alloc>::\n                              propagate_on_container_move_assignment::value)>\n  FMT_CONSTEXPR20 auto move_alloc(basic_memory_buffer& other) -> bool {\n    alloc_ = std::move(other.alloc_);\n    return true;\n  }\n  // If the allocator does not propagate then copy the data from other.\n  template <typename Alloc = Allocator,\n            FMT_ENABLE_IF(!std::allocator_traits<Alloc>::\n                              propagate_on_container_move_assignment::value)>\n  FMT_CONSTEXPR20 auto move_alloc(basic_memory_buffer& other) -> bool {\n    T* data = other.data();\n    if (alloc_ == other.alloc_ || data == other.store_) return true;\n    size_t size = other.size();\n    // Perform copy operation, allocators are different.\n    this->resize(size);\n    detail::copy<T>(data, data + size, this->data());\n    return false;\n  }\n\n  // Move data from other to this buffer.\n  FMT_CONSTEXPR20 void move(basic_memory_buffer& other) {\n    T* data = other.data();\n    size_t size = other.size(), capacity = other.capacity();\n    if (!move_alloc(other)) return;\n    if (data == other.store_) {\n      this->set(store_, capacity);\n      detail::copy<T>(other.store_, other.store_ + size, store_);\n    } else {\n      this->set(data, capacity);\n      // Set pointer to the inline array so that delete is not called\n      // when deallocating.\n      other.set(other.store_, 0);\n      other.clear();\n    }\n    this->resize(size);\n  }\n\n public:\n  /// Constructs a `basic_memory_buffer` object moving the content of the other\n  /// object to it.\n  FMT_CONSTEXPR20 basic_memory_buffer(basic_memory_buffer&& other) noexcept\n      : detail::buffer<T>(grow) {\n    move(other);\n  }\n\n  /// Moves the content of the other `basic_memory_buffer` object to this one.\n  auto operator=(basic_memory_buffer&& other) noexcept -> basic_memory_buffer& {\n    FMT_ASSERT(this != &other, \"\");\n    deallocate();\n    move(other);\n    return *this;\n  }\n\n  // Returns a copy of the allocator associated with this buffer.\n  auto get_allocator() const -> Allocator { return alloc_; }\n\n  /// Resizes the buffer to contain `count` elements. If T is a POD type new\n  /// elements may not be initialized.\n  FMT_CONSTEXPR void resize(size_t count) { this->try_resize(count); }\n\n  /// Increases the buffer capacity to `new_capacity`.\n  void reserve(size_t new_capacity) { this->try_reserve(new_capacity); }\n\n  using detail::buffer<T>::append;\n  template <typename ContiguousRange>\n  FMT_CONSTEXPR20 void append(const ContiguousRange& range) {\n    append(range.data(), range.data() + range.size());\n  }\n};\n\nusing memory_buffer = basic_memory_buffer<char>;\n\ntemplate <size_t SIZE>\nFMT_NODISCARD auto to_string(const basic_memory_buffer<char, SIZE>& buf)\n    -> std::string {\n  auto size = buf.size();\n  detail::assume(size < std::string().max_size());\n  return {buf.data(), size};\n}\n\n// A writer to a buffered stream. It doesn't own the underlying stream.\nclass writer {\n private:\n  detail::buffer<char>* buf_;\n\n  // We cannot create a file buffer in advance because any write to a FILE may\n  // invalidate it.\n  FILE* file_;\n\n public:\n  inline writer(FILE* f) : buf_(nullptr), file_(f) {}\n  inline writer(detail::buffer<char>& buf) : buf_(&buf) {}\n\n  /// Formats `args` according to specifications in `fmt` and writes the\n  /// output to the file.\n  template <typename... T> void print(format_string<T...> fmt, T&&... args) {\n    if (buf_)\n      fmt::format_to(appender(*buf_), fmt, std::forward<T>(args)...);\n    else\n      fmt::print(file_, fmt, std::forward<T>(args)...);\n  }\n};\n\nclass string_buffer {\n private:\n  std::string str_;\n  detail::container_buffer<std::string> buf_;\n\n public:\n  inline string_buffer() : buf_(str_) {}\n\n  inline operator writer() { return buf_; }\n  inline auto str() -> std::string& { return str_; }\n};\n\ntemplate <typename T, size_t SIZE, typename Allocator>\nstruct is_contiguous<basic_memory_buffer<T, SIZE, Allocator>> : std::true_type {\n};\n\n// Suppress a misleading warning in older versions of clang.\nFMT_PRAGMA_CLANG(diagnostic ignored \"-Wweak-vtables\")\n\n/// An error reported from a formatting function.\nclass FMT_SO_VISIBILITY(\"default\") format_error : public std::runtime_error {\n public:\n  using std::runtime_error::runtime_error;\n};\n\nclass loc_value;\n\nFMT_END_EXPORT\nnamespace detail {\nFMT_API auto write_console(int fd, string_view text) -> bool;\nFMT_API void print(FILE*, string_view);\n}  // namespace detail\n\nnamespace detail {\ntemplate <typename Char, size_t N> struct fixed_string {\n  FMT_CONSTEXPR20 fixed_string(const Char (&s)[N]) {\n    detail::copy<Char, const Char*, Char*>(static_cast<const Char*>(s), s + N,\n                                           data);\n  }\n  Char data[N] = {};\n};\n\n// Converts a compile-time string to basic_string_view.\nFMT_EXPORT template <typename Char, size_t N>\nconstexpr auto compile_string_to_view(const Char (&s)[N])\n    -> basic_string_view<Char> {\n  // Remove trailing NUL character if needed. Won't be present if this is used\n  // with a raw character array (i.e. not defined as a string).\n  return {s, N - (std::char_traits<Char>::to_int_type(s[N - 1]) == 0 ? 1 : 0)};\n}\nFMT_EXPORT template <typename Char>\nconstexpr auto compile_string_to_view(basic_string_view<Char> s)\n    -> basic_string_view<Char> {\n  return s;\n}\n\n// Returns true if value is negative, false otherwise.\n// Same as `value < 0` but doesn't produce warnings if T is an unsigned type.\ntemplate <typename T, FMT_ENABLE_IF(is_signed<T>::value)>\nconstexpr auto is_negative(T value) -> bool {\n  return value < 0;\n}\ntemplate <typename T, FMT_ENABLE_IF(!is_signed<T>::value)>\nconstexpr auto is_negative(T) -> bool {\n  return false;\n}\n\n// Smallest of uint32_t, uint64_t, uint128_t that is large enough to\n// represent all values of an integral type T.\ntemplate <typename T>\nusing uint32_or_64_or_128_t =\n    conditional_t<num_bits<T>() <= 32 && !FMT_REDUCE_INT_INSTANTIATIONS,\n                  uint32_t,\n                  conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>>;\ntemplate <typename T>\nusing uint64_or_128_t = conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>;\n\n#define FMT_POWERS_OF_10(factor)                                  \\\n  factor * 10, (factor) * 100, (factor) * 1000, (factor) * 10000, \\\n      (factor) * 100000, (factor) * 1000000, (factor) * 10000000, \\\n      (factor) * 100000000, (factor) * 1000000000\n\n// Converts value in the range [0, 100) to a string.\n// GCC generates slightly better code when value is pointer-size.\ninline auto digits2(size_t value) -> const char* {\n  // Align data since unaligned access may be slower when crossing a\n  // hardware-specific boundary.\n  alignas(2) static const char data[] =\n      \"0001020304050607080910111213141516171819\"\n      \"2021222324252627282930313233343536373839\"\n      \"4041424344454647484950515253545556575859\"\n      \"6061626364656667686970717273747576777879\"\n      \"8081828384858687888990919293949596979899\";\n  return &data[value * 2];\n}\n\ntemplate <typename Char> constexpr auto getsign(sign s) -> Char {\n  return static_cast<char>(((' ' << 24) | ('+' << 16) | ('-' << 8)) >>\n                           (static_cast<int>(s) * 8));\n}\n\ntemplate <typename T> FMT_CONSTEXPR auto count_digits_fallback(T n) -> int {\n  int count = 1;\n  for (;;) {\n    // Integer division is slow so do it for a group of four digits instead\n    // of for every digit. The idea comes from the talk by Alexandrescu\n    // \"Three Optimization Tips for C++\". See speed-test for a comparison.\n    if (n < 10) return count;\n    if (n < 100) return count + 1;\n    if (n < 1000) return count + 2;\n    if (n < 10000) return count + 3;\n    n /= 10000u;\n    count += 4;\n  }\n}\n#if FMT_USE_INT128\nFMT_CONSTEXPR inline auto count_digits(uint128_opt n) -> int {\n  return count_digits_fallback(n);\n}\n#endif\n\n#ifdef FMT_BUILTIN_CLZLL\n// It is a separate function rather than a part of count_digits to workaround\n// the lack of static constexpr in constexpr functions.\ninline auto do_count_digits(uint64_t n) -> int {\n  // This has comparable performance to the version by Kendall Willets\n  // (https://github.com/fmtlib/format-benchmark/blob/master/digits10)\n  // but uses smaller tables.\n  // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)).\n  static constexpr uint8_t bsr2log10[] = {\n      1,  1,  1,  2,  2,  2,  3,  3,  3,  4,  4,  4,  4,  5,  5,  5,\n      6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  9,  9,  9,  10, 10, 10,\n      10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,\n      15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20};\n  auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63];\n  static constexpr uint64_t zero_or_powers_of_10[] = {\n      0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL),\n      10000000000000000000ULL};\n  return t - (n < zero_or_powers_of_10[t]);\n}\n#endif\n\n// Returns the number of decimal digits in n. Leading zeros are not counted\n// except for n == 0 in which case count_digits returns 1.\nFMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int {\n#ifdef FMT_BUILTIN_CLZLL\n  if (!is_constant_evaluated() && !FMT_OPTIMIZE_SIZE) return do_count_digits(n);\n#endif\n  return count_digits_fallback(n);\n}\n\n// Counts the number of digits in n. BITS = log2(radix).\ntemplate <int BITS, typename UInt>\nFMT_CONSTEXPR auto count_digits(UInt n) -> int {\n#ifdef FMT_BUILTIN_CLZ\n  if (!is_constant_evaluated() && num_bits<UInt>() == 32)\n    return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1;\n#endif\n  // Lambda avoids unreachable code warnings from NVHPC.\n  return [](UInt m) {\n    int num_digits = 0;\n    do {\n      ++num_digits;\n    } while ((m >>= BITS) != 0);\n    return num_digits;\n  }(n);\n}\n\n#ifdef FMT_BUILTIN_CLZ\n// It is a separate function rather than a part of count_digits to workaround\n// the lack of static constexpr in constexpr functions.\nFMT_INLINE auto do_count_digits(uint32_t n) -> int {\n// An optimization by Kendall Willets from https://bit.ly/3uOIQrB.\n// This increments the upper 32 bits (log10(T) - 1) when >= T is added.\n#  define FMT_INC(T) (((sizeof(#T) - 1ull) << 32) - T)\n  static constexpr uint64_t table[] = {\n      FMT_INC(0),          FMT_INC(0),          FMT_INC(0),           // 8\n      FMT_INC(10),         FMT_INC(10),         FMT_INC(10),          // 64\n      FMT_INC(100),        FMT_INC(100),        FMT_INC(100),         // 512\n      FMT_INC(1000),       FMT_INC(1000),       FMT_INC(1000),        // 4096\n      FMT_INC(10000),      FMT_INC(10000),      FMT_INC(10000),       // 32k\n      FMT_INC(100000),     FMT_INC(100000),     FMT_INC(100000),      // 256k\n      FMT_INC(1000000),    FMT_INC(1000000),    FMT_INC(1000000),     // 2048k\n      FMT_INC(10000000),   FMT_INC(10000000),   FMT_INC(10000000),    // 16M\n      FMT_INC(100000000),  FMT_INC(100000000),  FMT_INC(100000000),   // 128M\n      FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000),  // 1024M\n      FMT_INC(1000000000), FMT_INC(1000000000)                        // 4B\n  };\n  auto inc = table[FMT_BUILTIN_CLZ(n | 1) ^ 31];\n  return static_cast<int>((n + inc) >> 32);\n}\n#endif\n\n// Optional version of count_digits for better performance on 32-bit platforms.\nFMT_CONSTEXPR20 inline auto count_digits(uint32_t n) -> int {\n#ifdef FMT_BUILTIN_CLZ\n  if (!is_constant_evaluated() && !FMT_OPTIMIZE_SIZE) return do_count_digits(n);\n#endif\n  return count_digits_fallback(n);\n}\n\ntemplate <typename Int> constexpr auto digits10() noexcept -> int {\n  return std::numeric_limits<Int>::digits10;\n}\ntemplate <> constexpr auto digits10<int128_opt>() noexcept -> int { return 38; }\ntemplate <> constexpr auto digits10<uint128_t>() noexcept -> int { return 38; }\n\ntemplate <typename Char> struct thousands_sep_result {\n  std::string grouping;\n  Char thousands_sep;\n};\n\ntemplate <typename Char>\nFMT_API auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char>;\ntemplate <typename Char>\ninline auto thousands_sep(locale_ref loc) -> thousands_sep_result<Char> {\n  auto result = thousands_sep_impl<char>(loc);\n  return {result.grouping, Char(result.thousands_sep)};\n}\ntemplate <>\ninline auto thousands_sep(locale_ref loc) -> thousands_sep_result<wchar_t> {\n  return thousands_sep_impl<wchar_t>(loc);\n}\n\ntemplate <typename Char>\nFMT_API auto decimal_point_impl(locale_ref loc) -> Char;\ntemplate <typename Char> inline auto decimal_point(locale_ref loc) -> Char {\n  return Char(decimal_point_impl<char>(loc));\n}\ntemplate <> inline auto decimal_point(locale_ref loc) -> wchar_t {\n  return decimal_point_impl<wchar_t>(loc);\n}\n\n#ifndef FMT_HEADER_ONLY\nFMT_BEGIN_EXPORT\nextern template FMT_API auto thousands_sep_impl<char>(locale_ref)\n    -> thousands_sep_result<char>;\nextern template FMT_API auto thousands_sep_impl<wchar_t>(locale_ref)\n    -> thousands_sep_result<wchar_t>;\nextern template FMT_API auto decimal_point_impl(locale_ref) -> char;\nextern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;\nFMT_END_EXPORT\n#endif  // FMT_HEADER_ONLY\n\n// Compares two characters for equality.\ntemplate <typename Char> auto equal2(const Char* lhs, const char* rhs) -> bool {\n  return lhs[0] == Char(rhs[0]) && lhs[1] == Char(rhs[1]);\n}\ninline auto equal2(const char* lhs, const char* rhs) -> bool {\n  return memcmp(lhs, rhs, 2) == 0;\n}\n\n// Writes a two-digit value to out.\ntemplate <typename Char>\nFMT_CONSTEXPR20 FMT_INLINE void write2digits(Char* out, size_t value) {\n  if (!is_constant_evaluated() && std::is_same<Char, char>::value &&\n      !FMT_OPTIMIZE_SIZE) {\n    memcpy(out, digits2(value), 2);\n    return;\n  }\n  *out++ = static_cast<Char>('0' + value / 10);\n  *out = static_cast<Char>('0' + value % 10);\n}\n\n// Formats a decimal unsigned integer value writing to out pointing to a buffer\n// of specified size. The caller must ensure that the buffer is large enough.\ntemplate <typename Char, typename UInt>\nFMT_CONSTEXPR20 auto do_format_decimal(Char* out, UInt value, int size)\n    -> Char* {\n  FMT_ASSERT(size >= count_digits(value), \"invalid digit count\");\n  unsigned n = to_unsigned(size);\n  while (value >= 100) {\n    // Integer division is slow so do it for a group of two digits instead\n    // of for every digit. The idea comes from the talk by Alexandrescu\n    // \"Three Optimization Tips for C++\". See speed-test for a comparison.\n    n -= 2;\n    write2digits(out + n, static_cast<unsigned>(value % 100));\n    value /= 100;\n  }\n  if (value >= 10) {\n    n -= 2;\n    write2digits(out + n, static_cast<unsigned>(value));\n  } else {\n    out[--n] = static_cast<Char>('0' + value);\n  }\n  return out + n;\n}\n\ntemplate <typename Char, typename UInt>\nFMT_CONSTEXPR FMT_INLINE auto format_decimal(Char* out, UInt value,\n                                             int num_digits) -> Char* {\n  do_format_decimal(out, value, num_digits);\n  return out + num_digits;\n}\n\ntemplate <typename Char, typename UInt, typename OutputIt,\n          FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<OutputIt>>::value)>\nFMT_CONSTEXPR auto format_decimal(OutputIt out, UInt value, int num_digits)\n    -> OutputIt {\n  if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {\n    do_format_decimal(ptr, value, num_digits);\n    return out;\n  }\n  // Buffer is large enough to hold all digits (digits10 + 1).\n  char buffer[digits10<UInt>() + 1];\n  if (is_constant_evaluated()) fill_n(buffer, sizeof(buffer), '\\0');\n  do_format_decimal(buffer, value, num_digits);\n  return copy_noinline<Char>(buffer, buffer + num_digits, out);\n}\n\ntemplate <typename Char, typename UInt>\nFMT_CONSTEXPR auto do_format_base2e(int base_bits, Char* out, UInt value,\n                                    int size, bool upper = false) -> Char* {\n  out += size;\n  do {\n    const char* digits = upper ? \"0123456789ABCDEF\" : \"0123456789abcdef\";\n    unsigned digit = static_cast<unsigned>(value & ((1u << base_bits) - 1));\n    *--out = static_cast<Char>(base_bits < 4 ? static_cast<char>('0' + digit)\n                                             : digits[digit]);\n  } while ((value >>= base_bits) != 0);\n  return out;\n}\n\n// Formats an unsigned integer in the power of two base (binary, octal, hex).\ntemplate <typename Char, typename UInt>\nFMT_CONSTEXPR auto format_base2e(int base_bits, Char* out, UInt value,\n                                 int num_digits, bool upper = false) -> Char* {\n  do_format_base2e(base_bits, out, value, num_digits, upper);\n  return out + num_digits;\n}\n\ntemplate <typename Char, typename OutputIt, typename UInt,\n          FMT_ENABLE_IF(is_back_insert_iterator<OutputIt>::value)>\nFMT_CONSTEXPR inline auto format_base2e(int base_bits, OutputIt out, UInt value,\n                                        int num_digits, bool upper = false)\n    -> OutputIt {\n  if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {\n    format_base2e(base_bits, ptr, value, num_digits, upper);\n    return out;\n  }\n  // Make buffer large enough for any base.\n  char buffer[num_bits<UInt>()];\n  if (is_constant_evaluated()) fill_n(buffer, sizeof(buffer), '\\0');\n  format_base2e(base_bits, buffer, value, num_digits, upper);\n  return detail::copy_noinline<Char>(buffer, buffer + num_digits, out);\n}\n\n// A converter from UTF-8 to UTF-16.\nclass utf8_to_utf16 {\n private:\n  basic_memory_buffer<wchar_t> buffer_;\n\n public:\n  FMT_API explicit utf8_to_utf16(string_view s);\n  inline operator basic_string_view<wchar_t>() const {\n    return {&buffer_[0], size()};\n  }\n  inline auto size() const -> size_t { return buffer_.size() - 1; }\n  inline auto c_str() const -> const wchar_t* { return &buffer_[0]; }\n  inline auto str() const -> std::wstring { return {&buffer_[0], size()}; }\n};\n\nenum class to_utf8_error_policy { abort, replace };\n\n// A converter from UTF-16/UTF-32 (host endian) to UTF-8.\ntemplate <typename WChar, typename Buffer = memory_buffer> class to_utf8 {\n private:\n  Buffer buffer_;\n\n public:\n  to_utf8() {}\n  explicit to_utf8(basic_string_view<WChar> s,\n                   to_utf8_error_policy policy = to_utf8_error_policy::abort) {\n    static_assert(sizeof(WChar) == 2 || sizeof(WChar) == 4,\n                  \"expected utf16 or utf32\");\n    if (!convert(s, policy)) {\n      FMT_THROW(std::runtime_error(sizeof(WChar) == 2 ? \"invalid utf16\"\n                                                      : \"invalid utf32\"));\n    }\n  }\n  operator string_view() const { return string_view(&buffer_[0], size()); }\n  auto size() const -> size_t { return buffer_.size() - 1; }\n  auto c_str() const -> const char* { return &buffer_[0]; }\n  auto str() const -> std::string { return std::string(&buffer_[0], size()); }\n\n  // Performs conversion returning a bool instead of throwing exception on\n  // conversion error. This method may still throw in case of memory allocation\n  // error.\n  auto convert(basic_string_view<WChar> s,\n               to_utf8_error_policy policy = to_utf8_error_policy::abort)\n      -> bool {\n    if (!convert(buffer_, s, policy)) return false;\n    buffer_.push_back(0);\n    return true;\n  }\n  static auto convert(Buffer& buf, basic_string_view<WChar> s,\n                      to_utf8_error_policy policy = to_utf8_error_policy::abort)\n      -> bool {\n    for (auto p = s.begin(); p != s.end(); ++p) {\n      uint32_t c = static_cast<uint32_t>(*p);\n      if (sizeof(WChar) == 2 && c >= 0xd800 && c <= 0xdfff) {\n        // Handle a surrogate pair.\n        ++p;\n        if (p == s.end() || (c & 0xfc00) != 0xd800 || (*p & 0xfc00) != 0xdc00) {\n          if (policy == to_utf8_error_policy::abort) return false;\n          buf.append(string_view(\"\\xEF\\xBF\\xBD\"));\n          --p;\n          continue;\n        }\n        c = (c << 10) + static_cast<uint32_t>(*p) - 0x35fdc00;\n      }\n      if (c < 0x80) {\n        buf.push_back(static_cast<char>(c));\n      } else if (c < 0x800) {\n        buf.push_back(static_cast<char>(0xc0 | (c >> 6)));\n        buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));\n      } else if ((c >= 0x800 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xffff)) {\n        buf.push_back(static_cast<char>(0xe0 | (c >> 12)));\n        buf.push_back(static_cast<char>(0x80 | ((c & 0xfff) >> 6)));\n        buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));\n      } else if (c >= 0x10000 && c <= 0x10ffff) {\n        buf.push_back(static_cast<char>(0xf0 | (c >> 18)));\n        buf.push_back(static_cast<char>(0x80 | ((c & 0x3ffff) >> 12)));\n        buf.push_back(static_cast<char>(0x80 | ((c & 0xfff) >> 6)));\n        buf.push_back(static_cast<char>(0x80 | (c & 0x3f)));\n      } else {\n        return false;\n      }\n    }\n    return true;\n  }\n};\n\n// Computes 128-bit result of multiplication of two 64-bit unsigned integers.\nFMT_INLINE auto umul128(uint64_t x, uint64_t y) noexcept -> uint128_fallback {\n#if FMT_USE_INT128\n  auto p = static_cast<uint128_opt>(x) * static_cast<uint128_opt>(y);\n  return {static_cast<uint64_t>(p >> 64), static_cast<uint64_t>(p)};\n#elif defined(_MSC_VER) && defined(_M_X64)\n  auto hi = uint64_t();\n  auto lo = _umul128(x, y, &hi);\n  return {hi, lo};\n#else\n  const uint64_t mask = static_cast<uint64_t>(max_value<uint32_t>());\n\n  uint64_t a = x >> 32;\n  uint64_t b = x & mask;\n  uint64_t c = y >> 32;\n  uint64_t d = y & mask;\n\n  uint64_t ac = a * c;\n  uint64_t bc = b * c;\n  uint64_t ad = a * d;\n  uint64_t bd = b * d;\n\n  uint64_t intermediate = (bd >> 32) + (ad & mask) + (bc & mask);\n\n  return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32),\n          (intermediate << 32) + (bd & mask)};\n#endif\n}\n\nnamespace dragonbox {\n// Computes floor(log10(pow(2, e))) for e in [-2620, 2620] using the method from\n// https://fmt.dev/papers/Dragonbox.pdf#page=28, section 6.1.\ninline auto floor_log10_pow2(int e) noexcept -> int {\n  FMT_ASSERT(e <= 2620 && e >= -2620, \"too large exponent\");\n  static_assert((-1 >> 1) == -1, \"right shift is not arithmetic\");\n  return (e * 315653) >> 20;\n}\n\ninline auto floor_log2_pow10(int e) noexcept -> int {\n  FMT_ASSERT(e <= 1233 && e >= -1233, \"too large exponent\");\n  return (e * 1741647) >> 19;\n}\n\n// Computes upper 64 bits of multiplication of two 64-bit unsigned integers.\ninline auto umul128_upper64(uint64_t x, uint64_t y) noexcept -> uint64_t {\n#if FMT_USE_INT128\n  auto p = static_cast<uint128_opt>(x) * static_cast<uint128_opt>(y);\n  return static_cast<uint64_t>(p >> 64);\n#elif defined(_MSC_VER) && defined(_M_X64)\n  return __umulh(x, y);\n#else\n  return umul128(x, y).high();\n#endif\n}\n\n// Computes upper 128 bits of multiplication of a 64-bit unsigned integer and a\n// 128-bit unsigned integer.\ninline auto umul192_upper128(uint64_t x, uint128_fallback y) noexcept\n    -> uint128_fallback {\n  uint128_fallback r = umul128(x, y.high());\n  r += umul128_upper64(x, y.low());\n  return r;\n}\n\nFMT_API auto get_cached_power(int k) noexcept -> uint128_fallback;\n\n// Type-specific information that Dragonbox uses.\ntemplate <typename T, typename Enable = void> struct float_info;\n\ntemplate <> struct float_info<float> {\n  using carrier_uint = uint32_t;\n  static const int exponent_bits = 8;\n  static const int kappa = 1;\n  static const int big_divisor = 100;\n  static const int small_divisor = 10;\n  static const int min_k = -31;\n  static const int max_k = 46;\n  static const int shorter_interval_tie_lower_threshold = -35;\n  static const int shorter_interval_tie_upper_threshold = -35;\n};\n\ntemplate <> struct float_info<double> {\n  using carrier_uint = uint64_t;\n  static const int exponent_bits = 11;\n  static const int kappa = 2;\n  static const int big_divisor = 1000;\n  static const int small_divisor = 100;\n  static const int min_k = -292;\n  static const int max_k = 341;\n  static const int shorter_interval_tie_lower_threshold = -77;\n  static const int shorter_interval_tie_upper_threshold = -77;\n};\n\n// An 80- or 128-bit floating point number.\ntemplate <typename T>\nstruct float_info<T, enable_if_t<std::numeric_limits<T>::digits == 64 ||\n                                 std::numeric_limits<T>::digits == 113 ||\n                                 is_float128<T>::value>> {\n  using carrier_uint = detail::uint128_t;\n  static const int exponent_bits = 15;\n};\n\n// A double-double floating point number.\ntemplate <typename T>\nstruct float_info<T, enable_if_t<is_double_double<T>::value>> {\n  using carrier_uint = detail::uint128_t;\n};\n\ntemplate <typename T> struct decimal_fp {\n  using significand_type = typename float_info<T>::carrier_uint;\n  significand_type significand;\n  int exponent;\n};\n\ntemplate <typename T> FMT_API auto to_decimal(T x) noexcept -> decimal_fp<T>;\n}  // namespace dragonbox\n\n// Returns true iff Float has the implicit bit which is not stored.\ntemplate <typename Float> constexpr auto has_implicit_bit() -> bool {\n  // An 80-bit FP number has a 64-bit significand an no implicit bit.\n  return std::numeric_limits<Float>::digits != 64;\n}\n\n// Returns the number of significand bits stored in Float. The implicit bit is\n// not counted since it is not stored.\ntemplate <typename Float> constexpr auto num_significand_bits() -> int {\n  // std::numeric_limits may not support __float128.\n  return is_float128<Float>() ? 112\n                              : (std::numeric_limits<Float>::digits -\n                                 (has_implicit_bit<Float>() ? 1 : 0));\n}\n\ntemplate <typename Float>\nconstexpr auto exponent_mask() ->\n    typename dragonbox::float_info<Float>::carrier_uint {\n  using float_uint = typename dragonbox::float_info<Float>::carrier_uint;\n  return ((float_uint(1) << dragonbox::float_info<Float>::exponent_bits) - 1)\n         << num_significand_bits<Float>();\n}\ntemplate <typename Float> constexpr auto exponent_bias() -> int {\n  // std::numeric_limits may not support __float128.\n  return is_float128<Float>() ? 16383\n                              : std::numeric_limits<Float>::max_exponent - 1;\n}\n\nFMT_CONSTEXPR inline auto compute_exp_size(int exp) -> int {\n  auto prefix_size = 2;  // sign + 'e'\n  auto abs_exp = exp >= 0 ? exp : -exp;\n  if (abs_exp < 100) return prefix_size + 2;\n  return prefix_size + (abs_exp >= 1000 ? 4 : 3);\n}\n\n// Writes the exponent exp in the form \"[+-]d{2,3}\" to buffer.\ntemplate <typename Char, typename OutputIt>\nFMT_CONSTEXPR auto write_exponent(int exp, OutputIt out) -> OutputIt {\n  FMT_ASSERT(-10000 < exp && exp < 10000, \"exponent out of range\");\n  if (exp < 0) {\n    *out++ = static_cast<Char>('-');\n    exp = -exp;\n  } else {\n    *out++ = static_cast<Char>('+');\n  }\n  auto uexp = static_cast<uint32_t>(exp);\n  if (is_constant_evaluated()) {\n    if (uexp < 10) *out++ = '0';\n    return format_decimal<Char>(out, uexp, count_digits(uexp));\n  }\n  if (uexp >= 100u) {\n    const char* top = digits2(uexp / 100);\n    if (uexp >= 1000u) *out++ = static_cast<Char>(top[0]);\n    *out++ = static_cast<Char>(top[1]);\n    uexp %= 100;\n  }\n  const char* d = digits2(uexp);\n  *out++ = static_cast<Char>(d[0]);\n  *out++ = static_cast<Char>(d[1]);\n  return out;\n}\n\n// A floating-point number f * pow(2, e) where F is an unsigned type.\ntemplate <typename F> struct basic_fp {\n  F f;\n  int e;\n\n  static constexpr int num_significand_bits =\n      static_cast<int>(sizeof(F) * num_bits<unsigned char>());\n\n  constexpr basic_fp() : f(0), e(0) {}\n  constexpr basic_fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {}\n\n  // Constructs fp from an IEEE754 floating-point number.\n  template <typename Float> FMT_CONSTEXPR basic_fp(Float n) { assign(n); }\n\n  // Assigns n to this and return true iff predecessor is closer than successor.\n  template <typename Float, FMT_ENABLE_IF(!is_double_double<Float>::value)>\n  FMT_CONSTEXPR auto assign(Float n) -> bool {\n    static_assert(std::numeric_limits<Float>::digits <= 113, \"unsupported FP\");\n    // Assume Float is in the format [sign][exponent][significand].\n    using carrier_uint = typename dragonbox::float_info<Float>::carrier_uint;\n    const auto num_float_significand_bits =\n        detail::num_significand_bits<Float>();\n    const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;\n    const auto significand_mask = implicit_bit - 1;\n    auto u = bit_cast<carrier_uint>(n);\n    f = static_cast<F>(u & significand_mask);\n    auto biased_e = static_cast<int>((u & exponent_mask<Float>()) >>\n                                     num_float_significand_bits);\n    // The predecessor is closer if n is a normalized power of 2 (f == 0)\n    // other than the smallest normalized number (biased_e > 1).\n    auto is_predecessor_closer = f == 0 && biased_e > 1;\n    if (biased_e == 0)\n      biased_e = 1;  // Subnormals use biased exponent 1 (min exponent).\n    else if (has_implicit_bit<Float>())\n      f += static_cast<F>(implicit_bit);\n    e = biased_e - exponent_bias<Float>() - num_float_significand_bits;\n    if (!has_implicit_bit<Float>()) ++e;\n    return is_predecessor_closer;\n  }\n\n  template <typename Float, FMT_ENABLE_IF(is_double_double<Float>::value)>\n  FMT_CONSTEXPR auto assign(Float n) -> bool {\n    static_assert(std::numeric_limits<double>::is_iec559, \"unsupported FP\");\n    return assign(static_cast<double>(n));\n  }\n};\n\nusing fp = basic_fp<unsigned long long>;\n\n// Normalizes the value converted from double and multiplied by (1 << SHIFT).\ntemplate <int SHIFT = 0, typename F>\nFMT_CONSTEXPR auto normalize(basic_fp<F> value) -> basic_fp<F> {\n  // Handle subnormals.\n  const auto implicit_bit = F(1) << num_significand_bits<double>();\n  const auto shifted_implicit_bit = implicit_bit << SHIFT;\n  while ((value.f & shifted_implicit_bit) == 0) {\n    value.f <<= 1;\n    --value.e;\n  }\n  // Subtract 1 to account for hidden bit.\n  const auto offset = basic_fp<F>::num_significand_bits -\n                      num_significand_bits<double>() - SHIFT - 1;\n  value.f <<= offset;\n  value.e -= offset;\n  return value;\n}\n\n// Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking.\nFMT_CONSTEXPR inline auto multiply(uint64_t lhs, uint64_t rhs) -> uint64_t {\n#if FMT_USE_INT128\n  auto product = static_cast<__uint128_t>(lhs) * rhs;\n  auto f = static_cast<uint64_t>(product >> 64);\n  return (static_cast<uint64_t>(product) & (1ULL << 63)) != 0 ? f + 1 : f;\n#else\n  // Multiply 32-bit parts of significands.\n  uint64_t mask = (1ULL << 32) - 1;\n  uint64_t a = lhs >> 32, b = lhs & mask;\n  uint64_t c = rhs >> 32, d = rhs & mask;\n  uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d;\n  // Compute mid 64-bit of result and round.\n  uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);\n  return ac + (ad >> 32) + (bc >> 32) + (mid >> 32);\n#endif\n}\n\nFMT_CONSTEXPR inline auto operator*(fp x, fp y) -> fp {\n  return {multiply(x.f, y.f), x.e + y.e + 64};\n}\n\ntemplate <typename T, bool doublish = num_bits<T>() == num_bits<double>()>\nusing convert_float_result =\n    conditional_t<std::is_same<T, float>::value || doublish, double, T>;\n\ntemplate <typename T>\nconstexpr auto convert_float(T value) -> convert_float_result<T> {\n  return static_cast<convert_float_result<T>>(value);\n}\n\ntemplate <bool C, typename T, typename F, FMT_ENABLE_IF(C)>\nauto select(T true_value, F) -> T {\n  return true_value;\n}\ntemplate <bool C, typename T, typename F, FMT_ENABLE_IF(!C)>\nauto select(T, F false_value) -> F {\n  return false_value;\n}\n\ntemplate <typename Char, typename OutputIt>\nFMT_CONSTEXPR FMT_NOINLINE auto fill(OutputIt it, size_t n,\n                                     const basic_specs& specs) -> OutputIt {\n  auto fill_size = specs.fill_size();\n  if (fill_size == 1) return detail::fill_n(it, n, specs.fill_unit<Char>());\n  if (const Char* data = specs.fill<Char>()) {\n    for (size_t i = 0; i < n; ++i) it = copy<Char>(data, data + fill_size, it);\n  }\n  return it;\n}\n\n// Writes the output of f, padded according to format specifications in specs.\n// size: output size in code units.\n// width: output display width in (terminal) column positions.\ntemplate <typename Char, align default_align = align::left, typename OutputIt,\n          typename F>\nFMT_CONSTEXPR auto write_padded(OutputIt out, const format_specs& specs,\n                                size_t size, size_t width, F&& f) -> OutputIt {\n  static_assert(default_align == align::left || default_align == align::right,\n                \"\");\n  unsigned spec_width = to_unsigned(specs.width);\n  size_t padding = spec_width > width ? spec_width - width : 0;\n  // Shifts are encoded as string literals because static constexpr is not\n  // supported in constexpr functions.\n  auto* shifts =\n      default_align == align::left ? \"\\x1f\\x1f\\x00\\x01\" : \"\\x00\\x1f\\x00\\x01\";\n  size_t left_padding = padding >> shifts[static_cast<int>(specs.align())];\n  size_t right_padding = padding - left_padding;\n  auto it = reserve(out, size + padding * specs.fill_size());\n  if (left_padding != 0) it = fill<Char>(it, left_padding, specs);\n  it = f(it);\n  if (right_padding != 0) it = fill<Char>(it, right_padding, specs);\n  return base_iterator(out, it);\n}\n\ntemplate <typename Char, align default_align = align::left, typename OutputIt,\n          typename F>\nconstexpr auto write_padded(OutputIt out, const format_specs& specs,\n                            size_t size, F&& f) -> OutputIt {\n  return write_padded<Char, default_align>(out, specs, size, size, f);\n}\n\ntemplate <typename Char, align default_align = align::left, typename OutputIt>\nFMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes,\n                               const format_specs& specs = {}) -> OutputIt {\n  return write_padded<Char, default_align>(\n      out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {\n        const char* data = bytes.data();\n        return copy<Char>(data, data + bytes.size(), it);\n      });\n}\n\ntemplate <typename Char, typename OutputIt, typename UIntPtr>\nauto write_ptr(OutputIt out, UIntPtr value, const format_specs* specs)\n    -> OutputIt {\n  int num_digits = count_digits<4>(value);\n  auto size = to_unsigned(num_digits) + size_t(2);\n  auto write = [=](reserve_iterator<OutputIt> it) {\n    *it++ = static_cast<Char>('0');\n    *it++ = static_cast<Char>('x');\n    return format_base2e<Char>(4, it, value, num_digits);\n  };\n  return specs ? write_padded<Char, align::right>(out, *specs, size, write)\n               : base_iterator(out, write(reserve(out, size)));\n}\n\n// Returns true iff the code point cp is printable.\nFMT_API auto is_printable(uint32_t cp) -> bool;\n\ninline auto needs_escape(uint32_t cp) -> bool {\n  if (cp < 0x20 || cp == 0x7f || cp == '\"' || cp == '\\\\') return true;\n  if (const_check(FMT_OPTIMIZE_SIZE > 1)) return false;\n  return !is_printable(cp);\n}\n\ntemplate <typename Char> struct find_escape_result {\n  const Char* begin;\n  const Char* end;\n  uint32_t cp;\n};\n\ntemplate <typename Char>\nauto find_escape(const Char* begin, const Char* end)\n    -> find_escape_result<Char> {\n  for (; begin != end; ++begin) {\n    uint32_t cp = static_cast<unsigned_char<Char>>(*begin);\n    if (const_check(sizeof(Char) == 1) && cp >= 0x80) continue;\n    if (needs_escape(cp)) return {begin, begin + 1, cp};\n  }\n  return {begin, nullptr, 0};\n}\n\ninline auto find_escape(const char* begin, const char* end)\n    -> find_escape_result<char> {\n  if (const_check(!use_utf8)) return find_escape<char>(begin, end);\n  auto result = find_escape_result<char>{end, nullptr, 0};\n  for_each_codepoint(string_view(begin, to_unsigned(end - begin)),\n                     [&](uint32_t cp, string_view sv) {\n                       if (needs_escape(cp)) {\n                         result = {sv.begin(), sv.end(), cp};\n                         return false;\n                       }\n                       return true;\n                     });\n  return result;\n}\n\ntemplate <size_t width, typename Char, typename OutputIt>\nauto write_codepoint(OutputIt out, char prefix, uint32_t cp) -> OutputIt {\n  *out++ = static_cast<Char>('\\\\');\n  *out++ = static_cast<Char>(prefix);\n  Char buf[width];\n  fill_n(buf, width, static_cast<Char>('0'));\n  format_base2e(4, buf, cp, width);\n  return copy<Char>(buf, buf + width, out);\n}\n\ntemplate <typename OutputIt, typename Char>\nauto write_escaped_cp(OutputIt out, const find_escape_result<Char>& escape)\n    -> OutputIt {\n  auto c = static_cast<Char>(escape.cp);\n  switch (escape.cp) {\n  case '\\n':\n    *out++ = static_cast<Char>('\\\\');\n    c = static_cast<Char>('n');\n    break;\n  case '\\r':\n    *out++ = static_cast<Char>('\\\\');\n    c = static_cast<Char>('r');\n    break;\n  case '\\t':\n    *out++ = static_cast<Char>('\\\\');\n    c = static_cast<Char>('t');\n    break;\n  case '\"':  FMT_FALLTHROUGH;\n  case '\\'': FMT_FALLTHROUGH;\n  case '\\\\': *out++ = static_cast<Char>('\\\\'); break;\n  default:\n    if (escape.cp < 0x100) return write_codepoint<2, Char>(out, 'x', escape.cp);\n    if (escape.cp < 0x10000)\n      return write_codepoint<4, Char>(out, 'u', escape.cp);\n    if (escape.cp < 0x110000)\n      return write_codepoint<8, Char>(out, 'U', escape.cp);\n    for (Char escape_char : basic_string_view<Char>(\n             escape.begin, to_unsigned(escape.end - escape.begin))) {\n      out = write_codepoint<2, Char>(out, 'x',\n                                     static_cast<uint32_t>(escape_char) & 0xFF);\n    }\n    return out;\n  }\n  *out++ = c;\n  return out;\n}\n\ntemplate <typename Char, typename OutputIt>\nauto write_escaped_string(OutputIt out, basic_string_view<Char> str)\n    -> OutputIt {\n  *out++ = static_cast<Char>('\"');\n  auto begin = str.begin(), end = str.end();\n  do {\n    auto escape = find_escape(begin, end);\n    out = copy<Char>(begin, escape.begin, out);\n    begin = escape.end;\n    if (!begin) break;\n    out = write_escaped_cp<OutputIt, Char>(out, escape);\n  } while (begin != end);\n  *out++ = static_cast<Char>('\"');\n  return out;\n}\n\ntemplate <typename Char, typename OutputIt>\nauto write_escaped_char(OutputIt out, Char v) -> OutputIt {\n  Char v_array[1] = {v};\n  *out++ = static_cast<Char>('\\'');\n  if ((needs_escape(static_cast<uint32_t>(v)) && v != static_cast<Char>('\"')) ||\n      v == static_cast<Char>('\\'')) {\n    out = write_escaped_cp(out,\n                           find_escape_result<Char>{v_array, v_array + 1,\n                                                    static_cast<uint32_t>(v)});\n  } else {\n    *out++ = v;\n  }\n  *out++ = static_cast<Char>('\\'');\n  return out;\n}\n\ntemplate <typename Char, typename OutputIt>\nFMT_CONSTEXPR auto write_char(OutputIt out, Char value,\n                              const format_specs& specs) -> OutputIt {\n  bool is_debug = specs.type() == presentation_type::debug;\n  return write_padded<Char>(out, specs, 1, [=](reserve_iterator<OutputIt> it) {\n    if (is_debug) return write_escaped_char(it, value);\n    *it++ = value;\n    return it;\n  });\n}\n\ntemplate <typename Char> class digit_grouping {\n private:\n  std::string grouping_;\n  std::basic_string<Char> thousands_sep_;\n\n  struct next_state {\n    std::string::const_iterator group;\n    int pos;\n  };\n  auto initial_state() const -> next_state { return {grouping_.begin(), 0}; }\n\n  // Returns the next digit group separator position.\n  auto next(next_state& state) const -> int {\n    if (thousands_sep_.empty()) return max_value<int>();\n    if (state.group == grouping_.end()) return state.pos += grouping_.back();\n    if (*state.group <= 0 || *state.group == max_value<char>())\n      return max_value<int>();\n    state.pos += *state.group++;\n    return state.pos;\n  }\n\n public:\n  explicit digit_grouping(locale_ref loc, bool localized = true) {\n    if (!localized) return;\n    auto sep = thousands_sep<Char>(loc);\n    grouping_ = sep.grouping;\n    if (sep.thousands_sep) thousands_sep_.assign(1, sep.thousands_sep);\n  }\n  digit_grouping(std::string grouping, std::basic_string<Char> sep)\n      : grouping_(std::move(grouping)), thousands_sep_(std::move(sep)) {}\n\n  auto has_separator() const -> bool { return !thousands_sep_.empty(); }\n\n  auto count_separators(int num_digits) const -> int {\n    int count = 0;\n    auto state = initial_state();\n    while (num_digits > next(state)) ++count;\n    return count;\n  }\n\n  // Applies grouping to digits and writes the output to out.\n  template <typename Out, typename C>\n  auto apply(Out out, basic_string_view<C> digits) const -> Out {\n    auto num_digits = static_cast<int>(digits.size());\n    auto separators = basic_memory_buffer<int>();\n    separators.push_back(0);\n    auto state = initial_state();\n    while (int i = next(state)) {\n      if (i >= num_digits) break;\n      separators.push_back(i);\n    }\n    for (int i = 0, sep_index = static_cast<int>(separators.size() - 1);\n         i < num_digits; ++i) {\n      if (num_digits - i == separators[sep_index]) {\n        out = copy<Char>(thousands_sep_.data(),\n                         thousands_sep_.data() + thousands_sep_.size(), out);\n        --sep_index;\n      }\n      *out++ = static_cast<Char>(digits[to_unsigned(i)]);\n    }\n    return out;\n  }\n};\n\nFMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) {\n  prefix |= prefix != 0 ? value << 8 : value;\n  prefix += (1u + (value > 0xff ? 1 : 0)) << 24;\n}\n\n// Writes a decimal integer with digit grouping.\ntemplate <typename OutputIt, typename UInt, typename Char>\nauto write_int(OutputIt out, UInt value, unsigned prefix,\n               const format_specs& specs, const digit_grouping<Char>& grouping)\n    -> OutputIt {\n  static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, \"\");\n  int num_digits = 0;\n  auto buffer = memory_buffer();\n  switch (specs.type()) {\n  default: FMT_ASSERT(false, \"\"); FMT_FALLTHROUGH;\n  case presentation_type::none:\n  case presentation_type::dec:\n    num_digits = count_digits(value);\n    format_decimal<char>(appender(buffer), value, num_digits);\n    break;\n  case presentation_type::hex:\n    if (specs.alt())\n      prefix_append(prefix, unsigned(specs.upper() ? 'X' : 'x') << 8 | '0');\n    num_digits = count_digits<4>(value);\n    format_base2e<char>(4, appender(buffer), value, num_digits, specs.upper());\n    break;\n  case presentation_type::oct:\n    num_digits = count_digits<3>(value);\n    // Octal prefix '0' is counted as a digit, so only add it if precision\n    // is not greater than the number of digits.\n    if (specs.alt() && specs.precision <= num_digits && value != 0)\n      prefix_append(prefix, '0');\n    format_base2e<char>(3, appender(buffer), value, num_digits);\n    break;\n  case presentation_type::bin:\n    if (specs.alt())\n      prefix_append(prefix, unsigned(specs.upper() ? 'B' : 'b') << 8 | '0');\n    num_digits = count_digits<1>(value);\n    format_base2e<char>(1, appender(buffer), value, num_digits);\n    break;\n  case presentation_type::chr:\n    return write_char<Char>(out, static_cast<Char>(value), specs);\n  }\n\n  unsigned size = (prefix != 0 ? prefix >> 24 : 0) + to_unsigned(num_digits) +\n                  to_unsigned(grouping.count_separators(num_digits));\n  return write_padded<Char, align::right>(\n      out, specs, size, size, [&](reserve_iterator<OutputIt> it) {\n        for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)\n          *it++ = static_cast<Char>(p & 0xff);\n        return grouping.apply(it, string_view(buffer.data(), buffer.size()));\n      });\n}\n\n#if FMT_USE_LOCALE\n// Writes a localized value.\nFMT_API auto write_loc(appender out, loc_value value, const format_specs& specs,\n                       locale_ref loc) -> bool;\nauto write_loc(basic_appender<wchar_t> out, loc_value value,\n               const format_specs& specs, locale_ref loc) -> bool;\n#endif\ntemplate <typename OutputIt>\ninline auto write_loc(OutputIt, const loc_value&, const format_specs&,\n                      locale_ref) -> bool {\n  return false;\n}\n\ntemplate <typename UInt> struct write_int_arg {\n  UInt abs_value;\n  unsigned prefix;\n};\n\ntemplate <typename T>\nFMT_CONSTEXPR auto make_write_int_arg(T value, sign s)\n    -> write_int_arg<uint32_or_64_or_128_t<T>> {\n  auto prefix = 0u;\n  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);\n  if (is_negative(value)) {\n    prefix = 0x01000000 | '-';\n    abs_value = 0 - abs_value;\n  } else {\n    constexpr unsigned prefixes[4] = {0, 0, 0x1000000u | '+', 0x1000000u | ' '};\n    prefix = prefixes[static_cast<int>(s)];\n  }\n  return {abs_value, prefix};\n}\n\ntemplate <typename Char = char> struct loc_writer {\n  basic_appender<Char> out;\n  const format_specs& specs;\n  std::basic_string<Char> sep;\n  std::string grouping;\n  std::basic_string<Char> decimal_point;\n\n  template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>\n  auto operator()(T value) -> bool {\n    auto arg = make_write_int_arg(value, specs.sign());\n    write_int(out, static_cast<uint64_or_128_t<T>>(arg.abs_value), arg.prefix,\n              specs, digit_grouping<Char>(grouping, sep));\n    return true;\n  }\n\n  template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>\n  auto operator()(T) -> bool {\n    return false;\n  }\n};\n\n// Size and padding computation separate from write_int to avoid template bloat.\nstruct size_padding {\n  unsigned size;\n  unsigned padding;\n\n  FMT_CONSTEXPR size_padding(int num_digits, unsigned prefix,\n                             const format_specs& specs)\n      : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) {\n    if (specs.align() == align::numeric) {\n      auto width = to_unsigned(specs.width);\n      if (width > size) {\n        padding = width - size;\n        size = width;\n      }\n    } else if (specs.precision > num_digits) {\n      size = (prefix >> 24) + to_unsigned(specs.precision);\n      padding = to_unsigned(specs.precision - num_digits);\n    }\n  }\n};\n\ntemplate <typename Char, typename OutputIt, typename T>\nFMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg,\n                                        const format_specs& specs) -> OutputIt {\n  static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, \"\");\n\n  constexpr size_t buffer_size = num_bits<T>();\n  char buffer[buffer_size];\n  if (is_constant_evaluated()) fill_n(buffer, buffer_size, '\\0');\n  const char* begin = nullptr;\n  const char* end = buffer + buffer_size;\n\n  auto abs_value = arg.abs_value;\n  auto prefix = arg.prefix;\n  switch (specs.type()) {\n  default: FMT_ASSERT(false, \"\"); FMT_FALLTHROUGH;\n  case presentation_type::none:\n  case presentation_type::dec:\n    begin = do_format_decimal(buffer, abs_value, buffer_size);\n    break;\n  case presentation_type::hex:\n    begin = do_format_base2e(4, buffer, abs_value, buffer_size, specs.upper());\n    if (specs.alt())\n      prefix_append(prefix, unsigned(specs.upper() ? 'X' : 'x') << 8 | '0');\n    break;\n  case presentation_type::oct: {\n    begin = do_format_base2e(3, buffer, abs_value, buffer_size);\n    // Octal prefix '0' is counted as a digit, so only add it if precision\n    // is not greater than the number of digits.\n    auto num_digits = end - begin;\n    if (specs.alt() && specs.precision <= num_digits && abs_value != 0)\n      prefix_append(prefix, '0');\n    break;\n  }\n  case presentation_type::bin:\n    begin = do_format_base2e(1, buffer, abs_value, buffer_size);\n    if (specs.alt())\n      prefix_append(prefix, unsigned(specs.upper() ? 'B' : 'b') << 8 | '0');\n    break;\n  case presentation_type::chr:\n    return write_char<Char>(out, static_cast<Char>(abs_value), specs);\n  }\n\n  // Write an integer in the format\n  //   <left-padding><prefix><numeric-padding><digits><right-padding>\n  // prefix contains chars in three lower bytes and the size in the fourth byte.\n  int num_digits = static_cast<int>(end - begin);\n  // Slightly faster check for specs.width == 0 && specs.precision == -1.\n  if ((specs.width | (specs.precision + 1)) == 0) {\n    auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24));\n    for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)\n      *it++ = static_cast<Char>(p & 0xff);\n    return base_iterator(out, copy<Char>(begin, end, it));\n  }\n  auto sp = size_padding(num_digits, prefix, specs);\n  unsigned padding = sp.padding;\n  return write_padded<Char, align::right>(\n      out, specs, sp.size, [=](reserve_iterator<OutputIt> it) {\n        for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)\n          *it++ = static_cast<Char>(p & 0xff);\n        it = detail::fill_n(it, padding, static_cast<Char>('0'));\n        return copy<Char>(begin, end, it);\n      });\n}\n\ntemplate <typename Char, typename OutputIt, typename T>\nFMT_CONSTEXPR FMT_NOINLINE auto write_int_noinline(OutputIt out,\n                                                   write_int_arg<T> arg,\n                                                   const format_specs& specs)\n    -> OutputIt {\n  return write_int<Char>(out, arg, specs);\n}\n\ntemplate <typename Char, typename T,\n          FMT_ENABLE_IF(is_integral<T>::value &&\n                        !std::is_same<T, bool>::value &&\n                        !std::is_same<T, Char>::value)>\nFMT_CONSTEXPR FMT_INLINE auto write(basic_appender<Char> out, T value,\n                                    const format_specs& specs, locale_ref loc)\n    -> basic_appender<Char> {\n  if (specs.localized() && write_loc(out, value, specs, loc)) return out;\n  return write_int_noinline<Char>(out, make_write_int_arg(value, specs.sign()),\n                                  specs);\n}\n\n// An inlined version of write used in format string compilation.\ntemplate <typename Char, typename OutputIt, typename T,\n          FMT_ENABLE_IF(is_integral<T>::value &&\n                        !std::is_same<T, bool>::value &&\n                        !std::is_same<T, Char>::value &&\n                        !std::is_same<OutputIt, basic_appender<Char>>::value)>\nFMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,\n                                    const format_specs& specs, locale_ref loc)\n    -> OutputIt {\n  if (specs.localized() && write_loc(out, value, specs, loc)) return out;\n  return write_int<Char>(out, make_write_int_arg(value, specs.sign()), specs);\n}\n\ntemplate <typename Char, typename OutputIt>\nFMT_CONSTEXPR auto write(OutputIt out, Char value, const format_specs& specs,\n                         locale_ref loc = {}) -> OutputIt {\n  // char is formatted as unsigned char for consistency across platforms.\n  using unsigned_type =\n      conditional_t<std::is_same<Char, char>::value, unsigned char, unsigned>;\n  return check_char_specs(specs)\n             ? write_char<Char>(out, value, specs)\n             : write<Char>(out, static_cast<unsigned_type>(value), specs, loc);\n}\n\ntemplate <typename Char, typename OutputIt,\n          FMT_ENABLE_IF(std::is_same<Char, char>::value)>\nFMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,\n                         const format_specs& specs) -> OutputIt {\n  bool is_debug = specs.type() == presentation_type::debug;\n  if (specs.precision < 0 && specs.width == 0) {\n    auto&& it = reserve(out, s.size());\n    return is_debug ? write_escaped_string(it, s) : copy<char>(s, it);\n  }\n\n  size_t display_width_limit =\n      specs.precision < 0 ? SIZE_MAX : to_unsigned(specs.precision);\n  size_t display_width =\n      !is_debug || specs.precision == 0 ? 0 : 1;  // Account for opening '\"'.\n  size_t size = !is_debug || specs.precision == 0 ? 0 : 1;\n  for_each_codepoint(s, [&](uint32_t cp, string_view sv) {\n    if (is_debug && needs_escape(cp)) {\n      counting_buffer<char> buf;\n      write_escaped_cp(basic_appender<char>(buf),\n                       find_escape_result<char>{sv.begin(), sv.end(), cp});\n      // We're reinterpreting bytes as display width. That's okay\n      // because write_escaped_cp() only writes ASCII characters.\n      size_t cp_width = buf.count();\n      if (display_width + cp_width <= display_width_limit) {\n        display_width += cp_width;\n        size += cp_width;\n        // If this is the end of the string, account for closing '\"'.\n        if (display_width < display_width_limit && sv.end() == s.end()) {\n          ++display_width;\n          ++size;\n        }\n        return true;\n      }\n\n      size += display_width_limit - display_width;\n      display_width = display_width_limit;\n      return false;\n    }\n\n    size_t cp_width = display_width_of(cp);\n    if (cp_width + display_width <= display_width_limit) {\n      display_width += cp_width;\n      size += sv.size();\n      // If this is the end of the string, account for closing '\"'.\n      if (is_debug && display_width < display_width_limit &&\n          sv.end() == s.end()) {\n        ++display_width;\n        ++size;\n      }\n      return true;\n    }\n\n    return false;\n  });\n\n  struct bounded_output_iterator {\n    reserve_iterator<OutputIt> underlying_iterator;\n    size_t bound;\n\n    FMT_CONSTEXPR auto operator*() -> bounded_output_iterator& { return *this; }\n    FMT_CONSTEXPR auto operator++() -> bounded_output_iterator& {\n      return *this;\n    }\n    FMT_CONSTEXPR auto operator++(int) -> bounded_output_iterator& {\n      return *this;\n    }\n    FMT_CONSTEXPR auto operator=(char c) -> bounded_output_iterator& {\n      if (bound > 0) {\n        *underlying_iterator++ = c;\n        --bound;\n      }\n      return *this;\n    }\n  };\n\n  return write_padded<char>(\n      out, specs, size, display_width, [=](reserve_iterator<OutputIt> it) {\n        return is_debug\n                   ? write_escaped_string(bounded_output_iterator{it, size}, s)\n                         .underlying_iterator\n                   : copy<char>(s.data(), s.data() + size, it);\n      });\n}\n\ntemplate <typename Char, typename OutputIt,\n          FMT_ENABLE_IF(!std::is_same<Char, char>::value)>\nFMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,\n                         const format_specs& specs) -> OutputIt {\n  auto data = s.data();\n  auto size = s.size();\n  if (specs.precision >= 0 && to_unsigned(specs.precision) < size)\n    size = to_unsigned(specs.precision);\n\n  bool is_debug = specs.type() == presentation_type::debug;\n  if (is_debug) {\n    auto buf = counting_buffer<Char>();\n    write_escaped_string(basic_appender<Char>(buf), s);\n    size = buf.count();\n  }\n\n  return write_padded<Char>(\n      out, specs, size, [=](reserve_iterator<OutputIt> it) {\n        return is_debug ? write_escaped_string(it, s)\n                        : copy<Char>(data, data + size, it);\n      });\n}\n\ntemplate <typename Char, typename OutputIt>\nFMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,\n                         const format_specs& specs, locale_ref) -> OutputIt {\n  return write<Char>(out, s, specs);\n}\n\ntemplate <typename Char, typename OutputIt>\nFMT_CONSTEXPR auto write(OutputIt out, const Char* s, const format_specs& specs,\n                         locale_ref) -> OutputIt {\n  if (specs.type() == presentation_type::pointer)\n    return write_ptr<Char>(out, bit_cast<uintptr_t>(s), &specs);\n  if (!s) report_error(\"string pointer is null\");\n  return write<Char>(out, basic_string_view<Char>(s), specs, {});\n}\n\ntemplate <typename Char, typename OutputIt, typename T,\n          FMT_ENABLE_IF(is_integral<T>::value &&\n                        !std::is_same<T, bool>::value &&\n                        !std::is_same<T, Char>::value)>\nFMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {\n  auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);\n  bool negative = is_negative(value);\n  // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.\n  if (negative) abs_value = ~abs_value + 1;\n  int num_digits = count_digits(abs_value);\n  auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);\n  if (auto ptr = to_pointer<Char>(out, size)) {\n    if (negative) *ptr++ = static_cast<Char>('-');\n    format_decimal<Char>(ptr, abs_value, num_digits);\n    return out;\n  }\n  if (negative) *out++ = static_cast<Char>('-');\n  return format_decimal<Char>(out, abs_value, num_digits);\n}\n\ntemplate <typename Char>\nFMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end,\n                               format_specs& specs) -> const Char* {\n  FMT_ASSERT(begin != end, \"\");\n  auto alignment = align::none;\n  auto p = begin + code_point_length(begin);\n  if (end - p <= 0) p = begin;\n  for (;;) {\n    switch (to_ascii(*p)) {\n    case '<': alignment = align::left; break;\n    case '>': alignment = align::right; break;\n    case '^': alignment = align::center; break;\n    }\n    if (alignment != align::none) {\n      if (p != begin) {\n        auto c = *begin;\n        if (c == '}') return begin;\n        if (c == '{') {\n          report_error(\"invalid fill character '{'\");\n          return begin;\n        }\n        specs.set_fill(basic_string_view<Char>(begin, to_unsigned(p - begin)));\n        begin = p + 1;\n      } else {\n        ++begin;\n      }\n      break;\n    } else if (p == begin) {\n      break;\n    }\n    p = begin;\n  }\n  specs.set_align(alignment);\n  return begin;\n}\n\ntemplate <typename Char, typename OutputIt>\nFMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan,\n                                     format_specs specs, sign s) -> OutputIt {\n  auto str =\n      isnan ? (specs.upper() ? \"NAN\" : \"nan\") : (specs.upper() ? \"INF\" : \"inf\");\n  constexpr size_t str_size = 3;\n  auto size = str_size + (s != sign::none ? 1 : 0);\n  // Replace '0'-padding with space for non-finite values.\n  const bool is_zero_fill =\n      specs.fill_size() == 1 && specs.fill_unit<Char>() == '0';\n  if (is_zero_fill) specs.set_fill(' ');\n  return write_padded<Char>(out, specs, size,\n                            [=](reserve_iterator<OutputIt> it) {\n                              if (s != sign::none)\n                                *it++ = detail::getsign<Char>(s);\n                              return copy<Char>(str, str + str_size, it);\n                            });\n}\n\n// A decimal floating-point number significand * pow(10, exp).\nstruct big_decimal_fp {\n  const char* significand;\n  int significand_size;\n  int exponent;\n};\n\nconstexpr auto get_significand_size(const big_decimal_fp& f) -> int {\n  return f.significand_size;\n}\ntemplate <typename T>\ninline auto get_significand_size(const dragonbox::decimal_fp<T>& f) -> int {\n  return count_digits(f.significand);\n}\n\ntemplate <typename Char, typename OutputIt>\nconstexpr auto write_significand(OutputIt out, const char* significand,\n                                 int significand_size) -> OutputIt {\n  return copy<Char>(significand, significand + significand_size, out);\n}\ntemplate <typename Char, typename OutputIt, typename UInt>\ninline auto write_significand(OutputIt out, UInt significand,\n                              int significand_size) -> OutputIt {\n  return format_decimal<Char>(out, significand, significand_size);\n}\ntemplate <typename Char, typename OutputIt, typename T, typename Grouping>\nFMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,\n                                       int significand_size, int exponent,\n                                       const Grouping& grouping) -> OutputIt {\n  if (!grouping.has_separator()) {\n    out = write_significand<Char>(out, significand, significand_size);\n    return detail::fill_n(out, exponent, static_cast<Char>('0'));\n  }\n  auto buffer = memory_buffer();\n  write_significand<char>(appender(buffer), significand, significand_size);\n  detail::fill_n(appender(buffer), exponent, '0');\n  return grouping.apply(out, string_view(buffer.data(), buffer.size()));\n}\n\ntemplate <typename Char, typename UInt,\n          FMT_ENABLE_IF(std::is_integral<UInt>::value)>\ninline auto write_significand(Char* out, UInt significand, int significand_size,\n                              int integral_size, Char decimal_point) -> Char* {\n  if (!decimal_point) return format_decimal(out, significand, significand_size);\n  out += significand_size + 1;\n  Char* end = out;\n  int floating_size = significand_size - integral_size;\n  for (int i = floating_size / 2; i > 0; --i) {\n    out -= 2;\n    write2digits(out, static_cast<size_t>(significand % 100));\n    significand /= 100;\n  }\n  if (floating_size % 2 != 0) {\n    *--out = static_cast<Char>('0' + significand % 10);\n    significand /= 10;\n  }\n  *--out = decimal_point;\n  format_decimal(out - integral_size, significand, integral_size);\n  return end;\n}\n\ntemplate <typename OutputIt, typename UInt, typename Char,\n          FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<OutputIt>>::value)>\ninline auto write_significand(OutputIt out, UInt significand,\n                              int significand_size, int integral_size,\n                              Char decimal_point) -> OutputIt {\n  // Buffer is large enough to hold digits (digits10 + 1) and a decimal point.\n  Char buffer[digits10<UInt>() + 2];\n  auto end = write_significand(buffer, significand, significand_size,\n                               integral_size, decimal_point);\n  return detail::copy_noinline<Char>(buffer, end, out);\n}\n\ntemplate <typename OutputIt, typename Char>\nFMT_CONSTEXPR auto write_significand(OutputIt out, const char* significand,\n                                     int significand_size, int integral_size,\n                                     Char decimal_point) -> OutputIt {\n  out = detail::copy_noinline<Char>(significand, significand + integral_size,\n                                    out);\n  if (!decimal_point) return out;\n  *out++ = decimal_point;\n  return detail::copy_noinline<Char>(significand + integral_size,\n                                     significand + significand_size, out);\n}\n\ntemplate <typename OutputIt, typename Char, typename T, typename Grouping>\nFMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,\n                                       int significand_size, int integral_size,\n                                       Char decimal_point,\n                                       const Grouping& grouping) -> OutputIt {\n  if (!grouping.has_separator()) {\n    return write_significand(out, significand, significand_size, integral_size,\n                             decimal_point);\n  }\n  auto buffer = basic_memory_buffer<Char>();\n  write_significand(basic_appender<Char>(buffer), significand, significand_size,\n                    integral_size, decimal_point);\n  grouping.apply(\n      out, basic_string_view<Char>(buffer.data(), to_unsigned(integral_size)));\n  return detail::copy_noinline<Char>(buffer.data() + integral_size,\n                                     buffer.end(), out);\n}\n\n// Numbers with exponents greater or equal to the returned value will use\n// the exponential notation.\ntemplate <typename T> FMT_CONSTEVAL auto exp_upper() -> int {\n  return std::numeric_limits<T>::digits10 != 0\n             ? min_of(16, std::numeric_limits<T>::digits10 + 1)\n             : 16;\n}\n\n// Use the fixed notation if the exponent is in [-4, exp_upper),\n// e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation.\nconstexpr auto use_fixed(int exp, int exp_upper) -> bool {\n  return exp >= -4 && exp < exp_upper;\n}\n\ntemplate <typename Char> class fallback_digit_grouping {\n public:\n  constexpr fallback_digit_grouping(locale_ref, bool) {}\n\n  constexpr auto has_separator() const -> bool { return false; }\n\n  constexpr auto count_separators(int) const -> int { return 0; }\n\n  template <typename Out, typename C>\n  constexpr auto apply(Out out, basic_string_view<C>) const -> Out {\n    return out;\n  }\n};\n\ntemplate <typename Char, typename Grouping, typename OutputIt,\n          typename DecimalFP>\nFMT_CONSTEXPR20 auto write_fixed(OutputIt out, const DecimalFP& f,\n                                 int significand_size, Char decimal_point,\n                                 const format_specs& specs, sign s,\n                                 locale_ref loc = {}) -> OutputIt {\n  using iterator = reserve_iterator<OutputIt>;\n\n  int exp = f.exponent + significand_size;\n  long long size = significand_size + (s != sign::none ? 1 : 0);\n  if (f.exponent >= 0) {\n    // 1234e5 -> 123400000[.0+]\n    size += f.exponent;\n    int num_zeros = specs.precision - exp;\n    abort_fuzzing_if(num_zeros > 5000);\n    if (specs.alt()) {\n      ++size;\n      if (num_zeros <= 0 && specs.type() != presentation_type::fixed)\n        num_zeros = 0;\n      if (num_zeros > 0) size += num_zeros;\n    }\n    auto grouping = Grouping(loc, specs.localized());\n    size += grouping.count_separators(exp);\n    return write_padded<Char, align::right>(\n        out, specs, static_cast<size_t>(size), [&](iterator it) {\n          if (s != sign::none) *it++ = detail::getsign<Char>(s);\n          it = write_significand<Char>(it, f.significand, significand_size,\n                                       f.exponent, grouping);\n          if (!specs.alt()) return it;\n          *it++ = decimal_point;\n          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;\n        });\n  }\n  if (exp > 0) {\n    // 1234e-2 -> 12.34[0+]\n    int num_zeros = specs.alt() ? specs.precision - significand_size : 0;\n    size += 1 + max_of(num_zeros, 0);\n    auto grouping = Grouping(loc, specs.localized());\n    size += grouping.count_separators(exp);\n    return write_padded<Char, align::right>(\n        out, specs, to_unsigned(size), [&](iterator it) {\n          if (s != sign::none) *it++ = detail::getsign<Char>(s);\n          it = write_significand(it, f.significand, significand_size, exp,\n                                 decimal_point, grouping);\n          return num_zeros > 0 ? detail::fill_n(it, num_zeros, Char('0')) : it;\n        });\n  }\n  // 1234e-6 -> 0.001234\n  int num_zeros = -exp;\n  if (significand_size == 0 && specs.precision >= 0 &&\n      specs.precision < num_zeros) {\n    num_zeros = specs.precision;\n  }\n  bool pointy = num_zeros != 0 || significand_size != 0 || specs.alt();\n  size += 1 + (pointy ? 1 : 0) + num_zeros;\n  return write_padded<Char, align::right>(\n      out, specs, to_unsigned(size), [&](iterator it) {\n        if (s != sign::none) *it++ = detail::getsign<Char>(s);\n        *it++ = Char('0');\n        if (!pointy) return it;\n        *it++ = decimal_point;\n        it = detail::fill_n(it, num_zeros, Char('0'));\n        return write_significand<Char>(it, f.significand, significand_size);\n      });\n}\n\ntemplate <typename Char, typename Grouping, typename OutputIt,\n          typename DecimalFP>\nFMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f,\n                                    const format_specs& specs, sign s,\n                                    int exp_upper, locale_ref loc) -> OutputIt {\n  Char point = specs.localized() ? detail::decimal_point<Char>(loc) : Char('.');\n  int significand_size = get_significand_size(f);\n  int exp = f.exponent + significand_size - 1;\n  if (specs.type() == presentation_type::fixed ||\n      (specs.type() != presentation_type::exp &&\n       use_fixed(exp, specs.precision > 0 ? specs.precision : exp_upper))) {\n    return write_fixed<Char, Grouping>(out, f, significand_size, point, specs,\n                                       s, loc);\n  }\n\n  // Write value in the exponential format.\n  int num_zeros = 0;\n  long long size = significand_size + (s != sign::none ? 1 : 0);\n  if (specs.alt()) {\n    num_zeros = max_of(specs.precision - significand_size, 0);\n    size += num_zeros;\n  } else if (significand_size == 1) {\n    point = Char();\n  }\n  size += (point ? 1 : 0) + compute_exp_size(exp);\n  char exp_char = specs.upper() ? 'E' : 'e';\n  auto write = [=](reserve_iterator<OutputIt> it) {\n    if (s != sign::none) *it++ = detail::getsign<Char>(s);\n    // Insert a decimal point after the first digit and add an exponent.\n    it = write_significand(it, f.significand, significand_size, 1, point);\n    if (num_zeros > 0) it = detail::fill_n(it, num_zeros, Char('0'));\n    *it++ = Char(exp_char);\n    return write_exponent<Char>(exp, it);\n  };\n  auto usize = to_unsigned(size);\n  return specs.width > 0\n             ? write_padded<Char, align::right>(out, specs, usize, write)\n             : base_iterator(out, write(reserve(out, usize)));\n}\n\ntemplate <typename Char, typename OutputIt, typename DecimalFP>\nFMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP& f,\n                                 const format_specs& specs, sign s,\n                                 int exp_upper, locale_ref loc) -> OutputIt {\n  if (is_constant_evaluated()) {\n    return do_write_float<Char, fallback_digit_grouping<Char>>(out, f, specs, s,\n                                                               exp_upper, loc);\n  } else {\n    return do_write_float<Char, digit_grouping<Char>>(out, f, specs, s,\n                                                      exp_upper, loc);\n  }\n}\n\ntemplate <typename T> constexpr auto isnan(T value) -> bool {\n  return value != value;  // std::isnan doesn't support __float128.\n}\n\ntemplate <typename T, typename Enable = void>\nstruct has_isfinite : std::false_type {};\n\ntemplate <typename T>\nstruct has_isfinite<T, enable_if_t<sizeof(std::isfinite(T())) != 0>>\n    : std::true_type {};\n\ntemplate <typename T,\n          FMT_ENABLE_IF(is_floating_point<T>::value&& has_isfinite<T>::value)>\nFMT_CONSTEXPR20 auto isfinite(T value) -> bool {\n  constexpr T inf = T(std::numeric_limits<double>::infinity());\n  if (is_constant_evaluated())\n    return !detail::isnan(value) && value < inf && value > -inf;\n  return std::isfinite(value);\n}\ntemplate <typename T, FMT_ENABLE_IF(!has_isfinite<T>::value)>\nFMT_CONSTEXPR auto isfinite(T value) -> bool {\n  T inf = T(std::numeric_limits<double>::infinity());\n  // std::isfinite doesn't support __float128.\n  return !detail::isnan(value) && value < inf && value > -inf;\n}\n\ntemplate <typename T, FMT_ENABLE_IF(is_floating_point<T>::value)>\nFMT_INLINE FMT_CONSTEXPR auto signbit(T value) -> bool {\n  if (is_constant_evaluated()) {\n#ifdef __cpp_if_constexpr\n    if constexpr (std::numeric_limits<double>::is_iec559) {\n      auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value));\n      return (bits >> (num_bits<uint64_t>() - 1)) != 0;\n    }\n#endif\n  }\n  return std::signbit(static_cast<double>(value));\n}\n\ninline FMT_CONSTEXPR20 void adjust_precision(int& precision, int exp10) {\n  // Adjust fixed precision by exponent because it is relative to decimal\n  // point.\n  if (exp10 > 0 && precision > max_value<int>() - exp10)\n    FMT_THROW(format_error(\"number is too big\"));\n  precision += exp10;\n}\n\nclass bigint {\n private:\n  // A bigint is a number in the form bigit_[N - 1] ... bigit_[0] * 32^exp_.\n  using bigit = uint32_t;  // A big digit.\n  using double_bigit = uint64_t;\n  enum { bigit_bits = num_bits<bigit>() };\n  enum { bigits_capacity = 32 };\n  basic_memory_buffer<bigit, bigits_capacity> bigits_;\n  int exp_;\n\n  friend struct formatter<bigint>;\n\n  FMT_CONSTEXPR auto get_bigit(int i) const -> bigit {\n    return i >= exp_ && i < num_bigits() ? bigits_[i - exp_] : 0;\n  }\n\n  FMT_CONSTEXPR void subtract_bigits(int index, bigit other, bigit& borrow) {\n    auto result = double_bigit(bigits_[index]) - other - borrow;\n    bigits_[index] = static_cast<bigit>(result);\n    borrow = static_cast<bigit>(result >> (bigit_bits * 2 - 1));\n  }\n\n  FMT_CONSTEXPR void remove_leading_zeros() {\n    int num_bigits = static_cast<int>(bigits_.size()) - 1;\n    while (num_bigits > 0 && bigits_[num_bigits] == 0) --num_bigits;\n    bigits_.resize(to_unsigned(num_bigits + 1));\n  }\n\n  // Computes *this -= other assuming aligned bigints and *this >= other.\n  FMT_CONSTEXPR void subtract_aligned(const bigint& other) {\n    FMT_ASSERT(other.exp_ >= exp_, \"unaligned bigints\");\n    FMT_ASSERT(compare(*this, other) >= 0, \"\");\n    bigit borrow = 0;\n    int i = other.exp_ - exp_;\n    for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j)\n      subtract_bigits(i, other.bigits_[j], borrow);\n    if (borrow != 0) subtract_bigits(i, 0, borrow);\n    FMT_ASSERT(borrow == 0, \"\");\n    remove_leading_zeros();\n  }\n\n  FMT_CONSTEXPR void multiply(uint32_t value) {\n    bigit carry = 0;\n    const double_bigit wide_value = value;\n    for (size_t i = 0, n = bigits_.size(); i < n; ++i) {\n      double_bigit result = bigits_[i] * wide_value + carry;\n      bigits_[i] = static_cast<bigit>(result);\n      carry = static_cast<bigit>(result >> bigit_bits);\n    }\n    if (carry != 0) bigits_.push_back(carry);\n  }\n\n  template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||\n                                         std::is_same<UInt, uint128_t>::value)>\n  FMT_CONSTEXPR void multiply(UInt value) {\n    using half_uint =\n        conditional_t<std::is_same<UInt, uint128_t>::value, uint64_t, uint32_t>;\n    const int shift = num_bits<half_uint>() - bigit_bits;\n    const UInt lower = static_cast<half_uint>(value);\n    const UInt upper = value >> num_bits<half_uint>();\n    UInt carry = 0;\n    for (size_t i = 0, n = bigits_.size(); i < n; ++i) {\n      UInt result = lower * bigits_[i] + static_cast<bigit>(carry);\n      carry = (upper * bigits_[i] << shift) + (result >> bigit_bits) +\n              (carry >> bigit_bits);\n      bigits_[i] = static_cast<bigit>(result);\n    }\n    while (carry != 0) {\n      bigits_.push_back(static_cast<bigit>(carry));\n      carry >>= bigit_bits;\n    }\n  }\n\n  template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||\n                                         std::is_same<UInt, uint128_t>::value)>\n  FMT_CONSTEXPR void assign(UInt n) {\n    size_t num_bigits = 0;\n    do {\n      bigits_[num_bigits++] = static_cast<bigit>(n);\n      n >>= bigit_bits;\n    } while (n != 0);\n    bigits_.resize(num_bigits);\n    exp_ = 0;\n  }\n\n public:\n  FMT_CONSTEXPR bigint() : exp_(0) {}\n  explicit bigint(uint64_t n) { assign(n); }\n\n  bigint(const bigint&) = delete;\n  void operator=(const bigint&) = delete;\n\n  FMT_CONSTEXPR void assign(const bigint& other) {\n    auto size = other.bigits_.size();\n    bigits_.resize(size);\n    auto data = other.bigits_.data();\n    copy<bigit>(data, data + size, bigits_.data());\n    exp_ = other.exp_;\n  }\n\n  template <typename Int> FMT_CONSTEXPR void operator=(Int n) {\n    FMT_ASSERT(n > 0, \"\");\n    assign(uint64_or_128_t<Int>(n));\n  }\n\n  FMT_CONSTEXPR auto num_bigits() const -> int {\n    return static_cast<int>(bigits_.size()) + exp_;\n  }\n\n  FMT_CONSTEXPR auto operator<<=(int shift) -> bigint& {\n    FMT_ASSERT(shift >= 0, \"\");\n    exp_ += shift / bigit_bits;\n    shift %= bigit_bits;\n    if (shift == 0) return *this;\n    bigit carry = 0;\n    for (size_t i = 0, n = bigits_.size(); i < n; ++i) {\n      bigit c = bigits_[i] >> (bigit_bits - shift);\n      bigits_[i] = (bigits_[i] << shift) + carry;\n      carry = c;\n    }\n    if (carry != 0) bigits_.push_back(carry);\n    return *this;\n  }\n\n  template <typename Int> FMT_CONSTEXPR auto operator*=(Int value) -> bigint& {\n    FMT_ASSERT(value > 0, \"\");\n    multiply(uint32_or_64_or_128_t<Int>(value));\n    return *this;\n  }\n\n  friend FMT_CONSTEXPR auto compare(const bigint& b1, const bigint& b2) -> int {\n    int num_bigits1 = b1.num_bigits(), num_bigits2 = b2.num_bigits();\n    if (num_bigits1 != num_bigits2) return num_bigits1 > num_bigits2 ? 1 : -1;\n    int i = static_cast<int>(b1.bigits_.size()) - 1;\n    int j = static_cast<int>(b2.bigits_.size()) - 1;\n    int end = i - j;\n    if (end < 0) end = 0;\n    for (; i >= end; --i, --j) {\n      bigit b1_bigit = b1.bigits_[i], b2_bigit = b2.bigits_[j];\n      if (b1_bigit != b2_bigit) return b1_bigit > b2_bigit ? 1 : -1;\n    }\n    if (i != j) return i > j ? 1 : -1;\n    return 0;\n  }\n\n  // Returns compare(lhs1 + lhs2, rhs).\n  friend FMT_CONSTEXPR auto add_compare(const bigint& lhs1, const bigint& lhs2,\n                                        const bigint& rhs) -> int {\n    int max_lhs_bigits = max_of(lhs1.num_bigits(), lhs2.num_bigits());\n    int num_rhs_bigits = rhs.num_bigits();\n    if (max_lhs_bigits + 1 < num_rhs_bigits) return -1;\n    if (max_lhs_bigits > num_rhs_bigits) return 1;\n    double_bigit borrow = 0;\n    int min_exp = min_of(min_of(lhs1.exp_, lhs2.exp_), rhs.exp_);\n    for (int i = num_rhs_bigits - 1; i >= min_exp; --i) {\n      double_bigit sum = double_bigit(lhs1.get_bigit(i)) + lhs2.get_bigit(i);\n      bigit rhs_bigit = rhs.get_bigit(i);\n      if (sum > rhs_bigit + borrow) return 1;\n      borrow = rhs_bigit + borrow - sum;\n      if (borrow > 1) return -1;\n      borrow <<= bigit_bits;\n    }\n    return borrow != 0 ? -1 : 0;\n  }\n\n  // Assigns pow(10, exp) to this bigint.\n  FMT_CONSTEXPR20 void assign_pow10(int exp) {\n    FMT_ASSERT(exp >= 0, \"\");\n    if (exp == 0) return *this = 1;\n    int bitmask = 1 << (num_bits<unsigned>() -\n                        countl_zero(static_cast<uint32_t>(exp)) - 1);\n    // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by\n    // repeated squaring and multiplication.\n    *this = 5;\n    bitmask >>= 1;\n    while (bitmask != 0) {\n      square();\n      if ((exp & bitmask) != 0) *this *= 5;\n      bitmask >>= 1;\n    }\n    *this <<= exp;  // Multiply by pow(2, exp) by shifting.\n  }\n\n  FMT_CONSTEXPR20 void square() {\n    int num_bigits = static_cast<int>(bigits_.size());\n    int num_result_bigits = 2 * num_bigits;\n    basic_memory_buffer<bigit, bigits_capacity> n(std::move(bigits_));\n    bigits_.resize(to_unsigned(num_result_bigits));\n    auto sum = uint128_t();\n    for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) {\n      // Compute bigit at position bigit_index of the result by adding\n      // cross-product terms n[i] * n[j] such that i + j == bigit_index.\n      for (int i = 0, j = bigit_index; j >= 0; ++i, --j) {\n        // Most terms are multiplied twice which can be optimized in the future.\n        sum += double_bigit(n[i]) * n[j];\n      }\n      bigits_[bigit_index] = static_cast<bigit>(sum);\n      sum >>= num_bits<bigit>();  // Compute the carry.\n    }\n    // Do the same for the top half.\n    for (int bigit_index = num_bigits; bigit_index < num_result_bigits;\n         ++bigit_index) {\n      for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;)\n        sum += double_bigit(n[i++]) * n[j--];\n      bigits_[bigit_index] = static_cast<bigit>(sum);\n      sum >>= num_bits<bigit>();\n    }\n    remove_leading_zeros();\n    exp_ *= 2;\n  }\n\n  // If this bigint has a bigger exponent than other, adds trailing zero to make\n  // exponents equal. This simplifies some operations such as subtraction.\n  FMT_CONSTEXPR void align(const bigint& other) {\n    int exp_difference = exp_ - other.exp_;\n    if (exp_difference <= 0) return;\n    int num_bigits = static_cast<int>(bigits_.size());\n    bigits_.resize(to_unsigned(num_bigits + exp_difference));\n    for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)\n      bigits_[j] = bigits_[i];\n    fill_n(bigits_.data(), to_unsigned(exp_difference), 0U);\n    exp_ -= exp_difference;\n  }\n\n  // Divides this bignum by divisor, assigning the remainder to this and\n  // returning the quotient.\n  FMT_CONSTEXPR auto divmod_assign(const bigint& divisor) -> int {\n    FMT_ASSERT(this != &divisor, \"\");\n    if (compare(*this, divisor) < 0) return 0;\n    FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, \"\");\n    align(divisor);\n    int quotient = 0;\n    do {\n      subtract_aligned(divisor);\n      ++quotient;\n    } while (compare(*this, divisor) >= 0);\n    return quotient;\n  }\n};\n\n// format_dragon flags.\nenum dragon {\n  predecessor_closer = 1,\n  fixup = 2,  // Run fixup to correct exp10 which can be off by one.\n  fixed = 4,\n};\n\n// Formats a floating-point number using a variation of the Fixed-Precision\n// Positive Floating-Point Printout ((FPP)^2) algorithm by Steele & White:\n// https://fmt.dev/papers/p372-steele.pdf.\nFMT_CONSTEXPR20 inline void format_dragon(basic_fp<uint128_t> value,\n                                          unsigned flags, int num_digits,\n                                          buffer<char>& buf, int& exp10) {\n  bigint numerator;    // 2 * R in (FPP)^2.\n  bigint denominator;  // 2 * S in (FPP)^2.\n  // lower and upper are differences between value and corresponding boundaries.\n  bigint lower;             // (M^- in (FPP)^2).\n  bigint upper_store;       // upper's value if different from lower.\n  bigint* upper = nullptr;  // (M^+ in (FPP)^2).\n  // Shift numerator and denominator by an extra bit or two (if lower boundary\n  // is closer) to make lower and upper integers. This eliminates multiplication\n  // by 2 during later computations.\n  bool is_predecessor_closer = (flags & dragon::predecessor_closer) != 0;\n  int shift = is_predecessor_closer ? 2 : 1;\n  if (value.e >= 0) {\n    numerator = value.f;\n    numerator <<= value.e + shift;\n    lower = 1;\n    lower <<= value.e;\n    if (is_predecessor_closer) {\n      upper_store = 1;\n      upper_store <<= value.e + 1;\n      upper = &upper_store;\n    }\n    denominator.assign_pow10(exp10);\n    denominator <<= shift;\n  } else if (exp10 < 0) {\n    numerator.assign_pow10(-exp10);\n    lower.assign(numerator);\n    if (is_predecessor_closer) {\n      upper_store.assign(numerator);\n      upper_store <<= 1;\n      upper = &upper_store;\n    }\n    numerator *= value.f;\n    numerator <<= shift;\n    denominator = 1;\n    denominator <<= shift - value.e;\n  } else {\n    numerator = value.f;\n    numerator <<= shift;\n    denominator.assign_pow10(exp10);\n    denominator <<= shift - value.e;\n    lower = 1;\n    if (is_predecessor_closer) {\n      upper_store = 1ULL << 1;\n      upper = &upper_store;\n    }\n  }\n  int even = static_cast<int>((value.f & 1) == 0);\n  if (!upper) upper = &lower;\n  bool shortest = num_digits < 0;\n  if ((flags & dragon::fixup) != 0) {\n    if (add_compare(numerator, *upper, denominator) + even <= 0) {\n      --exp10;\n      numerator *= 10;\n      if (num_digits < 0) {\n        lower *= 10;\n        if (upper != &lower) *upper *= 10;\n      }\n    }\n    if ((flags & dragon::fixed) != 0) adjust_precision(num_digits, exp10 + 1);\n  }\n  // Invariant: value == (numerator / denominator) * pow(10, exp10).\n  if (shortest) {\n    // Generate the shortest representation.\n    num_digits = 0;\n    char* data = buf.data();\n    for (;;) {\n      int digit = numerator.divmod_assign(denominator);\n      bool low = compare(numerator, lower) - even < 0;  // numerator <[=] lower.\n      // numerator + upper >[=] pow10:\n      bool high = add_compare(numerator, *upper, denominator) + even > 0;\n      data[num_digits++] = static_cast<char>('0' + digit);\n      if (low || high) {\n        if (!low) {\n          ++data[num_digits - 1];\n        } else if (high) {\n          int result = add_compare(numerator, numerator, denominator);\n          // Round half to even.\n          if (result > 0 || (result == 0 && (digit % 2) != 0))\n            ++data[num_digits - 1];\n        }\n        buf.try_resize(to_unsigned(num_digits));\n        exp10 -= num_digits - 1;\n        return;\n      }\n      numerator *= 10;\n      lower *= 10;\n      if (upper != &lower) *upper *= 10;\n    }\n  }\n  // Generate the given number of digits.\n  exp10 -= num_digits - 1;\n  if (num_digits <= 0) {\n    auto digit = '0';\n    if (num_digits == 0) {\n      denominator *= 10;\n      digit = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0';\n    }\n    buf.push_back(digit);\n    return;\n  }\n  buf.try_resize(to_unsigned(num_digits));\n  for (int i = 0; i < num_digits - 1; ++i) {\n    int digit = numerator.divmod_assign(denominator);\n    buf[i] = static_cast<char>('0' + digit);\n    numerator *= 10;\n  }\n  int digit = numerator.divmod_assign(denominator);\n  auto result = add_compare(numerator, numerator, denominator);\n  if (result > 0 || (result == 0 && (digit % 2) != 0)) {\n    if (digit == 9) {\n      const auto overflow = '0' + 10;\n      buf[num_digits - 1] = overflow;\n      // Propagate the carry.\n      for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) {\n        buf[i] = '0';\n        ++buf[i - 1];\n      }\n      if (buf[0] == overflow) {\n        buf[0] = '1';\n        if ((flags & dragon::fixed) != 0)\n          buf.push_back('0');\n        else\n          ++exp10;\n      }\n      return;\n    }\n    ++digit;\n  }\n  buf[num_digits - 1] = static_cast<char>('0' + digit);\n}\n\n// Formats a floating-point number using the hexfloat format.\ntemplate <typename Float, FMT_ENABLE_IF(!is_double_double<Float>::value)>\nFMT_CONSTEXPR20 void format_hexfloat(Float value, format_specs specs,\n                                     buffer<char>& buf) {\n  // float is passed as double to reduce the number of instantiations and to\n  // simplify implementation.\n  static_assert(!std::is_same<Float, float>::value, \"\");\n\n  using info = dragonbox::float_info<Float>;\n\n  // Assume Float is in the format [sign][exponent][significand].\n  using carrier_uint = typename info::carrier_uint;\n\n  const auto num_float_significand_bits = detail::num_significand_bits<Float>();\n\n  basic_fp<carrier_uint> f(value);\n  f.e += num_float_significand_bits;\n  if (!has_implicit_bit<Float>()) --f.e;\n\n  const auto num_fraction_bits =\n      num_float_significand_bits + (has_implicit_bit<Float>() ? 1 : 0);\n  const auto num_xdigits = (num_fraction_bits + 3) / 4;\n\n  const auto leading_shift = ((num_xdigits - 1) * 4);\n  const auto leading_mask = carrier_uint(0xF) << leading_shift;\n  const auto leading_xdigit =\n      static_cast<uint32_t>((f.f & leading_mask) >> leading_shift);\n  if (leading_xdigit > 1) f.e -= (32 - countl_zero(leading_xdigit) - 1);\n\n  int print_xdigits = num_xdigits - 1;\n  if (specs.precision >= 0 && print_xdigits > specs.precision) {\n    const int shift = ((print_xdigits - specs.precision - 1) * 4);\n    const auto mask = carrier_uint(0xF) << shift;\n    const auto v = static_cast<uint32_t>((f.f & mask) >> shift);\n\n    if (v >= 8) {\n      const auto inc = carrier_uint(1) << (shift + 4);\n      f.f += inc;\n      f.f &= ~(inc - 1);\n    }\n\n    // Check long double overflow\n    if (!has_implicit_bit<Float>()) {\n      const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;\n      if ((f.f & implicit_bit) == implicit_bit) {\n        f.f >>= 4;\n        f.e += 4;\n      }\n    }\n\n    print_xdigits = specs.precision;\n  }\n\n  char xdigits[num_bits<carrier_uint>() / 4];\n  detail::fill_n(xdigits, sizeof(xdigits), '0');\n  format_base2e(4, xdigits, f.f, num_xdigits, specs.upper());\n\n  // Remove zero tail\n  while (print_xdigits > 0 && xdigits[print_xdigits] == '0') --print_xdigits;\n\n  buf.push_back('0');\n  buf.push_back(specs.upper() ? 'X' : 'x');\n  buf.push_back(xdigits[0]);\n  if (specs.alt() || print_xdigits > 0 || print_xdigits < specs.precision)\n    buf.push_back('.');\n  buf.append(xdigits + 1, xdigits + 1 + print_xdigits);\n  for (; print_xdigits < specs.precision; ++print_xdigits) buf.push_back('0');\n\n  buf.push_back(specs.upper() ? 'P' : 'p');\n\n  uint32_t abs_e;\n  if (f.e < 0) {\n    buf.push_back('-');\n    abs_e = static_cast<uint32_t>(-f.e);\n  } else {\n    buf.push_back('+');\n    abs_e = static_cast<uint32_t>(f.e);\n  }\n  format_decimal<char>(appender(buf), abs_e, detail::count_digits(abs_e));\n}\n\ntemplate <typename Float, FMT_ENABLE_IF(is_double_double<Float>::value)>\nFMT_CONSTEXPR20 void format_hexfloat(Float value, format_specs specs,\n                                     buffer<char>& buf) {\n  format_hexfloat(static_cast<double>(value), specs, buf);\n}\n\nconstexpr auto fractional_part_rounding_thresholds(int index) -> uint32_t {\n  // For checking rounding thresholds.\n  // The kth entry is chosen to be the smallest integer such that the\n  // upper 32-bits of 10^(k+1) times it is strictly bigger than 5 * 10^k.\n  // It is equal to ceil(2^31 + 2^32/10^(k + 1)).\n  // These are stored in a string literal because we cannot have static arrays\n  // in constexpr functions and non-static ones are poorly optimized.\n  return U\"\\x9999999a\\x828f5c29\\x80418938\\x80068db9\\x8000a7c6\\x800010c7\"\n         U\"\\x800001ae\\x8000002b\"[index];\n}\n\ntemplate <typename Float>\nFMT_CONSTEXPR20 auto format_float(Float value, int precision,\n                                  const format_specs& specs, bool binary32,\n                                  buffer<char>& buf) -> int {\n  // float is passed as double to reduce the number of instantiations.\n  static_assert(!std::is_same<Float, float>::value, \"\");\n  auto converted_value = convert_float(value);\n\n  const bool fixed = specs.type() == presentation_type::fixed;\n  if (value == 0) {\n    if (precision <= 0 || !fixed) {\n      buf.push_back('0');\n      return 0;\n    }\n    buf.try_resize(to_unsigned(precision));\n    fill_n(buf.data(), precision, '0');\n    return -precision;\n  }\n\n  int exp = 0;\n  bool use_dragon = true;\n  unsigned dragon_flags = 0;\n  if (!is_fast_float<Float>() || is_constant_evaluated()) {\n    const auto inv_log2_10 = 0.3010299956639812;  // 1 / log2(10)\n    using info = dragonbox::float_info<decltype(converted_value)>;\n    const auto f = basic_fp<typename info::carrier_uint>(converted_value);\n    // Compute exp, an approximate power of 10, such that\n    //   10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1).\n    // This is based on log10(value) == log2(value) / log2(10) and approximation\n    // of log2(value) by e + num_fraction_bits idea from double-conversion.\n    auto e = (f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10;\n    exp = static_cast<int>(e);\n    if (e > exp) ++exp;  // Compute ceil.\n    dragon_flags = dragon::fixup;\n  } else {\n    // Extract significand bits and exponent bits.\n    using info = dragonbox::float_info<double>;\n    auto br = bit_cast<uint64_t>(static_cast<double>(value));\n\n    const uint64_t significand_mask =\n        (static_cast<uint64_t>(1) << num_significand_bits<double>()) - 1;\n    uint64_t significand = (br & significand_mask);\n    int exponent = static_cast<int>((br & exponent_mask<double>()) >>\n                                    num_significand_bits<double>());\n\n    if (exponent != 0) {  // Check if normal.\n      exponent -= exponent_bias<double>() + num_significand_bits<double>();\n      significand |=\n          (static_cast<uint64_t>(1) << num_significand_bits<double>());\n      significand <<= 1;\n    } else {\n      // Normalize subnormal inputs.\n      FMT_ASSERT(significand != 0, \"zeros should not appear here\");\n      int shift = countl_zero(significand);\n      FMT_ASSERT(shift >= num_bits<uint64_t>() - num_significand_bits<double>(),\n                 \"\");\n      shift -= (num_bits<uint64_t>() - num_significand_bits<double>() - 2);\n      exponent = (std::numeric_limits<double>::min_exponent -\n                  num_significand_bits<double>()) -\n                 shift;\n      significand <<= shift;\n    }\n\n    // Compute the first several nonzero decimal significand digits.\n    // We call the number we get the first segment.\n    const int k = info::kappa - dragonbox::floor_log10_pow2(exponent);\n    exp = -k;\n    const int beta = exponent + dragonbox::floor_log2_pow10(k);\n    uint64_t first_segment;\n    bool has_more_segments;\n    int digits_in_the_first_segment;\n    {\n      const auto r = dragonbox::umul192_upper128(\n          significand << beta, dragonbox::get_cached_power(k));\n      first_segment = r.high();\n      has_more_segments = r.low() != 0;\n\n      // The first segment can have 18 ~ 19 digits.\n      if (first_segment >= 1000000000000000000ULL) {\n        digits_in_the_first_segment = 19;\n      } else {\n        // When it is of 18-digits, we align it to 19-digits by adding a bogus\n        // zero at the end.\n        digits_in_the_first_segment = 18;\n        first_segment *= 10;\n      }\n    }\n\n    // Compute the actual number of decimal digits to print.\n    if (fixed) adjust_precision(precision, exp + digits_in_the_first_segment);\n\n    // Use Dragon4 only when there might be not enough digits in the first\n    // segment.\n    if (digits_in_the_first_segment > precision) {\n      use_dragon = false;\n\n      if (precision <= 0) {\n        exp += digits_in_the_first_segment;\n\n        if (precision < 0) {\n          // Nothing to do, since all we have are just leading zeros.\n          buf.try_resize(0);\n        } else {\n          // We may need to round-up.\n          buf.try_resize(1);\n          if ((first_segment | static_cast<uint64_t>(has_more_segments)) >\n              5000000000000000000ULL) {\n            buf[0] = '1';\n          } else {\n            buf[0] = '0';\n          }\n        }\n      }  // precision <= 0\n      else {\n        exp += digits_in_the_first_segment - precision;\n\n        // When precision > 0, we divide the first segment into three\n        // subsegments, each with 9, 9, and 0 ~ 1 digits so that each fits\n        // in 32-bits which usually allows faster calculation than in\n        // 64-bits. Since some compiler (e.g. MSVC) doesn't know how to optimize\n        // division-by-constant for large 64-bit divisors, we do it here\n        // manually. The magic number 7922816251426433760 below is equal to\n        // ceil(2^(64+32) / 10^10).\n        const uint32_t first_subsegment = static_cast<uint32_t>(\n            dragonbox::umul128_upper64(first_segment, 7922816251426433760ULL) >>\n            32);\n        const uint64_t second_third_subsegments =\n            first_segment - first_subsegment * 10000000000ULL;\n\n        uint64_t prod;\n        uint32_t digits;\n        bool should_round_up;\n        int number_of_digits_to_print = min_of(precision, 9);\n\n        // Print a 9-digits subsegment, either the first or the second.\n        auto print_subsegment = [&](uint32_t subsegment, char* buffer) {\n          int number_of_digits_printed = 0;\n\n          // If we want to print an odd number of digits from the subsegment,\n          if ((number_of_digits_to_print & 1) != 0) {\n            // Convert to 64-bit fixed-point fractional form with 1-digit\n            // integer part. The magic number 720575941 is a good enough\n            // approximation of 2^(32 + 24) / 10^8; see\n            // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case\n            // for details.\n            prod = ((subsegment * static_cast<uint64_t>(720575941)) >> 24) + 1;\n            digits = static_cast<uint32_t>(prod >> 32);\n            *buffer = static_cast<char>('0' + digits);\n            number_of_digits_printed++;\n          }\n          // If we want to print an even number of digits from the\n          // first_subsegment,\n          else {\n            // Convert to 64-bit fixed-point fractional form with 2-digits\n            // integer part. The magic number 450359963 is a good enough\n            // approximation of 2^(32 + 20) / 10^7; see\n            // https://jk-jeon.github.io/posts/2022/12/fixed-precision-formatting/#fixed-length-case\n            // for details.\n            prod = ((subsegment * static_cast<uint64_t>(450359963)) >> 20) + 1;\n            digits = static_cast<uint32_t>(prod >> 32);\n            write2digits(buffer, digits);\n            number_of_digits_printed += 2;\n          }\n\n          // Print all digit pairs.\n          while (number_of_digits_printed < number_of_digits_to_print) {\n            prod = static_cast<uint32_t>(prod) * static_cast<uint64_t>(100);\n            digits = static_cast<uint32_t>(prod >> 32);\n            write2digits(buffer + number_of_digits_printed, digits);\n            number_of_digits_printed += 2;\n          }\n        };\n\n        // Print first subsegment.\n        print_subsegment(first_subsegment, buf.data());\n\n        // Perform rounding if the first subsegment is the last subsegment to\n        // print.\n        if (precision <= 9) {\n          // Rounding inside the subsegment.\n          // We round-up if:\n          //  - either the fractional part is strictly larger than 1/2, or\n          //  - the fractional part is exactly 1/2 and the last digit is odd.\n          // We rely on the following observations:\n          //  - If fractional_part >= threshold, then the fractional part is\n          //    strictly larger than 1/2.\n          //  - If the MSB of fractional_part is set, then the fractional part\n          //    must be at least 1/2.\n          //  - When the MSB of fractional_part is set, either\n          //    second_third_subsegments being nonzero or has_more_segments\n          //    being true means there are further digits not printed, so the\n          //    fractional part is strictly larger than 1/2.\n          if (precision < 9) {\n            uint32_t fractional_part = static_cast<uint32_t>(prod);\n            should_round_up =\n                fractional_part >= fractional_part_rounding_thresholds(\n                                       8 - number_of_digits_to_print) ||\n                ((fractional_part >> 31) &\n                 ((digits & 1) | (second_third_subsegments != 0) |\n                  has_more_segments)) != 0;\n          }\n          // Rounding at the subsegment boundary.\n          // In this case, the fractional part is at least 1/2 if and only if\n          // second_third_subsegments >= 5000000000ULL, and is strictly larger\n          // than 1/2 if we further have either second_third_subsegments >\n          // 5000000000ULL or has_more_segments == true.\n          else {\n            should_round_up = second_third_subsegments > 5000000000ULL ||\n                              (second_third_subsegments == 5000000000ULL &&\n                               ((digits & 1) != 0 || has_more_segments));\n          }\n        }\n        // Otherwise, print the second subsegment.\n        else {\n          // Compilers are not aware of how to leverage the maximum value of\n          // second_third_subsegments to find out a better magic number which\n          // allows us to eliminate an additional shift. 1844674407370955162 =\n          // ceil(2^64/10) < ceil(2^64*(10^9/(10^10 - 1))).\n          const uint32_t second_subsegment =\n              static_cast<uint32_t>(dragonbox::umul128_upper64(\n                  second_third_subsegments, 1844674407370955162ULL));\n          const uint32_t third_subsegment =\n              static_cast<uint32_t>(second_third_subsegments) -\n              second_subsegment * 10;\n\n          number_of_digits_to_print = precision - 9;\n          print_subsegment(second_subsegment, buf.data() + 9);\n\n          // Rounding inside the subsegment.\n          if (precision < 18) {\n            // The condition third_subsegment != 0 implies that the segment was\n            // of 19 digits, so in this case the third segment should be\n            // consisting of a genuine digit from the input.\n            uint32_t fractional_part = static_cast<uint32_t>(prod);\n            should_round_up =\n                fractional_part >= fractional_part_rounding_thresholds(\n                                       8 - number_of_digits_to_print) ||\n                ((fractional_part >> 31) &\n                 ((digits & 1) | (third_subsegment != 0) |\n                  has_more_segments)) != 0;\n          }\n          // Rounding at the subsegment boundary.\n          else {\n            // In this case, the segment must be of 19 digits, thus\n            // the third subsegment should be consisting of a genuine digit from\n            // the input.\n            should_round_up = third_subsegment > 5 ||\n                              (third_subsegment == 5 &&\n                               ((digits & 1) != 0 || has_more_segments));\n          }\n        }\n\n        // Round-up if necessary.\n        if (should_round_up) {\n          ++buf[precision - 1];\n          for (int i = precision - 1; i > 0 && buf[i] > '9'; --i) {\n            buf[i] = '0';\n            ++buf[i - 1];\n          }\n          if (buf[0] > '9') {\n            buf[0] = '1';\n            if (fixed)\n              buf[precision++] = '0';\n            else\n              ++exp;\n          }\n        }\n        buf.try_resize(to_unsigned(precision));\n      }\n    }  // if (digits_in_the_first_segment > precision)\n    else {\n      // Adjust the exponent for its use in Dragon4.\n      exp += digits_in_the_first_segment - 1;\n    }\n  }\n  if (use_dragon) {\n    auto f = basic_fp<uint128_t>();\n    bool is_predecessor_closer = binary32 ? f.assign(static_cast<float>(value))\n                                          : f.assign(converted_value);\n    if (is_predecessor_closer) dragon_flags |= dragon::predecessor_closer;\n    if (fixed) dragon_flags |= dragon::fixed;\n    // Limit precision to the maximum possible number of significant digits in\n    // an IEEE754 double because we don't need to generate zeros.\n    const int max_double_digits = 767;\n    if (precision > max_double_digits) precision = max_double_digits;\n    format_dragon(f, dragon_flags, precision, buf, exp);\n  }\n  if (!fixed && !specs.alt()) {\n    // Remove trailing zeros.\n    auto num_digits = buf.size();\n    while (num_digits > 0 && buf[num_digits - 1] == '0') {\n      --num_digits;\n      ++exp;\n    }\n    buf.try_resize(num_digits);\n  }\n  return exp;\n}\n\ntemplate <typename Char, typename OutputIt, typename T,\n          FMT_ENABLE_IF(is_floating_point<T>::value)>\nFMT_CONSTEXPR20 auto write(OutputIt out, T value, format_specs specs,\n                           locale_ref loc = {}) -> OutputIt {\n  if (specs.localized() && write_loc(out, value, specs, loc)) return out;\n\n  // Use signbit because value < 0 is false for NaN.\n  sign s = detail::signbit(value) ? sign::minus : specs.sign();\n\n  if (!detail::isfinite(value))\n    return write_nonfinite<Char>(out, detail::isnan(value), specs, s);\n\n  if (specs.align() == align::numeric && s != sign::none) {\n    *out++ = detail::getsign<Char>(s);\n    s = sign::none;\n    if (specs.width != 0) --specs.width;\n  }\n\n  const int exp_upper = detail::exp_upper<T>();\n  int precision = specs.precision;\n  if (precision < 0) {\n    if (specs.type() != presentation_type::none) {\n      precision = 6;\n    } else if (is_fast_float<T>::value && !is_constant_evaluated()) {\n      // Use Dragonbox for the shortest format.\n      auto dec = dragonbox::to_decimal(static_cast<fast_float_t<T>>(value));\n      return write_float<Char>(out, dec, specs, s, exp_upper, loc);\n    }\n  }\n\n  memory_buffer buffer;\n  if (specs.type() == presentation_type::hexfloat) {\n    if (s != sign::none) buffer.push_back(detail::getsign<char>(s));\n    format_hexfloat(convert_float(value), specs, buffer);\n    return write_bytes<Char, align::right>(out, {buffer.data(), buffer.size()},\n                                           specs);\n  }\n\n  if (specs.type() == presentation_type::exp) {\n    if (precision == max_value<int>())\n      report_error(\"number is too big\");\n    else\n      ++precision;\n    if (specs.precision != 0) specs.set_alt();\n  } else if (specs.type() == presentation_type::fixed) {\n    if (specs.precision != 0) specs.set_alt();\n  } else if (precision == 0) {\n    precision = 1;\n  }\n  int exp = format_float(convert_float(value), precision, specs,\n                         std::is_same<T, float>(), buffer);\n\n  specs.precision = precision;\n  auto f = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};\n  return write_float<Char>(out, f, specs, s, exp_upper, loc);\n}\n\ntemplate <typename Char, typename OutputIt, typename T,\n          FMT_ENABLE_IF(is_fast_float<T>::value)>\nFMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt {\n  if (is_constant_evaluated()) return write<Char>(out, value, format_specs());\n\n  auto s = detail::signbit(value) ? sign::minus : sign::none;\n  auto mask = exponent_mask<fast_float_t<T>>();\n  if ((bit_cast<decltype(mask)>(value) & mask) == mask)\n    return write_nonfinite<Char>(out, std::isnan(value), {}, s);\n\n  auto dec = dragonbox::to_decimal(static_cast<fast_float_t<T>>(value));\n  auto significand = dec.significand;\n  int significand_size = count_digits(significand);\n  int exponent = dec.exponent + significand_size - 1;\n  if (use_fixed(exponent, detail::exp_upper<T>())) {\n    return write_fixed<Char, fallback_digit_grouping<Char>>(\n        out, dec, significand_size, Char('.'), {}, s);\n  }\n\n  // Write value in the exponential format.\n  const char* prefix = \"e+\";\n  int abs_exponent = exponent;\n  if (exponent < 0) {\n    abs_exponent = -exponent;\n    prefix = \"e-\";\n  }\n  auto has_decimal_point = significand_size != 1;\n  size_t size = std::is_pointer<OutputIt>::value\n                    ? 0u\n                    : to_unsigned((s != sign::none ? 1 : 0) + significand_size +\n                                  (has_decimal_point ? 1 : 0) +\n                                  (abs_exponent >= 100 ? 5 : 4));\n  if (auto ptr = to_pointer<Char>(out, size)) {\n    if (s != sign::none) *ptr++ = Char('-');\n    if (has_decimal_point) {\n      auto begin = ptr;\n      ptr = format_decimal<Char>(ptr, significand, significand_size + 1);\n      *begin = begin[1];\n      begin[1] = '.';\n    } else {\n      *ptr++ = static_cast<Char>('0' + significand);\n    }\n    if (std::is_same<Char, char>::value) {\n      memcpy(ptr, prefix, 2);\n      ptr += 2;\n    } else {\n      *ptr++ = prefix[0];\n      *ptr++ = prefix[1];\n    }\n    if (abs_exponent >= 100) {\n      *ptr++ = static_cast<Char>('0' + abs_exponent / 100);\n      abs_exponent %= 100;\n    }\n    write2digits(ptr, static_cast<unsigned>(abs_exponent));\n    return select<std::is_pointer<OutputIt>::value>(ptr + 2, out);\n  }\n  auto it = reserve(out, size);\n  if (s != sign::none) *it++ = Char('-');\n  // Insert a decimal point after the first digit and add an exponent.\n  it = write_significand(it, significand, significand_size, 1,\n                         has_decimal_point ? Char('.') : Char());\n  *it++ = Char('e');\n  it = write_exponent<Char>(exponent, it);\n  return base_iterator(out, it);\n}\n\ntemplate <typename Char, typename OutputIt, typename T,\n          FMT_ENABLE_IF(is_floating_point<T>::value &&\n                        !is_fast_float<T>::value)>\ninline auto write(OutputIt out, T value) -> OutputIt {\n  return write<Char>(out, value, {});\n}\n\ntemplate <typename Char, typename OutputIt>\nauto write(OutputIt out, monostate, format_specs = {}, locale_ref = {})\n    -> OutputIt {\n  FMT_ASSERT(false, \"\");\n  return out;\n}\n\ntemplate <typename Char, typename OutputIt>\nFMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> value)\n    -> OutputIt {\n  return copy_noinline<Char>(value.begin(), value.end(), out);\n}\n\ntemplate <typename Char, typename OutputIt, typename T,\n          FMT_ENABLE_IF(has_to_string_view<T>::value)>\nconstexpr auto write(OutputIt out, const T& value) -> OutputIt {\n  return write<Char>(out, to_string_view(value));\n}\n\n// FMT_ENABLE_IF() condition separated to workaround an MSVC bug.\ntemplate <\n    typename Char, typename OutputIt, typename T,\n    bool check = std::is_enum<T>::value && !std::is_same<T, Char>::value &&\n                 mapped_type_constant<T, Char>::value != type::custom_type,\n    FMT_ENABLE_IF(check)>\nFMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {\n  return write<Char>(out, static_cast<underlying_t<T>>(value));\n}\n\ntemplate <typename Char, typename OutputIt, typename T,\n          FMT_ENABLE_IF(std::is_same<T, bool>::value)>\nFMT_CONSTEXPR auto write(OutputIt out, T value, const format_specs& specs = {},\n                         locale_ref = {}) -> OutputIt {\n  return specs.type() != presentation_type::none &&\n                 specs.type() != presentation_type::string\n             ? write<Char>(out, value ? 1 : 0, specs, {})\n             : write_bytes<Char>(out, value ? \"true\" : \"false\", specs);\n}\n\ntemplate <typename Char, typename OutputIt>\nFMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt {\n  auto it = reserve(out, 1);\n  *it++ = value;\n  return base_iterator(out, it);\n}\n\ntemplate <typename Char, typename OutputIt>\nFMT_CONSTEXPR20 auto write(OutputIt out, const Char* value) -> OutputIt {\n  if (value) return write(out, basic_string_view<Char>(value));\n  report_error(\"string pointer is null\");\n  return out;\n}\n\ntemplate <typename Char, typename OutputIt, typename T,\n          FMT_ENABLE_IF(std::is_same<T, void>::value)>\nauto write(OutputIt out, const T* value, const format_specs& specs = {},\n           locale_ref = {}) -> OutputIt {\n  return write_ptr<Char>(out, bit_cast<uintptr_t>(value), &specs);\n}\n\ntemplate <typename Char, typename OutputIt, typename T,\n          FMT_ENABLE_IF(mapped_type_constant<T, Char>::value ==\n                            type::custom_type &&\n                        !std::is_fundamental<T>::value)>\nFMT_CONSTEXPR auto write(OutputIt out, const T& value) -> OutputIt {\n  auto f = formatter<T, Char>();\n  auto parse_ctx = parse_context<Char>({});\n  f.parse(parse_ctx);\n  auto ctx = basic_format_context<OutputIt, Char>(out, {}, {});\n  return f.format(value, ctx);\n}\n\ntemplate <typename T>\nusing is_builtin =\n    bool_constant<std::is_same<T, int>::value || FMT_BUILTIN_TYPES>;\n\n// An argument visitor that formats the argument and writes it via the output\n// iterator. It's a class and not a generic lambda for compatibility with C++11.\ntemplate <typename Char> struct default_arg_formatter {\n  using context = buffered_context<Char>;\n\n  basic_appender<Char> out;\n\n  void operator()(monostate) { report_error(\"argument not found\"); }\n\n  template <typename T, FMT_ENABLE_IF(is_builtin<T>::value)>\n  void operator()(T value) {\n    write<Char>(out, value);\n  }\n\n  template <typename T, FMT_ENABLE_IF(!is_builtin<T>::value)>\n  void operator()(T) {\n    FMT_ASSERT(false, \"\");\n  }\n\n  void operator()(typename basic_format_arg<context>::handle h) {\n    // Use a null locale since the default format must be unlocalized.\n    auto parse_ctx = parse_context<Char>({});\n    auto format_ctx = context(out, {}, {});\n    h.format(parse_ctx, format_ctx);\n  }\n};\n\ntemplate <typename Char> struct arg_formatter {\n  basic_appender<Char> out;\n  const format_specs& specs;\n  FMT_NO_UNIQUE_ADDRESS locale_ref locale;\n\n  template <typename T, FMT_ENABLE_IF(is_builtin<T>::value)>\n  FMT_CONSTEXPR FMT_INLINE void operator()(T value) {\n    detail::write<Char>(out, value, specs, locale);\n  }\n\n  template <typename T, FMT_ENABLE_IF(!is_builtin<T>::value)>\n  void operator()(T) {\n    FMT_ASSERT(false, \"\");\n  }\n\n  void operator()(typename basic_format_arg<buffered_context<Char>>::handle) {\n    // User-defined types are handled separately because they require access\n    // to the parse context.\n  }\n};\n\nstruct dynamic_spec_getter {\n  template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>\n  FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {\n    return is_negative(value) ? ~0ull : static_cast<unsigned long long>(value);\n  }\n\n  template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>\n  FMT_CONSTEXPR auto operator()(T) -> unsigned long long {\n    report_error(\"width/precision is not integer\");\n    return 0;\n  }\n};\n\ntemplate <typename Context>\nFMT_CONSTEXPR void handle_dynamic_spec(\n    arg_id_kind kind, int& value,\n    const arg_ref<typename Context::char_type>& ref, Context& ctx) {\n  if (kind == arg_id_kind::none) return;\n  auto arg =\n      kind == arg_id_kind::index ? ctx.arg(ref.index) : ctx.arg(ref.name);\n  if (!arg) report_error(\"argument not found\");\n  unsigned long long result = arg.visit(dynamic_spec_getter());\n  if (result > to_unsigned(max_value<int>()))\n    report_error(\"width/precision is out of range\");\n  value = static_cast<int>(result);\n}\n\n#if FMT_USE_NONTYPE_TEMPLATE_ARGS\ntemplate <typename T, typename Char, size_t N,\n          fmt::detail::fixed_string<Char, N> Str>\nstruct static_named_arg : view {\n  static constexpr auto name = Str.data;\n\n  const T& value;\n  static_named_arg(const T& v) : value(v) {}\n};\n\ntemplate <typename T, typename Char, size_t N,\n          fmt::detail::fixed_string<Char, N> Str>\nstruct is_named_arg<static_named_arg<T, Char, N, Str>> : std::true_type {};\n\ntemplate <typename T, typename Char, size_t N,\n          fmt::detail::fixed_string<Char, N> Str>\nstruct is_static_named_arg<static_named_arg<T, Char, N, Str>> : std::true_type {\n};\n\ntemplate <typename Char, size_t N, fmt::detail::fixed_string<Char, N> Str>\nstruct udl_arg {\n  template <typename T> auto operator=(T&& value) const {\n    return static_named_arg<T, Char, N, Str>(std::forward<T>(value));\n  }\n};\n#else\ntemplate <typename Char> struct udl_arg {\n  const Char* str;\n\n  template <typename T> auto operator=(T&& value) const -> named_arg<Char, T> {\n    return {str, std::forward<T>(value)};\n  }\n};\n#endif  // FMT_USE_NONTYPE_TEMPLATE_ARGS\n\ntemplate <typename Char = char> struct format_handler {\n  parse_context<Char> parse_ctx;\n  buffered_context<Char> ctx;\n\n  void on_text(const Char* begin, const Char* end) {\n    copy_noinline<Char>(begin, end, ctx.out());\n  }\n\n  FMT_CONSTEXPR auto on_arg_id() -> int { return parse_ctx.next_arg_id(); }\n  FMT_CONSTEXPR auto on_arg_id(int id) -> int {\n    parse_ctx.check_arg_id(id);\n    return id;\n  }\n  FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {\n    parse_ctx.check_arg_id(id);\n    int arg_id = ctx.arg_id(id);\n    if (arg_id < 0) report_error(\"argument not found\");\n    return arg_id;\n  }\n\n  FMT_INLINE void on_replacement_field(int id, const Char*) {\n    ctx.arg(id).visit(default_arg_formatter<Char>{ctx.out()});\n  }\n\n  auto on_format_specs(int id, const Char* begin, const Char* end)\n      -> const Char* {\n    auto arg = ctx.arg(id);\n    if (!arg) report_error(\"argument not found\");\n    // Not using a visitor for custom types gives better codegen.\n    if (arg.format_custom(begin, parse_ctx, ctx)) return parse_ctx.begin();\n\n    auto specs = dynamic_format_specs<Char>();\n    begin = parse_format_specs(begin, end, specs, parse_ctx, arg.type());\n    if (specs.dynamic()) {\n      handle_dynamic_spec(specs.dynamic_width(), specs.width, specs.width_ref,\n                          ctx);\n      handle_dynamic_spec(specs.dynamic_precision(), specs.precision,\n                          specs.precision_ref, ctx);\n    }\n\n    arg.visit(arg_formatter<Char>{ctx.out(), specs, ctx.locale()});\n    return begin;\n  }\n\n  FMT_NORETURN void on_error(const char* message) { report_error(message); }\n};\n\n// It is used in format-inl.h and os.cc.\nusing format_func = void (*)(detail::buffer<char>&, int, const char*);\nFMT_API void do_report_error(format_func func, int error_code,\n                             const char* message) noexcept;\n\nFMT_API void format_error_code(buffer<char>& out, int error_code,\n                               string_view message) noexcept;\n\ntemplate <typename T, typename Char, type TYPE>\ntemplate <typename FormatContext>\nFMT_CONSTEXPR auto native_formatter<T, Char, TYPE>::format(\n    const T& val, FormatContext& ctx) const -> decltype(ctx.out()) {\n  if (!specs_.dynamic())\n    return write<Char>(ctx.out(), val, specs_, ctx.locale());\n  auto specs = format_specs(specs_);\n  handle_dynamic_spec(specs.dynamic_width(), specs.width, specs_.width_ref,\n                      ctx);\n  handle_dynamic_spec(specs.dynamic_precision(), specs.precision,\n                      specs_.precision_ref, ctx);\n  return write<Char>(ctx.out(), val, specs, ctx.locale());\n}\n}  // namespace detail\n\nFMT_BEGIN_EXPORT\n\n// A generic formatting context with custom output iterator and character\n// (code unit) support. Char is the format string code unit type which can be\n// different from OutputIt::value_type.\ntemplate <typename OutputIt, typename Char> class generic_context {\n private:\n  OutputIt out_;\n  basic_format_args<generic_context> args_;\n  locale_ref loc_;\n\n public:\n  using char_type = Char;\n  using iterator = OutputIt;\n  enum { builtin_types = FMT_BUILTIN_TYPES };\n\n  constexpr generic_context(OutputIt out,\n                            basic_format_args<generic_context> args,\n                            locale_ref loc = {})\n      : out_(out), args_(args), loc_(loc) {}\n  generic_context(generic_context&&) = default;\n  generic_context(const generic_context&) = delete;\n  void operator=(const generic_context&) = delete;\n\n  constexpr auto arg(int id) const -> basic_format_arg<generic_context> {\n    return args_.get(id);\n  }\n  auto arg(basic_string_view<Char> name) const\n      -> basic_format_arg<generic_context> {\n    return args_.get(name);\n  }\n  constexpr auto arg_id(basic_string_view<Char> name) const -> int {\n    return args_.get_id(name);\n  }\n\n  constexpr auto out() const -> iterator { return out_; }\n\n  void advance_to(iterator it) {\n    if (!detail::is_back_insert_iterator<iterator>()) out_ = it;\n  }\n\n  constexpr auto locale() const -> locale_ref { return loc_; }\n};\n\nclass loc_value {\n private:\n  basic_format_arg<context> value_;\n\n public:\n  template <typename T, FMT_ENABLE_IF(!detail::is_float128<T>::value)>\n  loc_value(T value) : value_(value) {}\n\n  template <typename T, FMT_ENABLE_IF(detail::is_float128<T>::value)>\n  loc_value(T) {}\n\n  template <typename Visitor> auto visit(Visitor&& vis) -> decltype(vis(0)) {\n    return value_.visit(vis);\n  }\n};\n\n// A locale facet that formats values in UTF-8.\n// It is parameterized on the locale to avoid the heavy <locale> include.\ntemplate <typename Locale> class format_facet : public Locale::facet {\n private:\n  std::string separator_;\n  std::string grouping_;\n  std::string decimal_point_;\n\n protected:\n  virtual auto do_put(appender out, loc_value val,\n                      const format_specs& specs) const -> bool;\n\n public:\n  static FMT_API typename Locale::id id;\n\n  explicit format_facet(Locale& loc);\n  explicit format_facet(string_view sep = \"\", std::string grouping = \"\\3\",\n                        std::string decimal_point = \".\")\n      : separator_(sep.data(), sep.size()),\n        grouping_(grouping),\n        decimal_point_(decimal_point) {}\n\n  auto put(appender out, loc_value val, const format_specs& specs) const\n      -> bool {\n    return do_put(out, val, specs);\n  }\n};\n\n#define FMT_FORMAT_AS(Type, Base)                                   \\\n  template <typename Char>                                          \\\n  struct formatter<Type, Char> : formatter<Base, Char> {            \\\n    template <typename FormatContext>                               \\\n    FMT_CONSTEXPR auto format(Type value, FormatContext& ctx) const \\\n        -> decltype(ctx.out()) {                                    \\\n      return formatter<Base, Char>::format(value, ctx);             \\\n    }                                                               \\\n  }\n\nFMT_FORMAT_AS(signed char, int);\nFMT_FORMAT_AS(unsigned char, unsigned);\nFMT_FORMAT_AS(short, int);\nFMT_FORMAT_AS(unsigned short, unsigned);\nFMT_FORMAT_AS(long, detail::long_type);\nFMT_FORMAT_AS(unsigned long, detail::ulong_type);\nFMT_FORMAT_AS(Char*, const Char*);\nFMT_FORMAT_AS(detail::std_string_view<Char>, basic_string_view<Char>);\nFMT_FORMAT_AS(std::nullptr_t, const void*);\nFMT_FORMAT_AS(void*, const void*);\n\ntemplate <typename Char, size_t N>\nstruct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> {};\n\ntemplate <typename Char, typename Traits, typename Allocator>\nclass formatter<std::basic_string<Char, Traits, Allocator>, Char>\n    : public formatter<basic_string_view<Char>, Char> {};\n\ntemplate <int N, typename Char>\nstruct formatter<detail::bitint<N>, Char> : formatter<long long, Char> {};\ntemplate <int N, typename Char>\nstruct formatter<detail::ubitint<N>, Char>\n    : formatter<unsigned long long, Char> {};\n\ntemplate <typename Char>\nstruct formatter<detail::float128, Char>\n    : detail::native_formatter<detail::float128, Char,\n                               detail::type::float_type> {};\n\ntemplate <typename T, typename Char>\nstruct formatter<T, Char, void_t<detail::format_as_result<T>>>\n    : formatter<detail::format_as_result<T>, Char> {\n  template <typename FormatContext>\n  FMT_CONSTEXPR auto format(const T& value, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    auto&& val = format_as(value);  // Make an lvalue reference for format.\n    return formatter<detail::format_as_result<T>, Char>::format(val, ctx);\n  }\n};\n\n/**\n * Converts `p` to `const void*` for pointer formatting.\n *\n * **Example**:\n *\n *     auto s = fmt::format(\"{}\", fmt::ptr(p));\n */\ntemplate <typename T> auto ptr(T p) -> const void* {\n  static_assert(std::is_pointer<T>::value, \"fmt::ptr used with non-pointer\");\n  return detail::bit_cast<const void*>(p);\n}\n\n/**\n * Converts `e` to the underlying type.\n *\n * **Example**:\n *\n *     enum class color { red, green, blue };\n *     auto s = fmt::format(\"{}\", fmt::underlying(color::red));  // s == \"0\"\n */\ntemplate <typename Enum>\nconstexpr auto underlying(Enum e) noexcept -> underlying_t<Enum> {\n  return static_cast<underlying_t<Enum>>(e);\n}\n\nnamespace enums {\ntemplate <typename Enum, FMT_ENABLE_IF(std::is_enum<Enum>::value)>\nconstexpr auto format_as(Enum e) noexcept -> underlying_t<Enum> {\n  return static_cast<underlying_t<Enum>>(e);\n}\n}  // namespace enums\n\n#ifdef __cpp_lib_byte\ntemplate <typename Char>\nstruct formatter<std::byte, Char> : formatter<unsigned, Char> {\n  static auto format_as(std::byte b) -> unsigned char {\n    return static_cast<unsigned char>(b);\n  }\n  template <typename Context>\n  auto format(std::byte b, Context& ctx) const -> decltype(ctx.out()) {\n    return formatter<unsigned, Char>::format(format_as(b), ctx);\n  }\n};\n#endif\n\nstruct bytes {\n  string_view data;\n\n  inline explicit bytes(string_view s) : data(s) {}\n};\n\ntemplate <> struct formatter<bytes> {\n private:\n  detail::dynamic_format_specs<> specs_;\n\n public:\n  FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {\n    return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,\n                              detail::type::string_type);\n  }\n\n  template <typename FormatContext>\n  auto format(bytes b, FormatContext& ctx) const -> decltype(ctx.out()) {\n    auto specs = specs_;\n    detail::handle_dynamic_spec(specs.dynamic_width(), specs.width,\n                                specs.width_ref, ctx);\n    detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision,\n                                specs.precision_ref, ctx);\n    return detail::write_bytes<char>(ctx.out(), b.data, specs);\n  }\n};\n\n// group_digits_view is not derived from view because it copies the argument.\ntemplate <typename T> struct group_digits_view {\n  T value;\n};\n\n/**\n * Returns a view that formats an integer value using ',' as a\n * locale-independent thousands separator.\n *\n * **Example**:\n *\n *     fmt::print(\"{}\", fmt::group_digits(12345));\n *     // Output: \"12,345\"\n */\ntemplate <typename T> auto group_digits(T value) -> group_digits_view<T> {\n  return {value};\n}\n\ntemplate <typename T> struct formatter<group_digits_view<T>> : formatter<T> {\n private:\n  detail::dynamic_format_specs<> specs_;\n\n public:\n  FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {\n    return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,\n                              detail::type::int_type);\n  }\n\n  template <typename FormatContext>\n  auto format(group_digits_view<T> view, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    auto specs = specs_;\n    detail::handle_dynamic_spec(specs.dynamic_width(), specs.width,\n                                specs.width_ref, ctx);\n    detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision,\n                                specs.precision_ref, ctx);\n    auto arg = detail::make_write_int_arg(view.value, specs.sign());\n    return detail::write_int(\n        ctx.out(), static_cast<detail::uint64_or_128_t<T>>(arg.abs_value),\n        arg.prefix, specs, detail::digit_grouping<char>(\"\\3\", \",\"));\n  }\n};\n\ntemplate <typename T, typename Char> struct nested_view {\n  const formatter<T, Char>* fmt;\n  const T* value;\n};\n\ntemplate <typename T, typename Char>\nstruct formatter<nested_view<T, Char>, Char> {\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    return ctx.begin();\n  }\n  template <typename FormatContext>\n  auto format(nested_view<T, Char> view, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    return view.fmt->format(*view.value, ctx);\n  }\n};\n\ntemplate <typename T, typename Char = char> struct nested_formatter {\n private:\n  basic_specs specs_;\n  int width_;\n  formatter<T, Char> formatter_;\n\n public:\n  constexpr nested_formatter() : width_(0) {}\n\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    auto it = ctx.begin(), end = ctx.end();\n    if (it == end) return it;\n    auto specs = format_specs();\n    it = detail::parse_align(it, end, specs);\n    specs_ = specs;\n    Char c = *it;\n    auto width_ref = detail::arg_ref<Char>();\n    if ((c >= '0' && c <= '9') || c == '{') {\n      it = detail::parse_width(it, end, specs, width_ref, ctx);\n      width_ = specs.width;\n    }\n    ctx.advance_to(it);\n    return formatter_.parse(ctx);\n  }\n\n  template <typename FormatContext, typename F>\n  auto write_padded(FormatContext& ctx, F write) const -> decltype(ctx.out()) {\n    if (width_ == 0) return write(ctx.out());\n    auto buf = basic_memory_buffer<Char>();\n    write(basic_appender<Char>(buf));\n    auto specs = format_specs();\n    specs.width = width_;\n    specs.copy_fill_from(specs_);\n    specs.set_align(specs_.align());\n    return detail::write<Char>(\n        ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs);\n  }\n\n  auto nested(const T& value) const -> nested_view<T, Char> {\n    return nested_view<T, Char>{&formatter_, &value};\n  }\n};\n\ninline namespace literals {\n#if FMT_USE_NONTYPE_TEMPLATE_ARGS\ntemplate <detail::fixed_string S> constexpr auto operator\"\"_a() {\n  using char_t = remove_cvref_t<decltype(*S.data)>;\n  return detail::udl_arg<char_t, sizeof(S.data) / sizeof(char_t), S>();\n}\n#else\n/**\n * User-defined literal equivalent of `fmt::arg`.\n *\n * **Example**:\n *\n *     using namespace fmt::literals;\n *     fmt::print(\"The answer is {answer}.\", \"answer\"_a=42);\n */\nconstexpr auto operator\"\"_a(const char* s, size_t) -> detail::udl_arg<char> {\n  return {s};\n}\n#endif  // FMT_USE_NONTYPE_TEMPLATE_ARGS\n}  // namespace literals\n\n/// A fast integer formatter.\nclass format_int {\n private:\n  // Buffer should be large enough to hold all digits (digits10 + 1),\n  // a sign and a null character.\n  enum { buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3 };\n  mutable char buffer_[buffer_size];\n  char* str_;\n\n  template <typename UInt>\n  FMT_CONSTEXPR20 auto format_unsigned(UInt value) -> char* {\n    auto n = static_cast<detail::uint32_or_64_or_128_t<UInt>>(value);\n    return detail::do_format_decimal(buffer_, n, buffer_size - 1);\n  }\n\n  template <typename Int>\n  FMT_CONSTEXPR20 auto format_signed(Int value) -> char* {\n    auto abs_value = static_cast<detail::uint32_or_64_or_128_t<Int>>(value);\n    bool negative = value < 0;\n    if (negative) abs_value = 0 - abs_value;\n    auto begin = format_unsigned(abs_value);\n    if (negative) *--begin = '-';\n    return begin;\n  }\n\n public:\n  FMT_CONSTEXPR20 explicit format_int(int value) : str_(format_signed(value)) {}\n  FMT_CONSTEXPR20 explicit format_int(long value)\n      : str_(format_signed(value)) {}\n  FMT_CONSTEXPR20 explicit format_int(long long value)\n      : str_(format_signed(value)) {}\n  FMT_CONSTEXPR20 explicit format_int(unsigned value)\n      : str_(format_unsigned(value)) {}\n  FMT_CONSTEXPR20 explicit format_int(unsigned long value)\n      : str_(format_unsigned(value)) {}\n  FMT_CONSTEXPR20 explicit format_int(unsigned long long value)\n      : str_(format_unsigned(value)) {}\n\n  /// Returns the number of characters written to the output buffer.\n  FMT_CONSTEXPR20 auto size() const -> size_t {\n    return detail::to_unsigned(buffer_ - str_ + buffer_size - 1);\n  }\n\n  /// Returns a pointer to the output buffer content. No terminating null\n  /// character is appended.\n  FMT_CONSTEXPR20 auto data() const -> const char* { return str_; }\n\n  /// Returns a pointer to the output buffer content with terminating null\n  /// character appended.\n  FMT_CONSTEXPR20 auto c_str() const -> const char* {\n    buffer_[buffer_size - 1] = '\\0';\n    return str_;\n  }\n\n  /// Returns the content of the output buffer as an `std::string`.\n  inline auto str() const -> std::string { return {str_, size()}; }\n};\n\n#if FMT_CLANG_ANALYZER\n#  define FMT_STRING_IMPL(s, base) s\n#else\n#  define FMT_STRING_IMPL(s, base)                                           \\\n    [] {                                                                     \\\n      /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \\\n      /* Use a macro-like name to avoid shadowing warnings. */               \\\n      struct FMT_VISIBILITY(\"hidden\") FMT_COMPILE_STRING : base {            \\\n        using char_type = fmt::remove_cvref_t<decltype(s[0])>;               \\\n        constexpr explicit operator fmt::basic_string_view<char_type>()      \\\n            const {                                                          \\\n          return fmt::detail::compile_string_to_view<char_type>(s);          \\\n        }                                                                    \\\n      };                                                                     \\\n      using FMT_STRING_VIEW =                                                \\\n          fmt::basic_string_view<typename FMT_COMPILE_STRING::char_type>;    \\\n      fmt::detail::ignore_unused(FMT_STRING_VIEW(FMT_COMPILE_STRING()));     \\\n      return FMT_COMPILE_STRING();                                           \\\n    }()\n#endif  // FMT_CLANG_ANALYZER\n\n/**\n * Constructs a legacy compile-time format string from a string literal `s`.\n *\n * **Example**:\n *\n *     // A compile-time error because 'd' is an invalid specifier for strings.\n *     std::string s = fmt::format(FMT_STRING(\"{:d}\"), \"foo\");\n */\n#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string)\n\nFMT_API auto vsystem_error(int error_code, string_view fmt, format_args args)\n    -> std::system_error;\n\n/**\n * Constructs `std::system_error` with a message formatted with\n * `fmt::format(fmt, args...)`.\n * `error_code` is a system error code as given by `errno`.\n *\n * **Example**:\n *\n *     // This throws std::system_error with the description\n *     //   cannot open file 'madeup': No such file or directory\n *     // or similar (system message may vary).\n *     const char* filename = \"madeup\";\n *     FILE* file = fopen(filename, \"r\");\n *     if (!file)\n *       throw fmt::system_error(errno, \"cannot open file '{}'\", filename);\n */\ntemplate <typename... T>\nauto system_error(int error_code, format_string<T...> fmt, T&&... args)\n    -> std::system_error {\n  return vsystem_error(error_code, fmt.str, vargs<T...>{{args...}});\n}\n\n/**\n * Formats an error message for an error returned by an operating system or a\n * language runtime, for example a file opening error, and writes it to `out`.\n * The format is the same as the one used by `std::system_error(ec, message)`\n * where `ec` is `std::error_code(error_code, std::generic_category())`.\n * It is implementation-defined but normally looks like:\n *\n *     <message>: <system-message>\n *\n * where `<message>` is the passed message and `<system-message>` is the system\n * message corresponding to the error code.\n * `error_code` is a system error code as given by `errno`.\n */\nFMT_API void format_system_error(detail::buffer<char>& out, int error_code,\n                                 const char* message) noexcept;\n\n// Reports a system error without throwing an exception.\n// Can be used to report errors from destructors.\nFMT_API void report_system_error(int error_code, const char* message) noexcept;\n\ninline auto vformat(locale_ref loc, string_view fmt, format_args args)\n    -> std::string {\n  auto buf = memory_buffer();\n  detail::vformat_to(buf, fmt, args, loc);\n  return {buf.data(), buf.size()};\n}\n\ntemplate <typename... T>\nFMT_INLINE auto format(locale_ref loc, format_string<T...> fmt, T&&... args)\n    -> std::string {\n  return vformat(loc, fmt.str, vargs<T...>{{args...}});\n}\n\ntemplate <typename OutputIt,\n          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>\nauto vformat_to(OutputIt out, locale_ref loc, string_view fmt, format_args args)\n    -> OutputIt {\n  auto&& buf = detail::get_buffer<char>(out);\n  detail::vformat_to(buf, fmt, args, loc);\n  return detail::get_iterator(buf, out);\n}\n\ntemplate <typename OutputIt, typename... T,\n          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>\nFMT_INLINE auto format_to(OutputIt out, locale_ref loc, format_string<T...> fmt,\n                          T&&... args) -> OutputIt {\n  return fmt::vformat_to(out, loc, fmt.str, vargs<T...>{{args...}});\n}\n\ntemplate <typename... T>\nFMT_NODISCARD FMT_INLINE auto formatted_size(locale_ref loc,\n                                             format_string<T...> fmt,\n                                             T&&... args) -> size_t {\n  auto buf = detail::counting_buffer<>();\n  detail::vformat_to(buf, fmt.str, vargs<T...>{{args...}}, loc);\n  return buf.count();\n}\n\nFMT_API auto vformat(string_view fmt, format_args args) -> std::string;\n\n/**\n * Formats `args` according to specifications in `fmt` and returns the result\n * as a string.\n *\n * **Example**:\n *\n *     #include <fmt/format.h>\n *     std::string message = fmt::format(\"The answer is {}.\", 42);\n */\ntemplate <typename... T>\nFMT_NODISCARD FMT_INLINE auto format(format_string<T...> fmt, T&&... args)\n    -> std::string {\n  return vformat(fmt.str, vargs<T...>{{args...}});\n}\n\n/**\n * Converts `value` to `std::string` using the default format for type `T`.\n *\n * **Example**:\n *\n *     std::string answer = fmt::to_string(42);\n */\ntemplate <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>\nFMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(T value) -> std::string {\n  // The buffer should be large enough to store the number including the sign\n  // or \"false\" for bool.\n  char buffer[max_of(detail::digits10<T>() + 2, 5)];\n  return {buffer, detail::write<char>(buffer, value)};\n}\n\ntemplate <typename T, FMT_ENABLE_IF(detail::use_format_as<T>::value)>\nFMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(const T& value)\n    -> std::string {\n  return to_string(format_as(value));\n}\n\ntemplate <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value &&\n                                    !detail::use_format_as<T>::value)>\nFMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(const T& value)\n    -> std::string {\n  auto buffer = memory_buffer();\n  detail::write<char>(appender(buffer), value);\n  return {buffer.data(), buffer.size()};\n}\n\nFMT_END_EXPORT\nFMT_END_NAMESPACE\n\n#ifdef FMT_HEADER_ONLY\n#  define FMT_FUNC inline\n#  include \"format-inl.h\"\n#endif\n\n// Restore _LIBCPP_REMOVE_TRANSITIVE_INCLUDES.\n#ifdef FMT_REMOVE_TRANSITIVE_INCLUDES\n#  undef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES\n#endif\n\n#endif  // FMT_FORMAT_H_\n"
  },
  {
    "path": "thirdparty/fmt/include/fmt/os.h",
    "content": "// Formatting library for C++ - optional OS-specific functionality\n//\n// Copyright (c) 2012 - present, Victor Zverovich\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\n#ifndef FMT_OS_H_\n#define FMT_OS_H_\n\n#include \"format.h\"\n\n#ifndef FMT_MODULE\n#  include <cerrno>\n#  include <cstddef>\n#  include <cstdio>\n#  include <system_error>  // std::system_error\n\n#  if FMT_HAS_INCLUDE(<xlocale.h>)\n#    include <xlocale.h>  // LC_NUMERIC_MASK on macOS\n#  endif\n#endif  // FMT_MODULE\n\n#ifndef FMT_USE_FCNTL\n// UWP doesn't provide _pipe.\n#  if FMT_HAS_INCLUDE(\"winapifamily.h\")\n#    include <winapifamily.h>\n#  endif\n#  if (FMT_HAS_INCLUDE(<fcntl.h>) || defined(__APPLE__) || \\\n       defined(__linux__)) &&                              \\\n      (!defined(WINAPI_FAMILY) ||                          \\\n       (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)) &&    \\\n      !defined(__wasm__)\n#    include <fcntl.h>  // for O_RDONLY\n#    define FMT_USE_FCNTL 1\n#  else\n#    define FMT_USE_FCNTL 0\n#  endif\n#endif\n\n#ifndef FMT_POSIX\n#  if defined(_WIN32) && !defined(__MINGW32__)\n// Fix warnings about deprecated symbols.\n#    define FMT_POSIX(call) _##call\n#  else\n#    define FMT_POSIX(call) call\n#  endif\n#endif\n\n// Calls to system functions are wrapped in FMT_SYSTEM for testability.\n#ifdef FMT_SYSTEM\n#  define FMT_HAS_SYSTEM\n#  define FMT_POSIX_CALL(call) FMT_SYSTEM(call)\n#else\n#  define FMT_SYSTEM(call) ::call\n#  ifdef _WIN32\n// Fix warnings about deprecated symbols.\n#    define FMT_POSIX_CALL(call) ::_##call\n#  else\n#    define FMT_POSIX_CALL(call) ::call\n#  endif\n#endif\n\n// Retries the expression while it evaluates to error_result and errno\n// equals to EINTR.\n#ifndef _WIN32\n#  define FMT_RETRY_VAL(result, expression, error_result) \\\n    do {                                                  \\\n      (result) = (expression);                            \\\n    } while ((result) == (error_result) && errno == EINTR)\n#else\n#  define FMT_RETRY_VAL(result, expression, error_result) result = (expression)\n#endif\n\n#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)\n\nFMT_BEGIN_NAMESPACE\nFMT_BEGIN_EXPORT\n\n/**\n * A reference to a null-terminated string. It can be constructed from a C\n * string or `std::string`.\n *\n * You can use one of the following type aliases for common character types:\n *\n * +---------------+-----------------------------+\n * | Type          | Definition                  |\n * +===============+=============================+\n * | cstring_view  | basic_cstring_view<char>    |\n * +---------------+-----------------------------+\n * | wcstring_view | basic_cstring_view<wchar_t> |\n * +---------------+-----------------------------+\n *\n * This class is most useful as a parameter type for functions that wrap C APIs.\n */\ntemplate <typename Char> class basic_cstring_view {\n private:\n  const Char* data_;\n\n public:\n  /// Constructs a string reference object from a C string.\n  basic_cstring_view(const Char* s) : data_(s) {}\n\n  /// Constructs a string reference from an `std::string` object.\n  basic_cstring_view(const std::basic_string<Char>& s) : data_(s.c_str()) {}\n\n  /// Returns the pointer to a C string.\n  auto c_str() const -> const Char* { return data_; }\n};\n\nusing cstring_view = basic_cstring_view<char>;\nusing wcstring_view = basic_cstring_view<wchar_t>;\n\n#ifdef _WIN32\nFMT_API const std::error_category& system_category() noexcept;\n\nnamespace detail {\nFMT_API void format_windows_error(buffer<char>& out, int error_code,\n                                  const char* message) noexcept;\n}\n\nFMT_API std::system_error vwindows_error(int error_code, string_view fmt,\n                                         format_args args);\n\n/**\n * Constructs a `std::system_error` object with the description of the form\n *\n *     <message>: <system-message>\n *\n * where `<message>` is the formatted message and `<system-message>` is the\n * system message corresponding to the error code.\n * `error_code` is a Windows error code as given by `GetLastError`.\n * If `error_code` is not a valid error code such as -1, the system message\n * will look like \"error -1\".\n *\n * **Example**:\n *\n *     // This throws a system_error with the description\n *     //   cannot open file 'foo': The system cannot find the file specified.\n *     // or similar (system message may vary) if the file doesn't exist.\n *     const char *filename = \"foo\";\n *     LPOFSTRUCT of = LPOFSTRUCT();\n *     HFILE file = OpenFile(filename, &of, OF_READ);\n *     if (file == HFILE_ERROR) {\n *       throw fmt::windows_error(GetLastError(),\n *                                \"cannot open file '{}'\", filename);\n *     }\n */\ntemplate <typename... T>\nauto windows_error(int error_code, string_view message, const T&... args)\n    -> std::system_error {\n  return vwindows_error(error_code, message, vargs<T...>{{args...}});\n}\n\n// Reports a Windows error without throwing an exception.\n// Can be used to report errors from destructors.\nFMT_API void report_windows_error(int error_code, const char* message) noexcept;\n#else\ninline auto system_category() noexcept -> const std::error_category& {\n  return std::system_category();\n}\n#endif  // _WIN32\n\n// std::system is not available on some platforms such as iOS (#2248).\n#ifdef __OSX__\ntemplate <typename S, typename... Args, typename Char = char_t<S>>\nvoid say(const S& fmt, Args&&... args) {\n  std::system(format(\"say \\\"{}\\\"\", format(fmt, args...)).c_str());\n}\n#endif\n\n// A buffered file.\nclass buffered_file {\n private:\n  FILE* file_;\n\n  friend class file;\n\n  inline explicit buffered_file(FILE* f) : file_(f) {}\n\n public:\n  buffered_file(const buffered_file&) = delete;\n  void operator=(const buffered_file&) = delete;\n\n  // Constructs a buffered_file object which doesn't represent any file.\n  inline buffered_file() noexcept : file_(nullptr) {}\n\n  // Destroys the object closing the file it represents if any.\n  FMT_API ~buffered_file() noexcept;\n\n public:\n  inline buffered_file(buffered_file&& other) noexcept : file_(other.file_) {\n    other.file_ = nullptr;\n  }\n\n  inline auto operator=(buffered_file&& other) -> buffered_file& {\n    close();\n    file_ = other.file_;\n    other.file_ = nullptr;\n    return *this;\n  }\n\n  // Opens a file.\n  FMT_API buffered_file(cstring_view filename, cstring_view mode);\n\n  // Closes the file.\n  FMT_API void close();\n\n  // Returns the pointer to a FILE object representing this file.\n  inline auto get() const noexcept -> FILE* { return file_; }\n\n  FMT_API auto descriptor() const -> int;\n\n  template <typename... T>\n  inline void print(string_view fmt, const T&... args) {\n    fmt::vargs<T...> vargs = {{args...}};\n    detail::is_locking<T...>() ? fmt::vprint_buffered(file_, fmt, vargs)\n                               : fmt::vprint(file_, fmt, vargs);\n  }\n};\n\n#if FMT_USE_FCNTL\n\n// A file. Closed file is represented by a file object with descriptor -1.\n// Methods that are not declared with noexcept may throw\n// fmt::system_error in case of failure. Note that some errors such as\n// closing the file multiple times will cause a crash on Windows rather\n// than an exception. You can get standard behavior by overriding the\n// invalid parameter handler with _set_invalid_parameter_handler.\nclass FMT_API file {\n private:\n  int fd_;  // File descriptor.\n\n  // Constructs a file object with a given descriptor.\n  explicit file(int fd) : fd_(fd) {}\n\n  friend struct pipe;\n\n public:\n  // Possible values for the oflag argument to the constructor.\n  enum {\n    RDONLY = FMT_POSIX(O_RDONLY),  // Open for reading only.\n    WRONLY = FMT_POSIX(O_WRONLY),  // Open for writing only.\n    RDWR = FMT_POSIX(O_RDWR),      // Open for reading and writing.\n    CREATE = FMT_POSIX(O_CREAT),   // Create if the file doesn't exist.\n    APPEND = FMT_POSIX(O_APPEND),  // Open in append mode.\n    TRUNC = FMT_POSIX(O_TRUNC)     // Truncate the content of the file.\n  };\n\n  // Constructs a file object which doesn't represent any file.\n  inline file() noexcept : fd_(-1) {}\n\n  // Opens a file and constructs a file object representing this file.\n  file(cstring_view path, int oflag);\n\n public:\n  file(const file&) = delete;\n  void operator=(const file&) = delete;\n\n  inline file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; }\n\n  // Move assignment is not noexcept because close may throw.\n  inline auto operator=(file&& other) -> file& {\n    close();\n    fd_ = other.fd_;\n    other.fd_ = -1;\n    return *this;\n  }\n\n  // Destroys the object closing the file it represents if any.\n  ~file() noexcept;\n\n  // Returns the file descriptor.\n  inline auto descriptor() const noexcept -> int { return fd_; }\n\n  // Closes the file.\n  void close();\n\n  // Returns the file size. The size has signed type for consistency with\n  // stat::st_size.\n  auto size() const -> long long;\n\n  // Attempts to read count bytes from the file into the specified buffer.\n  auto read(void* buffer, size_t count) -> size_t;\n\n  // Attempts to write count bytes from the specified buffer to the file.\n  auto write(const void* buffer, size_t count) -> size_t;\n\n  // Duplicates a file descriptor with the dup function and returns\n  // the duplicate as a file object.\n  static auto dup(int fd) -> file;\n\n  // Makes fd be the copy of this file descriptor, closing fd first if\n  // necessary.\n  void dup2(int fd);\n\n  // Makes fd be the copy of this file descriptor, closing fd first if\n  // necessary.\n  void dup2(int fd, std::error_code& ec) noexcept;\n\n  // Creates a buffered_file object associated with this file and detaches\n  // this file object from the file.\n  auto fdopen(const char* mode) -> buffered_file;\n\n#  if defined(_WIN32) && !defined(__MINGW32__)\n  // Opens a file and constructs a file object representing this file by\n  // wcstring_view filename. Windows only.\n  static file open_windows_file(wcstring_view path, int oflag);\n#  endif\n};\n\nstruct FMT_API pipe {\n  file read_end;\n  file write_end;\n\n  // Creates a pipe setting up read_end and write_end file objects for reading\n  // and writing respectively.\n  pipe();\n};\n\n// Returns the memory page size.\nauto getpagesize() -> long;\n\nnamespace detail {\n\nstruct buffer_size {\n  constexpr buffer_size() = default;\n  size_t value = 0;\n  FMT_CONSTEXPR auto operator=(size_t val) const -> buffer_size {\n    auto bs = buffer_size();\n    bs.value = val;\n    return bs;\n  }\n};\n\nstruct ostream_params {\n  int oflag = file::WRONLY | file::CREATE | file::TRUNC;\n  size_t buffer_size = BUFSIZ > 32768 ? BUFSIZ : 32768;\n\n  constexpr ostream_params() {}\n\n  template <typename... T>\n  ostream_params(T... params, int new_oflag) : ostream_params(params...) {\n    oflag = new_oflag;\n  }\n\n  template <typename... T>\n  ostream_params(T... params, detail::buffer_size bs)\n      : ostream_params(params...) {\n    this->buffer_size = bs.value;\n  }\n\n// Intel has a bug that results in failure to deduce a constructor\n// for empty parameter packs.\n#  if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 2000\n  ostream_params(int new_oflag) : oflag(new_oflag) {}\n  ostream_params(detail::buffer_size bs) : buffer_size(bs.value) {}\n#  endif\n};\n\n}  // namespace detail\n\nFMT_INLINE_VARIABLE constexpr auto buffer_size = detail::buffer_size();\n\n/// A fast buffered output stream for writing from a single thread. Writing from\n/// multiple threads without external synchronization may result in a data race.\nclass ostream : private detail::buffer<char> {\n private:\n  file file_;\n\n  FMT_API ostream(cstring_view path, const detail::ostream_params& params);\n\n  FMT_API static void grow(buffer<char>& buf, size_t);\n\n public:\n  FMT_API ostream(ostream&& other) noexcept;\n  FMT_API ~ostream();\n\n  operator writer() {\n    detail::buffer<char>& buf = *this;\n    return buf;\n  }\n\n  inline void flush() {\n    if (size() == 0) return;\n    file_.write(data(), size() * sizeof(data()[0]));\n    clear();\n  }\n\n  template <typename... T>\n  friend auto output_file(cstring_view path, T... params) -> ostream;\n\n  inline void close() {\n    flush();\n    file_.close();\n  }\n\n  /// Formats `args` according to specifications in `fmt` and writes the\n  /// output to the file.\n  template <typename... T> void print(format_string<T...> fmt, T&&... args) {\n    vformat_to(appender(*this), fmt.str, vargs<T...>{{args...}});\n  }\n};\n\n/**\n * Opens a file for writing. Supported parameters passed in `params`:\n *\n * - `<integer>`: Flags passed to [open](\n *   https://pubs.opengroup.org/onlinepubs/007904875/functions/open.html)\n *   (`file::WRONLY | file::CREATE | file::TRUNC` by default)\n * - `buffer_size=<integer>`: Output buffer size\n *\n * **Example**:\n *\n *     auto out = fmt::output_file(\"guide.txt\");\n *     out.print(\"Don't {}\", \"Panic\");\n */\ntemplate <typename... T>\ninline auto output_file(cstring_view path, T... params) -> ostream {\n  return {path, detail::ostream_params(params...)};\n}\n#endif  // FMT_USE_FCNTL\n\nFMT_END_EXPORT\nFMT_END_NAMESPACE\n\n#endif  // FMT_OS_H_\n"
  },
  {
    "path": "thirdparty/fmt/include/fmt/ostream.h",
    "content": "// Formatting library for C++ - std::ostream support\n//\n// Copyright (c) 2012 - present, Victor Zverovich\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\n#ifndef FMT_OSTREAM_H_\n#define FMT_OSTREAM_H_\n\n#ifndef FMT_MODULE\n#  include <fstream>  // std::filebuf\n#endif\n\n#ifdef _WIN32\n#  ifdef __GLIBCXX__\n#    include <ext/stdio_filebuf.h>\n#    include <ext/stdio_sync_filebuf.h>\n#  endif\n#  include <io.h>\n#endif\n\n#include \"chrono.h\"  // formatbuf\n\n#ifdef _MSVC_STL_UPDATE\n#  define FMT_MSVC_STL_UPDATE _MSVC_STL_UPDATE\n#elif defined(_MSC_VER) && _MSC_VER < 1912  // VS 15.5\n#  define FMT_MSVC_STL_UPDATE _MSVC_LANG\n#else\n#  define FMT_MSVC_STL_UPDATE 0\n#endif\n\nFMT_BEGIN_NAMESPACE\nnamespace detail {\n\n// Generate a unique explicit instantiation in every translation unit using a\n// tag type in an anonymous namespace.\nnamespace {\nstruct file_access_tag {};\n}  // namespace\ntemplate <typename Tag, typename BufType, FILE* BufType::*FileMemberPtr>\nclass file_access {\n  friend auto get_file(BufType& obj) -> FILE* { return obj.*FileMemberPtr; }\n};\n\n#if FMT_MSVC_STL_UPDATE\ntemplate class file_access<file_access_tag, std::filebuf,\n                           &std::filebuf::_Myfile>;\nauto get_file(std::filebuf&) -> FILE*;\n#endif\n\n// Write the content of buf to os.\n// It is a separate function rather than a part of vprint to simplify testing.\ntemplate <typename Char>\nvoid write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {\n  const Char* buf_data = buf.data();\n  using unsigned_streamsize = make_unsigned_t<std::streamsize>;\n  unsigned_streamsize size = buf.size();\n  unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());\n  do {\n    unsigned_streamsize n = size <= max_size ? size : max_size;\n    os.write(buf_data, static_cast<std::streamsize>(n));\n    buf_data += n;\n    size -= n;\n  } while (size != 0);\n}\n\ntemplate <typename T> struct streamed_view {\n  const T& value;\n};\n}  // namespace detail\n\n// Formats an object of type T that has an overloaded ostream operator<<.\ntemplate <typename Char>\nstruct basic_ostream_formatter : formatter<basic_string_view<Char>, Char> {\n  void set_debug_format() = delete;\n\n  template <typename T, typename Context>\n  auto format(const T& value, Context& ctx) const -> decltype(ctx.out()) {\n    auto buffer = basic_memory_buffer<Char>();\n    auto&& formatbuf = detail::formatbuf<std::basic_streambuf<Char>>(buffer);\n    auto&& output = std::basic_ostream<Char>(&formatbuf);\n    output.imbue(std::locale::classic());  // The default is always unlocalized.\n    output << value;\n    output.exceptions(std::ios_base::failbit | std::ios_base::badbit);\n    return formatter<basic_string_view<Char>, Char>::format(\n        {buffer.data(), buffer.size()}, ctx);\n  }\n};\n\nusing ostream_formatter = basic_ostream_formatter<char>;\n\ntemplate <typename T, typename Char>\nstruct formatter<detail::streamed_view<T>, Char>\n    : basic_ostream_formatter<Char> {\n  template <typename Context>\n  auto format(detail::streamed_view<T> view, Context& ctx) const\n      -> decltype(ctx.out()) {\n    return basic_ostream_formatter<Char>::format(view.value, ctx);\n  }\n};\n\n/**\n * Returns a view that formats `value` via an ostream `operator<<`.\n *\n * **Example**:\n *\n *     fmt::print(\"Current thread id: {}\\n\",\n *                fmt::streamed(std::this_thread::get_id()));\n */\ntemplate <typename T>\nconstexpr auto streamed(const T& value) -> detail::streamed_view<T> {\n  return {value};\n}\n\ninline void vprint(std::ostream& os, string_view fmt, format_args args) {\n  auto buffer = memory_buffer();\n  detail::vformat_to(buffer, fmt, args);\n  FILE* f = nullptr;\n#if FMT_MSVC_STL_UPDATE && FMT_USE_RTTI\n  if (auto* buf = dynamic_cast<std::filebuf*>(os.rdbuf()))\n    f = detail::get_file(*buf);\n#elif defined(_WIN32) && defined(__GLIBCXX__) && FMT_USE_RTTI\n  auto* rdbuf = os.rdbuf();\n  if (auto* sfbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf<char>*>(rdbuf))\n    f = sfbuf->file();\n  else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf<char>*>(rdbuf))\n    f = fbuf->file();\n#endif\n#ifdef _WIN32\n  if (f) {\n    int fd = _fileno(f);\n    if (_isatty(fd)) {\n      os.flush();\n      if (detail::write_console(fd, {buffer.data(), buffer.size()})) return;\n    }\n  }\n#endif\n  detail::ignore_unused(f);\n  detail::write_buffer(os, buffer);\n}\n\n/**\n * Prints formatted data to the stream `os`.\n *\n * **Example**:\n *\n *     fmt::print(cerr, \"Don't {}!\", \"panic\");\n */\nFMT_EXPORT template <typename... T>\nvoid print(std::ostream& os, format_string<T...> fmt, T&&... args) {\n  fmt::vargs<T...> vargs = {{args...}};\n  if (detail::const_check(detail::use_utf8)) return vprint(os, fmt.str, vargs);\n  auto buffer = memory_buffer();\n  detail::vformat_to(buffer, fmt.str, vargs);\n  detail::write_buffer(os, buffer);\n}\n\nFMT_EXPORT template <typename... T>\nvoid println(std::ostream& os, format_string<T...> fmt, T&&... args) {\n  fmt::print(os, FMT_STRING(\"{}\\n\"),\n             fmt::format(fmt, std::forward<T>(args)...));\n}\n\nFMT_END_NAMESPACE\n\n#endif  // FMT_OSTREAM_H_\n"
  },
  {
    "path": "thirdparty/fmt/include/fmt/printf.h",
    "content": "// Formatting library for C++ - legacy printf implementation\n//\n// Copyright (c) 2012 - 2016, Victor Zverovich\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\n#ifndef FMT_PRINTF_H_\n#define FMT_PRINTF_H_\n\n#ifndef FMT_MODULE\n#  include <algorithm>  // std::find\n#  include <limits>     // std::numeric_limits\n#endif\n\n#include \"format.h\"\n\nFMT_BEGIN_NAMESPACE\nFMT_BEGIN_EXPORT\n\ntemplate <typename Char> class basic_printf_context {\n private:\n  basic_appender<Char> out_;\n  basic_format_args<basic_printf_context> args_;\n\n  static_assert(std::is_same<Char, char>::value ||\n                    std::is_same<Char, wchar_t>::value,\n                \"Unsupported code unit type.\");\n\n public:\n  using char_type = Char;\n  enum { builtin_types = 1 };\n\n  /// Constructs a `printf_context` object. References to the arguments are\n  /// stored in the context object so make sure they have appropriate lifetimes.\n  basic_printf_context(basic_appender<Char> out,\n                       basic_format_args<basic_printf_context> args)\n      : out_(out), args_(args) {}\n\n  auto out() -> basic_appender<Char> { return out_; }\n  void advance_to(basic_appender<Char>) {}\n\n  auto locale() -> locale_ref { return {}; }\n\n  auto arg(int id) const -> basic_format_arg<basic_printf_context> {\n    return args_.get(id);\n  }\n};\n\nnamespace detail {\n\n// Return the result via the out param to workaround gcc bug 77539.\ntemplate <bool IS_CONSTEXPR, typename T, typename Ptr = const T*>\nFMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr& out) -> bool {\n  for (out = first; out != last; ++out) {\n    if (*out == value) return true;\n  }\n  return false;\n}\n\ntemplate <>\ninline auto find<false, char>(const char* first, const char* last, char value,\n                              const char*& out) -> bool {\n  out =\n      static_cast<const char*>(memchr(first, value, to_unsigned(last - first)));\n  return out != nullptr;\n}\n\n// Checks if a value fits in int - used to avoid warnings about comparing\n// signed and unsigned integers.\ntemplate <bool IS_SIGNED> struct int_checker {\n  template <typename T> static auto fits_in_int(T value) -> bool {\n    return value <= to_unsigned(max_value<int>());\n  }\n  inline static auto fits_in_int(bool) -> bool { return true; }\n};\n\ntemplate <> struct int_checker<true> {\n  template <typename T> static auto fits_in_int(T value) -> bool {\n    return value >= (std::numeric_limits<int>::min)() &&\n           value <= max_value<int>();\n  }\n  inline static auto fits_in_int(int) -> bool { return true; }\n};\n\nstruct printf_precision_handler {\n  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>\n  auto operator()(T value) -> int {\n    if (!int_checker<std::numeric_limits<T>::is_signed>::fits_in_int(value))\n      report_error(\"number is too big\");\n    return max_of(static_cast<int>(value), 0);\n  }\n\n  template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>\n  auto operator()(T) -> int {\n    report_error(\"precision is not integer\");\n    return 0;\n  }\n};\n\n// An argument visitor that returns true iff arg is a zero integer.\nstruct is_zero_int {\n  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>\n  auto operator()(T value) -> bool {\n    return value == 0;\n  }\n\n  template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>\n  auto operator()(T) -> bool {\n    return false;\n  }\n};\n\ntemplate <typename T> struct make_unsigned_or_bool : std::make_unsigned<T> {};\n\ntemplate <> struct make_unsigned_or_bool<bool> {\n  using type = bool;\n};\n\ntemplate <typename T, typename Context> class arg_converter {\n private:\n  using char_type = typename Context::char_type;\n\n  basic_format_arg<Context>& arg_;\n  char_type type_;\n\n public:\n  arg_converter(basic_format_arg<Context>& arg, char_type type)\n      : arg_(arg), type_(type) {}\n\n  void operator()(bool value) {\n    if (type_ != 's') operator()<bool>(value);\n  }\n\n  template <typename U, FMT_ENABLE_IF(std::is_integral<U>::value)>\n  void operator()(U value) {\n    bool is_signed = type_ == 'd' || type_ == 'i';\n    using target_type = conditional_t<std::is_same<T, void>::value, U, T>;\n    if (const_check(sizeof(target_type) <= sizeof(int))) {\n      // Extra casts are used to silence warnings.\n      using unsigned_type = typename make_unsigned_or_bool<target_type>::type;\n      if (is_signed)\n        arg_ = static_cast<int>(static_cast<target_type>(value));\n      else\n        arg_ = static_cast<unsigned>(static_cast<unsigned_type>(value));\n    } else {\n      // glibc's printf doesn't sign extend arguments of smaller types:\n      //   std::printf(\"%lld\", -42);  // prints \"4294967254\"\n      // but we don't have to do the same because it's a UB.\n      if (is_signed)\n        arg_ = static_cast<long long>(value);\n      else\n        arg_ = static_cast<typename make_unsigned_or_bool<U>::type>(value);\n    }\n  }\n\n  template <typename U, FMT_ENABLE_IF(!std::is_integral<U>::value)>\n  void operator()(U) {}  // No conversion needed for non-integral types.\n};\n\n// Converts an integer argument to T for printf, if T is an integral type.\n// If T is void, the argument is converted to corresponding signed or unsigned\n// type depending on the type specifier: 'd' and 'i' - signed, other -\n// unsigned).\ntemplate <typename T, typename Context, typename Char>\nvoid convert_arg(basic_format_arg<Context>& arg, Char type) {\n  arg.visit(arg_converter<T, Context>(arg, type));\n}\n\n// Converts an integer argument to char for printf.\ntemplate <typename Context> class char_converter {\n private:\n  basic_format_arg<Context>& arg_;\n\n public:\n  explicit char_converter(basic_format_arg<Context>& arg) : arg_(arg) {}\n\n  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>\n  void operator()(T value) {\n    arg_ = static_cast<typename Context::char_type>(value);\n  }\n\n  template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>\n  void operator()(T) {}  // No conversion needed for non-integral types.\n};\n\n// An argument visitor that return a pointer to a C string if argument is a\n// string or null otherwise.\ntemplate <typename Char> struct get_cstring {\n  template <typename T> auto operator()(T) -> const Char* { return nullptr; }\n  auto operator()(const Char* s) -> const Char* { return s; }\n};\n\n// Checks if an argument is a valid printf width specifier and sets\n// left alignment if it is negative.\nclass printf_width_handler {\n private:\n  format_specs& specs_;\n\n public:\n  inline explicit printf_width_handler(format_specs& specs) : specs_(specs) {}\n\n  template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>\n  auto operator()(T value) -> unsigned {\n    auto width = static_cast<uint32_or_64_or_128_t<T>>(value);\n    if (detail::is_negative(value)) {\n      specs_.set_align(align::left);\n      width = 0 - width;\n    }\n    unsigned int_max = to_unsigned(max_value<int>());\n    if (width > int_max) report_error(\"number is too big\");\n    return static_cast<unsigned>(width);\n  }\n\n  template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>\n  auto operator()(T) -> unsigned {\n    report_error(\"width is not integer\");\n    return 0;\n  }\n};\n\n// Workaround for a bug with the XL compiler when initializing\n// printf_arg_formatter's base class.\ntemplate <typename Char>\nauto make_arg_formatter(basic_appender<Char> iter, format_specs& s)\n    -> arg_formatter<Char> {\n  return {iter, s, locale_ref()};\n}\n\n// The `printf` argument formatter.\ntemplate <typename Char>\nclass printf_arg_formatter : public arg_formatter<Char> {\n private:\n  using base = arg_formatter<Char>;\n  using context_type = basic_printf_context<Char>;\n\n  context_type& context_;\n\n  void write_null_pointer(bool is_string = false) {\n    auto s = this->specs;\n    s.set_type(presentation_type::none);\n    write_bytes<Char>(this->out, is_string ? \"(null)\" : \"(nil)\", s);\n  }\n\n  template <typename T> void write(T value) {\n    detail::write<Char>(this->out, value, this->specs, this->locale);\n  }\n\n public:\n  printf_arg_formatter(basic_appender<Char> iter, format_specs& s,\n                       context_type& ctx)\n      : base(make_arg_formatter(iter, s)), context_(ctx) {}\n\n  void operator()(monostate value) { write(value); }\n\n  template <typename T, FMT_ENABLE_IF(detail::is_integral<T>::value)>\n  void operator()(T value) {\n    // MSVC2013 fails to compile separate overloads for bool and Char so use\n    // std::is_same instead.\n    if (!std::is_same<T, Char>::value) {\n      write(value);\n      return;\n    }\n    format_specs s = this->specs;\n    if (s.type() != presentation_type::none &&\n        s.type() != presentation_type::chr) {\n      return (*this)(static_cast<int>(value));\n    }\n    s.set_sign(sign::none);\n    s.clear_alt();\n    s.set_fill(' ');  // Ignore '0' flag for char types.\n    // align::numeric needs to be overwritten here since the '0' flag is\n    // ignored for non-numeric types\n    if (s.align() == align::none || s.align() == align::numeric)\n      s.set_align(align::right);\n    detail::write<Char>(this->out, static_cast<Char>(value), s);\n  }\n\n  template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>\n  void operator()(T value) {\n    write(value);\n  }\n\n  void operator()(const char* value) {\n    if (value)\n      write(value);\n    else\n      write_null_pointer(this->specs.type() != presentation_type::pointer);\n  }\n\n  void operator()(const wchar_t* value) {\n    if (value)\n      write(value);\n    else\n      write_null_pointer(this->specs.type() != presentation_type::pointer);\n  }\n\n  void operator()(basic_string_view<Char> value) { write(value); }\n\n  void operator()(const void* value) {\n    if (value)\n      write(value);\n    else\n      write_null_pointer();\n  }\n\n  void operator()(typename basic_format_arg<context_type>::handle handle) {\n    auto parse_ctx = parse_context<Char>({});\n    handle.format(parse_ctx, context_);\n  }\n};\n\ntemplate <typename Char>\nvoid parse_flags(format_specs& specs, const Char*& it, const Char* end) {\n  for (; it != end; ++it) {\n    switch (*it) {\n    case '-': specs.set_align(align::left); break;\n    case '+': specs.set_sign(sign::plus); break;\n    case '0': specs.set_fill('0'); break;\n    case ' ':\n      if (specs.sign() != sign::plus) specs.set_sign(sign::space);\n      break;\n    case '#': specs.set_alt(); break;\n    default:  return;\n    }\n  }\n}\n\ntemplate <typename Char, typename GetArg>\nauto parse_header(const Char*& it, const Char* end, format_specs& specs,\n                  GetArg get_arg) -> int {\n  int arg_index = -1;\n  Char c = *it;\n  if (c >= '0' && c <= '9') {\n    // Parse an argument index (if followed by '$') or a width possibly\n    // preceded with '0' flag(s).\n    int value = parse_nonnegative_int(it, end, -1);\n    if (it != end && *it == '$') {  // value is an argument index\n      ++it;\n      arg_index = value != -1 ? value : max_value<int>();\n    } else {\n      if (c == '0') specs.set_fill('0');\n      if (value != 0) {\n        // Nonzero value means that we parsed width and don't need to\n        // parse it or flags again, so return now.\n        if (value == -1) report_error(\"number is too big\");\n        specs.width = value;\n        return arg_index;\n      }\n    }\n  }\n  parse_flags(specs, it, end);\n  // Parse width.\n  if (it != end) {\n    if (*it >= '0' && *it <= '9') {\n      specs.width = parse_nonnegative_int(it, end, -1);\n      if (specs.width == -1) report_error(\"number is too big\");\n    } else if (*it == '*') {\n      ++it;\n      specs.width = static_cast<int>(\n          get_arg(-1).visit(detail::printf_width_handler(specs)));\n    }\n  }\n  return arg_index;\n}\n\ninline auto parse_printf_presentation_type(char c, type t, bool& upper)\n    -> presentation_type {\n  using pt = presentation_type;\n  constexpr auto integral_set = sint_set | uint_set | bool_set | char_set;\n  switch (c) {\n  case 'd': return in(t, integral_set) ? pt::dec : pt::none;\n  case 'o': return in(t, integral_set) ? pt::oct : pt::none;\n  case 'X': upper = true; FMT_FALLTHROUGH;\n  case 'x': return in(t, integral_set) ? pt::hex : pt::none;\n  case 'E': upper = true; FMT_FALLTHROUGH;\n  case 'e': return in(t, float_set) ? pt::exp : pt::none;\n  case 'F': upper = true; FMT_FALLTHROUGH;\n  case 'f': return in(t, float_set) ? pt::fixed : pt::none;\n  case 'G': upper = true; FMT_FALLTHROUGH;\n  case 'g': return in(t, float_set) ? pt::general : pt::none;\n  case 'A': upper = true; FMT_FALLTHROUGH;\n  case 'a': return in(t, float_set) ? pt::hexfloat : pt::none;\n  case 'c': return in(t, integral_set) ? pt::chr : pt::none;\n  case 's': return in(t, string_set | cstring_set) ? pt::string : pt::none;\n  case 'p': return in(t, pointer_set | cstring_set) ? pt::pointer : pt::none;\n  default:  return pt::none;\n  }\n}\n\ntemplate <typename Char, typename Context>\nvoid vprintf(buffer<Char>& buf, basic_string_view<Char> format,\n             basic_format_args<Context> args) {\n  using iterator = basic_appender<Char>;\n  auto out = iterator(buf);\n  auto context = basic_printf_context<Char>(out, args);\n  auto parse_ctx = parse_context<Char>(format);\n\n  // Returns the argument with specified index or, if arg_index is -1, the next\n  // argument.\n  auto get_arg = [&](int arg_index) {\n    if (arg_index < 0)\n      arg_index = parse_ctx.next_arg_id();\n    else\n      parse_ctx.check_arg_id(--arg_index);\n    auto arg = context.arg(arg_index);\n    if (!arg) report_error(\"argument not found\");\n    return arg;\n  };\n\n  const Char* start = parse_ctx.begin();\n  const Char* end = parse_ctx.end();\n  auto it = start;\n  while (it != end) {\n    if (!find<false, Char>(it, end, '%', it)) {\n      it = end;  // find leaves it == nullptr if it doesn't find '%'.\n      break;\n    }\n    Char c = *it++;\n    if (it != end && *it == c) {\n      write(out, basic_string_view<Char>(start, to_unsigned(it - start)));\n      start = ++it;\n      continue;\n    }\n    write(out, basic_string_view<Char>(start, to_unsigned(it - 1 - start)));\n\n    auto specs = format_specs();\n    specs.set_align(align::right);\n\n    // Parse argument index, flags and width.\n    int arg_index = parse_header(it, end, specs, get_arg);\n    if (arg_index == 0) report_error(\"argument not found\");\n\n    // Parse precision.\n    if (it != end && *it == '.') {\n      ++it;\n      c = it != end ? *it : 0;\n      if ('0' <= c && c <= '9') {\n        specs.precision = parse_nonnegative_int(it, end, 0);\n      } else if (c == '*') {\n        ++it;\n        specs.precision =\n            static_cast<int>(get_arg(-1).visit(printf_precision_handler()));\n      } else {\n        specs.precision = 0;\n      }\n    }\n\n    auto arg = get_arg(arg_index);\n    // For d, i, o, u, x, and X conversion specifiers, if a precision is\n    // specified, the '0' flag is ignored\n    if (specs.precision >= 0 && is_integral_type(arg.type())) {\n      // Ignore '0' for non-numeric types or if '-' present.\n      specs.set_fill(' ');\n    }\n    if (specs.precision >= 0 && arg.type() == type::cstring_type) {\n      auto str = arg.visit(get_cstring<Char>());\n      auto str_end = str + specs.precision;\n      auto nul = std::find(str, str_end, Char());\n      auto sv = basic_string_view<Char>(\n          str, to_unsigned(nul != str_end ? nul - str : specs.precision));\n      arg = sv;\n    }\n    if (specs.alt() && arg.visit(is_zero_int())) specs.clear_alt();\n    if (specs.fill_unit<Char>() == '0') {\n      if (is_arithmetic_type(arg.type()) && specs.align() != align::left) {\n        specs.set_align(align::numeric);\n      } else {\n        // Ignore '0' flag for non-numeric types or if '-' flag is also present.\n        specs.set_fill(' ');\n      }\n    }\n\n    // Parse length and convert the argument to the required type.\n    c = it != end ? *it++ : 0;\n    Char t = it != end ? *it : 0;\n    switch (c) {\n    case 'h':\n      if (t == 'h') {\n        ++it;\n        t = it != end ? *it : 0;\n        convert_arg<signed char>(arg, t);\n      } else {\n        convert_arg<short>(arg, t);\n      }\n      break;\n    case 'l':\n      if (t == 'l') {\n        ++it;\n        t = it != end ? *it : 0;\n        convert_arg<long long>(arg, t);\n      } else {\n        convert_arg<long>(arg, t);\n      }\n      break;\n    case 'j': convert_arg<intmax_t>(arg, t); break;\n    case 'z': convert_arg<size_t>(arg, t); break;\n    case 't': convert_arg<std::ptrdiff_t>(arg, t); break;\n    case 'L':\n      // printf produces garbage when 'L' is omitted for long double, no\n      // need to do the same.\n      break;\n    default: --it; convert_arg<void>(arg, c);\n    }\n\n    // Parse type.\n    if (it == end) report_error(\"invalid format string\");\n    char type = static_cast<char>(*it++);\n    if (is_integral_type(arg.type())) {\n      // Normalize type.\n      switch (type) {\n      case 'i':\n      case 'u': type = 'd'; break;\n      case 'c':\n        arg.visit(char_converter<basic_printf_context<Char>>(arg));\n        break;\n      }\n    }\n    bool upper = false;\n    specs.set_type(parse_printf_presentation_type(type, arg.type(), upper));\n    if (specs.type() == presentation_type::none)\n      report_error(\"invalid format specifier\");\n    if (upper) specs.set_upper();\n\n    start = it;\n\n    // Format argument.\n    arg.visit(printf_arg_formatter<Char>(out, specs, context));\n  }\n  write(out, basic_string_view<Char>(start, to_unsigned(it - start)));\n}\n}  // namespace detail\n\nusing printf_context = basic_printf_context<char>;\nusing wprintf_context = basic_printf_context<wchar_t>;\n\nusing printf_args = basic_format_args<printf_context>;\nusing wprintf_args = basic_format_args<wprintf_context>;\n\n/// Constructs an `format_arg_store` object that contains references to\n/// arguments and can be implicitly converted to `printf_args`.\ntemplate <typename Char = char, typename... T>\ninline auto make_printf_args(T&... args)\n    -> decltype(fmt::make_format_args<basic_printf_context<Char>>(args...)) {\n  return fmt::make_format_args<basic_printf_context<Char>>(args...);\n}\n\ntemplate <typename Char> struct vprintf_args {\n  using type = basic_format_args<basic_printf_context<Char>>;\n};\n\ntemplate <typename Char>\ninline auto vsprintf(basic_string_view<Char> fmt,\n                     typename vprintf_args<Char>::type args)\n    -> std::basic_string<Char> {\n  auto buf = basic_memory_buffer<Char>();\n  detail::vprintf(buf, fmt, args);\n  return {buf.data(), buf.size()};\n}\n\n/**\n * Formats `args` according to specifications in `fmt` and returns the result\n * as as string.\n *\n * **Example**:\n *\n *     std::string message = fmt::sprintf(\"The answer is %d\", 42);\n */\ntemplate <typename... T>\ninline auto sprintf(string_view fmt, const T&... args) -> std::string {\n  return vsprintf(fmt, make_printf_args(args...));\n}\ntemplate <typename... T>\nFMT_DEPRECATED auto sprintf(basic_string_view<wchar_t> fmt, const T&... args)\n    -> std::wstring {\n  return vsprintf(fmt, make_printf_args<wchar_t>(args...));\n}\n\ntemplate <typename Char>\nauto vfprintf(std::FILE* f, basic_string_view<Char> fmt,\n              typename vprintf_args<Char>::type args) -> int {\n  auto buf = basic_memory_buffer<Char>();\n  detail::vprintf(buf, fmt, args);\n  size_t size = buf.size();\n  return std::fwrite(buf.data(), sizeof(Char), size, f) < size\n             ? -1\n             : static_cast<int>(size);\n}\n\n/**\n * Formats `args` according to specifications in `fmt` and writes the output\n * to `f`.\n *\n * **Example**:\n *\n *     fmt::fprintf(stderr, \"Don't %s!\", \"panic\");\n */\ntemplate <typename... T>\ninline auto fprintf(std::FILE* f, string_view fmt, const T&... args) -> int {\n  return vfprintf(f, fmt, make_printf_args(args...));\n}\ntemplate <typename... T>\nFMT_DEPRECATED auto fprintf(std::FILE* f, basic_string_view<wchar_t> fmt,\n                            const T&... args) -> int {\n  return vfprintf(f, fmt, make_printf_args<wchar_t>(args...));\n}\n\n/**\n * Formats `args` according to specifications in `fmt` and writes the output\n * to `stdout`.\n *\n * **Example**:\n *\n *   fmt::printf(\"Elapsed time: %.2f seconds\", 1.23);\n */\ntemplate <typename... T>\ninline auto printf(string_view fmt, const T&... args) -> int {\n  return vfprintf(stdout, fmt, make_printf_args(args...));\n}\n\nFMT_END_EXPORT\nFMT_END_NAMESPACE\n\n#endif  // FMT_PRINTF_H_\n"
  },
  {
    "path": "thirdparty/fmt/include/fmt/ranges.h",
    "content": "// Formatting library for C++ - range and tuple support\n//\n// Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\n#ifndef FMT_RANGES_H_\n#define FMT_RANGES_H_\n\n#ifndef FMT_MODULE\n#  include <initializer_list>\n#  include <iterator>\n#  include <tuple>\n#  include <type_traits>\n#  include <utility>\n#endif\n\n#include \"format.h\"\n\n#if FMT_HAS_CPP_ATTRIBUTE(clang::lifetimebound)\n#  define FMT_LIFETIMEBOUND [[clang::lifetimebound]]\n#else\n#  define FMT_LIFETIMEBOUND\n#endif\nFMT_PRAGMA_CLANG(diagnostic error \"-Wreturn-stack-address\")\n\nFMT_BEGIN_NAMESPACE\n\nFMT_EXPORT\nenum class range_format { disabled, map, set, sequence, string, debug_string };\n\nnamespace detail {\n\ntemplate <typename T> class is_map {\n  template <typename U> static auto check(U*) -> typename U::mapped_type;\n  template <typename> static void check(...);\n\n public:\n  static constexpr bool value =\n      !std::is_void<decltype(check<T>(nullptr))>::value;\n};\n\ntemplate <typename T> class is_set {\n  template <typename U> static auto check(U*) -> typename U::key_type;\n  template <typename> static void check(...);\n\n public:\n  static constexpr bool value =\n      !std::is_void<decltype(check<T>(nullptr))>::value && !is_map<T>::value;\n};\n\n// C array overload\ntemplate <typename T, size_t N>\nauto range_begin(const T (&arr)[N]) -> const T* {\n  return arr;\n}\ntemplate <typename T, size_t N> auto range_end(const T (&arr)[N]) -> const T* {\n  return arr + N;\n}\n\ntemplate <typename T, typename Enable = void>\nstruct has_member_fn_begin_end_t : std::false_type {};\n\ntemplate <typename T>\nstruct has_member_fn_begin_end_t<T, void_t<decltype(*std::declval<T>().begin()),\n                                           decltype(std::declval<T>().end())>>\n    : std::true_type {};\n\n// Member function overloads.\ntemplate <typename T>\nauto range_begin(T&& rng) -> decltype(static_cast<T&&>(rng).begin()) {\n  return static_cast<T&&>(rng).begin();\n}\ntemplate <typename T>\nauto range_end(T&& rng) -> decltype(static_cast<T&&>(rng).end()) {\n  return static_cast<T&&>(rng).end();\n}\n\n// ADL overloads. Only participate in overload resolution if member functions\n// are not found.\ntemplate <typename T>\nauto range_begin(T&& rng)\n    -> enable_if_t<!has_member_fn_begin_end_t<T&&>::value,\n                   decltype(begin(static_cast<T&&>(rng)))> {\n  return begin(static_cast<T&&>(rng));\n}\ntemplate <typename T>\nauto range_end(T&& rng) -> enable_if_t<!has_member_fn_begin_end_t<T&&>::value,\n                                       decltype(end(static_cast<T&&>(rng)))> {\n  return end(static_cast<T&&>(rng));\n}\n\ntemplate <typename T, typename Enable = void>\nstruct has_const_begin_end : std::false_type {};\ntemplate <typename T, typename Enable = void>\nstruct has_mutable_begin_end : std::false_type {};\n\ntemplate <typename T>\nstruct has_const_begin_end<\n    T, void_t<decltype(*detail::range_begin(\n                  std::declval<const remove_cvref_t<T>&>())),\n              decltype(detail::range_end(\n                  std::declval<const remove_cvref_t<T>&>()))>>\n    : std::true_type {};\n\ntemplate <typename T>\nstruct has_mutable_begin_end<\n    T, void_t<decltype(*detail::range_begin(std::declval<T&>())),\n              decltype(detail::range_end(std::declval<T&>())),\n              // the extra int here is because older versions of MSVC don't\n              // SFINAE properly unless there are distinct types\n              int>> : std::true_type {};\n\ntemplate <typename T, typename _ = void> struct is_range_ : std::false_type {};\ntemplate <typename T>\nstruct is_range_<T, void>\n    : std::integral_constant<bool, (has_const_begin_end<T>::value ||\n                                    has_mutable_begin_end<T>::value)> {};\n\n// tuple_size and tuple_element check.\ntemplate <typename T> class is_tuple_like_ {\n  template <typename U, typename V = typename std::remove_cv<U>::type>\n  static auto check(U* p) -> decltype(std::tuple_size<V>::value, 0);\n  template <typename> static void check(...);\n\n public:\n  static constexpr bool value =\n      !std::is_void<decltype(check<T>(nullptr))>::value;\n};\n\n// Check for integer_sequence\n#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VERSION >= 1900\ntemplate <typename T, T... N>\nusing integer_sequence = std::integer_sequence<T, N...>;\ntemplate <size_t... N> using index_sequence = std::index_sequence<N...>;\ntemplate <size_t N> using make_index_sequence = std::make_index_sequence<N>;\n#else\ntemplate <typename T, T... N> struct integer_sequence {\n  using value_type = T;\n\n  static FMT_CONSTEXPR auto size() -> size_t { return sizeof...(N); }\n};\n\ntemplate <size_t... N> using index_sequence = integer_sequence<size_t, N...>;\n\ntemplate <typename T, size_t N, T... Ns>\nstruct make_integer_sequence : make_integer_sequence<T, N - 1, N - 1, Ns...> {};\ntemplate <typename T, T... Ns>\nstruct make_integer_sequence<T, 0, Ns...> : integer_sequence<T, Ns...> {};\n\ntemplate <size_t N>\nusing make_index_sequence = make_integer_sequence<size_t, N>;\n#endif\n\ntemplate <typename T>\nusing tuple_index_sequence = make_index_sequence<std::tuple_size<T>::value>;\n\ntemplate <typename T, typename C, bool = is_tuple_like_<T>::value>\nclass is_tuple_formattable_ {\n public:\n  static constexpr bool value = false;\n};\ntemplate <typename T, typename C> class is_tuple_formattable_<T, C, true> {\n  template <size_t... Is>\n  static auto all_true(index_sequence<Is...>,\n                       integer_sequence<bool, (Is >= 0)...>) -> std::true_type;\n  static auto all_true(...) -> std::false_type;\n\n  template <size_t... Is>\n  static auto check(index_sequence<Is...>) -> decltype(all_true(\n      index_sequence<Is...>{},\n      integer_sequence<bool,\n                       (is_formattable<typename std::tuple_element<Is, T>::type,\n                                       C>::value)...>{}));\n\n public:\n  static constexpr bool value =\n      decltype(check(tuple_index_sequence<T>{}))::value;\n};\n\ntemplate <typename Tuple, typename F, size_t... Is>\nFMT_CONSTEXPR void for_each(index_sequence<Is...>, Tuple&& t, F&& f) {\n  using std::get;\n  // Using a free function get<Is>(Tuple) now.\n  const int unused[] = {0, ((void)f(get<Is>(t)), 0)...};\n  ignore_unused(unused);\n}\n\ntemplate <typename Tuple, typename F>\nFMT_CONSTEXPR void for_each(Tuple&& t, F&& f) {\n  for_each(tuple_index_sequence<remove_cvref_t<Tuple>>(),\n           std::forward<Tuple>(t), std::forward<F>(f));\n}\n\ntemplate <typename Tuple1, typename Tuple2, typename F, size_t... Is>\nvoid for_each2(index_sequence<Is...>, Tuple1&& t1, Tuple2&& t2, F&& f) {\n  using std::get;\n  const int unused[] = {0, ((void)f(get<Is>(t1), get<Is>(t2)), 0)...};\n  ignore_unused(unused);\n}\n\ntemplate <typename Tuple1, typename Tuple2, typename F>\nvoid for_each2(Tuple1&& t1, Tuple2&& t2, F&& f) {\n  for_each2(tuple_index_sequence<remove_cvref_t<Tuple1>>(),\n            std::forward<Tuple1>(t1), std::forward<Tuple2>(t2),\n            std::forward<F>(f));\n}\n\nnamespace tuple {\n// Workaround a bug in MSVC 2019 (v140).\ntemplate <typename Char, typename... T>\nusing result_t = std::tuple<formatter<remove_cvref_t<T>, Char>...>;\n\nusing std::get;\ntemplate <typename Tuple, typename Char, size_t... Is>\nauto get_formatters(index_sequence<Is...>)\n    -> result_t<Char, decltype(get<Is>(std::declval<Tuple>()))...>;\n}  // namespace tuple\n\n#if FMT_MSC_VERSION && FMT_MSC_VERSION < 1920\n// Older MSVC doesn't get the reference type correctly for arrays.\ntemplate <typename R> struct range_reference_type_impl {\n  using type = decltype(*detail::range_begin(std::declval<R&>()));\n};\n\ntemplate <typename T, size_t N> struct range_reference_type_impl<T[N]> {\n  using type = T&;\n};\n\ntemplate <typename T>\nusing range_reference_type = typename range_reference_type_impl<T>::type;\n#else\ntemplate <typename Range>\nusing range_reference_type =\n    decltype(*detail::range_begin(std::declval<Range&>()));\n#endif\n\n// We don't use the Range's value_type for anything, but we do need the Range's\n// reference type, with cv-ref stripped.\ntemplate <typename Range>\nusing uncvref_type = remove_cvref_t<range_reference_type<Range>>;\n\ntemplate <typename T>\nstruct range_format_kind_\n    : std::integral_constant<range_format,\n                             std::is_same<uncvref_type<T>, T>::value\n                                 ? range_format::disabled\n                             : is_map<T>::value ? range_format::map\n                             : is_set<T>::value ? range_format::set\n                                                : range_format::sequence> {};\n\ntemplate <range_format K>\nusing range_format_constant = std::integral_constant<range_format, K>;\n\n// These are not generic lambdas for compatibility with C++11.\ntemplate <typename Char> struct parse_empty_specs {\n  template <typename Formatter> FMT_CONSTEXPR void operator()(Formatter& f) {\n    f.parse(ctx);\n    detail::maybe_set_debug_format(f, true);\n  }\n  parse_context<Char>& ctx;\n};\ntemplate <typename FormatContext> struct format_tuple_element {\n  using char_type = typename FormatContext::char_type;\n\n  template <typename T>\n  void operator()(const formatter<T, char_type>& f, const T& v) {\n    if (i > 0) ctx.advance_to(detail::copy<char_type>(separator, ctx.out()));\n    ctx.advance_to(f.format(v, ctx));\n    ++i;\n  }\n\n  int i;\n  FormatContext& ctx;\n  basic_string_view<char_type> separator;\n};\n\n}  // namespace detail\n\nFMT_EXPORT\ntemplate <typename T> struct is_tuple_like {\n  static constexpr bool value =\n      detail::is_tuple_like_<T>::value && !detail::is_range_<T>::value;\n};\n\nFMT_EXPORT\ntemplate <typename T, typename C> struct is_tuple_formattable {\n  static constexpr bool value = detail::is_tuple_formattable_<T, C>::value;\n};\n\ntemplate <typename Tuple, typename Char>\nstruct formatter<Tuple, Char,\n                 enable_if_t<fmt::is_tuple_like<Tuple>::value &&\n                             fmt::is_tuple_formattable<Tuple, Char>::value>> {\n private:\n  decltype(detail::tuple::get_formatters<Tuple, Char>(\n      detail::tuple_index_sequence<Tuple>())) formatters_;\n\n  basic_string_view<Char> separator_ = detail::string_literal<Char, ',', ' '>{};\n  basic_string_view<Char> opening_bracket_ =\n      detail::string_literal<Char, '('>{};\n  basic_string_view<Char> closing_bracket_ =\n      detail::string_literal<Char, ')'>{};\n\n public:\n  FMT_CONSTEXPR formatter() {}\n\n  FMT_CONSTEXPR void set_separator(basic_string_view<Char> sep) {\n    separator_ = sep;\n  }\n\n  FMT_CONSTEXPR void set_brackets(basic_string_view<Char> open,\n                                  basic_string_view<Char> close) {\n    opening_bracket_ = open;\n    closing_bracket_ = close;\n  }\n\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    auto it = ctx.begin();\n    auto end = ctx.end();\n    if (it != end && detail::to_ascii(*it) == 'n') {\n      ++it;\n      set_brackets({}, {});\n      set_separator({});\n    }\n    if (it != end && *it != '}') report_error(\"invalid format specifier\");\n    ctx.advance_to(it);\n    detail::for_each(formatters_, detail::parse_empty_specs<Char>{ctx});\n    return it;\n  }\n\n  template <typename FormatContext>\n  auto format(const Tuple& value, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    ctx.advance_to(detail::copy<Char>(opening_bracket_, ctx.out()));\n    detail::for_each2(\n        formatters_, value,\n        detail::format_tuple_element<FormatContext>{0, ctx, separator_});\n    return detail::copy<Char>(closing_bracket_, ctx.out());\n  }\n};\n\nFMT_EXPORT\ntemplate <typename T, typename Char> struct is_range {\n  static constexpr bool value =\n      detail::is_range_<T>::value && !detail::has_to_string_view<T>::value;\n};\n\nnamespace detail {\n\ntemplate <typename Char, typename Element>\nusing range_formatter_type = formatter<remove_cvref_t<Element>, Char>;\n\ntemplate <typename R>\nusing maybe_const_range =\n    conditional_t<has_const_begin_end<R>::value, const R, R>;\n\ntemplate <typename R, typename Char>\nstruct is_formattable_delayed\n    : is_formattable<uncvref_type<maybe_const_range<R>>, Char> {};\n}  // namespace detail\n\ntemplate <typename...> struct conjunction : std::true_type {};\ntemplate <typename P> struct conjunction<P> : P {};\ntemplate <typename P1, typename... Pn>\nstruct conjunction<P1, Pn...>\n    : conditional_t<bool(P1::value), conjunction<Pn...>, P1> {};\n\nFMT_EXPORT\ntemplate <typename T, typename Char, typename Enable = void>\nstruct range_formatter;\n\ntemplate <typename T, typename Char>\nstruct range_formatter<\n    T, Char,\n    enable_if_t<conjunction<std::is_same<T, remove_cvref_t<T>>,\n                            is_formattable<T, Char>>::value>> {\n private:\n  detail::range_formatter_type<Char, T> underlying_;\n  basic_string_view<Char> separator_ = detail::string_literal<Char, ',', ' '>{};\n  basic_string_view<Char> opening_bracket_ =\n      detail::string_literal<Char, '['>{};\n  basic_string_view<Char> closing_bracket_ =\n      detail::string_literal<Char, ']'>{};\n  bool is_debug = false;\n\n  template <typename Output, typename It, typename Sentinel, typename U = T,\n            FMT_ENABLE_IF(std::is_same<U, Char>::value)>\n  auto write_debug_string(Output& out, It it, Sentinel end) const -> Output {\n    auto buf = basic_memory_buffer<Char>();\n    for (; it != end; ++it) buf.push_back(*it);\n    auto specs = format_specs();\n    specs.set_type(presentation_type::debug);\n    return detail::write<Char>(\n        out, basic_string_view<Char>(buf.data(), buf.size()), specs);\n  }\n\n  template <typename Output, typename It, typename Sentinel, typename U = T,\n            FMT_ENABLE_IF(!std::is_same<U, Char>::value)>\n  auto write_debug_string(Output& out, It, Sentinel) const -> Output {\n    return out;\n  }\n\n public:\n  FMT_CONSTEXPR range_formatter() {}\n\n  FMT_CONSTEXPR auto underlying() -> detail::range_formatter_type<Char, T>& {\n    return underlying_;\n  }\n\n  FMT_CONSTEXPR void set_separator(basic_string_view<Char> sep) {\n    separator_ = sep;\n  }\n\n  FMT_CONSTEXPR void set_brackets(basic_string_view<Char> open,\n                                  basic_string_view<Char> close) {\n    opening_bracket_ = open;\n    closing_bracket_ = close;\n  }\n\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    auto it = ctx.begin();\n    auto end = ctx.end();\n    detail::maybe_set_debug_format(underlying_, true);\n    if (it == end) return underlying_.parse(ctx);\n\n    switch (detail::to_ascii(*it)) {\n    case 'n':\n      set_brackets({}, {});\n      ++it;\n      break;\n    case '?':\n      is_debug = true;\n      set_brackets({}, {});\n      ++it;\n      if (it == end || *it != 's') report_error(\"invalid format specifier\");\n      FMT_FALLTHROUGH;\n    case 's':\n      if (!std::is_same<T, Char>::value)\n        report_error(\"invalid format specifier\");\n      if (!is_debug) {\n        set_brackets(detail::string_literal<Char, '\"'>{},\n                     detail::string_literal<Char, '\"'>{});\n        set_separator({});\n        detail::maybe_set_debug_format(underlying_, false);\n      }\n      ++it;\n      return it;\n    }\n\n    if (it != end && *it != '}') {\n      if (*it != ':') report_error(\"invalid format specifier\");\n      detail::maybe_set_debug_format(underlying_, false);\n      ++it;\n    }\n\n    ctx.advance_to(it);\n    return underlying_.parse(ctx);\n  }\n\n  template <typename R, typename FormatContext>\n  auto format(R&& range, FormatContext& ctx) const -> decltype(ctx.out()) {\n    auto out = ctx.out();\n    auto it = detail::range_begin(range);\n    auto end = detail::range_end(range);\n    if (is_debug) return write_debug_string(out, std::move(it), end);\n\n    out = detail::copy<Char>(opening_bracket_, out);\n    int i = 0;\n    for (; it != end; ++it) {\n      if (i > 0) out = detail::copy<Char>(separator_, out);\n      ctx.advance_to(out);\n      auto&& item = *it;  // Need an lvalue\n      out = underlying_.format(item, ctx);\n      ++i;\n    }\n    out = detail::copy<Char>(closing_bracket_, out);\n    return out;\n  }\n};\n\nFMT_EXPORT\ntemplate <typename T, typename Char, typename Enable = void>\nstruct range_format_kind\n    : conditional_t<\n          is_range<T, Char>::value, detail::range_format_kind_<T>,\n          std::integral_constant<range_format, range_format::disabled>> {};\n\ntemplate <typename R, typename Char>\nstruct formatter<\n    R, Char,\n    enable_if_t<conjunction<\n        bool_constant<\n            range_format_kind<R, Char>::value != range_format::disabled &&\n            range_format_kind<R, Char>::value != range_format::map &&\n            range_format_kind<R, Char>::value != range_format::string &&\n            range_format_kind<R, Char>::value != range_format::debug_string>,\n        detail::is_formattable_delayed<R, Char>>::value>> {\n private:\n  using range_type = detail::maybe_const_range<R>;\n  range_formatter<detail::uncvref_type<range_type>, Char> range_formatter_;\n\n public:\n  using nonlocking = void;\n\n  FMT_CONSTEXPR formatter() {\n    if (detail::const_check(range_format_kind<R, Char>::value !=\n                            range_format::set))\n      return;\n    range_formatter_.set_brackets(detail::string_literal<Char, '{'>{},\n                                  detail::string_literal<Char, '}'>{});\n  }\n\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    return range_formatter_.parse(ctx);\n  }\n\n  template <typename FormatContext>\n  auto format(range_type& range, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    return range_formatter_.format(range, ctx);\n  }\n};\n\n// A map formatter.\ntemplate <typename R, typename Char>\nstruct formatter<\n    R, Char,\n    enable_if_t<conjunction<\n        bool_constant<range_format_kind<R, Char>::value == range_format::map>,\n        detail::is_formattable_delayed<R, Char>>::value>> {\n private:\n  using map_type = detail::maybe_const_range<R>;\n  using element_type = detail::uncvref_type<map_type>;\n\n  decltype(detail::tuple::get_formatters<element_type, Char>(\n      detail::tuple_index_sequence<element_type>())) formatters_;\n  bool no_delimiters_ = false;\n\n public:\n  FMT_CONSTEXPR formatter() {}\n\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    auto it = ctx.begin();\n    auto end = ctx.end();\n    if (it != end) {\n      if (detail::to_ascii(*it) == 'n') {\n        no_delimiters_ = true;\n        ++it;\n      }\n      if (it != end && *it != '}') {\n        if (*it != ':') report_error(\"invalid format specifier\");\n        ++it;\n      }\n      ctx.advance_to(it);\n    }\n    detail::for_each(formatters_, detail::parse_empty_specs<Char>{ctx});\n    return it;\n  }\n\n  template <typename FormatContext>\n  auto format(map_type& map, FormatContext& ctx) const -> decltype(ctx.out()) {\n    auto out = ctx.out();\n    basic_string_view<Char> open = detail::string_literal<Char, '{'>{};\n    if (!no_delimiters_) out = detail::copy<Char>(open, out);\n    int i = 0;\n    basic_string_view<Char> sep = detail::string_literal<Char, ',', ' '>{};\n    for (auto&& value : map) {\n      if (i > 0) out = detail::copy<Char>(sep, out);\n      ctx.advance_to(out);\n      detail::for_each2(formatters_, value,\n                        detail::format_tuple_element<FormatContext>{\n                            0, ctx, detail::string_literal<Char, ':', ' '>{}});\n      ++i;\n    }\n    basic_string_view<Char> close = detail::string_literal<Char, '}'>{};\n    if (!no_delimiters_) out = detail::copy<Char>(close, out);\n    return out;\n  }\n};\n\n// A (debug_)string formatter.\ntemplate <typename R, typename Char>\nstruct formatter<\n    R, Char,\n    enable_if_t<range_format_kind<R, Char>::value == range_format::string ||\n                range_format_kind<R, Char>::value ==\n                    range_format::debug_string>> {\n private:\n  using range_type = detail::maybe_const_range<R>;\n  using string_type =\n      conditional_t<std::is_constructible<\n                        detail::std_string_view<Char>,\n                        decltype(detail::range_begin(std::declval<R>())),\n                        decltype(detail::range_end(std::declval<R>()))>::value,\n                    detail::std_string_view<Char>, std::basic_string<Char>>;\n\n  formatter<string_type, Char> underlying_;\n\n public:\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    return underlying_.parse(ctx);\n  }\n\n  template <typename FormatContext>\n  auto format(range_type& range, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    auto out = ctx.out();\n    if (detail::const_check(range_format_kind<R, Char>::value ==\n                            range_format::debug_string))\n      *out++ = '\"';\n    out = underlying_.format(\n        string_type{detail::range_begin(range), detail::range_end(range)}, ctx);\n    if (detail::const_check(range_format_kind<R, Char>::value ==\n                            range_format::debug_string))\n      *out++ = '\"';\n    return out;\n  }\n};\n\ntemplate <typename It, typename Sentinel, typename Char = char>\nstruct join_view : detail::view {\n  It begin;\n  Sentinel end;\n  basic_string_view<Char> sep;\n\n  join_view(It b, Sentinel e, basic_string_view<Char> s)\n      : begin(std::move(b)), end(e), sep(s) {}\n};\n\ntemplate <typename It, typename Sentinel, typename Char>\nstruct formatter<join_view<It, Sentinel, Char>, Char> {\n private:\n  using value_type =\n#ifdef __cpp_lib_ranges\n      std::iter_value_t<It>;\n#else\n      typename std::iterator_traits<It>::value_type;\n#endif\n  formatter<remove_cvref_t<value_type>, Char> value_formatter_;\n\n  using view = conditional_t<std::is_copy_constructible<It>::value,\n                             const join_view<It, Sentinel, Char>,\n                             join_view<It, Sentinel, Char>>;\n\n public:\n  using nonlocking = void;\n\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    return value_formatter_.parse(ctx);\n  }\n\n  template <typename FormatContext>\n  auto format(view& value, FormatContext& ctx) const -> decltype(ctx.out()) {\n    using iter =\n        conditional_t<std::is_copy_constructible<view>::value, It, It&>;\n    iter it = value.begin;\n    auto out = ctx.out();\n    if (it == value.end) return out;\n    out = value_formatter_.format(*it, ctx);\n    ++it;\n    while (it != value.end) {\n      out = detail::copy<Char>(value.sep.begin(), value.sep.end(), out);\n      ctx.advance_to(out);\n      out = value_formatter_.format(*it, ctx);\n      ++it;\n    }\n    return out;\n  }\n};\n\nFMT_EXPORT\ntemplate <typename Tuple, typename Char> struct tuple_join_view : detail::view {\n  const Tuple& tuple;\n  basic_string_view<Char> sep;\n\n  tuple_join_view(const Tuple& t, basic_string_view<Char> s)\n      : tuple(t), sep{s} {}\n};\n\n// Define FMT_TUPLE_JOIN_SPECIFIERS to enable experimental format specifiers\n// support in tuple_join. It is disabled by default because of issues with\n// the dynamic width and precision.\n#ifndef FMT_TUPLE_JOIN_SPECIFIERS\n#  define FMT_TUPLE_JOIN_SPECIFIERS 0\n#endif\n\ntemplate <typename Tuple, typename Char>\nstruct formatter<tuple_join_view<Tuple, Char>, Char,\n                 enable_if_t<is_tuple_like<Tuple>::value>> {\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    return do_parse(ctx, std::tuple_size<Tuple>());\n  }\n\n  template <typename FormatContext>\n  auto format(const tuple_join_view<Tuple, Char>& value,\n              FormatContext& ctx) const -> typename FormatContext::iterator {\n    return do_format(value, ctx, std::tuple_size<Tuple>());\n  }\n\n private:\n  decltype(detail::tuple::get_formatters<Tuple, Char>(\n      detail::tuple_index_sequence<Tuple>())) formatters_;\n\n  FMT_CONSTEXPR auto do_parse(parse_context<Char>& ctx,\n                              std::integral_constant<size_t, 0>)\n      -> const Char* {\n    return ctx.begin();\n  }\n\n  template <size_t N>\n  FMT_CONSTEXPR auto do_parse(parse_context<Char>& ctx,\n                              std::integral_constant<size_t, N>)\n      -> const Char* {\n    auto end = ctx.begin();\n#if FMT_TUPLE_JOIN_SPECIFIERS\n    end = std::get<std::tuple_size<Tuple>::value - N>(formatters_).parse(ctx);\n    if (N > 1) {\n      auto end1 = do_parse(ctx, std::integral_constant<size_t, N - 1>());\n      if (end != end1)\n        report_error(\"incompatible format specs for tuple elements\");\n    }\n#endif\n    return end;\n  }\n\n  template <typename FormatContext>\n  auto do_format(const tuple_join_view<Tuple, Char>&, FormatContext& ctx,\n                 std::integral_constant<size_t, 0>) const ->\n      typename FormatContext::iterator {\n    return ctx.out();\n  }\n\n  template <typename FormatContext, size_t N>\n  auto do_format(const tuple_join_view<Tuple, Char>& value, FormatContext& ctx,\n                 std::integral_constant<size_t, N>) const ->\n      typename FormatContext::iterator {\n    using std::get;\n    auto out =\n        std::get<std::tuple_size<Tuple>::value - N>(formatters_)\n            .format(get<std::tuple_size<Tuple>::value - N>(value.tuple), ctx);\n    if (N <= 1) return out;\n    out = detail::copy<Char>(value.sep, out);\n    ctx.advance_to(out);\n    return do_format(value, ctx, std::integral_constant<size_t, N - 1>());\n  }\n};\n\nnamespace detail {\n// Check if T has an interface like a container adaptor (e.g. std::stack,\n// std::queue, std::priority_queue).\ntemplate <typename T> class is_container_adaptor_like {\n  template <typename U> static auto check(U* p) -> typename U::container_type;\n  template <typename> static void check(...);\n\n public:\n  static constexpr bool value =\n      !std::is_void<decltype(check<T>(nullptr))>::value;\n};\n\ntemplate <typename Container> struct all {\n  const Container& c;\n  auto begin() const -> typename Container::const_iterator { return c.begin(); }\n  auto end() const -> typename Container::const_iterator { return c.end(); }\n};\n}  // namespace detail\n\ntemplate <typename T, typename Char>\nstruct formatter<\n    T, Char,\n    enable_if_t<conjunction<detail::is_container_adaptor_like<T>,\n                            bool_constant<range_format_kind<T, Char>::value ==\n                                          range_format::disabled>>::value>>\n    : formatter<detail::all<typename T::container_type>, Char> {\n  using all = detail::all<typename T::container_type>;\n  template <typename FormatContext>\n  auto format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) {\n    struct getter : T {\n      static auto get(const T& v) -> all {\n        return {v.*(&getter::c)};  // Access c through the derived class.\n      }\n    };\n    return formatter<all>::format(getter::get(value), ctx);\n  }\n};\n\nFMT_BEGIN_EXPORT\n\n/// Returns a view that formats the iterator range `[begin, end)` with elements\n/// separated by `sep`.\ntemplate <typename It, typename Sentinel>\nauto join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel> {\n  return {std::move(begin), end, sep};\n}\n\n/**\n * Returns a view that formats `range` with elements separated by `sep`.\n *\n * **Example**:\n *\n *     auto v = std::vector<int>{1, 2, 3};\n *     fmt::print(\"{}\", fmt::join(v, \", \"));\n *     // Output: 1, 2, 3\n *\n * `fmt::join` applies passed format specifiers to the range elements:\n *\n *     fmt::print(\"{:02}\", fmt::join(v, \", \"));\n *     // Output: 01, 02, 03\n */\ntemplate <typename Range, FMT_ENABLE_IF(!is_tuple_like<Range>::value)>\nauto join(Range&& r, string_view sep)\n    -> join_view<decltype(detail::range_begin(r)),\n                 decltype(detail::range_end(r))> {\n  return {detail::range_begin(r), detail::range_end(r), sep};\n}\n\n/**\n * Returns an object that formats `std::tuple` with elements separated by `sep`.\n *\n * **Example**:\n *\n *     auto t = std::tuple<int, char>(1, 'a');\n *     fmt::print(\"{}\", fmt::join(t, \", \"));\n *     // Output: 1, a\n */\ntemplate <typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>\nFMT_CONSTEXPR auto join(const Tuple& tuple FMT_LIFETIMEBOUND, string_view sep)\n    -> tuple_join_view<Tuple, char> {\n  return {tuple, sep};\n}\n\n/**\n * Returns an object that formats `std::initializer_list` with elements\n * separated by `sep`.\n *\n * **Example**:\n *\n *     fmt::print(\"{}\", fmt::join({1, 2, 3}, \", \"));\n *     // Output: \"1, 2, 3\"\n */\ntemplate <typename T>\nauto join(std::initializer_list<T> list, string_view sep)\n    -> join_view<const T*, const T*> {\n  return join(std::begin(list), std::end(list), sep);\n}\n\nFMT_END_EXPORT\nFMT_END_NAMESPACE\n\n#endif  // FMT_RANGES_H_\n"
  },
  {
    "path": "thirdparty/fmt/include/fmt/std.h",
    "content": "// Formatting library for C++ - formatters for standard library types\n//\n// Copyright (c) 2012 - present, Victor Zverovich\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\n#ifndef FMT_STD_H_\n#define FMT_STD_H_\n\n#include \"format.h\"\n#include \"ostream.h\"\n\n#ifndef FMT_MODULE\n#  include <atomic>\n#  include <bitset>\n#  include <complex>\n#  include <exception>\n#  include <functional>  // std::reference_wrapper\n#  include <memory>\n#  include <thread>\n#  include <type_traits>\n#  include <typeinfo>  // std::type_info\n#  include <utility>   // std::make_index_sequence\n\n// Check FMT_CPLUSPLUS to suppress a bogus warning in MSVC.\n#  if FMT_CPLUSPLUS >= 201703L\n#    if FMT_HAS_INCLUDE(<filesystem>) && \\\n        (!defined(FMT_CPP_LIB_FILESYSTEM) || FMT_CPP_LIB_FILESYSTEM != 0)\n#      include <filesystem>\n#    endif\n#    if FMT_HAS_INCLUDE(<variant>)\n#      include <variant>\n#    endif\n#    if FMT_HAS_INCLUDE(<optional>)\n#      include <optional>\n#    endif\n#  endif\n// Use > instead of >= in the version check because <source_location> may be\n// available after C++17 but before C++20 is marked as implemented.\n#  if FMT_CPLUSPLUS > 201703L && FMT_HAS_INCLUDE(<source_location>)\n#    include <source_location>\n#  endif\n#  if FMT_CPLUSPLUS > 202002L && FMT_HAS_INCLUDE(<expected>)\n#    include <expected>\n#  endif\n#endif  // FMT_MODULE\n\n#if FMT_HAS_INCLUDE(<version>)\n#  include <version>\n#endif\n\n// GCC 4 does not support FMT_HAS_INCLUDE.\n#if FMT_HAS_INCLUDE(<cxxabi.h>) || defined(__GLIBCXX__)\n#  include <cxxabi.h>\n// Android NDK with gabi++ library on some architectures does not implement\n// abi::__cxa_demangle().\n#  ifndef __GABIXX_CXXABI_H__\n#    define FMT_HAS_ABI_CXA_DEMANGLE\n#  endif\n#endif\n\n#ifdef FMT_CPP_LIB_FILESYSTEM\n// Use the provided definition.\n#elif defined(__cpp_lib_filesystem)\n#  define FMT_CPP_LIB_FILESYSTEM __cpp_lib_filesystem\n#else\n#  define FMT_CPP_LIB_FILESYSTEM 0\n#endif\n\n#ifdef FMT_CPP_LIB_VARIANT\n// Use the provided definition.\n#elif defined(__cpp_lib_variant)\n#  define FMT_CPP_LIB_VARIANT __cpp_lib_variant\n#else\n#  define FMT_CPP_LIB_VARIANT 0\n#endif\n\nFMT_BEGIN_NAMESPACE\nnamespace detail {\n\n#if FMT_CPP_LIB_FILESYSTEM\n\ntemplate <typename Char, typename PathChar>\nauto get_path_string(const std::filesystem::path& p,\n                     const std::basic_string<PathChar>& native) {\n  if constexpr (std::is_same_v<Char, char> && std::is_same_v<PathChar, wchar_t>)\n    return to_utf8<wchar_t>(native, to_utf8_error_policy::replace);\n  else\n    return p.string<Char>();\n}\n\ntemplate <typename Char, typename PathChar>\nvoid write_escaped_path(basic_memory_buffer<Char>& quoted,\n                        const std::filesystem::path& p,\n                        const std::basic_string<PathChar>& native) {\n  if constexpr (std::is_same_v<Char, char> &&\n                std::is_same_v<PathChar, wchar_t>) {\n    auto buf = basic_memory_buffer<wchar_t>();\n    write_escaped_string<wchar_t>(std::back_inserter(buf), native);\n    bool valid = to_utf8<wchar_t>::convert(quoted, {buf.data(), buf.size()});\n    FMT_ASSERT(valid, \"invalid utf16\");\n  } else if constexpr (std::is_same_v<Char, PathChar>) {\n    write_escaped_string<std::filesystem::path::value_type>(\n        std::back_inserter(quoted), native);\n  } else {\n    write_escaped_string<Char>(std::back_inserter(quoted), p.string<Char>());\n  }\n}\n\n#endif  // FMT_CPP_LIB_FILESYSTEM\n\n#if defined(__cpp_lib_expected) || FMT_CPP_LIB_VARIANT\n\ntemplate <typename Char, typename OutputIt, typename T, typename FormatContext>\nauto write_escaped_alternative(OutputIt out, const T& v, FormatContext& ctx)\n    -> OutputIt {\n  if constexpr (has_to_string_view<T>::value)\n    return write_escaped_string<Char>(out, detail::to_string_view(v));\n  if constexpr (std::is_same_v<T, Char>) return write_escaped_char(out, v);\n\n  formatter<std::remove_cv_t<T>, Char> underlying;\n  maybe_set_debug_format(underlying, true);\n  return underlying.format(v, ctx);\n}\n#endif\n\n#if FMT_CPP_LIB_VARIANT\n\ntemplate <typename> struct is_variant_like_ : std::false_type {};\ntemplate <typename... Types>\nstruct is_variant_like_<std::variant<Types...>> : std::true_type {};\n\ntemplate <typename Variant, typename Char> class is_variant_formattable {\n  template <size_t... Is>\n  static auto check(std::index_sequence<Is...>) -> std::conjunction<\n      is_formattable<std::variant_alternative_t<Is, Variant>, Char>...>;\n\n public:\n  static constexpr bool value = decltype(check(\n      std::make_index_sequence<std::variant_size<Variant>::value>()))::value;\n};\n\n#endif  // FMT_CPP_LIB_VARIANT\n\n#if FMT_USE_RTTI\ninline auto normalize_libcxx_inline_namespaces(string_view demangled_name_view,\n                                               char* begin) -> string_view {\n  // Normalization of stdlib inline namespace names.\n  // libc++ inline namespaces.\n  //  std::__1::*       -> std::*\n  //  std::__1::__fs::* -> std::*\n  // libstdc++ inline namespaces.\n  //  std::__cxx11::*             -> std::*\n  //  std::filesystem::__cxx11::* -> std::filesystem::*\n  if (demangled_name_view.starts_with(\"std::\")) {\n    char* to = begin + 5;  // std::\n    for (const char *from = to, *end = begin + demangled_name_view.size();\n         from < end;) {\n      // This is safe, because demangled_name is NUL-terminated.\n      if (from[0] == '_' && from[1] == '_') {\n        const char* next = from + 1;\n        while (next < end && *next != ':') next++;\n        if (next[0] == ':' && next[1] == ':') {\n          from = next + 2;\n          continue;\n        }\n      }\n      *to++ = *from++;\n    }\n    demangled_name_view = {begin, detail::to_unsigned(to - begin)};\n  }\n  return demangled_name_view;\n}\n\ntemplate <class OutputIt>\nauto normalize_msvc_abi_name(string_view abi_name_view, OutputIt out)\n    -> OutputIt {\n  const string_view demangled_name(abi_name_view);\n  for (size_t i = 0; i < demangled_name.size(); ++i) {\n    auto sub = demangled_name;\n    sub.remove_prefix(i);\n    if (sub.starts_with(\"enum \")) {\n      i += 4;\n      continue;\n    }\n    if (sub.starts_with(\"class \") || sub.starts_with(\"union \")) {\n      i += 5;\n      continue;\n    }\n    if (sub.starts_with(\"struct \")) {\n      i += 6;\n      continue;\n    }\n    if (*sub.begin() != ' ') *out++ = *sub.begin();\n  }\n  return out;\n}\n\ntemplate <typename OutputIt>\nauto write_demangled_name(OutputIt out, const std::type_info& ti) -> OutputIt {\n#  ifdef FMT_HAS_ABI_CXA_DEMANGLE\n  int status = 0;\n  size_t size = 0;\n  std::unique_ptr<char, void (*)(void*)> demangled_name_ptr(\n      abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &free);\n\n  string_view demangled_name_view;\n  if (demangled_name_ptr) {\n    demangled_name_view = normalize_libcxx_inline_namespaces(\n        demangled_name_ptr.get(), demangled_name_ptr.get());\n  } else {\n    demangled_name_view = string_view(ti.name());\n  }\n  return detail::write_bytes<char>(out, demangled_name_view);\n#  elif FMT_MSC_VERSION && defined(_MSVC_STL_UPDATE)\n  return normalize_msvc_abi_name(ti.name(), out);\n#  elif FMT_MSC_VERSION && defined(_LIBCPP_VERSION)\n  const string_view demangled_name = ti.name();\n  std::string name_copy(demangled_name.size(), '\\0');\n  // normalize_msvc_abi_name removes class, struct, union etc that MSVC has in\n  // front of types\n  name_copy.erase(normalize_msvc_abi_name(demangled_name, name_copy.begin()),\n                  name_copy.end());\n  // normalize_libcxx_inline_namespaces removes the inline __1, __2, etc\n  // namespaces libc++ uses for ABI versioning On MSVC ABI + libc++\n  // environments, we need to eliminate both of them.\n  const string_view normalized_name =\n      normalize_libcxx_inline_namespaces(name_copy, name_copy.data());\n  return detail::write_bytes<char>(out, normalized_name);\n#  else\n  return detail::write_bytes<char>(out, string_view(ti.name()));\n#  endif\n}\n\n#endif  // FMT_USE_RTTI\n\ntemplate <typename T, typename Enable = void>\nstruct has_flip : std::false_type {};\n\ntemplate <typename T>\nstruct has_flip<T, void_t<decltype(std::declval<T>().flip())>>\n    : std::true_type {};\n\ntemplate <typename T> struct is_bit_reference_like {\n  static constexpr bool value = std::is_convertible<T, bool>::value &&\n                                std::is_nothrow_assignable<T, bool>::value &&\n                                has_flip<T>::value;\n};\n\n// Workaround for libc++ incompatibility with C++ standard.\n// According to the Standard, `bitset::operator[] const` returns bool.\n#if defined(_LIBCPP_VERSION) && !defined(FMT_IMPORT_STD)\ntemplate <typename C>\nstruct is_bit_reference_like<std::__bit_const_reference<C>> {\n  static constexpr bool value = true;\n};\n#endif\n\ntemplate <typename T, typename Enable = void>\nstruct has_format_as : std::false_type {};\ntemplate <typename T>\nstruct has_format_as<T, void_t<decltype(format_as(std::declval<const T&>()))>>\n    : std::true_type {};\n\ntemplate <typename T, typename Enable = void>\nstruct has_format_as_member : std::false_type {};\ntemplate <typename T>\nstruct has_format_as_member<\n    T, void_t<decltype(formatter<T>::format_as(std::declval<const T&>()))>>\n    : std::true_type {};\n\n}  // namespace detail\n\ntemplate <typename T, typename Deleter>\nauto ptr(const std::unique_ptr<T, Deleter>& p) -> const void* {\n  return p.get();\n}\ntemplate <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {\n  return p.get();\n}\n\n#if FMT_CPP_LIB_FILESYSTEM\n\ntemplate <typename Char> struct formatter<std::filesystem::path, Char> {\n private:\n  format_specs specs_;\n  detail::arg_ref<Char> width_ref_;\n  bool debug_ = false;\n  char path_type_ = 0;\n\n public:\n  FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; }\n\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) {\n    auto it = ctx.begin(), end = ctx.end();\n    if (it == end) return it;\n\n    it = detail::parse_align(it, end, specs_);\n    if (it == end) return it;\n\n    Char c = *it;\n    if ((c >= '0' && c <= '9') || c == '{')\n      it = detail::parse_width(it, end, specs_, width_ref_, ctx);\n    if (it != end && *it == '?') {\n      debug_ = true;\n      ++it;\n    }\n    if (it != end && (*it == 'g')) path_type_ = detail::to_ascii(*it++);\n    return it;\n  }\n\n  template <typename FormatContext>\n  auto format(const std::filesystem::path& p, FormatContext& ctx) const {\n    auto specs = specs_;\n    auto path_string =\n        !path_type_ ? p.native()\n                    : p.generic_string<std::filesystem::path::value_type>();\n\n    detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,\n                                ctx);\n    if (!debug_) {\n      auto s = detail::get_path_string<Char>(p, path_string);\n      return detail::write(ctx.out(), basic_string_view<Char>(s), specs);\n    }\n    auto quoted = basic_memory_buffer<Char>();\n    detail::write_escaped_path(quoted, p, path_string);\n    return detail::write(ctx.out(),\n                         basic_string_view<Char>(quoted.data(), quoted.size()),\n                         specs);\n  }\n};\n\nclass path : public std::filesystem::path {\n public:\n  auto display_string() const -> std::string {\n    const std::filesystem::path& base = *this;\n    return fmt::format(FMT_STRING(\"{}\"), base);\n  }\n  auto system_string() const -> std::string { return string(); }\n\n  auto generic_display_string() const -> std::string {\n    const std::filesystem::path& base = *this;\n    return fmt::format(FMT_STRING(\"{:g}\"), base);\n  }\n  auto generic_system_string() const -> std::string { return generic_string(); }\n};\n\n#endif  // FMT_CPP_LIB_FILESYSTEM\n\ntemplate <size_t N, typename Char>\nstruct formatter<std::bitset<N>, Char>\n    : nested_formatter<basic_string_view<Char>, Char> {\n private:\n  // This is a functor because C++11 doesn't support generic lambdas.\n  struct writer {\n    const std::bitset<N>& bs;\n\n    template <typename OutputIt>\n    FMT_CONSTEXPR auto operator()(OutputIt out) -> OutputIt {\n      for (auto pos = N; pos > 0; --pos)\n        out = detail::write<Char>(out, bs[pos - 1] ? Char('1') : Char('0'));\n      return out;\n    }\n  };\n\n public:\n  template <typename FormatContext>\n  auto format(const std::bitset<N>& bs, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    return this->write_padded(ctx, writer{bs});\n  }\n};\n\ntemplate <typename Char>\nstruct formatter<std::thread::id, Char> : basic_ostream_formatter<Char> {};\n\n#ifdef __cpp_lib_optional\ntemplate <typename T, typename Char>\nstruct formatter<std::optional<T>, Char,\n                 std::enable_if_t<is_formattable<T, Char>::value>> {\n private:\n  formatter<std::remove_cv_t<T>, Char> underlying_;\n  static constexpr basic_string_view<Char> optional =\n      detail::string_literal<Char, 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l',\n                             '('>{};\n  static constexpr basic_string_view<Char> none =\n      detail::string_literal<Char, 'n', 'o', 'n', 'e'>{};\n\n public:\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) {\n    detail::maybe_set_debug_format(underlying_, true);\n    return underlying_.parse(ctx);\n  }\n\n  template <typename FormatContext>\n  auto format(const std::optional<T>& opt, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    if (!opt) return detail::write<Char>(ctx.out(), none);\n\n    auto out = ctx.out();\n    out = detail::write<Char>(out, optional);\n    ctx.advance_to(out);\n    out = underlying_.format(*opt, ctx);\n    return detail::write(out, ')');\n  }\n};\n#endif  // __cpp_lib_optional\n\n#ifdef __cpp_lib_expected\ntemplate <typename T, typename E, typename Char>\nstruct formatter<std::expected<T, E>, Char,\n                 std::enable_if_t<(std::is_void<T>::value ||\n                                   is_formattable<T, Char>::value) &&\n                                  is_formattable<E, Char>::value>> {\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    return ctx.begin();\n  }\n\n  template <typename FormatContext>\n  auto format(const std::expected<T, E>& value, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    auto out = ctx.out();\n\n    if (value.has_value()) {\n      out = detail::write<Char>(out, \"expected(\");\n      if constexpr (!std::is_void<T>::value)\n        out = detail::write_escaped_alternative<Char>(out, *value, ctx);\n    } else {\n      out = detail::write<Char>(out, \"unexpected(\");\n      out = detail::write_escaped_alternative<Char>(out, value.error(), ctx);\n    }\n    *out++ = ')';\n    return out;\n  }\n};\n#endif  // __cpp_lib_expected\n\n#ifdef __cpp_lib_source_location\ntemplate <> struct formatter<std::source_location> {\n  FMT_CONSTEXPR auto parse(parse_context<>& ctx) { return ctx.begin(); }\n\n  template <typename FormatContext>\n  auto format(const std::source_location& loc, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    auto out = ctx.out();\n    out = detail::write(out, loc.file_name());\n    out = detail::write(out, ':');\n    out = detail::write<char>(out, loc.line());\n    out = detail::write(out, ':');\n    out = detail::write<char>(out, loc.column());\n    out = detail::write(out, \": \");\n    out = detail::write(out, loc.function_name());\n    return out;\n  }\n};\n#endif\n\n#if FMT_CPP_LIB_VARIANT\n\ntemplate <typename T> struct is_variant_like {\n  static constexpr bool value = detail::is_variant_like_<T>::value;\n};\n\ntemplate <typename Char> struct formatter<std::monostate, Char> {\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    return ctx.begin();\n  }\n\n  template <typename FormatContext>\n  auto format(const std::monostate&, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    return detail::write<Char>(ctx.out(), \"monostate\");\n  }\n};\n\ntemplate <typename Variant, typename Char>\nstruct formatter<Variant, Char,\n                 std::enable_if_t<std::conjunction_v<\n                     is_variant_like<Variant>,\n                     detail::is_variant_formattable<Variant, Char>>>> {\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    return ctx.begin();\n  }\n\n  template <typename FormatContext>\n  auto format(const Variant& value, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    auto out = ctx.out();\n\n    out = detail::write<Char>(out, \"variant(\");\n    FMT_TRY {\n      std::visit(\n          [&](const auto& v) {\n            out = detail::write_escaped_alternative<Char>(out, v, ctx);\n          },\n          value);\n    }\n    FMT_CATCH(const std::bad_variant_access&) {\n      detail::write<Char>(out, \"valueless by exception\");\n    }\n    *out++ = ')';\n    return out;\n  }\n};\n\n#endif  // FMT_CPP_LIB_VARIANT\n\ntemplate <> struct formatter<std::error_code> {\n private:\n  format_specs specs_;\n  detail::arg_ref<char> width_ref_;\n  bool debug_ = false;\n\n public:\n  FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; }\n\n  FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {\n    auto it = ctx.begin(), end = ctx.end();\n    if (it == end) return it;\n\n    it = detail::parse_align(it, end, specs_);\n\n    char c = *it;\n    if (it != end && ((c >= '0' && c <= '9') || c == '{'))\n      it = detail::parse_width(it, end, specs_, width_ref_, ctx);\n\n    if (it != end && *it == '?') {\n      debug_ = true;\n      ++it;\n    }\n    if (it != end && *it == 's') {\n      specs_.set_type(presentation_type::string);\n      ++it;\n    }\n    return it;\n  }\n\n  template <typename FormatContext>\n  FMT_CONSTEXPR20 auto format(const std::error_code& ec,\n                              FormatContext& ctx) const -> decltype(ctx.out()) {\n    auto specs = specs_;\n    detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,\n                                ctx);\n    auto buf = memory_buffer();\n    if (specs_.type() == presentation_type::string) {\n      buf.append(ec.message());\n    } else {\n      buf.append(string_view(ec.category().name()));\n      buf.push_back(':');\n      detail::write<char>(appender(buf), ec.value());\n    }\n    auto quoted = memory_buffer();\n    auto str = string_view(buf.data(), buf.size());\n    if (debug_) {\n      detail::write_escaped_string<char>(std::back_inserter(quoted), str);\n      str = string_view(quoted.data(), quoted.size());\n    }\n    return detail::write<char>(ctx.out(), str, specs);\n  }\n};\n\n#if FMT_USE_RTTI\ntemplate <> struct formatter<std::type_info> {\n public:\n  FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {\n    return ctx.begin();\n  }\n\n  template <typename Context>\n  auto format(const std::type_info& ti, Context& ctx) const\n      -> decltype(ctx.out()) {\n    return detail::write_demangled_name(ctx.out(), ti);\n  }\n};\n#endif  // FMT_USE_RTTI\n\ntemplate <typename T>\nstruct formatter<\n    T, char,\n    typename std::enable_if<std::is_base_of<std::exception, T>::value>::type> {\n private:\n  bool with_typename_ = false;\n\n public:\n  FMT_CONSTEXPR auto parse(parse_context<>& ctx) -> const char* {\n    auto it = ctx.begin();\n    auto end = ctx.end();\n    if (it == end || *it == '}') return it;\n    if (*it == 't') {\n      ++it;\n      with_typename_ = FMT_USE_RTTI != 0;\n    }\n    return it;\n  }\n\n  template <typename Context>\n  auto format(const std::exception& ex, Context& ctx) const\n      -> decltype(ctx.out()) {\n    auto out = ctx.out();\n#if FMT_USE_RTTI\n    if (with_typename_) {\n      out = detail::write_demangled_name(out, typeid(ex));\n      *out++ = ':';\n      *out++ = ' ';\n    }\n#endif\n    return detail::write_bytes<char>(out, string_view(ex.what()));\n  }\n};\n\n// We can't use std::vector<bool, Allocator>::reference and\n// std::bitset<N>::reference because the compiler can't deduce Allocator and N\n// in partial specialization.\ntemplate <typename BitRef, typename Char>\nstruct formatter<BitRef, Char,\n                 enable_if_t<detail::is_bit_reference_like<BitRef>::value>>\n    : formatter<bool, Char> {\n  template <typename FormatContext>\n  FMT_CONSTEXPR auto format(const BitRef& v, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    return formatter<bool, Char>::format(v, ctx);\n  }\n};\n\ntemplate <typename T, typename Char>\nstruct formatter<std::atomic<T>, Char,\n                 enable_if_t<is_formattable<T, Char>::value>>\n    : formatter<T, Char> {\n  template <typename FormatContext>\n  auto format(const std::atomic<T>& v, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    return formatter<T, Char>::format(v.load(), ctx);\n  }\n};\n\n#ifdef __cpp_lib_atomic_flag_test\ntemplate <typename Char>\nstruct formatter<std::atomic_flag, Char> : formatter<bool, Char> {\n  template <typename FormatContext>\n  auto format(const std::atomic_flag& v, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    return formatter<bool, Char>::format(v.test(), ctx);\n  }\n};\n#endif  // __cpp_lib_atomic_flag_test\n\ntemplate <typename T, typename Char> struct formatter<std::complex<T>, Char> {\n private:\n  detail::dynamic_format_specs<Char> specs_;\n\n  template <typename FormatContext, typename OutputIt>\n  FMT_CONSTEXPR auto do_format(const std::complex<T>& c,\n                               detail::dynamic_format_specs<Char>& specs,\n                               FormatContext& ctx, OutputIt out) const\n      -> OutputIt {\n    if (c.real() != 0) {\n      *out++ = Char('(');\n      out = detail::write<Char>(out, c.real(), specs, ctx.locale());\n      specs.set_sign(sign::plus);\n      out = detail::write<Char>(out, c.imag(), specs, ctx.locale());\n      if (!detail::isfinite(c.imag())) *out++ = Char(' ');\n      *out++ = Char('i');\n      *out++ = Char(')');\n      return out;\n    }\n    out = detail::write<Char>(out, c.imag(), specs, ctx.locale());\n    if (!detail::isfinite(c.imag())) *out++ = Char(' ');\n    *out++ = Char('i');\n    return out;\n  }\n\n public:\n  FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {\n    if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin();\n    return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,\n                              detail::type_constant<T, Char>::value);\n  }\n\n  template <typename FormatContext>\n  auto format(const std::complex<T>& c, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    auto specs = specs_;\n    if (specs.dynamic()) {\n      detail::handle_dynamic_spec(specs.dynamic_width(), specs.width,\n                                  specs.width_ref, ctx);\n      detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision,\n                                  specs.precision_ref, ctx);\n    }\n\n    if (specs.width == 0) return do_format(c, specs, ctx, ctx.out());\n    auto buf = basic_memory_buffer<Char>();\n\n    auto outer_specs = format_specs();\n    outer_specs.width = specs.width;\n    outer_specs.copy_fill_from(specs);\n    outer_specs.set_align(specs.align());\n\n    specs.width = 0;\n    specs.set_fill({});\n    specs.set_align(align::none);\n\n    do_format(c, specs, ctx, basic_appender<Char>(buf));\n    return detail::write<Char>(ctx.out(),\n                               basic_string_view<Char>(buf.data(), buf.size()),\n                               outer_specs);\n  }\n};\n\ntemplate <typename T, typename Char>\nstruct formatter<std::reference_wrapper<T>, Char,\n                 // Guard against format_as because reference_wrapper is\n                 // implicitly convertible to T&.\n                 enable_if_t<is_formattable<remove_cvref_t<T>, Char>::value &&\n                             !detail::has_format_as<T>::value &&\n                             !detail::has_format_as_member<T>::value>>\n    : formatter<remove_cvref_t<T>, Char> {\n  template <typename FormatContext>\n  auto format(std::reference_wrapper<T> ref, FormatContext& ctx) const\n      -> decltype(ctx.out()) {\n    return formatter<remove_cvref_t<T>, Char>::format(ref.get(), ctx);\n  }\n};\n\nFMT_END_NAMESPACE\n\n#endif  // FMT_STD_H_\n"
  },
  {
    "path": "thirdparty/fmt/include/fmt/xchar.h",
    "content": "// Formatting library for C++ - optional wchar_t and exotic character support\n//\n// Copyright (c) 2012 - present, Victor Zverovich\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\n#ifndef FMT_XCHAR_H_\n#define FMT_XCHAR_H_\n\n#include \"color.h\"\n#include \"format.h\"\n#include \"ostream.h\"\n#include \"ranges.h\"\n\n#ifndef FMT_MODULE\n#  include <cwchar>\n#  if FMT_USE_LOCALE\n#    include <locale>\n#  endif\n#endif\n\nFMT_BEGIN_NAMESPACE\nnamespace detail {\n\ntemplate <typename T>\nusing is_exotic_char = bool_constant<!std::is_same<T, char>::value>;\n\ntemplate <typename S, typename = void> struct format_string_char {};\n\ntemplate <typename S>\nstruct format_string_char<\n    S, void_t<decltype(sizeof(detail::to_string_view(std::declval<S>())))>> {\n  using type = char_t<S>;\n};\n\ntemplate <typename S>\nstruct format_string_char<\n    S, enable_if_t<std::is_base_of<detail::compile_string, S>::value>> {\n  using type = typename S::char_type;\n};\n\ntemplate <typename S>\nusing format_string_char_t = typename format_string_char<S>::type;\n\ninline auto write_loc(basic_appender<wchar_t> out, loc_value value,\n                      const format_specs& specs, locale_ref loc) -> bool {\n#if FMT_USE_LOCALE\n  auto& numpunct =\n      std::use_facet<std::numpunct<wchar_t>>(loc.get<std::locale>());\n  auto separator = std::wstring();\n  auto grouping = numpunct.grouping();\n  if (!grouping.empty()) separator = std::wstring(1, numpunct.thousands_sep());\n  return value.visit(loc_writer<wchar_t>{out, specs, separator, grouping, {}});\n#endif\n  return false;\n}\n\ntemplate <typename Char>\nvoid vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,\n                basic_format_args<buffered_context<Char>> args,\n                locale_ref loc = {}) {\n  static_assert(!std::is_same<Char, char>::value, \"\");\n  auto out = basic_appender<Char>(buf);\n  parse_format_string(\n      fmt, format_handler<Char>{parse_context<Char>(fmt), {out, args, loc}});\n}\n}  // namespace detail\n\nFMT_BEGIN_EXPORT\n\nusing wstring_view = basic_string_view<wchar_t>;\nusing wformat_parse_context = parse_context<wchar_t>;\nusing wformat_context = buffered_context<wchar_t>;\nusing wformat_args = basic_format_args<wformat_context>;\nusing wmemory_buffer = basic_memory_buffer<wchar_t>;\n\ntemplate <typename Char, typename... T> struct basic_fstring {\n private:\n  basic_string_view<Char> str_;\n\n  static constexpr int num_static_named_args =\n      detail::count_static_named_args<T...>();\n\n  using checker = detail::format_string_checker<\n      Char, static_cast<int>(sizeof...(T)), num_static_named_args,\n      num_static_named_args != detail::count_named_args<T...>()>;\n\n  using arg_pack = detail::arg_pack<T...>;\n\n public:\n  using t = basic_fstring;\n\n  template <typename S,\n            FMT_ENABLE_IF(\n                std::is_convertible<const S&, basic_string_view<Char>>::value)>\n  FMT_CONSTEVAL FMT_ALWAYS_INLINE basic_fstring(const S& s) : str_(s) {\n    if (FMT_USE_CONSTEVAL)\n      detail::parse_format_string<Char>(s, checker(s, arg_pack()));\n  }\n  template <typename S,\n            FMT_ENABLE_IF(std::is_base_of<detail::compile_string, S>::value&&\n                              std::is_same<typename S::char_type, Char>::value)>\n  FMT_ALWAYS_INLINE basic_fstring(const S&) : str_(S()) {\n    FMT_CONSTEXPR auto sv = basic_string_view<Char>(S());\n    FMT_CONSTEXPR int ignore =\n        (parse_format_string(sv, checker(sv, arg_pack())), 0);\n    detail::ignore_unused(ignore);\n  }\n  basic_fstring(runtime_format_string<Char> fmt) : str_(fmt.str) {}\n\n  operator basic_string_view<Char>() const { return str_; }\n  auto get() const -> basic_string_view<Char> { return str_; }\n};\n\ntemplate <typename Char, typename... T>\nusing basic_format_string = basic_fstring<Char, T...>;\n\ntemplate <typename... T>\nusing wformat_string = typename basic_format_string<wchar_t, T...>::t;\ninline auto runtime(wstring_view s) -> runtime_format_string<wchar_t> {\n  return {{s}};\n}\n\ntemplate <typename... T>\nconstexpr auto make_wformat_args(T&... args)\n    -> decltype(fmt::make_format_args<wformat_context>(args...)) {\n  return fmt::make_format_args<wformat_context>(args...);\n}\n\n#if !FMT_USE_NONTYPE_TEMPLATE_ARGS\ninline namespace literals {\ninline auto operator\"\"_a(const wchar_t* s, size_t) -> detail::udl_arg<wchar_t> {\n  return {s};\n}\n}  // namespace literals\n#endif\n\ntemplate <typename It, typename Sentinel>\nauto join(It begin, Sentinel end, wstring_view sep)\n    -> join_view<It, Sentinel, wchar_t> {\n  return {begin, end, sep};\n}\n\ntemplate <typename Range, FMT_ENABLE_IF(!is_tuple_like<Range>::value)>\nauto join(Range&& range, wstring_view sep)\n    -> join_view<decltype(std::begin(range)), decltype(std::end(range)),\n                 wchar_t> {\n  return join(std::begin(range), std::end(range), sep);\n}\n\ntemplate <typename T>\nauto join(std::initializer_list<T> list, wstring_view sep)\n    -> join_view<const T*, const T*, wchar_t> {\n  return join(std::begin(list), std::end(list), sep);\n}\n\ntemplate <typename Tuple, FMT_ENABLE_IF(is_tuple_like<Tuple>::value)>\nauto join(const Tuple& tuple, basic_string_view<wchar_t> sep)\n    -> tuple_join_view<Tuple, wchar_t> {\n  return {tuple, sep};\n}\n\ntemplate <typename Char, FMT_ENABLE_IF(!std::is_same<Char, char>::value)>\nauto vformat(basic_string_view<Char> fmt,\n             basic_format_args<buffered_context<Char>> args)\n    -> std::basic_string<Char> {\n  auto buf = basic_memory_buffer<Char>();\n  detail::vformat_to(buf, fmt, args);\n  return {buf.data(), buf.size()};\n}\n\ntemplate <typename... T>\nauto format(wformat_string<T...> fmt, T&&... args) -> std::wstring {\n  return vformat(fmt::wstring_view(fmt), fmt::make_wformat_args(args...));\n}\n\ntemplate <typename OutputIt, typename... T>\nauto format_to(OutputIt out, wformat_string<T...> fmt, T&&... args)\n    -> OutputIt {\n  return vformat_to(out, fmt::wstring_view(fmt),\n                    fmt::make_wformat_args(args...));\n}\n\n// Pass char_t as a default template parameter instead of using\n// std::basic_string<char_t<S>> to reduce the symbol size.\ntemplate <typename S, typename... T,\n          typename Char = detail::format_string_char_t<S>,\n          FMT_ENABLE_IF(!std::is_same<Char, char>::value &&\n                        !std::is_same<Char, wchar_t>::value)>\nauto format(const S& fmt, T&&... args) -> std::basic_string<Char> {\n  return vformat(detail::to_string_view(fmt),\n                 fmt::make_format_args<buffered_context<Char>>(args...));\n}\n\ntemplate <typename S, typename Char = detail::format_string_char_t<S>,\n          FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>\ninline auto vformat(locale_ref loc, const S& fmt,\n                    basic_format_args<buffered_context<Char>> args)\n    -> std::basic_string<Char> {\n  auto buf = basic_memory_buffer<Char>();\n  detail::vformat_to(buf, detail::to_string_view(fmt), args, loc);\n  return {buf.data(), buf.size()};\n}\n\ntemplate <typename S, typename... T,\n          typename Char = detail::format_string_char_t<S>,\n          FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>\ninline auto format(locale_ref loc, const S& fmt, T&&... args)\n    -> std::basic_string<Char> {\n  return vformat(loc, detail::to_string_view(fmt),\n                 fmt::make_format_args<buffered_context<Char>>(args...));\n}\n\ntemplate <typename OutputIt, typename S,\n          typename Char = detail::format_string_char_t<S>,\n          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&\n                            detail::is_exotic_char<Char>::value)>\nauto vformat_to(OutputIt out, const S& fmt,\n                basic_format_args<buffered_context<Char>> args) -> OutputIt {\n  auto&& buf = detail::get_buffer<Char>(out);\n  detail::vformat_to(buf, detail::to_string_view(fmt), args);\n  return detail::get_iterator(buf, out);\n}\n\ntemplate <typename OutputIt, typename S, typename... T,\n          typename Char = detail::format_string_char_t<S>,\n          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value &&\n                        !std::is_same<Char, char>::value &&\n                        !std::is_same<Char, wchar_t>::value)>\ninline auto format_to(OutputIt out, const S& fmt, T&&... args) -> OutputIt {\n  return vformat_to(out, detail::to_string_view(fmt),\n                    fmt::make_format_args<buffered_context<Char>>(args...));\n}\n\ntemplate <typename S, typename OutputIt, typename... Args,\n          typename Char = detail::format_string_char_t<S>,\n          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&\n                            detail::is_exotic_char<Char>::value)>\ninline auto vformat_to(OutputIt out, locale_ref loc, const S& fmt,\n                       basic_format_args<buffered_context<Char>> args)\n    -> OutputIt {\n  auto&& buf = detail::get_buffer<Char>(out);\n  vformat_to(buf, detail::to_string_view(fmt), args, loc);\n  return detail::get_iterator(buf, out);\n}\n\ntemplate <typename OutputIt, typename S, typename... T,\n          typename Char = detail::format_string_char_t<S>,\n          bool enable = detail::is_output_iterator<OutputIt, Char>::value &&\n                        detail::is_exotic_char<Char>::value>\ninline auto format_to(OutputIt out, locale_ref loc, const S& fmt, T&&... args)\n    -> typename std::enable_if<enable, OutputIt>::type {\n  return vformat_to(out, loc, detail::to_string_view(fmt),\n                    fmt::make_format_args<buffered_context<Char>>(args...));\n}\n\ntemplate <typename OutputIt, typename Char, typename... Args,\n          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&\n                            detail::is_exotic_char<Char>::value)>\ninline auto vformat_to_n(OutputIt out, size_t n, basic_string_view<Char> fmt,\n                         basic_format_args<buffered_context<Char>> args)\n    -> format_to_n_result<OutputIt> {\n  using traits = detail::fixed_buffer_traits;\n  auto buf = detail::iterator_buffer<OutputIt, Char, traits>(out, n);\n  detail::vformat_to(buf, fmt, args);\n  return {buf.out(), buf.count()};\n}\n\ntemplate <typename OutputIt, typename S, typename... T,\n          typename Char = detail::format_string_char_t<S>,\n          FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, Char>::value&&\n                            detail::is_exotic_char<Char>::value)>\ninline auto format_to_n(OutputIt out, size_t n, const S& fmt, T&&... args)\n    -> format_to_n_result<OutputIt> {\n  return vformat_to_n(out, n, fmt::basic_string_view<Char>(fmt),\n                      fmt::make_format_args<buffered_context<Char>>(args...));\n}\n\ntemplate <typename S, typename... T,\n          typename Char = detail::format_string_char_t<S>,\n          FMT_ENABLE_IF(detail::is_exotic_char<Char>::value)>\ninline auto formatted_size(const S& fmt, T&&... args) -> size_t {\n  auto buf = detail::counting_buffer<Char>();\n  detail::vformat_to(buf, detail::to_string_view(fmt),\n                     fmt::make_format_args<buffered_context<Char>>(args...));\n  return buf.count();\n}\n\ninline void vprint(std::FILE* f, wstring_view fmt, wformat_args args) {\n  auto buf = wmemory_buffer();\n  detail::vformat_to(buf, fmt, args);\n  buf.push_back(L'\\0');\n  if (std::fputws(buf.data(), f) == -1)\n    FMT_THROW(system_error(errno, FMT_STRING(\"cannot write to file\")));\n}\n\ninline void vprint(wstring_view fmt, wformat_args args) {\n  vprint(stdout, fmt, args);\n}\n\ntemplate <typename... T>\nvoid print(std::FILE* f, wformat_string<T...> fmt, T&&... args) {\n  return vprint(f, wstring_view(fmt), fmt::make_wformat_args(args...));\n}\n\ntemplate <typename... T> void print(wformat_string<T...> fmt, T&&... args) {\n  return vprint(wstring_view(fmt), fmt::make_wformat_args(args...));\n}\n\ntemplate <typename... T>\nvoid println(std::FILE* f, wformat_string<T...> fmt, T&&... args) {\n  return print(f, L\"{}\\n\", fmt::format(fmt, std::forward<T>(args)...));\n}\n\ntemplate <typename... T> void println(wformat_string<T...> fmt, T&&... args) {\n  return print(L\"{}\\n\", fmt::format(fmt, std::forward<T>(args)...));\n}\n\ninline auto vformat(text_style ts, wstring_view fmt, wformat_args args)\n    -> std::wstring {\n  auto buf = wmemory_buffer();\n  detail::vformat_to(buf, ts, fmt, args);\n  return {buf.data(), buf.size()};\n}\n\ntemplate <typename... T>\ninline auto format(text_style ts, wformat_string<T...> fmt, T&&... args)\n    -> std::wstring {\n  return fmt::vformat(ts, fmt, fmt::make_wformat_args(args...));\n}\n\ninline void vprint(std::wostream& os, wstring_view fmt, wformat_args args) {\n  auto buffer = basic_memory_buffer<wchar_t>();\n  detail::vformat_to(buffer, fmt, args);\n  detail::write_buffer(os, buffer);\n}\n\ntemplate <typename... T>\nvoid print(std::wostream& os, wformat_string<T...> fmt, T&&... args) {\n  vprint(os, fmt, fmt::make_format_args<buffered_context<wchar_t>>(args...));\n}\n\ntemplate <typename... T>\nvoid println(std::wostream& os, wformat_string<T...> fmt, T&&... args) {\n  print(os, L\"{}\\n\", fmt::format(fmt, std::forward<T>(args)...));\n}\n\n/// Converts `value` to `std::wstring` using the default format for type `T`.\ntemplate <typename T> inline auto to_wstring(const T& value) -> std::wstring {\n  return format(FMT_STRING(L\"{}\"), value);\n}\nFMT_END_EXPORT\nFMT_END_NAMESPACE\n\n#endif  // FMT_XCHAR_H_\n"
  },
  {
    "path": "thirdparty/fmt/src/fmt.cc",
    "content": "module;\n\n#define FMT_MODULE\n\n#ifdef _MSVC_LANG\n#  define FMT_CPLUSPLUS _MSVC_LANG\n#else\n#  define FMT_CPLUSPLUS __cplusplus\n#endif\n\n// Put all implementation-provided headers into the global module fragment\n// to prevent attachment to this module.\n#ifndef FMT_IMPORT_STD\n#  include <algorithm>\n#  include <bitset>\n#  include <chrono>\n#  include <cmath>\n#  include <complex>\n#  include <cstddef>\n#  include <cstdint>\n#  include <cstdio>\n#  include <cstdlib>\n#  include <cstring>\n#  include <ctime>\n#  include <exception>\n#  if FMT_CPLUSPLUS > 202002L\n#    include <expected>\n#  endif\n#  include <filesystem>\n#  include <fstream>\n#  include <functional>\n#  include <iterator>\n#  include <limits>\n#  include <locale>\n#  include <memory>\n#  include <optional>\n#  include <ostream>\n#  include <source_location>\n#  include <stdexcept>\n#  include <string>\n#  include <string_view>\n#  include <system_error>\n#  include <thread>\n#  include <type_traits>\n#  include <typeinfo>\n#  include <utility>\n#  include <variant>\n#  include <vector>\n#else\n#  include <limits.h>\n#  include <stdint.h>\n#  include <stdio.h>\n#  include <stdlib.h>\n#  include <string.h>\n#  include <time.h>\n#endif\n#include <cerrno>\n#include <climits>\n#include <version>\n\n#if __has_include(<cxxabi.h>)\n#  include <cxxabi.h>\n#endif\n#if defined(_MSC_VER) || defined(__MINGW32__)\n#  include <intrin.h>\n#endif\n#if defined __APPLE__ || defined(__FreeBSD__)\n#  include <xlocale.h>\n#endif\n#if __has_include(<winapifamily.h>)\n#  include <winapifamily.h>\n#endif\n#if (__has_include(<fcntl.h>) || defined(__APPLE__) || \\\n     defined(__linux__)) &&                            \\\n    (!defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))\n#  include <fcntl.h>\n#  include <sys/stat.h>\n#  include <sys/types.h>\n#  ifndef _WIN32\n#    include <unistd.h>\n#  else\n#    include <io.h>\n#  endif\n#endif\n#ifdef _WIN32\n#  if defined(__GLIBCXX__)\n#    include <ext/stdio_filebuf.h>\n#    include <ext/stdio_sync_filebuf.h>\n#  endif\n#  define WIN32_LEAN_AND_MEAN\n#  include <windows.h>\n#endif\n\nexport module fmt;\n\n#ifdef FMT_IMPORT_STD\nimport std;\n#endif\n\n#define FMT_EXPORT export\n#define FMT_BEGIN_EXPORT export {\n#define FMT_END_EXPORT }\n\n// If you define FMT_ATTACH_TO_GLOBAL_MODULE\n//  - all declarations are detached from module 'fmt'\n//  - the module behaves like a traditional static library, too\n//  - all library symbols are mangled traditionally\n//  - you can mix TUs with either importing or #including the {fmt} API\n#ifdef FMT_ATTACH_TO_GLOBAL_MODULE\nextern \"C++\" {\n#endif\n\n#ifndef FMT_OS\n#  define FMT_OS 1\n#endif\n\n// All library-provided declarations and definitions must be in the module\n// purview to be exported.\n#include \"fmt/args.h\"\n#include \"fmt/chrono.h\"\n#include \"fmt/color.h\"\n#include \"fmt/compile.h\"\n#include \"fmt/format.h\"\n#if FMT_OS\n#  include \"fmt/os.h\"\n#endif\n#include \"fmt/ostream.h\"\n#include \"fmt/printf.h\"\n#include \"fmt/ranges.h\"\n#include \"fmt/std.h\"\n#include \"fmt/xchar.h\"\n\n#ifdef FMT_ATTACH_TO_GLOBAL_MODULE\n}\n#endif\n\n// gcc doesn't yet implement private module fragments\n#if !FMT_GCC_VERSION\nmodule :private;\n#endif\n\n#ifdef FMT_ATTACH_TO_GLOBAL_MODULE\nextern \"C++\" {\n#endif\n\n#if FMT_HAS_INCLUDE(\"format.cc\")\n#  include \"format.cc\"\n#endif\n#if FMT_OS && FMT_HAS_INCLUDE(\"os.cc\")\n#  include \"os.cc\"\n#endif\n\n#ifdef FMT_ATTACH_TO_GLOBAL_MODULE\n}\n#endif\n"
  },
  {
    "path": "thirdparty/fmt/src/format.cc",
    "content": "// Formatting library for C++\n//\n// Copyright (c) 2012 - 2016, Victor Zverovich\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\n#include \"fmt/format-inl.h\"\n\nFMT_BEGIN_NAMESPACE\n\n#if FMT_USE_LOCALE\ntemplate FMT_API locale_ref::locale_ref(const std::locale& loc);  // DEPRECATED!\ntemplate FMT_API auto locale_ref::get<std::locale>() const -> std::locale;\n#endif\n\nnamespace detail {\n\ntemplate FMT_API auto dragonbox::to_decimal(float x) noexcept\n    -> dragonbox::decimal_fp<float>;\ntemplate FMT_API auto dragonbox::to_decimal(double x) noexcept\n    -> dragonbox::decimal_fp<double>;\n\n// Explicit instantiations for char.\n\ntemplate FMT_API auto thousands_sep_impl(locale_ref)\n    -> thousands_sep_result<char>;\ntemplate FMT_API auto decimal_point_impl(locale_ref) -> char;\n\n// DEPRECATED!\ntemplate FMT_API void buffer<char>::append(const char*, const char*);\n\n// Explicit instantiations for wchar_t.\n\ntemplate FMT_API auto thousands_sep_impl(locale_ref)\n    -> thousands_sep_result<wchar_t>;\ntemplate FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;\n\n// DEPRECATED!\ntemplate FMT_API void buffer<wchar_t>::append(const wchar_t*, const wchar_t*);\n\n}  // namespace detail\nFMT_END_NAMESPACE\n"
  },
  {
    "path": "thirdparty/fmt/src/os.cc",
    "content": "// Formatting library for C++ - optional OS-specific functionality\n//\n// Copyright (c) 2012 - 2016, Victor Zverovich\n// All rights reserved.\n//\n// For the license information refer to format.h.\n\n// Disable bogus MSVC warnings.\n#if !defined(_CRT_SECURE_NO_WARNINGS) && defined(_MSC_VER)\n#  define _CRT_SECURE_NO_WARNINGS\n#endif\n\n#include \"fmt/os.h\"\n\n#ifndef FMT_MODULE\n#  include <climits>\n\n#  if FMT_USE_FCNTL\n#    include <sys/stat.h>\n#    include <sys/types.h>\n\n#    ifdef _WRS_KERNEL    // VxWorks7 kernel\n#      include <ioLib.h>  // getpagesize\n#    endif\n\n#    ifndef _WIN32\n#      include <unistd.h>\n#    else\n#      ifndef WIN32_LEAN_AND_MEAN\n#        define WIN32_LEAN_AND_MEAN\n#      endif\n#      include <io.h>\n#    endif  // _WIN32\n#  endif    // FMT_USE_FCNTL\n\n#  ifdef _WIN32\n#    include <windows.h>\n#  endif\n#endif\n\n#ifdef _WIN32\n#  ifndef S_IRUSR\n#    define S_IRUSR _S_IREAD\n#  endif\n#  ifndef S_IWUSR\n#    define S_IWUSR _S_IWRITE\n#  endif\n#  ifndef S_IRGRP\n#    define S_IRGRP 0\n#  endif\n#  ifndef S_IWGRP\n#    define S_IWGRP 0\n#  endif\n#  ifndef S_IROTH\n#    define S_IROTH 0\n#  endif\n#  ifndef S_IWOTH\n#    define S_IWOTH 0\n#  endif\n#endif\n\nnamespace {\n#ifdef _WIN32\n// Return type of read and write functions.\nusing rwresult = int;\n\n// On Windows the count argument to read and write is unsigned, so convert\n// it from size_t preventing integer overflow.\ninline unsigned convert_rwcount(size_t count) {\n  return count <= UINT_MAX ? static_cast<unsigned>(count) : UINT_MAX;\n}\n#elif FMT_USE_FCNTL\n// Return type of read and write functions.\nusing rwresult = ssize_t;\n\ninline auto convert_rwcount(size_t count) -> size_t { return count; }\n#endif\n}  // namespace\n\nFMT_BEGIN_NAMESPACE\n\n#ifdef _WIN32\nnamespace detail {\n\nclass system_message {\n  system_message(const system_message&) = delete;\n  void operator=(const system_message&) = delete;\n\n  unsigned long result_;\n  wchar_t* message_;\n\n  static bool is_whitespace(wchar_t c) noexcept {\n    return c == L' ' || c == L'\\n' || c == L'\\r' || c == L'\\t' || c == L'\\0';\n  }\n\n public:\n  explicit system_message(unsigned long error_code)\n      : result_(0), message_(nullptr) {\n    result_ = FormatMessageW(\n        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |\n            FORMAT_MESSAGE_IGNORE_INSERTS,\n        nullptr, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\n        reinterpret_cast<wchar_t*>(&message_), 0, nullptr);\n    if (result_ != 0) {\n      while (result_ != 0 && is_whitespace(message_[result_ - 1])) {\n        --result_;\n      }\n    }\n  }\n  ~system_message() { LocalFree(message_); }\n  explicit operator bool() const noexcept { return result_ != 0; }\n  operator basic_string_view<wchar_t>() const noexcept {\n    return basic_string_view<wchar_t>(message_, result_);\n  }\n};\n\nclass utf8_system_category final : public std::error_category {\n public:\n  const char* name() const noexcept override { return \"system\"; }\n  std::string message(int error_code) const override {\n    auto&& msg = system_message(error_code);\n    if (msg) {\n      auto utf8_message = to_utf8<wchar_t>();\n      if (utf8_message.convert(msg)) {\n        return utf8_message.str();\n      }\n    }\n    return \"unknown error\";\n  }\n};\n\n}  // namespace detail\n\nFMT_API const std::error_category& system_category() noexcept {\n  static const detail::utf8_system_category category;\n  return category;\n}\n\nstd::system_error vwindows_error(int err_code, string_view format_str,\n                                 format_args args) {\n  auto ec = std::error_code(err_code, system_category());\n  return std::system_error(ec, vformat(format_str, args));\n}\n\nvoid detail::format_windows_error(detail::buffer<char>& out, int error_code,\n                                  const char* message) noexcept {\n  FMT_TRY {\n    auto&& msg = system_message(error_code);\n    if (msg) {\n      auto utf8_message = to_utf8<wchar_t>();\n      if (utf8_message.convert(msg)) {\n        fmt::format_to(appender(out), FMT_STRING(\"{}: {}\"), message,\n                       string_view(utf8_message));\n        return;\n      }\n    }\n  }\n  FMT_CATCH(...) {}\n  format_error_code(out, error_code, message);\n}\n\nvoid report_windows_error(int error_code, const char* message) noexcept {\n  do_report_error(detail::format_windows_error, error_code, message);\n}\n#endif  // _WIN32\n\nbuffered_file::~buffered_file() noexcept {\n  if (file_ && FMT_SYSTEM(fclose(file_)) != 0)\n    report_system_error(errno, \"cannot close file\");\n}\n\nbuffered_file::buffered_file(cstring_view filename, cstring_view mode) {\n  FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())),\n                nullptr);\n  if (!file_)\n    FMT_THROW(system_error(errno, FMT_STRING(\"cannot open file {}\"),\n                           filename.c_str()));\n}\n\nvoid buffered_file::close() {\n  if (!file_) return;\n  int result = FMT_SYSTEM(fclose(file_));\n  file_ = nullptr;\n  if (result != 0)\n    FMT_THROW(system_error(errno, FMT_STRING(\"cannot close file\")));\n}\n\nauto buffered_file::descriptor() const -> int {\n#ifdef FMT_HAS_SYSTEM\n  // fileno is a macro on OpenBSD.\n#  ifdef fileno\n#    undef fileno\n#  endif\n  int fd = FMT_POSIX_CALL(fileno(file_));\n#elif defined(_WIN32)\n  int fd = _fileno(file_);\n#else\n  int fd = fileno(file_);\n#endif\n  if (fd == -1)\n    FMT_THROW(system_error(errno, FMT_STRING(\"cannot get file descriptor\")));\n  return fd;\n}\n\n#if FMT_USE_FCNTL\n#  ifdef _WIN32\nusing mode_t = int;\n#  endif\n\nconstexpr mode_t default_open_mode =\n    S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;\n\nfile::file(cstring_view path, int oflag) {\n#  if defined(_WIN32) && !defined(__MINGW32__)\n  fd_ = -1;\n  auto converted = detail::utf8_to_utf16(string_view(path.c_str()));\n  *this = file::open_windows_file(converted.c_str(), oflag);\n#  else\n  FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, default_open_mode)));\n  if (fd_ == -1)\n    FMT_THROW(\n        system_error(errno, FMT_STRING(\"cannot open file {}\"), path.c_str()));\n#  endif\n}\n\nfile::~file() noexcept {\n  // Don't retry close in case of EINTR!\n  // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html\n  if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0)\n    report_system_error(errno, \"cannot close file\");\n}\n\nvoid file::close() {\n  if (fd_ == -1) return;\n  // Don't retry close in case of EINTR!\n  // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html\n  int result = FMT_POSIX_CALL(close(fd_));\n  fd_ = -1;\n  if (result != 0)\n    FMT_THROW(system_error(errno, FMT_STRING(\"cannot close file\")));\n}\n\nauto file::size() const -> long long {\n#  ifdef _WIN32\n  // Use GetFileSize instead of GetFileSizeEx for the case when _WIN32_WINNT\n  // is less than 0x0500 as is the case with some default MinGW builds.\n  // Both functions support large file sizes.\n  DWORD size_upper = 0;\n  HANDLE handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd_));\n  DWORD size_lower = FMT_SYSTEM(GetFileSize(handle, &size_upper));\n  if (size_lower == INVALID_FILE_SIZE) {\n    DWORD error = GetLastError();\n    if (error != NO_ERROR)\n      FMT_THROW(windows_error(error, \"cannot get file size\"));\n  }\n  unsigned long long long_size = size_upper;\n  return (long_size << sizeof(DWORD) * CHAR_BIT) | size_lower;\n#  else\n  using Stat = struct stat;\n  Stat file_stat = Stat();\n  if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1)\n    FMT_THROW(system_error(errno, FMT_STRING(\"cannot get file attributes\")));\n  static_assert(sizeof(long long) >= sizeof(file_stat.st_size),\n                \"return type of file::size is not large enough\");\n  return file_stat.st_size;\n#  endif\n}\n\nauto file::read(void* buffer, size_t count) -> size_t {\n  rwresult result = 0;\n  FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count))));\n  if (result < 0)\n    FMT_THROW(system_error(errno, FMT_STRING(\"cannot read from file\")));\n  return detail::to_unsigned(result);\n}\n\nauto file::write(const void* buffer, size_t count) -> size_t {\n  rwresult result = 0;\n  FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));\n  if (result < 0)\n    FMT_THROW(system_error(errno, FMT_STRING(\"cannot write to file\")));\n  return detail::to_unsigned(result);\n}\n\nauto file::dup(int fd) -> file {\n  // Don't retry as dup doesn't return EINTR.\n  // http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html\n  int new_fd = FMT_POSIX_CALL(dup(fd));\n  if (new_fd == -1)\n    FMT_THROW(system_error(\n        errno, FMT_STRING(\"cannot duplicate file descriptor {}\"), fd));\n  return file(new_fd);\n}\n\nvoid file::dup2(int fd) {\n  int result = 0;\n  FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));\n  if (result == -1) {\n    FMT_THROW(system_error(\n        errno, FMT_STRING(\"cannot duplicate file descriptor {} to {}\"), fd_,\n        fd));\n  }\n}\n\nvoid file::dup2(int fd, std::error_code& ec) noexcept {\n  int result = 0;\n  FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));\n  if (result == -1) ec = std::error_code(errno, std::generic_category());\n}\n\nauto file::fdopen(const char* mode) -> buffered_file {\n// Don't retry as fdopen doesn't return EINTR.\n#  if defined(__MINGW32__) && defined(_POSIX_)\n  FILE* f = ::fdopen(fd_, mode);\n#  else\n  FILE* f = FMT_POSIX_CALL(fdopen(fd_, mode));\n#  endif\n  if (!f) {\n    FMT_THROW(system_error(\n        errno, FMT_STRING(\"cannot associate stream with file descriptor\")));\n  }\n  buffered_file bf(f);\n  fd_ = -1;\n  return bf;\n}\n\n#  if defined(_WIN32) && !defined(__MINGW32__)\nfile file::open_windows_file(wcstring_view path, int oflag) {\n  int fd = -1;\n  auto err = _wsopen_s(&fd, path.c_str(), oflag, _SH_DENYNO, default_open_mode);\n  if (fd == -1) {\n    FMT_THROW(system_error(err, FMT_STRING(\"cannot open file {}\"),\n                           detail::to_utf8<wchar_t>(path.c_str()).c_str()));\n  }\n  return file(fd);\n}\n#  endif\n\npipe::pipe() {\n  int fds[2] = {};\n#  ifdef _WIN32\n  // Make the default pipe capacity same as on Linux 2.6.11+.\n  enum { DEFAULT_CAPACITY = 65536 };\n  int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY));\n#  else\n  // Don't retry as the pipe function doesn't return EINTR.\n  // http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html\n  int result = FMT_POSIX_CALL(pipe(fds));\n#  endif\n  if (result != 0)\n    FMT_THROW(system_error(errno, FMT_STRING(\"cannot create pipe\")));\n  // The following assignments don't throw.\n  read_end = file(fds[0]);\n  write_end = file(fds[1]);\n}\n\n#  if !defined(__MSDOS__)\nauto getpagesize() -> long {\n#    ifdef _WIN32\n  SYSTEM_INFO si;\n  GetSystemInfo(&si);\n  return si.dwPageSize;\n#    else\n#      ifdef _WRS_KERNEL\n  long size = FMT_POSIX_CALL(getpagesize());\n#      else\n  long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE));\n#      endif\n\n  if (size < 0)\n    FMT_THROW(system_error(errno, FMT_STRING(\"cannot get memory page size\")));\n  return size;\n#    endif\n}\n#  endif\n\nvoid ostream::grow(buffer<char>& buf, size_t) {\n  if (buf.size() == buf.capacity()) static_cast<ostream&>(buf).flush();\n}\n\nostream::ostream(cstring_view path, const detail::ostream_params& params)\n    : buffer<char>(grow), file_(path, params.oflag) {\n  set(new char[params.buffer_size], params.buffer_size);\n}\n\nostream::ostream(ostream&& other) noexcept\n    : buffer<char>(grow, other.data(), other.size(), other.capacity()),\n      file_(std::move(other.file_)) {\n  other.clear();\n  other.set(nullptr, 0);\n}\n\nostream::~ostream() {\n  flush();\n  delete[] data();\n}\n#endif  // FMT_USE_FCNTL\nFMT_END_NAMESPACE\n"
  },
  {
    "path": "thirdparty/notes.md",
    "content": "For CppAD, remember to change `# define CPPAD_C_COMPILER_MSVC_FLAGS 0` and `# define CPPAD_HAS_TMPNAM_S 0` in `cppad/include/configure.hpp`\n\nUse `Get-ChildItem -Path . -Recurse -Filter *.xrst | Remove-Item -Force` to remove all `.xrst` files in CppAD directory.\n\nFor IPOPT, remember to mask `IPOPTLIB_EXPORT` in `solvers/ipopt/IpoptConfig.h`"
  },
  {
    "path": "thirdparty/solvers/copt/copt.h",
    "content": "#ifndef __COPT_H__\n#define __COPT_H__\n\n#ifdef _WIN32\n#define COPT_CALL __stdcall\n#else\n#define COPT_CALL\n#endif\n\n#ifdef _WIN32\n#if defined(__MINGW64__)\n#define COPT_INT64 long long\n#else\n#define COPT_INT64 __int64\n#endif\n#elif defined(__LP64__) || defined(_LP64) || defined(__ILP64__) || defined(_ILP64)\n#define COPT_INT64 long\n#else\n#define COPT_INT64 long long\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define COPT_VERSION_MAJOR                      8\n#define COPT_VERSION_MINOR                      0\n#define COPT_VERSION_TECHNICAL                  1\n\n\n/*\n * Constants\n */\n\n/* Optimization direction */\n#define COPT_MINIMIZE                           1\n#define COPT_MAXIMIZE                          -1\n\n/* Default infinity value */\n#define COPT_INFINITY                           1e30\n#define COPT_UNDEFINED                          1e40\n\n/* Recommended buffer size for messages */\n#define COPT_BUFFSIZE                           1000\n\n/* Constraint types */\n#define COPT_LESS_EQUAL                        'L'\n#define COPT_GREATER_EQUAL                     'G'\n#define COPT_EQUAL                             'E'\n#define COPT_FREE                              'N'\n#define COPT_RANGE                             'R'\n\n/* Variable types */\n#define COPT_CONTINUOUS                        'C'\n#define COPT_BINARY                            'B'\n#define COPT_INTEGER                           'I'\n\n/* SOS types */\n#define COPT_SOS_TYPE1                          1\n#define COPT_SOS_TYPE2                          2\n\n/* Indicator types */\n#define COPT_INDICATOR_IF                       1\n#define COPT_INDICATOR_ONLYIF                   2\n#define COPT_INDICATOR_IFANDONLYIF              3\n\n/* Cone types */\n#define COPT_CONE_QUAD                          1\n#define COPT_CONE_RQUAD                         2\n\n/* Exponential cone types */\n#define COPT_EXPCONE_PRIMAL                     3\n#define COPT_EXPCONE_DUAL                       4\n\n/* API function return code */\n#define COPT_RETCODE_OK                         0\n#define COPT_RETCODE_MEMORY                     1\n#define COPT_RETCODE_FILE                       2\n#define COPT_RETCODE_INVALID                    3\n#define COPT_RETCODE_LICENSE                    4\n#define COPT_RETCODE_INTERNAL                   5\n#define COPT_RETCODE_THREAD                     6\n#define COPT_RETCODE_SERVER                     7\n#define COPT_RETCODE_NONCONVEX                  8\n#define COPT_RETCODE_MEMORY_GPU                 9\n\n/* Basis status */\n#define COPT_BASIS_LOWER                        0\n#define COPT_BASIS_BASIC                        1\n#define COPT_BASIS_UPPER                        2\n#define COPT_BASIS_SUPERBASIC                   3\n#define COPT_BASIS_FIXED                        4\n\n/* LP status */\n#define COPT_LPSTATUS_UNSTARTED                 0\n#define COPT_LPSTATUS_OPTIMAL                   1\n#define COPT_LPSTATUS_INFEASIBLE                2\n#define COPT_LPSTATUS_UNBOUNDED                 3\n#define COPT_LPSTATUS_NUMERICAL                 5\n#define COPT_LPSTATUS_IMPRECISE                 7\n#define COPT_LPSTATUS_TIMEOUT                   8\n#define COPT_LPSTATUS_UNFINISHED                9\n#define COPT_LPSTATUS_INTERRUPTED               10\n#define COPT_LPSTATUS_ITERLIMIT                 11\n\n/* MIP status */\n#define COPT_MIPSTATUS_UNSTARTED                0\n#define COPT_MIPSTATUS_OPTIMAL                  1\n#define COPT_MIPSTATUS_INFEASIBLE               2\n#define COPT_MIPSTATUS_UNBOUNDED                3\n#define COPT_MIPSTATUS_INF_OR_UNB               4\n#define COPT_MIPSTATUS_NODELIMIT                6\n#define COPT_MIPSTATUS_TIMEOUT                  8\n#define COPT_MIPSTATUS_UNFINISHED               9\n#define COPT_MIPSTATUS_INTERRUPTED              10\n\n/* Callback context */\n#define COPT_CBCONTEXT_MIPRELAX                 0x1\n#define COPT_CBCONTEXT_MIPSOL                   0x2\n#define COPT_CBCONTEXT_MIPNODE                  0x4\n#define COPT_CBCONTEXT_INCUMBENT                0x8\n\n/* Callback information */\n#define COPT_CBINFO_BESTOBJ                     \"BestObj\"\n#define COPT_CBINFO_BESTBND                     \"BestBnd\"\n#define COPT_CBINFO_HASINCUMBENT                \"HasIncumbent\"\n#define COPT_CBINFO_INCUMBENT                   \"Incumbent\"\n#define COPT_CBINFO_MIPCANDIDATE                \"MipCandidate\"\n#define COPT_CBINFO_MIPCANDOBJ                  \"MipCandObj\"\n#define COPT_CBINFO_RELAXSOLUTION               \"RelaxSolution\"\n#define COPT_CBINFO_RELAXSOLOBJ                 \"RelaxSolObj\"\n#define COPT_CBINFO_NODESTATUS                  \"NodeStatus\"\n\n/*\n * Parameters and attributes\n */\n\n/* Double parameters */\n#define COPT_DBLPARAM_TIMELIMIT                 \"TimeLimit\"\n#define COPT_DBLPARAM_SOLTIMELIMIT              \"SolTimeLimit\"\n#define COPT_DBLPARAM_MATRIXTOL                 \"MatrixTol\"\n#define COPT_DBLPARAM_FEASTOL                   \"FeasTol\"\n#define COPT_DBLPARAM_DUALTOL                   \"DualTol\"\n#define COPT_DBLPARAM_INTTOL                    \"IntTol\"\n#define COPT_DBLPARAM_PDLPTOL                   \"PDLPTol\"\n#define COPT_DBLPARAM_NLPTOL                    \"NLPTol\"\n#define COPT_DBLPARAM_RELGAP                    \"RelGap\"\n#define COPT_DBLPARAM_ABSGAP                    \"AbsGap\"\n#define COPT_DBLPARAM_TUNETIMELIMIT             \"TuneTimeLimit\"\n#define COPT_DBLPARAM_TUNETARGETTIME            \"TuneTargetTime\"\n#define COPT_DBLPARAM_TUNETARGETRELGAP          \"TuneTargetRelGap\"\n#define COPT_DBLPARAM_MULTIOBJTIMELIMIT         \"MultiObjTimeLimit\"\n\n/* Integer parameters */\n#define COPT_INTPARAM_LOGGING                   \"Logging\"\n#define COPT_INTPARAM_LOGLEVEL                  \"LogLevel\"\n#define COPT_INTPARAM_LOGTOCONSOLE              \"LogToConsole\"\n#define COPT_INTPARAM_PRESOLVE                  \"Presolve\"\n#define COPT_INTPARAM_SCALING                   \"Scaling\"\n#define COPT_INTPARAM_DUALIZE                   \"Dualize\"\n#define COPT_INTPARAM_LPMETHOD                  \"LpMethod\"\n#define COPT_INTPARAM_GPUMODE                   \"GPUMode\"\n#define COPT_INTPARAM_GPUDEVICE                 \"GPUDevice\"\n#define COPT_INTPARAM_REQFARKASRAY              \"ReqFarkasRay\"\n#define COPT_INTPARAM_REQSENSITIVITY            \"ReqSensitivity\"\n#define COPT_INTPARAM_DUALPRICE                 \"DualPrice\"\n#define COPT_INTPARAM_DUALPERTURB               \"DualPerturb\"\n#define COPT_INTPARAM_CUTLEVEL                  \"CutLevel\"\n#define COPT_INTPARAM_ROOTCUTLEVEL              \"RootCutLevel\"\n#define COPT_INTPARAM_TREECUTLEVEL              \"TreeCutLevel\"\n#define COPT_INTPARAM_ROOTCUTROUNDS             \"RootCutRounds\"\n#define COPT_INTPARAM_NODECUTROUNDS             \"NodeCutRounds\"\n#define COPT_INTPARAM_HEURLEVEL                 \"HeurLevel\"\n#define COPT_INTPARAM_PREROOTHEURLEVEL          \"PreRootHeurLevel\"\n#define COPT_INTPARAM_ROUNDINGHEURLEVEL         \"RoundingHeurLevel\"\n#define COPT_INTPARAM_DIVINGHEURLEVEL           \"DivingHeurLevel\"\n#define COPT_INTPARAM_FAPHEURLEVEL              \"FAPHeurLevel\"\n#define COPT_INTPARAM_SUBMIPHEURLEVEL           \"SubMipHeurLevel\"\n#define COPT_INTPARAM_STRONGBRANCHING           \"StrongBranching\"\n#define COPT_INTPARAM_CONFLICTANALYSIS          \"ConflictAnalysis\"\n#define COPT_INTPARAM_NODELIMIT                 \"NodeLimit\"\n#define COPT_INTPARAM_MIPTASKS                  \"MipTasks\"\n#define COPT_INTPARAM_BARHOMOGENEOUS            \"BarHomogeneous\"\n#define COPT_INTPARAM_BARORDER                  \"BarOrder\"\n#define COPT_INTPARAM_BARSTART                  \"BarStart\"\n#define COPT_INTPARAM_BARITERLIMIT              \"BarIterLimit\"\n#define COPT_INTPARAM_NONCONVEX                 \"NonConvex\"\n#define COPT_INTPARAM_NLPMUUPDATE               \"NLPMuUpdate\"\n#define COPT_INTPARAM_NLPLINSCALE               \"NLPLinScale\"\n#define COPT_INTPARAM_NLPITERLIMIT              \"NLPIterLimit\"\n#define COPT_INTPARAM_THREADS                   \"Threads\"\n#define COPT_INTPARAM_BARTHREADS                \"BarThreads\"\n#define COPT_INTPARAM_SIMPLEXTHREADS            \"SimplexThreads\"\n#define COPT_INTPARAM_CROSSOVERTHREADS          \"CrossoverThreads\"\n#define COPT_INTPARAM_CROSSOVER                 \"Crossover\"\n#define COPT_INTPARAM_SDPMETHOD                 \"SDPMethod\"\n#define COPT_INTPARAM_IISMETHOD                 \"IISMethod\"\n#define COPT_INTPARAM_FEASRELAXMODE             \"FeasRelaxMode\"\n#define COPT_INTPARAM_MIPSTARTMODE              \"MipStartMode\"\n#define COPT_INTPARAM_MIPSTARTNODELIMIT         \"MipStartNodeLimit\"\n#define COPT_INTPARAM_TUNEMETHOD                \"TuneMethod\"\n#define COPT_INTPARAM_TUNEMODE                  \"TuneMode\"\n#define COPT_INTPARAM_TUNEMEASURE               \"TuneMeasure\"\n#define COPT_INTPARAM_TUNEPERMUTES              \"TunePermutes\"\n#define COPT_INTPARAM_TUNEOUTPUTLEVEL           \"TuneOutputLevel\"\n#define COPT_INTPARAM_MULTIOBJPARAMMODE         \"MultiObjParamMode\"\n#define COPT_INTPARAM_LAZYCONSTRAINTS           \"LazyConstraints\"\n#define COPT_INTPARAM_LINEARIZEINDICATORS       \"LinearizeIndicators\"\n#define COPT_INTPARAM_LINEARIZESOS              \"LinearizeSos\"\n#define COPT_INTPARAM_MIPREPAIR                 \"MipRepair\"\n#define COPT_INTPARAM_MIPNLPITERLIMIT           \"MipNLPIterLimit\"\n\n/* Double attributes */\n#define COPT_DBLATTR_SOLVINGTIME                \"SolvingTime\"\n#define COPT_DBLATTR_OBJCONST                   \"ObjConst\"\n#define COPT_DBLATTR_LPOBJVAL                   \"LpObjval\"\n#define COPT_DBLATTR_BESTOBJ                    \"BestObj\"\n#define COPT_DBLATTR_BESTBND                    \"BestBnd\"\n#define COPT_DBLATTR_BESTGAP                    \"BestGap\"\n#define COPT_DBLATTR_FEASRELAXOBJ               \"FeasRelaxObj\"\n\n/* Integer attributes */\n#define COPT_INTATTR_MULTIOBJS                  \"MultiObjs\"\n#define COPT_INTATTR_COLS                       \"Cols\"\n#define COPT_INTATTR_PSDCOLS                    \"PSDCols\"\n#define COPT_INTATTR_ROWS                       \"Rows\"\n#define COPT_INTATTR_ELEMS                      \"Elems\"\n#define COPT_INTATTR_QELEMS                     \"QElems\"\n#define COPT_INTATTR_NLELEMS                    \"NLElems\"\n#define COPT_INTATTR_PSDELEMS                   \"PSDElems\"\n#define COPT_INTATTR_SYMMATS                    \"SymMats\"\n#define COPT_INTATTR_BINS                       \"Bins\"\n#define COPT_INTATTR_INTS                       \"Ints\"\n#define COPT_INTATTR_SOSS                       \"Soss\"\n#define COPT_INTATTR_CONES                      \"Cones\"\n#define COPT_INTATTR_EXPCONES                   \"ExpCones\"\n#define COPT_INTATTR_AFFINECONES                \"AffineCones\"\n#define COPT_INTATTR_QCONSTRS                   \"QConstrs\"\n#define COPT_INTATTR_NLCONSTRS                  \"NLConstrs\"\n#define COPT_INTATTR_PSDCONSTRS                 \"PSDConstrs\"\n#define COPT_INTATTR_LMICONSTRS                 \"LMIConstrs\"\n#define COPT_INTATTR_INDICATORS                 \"Indicators\"\n#define COPT_INTATTR_IISCOLS                    \"IISCols\"\n#define COPT_INTATTR_IISROWS                    \"IISRows\"\n#define COPT_INTATTR_IISSOSS                    \"IISSOSs\"\n#define COPT_INTATTR_IISINDICATORS              \"IISIndicators\"\n#define COPT_INTATTR_OBJSENSE                   \"ObjSense\"\n#define COPT_INTATTR_LPSTATUS                   \"LpStatus\"\n#define COPT_INTATTR_MIPSTATUS                  \"MipStatus\"\n#define COPT_INTATTR_SIMPLEXITER                \"SimplexIter\"\n#define COPT_INTATTR_BARRIERITER                \"BarrierIter\"\n#define COPT_INTATTR_PDLPITER                   \"PDLPIter\"\n#define COPT_INTATTR_NODECNT                    \"NodeCnt\"\n#define COPT_INTATTR_POOLSOLS                   \"PoolSols\"\n#define COPT_INTATTR_TUNERESULTS                \"TuneResults\"\n#define COPT_INTATTR_HASLPSOL                   \"HasLpSol\"\n#define COPT_INTATTR_HASDUALFARKAS              \"HasDualFarkas\"\n#define COPT_INTATTR_HASPRIMALRAY               \"HasPrimalRay\"\n#define COPT_INTATTR_HASBASIS                   \"HasBasis\"\n#define COPT_INTATTR_HASMIPSOL                  \"HasMipSol\"\n#define COPT_INTATTR_HASBRANCHFACTOR            \"HasBranchFactor\"\n#define COPT_INTATTR_HASQOBJ                    \"HasQObj\"\n#define COPT_INTATTR_HASNLOBJ                   \"HasNLObj\"\n#define COPT_INTATTR_HASPSDOBJ                  \"HasPSDObj\"\n#define COPT_INTATTR_HASIIS                     \"HasIIS\"\n#define COPT_INTATTR_HASFEASRELAXSOL            \"HasFeasRelaxSol\"\n#define COPT_INTATTR_HASSENSITIVITY             \"HasSensitivity\"\n#define COPT_INTATTR_ISMIP                      \"IsMIP\"\n#define COPT_INTATTR_ISMINIIS                   \"IsMinIIS\"\n\n/* Variable info types */\n#define COPT_DBLINFO_OBJ                        \"Obj\"\n#define COPT_DBLINFO_LB                         \"LB\"\n#define COPT_DBLINFO_UB                         \"UB\"\n#define COPT_DBLINFO_VALUE                      \"Value\"\n#define COPT_DBLINFO_SLACK                      \"Slack\"\n#define COPT_DBLINFO_DUAL                       \"Dual\"\n#define COPT_DBLINFO_REDCOST                    \"RedCost\"\n#define COPT_DBLINFO_DUALFARKAS                 \"DualFarkas\"\n#define COPT_DBLINFO_PRIMALRAY                  \"PrimalRay\"\n#define COPT_DBLINFO_RELAXLB                    \"RelaxLB\"\n#define COPT_DBLINFO_RELAXUB                    \"RelaxUB\"\n#define COPT_DBLINFO_RELAXVALUE                 \"RelaxValue\"\n#define COPT_DBLINFO_BRANCHFACTOR               \"BranchFactor\"\n#define COPT_DBLINFO_SAOBJLOW                   \"SAObjLow\"\n#define COPT_DBLINFO_SAOBJUP                    \"SAObjUp\"\n#define COPT_DBLINFO_SALBLOW                    \"SALBLow\"\n#define COPT_DBLINFO_SALBUP                     \"SALBUp\"\n#define COPT_DBLINFO_SAUBLOW                    \"SAUBLow\"\n#define COPT_DBLINFO_SAUBUP                     \"SAUBUp\"\n\n/* Nonlinear operation codes */\n#define COPT_NL_PLUS                            -10\n#define COPT_NL_MINUS                           -11\n#define COPT_NL_MULT                            -12\n#define COPT_NL_DIV                             -13\n#define COPT_NL_POW                             -14\n#define COPT_NL_SQRT                            -15\n#define COPT_NL_EXP                             -16\n#define COPT_NL_LOG                             -17\n#define COPT_NL_LOG10                           -18\n#define COPT_NL_NEG                             -19\n#define COPT_NL_ABS                             -20\n#define COPT_NL_FLOOR                           -21\n#define COPT_NL_CEIL                            -22\n#define COPT_NL_SIN                             -31\n#define COPT_NL_COS                             -32\n#define COPT_NL_TAN                             -33\n#define COPT_NL_SINH                            -34\n#define COPT_NL_COSH                            -35\n#define COPT_NL_TANH                            -36\n#define COPT_NL_ASIN                            -41\n#define COPT_NL_ACOS                            -42\n#define COPT_NL_ATAN                            -43\n#define COPT_NL_ASINH                           -44\n#define COPT_NL_ACOSH                           -45\n#define COPT_NL_ATANH                           -46\n#define COPT_NL_ATAN2                           -47\n#define COPT_NL_SUM                             -50\n#define COPT_NL_GET                             -60\n#define COPT_NL_POSTFIX                         -99\n\n/* Multi-objective parameters */\n#define COPT_MULTIOBJ_PRIORITY                  \"MultiObjPriority\"\n#define COPT_MULTIOBJ_WEIGHT                    \"MultiObjWeight\"\n#define COPT_MULTIOBJ_ABSTOL                    \"MultiObjAbsTol\"\n#define COPT_MULTIOBJ_RELTOL                    \"MultiObjRelTol\"\n\n/* COPT client config keywords */\n#define COPT_CLIENT_CAFILE                      \"CaFile\"\n#define COPT_CLIENT_CERTFILE                    \"CertFile\"\n#define COPT_CLIENT_CERTKEYFILE                 \"CertKeyFile\"\n#define COPT_CLIENT_CLUSTER                     \"Cluster\"\n#define COPT_CLIENT_FLOATING                    \"Floating\"\n#define COPT_CLIENT_PASSWORD                    \"PassWord\"\n#define COPT_CLIENT_PORT                        \"Port\"\n#define COPT_CLIENT_PRIORITY                    \"Priority\"\n#define COPT_CLIENT_WAITTIME                    \"WaitTime\"\n#define COPT_CLIENT_WEBSERVER                   \"WebServer\"\n#define COPT_CLIENT_WEBLICENSEID                \"WebLicenseId\"\n#define COPT_CLIENT_WEBACCESSKEY                \"WebAccessKey\"\n#define COPT_CLIENT_WEBTOKENDURATION            \"WebTokenDuration\"\n\n/*\n * API functions\n */\n\ntypedef struct copt_env_config_s copt_env_config;\ntypedef struct copt_env_s  copt_env;\ntypedef struct copt_prob_s copt_prob;\n\nint COPT_CALL COPT_GetBanner(char *buff, int buffSize);\nint COPT_CALL COPT_GetRetcodeMsg(int code, char *buff, int buffSize);\n\nint COPT_CALL COPT_CreateEnvConfig(copt_env_config **p_config);\nint COPT_CALL COPT_DeleteEnvConfig(copt_env_config **p_config);\nint COPT_CALL COPT_SetEnvConfig(copt_env_config *config, const char *name, const char *value);\n\nint COPT_CALL COPT_CreateEnv(copt_env **p_env);\nint COPT_CALL COPT_CreateEnvWithPath(const char *licDir, copt_env **p_env);\nint COPT_CALL COPT_CreateEnvWithConfig(copt_env_config *config, copt_env **p_env);\nint COPT_CALL COPT_CloseEnv(copt_env **p_env);\nint COPT_CALL COPT_DeleteEnv(copt_env **p_env);\nint COPT_CALL COPT_GetLicenseMsg(copt_env *env, char *buff, int buffSize);\n\nint COPT_CALL COPT_CreateProb(copt_env *env, copt_prob **p_prob);\nint COPT_CALL COPT_CreateCopy(copt_prob *src_prob, copt_prob **p_dst_prob);\nint COPT_CALL COPT_ClearProb(copt_prob *prob);\nint COPT_CALL COPT_DeleteProb(copt_prob **p_prob);\n\nint COPT_CALL COPT_LoadProb(copt_prob *prob,\n    int               nCol,\n    int               nRow,\n    int               iObjSense,\n    double            dObjConst,\n    const double      *colObj,\n    const int         *colMatBeg,\n    const int         *colMatCnt,\n    const int         *colMatIdx,\n    const double      *colMatElem,\n    const char        *colType,\n    const double      *colLower,\n    const double      *colUpper,\n    const char        *rowSense,\n    const double      *rowBound,\n    const double      *rowUpper,\n    char const *const *colNames,\n    char const *const *rowNames);\n\nint COPT_CALL COPT_AddCol(copt_prob *prob,\n    double            dColObj,\n    int               nColMatCnt,\n    const int         *colMatIdx,\n    const double      *colMatElem,\n    char              cColType,\n    double            dColLower,\n    double            dColUpper,\n    const char        *colName);\n\nint COPT_CALL COPT_AddPSDCol(copt_prob *prob,\n    int               colDim,\n    const char        *name);\n\nint COPT_CALL COPT_AddRow(copt_prob *prob,\n    int               nRowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    char              cRowSense,\n    double            dRowBound,\n    double            dRowUpper,\n    const char        *rowName);\n\nint COPT_CALL COPT_AddCols(copt_prob *prob,\n    int               nAddCol,\n    const double      *colObj,\n    const int         *colMatBeg,\n    const int         *colMatCnt,\n    const int         *colMatIdx,\n    const double      *colMatElem,\n    const char        *colType,\n    const double      *colLower,\n    const double      *colUpper,\n    char const *const *colNames);\n\nint COPT_CALL COPT_AddPSDCols(copt_prob *prob,\n    int               nAddCol,\n    const int         *colDims,\n    char const *const *names);\n\nint COPT_CALL COPT_AddRows(copt_prob *prob,\n    int               nAddRow,\n    const int         *rowMatBeg,\n    const int         *rowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    const char        *rowSense,\n    const double      *rowBound,\n    const double      *rowUpper,\n    char const *const *rowNames);\n\nint COPT_CALL COPT_AddLazyConstr(copt_prob *prob,\n    int               nRowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    char              cRowSense,\n    double            dRowBound,\n    double            dRowUpper,\n    const char        *rowName);\n\nint COPT_CALL COPT_AddLazyConstrs(copt_prob *prob,\n    int               nAddRow,\n    const int         *rowMatBeg,\n    const int         *rowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    const char        *rowSense,\n    const double      *rowBound,\n    const double      *rowUpper,\n    char const *const *rowNames);\n\nint COPT_CALL COPT_AddUserCut(copt_prob *prob,\n    int               nRowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    char              cRowSense,\n    double            dRowBound,\n    double            dRowUpper,\n    const char        *rowName);\n\nint COPT_CALL COPT_AddUserCuts(copt_prob *prob,\n    int               nAddRow,\n    const int         *rowMatBeg,\n    const int         *rowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    const char        *rowSense,\n    const double      *rowBound,\n    const double      *rowUpper,\n    char const *const *rowNames);\n\nint COPT_CALL COPT_AddSOSs(copt_prob *prob,\n    int               nAddSOS,\n    const int         *sosType,\n    const int         *sosMatBeg,\n    const int         *sosMatCnt,\n    const int         *sosMatIdx,\n    const double      *sosMatWt);\n\nint COPT_CALL COPT_AddCones(copt_prob *prob,\n    int               nAddCone,\n    const int         *coneType,\n    const int         *coneBeg,\n    const int         *coneCnt,\n    const int         *coneIdx);\n\nint COPT_CALL COPT_AddExpCones(copt_prob *prob,\n    int               nAddCone,\n    const int         *coneType,\n    const int         *coneIdx);\n\nint COPT_CALL COPT_AddAffineCone(copt_prob *prob,\n    int               coneType,\n    int               nConeDim,\n    int               nAlphaDim,\n    const double      *alphaElem,\n    const int         *psdBeg,\n    const int         *psdCnt,\n    const int         *psdColIdx,\n    const int         *psdMatIdx,\n    const int         *rowMatBeg,\n    const int         *rowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    const double      *rowConst,\n    const char        *name);\n\nint COPT_CALL COPT_AddQConstr(copt_prob *prob,\n    int               nRowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    int               nQMatCnt,\n    const int         *qMatRow,\n    const int         *qMatCol,\n    const double      *qMatElem,\n    char              cRowsense,\n    double            dRowBound,\n    const char        *name);\n\nint COPT_CALL COPT_AddNLConstr(copt_prob *prob,\n    int               nToken,\n    int               nTokenElem,\n    const int         *token,\n    const double      *tokenElem,\n    int               nRowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    char              cRowSense,\n    double            dRowBound,\n    double            dRowUpper,\n    const char        *name);\n\nint COPT_CALL COPT_AddNLConstrs(copt_prob *prob,\n    int               nConstrs,\n    const int         *tokenBeg,\n    const int         *tokenCnt,\n    const int         *tokenElemBeg,\n    const int         *tokenElemCnt,\n    const int         *token,\n    const double      *tokenElem,\n    const int         *rowMatBeg,\n    const int         *rowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    const char        *rowSense,\n    const double      *rowBound,\n    const double      *rowUpper,\n    char const *const *rowNames);\n\nint COPT_CALL COPT_AddPSDConstr(copt_prob *prob,\n    int               nRowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    int               nColCnt,\n    const int         *psdColIdx,\n    const int         *symMatIdx,\n    char              cRowSense,\n    double            dRowBound,\n    double            dRowUpper,\n    const char        *name);\n\nint COPT_CALL COPT_AddLMIConstr(copt_prob *prob,\n    int               nDim,\n    int               nLMIMatCnt,\n    const int         *colIdx,\n    const int         *symMatIdx,\n    int               constMatIdx,\n    const char        *name);\n\nint COPT_CALL COPT_AddIndicator(copt_prob *prob,\n    int               binColIdx,\n    int               binColVal,\n    int               nRowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    char              cRowSense,\n    double            dRowBound);\n\nint COPT_CALL COPT_AddIndicators(copt_prob *prob,\n    int               nInd,\n    const int         *indType,\n    const int         *binColIdx,\n    const int         *binColVal,\n    const int         *rowMatBeg,\n    const int         *rowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    const char        *cRowSense,\n    const double      *dRowBound,\n    char const *const *indNames);\n\nint COPT_CALL COPT_GetCols(copt_prob *prob,\n    int               nCol,\n    const int         *list,\n    int               *colMatBeg,\n    int               *colMatCnt,\n    int               *colMatIdx,\n    double            *colMatElem,\n    int               nElemSize,\n    int               *pReqSize);\n\nint COPT_CALL COPT_GetPSDCols(copt_prob *prob,\n    int               nCol,\n    const int         *list,\n    int               *colDims,\n    int               *colLens);\n\nint COPT_CALL COPT_GetRows(copt_prob *prob,\n    int               nRow,\n    const int         *list,\n    int               *rowMatBeg,\n    int               *rowMatCnt,\n    int               *rowMatIdx,\n    double            *rowMatElem,\n    int               nElemSize,\n    int               *pReqSize);\n\nint COPT_CALL COPT_GetSOSs(copt_prob *prob,\n    int               nSos,\n    const int         *list,\n    int               *sosType,\n    int               *sosMatBeg,\n    int               *sosMatCnt,\n    int               *sosMatIdx,\n    double            *sosMatWt,\n    int               nElemSize,\n    int               *pReqSize);\n\nint COPT_CALL COPT_GetCones(copt_prob *prob,\n    int               nCone,\n    const int         *list,\n    int               *coneType,\n    int               *coneBeg,\n    int               *coneCnt,\n    int               *coneIdx,\n    int               nElemSize,\n    int               *pReqSize);\n\nint COPT_CALL COPT_GetExpCones(copt_prob *prob,\n    int               nCone,\n    const int         *list,\n    int               *coneType,\n    int               *coneIdx,\n    int               nElemSize,\n    int               *pReqSize);\n\nint COPT_CALL COPT_GetAffineCone(copt_prob *prob,\n    int               affConeIdx,\n    int               *coneType,\n    int               *nConeDim,\n    int               *nAlphaDim,\n    double            *alphaElem,\n    int               *psdBeg,\n    int               *psdCnt,\n    int               *psdColIdx,\n    int               *psdMatIdx,\n    int               nPsdElemSize,\n    int               *pPsdReqSize,\n    int               *rowMatBeg,\n    int               *rowMatCnt,\n    int               *rowMatIdx,\n    double            *rowMatElem,\n    double            *rowConst,\n    int               nElemSize,\n    int               *pReqSize);\n\nint COPT_CALL COPT_GetQConstr(copt_prob *prob,\n    int               qConstrIdx,\n    int               *qMatRow,\n    int               *qMatCol,\n    double            *qMatElem,\n    int               nQElemSize,\n    int               *pQReqSize,\n    int               *rowMatIdx,\n    double            *rowMatElem,\n    char              *cRowSense,\n    double            *dRowBound,\n    int               nElemSize,\n    int               *pReqSize);\n\nint COPT_CALL COPT_GetNLConstr(copt_prob *prob,\n    int               nlConstrIdx,\n    int               *token,\n    double            *tokenElem,\n    int               nToken,\n    int               nTokenElem,\n    int               *pReqToken,\n    int               *pReqTokenElem,\n    int               *rowMatIdx,\n    double            *rowMatElem,\n    double            *dRowLower,\n    double            *dRowUpper,\n    int               nElemSize,\n    int               *pReqElemSize);\n\nint COPT_CALL COPT_GetPSDConstr(copt_prob *prob,\n    int               psdConstrIdx,\n    int               *psdColIdx,\n    int               *symMatIdx,\n    int               nColSize,\n    int               *pColReqSize,\n    int               *rowMatIdx,\n    double            *rowMatElem,\n    double            *dRowLower,\n    double            *dRowUpper,\n    int               nElemSize,\n    int               *pReqSize);\n\nint COPT_CALL COPT_GetLMIConstr(copt_prob *prob,\n    int               lmiConstrIdx,\n    int               *nDim,\n    int               *nLMILen,\n    int               *colIdx,\n    int               *symMatIdx,\n    int               *constMatIdx,\n    int               nElemSize,\n    int               *pReqSize);\n\nint COPT_CALL COPT_GetIndicator(copt_prob *prob,\n    int               rowIdx,\n    int               *binColIdx,\n    int               *binColVal,\n    int               *nRowMatCnt,\n    int               *rowMatIdx,\n    double            *rowMatElem,\n    char              *cRowSense,\n    double            *dRowBound,\n    int               nElemSize,\n    int               *pReqSize);\n\nint COPT_CALL COPT_GetIndicators(copt_prob *prob,\n    int               nInd,\n    int               *list,\n    int               *indType,\n    int               *binColIdx,\n    int               *binColVal,\n    int               *rowMatBeg,\n    int               *rowMatCnt,\n    int               *rowMatIdx,\n    double            *rowMatElem,\n    char              *cRowSense,\n    double            *dRowBound,\n    int               nElemSize,\n    int               *pReqSize);\n\nint COPT_CALL COPT_GetElem(copt_prob *prob, int iCol, int iRow, double *p_elem);\nint COPT_CALL COPT_SetElem(copt_prob *prob, int iCol, int iRow, double newElem);\nint COPT_CALL COPT_SetElems(copt_prob *prob, int nelem, const int *cols, const int *rows, const double *elems);\n\nint COPT_CALL COPT_GetPSDElem(copt_prob *prob, int iCol, int iRow, int *p_idx);\nint COPT_CALL COPT_SetPSDElem(copt_prob *prob, int iCol, int iRow, int newIdx);\n\nint COPT_CALL COPT_GetLMIElem(copt_prob *prob, int iCol, int iRow, int *p_idx);\nint COPT_CALL COPT_SetLMIElem(copt_prob *prob, int iCol, int iRow, int newIdx);\n\nint COPT_CALL COPT_DelCols(copt_prob *prob, int num, const int *list);\nint COPT_CALL COPT_DelPSDCols(copt_prob *prob, int num, const int *list);\nint COPT_CALL COPT_DelRows(copt_prob *prob, int num, const int *list);\nint COPT_CALL COPT_DelSOSs(copt_prob *prob, int num, const int *list);\nint COPT_CALL COPT_DelCones(copt_prob *prob, int num, const int *list);\nint COPT_CALL COPT_DelExpCones(copt_prob *prob, int num, const int *list);\nint COPT_CALL COPT_DelAffineCones(copt_prob *prob, int num, const int *list);\nint COPT_CALL COPT_DelQConstrs(copt_prob *prob, int num, const int *list);\nint COPT_CALL COPT_DelNLConstrs(copt_prob *prob, int num, const int *list);\nint COPT_CALL COPT_DelPSDConstrs(copt_prob *prob, int num, const int *list);\nint COPT_CALL COPT_DelLMIConstrs(copt_prob *prob, int num, const int *list);\nint COPT_CALL COPT_DelIndicators(copt_prob *prob, int num, const int *list);\n\nint COPT_CALL COPT_SetQuadObj(copt_prob* prob, int num, const int *qRow, const int *qCol, const double *qElem);\nint COPT_CALL COPT_GetQuadObj(copt_prob* prob, int *p_nQElem, int *qRow, int *qCol, double *qElem);\nint COPT_CALL COPT_DelQuadObj(copt_prob* prob);\n\nint COPT_CALL COPT_SetNLObj(copt_prob *prob, int nToken, int nTokenElem, const int *token, const double *tokenElem);\nint COPT_CALL COPT_GetNLObj(copt_prob *prob, int *p_nToken, int *p_nTokenElem, int *token, double *tokenElem);\nint COPT_CALL COPT_DelNLObj(copt_prob *prob);\n\nint COPT_CALL COPT_SetPSDObj(copt_prob *prob, int iCol, int newIdx);\nint COPT_CALL COPT_GetPSDObj(copt_prob *prob, int iCol, int *p_idx);\nint COPT_CALL COPT_DelPSDObj(copt_prob *prob);\n\nint COPT_CALL COPT_AddSymMat(copt_prob *prob, int ndim, int nelem, const int *rows, const int *cols, const double *elems);\nint COPT_CALL COPT_GetSymMat(copt_prob *prob, int iMat, int *p_nDim, int *p_nElem, int *rows, int *cols, double *elems);\n\nint COPT_CALL COPT_SetObjSense(copt_prob *prob, int iObjSense);\nint COPT_CALL COPT_SetObjConst(copt_prob *prob, double dObjConst);\n\nint COPT_CALL COPT_SetColObj(copt_prob *prob, int num, const int *list, const double *obj);\nint COPT_CALL COPT_SetColType(copt_prob *prob, int num, const int *list, const char *type);\nint COPT_CALL COPT_SetColLower(copt_prob *prob, int num, const int *list, const double *lower);\nint COPT_CALL COPT_SetColUpper(copt_prob *prob, int num, const int *list, const double *upper);\nint COPT_CALL COPT_SetColNames(copt_prob *prob, int num, const int *list, char const *const *names);\nint COPT_CALL COPT_SetColBranchFactors(copt_prob *prob, int num, const int *list, const double *branchFactors);\n\nint COPT_CALL COPT_SetPSDColNames(copt_prob *prob, int num, const int *list, char const *const *names);\n\nint COPT_CALL COPT_SetRowLower(copt_prob *prob, int num, const int *list, const double *lower);\nint COPT_CALL COPT_SetRowUpper(copt_prob *prob, int num, const int *list, const double *upper);\nint COPT_CALL COPT_SetRowNames(copt_prob *prob, int num, const int *list, char const *const *names);\n\nint COPT_CALL COPT_SetAffineConeNames(copt_prob *prob, int num, const int *list, char const *const *names);\n\nint COPT_CALL COPT_SetQConstrSense(copt_prob *prob, int num, const int *list, const char *sense);\nint COPT_CALL COPT_SetQConstrRhs(copt_prob *prob, int num, const int *list, const double *rhs);\nint COPT_CALL COPT_SetQConstrNames(copt_prob *prob, int num, const int *list, char const *const *names);\n\nint COPT_CALL COPT_SetNLConstrLower(copt_prob *prob, int num, const int *list, const double *lower);\nint COPT_CALL COPT_SetNLConstrUpper(copt_prob *prob, int num, const int *list, const double *upper);\nint COPT_CALL COPT_SetNLConstrNames(copt_prob *prob, int num, const int *list, char const *const *names);\n\nint COPT_CALL COPT_SetPSDConstrLower(copt_prob *prob, int num, const int *list, const double *lower);\nint COPT_CALL COPT_SetPSDConstrUpper(copt_prob *prob, int num, const int *list, const double *upper);\nint COPT_CALL COPT_SetPSDConstrNames(copt_prob *prob, int num, const int *list, char const *const *names);\n\nint COPT_CALL COPT_SetLMIConstrRhs(copt_prob *prob, int num, const int *list, const int *newIdx);\nint COPT_CALL COPT_SetLMIConstrNames(copt_prob *prob, int num, const int *list, char const *const *names);\n\nint COPT_CALL COPT_SetIndicatorNames(copt_prob *prob, int num, const int *list, char const *const *names);\n\nint COPT_CALL COPT_ReplaceColObj(copt_prob *prob, int num, const int *list, const double *obj);\nint COPT_CALL COPT_ReplacePSDObj(copt_prob *prob, int num, const int *list, const int *idx);\n\nint COPT_CALL COPT_MultiObjSetColObj(copt_prob *prob, int iObj, int num, const int *list, const double *colObj);\nint COPT_CALL COPT_MultiObjGetColObj(copt_prob *prob, int iObj, int num, const int *list, double *colObj);\nint COPT_CALL COPT_MultiObjDelColObj(copt_prob *prob, int iObj);\n\nint COPT_CALL COPT_MultiObjSetObjSense(copt_prob *prob, int iObj, int iObjSense);\nint COPT_CALL COPT_MultiObjSetObjConst(copt_prob *prob, int iObj, double dObjConst);\n\nint COPT_CALL COPT_MultiObjSetObjParam(copt_prob *prob, int iObj, const char *paramName, double dblParam);\nint COPT_CALL COPT_MultiObjGetObjParam(copt_prob *prob, int iObj, const char *paramName, double *p_dblParam);\nint COPT_CALL COPT_MultiObjResetObjParam(copt_prob *prob, int iObj);\n\nint COPT_CALL COPT_MultiObjSetIntParam(copt_prob *prob, int iObj, const char *paramName, int intParam);\nint COPT_CALL COPT_MultiObjGetIntParam(copt_prob *prob, int iObj, const char *paramName, int *p_intParam);\nint COPT_CALL COPT_MultiObjSetDblParam(copt_prob *prob, int iObj, const char *paramName, double dblParam);\nint COPT_CALL COPT_MultiObjGetDblParam(copt_prob *prob, int iObj, const char *paramName, double *p_dblParam);\nint COPT_CALL COPT_MultiObjResetParam(copt_prob *prob, int iObj);\n\nint COPT_CALL COPT_MultiObjGetIntAttr(copt_prob *prob, int iObj, const char *attrName, int *p_intAttr);\nint COPT_CALL COPT_MultiObjGetDblAttr(copt_prob *prob, int iObj, const char *attrName, double *p_dblAttr);\n\nint COPT_CALL COPT_MultiObjGetPoolObjVal(copt_prob *prob, int iObj, int iSol, double *p_objVal);\n\nint COPT_CALL COPT_ReadMps(copt_prob *prob, const char *mpsfilename);\nint COPT_CALL COPT_ReadLp(copt_prob *prob, const char *lpfilename);\nint COPT_CALL COPT_ReadSDPA(copt_prob *prob, const char *sdpafilename);\nint COPT_CALL COPT_ReadCbf(copt_prob *prob, const char *cbffilename);\nint COPT_CALL COPT_ReadBin(copt_prob *prob, const char *binfilename);\nint COPT_CALL COPT_ReadSol(copt_prob *prob, const char *solfilename);\nint COPT_CALL COPT_ReadJsonSol(copt_prob *prob, const char *solfilename);\nint COPT_CALL COPT_ReadBasis(copt_prob *prob, const char *basfilename);\nint COPT_CALL COPT_ReadMst(copt_prob *prob, const char *mstfilename);\nint COPT_CALL COPT_ReadOrd(copt_prob *prob, const char *ordfilename);\nint COPT_CALL COPT_ReadParam(copt_prob *prob, const char *parfilename);\nint COPT_CALL COPT_ReadParamStr(copt_prob *prob, const char *strParam);\nint COPT_CALL COPT_ReadTune(copt_prob *prob, const char *tunefilename);\nint COPT_CALL COPT_ReadBlob(copt_prob *prob, void *blob, COPT_INT64 len);\n\nint COPT_CALL COPT_WriteMps(copt_prob *prob, const char *mpsfilename);\nint COPT_CALL COPT_WriteLp(copt_prob *prob, const char *lpfilename);\nint COPT_CALL COPT_WriteCbf(copt_prob *prob, const char *cbffilename);\nint COPT_CALL COPT_WriteBin(copt_prob *prob, const char *binfilename);\nint COPT_CALL COPT_WriteNL(copt_prob *prob, const char *nlfilename);\nint COPT_CALL COPT_WriteIIS(copt_prob *prob, const char *iisfilename);\nint COPT_CALL COPT_WriteRelax(copt_prob *prob, const char *relaxfilename);\nint COPT_CALL COPT_WriteSol(copt_prob *prob, const char *solfilename);\nint COPT_CALL COPT_WriteJsonSol(copt_prob *prob, const char *solfilename);\nint COPT_CALL COPT_WritePoolSol(copt_prob *prob, int iSol, const char *solfilename);\nint COPT_CALL COPT_WriteBasis(copt_prob *prob, const char *basfilename);\nint COPT_CALL COPT_WriteMst(copt_prob *prob, const char *mstfilename);\nint COPT_CALL COPT_WriteOrd(copt_prob *prob, const char *ordfilename);\nint COPT_CALL COPT_WriteParam(copt_prob *prob, const char *parfilename);\nint COPT_CALL COPT_WriteTuneParam(copt_prob *prob, int idx, const char *parfilename);\nint COPT_CALL COPT_WriteMpsStr(copt_prob *prob, char *str, int nStrSize, int *pReqSize);\nint COPT_CALL COPT_WriteParamStr(copt_prob *prob, char *str, int nStrSize, int *pReqSize);\nint COPT_CALL COPT_WriteBlob(copt_prob *prob, int tryCompress, void **p_blob, COPT_INT64 *pLen);\n\nint COPT_CALL COPT_AddMipStart(copt_prob *prob, int num, const int *list, const double *colVal);\nint COPT_CALL COPT_SetNLPrimalStart(copt_prob *prob, int num, const int *list, const double *colVal);\n\nint COPT_CALL COPT_SolveLp(copt_prob *prob);\nint COPT_CALL COPT_Solve(copt_prob *prob);\n\nint COPT_CALL COPT_ComputeIIS(copt_prob *prob);\n\nint COPT_CALL COPT_FeasRelax(copt_prob *prob, const double *colLowPen, const double *colUppPen, const double *rowBndPen, const double *rowUppPen);\n\nint COPT_CALL COPT_Tune(copt_prob *prob);\nint COPT_CALL COPT_LoadTuneParam(copt_prob *prob, int idx);\n\nint COPT_CALL COPT_GetSolution(copt_prob *prob, double *colVal);\nint COPT_CALL COPT_GetLpSolution(copt_prob *prob, double *value, double *slack, double *rowDual, double *redCost);\nint COPT_CALL COPT_SetLpSolution(copt_prob *prob, const double *value, const double *slack, const double *rowDual, const double *redCost);\nint COPT_CALL COPT_GetBasis(copt_prob *prob, int *colBasis, int *rowBasis);\nint COPT_CALL COPT_SetBasis(copt_prob *prob, const int *colBasis, const int *rowBasis);\nint COPT_CALL COPT_SetSlackBasis(copt_prob *prob);\n\nint COPT_CALL COPT_GetPoolObjVal(copt_prob *prob, int iSol, double *p_objVal);\nint COPT_CALL COPT_GetPoolSolution(copt_prob *prob, int iSol, int num, const int *list, double *colVal);\n\nint COPT_CALL COPT_SetIntParam(copt_prob *prob, const char *paramName, int intParam);\nint COPT_CALL COPT_GetIntParam(copt_prob *prob, const char *paramName, int *p_intParam);\nint COPT_CALL COPT_GetIntParamDef(copt_prob *prob, const char *paramName, int *p_intParam);\nint COPT_CALL COPT_GetIntParamMin(copt_prob *prob, const char *paramName, int *p_intParam);\nint COPT_CALL COPT_GetIntParamMax(copt_prob *prob, const char *paramName, int *p_intParam);\n\nint COPT_CALL COPT_SetDblParam(copt_prob *prob, const char *paramName, double dblParam);\nint COPT_CALL COPT_GetDblParam(copt_prob *prob, const char *paramName, double *p_dblParam);\nint COPT_CALL COPT_GetDblParamDef(copt_prob *prob, const char *paramName, double *p_dblParam);\nint COPT_CALL COPT_GetDblParamMin(copt_prob *prob, const char *paramName, double *p_dblParam);\nint COPT_CALL COPT_GetDblParamMax(copt_prob *prob, const char *paramName, double *p_dblParam);\n\nint COPT_CALL COPT_ResetParam(copt_prob *prob);\nint COPT_CALL COPT_Reset(copt_prob *prob, int iClearAll);\n\nint COPT_CALL COPT_GetIntAttr(copt_prob *prob, const char *attrName, int *p_intAttr);\nint COPT_CALL COPT_GetDblAttr(copt_prob *prob, const char *attrName, double *p_dblAttr);\n\nint COPT_CALL COPT_GetColIdx(copt_prob *prob, const char *colName, int *p_iCol);\nint COPT_CALL COPT_GetPSDColIdx(copt_prob *prob, const char *psdColName, int *p_iPSDCol);\nint COPT_CALL COPT_GetRowIdx(copt_prob *prob, const char *rowName, int *p_iRow);\nint COPT_CALL COPT_GetAffineConeIdx(copt_prob *prob, const char *affConeName, int *p_iAffCone);\nint COPT_CALL COPT_GetQConstrIdx(copt_prob *prob, const char *qConstrName, int *p_iQConstr);\nint COPT_CALL COPT_GetNLConstrIdx(copt_prob *prob, const char *nlConstrName, int *p_iNLConstr);\nint COPT_CALL COPT_GetPSDConstrIdx(copt_prob *prob, const char *psdConstrName, int *p_iPSDConstr);\nint COPT_CALL COPT_GetLMIConstrIdx(copt_prob *prob, const char *lmiConstrName, int *p_iLMIConstr);\nint COPT_CALL COPT_GetIndicatorIdx(copt_prob *prob, const char *indicatorName, int *p_iIndicator);\n\nint COPT_CALL COPT_GetColInfo(copt_prob *prob, const char *infoName, int num, const int *list, double *info);\nint COPT_CALL COPT_GetPSDColInfo(copt_prob *prob, const char *infoName, int iCol, double *info);\nint COPT_CALL COPT_GetRowInfo(copt_prob *prob, const char *infoName, int num, const int *list, double *info);\nint COPT_CALL COPT_GetQConstrInfo(copt_prob *prob, const char *infoName, int num, const int *list, double *info);\nint COPT_CALL COPT_GetNLConstrInfo(copt_prob *prob, const char *infoName, int num, const int *list, double *info);\nint COPT_CALL COPT_GetPSDConstrInfo(copt_prob *prob, const char *infoName, int num, const int *list, double *info);\nint COPT_CALL COPT_GetLMIConstrInfo(copt_prob *prob, const char *infoName, int iLMI, double *info);\n\nint COPT_CALL COPT_GetColType(copt_prob *prob, int num, const int *list, char *type);\nint COPT_CALL COPT_GetColBasis(copt_prob *prob, int num, const int *list, int *colBasis);\nint COPT_CALL COPT_GetRowBasis(copt_prob *prob, int num, const int *list, int *rowBasis);\nint COPT_CALL COPT_GetQConstrSense(copt_prob *prob, int num, const int *list, char *sense);\nint COPT_CALL COPT_GetQConstrRhs(copt_prob *prob, int num, const int *list, double *rhs);\nint COPT_CALL COPT_GetLMIConstrRhs(copt_prob *prob, int num, const int *list, int *constMatIdx);\n\nint COPT_CALL COPT_GetColLowerIIS(copt_prob *prob, int num, const int *list, int *colLowerIIS);\nint COPT_CALL COPT_GetColUpperIIS(copt_prob *prob, int num, const int *list, int *colUpperIIS);\nint COPT_CALL COPT_GetRowLowerIIS(copt_prob *prob, int num, const int *list, int *rowLowerIIS);\nint COPT_CALL COPT_GetRowUpperIIS(copt_prob *prob, int num, const int *list, int *rowUpperIIS);\nint COPT_CALL COPT_GetSOSIIS(copt_prob *prob, int num, const int *list, int *sosIIS);\nint COPT_CALL COPT_GetIndicatorIIS(copt_prob *prob, int num, const int *list, int *indicatorIIS);\n\nint COPT_CALL COPT_GetColName(copt_prob *prob, int iCol, char *buff, int buffSize, int *pReqSize);\nint COPT_CALL COPT_GetPSDColName(copt_prob *prob, int iPSDCol, char *buff, int buffSize, int *pReqSize);\nint COPT_CALL COPT_GetRowName(copt_prob *prob, int iRow, char *buff, int buffSize, int *pReqSize);\nint COPT_CALL COPT_GetAffineConeName(copt_prob *prob, int iAffCone, char *buff, int buffSize, int *pReqSize);\nint COPT_CALL COPT_GetQConstrName(copt_prob *prob, int iQConstr, char *buff, int buffSize, int *pReqSize);\nint COPT_CALL COPT_GetNLConstrName(copt_prob *prob, int iNLConstr, char *buff, int buffSize, int *pReqSize);\nint COPT_CALL COPT_GetPSDConstrName(copt_prob *prob, int iPSDConstr, char *buff, int buffSize, int *pReqSize);\nint COPT_CALL COPT_GetLMIConstrName(copt_prob *prob, int iLMIConstr, char *buff, int buffSize, int *pReqSize);\nint COPT_CALL COPT_GetIndicatorName(copt_prob *prob, int iIndicator, char *buff, int buffSize, int *pReqSize);\n\nint COPT_CALL COPT_SetLogFile(copt_prob *prob, const char *logfilename);\nint COPT_CALL COPT_SetLogCallback(copt_prob *prob, void (COPT_CALL *logcb)(char *msg, void *userdata), void *userdata);\n\nint COPT_CALL COPT_SetCallback(copt_prob *prob,\n    int (COPT_CALL *cb)(copt_prob *prob, void *cbdata, int cbctx, void *userdata),\n    int               cbctx,\n    void              *userdata);\nint COPT_CALL COPT_GetCallbackInfo(void *cbdata, const char *cbinfo, void *p_val);\nint COPT_CALL COPT_AddCallbackSolution(void *cbdata, const double *sol, double *p_objval);\nint COPT_CALL COPT_AddCallbackUserCut(void *cbdata,\n    int               nRowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    char              cRowSense,\n    double            dRowRhs);\nint COPT_CALL COPT_AddCallbackUserCuts(void *cbdata,\n    int               nAddRow,\n    const int         *rowMatBeg,\n    const int         *rowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    const char        *rowSense,\n    const double      *rowRhs);\nint COPT_CALL COPT_AddCallbackLazyConstr(void *cbdata,\n    int               nRowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    char              cRowSense,\n    double            dRowRhs);\nint COPT_CALL COPT_AddCallbackLazyConstrs(void *cbdata,\n    int               nAddRow,\n    const int         *rowMatBeg,\n    const int         *rowMatCnt,\n    const int         *rowMatIdx,\n    const double      *rowMatElem,\n    const char        *rowSense,\n    const double      *rowRhs);\n\nint COPT_CALL COPT_Interrupt(copt_prob *prob);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* __COPT_H__ */\n"
  },
  {
    "path": "thirdparty/solvers/gurobi/gurobi_c.h",
    "content": "/* Copyright 2025, Gurobi Optimization, LLC */\n \n#ifndef _GUROBI_C_H\n#define _GUROBI_C_H\n \n#ifdef __cplusplus\nextern \"C\" {\n#endif\n \n#include <stdio.h>\n\ntypedef struct _GRBbatch GRBbatch;\ntypedef struct _GRBmodel GRBmodel;\ntypedef struct _GRBenv GRBenv;\n\n#if defined(_WIN64) && !defined(WIN64)\n#define WIN64\n#endif\n\n#if defined(_WIN32) && !defined(_WIN64) && !defined(WIN32)\n#define WIN32\n#endif\n\n#if !defined(WIN32) && !defined(WIN64)\n#define __cdecl\n#define __stdcall\n#endif\n\n/* Deprecation macro */\n\n#if __cplusplus >= 201103L\n#  define GRB_DEPRECATED(WHY,X) [[deprecated(WHY)]] X\n#elif defined(__GNUC__) || defined(__clang__)\n#  define GRB_DEPRECATED(WHY,X) X __attribute__((deprecated))\n#elif defined(_MSC_VER)\n#  define GRB_DEPRECATED(WHY,X) __declspec(deprecated) X\n#else\n#  define GRB_DEPRECATED(WHY,X) X\n#endif\n\n/* Version numbers */\n\n#define GRB_VERSION_MAJOR     13\n#define GRB_VERSION_MINOR     0\n#define GRB_VERSION_TECHNICAL 0\n\n/* Default and max priority for Compute Server jobs */\n\n#define DEFAULT_CS_PRIORITY 0\n#define MAX_CS_PRIORITY 100\n\n/* Default port number for Compute Server */\n\n#define DEFAULT_CS_PORT 61000\n\n/* Default Compute Server hangup duration */\n\n#define DEFAULT_CS_HANGUP 60\n\n/* Error codes: adjust MIN/MAX if adding new codes */\n\n#define GRB_C_MIN_ERROR                    10001\n#define GRB_ERROR_OUT_OF_MEMORY            10001\n#define GRB_ERROR_NULL_ARGUMENT            10002\n#define GRB_ERROR_INVALID_ARGUMENT         10003\n#define GRB_ERROR_UNKNOWN_ATTRIBUTE        10004\n#define GRB_ERROR_DATA_NOT_AVAILABLE       10005\n#define GRB_ERROR_INDEX_OUT_OF_RANGE       10006\n#define GRB_ERROR_UNKNOWN_PARAMETER        10007\n#define GRB_ERROR_VALUE_OUT_OF_RANGE       10008\n#define GRB_ERROR_NO_LICENSE               10009\n#define GRB_ERROR_SIZE_LIMIT_EXCEEDED      10010\n#define GRB_ERROR_CALLBACK                 10011\n#define GRB_ERROR_FILE_READ                10012\n#define GRB_ERROR_FILE_WRITE               10013\n#define GRB_ERROR_NUMERIC                  10014\n#define GRB_ERROR_IIS_NOT_INFEASIBLE       10015\n#define GRB_ERROR_NOT_FOR_MIP              10016\n#define GRB_ERROR_OPTIMIZATION_IN_PROGRESS 10017\n#define GRB_ERROR_DUPLICATES               10018\n#define GRB_ERROR_NODEFILE                 10019\n#define GRB_ERROR_Q_NOT_PSD                10020\n#define GRB_ERROR_QCP_EQUALITY_CONSTRAINT  10021\n#define GRB_ERROR_NETWORK                  10022\n#define GRB_ERROR_JOB_REJECTED             10023\n#define GRB_ERROR_NOT_SUPPORTED            10024\n#define GRB_ERROR_EXCEED_2B_NONZEROS       10025\n#define GRB_ERROR_INVALID_PIECEWISE_OBJ    10026\n#define GRB_ERROR_UPDATEMODE_CHANGE        10027\n#define GRB_ERROR_CLOUD                    10028\n#define GRB_ERROR_MODEL_MODIFICATION       10029\n#define GRB_ERROR_CSWORKER                 10030\n#define GRB_ERROR_TUNE_MODEL_TYPES         10031\n#define GRB_ERROR_SECURITY                 10032\n#define GRB_ERROR_GPU                      10033\n#define GRB_ERROR_OVERFLOW                 10034\n#define GRB_C_MAX_ERROR                    10034\n\n/* Constraint senses */\n\n#define GRB_LESS_EQUAL    '<'\n#define GRB_GREATER_EQUAL '>'\n#define GRB_EQUAL         '='\n\n/* Variable types */\n\n#define GRB_CONTINUOUS 'C'\n#define GRB_BINARY     'B'\n#define GRB_INTEGER    'I'\n#define GRB_SEMICONT   'S'\n#define GRB_SEMIINT    'N'\n\n/* Objective sense */\n\n#define GRB_MINIMIZE 1\n#define GRB_MAXIMIZE -1\n\n/* SOS types */\n\n#define GRB_SOS_TYPE1 1\n#define GRB_SOS_TYPE2 2\n\n/* Numeric constants */\n\n#define GRB_INFINITY  1e100\n#define GRB_UNDEFINED 1e101\n#define GRB_MAXINT    2000000000\n\n/* Limits */\n\n#define GRB_MAX_NAMELEN    255\n#define GRB_MAX_STRLEN     512\n#define GRB_MAX_TAGLEN    10240\n#define GRB_MAX_CONCURRENT 64\n\n/* Callback */\n\n#define CB_ARGS GRBmodel *model, void *cbdata, int where, void *usrdata\n#define LOGCB_ARGS char *msg, void *logdata\n\n/* Query interface */\n\nint __stdcall\n  GRBgetattrinfo(GRBmodel *model, const char *attrname, int *datatypeP,\n                 int *attrtypeP, int *settableP);\nint __stdcall\n  GRBisattravailable(GRBmodel *model, const char *attrname);\nint __stdcall\n  GRBgetintattr(GRBmodel *model, const char *attrname, int *valueP);\nint __stdcall\n  GRBsetintattr(GRBmodel *model, const char *attrname, int newvalue);\nint __stdcall\n  GRBgetintattrelement(GRBmodel *model, const char *attrname,\n                       int element, int *valueP);\nint __stdcall\n  GRBsetintattrelement(GRBmodel *model, const char *attrname,\n                       int element, int newvalue);\nint __stdcall\n  GRBgetintattrarray(GRBmodel *model, const char *attrname,\n                     int first, int len, int *values);\nint __stdcall\n  GRBsetintattrarray(GRBmodel *model, const char *attrname,\n                     int first, int len, int *newvalues);\nint __stdcall\n  GRBgetintattrlist(GRBmodel *model, const char *attrname,\n                    int len, int *ind, int *values);\nint __stdcall\n  GRBsetintattrlist(GRBmodel *model, const char *attrname,\n                    int len, int *ind, int *newvalues);\nint __stdcall\n  GRBgetcharattrelement(GRBmodel *model, const char *attrname,\n                        int element, char *valueP);\nint __stdcall\n  GRBsetcharattrelement(GRBmodel *model, const char *attrname,\n                        int element, char newvalue);\nint __stdcall\n  GRBgetcharattrarray(GRBmodel *model, const char *attrname,\n                      int first, int len, char *values);\nint __stdcall\n  GRBsetcharattrarray(GRBmodel *model, const char *attrname,\n                      int first, int len, char *newvalues);\nint __stdcall\n  GRBgetcharattrlist(GRBmodel *model, const char *attrname,\n                     int len, int *ind, char *values);\nint __stdcall\n  GRBsetcharattrlist(GRBmodel *model, const char *attrname,\n                     int len, int *ind, char *newvalues);\nint __stdcall\n  GRBgetdblattr(GRBmodel *model, const char *attrname, double *valueP);\nint __stdcall\n  GRBsetdblattr(GRBmodel *model, const char *attrname, double newvalue);\nint __stdcall\n  GRBgetdblattrelement(GRBmodel *model, const char *attrname,\n                       int element, double *valueP);\nint __stdcall\n  GRBsetdblattrelement(GRBmodel *model, const char *attrname,\n                       int element, double newvalue);\nint __stdcall\n  GRBgetdblattrarray(GRBmodel *model, const char *attrname,\n                     int first, int len, double *values);\nint __stdcall\n  GRBsetdblattrarray(GRBmodel *model, const char *attrname,\n                     int first, int len, double *newvalues);\nint __stdcall\n  GRBgetdblattrlist(GRBmodel *model, const char *attrname,\n                    int len, int *ind, double *values);\nint __stdcall\n  GRBsetdblattrlist(GRBmodel *model, const char *attrname,\n                    int len, int *ind, double *newvalues);\nint __stdcall\n  GRBgetstrattr(GRBmodel *model, const char *attrname, char **valueP);\nint __stdcall\n  GRBsetstrattr(GRBmodel *model, const char *attrname, const char *newvalue);\nint __stdcall\n  GRBgetstrattrelement(GRBmodel *model, const char *attrname,\n                       int element, char **valueP);\nint __stdcall\n  GRBsetstrattrelement(GRBmodel *model, const char *attrname,\n                       int element, const char *newvalue);\nint __stdcall\n  GRBgetstrattrarray(GRBmodel *model, const char *attrname,\n                     int first, int len, char **values);\nint __stdcall\n  GRBsetstrattrarray(GRBmodel *model, const char *attrname,\n                     int first, int len, char **newvalues);\nint __stdcall\n  GRBgetstrattrlist(GRBmodel *model, const char *attrname,\n                    int len, int *ind, char **values);\nint __stdcall\n  GRBsetstrattrlist(GRBmodel *model, const char *attrname,\n                    int len, int *ind, char **newvalues);\nint __stdcall\n  GRBsetcallbackfunc(GRBmodel *model,\n                     int (__stdcall *cb)(CB_ARGS),\n                     void  *usrdata);\nint __stdcall\n  GRBsetcallbackfuncadv(GRBmodel *model,\n                        int (__stdcall *cb)(CB_ARGS),\n                        void  *usrdata,\n                        unsigned int wheres);\nint __stdcall\n  GRBgetcallbackfuncenv(GRBenv *env,\n                        int (__stdcall **cbP)(CB_ARGS));\nint __stdcall\n  GRBsetcallbackfuncenv(GRBenv *env,\n                        int (__stdcall *cb)(CB_ARGS),\n                        void  *usrdata);\nint __stdcall\n  GRBsetcallbackfuncenvadv(GRBenv *env,\n                           int (__stdcall *cb)(CB_ARGS),\n                           void  *usrdata,\n                           unsigned int wheres);\nint __stdcall\n  GRBgetcallbackfunc(GRBmodel *model,\n                     int (__stdcall **cbP)(CB_ARGS));\nint __stdcall\n  GRBsetlogcallbackfunc(GRBmodel       *model,\n                        int (__stdcall *cb)(LOGCB_ARGS),\n                        void           *logdata);\nint __stdcall\n  GRBsetlogcallbackfuncenv(GRBenv         *env,\n                           int (__stdcall *cb)(LOGCB_ARGS),\n                           void           *logdata);\nint __stdcall\n  GRBgetlogcallbackfuncenv(GRBenv         *env,\n                           int (__stdcall **cbP)(LOGCB_ARGS),\n                           void           **logdataP);\n\nint __stdcall\n  GRBcbproceed(void *cbdata);\nint __stdcall\n  GRBcbget(void *cbdata, int where, int what, void *resultP);\nint __stdcall\n  GRBcbsetintparam(void *cbdata, const char *paramname, int newvalue);\nint __stdcall\n  GRBcbsetdblparam(void *cbdata, const char *paramname, double newvalue);\nint __stdcall\n  GRBcbsetstrparam(void *cbdata, const char *paramname, const char *newvalue);\nint __stdcall\n  GRBcbsetparam(void *cbdata, const char *paramname, const char *newvalue);\nint __stdcall\n  GRBcbsolution(void *cbdata, const double *solution, double *objvalP);\nint __stdcall\n  GRBcbcut(void *cbdata, int cutlen, const int *cutind, const double *cutval,\n           char cutsense, double cutrhs);\nint __stdcall\n  GRBcblazy(void *cbdata, int lazylen, const int *lazyind,\n            const double *lazyval, char lazysense, double lazyrhs);\n\n\n/*\n   ATTRIBUTES\n*/\n\n/* Model attributes */\n\n#define GRB_INT_ATTR_NUMCONSTRS    \"NumConstrs\"    /* # of constraints */\n#define GRB_INT_ATTR_NUMVARS       \"NumVars\"       /* # of vars */\n#define GRB_INT_ATTR_NUMSOS        \"NumSOS\"        /* # of sos constraints */\n#define GRB_INT_ATTR_NUMQCONSTRS   \"NumQConstrs\"   /* # of quadratic constraints */\n#define GRB_INT_ATTR_NUMGENCONSTRS \"NumGenConstrs\" /* # of general constraints */\n#define GRB_INT_ATTR_NUMNZS        \"NumNZs\"        /* # of nz in A */\n#define GRB_DBL_ATTR_DNUMNZS       \"DNumNZs\"       /* # of nz in A */\n#define GRB_INT_ATTR_NUMQNZS       \"NumQNZs\"       /* # of nz in Q */\n#define GRB_INT_ATTR_NUMQCNZS      \"NumQCNZs\"      /* # of nz in q constraints */\n#define GRB_INT_ATTR_NUMINTVARS    \"NumIntVars\"    /* # of integer vars */\n#define GRB_INT_ATTR_NUMBINVARS    \"NumBinVars\"    /* # of binary vars */\n#define GRB_INT_ATTR_NUMPWLOBJVARS \"NumPWLObjVars\" /* # of variables with PWL obj. */\n#define GRB_STR_ATTR_MODELNAME     \"ModelName\"     /* model name */\n#define GRB_INT_ATTR_MODELSENSE    \"ModelSense\"    /* 1=min, -1=max */\n#define GRB_DBL_ATTR_OBJCON        \"ObjCon\"        /* Objective constant */\n#define GRB_INT_ATTR_IS_MIP        \"IsMIP\"         /* Is model a MIP? */\n#define GRB_INT_ATTR_IS_QP         \"IsQP\"          /* Is model a QP/MIQP (without Q/NL constraints)? */\n#define GRB_INT_ATTR_IS_QCP        \"IsQCP\"         /* Model has quadratic constr? */\n#define GRB_INT_ATTR_IS_MULTIOBJ   \"IsMultiObj\"    /* Model has multiple objectives? */\n#define GRB_INT_ATTR_LICENSE_EXPIRATION \"LicenseExpiration\" /* License expiration date */\n#define GRB_INT_ATTR_NUMTAGGED     \"NumTagged\"     /* number of tagged elements in model */\n#define GRB_INT_ATTR_FINGERPRINT   \"Fingerprint\"   /* fingerprint computed from the model data and attributes influencing the optimization process */\n\n/* Batch attributes */\n#define GRB_INT_ATTR_BATCHERRORCODE    \"BatchErrorCode\"\n#define GRB_STR_ATTR_BATCHERRORMESSAGE \"BatchErrorMessage\"\n#define GRB_STR_ATTR_BATCHID           \"BatchID\"\n#define GRB_INT_ATTR_BATCHSTATUS       \"BatchStatus\"\n\n/* Variable attributes */\n\n#define GRB_DBL_ATTR_LB             \"LB\"              /* Lower bound */\n#define GRB_DBL_ATTR_UB             \"UB\"              /* Upper bound */\n#define GRB_DBL_ATTR_OBJ            \"Obj\"             /* Objective coeff */\n#define GRB_CHAR_ATTR_VTYPE         \"VType\"           /* Integrality type */\n#define GRB_DBL_ATTR_START          \"Start\"           /* MIP start value, depends on startnumber */\n#define GRB_DBL_ATTR_PSTART         \"PStart\"          /* LP primal solution warm start */\n#define GRB_INT_ATTR_BRANCHPRIORITY \"BranchPriority\"  /* MIP branch priority */\n#define GRB_STR_ATTR_VARNAME        \"VarName\"         /* Variable name */\n#define GRB_INT_ATTR_PWLOBJCVX      \"PWLObjCvx\"       /* Convexity of variable PWL obj */\n#define GRB_DBL_ATTR_VARHINTVAL     \"VarHintVal\"      /* variable hint value */\n#define GRB_INT_ATTR_VARHINTPRI     \"VarHintPri\"      /* variable hint priority */\n#define GRB_INT_ATTR_PARTITION      \"Partition\"       /* user specified variable partition */\n#define GRB_INT_ATTR_POOLIGNORE     \"PoolIgnore\"      /* Ignore variable for solution identity check in solution pool */\n#define GRB_STR_ATTR_VTAG           \"VTag\"            /* variable tags */\n\n/* Constraint attributes */\n\n#define GRB_STR_ATTR_CTAG       \"CTag\"       /* linear constraint tags */\n#define GRB_DBL_ATTR_RHS        \"RHS\"        /* RHS */\n#define GRB_DBL_ATTR_DSTART     \"DStart\"     /* LP dual solution warm start */\n#define GRB_CHAR_ATTR_SENSE     \"Sense\"      /* Sense ('<', '>', or '=') */\n#define GRB_STR_ATTR_CONSTRNAME \"ConstrName\" /* Constraint name */\n#define GRB_INT_ATTR_LAZY       \"Lazy\"       /* Lazy constraint? */\n\n/* Quadratic constraint attributes */\n\n#define GRB_STR_ATTR_QCTAG    \"QCTag\"   /* quadratic constraint tags */\n#define GRB_DBL_ATTR_QCRHS    \"QCRHS\"   /* QC RHS */\n#define GRB_CHAR_ATTR_QCSENSE \"QCSense\" /* QC sense ('<', '>', or '=') */\n#define GRB_STR_ATTR_QCNAME   \"QCName\"  /* QC name */\n\n/* General constraint attributes */\n\n#define GRB_INT_ATTR_GENCONSTRTYPE  \"GenConstrType\"  /* Type of general constraint */\n#define GRB_STR_ATTR_GENCONSTRNAME  \"GenConstrName\"  /* Name of general constraint */\n\n/* General function constraint attributes */\n\n#define GRB_INT_ATTR_FUNCPIECES      \"FuncPieces\"       /* An option for PWL translation */\n#define GRB_DBL_ATTR_FUNCPIECEERROR  \"FuncPieceError\"   /* An option for PWL translation */\n#define GRB_DBL_ATTR_FUNCPIECELENGTH \"FuncPieceLength\"  /* An option for PWL translation */\n#define GRB_DBL_ATTR_FUNCPIECERATIO  \"FuncPieceRatio\"   /* An option for PWL translation */\n#define GRB_INT_ATTR_FUNCNONLINEAR   \"FuncNonlinear\"    /* An option for PWL translation */\n\n/* Model statistics */\n\n#define GRB_DBL_ATTR_MAX_COEFF      \"MaxCoeff\"     /* Max (abs) nz coeff in A */\n#define GRB_DBL_ATTR_MIN_COEFF      \"MinCoeff\"     /* Min (abs) nz coeff in A */\n#define GRB_DBL_ATTR_MAX_BOUND      \"MaxBound\"     /* Max (abs) finite var bd */\n#define GRB_DBL_ATTR_MIN_BOUND      \"MinBound\"     /* Min (abs) var bd */\n#define GRB_DBL_ATTR_MAX_OBJ_COEFF  \"MaxObjCoeff\"  /* Max (abs) obj coeff */\n#define GRB_DBL_ATTR_MIN_OBJ_COEFF  \"MinObjCoeff\"  /* Min (abs) obj coeff */\n#define GRB_DBL_ATTR_MAX_RHS        \"MaxRHS\"       /* Max (abs) rhs coeff */\n#define GRB_DBL_ATTR_MIN_RHS        \"MinRHS\"       /* Min (abs) rhs coeff */\n#define GRB_DBL_ATTR_MAX_QCCOEFF    \"MaxQCCoeff\"   /* Max (abs) nz coeff in Q */\n#define GRB_DBL_ATTR_MIN_QCCOEFF    \"MinQCCoeff\"   /* Min (abs) nz coeff in Q */\n#define GRB_DBL_ATTR_MAX_QOBJ_COEFF \"MaxQObjCoeff\" /* Max (abs) obj coeff of quadratic part */\n#define GRB_DBL_ATTR_MIN_QOBJ_COEFF \"MinQObjCoeff\" /* Min (abs) obj coeff of quadratic part */\n#define GRB_DBL_ATTR_MAX_QCLCOEFF   \"MaxQCLCoeff\"  /* Max (abs) nz coeff in linear part of Q */\n#define GRB_DBL_ATTR_MIN_QCLCOEFF   \"MinQCLCoeff\"  /* Min (abs) nz coeff in linear part of Q */\n#define GRB_DBL_ATTR_MAX_QCRHS      \"MaxQCRHS\"     /* Max (abs) rhs of Q */\n#define GRB_DBL_ATTR_MIN_QCRHS      \"MinQCRHS\"     /* Min (abs) rhs of Q */\n\n/* Model solution attributes */\n\n#define GRB_DBL_ATTR_RUNTIME       \"Runtime\"     /* Run time for optimization */\n#define GRB_DBL_ATTR_WORK          \"Work\"        /* Work for optimization */\n#define GRB_INT_ATTR_STATUS        \"Status\"      /* Optimization status */\n#define GRB_DBL_ATTR_OBJVAL        \"ObjVal\"      /* Solution objective */\n#define GRB_DBL_ATTR_OBJBOUND      \"ObjBound\"    /* Best bound on solution */\n#define GRB_DBL_ATTR_OBJBOUNDC     \"ObjBoundC\"   /* Continuous bound */\n#define GRB_DBL_ATTR_POOLOBJBOUND  \"PoolObjBound\" /* Best bound on pool solution */\n#define GRB_DBL_ATTR_POOLNOBJVAL   \"PoolNObjVal\" /* Solution objective, depends on solutionnumber */\n#define GRB_DBL_ATTR_POOLOBJVAL    \"PoolObjVal\"  /* Deprecated since v13 - use GRB_DBL_ATTR_POOLNOBJVAL instead */\n#define GRB_DBL_ATTR_MIPGAP        \"MIPGap\"      /* MIP optimality gap */\n#define GRB_INT_ATTR_SOLCOUNT      \"SolCount\"    /* # of solutions found */\n#define GRB_DBL_ATTR_ITERCOUNT     \"IterCount\"   /* Iters performed (simplex) */\n#define GRB_INT_ATTR_BARSTATUS     \"BarStatus\"   /* Status computed by barrier before crossover */\n#define GRB_INT_ATTR_BARITERCOUNT  \"BarIterCount\" /* Iters performed (barrier) */\n#define GRB_INT_ATTR_NLBARITERCOUNT \"NLBarIterCount\" /* Iters performed (NL barrier) */\n#define GRB_DBL_ATTR_PDHGITERCOUNT \"PDHGIterCount\" /* Iters performed (PDHG) */\n#define GRB_DBL_ATTR_NODECOUNT     \"NodeCount\"    /* Nodes explored (B&C) */\n#define GRB_DBL_ATTR_OPENNODECOUNT \"OpenNodeCount\" /* Unexplored nodes (B&C) */\n#define GRB_INT_ATTR_HASDUALNORM   \"HasDualNorm\"  /* 0, no basis,\n                                                     1, has basis, so can be computed\n                                                     2, available */\n#define GRB_INT_ATTR_CONCURRENTWINMETHOD  \"ConcurrentWinMethod\"      /* method that solved LP using concurrent */\n\n/* Variable attributes related to the current solution */\n\n#define GRB_DBL_ATTR_X         \"X\"         /* Solution value */\n#define GRB_DBL_ATTR_POOLNX    \"PoolNX\"    /* Alternate MIP solution, depends on solutionnumber */\n#define GRB_DBL_ATTR_XN        \"Xn\"        /* Deprecated since v13 - use GRB_DBL_ATTR_POOLNX instead */\n#define GRB_DBL_ATTR_BARX      \"BarX\"      /* Best barrier primal iterate */\n#define GRB_DBL_ATTR_BARPI     \"BarPi\"     /* Best barrier dual iterate */\n#define GRB_DBL_ATTR_RC        \"RC\"        /* Reduced costs */\n#define GRB_DBL_ATTR_VDUALNORM \"VDualNorm\" /* Dual norm square */\n#define GRB_INT_ATTR_VBASIS    \"VBasis\"    /* Variable basis status */\n\n/* Constraint attributes related to the current solution */\n\n#define GRB_DBL_ATTR_PI        \"Pi\"        /* Dual value */\n#define GRB_DBL_ATTR_QCPI      \"QCPi\"      /* Dual value for QC */\n#define GRB_DBL_ATTR_SLACK     \"Slack\"     /* Constraint slack */\n#define GRB_DBL_ATTR_QCSLACK   \"QCSlack\"   /* QC Constraint slack */\n#define GRB_DBL_ATTR_CDUALNORM \"CDualNorm\" /* Dual norm square */\n#define GRB_INT_ATTR_CBASIS    \"CBasis\"    /* Constraint basis status */\n\n/* Solution quality attributes */\n\n#define GRB_DBL_ATTR_MAX_VIO                \"MaxVio\"\n#define GRB_DBL_ATTR_BOUND_VIO              \"BoundVio\"\n#define GRB_DBL_ATTR_BOUND_SVIO             \"BoundSVio\"\n#define GRB_INT_ATTR_BOUND_VIO_INDEX        \"BoundVioIndex\"\n#define GRB_INT_ATTR_BOUND_SVIO_INDEX       \"BoundSVioIndex\"\n#define GRB_DBL_ATTR_BOUND_VIO_SUM          \"BoundVioSum\"\n#define GRB_DBL_ATTR_BOUND_SVIO_SUM         \"BoundSVioSum\"\n#define GRB_DBL_ATTR_CONSTR_VIO             \"ConstrVio\"\n#define GRB_DBL_ATTR_CONSTR_SVIO            \"ConstrSVio\"\n#define GRB_INT_ATTR_CONSTR_VIO_INDEX       \"ConstrVioIndex\"\n#define GRB_INT_ATTR_CONSTR_SVIO_INDEX      \"ConstrSVioIndex\"\n#define GRB_DBL_ATTR_CONSTR_VIO_SUM         \"ConstrVioSum\"\n#define GRB_DBL_ATTR_CONSTR_SVIO_SUM        \"ConstrSVioSum\"\n#define GRB_DBL_ATTR_CONSTR_RESIDUAL        \"ConstrResidual\"\n#define GRB_DBL_ATTR_CONSTR_SRESIDUAL       \"ConstrSResidual\"\n#define GRB_INT_ATTR_CONSTR_RESIDUAL_INDEX  \"ConstrResidualIndex\"\n#define GRB_INT_ATTR_CONSTR_SRESIDUAL_INDEX \"ConstrSResidualIndex\"\n#define GRB_DBL_ATTR_CONSTR_RESIDUAL_SUM    \"ConstrResidualSum\"\n#define GRB_DBL_ATTR_CONSTR_SRESIDUAL_SUM   \"ConstrSResidualSum\"\n#define GRB_DBL_ATTR_DUAL_VIO               \"DualVio\"\n#define GRB_DBL_ATTR_DUAL_SVIO              \"DualSVio\"\n#define GRB_INT_ATTR_DUAL_VIO_INDEX         \"DualVioIndex\"\n#define GRB_INT_ATTR_DUAL_SVIO_INDEX        \"DualSVioIndex\"\n#define GRB_DBL_ATTR_DUAL_VIO_SUM           \"DualVioSum\"\n#define GRB_DBL_ATTR_DUAL_SVIO_SUM          \"DualSVioSum\"\n#define GRB_DBL_ATTR_DUAL_RESIDUAL          \"DualResidual\"\n#define GRB_DBL_ATTR_DUAL_SRESIDUAL         \"DualSResidual\"\n#define GRB_INT_ATTR_DUAL_RESIDUAL_INDEX    \"DualResidualIndex\"\n#define GRB_INT_ATTR_DUAL_SRESIDUAL_INDEX   \"DualSResidualIndex\"\n#define GRB_DBL_ATTR_DUAL_RESIDUAL_SUM      \"DualResidualSum\"\n#define GRB_DBL_ATTR_DUAL_SRESIDUAL_SUM     \"DualSResidualSum\"\n#define GRB_DBL_ATTR_INT_VIO                \"IntVio\"\n#define GRB_INT_ATTR_INT_VIO_INDEX          \"IntVioIndex\"\n#define GRB_DBL_ATTR_INT_VIO_SUM            \"IntVioSum\"\n#define GRB_DBL_ATTR_COMPL_VIO              \"ComplVio\"\n#define GRB_INT_ATTR_COMPL_VIO_INDEX        \"ComplVioIndex\"\n#define GRB_DBL_ATTR_COMPL_VIO_SUM          \"ComplVioSum\"\n#define GRB_DBL_ATTR_KAPPA                  \"Kappa\"\n#define GRB_DBL_ATTR_KAPPA_EXACT            \"KappaExact\"\n#define GRB_DBL_ATTR_N2KAPPA                \"N2Kappa\"\n\n/* Solution pool quality attributes, controlled by parameter SolutionNumber (= i)\n */\n#define GRB_DBL_ATTR_POOL_MAX_VIO           \"PoolNMaxVio\"\n#define GRB_DBL_ATTR_POOL_BOUND_VIO         \"PoolNBoundVio\"\n#define GRB_INT_ATTR_POOL_BOUND_VIO_INDEX   \"PoolNBoundVioIndex\"\n#define GRB_DBL_ATTR_POOL_BOUND_VIO_SUM     \"PoolNBoundVioSum\"\n#define GRB_DBL_ATTR_POOL_CONSTR_VIO        \"PoolNConstrVio\"\n#define GRB_INT_ATTR_POOL_CONSTR_VIO_INDEX  \"PoolNConstrVioIndex\"\n#define GRB_DBL_ATTR_POOL_CONSTR_VIO_SUM    \"PoolNConstrVioSum\"\n#define GRB_DBL_ATTR_POOL_INT_VIO           \"PoolNIntVio\"\n#define GRB_INT_ATTR_POOL_INT_VIO_INDEX     \"PoolNIntVioIndex\"\n#define GRB_DBL_ATTR_POOL_INT_VIO_SUM       \"PoolNIntVioSum\"\n\n/* LP sensitivity analysis */\n\n#define GRB_DBL_ATTR_SA_OBJLOW \"SAObjLow\"\n#define GRB_DBL_ATTR_SA_OBJUP  \"SAObjUp\"\n#define GRB_DBL_ATTR_SA_LBLOW  \"SALBLow\"\n#define GRB_DBL_ATTR_SA_LBUP   \"SALBUp\"\n#define GRB_DBL_ATTR_SA_UBLOW  \"SAUBLow\"\n#define GRB_DBL_ATTR_SA_UBUP   \"SAUBUp\"\n#define GRB_DBL_ATTR_SA_RHSLOW \"SARHSLow\"\n#define GRB_DBL_ATTR_SA_RHSUP  \"SARHSUp\"\n\n/* IIS */\n\n#define GRB_INT_ATTR_IIS_MINIMAL   \"IISMinimal\"   /* Boolean: Is IIS Minimal? */\n#define GRB_INT_ATTR_IIS_LB        \"IISLB\"        /* Boolean: Is var LB in IIS? */\n#define GRB_INT_ATTR_IIS_UB        \"IISUB\"        /* Boolean: Is var UB in IIS? */\n#define GRB_INT_ATTR_IIS_CONSTR    \"IISConstr\"    /* Boolean: Is constr in IIS? */\n#define GRB_INT_ATTR_IIS_SOS       \"IISSOS\"       /* Boolean: Is SOS in IIS? */\n#define GRB_INT_ATTR_IIS_QCONSTR   \"IISQConstr\"   /* Boolean: Is QConstr in IIS? */\n#define GRB_INT_ATTR_IIS_GENCONSTR \"IISGenConstr\" /* Boolean: Is general constr in IIS? */\n\n#define GRB_INT_ATTR_IIS_LBFORCE        \"IISLBForce\"        /* Force var LB to be (1) or to not be (0) in final IIS */\n#define GRB_INT_ATTR_IIS_UBFORCE        \"IISUBForce\"        /* Force var UB to be (1) or to not be (0) in final IIS */\n#define GRB_INT_ATTR_IIS_CONSTRFORCE    \"IISConstrForce\"    /* Force constr to be (1) or to not be (0) in final IIS */\n#define GRB_INT_ATTR_IIS_SOSFORCE       \"IISSOSForce\"       /* Force SOS to be (1) or to not be (0) in final IIS */\n#define GRB_INT_ATTR_IIS_QCONSTRFORCE   \"IISQConstrForce\"   /* Force QConstr to be (1) or to not be (0) in final IIS */\n#define GRB_INT_ATTR_IIS_GENCONSTRFORCE \"IISGenConstrForce\" /* Force general constr to be (1) or to not be (0) in final IIS */\n\n/* Tuning */\n\n#define GRB_INT_ATTR_TUNE_RESULTCOUNT \"TuneResultCount\"\n\n/* Advanced simplex features */\n\n#define GRB_DBL_ATTR_FARKASDUAL  \"FarkasDual\"\n#define GRB_DBL_ATTR_FARKASPROOF \"FarkasProof\"\n#define GRB_DBL_ATTR_UNBDRAY     \"UnbdRay\"\n#define GRB_INT_ATTR_INFEASVAR   \"InfeasVar\"\n#define GRB_INT_ATTR_UNBDVAR     \"UnbdVar\"\n\n/* Presolve attribute */\n\n#define GRB_INT_ATTR_VARPRESTAT \"VarPreStat\"\n#define GRB_DBL_ATTR_PREFIXVAL  \"PreFixVal\"\n\n/* Multi objective attribute, controlled by parameter ObjNumber (= i)\n *\n * Note if you add an new attribute, adjust the const array\n * OBJNUMATTRNAMES and define OBJNUMATTRS in attrcache.c.\n */\n#define GRB_DBL_ATTR_OBJN         \"ObjN\"         /* ith objective */\n#define GRB_DBL_ATTR_OBJNVAL      \"ObjNVal\"      /* Solution objective for Multi-objectives, also depends on solutionnumber */\n#define GRB_DBL_ATTR_OBJNCON      \"ObjNCon\"      /* constant term */\n#define GRB_DBL_ATTR_OBJNWEIGHT   \"ObjNWeight\"   /* weight */\n#define GRB_INT_ATTR_OBJNPRIORITY \"ObjNPriority\" /* priority */\n#define GRB_DBL_ATTR_OBJNRELTOL   \"ObjNRelTol\"   /* relative tolerance */\n#define GRB_DBL_ATTR_OBJNABSTOL   \"ObjNAbsTol\"   /* absolute tolerance */\n#define GRB_STR_ATTR_OBJNNAME     \"ObjNName\"     /* name */\n\n#define GRB_INT_ATTR_NUMOBJPASSES          \"NumObjPasses\"          /* number of optimization passes during the multi-objective solve */\n#define GRB_INT_ATTR_OBJNPASS              \"ObjNPass\"              /* optimization pass in which the selected objective function was processed */\n#define GRB_DBL_ATTR_OBJPASSNITERCOUNT     \"ObjPassNIterCount\"     /* simplex iteration count for a pass during the multi-objective solve */\n#define GRB_DBL_ATTR_OBJPASSNMIPGAP        \"ObjPassNMIPGap\"        /* MIP gap for a pass during the multi-objective solve */\n#define GRB_DBL_ATTR_OBJPASSNNODECOUNT     \"ObjPassNNodeCount\"     /* number of explored nodes for a pass during the multi-objective solve */\n#define GRB_DBL_ATTR_OBJPASSNOBJBOUND      \"ObjPassNObjBound\"      /* objective bound for a pass during the multi-objective solve */\n#define GRB_DBL_ATTR_OBJPASSNOBJVAL        \"ObjPassNObjVal\"        /* objective value for a pass during the multi-objective solve */\n#define GRB_DBL_ATTR_OBJPASSNOPENNODECOUNT \"ObjPassNOpenNodeCount\" /* number of unexplored nodes for a pass during the multi-objective solve */\n#define GRB_DBL_ATTR_OBJPASSNRUNTIME       \"ObjPassNRuntime\"       /* runtime for a pass during the multi-objective solve */\n#define GRB_INT_ATTR_OBJPASSNSTATUS        \"ObjPassNStatus\"        /* status for a pass during the multi-objective solve */\n#define GRB_DBL_ATTR_OBJPASSNWORK          \"ObjPassNWork\"          /* work done for a pass during the multi-objective solve */\n\n/* Scenario attributes, controlled by parameter ScenarioNumber (= i)\n *\n * Note if you add an new attribute, adjust the const array\n * SCENARIONUMATTRNAMES and define SCENARIONUMATTRS in attrcache.c.\n */\n\n#define GRB_DBL_ATTR_SCENNLB       \"ScenNLB\"       /* lower bound in scenario i */\n#define GRB_DBL_ATTR_SCENNUB       \"ScenNUB\"       /* upper bound in scenario i */\n#define GRB_DBL_ATTR_SCENNOBJ      \"ScenNObj\"      /* objective in scenario i */\n#define GRB_DBL_ATTR_SCENNRHS      \"ScenNRHS\"      /* right hand side in scenario i */\n#define GRB_STR_ATTR_SCENNNAME     \"ScenNName\"     /* name of scenario i */\n#define GRB_DBL_ATTR_SCENNX        \"ScenNX\"        /* solution value in scenario i */\n#define GRB_DBL_ATTR_SCENNOBJBOUND \"ScenNObjBound\" /* objective bound for scenario i */\n#define GRB_DBL_ATTR_SCENNOBJVAL   \"ScenNObjVal\"   /* objective value for scenario i */\n\n#define GRB_INT_ATTR_NUMOBJ       \"NumObj\"       /* number of objectives */\n#define GRB_INT_ATTR_NUMSCENARIOS \"NumScenarios\" /* number of scenarios */\n#define GRB_INT_ATTR_NUMSTART     \"NumStart\"     /* number of MIP starts */\n\n\n/* Memory consumption statistics */\n\n#define GRB_DBL_ATTR_MEMUSED      \"MemUsed\"        /* current amount of allocated memory (in GB) in master environment */\n#define GRB_DBL_ATTR_MAXMEMUSED   \"MaxMemUsed\"     /* maximum amount of allocated memory (in GB) in master environment */\n\n\n/* Alternate define */\n\n#define GRB_DBL_ATTR_Xn \"Xn\"      /* Deprecated since v13 - use GRB_DBL_ATTR_POOLNX instead */\n\n/* General constraints */\n\n#define GRB_GENCONSTR_MAX         0\n#define GRB_GENCONSTR_MIN         1\n#define GRB_GENCONSTR_ABS         2\n#define GRB_GENCONSTR_AND         3\n#define GRB_GENCONSTR_OR          4\n#define GRB_GENCONSTR_NORM        5\n#define GRB_GENCONSTR_NL          6\n#define GRB_GENCONSTR_INDICATOR   7\n#define GRB_GENCONSTR_PWL         8\n#define GRB_GENCONSTR_POLY        9\n#define GRB_GENCONSTR_EXP        10\n#define GRB_GENCONSTR_EXPA       11\n#define GRB_GENCONSTR_LOG        12\n#define GRB_GENCONSTR_LOGA       13\n#define GRB_GENCONSTR_POW        14\n#define GRB_GENCONSTR_SIN        15\n#define GRB_GENCONSTR_COS        16\n#define GRB_GENCONSTR_TAN        17\n#define GRB_GENCONSTR_LOGISTIC   18\n\n#define NUMGENCONSTYPES          19\n\n/* Operation codes for genconstrNL */\n\n#define GRB_OPCODE_CONSTANT      0\n#define GRB_OPCODE_VARIABLE      1\n#define GRB_OPCODE_PLUS          2\n#define GRB_OPCODE_MINUS         3\n#define GRB_OPCODE_MULTIPLY      4\n#define GRB_OPCODE_DIVIDE        5\n#define GRB_OPCODE_UMINUS        6\n#define GRB_OPCODE_SQUARE        7\n#define GRB_OPCODE_SQRT          8\n#define GRB_OPCODE_SIN           9\n#define GRB_OPCODE_COS           10\n#define GRB_OPCODE_TAN           11\n#define GRB_OPCODE_POW           12\n#define GRB_OPCODE_EXP           13\n#define GRB_OPCODE_LOG           14\n#define GRB_OPCODE_LOG2          15\n#define GRB_OPCODE_LOG10         16\n#define GRB_OPCODE_LOGISTIC      17\n#define GRB_OPCODE_TANH          18\n#define GRB_OPCODE_SIGNPOW       19\n\n#define NUMOPCODETYPES           20\n\n/* Additional ones, internally used only */\n#define GRB_OPCODE_VCPOW         20\n#define GRB_OPCODE_CVPOW         21\n\n\n/*\n   CALLBACKS\n*/\n\n/* For callback */\n\n#define GRB_CB_POLLING   0\n#define GRB_CB_PRESOLVE  1\n#define GRB_CB_SIMPLEX   2\n#define GRB_CB_MIP       3\n#define GRB_CB_MIPSOL    4\n#define GRB_CB_MIPNODE   5\n#define GRB_CB_MESSAGE   6\n#define GRB_CB_BARRIER   7\n#define GRB_CB_MULTIOBJ  8\n#define GRB_CB_IIS       9\n#define GRB_CB_PDHG     10\n#define GRB_CB_NLBAR    11\n#define GRB_CB_MAX      11\n\n/* Supported names for callback */\n\n#define GRB_CB_PRE_COLDEL  1000\n#define GRB_CB_PRE_ROWDEL  1001\n#define GRB_CB_PRE_SENCHG  1002\n#define GRB_CB_PRE_BNDCHG  1003\n#define GRB_CB_PRE_COECHG  1004\n\n#define GRB_CB_SPX_ITRCNT  2000\n#define GRB_CB_SPX_OBJVAL  2001\n#define GRB_CB_SPX_PRIMINF 2002\n#define GRB_CB_SPX_DUALINF 2003\n#define GRB_CB_SPX_ISPERT  2004\n\n#define GRB_CB_MIP_OBJBST         3000\n#define GRB_CB_MIP_OBJBND         3001\n#define GRB_CB_MIP_NODCNT         3002\n#define GRB_CB_MIP_SOLCNT         3003\n#define GRB_CB_MIP_CUTCNT         3004\n#define GRB_CB_MIP_NODLFT         3005\n#define GRB_CB_MIP_ITRCNT         3006\n#define GRB_CB_MIP_OPENSCENARIOS  3007\n#define GRB_CB_MIP_PHASE          3008\n\n#define GRB_CB_MIPSOL_SOL            4001\n#define GRB_CB_MIPSOL_OBJ            4002\n#define GRB_CB_MIPSOL_OBJBST         4003\n#define GRB_CB_MIPSOL_OBJBND         4004\n#define GRB_CB_MIPSOL_NODCNT         4005\n#define GRB_CB_MIPSOL_SOLCNT         4006\n#define GRB_CB_MIPSOL_OPENSCENARIOS  4007\n#define GRB_CB_MIPSOL_PHASE          4008\n\n#define GRB_CB_MIPNODE_STATUS         5001\n#define GRB_CB_MIPNODE_REL            5002\n#define GRB_CB_MIPNODE_OBJBST         5003\n#define GRB_CB_MIPNODE_OBJBND         5004\n#define GRB_CB_MIPNODE_NODCNT         5005\n#define GRB_CB_MIPNODE_SOLCNT         5006\n#define GRB_CB_MIPNODE_BRVAR          5007\n#define GRB_CB_MIPNODE_OPENSCENARIOS  5008\n#define GRB_CB_MIPNODE_PHASE          5009\n\n#define GRB_CB_MSG_STRING  6001\n#define GRB_CB_RUNTIME     6002\n#define GRB_CB_WORK        6003\n#define GRB_CB_MEMUSED     6004\n#define GRB_CB_MAXMEMUSED  6005\n\n#define GRB_CB_BARRIER_ITRCNT  7001\n#define GRB_CB_BARRIER_PRIMOBJ 7002\n#define GRB_CB_BARRIER_DUALOBJ 7003\n#define GRB_CB_BARRIER_PRIMINF 7004\n#define GRB_CB_BARRIER_DUALINF 7005\n#define GRB_CB_BARRIER_COMPL   7006\n\n#define GRB_CB_MULTIOBJ_OBJCNT  8001\n#define GRB_CB_MULTIOBJ_SOLCNT  8002\n#define GRB_CB_MULTIOBJ_SOL     8003\n#define GRB_CB_MULTIOBJ_ITRCNT  8004\n#define GRB_CB_MULTIOBJ_OBJBST  8005 /* if single objective is an LP we\n                                      * still do not have a \"_OBJVAL\", the\n                                      * user can query the _OBJBST/_OBJBND\n                                      * values instead */\n#define GRB_CB_MULTIOBJ_OBJBND  8006\n#define GRB_CB_MULTIOBJ_STATUS  8007\n#define GRB_CB_MULTIOBJ_MIPGAP  8008\n#define GRB_CB_MULTIOBJ_NODCNT  8009\n#define GRB_CB_MULTIOBJ_NODLFT  8010\n#define GRB_CB_MULTIOBJ_RUNTIME 8011\n#define GRB_CB_MULTIOBJ_WORK    8012\n/* TODO maybe we should also support, think about in MIP/LP cases if not applicable\n#define GRB_CB_MULTIOBJ_PRIMINF 8012\n#define GRB_CB_MULTIOBJ_DUALINF 8013\n#define GRB_CB_MULTIOBJ_ISPERT  8014\n*/\n\n#define GRB_CB_IIS_CONSTRMIN    9001\n#define GRB_CB_IIS_CONSTRMAX    9002\n#define GRB_CB_IIS_CONSTRGUESS  9003\n#define GRB_CB_IIS_BOUNDMIN     9004\n#define GRB_CB_IIS_BOUNDMAX     9005\n#define GRB_CB_IIS_BOUNDGUESS   9006\n\n#define GRB_CB_PDHG_ITRCNT      10001\n#define GRB_CB_PDHG_PRIMOBJ     10002\n#define GRB_CB_PDHG_DUALOBJ     10003\n#define GRB_CB_PDHG_PRIMINF     10004\n#define GRB_CB_PDHG_DUALINF     10005\n#define GRB_CB_PDHG_COMPL       10006\n\n#define GRB_CB_NLBAR_ITRCNT     11001\n#define GRB_CB_NLBAR_PRIMOBJ    11002\n#define GRB_CB_NLBAR_PRIMINF    11003\n#define GRB_CB_NLBAR_DUALINF    11004\n#define GRB_CB_NLBAR_COMPL      11005\n\n/* FeasRelax method parameter values */\n\n#define GRB_FEASRELAX_LINEAR      0\n#define GRB_FEASRELAX_QUADRATIC   1\n#define GRB_FEASRELAX_CARDINALITY 2\n\nint __stdcall\n  GRBgetcoeff(GRBmodel *model, int constr, int var, double *valP);\nint __stdcall\n  GRBgetconstrs(GRBmodel *model, int *numnzP, int *cbeg,\n                int *cind, double *cval, int start, int len);\nint __stdcall\n  GRBXgetconstrs(GRBmodel *model, size_t *numnzP, size_t *cbeg,\n                 int *cind, double *cval, int start, int len);\nint __stdcall\n  GRBgetvars(GRBmodel *model, int *numnzP, int *vbeg, int *vind,\n             double *vval, int start, int len);\nint __stdcall\n  GRBXgetvars(GRBmodel *model, size_t *numnzP, size_t *vbeg, int *vind,\n              double *vval, int start, int len);\nint __stdcall\n  GRBgetsos(GRBmodel *model, int *nummembersP, int *sostype, int *beg,\n            int *ind, double *weight, int start, int len);\nint __stdcall\n  GRBgetgenconstrMax(GRBmodel *model, int genconstr, int *resvarP,\n                     int *nvarsP, int *vars, double *constantP);\nint __stdcall\n  GRBgetgenconstrMin(GRBmodel *model, int genconstr, int *resvarP,\n                     int *nvarsP, int *vars, double *constantP);\nint __stdcall\n  GRBgetgenconstrAbs(GRBmodel *model, int genconstr, int *resvarP, int *argvarP);\nint __stdcall\n  GRBgetgenconstrAnd(GRBmodel *model, int genconstr, int *resvarP,\n                     int *nvarsP, int *vars);\nint __stdcall\n  GRBgetgenconstrOr(GRBmodel *model, int genconstr, int *resvarP,\n                    int *nvarsP, int *vars);\nint __stdcall\n  GRBgetgenconstrNorm(GRBmodel *model, int genconstr, int *resvarP,\n                      int *nvarsP, int *vars, double *whichP);\nint __stdcall\nGRBgetgenconstrNL(GRBmodel *model, int genconstr, int *resvarP, int *nnodesP,\n                  int *opcode, double *data, int *parent);\nint __stdcall\n  GRBgetgenconstrIndicator(GRBmodel *model, int genconstr, int *binvarP, int *binvalP,\n                           int *nvarsP, int *vars, double *vals,\n                           char *senseP, double *rhsP);\nint __stdcall\n  GRBgetgenconstrPWL(GRBmodel *model, int genconstr, int *xvarP, int *yvarP,\n                     int *nptsP, double *xpts, double *ypts);\nint __stdcall\n  GRBgetgenconstrPoly(GRBmodel *model, int genconstr, int *xvarP,\n                      int *yvarP, int *plenP, double *p);\nint __stdcall\n  GRBgetgenconstrExpA(GRBmodel *model, int genconstr, int *xvarP,\n                      int *yvarP, double *aP);\nint __stdcall\n  GRBgetgenconstrLogA(GRBmodel *model, int genconstr, int *xvarP,\n                      int *yvarP, double *aP);\nint __stdcall\n  GRBgetgenconstrPow(GRBmodel *model, int genconstr, int *xvarP,\n                     int *yvarP, double *aP);\nint __stdcall\n  GRBgetgenconstrExp(GRBmodel *model, int genconstr, int *xvarP, int *yvarP);\nint __stdcall\n  GRBgetgenconstrLog(GRBmodel *model, int genconstr, int *xvarP, int *yvarP);\nint __stdcall\n  GRBgetgenconstrLogistic(GRBmodel *model, int genconstr, int *xvarP,\n                          int *yvarP);\nint __stdcall\n  GRBgetgenconstrSin(GRBmodel *model, int genconstr, int *xvarP, int *yvarP);\nint __stdcall\n  GRBgetgenconstrCos(GRBmodel *model, int genconstr, int *xvarP, int *yvarP);\nint __stdcall\n  GRBgetgenconstrTan(GRBmodel *model, int genconstr, int *xvarP, int *yvarP);\nint __stdcall\n  GRBgetq(GRBmodel *model, int *numqnzP, int *qrow, int *qcol, double *qval);\nint __stdcall\n  GRBgetqconstr(GRBmodel *model, int qconstr,\n                int *numlnzP, int *lind, double *lval,\n                int *numqnzP, int *qrow, int *qcol, double *qval);\nint __stdcall\n  GRBgetvarbyname(GRBmodel *model, const char *name, int *indexP);\nint __stdcall\n  GRBgetconstrbyname(GRBmodel *model, const char *name, int *indexP);\nint __stdcall\n  GRBgetqconstrbyname(GRBmodel *model, const char *name, int *indexP);\nint __stdcall\n  GRBgetpwlobj(GRBmodel *model, int var, int *pointsP,\n               double *x, double *y);\n\nint __stdcall\n  GRBoptimize(GRBmodel *model);\nint __stdcall\n  GRBoptimizeasync(GRBmodel *model);\nint __stdcall\n  GRBoptimizebatch(GRBmodel *model, char *batchid);\n\nGRBmodel * __stdcall\n  GRBcopymodel(GRBmodel *model);\nint __stdcall\n  GRBcopymodeltoenv(GRBmodel *model, GRBenv *env, GRBmodel **resultP);\nint __stdcall\n  GRBfixmodel(GRBmodel *model, GRBmodel **fixedP);\nint __stdcall\n  GRBfeasrelax(GRBmodel *model, int relaxobjtype, int minrelax,\n               double *lbpen, double *ubpen, double *rhspen,\n               double *feasobjP);\nint __stdcall\n  GRBsinglescenariomodel(GRBmodel *model, GRBmodel **singlescenarioP);\nint __stdcall\n  GRBconverttofixed(GRBmodel *model);\n\n/* Undocumented routines */\n\nint __stdcall\n  GRBgetcbwhatinfo(void *cbdata, int what, int *typeP, int *sizeP);\nint __stdcall\n  GRBrelaxmodel(GRBmodel *model, GRBmodel **relaxedP);\nint __stdcall\n  GRBpresolvemodel(GRBmodel *model, GRBmodel **presolvedP);\nint __stdcall\n  GRBiismodel(GRBmodel *model, GRBmodel **iisP);\nint __stdcall\n  GRBfeasibility(GRBmodel *model, GRBmodel **feasP);\nint __stdcall\n  GRBlinearizemodel(GRBmodel *model, GRBmodel **linearizedP);\nint __stdcall\n  GRBresultmodel(GRBmodel *model, char *type, GRBmodel **resultP);\nGRBmodel * __stdcall\n  GRBfixedmodel(GRBmodel *model);\nint __stdcall\n  GRBdualmodel(GRBmodel *model, GRBmodel **dualP);\nint __stdcall\n  GRBisgpusupported(GRBenv *env);\nint __stdcall\n  GRBisgpubuild(void);\n\n#define MALLOCCB_ARGS size_t size, void *syscbusrdata\n#define CALLOCCB_ARGS size_t nmemb, size_t size, void *syscbusrdata\n#define REALLOCCB_ARGS void *ptr, size_t size, void *syscbusrdata\n#define FREECB_ARGS void *ptr, void *syscbusrdata\n#define THREADCREATECB_ARGS void **threadP, void (*start_routine)(void *), void *arg, void *syscbusrdata\n#define THREADJOINCB_ARGS void *thread, void *syscbusrdata\n\n#define GRBemptyenvadv(envP, malloccb, callocbc, realloccb, freecb, threadcreatecb, threadjoincb, syscbusrdata) GRBemptyenvadvinternal(envP, -1, GRB_VERSION_MAJOR, GRB_VERSION_MINOR, GRB_VERSION_TECHNICAL, malloccb, callocbc, realloccb, freecb, threadcreatecb, threadjoincb, syscbusrdata)\n\nint __stdcall\n  GRBemptyenvadvnocheck(GRBenv **envP,\n                        void * (__stdcall *malloccb)(MALLOCCB_ARGS),\n                        void * (__stdcall *calloccb)(CALLOCCB_ARGS),\n                        void * (__stdcall *realloccb)(REALLOCCB_ARGS),\n                        void   (__stdcall *freecb)(FREECB_ARGS),\n                        int    (__stdcall *threadcreatecb)(THREADCREATECB_ARGS),\n                        void   (__stdcall *threadjoincb)(THREADJOINCB_ARGS),\n                        void              *syscbusrdata);\n\nint __stdcall\n  GRBemptyenvadvinternal(GRBenv **envP, int apitype, int major, int minor, int tech,\n                         void * (__stdcall *malloccb)(MALLOCCB_ARGS),\n                         void * (__stdcall *calloccb)(CALLOCCB_ARGS),\n                         void * (__stdcall *realloccb)(REALLOCCB_ARGS),\n                         void   (__stdcall *freecb)(FREECB_ARGS),\n                         int    (__stdcall *threadcreatecb)(THREADCREATECB_ARGS),\n                         void   (__stdcall *threadjoincb)(THREADJOINCB_ARGS),\n                         void              *syscbusrdata);\n\nint __stdcall\n  GRBreadmodel(GRBenv *env, const char *filename, GRBmodel **modelP);\nint __stdcall\n  GRBread(GRBmodel *model, const char *filename);\nint __stdcall\n  GRBwrite(GRBmodel *model, const char *filename);\nint __stdcall\n  GRBismodelfile(const char *filename);\nint __stdcall\n  GRBisattrfile(const char *filename);\nint __stdcall\n  GRBfiletype(const char *filename);\nint __stdcall\n  GRBisrecordfile(const char *filename);\nint __stdcall\n  GRBgetjsonsolution(GRBmodel *model, char **buffP);\nint __stdcall\n  GRBloadjson(GRBenv *env, const char *fname, char **buffP);\nint __stdcall\n  GRBnewmodel(GRBenv *env, GRBmodel **modelP, const char *Pname, int numvars,\n              double *obj, double *lb, double *ub, char *vtype,\n              char **varnames);\n\nint __stdcall\n  GRBloadmodel(GRBenv *env, GRBmodel **modelP, const char *Pname,\n               int numvars, int numconstrs,\n               int objsense, double objcon, double *obj,\n               char *sense, double *rhs,\n               int *vbeg, int *vlen, int *vind, double *vval,\n               double *lb, double *ub, char *vtype,\n               char **varnames, char **constrnames);\n\nint __stdcall\n  GRBXloadmodel(GRBenv *env, GRBmodel **modelP, const char *Pname,\n                int numvars, int numconstrs,\n                int objsense, double objcon, double *obj,\n                char *sense, double *rhs,\n                size_t *vbeg, int *vlen, int *vind, double *vval,\n                double *lb, double *ub, char *vtype,\n                char **varnames, char **constrnames);\n\nint __stdcall\n  GRBaddvar(GRBmodel *model, int numnz, int *vind, double *vval,\n            double obj, double lb, double ub, char vtype,\n            const char *varname);\nint __stdcall\n  GRBaddvars(GRBmodel *model, int numvars, int numnz,\n             int *vbeg, int *vind, double *vval,\n             double *obj, double *lb, double *ub, char *vtype,\n             char **varnames);\nint __stdcall\n  GRBXaddvars(GRBmodel *model, int numvars, size_t numnz,\n              size_t *vbeg, int *vind, double *vval,\n              double *obj, double *lb, double *ub, char *vtype,\n              char **varnames);\nint __stdcall\n  GRBaddconstr(GRBmodel *model, int numnz, int *cind, double *cval,\n               char sense, double rhs, const char *constrname);\nint __stdcall\n  GRBaddconstrs(GRBmodel *model, int numconstrs, int numnz,\n                int *cbeg, int *cind, double *cval,\n                char *sense, double *rhs, char **constrnames);\nint __stdcall\n  GRBXaddconstrs(GRBmodel *model, int numconstrs, size_t numnz,\n                 size_t *cbeg, int *cind, double *cval,\n                 char *sense, double *rhs, char **constrnames);\nint __stdcall\n  GRBaddrangeconstr(GRBmodel *model, int numnz, int *cind, double *cval,\n                    double lower, double upper, const char *constrname);\nint __stdcall\n  GRBaddrangeconstrs(GRBmodel *model, int numconstrs, int numnz,\n                     int *cbeg, int *cind, double *cval,\n                     double *lower, double *upper, char **constrnames);\nint __stdcall\n  GRBXaddrangeconstrs(GRBmodel *model, int numconstrs, size_t numnz,\n                      size_t *cbeg, int *cind, double *cval,\n                      double *lower, double *upper, char **constrnames);\nint __stdcall\n  GRBaddsos(GRBmodel *model, int numsos, int nummembers, int *types,\n            int *beg, int *ind, double *weight);\nint __stdcall\n  GRBaddgenconstrMax(GRBmodel *model, const char *name,\n                     int resvar, int nvars, const int *vars,\n                     double constant);\nint __stdcall\n  GRBaddgenconstrMin(GRBmodel *model, const char *name,\n                     int resvar, int nvars, const int *vars,\n                     double constant);\nint __stdcall\n  GRBaddgenconstrAbs(GRBmodel *model, const char *name,\n                     int resvar, int argvar);\nint __stdcall\n  GRBaddgenconstrAnd(GRBmodel *model, const char *name,\n                     int resvar, int nvars, const int *vars);\nint __stdcall\n  GRBaddgenconstrOr(GRBmodel *model, const char *name,\n                    int resvar, int nvars, const int *vars);\nint __stdcall\n  GRBaddgenconstrNorm(GRBmodel *model, const char *name,\n                      int resvar, int nvars, const int *vars, double which);\nint __stdcall\nGRBaddgenconstrNL(GRBmodel *model,\n                  const char *name, int resvar, int nnodes, const int *opcode,\n                  const double *data, const int *parent);\nint __stdcall\n  GRBaddgenconstrIndicator(GRBmodel *model, const char *name,\n                           int binvar, int binval, int nvars, const int *vars,\n                           const double *vals, char sense, double rhs);\nint __stdcall\n  GRBaddgenconstrPWL(GRBmodel *model, const char *name,\n                     int xvar, int yvar, int npts,\n                     const double *xpts, const double *ypts);\nint __stdcall\n  GRBaddgenconstrPoly(GRBmodel *model, const char *name, int xvar, int yvar,\n                      int plen, const double *p, const char *options);\nint __stdcall\n  GRBaddgenconstrExpA(GRBmodel *model, const char *name, int xvar,\n                      int yvar, double a, const char *options);\nint __stdcall\n  GRBaddgenconstrLogA(GRBmodel *model, const char *name, int xvar,\n                      int yvar, double a, const char *options);\nint __stdcall\n  GRBaddgenconstrPow(GRBmodel *model, const char *name, int xvar,\n                     int yvar, double a, const char *options);\nint __stdcall\n  GRBaddgenconstrExp(GRBmodel *model, const char *name, int xvar,\n                     int yvar, const char *options);\nint __stdcall\n  GRBaddgenconstrLog(GRBmodel *model, const char *name, int xvar,\n                     int yvar, const char *options);\nint __stdcall\n  GRBaddgenconstrSin(GRBmodel *model, const char *name, int xvar,\n                     int yvar, const char *options);\nint __stdcall\n  GRBaddgenconstrCos(GRBmodel *model, const char *name, int xvar,\n                     int yvar, const char *options);\nint __stdcall\n  GRBaddgenconstrTan(GRBmodel *model, const char *name, int xvar,\n                     int yvar, const char *options);\nint __stdcall\n  GRBaddgenconstrLogistic(GRBmodel *model, const char *name, int xvar,\n                          int yvar, const char *options);\nint __stdcall\n  GRBaddqconstr(GRBmodel *model, int numlnz, int *lind, double *lval,\n                int numqnz, int *qrow, int *qcol, double *qval,\n                char sense, double rhs, const char *QCname);\nint __stdcall\n  GRBaddcone(GRBmodel *model, int nummembers, int *members);\nint __stdcall\n  GRBaddqpterms(GRBmodel *model, int numqnz, int *qrow, int *qcol,\n                double *qval);\nint __stdcall\n  GRBdelvars(GRBmodel *model, int len, int *ind);\nint __stdcall\n  GRBdelconstrs(GRBmodel *model, int len, int *ind);\nint __stdcall\n  GRBdelsos(GRBmodel *model, int len, int *ind);\nint __stdcall\n  GRBdelgenconstrs(GRBmodel *model, int len, int *ind);\nint __stdcall\n  GRBdelqconstrs(GRBmodel *model, int len, int *ind);\nint __stdcall\n  GRBdelq(GRBmodel *model);\nint __stdcall\n  GRBchgcoeffs(GRBmodel *model, int cnt, int *cind, int *vind, double *val);\nint __stdcall\n  GRBXchgcoeffs(GRBmodel *model, size_t cnt, int *cind, int *vind, double *val);\nint __stdcall\n  GRBsetpwlobj(GRBmodel *model, int var, int points, double *x,\n               double *y);\n\nint __stdcall\n  GRBupdatemodel(GRBmodel *model);\n\nint __stdcall\n  GRBreset(GRBmodel *model, int clearall);\n\nint __stdcall\n  GRBfreemodel(GRBmodel *model);\n\nint __stdcall\n  GRBcomputeIIS(GRBmodel *model);\n\n/* simplex advanced routines */\n\ntypedef struct _GRBsvec\n{\n  int     len; /* sparse vector length. -1: It is a dense vector. */\n  int    *ind; /* indices array of the sparse vector */\n  double *val; /* value array of the sparse vector */\n} GRBsvec;\n\nint __stdcall\n  GRBFSolve(GRBmodel *model, GRBsvec *b, GRBsvec *x);\n\nint __stdcall\n  GRBBinvColj(GRBmodel *model, int j, GRBsvec *x);\n\nint __stdcall\n  GRBBinvj(GRBmodel *model, int j, GRBsvec *x);\n\nint __stdcall\n  GRBBSolve(GRBmodel *model, GRBsvec *b, GRBsvec *x);\n\nint __stdcall\n  GRBBinvi(GRBmodel *model, int i, GRBsvec *x);\n\nint __stdcall\n  GRBBinvRowi(GRBmodel *model, int i, GRBsvec *x);\n\nint __stdcall\n  GRBgetBasisHead(GRBmodel *model, int *bhead);\n\nint __stdcall\n  GRBcbstoponemultiobj(GRBmodel *model, void *cbdata, int objnum);\n\nint __stdcall\n  GRBsingularvectors(GRBmodel *model, double *left, double *right);\n\n/* Model status codes */\n\n#define GRB_LOADED              1\n#define GRB_OPTIMAL             2\n#define GRB_INFEASIBLE          3\n#define GRB_INF_OR_UNBD         4\n#define GRB_UNBOUNDED           5\n#define GRB_CUTOFF              6\n#define GRB_ITERATION_LIMIT     7\n#define GRB_NODE_LIMIT          8\n#define GRB_TIME_LIMIT          9\n#define GRB_SOLUTION_LIMIT     10\n#define GRB_INTERRUPTED        11\n#define GRB_NUMERIC            12\n#define GRB_SUBOPTIMAL         13\n#define GRB_INPROGRESS         14\n#define GRB_USER_OBJ_LIMIT     15\n#define GRB_WORK_LIMIT         16\n#define GRB_MEM_LIMIT          17\n#define GRB_LOCALLY_OPTIMAL    18\n#define GRB_LOCALLY_INFEASIBLE 19\n\n/* Basis status info */\n\n#define GRB_BASIC           0\n#define GRB_NONBASIC_LOWER -1\n#define GRB_NONBASIC_UPPER -2\n#define GRB_SUPERBASIC     -3\n\n/* Undocumented routines */\n\nint __stdcall\n  GRBstrongbranch(GRBmodel *model, int num, int *cand,\n                  double *downobjbd, double *upobjbd, int *statusP);\n/**************/\n/* Parameters */\n/**************/\n\n/* Termination */\n\n#define GRB_INT_PAR_BARITERLIMIT   \"BarIterLimit\"\n#define GRB_DBL_PAR_CUTOFF         \"Cutoff\"\n#define GRB_DBL_PAR_ITERATIONLIMIT \"IterationLimit\"\n#define GRB_DBL_PAR_NODELIMIT      \"NodeLimit\"\n#define GRB_INT_PAR_SOLUTIONLIMIT  \"SolutionLimit\"\n#define GRB_DBL_PAR_TIMELIMIT      \"TimeLimit\"\n#define GRB_DBL_PAR_WORKLIMIT      \"WorkLimit\"\n#define GRB_DBL_PAR_MEMLIMIT       \"MemLimit\"\n#define GRB_DBL_PAR_SOFTMEMLIMIT   \"SoftMemLimit\"\n#define GRB_DBL_PAR_BESTOBJSTOP    \"BestObjStop\"\n#define GRB_DBL_PAR_BESTBDSTOP     \"BestBdStop\"\n#define GRB_INT_PAR_NLBARITERLIMIT \"NLBarIterLimit\"\n\n/* Tolerances */\n\n#define GRB_DBL_PAR_FEASIBILITYTOL \"FeasibilityTol\"\n#define GRB_DBL_PAR_INTFEASTOL     \"IntFeasTol\"\n#define GRB_DBL_PAR_MARKOWITZTOL   \"MarkowitzTol\"\n#define GRB_DBL_PAR_MIPGAP         \"MIPGap\"\n#define GRB_DBL_PAR_MIPGAPABS      \"MIPGapAbs\"\n#define GRB_DBL_PAR_OPTIMALITYTOL  \"OptimalityTol\"\n#define GRB_DBL_PAR_PSDTOL         \"PSDTol\"\n#define GRB_DBL_PAR_NLBARPFEASTOL  \"NLBarPFeasTol\"\n#define GRB_DBL_PAR_NLBARDFEASTOL  \"NLBarDFeasTol\"\n#define GRB_DBL_PAR_NLBARCFEASTOL  \"NLBarCFeasTol\"\n\n/* Simplex */\n\n#define GRB_INT_PAR_METHOD            \"Method\"\n#define GRB_INT_PAR_CONCURRENTMETHOD  \"ConcurrentMethod\"\n#define GRB_DBL_PAR_PERTURBVALUE      \"PerturbValue\"\n#define GRB_DBL_PAR_OBJSCALE          \"ObjScale\"\n#define GRB_INT_PAR_SCALEFLAG         \"ScaleFlag\"\n#define GRB_INT_PAR_SIMPLEXPRICING    \"SimplexPricing\"\n#define GRB_INT_PAR_QUAD              \"Quad\"\n#define GRB_INT_PAR_NORMADJUST        \"NormAdjust\"\n#define GRB_INT_PAR_SIFTING           \"Sifting\"\n#define GRB_INT_PAR_SIFTMETHOD        \"SiftMethod\"\n#define GRB_INT_PAR_LPWARMSTART       \"LPWarmStart\"\n#define GRB_INT_PAR_NETWORKALG        \"NetworkAlg\"\n\n/* Barrier */\n\n#define GRB_DBL_PAR_BARCONVTOL     \"BarConvTol\"\n#define GRB_INT_PAR_BARCORRECTORS  \"BarCorrectors\"\n#define GRB_INT_PAR_BARHOMOGENEOUS \"BarHomogeneous\"\n#define GRB_INT_PAR_BARORDER       \"BarOrder\"\n#define GRB_DBL_PAR_BARQCPCONVTOL  \"BarQCPConvTol\"\n#define GRB_INT_PAR_CROSSOVER      \"Crossover\"\n#define GRB_INT_PAR_CROSSOVERBASIS \"CrossoverBasis\"\n\n/* PDHG */\n\n#define GRB_DBL_PAR_PDHGITERLIMIT  \"PDHGIterLimit\"\n#define GRB_DBL_PAR_PDHGRELTOL     \"PDHGRelTol\"\n#define GRB_DBL_PAR_PDHGABSTOL     \"PDHGAbsTol\"\n#define GRB_DBL_PAR_PDHGCONVTOL    \"PDHGConvTol\"\n#define GRB_INT_PAR_PDHGGPU        \"PDHGGPU\"\n\n/* MIP */\n\n#define GRB_INT_PAR_BRANCHDIR           \"BranchDir\"\n#define GRB_INT_PAR_DEGENMOVES          \"DegenMoves\"\n#define GRB_INT_PAR_DISCONNECTED        \"Disconnected\"\n#define GRB_INT_PAR_FIXVARSININDICATORS \"FixVarsInIndicators\"\n#define GRB_DBL_PAR_HEURISTICS          \"Heuristics\"\n#define GRB_DBL_PAR_IMPROVESTARTGAP     \"ImproveStartGap\"\n#define GRB_DBL_PAR_IMPROVESTARTTIME    \"ImproveStartTime\"\n#define GRB_DBL_PAR_IMPROVESTARTWORK    \"ImproveStartWork\"\n#define GRB_DBL_PAR_IMPROVESTARTNODES   \"ImproveStartNodes\"\n#define GRB_INT_PAR_INTEGRALITYFOCUS    \"IntegralityFocus\"\n#define GRB_INT_PAR_MINRELNODES         \"MinRelNodes\"\n#define GRB_INT_PAR_MIPFOCUS            \"MIPFocus\"\n#define GRB_INT_PAR_NLPHEUR             \"NLPHeur\"\n#define GRB_STR_PAR_NODEFILEDIR         \"NodefileDir\"\n#define GRB_DBL_PAR_NODEFILESTART       \"NodefileStart\"\n#define GRB_INT_PAR_NODEMETHOD          \"NodeMethod\"\n#define GRB_DBL_PAR_NORELHEURTIME       \"NoRelHeurTime\"\n#define GRB_DBL_PAR_NORELHEURWORK       \"NoRelHeurWork\"\n#define GRB_INT_PAR_NORELHEURSOLUTIONS  \"NoRelHeurSolutions\"\n#define GRB_INT_PAR_OBBT                \"OBBT\"\n#define GRB_INT_PAR_PUMPPASSES          \"PumpPasses\"\n#define GRB_INT_PAR_RINS                \"RINS\"\n#define GRB_STR_PAR_SOLFILES            \"SolFiles\"\n#define GRB_INT_PAR_STARTNODELIMIT      \"StartNodeLimit\"\n#define GRB_DBL_PAR_STARTTIMELIMIT      \"StartTimeLimit\"\n#define GRB_DBL_PAR_STARTWORKLIMIT      \"StartWorkLimit\"\n#define GRB_INT_PAR_SUBMIPNODES         \"SubMIPNodes\"\n#define GRB_INT_PAR_SYMMETRY            \"Symmetry\"\n#define GRB_INT_PAR_VARBRANCH           \"VarBranch\"\n#define GRB_INT_PAR_SOLUTIONNUMBER      \"SolutionNumber\"\n#define GRB_INT_PAR_ZEROOBJNODES        \"ZeroObjNodes\"\n\n/* MIP cuts */\n\n#define GRB_INT_PAR_CUTS            \"Cuts\"\n\n#define GRB_INT_PAR_CLIQUECUTS      \"CliqueCuts\"\n#define GRB_INT_PAR_COVERCUTS       \"CoverCuts\"\n#define GRB_INT_PAR_FLOWCOVERCUTS   \"FlowCoverCuts\"\n#define GRB_INT_PAR_FLOWPATHCUTS    \"FlowPathCuts\"\n#define GRB_INT_PAR_GUBCOVERCUTS    \"GUBCoverCuts\"\n#define GRB_INT_PAR_IMPLIEDCUTS     \"ImpliedCuts\"\n#define GRB_INT_PAR_PROJIMPLIEDCUTS \"ProjImpliedCuts\"\n#define GRB_INT_PAR_MIPSEPCUTS      \"MIPSepCuts\"\n#define GRB_INT_PAR_MIRCUTS         \"MIRCuts\"\n#define GRB_INT_PAR_STRONGCGCUTS    \"StrongCGCuts\"\n#define GRB_INT_PAR_MODKCUTS        \"ModKCuts\"\n#define GRB_INT_PAR_ZEROHALFCUTS    \"ZeroHalfCuts\"\n#define GRB_INT_PAR_NETWORKCUTS     \"NetworkCuts\"\n#define GRB_INT_PAR_SUBMIPCUTS      \"SubMIPCuts\"\n#define GRB_INT_PAR_INFPROOFCUTS    \"InfProofCuts\"\n#define GRB_INT_PAR_RLTCUTS         \"RLTCuts\"\n#define GRB_INT_PAR_RELAXLIFTCUTS   \"RelaxLiftCuts\"\n#define GRB_INT_PAR_BQPCUTS         \"BQPCuts\"\n#define GRB_INT_PAR_PSDCUTS         \"PSDCuts\"\n#define GRB_INT_PAR_LIFTPROJECTCUTS \"LiftProjectCuts\"\n#define GRB_INT_PAR_MIXINGCUTS      \"MixingCuts\"\n#define GRB_INT_PAR_DUALIMPLIEDCUTS \"DualImpliedCuts\"\n#define GRB_INT_PAR_MASTERKNAPSACKCUTS \"MasterKnapsackCuts\"\n\n#define GRB_INT_PAR_CUTAGGPASSES    \"CutAggPasses\"\n#define GRB_INT_PAR_CUTPASSES       \"CutPasses\"\n#define GRB_INT_PAR_GOMORYPASSES    \"GomoryPasses\"\n\n/* Distributed algorithms */\n\n#define GRB_STR_PAR_WORKERPOOL      \"WorkerPool\"\n#define GRB_STR_PAR_WORKERPASSWORD  \"WorkerPassword\"\n\n/* Licensing and Compute Server */\n#define GRB_STR_PAR_COMPUTESERVER     \"ComputeServer\"\n#define GRB_STR_PAR_TOKENSERVER       \"TokenServer\"\n#define GRB_STR_PAR_SERVERPASSWORD    \"ServerPassword\"\n#define GRB_INT_PAR_SERVERTIMEOUT     \"ServerTimeout\"\n#define GRB_STR_PAR_CSROUTER          \"CSRouter\"\n#define GRB_STR_PAR_CSGROUP           \"CSGroup\"\n#define GRB_DBL_PAR_CSQUEUETIMEOUT    \"CSQueueTimeout\"\n#define GRB_INT_PAR_CSPRIORITY        \"CSPriority\"\n#define GRB_INT_PAR_CSIDLETIMEOUT     \"CSIdleTimeout\"\n#define GRB_INT_PAR_CSTLSINSECURE     \"CSTLSInsecure\"\n#define GRB_INT_PAR_TSPORT            \"TSPort\"\n#define GRB_STR_PAR_CLOUDACCESSID     \"CloudAccessID\"\n#define GRB_STR_PAR_CLOUDSECRETKEY    \"CloudSecretKey\"\n#define GRB_STR_PAR_CLOUDPOOL         \"CloudPool\"\n#define GRB_STR_PAR_CLOUDHOST         \"CloudHost\"\n#define GRB_STR_PAR_CSMANAGER         \"CSManager\"\n#define GRB_STR_PAR_CSAUTHTOKEN       \"CSAuthToken\"\n#define GRB_STR_PAR_CSAPIACCESSID     \"CSAPIAccessID\"\n#define GRB_STR_PAR_CSAPISECRET       \"CSAPISecret\"\n#define GRB_INT_PAR_CSBATCHMODE       \"CSBatchMode\"\n#define GRB_STR_PAR_USERNAME          \"Username\"\n#define GRB_STR_PAR_CSAPPNAME         \"CSAppName\"\n#define GRB_INT_PAR_CSCLIENTLOG       \"CSClientLog\"\n#define GRB_STR_PAR_WLSACCESSID       \"WLSAccessID\"\n#define GRB_STR_PAR_WLSSECRET         \"WLSSecret\"\n#define GRB_INT_PAR_WLSTOKENDURATION  \"WLSTokenDuration\"\n#define GRB_DBL_PAR_WLSTOKENREFRESH   \"WLSTokenRefresh\"\n#define GRB_STR_PAR_WLSTOKEN          \"WLSToken\"\n#define GRB_INT_PAR_LICENSEID         \"LicenseID\"\n#define GRB_STR_PAR_WLSPROXY          \"WLSProxy\"\n#define GRB_STR_PAR_WLSCONFIG         \"WLSConfig\"\n\n/* NL barrier */\n\n#define GRB_INT_PAR_OPTIMALITYTARGET  \"OptimalityTarget\"\n\n\n/* Other */\n\n#define GRB_INT_PAR_AGGREGATE         \"Aggregate\"\n#define GRB_INT_PAR_AGGFILL           \"AggFill\"\n#define GRB_INT_PAR_CONCURRENTMIP     \"ConcurrentMIP\"\n#define GRB_INT_PAR_CONCURRENTJOBS    \"ConcurrentJobs\"\n#define GRB_INT_PAR_DISPLAYINTERVAL   \"DisplayInterval\"\n#define GRB_INT_PAR_DISTRIBUTEDMIPJOBS \"DistributedMIPJobs\"\n#define GRB_INT_PAR_DUALREDUCTIONS    \"DualReductions\"\n#define GRB_DBL_PAR_FEASRELAXBIGM     \"FeasRelaxBigM\"\n#define GRB_INT_PAR_IISMETHOD         \"IISMethod\"\n#define GRB_INT_PAR_INFUNBDINFO       \"InfUnbdInfo\"\n#define GRB_INT_PAR_JSONSOLDETAIL     \"JSONSolDetail\"\n#define GRB_INT_PAR_LAZYCONSTRAINTS   \"LazyConstraints\"\n#define GRB_STR_PAR_LOGFILE           \"LogFile\"\n#define GRB_INT_PAR_LOGTOCONSOLE      \"LogToConsole\"\n#define GRB_INT_PAR_MIQCPMETHOD       \"MIQCPMethod\"\n#define GRB_INT_PAR_NONCONVEX         \"NonConvex\"\n#define GRB_INT_PAR_NUMERICFOCUS      \"NumericFocus\"\n#define GRB_INT_PAR_OUTPUTFLAG        \"OutputFlag\"\n#define GRB_INT_PAR_PRECRUSH          \"PreCrush\"\n#define GRB_INT_PAR_PREDEPROW         \"PreDepRow\"\n#define GRB_INT_PAR_PREDUAL           \"PreDual\"\n#define GRB_INT_PAR_PREPASSES         \"PrePasses\"\n#define GRB_INT_PAR_PREQLINEARIZE     \"PreQLinearize\"\n#define GRB_INT_PAR_PRESOLVE          \"Presolve\"\n#define GRB_DBL_PAR_PRESOS1BIGM       \"PreSOS1BigM\"\n#define GRB_DBL_PAR_PRESOS2BIGM       \"PreSOS2BigM\"\n#define GRB_INT_PAR_PRESOS1ENCODING   \"PreSOS1Encoding\"\n#define GRB_INT_PAR_PRESOS2ENCODING   \"PreSOS2Encoding\"\n#define GRB_INT_PAR_PRESPARSIFY       \"PreSparsify\"\n#define GRB_INT_PAR_PREMIQCPFORM      \"PreMIQCPForm\"\n#define GRB_INT_PAR_QCPDUAL           \"QCPDual\"\n#define GRB_INT_PAR_RECORD            \"Record\"\n#define GRB_STR_PAR_RESULTFILE        \"ResultFile\"\n#define GRB_INT_PAR_SEED              \"Seed\"\n#define GRB_INT_PAR_SOLUTIONTARGET    \"SolutionTarget\"\n#define GRB_INT_PAR_THREADS           \"Threads\"\n#define GRB_INT_PAR_THREADLIMIT       \"ThreadLimit\"\n#define GRB_DBL_PAR_TUNETIMELIMIT     \"TuneTimeLimit\"\n#define GRB_INT_PAR_TUNERESULTS       \"TuneResults\"\n#define GRB_INT_PAR_TUNECRITERION     \"TuneCriterion\"\n#define GRB_INT_PAR_TUNETRIALS        \"TuneTrials\"\n#define GRB_INT_PAR_TUNEOUTPUT        \"TuneOutput\"\n#define GRB_INT_PAR_TUNEJOBS          \"TuneJobs\"\n#define GRB_DBL_PAR_TUNECLEANUP       \"TuneCleanup\"\n#define GRB_DBL_PAR_TUNETARGETMIPGAP  \"TuneTargetMIPGap\"\n#define GRB_DBL_PAR_TUNETARGETTIME    \"TuneTargetTime\"\n#define GRB_INT_PAR_TUNEMETRIC        \"TuneMetric\"\n#define GRB_INT_PAR_TUNEDYNAMICJOBS   \"TuneDynamicJobs\"\n#define GRB_INT_PAR_UPDATEMODE        \"UpdateMode\"\n#define GRB_INT_PAR_OBJNUMBER         \"ObjNumber\"\n#define GRB_INT_PAR_OBJPASSNUMBER     \"ObjPassNumber\"\n#define GRB_INT_PAR_MULTIOBJMETHOD    \"MultiObjMethod\"\n#define GRB_INT_PAR_MULTIOBJPRE       \"MultiObjPre\"\n#define GRB_INT_PAR_SCENARIONUMBER    \"ScenarioNumber\"\n#define GRB_INT_PAR_POOLSOLUTIONS     \"PoolSolutions\"\n#define GRB_DBL_PAR_POOLGAP           \"PoolGap\"\n#define GRB_DBL_PAR_POOLGAPABS        \"PoolGapAbs\"\n#define GRB_INT_PAR_POOLSEARCHMODE    \"PoolSearchMode\"\n#define GRB_INT_PAR_IGNORENAMES       \"IgnoreNames\"\n#define GRB_INT_PAR_STARTNUMBER       \"StartNumber\"\n#define GRB_INT_PAR_PARTITIONPLACE    \"PartitionPlace\"\n#define GRB_INT_PAR_FUNCPIECES        \"FuncPieces\"\n#define GRB_DBL_PAR_FUNCPIECELENGTH   \"FuncPieceLength\"\n#define GRB_DBL_PAR_FUNCPIECEERROR    \"FuncPieceError\"\n#define GRB_DBL_PAR_FUNCPIECERATIO    \"FuncPieceRatio\"\n#define GRB_DBL_PAR_FUNCMAXVAL        \"FuncMaxVal\"\n#define GRB_INT_PAR_FUNCNONLINEAR     \"FuncNonlinear\"\n#define GRB_STR_PAR_DUMMY             \"Dummy\"\n#define GRB_STR_PAR_JOBID             \"JobID\"\n#define GRB_INT_PAR_INHERITPARAMS     \"InheritParams\"\n\n\n/* Parameter enumerations */\n\n/* Cuts parameter values */\n\n#define GRB_CUTS_AUTO          -1\n#define GRB_CUTS_OFF            0\n#define GRB_CUTS_CONSERVATIVE   1\n#define GRB_CUTS_AGGRESSIVE     2\n#define GRB_CUTS_VERYAGGRESSIVE 3\n\n/* Presolve parameter values */\n\n#define GRB_PRESOLVE_AUTO        -1\n#define GRB_PRESOLVE_OFF          0\n#define GRB_PRESOLVE_CONSERVATIVE 1\n#define GRB_PRESOLVE_AGGRESSIVE   2\n\n/* Method parameter values */\n\n#define GRB_METHOD_NONE                            -1\n#define GRB_METHOD_AUTO                            -1\n#define GRB_METHOD_PRIMAL                           0\n#define GRB_METHOD_DUAL                             1\n#define GRB_METHOD_BARRIER                          2\n#define GRB_METHOD_CONCURRENT                       3\n#define GRB_METHOD_DETERMINISTIC_CONCURRENT         4\n#define GRB_METHOD_DETERMINISTIC_CONCURRENT_SIMPLEX 5 /* Deprecated since v11 */\n#define GRB_METHOD_PDHG                             6\n\n#define GRB_CONCURRENTMETHOD_AUTO                -1\n#define GRB_CONCURRENTMETHOD_BARRIER_PRIMAL_DUAL  0\n#define GRB_CONCURRENTMETHOD_BARRIER_DUAL         1\n#define GRB_CONCURRENTMETHOD_BARRIER_PRIMAL       2\n#define GRB_CONCURRENTMETHOD_PRIMAL_DUAL          3\n\n/* BarHomogeneous parameter values */\n\n#define GRB_BARHOMOGENEOUS_AUTO -1\n#define GRB_BARHOMOGENEOUS_OFF   0\n#define GRB_BARHOMOGENEOUS_ON    1\n\n/* BarOrder parameter values */\n\n#define GRB_BARORDER_AUTOMATIC       -1\n#define GRB_BARORDER_AMD              0\n#define GRB_BARORDER_NESTEDDISSECTION 1\n\n/* MIPFocus parameter values */\n\n#define GRB_MIPFOCUS_BALANCED    0\n#define GRB_MIPFOCUS_FEASIBILITY 1\n#define GRB_MIPFOCUS_OPTIMALITY  2\n#define GRB_MIPFOCUS_BESTBOUND   3\n\n/* SimplexPricing parameter values */\n\n#define GRB_SIMPLEXPRICING_AUTO           -1\n#define GRB_SIMPLEXPRICING_PARTIAL         0\n#define GRB_SIMPLEXPRICING_STEEPEST_EDGE   1\n#define GRB_SIMPLEXPRICING_DEVEX           2\n#define GRB_SIMPLEXPRICING_STEEPEST_QUICK  3\n\n/* VarBranch parameter values */\n\n#define GRB_VARBRANCH_AUTO          -1\n#define GRB_VARBRANCH_PSEUDO_REDUCED 0\n#define GRB_VARBRANCH_PSEUDO_SHADOW  1\n#define GRB_VARBRANCH_MAX_INFEAS     2\n#define GRB_VARBRANCH_STRONG         3\n\n/* PartitionPlace parameter values */\n\n#define GRB_PARTITION_EARLY     16\n#define GRB_PARTITION_ROOTSTART 8\n#define GRB_PARTITION_ROOTEND   4\n#define GRB_PARTITION_NODES     2\n#define GRB_PARTITION_CLEANUP   1\n\n/* Callback phase values */\n\n#define GRB_PHASE_MIP_NOREL   0\n#define GRB_PHASE_MIP_SEARCH  1\n#define GRB_PHASE_MIP_IMPROVE 2\n\nint __stdcall\n  GRBcheckmodel(GRBmodel *model);\nvoid __stdcall\n  GRBterminate(GRBmodel *model);\nint __stdcall\n  GRBreplay(const char *filename);\nint __stdcall\n  GRBsetobjective(GRBmodel *model, int sense, double constant,\n                  int lnz, int *lind, double *lval,\n                  int qnz, int *qrow, int *qcol, double *qval);\nint __stdcall\n  GRBsetobjectiven(GRBmodel *model, int index, int priority, double weight,\n                   double abstol, double reltol, const char *name,\n                   double constant, int lnz, int *lind, double *lval);\nvoid __stdcall\n  GRBclean2(int *lenP, int *ind, double *val);\nint __stdcall\n  GRBclean2checknan(int *lenP, int *ind, double *val);\nvoid __stdcall\n  GRBclean3(int *lenP, int *ind0, int *ind1, double *val);\nint __stdcall\n  GRBclean3checknan(int *lenP, int *ind0, int *ind1, double *val);\n\nint __stdcall\n  GRBprintquality(GRBmodel *model);\n\n/* Logging */\n\nvoid __stdcall\n  GRBmsg(GRBenv *env, const char *message);\n\n\n/* Parameter routines */\n\nint __stdcall\n  GRBgetintparam(GRBenv *env, const char *paramname, int *valueP);\nint __stdcall\n  GRBgetdblparam(GRBenv *env, const char *paramname, double *valueP);\nint __stdcall\n  GRBgetstrparam(GRBenv *env, const char *paramname, char *valueP);\nint __stdcall\n  GRBgetlongstrparam(GRBenv *env, const char *paramname, char *valueP,\n                     int size, int *requiredlenP);\nint __stdcall\n  GRBgetintparaminfo(GRBenv *env, const char *paramname, int *valueP,\n                     int *minP, int *maxP, int *defP);\nint __stdcall\n  GRBgetdblparaminfo(GRBenv *env, const char *paramname, double *valueP,\n                     double *minP, double *maxP, double *defP);\nint __stdcall\n  GRBgetstrparaminfo(GRBenv *env, const char *paramname, char *valueP,\n                     char *defP);\nint __stdcall\n  GRBgetparamflags(GRBenv *env, const char *parname, unsigned int *valueP);\nint __stdcall\n  GRBsetparam(GRBenv *env, const char *paramname, const char *value);\nint __stdcall\n  GRBsetintparam(GRBenv *env, const char *paramname, int value);\nint __stdcall\n  GRBsetdblparam(GRBenv *env, const char *paramname, double value);\nint __stdcall\n  GRBsetstrparam(GRBenv *env, const char *paramname, const char *value);\nint __stdcall\n  GRBgetparamtype(GRBenv *env, const char *paramname);\nint __stdcall\n  GRBresetparams(GRBenv *env);\nint __stdcall\n  GRBwriteparams(GRBenv *env, const char *filename);\nint __stdcall\n  GRBreadparams(GRBenv *env, const char *filename);\nint __stdcall\n  GRBreadconcurrentsettings(GRBmodel *model, const char *filename);\nint __stdcall\n  GRBreadmultiobjsettings(GRBmodel *model, const char *filename);\nint __stdcall\n  GRBreadtunebasesettings(GRBenv *env, const char *filename);\nint __stdcall\n  GRBreadtuneignoresettings(GRBenv *env, const char *filename);\nint __stdcall\n  GRBgetnumparams(GRBenv *env);\nint __stdcall\n  GRBgetparamname(GRBenv *env, int parnum, char **paramnameP);\nint __stdcall\n  GRBgetnumattributes(GRBmodel *model);\nint __stdcall\n  GRBgetattrname(GRBmodel *model, int i, char **attrnameP);\n\n/* Environment routines */\n\n// #define GRBloadenv(envP, logfilename) GRBloadenvinternal(envP, logfilename, GRB_VERSION_MAJOR, GRB_VERSION_MINOR, GRB_VERSION_TECHNICAL)\n// #define GRBemptyenv(envP) GRBemptyenvinternal(envP, GRB_VERSION_MAJOR, GRB_VERSION_MINOR, GRB_VERSION_TECHNICAL)\nint __stdcall\nGRBloadenv(GRBenv **envP, const char *logfilename);\nint __stdcall\nGRBemptyenv(GRBenv **envP);\nint __stdcall\nGRBloadenvinternal(GRBenv **envP, const char *logfilename, int major, int minor, int tech);\nint __stdcall\nGRBemptyenvinternal(GRBenv **envP, int major, int minor, int tech);\nint __stdcall\n  GRBstartenv(GRBenv *env);\nint __stdcall\n  GRBloadenvadv(GRBenv **envP, const char *logfilename,\n                int apitype, int major, int minor, int tech,\n                const char *server, const char *router,\n                const char *password, const char *group,\n                int priority, int idletimeout,\n                const char *cloudaccessid, const char *cloudsecretkey,\n                int (__stdcall *cb)(CB_ARGS), void *usrdata,\n                int (__stdcall *logcb)(LOGCB_ARGS), void *logdata);\nGRBenv *__stdcall\n  GRBgetenv(GRBmodel *model);\nGRBenv *__stdcall\n  GRBgetconcurrentenv(GRBmodel *model, int num);\nvoid __stdcall\n  GRBdiscardconcurrentenvs(GRBmodel *model);\nGRBenv *__stdcall\n  GRBgetmultiobjenv(GRBmodel *model, int num);\nvoid __stdcall\n  GRBdiscardmultiobjenvs(GRBmodel *model);\nGRBenv *__stdcall\n  GRBgettuneenv(GRBenv *env, int num);\nvoid __stdcall\n  GRBdiscardtuneenvs(GRBenv *env);\nvoid __stdcall\n  GRBreleaselicense(GRBenv *env);\nvoid __stdcall\n  GRBfreeenv(GRBenv *env);\nconst char * __stdcall\n  GRBgeterrormsg(GRBenv *env);\nconst char * __stdcall\n  GRBgetmerrormsg(GRBmodel *model);\nvoid __stdcall\n  GRBgetcommstats(GRBenv *env, double *recvtimeP, double *recvbytesP,\n                  double *recvmsgsP, double *sendtimeP,\n                  double *sendbytesP, double *sendmsgsP);\n\n/* Version info */\n\nvoid __stdcall\n  GRBversion(int *majorP, int *minorP, int *technicalP);\n\nvoid __stdcall\n  GRBgetdistro(char *str);\n\nchar * __stdcall\n  GRBplatform(void);\n\nchar * __stdcall\n  GRBplatformext(void);\n\nint __stdcall\n  GRBlisttokens(void);\n\nint __stdcall\n  GRBgetwlstokenlifespan(GRBenv *env, int *lifespanP);\n\n/* Used in Matlab API */\nvoid __stdcall\n  GRBsortIDi(int len, int *ind, double *val);\n\n/* batch-related routines */\nint __stdcall\n  GRBabortbatch(GRBbatch *batch);\nint __stdcall\n  GRBdiscardbatch(GRBbatch *batch);\nint __stdcall\n  GRBretrybatch(GRBbatch *batch);\nint __stdcall\n  GRBfreebatch(GRBbatch *batch);\nint __stdcall\n  GRBgetbatch(GRBenv *env, const char *batchID, GRBbatch **batchP);\nint __stdcall\n  GRBgetbatchjsonsolution(GRBbatch *batch, char **jsonsolP);\nint __stdcall\n  GRBgetbatchintattr(GRBbatch *batch, const char *attrname, int *valueP);\nint __stdcall\n  GRBgetbatchstrattr(GRBbatch *batch, const char *attrname, char **valueP);\nint __stdcall\n  GRBgetbatchattrname(GRBenv *env, int n, char **attrnameP);\nint __stdcall\n  GRBgetbatchattrflags(GRBbatch *batch, const char *attrname, unsigned *flagsP);\nint __stdcall GRBgetbatchattrinfo(GRBbatch *batch, const char *attrname, int *datatypeP, int *settableP);\nint __stdcall\n  GRBupdatebatch(GRBbatch *batch);\nint __stdcall\n  GRBwritebatchjsonsolution(GRBbatch *batch, const char *filename);\nint __stdcall\n  GRBgetnumbatchattributes(GRBenv *env);\nGRBenv *__stdcall\n  GRBgetbatchenv(GRBbatch *batch);\n\n/* dummy wrapper for free function */\nvoid __stdcall\n  GRBfree(void *ptr);\n/* Batch object status codes */\n\n#define GRB_BATCH_STATUS_UNKNOWN 0\n#define GRB_BATCH_CREATED        1\n#define GRB_BATCH_SUBMITTED      2\n#define GRB_BATCH_ABORTED        3\n#define GRB_BATCH_FAILED         4\n#define GRB_BATCH_COMPLETED      5\n\n\n/* Async interface */\n\nint __stdcall\n  GRBsync(GRBmodel *model);\n\nint __stdcall\n  GRBpingserver(const char *server, const char *password);\n\n\n/* pre-fetching attributes from Compute Server */\n\nint __stdcall\n  GRBprefetchattr(GRBmodel *model, const char *attrname);\n/* Tuning */\n\nint __stdcall\n  GRBtunemodel(GRBmodel *model);\nint __stdcall\n  GRBtunemodels(GRBenv *env, int nummodels, GRBmodel **models);\nint __stdcall\n  GRBgettuneresult(GRBmodel *model, int result);\nint __stdcall\n  GRBgettunelog(GRBmodel *model, int result, char **logP);\nint __stdcall\n  GRBwritetunelog(GRBmodel *model, int result, const char *filename);\nint __stdcall\n  GRBwritetuneparamsets(GRBmodel *model, const char *filename);\nvoid __stdcall\n  GRBtuneparamsPrint(void);\n \n#ifdef __cplusplus\n}\n#endif\n \n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/HConfig.h",
    "content": "#ifndef HCONFIG_H_\n#define HCONFIG_H_\n\n#define FAST_BUILD\n/* #undef ZLIB_FOUND */\n#define CUPDLP_CPU\n/* #undef CUPDLP_GPU */\n/* #undef HIPO */\n/* #undef CMAKE_BUILD_TYPE */\n/* #undef HIGHSINT64 */\n/* #undef HIGHS_NO_DEFAULT_THREADS */\n#define HIGHS_HAVE_MM_PAUSE\n/* #undef HIGHS_HAVE_BUILTIN_CLZ */\n#define HIGHS_HAVE_BITSCAN_REVERSE\n/* #undef BLAS_LIBRARIES */\n\n#define HIGHS_GITHASH \"755a8e027\"\n#define HIGHS_VERSION_MAJOR 1\n#define HIGHS_VERSION_MINOR 12\n#define HIGHS_VERSION_PATCH 0\n\n#endif /* HCONFIG_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/Highs.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file Highs.h\n * @brief The HiGHS class\n */\n#ifndef HIGHS_H_\n#define HIGHS_H_\n\n#include <sstream>\n\n#include \"lp_data/HighsCallback.h\"\n#include \"lp_data/HighsIis.h\"\n#include \"lp_data/HighsLpUtils.h\"\n#include \"lp_data/HighsRanging.h\"\n#include \"lp_data/HighsSolutionDebug.h\"\n#include \"model/HighsModel.h\"\n#include \"presolve/ICrash.h\"\n#include \"presolve/PresolveComponent.h\"\n\n/**\n * @brief Return the version\n */\nconst char* highsVersion();\n\n/**\n * @brief Return detailed version information, githash and compilation\n * date\n */\nHighsInt highsVersionMajor();\nHighsInt highsVersionMinor();\nHighsInt highsVersionPatch();\nconst char* highsGithash();\n\n/**\n * @brief Class to set parameters and run HiGHS\n */\nclass Highs {\n public:\n  Highs();\n  virtual ~Highs() { this->closeLogFile(); }\n\n  /**\n   * @brief Return the version as a string\n   */\n  std::string version() const { return highsVersion(); }\n\n  /**\n   * @brief Return major version\n   */\n  HighsInt versionMajor() const { return highsVersionMajor(); }\n\n  /**\n   * @brief Return minor version\n   */\n  HighsInt versionMinor() const { return highsVersionMinor(); }\n\n  /**\n   * @brief Return patch version\n   */\n  HighsInt versionPatch() const { return highsVersionPatch(); }\n\n  /**\n   * @brief Return githash\n   */\n  std::string githash() const { return highsGithash(); }\n\n  /**\n   * @brief Reset the options and then call clearModel()\n   */\n  HighsStatus clear();\n\n  /**\n   * @brief Clear the incumbent model and then call clearSolver()\n   */\n  HighsStatus clearModel();\n\n  /**\n   * @brief Clear all solution data associated with the model\n   */\n  HighsStatus clearSolver();\n\n  /**\n   * @brief Clear all dual data associated with the model\n   */\n  HighsStatus clearSolverDualData();\n\n  /**\n   * Methods for model input\n   */\n\n  /**\n   * Every model loading module eventually uses\n   * passModel(HighsModel model) to communicate the model to HiGHS.\n   */\n\n  /**\n   * @brief Pass a HighsModel instance to Highs\n   */\n  HighsStatus passModel(HighsModel model);\n\n  /**\n   * @brief Pass a HighsLp instance to Highs\n   */\n  HighsStatus passModel(HighsLp lp);\n\n  /**\n   * @brief Pass a QP (possibly with integrality data) via pointers to vectors\n   * of data\n   */\n  HighsStatus passModel(\n      const HighsInt num_col, const HighsInt num_row, const HighsInt num_nz,\n      const HighsInt q_num_nz, const HighsInt a_format, const HighsInt q_format,\n      const HighsInt sense, const double offset, const double* col_cost,\n      const double* col_lower, const double* col_upper, const double* row_lower,\n      const double* row_upper, const HighsInt* a_start, const HighsInt* a_index,\n      const double* a_value, const HighsInt* q_start, const HighsInt* q_index,\n      const double* q_value, const HighsInt* integrality = nullptr);\n\n  /**\n   * @brief Pass an LP (possibly with integrality data) via pointers to vectors\n   * of data\n   */\n  HighsStatus passModel(const HighsInt num_col, const HighsInt num_row,\n                        const HighsInt num_nz, const HighsInt a_format,\n                        const HighsInt sense, const double offset,\n                        const double* col_cost, const double* col_lower,\n                        const double* col_upper, const double* row_lower,\n                        const double* row_upper, const HighsInt* a_start,\n                        const HighsInt* a_index, const double* a_value,\n                        const HighsInt* integrality = nullptr);\n\n  /**\n   * @brief Pass a HighsHessian instance for the incumbent model\n   */\n  HighsStatus passHessian(HighsHessian hessian_);\n\n  /**\n   * @brief Pass the Hessian for the incumbent model via pointers to vectors of\n   * data\n   */\n  HighsStatus passHessian(const HighsInt dim, const HighsInt num_nz,\n                          const HighsInt format, const HighsInt* start,\n                          const HighsInt* index, const double* value);\n  /**\n   * @brief Pass multiple linear objectives for the incumbent model\n   */\n  HighsStatus passLinearObjectives(\n      const HighsInt num_linear_objective,\n      const HighsLinearObjective* linear_objective);\n\n  /**\n   * @brief Add a linear objective for the incumbent model\n   */\n  HighsStatus addLinearObjective(const HighsLinearObjective& linear_objective,\n                                 const HighsInt iObj = -1);\n\n  /**\n   * @brief Get number of linear objectives from the incumbent model\n   */\n  HighsInt getNumLinearObjectives() const {\n    return multi_linear_objective_.size();\n  }\n\n  /**\n   * @brief Get a linear objective from the incumbent model\n   */\n  const HighsLinearObjective& getLinearObjective(const HighsInt idx) const {\n    assert(idx >= 0 && idx < int(multi_linear_objective_.size()));\n    return multi_linear_objective_[idx];\n  }\n\n  /**\n   * @brief Clear the multiple linear objective data\n   */\n  HighsStatus clearLinearObjectives();\n\n  /**\n   * @brief Pass a column name to the incumbent model\n   */\n  HighsStatus passColName(const HighsInt col, const std::string& name);\n\n  /**\n   * @brief Pass a row name to the incumbent model\n   */\n  HighsStatus passRowName(const HighsInt row, const std::string& name);\n\n  /**\n   * @brief Pass a model name to the incumbent model\n   */\n  HighsStatus passModelName(const std::string& name);\n\n  /**\n   * @brief Read in a model\n   */\n  HighsStatus readModel(const std::string& filename);\n\n  /**\n   * @brief Read in a basis\n   */\n  HighsStatus readBasis(const std::string& filename);\n\n  /**\n   * @brief Presolve the incumbent model, allowing the presolved model\n   * to be extracted. Subsequent solution of the incumbent model will\n   * only use presolve if there is no valid basis\n   */\n  HighsStatus presolve();\n\n  /**\n   * @brief Run the solver, accounting for any multiple objective\n   */\n  HighsStatus run();\n\n  /**\n   * @brief Postsolve the incumbent model using a solution\n   */\n  HighsStatus postsolve(const HighsSolution& solution);\n\n  /**\n   * @brief Postsolve the incumbent model using a solution and basis\n   */\n  HighsStatus postsolve(const HighsSolution& solution, const HighsBasis& basis);\n\n  /**\n   * @brief Write the current solution to a file in a given style\n   */\n  HighsStatus writeSolution(const std::string& filename,\n                            const HighsInt style = kSolutionStyleRaw);\n\n  /**\n   * @brief Read a HiGHS solution file in a given style\n   */\n  HighsStatus readSolution(const std::string& filename,\n                           const HighsInt style = kSolutionStyleRaw);\n\n  /**\n   * @brief Assess the validity, integrality and feasibility of the\n   * current primal solution. Of value after calling\n   * Highs::readSolution\n   */\n  HighsStatus assessPrimalSolution(bool& valid, bool& integral,\n                                   bool& feasible) const;\n\n  /**\n   * Methods for HiGHS option input/output\n   */\n\n  /**\n   * @brief Set an option to the bool/HighsInt/double/string value if it's\n   * legal and, for bool/HighsInt/double, only if it's of the correct type\n   */\n\n  HighsStatus setOptionValue(const std::string& option, const bool value);\n\n  HighsStatus setOptionValue(const std::string& option, const HighsInt value);\n\n#ifdef HIGHSINT64\n  HighsStatus setOptionValue(const std::string& option, const int value) {\n    return setOptionValue(option, HighsInt{value});\n  }\n#endif\n\n  HighsStatus setOptionValue(const std::string& option, const double value);\n\n  HighsStatus setOptionValue(const std::string& option,\n                             const std::string& value);\n\n  HighsStatus setOptionValue(const std::string& option, const char* value);\n\n  /**\n   * @brief Read option values from a file\n   */\n  HighsStatus readOptions(const std::string& filename);\n\n  /**\n   * @brief Pass a HighsOptions instance to Highs\n   */\n  HighsStatus passOptions(const HighsOptions& options);\n\n  /**\n   * @brief Get a const reference to the internal option values\n   */\n  const HighsOptions& getOptions() const { return options_; }\n\n  /**\n   * @brief Gets an option value as bool/HighsInt/double/string and, for\n   * bool/int/double, only if it's of the correct type.\n   *\n   * NB Deprecate in v2.0, in order to replace with more general\n   * get*OptionValues\n   */\n  HighsStatus getOptionValue(const std::string& option, bool& value) const {\n    return this->getBoolOptionValues(option, &value);\n  }\n\n  HighsStatus getOptionValue(const std::string& option, HighsInt& value) const {\n    return this->getIntOptionValues(option, &value);\n  }\n\n  HighsStatus getOptionValue(const std::string& option, double& value) const {\n    return this->getDoubleOptionValues(option, &value);\n  }\n\n  HighsStatus getOptionValue(const std::string& option,\n                             std::string& value) const {\n    return this->getStringOptionValues(option, &value);\n  }\n\n  /**\n   * @brief Get the type expected by an option\n   */\n  HighsStatus getOptionType(const std::string& option,\n                            HighsOptionType& type) const {\n    return this->getOptionType(option, &type);\n  }\n\n  /**\n   * @brief Reset the options to the default values\n   */\n  HighsStatus resetOptions();\n\n  /**\n   * @brief Write (deviations from default values of) the options to a\n   * file, using the standard format used to read options from a file.\n   * Possible to write only deviations from default values.\n   */\n  HighsStatus writeOptions(const std::string& filename,  //!< The filename\n                           const bool report_only_deviations = false);\n\n  /**\n   * @brief Returns the number of user-settable options\n   */\n  HighsInt getNumOptions() const {\n    return this->options_.num_user_settable_options_;\n  }\n\n  /**\n   * @brief Get the number of user-settable options\n   */\n  HighsStatus getOptionName(const HighsInt index, std::string* name) const;\n\n  /**\n   * @brief Get the type of an option\n   */\n  HighsStatus getOptionType(const std::string& option,\n                            HighsOptionType* type) const;\n\n  /**\n   * @brief Get the current and default values of a bool option\n   */\n  HighsStatus getBoolOptionValues(const std::string& option,\n                                  bool* current_value = nullptr,\n                                  bool* default_value = nullptr) const;\n\n  /**\n   * @brief Get the current, min, max and default values of an int option\n   */\n  HighsStatus getIntOptionValues(const std::string& option,\n                                 HighsInt* current_value = nullptr,\n                                 HighsInt* min_value = nullptr,\n                                 HighsInt* max_value = nullptr,\n                                 HighsInt* default_value = nullptr) const;\n\n  /**\n   * @brief Get the current, min, max and default values of a double option\n   */\n  HighsStatus getDoubleOptionValues(const std::string& option,\n                                    double* current_value = nullptr,\n                                    double* min_value = nullptr,\n                                    double* max_value = nullptr,\n                                    double* default_value = nullptr) const;\n\n  /**\n   * @brief Get the current and default values of a string option\n   */\n  HighsStatus getStringOptionValues(const std::string& option,\n                                    std::string* current_value = nullptr,\n                                    std::string* default_value = nullptr) const;\n\n  /**\n   * @brief Get a const reference to the internal info values\n   * type.\n   */\n  const HighsInfo& getInfo() const { return info_; }\n\n  /**\n   * @brief Get an info value as HighsInt/int64_t/double, and only if\n   * it's of the correct type.\n   */\n\n  HighsStatus getInfoValue(const std::string& info, HighsInt& value) const;\n\n#ifndef HIGHSINT64\n  HighsStatus getInfoValue(const std::string& info, int64_t& value) const;\n#endif\n\n  HighsStatus getInfoValue(const std::string& info, double& value) const;\n\n  HighsStatus getInfoType(const std::string& info, HighsInfoType& type) const;\n\n  /**\n   * @brief Write info values to a file, with the extension \".html\"\n   * producing HTML, otherwise using the standard format used to read\n   * options from a file.\n   */\n  HighsStatus writeInfo(const std::string& filename = \"\") const;\n\n  /**\n   * @brief Get the value of infinity used by HiGHS\n   */\n  double getInfinity() const { return kHighsInf; }\n\n  /**\n   * @brief Get the size of HighsInt\n   */\n  HighsInt getSizeofHighsInt() const {\n    return sizeof(options_.num_user_settable_options_);\n  }\n\n  /**\n   * @brief Get the run time of HiGHS\n   */\n  double getRunTime() const { return timer_.read(); }\n\n  /**\n   * Methods for model output\n   */\n\n  /**\n   * @brief Identify the standard form of the HighsLp instance in\n   * HiGHS\n   */\n  HighsStatus getStandardFormLp(HighsInt& num_col, HighsInt& num_row,\n                                HighsInt& num_nz, double& offset,\n                                double* cost = nullptr, double* rhs = nullptr,\n                                HighsInt* start = nullptr,\n                                HighsInt* index = nullptr,\n                                double* value = nullptr);\n\n  /**\n   * @brief Return a const reference to the internal presolved HighsLp\n   * instance\n   */\n  const HighsLp& getPresolvedLp() const { return presolved_model_.lp_; }\n\n  /**\n   * @brief Return a const reference to the internal presolved\n   * HighsModel instance\n   */\n  const HighsModel& getPresolvedModel() const { return presolved_model_; }\n\n  /**\n   * @brief Return a const reference to the logging data for presolve\n   */\n  const HighsPresolveLog& getPresolveLog() const { return presolve_log_; }\n\n  /**\n   * @brief Return a const pointer to the original column indices for\n   * the presolved model\n   */\n  const HighsInt* getPresolveOrigColsIndex() const {\n    return presolve_.data_.postSolveStack.getOrigColsIndex();\n  }\n\n  /**\n   * @brief Return a const pointer to the original row indices for the\n   * presolved model\n   */\n  const HighsInt* getPresolveOrigRowsIndex() const {\n    return presolve_.data_.postSolveStack.getOrigRowsIndex();\n  }\n\n  /**\n   * @brief Return an LP associated with a MIP and its solution, with\n   * each integer variable fixed to the value it takes in the MIP\n   * solution. If no solution is available, an error is returned.\n   */\n  HighsStatus getFixedLp(HighsLp& lp) const;\n\n  /**\n   * @brief Return a const reference to the incumbent LP\n   */\n  const HighsLp& getLp() const { return model_.lp_; }\n\n  /**\n   * @brief Return a const reference to the incumbent model\n   */\n  const HighsModel& getModel() const { return model_; }\n\n  /**\n   * @brief Return a const reference to the internal HighsSolution\n   * instance\n   */\n  const HighsSolution& getSolution() const { return solution_; }\n\n  /**\n   * @brief Return a const reference to the internal IIS LP instance\n   */\n  const HighsLp& getIisLp() const { return iis_.model_.lp_; }\n\n  /**\n   * @brief Zero all clocks in the internal HighsTimer instance\n   */\n  void zeroAllClocks() { timer_.zeroAllClocks(); };\n\n  /**\n   * @brief Return a const reference to the internal HighsSolution\n   * instance\n   */\n  const std::vector<HighsObjectiveSolution>& getSavedMipSolutions() const {\n    return saved_objective_and_solution_;\n  }\n\n  /**\n   * @brief Return a const reference to the internal ICrash info instance\n   */\n  const ICrashInfo& getICrashInfo() const { return icrash_info_; };\n\n  /**\n   * @brief Return a const reference to the internal HighsBasis instance\n   */\n  const HighsBasis& getBasis() const { return basis_; }\n\n  /**\n   * @brief Return the status for the incumbent model.\n   */\n  const HighsModelStatus& getModelStatus() const { return model_status_; }\n\n  /**\n   * @brief Returns the current model's presolve status\n   */\n  const HighsPresolveStatus& getModelPresolveStatus() const {\n    return model_presolve_status_;\n  }\n\n  /**\n   * @brief Indicate whether a dual unbounded ray exists, and (at the\n   * expense of solving an LP) gets it if it does not and\n   * dual_ray_value is not nullptr\n   */\n  HighsStatus getDualRay(bool& has_dual_ray, double* dual_ray_value = nullptr);\n\n  /**\n   * @brief Indicate whether a dual unbounded ray exists, and gets it\n   * if it does\n   */\n  HighsStatus getDualRaySparse(bool& has_dual_ray, HVector& row_ep_buffer);\n\n  /**\n   * @brief Indicate whether a dual unboundedness direction exists,\n   * and (at the expense of solving an LP) gets it if\n   * dual_unboundedness_direction is not nullptr\n   */\n  HighsStatus getDualUnboundednessDirection(\n      bool& has_dual_unboundedness_direction,\n      double* dual_unboundedness_direction_value = nullptr);\n\n  /**\n   * @brief Indicate whether a primal unbounded ray exists, and (at\n   * the expense of solving an LP) gets it if primal_ray is not\n   * nullptr\n   */\n  HighsStatus getPrimalRay(bool& has_primal_ray,\n                           double* primal_ray_value = nullptr);\n\n  /**\n   * @brief Get the ranging information for the current LP\n   */\n  HighsStatus getRanging(HighsRanging& ranging);\n\n  /**\n   * @brief Solve the feasibility relaxation problem\n   */\n  HighsStatus feasibilityRelaxation(const double global_lower_penalty,\n                                    const double global_upper_penalty,\n                                    const double global_rhs_penalty,\n                                    const double* local_lower_penalty = nullptr,\n                                    const double* local_upper_penalty = nullptr,\n                                    const double* local_rhs_penalty = nullptr);\n\n  /**\n   * @brief Get the ill-conditioning information for the current basis\n   */\n  HighsStatus getIllConditioning(HighsIllConditioning& ill_conditioning,\n                                 const bool constraint,\n                                 const HighsInt method = 0,\n                                 const double ill_conditioning_bound = 1e-4);\n\n  /**\n   * @brief Get the suggested objective and bound scaling for the incumbent\n   * model\n   */\n  HighsStatus getObjectiveBoundScaling(HighsInt& suggested_objective_scale,\n                                       HighsInt& suggested_bound_scale);\n\n  /**\n   * @brief Get (any) irreducible infeasible subsystem (IIS)\n   * information for the incumbent model\n   */\n  HighsStatus getIis(HighsIis& iis);\n\n  /**\n   * @brief Get the current model objective function value\n   */\n  double getObjectiveValue() const { return info_.objective_function_value; }\n\n  /**\n   * @brief Try to get the current dual objective function value\n   */\n  HighsStatus getDualObjectiveValue(double& dual_objective_value) const;\n\n  /**\n   * Methods for operations with the invertible representation of the\n   * current basis matrix\n   */\n\n  /**\n   * @brief Returns true if an invertible representation of the\n   * current basis matrix is available\n   */\n  bool hasInvert() const;\n\n  /**\n   * @brief Gets the basic variables in the order corresponding to\n   * calls to getBasisInverseRow, getBasisInverseCol, getBasisSolve,\n   * getBasisTransposeSolve, getReducedRow and\n   * getReducedColumn. Non-negative entries are indices of columns,\n   * and negative entries are -(row_index+1).\n   */\n  HighsStatus getBasicVariables(HighsInt* basic_variables);\n\n  /**\n   * @brief Form a row of \\f$B^{-1}\\f$ for basis matrix \\f$B\\f$,\n   * returning the indices of the nonzeros unless row_num_nz is\n   * nullptr\n   */\n  HighsStatus getBasisInverseRow(const HighsInt row, double* row_vector,\n                                 HighsInt* row_num_nz = nullptr,\n                                 HighsInt* row_indices = nullptr);\n\n  /**\n   * @brief Form a column of \\f$B^{-1}\\f$ for basis matrix \\f$B\\f$,\n   * returning the indices of the nonzeros unless col_num_nz is\n   * nullptr\n   */\n  HighsStatus getBasisInverseCol(const HighsInt col, double* col_vector,\n                                 HighsInt* col_num_nz = nullptr,\n                                 HighsInt* col_indices = nullptr);\n\n  /**\n   * @brief Form \\f$\\mathbf{x}=B^{-1}\\mathbf{b}\\f$ for a given vector\n   * \\f$\\mathbf{b}\\f$, returning the indices of the nonzeros unless\n   * solution_num_nz is nullptr\n   */\n  HighsStatus getBasisSolve(const double* rhs, double* solution_vector,\n                            HighsInt* solution_num_nz = nullptr,\n                            HighsInt* solution_indices = nullptr);\n\n  /**\n   * @brief Form \\f$\\mathbf{x}=B^{-T}\\mathbf{b}\\f$ for a given vector\n   * \\f$\\mathbf{b}\\f$, returning the indices of the nonzeros unless\n   * solution_num_nz is nullptr\n   */\n  HighsStatus getBasisTransposeSolve(const double* rhs, double* solution_vector,\n                                     HighsInt* solution_num_nz = nullptr,\n                                     HighsInt* solution_indices = nullptr);\n\n  /**\n   * @brief Form a row of \\f$B^{-1}A\\f$, returning the indices of the\n   * nonzeros unless row_num_nz is nullptr, computing the row using\n   * pass_basis_inverse_row_vector unless it is nullptr\n   */\n  HighsStatus getReducedRow(\n      const HighsInt row, double* row_vector, HighsInt* row_num_nz = nullptr,\n      HighsInt* row_indices = nullptr,\n      const double* pass_basis_inverse_row_vector = nullptr);\n\n  /**\n   * @brief Form a column of \\f$B^{-1}A\\f$, returning the indices of\n   * the nonzeros unless col_num_nz is nullptr\n   */\n  HighsStatus getReducedColumn(const HighsInt col, double* col_vector,\n                               HighsInt* col_num_nz = nullptr,\n                               HighsInt* col_indices = nullptr);\n\n  /**\n   * @brief Get the condition number of the current basis matrix,\n   * possibly computing it exactly and reporting the error in the\n   * approximate condition number\n   */\n  HighsStatus getKappa(double& kappa, const bool exact = false,\n                       const bool report = false) const;\n\n  /**\n   * @brief Get the number of columns in the incumbent model\n   */\n  HighsInt getNumCol() const { return model_.lp_.num_col_; }\n\n  /**\n   * @brief Get the number of rows in the incumbent model\n   */\n  HighsInt getNumRow() const { return model_.lp_.num_row_; }\n\n  /**\n   * @brief Get the number of (constraint matrix) nonzeros in the incumbent\n   * model\n   */\n  HighsInt getNumNz() const { return model_.lp_.a_matrix_.numNz(); }\n\n  /**\n   * @brief Get the number of Hessian matrix nonzeros in the incumbent model\n   */\n  HighsInt getHessianNumNz() const { return model_.hessian_.numNz(); }\n\n  /**\n   * @brief Get the objective sense of the incumbent model\n   */\n  HighsStatus getObjectiveSense(ObjSense& sense) const;\n\n  /**\n   * @brief Get the objective offset of the incumbent model\n   */\n  HighsStatus getObjectiveOffset(double& offset) const;\n\n  /**\n   * @brief Get multiple columns from the model given by an interval [from_col,\n   * to_col]\n   */\n  HighsStatus getCols(\n      const HighsInt\n          from_col,  //!< The index of the first column to get from the model\n      const HighsInt\n          to_col,  //!< The index of the last column to get from the model\n      HighsInt& num_col,  //!< Number of columns got from the model\n      double* cost,       //!< Array of size num_col with costs\n      double* lower,      //!< Array of size num_col with lower bounds\n      double* upper,      //!< Array of size num_col with upper bounds\n      HighsInt& num_nz,   //!< Number of nonzeros got from the model\n      HighsInt*\n          start,  //!< Array of size num_col with start indices of the columns\n      HighsInt*\n          index,     //!< Array of size num_nz with row indices for the columns\n      double* value  //!< Array of size num_nz with row values for the columns\n  ) const;\n\n  /**\n   * @brief Get multiple columns from the model given by a set\n   */\n  HighsStatus getCols(\n      const HighsInt num_set_entries,  //!< The number of indices in the set\n      const HighsInt* set,  //!< Array of size num_set_entries with indices of\n                            //!< columns to get\n      HighsInt& num_col,    //!< Number of columns got from the model\n      double* cost,         //!< Array of size num_col with costs\n      double* lower,        //!< Array of size num_col with lower bounds\n      double* upper,        //!< Array of size num_col with upper bounds\n      HighsInt& num_nz,     //!< Number of nonzeros got from the model\n      HighsInt*\n          start,  //!< Array of size num_col with start indices of the columns\n      HighsInt*\n          index,     //!< Array of size num_nz with row indices for the columns\n      double* value  //!< Array of size num_nz with row values for the columns\n  ) const;\n\n  /**\n   * @brief Get multiple columns from the model given by a mask\n   */\n  HighsStatus getCols(\n      const HighsInt* mask,  //!< Full length array with 1 => get; 0 => not\n      HighsInt& num_col,     //!< Number of columns got from the model\n      double* cost,          //!< Array of size num_col with cost\n      double* lower,         //!< Array of size num_col with lower bounds\n      double* upper,         //!< Array of size num_col with upper bounds\n      HighsInt& num_nz,      //!< Number of nonzeros got from the model\n      HighsInt*\n          start,  //!<  Array of size num_col with start indices of the columns\n      HighsInt*\n          index,     //!<  Array of size num_nz with row indices for the columns\n      double* value  //!<  Array of size num_nz with row values for the columns\n  ) const;\n\n  /**\n   * @brief Get a column name from the incumbent model\n   */\n  HighsStatus getColName(const HighsInt col, std::string& name) const;\n\n  /**\n   * @brief Get column index corresponding to name\n   */\n  HighsStatus getColByName(const std::string& name, HighsInt& col);\n\n  /**\n   * @brief Get a column integrality from the incumbent model\n   */\n  HighsStatus getColIntegrality(const HighsInt col,\n                                HighsVarType& integrality) const;\n\n  /**\n   * @brief Get multiple rows from the model given by an interval [from_row,\n   * to_row]\n   */\n  HighsStatus getRows(\n      const HighsInt\n          from_row,  //!< The index of the first row to get from the model\n      const HighsInt\n          to_row,         //!< The index of the last row to get from the model\n      HighsInt& num_row,  //!< Number of rows got from the model\n      double* lower,      //!< Array of size num_row with lower bounds\n      double* upper,      //!< Array of size num_row with upper bounds\n      HighsInt& num_nz,   //!< Number of nonzeros got from the model\n      HighsInt*\n          start,  //!< Array of size num_row with start indices of the rows\n      HighsInt*\n          index,     //!< Array of size num_nz with column indices for the rows\n      double* value  //!< Array of size num_nz with column values for the rows\n  ) const;\n\n  /**\n   * @brief Get multiple rows from the model given by a set\n   */\n  HighsStatus getRows(\n      const HighsInt num_set_entries,  //!< The number of indices in the set\n      const HighsInt*\n          set,  //!< Array of size num_set_entries with indices of rows to get\n      HighsInt& num_row,  //!< Number of rows got from the model\n      double* lower,      //!< Array of size num_row with lower bounds\n      double* upper,      //!< Array of size num_row with upper bounds\n      HighsInt& num_nz,   //!< Number of nonzeros got from the model\n      HighsInt*\n          start,  //!< Array of size num_row with start indices of the rows\n      HighsInt*\n          index,     //!< Array of size num_nz with column indices for the rows\n      double* value  //!< Array of size num_nz with column values for the rows\n  ) const;\n\n  /**\n   * @brief Get multiple rows from the model given by a mask\n   */\n  HighsStatus getRows(\n      const HighsInt* mask,  //!< Full length array with 1 => get; 0 => not\n      HighsInt& num_row,     //!< Number of rows got from the model\n      double* lower,         //!< Array of size num_row with lower bounds\n      double* upper,         //!< Array of size num_row with upper bounds\n      HighsInt& num_nz,      //!< Number of nonzeros got from the model\n      HighsInt*\n          start,  //!< Array of size num_row with start indices of the rows\n      HighsInt*\n          index,     //!< Array of size num_nz with column indices for the rows\n      double* value  //!< Array of size num_nz with column values for the rows\n  ) const;\n\n  /**\n   * @brief Get a row name from the incumbent model\n   */\n  HighsStatus getRowName(const HighsInt row, std::string& name) const;\n\n  /**\n   * @brief Get row index corresponding to name\n   */\n  HighsStatus getRowByName(const std::string& name, HighsInt& row);\n\n  /**\n   * @brief Get a matrix coefficient\n   */\n  HighsStatus getCoeff(const HighsInt row, const HighsInt col,\n                       double& value) const;\n\n  /**\n   * @brief Write out the incumbent model to a file\n   */\n  HighsStatus writeModel(const std::string& filename = \"\");\n\n  /**\n   * @brief Write out the incumbent presolved model to a file\n   */\n  HighsStatus writePresolvedModel(const std::string& filename = \"\");\n\n  /**\n   * @brief Write out the internal IIS LP instance to a file\n   */\n  HighsStatus writeIisModel(const std::string& filename = \"\");\n\n  /**\n   * @brief Write out the given model to a file\n   */\n  HighsStatus writeLocalModel(HighsModel& model,\n                              const std::string& filename = \"\");\n\n  /**\n   * @brief Write out the internal HighsBasis instance to a file\n   */\n  HighsStatus writeBasis(const std::string& filename = \"\");\n\n  /**\n   * Methods for incumbent model modification\n   */\n\n  /**\n   * @brief Change the objective sense of the incumbent model\n   */\n  HighsStatus changeObjectiveSense(const ObjSense sense);\n\n  /**\n   * @brief Change the objective offset of the incumbent model\n   */\n  HighsStatus changeObjectiveOffset(const double offset);\n\n  /**\n   * @brief Change the integrality of a column\n   */\n  HighsStatus changeColIntegrality(const HighsInt col,\n                                   const HighsVarType integrality);\n\n  /**\n   * @brief Change the integrality of multiple columns given by an\n   * interval [from_col, to_col]\n   */\n  HighsStatus changeColsIntegrality(const HighsInt from_col,\n                                    const HighsInt to_col,\n                                    const HighsVarType* integrality);\n\n  /**\n   * @brief Change the integrality of multiple columns given by a set of indices\n   */\n  HighsStatus changeColsIntegrality(const HighsInt num_set_entries,\n                                    const HighsInt* set,\n                                    const HighsVarType* integrality);\n\n  /**\n   * @brief Change the integrality of multiple columns given by a mask\n   * (full length array with 1 => change; 0 => not)\n   */\n  HighsStatus changeColsIntegrality(const HighsInt* mask,\n                                    const HighsVarType* integrality);\n\n  /**\n   * @brief Clear the integrality of all columns\n   */\n  HighsStatus clearIntegrality() {\n    this->model_.lp_.integrality_.clear();\n    return HighsStatus::kOk;\n  }\n\n  /**\n   * @brief Change the cost of a column\n   */\n  HighsStatus changeColCost(const HighsInt col, const double cost);\n\n  /**\n   * @brief Change the cost of multiple columns given by an interval [from_col,\n   * to_col]\n   */\n  HighsStatus changeColsCost(const HighsInt from_col, const HighsInt to_col,\n                             const double* cost);\n\n  /**\n   * @brief Change the cost of multiple columns given by a set of indices\n   */\n  HighsStatus changeColsCost(const HighsInt num_set_entries,\n                             const HighsInt* set, const double* cost);\n\n  /**\n   * @brief Change the cost of multiple columns given by a mask\n   * (full length array with 1 => change; 0 => not)\n   */\n  HighsStatus changeColsCost(const HighsInt* mask, const double* cost);\n\n  /**\n   * @brief Change the bounds of a column\n   */\n  HighsStatus changeColBounds(const HighsInt col, const double lower,\n                              const double upper);\n\n  /**\n   * @brief Change the bounds of multiple columns given by an interval\n   * [from_col, to_col]\n   */\n  HighsStatus changeColsBounds(const HighsInt from_col, const HighsInt to_col,\n                               const double* lower, const double* upper);\n\n  /**\n   * @brief Change the bounds of multiple columns given by a set of indices\n   */\n  HighsStatus changeColsBounds(const HighsInt num_set_entries,\n                               const HighsInt* set, const double* lower,\n                               const double* upper);\n\n  /**\n   * @brief Change the cost of multiple columns given by a mask (full\n   * length array with 1 => change; 0 => not)\n   */\n  HighsStatus changeColsBounds(const HighsInt* mask, const double* lower,\n                               const double* upper);\n\n  /**\n   * @brief Change the bounds of a row\n   */\n  HighsStatus changeRowBounds(const HighsInt row, const double lower,\n                              const double upper);\n\n  /**\n   * @brief Change the bounds of multiple rows given by an interval [from_row,\n   * to_row]\n   */\n  HighsStatus changeRowsBounds(const HighsInt from_row, const HighsInt to_row,\n                               const double* lower, const double* upper);\n\n  /**\n   * @brief Change the bounds of multiple rows given by a set of indices\n   */\n  HighsStatus changeRowsBounds(const HighsInt num_set_entries,\n                               const HighsInt* set, const double* lower,\n                               const double* upper);\n\n  /**\n   * @brief Change the cost of multiple rows given by a mask (full\n   * length array with 1 => change; 0 => not)\n   */\n  HighsStatus changeRowsBounds(const HighsInt* mask, const double* lower,\n                               const double* upper);\n\n  /**\n   * @brief Change a matrix coefficient\n   */\n  HighsStatus changeCoeff(const HighsInt row, const HighsInt col,\n                          const double value);\n  /**\n   * @brief Sets the constraint matrix format of the incumbent model\n   */\n  HighsStatus setMatrixFormat(const MatrixFormat desired_format) {\n    this->model_.lp_.setFormat(desired_format);\n    return HighsStatus::kOk;\n  }\n\n  /**\n   * @brief Adds a variable to the incumbent model, without the matrix\n   * coefficients if num_new_nz = 0, in which case indices and values\n   * arrays can be nullptr\n   */\n  HighsStatus addCol(const double cost, const double lower, const double upper,\n                     const HighsInt num_new_nz, const HighsInt* indices,\n                     const double* values);\n\n  /**\n   * @brief Adds multiple columns to the incumbent model, without the matrix\n   * coefficients if num_new_nz = 0, in which case column-wise starts,\n   * indices and values arrays can be nullptr\n   */\n  HighsStatus addCols(const HighsInt num_new_col, const double* cost,\n                      const double* lower, const double* upper,\n                      const HighsInt num_new_nz, const HighsInt* starts,\n                      const HighsInt* indices, const double* values);\n\n  /**\n   * @brief Adds a variable to the incumbent model, without the cost or matrix\n   * coefficients\n   */\n  HighsStatus addVar(const double lower = 0, const double upper = kHighsInf) {\n    return this->addVars(1, &lower, &upper);\n  }\n\n  /**\n   * @brief Adds multiple variables to the incumbent model, without the costs or\n   * matrix coefficients\n   */\n  HighsStatus addVars(const HighsInt num_new_var, const double* lower,\n                      const double* upper);\n\n  /**\n   * @brief Add a row to the incumbent model, without the matrix coefficients if\n   * num_new_nz = 0, in which case indices and values arrays can be\n   * nullptr\n   */\n  HighsStatus addRow(const double lower, const double upper,\n                     const HighsInt num_new_nz, const HighsInt* indices,\n                     const double* values);\n\n  /**\n   * @brief Adds multiple rows to the incumbent model, without the matrix\n   * coefficients if num_new_nz = 0, in which case row-wise starts,\n   * indices and values arrays can be nullptr\n   */\n  HighsStatus addRows(const HighsInt num_new_row, const double* lower,\n                      const double* upper, const HighsInt num_new_nz,\n                      const HighsInt* starts, const HighsInt* indices,\n                      const double* values);\n\n  HighsStatus ensureColwise() {\n    this->model_.lp_.ensureColwise();\n    return HighsStatus::kOk;\n  }\n\n  HighsStatus ensureRowwise() {\n    this->model_.lp_.ensureRowwise();\n    return HighsStatus::kOk;\n  }\n\n  /**\n   * @brief Delete multiple columns from the incumbent model given by an\n   * interval [from_col, to_col]\n   */\n  HighsStatus deleteCols(const HighsInt from_col, const HighsInt to_col);\n\n  /**\n   * @brief Delete multiple columns from the incumbent model given by a set\n   */\n  HighsStatus deleteCols(const HighsInt num_set_entries, const HighsInt* set);\n\n  /**\n   * @brief Delete multiple columns from the incumbent model given by\n   * a mask (full length array with 1 => delete; 0 => keep). New index\n   * of any column kept is returned in place of the value 0.  For\n   * deleted columns, a value of -1 is returned.\n   */\n  HighsStatus deleteCols(HighsInt* mask);\n\n  /**\n   * @brief Delete multiple variables from the incumbent model given by an\n   * interval [from_var, to_var]\n   */\n  HighsStatus deleteVars(const HighsInt from_var, const HighsInt to_var) {\n    return deleteCols(from_var, to_var);\n  }\n\n  /**\n   * @brief Delete multiple variables from the incumbent model given by a set\n   */\n  HighsStatus deleteVars(const HighsInt num_set_entries, const HighsInt* set) {\n    return deleteCols(num_set_entries, set);\n  }\n\n  /**\n   * @brief Delete multiple variables from the incumbent model given\n   * by a mask (full length array with 1 => delete; 0 => keep). New\n   * index of any variable not deleted is returned in place of the\n   * value 0. For deleted variables, a value of -1 is returned.\n   */\n  HighsStatus deleteVars(HighsInt* mask) { return deleteCols(mask); }\n\n  /**\n   * @brief Delete multiple rows from the incumbent model given by an interval\n   * [from_row, to_row]\n   */\n  HighsStatus deleteRows(const HighsInt from_row, const HighsInt to_row);\n\n  /**\n   * @brief Delete multiple rows from the incumbent model given by a set\n   */\n  HighsStatus deleteRows(const HighsInt num_set_entries, const HighsInt* set);\n\n  /**\n   * @brief Delete multiple rows from the incumbent model given by a\n   * mask (full length array with 1 => delete; 0 => keep). New index\n   * of any row not deleted is returned in place of the value 0. For\n   * deleted rows, a value of -1 is returned.\n   */\n  HighsStatus deleteRows(HighsInt* mask);\n\n  /**\n   * @brief Scale a matrix column (and cost) by a constant - flipping bounds if\n   * the constant is negative\n   */\n  HighsStatus scaleCol(const HighsInt col, const double scale_value);\n\n  /**\n   * @brief Scale a matrix row by a constant - flipping bounds if the constant\n   * is negative\n   */\n  HighsStatus scaleRow(const HighsInt row, const double scale_value);\n\n  /**\n   * Other methods for specialist applications\n   */\n\n  /**\n   * Methods for setting basis_ and solution_\n   */\n\n  /**\n   * @brief Pass a HighsSolution instance to set the internal\n   * HighsSolution instance. If any of col_value, col_dual and\n   * row_dual is not set, the internal HighsSolution instance is not\n   * updated\n   */\n  HighsStatus setSolution(const HighsSolution& solution);\n\n  /**\n   * @brief Pass a sparse primal solution\n   */\n  HighsStatus setSolution(const HighsInt num_entries, const HighsInt* index,\n                          const double* value);\n\n  /**\n   * @brief Set the callback method to use for HiGHS\n   */\n  HighsStatus setCallback(HighsCallbackFunctionType user_callback,\n                          void* user_callback_data = nullptr);\n  HighsStatus setCallback(HighsCCallbackType c_callback,\n                          void* user_callback_data = nullptr);\n\n  /**\n   * @brief Start callback of given type\n   */\n  HighsStatus startCallback(const int callback_type);\n  HighsStatus startCallback(const HighsCallbackType callback_type);\n\n  /**\n   * @brief Stop callback of given type\n   */\n  HighsStatus stopCallback(const int callback_type);\n  HighsStatus stopCallback(const HighsCallbackType callback_type);\n\n  /**\n   * @brief Use the HighsBasis passed to set the internal HighsBasis\n   * instance. The origin string is used to identify the source of the\n   * HighsBasis instance.\n   */\n  HighsStatus setBasis(const HighsBasis& basis, const std::string& origin = \"\");\n\n  /**\n   * @brief Clear the internal HighsBasis instance\n   */\n  HighsStatus setBasis();\n\n  /**\n   * @brief Return a const reference to the internal sub-solver call and time\n   * instance\n   */\n  const HighsSubSolverCallTime& getSubSolverCallTime() const {\n    return sub_solver_call_time_;\n  }\n\n  /**\n   * @brief Report internal sub-solver call and time instance\n   */\n  void reportSubSolverCallTime() const;\n\n  /**\n   * @brief Initialise the internal sub-solver call and time instance\n   */\n  void initialiseSubSolverCallTime() {\n    this->sub_solver_call_time_.initialise();\n  }\n\n  /**\n   * @brief Run IPX crossover from a given HighsSolution instance and,\n   * if successful, set the internal HighsBasis and HighsSolution\n   * instance\n   */\n  HighsStatus crossover(const HighsSolution& user_solution);\n\n  /**\n   * @brief Open a named log file\n   */\n  HighsStatus openLogFile(const std::string& log_file = \"\");\n\n  /**\n   * @brief Close any open log file\n   */\n  HighsStatus closeLogFile();\n\n  /**\n   * @brief Interpret common qualifiers to string values\n   */\n  std::string presolveStatusToString(\n      const HighsPresolveStatus presolve_status) const;\n  std::string modelStatusToString(const HighsModelStatus model_status) const;\n  std::string solutionStatusToString(const HighsInt solution_status) const;\n  std::string basisStatusToString(const HighsBasisStatus basis_status) const;\n  std::string basisValidityToString(const HighsInt basis_validity) const;\n  std::string presolveRuleTypeToString(const HighsInt presolve_rule) const;\n\n  /**\n   * @brief Releases all resources held by the global scheduler instance. It is\n   * not thread-safe to call this function while calling run() or presolve() on\n   * any other Highs instance in any thread. After this function has terminated\n   * it is guaranteed that eventually all previously created scheduler threads\n   * will terminate and allocated memory will be released. After this function\n   * has returned the option value for the number of threads may be altered to a\n   * new value before the next call to run() or presolve(). If the given bool\n   * parameter has value true, then the function will not return until all\n   * memory is freed, which might be desirable when debugging heap memory but\n   * requires the calling thread to wait for all scheduler threads to wake-up\n   * which is usually not necessary.\n   */\n  static void resetGlobalScheduler(bool blocking = false);\n\n  // Start of advanced methods for HiGHS MIP solver\n\n  const HighsSimplexStats& getSimplexStats() const {\n    return ekk_instance_.getSimplexStats();\n  }\n  void reportSimplexStats(FILE* file) const {\n    ekk_instance_.reportSimplexStats(file);\n  }\n\n  /**\n   * @brief Put a copy of the current iterate - basis; invertible\n   * representation and dual edge weights - into storage within\n   * HSimplexNla. Advanced method: for HiGHS MIP solver\n   */\n  HighsStatus putIterate();\n\n  /**\n   * @brief Get a copy of the iterate stored within HSimplexNla and\n   * overwrite the current iterate. Advanced method: for HiGHS MIP\n   * solver\n   */\n  HighsStatus getIterate();\n\n  /**\n   * @brief Get the dual edge weights (steepest/devex) in the order of\n   * the basic indices or nullptr when they are not available.\n   */\n  const double* getDualEdgeWeights() const {\n    return ekk_instance_.status_.has_dual_steepest_edge_weights\n               ? ekk_instance_.dual_edge_weight_.data()\n               : nullptr;\n  }\n\n  /**\n   * @brief Gets the internal basic variable index array in the order\n   * corresponding to calls to getBasisInverseRow, getBasisInverseCol,\n   * getBasisSolve, getBasisTransposeSolve, getReducedRow and getReducedColumn.\n   * Entries are indices of columns if in [0,num_col), and entries in [num_col,\n   * num_col+num_row) are (num_col+row_index).\n   */\n  const HighsInt* getBasicVariablesArray() const;\n\n  /**\n   * @brief Form a row of \\f$B^{-1}\\f$ for basis matrix \\f$B\\f$,\n   * returning the result in the given HVector buffer which is\n   * expected to be setup with dimension num_row. The buffers\n   * previous contents will be overwritten.\n   */\n  HighsStatus getBasisInverseRowSparse(const HighsInt row,\n                                       HVector& row_ep_buffer);\n\n  /**\n   * @brief Get the primal simplex phase 1 dual values. Advanced\n   * method: for HiGHS IIS calculation\n   */\n  const std::vector<double>& getPrimalPhase1Dual() const {\n    return ekk_instance_.primal_phase1_dual_;\n  }\n\n  /**\n   * @brief Development methods\n   */\n  HighsInt defineClock(const char* name) {\n    return this->timer_.clock_def(name);\n  }\n  void writeAllClocks() { this->timer_.writeAllClocks(); }\n  HighsStatus clearModelNames() {\n    this->model_.lp_.col_names_.clear();\n    this->model_.lp_.row_names_.clear();\n    return HighsStatus::kOk;\n  }\n\n  // Start of deprecated methods\n\n  std::string compilationDate() const { return \"deprecated\"; }\n\n  HighsStatus setLogCallback(void (*user_log_callback)(HighsLogType,\n                                                       const char*, void*),\n                             void* user_log_callback_data = nullptr);\n\n  HighsInt getNumCols() const {\n    deprecationMessage(\"getNumCols\", \"getNumCol\");\n    return getNumCol();\n  }\n  HighsInt getNumRows() const {\n    deprecationMessage(\"getNumRows\", \"getNumRow\");\n    return getNumRow();\n  }\n  HighsInt getNumEntries() {\n    deprecationMessage(\"getNumEntries\", \"getNumNz\");\n    return getNumNz();\n  }\n\n  HighsStatus setHighsOptionValue(const std::string& option, const bool value);\n\n  HighsStatus setHighsOptionValue(const std::string& option,\n                                  const HighsInt value);\n\n#ifdef HIGHSINT64\n  HighsStatus setHighsOptionValue(const std::string& option,\n                                  const int value  //!< The option value\n  ) {\n    deprecationMessage(\"setHighsOptionValue\", \"setOptionValue\");\n    return setOptionValue(option, HighsInt{value});\n  }\n#endif\n\n  HighsStatus setHighsOptionValue(const std::string& option,\n                                  const double value);\n\n  HighsStatus setHighsOptionValue(\n      const std::string& option,\n      const std::string& value  //!< The option value\n  );\n\n  HighsStatus setHighsOptionValue(const std::string& option, const char* value);\n\n  HighsStatus readHighsOptions(const std::string& filename  //!< The filename\n  );\n\n  HighsStatus passHighsOptions(const HighsOptions& options  //!< The options\n  );\n\n  HighsStatus getHighsOptionValue(const std::string& option, bool& value);\n\n  HighsStatus getHighsOptionValue(const std::string& option, HighsInt& value);\n\n  HighsStatus getHighsOptionValue(const std::string& option, double& value);\n\n  HighsStatus getHighsOptionValue(const std::string& option,\n                                  std::string& value);\n\n  HighsStatus getHighsOptionType(const std::string& option,\n                                 HighsOptionType& type  //!< The option type\n  );\n\n  const HighsOptions& getHighsOptions() const;\n\n  HighsStatus resetHighsOptions();\n\n  HighsStatus writeHighsOptions(const std::string& filename,  //!< The filename\n                                const bool report_only_deviations = true);\n\n  HighsInt getSimplexIterationCount() {\n    deprecationMessage(\"getSimplexIterationCount\", \"None\");\n    return info_.simplex_iteration_count;\n  }\n\n  HighsStatus setHighsLogfile(FILE* logfile = nullptr);\n\n  HighsStatus setHighsOutput(FILE* output = nullptr);\n\n  const HighsInfo& getHighsInfo() const;\n\n  HighsStatus getHighsInfoValue(const std::string& info, HighsInt& value);\n\n  HighsStatus getHighsInfoValue(const std::string& info,\n                                double& value) const;  //!< The info value\n\n  HighsStatus writeHighsInfo(const std::string& filename  //!< The filename\n  );\n\n  double getHighsInfinity();\n\n  double getHighsRunTime();\n\n  const HighsModelStatus& getModelStatus(const bool scaled_model) const;\n\n  void logHeader();\n\n  void deprecationMessage(const std::string& method_name,\n                          const std::string& alt_method_name) const;\n\n  /**\n   * @brief Get the hot start basis data from the most recent simplex\n   * solve. Advanced method: for HiGHS MIP solver\n   */\n  const HotStart& getHotStart() const { return ekk_instance_.hot_start_; }\n\n  /**\n   * @brief Set up for simplex using the supplied hot start\n   * data. Advanced method: for HiGHS MIP solver\n   */\n  HighsStatus setHotStart(const HotStart& hot_start) {\n    this->deprecationMessage(\"setHotStart\", \"None\");\n    return HighsStatus::kError;\n  }\n\n  /**\n   * @brief Freeze the current internal HighsBasis instance and\n   * standard NLA, returning a value to be used to recover this basis\n   * and standard NLA at minimal cost. Advanced method: for HiGHS MIP\n   * solver\n   */\n  HighsStatus freezeBasis(HighsInt& frozen_basis_id) {\n    this->deprecationMessage(\"freezeBasis\", \"None\");\n    return HighsStatus::kError;\n  }\n\n  /**\n   * @brief Unfreeze a frozen HighsBasis instance and standard NLA (if\n   * possible). Advanced method: for HiGHS MIP solver\n   */\n  HighsStatus unfreezeBasis(const HighsInt frozen_basis_id) {\n    this->deprecationMessage(\"unfreezeBasis\", \"None\");\n    return HighsStatus::kError;\n  }\n\n  /**\n   * @brief Check that all frozen basis data has been\n   * cleared. Advanced method: for HiGHS MIP solver\n   */\n  HighsStatus frozenBasisAllDataClear() {\n    this->deprecationMessage(\"frozenBasisAllDataClear\", \"None\");\n    return HighsStatus::kError;\n  }\n\n  // End of deprecated methods\n private:\n  HighsSolution solution_;\n  HighsBasis basis_;\n  ICrashInfo icrash_info_;\n\n  HighsModel model_;\n  std::vector<HighsLinearObjective> multi_linear_objective_;\n\n  HighsModel presolved_model_;\n  HighsTimer timer_;\n\n  HighsCallback callback_;\n  HighsOptions options_;\n  HighsInfo info_;\n  HighsRanging ranging_;\n  HighsIis iis_;\n  std::vector<HighsObjectiveSolution> saved_objective_and_solution_;\n  HighsFiles files_;\n\n  HighsPresolveStatus model_presolve_status_ =\n      HighsPresolveStatus::kNotPresolved;\n  HighsModelStatus model_status_ = HighsModelStatus::kNotset;\n\n  bool standard_form_valid_;\n  double standard_form_offset_;\n  std::vector<double> standard_form_cost_;\n  std::vector<double> standard_form_rhs_;\n  HighsSparseMatrix standard_form_matrix_;\n\n  HEkk ekk_instance_;\n\n  HighsPresolveLog presolve_log_;\n\n  HighsSubSolverCallTime sub_solver_call_time_;\n\n  HighsInt max_threads = 0;\n  // This is strictly for debugging. It's used to check whether\n  // returnFromOptimizeModel() was called after the previous call to\n  // Highs::optimizeModel() and, assuming that this is always done, it checks\n  // whether Highs::optimizeModel() is called recursively.\n  bool called_return_from_optimize_model = true;\n  HighsInt debug_optimize_call_num_ = 0;\n\n  bool written_log_header_ = false;\n\n  void reportModelStats() const;\n  HighsStatus optimizeModel();\n\n  void exactResizeModel() {\n    this->model_.lp_.exactResize();\n    this->model_.hessian_.exactResize();\n  }\n\n  HighsStatus completeSolutionFromDiscreteAssignment();\n\n  HighsStatus callSolveLp(HighsLp& lp, const string message);\n  HighsStatus callSolveQp();\n  HighsStatus callSolveMip();\n  HighsStatus callRunPostsolve(const HighsSolution& solution,\n                               const HighsBasis& basis);\n\n  PresolveComponent presolve_;\n  HighsPresolveStatus runPresolve(const bool force_lp_presolve,\n                                  const bool force_presolve = false);\n  HighsPostsolveStatus runPostsolve();\n\n  HighsStatus openWriteFile(const string filename, const string method_name,\n                            FILE*& file, HighsFileType& file_type) const;\n\n  void reportModel(const HighsModel& model);\n  void newHighsBasis();\n  void forceHighsSolutionBasisSize();\n  //\n  // For cases where there is no solution data for the model, but its\n  // status is proved otherwise. Sets the model status, then clears any solution\n  // and basis data\n  void setHighsModelStatusAndClearSolutionAndBasis(\n      const HighsModelStatus model_status);\n\n  // Clears derived model properties (like any presolved model,\n  // standard form LP, and ray information) that (unlike solution and\n  // basis) cannot be updated\n  void clearDerivedModelProperties();\n\n  // Clears the presolved model and its status\n  void clearPresolve();\n\n  // Clears the standard form LP\n  void clearStandardFormLp();\n\n  // Clears the ray records\n  void clearRayRecords() { this->ekk_instance_.clearRayRecords(); }\n  //\n  // Methods to clear solver data for users in Highs class members\n  // before (possibly) updating them with data from trying to solve\n  // the incumbent model.\n  //\n  // Invalidates all solver data in Highs class members by calling\n  // invalidateModelStatus(), invalidateSolution(), invalidateBasis(),\n  // invalidateRanging(), invalidateInfo(), invalidateEkk() and\n  // invalidateIis()\n  void invalidateSolverData();\n\n  // Invalidates all solver dual data in Highs class members by calling\n  // invalidateModelStatus(), invalidateRanging(), and invalidateInfo()\n  //\n  // Used when only the objective changes\n  void invalidateSolverDualData();\n  //\n  // Invalidates the model status, solution_ and info_\n  void invalidateModelStatusSolutionAndInfo();\n  //\n  // Invalidates the model status and info_\n  void invalidateModelStatusAndInfo();\n  //\n  // Sets model status to HighsModelStatus::kNotset\n  void invalidateModelStatus();\n  //\n  // Invalidates primal and dual solution\n  void invalidateSolution();\n  //\n  // Invalidates basis\n  void invalidateBasis();\n  //\n  // Invalidates info_ and resets the values of its members\n  void invalidateInfo();\n  //\n  // Invalidates ranging_\n  void invalidateRanging();\n\n  // Invalidates ekk_instance_\n  void invalidateEkk();\n\n  // Invalidates iis_\n  void invalidateIis();\n\n  HighsStatus returnFromWriteSolution(FILE* file,\n                                      const HighsStatus return_status);\n  HighsStatus returnFromOptimizeModel(const HighsStatus return_status,\n                                      const bool undo_mods);\n  HighsStatus returnFromHighs(const HighsStatus return_status);\n  void reportSolvedLpQpStats();\n\n  // Interface methods\n  HighsStatus formStandardFormLp();\n  HighsStatus basisForSolution();\n  HighsStatus addColsInterface(\n      HighsInt ext_num_new_col, const double* ext_col_cost,\n      const double* ext_col_lower, const double* ext_col_upper,\n      HighsInt ext_num_new_nz, const HighsInt* ext_a_start,\n      const HighsInt* ext_a_index, const double* ext_a_value);\n\n  HighsStatus addRowsInterface(HighsInt ext_num_new_row,\n                               const double* ext_row_lower,\n                               const double* ext_row_upper,\n                               HighsInt ext_num_new_nz,\n                               const HighsInt* ext_ar_start,\n                               const HighsInt* ext_ar_index,\n                               const double* ext_ar_value);\n\n  void deleteColsInterface(HighsIndexCollection& index_collection);\n\n  void deleteRowsInterface(HighsIndexCollection& index_collection);\n\n  void getColsInterface(const HighsIndexCollection& index_collection,\n                        HighsInt& num_col, double* cost, double* lower,\n                        double* upper, HighsInt& num_nz, HighsInt* start,\n                        HighsInt* index, double* value) const;\n\n  void getRowsInterface(const HighsIndexCollection& index_collection,\n                        HighsInt& num_row, double* lower, double* upper,\n                        HighsInt& num_nz, HighsInt* start, HighsInt* index,\n                        double* value) const;\n\n  void getCoefficientInterface(const HighsInt ext_row, const HighsInt ext_col,\n                               double& value) const;\n\n  HighsStatus changeObjectiveSenseInterface(const ObjSense ext_sense);\n  HighsStatus changeObjectiveOffsetInterface(const double ext_offset);\n  HighsStatus changeIntegralityInterface(HighsIndexCollection& index_collection,\n                                         const HighsVarType* usr_inegrality);\n  HighsStatus changeCostsInterface(HighsIndexCollection& index_collection,\n                                   const double* usr_col_cost);\n\n  bool feasibleWrtBounds(const bool columns = true) const;\n  HighsStatus changeColBoundsInterface(HighsIndexCollection& index_collection,\n                                       const double* usr_col_lower,\n                                       const double* usr_col_upper);\n  HighsStatus changeRowBoundsInterface(HighsIndexCollection& index_collection,\n                                       const double* usr_row_lower,\n                                       const double* usr_row_upper);\n  void changeCoefficientInterface(const HighsInt ext_row,\n                                  const HighsInt ext_col,\n                                  const double ext_new_value);\n  HighsStatus scaleColInterface(const HighsInt col, const double scale_value);\n  HighsStatus scaleRowInterface(const HighsInt row, const double scale_value);\n\n  void setNonbasicStatusInterface(const HighsIndexCollection& index_collection,\n                                  const bool columns);\n  void appendNonbasicColsToBasisInterface(const HighsInt ext_num_new_col);\n  void appendBasicRowsToBasisInterface(const HighsInt ext_num_new_row);\n\n  HighsStatus getBasicVariablesInterface(HighsInt* basic_variables);\n  HighsStatus basisSolveInterface(const vector<double>& rhs,\n                                  double* solution_vector,\n                                  HighsInt* solution_num_nz,\n                                  HighsInt* solution_indices, bool transpose);\n\n  void zeroIterationCounts();\n\n  HighsStatus getDualRayInterface(bool& has_dual_ray, double* dual_ray_value);\n\n  HighsStatus getPrimalRayInterface(bool& has_primal_ray,\n                                    double* primal_ray_value);\n  HighsStatus getRangingInterface();\n\n  HighsStatus getIisInterface();\n  HighsStatus getIisInterfaceReturn(const HighsStatus return_status);\n\n  HighsStatus elasticityFilterReturn(\n      const HighsStatus return_status, const bool feasible_model,\n      const std::string& original_model_name, const HighsInt original_num_col,\n      const HighsInt original_num_row,\n      const std::vector<double>& original_col_cost,\n      const std::vector<double>& original_col_lower,\n      const std::vector<double> original_col_upper,\n      const std::vector<HighsVarType> original_integrality);\n  HighsStatus elasticityFilter(const double global_lower_penalty,\n                               const double global_upper_penalty,\n                               const double global_rhs_penalty,\n                               const double* local_lower_penalty,\n                               const double* local_upper_penalty,\n                               const double* local_rhs_penalty,\n                               const bool get_infeasible_row,\n                               std::vector<HighsInt>& infeasible_row_subset);\n  HighsStatus extractIis(HighsInt& num_iis_col, HighsInt& num_iis_row,\n                         HighsInt* iis_col_index, HighsInt* iis_row_index,\n                         HighsInt* iis_col_bound, HighsInt* iis_row_bound);\n\n  HighsStatus returnFromLexicographicOptimization(\n      const HighsStatus return_status, HighsInt original_lp_num_row);\n  HighsStatus multiobjectiveSolve();\n\n  bool aFormatOk(const HighsInt num_nz, const HighsInt format);\n  bool qFormatOk(const HighsInt num_nz, const HighsInt format);\n  void clearZeroHessian();\n  HighsStatus checkOptimality(const std::string& solver_type);\n  HighsStatus lpKktCheck(const HighsLp& lp, const std::string& message = \"\");\n  HighsStatus invertRequirementError(std::string method_name) const;\n\n  HighsStatus handleInfCost();\n  void restoreInfCost(HighsStatus& return_status);\n  HighsStatus optionChangeAction();\n\n  HighsStatus userScaleModel(HighsUserScaleData& data);\n  HighsStatus userScaleSolution(HighsUserScaleData& data,\n                                bool update_kkt = false);\n  HighsStatus computeIllConditioning(HighsIllConditioning& ill_conditioning,\n                                     const bool constraint,\n                                     const HighsInt method,\n                                     const double ill_conditioning_bound);\n  void formIllConditioningLp0(HighsLp& ill_conditioning_lp,\n                              std::vector<HighsInt>& basic_var,\n                              const bool constraint);\n  void formIllConditioningLp1(HighsLp& ill_conditioning_lp,\n                              std::vector<HighsInt>& basic_var,\n                              const bool constraint,\n                              const double ill_conditioning_bound);\n  bool infeasibleBoundsOk();\n  bool validLinearObjective(const HighsLinearObjective& linear_objective,\n                            const HighsInt iObj) const;\n  bool hasRepeatedLinearObjectivePriorities(\n      const HighsLinearObjective* linear_objective = nullptr) const;\n\n  bool tryPdlpCleanup(HighsInt& pdlp_cleanup_iteration_limit,\n                      const HighsInfo& presolved_lp_info) const;\n\n  bool optionsHasHighsFiles() const;\n  void saveHighsFiles();\n  void getHighsFiles();\n};\n\n// Start of deprecated methods not in the Highs class\n\nconst char* highsCompilationDate();\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/filereaderlp/builder.hpp",
    "content": "#ifndef __READERLP_BUILDER_HPP__\n#define __READERLP_BUILDER_HPP__\n\n#include <memory>\n#include <string>\n#include <unordered_map>\n\n#include \"model.hpp\"\n\nstruct Builder {\n  std::unordered_map<std::string, std::shared_ptr<Variable>> variables;\n\n  Model model;\n\n  std::shared_ptr<Variable> getvarbyname(const std::string& name) {\n    auto it = variables.find(name);\n    if (it != variables.end()) return it->second;\n    auto newvar = std::shared_ptr<Variable>(new Variable(name));\n    variables.insert(std::make_pair(name, newvar));\n    model.variables.push_back(newvar);\n    return newvar;\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/filereaderlp/def.hpp",
    "content": "#ifndef __READERLP_DEF_HPP__\n#define __READERLP_DEF_HPP__\n\n#include <stdexcept>\n#include <string>\n\nvoid inline lpassert(bool condition) {\n  if (!condition) {\n    throw std::invalid_argument(\"File not existent or illegal file format.\");\n  }\n}\n\nconst std::string LP_KEYWORD_INF[] = {\"infinity\", \"inf\"};\nconst std::string LP_KEYWORD_FREE[] = {\"free\"};\n\nconst unsigned int LP_KEYWORD_INF_N = 2;\nconst unsigned int LP_KEYWORD_FREE_N = 1;\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/filereaderlp/model.hpp",
    "content": "#ifndef __READERLP_MODEL_HPP__\n#define __READERLP_MODEL_HPP__\n\n#include <limits>\n#include <memory>\n#include <string>\n#include <vector>\n\nenum class VariableType {\n  CONTINUOUS,\n  BINARY,\n  GENERAL,\n  SEMICONTINUOUS,\n  SEMIINTEGER\n};\n\nenum class ObjectiveSense { MIN, MAX };\n\nstruct Variable {\n  VariableType type = VariableType::CONTINUOUS;\n  double lowerbound = 0.0;\n  double upperbound = std::numeric_limits<double>::infinity();\n  std::string name;\n\n  Variable(std::string n = \"\") : name(n){};\n};\n\nstruct LinTerm {\n  std::shared_ptr<Variable> var;\n  double coef = 1.0;\n};\n\nstruct QuadTerm {\n  std::shared_ptr<Variable> var1;\n  std::shared_ptr<Variable> var2;\n  double coef = 1.0;\n};\n\nstruct Expression {\n  std::vector<std::shared_ptr<LinTerm>> linterms;\n  std::vector<std::shared_ptr<QuadTerm>> quadterms;\n  double offset = 0.0;\n  std::string name = \"\";\n};\n\nstruct Constraint {\n  double lowerbound = -std::numeric_limits<double>::infinity();\n  double upperbound = std::numeric_limits<double>::infinity();\n  std::shared_ptr<Expression> expr;\n\n  Constraint() : expr(std::shared_ptr<Expression>(new Expression)){};\n};\n\nstruct SOS {\n  std::string name = \"\";\n  short type = 0;  // 1 or 2\n  std::vector<std::pair<std::shared_ptr<Variable>, double>> entries;\n};\n\nstruct Model {\n  std::shared_ptr<Expression> objective;\n  ObjectiveSense sense;\n  std::vector<std::shared_ptr<Constraint>> constraints;\n  std::vector<std::shared_ptr<Variable>> variables;\n  std::vector<std::shared_ptr<SOS>> soss;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/filereaderlp/reader.hpp",
    "content": "#ifndef __READERLP_READER_HPP__\n#define __READERLP_READER_HPP__\n\n#include <string>\n\n#include \"model.hpp\"\n\nModel readinstance(std::string filename);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/interfaces/highs_c_api.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_C_API\n#define HIGHS_C_API\n//\n// Welcome to the HiGHS C API!\n//\n// The simplest way to use HiGHS to solve an LP, MIP or QP from C is\n// to pass the problem data to the appropriate method Highs_lpCall,\n// Highs_mipCall or Highs_qpCall, and these methods return the\n// appropriate solution information\n//\n// For sophisticated applications, where esoteric solution\n// information is needed, or if a sequence of modified models need to\n// be solved, use the Highs_create method to generate a pointer to an\n// instance of the C++ Highs class, and then use any of a large number\n// of models for which this pointer is the first parameter.\n//\n#include \"lp_data/HighsCallbackStruct.h\"\n\nstatic const HighsInt kHighsMaximumStringLength = 512;\n\nstatic const HighsInt kHighsStatusError = -1;\nstatic const HighsInt kHighsStatusOk = 0;\nstatic const HighsInt kHighsStatusWarning = 1;\n\nstatic const HighsInt kHighsVarTypeContinuous = 0;\nstatic const HighsInt kHighsVarTypeInteger = 1;\nstatic const HighsInt kHighsVarTypeSemiContinuous = 2;\nstatic const HighsInt kHighsVarTypeSemiInteger = 3;\nstatic const HighsInt kHighsVarTypeImplicitInteger = 4;\n\nstatic const HighsInt kHighsOptionTypeBool = 0;\nstatic const HighsInt kHighsOptionTypeInt = 1;\nstatic const HighsInt kHighsOptionTypeDouble = 2;\nstatic const HighsInt kHighsOptionTypeString = 3;\n\nstatic const HighsInt kHighsInfoTypeInt64 = -1;\nstatic const HighsInt kHighsInfoTypeInt = 1;\nstatic const HighsInt kHighsInfoTypeDouble = 2;\n\nstatic const HighsInt kHighsObjSenseMinimize = 1;\nstatic const HighsInt kHighsObjSenseMaximize = -1;\n\nstatic const HighsInt kHighsMatrixFormatColwise = 1;\nstatic const HighsInt kHighsMatrixFormatRowwise = 2;\n\nstatic const HighsInt kHighsHessianFormatTriangular = 1;\nstatic const HighsInt kHighsHessianFormatSquare = 2;\n\nstatic const HighsInt kHighsSolutionStatusNone = 0;\nstatic const HighsInt kHighsSolutionStatusInfeasible = 1;\nstatic const HighsInt kHighsSolutionStatusFeasible = 2;\n\nstatic const HighsInt kHighsBasisValidityInvalid = 0;\nstatic const HighsInt kHighsBasisValidityValid = 1;\n\nstatic const HighsInt kHighsPresolveStatusNotPresolved = -1;\nstatic const HighsInt kHighsPresolveStatusNotReduced = 0;\nstatic const HighsInt kHighsPresolveStatusInfeasible = 1;\nstatic const HighsInt kHighsPresolveStatusUnboundedOrInfeasible = 2;\nstatic const HighsInt kHighsPresolveStatusReduced = 3;\nstatic const HighsInt kHighsPresolveStatusReducedToEmpty = 4;\nstatic const HighsInt kHighsPresolveStatusTimeout = 5;\nstatic const HighsInt kHighsPresolveStatusNullError = 6;\nstatic const HighsInt kHighsPresolveStatusOptionsError = 7;\nstatic const HighsInt kHighsPresolveStatusOutOfMemory = 8;\n\nstatic const HighsInt kHighsModelStatusNotset = 0;\nstatic const HighsInt kHighsModelStatusLoadError = 1;\nstatic const HighsInt kHighsModelStatusModelError = 2;\nstatic const HighsInt kHighsModelStatusPresolveError = 3;\nstatic const HighsInt kHighsModelStatusSolveError = 4;\nstatic const HighsInt kHighsModelStatusPostsolveError = 5;\nstatic const HighsInt kHighsModelStatusModelEmpty = 6;\nstatic const HighsInt kHighsModelStatusOptimal = 7;\nstatic const HighsInt kHighsModelStatusInfeasible = 8;\nstatic const HighsInt kHighsModelStatusUnboundedOrInfeasible = 9;\nstatic const HighsInt kHighsModelStatusUnbounded = 10;\nstatic const HighsInt kHighsModelStatusObjectiveBound = 11;\nstatic const HighsInt kHighsModelStatusObjectiveTarget = 12;\nstatic const HighsInt kHighsModelStatusTimeLimit = 13;\nstatic const HighsInt kHighsModelStatusIterationLimit = 14;\nstatic const HighsInt kHighsModelStatusUnknown = 15;\nstatic const HighsInt kHighsModelStatusSolutionLimit = 16;\nstatic const HighsInt kHighsModelStatusInterrupt = 17;\n\nstatic const HighsInt kHighsBasisStatusLower = 0;\nstatic const HighsInt kHighsBasisStatusBasic = 1;\nstatic const HighsInt kHighsBasisStatusUpper = 2;\nstatic const HighsInt kHighsBasisStatusZero = 3;\nstatic const HighsInt kHighsBasisStatusNonbasic = 4;\n\nstatic const HighsInt kHighsCallbackLogging = 0;\nstatic const HighsInt kHighsCallbackSimplexInterrupt = 1;\nstatic const HighsInt kHighsCallbackIpmInterrupt = 2;\nstatic const HighsInt kHighsCallbackMipSolution = 3;\nstatic const HighsInt kHighsCallbackMipImprovingSolution = 4;\nstatic const HighsInt kHighsCallbackMipLogging = 5;\nstatic const HighsInt kHighsCallbackMipInterrupt = 6;\nstatic const HighsInt kHighsCallbackMipGetCutPool = 7;\nstatic const HighsInt kHighsCallbackMipDefineLazyConstraints = 8;\nstatic const HighsInt kHighsCallbackCallbackMipUserSolution = 9;\n\nstatic const char* const kHighsCallbackDataOutLogTypeName = \"log_type\";\nstatic const char* const kHighsCallbackDataOutRunningTimeName = \"running_time\";\nstatic const char* const kHighsCallbackDataOutSimplexIterationCountName =\n    \"simplex_iteration_count\";\nstatic const char* const kHighsCallbackDataOutIpmIterationCountName =\n    \"ipm_iteration_count\";\nstatic const char* const kHighsCallbackDataOutPdlpIterationCountName =\n    \"pdlp_iteration_count\";\nstatic const char* const kHighsCallbackDataOutObjectiveFunctionValueName =\n    \"objective_function_value\";\nstatic const char* const kHighsCallbackDataOutMipNodeCountName =\n    \"mip_node_count\";\nstatic const char* const kHighsCallbackDataOutMipTotalLpIterationsName =\n    \"mip_total_lp_iterations\";\nstatic const char* const kHighsCallbackDataOutMipPrimalBoundName =\n    \"mip_primal_bound\";\nstatic const char* const kHighsCallbackDataOutMipDualBoundName =\n    \"mip_dual_bound\";\nstatic const char* const kHighsCallbackDataOutMipGapName = \"mip_gap\";\nstatic const char* const kHighsCallbackDataOutMipSolutionName = \"mip_solution\";\nstatic const char* const kHighsCallbackDataOutCutpoolNumColName =\n    \"cutpool_num_col\";\nstatic const char* const kHighsCallbackDataOutCutpoolNumCutName =\n    \"cutpool_num_cut\";\nstatic const char* const kHighsCallbackDataOutCutpoolNumNzName =\n    \"cutpool_num_nz\";\nstatic const char* const kHighsCallbackDataOutCutpoolStartName =\n    \"cutpool_start\";\nstatic const char* const kHighsCallbackDataOutCutpoolIndexName =\n    \"cutpool_index\";\nstatic const char* const kHighsCallbackDataOutCutpoolValueName =\n    \"cutpool_value\";\nstatic const char* const kHighsCallbackDataOutCutpoolLowerName =\n    \"cutpool_lower\";\nstatic const char* const kHighsCallbackDataOutCutpoolUpperName =\n    \"cutpool_upper\";\n\nconst HighsInt kHighsIisStrategyLight = 0;\nconst HighsInt kHighsIisStrategyFromLpRowPriority = 1;  // WIP\nconst HighsInt kHighsIisStrategyFromLpColPriority = 2;  // WIP\n\nconst HighsInt kHighsIisBoundFree = 1;\nconst HighsInt kHighsIisBoundLower = 2;\nconst HighsInt kHighsIisBoundUpper = 3;\nconst HighsInt kHighsIisBoundBoxed = 4;\n\nconst HighsInt kHighsIisStatusInConflict = 0;\nconst HighsInt kHighsIisStatusNotInConflict = 1;\nconst HighsInt kHighsIisStatusMaybeInConflict = 2;\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Formulate and solve a linear program using HiGHS.\n *\n * @param num_col   The number of columns.\n * @param num_row   The number of rows.\n * @param num_nz    The number of nonzeros in the constraint matrix.\n * @param a_format  The format of the constraint matrix as a\n *                  `kHighsMatrixFormat` constant.\n * @param sense     The optimization sense as a `kHighsObjSense` constant.\n * @param offset    The objective constant.\n * @param col_cost  An array of length [num_col] with the column costs.\n * @param col_lower An array of length [num_col] with the column lower bounds.\n * @param col_upper An array of length [num_col] with the column upper bounds.\n * @param row_lower An array of length [num_row] with the row lower bounds.\n * @param row_upper An array of length [num_row] with the row upper bounds.\n * @param a_start   The constraint matrix is provided to HiGHS in compressed\n *                  sparse column form (if `a_format` is\n *                  `kHighsMatrixFormatColwise`, otherwise compressed sparse row\n *                  form). The sparse matrix consists of three arrays,\n *                  `a_start`, `a_index`, and `a_value`. `a_start` is an array\n *                  of length [num_col] containing the starting index of each\n *                  column in `a_index`. If `a_format` is\n *                  `kHighsMatrixFormatRowwise` the array is of length [num_row]\n *                  corresponding to each row.\n * @param a_index   An array of length [num_nz] with indices of matrix entries.\n * @param a_value   An array of length [num_nz] with values of matrix entries.\n *\n * @param col_value      An array of length [num_col], to be filled with the\n *                       primal column solution.\n * @param col_dual       An array of length [num_col], to be filled with the\n *                       dual column solution.\n * @param row_value      An array of length [num_row], to be filled with the\n *                       primal row solution.\n * @param row_dual       An array of length [num_row], to be filled with the\n *                       dual row solution.\n * @param col_basis_status  An array of length [num_col], to be filled with the\n *                          basis status of the columns in the form of a\n *                          `kHighsBasisStatus` constant.\n * @param row_basis_status  An array of length [num_row], to be filled with the\n *                          basis status of the rows in the form of a\n *                          `kHighsBasisStatus` constant.\n * @param model_status      The location in which to place the termination\n *                          status of the model after the solve in the form of a\n *                          `kHighsModelStatus` constant.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_lpCall(const HighsInt num_col, const HighsInt num_row,\n                      const HighsInt num_nz, const HighsInt a_format,\n                      const HighsInt sense, const double offset,\n                      const double* col_cost, const double* col_lower,\n                      const double* col_upper, const double* row_lower,\n                      const double* row_upper, const HighsInt* a_start,\n                      const HighsInt* a_index, const double* a_value,\n                      double* col_value, double* col_dual, double* row_value,\n                      double* row_dual, HighsInt* col_basis_status,\n                      HighsInt* row_basis_status, HighsInt* model_status);\n\n/**\n * Formulate and solve a mixed-integer linear program using HiGHS.\n *\n * The signature of this method is identical to `Highs_lpCall`, except that it\n * has an additional `integrality` argument, and that it is missing the\n * `col_dual`, `row_dual`, `col_basis_status` and `row_basis_status` arguments.\n *\n * @param integrality   An array of length [num_col], containing a\n *                      `kHighsVarType` constant for each column.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_mipCall(const HighsInt num_col, const HighsInt num_row,\n                       const HighsInt num_nz, const HighsInt a_format,\n                       const HighsInt sense, const double offset,\n                       const double* col_cost, const double* col_lower,\n                       const double* col_upper, const double* row_lower,\n                       const double* row_upper, const HighsInt* a_start,\n                       const HighsInt* a_index, const double* a_value,\n                       const HighsInt* integrality, double* col_value,\n                       double* row_value, HighsInt* model_status);\n\n/**\n * Formulate and solve a quadratic program using HiGHS.\n *\n * The signature of this method is identical to `Highs_lpCall`, except that it\n * has additional arguments for specifying the Hessian matrix.\n *\n * @param q_num_nz  The number of nonzeros in the Hessian matrix.\n * @param q_format  The format of the Hessian matrix in the form of a\n *                  `kHighsHessianStatus` constant. If q_num_nz > 0, this must\n *                  be `kHighsHessianFormatTriangular`.\n * @param q_start   The Hessian matrix is provided to HiGHS as the lower\n *                  triangular component in compressed sparse column form\n *                  (or, equivalently, as the upper triangular component\n *                  in compressed sparse row form). The sparse matrix consists\n *                  of three arrays, `q_start`, `q_index`, and `q_value`.\n *                  `q_start` is an array of length [num_col].\n * @param q_index   An array of length [q_num_nz] with indices of matrix\n *                  entries.\n * @param q_value   An array of length [q_num_nz] with values of matrix entries.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_qpCall(\n    const HighsInt num_col, const HighsInt num_row, const HighsInt num_nz,\n    const HighsInt q_num_nz, const HighsInt a_format, const HighsInt q_format,\n    const HighsInt sense, const double offset, const double* col_cost,\n    const double* col_lower, const double* col_upper, const double* row_lower,\n    const double* row_upper, const HighsInt* a_start, const HighsInt* a_index,\n    const double* a_value, const HighsInt* q_start, const HighsInt* q_index,\n    const double* q_value, double* col_value, double* col_dual,\n    double* row_value, double* row_dual, HighsInt* col_basis_status,\n    HighsInt* row_basis_status, HighsInt* model_status);\n\n/**\n * Create a Highs instance and return the reference.\n *\n * Call `Highs_destroy` on the returned reference to clean up allocated memory.\n *\n * @returns A pointer to the Highs instance.\n */\nvoid* Highs_create(void);\n\n/**\n * Destroy the model `highs` created by `Highs_create` and free all\n * corresponding memory. Future calls using `highs` are not allowed.\n *\n * To empty a model without invalidating `highs`, see `Highs_clearModel`.\n *\n * @param highs     A pointer to the Highs instance.\n */\nvoid Highs_destroy(void* highs);\n\n/**\n * Return the HiGHS version number as a string of the form \"vX.Y.Z\".\n *\n * @returns The HiGHS version as a `char*`.\n */\nconst char* Highs_version(void);\n\n/**\n * Return the HiGHS major version number.\n *\n * @returns The HiGHS major version number.\n */\nHighsInt Highs_versionMajor(void);\n\n/**\n * Return the HiGHS minor version number.\n *\n * @returns The HiGHS minor version number.\n */\nHighsInt Highs_versionMinor(void);\n\n/**\n * Return the HiGHS patch version number.\n *\n * @returns The HiGHS patch version number.\n */\nHighsInt Highs_versionPatch(void);\n\n/**\n * Return the HiGHS githash.\n *\n * @returns The HiGHS githash.\n */\nconst char* Highs_githash(void);\n\n/**\n * Read a model from `filename` into `highs`.\n *\n * @param highs     A pointer to the Highs instance.\n * @param filename  The filename to read.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_readModel(void* highs, const char* filename);\n\n/**\n * Write the model in `highs` to `filename`.\n *\n * @param highs     A pointer to the Highs instance.\n * @param filename  The filename to write.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_writeModel(void* highs, const char* filename);\n\n/**\n * Write the presolved model in `highs` to `filename`.\n *\n * @param highs     A pointer to the Highs instance.\n * @param filename  The filename to write.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_writePresolvedModel(void* highs, const char* filename);\n\n/**\n * Reset the options and then call `clearModel`.\n *\n * See `Highs_destroy` to free all associated memory.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_clear(void* highs);\n\n/**\n * Remove all variables and constraints from the model `highs`, but do not\n * invalidate the pointer `highs`. Future calls (for example, adding new\n * variables and constraints) are allowed.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_clearModel(void* highs);\n\n/**\n * Clear all solution data associated with the model.\n *\n * See `Highs_destroy` to clear the model and free all associated memory.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_clearSolver(void* highs);\n\n/**\n * Presolve a model.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_presolve(void* highs);\n\n/**\n * Optimize a model. The algorithm used by HiGHS depends on the options that\n * have been set.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_run(void* highs);\n\n/**\n * Postsolve a model using a primal (and possibly dual) solution. The\n * postsolved solution can be retrieved later by calling\n * `Highs_getSolution`.\n *\n * @param highs       A pointer to the Highs instance.\n * @param col_value   An array of length [num_col] with the column solution\n *                    values.\n * @param col_dual    An array of length [num_col] with the column dual\n *                    values, or a null pointer if not known.\n * @param row_dual    An array of length [num_row] with the row dual values,\n *                    or a null pointer if not known.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_postsolve(void* highs, const double* col_value,\n                         const double* col_dual, const double* row_dual);\n\n/**\n * Write the solution information (including dual and basis status, if\n * available) to a file.\n *\n * See also: `Highs_writeSolutionPretty`.\n *\n * @param highs     A pointer to the Highs instance.\n * @param filename  The name of the file to write the results to.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_writeSolution(const void* highs, const char* filename);\n\n/**\n * Write the solution information (including dual and basis status, if\n * available) to a file in a human-readable format.\n *\n * The method identical to `Highs_writeSolution`, except that the\n * printout is in a human-readable format.\n *\n * @param highs     A pointer to the Highs instance.\n * @param filename  The name of the file to write the results to.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_writeSolutionPretty(const void* highs, const char* filename);\n\n/**\n * Pass a linear program (LP) to HiGHS in a single function call.\n *\n * The signature of this function is identical to `Highs_passModel`, without the\n * arguments for passing the Hessian matrix of a quadratic program and the\n * integrality vector.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_passLp(void* highs, const HighsInt num_col,\n                      const HighsInt num_row, const HighsInt num_nz,\n                      const HighsInt a_format, const HighsInt sense,\n                      const double offset, const double* col_cost,\n                      const double* col_lower, const double* col_upper,\n                      const double* row_lower, const double* row_upper,\n                      const HighsInt* a_start, const HighsInt* a_index,\n                      const double* a_value);\n\n/**\n * Pass a mixed-integer linear program (MILP) to HiGHS in a single function\n * call.\n *\n * The signature of function is identical to `Highs_passModel`, without the\n * arguments for passing the Hessian matrix of a quadratic program.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_passMip(void* highs, const HighsInt num_col,\n                       const HighsInt num_row, const HighsInt num_nz,\n                       const HighsInt a_format, const HighsInt sense,\n                       const double offset, const double* col_cost,\n                       const double* col_lower, const double* col_upper,\n                       const double* row_lower, const double* row_upper,\n                       const HighsInt* a_start, const HighsInt* a_index,\n                       const double* a_value, const HighsInt* integrality);\n\n/**\n * Pass a model to HiGHS in a single function call. This is faster than\n * constructing the model using `Highs_addRow` and `Highs_addCol`.\n *\n * @param highs       A pointer to the Highs instance.\n * @param num_col     The number of columns.\n * @param num_row     The number of rows.\n * @param num_nz      The number of elements in the constraint matrix.\n * @param q_num_nz    The number of elements in the Hessian matrix.\n * @param a_format    The format of the constraint matrix to use in the form of\n *                    a `kHighsMatrixFormat` constant.\n * @param q_format    The format of the Hessian matrix to use in the form of a\n *                    `kHighsHessianFormat` constant.\n * @param sense       The optimization sense in the form of a `kHighsObjSense`\n *                    constant.\n * @param offset      The constant term in the objective function.\n * @param col_cost    An array of length [num_col] with the objective\n *                    coefficients.\n * @param col_lower   An array of length [num_col] with the lower column bounds.\n * @param col_upper   An array of length [num_col] with the upper column bounds.\n * @param row_lower   An array of length [num_row] with the upper row bounds.\n * @param row_upper   An array of length [num_row] with the upper row bounds.\n * @param a_start     The constraint matrix is provided to HiGHS in compressed\n *                    sparse column form (if `a_format` is\n *                    `kHighsMatrixFormatColwise`, otherwise compressed sparse\n *                    row form). The sparse matrix consists of three arrays,\n *                    `a_start`, `a_index`, and `a_value`. `a_start` is an array\n *                    of length [num_col] containing the starting index of each\n *                    column in `a_index`. If `a_format` is\n *                    `kHighsMatrixFormatRowwise` the array is of length\n *                    [num_row] corresponding to each row.\n * @param a_index     An array of length [num_nz] with indices of matrix\n *                    entries.\n * @param a_value     An array of length [num_nz] with values of matrix entries.\n * @param q_start     The Hessian matrix is provided to HiGHS as the lower\n *                    triangular component in compressed sparse column form\n *                    (or, equivalently, as the upper triangular component\n *                    in compressed sparse row form). The sparse matrix consists\n *                    of three arrays, `q_start`, `q_index`, and `q_value`.\n *                    `q_start` is an array of length [num_col]. If the model\n *                    is linear, pass NULL.\n * @param q_index     An array of length [q_num_nz] with indices of matrix\n *                    entries. If the model is linear, pass NULL.\n * @param q_value     An array of length [q_num_nz] with values of matrix\n *                     entries. If the model is linear, pass NULL.\n * @param integrality An array of length [num_col] containing a `kHighsVarType`\n *                    constant for each column.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_passModel(void* highs, const HighsInt num_col,\n                         const HighsInt num_row, const HighsInt num_nz,\n                         const HighsInt q_num_nz, const HighsInt a_format,\n                         const HighsInt q_format, const HighsInt sense,\n                         const double offset, const double* col_cost,\n                         const double* col_lower, const double* col_upper,\n                         const double* row_lower, const double* row_upper,\n                         const HighsInt* a_start, const HighsInt* a_index,\n                         const double* a_value, const HighsInt* q_start,\n                         const HighsInt* q_index, const double* q_value,\n                         const HighsInt* integrality);\n\n/**\n * Set the Hessian matrix for a quadratic objective.\n *\n * @param highs     A pointer to the Highs instance.\n * @param dim       The dimension of the Hessian matrix. Should be [num_col].\n * @param num_nz    The number of non-zero elements in the Hessian matrix.\n * @param format    The format of the Hessian matrix as a `kHighsHessianFormat`\n *                  constant. This must be `kHighsHessianFormatTriangular`.\n * @param start     The Hessian matrix is provided to HiGHS as the lower\n *                  triangular component in compressed sparse column form\n *                  (or, equivalently, as the upper triangular component\n *                  in compressed sparse row form), using `q_start`, `q_index`,\n *                  and `q_value`.The Hessian matrix is provided to HiGHS as the\n *                  lower triangular component in compressed sparse column form.\n *                  The sparse matrix consists of three arrays, `start`,\n *                  `index`, and `value`. `start` is an array of length\n *                  [num_col] containing the starting index of each column in\n *                  `index`.\n * @param index     An array of length [num_nz] with indices of matrix entries.\n * @param value     An array of length [num_nz] with values of matrix entries.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_passHessian(void* highs, const HighsInt dim,\n                           const HighsInt num_nz, const HighsInt format,\n                           const HighsInt* start, const HighsInt* index,\n                           const double* value);\n\n/**\n * Passes multiple linear objective data to HiGHS, clearing any such\n * data already in HiGHS\n *\n * @param highs         A pointer to the Highs instance.\n * @param weight        A pointer to the weights of the linear objective, with\n *                      its positive/negative sign determining whether it is\n *                      minimized or maximized during lexicographic optimization\n * @param offset        A pointer to the objective offsets\n * @param coefficients  A pointer to the objective coefficients\n * @param abs_tolerance A pointer to the absolute tolerances used when\n *                      constructing objective constraints during lexicographic\n *                      optimization\n * @param rel_tolerance A pointer to the relative tolerances used when\n *                      constructing objective constraints during lexicographic\n *                      optimization\n * @param priority      A pointer to the priorities of the objectives during\n *                      lexicographic optimization\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\n\nHighsInt Highs_passLinearObjectives(const void* highs,\n                                    const HighsInt num_linear_objective,\n                                    const double* weight, const double* offset,\n                                    const double* coefficients,\n                                    const double* abs_tolerance,\n                                    const double* rel_tolerance,\n                                    const HighsInt* priority);\n\n/**\n * Adds linear objective data to HiGHS\n *\n * @param highs         A pointer to the Highs instance.\n * @param weight        The weight of the linear objective, with its\n *                      positive/negative sign determining whether it is\n *                      minimized or maximized during lexicographic\n *                      optimization\n * @param offset        The objective offset\n * @param coefficients  A pointer to the objective coefficients\n * @param abs_tolerance The absolute tolerance used when constructing an\n *                      objective constraint during lexicographic optimization\n * @param rel_tolerance The relative tolerance used when constructing an\n *                      objective constraint during lexicographic optimization\n * @param priority      The priority of this objective during lexicographic\n *                      optimization\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\n\nHighsInt Highs_addLinearObjective(const void* highs, const double weight,\n                                  const double offset,\n                                  const double* coefficients,\n                                  const double abs_tolerance,\n                                  const double rel_tolerance,\n                                  const HighsInt priority);\n\n/**\n * Clears any multiple linear objective data in HiGHS\n *\n * @param highs A pointer to the Highs instance.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\n\nHighsInt Highs_clearLinearObjectives(const void* highs);\n/**\n * Pass the name of a row.\n *\n * @param highs A pointer to the Highs instance.\n * @param row   The row for which the name is supplied.\n * @param name  The name of the row.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_passRowName(const void* highs, const HighsInt row,\n                           const char* name);\n\n/**\n * Pass the name of a column.\n *\n * @param highs A pointer to the Highs instance.\n * @param col   The column for which the name is supplied.\n * @param name  The name of the column.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_passColName(const void* highs, const HighsInt col,\n                           const char* name);\n\n/**\n * Pass the name of the model.\n *\n * @param highs A pointer to the Highs instance.\n * @param name  The name of the model.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_passModelName(const void* highs, const char* name);\n\n/**\n * Read the option values from file.\n *\n * @param highs     A pointer to the Highs instance.\n * @param filename  The filename from which to read the option values.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_readOptions(const void* highs, const char* filename);\n\n/**\n * Set a boolean-valued option.\n *\n * @param highs     A pointer to the Highs instance.\n * @param option    The name of the option.\n * @param value     The new value of the option.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_setBoolOptionValue(void* highs, const char* option,\n                                  const HighsInt value);\n\n/**\n * Set an int-valued option.\n *\n * @param highs     A pointer to the Highs instance.\n * @param option    The name of the option.\n * @param value     The new value of the option.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_setIntOptionValue(void* highs, const char* option,\n                                 const HighsInt value);\n\n/**\n * Set a double-valued option.\n *\n * @param highs     A pointer to the Highs instance.\n * @param option    The name of the option.\n * @param value     The new value of the option.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_setDoubleOptionValue(void* highs, const char* option,\n                                    const double value);\n\n/**\n * Set a string-valued option.\n *\n * @param highs     A pointer to the Highs instance.\n * @param option    The name of the option.\n * @param value     The new value of the option.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_setStringOptionValue(void* highs, const char* option,\n                                    const char* value);\n\n/**\n * Get a boolean-valued option.\n *\n * @param highs     A pointer to the Highs instance.\n * @param option    The name of the option.\n * @param value     The location in which the current value of the option should\n *                  be placed.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getBoolOptionValue(const void* highs, const char* option,\n                                  HighsInt* value);\n\n/**\n * Get an int-valued option.\n *\n * @param highs     A pointer to the Highs instance.\n * @param option    The name of the option.\n * @param value     The location in which the current value of the option should\n *                  be placed.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getIntOptionValue(const void* highs, const char* option,\n                                 HighsInt* value);\n\n/**\n * Get a double-valued option.\n *\n * @param highs     A pointer to the Highs instance.\n * @param option    The name of the option.\n * @param value     The location in which the current value of the option should\n *                  be placed.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getDoubleOptionValue(const void* highs, const char* option,\n                                    double* value);\n\n/**\n * Get a string-valued option.\n *\n * @param highs     A pointer to the Highs instance.\n * @param option    The name of the option.\n * @param value     A pointer to allocated memory (of at least\n *                  `kMaximumStringLength`) to store the current value of the\n *                  option.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getStringOptionValue(const void* highs, const char* option,\n                                    char* value);\n\n/**\n * Get the type expected by an option.\n *\n * @param highs     A pointer to the Highs instance.\n * @param option    The name of the option.\n * @param type      A HighsInt in which the corresponding `kHighsOptionType`\n *                  constant should be placed.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getOptionType(const void* highs, const char* option,\n                             HighsInt* type);\n\n/**\n * Reset all options to their default value.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_resetOptions(void* highs);\n\n/**\n * Write the current options to file.\n *\n * @param highs     A pointer to the Highs instance.\n * @param filename  The filename to write the options to.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_writeOptions(const void* highs, const char* filename);\n\n/**\n * Write the value of non-default options to file.\n *\n * This is similar to `Highs_writeOptions`, except only options with\n * non-default value are written to `filename`.\n *\n * @param highs     A pointer to the Highs instance.\n * @param filename  The filename to write the options to.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_writeOptionsDeviations(const void* highs, const char* filename);\n\n/**\n * Return the number of options\n *\n * @param highs     A pointer to the Highs instance.\n */\nHighsInt Highs_getNumOptions(const void* highs);\n\n/**\n * Get the name of an option identified by index\n *\n * @param highs     A pointer to the Highs instance.\n * @param index     The index of the option.\n * @param name      The name of the option.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getOptionName(const void* highs, const HighsInt index,\n                             char** name);\n\n/**\n * Get the current and default values of a bool option\n *\n * @param highs         A pointer to the Highs instance.\n * @param current_value A pointer to the current value of the option.\n * @param default_value A pointer to the default value of the option.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getBoolOptionValues(const void* highs, const char* option,\n                                   HighsInt* current_value,\n                                   HighsInt* default_value);\n/**\n * Get the current and default values of a HighsInt option\n *\n * @param highs         A pointer to the Highs instance.\n * @param current_value A pointer to the current value of the option.\n * @param min_value     A pointer to the minimum value of the option.\n * @param max_value     A pointer to the maximum value of the option.\n * @param default_value A pointer to the default value of the option.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getIntOptionValues(const void* highs, const char* option,\n                                  HighsInt* current_value, HighsInt* min_value,\n                                  HighsInt* max_value, HighsInt* default_value);\n\n/**\n * Get the current and default values of a double option\n *\n * @param highs         A pointer to the Highs instance.\n * @param current_value A pointer to the current value of the option.\n * @param min_value     A pointer to the minimum value of the option.\n * @param max_value     A pointer to the maximum value of the option.\n * @param default_value A pointer to the default value of the option.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getDoubleOptionValues(const void* highs, const char* option,\n                                     double* current_value, double* min_value,\n                                     double* max_value, double* default_value);\n\n/**\n * Get the current and default values of a string option\n *\n * @param highs         A pointer to the Highs instance.\n * @param current_value A pointer to the current value of the option.\n * @param default_value A pointer to the default value of the option.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getStringOptionValues(const void* highs, const char* option,\n                                     char* current_value, char* default_value);\n\n/**\n * Get an int-valued info value.\n *\n * @param highs     A pointer to the Highs instance.\n * @param info      The name of the info item.\n * @param value     A reference to an integer that the result will be stored in.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getIntInfoValue(const void* highs, const char* info,\n                               HighsInt* value);\n\n/**\n * Get a double-valued info value.\n *\n * @param highs     A pointer to the Highs instance.\n * @param info      The name of the info item.\n * @param value     A reference to a double that the result will be stored in.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getDoubleInfoValue(const void* highs, const char* info,\n                                  double* value);\n\n/**\n * Get an int64-valued info value.\n *\n * @param highs     A pointer to the Highs instance.\n * @param info      The name of the info item.\n * @param value     A reference to an int64 that the result will be stored in.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getInt64InfoValue(const void* highs, const char* info,\n                                 int64_t* value);\n\n/**\n * Get the type expected by an info item.\n *\n * @param highs     A pointer to the Highs instance.\n * @param info      The name of the info item.\n * @param type      A HighsInt in which the corresponding `kHighsOptionType`\n *                  constant is stored.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getInfoType(const void* highs, const char* info, HighsInt* type);\n\n/**\n * Get the primal and dual solution from an optimized model.\n *\n * @param highs      A pointer to the Highs instance.\n * @param col_value  An array of length [num_col], to be filled with primal\n *                   column values.\n * @param col_dual   An array of length [num_col], to be filled with dual column\n *                   values.\n * @param row_value  An array of length [num_row], to be filled with primal row\n *                   values.\n * @param row_dual   An array of length [num_row], to be filled with dual row\n *                   values.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getSolution(const void* highs, double* col_value,\n                           double* col_dual, double* row_value,\n                           double* row_dual);\n\n/**\n * Given a linear program with a basic feasible solution, get the column and row\n * basis statuses.\n *\n * @param highs       A pointer to the Highs instance.\n * @param col_status  An array of length [num_col], to be filled with the column\n *                    basis statuses in the form of a `kHighsBasisStatus`\n *                    constant.\n * @param row_status  An array of length [num_row], to be filled with the row\n *                    basis statuses in the form of a `kHighsBasisStatus`\n *                    constant.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getBasis(const void* highs, HighsInt* col_status,\n                        HighsInt* row_status);\n\n/**\n * Return the optimization status of the model in the form of a\n * `kHighsModelStatus` constant.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns An integer corresponding to the `kHighsModelStatus` constant\n */\nHighsInt Highs_getModelStatus(const void* highs);\n\n/**\n * Indicates whether a dual ray that is a certificate of primal\n * infeasibility currently exists, and (at the expense of solving an\n * LP) gets it if it does not and dual_ray_value is not nullptr.\n *\n * @param highs             A pointer to the Highs instance.\n * @param has_dual_ray      A pointer to a HighsInt to store 1 if a dual ray\n *                          currently exists.\n * @param dual_ray_value    An array of length [num_row] filled with the\n *                          unbounded ray.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getDualRay(const void* highs, HighsInt* has_dual_ray,\n                          double* dual_ray_value);\n\n/**\n * Indicates whether a dual unboundedness direction (corresponding to a\n * certificate of primal infeasibility) exists, and (at the expense of\n * solving an LP) gets it if it does not and\n * dual_unboundedness_direction is not nullptr\n *\n * @param highs                                   A pointer to the Highs\n *                                                instance.\n * @param has_dual_unboundedness_direction        A pointer to a HighsInt to\n *                                                store 1 if the dual\n *                                                unboundedness direction\n *                                                exists.\n * @param dual_unboundedness_direction_value      An array of length [num_col]\n *                                                filled with the unboundedness\n *                                                direction.\n */\nHighsInt Highs_getDualUnboundednessDirection(\n    const void* highs, HighsInt* has_dual_unboundedness_direction,\n    double* dual_unboundedness_direction_value);\n\n/**\n * Indicates whether a primal ray that is a certificate of primal\n * unboundedness currently exists, and (at the expense of solving an\n * LP) gets it if it does not and primal_ray_value is not nullptr.\n *\n * @param highs             A pointer to the Highs instance.\n * @param has_primal_ray    A pointer to a HighsInt to store 1 if the primal ray\n *                          exists.\n * @param primal_ray_value  An array of length [num_col] filled with the\n *                          unbounded ray.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getPrimalRay(const void* highs, HighsInt* has_primal_ray,\n                            double* primal_ray_value);\n\n/**\n * Get the primal objective function value.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns The primal objective function value\n */\ndouble Highs_getObjectiveValue(const void* highs);\n\n/**\n * Get the indices of the rows and columns that make up the basis matrix ``B``\n * of a basic feasible solution.\n *\n * Non-negative entries are indices of columns, and negative entries are\n * `-row_index - 1`. For example, `{1, -1}` would be the second column and first\n * row.\n *\n * The order of these rows and columns is important for calls to the functions:\n *\n *  - `Highs_getBasisInverseRow`\n *  - `Highs_getBasisInverseCol`\n *  - `Highs_getBasisSolve`\n *  - `Highs_getBasisTransposeSolve`\n *  - `Highs_getReducedRow`\n *  - `Highs_getReducedColumn`\n *\n * @param highs             A pointer to the Highs instance.\n * @param basic_variables   An array of size [num_rows], filled with the indices\n *                          of the basic variables.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getBasicVariables(const void* highs, HighsInt* basic_variables);\n\n/**\n * Get a row of the inverse basis matrix ``B^{-1}``.\n *\n * See `Highs_getBasicVariables` for a description of the ``B`` matrix.\n *\n * The arrays `row_vector` and `row_index` must have an allocated length of\n * [num_row]. However, check `row_num_nz` to see how many non-zero elements are\n * actually stored.\n *\n * @param highs         A pointer to the Highs instance.\n * @param row           The index of the row to compute.\n * @param row_vector    An array of length [num_row] in which to store the\n *                      values of the non-zero elements.\n * @param row_num_nz    The number of non-zeros in the row.\n * @param row_index     An array of length [num_row] in which to store the\n *                      indices of the non-zero elements.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getBasisInverseRow(const void* highs, const HighsInt row,\n                                  double* row_vector, HighsInt* row_num_nz,\n                                  HighsInt* row_index);\n\n/**\n * Get a column of the inverse basis matrix ``B^{-1}``.\n *\n * See `Highs_getBasicVariables` for a description of the ``B`` matrix.\n *\n * The arrays `col_vector` and `col_index` must have an allocated length of\n * [num_row]. However, check `col_num_nz` to see how many non-zero elements are\n * actually stored.\n *\n * @param highs         A pointer to the Highs instance.\n * @param col           The index of the column to compute.\n * @param col_vector    An array of length [num_row] in which to store the\n *                      values of the non-zero elements.\n * @param col_num_nz    The number of non-zeros in the column.\n * @param col_index     An array of length [num_row] in which to store the\n *                      indices of the non-zero elements.\n\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getBasisInverseCol(const void* highs, const HighsInt col,\n                                  double* col_vector, HighsInt* col_num_nz,\n                                  HighsInt* col_index);\n\n/**\n * Compute ``\\mathbf{x}=B^{-1}\\mathbf{b}`` for a given vector\n * ``\\mathbf{b}``.\n *\n * See `Highs_getBasicVariables` for a description of the ``B`` matrix.\n *\n * The arrays `solution_vector` and `solution_index` must have an allocated\n * length of [num_row]. However, check `solution_num_nz` to see how many\n * non-zero elements are actually stored.\n *\n * @param highs             A pointer to the Highs instance.\n * @param rhs               The right-hand side vector ``b``.\n * @param solution_vector   An array of length [num_row] in which to store the\n *                          values of the non-zero elements.\n * @param solution_num_nz   The number of non-zeros in the solution.\n * @param solution_index    An array of length [num_row] in which to store the\n *                          indices of the non-zero elements.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getBasisSolve(const void* highs, const double* rhs,\n                             double* solution_vector, HighsInt* solution_num_nz,\n                             HighsInt* solution_index);\n\n/**\n * Compute ``\\mathbf{x}=B^{-T}\\mathbf{b}`` for a given vector\n * ``\\mathbf{b}``.\n *\n * See `Highs_getBasicVariables` for a description of the ``B`` matrix.\n *\n * The arrays `solution_vector` and `solution_index` must have an allocated\n * length of [num_row]. However, check `solution_num_nz` to see how many\n * non-zero elements are actually stored.\n *\n * @param highs             A pointer to the Highs instance.\n * @param rhs               The right-hand side vector ``b``\n * @param solution_vector   An array of length [num_row] in which to store the\n *                          values of the non-zero elements.\n * @param solution_num_nz   The number of non-zeros in the solution.\n * @param solution_index    An array of length [num_row] in which to store the\n *                          indices of the non-zero elements.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getBasisTransposeSolve(const void* highs, const double* rhs,\n                                      double* solution_vector,\n                                      HighsInt* solution_nz,\n                                      HighsInt* solution_index);\n\n/**\n * Compute a row of ``B^{-1}A``.\n *\n * See `Highs_getBasicVariables` for a description of the ``B`` matrix.\n *\n * The arrays `row_vector` and `row_index` must have an allocated length of\n * [num_col]. However, check `row_num_nz` to see how many non-zero elements are\n * actually stored.\n *\n * @param highs         A pointer to the Highs instance.\n * @param row           The index of the row to compute.\n * @param row_vector    An array of length [num_col] in which to store the\n *                      values of the non-zero elements.\n * @param row_num_nz    The number of non-zeros in the row.\n * @param row_index     An array of length [num_col] in which to store the\n *                      indices of the non-zero elements.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getReducedRow(const void* highs, const HighsInt row,\n                             double* row_vector, HighsInt* row_num_nz,\n                             HighsInt* row_index);\n\n/**\n * Compute a column of ``B^{-1}A``.\n *\n * See `Highs_getBasicVariables` for a description of the ``B`` matrix.\n *\n * The arrays `col_vector` and `col_index` must have an allocated length of\n * [num_row]. However, check `col_num_nz` to see how many non-zero elements are\n * actually stored.\n *\n * @param highs         A pointer to the Highs instance.\n * @param col           The index of the column to compute.\n * @param col_vector    An array of length [num_row] in which to store the\n*                       values of the non-zero elements.\n * @param col_num_nz    The number of non-zeros in the column.\n * @param col_index     An array of length [num_row] in which to store the\n*                       indices of the non-zero elements.\n\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getReducedColumn(const void* highs, const HighsInt col,\n                                double* col_vector, HighsInt* col_num_nz,\n                                HighsInt* col_index);\n\n/**\n * Set a basic feasible solution by passing the column and row basis statuses to\n * the model.\n *\n * @param highs       A pointer to the Highs instance.\n * @param col_status  an array of length [num_col] with the column basis status\n *                    in the form of `kHighsBasisStatus` constants\n * @param row_status  an array of length [num_row] with the row basis status\n *                    in the form of `kHighsBasisStatus` constants\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_setBasis(void* highs, const HighsInt* col_status,\n                        const HighsInt* row_status);\n\n/**\n * Set a logical basis in the model.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_setLogicalBasis(void* highs);\n\n/**\n * Set a solution by passing the column and row primal and dual solution values.\n *\n * For any values that are unavailable, pass NULL.\n *\n * @param highs       A pointer to the Highs instance.\n * @param col_value   An array of length [num_col] with the column solution\n *                    values.\n * @param row_value   An array of length [num_row] with the row solution\n *                    values.\n * @param col_dual    An array of length [num_col] with the column dual values.\n * @param row_dual    An array of length [num_row] with the row dual values.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_setSolution(void* highs, const double* col_value,\n                           const double* row_value, const double* col_dual,\n                           const double* row_dual);\n\n/**\n * Set a partial primal solution by passing values for a set of variables\n *\n * @param highs       A pointer to the Highs instance.\n * @param num_entries Number of variables in the set\n * @param index       Indices of variables in the set\n * @param value       Values of variables in the set\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_setSparseSolution(void* highs, const HighsInt num_entries,\n                                 const HighsInt* index, const double* value);\n\n/**\n * Set the callback method to use for HiGHS\n *\n * @param highs              A pointer to the Highs instance.\n * @param user_callback      A pointer to the user callback\n * @param user_callback_data A pointer to the user callback data\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_setCallback(void* highs, HighsCCallbackType user_callback,\n                           void* user_callback_data);\n\n/**\n * Start callback of given type\n *\n * @param highs         A pointer to the Highs instance.\n * @param callback_type The type of callback to be started\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_startCallback(void* highs, const HighsInt callback_type);\n\n/**\n * Stop callback of given type\n *\n * @param highs         A pointer to the Highs instance.\n * @param callback_type The type of callback to be stopped\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_stopCallback(void* highs, const HighsInt callback_type);\n\n/**\n * Return the cumulative wall-clock time spent in `Highs_run`.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns The cumulative wall-clock time spent in `Highs_run`\n */\ndouble Highs_getRunTime(const void* highs);\n\n/**\n * Reset the clocks in a `highs` model.\n *\n * Each `highs` model contains a single instance of clock that records how much\n * time is spent in various parts of the algorithm. This clock is not reset on\n * entry to `Highs_run`, so repeated calls to `Highs_run` report the cumulative\n * time spent in the algorithm. A side-effect is that this will trigger a time\n * limit termination once the cumulative run time exceeds the time limit, rather\n * than the run time of each individual call to `Highs_run`.\n *\n * As a work-around, call `Highs_zeroAllClocks` before each call to `Highs_run`.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_zeroAllClocks(const void* highs);\n\n/**\n * Add a new column (variable) to the model.\n *\n * @param highs         A pointer to the Highs instance.\n * @param cost          The objective coefficient of the column.\n * @param lower         The lower bound of the column.\n * @param upper         The upper bound of the column.\n * @param num_new_nz    The number of non-zeros in the column.\n * @param index         An array of size [num_new_nz] with the row indices.\n * @param value         An array of size [num_new_nz] with row values.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_addCol(void* highs, const double cost, const double lower,\n                      const double upper, const HighsInt num_new_nz,\n                      const HighsInt* index, const double* value);\n\n/**\n * Add multiple columns (variables) to the model.\n *\n * @param highs         A pointer to the Highs instance.\n * @param num_new_col   The number of new columns to add.\n * @param costs         An array of size [num_new_col] with objective\n *                      coefficients.\n * @param lower         An array of size [num_new_col] with lower bounds.\n * @param upper         An array of size [num_new_col] with upper bounds.\n * @param num_new_nz    The number of new nonzeros in the constraint matrix.\n * @param starts        The constraint coefficients are given as a matrix in\n *                      compressed sparse column form by the arrays `starts`,\n *                      `index`, and `value`. `starts` is an array of size\n *                      [num_new_cols] with the start index of each row in\n *                      indices and values.\n * @param index         An array of size [num_new_nz] with row indices.\n * @param value         An array of size [num_new_nz] with row values.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_addCols(void* highs, const HighsInt num_new_col,\n                       const double* costs, const double* lower,\n                       const double* upper, const HighsInt num_new_nz,\n                       const HighsInt* starts, const HighsInt* index,\n                       const double* value);\n\n/**\n * Add a new variable to the model.\n *\n * @param highs         A pointer to the Highs instance.\n * @param lower         The lower bound of the column.\n * @param upper         The upper bound of the column.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_addVar(void* highs, const double lower, const double upper);\n\n/**\n * Add multiple variables to the model.\n *\n * @param highs         A pointer to the Highs instance.\n * @param num_new_var   The number of new variables to add.\n * @param lower         An array of size [num_new_var] with lower bounds.\n * @param upper         An array of size [num_new_var] with upper bounds.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_addVars(void* highs, const HighsInt num_new_var,\n                       const double* lower, const double* upper);\n\n/**\n * Add a new row (a linear constraint) to the model.\n *\n * @param highs         A pointer to the Highs instance.\n * @param lower         The lower bound of the row.\n * @param upper         The upper bound of the row.\n * @param num_new_nz    The number of non-zeros in the row\n * @param index         An array of size [num_new_nz] with column indices.\n * @param value         An array of size [num_new_nz] with column values.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_addRow(void* highs, const double lower, const double upper,\n                      const HighsInt num_new_nz, const HighsInt* index,\n                      const double* value);\n\n/**\n * Add multiple rows (linear constraints) to the model.\n *\n * @param highs         A pointer to the Highs instance.\n * @param num_new_row   The number of new rows to add\n * @param lower         An array of size [num_new_row] with the lower bounds of\n *                      the rows.\n * @param upper         An array of size [num_new_row] with the upper bounds of\n *                      the rows.\n * @param num_new_nz    The number of non-zeros in the rows.\n * @param starts        The constraint coefficients are given as a matrix in\n *                      compressed sparse row form by the arrays `starts`,\n *                      `index`, and `value`. `starts` is an array of size\n *                      [num_new_rows] with the start index of each row in\n *                      indices and values.\n * @param index         An array of size [num_new_nz] with column indices.\n * @param value         An array of size [num_new_nz] with column values.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_addRows(void* highs, const HighsInt num_new_row,\n                       const double* lower, const double* upper,\n                       const HighsInt num_new_nz, const HighsInt* starts,\n                       const HighsInt* index, const double* value);\n\n/**\n * Ensure that the constraint matrix of the incumbent model is stored\n * column-wise.\n *\n * @param highs         A pointer to the Highs instance.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_ensureColwise(void* highs);\n\n/**\n * Ensure that the constraint matrix of the incumbent model is stored row-wise.\n *\n * @param highs         A pointer to the Highs instance.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_ensureRowwise(void* highs);\n\n/**\n * Change the objective sense of the model.\n *\n * @param highs     A pointer to the Highs instance.\n * @param sense     The new optimization sense in the form of a `kHighsObjSense`\n *                  constant.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeObjectiveSense(void* highs, const HighsInt sense);\n\n/**\n * Change the objective offset of the model.\n *\n * @param highs     A pointer to the Highs instance.\n * @param offset    The new objective offset.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeObjectiveOffset(void* highs, const double offset);\n\n/**\n * Change the integrality of a column.\n *\n * @param highs         A pointer to the Highs instance.\n * @param col           The column index to change.\n * @param integrality   The new integrality of the column in the form of a\n *                      `kHighsVarType` constant.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeColIntegrality(void* highs, const HighsInt col,\n                                    const HighsInt integrality);\n\n/**\n * Change the integrality of multiple adjacent columns.\n *\n * @param highs         A pointer to the Highs instance.\n * @param from_col      The index of the first column whose integrality changes.\n * @param to_col        The index of the last column whose integrality\n *                      changes.\n * @param integrality   An array of length [to_col - from_col + 1] with the new\n *                      integralities of the columns in the form of\n *                      `kHighsVarType` constants.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeColsIntegralityByRange(void* highs,\n                                            const HighsInt from_col,\n                                            const HighsInt to_col,\n                                            const HighsInt* integrality);\n\n/**\n * Change the integrality of multiple columns given by an array of indices.\n *\n * @param highs             A pointer to the Highs instance.\n * @param num_set_entries   The number of columns to change.\n * @param set               An array of size [num_set_entries] with the indices\n *                          of the columns to change.\n * @param integrality       An array of length [num_set_entries] with the new\n *                          integralities of the columns in the form of\n *                          `kHighsVarType` constants.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeColsIntegralityBySet(void* highs,\n                                          const HighsInt num_set_entries,\n                                          const HighsInt* set,\n                                          const HighsInt* integrality);\n\n/**\n * Change the integrality of multiple columns given by a mask.\n *\n * @param highs         A pointer to the Highs instance.\n * @param mask          An array of length [num_col] with 1 if the column\n *                      integrality should be changed and 0 otherwise.\n * @param integrality   An array of length [num_col] with the new\n *                      integralities of the columns in the form of\n *                      `kHighsVarType` constants.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeColsIntegralityByMask(void* highs, const HighsInt* mask,\n                                           const HighsInt* integrality);\n\n/**\n * Clear the integrality of all columns\n *\n * @param highs         A pointer to the Highs instance.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_clearIntegrality(void* highs);\n\n/**\n * Change the objective coefficient of a column.\n *\n * @param highs     A pointer to the Highs instance.\n * @param col       The index of the column fo change.\n * @param cost      The new objective coefficient.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeColCost(void* highs, const HighsInt col,\n                             const double cost);\n\n/**\n * Change the cost coefficients of multiple adjacent columns.\n *\n * @param highs     A pointer to the Highs instance.\n * @param from_col  The index of the first column whose cost changes.\n * @param to_col    The index of the last column whose cost changes.\n * @param cost      An array of length [to_col - from_col + 1] with the new\n *                  objective coefficients.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeColsCostByRange(void* highs, const HighsInt from_col,\n                                     const HighsInt to_col, const double* cost);\n\n/**\n * Change the cost of multiple columns given by an array of indices.\n *\n * @param highs             A pointer to the Highs instance.\n * @param num_set_entries   The number of columns to change.\n * @param set               An array of size [num_set_entries] with the indices\n *                          of the columns to change.\n * @param cost              An array of length [num_set_entries] with the new\n *                          costs of the columns.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeColsCostBySet(void* highs, const HighsInt num_set_entries,\n                                   const HighsInt* set, const double* cost);\n\n/**\n * Change the cost of multiple columns given by a mask.\n *\n * @param highs     A pointer to the Highs instance.\n * @param mask      An array of length [num_col] with 1 if the column\n *                  cost should be changed and 0 otherwise.\n * @param cost      An array of length [num_col] with the new costs.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeColsCostByMask(void* highs, const HighsInt* mask,\n                                    const double* cost);\n\n/**\n * Change the variable bounds of a column.\n *\n * @param highs     A pointer to the Highs instance.\n * @param col       The index of the column whose bounds are to change.\n * @param lower     The new lower bound.\n * @param upper     The new upper bound.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeColBounds(void* highs, const HighsInt col,\n                               const double lower, const double upper);\n\n/**\n * Change the variable bounds of multiple adjacent columns.\n *\n * @param highs     A pointer to the Highs instance.\n * @param from_col  The index of the first column whose bound changes.\n * @param to_col    The index of the last column whose bound changes.\n * @param lower     An array of length [to_col - from_col + 1] with the new\n *                  lower bounds.\n * @param upper     An array of length [to_col - from_col + 1] with the new\n *                  upper bounds.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeColsBoundsByRange(void* highs, const HighsInt from_col,\n                                       const HighsInt to_col,\n                                       const double* lower,\n                                       const double* upper);\n\n/**\n * Change the bounds of multiple columns given by an array of indices.\n *\n * @param highs             A pointer to the Highs instance.\n * @param num_set_entries   The number of columns to change.\n * @param set               An array of size [num_set_entries] with the indices\n *                          of the columns to change.\n * @param lower             An array of length [num_set_entries] with the new\n *                          lower bounds.\n * @param upper             An array of length [num_set_entries] with the new\n *                          upper bounds.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeColsBoundsBySet(void* highs,\n                                     const HighsInt num_set_entries,\n                                     const HighsInt* set, const double* lower,\n                                     const double* upper);\n\n/**\n * Change the variable bounds of multiple columns given by a mask.\n *\n * @param highs     A pointer to the Highs instance.\n * @param mask      An array of length [num_col] with 1 if the column\n *                  bounds should be changed and 0 otherwise.\n * @param lower     An array of length [num_col] with the new lower bounds.\n * @param upper     An array of length [num_col] with the new upper bounds.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeColsBoundsByMask(void* highs, const HighsInt* mask,\n                                      const double* lower, const double* upper);\n\n/**\n * Change the bounds of a row.\n *\n * @param highs     A pointer to the Highs instance.\n * @param row       The index of the row whose bounds are to change.\n * @param lower     The new lower bound.\n * @param upper     The new upper bound.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeRowBounds(void* highs, const HighsInt row,\n                               const double lower, const double upper);\n\n/**\n * Change the variable bounds of multiple adjacent rows.\n *\n * @param highs     A pointer to the Highs instance.\n * @param from_row  The index of the first row whose bound changes.\n * @param to_row    The index of the last row whose bound changes.\n * @param lower     An array of length [to_row - from_row + 1] with the new\n *                  lower bounds.\n * @param upper     An array of length [to_row - from_row + 1] with the new\n *                  upper bounds.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeRowsBoundsByRange(void* highs, const HighsInt from_row,\n                                       const HighsInt to_row,\n                                       const double* lower,\n                                       const double* upper);\n\n/**\n * Change the bounds of multiple rows given by an array of indices.\n *\n * @param highs             A pointer to the Highs instance.\n * @param num_set_entries   The number of rows to change.\n * @param set               An array of size [num_set_entries] with the indices\n *                          of the rows to change.\n * @param lower             An array of length [num_set_entries] with the new\n *                          lower bounds.\n * @param upper             An array of length [num_set_entries] with the new\n *                          upper bounds.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeRowsBoundsBySet(void* highs,\n                                     const HighsInt num_set_entries,\n                                     const HighsInt* set, const double* lower,\n                                     const double* upper);\n\n/**\n * Change the bounds of multiple rows given by a mask.\n *\n * @param highs     A pointer to the Highs instance.\n * @param mask      An array of length [num_row] with 1 if the row\n *                  bounds should be changed and 0 otherwise.\n * @param lower     An array of length [num_row] with the new lower bounds.\n * @param upper     An array of length [num_row] with the new upper bounds.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeRowsBoundsByMask(void* highs, const HighsInt* mask,\n                                      const double* lower, const double* upper);\n\n/**\n * Change a coefficient in the constraint matrix.\n *\n * @param highs     A pointer to the Highs instance.\n * @param row       The index of the row to change.\n * @param col       The index of the column to change.\n * @param value     The new constraint coefficient.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_changeCoeff(void* highs, const HighsInt row, const HighsInt col,\n                           const double value);\n\n/**\n * Get the objective sense.\n *\n * @param highs     A pointer to the Highs instance.\n * @param sense     The location in which the current objective sense should be\n *                  placed. The sense is a `kHighsObjSense` constant.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getObjectiveSense(const void* highs, HighsInt* sense);\n\n/**\n * Get the objective offset.\n *\n * @param highs     A pointer to the Highs instance.\n * @param offset    The location in which the current objective offset should be\n *                  placed.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getObjectiveOffset(const void* highs, double* offset);\n\n/**\n * Get data associated with multiple adjacent columns from the model.\n *\n * To query the constraint coefficients, this function should be called twice.\n *\n * First, call this function with `matrix_start`, `matrix_index`, and\n * `matrix_value` as `NULL`. This call will populate `num_nz` with the number of\n * nonzero elements in the corresponding section of the constraint matrix.\n *\n * Second, allocate new `matrix_index` and `matrix_value` arrays of length\n * `num_nz` and call this function again to populate the new arrays with their\n * contents.\n *\n * @param highs         A pointer to the Highs instance.\n * @param from_col      The first column for which to query data for.\n * @param to_col        The last column (inclusive) for which to query data for.\n * @param num_col       A HighsInt populated with the number of columns got from\n *                      the model (this should equal `to_col - from_col + 1`).\n * @param costs         An array of size [to_col - from_col + 1] for the column\n *                      cost coefficients.\n * @param lower         An array of size [to_col - from_col + 1] for the column\n *                      lower bounds.\n * @param upper         An array of size [to_col - from_col + 1] for the column\n *                      upper bounds.\n * @param num_nz        A HighsInt to be populated with the number of non-zero\n *                      elements in the constraint matrix.\n * @param matrix_start  An array of size [to_col - from_col + 1] with the start\n *                      indices of each column in `matrix_index` and\n *                      `matrix_value`.\n * @param matrix_index  An array of size [num_nz] with the row indices of each\n *                      element in the constraint matrix.\n * @param matrix_value  An array of size [num_nz] with the non-zero elements of\n *                      the constraint matrix.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getColsByRange(const void* highs, const HighsInt from_col,\n                              const HighsInt to_col, HighsInt* num_col,\n                              double* costs, double* lower, double* upper,\n                              HighsInt* num_nz, HighsInt* matrix_start,\n                              HighsInt* matrix_index, double* matrix_value);\n\n/**\n * Get data associated with multiple columns given by an array.\n *\n * This function is identical to `Highs_getColsByRange`, except for how the\n * columns are specified.\n *\n * @param num_set_indices   The number of indices in `set`.\n * @param set               An array of size [num_set_entries] with the column\n *                          indices to get.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getColsBySet(const void* highs, const HighsInt num_set_entries,\n                            const HighsInt* set, HighsInt* num_col,\n                            double* costs, double* lower, double* upper,\n                            HighsInt* num_nz, HighsInt* matrix_start,\n                            HighsInt* matrix_index, double* matrix_value);\n\n/**\n * Get data associated with multiple columns given by a mask.\n *\n * This function is identical to `Highs_getColsByRange`, except for how the\n * columns are specified.\n *\n * @param mask  An array of length [num_col] containing a `1` to get the column\n *              and `0` otherwise.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getColsByMask(const void* highs, const HighsInt* mask,\n                             HighsInt* num_col, double* costs, double* lower,\n                             double* upper, HighsInt* num_nz,\n                             HighsInt* matrix_start, HighsInt* matrix_index,\n                             double* matrix_value);\n\n/**\n * Get data associated with multiple adjacent rows from the model.\n *\n * To query the constraint coefficients, this function should be called twice.\n *\n * First, call this function with `matrix_start`, `matrix_index`, and\n * `matrix_value` as `NULL`. This call will populate `num_nz` with the number of\n * nonzero elements in the corresponding section of the constraint matrix.\n *\n * Second, allocate new `matrix_index` and `matrix_value` arrays of length\n * `num_nz` and call this function again to populate the new arrays with their\n * contents.\n *\n * @param highs         A pointer to the Highs instance.\n * @param from_row      The first row for which to query data for.\n * @param to_row        The last row (inclusive) for which to query data for.\n * @param num_row       A HighsInt to be populated with the number of rows got\n *                      from the model.\n * @param lower         An array of size [to_row - from_row + 1] for the row\n *                      lower bounds.\n * @param upper         An array of size [to_row - from_row + 1] for the row\n *                      upper bounds.\n * @param num_nz        A HighsInt to be populated with the number of non-zero\n *                      elements in the constraint matrix.\n * @param matrix_start  An array of size [to_row - from_row + 1] with the start\n *                      indices of each row in `matrix_index` and\n *                      `matrix_value`.\n * @param matrix_index  An array of size [num_nz] with the column indices of\n *                      each element in the constraint matrix.\n * @param matrix_value  An array of size [num_nz] with the non-zero elements of\n *                      the constraint matrix.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getRowsByRange(const void* highs, const HighsInt from_row,\n                              const HighsInt to_row, HighsInt* num_row,\n                              double* lower, double* upper, HighsInt* num_nz,\n                              HighsInt* matrix_start, HighsInt* matrix_index,\n                              double* matrix_value);\n\n/**\n * Get data associated with multiple rows given by an array.\n *\n * This function is identical to `Highs_getRowsByRange`, except for how the\n * rows are specified.\n *\n * @param num_set_indices   The number of indices in `set`.\n * @param set               An array of size [num_set_entries] containing the\n *                          row indices to get.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getRowsBySet(const void* highs, const HighsInt num_set_entries,\n                            const HighsInt* set, HighsInt* num_row,\n                            double* lower, double* upper, HighsInt* num_nz,\n                            HighsInt* matrix_start, HighsInt* matrix_index,\n                            double* matrix_value);\n\n/**\n * Get data associated with multiple rows given by a mask.\n *\n * This function is identical to `Highs_getRowsByRange`, except for how the\n * rows are specified.\n *\n * @param mask  An array of length [num_row] containing a `1` to get the row and\n *              `0` otherwise.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getRowsByMask(const void* highs, const HighsInt* mask,\n                             HighsInt* num_row, double* lower, double* upper,\n                             HighsInt* num_nz, HighsInt* matrix_start,\n                             HighsInt* matrix_index, double* matrix_value);\n/**\n * Get the name of a row.\n *\n * @param row   The index of the row to query.\n * @param name  A pointer in which to store the name of the row. This must have\n *              length `kHighsMaximumStringLength`.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getRowName(const void* highs, const HighsInt row, char* name);\n\n/**\n * Get the index of a row from its name.\n *\n * If multiple rows have the same name, or if no row exists with `name`, this\n * function returns `kHighsStatusError`.\n *\n * @param name A pointer of the name of the row to query.\n * @param row  A pointer in which to store the index of the row\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getRowByName(const void* highs, const char* name, HighsInt* row);\n\n/**\n * Get the name of a column.\n *\n * @param col   The index of the column to query.\n * @param name  A pointer in which to store the name of the column. This must\n *              have length `kHighsMaximumStringLength`.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getColName(const void* highs, const HighsInt col, char* name);\n\n/**\n * Get the index of a column from its name.\n *\n * If multiple columns have the same name, or if no column exists with `name`,\n * this function returns `kHighsStatusError`.\n *\n * @param name A pointer of the name of the column to query.\n * @param col  A pointer in which to store the index of the column\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getColByName(const void* highs, const char* name, HighsInt* col);\n\n/**\n * Get the integrality of a column.\n *\n * @param col          The index of the column to query.\n * @param integrality  A HighsInt in which the integrality of the column should\n *                     be placed. The integer is one of the `kHighsVarTypeXXX`\n *                     constants.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getColIntegrality(const void* highs, const HighsInt col,\n                                 HighsInt* integrality);\n\n/**\n * Delete multiple adjacent columns.\n *\n * @param highs     A pointer to the Highs instance.\n * @param from_col  The index of the first column to delete.\n * @param to_col    The index of the last column to delete.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_deleteColsByRange(void* highs, const HighsInt from_col,\n                                 const HighsInt to_col);\n\n/**\n * Delete multiple columns given by an array of indices.\n *\n * @param highs             A pointer to the Highs instance.\n * @param num_set_entries   The number of columns to delete.\n * @param set               An array of size [num_set_entries] with the indices\n *                          of the columns to delete.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_deleteColsBySet(void* highs, const HighsInt num_set_entries,\n                               const HighsInt* set);\n\n/**\n * Delete multiple columns given by a mask.\n *\n * @param highs     A pointer to the Highs instance.\n * @param mask      An array of length [num_col] with 1 if the column\n *                  should be deleted and 0 otherwise.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_deleteColsByMask(void* highs, HighsInt* mask);\n\n/**\n * Delete multiple adjacent rows.\n *\n * @param highs     A pointer to the Highs instance.\n * @param from_row  The index of the first row to delete.\n * @param to_row    The index of the last row to delete.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_deleteRowsByRange(void* highs, const HighsInt from_row,\n                                 const HighsInt to_row);\n\n/**\n * Delete multiple rows given by an array of indices.\n *\n * @param highs             A pointer to the Highs instance.\n * @param num_set_entries   The number of rows to delete.\n * @param set               An array of size [num_set_entries] with the indices\n *                          of the rows to delete.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_deleteRowsBySet(void* highs, const HighsInt num_set_entries,\n                               const HighsInt* set);\n\n/**\n * Delete multiple rows given by a mask.\n *\n * @param highs     A pointer to the Highs instance.\n * @param mask      An array of length [num_row] with `1` if the row should be\n *                  deleted and `0` otherwise. The new index of any column not\n *                  deleted is stored in place of the value `0`.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_deleteRowsByMask(void* highs, HighsInt* mask);\n\n/**\n * Scale a column by a constant.\n *\n * Scaling a column modifies the elements in the constraint matrix, the variable\n * bounds, and the objective coefficient.\n *\n * @param highs     A pointer to the Highs instance.\n * @param col       The index of the column to scale.\n * @param scaleval  The value by which to scale the column. If `scaleval < 0`,\n *                  the variable bounds flipped.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_scaleCol(void* highs, const HighsInt col, const double scaleval);\n\n/**\n * Scale a row by a constant.\n *\n * @param highs     A pointer to the Highs instance.\n * @param row       The index of the row to scale.\n * @param scaleval  The value by which to scale the row. If `scaleval < 0`, the\n *                  row bounds are flipped.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_scaleRow(void* highs, const HighsInt row, const double scaleval);\n\n/**\n * Return the value of infinity used by HiGHS.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns The value of infinity used by HiGHS.\n */\ndouble Highs_getInfinity(const void* highs);\n\n/**\n * Return the size of integers used by HiGHS.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns The size of integers used by HiGHS.\n */\nHighsInt Highs_getSizeofHighsInt(const void* highs);\n\n/**\n * Return the number of columns in the model.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns The number of columns in the model.\n */\nHighsInt Highs_getNumCol(const void* highs);\n\n/**\n * Return the number of rows in the model.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns The number of rows in the model.\n */\nHighsInt Highs_getNumRow(const void* highs);\n\n/**\n * Return the number of nonzeros in the constraint matrix of the model.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns The number of nonzeros in the constraint matrix of the model.\n */\nHighsInt Highs_getNumNz(const void* highs);\n\n/**\n * Return the number of nonzeroes in the Hessian matrix of the model.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns The number of nonzeroes in the Hessian matrix of the model.\n */\nHighsInt Highs_getHessianNumNz(const void* highs);\n\n/**\n * Return the number of columns in the presolved model.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns The number of columns in the presolved model.\n */\nHighsInt Highs_getPresolvedNumCol(const void* highs);\n\n/**\n * Return the number of rows in the presolved model.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns The number of rows in the presolved model.\n */\nHighsInt Highs_getPresolvedNumRow(const void* highs);\n\n/**\n * Return the number of nonzeros in the constraint matrix of the presolved\n * model.\n *\n * @param highs     A pointer to the Highs instance.\n *\n * @returns The number of nonzeros in the constraint matrix of the presolved\n * model.\n */\nHighsInt Highs_getPresolvedNumNz(const void* highs);\n\n/**\n * Get the data from a HiGHS model.\n *\n * The input arguments have the same meaning (in a different order) to those\n * used in `Highs_passModel`.\n *\n * Note that all arrays must be pre-allocated to the correct size before calling\n * `Highs_getModel`. Use the following query methods to check the appropriate\n * size:\n *  - `Highs_getNumCol`\n *  - `Highs_getNumRow`\n *  - `Highs_getNumNz`\n *  - `Highs_getHessianNumNz`\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getModel(const void* highs, const HighsInt a_format,\n                        const HighsInt q_format, HighsInt* num_col,\n                        HighsInt* num_row, HighsInt* num_nz,\n                        HighsInt* hessian_num_nz, HighsInt* sense,\n                        double* offset, double* col_cost, double* col_lower,\n                        double* col_upper, double* row_lower, double* row_upper,\n                        HighsInt* a_start, HighsInt* a_index, double* a_value,\n                        HighsInt* q_start, HighsInt* q_index, double* q_value,\n                        HighsInt* integrality);\n\n/**\n * Get the data from a HiGHS LP.\n *\n * The input arguments have the same meaning (in a different order) to those\n * used in `Highs_passModel`.\n *\n * Note that all arrays must be pre-allocated to the correct size before calling\n * `Highs_getModel`. Use the following query methods to check the appropriate\n * size:\n *  - `Highs_getNumCol`\n *  - `Highs_getNumRow`\n *  - `Highs_getNumNz`\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getLp(const void* highs, const HighsInt a_format,\n                     HighsInt* num_col, HighsInt* num_row, HighsInt* num_nz,\n                     HighsInt* sense, double* offset, double* col_cost,\n                     double* col_lower, double* col_upper, double* row_lower,\n                     double* row_upper, HighsInt* a_start, HighsInt* a_index,\n                     double* a_value, HighsInt* integrality);\n\n/**\n * Get the data from a HiGHS presolved LP.\n *\n * The input arguments have the same meaning (in a different order) to those\n * used in `Highs_passModel`.\n *\n * Note that all arrays must be pre-allocated to the correct size before calling\n * `Highs_getModel`. Use the following query methods to check the appropriate\n * size:\n *  - `Highs_getPresolvedNumCol`\n *  - `Highs_getPresolvedNumRow`\n *  - `Highs_getPresolvedNumNz`\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getPresolvedLp(const void* highs, const HighsInt a_format,\n                              HighsInt* num_col, HighsInt* num_row,\n                              HighsInt* num_nz, HighsInt* sense, double* offset,\n                              double* col_cost, double* col_lower,\n                              double* col_upper, double* row_lower,\n                              double* row_upper, HighsInt* a_start,\n                              HighsInt* a_index, double* a_value,\n                              HighsInt* integrality);\n\n/**\n * Get the data from a HiGHS IIS LP.\n *\n * The input arguments have the same meaning (in a different order) to those\n * used in `Highs_passModel`.\n *\n * Note that all arrays must be pre-allocated to the correct size before calling\n * `Highs_getModel`. Use the following query methods to check the appropriate\n * size:\n *  - `Highs_getPresolvedNumCol`\n *  - `Highs_getPresolvedNumRow`\n *  - `Highs_getPresolvedNumNz`\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getIisLp(const void* highs, const HighsInt a_format,\n                        HighsInt* num_col, HighsInt* num_row, HighsInt* num_nz,\n                        HighsInt* sense, double* offset, double* col_cost,\n                        double* col_lower, double* col_upper, double* row_lower,\n                        double* row_upper, HighsInt* a_start, HighsInt* a_index,\n                        double* a_value, HighsInt* integrality);\n\n/**\n * Get the LP corresponding to a MIP with non-continuous variables\n * fixed at a MIP solution\n *\n * The input arguments have the same meaning (in a different order) to those\n * used in `Highs_passModel`.\n *\n * Note that all arrays must be pre-allocated to the correct size before calling\n * `Highs_getModel`. Use the following query methods to check the appropriate\n * size:\n *  - `Highs_getNumCol`\n *  - `Highs_getNumRow`\n *  - `Highs_getNumNz`\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getFixedLp(const void* highs, const HighsInt a_format,\n                          HighsInt* num_col, HighsInt* num_row,\n                          HighsInt* num_nz, HighsInt* sense, double* offset,\n                          double* col_cost, double* col_lower,\n                          double* col_upper, double* row_lower,\n                          double* row_upper, HighsInt* a_start,\n                          HighsInt* a_index, double* a_value);\n\n/**\n * Set a primal (and possibly dual) solution as a starting point, then run\n * crossover to compute a basic feasible solution.\n *\n * @param highs      A pointer to the Highs instance.\n * @param num_col    The number of variables.\n * @param num_row    The number of rows.\n * @param col_value  An array of length [num_col] with optimal primal solution\n *                   for each column.\n * @param col_dual   An array of length [num_col] with optimal dual solution for\n *                   each column. May be `NULL`, in which case no dual solution\n *                   is passed.\n * @param row_dual   An array of length [num_row] with optimal dual solution for\n *                   each row. . May be `NULL`, in which case no dual solution\n *                   is passed.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_crossover(void* highs, const HighsInt num_col,\n                         const HighsInt num_row, const double* col_value,\n                         const double* col_dual, const double* row_dual);\n\n/**\n * Compute the ranging information for all costs and bounds. For\n * nonbasic variables the ranging information is relative to the\n * active bound. For basic variables the ranging information relates\n * to...\n *\n * For any values that are not required, pass NULL.\n *\n * @param highs                  A pointer to the Highs instance.\n * @param col_cost_up_value      The upper range of the cost value\n * @param col_cost_up_objective  The objective at the upper cost range\n * @param col_cost_up_in_var     The variable entering the basis at the upper\n *                               cost range\n * @param col_cost_up_ou_var     The variable leaving the basis at the upper\n *                               cost range\n * @param col_cost_dn_value      The lower range of the cost value\n * @param col_cost_dn_objective  The objective at the lower cost range\n * @param col_cost_dn_in_var     The variable entering the basis at the lower\n *                               cost range\n * @param col_cost_dn_ou_var     The variable leaving the basis at the lower\n *                               cost range\n * @param col_bound_up_value     The upper range of the column bound value\n * @param col_bound_up_objective The objective at the upper column bound range\n * @param col_bound_up_in_var    The variable entering the basis at the upper\n *                               column bound range\n * @param col_bound_up_ou_var    The variable leaving the basis at the upper\n *                               column bound range\n * @param col_bound_dn_value     The lower range of the column bound value\n * @param col_bound_dn_objective The objective at the lower column bound range\n * @param col_bound_dn_in_var    The variable entering the basis at the lower\n *                               column bound range\n * @param col_bound_dn_ou_var    The variable leaving the basis at the lower\n *                               column bound range\n * @param row_bound_up_value     The upper range of the row bound value\n * @param row_bound_up_objective The objective at the upper row bound range\n * @param row_bound_up_in_var    The variable entering the basis at the upper\n *                               row bound range\n * @param row_bound_up_ou_var    The variable leaving the basis at the upper row\n *                               bound range\n * @param row_bound_dn_value     The lower range of the row bound value\n * @param row_bound_dn_objective The objective at the lower row bound range\n * @param row_bound_dn_in_var    The variable entering the basis at the lower\n *                               row bound range\n * @param row_bound_dn_ou_var    The variable leaving the basis at the lower row\n *                               bound range\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getRanging(\n    void* highs,\n    //\n    double* col_cost_up_value, double* col_cost_up_objective,\n    HighsInt* col_cost_up_in_var, HighsInt* col_cost_up_ou_var,\n    double* col_cost_dn_value, double* col_cost_dn_objective,\n    HighsInt* col_cost_dn_in_var, HighsInt* col_cost_dn_ou_var,\n    double* col_bound_up_value, double* col_bound_up_objective,\n    HighsInt* col_bound_up_in_var, HighsInt* col_bound_up_ou_var,\n    double* col_bound_dn_value, double* col_bound_dn_objective,\n    HighsInt* col_bound_dn_in_var, HighsInt* col_bound_dn_ou_var,\n    double* row_bound_up_value, double* row_bound_up_objective,\n    HighsInt* row_bound_up_in_var, HighsInt* row_bound_up_ou_var,\n    double* row_bound_dn_value, double* row_bound_dn_objective,\n    HighsInt* row_bound_dn_in_var, HighsInt* row_bound_dn_ou_var);\n\n/**\n * Compute the solution corresponding to a (possibly weighted) sum of\n * (allowable) infeasibilities in an LP/MIP.\n *\n * If local penalties are not defined, pass NULL, and the global\n * penalty will be used. Negative penalty values imply that the bound\n * or RHS value cannot be violated\n *\n * @param highs                             A pointer to the Highs instance.\n * @param const double global_lower_penalty The penalty for violating lower\n * bounds on variables\n * @param const double global_upper_penalty The penalty for violating upper\n * bounds on variables\n * @param const double global_rhs_penalty   The penalty for violating constraint\n * RHS values\n * @param const double* local_lower_penalty The penalties for violating specific\n * lower bounds on variables\n * @param const double* local_upper_penalty The penalties for violating specific\n * upper bounds on variables\n * @param const double* local_rhs_penalty   The penalties for violating specific\n * constraint RHS values\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\n\nHighsInt Highs_feasibilityRelaxation(void* highs,\n                                     const double global_lower_penalty,\n                                     const double global_upper_penalty,\n                                     const double global_rhs_penalty,\n                                     const double* local_lower_penalty,\n                                     const double* local_upper_penalty,\n                                     const double* local_rhs_penalty);\n\n/**\n * Attempt to compute an irreducible infeasibility subsystem (IIS) for\n * an LP, QP, or the relaxation of a MIP. If no IIS is found, then the\n * number of IIS columns and rows will be zero.\n *\n * @param highs                      A pointer to the Highs instance.\n * @param const HighsInt iis_num_col Number of columns in the IIS.\n * @param const HighsInt iis_num_row Number of rows in the IIS.\n * @param const HighsInt* col_index  An array of length [iis_num_col], to be\n *                                   filled with the indices of original\n *                                   variables in the IIS.\n * @param const HighsInt* row_index  An array of length [iis_num_col], to be\n *                                   filled with the indices of original\n *                                   constraints in the IIS.\n * @param const HighsInt* col_bound  An array of length [iis_num_col], to be\n *                                   filled with the bound status of variables\n *                                   in the IIS.\n * @param const HighsInt* row_bound  An array of length [iis_num_col], to be\n *                                   filled with the bound status of constraints\n *                                   in the IIS.\n * @param const HighsInt* col_status An array of length [num_col], to be\n *                                   filled with the IIS status of all original\n *                                   variables.\n * @param const HighsInt* row_status n array of length [num_col], to be\n *                                   filled with the IIS status of all original\n *                                   constraints.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_getIis(void* highs, HighsInt* iis_num_col, HighsInt* iis_num_row,\n                      HighsInt* col_index, HighsInt* row_index,\n                      HighsInt* col_bound, HighsInt* row_bound,\n                      HighsInt* col_status, HighsInt* row_status);\n/**\n * Releases all resources held by the global scheduler instance.\n *\n * It is not thread-safe to call this function while calling `Highs_run` or one\n * of the `Highs_XXXcall` methods on any other Highs instance in any thread.\n *\n * After this function has terminated, it is guaranteed that eventually all\n * previously created scheduler threads will terminate and allocated memory will\n * be released.\n *\n * After this function has returned, the option value for the number of threads\n * may be altered to a new value before the next call to `Highs_run` or one of\n * the `Highs_XXXcall` methods.\n *\n * @param blocking   If the `blocking` parameter has a nonzero value, then this\n *                   function will not return until all memory is freed, which\n *                   might be desirable when debugging heap memory, but it\n *                   requires the calling thread to wait for all scheduler\n *                   threads to wake-up which is usually not necessary.\n *\n * @returns No status is returned since the function call cannot fail. Calling\n * this function while any Highs instance is in use on any thread is\n * undefined behavior and may cause crashes, but cannot be detected and hence\n * is fully in the callers responsibility.\n */\nvoid Highs_resetGlobalScheduler(const HighsInt blocking);\n\n/**\n * Get a void* pointer to a callback data item\n *\n * @param data_out      A pointer to the HighsCallbackDataOut instance.\n * @param item_name     The name of the item.\n *\n * @returns A void* pointer to the callback data item, or NULL if item_name not\n * valid\n */\nconst void* Highs_getCallbackDataOutItem(const HighsCallbackDataOut* data_out,\n                                         const char* item_name);\n\n/**\n * Set a solution within a callback by passing a subset of the values.\n *\n * For any values that are unavailable/unknown, pass kHighsUndefined.\n *\n * @param data_in     A pointer to the callback input data instance.\n * @param num_entries Number of variables in the set\n * @param value       An array of length [num_entries <= num_col] with\n *                    column solution values.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_setCallbackSolution(HighsCallbackDataIn* data_in,\n                                   const HighsInt num_entries,\n                                   const double* value);\n\n/**\n * Set a partial primal solution by passing values for a set of variables,\n * within a valid callback.\n *\n * @param data_in     A pointer to the callback input data instance.\n * @param num_entries Number of variables in the set\n * @param index       Indices of variables in the set\n * @param value       Values of variables in the set\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_setCallbackSparseSolution(HighsCallbackDataIn* data_in,\n                                         const HighsInt num_entries,\n                                         const HighsInt* index,\n                                         const double* value);\n\n/**\n * Finds a feasible solution for a given (partial) primal user solution,\n * within a valid callback.\n *\n * On success, the user solution is updated within the callback input data\n * instance.\n *\n * @returns A `kHighsStatus` constant indicating whether the call succeeded.\n */\nHighsInt Highs_repairCallbackSolution(HighsCallbackDataIn* data_in);\n\n// *********************\n// * Deprecated methods*\n// *********************\n\n/**\n * Return the HiGHS compilation date.\n *\n * @returns Thse HiGHS compilation date.\n */\nstatic const char* Highs_compilationDate(void);\n\n// These are deprecated because they don't follow the style guide. Constants\n// must begin with `k`.\nstatic const HighsInt HighsStatuskError = -1;\nstatic const HighsInt HighsStatuskOk = 0;\nstatic const HighsInt HighsStatuskWarning = 1;\n\nHighsInt Highs_call(const HighsInt num_col, const HighsInt num_row,\n                    const HighsInt num_nz, const double* col_cost,\n                    const double* col_lower, const double* col_upper,\n                    const double* row_lower, const double* row_upper,\n                    const HighsInt* a_start, const HighsInt* a_index,\n                    const double* a_value, double* col_value, double* col_dual,\n                    double* row_value, double* row_dual,\n                    HighsInt* col_basis_status, HighsInt* row_basis_status,\n                    HighsInt* model_status);\n\nHighsInt Highs_runQuiet(void* highs);\n\nHighsInt Highs_setHighsLogfile(void* highs, const void* logfile);\n\nHighsInt Highs_setHighsOutput(void* highs, const void* outputfile);\n\nHighsInt Highs_getIterationCount(const void* highs);\n\nHighsInt Highs_getSimplexIterationCount(const void* highs);\n\nHighsInt Highs_setHighsBoolOptionValue(void* highs, const char* option,\n                                       const HighsInt value);\n\nHighsInt Highs_setHighsIntOptionValue(void* highs, const char* option,\n                                      const HighsInt value);\n\nHighsInt Highs_setHighsDoubleOptionValue(void* highs, const char* option,\n                                         const double value);\n\nHighsInt Highs_setHighsStringOptionValue(void* highs, const char* option,\n                                         const char* value);\n\nHighsInt Highs_setHighsOptionValue(void* highs, const char* option,\n                                   const char* value);\n\nHighsInt Highs_getHighsBoolOptionValue(const void* highs, const char* option,\n                                       HighsInt* value);\n\nHighsInt Highs_getHighsIntOptionValue(const void* highs, const char* option,\n                                      HighsInt* value);\n\nHighsInt Highs_getHighsDoubleOptionValue(const void* highs, const char* option,\n                                         double* value);\n\nHighsInt Highs_getHighsStringOptionValue(const void* highs, const char* option,\n                                         char* value);\n\nHighsInt Highs_getHighsOptionType(const void* highs, const char* option,\n                                  HighsInt* type);\n\nHighsInt Highs_resetHighsOptions(void* highs);\n\nHighsInt Highs_getHighsIntInfoValue(const void* highs, const char* info,\n                                    HighsInt* value);\n\nHighsInt Highs_getHighsDoubleInfoValue(const void* highs, const char* info,\n                                       double* value);\n\nHighsInt Highs_getNumCols(const void* highs);\n\nHighsInt Highs_getNumRows(const void* highs);\n\ndouble Highs_getHighsInfinity(const void* highs);\n\ndouble Highs_getHighsRunTime(const void* highs);\n\nHighsInt Highs_setOptionValue(void* highs, const char* option,\n                              const char* value);\n\nHighsInt Highs_getScaledModelStatus(const void* highs);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/io/Filereader.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file io/Filereader.h\n * @brief\n */\n#ifndef IO_FILEREADER_H_\n#define IO_FILEREADER_H_\n\n#include \"io/HighsIO.h\"\n#include \"lp_data/HighsOptions.h\"\n#include \"model/HighsModel.h\"\n\nenum class FilereaderRetcode {\n  kOk = 0,\n  kWarning = 1,\n  kFileNotFound = 2,\n  kParserError = 3,\n  kNotImplemented = 4,\n  kTimeout\n};\n\nvoid interpretFilereaderRetcode(const HighsLogOptions& log_options,\n                                const std::string filename,\n                                const FilereaderRetcode code);\nstd::string extractModelName(const std::string filename);\n\nclass Filereader {\n public:\n  virtual FilereaderRetcode readModelFromFile(const HighsOptions& options,\n                                              const std::string filename,\n                                              HighsModel& model) = 0;\n  virtual HighsStatus writeModelToFile(const HighsOptions& options,\n                                       const std::string filename,\n                                       const HighsModel& model) = 0;\n  static Filereader* getFilereader(const HighsLogOptions& log_options,\n                                   const std::string filename);\n\n  virtual ~Filereader(){};\n};\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/io/FilereaderEms.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file io/FilereaderEms.h\n * @brief\n */\n\n#ifndef IO_FILEREADER_EMS_H_\n#define IO_FILEREADER_EMS_H_\n\n#include <list>\n\n#include \"io/Filereader.h\"\n#include \"io/HighsIO.h\"  // For messages.\n\nclass FilereaderEms : public Filereader {\n public:\n  FilereaderRetcode readModelFromFile(const HighsOptions& options,\n                                      const std::string filename,\n                                      HighsModel& model);\n  HighsStatus writeModelToFile(const HighsOptions& options,\n                               const std::string filename,\n                               const HighsModel& model);\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/io/FilereaderLp.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file io/FilereaderLp.cpp\n * @brief\n */\n\n#ifndef IO_FILEREADER_LP_H_\n#define IO_FILEREADER_LP_H_\n\n#include <list>\n\n#include \"io/Filereader.h\"\n#include \"io/HighsIO.h\"\n\n#define BUFFERSIZE 561\n#define LP_MAX_LINE_LENGTH 560\n#define LP_MAX_NAME_LENGTH 255\n\n#define LP_COMMENT_FILESTART (\"File written by HiGHS .lp file handler\")\n\nclass FilereaderLp : public Filereader {\n public:\n  FilereaderRetcode readModelFromFile(const HighsOptions& options,\n                                      const std::string filename,\n                                      HighsModel& model);\n\n  HighsStatus writeModelToFile(const HighsOptions& options,\n                               const std::string filename,\n                               const HighsModel& model);\n\n private:\n  // functions to write files\n  HighsInt linelength;\n  void writeToFile(FILE* file, const char* format, ...);\n  void writeToFileLineEnd(FILE* file);\n  void writeToFileValue(FILE* file, const double value,\n                        const bool force_plus = true);\n  void writeToFileVar(FILE* file, const std::string var_name);\n  void writeToFileMatrixRow(FILE* file, const HighsInt iRow,\n                            const HighsSparseMatrix ar_matrix,\n                            const std::vector<string> col_names);\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/io/FilereaderMps.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file io/FilereaderMps.h\n * @brief\n */\n#ifndef IO_FILEREADER_MPS_H_\n#define IO_FILEREADER_MPS_H_\n\n#include \"io/Filereader.h\"\n#include \"lp_data/HighsStatus.h\"\n\nclass FilereaderMps : public Filereader {\n public:\n  FilereaderRetcode readModelFromFile(const HighsOptions& options,\n                                      const std::string filename,\n                                      HighsModel& model);\n  HighsStatus writeModelToFile(const HighsOptions& options,\n                               const std::string filename,\n                               const HighsModel& model);\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/io/HMPSIO.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file io/HMPSIO.h\n * @brief\n */\n#ifndef IO_HMPSIO_H_\n#define IO_HMPSIO_H_\n\n#include <cmath>\n#include <cstring>\n#include <fstream>\n#include <iostream>\n#include <map>\n#include <vector>\n\n#include \"io/Filereader.h\"\n#include \"util/HighsInt.h\"\n\nusing std::string;\nusing std::vector;\n\nconst HighsInt MPS_ROW_TY_N = 0;\nconst HighsInt MPS_ROW_TY_E = 1;\nconst HighsInt MPS_ROW_TY_L = 2;\nconst HighsInt MPS_ROW_TY_G = 3;\nconst HighsInt field_1_start = 1;\nconst HighsInt field_1_width = 2;\nconst HighsInt field_2_start = 4;\nconst HighsInt field_2_width = 8;\nconst HighsInt field_3_start = 14;\nconst HighsInt field_3_width = 8;\nconst HighsInt field_4_start = 24;\nconst HighsInt field_4_width = 12;\nconst HighsInt field_5_start = 39;\nconst HighsInt field_5_width = 8;\nconst HighsInt field_6_start = 49;\nconst HighsInt field_6_width = 12;\n\nFilereaderRetcode readMps(\n    const HighsLogOptions& log_options, const std::string filename,\n    HighsInt mxNumRow, HighsInt mxNumCol, HighsInt& numRow, HighsInt& numCol,\n    ObjSense& objSense, double& objOffset, vector<HighsInt>& Astart,\n    vector<HighsInt>& Aindex, vector<double>& Avalue, vector<double>& colCost,\n    vector<double>& colLower, vector<double>& colUpper,\n    vector<double>& rowLower, vector<double>& rowUpper,\n    vector<HighsVarType>& integerColumn, std::string& objective_name,\n    vector<std::string>& col_names, vector<std::string>& row_names,\n    HighsInt& Qdim, vector<HighsInt>& Qstart, vector<HighsInt>& Qindex,\n    vector<double>& Qvalue, HighsInt& cost_row_location, bool& warning_issued,\n    const HighsInt keep_n_rows = 0);\n\nHighsStatus writeMps(\n    const HighsLogOptions& log_options, const std::string filename,\n    const std::string model_name, const HighsInt& num_row,\n    const HighsInt& num_col, const HighsInt& q_dim, const ObjSense& sense,\n    const double& offset, const vector<double>& col_cost,\n    const vector<double>& col_lower, const vector<double>& col_upper,\n    const vector<double>& row_lower, const vector<double>& row_upper,\n    const vector<HighsInt>& a_start, const vector<HighsInt>& a_index,\n    const vector<double>& a_value, const vector<HighsInt>& q_start,\n    const vector<HighsInt>& q_index, const vector<double>& q_value,\n    const vector<HighsVarType>& integrality, std::string objective_name,\n    const vector<std::string>& col_names, const vector<std::string>& row_names,\n    const bool use_free_format = true);\n\nbool load_mpsLine(std::istream& file, HighsVarType& integerVar, HighsInt lmax,\n                  char* line, char* flag, double* data);\n\nHighsStatus writeModelAsMps(const HighsOptions& options,\n                            const std::string filename, const HighsModel& model,\n                            const bool free = true);\n\n#endif /* IO_HMPSIO_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/io/HMpsFF.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file io/HMpsFF.h\n * @brief\n */\n#ifndef IO_HMPSFF_H_\n#define IO_HMPSFF_H_\n\n#include <algorithm>\n#include <cassert>\n#include <chrono>\n#include <cmath>\n#include <cstdio>\n#include <cstring>\n#include <fstream>\n#include <iostream>\n#include <iterator>\n#include <limits>\n#include <map>\n#include <memory>\n#include <tuple>\n#include <unordered_map>\n#include <utility>\n#include <vector>\n\n#include \"io/HighsIO.h\"\n#include \"model/HighsModel.h\"\n// #include \"util/HighsInt.h\"\n#include \"util/stringutil.h\"\n\nusing Triplet = std::tuple<HighsInt, HighsInt, double>;\n\nconst std::string mps_comment_chars = \"*$\";\n\nenum class FreeFormatParserReturnCode {\n  kSuccess,\n  kParserError,\n  kFileNotFound,\n  kFixedFormat,\n  kTimeout,\n};\n\nnamespace free_format_parser {\n\n// private:\nusing wall_clock = std::chrono::high_resolution_clock;\nusing time_point = wall_clock::time_point;\n\ndouble getWallTime();\n\nclass HMpsFF {\n public:\n  HMpsFF() {}\n  FreeFormatParserReturnCode loadProblem(const HighsLogOptions& log_options,\n                                         const std::string filename,\n                                         HighsModel& model);\n\n  double time_limit_ = kHighsInf;\n  bool warning_issued_ = false;\n\n private:\n  double start_time;\n\n  HighsInt num_row;\n  HighsInt num_col;\n  HighsInt num_nz;\n  std::string mps_name;\n\n  ObjSense obj_sense = ObjSense::kMinimize;  // Minimization by default\n  double obj_offset = 0;\n\n  std::vector<HighsInt> a_start;\n  std::vector<HighsInt> a_index;\n  std::vector<double> a_value;\n  std::vector<double> col_cost;\n  std::vector<double> col_lower;\n  std::vector<double> col_upper;\n  std::vector<double> row_lower;\n  std::vector<double> row_upper;\n\n  std::vector<std::string> row_names;\n  std::vector<std::string> col_names;\n\n  std::vector<HighsVarType> col_integrality;\n\n  HighsInt q_dim;\n  std::vector<HighsInt> q_start;\n  std::vector<HighsInt> q_index;\n  std::vector<double> q_value;\n\n  // Keep track of columns that are binary by default, being columns\n  // that are defined as integer by markers in the column section, or\n  // as binary by having a BV flag in the BOUNDS section, and without\n  // any LI or UI flags in the BOUNDS section\n  std::vector<bool> col_binary;\n\n  // Record where the cost row is encountered\n  HighsInt cost_row_location;\n\n  // Record whether there are duplicate row or column names, and the\n  // name and indices of the first duplicates\n  bool has_duplicate_row_name_;\n  bool has_duplicate_col_name_;\n  std::string duplicate_row_name_;\n  HighsInt duplicate_row_name_index0_;\n  HighsInt duplicate_row_name_index1_;\n  std::string duplicate_col_name_;\n  HighsInt duplicate_col_name_index0_;\n  HighsInt duplicate_col_name_index1_;\n\n  // Record whether there is a data entry in the RHS section of an MPS\n  // file for the objective or a row. Have to be class data members so\n  // that they can be used by parseName and addRhs in HMpsFF::parseRhs\n  bool has_obj_entry_;\n  std::vector<bool> has_row_entry_;\n\n  /// load LP from MPS file as transposed triplet matrix\n  HighsInt parseFile(std::string filename);\n  HighsInt fillMatrix(const HighsLogOptions& log_options);\n  HighsInt fillHessian(const HighsLogOptions& log_options);\n\n  /// how to treat variables that appear in COLUMNS section first\n  /// assume them to be binary as in the original IBM interpretation\n  /// or integer with default bounds\n  bool kintegerVarsInColumnsAreBinary = true;\n\n  enum class Parsekey {\n    kName,\n    kObjsense,\n    kMax,\n    kMin,\n    kRows,\n    kCols,\n    kRhs,\n    kBounds,\n    kRanges,\n    kQsection,\n    kQmatrix,\n    kQuadobj,\n    kQcmatrix,\n    kCsection,\n    kDelayedrows,\n    kModelcuts,\n    kUsercuts,\n    kIndicators,\n    kSets,\n    kSos,\n    kGencons,\n    kPwlobj,\n    kPwlnam,\n    kPwlcon,\n    kNone,\n    kEnd,\n    kFail,\n    kComment,\n    kFixedFormat,\n    kTimeout\n  };\n\n  enum class Boundtype { kLe, kEq, kGe };  //, kFr };\n\n  // see\n  // https://docs.mosek.com/latest_kkt/capi/mps-format.html#csection-optional\n  enum class ConeType { kZero, kQuad, kRQuad, kPExp, kPPow, kDExp, kDPow };\n\n  std::string objective_name;\n  std::vector<Boundtype> row_type;\n  std::vector<HighsInt> integer_column;\n\n  std::vector<Triplet> entries;\n  std::vector<Triplet> q_entries;\n  std::vector<std::vector<Triplet>> qrows_entries;\n  std::vector<std::pair<HighsInt, double>> coeffobj;\n\n  std::vector<std::string> sos_name;\n  std::vector<short> sos_type;\n  std::vector<std::vector<std::pair<HighsInt, double>>> sos_entries;\n\n  std::vector<std::string> cone_name;\n  std::vector<ConeType> cone_type;\n  std::vector<double> cone_param;\n  std::vector<std::vector<HighsInt>> cone_entries;\n  std::unordered_map<std::string, HighsInt> rowname2idx;\n  std::unordered_map<std::string, HighsInt> colname2idx;\n\n  mutable std::string section_args;\n\n  bool timeout();\n  bool getMpsLine(std::istream& file, std::string& strline, bool& skip);\n\n  FreeFormatParserReturnCode parse(const HighsLogOptions& log_options,\n                                   const std::string& filename);\n  // Checks first word of strline and wraps it by it_begin and it_end\n  HMpsFF::Parsekey checkFirstWord(std::string& strline, size_t& start,\n                                  size_t& end, std::string& word) const;\n\n  // Get index of column from column name, possibly adding new column\n  // if no index is found\n  HighsInt getColIdx(const std::string& colname, const bool add_if_new = true);\n\n  HMpsFF::Parsekey parseDefault(const HighsLogOptions& log_options,\n                                std::istream& file);\n  HMpsFF::Parsekey parseObjsense(const HighsLogOptions& log_options,\n                                 std::istream& file);\n  HMpsFF::Parsekey parseRows(const HighsLogOptions& log_options,\n                             std::istream& file);\n  HMpsFF::Parsekey parseCols(const HighsLogOptions& log_options,\n                             std::istream& file);\n  HMpsFF::Parsekey parseRhs(const HighsLogOptions& log_options,\n                            std::istream& file);\n  HMpsFF::Parsekey parseRanges(const HighsLogOptions& log_options,\n                               std::istream& file);\n  HMpsFF::Parsekey parseBounds(const HighsLogOptions& log_options,\n                               std::istream& file);\n  HMpsFF::Parsekey parseHessian(const HighsLogOptions& log_options,\n                                std::istream& file,\n                                const HMpsFF::Parsekey keyword);\n  HMpsFF::Parsekey parseQuadRows(const HighsLogOptions& log_options,\n                                 std::istream& file,\n                                 const HMpsFF::Parsekey keyword);\n  HMpsFF::Parsekey parseCones(const HighsLogOptions& log_options,\n                              std::istream& file);\n  HMpsFF::Parsekey parseSos(const HighsLogOptions& log_options,\n                            std::istream& file, const HMpsFF::Parsekey keyword);\n\n  bool cannotParseSection(const HighsLogOptions& log_options,\n                          const HMpsFF::Parsekey keyword);\n  bool allZeroed(const std::vector<double>& value);\n  double getValue(const std::string& word, bool& is_nan,\n                  const HighsInt id = -1) const;\n};\n\n}  // namespace free_format_parser\n#endif /* IO_HMPSFF_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/io/HighsIO.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file io/HighsIO.h\n * @brief IO methods for HiGHS - currently just print/log messages\n */\n#ifndef HIGHS_IO_H\n#define HIGHS_IO_H\n\n#include <array>\n#include <iostream>\n\n#include \"lp_data/HighsCallback.h\"\n\nclass HighsOptions;\n\nconst HighsInt kIoBufferSize = 1024;  // 65536;\n\nenum class HighsFileType { kMinimal = 0, kFull, kMps, kLp, kMd };\n\n/**\n * @brief IO methods for HiGHS - currently just print/log messages\n */\nconst char* const HighsLogTypeTag[] = {\"\", \"\",          \"\",\n                                       \"\", \"WARNING: \", \"ERROR:   \"};\nenum LogDevLevel {\n  kHighsLogDevLevelMin = 0,\n  kHighsLogDevLevelNone = kHighsLogDevLevelMin,  // 0\n  kHighsLogDevLevelInfo,                         // 1\n  kHighsLogDevLevelDetailed,                     // 2\n  kHighsLogDevLevelVerbose,                      // 3\n  kHighsLogDevLevelMax = kHighsLogDevLevelVerbose\n};\n\nstruct HighsLogOptions {\n  FILE* log_stream;\n  bool* output_flag;\n  bool* log_to_console;\n  HighsInt* log_dev_level;\n  void (*user_log_callback)(HighsLogType, const char*, void*);\n  void* user_log_callback_data;\n  HighsCallbackFunctionType user_callback;\n  void* user_callback_data;\n  bool user_callback_active;\n  void clear();\n  HighsLogOptions()\n      : log_stream(nullptr),\n        output_flag(nullptr),\n        log_to_console(nullptr),\n        log_dev_level(nullptr),\n        user_log_callback(nullptr),\n        user_log_callback_data(nullptr),\n        user_callback_data(nullptr),\n        user_callback_active(false){};\n};\n\n/**\n * @brief Write the HiGHS version and copyright statement\n */\nvoid highsLogHeader(const HighsLogOptions& log_options, const bool log_githash);\n\n/**\n * @brief Convert a double number to a string using given tolerance\n */\nstd::array<char, 32> highsDoubleToString(const double val,\n                                         const double tolerance);\n\n/**\n * @brief For _single-line_ user logging with message type notification\n */\n// Printing format: must contain exactly one \"\\n\" at end of format\nvoid highsLogUser(const HighsLogOptions& log_options_, const HighsLogType type,\n                  const char* format, ...);\n\n/**\n * @brief For development logging\n */\nvoid highsLogDev(const HighsLogOptions& log_options_, const HighsLogType type,\n                 const char* format, ...);\n\n/**\n * @brief Replaces fprintf(file,... so that when file=stdout highsLogUser is\n * used\n */\n// Printing format: must contain exactly one \"\\n\" at end of format\nvoid highsFprintfString(FILE* file, const HighsLogOptions& log_options_,\n                        const std::string& s);\n\n/**\n * @brief For development logging when true log_options may not be available -\n * indicated by null pointer\n */\nvoid highsReportDevInfo(const HighsLogOptions* log_options,\n                        const std::string line);\n\nvoid highsOpenLogFile(HighsOptions& options, const std::string log_file);\n\nvoid highsReportLogOptions(const HighsLogOptions& log_options_);\n\nstd::string highsFormatToString(const char* format, ...);\n\nconst std::string highsBoolToString(const bool b,\n                                    const HighsInt field_width = 2);\n\nconst std::string highsInsertMdEscapes(const std::string from_string);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/io/LoadOptions.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file io/LoadOptions.h\n * @brief\n */\n\n#ifndef IO_LOAD_OPTIONS_H_\n#define IO_LOAD_OPTIONS_H_\n\n#include \"lp_data/HighsOptions.h\"\n\nenum class HighsLoadOptionsStatus { kError = -1, kOk = 0, kEmpty = 1 };\n\n// For extended options to be parsed from filename\nHighsLoadOptionsStatus loadOptionsFromFile(\n    const HighsLogOptions& report_log_options, HighsOptions& options,\n    const std::string filename);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/IpxSolution.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file ipm/IpxSolution.h\n * @brief\n */\n#ifndef IPM_IPX_SOLUTION_H_\n#define IPM_IPX_SOLUTION_H_\n\n#include <stdint.h>\n\n#include <vector>\n\n#include \"util/HighsInt.h\"\ntypedef HighsInt ipxint;\n\nstruct IpxSolution {\n  ipxint num_col;\n  ipxint num_row;\n  std::vector<double> ipx_col_value;\n  std::vector<double> ipx_row_value;\n  std::vector<double> ipx_col_dual;\n  std::vector<double> ipx_row_dual;\n  std::vector<ipxint> ipx_col_status;\n  std::vector<ipxint> ipx_row_status;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/IpxWrapper.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file ipm/IpxWrapper.h\n * @brief\n */\n#ifndef IPM_IPX_WRAPPER_H_\n#define IPM_IPX_WRAPPER_H_\n\n#include <algorithm>\n#include <cassert>\n\n#include \"ipm/IpxSolution.h\"\n#include \"ipm/ipx/ipx_status.h\"\n#include \"ipm/ipx/lp_solver.h\"\n#include \"lp_data/HighsSolution.h\"\n\n#ifdef HIPO\n#include \"ipm/hipo/ipm/Solver.h\"\n#endif\n\nHighsStatus solveLpIpx(HighsLpSolverObject& solver_object);\n\nHighsStatus solveLpIpx(const HighsOptions& options, HighsTimer& timer,\n                       const HighsLp& lp, HighsBasis& highs_basis,\n                       HighsSolution& highs_solution,\n                       HighsModelStatus& model_status, HighsInfo& highs_info,\n                       HighsCallback& callback);\n\n#ifdef HIPO\nHighsStatus solveLpHipo(HighsLpSolverObject& solver_object);\n\nHighsStatus solveLpHipo(const HighsOptions& options, HighsTimer& timer,\n                        const HighsLp& lp, HighsBasis& highs_basis,\n                        HighsSolution& highs_solution,\n                        HighsModelStatus& model_status, HighsInfo& highs_info,\n                        HighsCallback& callback);\n\nHighsStatus reportHipoStatus(const HighsOptions& options,\n                             const hipo::Int status, const hipo::Solver& hipo);\n\nHighsStatus reportHipoCrossoverStatus(const HighsOptions& options,\n                                      const ipx::Int status);\n\nvoid reportHipoNoProgress(const HighsOptions& options,\n                          const hipo::Info& hipo_info);\n\nvoid getHipoNonVertexSolution(const HighsOptions& options, const HighsLp& lp,\n                              const hipo::Int num_col, const hipo::Int num_row,\n                              const std::vector<double>& rhs,\n                              const std::vector<char>& constraint_type,\n                              const hipo::Solver& hipo,\n                              const HighsModelStatus model_status,\n                              HighsSolution& highs_solution);\n\n#endif\n\nvoid fillInIpxData(const HighsLp& lp, ipx::Int& num_col, ipx::Int& num_row,\n                   double& offset, std::vector<double>& obj,\n                   std::vector<double>& col_lb, std::vector<double>& col_ub,\n                   std::vector<ipx::Int>& Ap, std::vector<ipx::Int>& Ai,\n                   std::vector<double>& Ax, std::vector<double>& rhs,\n                   std::vector<char>& constraint_type);\n\nHighsStatus reportIpxSolveStatus(const HighsOptions& options,\n                                 const ipx::Int solve_status,\n                                 const ipx::Int error_flag);\n\nHighsStatus reportIpxIpmCrossoverStatus(const HighsOptions& options,\n                                        const ipx::Int status,\n                                        const bool ipm_status);\n\nbool ipxStatusError(const bool status_error, const HighsOptions& options,\n                    std::string solver, std::string message,\n                    const int value = -1);\n\nbool illegalIpxSolvedStatus(const ipx::Info& ipx_info,\n                            const HighsOptions& options);\n\nbool illegalIpxStoppedIpmStatus(const ipx::Info& ipx_info,\n                                const HighsOptions& options);\n\nbool illegalIpxStoppedCrossoverStatus(const ipx::Info& ipx_info,\n                                      const HighsOptions& options);\n\nvoid reportIpmNoProgress(const HighsOptions& options,\n                         const ipx::Info& ipx_info);\n\nvoid getHighsNonVertexSolution(const HighsOptions& options, const HighsLp& lp,\n                               const ipx::Int num_col, const ipx::Int num_row,\n                               const std::vector<double>& rhs,\n                               const std::vector<char>& constraint_type,\n                               const ipx::LpSolver& lps,\n                               const HighsModelStatus model_status,\n                               HighsSolution& highs_solution);\n\nvoid reportSolveData(const HighsLogOptions& log_options,\n                     const ipx::Info& ipx_info);\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu.h",
    "content": "#ifndef _BASICLU_H\n#define _BASICLU_H\n\n#ifdef __cplusplus\nextern \"C\"{\n#endif\n\n/*\n * BASICLU integer type\n *\n * All integers in BASICLU code are of type lu_int, which must be a signed\n * integer type. It is required that all integer values arising in the\n * computation can be stored in double variables and converted back to lu_int\n * without altering their value.\n *\n * LU_INT_MAX must be the maximum value of a variable of type lu_int.\n *\n * The default is 64 bit integers to make the code easily callable from Julia.\n * int64_t is optional in the C99 standard, but available on most systems.\n *\n */\n#include <limits.h>\n#include <stdint.h>\n#include \"HConfig.h\"\n  \n#ifdef HIGHSINT64\ntypedef int64_t lu_int;\n#define LU_INT_MAX INT64_MAX\n#else\ntypedef int lu_int;\n#define LU_INT_MAX INT_MAX\n#endif\n/* #include <limits.h> */\n/* typedef long lu_int; */\n/* #define LU_INT_MAX LONG_MAX */\n\n/* size of istore */\n#define BASICLU_SIZE_ISTORE_1 1024\n#define BASICLU_SIZE_ISTORE_M 21\n\n/* size of xstore */\n#define BASICLU_SIZE_XSTORE_1 1024\n#define BASICLU_SIZE_XSTORE_M 4\n\n/* ------------ */\n/* status codes */\n/* ------------ */\n\n#define BASICLU_OK 0\n#define BASICLU_REALLOCATE 1\n#define BASICLU_WARNING_singular_matrix 2\n#define BASICLU_ERROR_invalid_store (-1)\n#define BASICLU_ERROR_invalid_call (-2)\n#define BASICLU_ERROR_argument_missing (-3)\n#define BASICLU_ERROR_invalid_argument (-4)\n#define BASICLU_ERROR_maximum_updates (-5)\n#define BASICLU_ERROR_singular_update (-6)\n\n#define BASICLU_ERROR_invalid_object (-8)\n#define BASICLU_ERROR_out_of_memory (-9)\n\n/* ------------------------ */\n/* public entries in xstore */\n/* ------------------------ */\n\n/* user parameters */\n#define BASICLU_MEMORYL 1\n#define BASICLU_MEMORYU 2\n#define BASICLU_MEMORYW 3\n#define BASICLU_DROP_TOLERANCE 4\n#define BASICLU_ABS_PIVOT_TOLERANCE 5\n#define BASICLU_REL_PIVOT_TOLERANCE 6\n#define BASICLU_BIAS_NONZEROS 7\n#define BASICLU_MAXN_SEARCH_PIVOT 8\n#define BASICLU_PAD 9\n#define BASICLU_STRETCH 10\n#define BASICLU_COMPRESSION_THRESHOLD 11\n#define BASICLU_SPARSE_THRESHOLD 12\n#define BASICLU_REMOVE_COLUMNS 13\n#define BASICLU_SEARCH_ROWS 14\n\n/* user readable */\n#define BASICLU_DIM 64\n#define BASICLU_STATUS 65\n#define BASICLU_ADD_MEMORYL 66\n#define BASICLU_ADD_MEMORYU 67\n#define BASICLU_ADD_MEMORYW 68\n\n#define BASICLU_NUPDATE 70\n#define BASICLU_NFORREST 71\n#define BASICLU_NFACTORIZE 72\n#define BASICLU_NUPDATE_TOTAL 73\n#define BASICLU_NFORREST_TOTAL 74\n#define BASICLU_NSYMPERM_TOTAL 75\n#define BASICLU_LNZ 76\n#define BASICLU_UNZ 77\n#define BASICLU_RNZ 78\n#define BASICLU_MIN_PIVOT 79\n#define BASICLU_MAX_PIVOT 80\n#define BASICLU_UPDATE_COST 81\n#define BASICLU_TIME_FACTORIZE 82\n#define BASICLU_TIME_SOLVE 83\n#define BASICLU_TIME_UPDATE 84\n#define BASICLU_TIME_FACTORIZE_TOTAL 85\n#define BASICLU_TIME_SOLVE_TOTAL 86\n#define BASICLU_TIME_UPDATE_TOTAL 87\n#define BASICLU_LFLOPS 88\n#define BASICLU_UFLOPS 89\n#define BASICLU_RFLOPS 90\n#define BASICLU_CONDEST_L 91\n#define BASICLU_CONDEST_U 92\n#define BASICLU_MAX_ETA 93\n#define BASICLU_NORM_L 94\n#define BASICLU_NORM_U 95\n#define BASICLU_NORMEST_LINV 96\n#define BASICLU_NORMEST_UINV 97\n#define BASICLU_MATRIX_ONENORM 98\n#define BASICLU_MATRIX_INFNORM 99\n#define BASICLU_RESIDUAL_TEST 111\n\n#define BASICLU_MATRIX_NZ 100\n#define BASICLU_RANK 101\n#define BASICLU_BUMP_SIZE 102\n#define BASICLU_BUMP_NZ 103\n#define BASICLU_NSEARCH_PIVOT 104\n#define BASICLU_NEXPAND 105\n#define BASICLU_NGARBAGE 106\n#define BASICLU_FACTOR_FLOPS 107\n#define BASICLU_TIME_SINGLETONS 108\n#define BASICLU_TIME_SEARCH_PIVOT 109\n#define BASICLU_TIME_ELIM_PIVOT 110\n\n#define BASICLU_PIVOT_ERROR 120\n\n/* ----------------------- */\n/* user callable functions */\n/* ----------------------- */\n\n#include \"ipm/basiclu/basiclu_initialize.h\"\n#include \"ipm/basiclu/basiclu_factorize.h\"\n#include \"ipm/basiclu/basiclu_get_factors.h\"\n#include \"ipm/basiclu/basiclu_solve_dense.h\"\n#include \"ipm/basiclu/basiclu_solve_sparse.h\"\n#include \"ipm/basiclu/basiclu_solve_for_update.h\"\n#include \"ipm/basiclu/basiclu_update.h\"\n\n#include \"ipm/basiclu/basiclu_object.h\"\n#include \"ipm/basiclu/basiclu_obj_initialize.h\"\n#include \"ipm/basiclu/basiclu_obj_factorize.h\"\n#include \"ipm/basiclu/basiclu_obj_get_factors.h\"\n#include \"ipm/basiclu/basiclu_obj_solve_dense.h\"\n#include \"ipm/basiclu/basiclu_obj_solve_sparse.h\"\n#include \"ipm/basiclu/basiclu_obj_solve_for_update.h\"\n#include \"ipm/basiclu/basiclu_obj_update.h\"\n#include \"ipm/basiclu/basiclu_obj_free.h\"\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_factorize.h",
    "content": "lu_int basiclu_factorize\n(\n    lu_int istore[],\n    double xstore[],\n    lu_int Li[],\n    double Lx[],\n    lu_int Ui[],\n    double Ux[],\n    lu_int Wi[],\n    double Wx[],\n    const lu_int Bbegin[],\n    const lu_int Bend[],\n    const lu_int Bi[],\n    const double Bx[],\n    lu_int c0ntinue\n);\n\n/*\nPurpose:\n\n    Factorize the matrix B into its LU factors. Choose pivot elements by a\n    Markowitz criterion subject to columnwise threshold pivoting (the pivot may\n    not be smaller than a factor of the largest entry in its column).\n\nReturn:\n\n    BASICLU_ERROR_invalid_store if istore, xstore do not hold a BASICLU\n    instance. In this case xstore[BASICLU_STATUS] is not set.\n\n    Otherwise return the status code. See xstore[BASICLU_STATUS] below.\n\nArguments:\n\n    lu_int istore[]\n    double xstore[]\n\n        BASICLU instance. The instance determines the dimension of matrix B\n        (stored in xstore[BASICLU_DIM]).\n\n    lu_int Li[]\n    double Lx[]\n    lu_int Ui[]\n    double Ux[]\n    lu_int Wi[]\n    double Wx[]\n\n        Arrays used for workspace during the factorization and to store the\n        final factors. They must be allocated by the user and their length\n        must be provided as parameters:\n\n            xstore[BASICLU_MEMORYL]: length of Li and Lx\n            xstore[BASICLU_MEMORYU]: length of Ui and Ux\n            xstore[BASICLU_MEMORYW]: length of Wi and Wx\n\n        When the allocated length is insufficient to complete the factorization,\n        basiclu_factorize() returns to the caller for reallocation (see\n        xstore[BASICLU_STATUS] below). A successful factorization requires at\n        least nnz(B) length for each of the arrays.\n\n    const lu_int Bbegin[]\n    const lu_int Bend[]\n    const lu_int Bi[]\n    const double Bx[]\n\n        Matrix B in packed column form. Bi and Bx are arrays of row indices\n        and nonzero values. Column j of matrix B contains elements\n\n            Bi[Bbegin[j] .. Bend[j]-1], Bx[Bbegin[j] .. Bend[j]-1].\n\n        The columns must not contain duplicate row indices. The arrays Bbegin\n        and Bend may overlap, so that it is valid to pass Bp, Bp+1 for a matrix\n        stored in compressed column form (Bp, Bi, Bx).\n\n    lu_int c0ntinue\n\n        zero to start a new factorization; nonzero to continue a factorization\n        after reallocation.\n\nParameters:\n\n    xstore[BASICLU_DROP_TOLERANCE]\n\n        Nonzeros which magnitude is less than or equal to the drop tolerance can\n        be removed after each pivot step. They are guaranteed removed at the end\n        of the factorization. Default: 1e-20\n\n    xstore[BASICLU_ABS_PIVOT_TOLERANCE]\n\n        A pivot element must be nonzero and in absolute value must be greater\n        than or equal to xstore[BASICLU_ABS_PIVOT_TOLERANCE]. Default: 1e-14\n\n    xstore[BASICLU_REL_PIVOT_TOLERANCE]\n\n        A pivot element must be (in absolute value) greater than or equal to\n        xstore[BASICLU_REL_PIVOT_TOLERANCE] times the largest entry in its\n        column. A value greater than or equal to 1.0 is treated as 1.0 and\n        enforces partial pivoting. Default: 0.1\n\n    xstore[BASICLU_BIAS_NONZEROS]\n\n        When this value is greater than or equal to zero, the pivot choice\n        attempts to keep L sparse, putting entries into U when possible.\n        When this value is less than zero, the pivot choice attempts to keep U\n        sparse, putting entries into L when possible. Default: 1\n\n    xstore[BASICLU_MAXN_SEARCH_PIVOT]\n\n        The Markowitz search is terminated after searching\n        xstore[BASICLU_MAXN_SERACH_PIVOT] rows or columns if a numerically\n        stable pivot element has been found. Default: 3\n\n    xstore[BASICLU_SEARCH_ROWS]\n\n        If xstore[BASICLU_SEARCH_ROWS] is zero, then the Markowitz search only\n        scans columns. If nonzero, then both columns and rows are searched in\n        increasing order of number of entries. Default: 1\n\n    xstore[BASICLU_PAD]\n    xstore[BASICLU_STRETCH]\n\n        When a row or column cannot be updated by the pivot operation in place,\n        it is appended to the end of the workspace. For a row or column with nz\n        elements, xstore[BASICLU_PAD] + nz * xstore[BASICLU_STRETCH] elements\n        extra space are added for later fill-in.\n        Default: xstore[BASICLU_PAD] = 4, xstore[BASICLU_STRETCH] = 0.3\n\n    xstore[BASICLU_REMOVE_COLUMNS]\n\n        This parameter is present for compatibility to previous versions but has\n        no effect. If during factorization the maximum entry of a column of the\n        active submatrix becomes zero or less than\n        xstore[BASICLU_ABS_PIVOT_TOLERANCE], then that column is immediately\n        removed without choosing a pivot.\n\nInfo:\n\n    xstore[BASICLU_STATUS]: status code.\n\n        BASICLU_OK\n\n            The factorization has successfully completed.\n\n        BASICLU_WARNING_singular_matrix\n\n            The factorization did xstore[BASICLU_RANK] < xstore[BASICLU_DIM]\n            pivot steps. The remaining elements in the active submatrix are zero\n            or less than xstore[BASICLU_ABS_PIVOT_TOLERANCE]. The factors have\n            been augmented by unit columns to form a square matrix. See\n            basiclu_get_factors() on how to get the indices of linearly\n            dependent columns.\n\n        BASICLU_ERROR_argument_missing\n\n            One or more of the pointer/array arguments are NULL.\n\n        BASICLU_ERROR_invalid_call\n\n            c0ntinue is nonzero, but the factorization was not started before.\n\n        BASICLU_ERROR_invalid_argument\n\n            The matrix is invalid (a column has a negative number of entries,\n            a row index is out of range, or a column has duplicate entries).\n\n        BASICLU_REALLOCATE\n\n            Factorization requires more memory in Li,Lx and/or Ui,Ux and/or\n            Wi,Wx. The number of additional elements in each of the array pairs\n            required for the next pivot operation is given by:\n\n                xstore[BASICLU_ADD_MEMORYL] >= 0\n                xstore[BASICLU_ADD_MEMORYU] >= 0\n                xstore[BASICLU_ADD_MEMORYW] >= 0\n\n            The user must reallocate the arrays for which additional memory is\n            required. It is recommended to reallocate for the requested number\n            of additional elements plus some extra space (e.g. 0.5 times the\n            current array length). The new array lengths must be provided in\n\n                xstore[BASICLU_MEMORYL]: length of Li and Lx\n                xstore[BASICLU_MEMORYU]: length of Ui and Ux\n                xstore[BASICLU_MEMORYW]: length of Wi and Wx\n\n            basiclu_factorize() can be called again with c0ntinue not equal to\n            zero to continue the factorization.\n\n    xstore[BASICLU_MATRIX_NZ] number of nonzeros in B\n\n    xstore[BASICLU_MATRIX_ONENORM]\n    xstore[BASICLU_MATRIX_INFNORM] 1-norm and inf-norm of the input matrix\n                                   after replacing dependent columns by unit\n                                   columns.\n\n    xstore[BASICLU_RANK] number of pivot steps performed\n\n    xstore[BASICLU_BUMP_SIZE] dimension of matrix after removing singletons\n\n    xstore[BASICLU_BUMP_NZ] # nonzeros in matrix after removing singletons\n\n    xstore[BASICLU_NSEARCH_PIVOT] total # columns/rows searched for pivots\n\n    xstore[BASICLU_NEXPAND] # columns/rows which had to be appended to the end\n                            of the workspace for the rank-1 update\n\n    xstore[BASICLU_NGARBAGE] # garbage collections\n\n    xstore[BASICLU_FACTOR_FLOPS] # floating point operations performed,\n                                 counting multiply-add as one flop\n\n    xstore[BASICLU_TIME_SINGLETONS] wall clock time for removing the initial\n                                    triangular factors\n\n    xstore[BASICLU_TIME_SEARCH_PIVOT] wall clock time for Markowitz search\n\n    xstore[BASIClU_TIME_ELIM_PIVOT] wall clock time for pivot elimination\n\n    xstore[BASICLU_RESIDUAL_TEST]\n\n            An estimate for numerical stability of the factorization.\n            xstore[BASICLU_RESIDUAL_TEST] is the maximum of the scaled residuals\n\n              ||b-Bx|| / (||b|| + ||B||*||x||)\n\n            and\n\n              ||c-B'y|| / (||c|| + ||B'||*||y||),\n\n            where x=B\\b and y=B'\\c are computed from the LU factors, b and c\n            have components +/-1 that are chosen to make x respectively y large,\n            and ||.|| is the 1-norm. Here B is the input matrix after replacing\n            dependent columns by unit columns.\n\n            If xstore[BASICLU_RESIDUAL_TEST] > 1e-12, say, the factorization is\n            numerically unstable. (This is independent of the condition number\n            of B.) In this case tightening the relative pivot tolerance and\n            refactorizing is appropriate.\n\n    xstore[BASICLU_NORM_L]\n    xstore[BASICLU_NORM_U] 1-norm of L and U.\n\n    xstore[BASICLU_NORMEST_LINV]\n    xstore[BASICLU_NORMEST_UINV] Estimated 1-norm of L^{-1} and U^{-1},\n                                 computed by the LINPACK algorithm.\n\n    xstore[BASICLU_CONDEST_L]\n    xstore[BASICLU_CONDEST_U] Estimated 1-norm condition number of L and U.\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_get_factors.h",
    "content": "lu_int basiclu_get_factors\n(\n    lu_int istore[],\n    double xstore[],\n    lu_int Li[],\n    double Lx[],\n    lu_int Ui[],\n    double Ux[],\n    lu_int Wi[],\n    double Wx[],\n    lu_int rowperm[],\n    lu_int colperm[],\n    lu_int Lcolptr[],\n    lu_int Lrowidx[],\n    double Lvalue[],\n    lu_int Ucolptr[],\n    lu_int Urowidx[],\n    double Uvalue[]\n);\n\n/*\nPurpose:\n\n    Extract the row and column permutation and the LU factors. This routine can\n    be used only after basiclu_factorize() has completed and before a call to\n    basiclu_update(). At that point the factorized form of matrix B is\n\n        B[rowperm,colperm] = L*U,\n\n    where L is unit lower triangular and U is upper triangular. If the\n    factorization was singular (rank < m), then columns colperm[rank..m-1]\n    of B have been replaced by unit columns with entry 1 in position\n    rowperm[rank..m-1].\n\n    basiclu_get_factors() is intended when the user needs direct access to the\n    matrix factors. It is not required to solve linear systems with the factors\n    (see basiclu_solve_dense() and basiclu_solve_sparse() instead).\n\nReturn:\n\n    BASICLU_ERROR_invalid_store if istore, xstore do not hold a BASICLU\n    instance. In this case xstore[BASICLU_STATUS] is not set.\n\n    Otherwise return the status code. See xstore[BASICLU_STATUS] below.\n\nArguments:\n\n    lu_int istore[]\n    double xstore[]\n    lu_int Li[]\n    double Lx[]\n    lu_int Ui[]\n    double Ux[]\n    lu_int Wi[]\n    double Wx[]\n\n        The BASICLU instance after basiclu_factorize() has completed.\n\n    lu_int rowperm[m]\n\n        Returns the row permutation. If the row permutation is not required,\n        then NULL can be passed (this is not an error).\n\n    lu_int colperm[m]\n\n        Returns the column permutation. If the column permutation is not\n        required, then NULL can be passed (this is not an error).\n\n    lu_int Lcolptr[m+1]\n    lu_int Lrowidx[m+Lnz]\n    double Lvalue[m+Lnz], where Lnz = xstore[BASICLU_LNZ]\n\n        If all three arguments are not NULL, then they are filled with L in\n        compressed column form. The indices in each column are sorted with the\n        unit diagonal element at the front.\n\n        If any of the three arguments is NULL, then L is not returned\n        (this is not an error).\n\n    lu_int Ucolptr[m+1]\n    lu_int Urowidx[m+Unz]\n    double Uvalue[m+Unz], where Unz = xstore[BASICLU_UNZ]\n\n        If all three arguments are not NULL, then they are filled with U in\n        compressed column form. The indices in each column are sorted with the\n        diagonal element at the end.\n\n        If any of the three arguments is NULL, then U is not returned\n        (this is not an error).\n\nInfo:\n\n    xstore[BASICLU_STATUS]: status code.\n\n        BASICLU_OK\n\n            The requested quantities have been returned successfully.\n\n        BASICLU_ERROR_argument_missing\n\n            One or more of the mandatory pointer/array arguments are NULL.\n\n        BASICLU_ERROR_invalid_call\n\n            The BASICLU instance does not hold a fresh factorization (either\n            basiclu_factorize() has not completed or basiclu_update() has been\n            called in the meanwhile).\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_initialize.h",
    "content": "lu_int basiclu_initialize\n(\n    lu_int m,\n    lu_int istore[],\n    double xstore[]\n);\n\n/*\nPurpose:\n\n    Initialize istore, xstore to a BASICLU instance. Set parameters to defaults\n    and reset counters. The initialization fixes the dimension of matrices\n    which can be processed by this instance.\n\n    This routine must be called once before passing istore, xstore to any other\n    basiclu_ routine.\n\nReturn:\n\n    BASICLU_OK\n\n        m, istore, xstore were valid arguments. Only in this case are istore,\n        xstore initialized.\n\n    BASICLU_ERROR_argument_missing\n\n        istore or xstore is NULL.\n\n    BASICLU_ERROR_invalid_argument\n\n        m is less than or equal to zero.\n\nArguments:\n\n    lu_int m\n\n        The dimension of matrices which can be processed. m > 0.\n\n    lu_int istore[]\n    double xstore[]\n\n        Fixed size arrays. These must be allocated by the user as follows:\n\n          length of istore: BASICLU_SIZE_ISTORE_1 + BASICLU_SIZE_ISTORE_M * m\n          length of xstore: BASICLU_SIZE_XSTORE_1 + BASICLU_SIZE_XSTORE_M * m\n\nInfo:\n\n    After initialization, the following entries of xstore are maintained\n    throughout by all basiclu_ routines:\n\n    xstore[BASICLU_DIM] Matrix dimension (constant).\n\n    xstore[BASICLU_NUPDATE] Number of updates since last factorization. This is\n                            the sum of Forrest-Tomlin updates and permutation\n                            updates.\n\n    xstore[BASICLU_NFORREST] Number of Forrest-Tomlin updates since last\n                             factorization. The upper limit on Forrest-Tomlin\n                             updates before refactorization is m, but that is\n                             far too much for performance reasons and numerical\n                             stability.\n\n    xstore[BASICLU_NFACTORIZE] Number of factorizations since initialization.\n\n    xstore[BASICLU_NUPDATE_TOTAL] Number of updates since initialization.\n\n    xstore[BASICLU_NFORREST_TOTAL] Number of Forrest-Tomlin updates since\n                                   initialization.\n\n    xstore[BASICLU_NSYMPERM_TOTAL] Number of symmetric permutation updates since\n                                   initialization. A permutation update is\n                                   \"symmetric\" if the row and column\n                                   permutation can be updated symmetrically.\n\n    xstore[BASICLU_LNZ] Number of nonzeros in L excluding diagonal elements\n                        (not changed by updates).\n\n    xstore[BASICLU_UNZ] Number of nonzeros in U excluding diagonal elements\n                        (changed by updates).\n\n    xstore[BASICLU_RNZ] Number of nonzeros in update ETA vectors excluding\n                        diagonal elements (zero after factorization, increased\n                        by Forrest-Tomlin updates).\n\n    xstore[BASICLU_MIN_PIVOT]\n    xstore[BASICLU_MAX_PIVOT] After factorization these are the smallest and\n                              largest pivot element. xstore[BASICLU_MIN_PIVOT]\n                              is replaced when a smaller pivot occurs in an\n                              update. xstore[BASICLU_MAX_PIVOT] is replaced when\n                              a larger pivot occurs in an update.\n\n    xstore[BASICLU_UPDATE_COST] Deterministic measure of solve/update cost\n                                compared to cost of last factorization. This\n                                value is zero after factorization and\n                                monotonically increases with solves/updates.\n                                When xstore[BASICLU_UPDATE_COST] > 1.0, then\n                                a refactorization is good for performance.\n\n    xstore[BASICLU_TIME_FACTORIZE] Wall clock time for last factorization.\n\n    xstore[BASICLU_TIME_SOLVE] Wall clock time for all calls to\n                               basiclu_solve_sparse and basiclu_solve_for_update\n                               since last factorization.\n\n    xstore[BASICLU_TIME_UPDATE] Wall clock time for all calls to basiclu_update\n                                since last factorization.\n\n    xstore[BASICLU_TIME_FACTORIZE_TOTAL]\n    xstore[BASICLU_TIME_SOLVE_TOTAL]\n    xstore[BASICLU_TIME_UPDATE_TOTAL] Analogous to above, but summing up all\n                                      calls since initialization.\n\n    xstore[BASICLU_LFLOPS]\n    xstore[BASICLU_UFLOPS]\n    xstore[BASICLU_RFLOPS] Number of flops for operations with L, U and update\n                           ETA vectors in calls to basiclu_solve_sparse and\n                           basiclu_solve_for_update since last factorization.\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_obj_factorize.h",
    "content": "lu_int basiclu_obj_factorize\n(\n    struct basiclu_object *obj,\n    const lu_int *Bbegin,\n    const lu_int *Bend,\n    const lu_int *Bi,\n    const double *Bx\n);\n\n/*\nPurpose:\n\n    Call basiclu_factorize() on a BASICLU object.\n\nReturn:\n\n    BASICLU_ERROR_invalid_object\n\n        obj is NULL or initialized to a null object.\n\n    BASICLU_ERROR_out_of_memory\n\n        reallocation failed because of insufficient memory.\n\n    Other return codes are passed through from basiclu_factorize().\n\nArguments:\n\n    struct basiclu_object *obj\n\n        Pointer to an initialized BASICLU object.\n\n    The other arguments are passed through to basiclu_factorize().\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_obj_free.h",
    "content": "void basiclu_obj_free\n(\n    struct basiclu_object *obj\n);\n\n/*\nPurpose:\n\n    Free memory allocated from a BASICLU object. The object must have been\n    initialized before by basiclu_obj_initialize(). Subsequent calls to\n    basiclu_obj_free() will do nothing.\n\nArguments:\n\n    struct basiclu_object *obj\n\n        Pointer to the object which memory is to be freed. When obj is NULL,\n        then the routine does nothing.\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_obj_get_factors.h",
    "content": "lu_int basiclu_obj_get_factors\n(\n    struct basiclu_object *obj,\n    lu_int rowperm[],\n    lu_int colperm[],\n    lu_int Lcolptr[],\n    lu_int Lrowidx[],\n    double Lvalue[],\n    lu_int Ucolptr[],\n    lu_int Urowidx[],\n    double Uvalue[]\n);\n\n/*\nPurpose:\n\n    Call basiclu_get_factors() on a BASICLU object.\n\nReturn:\n\n    BASICLU_ERROR_invalid_object\n\n        obj is NULL or initialized to a null object.\n\n    Other return codes are passed through from basiclu_get_factors().\n\nArguments:\n\n    struct basiclu_object *obj\n\n        Pointer to an initialized BASICLU object.\n\n    The other arguments are passed through to basiclu_get_factors().\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_obj_initialize.h",
    "content": "lu_int basiclu_obj_initialize\n(\n    struct basiclu_object *obj,\n    lu_int m\n);\n\n/*\nPurpose:\n\n    Initialize a BASICLU object. When m is positive, then *obj is initialized to\n    process matrices of dimension m. When m is zero, then *obj is initialized to\n    a \"null\" object, which cannot be used for factorization, but can be passed\n    to basiclu_obj_free().\n\n    This routine must be called once before passing obj to any other\n    basiclu_obj_ routine. When obj is initialized to a null object, then the\n    routine can be called again to reinitialize obj.\n\nReturn:\n\n    BASICLU_OK\n\n        *obj successfully initialized.\n\n    BASICLU_ERROR_argument_missing\n\n        obj is NULL.\n\n    BASICLU_ERROR_invalid_argument\n\n        m is negative.\n\n    BASICLU_ERROR_out_of_memory\n\n        insufficient memory to initialize object.\n\nArguments:\n\n    struct basiclu_object *obj\n\n        Pointer to the object to be initialized.\n\n    lu_int m\n\n        The dimension of matrices which can be processed, or 0.\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_obj_solve_dense.h",
    "content": "lu_int basiclu_obj_solve_dense\n(\n    struct basiclu_object *obj,\n    const double rhs[],\n    double lhs[],\n    char trans\n);\n\n/*\nPurpose:\n\n    Call basiclu_solve_dense() on a BASICLU object.\n\nReturn:\n\n    BASICLU_ERROR_invalid_object\n\n        obj is NULL or initialized to a null object.\n\n    Other return codes are passed through from basiclu_solve_dense().\n\nArguments:\n\n    struct basiclu_object *obj\n\n        Pointer to an initialized BASICLU object.\n\n    The other arguments are passed through to basiclu_solve_dense().\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_obj_solve_for_update.h",
    "content": "lu_int basiclu_obj_solve_for_update\n(\n    struct basiclu_object *obj,\n    lu_int nzrhs,\n    const lu_int irhs[],\n    const double xrhs[],\n    char trans,\n    lu_int want_solution\n);\n\n/*\nPurpose:\n\n    Call basiclu_solve_for_update() on a BASICLU object. On success, if the\n    solution was requested, it is provided in obj->lhs and the nonzero pattern\n    is stored in obj->ilhs[0..obj->nzlhs-1].\n\nReturn:\n\n    BASICLU_ERROR_invalid_object\n\n        obj is NULL or initialized to a null object.\n\n    BASICLU_ERROR_out_of_memory\n\n        reallocation failed because of insufficient memory.\n\n    Other return codes are passed through from basiclu_solve_for_update().\n\nArguments:\n\n    struct basiclu_object *obj\n\n        Pointer to an initialized BASICLU object.\n\n    lu_int want_solution\n\n        Nonzero to compute the solution to the linear system,\n        zero to only prepare the update.\n\n    The other arguments are passed through to basiclu_solve_for_update().\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_obj_solve_sparse.h",
    "content": "lu_int basiclu_obj_solve_sparse\n(\n    struct basiclu_object *obj,\n    lu_int nzrhs,\n    const lu_int irhs[],\n    const double xrhs[],\n    char trans\n);\n\n/*\nPurpose:\n\n    Call basiclu_solve_sparse() on a BASICLU object. On success, the solution\n    is provided in obj->lhs and the nonzero pattern is stored in\n    obj->ilhs[0..obj->nzlhs-1].\n\nReturn:\n\n    BASICLU_ERROR_invalid_object\n\n        obj is NULL or initialized to a null object.\n\n    Other return codes are passed through from basiclu_solve_sparse().\n\nArguments:\n\n    struct basiclu_object *obj\n\n        Pointer to an initialized BASICLU object.\n\n    The other arguments are passed through to basiclu_solve_sparse().\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_obj_update.h",
    "content": "lu_int basiclu_obj_update\n(\n    struct basiclu_object *obj,\n    double xtbl\n);\n\n/*\nPurpose:\n\n    Call basiclu_update() on a BASICLU object.\n\nReturn:\n\n    BASICLU_ERROR_invalid_object\n\n        obj is NULL or initialized to a null object.\n\n    BASICLU_ERROR_out_of_memory\n\n        reallocation failed because of insufficient memory.\n\n    Other return codes are passed through from basiclu_update().\n\nArguments:\n\n    struct basiclu_object *obj\n\n        Pointer to an initialized BASICLU object.\n\n    The other arguments are passed through to basiclu_update().\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_object.h",
    "content": "struct basiclu_object\n{\n    lu_int *istore;\n    double *xstore;\n    lu_int *Li, *Ui, *Wi;\n    double *Lx, *Ux, *Wx;\n    double *lhs;\n    lu_int *ilhs;\n    lu_int nzlhs;\n    double realloc_factor;\n};\n\n/*\nA variable of type struct basiclu_object must be defined in user code. Its\nmembers are set and maintained by basiclu_obj_* routines. User code should only\naccess the following members:\n\n    xstore (read/write)\n\n        set parameters and get info values\n\n    lhs, ilhs, nzlhs (read only)\n\n        holds solution after solve_sparse() and solve_for_update()\n\n    realloc_factor (read/write)\n\n        Arrays are reallocated for max(realloc_factor, 1.0) times the\n        required size. Default: 1.5\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_solve_dense.h",
    "content": "lu_int basiclu_solve_dense\n(\n    lu_int istore[],\n    double xstore[],\n    lu_int Li[],\n    double Lx[],\n    lu_int Ui[],\n    double Ux[],\n    lu_int Wi[],\n    double Wx[],\n    const double rhs[],\n    double lhs[],\n    char trans\n);\n\n/*\nPurpose:\n\n    Given the factorization computed by basiclu_factorize() or basiclu_update()\n    and the dense right-hand side, rhs, solve a linear system for the solution\n    lhs.\n\nReturn:\n\n    BASICLU_ERROR_invalid_store if istore, xstore do not hold a BASICLU\n    instance. In this case xstore[BASICLU_STATUS] is not set.\n\n    Otherwise return the status code. See xstore[BASICLU_STATUS] below.\n\nArguments:\n\n    lu_int istore[]\n    double xstore[]\n    lu_int Li[]\n    double Lx[]\n    lu_int Ui[]\n    double Ux[]\n    lu_int Wi[]\n    double Wx[]\n\n        Factorization computed by basiclu_factorize() or basiclu_update().\n\n    const double rhs[m]\n\n        The right-hand side vector.\n\n    double lhs[m]\n\n        Uninitialized on entry. On return lhs holds the solution to the linear\n        system.\n\n        lhs and rhs are allowed to overlap. To overwrite rhs with the solution\n        pass pointers to the same array.\n\n    char trans\n\n        Defines which system to solve. 't' or 'T' for the transposed system, any\n        other character for the forward system.\n\nInfo:\n\n    xstore[BASICLU_STATUS]: status code.\n\n        BASICLU_OK\n\n            The linear system has been successfully solved.\n\n        BASICLU_ERROR_argument_missing\n\n            One or more of the pointer/array arguments are NULL.\n\n        BASICLU_ERROR_invalid_call\n\n            The factorization is invalid.\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_solve_for_update.h",
    "content": "lu_int basiclu_solve_for_update\n(\n    lu_int istore[],\n    double xstore[],\n    lu_int Li[],\n    double Lx[],\n    lu_int Ui[],\n    double Ux[],\n    lu_int Wi[],\n    double Wx[],\n    lu_int nzrhs,\n    const lu_int irhs[],\n    const double xrhs[],\n    lu_int *p_nzlhs,\n    lu_int ilhs[],\n    double lhs[],\n    char trans\n);\n\n/*\nPurpose:\n\n    Given the factorization computed by basiclu_factorize() or basiclu_update(),\n    solve a linear system in preparation to update the factorization.\n\n    When the forward system is solved, then the right-hand side is the column\n    to be inserted into the factorized matrix. When the transposed system is\n    solved, then the right-hand side is a unit vector with entry 1 in position\n    of the column to be replaced in the factorized matrix.\n\n    For BASICLU to prepare the update, it is sufficient to compute only a\n    partial solution. If the left-hand side is not requested by the user (see\n    below), then only one triangular solve is done. If the left-hand side is\n    requested, then a second triangular solve is required.\n\nReturn:\n\n    BASICLU_ERROR_invalid_store if istore, xstore do not hold a BASICLU\n    instance. In this case xstore[BASICLU_STATUS] is not set.\n\n    Otherwise return the status code. See xstore[BASICLU_STATUS] below.\n\nArguments:\n\n    lu_int istore[]\n    double xstore[]\n    lu_int Li[]\n    double Lx[]\n    lu_int Ui[]\n    double Ux[]\n    lu_int Wi[]\n    double Wx[]\n\n        Factorization computed by basiclu_factorize() or basiclu_update().\n\n    lu_int nzrhs\n    const lu_int irhs[nzrhs]\n    const double xrhs[nzrhs]\n\n        The right-hand side vector in compressed format.\n\n        When the forward system is solved, irhs[0..nzrhs-1] are the indices of\n        nonzeros and xrhs[0..nzrhs-1] the corresponding values. irhs must not\n        contain duplicates.\n        \n        When the transposed system is solved, the right-hand side is a unit\n        vector with entry 1 in position irhs[0]. nzrhs, xrhs and elements of\n        irhs other than irhs[0] are not accessed. xrhs can be NULL.\n\n    lu_int *p_nzlhs\n    lu_int ilhs[m]\n    lu_int lhs[m]\n\n        If any of p_nzlhs, ilhs or lhs is NULL, then the solution to the linear\n        system is not requested. In this case only the update is prepared.\n\n        Otherwise:\n\n        *p_nzlhs is uninitialized on entry. On return *p_nzlhs holds\n        the number of nonzeros in the solution.\n        The contents of ilhs is uninitialized on entry. On return\n        ilhs[0..*p_nzlhs-1] holds the indices of nonzeros in the solution.\n        The contents of lhs must be initialized to zero on entry. On return\n        the solution is  scattered into lhs.\n\n    char trans\n\n        Defines which system to solve. 't' or 'T' for the transposed system,\n        any other character for the forward system.\n\nParameters:\n\n    xstore[BASICLU_MEMORYL]: length of Li and Lx\n    xstore[BASICLU_MEMORYU]: length of Ui and Ux\n    xstore[BASICLU_MEMORYW]: length of Wi and Wx\n\n    xstore[BASICLU_SPARSE_THRESHOLD]\n\n        Defines which method is used for solving a triangular system. A\n        triangular solve can be done either by the two phase method of Gilbert\n        and Peierls (\"sparse solve\") or by a sequential pass through the vector\n        (\"sequential solve\").\n\n        When the solution to the linear system is requested, then two triangular\n        systems are solved. The first triangular solve is done sparse. The\n        second triangular solve is done sparse if its right-hand side has not\n        more than m * xstore[BASICLU_SPARSE_THRESHOLD] nonzeros. Otherwise the\n        sequential solve is used.\n\n        When the solution to the linear system is not requested, then this\n        parameter has no effect.\n\n        Default: 0.05\n\n    xstore[BASICLU_DROP_TOLERANCE]\n\n        Nonzeros which magnitude is less than or equal to the drop tolerance\n        are removed after each triangular solve. Default: 1e-20\n\nInfo:\n\n    xstore[BASICLU_STATUS]: status code.\n\n        BASICLU_OK\n\n            The updated has been successfully prepared and, if requested, the\n            solution to the linear system has been computed.\n\n        BASICLU_ERROR_argument_missing\n\n            One or more of the mandatory pointer/array arguments are NULL.\n\n        BASICLU_ERROR_invalid_call\n\n            The factorization is invalid.\n\n        BASICLU_ERROR_maximum_updates\n\n            There have already been m Forrest-Tomlin updates, see\n            xstore[BASICLU_NFORREST]. The factorization cannot be updated any\n            more and must be recomputed by basiclu_factorize().\n            The solution to the linear system has not been computed.\n\n        BASICLU_ERROR_invalid_argument\n\n            The right-hand side is invalid (forward system: nzrhs < 0 or\n            nzrhs > m or one or more indices out of range; backward system:\n            irhs[0] out of range).\n\n        BASICLU_REALLOCATE\n\n            The solve was aborted because of insufficient memory in Li,Lx or\n            Ui,Ux to store data for basiclu_update(). The number of additional\n            elements required is given by\n\n                xstore[BASICLU_ADD_MEMORYL] >= 0\n                xstore[BASICLU_ADD_MEMORYU] >= 0\n\n            The user must reallocate the arrays for which additional memory is\n            required. It is recommended to reallocate for the requested number\n            of additional elements plus some extra space for further updates\n            (e.g. 0.5 times the current array length). The new array lengths\n            must be provided in\n\n                xstore[BASICLU_MEMORYL]: length of Li and Lx\n                xstore[BASICLU_MEMORYU]: length of Ui and Ux\n\n            basiclu_solve_for_update() will start from scratch in the next call.\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_solve_sparse.h",
    "content": "lu_int basiclu_solve_sparse\n(\n    lu_int istore[],\n    double xstore[],\n    lu_int Li[],\n    double Lx[],\n    lu_int Ui[],\n    double Ux[],\n    lu_int Wi[],\n    double Wx [],\n    lu_int nzrhs,\n    const lu_int irhs[],\n    const double xrhs[],\n    lu_int *p_nzlhs,\n    lu_int ilhs[],\n    double lhs[],\n    char trans\n);\n\n/*\nPurpose:\n\n    Given the factorization computed by basiclu_factorize() or basiclu_update()\n    and the sparse right-hand side, rhs, solve a linear system for the solution\n    lhs.\n\nReturn:\n\n    BASICLU_ERROR_invalid_store if istore, xstore do not hold a BASICLU\n    instance. In this case xstore[BASICLU_STATUS] is not set.\n\n    Otherwise return the status code. See xstore[BASICLU_STATUS] below.\n\nArguments:\n\n    lu_int istore[]\n    double xstore[]\n    lu_int Li[]\n    double Lx[]\n    lu_int Ui[]\n    double Ux[]\n    lu_int Wi[]\n    double Wx[]\n\n        Factorization computed by basiclu_factorize() or basiclu_update().\n\n    lu_int nzrhs\n    const lu_int irhs[nzrhs]\n    const double xrhs[nzrhs]\n\n        The right-hand side vector in compressed format. irhs[0..nzrhs-1] are\n        the indices of nonzeros and xrhs[0..nzrhs-1] the corresponding values.\n        irhs must not contain duplicates.\n\n    lu_int *p_nzlhs\n    lu_int ilhs[m]\n    lu_int lhs[m]\n\n        *p_nzlhs is uninitialized on entry. On return *p_nzlhs holds\n        the number of nonzeros in the solution.\n        The contents of ilhs is uninitialized on entry. On return\n        ilhs[0..*p_nzlhs-1] holds the indices of nonzeros in the solution.\n        The contents lhs must be initialized to zero on entry. On return\n        the solution is scattered into lhs.\n\n    char trans\n\n        Defines which system to solve. 't' or 'T' for the transposed system,\n        any other character for the forward system.\n\nParameters:\n\n    xstore[BASICLU_SPARSE_THRESHOLD]\n\n        Defines which method is used for solving a triangular system. A\n        triangular solve can be done either by the two phase method of Gilbert\n        and Peierls (\"sparse solve\") or by a sequential pass through the vector\n        (\"sequential solve\").\n\n        Solving B*x=b requires two triangular solves. The first triangular solve\n        is done sparse. The second triangular solve is done sparse if its\n        right-hand side has not more than m * xstore[BASICLU_SPARSE_THRESHOLD]\n        nonzeros. Otherwise the sequential solve is used.\n\n        Default: 0.05\n\n    xstore[BASICLU_DROP_TOLERANCE]\n\n        Nonzeros which magnitude is less than or equal to the drop tolerance\n        are removed after each triangular solve. Default: 1e-20\n\nInfo:\n\n    xstore[BASICLU_STATUS]: status code.\n\n        BASICLU_OK\n\n            The linear system has been successfully solved.\n\n        BASICLU_ERROR_argument_missing\n\n            One or more of the pointer/array arguments are NULL.\n\n        BASICLU_ERROR_invalid_call\n\n            The factorization is invalid.\n\n        BASICLU_ERROR_invalid_argument\n\n            The right-hand side is invalid (nzrhs < 0 or nzrhs > m or one or\n            more indices out of range).\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/basiclu_update.h",
    "content": "lu_int basiclu_update\n(\n    lu_int istore[],\n    double xstore[],\n    lu_int Li[],\n    double Lx[],\n    lu_int Ui[],\n    double Ux[],\n    lu_int Wi[],\n    double Wx[],\n    double xtbl\n);\n\n/*\nPurpose:\n\n    Update the factorization to replace one column of the factorized matrix.\n    A call to basiclu_update() must be preceded by calls to\n    basiclu_solve_for_update() to provide the column to be inserted and the\n    index of the column to be replaced.\n\n    The column to be inserted is defined as the right-hand side in the last call\n    to basiclu_solve_for_update() in which the forward system was solved.\n\n    The index of the column to be replaced is defined by the unit vector in the\n    last call to basiclu_solve_for_update() in which the transposed system was\n    solved.\n\nReturn:\n\n    BASICLU_ERROR_invalid_store if istore, xstore do not hold a BASICLU\n    instance. In this case xstore[BASICLU_STATUS] is not set.\n\n    Otherwise return the status code. See xstore[BASICLU_STATUS] below.\n\nArguments:\n\n    lu_int istore[]\n    double xstore[]\n    lu_int Li[]\n    double Lx[]\n    lu_int Ui[]\n    double Ux[]\n    lu_int Wi[]\n    double Wx[]\n\n        Factorization computed by basiclu_factorize() or basiclu_update().\n\n    double xtbl\n\n        This is an optional argument to monitor numerical stability. xtbl can be\n        either of\n\n        (a) element j0 of the solution to the forward system computed by\n            basiclu_solve_for_update(), where j0 is the column to be replaced;\n\n        (b) the dot product of the incoming column and the solution to the\n            transposed system computed by basiclu_solve_for_update().\n\n        In either case xstore[BASICLU_PIVOT_ERROR] (see below) has a defined\n        value. If monitoring stability is not desired, xtbl can be any value.\n\nParameters:\n\n    xstore[BASICLU_MEMORYL]: length of Li and Lx\n    xstore[BASICLU_MEMORYU]: length of Ui and Ux\n    xstore[BASICLU_MEMORYW]: length of Wi and Wx\n\n    xstore[BASICLU_DROP_TOLERANCE]\n\n        Nonzeros which magnitude is less than or equal to the drop tolerance\n        are removed from the row eta matrix. Default: 1e-20\n\nInfo:\n\n    xstore[BASICLU_STATUS]: status code.\n\n        BASICLU_OK\n\n            The update has successfully completed.\n\n        BASICLU_ERROR_argument_missing\n\n            One or more of the pointer/array arguments are NULL.\n\n        BASICLU_ERROR_invalid_call\n\n            The factorization is invalid or the update was not prepared by two\n            calls to basiclu_solve_for_update().\n\n        BASICLU_REALLOCATE\n\n            Insufficient memory in Wi,Wx. The number of additional elements\n            required is given by\n\n                xstore[BASICLU_ADD_MEMORYW] > 0\n\n            The user must reallocate Wi,Wx. It is recommended to reallocate for\n            the requested number of additional elements plus some extra space\n            for further updates (e.g. 0.5 times the current array length). The\n            new array length must be provided in\n\n                xstore[BASICLU_MEMORYW]: length of Wi and Wx\n\n            basiclu_update will start from scratch in the next call.\n\n        BASICLU_ERROR_singular_update\n\n            The updated factorization would be (numerically) singular. No update\n            has been computed and the old factorization is still valid.\n\n    xstore[BASICLU_PIVOT_ERROR]\n\n        When xtbl was given (see above), then xstore[BASICLU_PIVOT_ERROR] is a\n        measure for numerical stability. It is the difference between two\n        computations of the new pivot element relative to the new pivot element.\n        A value larger than 1e-10 indicates numerical instability and suggests\n        refactorization (and possibly tightening the pivot tolerance).\n\n    xstore[BASICLU_MAX_ETA]\n\n        The maximum entry (in absolute value) in the eta vectors from the\n        Forrest-Tomlin update. A large value, say > 1e6, indicates that pivoting\n        on diagonal element was unstable and refactorization might be necessary.\n*/\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/lu_def.h",
    "content": "#ifndef _LU_DEF_H\n#define _LU_DEF_H\n\n/* -------------------------------------------------------------------------- */\n/* ANSI standard include files */\n/* -------------------------------------------------------------------------- */\n\n#include <stddef.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <math.h>\n#include <stdint.h>\n#include <assert.h>\n\n#include \"ipm/basiclu/basiclu.h\"\n\n#define BASICLU_HASH 7743090    /* hash in istore[0], xstore[0] */\n\nenum { NO_TASK, SINGLETONS, SETUP_BUMP, FACTORIZE_BUMP, BUILD_FACTORS };\n\n/* -------------------------------------------------------------------------- */\n/* standard macros and inlines */\n/* -------------------------------------------------------------------------- */\n\n#define MAX(a,b) ((a)>=(b) ? (a):(b))\n#define MIN(a,b) ((a)<=(b) ? (a):(b))\n\nstatic inline void lu_iswap(lu_int *x, lu_int i, lu_int j)\n{\n    lu_int t = x[i]; x[i] = x[j]; x[j] = t;\n}\n\nstatic inline void lu_fswap(double *x, lu_int i, lu_int j)\n{\n    double t = x[i]; x[i] = x[j]; x[j] = t;\n}\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/lu_file.h",
    "content": "#ifndef _LU_FILE_H\n#define _LU_FILE_H\n\nvoid lu_file_empty(\n    lu_int nlines, lu_int *begin, lu_int *end, lu_int *next, lu_int *prev,\n    lu_int fmem);\n\nvoid lu_file_reappend(\n    lu_int line, lu_int nlines, lu_int *begin, lu_int *end, lu_int *next,\n    lu_int *prev, lu_int *index, double *value, lu_int extra_space);\n\nlu_int lu_file_compress(\n    lu_int nlines, lu_int *begin, lu_int *end, const lu_int *next,\n    lu_int *index, double *value, double stretch, lu_int pad);\n\nlu_int lu_file_diff(\n    lu_int nrow, const lu_int *begin_row, const lu_int *end_row,\n    const lu_int *begin_col, const lu_int *end_col, const lu_int *index,\n    const double *value);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/lu_internal.h",
    "content": "#ifndef _LU_INTERNAL_H\n#define _LU_INTERNAL_H\n\n#include \"ipm/basiclu/lu_def.h\"\n\n/* -------------------------------------------------------------------------- */\n/* struct lu */\n/* -------------------------------------------------------------------------- */\n\n/*\n    This data structure provides access to istore, xstore.\n\n    lu_* routines do not access istore, xstore directly. Instead, they operate\n    on a struct lu object. Scalar quantities stored in istore, xstore are copied\n    to a struct lu object by lu_load() and copied back by lu_save(). Subarrays\n    of istore, xstore and the user arrays Li, Lx, Ui, Ux, Wi, Wx are aliased by\n    pointers in struct lu.\n*/\n\nstruct lu\n{\n    /* user parameters, not modified */\n    lu_int Lmem;\n    lu_int Umem;\n    lu_int Wmem;\n    double droptol;\n    double abstol;\n    double reltol;\n    lu_int nzbias;\n    lu_int maxsearch;\n    lu_int pad;\n    double stretch;\n    double compress_thres;\n    double sparse_thres;\n    lu_int search_rows;\n\n    /* user readable */\n    lu_int m;\n    lu_int addmemL;\n    lu_int addmemU;\n    lu_int addmemW;\n\n    lu_int nupdate;\n    lu_int nforrest;\n    lu_int nfactorize;\n    lu_int nupdate_total;\n    lu_int nforrest_total;\n    lu_int nsymperm_total;\n    lu_int Lnz;                  /* nz in L excluding diagonal */\n    lu_int Unz;                  /* nz in U excluding diagonal */\n    lu_int Rnz;                  /* nz in update etas excluding diagonal */\n    double min_pivot;\n    double max_pivot;\n    double max_eta;\n    double update_cost_numer;\n    double update_cost_denom;\n    double time_factorize;\n    double time_solve;\n    double time_update;\n    double time_factorize_total;\n    double time_solve_total;\n    double time_update_total;\n    lu_int Lflops;\n    lu_int Uflops;\n    lu_int Rflops;\n    double condestL;\n    double condestU;\n    double normL;\n    double normU;\n    double normestLinv;\n    double normestUinv;\n    double onenorm;             /* 1-norm and inf-norm of matrix after fresh  */\n    double infnorm;             /* factorization with dependent cols replaced */\n    double residual_test;       /* computed by lu_residual_test() */\n\n    lu_int matrix_nz;           /* nz in basis matrix when factorized */\n    lu_int rank;                /* rank of basis matrix when factorized */\n    lu_int bump_size;\n    lu_int bump_nz;\n    lu_int nsearch_pivot;       /* # rows/cols searched for pivot */\n    lu_int nexpand;             /* # rows/cols expanded in factorize */\n    lu_int ngarbage;            /* # garbage collections in factorize */\n    lu_int factor_flops;        /* # flops in factorize */\n    double time_singletons;\n    double time_search_pivot;\n    double time_elim_pivot;\n\n    double pivot_error;         /* error estimate for pivot in last update */\n\n    /* private */\n    lu_int task;                /* the part of factorization in progress */\n    lu_int pivot_row;           /* chosen pivot row */\n    lu_int pivot_col;           /* chosen pivot column */\n    lu_int ftran_for_update;    /* >= 0 if FTRAN prepared for update */\n    lu_int btran_for_update;    /* >= 0 if BTRAN prepared for update */\n    lu_int marker;              /* see @marked, below */\n    lu_int pivotlen;            /* length of @pivotcol, @pivotrow; <= 2*m */\n    lu_int rankdef;             /* # columns removed from active submatrix\n                                   because maximum was 0 or < abstol */\n    lu_int min_colnz;           /* colcount lists 1..min_colnz-1 are empty */\n    lu_int min_rownz;           /* rowcount lists 1..min_rownz-1 are empty */\n\n    /* aliases to user arrays */\n    lu_int *Lindex, *Uindex, *Windex;\n    double *Lvalue, *Uvalue, *Wvalue;\n\n    /*\n     * pointers into istore\n     *\n     * When two declaration lists are on one line, then the arrays from the\n     * second list share memory with the array from the first list. The arrays\n     * from the first lists are used during factorization, the arrays from the\n     * second lists are used during solves/updates.\n     */\n\n    /* documented in lu_singletons.c, lu_setup_bump.c, lu_build_factors.c */\n    lu_int *colcount_flink;     lu_int *pivotcol;\n    lu_int *colcount_blink;     lu_int *pivotrow;\n    lu_int *rowcount_flink;     lu_int *Rbegin, *eta_row;\n    lu_int *rowcount_blink;     lu_int *iwork1;\n    lu_int *Wbegin;             lu_int *Lbegin;    /* + Wbegin reused */\n    lu_int *Wend;               lu_int *Ltbegin;   /* + Wend   reused */\n    lu_int *Wflink;             lu_int *Ltbegin_p; /* + Wflink reused */\n    lu_int *Wblink;             lu_int *p;         /* + Wblink reused */\n    lu_int *pinv;               lu_int *pmap;\n    lu_int *qinv;               lu_int *qmap;\n    lu_int *Lbegin_p;           /* Lbegin_p reused */\n    lu_int *Ubegin;             /* Ubegin   reused */\n\n    lu_int *iwork0;             lu_int *marked;\n    /* iwork0: size m workspace, zeroed */\n    /* marked: size m workspace, 0 <= marked[i] <= @marker */\n\n    /* pointers into xstore */\n    double *work0;              /* size m workspace, zeroed */\n    double *work1;              /* size m workspace, uninitialized */\n    double *col_pivot;          /* pivot elements by column index */\n    double *row_pivot;          /* pivot elements by row index */\n};\n\n\n/* -------------------------------------------------------------------------- */\n/* Internal function prototypes */\n/* -------------------------------------------------------------------------- */\n\nlu_int lu_load(\n    struct lu *this, lu_int *istore, double *xstore, lu_int *Li, double *Lx,\n    lu_int *Ui, double *Ux, lu_int *Wi, double *Wx);\n\nlu_int lu_save(\n    const struct lu *this, lu_int *istore, double *xstore, lu_int status);\n\nvoid lu_reset(struct lu *this);\n\nvoid lu_initialize(lu_int m, lu_int *istore, double *xstore);\n\nlu_int lu_factorize_bump (struct lu *this);\n\nlu_int lu_build_factors(struct lu *this);\n\nvoid lu_garbage_perm(struct lu *this);\n\nlu_int lu_markowitz(struct lu *this);\n\nlu_int lu_pivot(struct lu *this);\n\nlu_int lu_setup_bump(\n    struct lu *this, const lu_int *Bbegin, const lu_int *Bend, const lu_int *Bi,\n    const double *Bx);\n\nlu_int lu_singletons(\n    struct lu *this, const lu_int *Bbegin, const lu_int *Bend, const lu_int *Bi,\n    const double *Bx);\n\nvoid lu_solve_dense(\n    struct lu *this, const double *rhs, double *lhs, char trans);\n\nlu_int lu_solve_for_update(\n    struct lu *this, const lu_int nrhs, const lu_int *irhs, const double *xrhs,\n    lu_int *nlhs, lu_int *ilhs, double *xlhs, char trans);\n\nvoid lu_solve_sparse(\n    struct lu *this, const lu_int nrhs, const lu_int *irhs, const double *xrhs,\n    lu_int *nlhs, lu_int *ilhs, double *xlhs, char trans);\n\nlu_int lu_dfs(\n    lu_int i, const lu_int *begin, const lu_int *end, const lu_int *index,\n    lu_int top, lu_int *xi, lu_int *pstack, lu_int *marked, const lu_int M);\n\nlu_int lu_solve_symbolic(\n    const lu_int m, const lu_int *begin, const lu_int *end, const lu_int *index,\n    const lu_int nrhs, const lu_int *irhs, lu_int *ilhs, lu_int *pstack,\n    lu_int *marked, const lu_int M);\n\nlu_int lu_solve_triangular(\n    const lu_int nz_symb, const lu_int *pattern_symb, const lu_int *begin,\n    const lu_int *end, const lu_int *index, const double *value,\n    const double *pivot, const double droptol, double *lhs, lu_int *pattern,\n    lu_int *flops);\n\nlu_int lu_update(struct lu *this, double xtbl);\n\ndouble lu_condest(\n    lu_int m, const lu_int *Ubegin, const lu_int *Ui, const double *Ux,\n    const double *pivot, const lu_int *perm, int upper, double *work,\n    double *norm, double *norminv);\n\ndouble lu_normest(\n    lu_int m, const lu_int *Ubegin, const lu_int *Ui, const double *Ux,\n    const double *pivot, const lu_int *perm, int upper, double *work);\n\nvoid lu_matrix_norm(\n    struct lu *this, const lu_int *Bbegin, const lu_int *Bend, const lu_int *Bi,\n    const double *Bx);\n\nvoid lu_residual_test(\n    struct lu *this, const lu_int *Bbegin, const lu_int *Bend, const lu_int *Bi,\n    const double *Bx);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/basiclu/lu_list.h",
    "content": "#ifndef _LU_LIST_H\n#define _LU_LIST_H\n\n/*\n * lu_list.h\n *\n * Copyright (C) 2016-2018  ERGO-Code\n *\n * Implementation of doubly linked lists (see [1] section 5.5)\n *\n * Maintain nelem elements in nlist doubly linked lists. Each element can belong\n * to zero or one list at a time.\n *\n * The implementation uses arrays\n *\n *  flink[0..nelem+nlist-1],\n *  blink[0..nelem+nlist-1].\n *\n * In each array, the leading nelem entries store links, the trailing nlist\n * entries store heads. That is, for 0 <= i < nelem and 0 <= j < nlist:\n *\n *  flink[i]        next element in the list containing element i\n *  blink[i]        previous element in the list containing element i\n *  flink[nelem+j]  first element in list j\n *  blink[nelem+j]  last element in list j\n *\n * The forward link of the last element in a list points to its flink-head. The\n * backward link of the first element in a list points to its blink-head. For\n * empty lists the heads point to themselves. When an element is not in any list\n * its links point to itself.\n *\n * Optionally the quantity min_list >= 1 can be updated such that lists\n * 1..min_list-1 are empty. Notice that list 0 is not covered by min_list.\n *\n * [1] Istvan Maros, Computational Techniques of the Simplex Method\n *\n * Methods:\n *\n *  lu_list_init\n *  lu_list_add\n *  lu_list_remove\n *  lu_list_move\n *  lu_list_swap\n *\n * The methods are defined in this header file as static inline. This header\n * file must be included after lu_def.h so that lu_int is defined.\n *\n */\n\n/* ==========================================================================\n * lu_list_init\n *\n * Initialize all lists to empty.\n * ========================================================================== */\n\nstatic inline void lu_list_init(\n    lu_int *flink, lu_int *blink, lu_int nelem, lu_int nlist, lu_int *min_list)\n{\n    lu_int i;\n    for (i = 0; i < nelem+nlist; i++) flink[i] = blink[i] = i;\n    if (min_list)\n        *min_list = MAX(1, nlist);\n}\n\n\n/* ==========================================================================\n * lu_list_add\n *\n * Add element @elem to list @list. @elem must not be in any list already.\n * If list > 0 and min_list != NULL, update *min_list = min(*min_list, list).\n * ========================================================================== */\n\nstatic inline void lu_list_add(\n    lu_int elem, lu_int list, lu_int *flink, lu_int *blink, lu_int nelem,\n    lu_int *min_list)\n{\n    lu_int temp;\n    assert(flink[elem] == elem);\n    assert(blink[elem] == elem);\n    /* append elem to the end of list */\n    temp = blink[nelem+list];\n    blink[nelem+list] = elem;\n    blink[elem] = temp;\n    flink[temp] = elem;\n    flink[elem] = nelem+list;\n    if (list > 0 && min_list && list < *min_list)\n        *min_list = list;\n}\n\n\n/* ==========================================================================\n * lu_list_remove\n *\n * Remove element @elem from its list. If @elem was not in a list before,\n * then do nothing.\n * ========================================================================== */\n\nstatic inline void lu_list_remove(\n    lu_int *flink, lu_int *blink, lu_int elem)\n{\n    flink[blink[elem]] = flink[elem];\n    blink[flink[elem]] = blink[elem];\n    flink[elem] = elem;\n    blink[elem] = elem;\n}\n\n\n/* ==========================================================================\n * lu_list_move\n *\n * Remove element @elem from its list (if in a list) and add it to list @list.\n * ========================================================================== */\n\nstatic inline void lu_list_move(\n    lu_int elem, lu_int list, lu_int *flink, lu_int *blink, lu_int nelem,\n    lu_int *min_list)\n{\n    lu_list_remove(flink, blink, elem);\n    lu_list_add(elem, list, flink, blink, nelem, min_list);\n}\n\n\n/* ==========================================================================\n * lu_list_swap\n *\n * Swap elements @e1 and @e2, which both must be in a list. If @e1 and @e2\n * are in the same list, then their positions are swapped. If they are in\n * different lists, then each is moved to the other's list.\n * ========================================================================== */\n\nstatic inline void lu_list_swap(\n    lu_int *flink, lu_int *blink, const lu_int e1, const lu_int e2)\n{\n    const lu_int e1next = flink[e1];\n    const lu_int e2next = flink[e2];\n    const lu_int e1prev = blink[e1];\n    const lu_int e2prev = blink[e2];\n\n    assert(e1next != e1);       /* must be in a list */\n    assert(e2next != e2);\n\n    if (e1next == e2)\n    {\n        flink[e2] = e1;\n        blink[e1] = e2;\n        flink[e1prev] = e2;\n        blink[e2] = e1prev;\n        flink[e1] = e2next;\n        blink[e2next] = e1;\n    }\n    else if (e2next == e1)\n    {\n        flink[e1] = e2;\n        blink[e2] = e1;\n        flink[e2] = e1next;\n        blink[e1next] = e2;\n        flink[e2prev] = e1;\n        blink[e1] = e2prev;\n    }\n    else\n    {\n        flink[e2] = e1next;\n        blink[e1next] = e2;\n        flink[e2prev] = e1;\n        blink[e1] = e2prev;\n        flink[e1prev] = e2;\n        blink[e2] = e1prev;\n        flink[e1] = e2next;\n        blink[e2next] = e1;\n    }\n}\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/basiclu_kernel.h",
    "content": "#ifndef IPX_BASICLU_KERNEL_H_\n#define IPX_BASICLU_KERNEL_H_\n\n#include \"ipm/ipx/lu_factorization.h\"\n\nnamespace ipx {\n\nclass BasicLuKernel : public LuFactorization {\nprivate:\n    void _Factorize(Int dim, const Int* Bbegin, const Int* Bend,\n                    const Int* Bi, const double* Bx, double pivottol,\n                    bool strict_abs_pivottol,\n                    SparseMatrix* L, SparseMatrix* U,\n                    std::vector<Int>* rowperm, std::vector<Int>* colperm,\n                    std::vector<Int>* dependent_cols) override;\n};\n\n}  // namespace ipx\n\n#endif  // IPX_BASICLU_KERNEL_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/basiclu_wrapper.h",
    "content": "#ifndef IPX_BASICLU_WRAPPER_H_\n#define IPX_BASICLU_WRAPPER_H_\n\n#include \"ipm/ipx/control.h\"\n#include \"ipm/ipx/lu_update.h\"\n\nnamespace ipx {\n\nclass BasicLu : public LuUpdate {\npublic:\n    BasicLu(const Control& control, Int dim);\n    ~BasicLu() = default;\n\nprivate:\n    Int _Factorize(const Int* Bbegin, const Int* Bend, const Int* Bi,\n                   const double* Bx, bool strict_abs_pivottol) override;\n    void _GetFactors(SparseMatrix* L, SparseMatrix* U, Int* rowperm,\n                     Int* colperm, std::vector<Int>* dependent_cols) override;\n    void _SolveDense(const Vector& rhs, Vector& lhs, char trans) override;\n    void _FtranForUpdate(Int nz, const Int* bi, const double* bx) override;\n    void _FtranForUpdate(Int nz, const Int* bi, const double* bx,\n                         IndexedVector& lhs) override;\n    void _BtranForUpdate(Int j) override;\n    void _BtranForUpdate(Int j, IndexedVector& lhs) override;\n    Int _Update(double pivot) override;\n    bool _NeedFreshFactorization() override;\n    double _fill_factor() const override;\n    double _pivottol() const override;\n    void _pivottol(double new_pivottol) override;\n\n    // Reallocates (Li,Lx), (Ui,Ux) and/or (Wi,Wx) as requested by BASICLU.\n    void Reallocate();\n\n    // When memory is reallocated, allocate for kReallocFactor*required amount.\n    static constexpr double kReallocFactor = 1.5;\n\n    const Control& control_;\n    std::vector<Int> istore_;\n    std::vector<double> xstore_;\n    std::vector<Int> Li_, Ui_, Wi_;\n    std::vector<double> Lx_, Ux_, Wx_;\n    double fill_factor_;\n};\n\n}  // namespace ipx\n\n#endif  // IPX_BASICLU_WRAPPER_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/basis.h",
    "content": "#ifndef IPX_BASIS_H_\n#define IPX_BASIS_H_\n\n#include <cassert>\n#include <memory>\n#include <vector>\n#include \"ipm/ipx/control.h\"\n#include \"ipm/ipx/indexed_vector.h\"\n#include \"ipm/ipx/lu_update.h\"\n#include \"ipm/ipx/model.h\"\n#include \"ipm/ipx/sparse_matrix.h\"\n\nnamespace ipx {\n\n// A Basis object is associated with a model. It manages an ordered set of m\n// column indices such that AI[:,basis] is nonsingular, where AI is the\n// m-by-(n+m) matrix of the model. The class provides the usual simplex-type\n// linear algebra operations.\n\nclass Basis {\npublic:\n    // Constructor initializes to slack basis. The object stores a reference to\n    // a model, which must be valid as long as the basis is used. No data from\n    // model is copied.\n    Basis(const Control& control, const Model& model);\n\n    // A basis object cannot be copied (at the moment) because the LU\n    // factorization is owned by a std::unique_ptr.\n    Basis(const Basis&) = delete;\n    Basis& operator=(const Basis&) = delete;\n\n    // Move is OK.\n    Basis(Basis&&) = default;\n    // But assignment is implicitly deleted due to reference members\n    Basis& operator=(Basis&&) = delete;\n\n    ~Basis() = default;\n\n    // Returns the index of the variable at position p in the basis.\n    Int operator[](Int p) const;\n\n    // If variable j is basic, then returns its position in the basis.\n    // Otherwise returns -1.\n    Int PositionOf(Int j) const;\n\n    // Returns true if variable j is in the basis.\n    bool IsBasic(Int j) const;\n\n    // Returns true if variable j is not in the basis.\n    bool IsNonbasic(Int j) const;\n\n    // Each variable has a status from one of the following:\n    //\n    //  NONBASIC_FIXED: variable is not in the basis (and will never enter)\n    //  NONBASIC:       variable is not in the basis (but may enter)\n    //  BASIC:          variable is in the basis (but may leave)\n    //  BASIC_FREE:     variable is in the basis (and will never leave)\n    //\n    // The notes in () are not enforced or required by the implementation.\n    // From the view point of the class the two nonbasic and the two basic\n    // statuses behave the same. The four statuses are provided to make writing\n    // user code more convenient.\n    enum BasicStatus { NONBASIC_FIXED = -2, NONBASIC, BASIC, BASIC_FREE };\n\n    // Returns status of variable j.\n    BasicStatus StatusOf(Int j) const;\n\n    // Switches status of variable j to NONBASIC_FIXED. The variable must not be\n    // in the basis.\n    void FixNonbasicVariable(Int j);\n\n    // Switches status of variable j to BASIC_FREE. The variable must be in the\n    // basis.\n    void FreeBasicVariable(Int j);\n\n    // Switches status from NONBASIC_FIXED to NONBASIC for all variables.\n    void UnfixVariables();\n\n    // Switches status from BASIC_FREE to BASIC for all variables.\n    void UnfreeVariables();\n\n    // Sets the basis to the slack basis.\n    void SetToSlackBasis();\n\n    // Loads basis and factorizes it.\n    // @basic_status: size n+m array with BasicStatus of each variable\n    // Returns: IPX_ERROR_invalid_basis if the basis is invalid (basic_status\n    //          contains an invalid entry or # basic variables != m). In this\n    //          case the old basis is unchanged.\n    //          Otherwise the return code from Factorize() is returned and the\n    //          old basis has been replaced. If the given basis is singular, it\n    //          will be repaired with slack variables by the LU factorization.\n    Int Load(const int* basic_status);\n\n    // Factorizes the current basis matrix from scratch. If nonsingular, a\n    // stability check is performed afterwards and the factorization is repeated\n    // with a tighter pivot tolerance if the LU factors were unstable.\n    // Returns: IPX_ERROR_basis_singular if the factorization was singular and\n    //          slack columns have been inserted into the basis. This is not an\n    //          \"error\" from the view point of the Basis object, which remains\n    //          in a perfectly valid state.\n    //          0 otherwise.\n    Int Factorize();\n\n    // Returns true if the LU factorization has not been updated.\n    bool FactorizationIsFresh() const;\n\n    // Extracts L, U and permutations such that\n    //\n    //   B[rowperm,colperm] = (L+I)*U,\n    //\n    // where B is the current basis matrix, L is strictly lower triangular and\n    // U is upper triangular. All arguments can be NULL, in which case the\n    // quantity is not returned. Can only be called if FactorizationIsFresh()\n    // returns true.\n    void GetLuFactors(SparseMatrix* L, SparseMatrix* U, Int* rowperm,\n                      Int* colperm) const;\n\n    // Solves linear system with dense right-hand side.\n    // @rhs: size m right-hand side vector\n    // @lhs: size m solution vector\n    // @trans: 't' or 'T' for transposed, other character for forward system\n    // @rhs and @lhs may refer to the same object.\n    void SolveDense(const Vector& rhs, Vector& lhs, char trans) const;\n\n    // Solves linear system in preparation for update.\n    // @j:   column index defining the linear system to be solved.\n    //       If j is basic then BTRAN is computed. RHS is the unit vector\n    //       corresponding to position of j in the basis.\n    //       If j is nonbasic then FTRAN is computed. RHS is AI[:,j].\n    // @lhs: returns the solution to the linear system if given.\n    void SolveForUpdate(Int j, IndexedVector& lhs);\n    void SolveForUpdate(Int j);\n\n    // Computes a row of the (simplex) tableau matrix and performs BTRAN in\n    // preparation for an update.\n    // @jb:    basic variable. When jb is at position p in the basis, then row p\n    //         of the tableau matrix is computed.\n    // @btran: BTRAN solution\n    // @row:   returns the tableau row. Basic variables have value zero.\n    // @ignore_fixed: If true, then the tableau row entry of variables with\n    //                status NONBASIC_FIXED is set to zero.\n    // The method chooses between a sparse-vector*sparse-matrix and a\n    // dense-vector*sparse-matrix operation. Accordingly the pattern of row is\n    // or is not set up.\n    void TableauRow(Int jb, IndexedVector& btran, IndexedVector& row,\n                    bool ignore_fixed = false);\n\n    // Exchanges basic variable jb with nonbasic variable jn if the update to\n    // the factorization is stable. In detail, the following steps are done:\n    //\n    // (1)  Updates the LU factorization.\n    // (2a) If the LU update was stable, updates the basis.\n    // (2b) If the LU update was unstable, keeps the basis unchanged and\n    //      refactorizes, possibly after tightening the LU pivot tolerance.\n    //\n    // Returns:\n    // (2a) The new basis might be refactorized for speed or memory reasons.\n    //      In this case returns Factorize(). Otherwise returns 0.\n    // (2b) If the factorization was not fresh and/or the pivot tolerance was\n    //      tightened, returns Factorize(). Otherwise returns\n    //      IPX_ERROR_basis_too_ill_conditioned. In this case the Basis object\n    //      is in an inconsistent state. (A basis repair could be done here; at\n    //      the moment we simply give up.)\n    //\n    // At least one of the forward or transposed system must have been solved\n    // before in preparation for the update.\n    //\n    // @jb: Basic variable that leaves the basis. Status of jb becomes NONBASIC.\n    // @jn: Nonbasic variable that enters the basis. Status of jn becomes BASIC.\n    // @tableau_entry: entry in pivot col and pivot row of the tableau matrix.\n    // @sys: > 0 if forward system needs to be solved in preparation for update.\n    //       < 0 if transposed sys needs to be solved in preparation for update.\n    //         0 if both systems have already been solved.\n    // @exchanged: true on return if the basis exchange was performed.\n    Int ExchangeIfStable(Int jb, Int jn, double tableau_entry, int sys,\n                         bool* exchanged);\n\n    // Computes x[basic], y and z[nonbasic] such that Ax=b and A'y+z=c.\n    // @x vector of size n+m. On entry the nonbasic components of x must be set.\n    // @y vector of size m, undefined on entry.\n    // @z vector of size n+m. On entry the basic components of z must be set.\n    // On return the remaining components have been computed.\n    void ComputeBasicSolution(Vector& x, Vector& y, Vector& z) const;\n\n    // Constructs a (nonsingular) basis. Given a nonnegative weight for each\n    // column of AI, columns with larger weight are preferably chosen as basic\n    // columns. Columns with infinite weight will always become basic unless the\n    // basis matrix would become singular. Columns with zero weight will always\n    // become nonbasic unless (for a slack column) they are required to form a\n    // nonsingular basis.\n    //\n    // If parameter crash_basis is nonzero, a crash procedure is used.\n    // Otherwise the method starts with the slack basis and pivots columns with\n    // zero or infinite weight out of or into the basis one at a time.\n    //\n    // @colweights: vector of length n+m with nonnegative entries\n    void ConstructBasisFromWeights(const double* colweights, Info* info);\n\n    // Estimates the smallest singular value of the basis matrix.\n    double MinSingularValue() const;\n\n    // Computes the # structural nonzero entries per row and column of\n    // inverse(B).\n    // @rowcounts, @colcounts: either NULL or size m array\n    void SymbolicInvert(Int* rowcounts, Int* colcounts) const;\n\n    // Computes the structural density of inverse(B).\n    double DensityInverse() const;\n\n    // Returns the associated Model.\n    const Model& model() const;\n\n    // Returns statistics.\n    Int factorizations() const;       // # LU factorizations\n    Int updates_total() const;        // total # basis updates\n    double frac_ftran_sparse() const; // fraction of FTRAN solutions sparse\n    double frac_btran_sparse() const; // fraction of BTRAN solutions sparse\n    double time_factorize() const;    // time LU factorizations\n    double time_ftran() const;        // time FTRAN, including partial\n    double time_btran() const;        // time BTRAN, including partial\n    double time_update() const;       // time LU update\n    double mean_fill() const;         // geom. mean of LU fill factors\n    double max_fill() const;          // max LU fill factor\n    \n    void reportBasisData() const;\n  \nprivate:\n    // Basis repair terminates when the maximum absolute entry in inverse(B)\n    // is smaller than kBasisRepairThreshold. At most kMaxBasisRepair repair\n    // operations are performed.\n    static constexpr double kBasisRepairThreshold = 1e5;\n    static constexpr Int kMaxBasisRepair = 200;\n\n    // Adjusts basis_ and map2basis_ after a singular factorization. Must be\n    // called exactly once after the factorization. Returns the # slack\n    // variables inserted into the basis (0 if the factorization was\n    // nonsingular).\n    Int AdaptToSingularFactorization();\n\n    // If possible, tightens the pivot tolerance for subsequent LU\n    // factorizations. Returns true if the tolerance was tightened.\n    bool TightenLuPivotTol();\n\n    // \"Crashes\" a basis with preference for variables with larger weight.\n    // On return the object has been initialized to a basis that is nonsingular\n    // in exact arithmetic. The condition number of the basis matrix can be\n    // unacceptably high, however.\n    void CrashBasis(const double* colweights);\n\n    // Repairs singularities in the basis matrix by replacing basic columns by\n    // slack columns. The status of slack variables that enter the basis becomes\n    // BASIC and the status of variables that leave the basis becomes NONBASIC.\n    // On return info->basis_repairs >= 0 if repaired successfully, < 0 if\n    // failed.\n    void Repair(Info* info);\n\n    // Factorizes the basis matrix using a strict absolute pivot tolerance (if\n    // supported by the LU implementation). Does not perform the stability check\n    // that Factorize() does.\n    // @num_dropped: if not NULL, returns the # columns that were dropped from\n    //               the basis matrix and replaced by unit columns.\n    void CrashFactorize(Int* num_dropped);\n\n    // Similar to ExchangeIfStable() but is guaranteed to exchange jb and jn.\n    // If refactorization is required (either for speed or because the LU\n    // update was unstable) calls CrashFactorize() on the new basis.\n    // @num_dropped: is passed to CrashFactorize() if called; otherwise is set\n    //               to 0 if not NULL.\n    void CrashExchange(Int jb, Int jn, double tableau_entry, int sys,\n                       Int* num_dropped);\n\n    // Pivots free variables into the basis if they can replace a nonfree\n    // basic variable. A variable is \"free\" if its weight is infinite. If a free\n    // variable cannot be pivoted into the basis, then its column is linearly\n    // dependent on columns of free basic variables. info->dependent_cols\n    // reports the # such variables.\n    void PivotFreeVariablesIntoBasis(const double* colweights, Info* info);\n\n    // Pivots fixed variables out of the basis if they can be replaced by a\n    // nonfixed variable. A variable is \"fixed\" if its weight is zero. If a\n    // fixed variable cannot be pivoted out of the basis, then\n    // the rows of AI without that variable are linearly dependent.\n    // info->dependent_rows reports the # such variables.\n    void PivotFixedVariablesOutOfBasis(const double* colweights, Info* info);\n\n    const Control& control_;\n    const Model& model_;\n    std::vector<Int> basis_;    // m column indices of AI\n\n    // For 0 <= j < n+m, map2basis_[j] is one of the following:\n    //  -2:            variable is NONBASIC_FIXED\n    //  -1:            variable is NONBASIC\n    //   0 <= p < m:   variable is BASIC and at position p in the basis\n    //   m <= p < 2*m: variable is BASIC_FREE and at position p-m in the basis\n    std::vector<Int> map2basis_;\n\n    mutable std::unique_ptr<LuUpdate> lu_; // LU factorization of basis matrix\n    bool factorization_is_fresh_;  // true if LU factorization not updated\n\n    Int num_factorizations_{0};    // # LU factorizations\n    Int num_updates_{0};           // # basis updates\n    Int num_ftran_{0};             // # FTRAN operations, excluding partial\n    Int num_btran_{0};             // # BTRAN operations, excluding partial\n    Int num_ftran_sparse_{0};      // # ... with sparse solution\n    Int num_btran_sparse_{0};      // # ... with sparse solution\n    double time_ftran_{0.0};       // time for FTRAN ops, including partial\n    double time_btran_{0.0};       // time for BTRAN ops, including partial\n    double time_update_{0.0};      // time for LU updates\n    double time_factorize_{0.0};   // time for LU factorizations\n    std::vector<double> fill_factors_; // fill factors from LU factorizations\n    double sum_ftran_density_{0.0};\n    double sum_btran_density_{0.0};\n};\n\ninline Int Basis::operator[](Int p) const {\n    return basis_[p];\n}\n\ninline Basis::BasicStatus Basis::StatusOf(Int j) const {\n    const Int m = model_.rows();\n    const Int p = map2basis_[j];\n    assert(p >= -2 && p < 2*m);\n    if (p < 0)\n        return p == -1 ? NONBASIC : NONBASIC_FIXED;\n    else\n        return p < m ? BASIC : BASIC_FREE;\n}\n\ninline Int Basis::PositionOf(Int j) const {\n    const Int m = model_.rows();\n    const Int p = map2basis_[j];\n    assert(p >= -2 && p < 2*m);\n    return p < 0 ? -1 : p < m ? p : p-m;\n}\n\ninline bool Basis::IsBasic(Int j) const {\n    return StatusOf(j) == BASIC || StatusOf(j) == BASIC_FREE;\n}\n\ninline bool Basis::IsNonbasic(Int j) const {\n    return StatusOf(j) == NONBASIC || StatusOf(j) == NONBASIC_FIXED;\n}\n\n// Returns x[basis] (in Matlab notation).\nVector CopyBasic(const Vector& x, const Basis& basis);\n\n}  // namespace ipx\n\n#endif  // IPX_BASIS_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/conjugate_residuals.h",
    "content": "#ifndef IPX_CONJUGATE_RESIDUALS_H_\n#define IPX_CONJUGATE_RESIDUALS_H_\n\n// Implementation of the (preconditioned) Conjugate Residuals (CR) method for\n// symmetric positive definite linear systems. Without preconditioning, the\n// method is implemented as in [1, Algorithm 6.20]. The implementation with\n// preconditioning is described in [2, Section 6.3].\n//\n// [1] Y. Saad, \"Iterative Methods for Sparse Linear Systems\", 2nd (2003)\n// [2] L. Schork, \"Basis Preconditioning in Interior Point Methods\", PhD thesis\n//     (2018)\n\n#include \"ipm/ipx/control.h\"\n#include \"ipm/ipx/linear_operator.h\"\n\nnamespace ipx {\n\nclass ConjugateResiduals {\npublic:\n    // Constructs a ConjugateReisdual object. The object does not have any\n    // memory allocated between calls to Solve().\n    // @control for InterruptCheck() and Debug(). No parameters are accessed.\n    ConjugateResiduals(const Control& control);\n\n    // Solves C*lhs = rhs. @lhs has initial iterate on entry, solution on\n    // return. The method terminates when reaching the accuracy criterion\n    //\n    //   Infnorm(residual) <= tol               (if resscale == NULL), or\n    //   Infnorm(resscale.*residual) <= tol     (if resscale != NULL).\n    //\n    // In the latter case, @resscale must be an array of dimension @rhs.size().\n    // The method also stops after @maxiter iterations. If @maxiter < 0, a\n    // maximum of @rhs.size()+100 iterations is performed. (In exact arithmetic\n    // the solution would be found after @rhs.size() iterations. It happened on\n    // some LP models with m << n, e.g. \"rvb-sub\" from MIPLIB2010, that the CR\n    // method did not reach the termination criterion within m iterations,\n    // causing the IPM to fail. Giving the CR method 100 extra iterations\n    // resolved the issue on all LP models from our test set where it occurred.)\n    //\n    // If the @P argument is given, it is used as preconditioner (which\n    // approximates inverse(C)) and must be symmetric positive definite.\n    //\n    void Solve(LinearOperator& C, const Vector& rhs,\n               double tol, const double* resscale, Int maxiter, Vector& lhs);\n    void Solve(LinearOperator& C, LinearOperator& P, const Vector& rhs,\n               double tol, const double* resscale, Int maxiter, Vector& lhs);\n\n    // Returns 0 if the last call to Solve() terminated successfully (i.e.\n    // the system was solved to the required accuracy). Otherwise returns\n    // IPX_ERROR_cr_iter_limit          if iteration limit was reached\n    // IPX_ERROR_cr_matrix_not_posdef   if v'*C*v <= 0 for some vector v\n    // IPX_ERROR_cr_precond_not_posdef  if v'*P*v <= 0 for some vector v\n    // IPX_ERROR_cr_inf_or_nan          if overflow occurred\n    // IPX_ERROR_cr_no_progress         if no progress due to round-off errors\n    // IPX_ERROR_user_interrupt         if interrupted by user in control\n    // IPX_ERROR_time_interrupt         if interrupted by time limit in control\n    Int errflag() const;\n\n    // Returns the # iterations in the last call to Solve().\n    Int iter() const;\n\n    // Returns the runtime of the last call to Solve().\n    double time() const;\n\nprivate:\n    const Control& control_;\n    Int errflag_{0};\n    Int iter_{0};\n    double time_{0.0};\n};\n\n}  // namespace ipx\n\n#endif  // IPX_CONJUGATE_RESIDUALS_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/control.h",
    "content": "#ifndef IPX_CONTROL_H_\n#define IPX_CONTROL_H_\n\n#include <fstream>\n#include <ostream>\n#include <sstream>\n#include <string>\n#include \"io/HighsIO.h\"\n#include \"ipm/ipx/ipx_internal.h\"\n#include \"ipm/ipx/multistream.h\"\n#include \"ipm/ipx/timer.h\"\n\nnamespace ipx {\n\n// Class Control handles\n// (1) accessing user parameters,\n// (2) solver output,\n// (3) solver interruption.\n// Currently the solver is interrupted only by time limit. The interrupt\n// mechanism could also be used if we run IPX and a simplex code concurrently\n// and want to interrupt IPX when the simplex finished. For that reason a\n// Control object cannot be copied; assuming that one thread sets an interrupt\n// signal (not implemented yet), a call to control.InterruptCheck() from any\n// part of the solver must return nonzero. Hence we must only have references or\n// pointers to a single Control object in the whole of IPX.\n\nclass Control {\npublic:\n    Control();\n\n    // disallow copy and copy construction\n    Control& operator=(const Control&) = delete;\n    Control(const Control&) = delete;\n\n    // disallow move and move construction\n    Control& operator=(Control&&) = delete;\n    Control(const Control&&) = delete;\n\n    // Returns IPX_ERROR_* if interrupt is requested, 0 otherwise.\n    Int InterruptCheck(const Int ipm_iteration_count = -1) const;\n\n    // Returns output streams for log and debugging messages. The streams\n    // evaluate to false if they discard output, so that we can write\n    //\n    //   if (control.Debug(3))\n    //     control.Debug(3) << expensive_computation(...) << '\\n';\n    //\n    // If the debug level is < 3, expensive_computation() is not performed.\n    void hLog(std::stringstream& logging) const;\n    void hLog(std::string str) const;\n    void hDebug(std::stringstream& logging, Int level=1) const;\n    std::ostream& Debug(Int level=1) const;\n\n    // Sends logging to HiGHS logging or the log stream according to\n    // parameters.highs_logging, if >= parameters.print_interval\n    // seconds have been elapsed since the last call to IntervalLog()\n    // or to ResetPrintInterval().\n    void hIntervalLog(std::stringstream& logging) const;\n    void ResetPrintInterval() const;\n\n    double Elapsed() const;     // total runtime\n\n    ipxint dualize() const { return parameters_.dualize; }\n    ipxint scale() const { return parameters_.scale; }\n    ipxint ipm_maxiter() const { return parameters_.ipm_maxiter; }\n    double ipm_feasibility_tol() const {\n        return parameters_.ipm_feasibility_tol; }\n    double ipm_optimality_tol() const { return parameters_.ipm_optimality_tol; }\n    double ipm_drop_primal() const { return parameters_.ipm_drop_primal; }\n    double ipm_drop_dual() const { return parameters_.ipm_drop_dual; }\n    double kkt_tol() const { return parameters_.kkt_tol; }\n    ipxint crash_basis() const { return parameters_.crash_basis; }\n    double dependency_tol() const { return parameters_.dependency_tol; }\n    double volume_tol() const { return parameters_.volume_tol; }\n    ipxint rows_per_slice() const { return parameters_.rows_per_slice; }\n    ipxint maxskip_updates() const { return parameters_.maxskip_updates; }\n    ipxint lu_kernel() const { return parameters_.lu_kernel; }\n    double lu_pivottol() const { return parameters_.lu_pivottol; }\n    ipxint run_crossover() const { return parameters_.run_crossover; }\n    double start_crossover_tol() const { return parameters_.start_crossover_tol; }\n    double pfeasibility_tol() const { return parameters_.pfeasibility_tol; }\n    double dfeasibility_tol() const { return parameters_.dfeasibility_tol; }\n    ipxint switchiter() const { return parameters_.switchiter; }\n    ipxint stop_at_switch() const { return parameters_.stop_at_switch; }\n    ipxint update_heuristic() const { return parameters_.update_heuristic; }\n    ipxint maxpasses() const { return parameters_.maxpasses; }\n    bool reportBasisData() const { return parameters_.analyse_basis_data; }\n    ipxint runCentring() const{return parameters_.run_centring; }\n    ipxint maxCentringSteps() const{return parameters_.max_centring_steps; }\n    double centringRatioTolerance() const{return parameters_.centring_ratio_tolerance; }\n    double centringRatioReduction() const {return parameters_.centring_ratio_reduction; }\n    double centringAlphaScaling() const{return parameters_.centring_alpha_scaling; }\n    ipxint badProductsTolerance() const{return parameters_.bad_products_tolerance; }\n    bool timelessLog() const{return parameters_.timeless_log; }\n\n    const Parameters& parameters() const;\n    void parameters(const Parameters& new_parameters);\n    void callback(HighsCallback* callback);\n\n    // Opens the log file defined in parameters.logfile, if any.\n    // Ignores if an error occurs; in this case no file log is written.\n    void OpenLogfile();\n\n    // Closes an opened log file, if any.\n    void CloseLogfile();\n\n    // Resets the total runtime counter.\n    void ResetTimer();\n\nprivate:\n    void MakeStream();           // composes output_\n    Parameters parameters_;\n    HighsCallback* callback_ = nullptr;\n    std::ofstream logfile_;\n    Timer timer_;                // total runtime\n    mutable Timer interval_;     // time since last interval log\n    mutable Multistream output_; // forwards to logfile and/or console\n    mutable Multistream dummy_;  // discards everything\n};\n\n// Formats integer, string literal or floating point value into a string of\n// size at least @width. So we can put formatted output into a stream without\n// altering the stream's state.\nstd::string Format(Int i, int width);\nstd::string Format(const char* c, int width);\nstd::string Format(double d, int width, int prec,\n                   std::ios_base::fmtflags floatfield);\n\n// shortcuts\ninline std::string Scientific(double d, int width, int prec) {\n    return Format(d, width, prec, std::ios_base::scientific);\n}\ninline std::string Fixed(double d, int width, int prec) {\n    return Format(d, width, prec, std::ios_base::fixed);\n}\ninline std::string sci2(double d) { return Scientific(d,0,2); }\ninline std::string sci8(double d) { return Scientific(d,0,8); }\ninline std::string fix2(double d) { return Fixed(d,0,2); }\ninline std::string fix8(double d) { return Fixed(d,0,8); }\n\n// Formats @text into a line of fixed width and indentation.\n// This is used to print messages like\n//\n//     Number of variables:                                1464\n//     Number of constraints:                              696\n//\n// consistently via control.hLog(h_logging_stream) using \n//\n//   h_logging_stream << Textline(\"Number of variables:\") << 1464 << '\\n'\n//                    << Textline(\"Number of constraints:\") << 696 << '\\n';\n//\ntemplate <typename T>\nstd::string Textline(const T& text) {\n    std::ostringstream s;\n    s << \"    \";\n    s.setf(std::ios_base::left);\n    s.width(52);\n    s << text;\n    return s.str();\n}\n\n}  // namespace ipx\n\n#endif  // IPX_CONTROL_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/crossover.h",
    "content": "#ifndef IPX_CROSSOVER_H_\n#define IPX_CROSSOVER_H_\n\n// Crossover method\n//\n// Given a basis and (x,y,z) that satisfies\n//\n//   lb[j] <= x[j] <= ub[j],                    (1)\n//    z[j] <= 0    if x[j] > lb[j],             (2a)\n//    z[j] >= 0    if x[j] < ub[j]              (2b)\n//\n// for all j, the crossover method updates the basis and (x,y,z) such that\n// z[j]=0 for all basic variables and x[j]=lb[j] or x[j]=ub[j] for all nonbasic\n// variables (or x[j]=0 if the variable is free). Hereby (1) and (2) are\n// maintained. The textbook method also keeps Ax and A'y+z unchanged.\n//\n// Nonbasic variables for which lb[j]<x[j]<ub[j] are called \"primal superbasic\"\n// and basic variables for which z[j]!=0 are called \"dual superbasic\". The\n// crossover algorithm removes superbasic variables in two push phases.\n//\n// Each iteration of the primal push phase chooses a primal superbasic variable\n// jn, moves x[jn] toward a bound (we choose the nearer one if jn has two finite\n// bounds and zero if it has none) and updates x[basic] to keep Ax unchanged. If\n// jn reaches its bound, then the push is complete. Otherwise a basic variable\n// jb reached its bound and blocked the step. In this case a basis update\n// exchanges jb by jn.\n//\n// Each iteration of the dual push phase chooses a dual superbasic variable jb,\n// moves z[jb] toward zero and updates z[nonbasic] to keep A'y+z unchanged. If\n// jb reaches zero, then the push is complete. Otherwise a nonbasic variable jn\n// became zero and blocked the step. In this case a basis update exchanges jb by\n// jn.\n\n#include <vector>\n#include \"ipm/ipx/basis.h\"\n#include \"ipm/ipx/control.h\"\n#include \"ipm/ipx/indexed_vector.h\"\n\nnamespace ipx {\n\nclass Crossover {\npublic:\n    // Constructor stores a reference to the Control object, which must be valid\n    // as long as the Crossover object is used.\n    Crossover(const Control& control);\n\n    // First runs the dual push phase; if this was successful, then runs the\n    // primal push phase.\n    //\n    // weights: Must either be NULL or an array of size n+m.\n    //          If given, then primal pushes are executed in decreasing order of\n    //          weights and dual pushes in increasing order.\n    //          If NULL, then both phases push variables in increasing order of\n    //          index.\n    //\n    // On return info->status_crossover and info->errflag have been set by\n    // PushPrimal() or PushDual().\n    //\n    void PushAll(Basis* basis, Vector& x, Vector& y, Vector& z,\n                 const double* weights, Info* info);\n\n    // Pushes a set of primal variables to one of their bounds.\n    //\n    // basis:           the basis to be updated; also provides the LP model.\n    // x:               size n+m vector, satisfying (1) on entry and return.\n    //                  x is updated while A*x (ideally) remains unchanged.\n    // variables:       indices of nonbasic variables (without duplicates) to be\n    //                  pushed to a bound.\n    // fixed_at_bound:  NULL or size n+m array. If fixed_at_bound[j] = true,\n    //                  then x[j] must be at a bound on entry and remains at\n    //                  this bound. If NULL, then no variable is fixed.\n    // info:            on return info->status_crossover is one of\n    //                  * IPX_STATUS_optimal      if terminated successfully,\n    //                  * IPX_STATUS_time_limit   if interrupted,\n    //                  * IPX_STATUS_failed       if failed.\n    //                  In the latter case info->errflag is set.\n    //\n    // If a variable to be pushed has two finite bounds, then the nearer one is\n    // chosen. If it has no finite bound, then it is pushed to zero.\n    //\n    void PushPrimal(Basis* basis, Vector& x, const std::vector<Int>& variables,\n                    const bool* fixed_at_bound, Info* info);\n\n    // As above, but with fixed_at_bound defined through z.\n    // Variable j is fixed at its bound if z[j]!=0.\n    void PushPrimal(Basis* basis, Vector& x, const std::vector<Int>& variables,\n                    const Vector& z, Info* info);\n\n    // Pushes a set of dual variables to zero.\n    //\n    // basis:           the basis to be updated; also provides the LP model.\n    // y, z:            size m and n+m vectors that are updated while A'y+z\n    //                  (ideally) remains unchanged.\n    // variables:       indices of basic variables (without duplicates) to be\n    //                  pushed to zero.\n    // sign_restrict:   size n+m array. z[j] is restricted to be\n    //                  * non-negative iff (sign_restrict[j] & 1) != 0,\n    //                  * non-positive iff (sign_restrict[j] & 2) != 0.\n    //                  The sign restriction must be satisfied on entry and is\n    //                  satisfied on return.\n    // info:            on return info->status_crossover is one of\n    //                  * IPX_STATUS_optimal      if terminated successfully,\n    //                  * IPX_STATUS_time_limit   if interrupted,\n    //                  * IPX_STATUS_failed       if failed.\n    //                  In the latter case info->errflag is set.\n    //\n    void PushDual(Basis* basis, Vector& y, Vector& z,\n                  const std::vector<Int>& variables,\n                  const int sign_restrict[], Info* info);\n\n    // As above, but with the sign restriction on z defined through x.\n    // z[j] is restricted to be\n    // * non-negative iff x[j] < ub[j],\n    // * non-positive iff x[j] > lb[j].\n    void PushDual(Basis* basis, Vector& y, Vector& z,\n                  const std::vector<Int>& variables,\n                  const Vector& x, Info* info);\n\n    // Number of pushes in last call to PushPrimal() and PushDual().\n    Int primal_pushes() const { return primal_pushes_; }\n    Int dual_pushes() const { return dual_pushes_; }\n\n    // Number of basis updates in last call to PushPrimal() and PushDual().\n    Int primal_pivots() const { return primal_pivots_; }\n    Int dual_pivots() const { return dual_pivots_; }\n\n    // Runtime of last call to PushPrimal() and PushDual().\n    double time_primal() const { return time_primal_; }\n    double time_dual() const { return time_dual_; }\n\nprivate:\n    // An entry of the tableau row/column is eligible as pivot only if it is\n    // larger than kPivotZeroTol in absolute value.\n    static constexpr double kPivotZeroTol = 1e-5;\n\n    // Two-pass ratio tests that allow infeasibilities up to feastol in order\n    // to choose a larger pivot.\n    Int PrimalRatioTest(const Vector& xbasic, const IndexedVector& ftran,\n                        const Vector& lbbasic, const Vector& ubbasic,\n                        double step, double feastol, bool* block_at_lb);\n    Int DualRatioTest(const Vector& z, const IndexedVector& row,\n                      const int sign_restrict[], double step,\n                      double feastol);\n\n    const Control& control_;\n\n    Int primal_pushes_{0};\n    Int dual_pushes_{0};\n    Int primal_pivots_{0};\n    Int dual_pivots_{0};\n    double time_primal_{0.0};\n    double time_dual_{0.0};\n};\n\n}  // namespace ipx\n\n#endif  // IPX_CROSSOVER_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/diagonal_precond.h",
    "content": "// Copyright (c) 2018-2019 ERGO-Code. See license.txt for license.\n\n#ifndef IPX_DIAGONAL_PRECOND_H_\n#define IPX_DIAGONAL_PRECOND_H_\n\n#include \"ipm/ipx/linear_operator.h\"\n#include \"ipm/ipx/model.h\"\n#include \"ipm/ipx/sparse_matrix.h\"\n\nnamespace ipx {\n\n// DiagonalPrecond provides inverse operations with the diagonal matrix\n//\n//   diag(AI*W*AI').                                (1)\n//\n// Here AI is the m-by-(n+m) matrix defined by the model, and W is a diagonal\n// (weight) matrix that is provided by the user.\n\nclass DiagonalPrecond : public LinearOperator {\npublic:\n    // Constructor stores a reference to the model. No data is copied. The model\n    // must be valid as long as the preconditioner is used.\n    explicit DiagonalPrecond(const Model& model);\n\n    // Factorizes the preconditioner. W must either hold n+m entries, or be\n    // NULL, in which case the first n entries are assumed 1.0 and the last\n    // m entries are assumed 0.0.\n    void Factorize(const double* W, Info* info);\n\n    // Returns computation time for calls to Apply() since last reset_time().\n    double time() const;\n    void reset_time();\n\nprivate:\n    void _Apply(const Vector& rhs, Vector& lhs, double* rhs_dot_lhs) override;\n\n    const Model& model_;\n    bool factorized_{false};    // preconditioner factorized?\n    Vector diagonal_;           // diagonal of normal matrix\n    double time_{0.0};\n};\n\n}  // namespace ipx\n\n#endif  // IPX_DIAGONAL_PRECOND_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/forrest_tomlin.h",
    "content": "#ifndef IPX_FORREST_TOMLIN_H_\n#define IPX_FORREST_TOMLIN_H_\n\n#include <memory>\n#include <vector>\n#include \"ipm/ipx/control.h\"\n#include \"ipm/ipx/lu_factorization.h\"\n#include \"ipm/ipx/lu_update.h\"\n\nnamespace ipx {\n\n// Generic implementation of the Forrest-Tomlin update [1] that can be used with\n// any LU factorization. The implementation does not exploit hypersparsity,\n// which excludes its use for such problems. For non-hypersparse problems the\n// implementation is better suited than BASICLU, however, because it stores L\n// and U in compressed form with permuted indices; hence solving triangular\n// systems with a dense rhs/lhs accesses memory contiguously. BASICLU could not\n// be implemented in that form due to re-permuting U to triangular form in the\n// updates. Hypersparsity support could be added to the present implementation\n// when required.\n//\n// [1] J.J.H. Forrest and J.A. Tomlin, \"Updated triangular factors of the basis\n//     to maintain sparsity in the product form simplex method\", Math.\n//     Programming 2 (1972)\n\nclass ForrestTomlin : public LuUpdate {\npublic:\n    // Constructor takes ownership of the LuFactorization object by a move from\n    // @lu.\n    ForrestTomlin(const Control& control, Int dim,\n                  std::unique_ptr<LuFactorization>& lu);\n    ~ForrestTomlin() = default;\n\nprivate:\n    Int _Factorize(const Int* Bbegin, const Int* Bend, const Int* Bi,\n                   const double* Bx, bool strict_abs_pivottol) override;\n    void _GetFactors(SparseMatrix* L, SparseMatrix* U, Int* rowperm,\n                     Int* colperm, std::vector<Int>* dependent_cols) override;\n    void _SolveDense(const Vector& rhs, Vector& lhs, char trans) override;\n    void _FtranForUpdate(Int nz, const Int* bi, const double* bx) override;\n    void _FtranForUpdate(Int nz, const Int* bi, const double* bx,\n                         IndexedVector& lhs) override;\n    void _BtranForUpdate(Int j) override;\n    void _BtranForUpdate(Int j, IndexedVector& lhs) override;\n    Int _Update(double pivot) override;\n    bool _NeedFreshFactorization() override;\n    double _fill_factor() const override;\n    double _pivottol() const override;\n    void _pivottol(double new_pivottol) override;\n\n    // Maximum # updates before refactorization is required.\n    static constexpr Int kMaxUpdates = 5000;\n\n    // Solves a linear system with the basis matrix. On entry @x holds the\n    // permuted right-hand side, on return it holds the permuted solution.\n    // @x must have dimension at least dim_ + # computed updates; the additional\n    // components are used as workspace.\n    // @trans: 't' or 'T' for transposed system.\n    void SolvePermuted(Vector& x, char trans);\n\n    // Computes the spike column for the FT update from\n    //   R_k^{-1} * ... * R_1^{-1} * L^{-1} * b\n    // and stores it in compressed form at the end of U. The spike is also\n    // returned as a full vector in work_.\n    // @nb, @bi, @bx: b in compressed form.\n    void ComputeSpike(Int nb, const Int* bi, const double* bx);\n\n    // Computes the partial BTRAN solution r = ep' * U^{-1}, where ep is the\n    // p-th unit vector and p the position of column @j in the pivot sequence.\n    // The row eta vector -r/r[p] without the unit diagonal entry is stored in\n    // compressed form at end of R. r is returned as a full vector in work_.\n    void ComputeEta(Int j);\n\n    const Control& control_;\n    const Int dim_;\n    std::unique_ptr<LuFactorization> lu_;\n\n    std::vector<Int> rowperm_;     // row permutation from factorization\n    std::vector<Int> colperm_;     // col permutation from factorization\n    std::vector<Int> rowperm_inv_; // inverse permutation of rowperm_\n    std::vector<Int> colperm_inv_; // inverse permutation of colperm_\n    std::vector<Int> dependent_cols_;\n                             // passed trough from _Factorize() to _GetFactors()\n\n    SparseMatrix L_;            // L from factorization\n    SparseMatrix U_;            // U from factorization with spike cols appended\n    SparseMatrix R_;            // cols of R build row eta matrices from updates\n\n    // replaced_[k] == p if update k replaced position p in pivot sequence.\n    // replaced_.size() is the # updates performed.\n    std::vector<Int> replaced_;\n    Int replace_next_;          // position to be replaced in next update\n    bool have_btran_{false};    // true if row eta has been computed\n    bool have_ftran_{false};    // true if spike has been computed\n    double fill_factor_{0.0};   // fill factor from last factorization\n    double pivottol_{0.1};      // LU pivot tolerance for next factorization\n    Vector work_;               // size dim_ + kMaxUpdates workspace\n};\n\n}  // namespace ipx\n\n#endif  // IPX_FORREST_TOMLIN_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/guess_basis.h",
    "content": "#ifndef IPX_GUESS_BASIS_H_\n#define IPX_GUESS_BASIS_H_\n\n#include \"ipm/ipx/control.h\"\n#include \"ipm/ipx/model.h\"\n\nnamespace ipx {\n\n// Returns a vector of m column indices (m = model.rows()) as a guess for a\n// basis. Columns with a larger weight are chosen preferably. The basis can be\n// singular (and usually is).\n//\n// @colweights size n+m array (n = model.cols()) with entries in the closed\n//             interval [0,INFINITY].\n//\nstd::vector<Int> GuessBasis(const Control& control, const Model& model,\n                            const double* colweights);\n\n}  // namespace ipx\n\n#endif // IPX_GUESS_BASIS_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/indexed_vector.h",
    "content": "#ifndef IPX_INDEXED_VECTOR_H_\n#define IPX_INDEXED_VECTOR_H_\n\n#include <vector>\n#include \"ipm/ipx/ipx_internal.h\"\n\nnamespace ipx {\n\n// IndexedVector stores a vector and optionally the indices of its nonzero\n// entries (its pattern). To iterate over the entries in an IndexedVector v:\n//\n//   double vmax = 0.0;\n//   Int imax = 0;\n//   auto update_max = [&vmax,&imax](Int i, double x) {\n//       if (x > vmax) {\n//           vmax = x;\n//           imax = i;\n//       }\n//   };\n//   for_each_nonzero(v, update_max);\n//\n// The loop iterates with indirect addressing over the nonzero entries if the\n// pattern is known and sparse, and with direct addressing over the whole vector\n// otherwise.\n//\n// When modifying the vector changes its pattern (e.g. by writing to v[i] for an\n// arbitrary index i), you have to invalidate the pattern or provide the new one.\n\nclass IndexedVector {\npublic:\n    // Constructs a vector of dimension @dim. Entries are initialized to zero\n    // and pattern becomes empty.\n    explicit IndexedVector(Int dim = 0);\n\n    Int dim() const { return elements_.size(); }\n\n    // Accesses entry 0 <= @i < dim() by value or reference.\n    double operator[](Int i) const { return elements_[i]; }\n    double& operator[](Int i) { return elements_[i]; }\n\n    // Returns true if pattern is known and sparse.\n    bool sparse() const;\n\n    // Returns # nonzeros, or a negative value if the pattern is unknown.\n    Int nnz() const { return nnz_; }\n\n    // Invalidates the pattern.\n    void InvalidatePattern() { nnz_ = -1; }\n\n    // Changes the # indices in the pattern to new_nnz <= dim(). A negative\n    // value invalidates the pattern.\n    void set_nnz(Int new_nnz) { nnz_ = new_nnz; }\n\n    // Returns the underlying array that stores the vector.\n    const double* elements() const { return &elements_[0]; }\n    double* elements() { return &elements_[0]; }\n\n    // Returns the underlying array that stores the pattern.\n    const Int* pattern() const { return pattern_.data(); }\n    Int* pattern() { return pattern_.data(); }\n\n    // Sets all entries to zero and the pattern to empty.\n    void set_to_zero();\n\nprivate:\n    Vector elements_;\n    std::vector<Int> pattern_;\n    // If nnz_ >= 0, then pattern_[0..nnz_-1] are the indices of (possible)\n    // nonzeros in elements_. If nnz_ < 0, then the pattern is unknown.\n    Int nnz_{0};\n};\n\ntemplate <typename C>\nvoid for_each_nonzero(IndexedVector& v, C& c) {\n    if (v.sparse()) {\n        const Int* pattern = v.pattern();\n        Int nnz = v.nnz();\n        for (Int p = 0; p < nnz; p++) {\n            const Int i = pattern[p];\n            c(i, v[i]);\n        }\n    } else {\n        Int dim = v.dim();\n        for (Int i = 0; i < dim; i++) {\n            const Int ii = i;   // make sure that caller does not change i\n            c(ii, v[i]);\n        }\n    }\n}\n\ntemplate <typename C>\nvoid for_each_nonzero(const IndexedVector& v, C& c) {\n    if (v.sparse()) {\n        const Int* pattern = v.pattern();\n        Int nnz = v.nnz();\n        for (Int p = 0; p < nnz; p++) {\n            const Int i = pattern[p];\n            c(i, v[i]);\n        }\n    } else {\n        Int dim = v.dim();\n        for (Int i = 0; i < dim; i++) {\n            const Int ii = i;   // make sure that caller does not change i\n            c(ii, v[i]);\n        }\n    }\n}\n\ndouble Dot(const IndexedVector& x, const Vector& y);\n\n}  // namespace ipx\n\n#endif  // IPX_INDEXED_VECTOR_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/info.h",
    "content": "#ifndef IPX_INFO_CPP_H_\n#define IPX_INFO_CPP_H_\n\n#include <ostream>\n#include <string>\n#include \"ipm/ipx/ipx_internal.h\"\n\nnamespace ipx {\n\n// Formatted output of Info. For each member one line is printed in the form\n//  info.status                                         1000\n//  info.status_ipm                                     1\n//  info.status_crossover                               1\n//  info.errflag                                        0\n//  info.num_var                                        89346\n//  info.num_constr                                     39855\n//  ...\n// The result can be parsed using the Julia function ParseInfo(), which recovers\n// an object of a Julia type analogue to struct ipx_info.\nstd::ostream& operator<<(std::ostream&, const Info&);\n\n// Returns a text representation of each status code.\nstd::string StatusString(Int status);\n\n}  // namespace ipx\n\n#endif  // IPX_INFO_CPP_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/ipm.h",
    "content": "#ifndef IPX_IPM_H_\n#define IPX_IPM_H_\n\n#include \"ipm/ipx/control.h\"\n#include \"ipm/ipx/kkt_solver.h\"\n#include \"ipm/ipx/iterate.h\"\n\nnamespace ipx {\n\n// IPM implements an interior point method based on KKTSolver and Iterate.\n// The algorithm is a variant of Mehrotra's [1] predictor-corrector method\n// that requires two linear system solves per iteration.\n//\n// [1] S. Mehrotra, \"On the implementation of a primal-dual interior point\n//     method\", SIAM J. Optim., 2 (1992).\n\nclass IPM {\npublic:\n    explicit IPM(const Control& control);\n\n    // Initializes @iterate with a starting point for Driver(). The KKT solver\n    // must allow Factorize(NULL, info) (see kkt_solver.h).\n    // On return info->status_ipm is\n    // IPX_STATUS_not_run    if successful,\n    // IPX_STATUS_time_limit if the KKT solver was interrupted by time limit,\n    // IPX_STATUS_failed     if the KKT solver failed with info->errflag.\n    // If the method did not terminate successfully, @iterate is unchanged.\n    void StartingPoint(KKTSolver* kkt, Iterate* iterate, Info* info);\n\n    // Updates @iterate by interior point iterations. On return ipm_status is\n    // IPX_STATUS_optimal       if iterate->term_crit_reached() is true,\n    // IPX_STATUS_iter_limit    if info->iter >= maxiter(),\n    // IPX_STATUS_no_progress   if no progress over a number of iterations,\n    // IPX_STATUS_time_limit    if interrupted by time limit,\n    // IPX_STATUS_failed        if the KKT solver failed with info->errflag.\n    void Driver(KKTSolver* kkt, Iterate* iterate, Info* info);\n\n    Int maxiter() const { return maxiter_; }\n    void maxiter(Int i) { maxiter_ = i; }\n\nprivate:\n    struct Step;\n    // IPM terminates when the complementarity gap of the current iterate\n    // exceeds kDivergeTol times the smallest complementarity gap of all\n    // iterates so far.\n    static constexpr double kDivergeTol = 1e6;\n\n    void ComputeStartingPoint();\n    void Predictor(Step& step);\n    void AddCorrector(Step& step);\n    void Centring(Step& step, double mu_to_use);\n    void AssessCentrality(const Vector& xl, const Vector& xu, const Vector& zl, \n                          const Vector& zu,double mu, bool print = true);\n    bool EvaluateCentringStep(const Step& step, double prev_ratio, Int prev_bad);\n    void StepSizes(const Step& step, bool isCentring = false);\n    void MakeStep(const Step& step, bool isCentring = false);\n    // Reduces the following linear system to KKT form:\n    //  [ AI                 ] [dx ]    [rb]\n    //  [ I  -I              ] [dxl] =  [rl]\n    //  [ I      I           ] [dxu]    [ru]\n    //  [          AI'  I -I ] [dy ]    [rc]\n    //  [    Zl        Xl    ] [dzl]    [sl]\n    //  [       Zu        Xu ] [dzu]    [su]\n    // Each of @rb, @rc, @rl and @ru can be NULL, in which case its entries are\n    // assumed to be 0.0. This is currently not used, but was implemented for\n    // computing centrality correctors.\n    void SolveNewtonSystem(const double* rb, const double* rc,\n                           const double* rl, const double* ru,\n                           const double* sl, const double* su, Step& lhs);\n    void PrintHeader();\n    void PrintOutput();\n\n    const Control& control_;\n    KKTSolver* kkt_{nullptr};\n    Iterate* iterate_{nullptr};\n    Info* info_{nullptr};\n\n    double step_primal_{0.0}, step_dual_{0.0};\n    // Counts the # bad iterations since the last good iteration. An iteration\n    // is bad if the primal or dual step size is < 0.05.\n    Int num_bad_iter_{0};\n    // Smallest complementarity gap of all iterates so far.\n    double best_complementarity_{0.0};\n\n    Int maxiter_{-1};\n\n    // indicators of centrality for centring steps\n    double centring_ratio{0.0};\n    Int bad_products{0};\n};\n\n}  // namespace ipx\n\n#endif  // IPX_IPM_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/ipx_c.h",
    "content": "#ifndef IPX_C_H_\n#define IPX_C_H_\n\n#include \"ipm/ipx/ipx_config.h\"\n#include \"ipm/ipx/ipx_info.h\"\n#include \"ipm/ipx/ipx_parameters.h\"\n#include \"ipm/ipx/ipx_status.h\"\n\n#ifdef __cplusplus\nextern \"C\"{\n#endif\n    /* These functions call their equivalent method of LpSolver for\n       the object pointed to by @self. See highs/lp_solver.h for\n       documentation of the methods. */\n    ipxint ipx_load_model(void* self, ipxint num_var, const double* obj,\n                          const double* lb, const double* ub, ipxint num_constr,\n                          const ipxint* Ap, const ipxint* Ai, const double* Ax,\n                          const double* rhs, const char* constr_type);\n    ipxint ipx_load_ipm_starting_point(void* self, const double* x,\n                                       const double* xl, const double* xu,\n                                       const double* slack, const double* y,\n                                       const double* zl, const double* zu);\n    ipxint ipx_solve(void* self);\n    struct ipx_info ipx_get_info(void* self);\n    ipxint ipx_get_interior_solution(void* self, double* x, double* xl,\n                                     double* xu, double* slack, double* y,\n                                     double* zl, double* zu);\n    ipxint ipx_get_basic_solution(void* self, double* x, double* slack,\n                                  double* y, double* z,\n                                  ipxint* cbasis, ipxint* vbasis);\n    struct ipx_parameters ipx_get_parameters(void* self);\n    void ipx_set_parameters(void* self, struct ipx_parameters);\n    void ipx_clear_model(void* self);\n\n    /* for debugging */\n    ipxint ipx_get_iterate(void* self, double* x, double* y, double* zl,\n                           double* zu, double* xl, double* xu);\n    ipxint ipx_get_basis(void* self, ipxint* cbasis, ipxint* vbasis);\n    ipxint ipx_get_kktmatrix(void* self, ipxint* AIp, ipxint* AIi, double* AIx,\n                             double* g);\n    ipxint ipx_symbolic_invert(void* self, ipxint* rowcounts,\n                               ipxint* colcounts);\n#ifdef __cplusplus\n}\n#endif\n\n#endif  /* IPX_C_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/ipx_config.h",
    "content": "#ifndef IPX_CONFIG_H_\n#define IPX_CONFIG_H_\n\n#include <stdint.h>\n\n#include \"util/HighsInt.h\"\ntypedef HighsInt ipxint;\n\n#endif /* IPX_CONFIG_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/ipx_info.h",
    "content": "#ifndef IPX_INFO_H_\n#define IPX_INFO_H_\n\n#include \"ipm/ipx/ipx_config.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\nstruct ipx_info {\n    ipxint status;\n    ipxint status_ipm;\n    ipxint status_crossover;\n    ipxint errflag;\n\n    /* dimension of LP model as given by user */\n    ipxint num_var;\n    ipxint num_constr;\n    ipxint num_entries;\n\n    /* dimension of constraint matrix in solver (including slack columns) */\n    ipxint num_rows_solver;\n    ipxint num_cols_solver;\n    ipxint num_entries_solver;\n\n    ipxint dualized;            /* dualized model? */\n    ipxint dense_cols;          /* # columns classified \"dense\" */\n\n    ipxint centring_tried;      /* centring steps tried? */\n    ipxint centring_success;    /* centring steps successful? */\n\n    /* reductions in IPM */\n    ipxint dependent_rows;      /* # dependent rows (to eq constr) removed */\n    ipxint dependent_cols;      /* # dependent cols (to free vars) removed */\n    ipxint rows_inconsistent;   /* dependent rows inconsistent? */\n    ipxint cols_inconsistent;   /* dependent cols inconsistent? */\n    ipxint primal_dropped;      /* # primal variables dropped to bound */\n    ipxint dual_dropped;        /* # dual variables dropped to zero */\n\n    /* interior solution */\n    double abs_presidual;       /* max violation A*x+s=rhs, x-xl=lb, x+xu=ub */\n    double abs_dresidual;       /* max violation A'y+zl-zu=obj */\n    double rel_presidual;       /* relative primal residual */\n    double rel_dresidual;       /* relative dual residual */\n    double pobjval;             /* primal objective */\n    double dobjval;             /* dual objective */\n    double rel_objgap;          /* relative gap between primal and dual obj */\n    double complementarity;     /* zl'xl + zu'xu + y'slack */\n    double normx;               /* infnorm(x) */\n    double normy;               /* infnorm(y) */\n    double normz;               /* infnorm(zl,zu) */\n\n    /* basic solution */\n    double objval;              /* (primal) objective */\n    double primal_infeas;       /* max violation of lb <= x <= ub */\n    double dual_infeas;         /* max violation of sign condition on (y,z) */\n\n    /* operation counts */\n    ipxint iter;                /* # interior point iterations */\n    ipxint kktiter1;            /* # linear solver iterations before switch */\n    ipxint kktiter2;            /* # linear solver iterations after switch */\n    ipxint basis_repairs;       /* # basis repairs after crash, < 0 discarded */\n    ipxint updates_start;       /* # basis updates for starting basis */\n    ipxint updates_ipm;         /* # basis updates in IPM */\n    ipxint updates_crossover;   /* # basis updates in crossover */\n\n    /* major computation times */\n    double time_total;          /* total runtime (wallclock) */\n    double time_ipm1;           /* IPM before switch */\n    double time_ipm2;           /* IPM after switch (without starting basis) */\n    double time_starting_basis; /* constructing starting basis */\n    double time_crossover;      /* crossover */\n\n    /* profiling linear solver */\n    double time_kkt_factorize;  /* factorize/build precond for KKT matrix */\n    double time_kkt_solve;      /* linear system solves with KKT matrix */\n    double time_maxvol;         /* algorithm \"maxvolume\" */\n    double time_cr1;            /* CR method with diag precond */\n    double time_cr1_AAt;        /* ... matrix-vector products with AA' */\n    double time_cr1_pre;        /* ... preconditioner (diag+dense col) */\n    double time_cr2;            /* CR method with basis precond */\n    double time_cr2_NNt;        /* ... matrix-vector products with NN' */\n    double time_cr2_B;          /* ... solves with B */\n    double time_cr2_Bt;         /* ... solves with B' */\n\n    /* profiling basis factorization */\n    double ftran_sparse;        /* fraction of FTRAN solutions sparse */\n    double btran_sparse;        /* fraction of BTRAN solutions sparse */\n    double time_ftran;          /* all FTRAN operations */\n    double time_btran;          /* all BTRAN operations */\n    double time_lu_invert;      /* LU factorizations */\n    double time_lu_update;      /* LU updates */\n    double mean_fill;           /* geom. mean of LU fill factors */\n    double max_fill;            /* max LU fill factor */\n    double time_symb_invert;    /* computing row/column counts of inverse(B) */\n\n    /* analysis of algorithm maxvolume */\n    ipxint maxvol_updates;      /* # basis updates */\n    ipxint maxvol_skipped;      /* # columns computed but basis not updated */\n    ipxint maxvol_passes;       /* # passes over tableau matrix */\n    ipxint tbl_nnz;             /* nnz in tbl matrix computed */\n    double tbl_max;             /* max entry in tbl matrix computed */\n    double frobnorm_squared;    /* Frobnorm^2 of tbl matrix computed */\n    double lambdamax;           /* max eigenval of transformed normal matrix */\n    double volume_increase;     /* base-2 log of volume(new)/volume(old) */\n};\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif  /* IPX_INFO_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/ipx_internal.h",
    "content": "#ifndef IPX_INTERNAL_H_\n#define IPX_INTERNAL_H_\n\n#include <cstring>\n#include <valarray>\n\n#include \"ipm/ipx/ipx_config.h\"\n#include \"ipm/ipx/ipx_info.h\"\n#include \"ipm/ipx/ipx_parameters.h\"\n#include \"ipm/ipx/ipx_status.h\"\n\nnamespace ipx {\n\nusing Int = ipxint;\n\nstruct Info : public ipx_info {\n  Info() { std::memset(this, 0, sizeof(Info)); }\n};\n\nstruct Parameters : public ipx_parameters {\n  Parameters() {\n    display = 1;\n    logfile = nullptr;\n    print_interval = 5.0;\n    analyse_basis_data = false;\n    time_limit = -1.0;\n    dualize = -1;\n    scale = 1;\n    ipm_maxiter = 300;\n    ipm_feasibility_tol = 1e-6;\n    ipm_optimality_tol = 1e-8;\n    ipm_drop_primal = 1e-9;\n    ipm_drop_dual = 1e-9;\n    kkt_tol = 0.3;\n    crash_basis = 1;\n    dependency_tol = 1e-6;\n    volume_tol = 2.0;\n    rows_per_slice = 10000;\n    maxskip_updates = 10;\n    lu_kernel = 0;\n    lu_pivottol = 0.0625;\n    run_crossover = 1;\n    start_crossover_tol = 1e-8;\n    pfeasibility_tol = 1e-7;\n    dfeasibility_tol = 1e-7;\n    debug = 0;\n    switchiter = -1;\n    stop_at_switch = 0;\n    update_heuristic = 1;\n    maxpasses = -1;\n    run_centring = 0;\n    max_centring_steps = 5;\n    centring_ratio_tolerance = 100.0;\n    centring_ratio_reduction = 1.5;\n    centring_alpha_scaling = 0.5;\n    bad_products_tolerance = 3;\n    highs_logging = false;\n    timeless_log = false;\n    log_options = nullptr;\n  }\n\n  Parameters(const ipx_parameters& p) : ipx_parameters(p) {}\n};\n\nusing Vector = std::valarray<double>;\n\n// A vector is treated sparse if it has no more than kHypersparseThreshold * dim\n// nonzeros.\nstatic constexpr double kHypersparseThreshold = 0.1;\n\n// When LU factorization is used for rank detection, columns of the active\n// submatrix whose maximum entry is <= kLuDependencyTol are removed immediately\n// without choosing a pivot.\nstatic constexpr double kLuDependencyTol = 1e-3;\n\n// A fresh LU factorization is considered unstable if\n//   ||b-Bx|| / (||b||+||B||*||x||) > kLuStabilityThreshold,\n// where x=B\\b is computed from the LU factors, b has components +/- 1 that are\n// chosen to make x large, and ||.|| is the 1-norm. An unstable factorization\n// triggers tightening of the pivot tolerance and refactorization.\nstatic constexpr double kLuStabilityThreshold = 1e-12;\n\n// A Forrest-Tomlin LU update is declared numerically unstable if the relative\n// error in the new diagonal entry of U is larger than kFtDiagErrorTol.\nstatic constexpr double kFtDiagErrorTol = 1e-8;\n\n}  // namespace ipx\n\n#endif // IPX_INTERNAL_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/ipx_parameters.h",
    "content": "#ifndef IPX_PARAMETERS_H_\n#define IPX_PARAMETERS_H_\n\n#include \"io/HighsIO.h\"\n#include \"ipm/ipx/ipx_config.h\"\n#include <iostream>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\nstruct ipx_parameters {\n    /* Solver control */\n    ipxint display;\n    const char* logfile;\n    double print_interval;\n    double time_limit;\n    bool analyse_basis_data;\n\n    /* Preprocessing */\n    ipxint dualize;\n    ipxint scale;\n\n    /* Interior point method */\n    ipxint ipm_maxiter;\n    double ipm_feasibility_tol;\n    double ipm_optimality_tol;\n    double ipm_drop_primal;\n    double ipm_drop_dual;\n\n    /* Linear solver */\n    double kkt_tol;\n\n    /* Basis construction in IPM */\n    ipxint crash_basis;\n    double dependency_tol;\n    double volume_tol;\n    ipxint rows_per_slice;\n    ipxint maxskip_updates;\n\n    /* LU factorization */\n    ipxint lu_kernel;\n    double lu_pivottol;\n\n    /* Crossover */\n    ipxint run_crossover;\n    double start_crossover_tol;\n    double pfeasibility_tol;\n    double dfeasibility_tol;\n\n    /* Debugging */\n    ipxint debug;\n    ipxint switchiter;\n    ipxint stop_at_switch;\n    ipxint update_heuristic;\n    ipxint maxpasses;\n\n    /* Centring */\n    ipxint run_centring;\n    ipxint max_centring_steps;\n    double centring_ratio_tolerance;\n    double centring_ratio_reduction;\n    double centring_alpha_scaling;\n    ipxint bad_products_tolerance;\n\n    /* HiGHS logging parameters */\n    bool highs_logging;\n    bool timeless_log;\n    const HighsLogOptions* log_options;\n  \n};\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif  /* IPX_PARAMETERS_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/ipx_status.h",
    "content": "#ifndef IPX_STATUS_H_\n#define IPX_STATUS_H_\n\n/* for status */\n#define IPX_STATUS_not_run                  0\n#define IPX_STATUS_solved                   1000\n#define IPX_STATUS_stopped                  1005\n#define IPX_STATUS_no_model                 1006\n#define IPX_STATUS_out_of_memory            1003\n#define IPX_STATUS_internal_error           1004\n\n/* for status_ipm and status_crossover */\n#define IPX_STATUS_optimal                  1\n#define IPX_STATUS_imprecise                2\n#define IPX_STATUS_primal_infeas            3\n#define IPX_STATUS_dual_infeas              4\n#define IPX_STATUS_user_interrupt           5\n#define IPX_STATUS_time_limit               6\n#define IPX_STATUS_iter_limit               7\n#define IPX_STATUS_no_progress              8\n#define IPX_STATUS_failed                   9\n#define IPX_STATUS_debug                    10\n\n/* error flags for invalid input */\n#define IPX_ERROR_argument_null             102\n#define IPX_ERROR_invalid_dimension         103\n#define IPX_ERROR_invalid_matrix            104\n#define IPX_ERROR_invalid_vector            105\n#define IPX_ERROR_invalid_basis             107\n\n/* error flags CR method */\n#define IPX_ERROR_cr_iter_limit             201\n#define IPX_ERROR_cr_matrix_not_posdef      202\n#define IPX_ERROR_cr_precond_not_posdef     203\n#define IPX_ERROR_cr_no_progress            204\n#define IPX_ERROR_cr_inf_or_nan             205\n\n/* error flags basis factorization */\n#define IPX_ERROR_basis_singular            301\n#define IPX_ERROR_basis_almost_singular     302\n#define IPX_ERROR_basis_update_singular     303\n#define IPX_ERROR_basis_repair_overflow     304\n#define IPX_ERROR_basis_repair_search       305\n#define IPX_ERROR_basis_too_ill_conditioned 306\n\n#define IPX_ERROR_lapack_chol               401\n#define IPX_ERROR_not_implemented           901\n#define IPX_ERROR_user_interrupt            998\n#define IPX_ERROR_time_interrupt            999\n\n#define IPX_basic                            0\n#define IPX_nonbasic                        -1\n#define IPX_nonbasic_lb                     -1\n#define IPX_nonbasic_ub                     -2\n#define IPX_superbasic                      -3\n\n#endif  /* IPX_STATUS_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/iterate.h",
    "content": "#ifndef IPX_ITERATE_H_\n#define IPX_ITERATE_H_\n\n#include <vector>\n#include \"ipm/ipx/model.h\"\n\nnamespace ipx {\n\n// Iterate manages the IPM iterate consisting of primal variables x[n+m],\n// xl[n+m], xu[n+m] and dual variables y[m], zl[n+m], zu[n+m], where m, n are\n// the # rows and structural columns of the model.\n//\n// Each x[j] is in one of three \"states\":\n//\n// \"fixed\":     The variable is not moved by the IPM. The IPM works as if b was\n//              reduced by x[j]*AI[:,j] and column j of AI would not be present.\n// \"free\":      The variable is treated by the IPM as if lb[j] and ub[j] would\n//              be infinite, regardless of their actual values.\n// \"barrier\":   The variable has at least one finite bound and a barrier term is\n//              added by the IPM.\n//\n// Notice that the state refers to the way the variable is treated by the IPM,\n// not to its bounds in the model. For example, a variable of fixed state might\n// have zero, one or both finite bounds in the model.\n\nclass Iterate {\npublic:\n    // Constructs an Iterate object associated with a model. @model must be\n    // valid as long as the object is used; no data is copied. The constructor\n    // initializes variables and states to be consistent with finite/infinite\n    // bounds in the model.\n    explicit Iterate(const Model& model);\n\n    // Copies the given values into the Iterate object and sets the state of\n    // each variable to\n    // - free     if the variable has no finite bound in the model,\n    // - barrier  otherwise.\n    // The variables must have values that are consistent with the bounds of the\n    // model; that is:\n    // - If lb[j]==-inf, then   xl[j]==inf and zl[j]==0.0.\n    // - If lb[j]> -inf, then 0<xl[j]< inf and zl[j]> 0.0.\n    // - If ub[j]==+inf, then   xu[j]==inf and zu[j]==0.0.\n    // - If ub[j]< +inf, then 0<xu[j]< inf and zu[j]> 0.0.\n    // Otherwise an assertion will fail.\n    void Initialize(const Vector& x, const Vector& xl, const Vector& xu,\n                    const Vector& y, const Vector& zl, const Vector& zu);\n\n    // Adds sp*[dx;dxl;dxu] to the primal iterate and sd*[dy;dzl;dzu] to the\n    // dual iterate (restrictions see below). Each of the pointer arguments can\n    // be NULL, in which case its entries are assumed to be 0.0.\n    // - x[j] is updated only if StateOf(j) != State::fixed.\n    // - xl[j] and zl[j] are updated only if has_barrier_lb(j). The update to\n    //                   each of xl[j] and zl[j] is truncated such that\n    //                   xl[j] >= kBarrierMin and zl[j] >= kBarrierMin.\n    // - xu[j] and zu[j] are updated only if has_barrier_ub(j). The update to\n    //                   each of xu[j] and zu[j] is truncated such that\n    //                   xu[j] >= kBarrierMin and zu[j] >= kBarrierMin.\n    // If a variable is not updated, then the entry in the step direction is not\n    // accessed.\n    void Update(double sp, const double* dx, const double* dxl,\n                const double* dxu, double sd, const double* dy,\n                const double* dzl, const double* dzu);\n\n    const Model& model() const { return model_; }\n\n    const Vector& x() const  { return x_; }\n    const Vector& xl() const { return xl_; }\n    const Vector& xu() const { return xu_; }\n    const Vector& y() const  { return y_; }\n    const Vector& zl() const { return zl_; }\n    const Vector& zu() const { return zu_; }\n\n    double x(Int j) const  { return x_[j]; }\n    double xl(Int j) const { return xl_[j]; }\n    double xu(Int j) const { return xu_[j]; }\n    double y(Int j) const  { return y_[j]; }\n    double zl(Int j) const { return zl_[j]; }\n    double zu(Int j) const { return zu_[j]; }\n\n    // Returns const references to the residual vectors\n    // rb = b-AI*x,\n    // rl = lb-x+xl,\n    // ru = ub-x-xu,\n    // rc = c-AI'y-zl+zu.\n    // Warning: The residuals are not evaluated immediately after a change to\n    // an Iterate object (such as by Update() or make_fixed()). Instead, the\n    // four residual vectors are evaluated when any of them is required, e.g.\n    // in calls to rb(), presidual(), etc. Hence if a reference to a residual\n    // vector is stored and the Iterate object is changed, you must call e.g.\n    // presidual() to ensure that the residuals are updated.\n    const Vector& rb() const;\n    const Vector& rl() const;\n    const Vector& ru() const;\n    const Vector& rc() const;\n\n    enum class State { fixed, free, barrier };\n\n    // Returns the state of variable j.\n    State StateOf(Int j) const;\n\n    // Returns true if a barrier term exists for the lower or upper bound.\n    // The following expression is true for each variable:\n    // (StateOf(j)==State::barrier) == (has_barrier_lb(j)||has_barrier_ub(j))\n    bool has_barrier_lb(Int j) const;\n    bool has_barrier_ub(Int j) const;\n\n    // Returns true if variable j is \"implied\", i.e. StateOf(j)==State::free\n    // but the variable has at least one finite bound in the model.\n    bool is_implied(Int j) const;\n\n    // Changes state of variable j to fixed and sets xl[j]=xu[j]=zl[j]=zu[j]=0.\n    // If @value is given, sets x[j]=@value.\n    void make_fixed(Int j);\n    void make_fixed(Int j, double value);\n\n    // Changes the state of variable j to free.\n    // make_implied_lb(j) lb[j] must be finite.\n    //                    The method leaves zl[j] and zu[j] unchanged. The cost\n    //                    coefficient of variable j in the remaining LP becomes\n    //                    c[j]-zl[j]+zu[j].\n    //                    Postprocess() sets x[j]=lb[j], zu[j]=0 and computes\n    //                    zl[j] to satisfy dual feasibility.\n    // make_implied_ub(j) ub[j] must be finite.\n    //                    The method leaves zl[j] and zu[j] unchanged. The cost\n    //                    coefficient of variable j in the remaining LP becomes\n    //                    c[j]-zl[j]+zu[j].\n    //                    Postprocess() sets x[j]=ub[j], zl[j]=0 and computes\n    //                    zu[j] to satisfy dual feasibility.\n    // make_implied_eq(j) must have lb[j]==ub[j].\n    //                    The method sets zl[j]=0 and zu[j]=0.\n    //                    Postprocess sets x[j]=lb[j] and chooses either zl[j]\n    //                    or zu[j] to be nonzero depending on the sign of the\n    //                    reduced cost.\n    void make_implied_lb(Int j);\n    void make_implied_ub(Int j);\n    void make_implied_eq(Int j);\n\n    // Returns the IPM scaling factor for variable j, which is\n    // 0                                 if StateOf(j)==State::fixed,\n    // inf                               if StateOf(j)==State::free,\n    // 1.0/sqrt(zl[j]/xl[j]+zu[j]/xu[j]) if StateOf(j)==State::barrier.\n    // In the latter case the scaling factor is finite and positive.\n    double ScalingFactor(Int j) const;\n\n    // Returns the primal/dual objective value in the LP that is currently\n    // being solved (after fixing and implying variables).\n    double pobjective() const;\n    double dobjective() const;\n\n    // Returns the primal/dual objective value obtained after postprocessing.\n    double pobjective_after_postproc() const;\n    double dobjective_after_postproc() const;\n\n    // Returns the infinity norm of [rb;rl;ru] and rc.\n    double presidual() const;\n    double dresidual() const;\n\n    // complementarity() returns the sum of the pairwise complementarity\n    // products xl[j]*zl[j] and xu[j]*zu[j] from all barrier terms. mu()\n    // returns the average, mu_min() the minimum and mu_max() the maximum.\n    double complementarity() const;\n    double mu() const;\n    double mu_min() const;\n    double mu_max() const;\n\n    // Returns true if the relative primal and dual residuals are <=\n    // feasibility_tol().\n    bool feasible() const;\n\n    // Returns true if the relative objective gap is <= optimality_tol().\n    bool optimal() const;\n\n    // Returns true if the iterate satisfies the IPM termination\n    // criterion.  If start_crossover_tol() <= 0, the termination\n    // criterion is feasible() && optimal(). If start_crossover_tol()\n    // > 0, it is additionally required that the relative residuals\n    // which result from dropping the iterate to complementarity are\n    // <= start_crossover_tol().\n    bool term_crit_reached() const;\n\n    double feasibility_tol() const { return feasibility_tol_; }\n    double optimality_tol() const { return optimality_tol_; }\n    double start_crossover_tol() const { return start_crossover_tol_; }\n\n    void feasibility_tol(double new_tol) { feasibility_tol_ = new_tol; }\n    void optimality_tol(double new_tol) { optimality_tol_ = new_tol; }\n    void start_crossover_tol(double new_tol) { start_crossover_tol_ = new_tol; }\n\n    // Substitutes x[j], xl[j], xu[j], zl[j] and zu[j] for fixed and implied\n    // variables as defined by their state. After Postprocess() the object is\n    // invalid for use as an IPM iterate.\n    void Postprocess();\n\n    // Calls Model::EvaluateInteriorSolution().\n    void EvaluatePostsolved(Info* info) const;\n\n    // Copies y and constructs x and z from the iterate such that\n    // x[j]==lb[j] || x[j]==ub[j] || z[j]==0.0 is true for each j.\n    // The method can only be called after Postprocess().\n    void DropToComplementarity(Vector& x, Vector& y, Vector& z) const;\n\n    double bounds_measure_;\n    double costs_measure_;\n\nprivate:\n    // A (primal or dual) variable that is required to be positive in the IPM is\n    // not moved closer to zero than kBarrierMin.\n    static constexpr double kBarrierMin = 1e-30;\n\n    void assert_consistency();\n    void Evaluate() const;\n    void ComputeResiduals() const;\n    void ComputeObjectives() const;\n    void ComputeComplementarity() const;\n\n    // Computes the maximum primal and dual residual that results from dropping\n    // a barrier variable. Dropping means to set either x[j] to a bound or zl[j]\n    // and zu[j] to zero, where the decision is made by the ratios or primal to\n    // dual variables.\n    void ResidualsFromDropping(double* pres, double* dres) const;\n\n    // Internally, the state of each variable is subdivided as follows:\n    //\n    // State::barrier is represented by StateDetail::\n    //\n    //     BARRIER_LB   0 < xl < inf, xu = inf, zl > 0, zu = 0.\n    //                  The variable is moved by the barrier solver. It has a\n    //                  finite lower bound and an infinite upper bound.\n    //    \n    //     BARRIER_UB   xl = inf, 0 < xu < inf, zl = 0, zu > 0.\n    //                  The variable is moved by the barrier solver. It has an\n    //                  infinite lower bound and a finite upper bound.\n    //    \n    //     BARRIER_BOXED 0 < xl < inf, 0 < xu < inf, zl > 0, zu > 0.\n    //                   The variable is moved by the barrier solver. It has a\n    //                   finite lower bound and a finite upper bound.\n    //\n    // State::fixed is represented by StateDetail::\n    //\n    //     FIXED        xl = 0, xu = 0, zl = 0, zu = 0.\n    //                  The variable is fixed at its current x value.\n    //\n    // State::free is represented by StateDetail::\n    //\n    //     FREE         xl = inf, xu = inf, zl = 0, zu = 0.\n    //                  The variable is moved by the barrier solver. It has no\n    //                  finite bound.\n    //    \n    //     IMPLIED_LB   xl = inf, xu = inf, zl >= 0, zu >= 0\n    //                  The variable has a finite lb but is treated as free by\n    //                  the barrier solver. (The ub may or may not be finite.)\n    //                  After termination we set x = lb, zu = 0 and compute zl\n    //                  from dual feasibility.\n    //                  Evaluate() subtracts (zl-zu) from the cost coefficient\n    //                  when computing the primal objective value.\n    //    \n    //     IMPLIED_UB   xl = inf, xu = inf, zl >= 0, zu >= 0\n    //                  The variable has a finite ub but is treated as free by\n    //                  the barrier solver. (The lb may or may not be finite.)\n    //                  After termination we set x = ub, zl = 0 and compute zu\n    //                  from dual feasibility.\n    //                  Evaluate() subtracts (zl-zu) from the cost coefficient\n    //                  when computing the primal objective value.\n    //    \n    //     IMPLIED_EQ   xl = inf, xu = inf, zl = 0, zu = 0\n    //                  The variable has lb == ub but is treated as free by\n    //                  the barrier solver. After termination we set x = lb\n    //                  and compute either zl or zu from dual feasibility and\n    //                  set the other one to zero.\n    //\n    enum class StateDetail { BARRIER_LB, BARRIER_UB, BARRIER_BOXED, FREE, FIXED,\n                             IMPLIED_LB, IMPLIED_UB, IMPLIED_EQ };\n\n    const Model& model_;\n    Vector x_, xl_, xu_, y_, zl_, zu_;\n    std::vector<StateDetail> variable_state_;\n\n    // The mutable quantities have a defined value if evaluated_ is true.\n    // They are computed by Evaluate(), which is called by any method that\n    // accesses any of these quantities.\n    mutable Vector rb_, rl_, ru_, rc_;\n    mutable double pobjective_{0.0};\n    mutable double dobjective_{0.0};\n    mutable double presidual_{0.0};\n    mutable double dresidual_{0.0};\n    mutable double offset_{0.0};\n    mutable double complementarity_{0.0};\n    mutable double mu_{0.0};\n    mutable double mu_min_{0.0};\n    mutable double mu_max_{0.0};\n    mutable bool evaluated_{false};\n    bool postprocessed_{false};\n\n    double feasibility_tol_{1e-6};\n    double optimality_tol_{1e-8};\n    double start_crossover_tol_{-1.0};\n};\n\ninline Iterate::State Iterate::StateOf(Int j) const {\n    switch (variable_state_[j]) {\n    case StateDetail::FIXED:\n        return State::fixed;\n    case StateDetail::FREE:\n    case StateDetail::IMPLIED_LB:\n    case StateDetail::IMPLIED_UB:\n    case StateDetail::IMPLIED_EQ:\n        return State::free;\n    default:\n        return State::barrier;\n    }\n}\n\ninline bool Iterate::has_barrier_lb(Int j) const {\n    return variable_state_[j] == StateDetail::BARRIER_LB\n        || variable_state_[j] == StateDetail::BARRIER_BOXED;\n}\n\ninline bool Iterate::has_barrier_ub(Int j) const{\n    return variable_state_[j] == StateDetail::BARRIER_UB\n        || variable_state_[j] == StateDetail::BARRIER_BOXED;\n}\n\ninline bool Iterate::is_implied(Int j) const {\n    return variable_state_[j] == StateDetail::IMPLIED_LB\n        || variable_state_[j] == StateDetail::IMPLIED_UB\n        || variable_state_[j] == StateDetail::IMPLIED_EQ;\n}\n\n}  // namespace ipx\n\n#endif  // IPX_ITERATE_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/kkt_solver.h",
    "content": "#ifndef IPX_KKT_SOLVER_H_\n#define IPX_KKT_SOLVER_H_\n\n#include \"ipm/ipx/basis.h\"\n#include \"ipm/ipx/iterate.h\"\n\nnamespace ipx {\n\n// Interface to KKT solver implementations. A KKT solver implements a direct or\n// iterative method for solving\n//\n//   [ G   AI' ] (x) = (a) ,                        (1)\n//   [ AI   0  ] (y)   (b)\n//\n// where AI is the m-by-(n+m) matrix defined by a model and G is a positive\n// semidefinite diagonal matrix. The solver may add regularization to G and/or\n// the zero block.\n//\n// An iterative solver must compute an approximate solution of the form\n//\n//   [ G   AI' ] (x) = (a) + (res)                  (2)\n//   [ AI   0  ] (y)   (b)   ( 0 )\n//\n// that satisfies Infnorm(D*res) <= tol, where D is the diagonal matrix with\n// entries D[i,i] = sqrt(1/G[i,i]) if G[i,i] != 0 and D[i,i] = 1 otherwise.\n\nclass KKTSolver {\npublic:\n    KKTSolver& operator=(const KKTSolver&) = delete;\n    KKTSolver& operator=(KKTSolver&&) = delete;\n    virtual ~KKTSolver() {}\n\n    // Factorizes the KKT matrix (direct solver) or prepares preconditioner\n    // (iterative solver). The diagonal matrix G is built from @iterate.\n    // The implementation is allowed to change variable statuses to eliminate\n    // close-to-converged variables from the IPM solve. Some implementations\n    // allow @iterate to be NULL, in which case G is assumed to be the identity\n    // matrix.\n    void Factorize(Iterate* iterate, Info* info);\n\n    // Solves KKT system. If an iterative method is used, @tol is the required\n    // tolerance for the residual in (2) as specified above.\n    void Solve(const Vector& a, const Vector& b, double tol,\n               Vector& x, Vector& y, Info* info);\n\n    // If an iterative method is used, returns the # iterations in all Solve()\n    // calls since the last call to Factorize(). A direct solver returns the #\n    // iterative refinement steps.\n    Int iter() const;\n\n    // If a basis matrix is maintained, returns the # basis changes in the last\n    // call to Factorize(). Otherwise returns 0.\n    Int basis_changes() const;\n\n    // If a basis matrix is maintained, returns a pointer to it.\n    // Otherwise returns NULL.\n    const Basis* basis() const;\n\nprivate:\n    virtual void _Factorize(Iterate* iterate, Info* info) = 0;\n    virtual void _Solve(const Vector& a, const Vector& b, double tol,\n                         Vector& x, Vector& y, Info* info) = 0;\n    virtual Int _iter() const = 0;\n    virtual Int _basis_changes() const { return 0; }\n    virtual const Basis* _basis() const { return nullptr; }\n};\n\n}  // namespace ipx\n\n#endif  // IPX_KKT_SOLVER_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/kkt_solver_basis.h",
    "content": "#ifndef IPX_KKT_SOLVER_BASIS_H_\n#define IPX_KKT_SOLVER_BASIS_H_\n\n#include \"ipm/ipx/basis.h\"\n#include \"ipm/ipx/control.h\"\n#include \"ipm/ipx/kkt_solver.h\"\n#include \"ipm/ipx/model.h\"\n#include \"ipm/ipx/splitted_normal_matrix.h\"\n\nnamespace ipx {\n\n// KKTSolverBasis implements a KKT solver using the CR method with basis\n// preconditioning. Maintaining a basis matrix allows to remove degenerate\n// variables from the optimization process. This technique is applied in\n// Factorize() if parameter ipm_drop_primal or ipm_drop_dual is positive.\n//\n// In the call to Factorize() @iterate must not be NULL.\n\nclass KKTSolverBasis : public KKTSolver {\npublic:\n    // Constructor wraps a Basis object into a KKTSolverBasis object. The basis\n    // must have been initialized to a starting basis and must be valid as long\n    // as the KKT solver is used. Its associated model defines the LP data.\n    KKTSolverBasis(const Control& control, Basis& basis);\n\n    Int maxiter() const { return maxiter_; }\n    void maxiter(Int new_maxiter) { maxiter_ = new_maxiter; }\n\nprivate:\n    // DropPrimal() and DropDual() do not choose entries as pivots that are <=\n    static constexpr double kPivotZeroTol = 1e-7;\n\n    void _Factorize(Iterate* iterate, Info* info) override;\n    void _Solve(const Vector& a, const Vector& b, double tol,\n                Vector& x, Vector& y, Info* info) override;\n    Int _iter() const override { return iter_; }\n    Int _basis_changes() const override { return basis_changes_; }\n    const Basis* _basis() const override { return &basis_; }\n\n    // Processes basic variables that are close to a bound by either pivoting\n    // them out of the basis or making them \"implied\"; i.e. the dual is fixed at\n    // its current value and the variable is treated as free by the interior\n    // point solver. After the LP solve finished, the primal is set to its\n    // bound.\n    void DropPrimal(Iterate* iterate, Info* info);\n\n    // Processes nonbasic variables whose dual is close to zero by either\n    // pivoting them into the basis or \"fixing\" the primal; i.e. the variable is\n    // removed from optimization and the primal remains at its current value.\n    // The dual is set to zero.\n    void DropDual(Iterate* iterate, Info* info);\n\n    const Control& control_;\n    const Model& model_;\n    Basis& basis_;\n    SplittedNormalMatrix splitted_normal_matrix_;\n    Vector colscale_;           // interior point column scaling factors\n    bool factorized_{false};    // preconditioner prepared?\n    Int maxiter_{-1};\n    Int iter_{0};\n    Int basis_changes_{0};\n};\n\n}  // namespace ipx\n\n#endif  // IPX_KKT_SOLVER_BASIS_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/kkt_solver_diag.h",
    "content": "// Copyright (c) 2018-2019 ERGO-Code. See license.txt for license.\n\n#ifndef IPX_KKT_SOLVER_DIAG_H_\n#define IPX_KKT_SOLVER_DIAG_H_\n\n#include \"ipm/ipx/control.h\"\n#include \"ipm/ipx/diagonal_precond.h\"\n#include \"ipm/ipx/kkt_solver.h\"\n#include \"ipm/ipx/model.h\"\n#include \"ipm/ipx/normal_matrix.h\"\n\nnamespace ipx {\n\n// KKTSolverDiag implements a KKT solver that applies the Conjugate Residuals\n// method with diagonal preconditioning to the normal equations. If the (1,1)\n// block of the KKT matrix is not positive definite, regularization is applied.\n//\n// In the call to Factorize() @iterate is allowed to be NULL, in which case the\n// (1,1) block of the KKT matrix is the identity matrix.\n\nclass KKTSolverDiag : public KKTSolver {\npublic:\n    KKTSolverDiag(const Control& control, const Model& model);\n\n    Int maxiter() const { return maxiter_; }\n    void maxiter(Int new_maxiter) { maxiter_ = new_maxiter; }\n\nprivate:\n    void _Factorize(Iterate* iterate, Info* info) override;\n    void _Solve(const Vector& a, const Vector& b, double tol,\n                Vector& x, Vector& y, Info* info) override;\n    Int _iter() const override { return iter_; };\n\n    const Control& control_;\n    const Model& model_;\n    NormalMatrix normal_matrix_;\n    DiagonalPrecond precond_;\n\n    Vector W_;               // diagonal matrix in AI*W*AI'\n    Vector resscale_;        // residual scaling factors for CR termination test\n    bool factorized_{false}; // KKT matrix factorized?\n    Int maxiter_{-1};\n    Int iter_{0};               // # CR iterations since last Factorize()\n};\n\n}  // namespace ipx\n\n#endif  // IPX_KKT_SOLVER_DIAG_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/linear_operator.h",
    "content": "#ifndef IPX_LINEAR_OPERATOR_H_\n#define IPX_LINEAR_OPERATOR_H_\n\n#include \"ipm/ipx/ipx_internal.h\"\n\nnamespace ipx {\n\nclass LinearOperator {\npublic:\n    LinearOperator& operator=(const LinearOperator&) = delete;\n    LinearOperator& operator=(LinearOperator&&) = delete;\n    virtual ~LinearOperator() {}\n\n    // Computes lhs = F(rhs), where F is a linear function. If rhs_dot_lhs is\n    // not NULL, then the argument returns dot(rhs,lhs). The implementation can\n    // assume that rhs and lhs do not refer to the same object.\n    void Apply(const Vector& rhs, Vector& lhs, double* rhs_dot_lhs);\n\nprivate:\n    virtual void _Apply(const Vector& rhs, Vector& lhs, double* rhs_dot_lhs)\n        = 0;\n};\n\n}  // namespace ipx\n\n#endif  // IPX_LINEAR_OPERATOR_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/lp_solver.h",
    "content": "#ifndef IPX_LP_SOLVER_H_\n#define IPX_LP_SOLVER_H_\n\n#include <memory>\n#include \"ipm/ipx/basis.h\"\n#include \"ipm/ipx/control.h\"\n#include \"ipm/ipx/ipm.h\"\n#include \"ipm/ipx/iterate.h\"\n#include \"ipm/ipx/model.h\"\n#include \"lp_data/HighsCallback.h\"\n\nnamespace ipx {\n\nclass LpSolver {\npublic:\n    // Loads an LP model in the form given in the reference documentation.\n    // @num_var: number of variables, must be > 0.\n    // @obj: size num_var array of objective coefficients.\n    // @lb: size num_var array of variable lower bounds, can have -INFINITY.\n    // @lb: size num_var array of variable upper bounds, can have +INFINITY.\n    // @num_constr: number of constraints, must be >= 0.\n    // @Ap, @Ai, @Ax: constraint matrix in CSC format; indices can be unsorted.\n    // @rhs: size num_constr array of right-hand side entries.\n    // @constr_type: size num_constr array of entries '>', '<' and '='.\n    // Returns:\n    //  0\n    //  IPX_ERROR_argument_null\n    //  IPX_ERROR_invalid_dimension\n    //  IPX_ERROR_invalid_matrix\n    //  IPX_ERROR_invalid_vector\n    Int LoadModel(Int num_var, const double offset,\n\t\t  const double* obj, const double* lb,\n                  const double* ub, Int num_constr, const Int* Ap,\n                  const Int* Ai, const double* Ax, const double* rhs,\n                  const char* constr_type);\n\n    // Loads a primal-dual point as starting point for the IPM.\n    // @x: size num_var array\n    // @xl: size num_var array, must satisfy xl[j] >= 0 for all j and\n    //      xl[j] == INFINITY iff lb[j] == -INFINITY.\n    // @xu: size num_var array, must satisfy xu[j] >= 0 for all j and\n    //      xu[j] == INFINITY iff ub[j] == INFINITY.\n    // @slack: size num_constr array, must satisfy\n    //         slack[i] == 0 if constr_type[i] == '='\n    //         slack[i] >= 0 if constr_type[i] == '<'\n    //         slack[i] <= 0 if constr_type[i] == '>'\n    // @y: size num_constr array, must satisfy\n    //     y[i] >= 0 if constr_type[i] == '>'\n    //     y[i] <= 0 if constr_type[i] == '<'\n    // @zl: size num_var array, must satsify zl[j] >= 0 for all j and\n    //      zl[j] == 0 if lb[j] == -INFINITY\n    // @zu: size num_var array, must satsify zu[j] >= 0 for all j and\n    //      zu[j] == 0 if ub[j] == INFINITY\n    // When a starting point was loading successfully (return value 0), then\n    // the next call to Solve() will start the IPM from that point, except that\n    // primal and dual slacks with value 0 are made positive if necessary. The\n    // IPM will skip the initial iterations and start directly with basis\n    // preconditioning.\n    // At the moment loading a starting point is not possible when the model was\n    // dualized during preprocessing. See parameters to turn dualization off.\n    // Returns:\n    // 0                            success\n    // IPX_ERROR_argument_null      an argument was NULL\n    // IPX_ERROR_invalid_vector     a sign condition was violated\n    // IPX_ERROR_not_implemented    the model was dualized during preprocessing\n    Int LoadIPMStartingPoint(const double* x, const double* xl,\n                             const double* xu, const double* slack,\n                             const double* y, const double* zl,\n                             const double* zu);\n\n    // Solves the model that is currently loaded in the object.\n    // Returns GetInfo().status.\n    Int Solve();\n\n    // Returns the solver info from the last call to Solve(). See the reference\n    // documentation for the meaning of Info values.\n    Info GetInfo() const;\n\n    // Returns the final IPM iterate from the last call to Solve() into user\n    // arrays. An iterate is available if GetInfo().status_ipm !=\n    // IPX_STATUS_not_run. If no iterate is available, the method does nothing.\n    // Each of the pointer arguments must either be NULL or an array of\n    // appropriate dimension. If NULL, the quantity is not returned.\n    // Returns -1 if no IPM iterate was available and 0 otherwise.\n    Int GetInteriorSolution(double* x, double* xl, double* xu, double* slack,\n                            double* y, double* zl, double* zu) const;\n\n    // Returns the basic solution and basis from the last call to Solve() into\n    // user arrays. A basic solution and basis are available if\n    // GetInfo().status_crossover == IPX_STATUS_optimal ||\n    // GetInfo().status_crossover == IPX_STATUS_imprecise. Otherwise the method\n    // does nothing. Each of the pointer arguments must either be NULL or an\n    // array of appropriate dimension. If NULL, the quantity is not returned.\n    // Returns -1 if no basic solution was available and 0 otherwise.\n    Int GetBasicSolution(double* x, double* slack, double* y, double* z,\n                         Int* cbasis, Int* vbasis) const;\n\n    // Returns/sets all parameters. Without calling SetParameters(), the solver\n    // uses the default values of a Parameters object.\n    Parameters GetParameters() const;\n    void SetParameters(Parameters new_parameters);\n\n    // Sets the callback in control\n    void SetCallback(HighsCallback* callback);\n\n    // Discards the model and solution (if any) but keeps the parameters.\n    void ClearModel();\n\n    // Discards the starting point (if any).\n    void ClearIPMStartingPoint();\n\n    // Runs crossover for the given starting point. The starting point must be\n    // complementary and satisfy bound and sign conditions; i.e. a dual variable\n    // must be non-positive (non-negative) when its primal is not at lower\n    // (upper) bound. Each of the pointer arguments can be NULL, in which case\n    // all elements of the vector are assumed to be zero.\n    // Returns:\n    // 0                            starting point OK\n    // IPX_ERROR_invalid_vector     starting point not complementary or violates\n    //                              bound or sign conditions\n    Int CrossoverFromStartingPoint(const double* x_start,\n                                   const double* slack_start,\n                                   const double* y_start,\n                                   const double* z_start);\n\n    // -------------------------------------------------------------------------\n    // The remaining methods are for debugging.\n    // -------------------------------------------------------------------------\n\n    // Returns the current IPM iterate without postsolve. The method does\n    // nothing when no iterate is available (i.e. when IPM was not started).\n    // @x, @xl, @xu, @zl, @zu: either NULL or size num_cols_solver arrays.\n    // @y: either NULL or size num_rows_solver array.\n    // Returns -1 if no IPM iterate was available and 0 otherwise.\n    Int GetIterate(double* x, double* y, double* zl, double* zu, double* xl,\n                   double* xu);\n\n    // Returns the current basis postsolved.\n    // - If crossover terminated successfully, this is the basis returned by\n    //   GetBasicSolution().\n    // - If crossover failed, this is the basis at which failure occured.\n    // - If crossover was not called, this is the basis from the IPM\n    //   preconditioner.\n    // - If no basis is available, the method does nothing.\n    // @cbasis: either NULL or size num_constr array.\n    // @vbasis: either NULL or size num_var array.\n    // Returns -1 if no basis was available and 0 otherwise.\n    Int GetBasis(Int* cbasis, Int* vbasis);\n\n    // Returns the constraint matrix from the solver (including slack columns)\n    // and the diagonal from the (1,1) block of the KKT matrix corresponding to\n    // the current IPM iterate. The method does nothing when no IPM iterate is\n    // available (i.e. when IPM was not started).\n    // @AIp: either NULL or size num_cols_solver + 1 array.\n    // @AIi, @AIx: either NULL or size num_entries_solver arrays.\n    // (If any of the three arguments is NULL, the matrix is not returned.)\n    // @g: either NULL or size num_cols_solver array.\n    // Returns -1 if no IPM iterate was available and 0 otherwise.\n    Int GetKKTMatrix(Int* AIp, Int* AIi, double* AIx, double* g);\n\n    // (Efficiently) computes the number of nonzeros per row and column of the\n    // symbolic inverse of the basis matrix.\n    // @rowcounts, @colcounts: either NULL or size num_rows_solver arrays.\n    // Returns -1 if no basis was available and 0 otherwise.\n    Int SymbolicInvert(Int* rowcounts, Int* colcounts);\n\nprivate:\n    void ClearSolution();\n    void InteriorPointSolve();\n    void RunIPM();\n    void MakeIPMStartingPointValid();\n    void ComputeStartingPoint(IPM& ipm);\n    void RunInitialIPM(IPM& ipm);\n    void BuildStartingBasis();\n    void RunMainIPM(IPM& ipm);\n    void BuildCrossoverStartingPoint();\n    void RunCrossover();\n    void PrintSummary();\n\n    Control control_;\n    Info info_;\n    Model model_;\n    std::unique_ptr<Iterate> iterate_;\n    std::unique_ptr<Basis> basis_;\n\n    // Basic solution computed by crossover and basic status of each variable\n    // (one of IPX_nonbasic_lb, IPX_nonbasic_ub, IPX_basic, IPX_superbasic).\n    // If crossover was not run or failed, then basic_statuses_ is empty.\n    // If crossover_weights_ is non-empty at call to RunCrossover(), then it\n    // contains model_.cols() + model_.rows() weights that define the order of\n    // primal and dual pushes.\n    Vector x_crossover_, y_crossover_, z_crossover_;\n    Vector crossover_weights_;\n    std::vector<Int> basic_statuses_;\n\n    // IPM starting point provided by user (presolved).\n    Vector x_start_, xl_start_, xu_start_, y_start_, zl_start_, zu_start_;\n};\n\n}  // namespace ipx\n\n#endif  // IPX_LP_SOLVER_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/lu_factorization.h",
    "content": "#ifndef IPX_LU_FACTORIZATION_H_\n#define IPX_LU_FACTORIZATION_H_\n\n#include <vector>\n#include \"ipm/ipx/ipx_internal.h\"\n#include \"ipm/ipx/sparse_matrix.h\"\n\nnamespace ipx {\n\n// Interface class for LU factorization. Implementations perform the\n// factorization and immediately return the factors. They do not preserve any\n// memory in their object.\n\nclass LuFactorization {\npublic:\n    virtual ~LuFactorization() {}\n    LuFactorization& operator=(const LuFactorization&) = delete;\n    LuFactorization& operator=(LuFactorization&&) = delete;\n\n    // Computes the factorization\n    //\n    //   B[rowperm,colperm] = (L+I)*U\n    //\n    // into a strict lower triangular matrix L and an upper triangular matrix U.\n    // If B is singular, the dependent columns are replaced by unit columns in\n    // the product (L+I)*U.\n    //\n    // @dim: dimension of matrix B\n    // @Bbegin, @Bend, @Bi, @Bx: matrix B in sparse column format. The row\n    //                           indices and nonzero values of column j are in\n    //                           Bi[Bbegin[j]..Bend[j]-1] and\n    //                           Bx[Bbegin[j]..Bend[j]-1].\n    //                           Indices need not be sorted, but there must be\n    //                           no duplicates or invalid entries (need not be\n    //                           checked by the implementation).\n    // @pivottol: tolerance for partial threshold pivoting, from (0,1].\n    // @strict_abs_pivottol: If true, then the implementation is asked to use\n    //                       kLuDependencyTol as absolute pivot tolerance and to\n    //                       remove columns from the active submatrix\n    //                       immediately when all entries became smaller than\n    //                       the absolute pivot tolerance. Need not be supported\n    //                       by the implementation.\n    // @L, @U: return the matrix factors with sorted indices. The objects are\n    //         resized as necessary.\n    // @rowperm, @colperm: return the row and column permutation. The objects\n    //                     are resized for dim entries.\n    // @dependent_cols: returns the column indices of B[:,colperm] in which\n    //                  no pivot was found.\n    //\n    // Factorize() cannot fail other than out of memory, in which case\n    // std::bad_alloc is thrown.\n    void Factorize(Int dim, const Int* Bbegin, const Int* Bend,\n                   const Int* Bi, const double* Bx, double pivottol,\n                   bool strict_abs_pivottol,\n                   SparseMatrix* L, SparseMatrix* U,\n                   std::vector<Int>* rowperm, std::vector<Int>* colperm,\n                   std::vector<Int>* dependent_cols);\n\n    // Returns a stability measure for the factorization computed in the last\n    // call to Factorize(). 0.0 means ultimately stable; a value >> machine\n    // precision means that the factorization was numerically unstable, i.e.\n    // the relative pivot tolerance was too small.\n    double stability() const;\n\nprivate:\n    virtual void _Factorize(Int dim, const Int* Bbegin, const Int* Bend,\n                            const Int* Bi, const double* Bx, double pivottol,\n                            bool strict_abs_pivottol,\n                            SparseMatrix* L, SparseMatrix* U,\n                            std::vector<Int>* rowperm,\n                            std::vector<Int>* colperm,\n                            std::vector<Int>* dependent_cols) = 0;\n\n    double stability_{0.0};\n};\n\n}  // namespace ipx\n\n#endif  // IPX_LU_FACTORIZATION_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/lu_update.h",
    "content": "#ifndef IPX_LU_UPDATE_H_\n#define IPX_LU_UPDATE_H_\n\n#include <vector>\n#include \"ipm/ipx/indexed_vector.h\"\n#include \"ipm/ipx/sparse_matrix.h\"\n\nnamespace ipx {\n\n// Interface class for LU factorization + update implementations.\n\nclass LuUpdate {\npublic:\n    virtual ~LuUpdate() {}\n    LuUpdate& operator=(const LuUpdate&) = delete;\n    LuUpdate& operator=(LuUpdate&&) = delete;\n\n    // Factorizes matrix given in compressed column format (4-array notation).\n    // The matrix dimension (denoted dim in the documentation of the following\n    // methods) is set by the constructor of the derived class. If during the\n    // course of the factorization a column of the active submatrix becomes\n    // (numerically) zero, it is replaced by a unit column in L*U.\n    //\n    // @strict_abs_pivottol: If true, then the implementation is asked to use\n    //                       kLuDependencyTol as absolute pivot tolerance and to\n    //                       remove columns from the active submatrix\n    //                       immediately when all entries became smaller than\n    //                       the absolute pivot tolerance. Need not be supported\n    //                       by the implementation.\n    //\n    // Factorize() cannot fail other than for out of memory, in which case\n    // std::bad_alloc is thrown. Returns\n    // 0 OK\n    // 1 OK, but the factorization is numerically unstable; suggests tightening\n    //   the pivot tolerance (see below) and to refactorize.\n    // 2 OK, but singularities occured and were replaced by unit columns.\n    // 3 = 1 and 2\n    Int Factorize(const Int* Bbegin, const Int* Bend, const Int* Bi,\n                  const double* Bx, bool strict_abs_pivottol);\n\n    // Exports LU factors. The method can only be called after a fresh\n    // factorization. (Otherwise an assertion will fail.) It returns L, U and\n    // permutations such that\n    //\n    //   B[rowperm,colperm] = (L+I)*U,\n    //\n    // where B is the matrix given to Factorize() after replacing dependent\n    // columns by unit columns. The indices in L and U are sorted. Any of the\n    // arguments can be NULL, in which case the quantity is not returned.\n    //\n    // @L: returns matrix L, will be resized as necessary.\n    // @U: returns matrix U, will be resized as necessary.\n    // @rowperm: size dim array, returns row permutation.\n    // @colperm: size dim array, returns column permutation.\n    // @dependent_cols: returns indices k for which U[:,k] was replaced by a\n    //                  unit column in Factorize().\n    void GetFactors(SparseMatrix* L, SparseMatrix* U, Int* rowperm,\n                    Int* colperm, std::vector<Int>* dependent_cols);\n\n    // Solves linear system with dense right-hand side and solution.\n    // @rhs, @lhs: size dim vectors, may refer to the same object.\n    // @trans: 't' or 'T' for transposed system\n    void SolveDense(const Vector& rhs, Vector& lhs, char trans);\n\n    // Solves B*x=b in preparation for replacing a column of B by b.\n    // @nz, @bi, @bx: b as compressed sparse vector.\n    // @lhs: size dim vector returning x.\n    // The 3-argument version can save the triangular solve with U.\n    void FtranForUpdate(Int nz, const Int* bi, const double* bx);\n    void FtranForUpdate(Int nz, const Int* bi, const double* bx,\n                        IndexedVector& lhs);\n\n    // Solves B'*y=ej in preparation for replacing column j of B, where ej\n    // denotes the j-th unit vector.\n    // @lhs: size dim vector returning y.\n    // The 1-argument version can save the triangular solve with L.\n    void BtranForUpdate(Int j);\n    void BtranForUpdate(Int j, IndexedVector& lhs);\n\n    // Updates factorization. The column to be replaced was defined in the last\n    // call to BtranForUpdate(). The new column was given in the last call to\n    // FtranForUpdate(). Both methods must have been called prior to Update().\n    // (Otherwise an assertion will fail.)\n    // @pivot: p-th entry of B^{-1}*b, if column p of B is to be replaced by b.\n    // Returns: < 0 if the updated matrix is (numerically) singular. The update\n    //              may or may not have been performed. The behaviour is\n    //              undefined if any of the solve routines is called before\n    //              computing a fresh factorization.\n    //          > 0 if the updated factorization looks numerically unstable.\n    //            0 otherwise\n    Int Update(double pivot);\n\n    // Returns true if refactorization is required or recommended for memory\n    // or speed. No stability test is done.\n    bool NeedFreshFactorization();\n\n    // Returns (nnz(L)+nnz(U))/nnz(B) from the last factorization.\n    double fill_factor() const;\n\n    // Gets/sets the tolerance for partial threshold pivoting in Factorize().\n    double pivottol() const;\n    void pivottol(double new_pivottol);\n\n    // Returns the number of updates since the last factorization.\n    Int updates() const;\n\nprivate:\n    virtual Int _Factorize(const Int* Bbegin, const Int* Bend, const Int* Bi,\n                           const double* Bx, bool strict_abs_pivottol) = 0;\n    virtual void _GetFactors(SparseMatrix* L, SparseMatrix* U, Int* rowperm,\n                             Int* colperm, std::vector<Int>* dep_cols) = 0;\n    virtual void _SolveDense(const Vector& rhs, Vector& lhs, char trans) = 0;\n    virtual void _FtranForUpdate(Int nz, const Int* bi, const double* bx) = 0;\n    virtual void _FtranForUpdate(Int nz, const Int* bi, const double* bx,\n                                IndexedVector& lhs) = 0;\n    virtual void _BtranForUpdate(Int p) = 0;\n    virtual void _BtranForUpdate(Int p, IndexedVector& lhs) = 0;\n    virtual Int _Update(double pivot) = 0;\n    virtual bool _NeedFreshFactorization() = 0;\n    virtual double _fill_factor() const = 0;\n    virtual double _pivottol() const = 0;\n    virtual void _pivottol(double new_pivottol) = 0;\n\n    Int updates_{0};            // counts updates since factorization\n};\n\n}  // namespace ipx\n\n#endif  // IPX_LU_UPDATE_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/maxvolume.h",
    "content": "#ifndef IPX_MAXVOLUME_H_\n#define IPX_MAXVOLUME_H_\n\n#include \"ipm/ipx/basis.h\"\n#include \"ipm/ipx/control.h\"\n\nnamespace ipx {\n\nclass Maxvolume {\npublic:\n    explicit Maxvolume(const Control& control);\n    Int RunSequential(const double* colscale, Basis& basis);\n    Int RunHeuristic(const double* colscale, Basis& basis);\n\n    Int updates() const;        // # basis updates\n    Int skipped() const;        // # columns computed but basis not updated\n    Int passes() const;         // # passes over tblmatrix (-1 for heuristic)\n    Int slices() const;         // # slices of tblmatrix formed (heuristic only)\n    double volinc() const;      // log2 of volume increase\n    double time() const;        // runtime\n\n    // The remaining statistics are only set by RunSequential() and count the\n    // final pass over the tableau matrix. They are meaningful only if no\n    // updates occured in the final pass; this is guaranteed if parameter\n    // max_passes was larger than passes().\n\n    Int tblnnz() const;              // nnz of tableau matrix\n    double tblmax() const;           // max entry of scaled tableau matrix\n    double frobnorm_squared() const; // Frob.norm squared of scaled tableau\n\nprivate:\n    static constexpr double kPivotZeroTol = 1e-7;\n\n    struct Slice;\n    void Reset();\n    Int Driver(Basis& basis, Slice& slice);\n    Int ScaleFtran(double colscale_jn, const Vector& invscale_basic,\n                   IndexedVector& ftran);\n\n    const Control& control_;\n    Int updates_{0};\n    Int skipped_{0};\n    Int passes_{0};\n    Int slices_{0};\n    double volinc_{0.0};\n    double time_{0.0};\n    Int tblnnz_{0};\n    double tblmax_{0.0};\n    double frobnorm_squared_{0.0};\n};\n\n}  // namespace ipx\n\n#endif  // IPX_MAXVOLUME_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/model.h",
    "content": "#ifndef IPX_MODEL_H_\n#define IPX_MODEL_H_\n\n#include <vector>\n#include \"ipm/ipx/control.h\"\n#include \"ipm/ipx/sparse_matrix.h\"\n\nnamespace ipx {\n\n// Model provides the interface between an LP model given by the user,\n//\n//   minimize   obj'x                                                    (1)\n//   subject to A*x {=,<,>} rhs, lbuser <= x <= ubuser,\n//\n// and the computational form used by the solver,\n//\n//   minimize   c'x\n//   subject to AI*x = b,                              (dual: y)\n//              x-xl = lb, xl >= 0,                    (dual: zl >= 0)\n//              x+xu = ub, xu >= 0.                    (dual: zu >= 0)\n//\n// The matrix AI has m >= 0 rows and n+m columns, where n > 0 is the number of\n// \"structural\" variables. The last m columns of AI form the identity matrix.\n// The last m components of c do not need to be zero (can happen when the model\n// was dualized in preprocessing). Entries of -lb and ub can be infinity.\n//\n// The user model is translated into computational form in two steps:\n// (a) scaling, which consists of\n//     - applying an automatic scaling algorithm to A (optional), and\n//     - \"flipping\" variables for which lbuser[j] is infinite but ubuser[j] is\n//        finite by multiplying the column of A by -1.\n// (b) dualization if appropriate\n//\n// A Model object cannot be modified other than discarding the data and loading\n// a new user model.\n\nclass Model {\npublic:\n    // Constructs an empty model.\n    Model() = default;\n\n    // Initializes a Model object from the form (1).\n    // @num_constr: number of rows of A\n    // @num_var: number of columns of A\n    // @Ap, @Ai, @Ax: matrix A in CSC format, 0-based indexing\n    // @rhs: array of size num_constr\n    // @constr_type: array of size num_constr with entries '=', '<' or '>'\n    // @obj: array of size num_var\n    // @lbuser: array of size num_var, entries can be -INFINITY\n    // @ubuser: array of size num_var, entries can be +INFINITY\n    // If the input is invalid an error code is returned and the Model object\n    // becomes empty.\n    // Returns:\n    //  0\n    //  IPX_ERROR_argument_null\n    //  IPX_ERROR_invalid_dimension\n    //  IPX_ERROR_invalid_matrix\n    //  IPX_ERROR_invalid_vector\n    Int Load(const Control& control, Int num_constr, Int num_var,\n             const Int* Ap, const Int* Ai, const double* Ax,\n             const double* rhs, const char* constr_type, const double offset,\n\t     const double* obj, const double* lbuser, const double* ubuser);\n    // Performs Flippo's test for deciding dualization\n    bool filippoDualizationTest() const;\n    // Writes statistics of input data and preprocessing to @info.\n    void GetInfo(Info* info) const;\n\n    // Returns true if the model is empty.\n    bool empty() const { return cols() == 0; }\n\n    // Deallocates all memory; the object becomes empty.\n    void clear();\n\n    // Returns the number of rows of AI.\n    Int rows() const { return num_rows_; }\n\n    // Returns the number of structural columns of AI (i.e. without the\n    // rightmost identity matrix).\n    Int cols() const { return num_cols_; }\n\n    // Returns the number of columns classified as dense.\n    Int num_dense_cols() const { return num_dense_cols_; }\n\n    // Returns true if column j is classified as dense (0 <= j < n+m).\n    bool IsDenseColumn(Int j) const {\n        return AI_.entries(j) >= nz_dense_;\n    }\n\n    // Returns true if the user model was dualized in preprocessing.\n    bool dualized() const { return dualized_; }\n\n    // Returns a reference to the matrix AI in CSC and CSR format.\n    const SparseMatrix& AI() const { return AI_; }\n    const SparseMatrix& AIt() const { return AIt_; }\n\n    // Returns the offset\n    const double offset() const { return offset_; }\n  \n    // Returns a reference to a model vector.\n    const Vector& b() const { return b_; }\n    const Vector& c() const { return c_; }\n    const Vector& lb() const { return lb_; }\n    const Vector& ub() const { return ub_; }\n\n    // Returns an entry of a model vector.\n    double b(Int i) const { return b_[i]; }\n    double c(Int j) const { return c_[j]; }\n    double lb(Int j) const { return lb_[j]; }\n    double ub(Int j) const { return ub_[j]; }\n\n    // Returns the infinity norm of [b; lb; ub], ignoring infinite entries.\n    double norm_bounds() const { return norm_bounds_; }\n\n    // Returns the infinity norm of c.\n    double norm_c() const { return norm_c_; }\n\n    // Transforms point from user model to solver model. Each of the pointer\n    // arguments can be NULL, in which case its components are assumed 0.0.\n    void PresolveStartingPoint(const double* x_user, const double* slack_user,\n                               const double* y_user, const double* z_user,\n                               Vector& x_solver, Vector& y_solver,\n                               Vector& z_solver) const;\n\n    // Performs the inverse operations to PostsolveInteriorSolution().\n    // The user vectors must all be given and must satisfy the sign conditions\n    // given in the reference documentation. Otherwise an error code will be\n    // returned. At the moment PresolveIPMStartingPoint() is not implemented\n    // for the case that the model was dualized in preprocessing.\n    // Returns:\n    //  0\n    //  IPX_ERROR_argument_null\n    //  IPX_ERROR_invalid_vector if a sign condition is violated\n    //  IPX_ERROR_not_implemented if the model was dualized in preprocessing.\n    Int PresolveIPMStartingPoint(const double* x_user,\n                                 const double* xl_user,\n                                 const double* xu_user,\n                                 const double* slack_user,\n                                 const double* y_user,\n                                 const double* zl_user,\n                                 const double* zu_user,\n                                 Vector& x_solver,\n                                 Vector& xl_solver,\n                                 Vector& xu_solver,\n                                 Vector& y_solver,\n                                 Vector& zl_solver,\n                                 Vector& zu_solver) const;\n\n    // Given an IPM iterate, recovers the solution to the user model (see the\n    // reference documentation). Each of the pointer arguments can be NULL, in\n    // which case the quantity is not returned. The sign conditions on the dual\n    // variables and those on the primal slack variables are staisfied if\n    // xl_solver, xu_solver, zl_solver and zu_solver are nonnegative.\n    void PostsolveInteriorSolution(const Vector& x_solver,\n                                   const Vector& xl_solver,\n                                   const Vector& xu_solver,\n                                   const Vector& y_solver,\n                                   const Vector& zl_solver,\n                                   const Vector& zu_solver,\n                                   double* x_user,\n                                   double* xl_user, double* xu_user,\n                                   double* slack_user,\n                                   double* y_user,\n                                   double* zl_user, double* zu_user) const;\n\n    // Evaluates the solution to the user model obtained from postsolving the\n    // IPM iterate. The following info members are set:\n    // abs_presidual, abs_dresidual, rel_presidual, rel_dresidual,\n    // pobjval, dobjval, rel_objgap, complementarity, normx, normy, normx.\n    void EvaluateInteriorSolution(const Vector& x_solver,\n                                  const Vector& xl_solver,\n                                  const Vector& xu_solver,\n                                  const Vector& y_solver,\n                                  const Vector& zl_solver,\n                                  const Vector& zu_solver,\n                                  Info* info) const;\n\n    // Given a basic solution to the solver model, recovers the basic solution\n    // to the user model. Each of the pointer arguments can be NULL.\n    void PostsolveBasicSolution(const Vector& x_solver,\n                                const Vector& y_solver,\n                                const Vector& z_solver,\n                                const std::vector<Int>& basic_status_solver,\n                                double* x_user, double* slack_user,\n                                double* y_user, double* z_user) const;\n\n    // Evaluates the solution to the user model obtained from postsolving the\n    // basic solution from the solver. The following info members are set:\n    // primal_infeas, dual_infeas, objval\n    void EvaluateBasicSolution(const Vector& x_solver,\n                               const Vector& y_solver,\n                               const Vector& z_solver,\n                               const std::vector<Int>& basic_status_solver,\n                               Info* info) const;\n\n    // Given a basic status for each variable in the solver model, recovers the\n    // basic statuses for constraints and variables in the user model. Each\n    // of the pointer arguments can be NULL.\n    void PostsolveBasis(const std::vector<Int>& basic_status_solver,\n                        Int* cbasis, Int* vbasis) const;\n\nprivate:\n    // Checks that the input is valid, and if so copies into the members below\n    // (see \"User model after scaling\"). If the input is invalid, an error code\n    // is returned and the object remains unchanged.\n    // Returns:\n    //  0\n    //  IPX_ERROR_argument_null\n    //  IPX_ERROR_invalid_dimension\n    //  IPX_ERROR_invalid_matrix\n    //  IPX_ERROR_invalid_vector\n    Int CopyInput(Int num_constr, Int num_var, const Int* Ap, const Int* Ai,\n                  const double* Ax, const double* rhs, const char* constr_type,\n                  const double offset, const double* obj, const double* lbuser,\n                  const double* ubuser);\n\n    // Scales A_, scaled_obj_, scaled_rhs_, scaled_lbuser_ and scaled_ubuser_\n    // according to parameter control.scale(). The scaling factors are stored in\n    // colscale_ and rowscale_. If all factors are 1.0 (either because scaling\n    // was turned off or because the algorithm did nothing), rowscale_ and\n    // colscale_ have size 0.\n    // In any case, variables for which lbuser is infinite but ubbuser is finite\n    // are \"flipped\" and their indices are kept in flipped_vars_.\n    void ScaleModel(const Control& control);\n\n    // Builds computational form without dualization. In Julia notation:\n    // num_rows = nc\n    // num_cols = nv\n    // AI       = [A eye(nc)]\n    // b        = rhs\n    // c        = [obj    ; zeros(nc)                      ]\n    // lb       = [lbuser ; constr_type_ .== '>' ? -Inf : 0]\n    // ub       = [ubuser ; constr_type_ .== '<' ? +Inf : 0]\n    // dualized = false\n    // Here nc = num_constr and nv = num_var. The data must have been loaded\n    // into the class member below (\"User model after scaling\") before calling\n    // this method.\n    void LoadPrimal();\n\n    // Builds computational form with dualization. In Julia notation:\n    // num_rows = nv\n    // num_cols = nc + nb\n    // AI       = [A' -eye(nv)[:,jboxed] eye(nv)]\n    // b        = obj\n    // c        = [-rhs                          ; ubuser[jb]  ; -lbuser     ]\n    // lb       = [constr_type .== '>' ? 0 : -Inf; zeros(nb)   ; zeros(nv)   ]\n    // ub       = [constr_type .== '<' ? 0 : +Inf; Inf*ones(nb); Inf*ones(nv)]\n    // dualized = true\n    // Here nc = num_constr, nv = num_var, nb is the number of boxed variables\n    // and jboxed are their indices. Every variable with a finite upper bound\n    // must have a finite lower bound (this is ensured after scaling). If a\n    // variable j of the input LP is a free variable, then the j-th slack\n    // variable of the model gets a zero upper bound (i.e. it is fixed at zero)\n    // and its objective coefficient is set to zero.\n    void LoadDual();\n\n    // Recursively equilibrates A_ in infinity norm using the algorithm from\n    // [1]. The scaling factors are truncated to powers of 2. Terminates when\n    // the entries of A_ are within the range [0.5,8).\n    // [1] P. A. Knight, D. Ruiz, B. Ucar, \"A symmetry preserving algorithm for\n    //     matrix scaling\", SIAM J. Matrix Anal., 35(3), 2014.\n    void EquilibrateMatrix();\n\n    // Initializes num_dense_cols_ and nz_dense_. We classify the maximum #\n    // columns as \"dense\" which have more than 40 nonzeros and more than 10\n    // times the # nonzeros than any column that is not \"dense\". If this yields\n    // more than 1000 dense columns, then no columns are classified as dense.\n    void FindDenseColumns();\n\n    // Prints the coefficient ranges of input data via\n    // control.hLog(). Must be called after CopyInput() and before\n    // ScaleModel().\n    void PrintCoefficientRange(const Control& control) const;\n\n    // Prints preprocessing operations via control.hLog().\n    void PrintPreprocessingLog(const Control& control) const;\n\n    // Applies the operations from ScaleModel() to a primal-dual point.\n    void ScalePoint(Vector& x, Vector& slack, Vector& y, Vector& z) const;\n    void ScalePoint(Vector& x, Vector& xl, Vector& xu, Vector& slack,\n                    Vector& y, Vector& zl, Vector& zu) const;\n\n    // ScaleBack*() do the reverse operation of ScaleModel().\n    void ScaleBackInteriorSolution(Vector& x, Vector& xl, Vector& xu,\n                                   Vector& slack, Vector& y, Vector& zl,\n                                   Vector& zu) const;\n    void ScaleBackResiduals(Vector& rb, Vector& rc, Vector& rl,\n                            Vector& ru) const;\n    void ScaleBackBasicSolution(Vector& x, Vector& slack, Vector& y,\n                                Vector& z) const;\n    void ScaleBackBasis(std::vector<Int>& cbasis,\n                        std::vector<Int>& vbasis) const;\n\n    // Applies the operations of LoadPrimal() or LoadDual() to a primal-dual\n    // point.\n    void DualizeBasicSolution(const Vector& x_user, const Vector& slack_user,\n                              const Vector& y_user, const Vector& z_user,\n                              Vector& x_solver, Vector& y_solver,\n                              Vector& z_solver) const;\n\n    // Applies the operations of LoadPrimal() or LoadDual() to a primal-dual\n    // point. Currently only implemented for dualized_ == false. Otherwise an\n    // assertion will fail.\n    void DualizeIPMStartingPoint(const Vector& x_user,\n                                 const Vector& xl_user,\n                                 const Vector& xu_user,\n                                 const Vector& slack_user,\n                                 const Vector& y_user,\n                                 const Vector& zl_user,\n                                 const Vector& zu_user,\n                                 Vector& x_solver,\n                                 Vector& xl_solver,\n                                 Vector& xu_solver,\n                                 Vector& y_solver,\n                                 Vector& zl_solver,\n                                 Vector& zu_solver) const;\n\n    // DualizeBack*() do the reverse operations of LoadPrimal() or LoadDual().\n    // Given the solution from the solver, they recover the solution to the\n    // scaled user model.\n    void DualizeBackInteriorSolution(const Vector& x_solver,\n                                     const Vector& xl_solver,\n                                     const Vector& xu_solver,\n                                     const Vector& y_solver,\n                                     const Vector& zl_solver,\n                                     const Vector& zu_solver,\n                                     Vector& x_user,\n                                     Vector& xl_user,\n                                     Vector& xu_user,\n                                     Vector& slack_user,\n                                     Vector& y_user,\n                                     Vector& zl_user,\n                                     Vector& zu_user) const;\n    void DualizeBackBasicSolution(const Vector& x_solver,\n                                  const Vector& y_solver,\n                                  const Vector& z_solver,\n                                  Vector& x_user,\n                                  Vector& slack_user,\n                                  Vector& y_user,\n                                  Vector& z_user) const;\n    void DualizeBackBasis(const std::vector<Int>& basic_status_solver,\n                          std::vector<Int>& cbasis_user,\n                          std::vector<Int>& vbasis_user) const;\n\n    void CorrectScaledBasicSolution(Vector& x, Vector& slack, Vector& y,\n                                    Vector& z,\n                                    const std::vector<Int> cbasis,\n                                    const std::vector<Int> vbasis) const;\n\n    // Performs lhs += alpha*A*rhs or lhs += alpha*A'rhs, where A is the user\n    // matrix after scaling. This matrix is not stored explicitly, but is used\n    // implicitly through AI.\n    // @trans: 't' or 'T' for multiplication with A'.\n    void MultiplyWithScaledMatrix(const Vector& rhs, double alpha, Vector& lhs,\n                                  char trans) const;\n\n    // Computational form model.\n    bool dualized_{false};        // model was dualized in preprocessing?\n    Int num_rows_{0};             // # rows of AI\n    Int num_cols_{0};             // # structural columns of AI\n    Int num_dense_cols_{0};       // # columns classified as dense\n    Int nz_dense_{0};             // minimum # nonzeros in a dense column\n    SparseMatrix AI_;             // matrix AI columnwise\n    SparseMatrix AIt_;            // matrix AI rowwise\n    Vector b_;\n    Vector c_;\n    Vector lb_;\n    Vector ub_;\n    double norm_bounds_{0.0};     // infinity norm of [b;lb;ub]\n    double norm_c_{0.0};          // infinity norm of c\n\n    // User model after scaling. The data members are first initialized by\n    // CopyInput() and the vectors and matrix are then modified by ScaleModel().\n    Int num_constr_{0};           // # constraints\n    Int num_eqconstr_{0};         // # equality constraints\n    Int num_var_{0};              // # variables\n    Int num_free_var_{0};         // # free variables\n    Int num_entries_{0};          // # entries in input matrix\n    std::vector<Int> boxed_vars_; // indices of boxed variables\n    std::vector<char> constr_type_;\n    double norm_obj_{0.0};        // Infnorm(obj) as given by user\n    double norm_rhs_{0.0};        // Infnorm(rhs,lb,ub) as given by user\n    double offset_;\n    Vector scaled_obj_;\n    Vector scaled_rhs_;\n    Vector scaled_lbuser_;\n    Vector scaled_ubuser_;\n    SparseMatrix A_;              // is cleared after preprocessing\n\n    // Data from ScaleModel() that is required by ScaleBack*().\n    std::vector<Int> flipped_vars_;\n    Vector colscale_;\n    Vector rowscale_;\n};\n\n// Returns the maximum violation of lb <= x <= ub.\ndouble PrimalInfeasibility(const Model& model, const Vector& x);\n\n// Returns the maximum violation of the dual feasibility condition\n//   z[j] <= 0 if x[j] > lb[j],\n//   z[j] >= 0 if x[j] < ub[j].\n// Note that dual feasibility implies complementarity, i.e.\n//   x[j] == lb[j] || x[j] == ub[j] || z[j] == 0.\ndouble DualInfeasibility(const Model& model, const Vector& x, const Vector& z);\n\n// Returns the maximum violation of Ax=b.\ndouble PrimalResidual(const Model& model, const Vector& x);\n\n// Returns the maximum violation of A'y+z=c.\ndouble DualResidual(const Model& model, const Vector& y, const Vector& z);\n\n}  // namespace ipx\n\n#endif  // IPX_MODEL_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/multistream.h",
    "content": "#ifndef IPX_MULTISTREAM_H_\n#define IPX_MULTISTREAM_H_\n\n#include <ostream>\n#include <vector>\n\nnamespace ipx {\n\n// Multistream allows redirecting output to multiple std::ostreams. It is used\n// from Control (see control.h) for printing log messages simultaneously to\n// standard output and a logfile.\n\nclass Multistream : public std::ostream {\npublic:\n    Multistream() : std::ostream(nullptr) {\n        std::ostream::rdbuf(&mbuffer_);\n    }\n\n    // adds a new stream to the object\n    void add(std::ostream& os) {\n        os.flush();\n        mbuffer_.add(os.rdbuf());\n    }\n\n    // discards all streams\n    void clear() {\n        mbuffer_.clear();\n    }\n\nprivate:\n    struct multibuffer : public std::streambuf {\n        void add(std::streambuf* b) {\n            buffers.push_back(b);\n        }\n        void clear() {\n            buffers.clear();\n        }\n        int overflow(int c) override {\n            for (std::streambuf* b : buffers)\n                b->sputc(static_cast<char>(c));\n            return c;\n        }\n    private:\n        std::vector<std::streambuf*> buffers;\n    };\n\n    multibuffer mbuffer_;\n};\n\n}  // namespace ipx\n\n#endif  // IPX_MULTISTREAM_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/normal_matrix.h",
    "content": "#ifndef IPX_NORMAL_MATRIX_H_\n#define IPX_NORMAL_MATRIX_H_\n\n#include \"ipm/ipx/linear_operator.h\"\n#include \"ipm/ipx/model.h\"\n\nnamespace ipx {\n\n// NormalMatrix provides matrix-vector operations with the matrix\n//\n//   AI*W*AI',\n//\n// where AI is the m-by-(n+m) matrix defined by the model, and W is a diagonal\n// (weight) matrix defined by the user.\n\nclass NormalMatrix : public LinearOperator {\npublic:\n    // Constructor stores a reference to the model. No data is copied. The model\n    // must be valid as long as the object is used.\n    explicit NormalMatrix(const Model& model);\n\n    // Prepares normal matrix for subsequent calls to Apply(). If W is not NULL,\n    // then W must hold n+m entries. No data is copied. The array must be valid\n    // in each subsequent call to Apply(). If W is NULL, then the first n\n    // entries are assumed 1.0 and the last m entries are assumed 0.0.\n    void Prepare(const double* W);\n\n    // Returns computation time for calls to Apply() since last reset_time().\n    double time() const;\n    void reset_time();\n\nprivate:\n    void _Apply(const Vector& rhs, Vector& lhs, double* rhs_dot_lhs) override;\n\n    const Model& model_;\n    const double* W_{nullptr};\n    bool prepared_{false};\n    Vector work_;            // size n+m workspace (2-pass matvec products only)\n    double time_{0.0};\n};\n\n}  // namespace ipx\n\n#endif  // IPX_NORMAL_MATRIX_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/power_method.h",
    "content": "#ifndef IPX_POWER_METHOD_H_\n#define IPX_POWER_METHOD_H_\n\n#include <cmath>\n#include \"ipm/ipx/ipx_internal.h\"\n#include \"ipm/ipx/utils.h\"\n\nnamespace ipx {\n\n// Power method for estimating the maximum eigenvalue of a linear operator f.\n// @func: function object that is called by func(v,fv) to evaluate fv=f(v).\n// @v: vector of dimension of the linear operator. On return holds an\n//     approximate eigenvector corresponding to the maximum eigenvalue of f.\n// Returns an estimate for the maximum eigenvalue of f.\n\ntemplate <typename F>\ndouble PowerMethod(F func, Vector& v) {\n    const Int maxiter = 100;\n    const double tol = 1e-3;\n    const Int dim = v.size();\n    Vector fv(dim);\n\n    // Construct starting vector and normalize.\n    for (Int i = 0; i < dim; i++)\n        v[i] = 1.0 + 1.0/(i+1);\n    v /= Twonorm(v);\n\n    // Run power method\n    double lambda = 0.0;\n    Int iter = 0;\n    while (iter++ < maxiter) {\n        func(v, fv);\n        double lambda_old = lambda;\n        lambda = Twonorm(fv);\n        v = fv/lambda;\n        if (std::abs(lambda-lambda_old) <= tol*lambda)\n            break;\n    }\n    return lambda;\n}\n\n}  // namespace ipx\n\n#endif // IPX_POWER_METHOD_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/sparse_matrix.h",
    "content": "#ifndef IPX_SPARSE_MATRIX_H_\n#define IPX_SPARSE_MATRIX_H_\n\n#include <vector>\n#include \"ipm/ipx/ipx_internal.h\"\n\nnamespace ipx {\n\n// Sparse matrix in CSC format.\n\nclass SparseMatrix {\npublic:\n    SparseMatrix();\n    SparseMatrix(Int nrow, Int ncol);\n    SparseMatrix(Int nrow, Int ncol, Int min_capacity);\n\n    Int rows() const { return nrow_; }\n    Int cols() const { return colptr_.size()-1; }\n    Int entries() const { return colptr_.back(); }\n\n    // # entries in column j\n    Int entries(Int j) const { return end(j)-begin(j); }\n\n    // Maximum # entries that can be stored in the matrix.\n    Int capacity() const { return rowidx_.size(); }\n\n    // Increases capacity if necessary such that capacity() >= min_capacity.\n    // Matrix remains unchanged, pointers are invalidated.\n    void reserve(Int min_capacity);\n\n    // Changes matrix dimensions. Matrix becomes empty, pointers are\n    // invalidated.\n    void resize(Int nrow, Int ncol, Int min_capacity = 0);\n\n    // Identical to resize(0,0).\n    void clear();\n\n    // Builds matrix from data in compressed column format. The matrix data must\n    // be valid (no duplicates, no out of range indices, no inf/nan values);\n    // this is not checked. The row indices in the input matrix need not be\n    // sorted, but those in the output matrix will be.\n    void LoadFromArrays(Int nrow, Int ncol, const Int* Abegin, const Int* Aend,\n                        const Int* Ai, const double* Ax);\n\n    Int begin(Int j) const { return colptr_[j]; }\n    Int end(Int j) const { return colptr_[j+1]; }\n\n    // Accesses entry at position @pos by value.\n    Int index(Int pos) const { return rowidx_[pos]; }\n    double value(Int pos) const { return values_[pos]; }\n\n    // Accesses entry at position @pos by reference.\n    Int& index(Int pos) { return rowidx_[pos]; }\n    double& value(Int pos) { return values_[pos]; }\n\n    // Accesses underlying arrays.\n    const Int *colptr() const { return colptr_.data(); }\n    const Int *rowidx() const { return rowidx_.data(); }\n    const double *values() const { return values_.data(); }\n    Int *colptr() { return colptr_.data(); }\n    Int *rowidx() { return rowidx_.data(); }\n    double *values() { return values_.data(); }\n\n    // Stores the entries in each column in increasing order of index.\n    void SortIndices();\n\n    // The following methods provide a queue for adding new columns to the\n    // matrix. Entries in the queue are not part of the matrix (so do not\n    // contribute to entries()).\n\n    // Appends an entry to the end of the queue.\n    void push_back(Int i, double x) {\n        rowidx_queue_.push_back(i);\n        values_queue_.push_back(x);\n    }\n\n    // Returns # entries in the queue.\n    Int queue_size() const { return rowidx_queue_.size(); }\n\n    // Accesses entry at position @pos in the queue by value.\n    Int qindex(Int pos) const { return rowidx_queue_[pos]; }\n    double qvalue(Int pos) const { return values_queue_[pos]; }\n\n    // Accesses entry at position @pos in the queue by reference.\n    Int& qindex(Int pos) { return rowidx_queue_[pos]; }\n    double& qvalue(Int pos) { return values_queue_[pos]; }\n\n    // Makes new column from queue. The queue becomes empty and cols()\n    // increases by 1.\n    void add_column();\n\n    // Discards queue.\n    void clear_queue();\n\nprivate:\n    // Returns true if row indices are sorted.\n    bool IsSorted() const;\n\n    Int nrow_;\n    std::vector<Int> colptr_;\n    std::vector<Int> rowidx_;\n    std::vector<double> values_;\n    std::vector<Int> rowidx_queue_;\n    std::vector<double> values_queue_;\n};\n\n// Builds transpose of matrix.\nSparseMatrix Transpose(const SparseMatrix& A);\n\n// Resizes @AT as necessary and fills with the tranpose of A.\nvoid Transpose(const SparseMatrix& A, SparseMatrix& AT);\n\n// Returns a copy of A[:,cols].\nSparseMatrix CopyColumns(const SparseMatrix& A, const std::vector<Int>& cols);\n\n// Permutes rows in place so that row i becomes row perm[i].\nvoid PermuteRows(SparseMatrix& A, const std::vector<Int>& perm);\n\n// Multiplies column j by s.\ninline void ScaleColumn(SparseMatrix& A, Int j, double s) {\n    Int p1 = A.begin(j);\n    Int p2 = A.end(j);\n    for (Int p = p1; p < p2; p++)\n        A.value(p) *= s;\n}\n\n// Removes diagonal entries from A. If @diag is not NULL, then it must be an\n// array of dimension A.cols() that holds the diagonal of A on return. Diagonal\n// entries that are not present in A are set to zero in @diag. Returns the #\n// entries removed from A.\nInt RemoveDiagonal(SparseMatrix& A, double* diag);\n\n// Returns dot(A[:,j], rhs).\ninline double DotColumn(const SparseMatrix& A, Int j, const Vector& rhs) {\n    Int p1 = A.begin(j);\n    Int p2 = A.end(j);\n    double d = 0.0;\n    for (Int p = p1; p < p2; p++)\n        d += rhs[A.index(p)] * A.value(p);\n    return d;\n}\n\n// Updates lhs := lhs + alpha * A[:,j].\ninline void ScatterColumn(const SparseMatrix& A, Int j, double alpha,\n                          Vector& lhs) {\n    Int p1 = A.begin(j);\n    Int p2 = A.end(j);\n    for (Int p = p1; p < p2; p++)\n        lhs[A.index(p)] += alpha * A.value(p);\n}\n\n// Updates lhs := lhs + alpha*A*rhs or lhs := lhs + alpha*A'*rhs.\n// @trans: 't' or 'T' for transposed product.\nvoid MultiplyAdd(const SparseMatrix& A, const Vector& rhs, double alpha,\n                 Vector& lhs, char trans);\n\n// Updates lhs := lhs + A*A'*rhs or lhs := lhs + A*D*D*A'*rhs,\n// where D is diagonal matrix if @D != NULL.\nvoid AddNormalProduct(const SparseMatrix& A, const double* D, const Vector& rhs,\n                      Vector& lhs);\n\n// Triangular solve with sparse matrix.\n// @x: right-hand side on entry, left-hand side on return.\n// @trans: 't' or 'T' for transposed system.\n// @uplo: must have *uplo == 'u' or *uplo == 'U' if A is upper triangular;\n//        otherwise A is lower triangular.\n// @unitdiag: nonzero if A has a unit diagonal that is not stored.\n// Returns the # nonzeros in the solution.\nInt TriangularSolve(const SparseMatrix& A, Vector& x, char trans,\n                    const char* uplo, int unitdiag);\n\n// Solves (L*U) x = x.\n// L unit lower triangular, stored without diagonal.\n// U upper triangular, diagonal element at end of column.\nvoid ForwardSolve(const SparseMatrix& L, const SparseMatrix& U, Vector& x);\n\n// Solves (L*U)' x = x.\n// L unit lower triangular, stored without diagonal.\n// U upper triangular, diagonal element at end of column.\nvoid BackwardSolve(const SparseMatrix& L, const SparseMatrix& U, Vector& x);\n\n// Returns the 1-norm and infinity-norm of A.\ndouble Onenorm(const SparseMatrix& A);\ndouble Infnorm(const SparseMatrix& A);\n\n// Estimates the 1-norm of inverse(A).\n// @A must be square and lower or upper triangular.\n// @uplo: must have *uplo == 'u' or *uplo == 'U' if A is upper triangular;\n//        otherwise A is lower triangular.\n// @unitdiag: nonzero if A has a unit diagonal that is not stored.\ndouble NormestInverse(const SparseMatrix& A, const char* uplo, int unitdiag);\n\n}  // namespace ipx\n\n#endif  // IPX_SPARSE_MATRIX_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/sparse_utils.h",
    "content": "#ifndef IPX_SPARSE_UTILS_H_\n#define IPX_SPARSE_UTILS_H_\n\n#include \"ipm/ipx/ipx_internal.h\"\n\nnamespace ipx {\n\n// Depth-first search in the graph of matrix A.\n//\n// @istart starting node, must be unmarked on entry.\n// @Ap, @Ai pattern of matrix A in CSC format.\n// @colmap The neighbours of node i are the entries in col j = @colmap[i] of A.\n//         If j is negative, node i has no neighbours. @colmap can be NULL, in\n//         which case the identity mapping is assumed.\n// @top, @istack On return @istack[newtop..@top-1] holds the reached nodes that\n//               have previously been unmarked; they are marked now and newtop\n//               is returned.\n// @marked, @marker Node i is \"marked\" iff @marked[i] == @marker.\n// @work workspace of size # rows of A.\n//\n// The code has been copied and adapted from cs_dfs.c, included in the CSPARSE\n// package [1].\n//\n// [1] T. Davis, \"Direct methods for sparse linear systems\" (2006)\n//\nInt DepthFirstSearch(Int istart, const Int* Ap, const Int* Ai,\n                     const Int* colmap, Int top, Int* istack, Int* marked,\n                     Int marker, Int* work);\n\n// Alternating augmenting path for extending a matching for an m-by-n matrix A.\n//\n// @jstart column of matrix A that should be matched.\n// @Ap, @Ai pattern of matrix A in CSC format.\n// @jmatch array of size m.\n//         Row i is matched to column j if @jmatch[i] = j >= 0.\n//         Row i is yet unmatched if @jmatch[i] == -1.\n//         Row i is unmatched and excluded from being matched if jmatch[i] < -1.\n// @cheap array of size n. On the first call, @cheap must hold @Ap[0..n-1].\n//        It must be unchanged between subsequent calls.\n// @marked array of size n. On entry @marked[j] != @jstart for all j.\n//         On return some entries were set to @jstart.\n// @work size m workspace.\n// @work2 size m+1 workspace.\n// @work3 size m+1 workspace.\n//\n// Returns true if the matching was extended.\n//\n// The code has been copied and adapted from cs_augment.c, included in the\n// CSPARSE package [1].\n//\n// [1] T. Davis, \"Direct methods for sparse linear systems\" (2006)\n//\nbool AugmentingPath(Int jstart, const Int* Ap, const Int* Ai, Int* jmatch,\n                    Int* cheap, Int* marked, Int* work, Int* work2, Int* work3);\n\n}  // namespace ipx\n\n#endif // IPX_SPARSE_UTILS_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/splitted_normal_matrix.h",
    "content": "#ifndef IPX_SPLITTED_NORMAL_MATRIX_H_\n#define IPX_SPLITTED_NORMAL_MATRIX_H_\n\n#include <vector>\n#include \"ipm/ipx/basis.h\"\n#include \"ipm/ipx/linear_operator.h\"\n#include \"ipm/ipx/model.h\"\n#include \"ipm/ipx/sparse_matrix.h\"\n\nnamespace ipx {\n\n// SplittedNormalMatrix provides matrix-vector products with\n//\n//   C = inv(B)*AI*AI'*inv(B') = I + inv(B)*N*N'*inv(B'),\n//\n// where AI is the m-by-(n+m) matrix defined by the model and [B N] is the\n// partitioning of AI into basic and nonbasic columns defined by the basis.\n// The columns of B and N are scaled by the interior point scaling factors\n// provided in the call to Prepare().\n//\n// When a variable has status BASIC_FREE, the row and column of C become a unit\n// vector. When a variable has status NONBASIC_FIXED, it is dropped from N.\n\nclass SplittedNormalMatrix : public LinearOperator {\npublic:\n    // Constructor stores a reference to the model. No data is copied. The model\n    // must be valid as long as the object is used.\n    explicit SplittedNormalMatrix(const Model& model);\n\n    // Prepares object for subsequent calls to Apply(). @colscale must hold n+m\n    // scaling factors for the columns of AI. The scaling factors are copied.\n    void Prepare(const Basis& basis, const double* colscale);\n\n    // Returns the column permutation from the LU factorization of the basis\n    // matrix. The permutation was stored in the object by Prepare().\n    const Int* colperm() const;\n\n    // Returns computation times for operations since last call to reset_time().\n    double time_B() const;\n    double time_Bt() const;\n    double time_NNt() const;\n    void reset_time();\n\nprivate:\n    void _Apply(const Vector& rhs, Vector& lhs, double* rhs_dot_lhs) override;\n\n    const Model& model_;\n    SparseMatrix L_;           // lower triangular factor without unit diagonal\n    SparseMatrix U_;           // upper triangular factor with scaled columns\n    SparseMatrix N_;           // N with scaled columns and permuted row indices\n    std::vector<Int> free_positions_; // positions corresponding to free vars\n    std::vector<Int> colperm_;        // column permutation from LU factor\n    std::vector<Int> rowperm_inv_;    // inverse row permutation from LU factor\n    Vector work_;                     // size m workspace\n    bool prepared_{false};            // operator prepared?\n    double time_B_{0.0};              // time solves with B\n    double time_Bt_{0.0};             // time solves with B'\n    double time_NNt_{0.0};            // time matrix-vector products with NN'\n};\n\n}  // namespace ipx\n\n#endif  // IPX_SPLITTED_NORMAL_MATRIX_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/starting_basis.h",
    "content": "#ifndef IPX_STARTING_BASIS_H_\n#define IPX_STARTING_BASIS_H_\n\n#include \"ipm/ipx/basis.h\"\n#include \"ipm/ipx/iterate.h\"\n\nnamespace ipx {\n\n// Constructs a basis with the following properties:\n//\n// If lb[j]=-inf and ub[j]=inf, then the variable becomes either\n// - basic with status BASIC_FREE, or\n// - nonbasic with status NONBASIC_FIXED.                         (1)\n//\n// If lb[j]==ub[j] and j is a slack variable, then it becomes either\n// - basic with status BASIC_FREE, or                             (2)\n// - nonbasic with status NONBASIC_FIXED.\n//\n// If lb[j]==ub[j] and j is not a slack variable, then it becomes\n// - nonbasic with status NONBASIC_FIXED.\n//\n// All other variables get status BASIC or NONBASIC.\n//\n// In case (1) the columns corresponding to free variables are linearly\n// dependent. In case (2) the rows to equality constraints are linearly\n// dependent. In each case the dependent variables are moved to zero without\n// altering the primal or dual residual.\n// TODO: we need to check for primal/dual infeasibility here.\n//\n// The method calls ConstructBasisFromWeights() using the interior point\n// scaling factors as column weights. If a variable gets status BASIC_FREE or\n// NONBASIC_FIXED, then its state in @iterate is changed accordingly to free or\n// fixed. On return info->errflag is nonzero if an error occured.\n//\nvoid StartingBasis(Iterate* iterate, Basis* basis, Info* info);\n\n}  // namespace ipx\n\n#endif  // IPX_STARTING_BASIS_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/symbolic_invert.h",
    "content": "#ifndef IPX_SYMBOLIC_INVERT_H_\n#define IPX_SYMBOLIC_INVERT_H_\n\n#include <vector>\n#include \"ipm/ipx/ipx_internal.h\"\n#include \"ipm/ipx/model.h\"\n\nnamespace ipx {\n\n// Computes the # structural nonzeros per row and column of inverse(B), where\n// B = AI[:,basis] is the m-by-m matrix defined by the model and basis.\n//\n// @basis must have size m and be such that B is structurally nonsingular.\n//        (Otherwise an assertion will fail.)\n// @rowcounts must either be NULL or an integer array of size m.\n//            If not NULL, then on return rowcounts[p], 0 <= p < m, holds the\n//            number of nonzeros in row p of inverse(B). Notice that row p of\n//            inverse(B) corresponds to column p of B.\n// @colcounts must either be NULL or an integer array of size m.\n//            If not NULL, then on return colcounts[i], 0 <= i < m, holds the\n//            number of nonzeros in column i of inverse(B). Notice that column\n//            i of inverse(B) corresponds to row p of B.\n//\nvoid SymbolicInvert(const Model& model, const std::vector<Int>& basis,\n                    Int* rowcounts, Int* colcounts);\n\n}  // namespace ipx\n\n#endif  // IPX_SYMBOLIC_INVERT_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/timer.h",
    "content": "#ifndef IPX_TIMER_H_\n#define IPX_TIMER_H_\n\n#include <chrono>\n\nnamespace ipx {\n\nclass Timer {\npublic:\n    Timer();\n    double Elapsed() const;\n    void Reset();\n\nprivate:\n    typedef std::chrono::time_point<std::chrono::high_resolution_clock>\n        TimePoint;\n    static TimePoint tic();\n    static double toc(TimePoint start);\n    TimePoint t0_;\n};\n\n}  // namespace ipx\n\n#endif  // IPX_TIMER_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/ipm/ipx/utils.h",
    "content": "#ifndef IPX_UTILS_H_\n#define IPX_UTILS_H_\n\n#include <vector>\n#include \"ipm/ipx/ipx_internal.h\"\n\nnamespace ipx {\n\nbool AllFinite(const Vector& x);\n\ndouble Onenorm(const Vector& x);\ndouble Twonorm(const Vector& x);\ndouble Infnorm(const Vector& x);\ndouble Dot(const Vector& x, const Vector& y);\n\n// Returns the index of an entry of maximum absolute value.\nInt FindMaxAbs(const Vector& x);\n\n// lhs[permuted_index] = rhs\nvoid Permute(const std::vector<Int>& permuted_index, const Vector& rhs,\n             Vector& lhs);\n\n// lhs = rhs[permuted_index]\nvoid PermuteBack(const std::vector<Int>& permuted_index, const Vector& rhs,\n                 Vector& lhs);\n\n// Returns the inverse permutation to @perm.\nstd::vector<Int> InversePerm(const std::vector<Int>& perm);\n\n// Returns the permutation that puts values[0..m-1] in increasing (if reverse is\n// false) or in decreasing (if reverse is true) order. If values==NULL, returns\n// the identity permutation.\nstd::vector<Int> Sortperm(Int m, const double* values, bool reverse);\n\n}  // namespace ipx\n\n#endif  // IPX_UTILS_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HConst.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HConst.h\n * @brief Constants for HiGHS\n */\n#ifndef LP_DATA_HCONST_H_\n#define LP_DATA_HCONST_H_\n\n#include <cmath>\n#include <limits>\n#include <string>\n\n#include \"util/HighsInt.h\"\n\nconst std::string kHighsCopyrightStatement =\n    \"Copyright (c) 2025 HiGHS under MIT licence terms\";\n\nconst size_t kHighsSize_tInf = std::numeric_limits<size_t>::max();\nconst HighsInt kHighsIInf = std::numeric_limits<HighsInt>::max();\nconst HighsInt kHighsIInf32 = std::numeric_limits<int>::max();\nconst double kHighsInf = std::numeric_limits<double>::infinity();\nconst double kHighsUndefined = kHighsInf;\nconst double kHighsTiny = 1e-14;\nconst double kHighsMacheps = std::ldexp(1, -52);\nconst double kHighsZero = 1e-50;\nconst std::string kHighsOffString = \"off\";\nconst std::string kHighsChooseString = \"choose\";\nconst std::string kHighsOnString = \"on\";\nconst HighsInt kHighsMaxStringLength = 512;\nconst HighsInt kSimplexConcurrencyLimit = 8;\nconst double kRunningAverageMultiplier = 0.05;\n\nconst double kExcessivelySmallObjectiveCoefficient = 1e-4;\nconst double kExcessivelyLargeObjectiveCoefficient = 1e6;\nconst double kExcessivelySmallBoundValue = 1e-4;\nconst double kExcessivelyLargeBoundValue = 1e6;\n\nconst HighsInt kNoThreadInstance = -1;\nconst bool kAllowDeveloperAssert = false;\nconst bool kExtendInvertWhenAddingRows = false;\n\nenum class HighsLogType { kInfo = 1, kDetailed, kVerbose, kWarning, kError };\n\nenum SimplexScaleStrategy {\n  kSimplexScaleStrategyMin = 0,\n  kSimplexScaleStrategyOff = kSimplexScaleStrategyMin,  // 0\n  kSimplexScaleStrategyChoose,                          // 1\n  kSimplexScaleStrategyEquilibration,                   // 2\n  kSimplexScaleStrategyForcedEquilibration,             // 3\n  kSimplexScaleStrategyMaxValue,                        // 4\n  kSimplexScaleStrategyMaxValue015 = kSimplexScaleStrategyMaxValue,\n  kSimplexScaleStrategyMaxValue0157 = kSimplexScaleStrategyMaxValue,\n  kSimplexScaleStrategyMax = kSimplexScaleStrategyMaxValue\n};\n\nenum HighsDebugLevel {\n  kHighsDebugLevelNone = 0,\n  kHighsDebugLevelCheap,\n  kHighsDebugLevelCostly,\n  kHighsDebugLevelExpensive,\n  kHighsDebugLevelMin = kHighsDebugLevelNone,\n  kHighsDebugLevelMax = kHighsDebugLevelExpensive\n};\n\nenum class HighsDebugStatus {\n  kNotChecked = -1,\n  kOk,\n  kSmallError,\n  kWarning,\n  kLargeError,\n  kError,\n  kExcessiveError,\n  kLogicalError,\n};\n\nenum HighsAnalysisLevel {\n  kHighsAnalysisLevelNone = 0,\n  kHighsAnalysisLevelModelData = 1,\n  kHighsAnalysisLevelSolverSummaryData = 2,\n  kHighsAnalysisLevelSolverRuntimeData = 4,\n  kHighsAnalysisLevelSolverTime = 8,\n  kHighsAnalysisLevelNlaData = 16,\n  kHighsAnalysisLevelNlaTime = 32,\n  kHighsAnalysisLevelMipData = 64,\n  kHighsAnalysisLevelMipTime = 128,\n  kHighsAnalysisLevelMin = kHighsAnalysisLevelNone,\n  kHighsAnalysisLevelMax =\n      kHighsAnalysisLevelModelData + kHighsAnalysisLevelSolverSummaryData +\n      kHighsAnalysisLevelSolverRuntimeData + kHighsAnalysisLevelSolverTime +\n      kHighsAnalysisLevelNlaData + kHighsAnalysisLevelNlaTime +\n      kHighsAnalysisLevelMipData + kHighsAnalysisLevelMipTime\n};\n\nenum class HighsVarType : uint8_t {\n  kContinuous = 0,\n  kInteger = 1,\n  kSemiContinuous = 2,\n  kSemiInteger = 3,\n  kImplicitInteger = 4,\n};\n\nenum class HighsOptionType { kBool = 0, kInt, kDouble, kString };\n\nenum class HighsInfoType { kInt64 = -1, kInt = 1, kDouble };\n\nenum OptionOffChooseOn {\n  kHighsOptionOff = -1,\n  kHighsOptionChoose,\n  kHighsOptionOn\n};\n\nenum IpxDualizeStrategy {\n  kIpxDualizeStrategyOff = kHighsOptionOff,\n  kIpxDualizeStrategyChoose = kHighsOptionChoose,\n  kIpxDualizeStrategyOn = kHighsOptionOn,\n  kIpxDualizeStrategyLukas,\n  kIpxDualizeStrategyFilippo,\n  kIpxDualizeStrategyMin = kIpxDualizeStrategyOff,\n  kIpxDualizeStrategyMax = kIpxDualizeStrategyFilippo,\n};\n\n/** SCIP/HiGHS Objective sense */\nenum class ObjSense { kMinimize = 1, kMaximize = -1 };\n\nenum class MatrixFormat { kColwise = 1, kRowwise, kRowwisePartitioned };\n\nenum class HessianFormat { kTriangular = 1, kSquare };\n\nenum SolutionStatus {\n  kSolutionStatusNone = 0,\n  kSolutionStatusInfeasible,\n  kSolutionStatusFeasible,\n  kSolutionStatusMin = kSolutionStatusNone,\n  kSolutionStatusMax = kSolutionStatusFeasible\n};\n\nenum BasisValidity {\n  kBasisValidityInvalid = 0,\n  kBasisValidityValid,\n  kBasisValidityMin = kBasisValidityInvalid,\n  kBasisValidityMax = kBasisValidityValid\n};\n\nconst std::string kHighsBasisFileV1 = \"v1\";  // Deprecated\nconst std::string kHighsBasisFileV2 = \"v2\";\n\nenum SolutionStyle {\n  kSolutionStyleOldRaw = -1,\n  kSolutionStyleRaw = 0,\n  kSolutionStylePretty,        // 1;\n  kSolutionStyleGlpsolRaw,     // 2;\n  kSolutionStyleGlpsolPretty,  // 3;\n  kSolutionStyleSparse,        // 4;\n  kSolutionStyleMin = kSolutionStyleOldRaw,\n  kSolutionStyleMax = kSolutionStyleSparse\n};\n\nenum GlpsolCostRowLocation {\n  kGlpsolCostRowLocationLast = -2,\n  kGlpsolCostRowLocationNone,         // -1\n  kGlpsolCostRowLocationNoneIfEmpty,  // 0\n  kGlpsolCostRowLocationMin = kGlpsolCostRowLocationLast\n};\n\nconst std::string kHighsFilenameDefault = \"\";\nconst std::string kHighsMinimalColNamePrefix = \"c\";\nconst std::string kHighsMinimalrowNamePrefix = \"r\";\nconst std::string kHighsUniqueColNamePrefix = \"c_ekk\";\nconst std::string kHighsUniquerowNamePrefix = \"r_ekk\";\n\nenum class HighsPresolveStatus {\n  kNotPresolved = -1,\n  kNotReduced,\n  kInfeasible,\n  kUnboundedOrInfeasible,\n  kReduced,\n  kReducedToEmpty,\n  kTimeout,\n  kNullError,     // V2.0: Delete since it's not used!\n  kOptionsError,  // V2.0: Delete since it's not used!\n  kNotSet,\n  kOutOfMemory,  // V2.0: Move above kNotSet\n};\n\nenum class HighsPostsolveStatus {  // V2.0: Delete if not used!\n  kNotPresolved = -1,\n  kNoPrimalSolutionError,\n  kSolutionRecovered,\n  kBasisError\n};\n\nenum class HighsModelStatus {\n  // NB Add new status values to the end so that int cast of status\n  // values is unchanged, since enums are not preserved in some\n  // interfaces\n  kNotset = 0,\n  kLoadError,  // V2.0: Delete since it's not used!\n  kModelError,\n  kPresolveError,  // V2.0: Delete since it's not used!\n  kSolveError,\n  kPostsolveError,  // V2.0: Delete if not used! Add to documentation if used\n  kModelEmpty,\n  kOptimal,\n  kInfeasible,\n  kUnboundedOrInfeasible,\n  kUnbounded,\n  kObjectiveBound,\n  kObjectiveTarget,\n  kTimeLimit,\n  kIterationLimit,\n  // V2.0: put kUnknown after kSolutionLimit and kInterrupt - and then\n  // modify kMax and highs_c_api.h, highs_csharp_api.cs,\n  // highspy/highs_bindings.cpp\n  kUnknown,\n  kSolutionLimit,\n  kInterrupt,\n  kMemoryLimit,\n  kHighsInterrupt,\n  kMin = kNotset,\n  kMax = kHighsInterrupt\n};\n\nenum HighsCallbackType : int {\n  kCallbackMin = 0,\n  kCallbackLogging = kCallbackMin,    // 0\n  kCallbackSimplexInterrupt,          // 1\n  kCallbackIpmInterrupt,              // 2\n  kCallbackMipSolution,               // 3\n  kCallbackMipImprovingSolution,      // 4\n  kCallbackMipLogging,                // 5\n  kCallbackMipInterrupt,              // 6\n  kCallbackMipGetCutPool,             // 7\n  kCallbackMipDefineLazyConstraints,  // 8\n  kCallbackMipUserSolution,           // 9\n  kCallbackMax = kCallbackMipUserSolution,\n  kNumCallbackType\n};\n\n/** SCIP/CPLEX-like HiGHS basis status for columns and rows. */\nenum class HighsBasisStatus : uint8_t {\n  kLower =\n      0,   // (slack) variable is at its lower bound [including fixed variables]\n  kBasic,  // (slack) variable is basic\n  kUpper,  // (slack) variable is at its upper bound\n  kZero,   // free variable is nonbasic and set to zero\n  kNonbasic  // nonbasic with no specific bound information - useful for users\n             // and postsolve\n};\n\n// Types of LP presolve rules\nenum PresolveRuleType : int {\n  kPresolveRuleIllegal = -1,\n  kPresolveRuleMin = 0,\n  kPresolveRuleEmptyRow = kPresolveRuleMin,\n  kPresolveRuleSingletonRow,\n  kPresolveRuleRedundantRow,\n  kPresolveRuleEmptyCol,\n  kPresolveRuleFixedCol,\n  kPresolveRuleDominatedCol,\n  // The remaining rules can be switched off\n  kPresolveRuleFirstAllowOff,\n  kPresolveRuleForcingRow = kPresolveRuleFirstAllowOff,\n  kPresolveRuleForcingCol,\n  kPresolveRuleFreeColSubstitution,\n  kPresolveRuleDoubletonEquation,\n  kPresolveRuleDependentEquations,\n  kPresolveRuleDependentFreeCols,\n  kPresolveRuleAggregator,\n  kPresolveRuleParallelRowsAndCols,\n  kPresolveRuleSparsify,\n  kPresolveRuleProbing,\n  kPresolveRuleMax = kPresolveRuleProbing,\n  kPresolveRuleLastAllowOff = kPresolveRuleMax,\n  kPresolveRuleCount\n};\n\nenum IisStrategy : int {\n  kIisStrategyMin = 0,\n  kIisStrategyLight = kIisStrategyMin,  // 0\n  kIisStrategyFromLpRowPriority,        // 1\n  kIisStrategyFromLpColPriority,        // 2\n  //  kIisStrategyFromRayRowPriority,                     // 3\n  //  kIisStrategyFromRayColPriority,                     // 4\n  kIisStrategyMax = kIisStrategyFromLpColPriority\n};\n\nenum IisStatus {\n  kIisStatusMin = 0,\n  kIisStatusInConflict = kIisStatusMin,  // 0\n  kIisStatusNotInConflict,               // 1\n  kIisStatusMaybeInConflict,             // 2\n  kIisStatusMax = kIisStatusMaybeInConflict\n};\n\nenum SubSolverIndex : int {\n  kSubSolverMip = 0,\n  kSubSolverSimplexBasis,\n  kSubSolverSimplexNoBasis,\n  kSubSolverHipo,\n  kSubSolverIpx,\n  kSubSolverHipoAc,\n  kSubSolverIpxAc,\n  kSubSolverPdlp,\n  kSubSolverQpAsm,\n  kSubSolverSubMip,\n  kSubSolverCount\n};\n\n// Default KKT tolerance\nconst double kDefaultKktTolerance = 1e-7;\n\n// Default QP Hessian regularization value\nconst double kHessianRegularizationValue = 1e-7;\n\n// Default and max allowed power-of-two matrix scale factor\nconst HighsInt kDefaultAllowedMatrixPow2Scale = 20;\nconst HighsInt kMaxAllowedMatrixPow2Scale = 30;\n\n// Illegal values of num/max/sum infeasibility - used to indicate that true\n// values aren't known\nconst double kHighsIllegalInfeasibilityMeasure = kHighsInf;\nconst HighsInt kHighsIllegalInfeasibilityCount = -1;\n\n// Illegal values of num/max/sum residual - used to indicate that true\n// values aren't known\nconst double kHighsIllegalResidualMeasure = kHighsInf;\nconst HighsInt kHighsIllegalResidualCount = -1;\n\n// Illegal values for HighsError - used to indicate that true\n// values aren't known\nconst double kHighsIllegalErrorValue = kHighsInf;\nconst HighsInt kHighsIllegalErrorIndex = -1;\n\n// Illegal values for complementarity violations used to indicate that true\n// values aren't known\nconst double kHighsIllegalComplementarityViolation = kHighsInf;\nconst HighsInt kHighsIllegalComplementarityCount = -1;\n\n// Maximum upper bound on semi-variables\nconst double kMaxSemiVariableUpper = 1e5;\n\n// Limit on primal values being realistic\nconst double kExcessivePrimalValue = 1e25;\n\n// Hash marker for duplicates\nconst HighsInt kHashIsDuplicate = -1;\n\n// Tolerance values for highsDoubleToString\nconst double kModelValueToStringTolerance = 1e-15;\nconst double kRangingValueToStringTolerance = 1e-13;\nconst double kHighsSolutionValueToStringTolerance = 1e-13;\nconst double kGlpsolSolutionValueToStringTolerance = 1e-12;\n\n// Termination link in linked lists\nconst HighsInt kNoLink = -1;\n\nconst int8_t kPivotIllegal = -1;\nconst int8_t kPivotLogical = 0;\nconst int8_t kPivotUnit = 1;\nconst int8_t kPivotRowSingleton = 2;\nconst int8_t kPivotColSingleton = 3;\nconst int8_t kPivotMarkowitz = 4;\n#endif /* LP_DATA_HCONST_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HStruct.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HStruct.h\n * @brief Structs for HiGHS\n */\n#ifndef LP_DATA_HSTRUCT_H_\n#define LP_DATA_HSTRUCT_H_\n\n#include <unordered_map>\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n\nstruct HighsFiles {\n  bool empty = true;\n  std::string read_solution_file = \"\";\n  std::string read_basis_file = \"\";\n  std::string write_model_file = \"\";\n  std::string write_iis_model_file = \"\";\n  std::string write_solution_file = \"\";\n  std::string write_basis_file = \"\";\n  void clear();\n};\n\nstruct HighsSolution {\n  bool value_valid = false;\n  bool dual_valid = false;\n  std::vector<double> col_value;\n  std::vector<double> col_dual;\n  std::vector<double> row_value;\n  std::vector<double> row_dual;\n  bool hasUndefined() const;\n  void invalidate();\n  void clear();\n  void print(const std::string& prefix = \"\",\n             const std::string& message = \"\") const;\n};\n\nstruct HighsObjectiveSolution {\n  double objective;\n  std::vector<double> col_value;\n  void clear();\n};\n\nstruct RefactorInfo {\n  bool use = false;\n  std::vector<HighsInt> pivot_row;\n  std::vector<HighsInt> pivot_var;\n  std::vector<int8_t> pivot_type;\n  double build_synthetic_tick;\n  void clear();\n};\n\n// Unused, but retained since there is a const reference to this in a\n// deprecated method\nstruct HotStart {\n  bool valid = false;\n  RefactorInfo refactor_info;\n  std::vector<int8_t> nonbasicMove;\n};\n\nstruct HighsBasis {\n  // Logical flags for a HiGHS basis:\n  //\n  // valid: has been factored by HiGHS\n  //\n  // alien: a basis that's been set externally, so cannot be assumed\n  // to even have the right number of basic and nonbasic variables\n  //\n  // useful: a basis that may be useful\n  //\n  // Need useful since, by default, a basis is alien but not useful\n  bool valid = false;\n  bool alien = true;\n  bool useful = false;\n  bool was_alien = true;\n  HighsInt debug_id = -1;\n  HighsInt debug_update_count = -1;\n  std::string debug_origin_name = \"None\";\n  std::vector<HighsBasisStatus> col_status;\n  std::vector<HighsBasisStatus> row_status;\n  void print(const std::string& prefix = \"\",\n             const std::string& message = \"\") const;\n  void printScalars(const std::string& prefix = \"\",\n                    const std::string& message = \"\") const;\n  void invalidate();\n  void clear();\n};\n\nstruct HighsScale {\n  HighsInt strategy;\n  bool has_scaling;\n  HighsInt num_col;\n  HighsInt num_row;\n  double cost;\n  std::vector<double> col;\n  std::vector<double> row;\n};\n\nstruct HighsLpMods {\n  // Semi-variables with zero lower bound that are treated as non-semi\n  std::vector<HighsInt> save_non_semi_variable_index;\n\n  // Semi-variables with inconsistent bounds that are fixed at zero\n  std::vector<HighsInt> save_inconsistent_semi_variable_index;\n  std::vector<double> save_inconsistent_semi_variable_lower_bound_value;\n  std::vector<double> save_inconsistent_semi_variable_upper_bound_value;\n  std::vector<HighsVarType> save_inconsistent_semi_variable_type;\n\n  // Semi-variables whose lower bound is ignored when solving the\n  // relaxation\n  std::vector<HighsInt> save_relaxed_semi_variable_lower_bound_index;\n  std::vector<double> save_relaxed_semi_variable_lower_bound_value;\n\n  // Semi-variables whose upper bound is too large to be used as a\n  // big-M when converting them to an integer variables plus an\n  // integer/continuous variables as appropriate\n  std::vector<HighsInt> save_tightened_semi_variable_upper_bound_index;\n  std::vector<double> save_tightened_semi_variable_upper_bound_value;\n\n  // Variables with infinite costs that are fixed during solve\n  std::vector<HighsInt> save_inf_cost_variable_index;\n  std::vector<double> save_inf_cost_variable_cost;\n  std::vector<double> save_inf_cost_variable_lower;\n  std::vector<double> save_inf_cost_variable_upper;\n\n  void clear();\n  bool isClear();\n};\n\nstruct HighsNameHash {\n  std::unordered_map<std::string, int> name2index;\n  void form(const std::vector<std::string>& name);\n  bool hasDuplicate(const std::vector<std::string>& name);\n  void update(int index, const std::string& old_name,\n              const std::string& new_name);\n  void clear();\n};\n\nstruct HighsPresolveRuleLog {\n  HighsInt call;\n  HighsInt col_removed;\n  HighsInt row_removed;\n};\n\nstruct HighsPresolveLog {\n  std::vector<HighsPresolveRuleLog> rule;\n  void clear();\n};\n\nstruct HighsIllConditioningRecord {\n  HighsInt index;\n  double multiplier;\n};\n\nstruct HighsIllConditioning {\n  std::vector<HighsIllConditioningRecord> record;\n  void clear();\n};\n\nstruct HighsLinearObjective {\n  double weight = 0;\n  double offset = 0;\n  std::vector<double> coefficients;\n  double abs_tolerance = -1;\n  double rel_tolerance = -1;\n  HighsInt priority = 0;\n  void clear();\n};\n\nstruct HighsSubSolverCallTime {\n  std::vector<std::string> name;\n  std::vector<HighsInt> num_call;\n  std::vector<double> run_time;\n  void initialise();\n  void add(const HighsSubSolverCallTime& sub_solver_call_time,\n           const bool analytic_centre = false);\n};\n\nstruct HighsSimplexStats {\n  bool valid;\n  HighsInt iteration_count;\n  HighsInt num_invert;\n  HighsInt last_invert_num_el;\n  HighsInt last_factored_basis_num_el;\n  double col_aq_density;\n  double row_ep_density;\n  double row_ap_density;\n  double row_DSE_density;\n  void report(FILE* file, const std::string message = \"\") const;\n  void initialise(const HighsInt iteration_count_ = 0);\n};\n\nstruct HighsUserScaleData {\n  HighsInt user_objective_scale;\n  HighsInt user_bound_scale;\n  double infinite_cost;\n  double infinite_bound;\n  double small_matrix_value;\n  double large_matrix_value;\n  HighsInt num_infinite_costs;\n  HighsInt num_infinite_hessian_values;\n  HighsInt num_infinite_col_bounds;\n  HighsInt num_infinite_row_bounds;\n  HighsInt num_small_matrix_values;\n  HighsInt num_large_matrix_values;\n  HighsInt suggested_user_objective_scale;\n  HighsInt suggested_user_bound_scale;\n  bool applied;\n  void initialise(const HighsInt& user_objective_scale_,\n                  const HighsInt& user_bound_scale_,\n                  const double& infinite_cost_, const double& infinite_bound_,\n                  const double& small_matrix_value_,\n                  const double& large_matrix_value_);\n  bool scaleError(std::string& message) const;\n  bool scaleWarning(std::string& message) const;\n};\n\n#endif /* LP_DATA_HSTRUCT_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsAnalysis.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsAnalysis.h\n * @brief\n */\n#ifndef LP_DATA_HIGHS_ANALYSIS_H_\n#define LP_DATA_HIGHS_ANALYSIS_H_\n\n#include <vector>\n\n#include \"HConfig.h\"\n#include \"util/HighsTimer.h\"\n\nstruct HighsTimerClock {\n  HighsTimer* timer_pointer_;\n  std::vector<HighsInt> clock_;\n};\n#endif /* LP_DATA_HIGHS_ANALYSIS_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsCallback.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsCallback.h\n * @brief\n */\n#ifndef LP_DATA_HIGHSCALLBACK_H_\n#define LP_DATA_HIGHSCALLBACK_H_\n\n#include <functional>\n\n// forward declaration to avoid circular dependency\nenum class HighsStatus;\nclass Highs;\n\n#include \"lp_data/HStruct.h\"\n#include \"lp_data/HighsCallbackStruct.h\"\n\nenum ExternalMipSolutionQueryOrigin {\n  kExternalMipSolutionQueryOriginAfterSetup = 0,\n  kExternalMipSolutionQueryOriginBeforeDive,\n  kExternalMipSolutionQueryOriginEvaluateRootNode0,\n  kExternalMipSolutionQueryOriginEvaluateRootNode1,\n  kExternalMipSolutionQueryOriginEvaluateRootNode2,\n  kExternalMipSolutionQueryOriginEvaluateRootNode3,\n  kExternalMipSolutionQueryOriginEvaluateRootNode4\n};\n\n/**\n * Struct to handle callback output data\n */\nstruct HighsCallbackOutput {\n  Highs* highs = nullptr;\n  HighsLogType log_type;\n  double running_time;\n  HighsInt simplex_iteration_count;\n  HighsInt ipm_iteration_count;\n  HighsInt pdlp_iteration_count;\n  double objective_function_value;\n  int64_t mip_node_count;\n  int64_t mip_total_lp_iterations;\n  double mip_primal_bound;\n  double mip_dual_bound;\n  double mip_gap;\n  std::vector<double> mip_solution;\n  HighsInt cutpool_num_col;\n  HighsInt cutpool_num_cut;\n  std::vector<HighsInt> cutpool_start;\n  std::vector<HighsInt> cutpool_index;\n  std::vector<double> cutpool_value;\n  std::vector<double> cutpool_lower;\n  std::vector<double> cutpool_upper;\n  ExternalMipSolutionQueryOrigin external_solution_query_origin;\n\n  operator HighsCallbackDataOut() const;\n};\n\nstruct HighsCallbackInput {\n  Highs* highs = nullptr;\n  bool user_interrupt = false;\n  bool user_has_solution = false;\n  std::vector<double> user_solution;\n\n  HighsStatus setSolution(HighsInt num_entries, const double* value);\n\n  HighsStatus setSolution(HighsInt num_entries, const HighsInt* index,\n                          const double* value);\n\n  HighsStatus repairSolution();\n\n  operator HighsCallbackDataIn() const;\n  HighsCallbackInput operator=(const HighsCallbackDataIn& data_in);\n};\n\nusing HighsCallbackFunctionType =\n    std::function<void(int, const std::string&, const HighsCallbackOutput*,\n                       HighsCallbackInput*, void*)>;\n\nstruct HighsCallback {\n  HighsCallback(Highs* highs) : highs(highs) {\n    data_out.highs = highs;\n    data_in.highs = highs;\n    clear();\n  }\n\n  // Function pointers cannot be used for Pybind11, so use std::function\n  HighsCallbackFunctionType user_callback = nullptr;\n  HighsCCallbackType c_callback = nullptr;\n  void* user_callback_data = nullptr;\n  Highs* highs = nullptr;\n  std::vector<bool> active;\n  HighsCallbackOutput data_out;\n  HighsCallbackInput data_in;\n  bool callbackActive(const int callback_type);\n  bool callbackAction(const int callback_type, std::string message = \"\");\n  void clearHighsCallbackOutput();\n  void clearHighsCallbackInput();\n  void clear();\n};\n#endif /* LP_DATA_HIGHSCALLBACK_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsCallbackStruct.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsCallbackStruct.h\n * @brief\n */\n#ifndef LP_DATA_HIGHSCALLBACKSTRUCT_H_\n#define LP_DATA_HIGHSCALLBACKSTRUCT_H_\n\n#include \"util/HighsInt.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n * Struct to handle callback output data\n *\n */\ntypedef struct {\n  void* cbdata;  // cast of HighsCallbackOutput\n  int log_type;  // cast of HighsLogType\n  double running_time;\n  HighsInt simplex_iteration_count;\n  HighsInt ipm_iteration_count;\n  HighsInt pdlp_iteration_count;\n  double objective_function_value;\n  int64_t mip_node_count;\n  int64_t mip_total_lp_iterations;\n  double mip_primal_bound;\n  double mip_dual_bound;\n  double mip_gap;\n  double* mip_solution;\n  HighsInt mip_solution_size;\n  HighsInt cutpool_num_col;\n  HighsInt cutpool_num_cut;\n  HighsInt cutpool_num_nz;\n  HighsInt* cutpool_start;\n  HighsInt* cutpool_index;\n  double* cutpool_value;\n  double* cutpool_lower;\n  double* cutpool_upper;\n  HighsInt external_solution_query_origin;\n} HighsCallbackDataOut;\n\n// Some external packages (e.g., jump) currently assume that the first 2 fields\n// of this struct are interrupt and solution. Rearranging the struct may be a\n// breaking change.\ntypedef struct {\n  int user_interrupt;\n  double* user_solution;\n  void* cbdata;  // cast of HighsCallbackInput (for internal use)\n  int user_has_solution;\n  HighsInt user_solution_size;\n} HighsCallbackDataIn;\n\n// Additional callback handling\ntypedef void (*HighsCCallbackType)(int, const char*,\n                                   const HighsCallbackDataOut*,\n                                   HighsCallbackDataIn*, void*);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* LP_DATA_HIGHSCALLBACKSTRUCT_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsDebug.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsDebug.h\n * @brief\n */\n#ifndef SIMPLEX_HIGHSDEBUG_H_\n#define SIMPLEX_HIGHSDEBUG_H_\n\n#include <string>\n#include <vector>\n\n#include \"io/HighsIO.h\"\n#include \"lp_data/HConst.h\"\n#include \"lp_data/HighsStatus.h\"\n\n// #include \"lp_data/HighsOptions.h\"\n\nHighsStatus debugDebugToHighsStatus(const HighsDebugStatus debug_status);\n\nHighsDebugStatus debugWorseStatus(const HighsDebugStatus status0,\n                                  const HighsDebugStatus status1);\n\nbool debugVectorRightSize(const std::vector<double> v,\n                          const HighsInt right_size);\n\nbool debugVectorRightSize(const std::vector<HighsInt> v,\n                          const HighsInt right_size);\n\n#endif  // SIMPLEX_HIGHSDEBUG_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsIis.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsIis.h\n * @brief Class-independent utilities for HiGHS\n */\n#ifndef LP_DATA_HIGHSIIS_H_\n#define LP_DATA_HIGHSIIS_H_\n\n#include \"model/HighsModel.h\"\n\nconst bool kIisDevReport = false;\n\nenum IisBoundStatus {\n  kIisBoundStatusDropped = -1,\n  kIisBoundStatusNull,   // 0\n  kIisBoundStatusFree,   // 1\n  kIisBoundStatusLower,  // 2\n  kIisBoundStatusUpper,  // 3\n  kIisBoundStatusBoxed   // 4\n};\n\nstruct HighsIisInfo {\n  double simplex_time = 0;\n  HighsInt simplex_iterations = 0;\n};\n\nclass HighsIis {\n public:\n  HighsIis() {}\n\n  void invalidate();\n  std::string iisBoundStatusToString(HighsInt bound_status) const;\n  void report(const std::string message, const HighsLp& lp) const;\n  void addCol(const HighsInt col, const HighsInt status = kIisBoundStatusNull);\n  void addRow(const HighsInt row, const HighsInt status = kIisBoundStatusNull);\n  void removeCol(const HighsInt col);\n  void removeRow(const HighsInt row);\n  HighsStatus getData(const HighsLp& lp, const HighsOptions& options,\n                      const HighsBasis& basis,\n                      const std::vector<HighsInt>& infeasible_row);\n  void getLp(const HighsLp& lp);\n  void getStatus(const HighsLp& lp);\n\n  HighsStatus compute(const HighsLp& lp, const HighsOptions& options,\n                      const HighsBasis* basis = nullptr);\n\n  bool trivial(const HighsLp& lp, const HighsOptions& options);\n  bool rowValueBounds(const HighsLp& lp, const HighsOptions& options);\n\n  bool lpDataOk(const HighsLp& lp, const HighsOptions& options) const;\n  bool lpOk(const HighsOptions& options) const;\n\n  // Data members\n  bool valid_ = false;\n  HighsInt strategy_ = kIisStrategyMin;\n  std::vector<HighsInt> col_index_;\n  std::vector<HighsInt> row_index_;\n  std::vector<HighsInt> col_bound_;\n  std::vector<HighsInt> row_bound_;\n  std::vector<HighsInt> col_status_;\n  std::vector<HighsInt> row_status_;\n  std::vector<HighsIisInfo> info_;\n  HighsModel model_;\n};\n\n#endif  // LP_DATA_HIGHSIIS_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsInfo.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsInfo.h\n * @brief\n */\n#ifndef LP_DATA_HIGHS_INFO_H_\n#define LP_DATA_HIGHS_INFO_H_\n\n#include <cstring>  // For strchr\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n#include \"lp_data/HighsStatus.h\"\n\nclass HighsOptions;\n\nenum class InfoStatus { kOk = 0, kUnknownInfo, kIllegalValue, kUnavailable };\n\nclass InfoRecord {\n public:\n  HighsInfoType type;\n  std::string name;\n  std::string description;\n  bool advanced;\n\n  InfoRecord(HighsInfoType Xtype, std::string Xname, std::string Xdescription,\n             bool Xadvanced) {\n    this->type = Xtype;\n    this->name = Xname;\n    this->description = Xdescription;\n    this->advanced = Xadvanced;\n  }\n\n  virtual ~InfoRecord() {}\n};\n\nclass InfoRecordInt64 : public InfoRecord {\n public:\n  int64_t* value;\n  int64_t default_value;\n  InfoRecordInt64(std::string Xname, std::string Xdescription, bool Xadvanced,\n                  int64_t* Xvalue_pointer, int64_t Xdefault_value)\n      : InfoRecord(HighsInfoType::kInt64, Xname, Xdescription, Xadvanced) {\n    value = Xvalue_pointer;\n    default_value = Xdefault_value;\n    *value = default_value;\n  }\n\n  virtual ~InfoRecordInt64() {}\n};\n\nclass InfoRecordInt : public InfoRecord {\n public:\n  HighsInt* value;\n  HighsInt default_value;\n  InfoRecordInt(std::string Xname, std::string Xdescription, bool Xadvanced,\n                HighsInt* Xvalue_pointer, HighsInt Xdefault_value)\n      : InfoRecord(HighsInfoType::kInt, Xname, Xdescription, Xadvanced) {\n    value = Xvalue_pointer;\n    default_value = Xdefault_value;\n    *value = default_value;\n  }\n\n  virtual ~InfoRecordInt() {}\n};\n\nclass InfoRecordDouble : public InfoRecord {\n public:\n  double* value;\n  double default_value;\n  InfoRecordDouble(std::string Xname, std::string Xdescription, bool Xadvanced,\n                   double* Xvalue_pointer, double Xdefault_value)\n      : InfoRecord(HighsInfoType::kDouble, Xname, Xdescription, Xadvanced) {\n    value = Xvalue_pointer;\n    default_value = Xdefault_value;\n    *value = default_value;\n  }\n\n  virtual ~InfoRecordDouble() {}\n};\n\n// For now, but later change so HiGHS properties are string based so that new\n// info (for debug and testing too) can be added easily. The info below\n// are just what has been used to parse info from argv.\n// todo: when creating the new info don't forget underscores for class\n// variables but no underscores for struct\nstruct HighsInfoStruct {\n  bool valid;\n  int64_t mip_node_count;\n  HighsInt simplex_iteration_count;\n  HighsInt ipm_iteration_count;\n  HighsInt crossover_iteration_count;\n  HighsInt pdlp_iteration_count;\n  HighsInt qp_iteration_count;\n  HighsInt primal_solution_status;\n  HighsInt dual_solution_status;\n  HighsInt basis_validity;\n  double objective_function_value;\n  double mip_dual_bound;\n  double mip_gap;\n  double max_integrality_violation;\n  HighsInt num_primal_infeasibilities;\n  double max_primal_infeasibility;\n  double sum_primal_infeasibilities;\n  HighsInt num_dual_infeasibilities;\n  double max_dual_infeasibility;\n  double sum_dual_infeasibilities;\n  HighsInt num_relative_primal_infeasibilities;\n  double max_relative_primal_infeasibility;\n  HighsInt num_relative_dual_infeasibilities;\n  double max_relative_dual_infeasibility;\n  HighsInt num_primal_residual_errors;\n  double max_primal_residual_error;\n  HighsInt num_dual_residual_errors;\n  double max_dual_residual_error;\n  HighsInt num_relative_primal_residual_errors;\n  double max_relative_primal_residual_error;\n  HighsInt num_relative_dual_residual_errors;\n  double max_relative_dual_residual_error;\n  HighsInt num_complementarity_violations;\n  double max_complementarity_violation;\n  double primal_dual_objective_error;\n  double primal_dual_integral;\n};\n\nclass HighsInfo : public HighsInfoStruct {\n public:\n  HighsInfo() { initRecords(); }\n\n  HighsInfo(const HighsInfo& info) {\n    initRecords();\n    HighsInfoStruct::operator=(info);\n  }\n\n  HighsInfo(HighsInfo&& info) {\n    records = std::move(info.records);\n    HighsInfoStruct::operator=(std::move(info));\n  }\n\n  const HighsInfo& operator=(const HighsInfo& other) {\n    if (&other != this) {\n      if ((HighsInt)records.size() == 0) initRecords();\n      HighsInfoStruct::operator=(other);\n    }\n    return *this;\n  }\n\n  const HighsInfo& operator=(HighsInfo&& other) {\n    if (&other != this) {\n      if ((HighsInt)records.size() == 0) initRecords();\n      HighsInfoStruct::operator=(other);\n    }\n    return *this;\n  }\n\n  virtual ~HighsInfo() {\n    if (records.size() > 0) deleteRecords();\n  }\n\n  void invalidate();\n  void invalidateKkt();\n  void invalidatePrimalKkt();\n  void invalidateDualKkt();\n\n private:\n  void deleteRecords() {\n    for (auto record : records) delete record;\n  }\n\n  void initRecords() {\n    InfoRecordInt64* record_int64;\n    InfoRecordInt* record_int;\n    InfoRecordDouble* record_double;\n    const bool advanced = false;  // Not used\n\n    record_int = new InfoRecordInt(\"simplex_iteration_count\",\n                                   \"Iteration count for simplex solver\",\n                                   advanced, &simplex_iteration_count, 0);\n    records.push_back(record_int);\n\n    record_int = new InfoRecordInt(\"ipm_iteration_count\",\n                                   \"Iteration count for IPM solver\", advanced,\n                                   &ipm_iteration_count, 0);\n    records.push_back(record_int);\n\n    record_int = new InfoRecordInt(\"crossover_iteration_count\",\n                                   \"Iteration count for crossover\", advanced,\n                                   &crossover_iteration_count, 0);\n    records.push_back(record_int);\n\n    record_int = new InfoRecordInt(\"pdlp_iteration_count\",\n                                   \"Iteration count for PDLP solver\", advanced,\n                                   &pdlp_iteration_count, 0);\n    records.push_back(record_int);\n\n    record_int =\n        new InfoRecordInt(\"qp_iteration_count\", \"Iteration count for QP solver\",\n                          advanced, &qp_iteration_count, 0);\n    records.push_back(record_int);\n\n    record_int = new InfoRecordInt(\"primal_solution_status\",\n                                   \"Model primal solution status: 0 => No \"\n                                   \"solution; 1 => Infeasible point; \"\n                                   \"2 => Feasible point\",\n                                   advanced, &primal_solution_status,\n                                   kSolutionStatusNone);\n    records.push_back(record_int);\n\n    record_int =\n        new InfoRecordInt(\"dual_solution_status\",\n                          \"Model dual solution status: 0 => No solution; 1 => \"\n                          \"Infeasible point; 2 \"\n                          \"=> Feasible point\",\n                          advanced, &dual_solution_status, kSolutionStatusNone);\n    records.push_back(record_int);\n\n    record_int = new InfoRecordInt(\n        \"basis_validity\", \"Model basis validity: 0 => Invalid; 1 => Valid\",\n        advanced, &basis_validity, kBasisValidityInvalid);\n    records.push_back(record_int);\n\n    record_double = new InfoRecordDouble(\"objective_function_value\",\n                                         \"Objective function value\", advanced,\n                                         &objective_function_value, 0);\n    records.push_back(record_double);\n\n    record_int64 =\n        new InfoRecordInt64(\"mip_node_count\", \"MIP solver node count\", advanced,\n                            &mip_node_count, 0);\n    records.push_back(record_int64);\n\n    record_double =\n        new InfoRecordDouble(\"mip_dual_bound\", \"MIP solver dual bound\",\n                             advanced, &mip_dual_bound, 0);\n    records.push_back(record_double);\n\n    record_double = new InfoRecordDouble(\"mip_gap\", \"MIP solver gap (%)\",\n                                         advanced, &mip_gap, 0);\n    records.push_back(record_double);\n\n    record_double = new InfoRecordDouble(\"max_integrality_violation\",\n                                         \"Max integrality violation\", advanced,\n                                         &max_integrality_violation, 0);\n    records.push_back(record_double);\n\n    record_int = new InfoRecordInt(\"num_primal_infeasibilities\",\n                                   \"Number of primal infeasibilities\", advanced,\n                                   &num_primal_infeasibilities, -1);\n    records.push_back(record_int);\n\n    record_double = new InfoRecordDouble(\n        \"max_primal_infeasibility\", \"Maximum primal infeasibility\", advanced,\n        &max_primal_infeasibility, 0);\n    records.push_back(record_double);\n\n    record_double = new InfoRecordDouble(\n        \"sum_primal_infeasibilities\", \"Sum of primal infeasibilities\", advanced,\n        &sum_primal_infeasibilities, 0);\n    records.push_back(record_double);\n\n    record_int = new InfoRecordInt(\"num_dual_infeasibilities\",\n                                   \"Number of dual infeasibilities\", advanced,\n                                   &num_dual_infeasibilities, -1);\n    records.push_back(record_int);\n\n    record_double = new InfoRecordDouble(\"max_dual_infeasibility\",\n                                         \"Maximum dual infeasibility\", advanced,\n                                         &max_dual_infeasibility, 0);\n    records.push_back(record_double);\n\n    record_double = new InfoRecordDouble(\n        \"sum_dual_infeasibilities\", \"Sum of dual infeasibilities\", advanced,\n        &sum_dual_infeasibilities, 0);\n    records.push_back(record_double);\n\n    record_int =\n        new InfoRecordInt(\"num_relative_primal_infeasibilities\",\n                          \"Number of relative primal infeasibilities\", advanced,\n                          &num_relative_primal_infeasibilities, -1);\n    records.push_back(record_int);\n\n    record_double =\n        new InfoRecordDouble(\"max_relative_primal_infeasibility\",\n                             \"Maximum relative primal infeasibility\", advanced,\n                             &max_relative_primal_infeasibility, 0);\n    records.push_back(record_double);\n\n    record_int =\n        new InfoRecordInt(\"num_relative_dual_infeasibilities\",\n                          \"Number of relative dual infeasibilities\", advanced,\n                          &num_relative_dual_infeasibilities, -1);\n    records.push_back(record_int);\n\n    record_double =\n        new InfoRecordDouble(\"max_relative_dual_infeasibility\",\n                             \"Maximum relative dual infeasibility\", advanced,\n                             &max_relative_dual_infeasibility, 0);\n    records.push_back(record_double);\n\n    record_int = new InfoRecordInt(\"num_primal_residual_errors\",\n                                   \"Number of primal residual errors\", advanced,\n                                   &num_primal_residual_errors, -1);\n    records.push_back(record_int);\n\n    record_double = new InfoRecordDouble(\n        \"max_primal_residual_error\", \"Maximum primal residual error\", advanced,\n        &max_primal_residual_error, 0);\n    records.push_back(record_double);\n\n    record_int = new InfoRecordInt(\"num_dual_residual_errors\",\n                                   \"Number of dual residual errors\", advanced,\n                                   &num_dual_residual_errors, -1);\n    records.push_back(record_int);\n\n    record_double = new InfoRecordDouble(\"max_dual_residual_error\",\n                                         \"Maximum dual residual error\",\n                                         advanced, &max_dual_residual_error, 0);\n    records.push_back(record_double);\n\n    record_int =\n        new InfoRecordInt(\"num_relative_primal_residual_errors\",\n                          \"Number of relative primal residual errors\", advanced,\n                          &num_relative_primal_residual_errors, -1);\n    records.push_back(record_int);\n\n    record_double =\n        new InfoRecordDouble(\"max_relative_primal_residual_error\",\n                             \"Maximum relative primal residual error\", advanced,\n                             &max_relative_primal_residual_error, 0);\n    records.push_back(record_double);\n\n    record_int =\n        new InfoRecordInt(\"num_relative_dual_residual_errors\",\n                          \"Number of relative dual residual errors\", advanced,\n                          &num_relative_dual_residual_errors, -1);\n    records.push_back(record_int);\n\n    record_double =\n        new InfoRecordDouble(\"max_relative_dual_residual_error\",\n                             \"Maximum relative dual residual error\", advanced,\n                             &max_relative_dual_residual_error, 0);\n    records.push_back(record_double);\n\n    record_int =\n        new InfoRecordInt(\"num_complementarity_violations\",\n                          \"Number of complementarity violations\", advanced,\n                          &num_complementarity_violations, -1);\n    records.push_back(record_int);\n\n    record_double = new InfoRecordDouble(\n        \"max_complementarity_violation\", \"Max complementarity violation\",\n        advanced, &max_complementarity_violation, 0);\n    records.push_back(record_double);\n\n    record_double = new InfoRecordDouble(\n        \"primal_dual_objective_error\", \"Primal-dual objective error\", advanced,\n        &primal_dual_objective_error, 0);\n    records.push_back(record_double);\n\n    record_double =\n        new InfoRecordDouble(\"primal_dual_integral\", \"Primal-dual integral\",\n                             advanced, &primal_dual_integral, 0);\n    records.push_back(record_double);\n  }\n\n public:\n  std::vector<InfoRecord*> records;\n};\n\nHighsStatus writeInfoToFile(\n    FILE* file, const bool valid, const HighsInfo& info,\n    const HighsFileType file_type = HighsFileType::kFull);\n\nInfoStatus getInfoIndex(const HighsLogOptions& report_log_options,\n                        const std::string& name,\n                        const std::vector<InfoRecord*>& info_records,\n                        HighsInt& index);\n\nInfoStatus checkInfo(const HighsLogOptions& report_log_options,\n                     const std::vector<InfoRecord*>& info_records);\nInfoStatus checkInfo(const InfoRecordInt& info);\nInfoStatus checkInfo(const InfoRecordDouble& info);\n\nInfoStatus getLocalInfoValue(const HighsLogOptions& report_log_options,\n                             const std::string& name, const bool valid,\n                             const std::vector<InfoRecord*>& info_records,\n                             int64_t& value);\nInfoStatus getLocalInfoValue(const HighsLogOptions& report_log_options,\n                             const std::string& name, const bool valid,\n                             const std::vector<InfoRecord*>& info_records,\n                             HighsInt& value);\nInfoStatus getLocalInfoValue(const HighsLogOptions& report_log_options,\n                             const std::string& name, const bool valid,\n                             const std::vector<InfoRecord*>& info_records,\n                             double& value);\n\nInfoStatus getLocalInfoType(const HighsLogOptions& report_log_options,\n                            const std::string& name,\n                            const std::vector<InfoRecord*>& info_records,\n                            HighsInfoType& type);\n\nHighsStatus writeInfoToFile(\n    FILE* file, const bool valid, const std::vector<InfoRecord*>& info_records,\n    const HighsFileType file_type = HighsFileType::kFull);\nvoid reportInfo(FILE* file, const std::vector<InfoRecord*>& info_records,\n                const HighsFileType file_type = HighsFileType::kFull);\nvoid reportInfo(FILE* file, const InfoRecordInt64& info,\n                const HighsFileType file_type = HighsFileType::kFull);\nvoid reportInfo(FILE* file, const InfoRecordInt& info,\n                const HighsFileType file_type = HighsFileType::kFull);\nvoid reportInfo(FILE* file, const InfoRecordDouble& info,\n                const HighsFileType file_type = HighsFileType::kFull);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsInfoDebug.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsInfoDebug.h\n * @brief\n */\n#ifndef LP_DATA_HIGHS_INFO_DEBUG_H_\n#define LP_DATA_HIGHS_INFO_DEBUG_H_\n\n#include \"lp_data/HStruct.h\"\n#include \"lp_data/HighsInfo.h\"\n#include \"lp_data/HighsLp.h\"\n#include \"lp_data/HighsOptions.h\"\n// #include \"lp_data/HighsLp.h\"\n\nHighsDebugStatus debugInfo(const HighsOptions& options, const HighsLp& lp,\n                           const HighsBasis& basis,\n                           const HighsSolution& solution, const HighsInfo& info,\n                           const HighsModelStatus model_status);\n\nHighsDebugStatus debugNoInfo(const HighsInfo& info);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsLp.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsLp.h\n * @brief\n */\n#ifndef LP_DATA_HIGHS_LP_H_\n#define LP_DATA_HIGHS_LP_H_\n\n#include <string>\n\n#include \"lp_data/HStruct.h\"\n#include \"util/HighsSparseMatrix.h\"\n\nclass HighsLp {\n public:\n  HighsLp() { clear(); }\n  // Model data\n  HighsInt num_col_;\n  HighsInt num_row_;\n\n  std::vector<double> col_cost_;\n  std::vector<double> col_lower_;\n  std::vector<double> col_upper_;\n  std::vector<double> row_lower_;\n  std::vector<double> row_upper_;\n\n  HighsSparseMatrix a_matrix_;\n\n  ObjSense sense_;\n  double offset_;\n\n  std::string model_name_;\n  std::string origin_name_;\n  std::string objective_name_;\n\n  std::string col_name_prefix_ = \"\";\n  std::string row_name_prefix_ = \"\";\n  HighsInt col_name_suffix_ = 0;\n  HighsInt row_name_suffix_ = 0;\n  std::vector<std::string> col_names_;\n  std::vector<std::string> row_names_;\n\n  std::vector<HighsVarType> integrality_;\n\n  HighsNameHash col_hash_;\n  HighsNameHash row_hash_;\n\n  HighsScale scale_;\n  bool is_scaled_;\n  bool is_moved_;\n  HighsInt cost_row_location_;\n  bool has_infinite_cost_;\n  HighsLpMods mods_;\n\n  bool operator==(const HighsLp& lp) const;\n  bool equalButForNames(const HighsLp& lp) const;\n  bool equalButForScalingAndNames(const HighsLp& lp) const;\n  bool equalVectors(const HighsLp& lp) const;\n  bool equalNames(const HighsLp& lp) const;\n  bool equalScaling(const HighsLp& lp) const;\n  bool isMip() const;\n  bool hasSemiVariables() const;\n  bool hasInfiniteCost(const double infinite_cost) const;\n  bool hasMods() const;\n  bool needsMods(const double infinite_cost) const;\n  double objectiveValue(const std::vector<double>& solution) const;\n  HighsCDouble objectiveCDoubleValue(const std::vector<double>& solution) const;\n  void setMatrixDimensions();\n  void setFormat(const MatrixFormat format);\n  void ensureColwise() { this->a_matrix_.ensureColwise(); };\n  void ensureRowwise() { this->a_matrix_.ensureRowwise(); };\n  void clearScaling();\n  void resetScale();\n  void clearScale();\n  void applyScale();\n  void unapplyScale();\n  void moveBackLpAndUnapplyScaling(HighsLp& lp);\n  void exactResize();\n  bool okNames() const;\n  void addColNames(const std::string name, const HighsInt num_new_col = 1);\n  void addRowNames(const std::string name, const HighsInt num_new_row = 1);\n  void deleteColsFromVectors(HighsInt& new_num_col,\n                             const HighsIndexCollection& index_collection);\n  void deleteRowsFromVectors(HighsInt& new_num_row,\n                             const HighsIndexCollection& index_collection);\n  void deleteCols(const HighsIndexCollection& index_collection);\n  void deleteRows(const HighsIndexCollection& index_collection);\n  void unapplyMods();\n  void clear();\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsLpSolverObject.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file simplex/HighsLpSolverObject.h\n * @brief Collection of class instances required to solve an LP\n */\n#ifndef LP_DATA_HIGHS_LP_SOLVER_OBJECT_H_\n#define LP_DATA_HIGHS_LP_SOLVER_OBJECT_H_\n\n#include \"lp_data/HighsInfo.h\"\n#include \"lp_data/HighsOptions.h\"\n#include \"simplex/HEkk.h\"\n\nclass HighsLpSolverObject {\n public:\n  HighsLpSolverObject(HighsLp& lp, HighsBasis& basis, HighsSolution& solution,\n                      HighsInfo& highs_info, HEkk& ekk_instance,\n                      HighsCallback& callback, HighsOptions& options,\n                      HighsTimer& timer,\n                      HighsSubSolverCallTime& sub_solver_call_time)\n      : lp_(lp),\n        basis_(basis),\n        solution_(solution),\n        highs_info_(highs_info),\n        ekk_instance_(ekk_instance),\n        callback_(callback),\n        options_(options),\n        timer_(timer),\n        sub_solver_call_time_(sub_solver_call_time) {}\n\n  HighsLp& lp_;\n  HighsBasis& basis_;\n  HighsSolution& solution_;\n  HighsInfo& highs_info_;\n  HEkk& ekk_instance_;\n  HighsCallback& callback_;\n  HighsOptions& options_;\n  HighsTimer& timer_;\n  HighsSubSolverCallTime& sub_solver_call_time_;\n  HighsModelStatus model_status_ = HighsModelStatus::kNotset;\n};\n\n#endif  // LP_DATA_HIGHS_LP_SOLVER_OBJECT_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsLpUtils.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsLpUtils.h\n * @brief Class-independent utilities for HiGHS\n */\n#ifndef LP_DATA_HIGHSLPUTILS_H_\n#define LP_DATA_HIGHSLPUTILS_H_\n\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n#include \"lp_data/HighsInfo.h\"\n#include \"lp_data/HighsLp.h\"\n#include \"lp_data/HighsStatus.h\"\n#include \"util/HighsUtils.h\"\n\n// class HighsLp;\nstruct SimplexScale;\nstruct HighsBasis;\nstruct HighsSolution;\nclass HighsOptions;\n\nusing std::vector;\n\nvoid writeBasisFile(FILE*& file, const HighsOptions& options, const HighsLp& lp,\n                    const HighsBasis& basis);\n\nHighsStatus getIndexFromName(\n    const HighsLogOptions& log_options, std::string& from_method,\n    const bool is_column, const std::string& name,\n    const std::unordered_map<std::string, int>& name2index, HighsInt& index,\n    const std::vector<std::string>& names);\n\nHighsStatus readBasisFile(const HighsLogOptions& log_options, HighsLp& lp,\n                          HighsBasis& basis, const std::string filename);\nHighsStatus readBasisStream(const HighsLogOptions& log_options, HighsLp& lp,\n                            HighsBasis& basis, std::ifstream& in_file);\n\n// Methods taking HighsLp as an argument\nHighsStatus assessLp(HighsLp& lp, const HighsOptions& options);\n\nbool lpDimensionsOk(std::string message, const HighsLp& lp,\n                    const HighsLogOptions& log_options);\n\nHighsStatus assessCosts(const HighsOptions& options, const HighsInt ml_col_os,\n                        const HighsIndexCollection& index_collection,\n                        vector<double>& cost, bool& has_infinite_cost,\n                        const double infinite_cost);\n\nHighsStatus assessBounds(const HighsOptions& options, const char* type,\n                         const HighsInt ml_ix_os,\n                         const HighsIndexCollection& index_collection,\n                         vector<double>& lower, vector<double>& upper,\n                         const double infinite_bound,\n                         const HighsVarType* integrality = nullptr);\n\nHighsStatus cleanBounds(const HighsOptions& options, HighsLp& lp);\n\nHighsStatus userScaleLp(HighsLp& lp, HighsUserScaleData& data,\n                        const HighsLogOptions& log_options);\n\nvoid userScaleLp(HighsLp& lp, HighsUserScaleData& data,\n                 const bool apply = true);\n\nvoid userScaleCosts(const vector<HighsVarType>& integrality,\n                    vector<double>& cost, HighsUserScaleData& data,\n                    const bool apply = true);\n\nvoid userScaleColBounds(const vector<HighsVarType>& integrality,\n                        vector<double>& lower, vector<double>& upper,\n                        HighsUserScaleData& data, const bool apply = true);\n\nvoid userScaleRowBounds(vector<double>& lower, vector<double>& upper,\n                        HighsUserScaleData& data, const bool apply = true);\n\nvoid userScaleMatrix(const vector<HighsVarType>& integrality,\n                     HighsSparseMatrix& matrix, HighsUserScaleData& data,\n                     const bool apply = true);\n\nHighsStatus userScaleStatus(const HighsLogOptions& log_options,\n                            const HighsUserScaleData& data);\n\nHighsStatus assessSemiVariables(HighsLp& lp, const HighsOptions& options,\n                                bool& made_semi_variable_mods);\nvoid relaxSemiVariables(HighsLp& lp, bool& made_semi_variable_mods);\n\nbool activeModifiedUpperBounds(const HighsOptions& options, const HighsLp& lp,\n                               const std::vector<double> col_value);\n\nbool considerScaling(const HighsOptions& options, HighsLp& lp);\nvoid scaleLp(const HighsOptions& options, HighsLp& lp,\n             const bool force_scaling = false);\nbool equilibrationScaleMatrix(const HighsOptions& options, HighsLp& lp,\n                              const HighsInt use_scale_strategy);\nbool maxValueScaleMatrix(const HighsOptions& options, HighsLp& lp,\n                         const HighsInt use_scale_strategy);\n\nHighsStatus applyScalingToLpCol(HighsLp& lp, const HighsInt col,\n                                const double colScale);\n\nHighsStatus applyScalingToLpRow(HighsLp& lp, const HighsInt row,\n                                const double rowScale);\n\nvoid unscaleSolution(HighsSolution& solution, const HighsScale& scale);\n\nvoid appendColsToLpVectors(HighsLp& lp, const HighsInt num_new_col,\n                           const vector<double>& colCost,\n                           const vector<double>& colLower,\n                           const vector<double>& colUpper);\n\nvoid appendRowsToLpVectors(HighsLp& lp, const HighsInt num_new_row,\n                           const vector<double>& rowLower,\n                           const vector<double>& rowUpper);\n\nvoid deleteScale(vector<double>& scale,\n                 const HighsIndexCollection& index_collection);\n\nvoid changeLpMatrixCoefficient(HighsLp& lp, const HighsInt row,\n                               const HighsInt col, const double new_value,\n                               const bool zero_new_value);\n\nHighsStatus changeLpIntegrality(HighsLp& lp,\n                                const HighsIndexCollection& index_collection,\n                                const vector<HighsVarType>& new_integrality,\n                                const HighsOptions options);\n\nvoid changeLpCosts(HighsLp& lp, const HighsIndexCollection& index_collection,\n                   const vector<double>& new_col_cost,\n                   const double infinite_cost);\n\nvoid changeLpColBounds(HighsLp& lp,\n                       const HighsIndexCollection& index_collection,\n                       const vector<double>& new_col_lower,\n                       const vector<double>& new_col_upper);\n\nvoid changeLpRowBounds(HighsLp& lp,\n                       const HighsIndexCollection& index_collection,\n                       const vector<double>& new_row_lower,\n                       const vector<double>& new_row_upper);\n\nvoid changeBounds(vector<double>& lower, vector<double>& upper,\n                  const HighsIndexCollection& index_collection,\n                  const vector<double>& new_lower,\n                  const vector<double>& new_upper);\n\n/**\n * @brief Report the data of an LP\n */\nvoid reportLp(const HighsLogOptions& log_options,\n              const HighsLp& lp,  //!< LP whose data are to be reported\n              const HighsLogType report_level = HighsLogType::kInfo\n              //!< INFO => scalar [dimensions];\n              //!< DETAILED => vector[costs/bounds];\n              //!< VERBOSE => vector+matrix\n);\n/**\n * @brief Report the brief data of an LP\n */\nvoid reportLpBrief(const HighsLogOptions& log_options,\n                   const HighsLp& lp  //!< LP whose data are to be reported\n);\n/**\n * @brief Report the data of an LP\n */\nvoid reportLpDimensions(const HighsLogOptions& log_options,\n                        const HighsLp& lp  //!< LP whose data are to be reported\n);\n/**\n * @brief Report the data of an LP\n */\nvoid reportLpObjSense(const HighsLogOptions& log_options,\n                      const HighsLp& lp  //!< LP whose data are to be reported\n);\n/**\n * @brief Report the data of an LP\n */\nvoid reportLpColVectors(const HighsLogOptions& log_options,\n                        const HighsLp& lp  //!< LP whose data are to be reported\n);\n/**\n * @brief Report the data of an LP\n */\nvoid reportLpRowVectors(const HighsLogOptions& log_options,\n                        const HighsLp& lp  //!< LP whose data are to be reported\n);\n/**\n * @brief Report the data of an LP\n */\nvoid reportLpColMatrix(const HighsLogOptions& log_options,\n                       const HighsLp& lp  //!< LP whose data are to be reported\n);\n\nvoid reportMatrix(const HighsLogOptions& log_options, const std::string message,\n                  const HighsInt num_col, const HighsInt num_nz,\n                  const HighsInt* start, const HighsInt* index,\n                  const double* value);\n\n// Get the number of integer-valued columns in the LP\nHighsInt getNumInt(const HighsLp& lp);\n\n// Get the costs for a contiguous set of columns\nvoid getLpCosts(const HighsLp& lp, const HighsInt from_col,\n                const HighsInt to_col, double* XcolCost);\n\n// Get the bounds for a contiguous set of columns\nvoid getLpColBounds(const HighsLp& lp, const HighsInt from_col,\n                    const HighsInt to_col, double* XcolLower,\n                    double* XcolUpper);\n\n// Get the bounds for a contiguous set of rows\nvoid getLpRowBounds(const HighsLp& lp, const HighsInt from_row,\n                    const HighsInt to_row, double* XrowLower,\n                    double* XrowUpper);\n\nvoid getLpMatrixCoefficient(const HighsLp& lp, const HighsInt row,\n                            const HighsInt col, double* val);\n// Analyse the data in an LP problem\nvoid analyseLp(const HighsLogOptions& log_options, const HighsLp& lp);\n\nHighsStatus readSolutionFile(const std::string filename,\n                             const HighsOptions& options, HighsLp& lp,\n                             HighsBasis& basis, HighsSolution& solution,\n                             const HighsInt style);\n\nHighsStatus readSolutionFileErrorReturn(std::ifstream& in_file);\nHighsStatus readSolutionFileReturn(const HighsStatus status,\n                                   HighsSolution& solution, HighsBasis& basis,\n                                   const HighsSolution& read_solution,\n                                   const HighsBasis& read_basis,\n                                   std::ifstream& in_file);\nbool readSolutionFileIgnoreLineOk(std::ifstream& in_file);\nbool readSolutionFileKeywordLineOk(std::string& keyword,\n                                   std::ifstream& in_file);\nbool readSolutionFileHashKeywordIntLineOk(std::string& hash,\n                                          std::string& keyword,\n                                          std::string& value_string,\n                                          HighsInt& value,\n                                          std::ifstream& in_file);\nbool readSolutionFileIdIgnoreLineOk(std::string& id, std::ifstream& in_file);\nbool readSolutionFileIdDoubleLineOk(std::string& id, double& value,\n                                    std::ifstream& in_file);\nbool readSolutionFileIdDoubleIntLineOk(std::string& id, double& value,\n                                       HighsInt& index, std::ifstream& in_file);\n\nvoid assessColPrimalSolution(const HighsOptions& options, const double primal,\n                             const double lower, const double upper,\n                             const HighsVarType type, double& col_infeasibility,\n                             double& integer_infeasibility);\n\nHighsStatus assessLpPrimalSolution(const std::string message,\n                                   const HighsOptions& options,\n                                   const HighsLp& lp,\n                                   const HighsSolution& solution, bool& valid,\n                                   bool& integral, bool& feasible);\n\nHighsStatus calculateRowValuesQuad(const HighsLp& lp,\n                                   const std::vector<double>& col_value,\n                                   std::vector<double>& row_value,\n                                   const HighsInt report_row = -1);\nHighsStatus calculateRowValuesQuad(const HighsLp& lp, HighsSolution& solution,\n                                   const HighsInt report_row = -1);\n\nHighsStatus calculateColDualsQuad(const HighsLp& lp, HighsSolution& solution);\n\nbool isColDataNull(const HighsLogOptions& log_options,\n                   const double* usr_col_cost, const double* usr_col_lower,\n                   const double* usr_col_upper);\nbool isRowDataNull(const HighsLogOptions& log_options,\n                   const double* usr_row_lower, const double* usr_row_upper);\nbool isMatrixDataNull(const HighsLogOptions& log_options,\n                      const HighsInt* usr_matrix_start,\n                      const HighsInt* usr_matrix_index,\n                      const double* usr_matrix_value);\n\nvoid reportPresolveReductions(const HighsLogOptions& log_options,\n                              HighsPresolveStatus presolve_status,\n                              const HighsLp& lp, const HighsLp& presolved_lp);\n\nbool isLessInfeasibleDSECandidate(const HighsLogOptions& log_options,\n                                  const HighsLp& lp);\n\nHighsLp withoutSemiVariables(const HighsLp& lp, HighsSolution& solution,\n                             const double primal_feasibility_tolerance);\n\nvoid removeRowsOfCountOne(const HighsLogOptions& log_options, HighsLp& lp);\n\n// Get subvectors from data structure of data0, data1, data2 and\n// matrix, where the storage of the matrix is compatible with the\n// vectors to be extracted from it\n//\n// Data to be extracted is given by sub_* being nullpointer\n//\n// * cost, lower and upper bounds for columns, and column-wise LP constraint\n// matrix\n//\n// * lower and upper bounds for rows, and row-wise LP constraint\n// * matrix. \"cost\" is nullptr, and so must be sub_vector_data0\n//\nvoid getSubVectors(const HighsIndexCollection& index_collection,\n                   const HighsInt data_dim, const double* data0,\n                   const double* data1, const double* data2,\n                   const HighsSparseMatrix& matrix, HighsInt& num_sub_vector,\n                   double* sub_vector_data0, double* sub_vector_data1,\n                   double* sub_vector_data2, HighsInt& sub_matrix_num_nz,\n                   HighsInt* sub_matrix_start, HighsInt* sub_matrix_index,\n                   double* sub_matrix_value);\n\nvoid getSubVectorsTranspose(const HighsIndexCollection& index_collection,\n                            const HighsInt data_dim, const double* data0,\n                            const double* data1, const double* data2,\n                            const HighsSparseMatrix& matrix,\n                            HighsInt& num_sub_vector, double* sub_vector_data0,\n                            double* sub_vector_data1, double* sub_vector_data2,\n                            HighsInt& sub_matrix_num_nz,\n                            HighsInt* sub_matrix_start,\n                            HighsInt* sub_matrix_index,\n                            double* sub_matrix_value);\n\nvoid initialiseUserScaleData(const HighsOptions& options,\n                             HighsUserScaleData& user_scale_data);\n#endif  // LP_DATA_HIGHSLPUTILS_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsModelUtils.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsModelUtils.h\n * @brief Class-independent utilities for HiGHS\n */\n#ifndef LP_DATA_HIGHSMODELUTILS_H_\n#define LP_DATA_HIGHSMODELUTILS_H_\n\n#include \"lp_data/HighsInfo.h\"\n#include \"model/HighsModel.h\"\n// #include \"Highs.h\"\n// #include \"lp_data/HighsStatus.h\"\n// #include \"lp_data/HStruct.h\"\n// #include \"lp_data/HighsInfo.h\"\n// #include \"lp_data/HighsLp.h\"\n// #include \"lp_data/HighsOptions.h\"\n\n// Analyse lower and upper bounds of a model\nvoid analyseModelBounds(const HighsLogOptions& log_options, const char* message,\n                        HighsInt numBd, const std::vector<double>& lower,\n                        const std::vector<double>& upper);\nbool hasNamesWithSpaces(const HighsLogOptions& log_options, const HighsLp& lp);\nbool hasNamesWithSpaces(const HighsLogOptions& log_options, const bool col,\n                        const std::vector<std::string>& names);\n\nvoid writeModelBoundSolution(\n    FILE* file, const HighsLogOptions& log_options, const bool columns,\n    const HighsInt dim, const std::vector<double>& lower,\n    const std::vector<double>& upper, const std::vector<std::string>& names,\n    const bool have_primal, const std::vector<double>& primal,\n    const bool have_dual, const std::vector<double>& dual,\n    const bool have_basis, const std::vector<HighsBasisStatus>& status,\n    const HighsVarType* integrality = NULL);\n\nvoid writeModelObjective(FILE* file, const HighsLogOptions& log_options,\n                         const HighsModel& model,\n                         const std::vector<double>& primal_solution);\n\nvoid writeLpObjective(FILE* file, const HighsLogOptions& log_options,\n                      const HighsLp& lp,\n                      const std::vector<double>& primal_solution);\n\nvoid writeObjectiveValue(FILE* file, const HighsLogOptions& log_options,\n                         const double objective_value);\n\nvoid writePrimalSolution(FILE* file, const HighsLogOptions& log_options,\n                         const HighsLp& lp,\n                         const std::vector<double>& primal_solution,\n                         const bool sparse = false);\n\nvoid writeModelSolution(FILE* file, const HighsLogOptions& log_options,\n                        const HighsModel& model, const HighsSolution& solution,\n                        const HighsInfo& info, const bool sparse = false);\n\nHighsInt maxNameLength(const HighsLp& lp);\nHighsInt maxNameLength(const std::vector<std::string>& names);\n\nHighsStatus normaliseNames(const HighsLogOptions& log_options, HighsLp& lp);\n\nHighsStatus normaliseNames(const HighsLogOptions& log_options, bool column,\n                           HighsInt num_name_required, std::string& name_prefix,\n                           HighsInt& name_suffix,\n                           std::vector<std::string>& names,\n                           HighsNameHash& name_hash);\n\nvoid writeSolutionFile(FILE* file, const HighsOptions& options,\n                       const HighsModel& model, const HighsBasis& basis,\n                       const HighsSolution& solution, const HighsInfo& info,\n                       const HighsModelStatus model_status,\n                       const HighsInt style);\n\nvoid writeGlpsolCostRow(FILE* file, const HighsLogOptions& log_options,\n                        const bool raw, const bool is_mip,\n                        const HighsInt row_id, const std::string objective_name,\n                        const double objective_function_value);\n\nvoid writeGlpsolSolution(FILE* file, const HighsOptions& options,\n                         const HighsModel& model, const HighsBasis& basis,\n                         const HighsSolution& solution,\n                         const HighsModelStatus model_status,\n                         const HighsInfo& info, const bool raw);\n\nvoid writeOldRawSolution(FILE* file, const HighsLogOptions& log_options,\n                         const HighsLp& lp, const HighsBasis& basis,\n                         const HighsSolution& solution);\n\nHighsBasisStatus checkedVarHighsNonbasicStatus(\n    const HighsBasisStatus ideal_status, const double lower,\n    const double upper);\n\nstd::string utilModelStatusToString(const HighsModelStatus model_status);\n\nstd::string utilSolutionStatusToString(const HighsInt solution_status);\n\nstd::string utilBasisStatusToString(const HighsBasisStatus basis_status);\n\nstd::string utilBasisValidityToString(const HighsInt basis_validity);\n\nstd::string utilPresolveRuleTypeToString(const HighsInt rule_type);\n\nHighsStatus highsStatusFromHighsModelStatus(HighsModelStatus model_status);\n\nstd::string statusToString(const HighsBasisStatus status, const double lower,\n                           const double upper);\nstd::string typeToString(const HighsVarType type);\n\nstd::string findModelObjectiveName(const HighsLp* lp,\n                                   const HighsHessian* hessian = nullptr);\n\n// bool repeatedNames(const std::vector<std::string> name);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsOptions.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsOptions.h\n * @brief\n */\n#ifndef LP_DATA_HIGHS_OPTIONS_H_\n#define LP_DATA_HIGHS_OPTIONS_H_\n\n#include <cstring>  // For strlen\n#include <vector>\n\n#include \"io/HighsIO.h\"\n#include \"lp_data/HConst.h\"\n#include \"lp_data/HighsStatus.h\"\n#include \"simplex/SimplexConst.h\"\n#include \"util/HFactorConst.h\"\n\nusing std::string;\n\nenum class OptionStatus { kOk = 0, kUnknownOption, kIllegalValue };\n\nconst bool kAdvancedInDocumentation = false;\n\nclass OptionRecord {\n public:\n  HighsOptionType type;\n  std::string name;\n  std::string description;\n  bool advanced;\n\n  OptionRecord(HighsOptionType Xtype, std::string Xname,\n               std::string Xdescription, bool Xadvanced) {\n    this->type = Xtype;\n    this->name = Xname;\n    this->description = Xdescription;\n    this->advanced = Xadvanced;\n  }\n\n  virtual ~OptionRecord() {}\n};\n\nclass OptionRecordBool : public OptionRecord {\n public:\n  bool* value;\n  bool default_value;\n  OptionRecordBool(std::string Xname, std::string Xdescription, bool Xadvanced,\n                   bool* Xvalue_pointer, bool Xdefault_value)\n      : OptionRecord(HighsOptionType::kBool, Xname, Xdescription, Xadvanced) {\n    value = Xvalue_pointer;\n    default_value = Xdefault_value;\n    *value = default_value;\n  }\n\n  void assignvalue(bool Xvalue) { *value = Xvalue; }\n\n  virtual ~OptionRecordBool() {}\n};\n\nclass OptionRecordInt : public OptionRecord {\n public:\n  HighsInt* value;\n  HighsInt lower_bound;\n  HighsInt default_value;\n  HighsInt upper_bound;\n  OptionRecordInt(std::string Xname, std::string Xdescription, bool Xadvanced,\n                  HighsInt* Xvalue_pointer, HighsInt Xlower_bound,\n                  HighsInt Xdefault_value, HighsInt Xupper_bound)\n      : OptionRecord(HighsOptionType::kInt, Xname, Xdescription, Xadvanced) {\n    value = Xvalue_pointer;\n    lower_bound = Xlower_bound;\n    default_value = Xdefault_value;\n    upper_bound = Xupper_bound;\n    *value = default_value;\n  }\n\n  void assignvalue(HighsInt Xvalue) { *value = Xvalue; }\n\n  virtual ~OptionRecordInt() {}\n};\n\nclass OptionRecordDouble : public OptionRecord {\n public:\n  double* value;\n  double lower_bound;\n  double upper_bound;\n  double default_value;\n  OptionRecordDouble(std::string Xname, std::string Xdescription,\n                     bool Xadvanced, double* Xvalue_pointer,\n                     double Xlower_bound, double Xdefault_value,\n                     double Xupper_bound)\n      : OptionRecord(HighsOptionType::kDouble, Xname, Xdescription, Xadvanced) {\n    value = Xvalue_pointer;\n    lower_bound = Xlower_bound;\n    default_value = Xdefault_value;\n    upper_bound = Xupper_bound;\n    *value = default_value;\n  }\n\n  void assignvalue(double Xvalue) { *value = Xvalue; }\n\n  virtual ~OptionRecordDouble() {}\n};\n\nclass OptionRecordString : public OptionRecord {\n public:\n  std::string* value;\n  std::string default_value;\n  OptionRecordString(std::string Xname, std::string Xdescription,\n                     bool Xadvanced, std::string* Xvalue_pointer,\n                     std::string Xdefault_value)\n      : OptionRecord(HighsOptionType::kString, Xname, Xdescription, Xadvanced) {\n    value = Xvalue_pointer;\n    default_value = Xdefault_value;\n    *value = default_value;\n  }\n\n  void assignvalue(std::string Xvalue) { *value = Xvalue; }\n\n  virtual ~OptionRecordString() {}\n};\n\nvoid highsOpenLogFile(HighsLogOptions& log_options,\n                      std::vector<OptionRecord*>& option_records,\n                      const std::string log_file);\n\nbool optionOffChooseOnOk(const HighsLogOptions& report_log_options,\n                         const string& name, const string& value);\nbool optionOffOnOk(const HighsLogOptions& report_log_options,\n                   const string& name, const string& value);\nbool optionSolverOk(const HighsLogOptions& report_log_options,\n                    const string& value);\nbool optionMipLpSolverOk(const HighsLogOptions& report_log_options,\n                         const string& value);\nbool optionMipIpmSolverOk(const HighsLogOptions& report_log_options,\n                          const string& value);\n\nbool boolFromString(std::string value, bool& bool_value);\n\nOptionStatus getOptionIndex(const HighsLogOptions& report_log_options,\n                            const std::string& name,\n                            const std::vector<OptionRecord*>& option_records,\n                            HighsInt& index);\n\nOptionStatus checkOptions(const HighsLogOptions& report_log_options,\n                          const std::vector<OptionRecord*>& option_records);\nOptionStatus checkOption(const HighsLogOptions& report_log_options,\n                         const OptionRecordInt& option);\nOptionStatus checkOption(const HighsLogOptions& report_log_options,\n                         const OptionRecordDouble& option);\n\nOptionStatus checkOptionValue(const HighsLogOptions& report_log_options,\n                              OptionRecordInt& option_records,\n                              const HighsInt value);\nOptionStatus checkOptionValue(const HighsLogOptions& report_log_options,\n                              OptionRecordDouble& option_records,\n                              const double value);\nOptionStatus checkOptionValue(const HighsLogOptions& report_log_options,\n                              OptionRecordString& option_records,\n                              const std::string value);\n\nOptionStatus setLocalOptionValue(const HighsLogOptions& report_log_options,\n                                 const std::string& name,\n                                 std::vector<OptionRecord*>& option_records,\n                                 const bool value);\n\nOptionStatus setLocalOptionValue(const HighsLogOptions& report_log_options,\n                                 const std::string& name,\n                                 std::vector<OptionRecord*>& option_records,\n                                 const HighsInt value);\n#ifdef HIGHSINT64\ninline OptionStatus setLocalOptionValue(\n    const HighsLogOptions& report_log_options, const std::string& name,\n    std::vector<OptionRecord*>& option_records, const int value) {\n  return setLocalOptionValue(report_log_options, name, option_records,\n                             HighsInt{value});\n}\n#endif\nOptionStatus setLocalOptionValue(const HighsLogOptions& report_log_options,\n                                 const std::string& name,\n                                 std::vector<OptionRecord*>& option_records,\n                                 const double value);\nOptionStatus setLocalOptionValue(const HighsLogOptions& report_log_options,\n                                 const std::string& name,\n                                 HighsLogOptions& log_options,\n                                 std::vector<OptionRecord*>& option_records,\n                                 const std::string value);\nOptionStatus setLocalOptionValue(const HighsLogOptions& report_log_options,\n                                 const std::string& name,\n                                 HighsLogOptions& log_options,\n                                 std::vector<OptionRecord*>& option_records,\n                                 const char* value);\n\nOptionStatus setLocalOptionValue(OptionRecordBool& option, const bool value);\nOptionStatus setLocalOptionValue(const HighsLogOptions& report_log_options,\n                                 OptionRecordInt& option, const HighsInt value);\nOptionStatus setLocalOptionValue(const HighsLogOptions& report_log_options,\n                                 OptionRecordDouble& option,\n                                 const double value);\nOptionStatus setLocalOptionValue(const HighsLogOptions& report_log_options,\n                                 OptionRecordString& option,\n                                 std::string const value);\n\nOptionStatus passLocalOptions(const HighsLogOptions& report_log_options,\n                              const HighsOptions& from_options,\n                              HighsOptions& to_options);\n\nOptionStatus getLocalOptionValues(\n    const HighsLogOptions& report_log_options, const std::string& name,\n    const std::vector<OptionRecord*>& option_records, bool* current_value,\n    bool* default_value = nullptr);\nOptionStatus getLocalOptionValues(\n    const HighsLogOptions& report_log_options, const std::string& name,\n    const std::vector<OptionRecord*>& option_records, HighsInt* current_value,\n    HighsInt* min_value = nullptr, HighsInt* max_value = nullptr,\n    HighsInt* default_value = nullptr);\nOptionStatus getLocalOptionValues(\n    const HighsLogOptions& report_log_options, const std::string& name,\n    const std::vector<OptionRecord*>& option_records, double* current_value,\n    double* min_value = nullptr, double* max_value = nullptr,\n    double* default_value = nullptr);\nOptionStatus getLocalOptionValues(\n    const HighsLogOptions& report_log_options, const std::string& name,\n    const std::vector<OptionRecord*>& option_records,\n    std::string* current_value, std::string* default_value = nullptr);\n\nOptionStatus getLocalOptionType(\n    const HighsLogOptions& report_log_options, const std::string& name,\n    const std::vector<OptionRecord*>& option_records,\n    HighsOptionType* type = nullptr);\n\nvoid resetLocalOptions(std::vector<OptionRecord*>& option_records);\n\nHighsStatus writeOptionsToFile(\n    FILE* file, const HighsLogOptions& report_log_options,\n    const std::vector<OptionRecord*>& option_records,\n    const bool report_only_deviations = false,\n    const HighsFileType file_type = HighsFileType::kFull);\nvoid reportOptions(FILE* file, const HighsLogOptions& report_log_options,\n                   const std::vector<OptionRecord*>& option_records,\n                   const bool report_only_deviations = false,\n                   const HighsFileType file_type = HighsFileType::kFull);\nvoid reportOption(FILE* file, const HighsLogOptions& report_log_options,\n                  const OptionRecordBool& option,\n                  const bool report_only_deviations,\n                  const HighsFileType file_type);\nvoid reportOption(FILE* file, const HighsLogOptions& report_log_options,\n                  const OptionRecordInt& option,\n                  const bool report_only_deviations,\n                  const HighsFileType file_type);\nvoid reportOption(FILE* file, const HighsLogOptions& report_log_options,\n                  const OptionRecordDouble& option,\n                  const bool report_only_deviations,\n                  const HighsFileType file_type);\nvoid reportOption(FILE* file, const HighsLogOptions& report_log_options,\n                  const OptionRecordString& option,\n                  const bool report_only_deviations,\n                  const HighsFileType file_type);\n\nconst string kSimplexString = \"simplex\";\nconst string kIpmString = \"ipm\";\nconst string kHipoString = \"hipo\";\nconst string kIpxString = \"ipx\";\nconst string kPdlpString = \"pdlp\";\n\nconst HighsInt kKeepNRowsDeleteRows = -1;\nconst HighsInt kKeepNRowsDeleteEntries = 0;\nconst HighsInt kKeepNRowsKeepRows = 1;\n\n// Strings for command line options\nconst string kModelFileString = \"model_file\";\nconst string kReadBasisFileString = \"read_basis_file\";\nconst string kWriteBasisFileString = \"write_basis_file\";\nconst string kPresolveString = \"presolve\";\nconst string kSolverString = \"solver\";\nconst string kParallelString = \"parallel\";\nconst string kRunCrossoverString = \"run_crossover\";\nconst string kTimeLimitString = \"time_limit\";\nconst string kOptionsFileString = \"options_file\";\nconst string kRandomSeedString = \"random_seed\";\nconst string kWriteSolutionFileString = \"solution_file\";\nconst string kRangingString = \"ranging\";\nconst string kVersionString = \"version\";\nconst string kWriteModelFileString = \"write_model_file\";\nconst string kWritePresolvedModelFileString = \"write_presolved_model_file\";\nconst string kWriteIisModelFileString = \"write_iis_model_file\";\nconst string kReadSolutionFileString = \"read_solution_file\";\n\n// String for HiGHS log file option\nconst string kLogFileString = \"log_file\";\n\n// Strings for HiPO system option\nconst string kHipoSystemString = \"hipo_system\";\nconst string kHipoAugmentedString = \"augmented\";\nconst string kHipoNormalEqString = \"normaleq\";\n\n// Strings for MIP LP/IPM options\nconst string kMipLpSolverString = \"mip_lp_solver\";\nconst string kMipIpmSolverString = \"mip_ipm_solver\";\n// Strings for HiPO parallel method\nconst string kHipoParallelString = \"hipo_parallel_type\";\nconst string kHipoTreeString = \"tree\";\nconst string kHipoNodeString = \"node\";\nconst string kHipoBothString = \"both\";\n\nstruct HighsOptionsStruct {\n  // Run-time options read from the command line\n  std::string presolve;\n  std::string solver;\n  std::string parallel;\n  std::string run_crossover;\n  double time_limit;\n  std::string read_solution_file;\n  std::string read_basis_file;\n  std::string write_model_file;\n  std::string solution_file;\n  std::string write_basis_file;\n  HighsInt random_seed;\n  std::string ranging;\n\n  // Options read from the file\n  double infinite_cost;\n  double infinite_bound;\n  double small_matrix_value;\n  double large_matrix_value;\n  double kkt_tolerance;\n  double primal_feasibility_tolerance;\n  double dual_feasibility_tolerance;\n  double primal_residual_tolerance;\n  double dual_residual_tolerance;\n  double optimality_tolerance;\n  double objective_bound;\n  double objective_target;\n  HighsInt threads;\n  HighsInt user_objective_scale;\n  HighsInt user_bound_scale;\n  HighsInt highs_debug_level;\n  HighsInt highs_analysis_level;\n  HighsInt simplex_strategy;\n  HighsInt simplex_scale_strategy;\n  HighsInt simplex_crash_strategy;\n  HighsInt simplex_dual_edge_weight_strategy;\n  HighsInt simplex_primal_edge_weight_strategy;\n  HighsInt simplex_iteration_limit;\n  HighsInt simplex_update_limit;\n  HighsInt simplex_min_concurrency;\n  HighsInt simplex_max_concurrency;\n\n  std::string log_file;\n  // Three bools are deprecated: remove in V2.0\n  bool write_model_to_file;\n  bool write_presolved_model_to_file;\n  bool write_solution_to_file;\n\n  HighsInt write_solution_style;\n  HighsInt glpsol_cost_row_location;\n  std::string write_presolved_model_file;\n  std::string write_iis_model_file;\n\n  // Control of HiGHS log\n  bool output_flag;\n  bool log_to_console;\n  bool timeless_log;\n\n  // Options for IPM solver\n  double ipm_optimality_tolerance;\n  HighsInt ipm_iteration_limit;\n  std::string hipo_system;\n  std::string hipo_parallel_type;\n  HighsInt hipo_block_size;\n\n  // Options for PDLP solver\n  bool pdlp_scaling;\n  HighsInt pdlp_iteration_limit;\n  HighsInt pdlp_e_restart_method;\n  double pdlp_optimality_tolerance;\n\n  // Options for QP solver\n  HighsInt qp_iteration_limit;\n  HighsInt qp_nullspace_limit;\n  double qp_regularization_value;\n\n  // Options for IIS calculation\n  HighsInt iis_strategy;\n\n  // Option for multi-objective optimization\n  bool blend_multi_objectives;\n\n  // Advanced options\n  HighsInt log_dev_level;\n  bool log_githash;\n  bool solve_relaxation;\n  bool allow_unbounded_or_infeasible;\n  bool use_implied_bounds_from_presolve;\n  bool lp_presolve_requires_basis_postsolve;\n  bool mps_parser_type_free;\n  bool use_warm_start;\n  HighsInt keep_n_rows;\n  HighsInt cost_scale_factor;\n  HighsInt allowed_matrix_scale_factor;\n  HighsInt allowed_cost_scale_factor;\n  HighsInt ipx_dualize_strategy;\n  HighsInt simplex_dualize_strategy;\n  HighsInt simplex_permute_strategy;\n  HighsInt max_dual_simplex_cleanup_level;\n  HighsInt max_dual_simplex_phase1_cleanup_level;\n  HighsInt simplex_price_strategy;\n  HighsInt simplex_unscaled_solution_strategy;\n  HighsInt presolve_reduction_limit;\n  HighsInt restart_presolve_reduction_limit;\n  HighsInt presolve_substitution_maxfillin;\n  HighsInt presolve_rule_off;\n  bool presolve_rule_logging;\n  bool presolve_remove_slacks;\n  bool simplex_initial_condition_check;\n  bool no_unnecessary_rebuild_refactor;\n  double simplex_initial_condition_tolerance;\n  double rebuild_refactor_solution_error_tolerance;\n  double dual_steepest_edge_weight_error_tolerance;\n  double dual_steepest_edge_weight_log_error_threshold;\n  double dual_simplex_cost_perturbation_multiplier;\n  double primal_simplex_bound_perturbation_multiplier;\n  double dual_simplex_pivot_growth_tolerance;\n  double presolve_pivot_threshold;\n  double factor_pivot_threshold;\n  double factor_pivot_tolerance;\n  double start_crossover_tolerance;\n  bool less_infeasible_DSE_check;\n  bool less_infeasible_DSE_choose_row;\n  bool use_original_HFactor_logic;\n  //  bool allow_pdlp_cleanup;\n  bool run_centring;\n  HighsInt max_centring_steps;\n  double centring_ratio_tolerance;\n\n  // Options for iCrash\n  bool icrash;\n  bool icrash_dualize;\n  std::string icrash_strategy;\n  double icrash_starting_weight;\n  HighsInt icrash_iterations;\n  HighsInt icrash_approx_iter;\n  bool icrash_exact;\n  bool icrash_breakpoints;\n\n  // Options for MIP solver\n  bool mip_detect_symmetry;\n  bool mip_allow_restart;\n  HighsInt mip_max_nodes;\n  HighsInt mip_max_stall_nodes;\n  HighsInt mip_max_start_nodes;\n  HighsInt mip_max_leaves;\n  HighsInt mip_max_improving_sols;\n  HighsInt mip_lp_age_limit;\n  HighsInt mip_pool_age_limit;\n  HighsInt mip_pool_soft_limit;\n  HighsInt mip_pscost_minreliable;\n  HighsInt mip_min_cliquetable_entries_for_parallelism;\n  HighsInt mip_report_level;\n  double mip_feasibility_tolerance;\n  double mip_rel_gap;\n  double mip_abs_gap;\n  double mip_heuristic_effort;\n  bool mip_heuristic_run_feasibility_jump;\n  bool mip_heuristic_run_rins;\n  bool mip_heuristic_run_rens;\n  bool mip_heuristic_run_root_reduced_cost;\n  bool mip_heuristic_run_zi_round;\n  bool mip_heuristic_run_shifting;\n  double mip_min_logging_interval;\n  std::string mip_lp_solver;\n  std::string mip_ipm_solver;\n\n#ifdef HIGHS_DEBUGSOL\n  std::string mip_debug_solution_file;\n#endif\n  bool mip_improving_solution_save;\n  bool mip_improving_solution_report_sparse;\n  std::string mip_improving_solution_file;\n  bool mip_root_presolve_only;\n  HighsInt mip_lifting_for_probing;\n\n  // Logging callback identifiers\n  HighsLogOptions log_options;\n  virtual ~HighsOptionsStruct() {}\n\n  HighsOptionsStruct()\n      : presolve(\"\"),\n        solver(\"\"),\n        parallel(\"\"),\n        run_crossover(\"\"),\n        time_limit(0.0),\n        read_solution_file(\"\"),\n        read_basis_file(\"\"),\n        write_model_file(\"\"),\n        solution_file(\"\"),\n        write_basis_file(\"\"),\n        random_seed(0),\n        ranging(\"\"),\n        infinite_cost(0.0),\n        infinite_bound(0.0),\n        small_matrix_value(0.0),\n        large_matrix_value(0.0),\n        kkt_tolerance(0.0),\n        primal_feasibility_tolerance(0.0),\n        dual_feasibility_tolerance(0.0),\n        primal_residual_tolerance(0.0),\n        dual_residual_tolerance(0.0),\n        optimality_tolerance(0.0),\n        objective_bound(0.0),\n        objective_target(0.0),\n        threads(0),\n        user_objective_scale(0),\n        user_bound_scale(0),\n        highs_debug_level(0),\n        highs_analysis_level(0),\n        simplex_strategy(0),\n        simplex_scale_strategy(0),\n        simplex_crash_strategy(0),\n        simplex_dual_edge_weight_strategy(0),\n        simplex_primal_edge_weight_strategy(0),\n        simplex_iteration_limit(0),\n        simplex_update_limit(0),\n        simplex_min_concurrency(0),\n        simplex_max_concurrency(0),\n        log_file(\"\"),\n        write_model_to_file(false),\n        write_presolved_model_to_file(false),\n        write_solution_to_file(false),\n        write_solution_style(0),\n        glpsol_cost_row_location(0),\n        write_presolved_model_file(\"\"),\n        write_iis_model_file(\"\"),\n        output_flag(false),\n        log_to_console(false),\n        timeless_log(false),\n        ipm_optimality_tolerance(0.0),\n        ipm_iteration_limit(0),\n        hipo_system(\"\"),\n        hipo_parallel_type(\"\"),\n        hipo_block_size(0),\n        pdlp_scaling(false),\n        pdlp_iteration_limit(0),\n        pdlp_e_restart_method(0),\n        pdlp_optimality_tolerance(0.0),\n        qp_iteration_limit(0),\n        qp_nullspace_limit(0),\n        qp_regularization_value(0),\n        iis_strategy(0),\n        blend_multi_objectives(false),\n        log_dev_level(0),\n        log_githash(false),\n        solve_relaxation(false),\n        allow_unbounded_or_infeasible(false),\n        use_implied_bounds_from_presolve(false),\n        lp_presolve_requires_basis_postsolve(false),\n        mps_parser_type_free(false),\n        use_warm_start(true),\n        keep_n_rows(0),\n        cost_scale_factor(0),\n        allowed_matrix_scale_factor(0),\n        allowed_cost_scale_factor(0),\n        ipx_dualize_strategy(0),\n        simplex_dualize_strategy(0),\n        simplex_permute_strategy(0),\n        max_dual_simplex_cleanup_level(0),\n        max_dual_simplex_phase1_cleanup_level(0),\n        simplex_price_strategy(0),\n        simplex_unscaled_solution_strategy(0),\n        presolve_reduction_limit(0),\n        restart_presolve_reduction_limit(0),\n        presolve_substitution_maxfillin(0),\n        presolve_rule_off(0),\n        presolve_rule_logging(false),\n        presolve_remove_slacks(false),\n        simplex_initial_condition_check(false),\n        no_unnecessary_rebuild_refactor(false),\n        simplex_initial_condition_tolerance(0.0),\n        rebuild_refactor_solution_error_tolerance(0.0),\n        dual_steepest_edge_weight_error_tolerance(0.0),\n        dual_steepest_edge_weight_log_error_threshold(0.0),\n        dual_simplex_cost_perturbation_multiplier(0.0),\n        primal_simplex_bound_perturbation_multiplier(0.0),\n        dual_simplex_pivot_growth_tolerance(0.0),\n        presolve_pivot_threshold(0.0),\n        factor_pivot_threshold(0.0),\n        factor_pivot_tolerance(0.0),\n        start_crossover_tolerance(0.0),\n        less_infeasible_DSE_check(false),\n        less_infeasible_DSE_choose_row(false),\n        use_original_HFactor_logic(false),\n        //        allow_pdlp_cleanup(false),\n        run_centring(false),\n        max_centring_steps(0),\n        centring_ratio_tolerance(0.0),\n        icrash(false),\n        icrash_dualize(false),\n        icrash_strategy(\"\"),\n        icrash_starting_weight(0.0),\n        icrash_iterations(0),\n        icrash_approx_iter(0),\n        icrash_exact(false),\n        icrash_breakpoints(false),\n        mip_detect_symmetry(false),\n        mip_allow_restart(false),\n        mip_max_nodes(0),\n        mip_max_stall_nodes(0),\n        mip_max_start_nodes(0),\n        mip_max_leaves(0),\n        mip_max_improving_sols(0),\n        mip_lp_age_limit(0),\n        mip_pool_age_limit(0),\n        mip_pool_soft_limit(0),\n        mip_pscost_minreliable(0),\n        mip_min_cliquetable_entries_for_parallelism(0),\n        mip_report_level(0),\n        mip_feasibility_tolerance(0.0),\n        mip_rel_gap(0.0),\n        mip_abs_gap(0.0),\n        mip_heuristic_effort(0.0),\n        mip_heuristic_run_feasibility_jump(false),\n        mip_heuristic_run_rins(false),\n        mip_heuristic_run_rens(false),\n        mip_heuristic_run_root_reduced_cost(false),\n        mip_heuristic_run_zi_round(false),\n        mip_heuristic_run_shifting(false),\n        mip_min_logging_interval(0.0),\n#ifdef HIGHS_DEBUGSOL\n        mip_debug_solution_file(\"\"),\n#endif\n        mip_improving_solution_save(false),\n        mip_improving_solution_report_sparse(false),\n        // clang-format off\n        mip_improving_solution_file(\"\"),\n        mip_root_presolve_only(false),\n        mip_lifting_for_probing(-1) {};\n  // clang-format on\n};\n\n// For now, but later change so HiGHS properties are string based so that new\n// options (for debug and testing too) can be added easily. The options below\n// are just what has been used to parse options from argv.\n// todo: when creating the new options don't forget underscores for class\n// variables but no underscores for struct\nclass HighsOptions : public HighsOptionsStruct {\n public:\n  HighsOptions() {\n    initRecords();\n    setLogOptions();\n  }\n\n  HighsOptions(const HighsOptions& options) {\n    initRecords();\n    HighsOptionsStruct::operator=(options);\n    setLogOptions();\n  }\n\n  HighsOptions(HighsOptions&& options) {\n    records = std::move(options.records);\n    HighsOptionsStruct::operator=(std::move(options));\n    this->log_options.log_stream = options.log_options.log_stream;\n    setLogOptions();\n  }\n\n  const HighsOptions& operator=(const HighsOptions& other) {\n    if (&other != this) {\n      if ((HighsInt)records.size() == 0) initRecords();\n      HighsOptionsStruct::operator=(other);\n      this->log_options.log_stream = other.log_options.log_stream;\n      setLogOptions();\n    }\n    return *this;\n  }\n\n  const HighsOptions& operator=(HighsOptions&& other) {\n    if (&other != this) {\n      if ((HighsInt)records.size() == 0) initRecords();\n      HighsOptionsStruct::operator=(other);\n      this->log_options.log_stream = other.log_options.log_stream;\n      setLogOptions();\n    }\n    return *this;\n  }\n\n  virtual ~HighsOptions() {\n    if (records.size() > 0) deleteRecords();\n  }\n\n private:\n  void initRecords() {\n    OptionRecordBool* record_bool;\n    OptionRecordInt* record_int;\n    OptionRecordDouble* record_double;\n    OptionRecordString* record_string;\n    bool advanced = false;\n    const bool now_advanced = true;\n    // Options read from the command line\n    record_string = new OptionRecordString(\n        kPresolveString, \"Presolve option: \\\"off\\\", \\\"choose\\\" or \\\"on\\\"\",\n        advanced, &presolve, kHighsChooseString);\n    records.push_back(record_string);\n\n    record_string =\n        new OptionRecordString(kSolverString,\n                               \"LP solver option: \\\"choose\\\", \\\"simplex\\\", \"\n                               \"\\\"ipm\\\", \\\"ipx\\\", \\\"hipo\\\" or \\\"pdlp\\\"\",\n                               advanced, &solver, kHighsChooseString);\n    records.push_back(record_string);\n\n    record_string = new OptionRecordString(\n        kParallelString, \"Parallel option: \\\"off\\\", \\\"choose\\\" or \\\"on\\\"\",\n        advanced, &parallel, kHighsChooseString);\n    records.push_back(record_string);\n\n    record_string = new OptionRecordString(\n        kRunCrossoverString, \"Run IPM crossover: \\\"off\\\", \\\"choose\\\" or \\\"on\\\"\",\n        advanced, &run_crossover, kHighsOnString);\n    records.push_back(record_string);\n\n    record_double =\n        new OptionRecordDouble(kTimeLimitString, \"Time limit (seconds)\",\n                               advanced, &time_limit, 0, kHighsInf, kHighsInf);\n    records.push_back(record_double);\n\n    record_string =\n        new OptionRecordString(kRangingString,\n                               \"Compute cost, bound, RHS and basic solution \"\n                               \"ranging: \\\"off\\\" or \\\"on\\\"\",\n                               advanced, &ranging, kHighsOffString);\n    records.push_back(record_string);\n    //\n    // Options read from the file\n    record_double = new OptionRecordDouble(\n        \"infinite_cost\",\n        \"Limit on |cost coefficient|: values greater than or equal to \"\n        \"this will be treated as infinite\",\n        advanced, &infinite_cost, 1e15, 1e20, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"infinite_bound\",\n        \"Limit on |constraint bound|: values greater than or equal to \"\n        \"this will be treated as infinite\",\n        advanced, &infinite_bound, 1e15, 1e20, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"small_matrix_value\",\n        \"Lower limit on |matrix entries|: values less than or equal to this \"\n        \"will be \"\n        \"treated as zero\",\n        advanced, &small_matrix_value, 1e-12, 1e-9, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"large_matrix_value\",\n        \"Upper limit on |matrix entries|: values greater than or equal to \"\n        \"this will be treated as infinite\",\n        advanced, &large_matrix_value, 1e0, 1e15, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"kkt_tolerance\",\n        \"If changed from its default value, this tolerance is used for all \"\n        \"feasibility and optimality (KKT) measures\",\n        advanced, &kkt_tolerance, 1e-10, kDefaultKktTolerance, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"primal_feasibility_tolerance\", \"Primal feasibility tolerance\",\n        advanced, &primal_feasibility_tolerance, 1e-10, kDefaultKktTolerance,\n        kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"dual_feasibility_tolerance\", \"Dual feasibility tolerance\", advanced,\n        &dual_feasibility_tolerance, 1e-10, kDefaultKktTolerance, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"primal_residual_tolerance\", \"Primal residual tolerance\", advanced,\n        &primal_residual_tolerance, 1e-10, kDefaultKktTolerance, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"dual_residual_tolerance\", \"Dual residual tolerance\", advanced,\n        &dual_residual_tolerance, 1e-10, kDefaultKktTolerance, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"optimality_tolerance\", \"Optimality tolerance\", advanced,\n        &optimality_tolerance, 1e-10, kDefaultKktTolerance, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"objective_bound\",\n        \"Objective bound for termination of the dual simplex solver\", advanced,\n        &objective_bound, -kHighsInf, kHighsInf, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"objective_target\",\n        \"Objective target for termination of the MIP solver\", advanced,\n        //\"primal simplex and \"\n        &objective_target, -kHighsInf, -kHighsInf, kHighsInf);\n    records.push_back(record_double);\n\n    record_int =\n        new OptionRecordInt(kRandomSeedString, \"Random seed used in HiGHS\",\n                            advanced, &random_seed, 0, 0, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"threads\", \"Number of threads used by HiGHS (0: automatic)\", advanced,\n        &threads, 0, 0, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"user_objective_scale\",\n        \"Exponent of power-of-two objective scaling for model\", advanced,\n        &user_objective_scale, -kHighsIInf, 0, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"user_bound_scale\", \"Exponent of power-of-two bound scaling for model\",\n        advanced, &user_bound_scale, -kHighsIInf, 0, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\"highs_debug_level\",\n                                     \"Debugging level in HiGHS\", now_advanced,\n                                     &highs_debug_level, kHighsDebugLevelMin,\n                                     kHighsDebugLevelMin, kHighsDebugLevelMax);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"highs_analysis_level\", \"Analysis level in HiGHS\", now_advanced,\n        &highs_analysis_level, kHighsAnalysisLevelMin,\n        kHighsAnalysisLevelMin,  // kHighsAnalysisLevelMipTime,  //\n        kHighsAnalysisLevelMax);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"simplex_strategy\",\n        \"Strategy for simplex solver 0 => Choose; 1 => Dual (serial); 2 => \"\n        \"Dual (SIP); 3 => Dual (PAMI); 4 => Primal\",\n        advanced, &simplex_strategy, kSimplexStrategyMin, kSimplexStrategyDual,\n        kSimplexStrategyMax);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"simplex_scale_strategy\",\n        \"Simplex scaling strategy: off / choose / equilibration (default) / \"\n        \"forced \"\n        \"equilibration / max value (0/1/2/3/4)\",\n        advanced, &simplex_scale_strategy, kSimplexScaleStrategyMin,\n        kSimplexScaleStrategyEquilibration, kSimplexScaleStrategyMax);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"simplex_crash_strategy\",\n        \"Strategy for simplex crash: off / LTSSF / Bixby (0/1/2)\", now_advanced,\n        &simplex_crash_strategy, kSimplexCrashStrategyMin,\n        kSimplexCrashStrategyOff, kSimplexCrashStrategyMax);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"simplex_dual_edge_weight_strategy\",\n        \"Strategy for simplex dual edge weights: Choose / \"\n        \"Dantzig / Devex / Steepest \"\n        \"Edge (-1/0/1/2)\",\n        advanced, &simplex_dual_edge_weight_strategy,\n        kSimplexEdgeWeightStrategyMin, kSimplexEdgeWeightStrategyChoose,\n        kSimplexEdgeWeightStrategyMax);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"simplex_primal_edge_weight_strategy\",\n        \"Strategy for simplex primal edge weights: Choose \"\n        \"/ Dantzig / Devex / Steepest \"\n        \"Edge (-1/0/1/2)\",\n        advanced, &simplex_primal_edge_weight_strategy,\n        kSimplexEdgeWeightStrategyMin, kSimplexEdgeWeightStrategyChoose,\n        kSimplexEdgeWeightStrategyMax);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"simplex_iteration_limit\",\n        \"Iteration limit for simplex solver when solving LPs, but not \"\n        \"subproblems in the MIP solver\",\n        advanced, &simplex_iteration_limit, 0, kHighsIInf, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"simplex_update_limit\",\n        \"Limit on the number of simplex UPDATE operations\", advanced,\n        &simplex_update_limit, 0, 5000, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"simplex_min_concurrency\",\n        \"Minimum level of concurrency in parallel simplex\", now_advanced,\n        &simplex_min_concurrency, 1, 1, kSimplexConcurrencyLimit);\n    records.push_back(record_int);\n\n    record_int =\n        new OptionRecordInt(\"simplex_max_concurrency\",\n                            \"Maximum level of concurrency in parallel simplex\",\n                            advanced, &simplex_max_concurrency, 1,\n                            kSimplexConcurrencyLimit, kSimplexConcurrencyLimit);\n    records.push_back(record_int);\n\n    record_bool =\n        new OptionRecordBool(\"output_flag\", \"Enables or disables solver output\",\n                             advanced, &output_flag, true);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\"log_to_console\",\n                                       \"Enables or disables console logging\",\n                                       advanced, &log_to_console, true);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\n        \"timeless_log\", \"Suppression of time-based data in logging\", true,\n        &timeless_log, false);\n    records.push_back(record_bool);\n\n    record_string = new OptionRecordString(kLogFileString, \"Log file\", advanced,\n                                           &log_file, \"\");\n    records.push_back(record_string);\n\n    record_bool =\n        new OptionRecordBool(\"write_model_to_file\", \"Write the model to a file\",\n                             advanced, &write_model_to_file, false);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\n        \"write_presolved_model_to_file\", \"Write the presolved model to a file\",\n        advanced, &write_presolved_model_to_file, false);\n    records.push_back(record_bool);\n\n    record_bool =\n        new OptionRecordBool(\"write_solution_to_file\",\n                             \"Write the primal and dual solution to a file\",\n                             advanced, &write_solution_to_file, false);\n    records.push_back(record_bool);\n\n    record_int = new OptionRecordInt(\n        \"write_solution_style\",\n        \"Style of solution file (raw = computer-readable, \"\n        \"pretty = human-readable): \"\n        \"-1 => HiGHS old raw (deprecated); 0 => HiGHS raw; \"\n        \"1 => HiGHS pretty; 2 => Glpsol raw; 3 => Glpsol pretty; \"\n        \"4 => HiGHS sparse raw\",\n        advanced, &write_solution_style, kSolutionStyleMin, kSolutionStyleRaw,\n        kSolutionStyleMax);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"glpsol_cost_row_location\",\n        \"Location of cost row for Glpsol file: \"\n        \"-2 => Last; -1 => None; 0 => None if empty, otherwise data file \"\n        \"location; 1 <= n <= num_row => Location n; n > \"\n        \"num_row => Last\",\n        advanced, &glpsol_cost_row_location, kGlpsolCostRowLocationMin, 0,\n        kHighsIInf);\n    records.push_back(record_int);\n\n    record_bool = new OptionRecordBool(\"icrash\", \"Run iCrash\", now_advanced,\n                                       &icrash, false);\n    records.push_back(record_bool);\n\n    record_bool =\n        new OptionRecordBool(\"icrash_dualize\", \"Dualize strategy for iCrash\",\n                             now_advanced, &icrash_dualize, false);\n    records.push_back(record_bool);\n\n    record_string =\n        new OptionRecordString(\"icrash_strategy\", \"Strategy for iCrash\",\n                               now_advanced, &icrash_strategy, \"ICA\");\n    records.push_back(record_string);\n\n    record_double = new OptionRecordDouble(\n        \"icrash_starting_weight\", \"iCrash starting weight\", now_advanced,\n        &icrash_starting_weight, 1e-10, 1e-3, 1e50);\n    records.push_back(record_double);\n\n    record_int =\n        new OptionRecordInt(\"icrash_iterations\", \"iCrash iterations\",\n                            now_advanced, &icrash_iterations, 0, 30, 200);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"icrash_approx_iter\", \"iCrash approximate minimization iterations\",\n        now_advanced, &icrash_approx_iter, 0, 50, 100);\n    records.push_back(record_int);\n\n    record_bool = new OptionRecordBool(\"icrash_exact\",\n                                       \"Exact subproblem solution for iCrash\",\n                                       now_advanced, &icrash_exact, false);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\n        \"icrash_breakpoints\", \"Exact subproblem solution for iCrash\",\n        now_advanced, &icrash_breakpoints, false);\n    records.push_back(record_bool);\n\n    record_string = new OptionRecordString(\n        kReadSolutionFileString, \"Read solution file\", advanced,\n        &read_solution_file, kHighsFilenameDefault);\n    records.push_back(record_string);\n\n    record_string = new OptionRecordString(\n        kReadBasisFileString, \"Read basis file\", advanced, &read_basis_file,\n        kHighsFilenameDefault);\n    records.push_back(record_string);\n\n    record_string = new OptionRecordString(\n        kWriteModelFileString, \"Write model file\", advanced, &write_model_file,\n        kHighsFilenameDefault);\n    records.push_back(record_string);\n\n    record_string =\n        new OptionRecordString(kWriteSolutionFileString, \"Write solution file\",\n                               advanced, &solution_file, kHighsFilenameDefault);\n    records.push_back(record_string);\n\n    record_string = new OptionRecordString(\n        kWriteBasisFileString, \"Write basis file\", advanced, &write_basis_file,\n        kHighsFilenameDefault);\n    records.push_back(record_string);\n\n    record_string = new OptionRecordString(\n        kWritePresolvedModelFileString, \"Write presolved model file\", advanced,\n        &write_presolved_model_file, kHighsFilenameDefault);\n    records.push_back(record_string);\n\n    record_string = new OptionRecordString(\n        kWriteIisModelFileString, \"Write IIS model file\", advanced,\n        &write_iis_model_file, kHighsFilenameDefault);\n    records.push_back(record_string);\n\n    record_bool = new OptionRecordBool(\n        \"mip_detect_symmetry\", \"Whether MIP symmetry should be detected\",\n        advanced, &mip_detect_symmetry, true);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\"mip_allow_restart\",\n                                       \"Whether MIP restart is permitted\",\n                                       advanced, &mip_allow_restart, true);\n    records.push_back(record_bool);\n\n    record_int = new OptionRecordInt(\"mip_max_nodes\",\n                                     \"MIP solver max number of nodes\", advanced,\n                                     &mip_max_nodes, 0, kHighsIInf, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"mip_max_stall_nodes\",\n        \"MIP solver max number of nodes where estimate is above cutoff bound\",\n        advanced, &mip_max_stall_nodes, 0, kHighsIInf, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"mip_max_start_nodes\",\n        \"MIP solver max number of nodes when completing a partial MIP start\",\n        advanced, &mip_max_start_nodes, 0, 500, kHighsIInf);\n    records.push_back(record_int);\n\n#ifdef HIGHS_DEBUGSOL\n    record_string = new OptionRecordString(\n        \"mip_debug_solution_file\",\n        \"Solution file for debug solution of the MIP solver\", advanced,\n        &mip_debug_solution_file, kHighsFilenameDefault);\n    records.push_back(record_string);\n#endif\n\n    record_bool =\n        new OptionRecordBool(\"mip_improving_solution_save\",\n                             \"Whether improving MIP solutions should be saved\",\n                             advanced, &mip_improving_solution_save, false);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\n        \"mip_improving_solution_report_sparse\",\n        \"Whether improving MIP solutions should be reported in sparse format\",\n        advanced, &mip_improving_solution_report_sparse, false);\n    records.push_back(record_bool);\n\n    record_string = new OptionRecordString(\n        \"mip_improving_solution_file\",\n        \"File for reporting improving MIP solutions: not reported for an empty \"\n        \"string \\\\\\\"\\\\\\\"\",\n        advanced, &mip_improving_solution_file, kHighsFilenameDefault);\n    records.push_back(record_string);\n\n    record_bool = new OptionRecordBool(\n        \"mip_root_presolve_only\",\n        \"Whether MIP presolve is only applied at the root node\", advanced,\n        &mip_root_presolve_only, false);\n    records.push_back(record_bool);\n\n    record_int = new OptionRecordInt(\n        \"mip_lifting_for_probing\", \"Level of lifting for probing that is used\",\n        advanced, &mip_lifting_for_probing, -1, -1, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"mip_max_leaves\", \"MIP solver max number of leaf nodes\", advanced,\n        &mip_max_leaves, 0, kHighsIInf, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"mip_max_improving_sols\",\n        \"Limit on the number of improving solutions found to stop the MIP \"\n        \"solver prematurely\",\n        advanced, &mip_max_improving_sols, 1, kHighsIInf, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"mip_lp_age_limit\",\n        \"Maximal age of dynamic LP rows before \"\n        \"they are removed from the LP relaxation in the MIP solver\",\n        advanced, &mip_lp_age_limit, 0, 10,\n        std::numeric_limits<int16_t>::max());\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"mip_pool_age_limit\",\n        \"Maximal age of rows in the MIP solver cutpool before they are deleted\",\n        advanced, &mip_pool_age_limit, 0, 30, 1000);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"mip_pool_soft_limit\",\n        \"Soft limit on the number of rows in the \"\n        \"MIP solver cutpool for dynamic age adjustment\",\n        advanced, &mip_pool_soft_limit, 1, 10000, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"mip_pscost_minreliable\",\n        \"Minimal number of observations before \"\n        \"MIP solver pseudo costs are considered reliable\",\n        advanced, &mip_pscost_minreliable, 0, 8, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"mip_min_cliquetable_entries_for_parallelism\",\n        \"Minimal number of entries in the MIP solver cliquetable before \"\n        \"neighbourhood \"\n        \"queries of the conflict graph use parallel processing\",\n        advanced, &mip_min_cliquetable_entries_for_parallelism, 0, 100000,\n        kHighsIInf);\n    records.push_back(record_int);\n\n    record_int =\n        new OptionRecordInt(\"mip_report_level\", \"MIP solver reporting level\",\n                            now_advanced, &mip_report_level, 0, 1, 2);\n    records.push_back(record_int);\n\n    record_double = new OptionRecordDouble(\n        \"mip_feasibility_tolerance\", \"MIP integrality tolerance\", advanced,\n        &mip_feasibility_tolerance, 1e-10, 1e-6, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"mip_heuristic_effort\", \"Effort spent for MIP heuristics\", advanced,\n        &mip_heuristic_effort, 0.0, 0.05, 1.0);\n    records.push_back(record_double);\n\n    record_bool =\n        new OptionRecordBool(\"mip_heuristic_run_feasibility_jump\",\n                             \"Use the feasibility jump heuristic\", advanced,\n                             &mip_heuristic_run_feasibility_jump, true);\n    records.push_back(record_bool);\n\n    record_bool =\n        new OptionRecordBool(\"mip_heuristic_run_rins\", \"Use the RINS heuristic\",\n                             advanced, &mip_heuristic_run_rins, true);\n    records.push_back(record_bool);\n\n    record_bool =\n        new OptionRecordBool(\"mip_heuristic_run_rens\", \"Use the RENS heuristic\",\n                             advanced, &mip_heuristic_run_rens, true);\n    records.push_back(record_bool);\n\n    record_bool =\n        new OptionRecordBool(\"mip_heuristic_run_root_reduced_cost\",\n                             \"Use the rootReducedCost heuristic\", advanced,\n                             &mip_heuristic_run_root_reduced_cost, true);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\"mip_heuristic_run_zi_round\",\n                                       \"Use the ZI Round heuristic\", advanced,\n                                       &mip_heuristic_run_zi_round, false);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\"mip_heuristic_run_shifting\",\n                                       \"Use the Shifting heuristic\", advanced,\n                                       &mip_heuristic_run_shifting, false);\n    records.push_back(record_bool);\n\n    record_double = new OptionRecordDouble(\n        \"mip_rel_gap\",\n        \"Tolerance on relative gap, |ub-lb|/|ub|, to determine whether \"\n        \"optimality has been reached for a MIP instance\",\n        advanced, &mip_rel_gap, 0.0, 1e-4, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"mip_abs_gap\",\n        \"Tolerance on absolute gap of MIP, |ub-lb|, to determine whether \"\n        \"optimality has been reached for a MIP instance\",\n        advanced, &mip_abs_gap, 0.0, 1e-6, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"mip_min_logging_interval\", \"MIP minimum logging interval\", advanced,\n        &mip_min_logging_interval, 0, 5, kHighsInf);\n    records.push_back(record_double);\n\n    record_string =\n        new OptionRecordString(kMipLpSolverString,\n                               \"MIP LP solver option: \\\"choose\\\", \\\"simplex\\\", \"\n                               \"\\\"ipm\\\", \\\"ipx\\\" or \\\"hipo\\\"\",\n                               advanced, &mip_lp_solver, kHighsChooseString);\n    records.push_back(record_string);\n\n    record_string = new OptionRecordString(\n        kMipIpmSolverString,\n        \"MIP IPM solver option: \\\"choose\\\", \\\"ipx\\\" or \\\"hipo\\\"\", advanced,\n        &mip_ipm_solver, kHighsChooseString);\n    records.push_back(record_string);\n\n    record_double = new OptionRecordDouble(\n        \"ipm_optimality_tolerance\", \"IPM optimality tolerance\", advanced,\n        &ipm_optimality_tolerance, 1e-12, 1e-1 * kDefaultKktTolerance,\n        kHighsInf);\n    records.push_back(record_double);\n\n    record_int = new OptionRecordInt(\n        \"ipm_iteration_limit\", \"Iteration limit for IPM solver\", advanced,\n        &ipm_iteration_limit, 0, kHighsIInf, kHighsIInf);\n    records.push_back(record_int);\n\n    record_string = new OptionRecordString(\n        kHipoSystemString,\n        \"HiPO Newton system option: \\\"augmented\\\", \\\"normaleq\\\" or \\\"choose\\\".\",\n        advanced, &hipo_system, kHighsChooseString);\n    records.push_back(record_string);\n\n    record_string =\n        new OptionRecordString(kHipoParallelString,\n                               \"HiPO parallel option: \\\"tree\\\", \"\n                               \"\\\"node\\\" or \\\"both\\\".\",\n                               advanced, &hipo_parallel_type, kHipoBothString);\n    records.push_back(record_string);\n\n    record_int = new OptionRecordInt(\n        \"hipo_block_size\", \"Block size for dense linear algebra within HiPO\",\n        advanced, &hipo_block_size, 0, 128, kHighsIInf);\n    records.push_back(record_int);\n\n    record_bool = new OptionRecordBool(\n        \"pdlp_scaling\", \"Scaling option for PDLP solver: Default = true\",\n        advanced, &pdlp_scaling, true);\n    records.push_back(record_bool);\n\n    record_int = new OptionRecordInt(\n        \"pdlp_iteration_limit\", \"Iteration limit for PDLP solver\", advanced,\n        &pdlp_iteration_limit, 0, kHighsIInf, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\"pdlp_e_restart_method\",\n                                     \"Restart mode for PDLP solver: 0 => none; \"\n                                     \"1 => GPU (default); 2 => CPU \",\n                                     advanced, &pdlp_e_restart_method, 0, 1, 2);\n    records.push_back(record_int);\n\n    record_double = new OptionRecordDouble(\n        \"pdlp_optimality_tolerance\", \"PDLP optimality tolerance\", advanced,\n        &pdlp_optimality_tolerance, 1e-12, kDefaultKktTolerance, kHighsInf);\n    records.push_back(record_double);\n\n    record_int = new OptionRecordInt(\n        \"qp_iteration_limit\", \"Iteration limit for QP solver\", advanced,\n        &qp_iteration_limit, 0, kHighsIInf, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\"qp_nullspace_limit\",\n                                     \"Nullspace limit for QP solver\", advanced,\n                                     &qp_nullspace_limit, 0, 4000, kHighsIInf);\n    records.push_back(record_int);\n\n    record_double = new OptionRecordDouble(\n        \"qp_regularization_value\", \"Regularization value added to the Hessian\",\n        advanced, &qp_regularization_value, 0, kHessianRegularizationValue,\n        kHighsInf);\n    records.push_back(record_double);\n\n    record_int = new OptionRecordInt(\n        \"iis_strategy\",\n        \"Strategy for IIS calculation: \"\n        //        \"Use LP and p\"\n        \"Light test / \"\n        \"Full and prioritise rows / \"\n        //        \"Use LP and p\"\n        \"Full and prioritise columns\"\n        //        \"Use unbounded dual ray and prioritise low number of rows / \"\n        //        \"Use ray and prioritise low numbers of columns \"\n        \" (0/1/2\"\n        //        \"/3/4)\",\n        \")\",\n        advanced, &iis_strategy, kIisStrategyMin, kIisStrategyLight,\n        kIisStrategyMax);\n    records.push_back(record_int);\n\n    record_bool = new OptionRecordBool(\n        \"blend_multi_objectives\",\n        \"Blend multiple objectives or apply lexicographically\", advanced,\n        &blend_multi_objectives, true);\n    records.push_back(record_bool);\n\n    // Fix the number of user settable options\n    num_user_settable_options_ = static_cast<HighsInt>(records.size());\n\n    // Advanced options\n    advanced = true;\n\n    record_int =\n        new OptionRecordInt(\"log_dev_level\",\n                            \"Output development messages: 0 => none; 1 => \"\n                            \"info; 2 => detailed; 3 => verbose\",\n                            advanced, &log_dev_level, kHighsLogDevLevelMin,\n                            kHighsLogDevLevelNone, kHighsLogDevLevelMax);\n    records.push_back(record_int);\n\n    record_bool = new OptionRecordBool(\"log_githash\", \"Log the githash\",\n                                       advanced, &log_githash, true);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\n        \"solve_relaxation\", \"Solve the relaxation of discrete model components\",\n        advanced, &solve_relaxation, false);\n    records.push_back(record_bool);\n\n    record_bool =\n        new OptionRecordBool(\"allow_unbounded_or_infeasible\",\n                             \"Allow ModelStatus::kUnboundedOrInfeasible\",\n                             advanced, &allow_unbounded_or_infeasible, false);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\n        \"use_implied_bounds_from_presolve\",\n        \"Use relaxed implied bounds from presolve\", advanced,\n        &use_implied_bounds_from_presolve, false);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\n        \"lp_presolve_requires_basis_postsolve\",\n        \"Prevents LP presolve steps for which postsolve cannot maintain a \"\n        \"basis\",\n        advanced, &lp_presolve_requires_basis_postsolve, true);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\"mps_parser_type_free\",\n                                       \"Use the free format MPS file reader\",\n                                       advanced, &mps_parser_type_free, true);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\"use_warm_start\",\n                                       \"Use any warm start that is available\",\n                                       advanced, &use_warm_start, true);\n    records.push_back(record_bool);\n\n    record_int =\n        new OptionRecordInt(\"keep_n_rows\",\n                            \"For multiple N-rows in MPS files: delete rows / \"\n                            \"delete entries / keep rows (-1/0/1)\",\n                            advanced, &keep_n_rows, kKeepNRowsDeleteRows,\n                            kKeepNRowsDeleteRows, kKeepNRowsKeepRows);\n    records.push_back(record_int);\n\n    record_int =\n        new OptionRecordInt(\"cost_scale_factor\", \"Scaling factor for costs\",\n                            advanced, &cost_scale_factor, -20, 0, 20);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"allowed_matrix_scale_factor\",\n        \"Largest power-of-two factor permitted when \"\n        \"scaling the constraint matrix\",\n        advanced, &allowed_matrix_scale_factor, 0,\n        kDefaultAllowedMatrixPow2Scale, kMaxAllowedMatrixPow2Scale);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"allowed_cost_scale_factor\",\n        \"Largest power-of-two factor permitted when scaling the costs\",\n        advanced, &allowed_cost_scale_factor, 0, 0, 20);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"ipx_dualize_strategy\", \"Strategy for dualizing before IPX\", advanced,\n        &ipx_dualize_strategy, kIpxDualizeStrategyMin, kIpxDualizeStrategyLukas,\n        kIpxDualizeStrategyMax);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"simplex_dualize_strategy\", \"Strategy for dualizing before simplex\",\n        advanced, &simplex_dualize_strategy, kHighsOptionOff, kHighsOptionOff,\n        kHighsOptionOn);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"simplex_permute_strategy\", \"Strategy for permuting before simplex\",\n        advanced, &simplex_permute_strategy, kHighsOptionOff, kHighsOptionOff,\n        kHighsOptionOn);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"max_dual_simplex_cleanup_level\", \"Max level of dual simplex cleanup\",\n        advanced, &max_dual_simplex_cleanup_level, 0, 1, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"max_dual_simplex_phase1_cleanup_level\",\n        \"Max level of dual simplex phase 1 cleanup\", advanced,\n        &max_dual_simplex_phase1_cleanup_level, 0, 2, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"simplex_price_strategy\", \"Strategy for PRICE in simplex\", advanced,\n        &simplex_price_strategy, kSimplexPriceStrategyMin,\n        kSimplexPriceStrategyRowSwitchColSwitch, kSimplexPriceStrategyMax);\n    records.push_back(record_int);\n\n    record_int =\n        new OptionRecordInt(\"simplex_unscaled_solution_strategy\",\n                            \"Strategy for solving unscaled LP in simplex\",\n                            advanced, &simplex_unscaled_solution_strategy,\n                            kSimplexUnscaledSolutionStrategyMin,\n                            kSimplexUnscaledSolutionStrategyRefine,\n                            kSimplexUnscaledSolutionStrategyMax);\n    records.push_back(record_int);\n\n    record_bool =\n        new OptionRecordBool(\"simplex_initial_condition_check\",\n                             \"Perform initial basis condition check in simplex\",\n                             advanced, &simplex_initial_condition_check, true);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\n        \"no_unnecessary_rebuild_refactor\",\n        \"No unnecessary refactorization on simplex rebuild\", advanced,\n        &no_unnecessary_rebuild_refactor, true);\n    records.push_back(record_bool);\n\n    record_double = new OptionRecordDouble(\n        \"simplex_initial_condition_tolerance\",\n        \"Tolerance on initial basis condition in simplex\", advanced,\n        &simplex_initial_condition_tolerance, 1.0, 1e14, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"rebuild_refactor_solution_error_tolerance\",\n        \"Tolerance on solution error when considering refactorization on \"\n        \"simplex rebuild\",\n        advanced, &rebuild_refactor_solution_error_tolerance, -kHighsInf, 1e-8,\n        kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"dual_steepest_edge_weight_error_tolerance\",\n        \"Tolerance on dual steepest edge weight errors\", advanced,\n        &dual_steepest_edge_weight_error_tolerance, 0.0, kHighsInf, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"dual_steepest_edge_weight_log_error_threshold\",\n        \"Threshold on dual steepest edge weight errors for Devex switch\",\n        advanced, &dual_steepest_edge_weight_log_error_threshold, 1.0, 1e1,\n        kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"dual_simplex_cost_perturbation_multiplier\",\n        \"Dual simplex cost perturbation multiplier: 0 => no perturbation\",\n        advanced, &dual_simplex_cost_perturbation_multiplier, 0.0, 1.0,\n        kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"primal_simplex_bound_perturbation_multiplier\",\n        \"Primal simplex bound perturbation multiplier: 0 => no perturbation\",\n        advanced, &primal_simplex_bound_perturbation_multiplier, 0.0, 1.0,\n        kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"dual_simplex_pivot_growth_tolerance\",\n        \"Dual simplex pivot growth tolerance\", advanced,\n        &dual_simplex_pivot_growth_tolerance, 1e-12, 1e-9, kHighsInf);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"presolve_pivot_threshold\",\n        \"Matrix factorization pivot threshold for substitutions in presolve\",\n        advanced, &presolve_pivot_threshold, kMinPivotThreshold, 0.01,\n        kMaxPivotThreshold);\n    records.push_back(record_double);\n\n    record_int = new OptionRecordInt(\n        \"presolve_reduction_limit\",\n        \"Limit on number of presolve reductions -1 => no limit\", advanced,\n        &presolve_reduction_limit, -1, -1, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"restart_presolve_reduction_limit\",\n        \"Limit on number of further presolve reductions on restart in MIP \"\n        \"solver -1 => no limit, otherwise, must be positive\",\n        advanced, &restart_presolve_reduction_limit, -1, -1, kHighsIInf);\n    records.push_back(record_int);\n\n    record_int = new OptionRecordInt(\n        \"presolve_rule_off\", \"Bit mask of presolve rules that are not allowed\",\n        advanced, &presolve_rule_off, 0, 0, kHighsIInf);\n    records.push_back(record_int);\n\n    record_bool = new OptionRecordBool(\n        \"presolve_rule_logging\", \"Log effectiveness of presolve rules for LP\",\n        advanced, &presolve_rule_logging, false);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\"presolve_remove_slacks\",\n                                       \"Remove slacks after presolve\", advanced,\n                                       &presolve_remove_slacks, false);\n    records.push_back(record_bool);\n\n    record_int = new OptionRecordInt(\n        \"presolve_substitution_maxfillin\",\n        \"Maximal fillin allowed for substitutions in presolve\", advanced,\n        &presolve_substitution_maxfillin, 0, 10, kHighsIInf);\n    records.push_back(record_int);\n\n    record_double = new OptionRecordDouble(\n        \"factor_pivot_threshold\", \"Matrix factorization pivot threshold\",\n        advanced, &factor_pivot_threshold, kMinPivotThreshold,\n        kDefaultPivotThreshold, kMaxPivotThreshold);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"factor_pivot_tolerance\", \"Matrix factorization pivot tolerance\",\n        advanced, &factor_pivot_tolerance, kMinPivotTolerance,\n        kDefaultPivotTolerance, kMaxPivotTolerance);\n    records.push_back(record_double);\n\n    record_double = new OptionRecordDouble(\n        \"start_crossover_tolerance\",\n        \"Tolerance to be satisfied before IPM crossover will start\", advanced,\n        &start_crossover_tolerance, 1e-12, 1e-1 * kDefaultKktTolerance,\n        kHighsInf);\n    records.push_back(record_double);\n\n    record_bool = new OptionRecordBool(\n        \"use_original_HFactor_logic\",\n        \"Use original HFactor logic for sparse vs hyper-sparse TRANs\", advanced,\n        &use_original_HFactor_logic, true);\n    records.push_back(record_bool);\n\n    record_bool = new OptionRecordBool(\n        \"less_infeasible_DSE_check\", \"Check whether LP is candidate for LiDSE\",\n        advanced, &less_infeasible_DSE_check, true);\n    records.push_back(record_bool);\n\n    record_bool =\n        new OptionRecordBool(\"less_infeasible_DSE_choose_row\",\n                             \"Use LiDSE if LP has right properties\", advanced,\n                             &less_infeasible_DSE_choose_row, true);\n    records.push_back(record_bool);\n\n    record_bool =\n        new OptionRecordBool(\"run_centring\", \"Perform centring steps or not\",\n                             advanced, &run_centring, false);\n    records.push_back(record_bool);\n\n    /*\n    record_bool = new OptionRecordBool(\"allow_pdlp_cleanup\",\n                                       \"Allow PDLP to be used to clean up \"\n                                       \"model with unknown status and no basis\",\n                                       advanced, &allow_pdlp_cleanup, true);\n    records.push_back(record_bool);\n    */\n\n    record_int =\n        new OptionRecordInt(\"max_centring_steps\",\n                            \"Maximum number of steps to use (default = 5) \"\n                            \"when computing the analytic centre\",\n                            advanced, &max_centring_steps, 0, 5, kHighsIInf);\n    records.push_back(record_int);\n\n    record_double = new OptionRecordDouble(\n        \"centring_ratio_tolerance\",\n        \"Centring stops when the ratio max(x_j*s_j) / min(x_j*s_j) is below \"\n        \"this tolerance (default = 100)\",\n        advanced, &centring_ratio_tolerance, 0, 100, kHighsInf);\n    records.push_back(record_double);\n\n    // Set up the log_options aliases\n    log_options.clear();\n    log_options.log_stream =\n        log_file.empty() ? nullptr : fopen(log_file.c_str(), \"w\");\n    log_options.output_flag = &output_flag;\n    log_options.log_to_console = &log_to_console;\n    log_options.log_dev_level = &log_dev_level;\n  }\n\n  void deleteRecords() {\n    for (auto record : records) delete record;\n  }\n\n public:\n  std::vector<OptionRecord*> records;\n  HighsInt num_user_settable_options_;\n  void setLogOptions();\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsRanging.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsRanging.h\n * @brief\n */\n#ifndef LP_DATA_HIGHS_RANGING_H_\n#define LP_DATA_HIGHS_RANGING_H_\n\n#include <vector>\n\n#include \"lp_data/HighsLpSolverObject.h\"\n\nstruct HighsRangingRecord {\n  std::vector<double> value_;\n  std::vector<double> objective_;\n  std::vector<HighsInt> in_var_;\n  std::vector<HighsInt> ou_var_;\n};\n\nstruct HighsRanging {\n  bool valid = false;\n  HighsRangingRecord col_cost_up;\n  HighsRangingRecord col_cost_dn;\n  HighsRangingRecord col_bound_up;\n  HighsRangingRecord col_bound_dn;\n  HighsRangingRecord row_bound_up;\n  HighsRangingRecord row_bound_dn;\n  void invalidate();\n  void clear();\n};\n\nHighsStatus getRangingData(HighsRanging& ranging,\n                           HighsLpSolverObject& solver_object);\nvoid writeRangingFile(FILE* file, const HighsLp& lp,\n                      const double objective_function_value,\n                      const HighsBasis& basis, const HighsSolution& solution,\n                      const HighsRanging& ranging, const HighsInt style);\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsSolution.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsSolution.h\n * @brief Class-independent utilities for HiGHS\n */\n#ifndef LP_DATA_HIGHSSOLUTION_H_\n#define LP_DATA_HIGHSSOLUTION_H_\n\n#include <string>\n#include <vector>\n\n#include \"io/HighsIO.h\"\n#include \"lp_data/HStruct.h\"\n#include \"lp_data/HighsInfo.h\"\n#include \"lp_data/HighsLpSolverObject.h\"\n#include \"lp_data/HighsStatus.h\"\n#include \"model/HighsModel.h\"\n\nclass HighsLp;\nstruct IpxSolution;\nclass HighsOptions;\n\nusing std::string;\n\n// Collecting absolute and relative errors, and the corresponding\n// indices is required for Glpsol output\nstruct HighsError {\n  double absolute_value;\n  HighsInt absolute_index;\n  double relative_value;\n  HighsInt relative_index;\n  void print(std::string message);\n  void reset();\n  void invalidate();\n};\n\n// These are values used for HighsSolutionDebug, or for Glpsol output,\n// so not worthy of being in HighsInfo\nstruct HighsPrimalDualErrors {\n  HighsInt num_nonzero_basic_duals;\n  double max_nonzero_basic_dual;\n  double sum_nonzero_basic_duals;\n  HighsInt num_off_bound_nonbasic;\n  double max_off_bound_nonbasic;\n  double sum_off_bound_nonbasic;\n  HighsInt glpsol_num_primal_residual_errors;\n  double glpsol_sum_primal_residual_errors;\n  HighsInt glpsol_num_dual_residual_errors;\n  double glpsol_sum_dual_residual_errors;\n  HighsError glpsol_max_primal_residual;\n  HighsError glpsol_max_primal_infeasibility;\n  HighsError glpsol_max_dual_residual;\n  HighsError glpsol_max_dual_infeasibility;\n};\n\nvoid getKktFailures(const HighsOptions& options, const HighsModel& model,\n                    const HighsSolution& solution, const HighsBasis& basis,\n                    HighsInfo& highs_info);\n\nvoid getKktFailures(const HighsOptions& options, const HighsModel& model,\n                    const HighsSolution& solution, const HighsBasis& basis,\n                    HighsInfo& highs_info,\n                    HighsPrimalDualErrors& primal_dual_errors,\n                    const bool get_residuals = false);\n\nvoid getLpKktFailures(const HighsOptions& options, const HighsLp& lp,\n                      const HighsSolution& solution, const HighsBasis& basis,\n                      HighsInfo& highs_info);\n\nvoid getLpKktFailures(const HighsOptions& options, const HighsLp& lp,\n                      const HighsSolution& solution, const HighsBasis& basis,\n                      HighsInfo& highs_info,\n                      HighsPrimalDualErrors& primal_dual_errors,\n                      const bool get_residuals = false);\n\nvoid getKktFailures(const HighsOptions& options, const bool is_qp,\n                    const HighsLp& lp, const std::vector<double>& gradient,\n                    const HighsSolution& solution, HighsInfo& highs_info,\n                    const bool get_residuals = false);\n\nvoid getVariableKktFailures(const double primal_feasibility_tolerance,\n                            const double dual_feasibility_tolerance,\n                            const double lower, const double upper,\n                            const double value, const double dual,\n                            const HighsVarType integrality,\n                            double& primal_infeasibility,\n                            double& dual_infeasibility, uint8_t& at_status,\n                            uint8_t& mid_status);\n\nvoid getPrimalDualGlpsolErrors(const HighsOptions& options, const HighsLp& lp,\n                               const std::vector<double>& gradient,\n                               const HighsSolution& solution,\n                               HighsPrimalDualErrors& primal_dual_errors);\n\nvoid getPrimalDualBasisErrors(const HighsOptions& options, const HighsLp& lp,\n                              const HighsSolution& solution,\n                              const HighsBasis& basis,\n                              HighsPrimalDualErrors& primal_dual_errors);\n\nbool getComplementarityViolations(const HighsLp& lp,\n                                  const HighsSolution& solution,\n                                  const double optimality_tolerance,\n                                  HighsInt& num_complementarity_violations,\n                                  double& max_complementarity_violation);\n\nbool computeDualObjectiveValue(const HighsModel& model,\n                               const HighsSolution& solution,\n                               double& dual_objective_value);\n\nbool computeDualObjectiveValue(const double* gradient, const HighsLp& lp,\n                               const HighsSolution& solution,\n                               double& dual_objective_value);\n\ndouble computeObjectiveValue(const HighsLp& lp, const HighsSolution& solution);\n\nvoid refineBasis(const HighsLp& lp, const HighsSolution& solution,\n                 HighsBasis& basis);\n\nHighsStatus ipxSolutionToHighsSolution(\n    const HighsOptions& options, const HighsLp& lp,\n    const std::vector<double>& rhs, const std::vector<char>& constraint_type,\n    const HighsInt ipx_num_col, const HighsInt ipx_num_row,\n    const std::vector<double>& ipx_x, const std::vector<double>& ipx_slack_vars,\n    const std::vector<double>& ipx_y, const std::vector<double>& ipx_zl,\n    const std::vector<double>& ipx_zu, HighsSolution& highs_solution);\n\nHighsStatus ipxBasicSolutionToHighsBasicSolution(\n    const HighsLogOptions& log_options, const HighsLp& lp,\n    const std::vector<double>& rhs, const std::vector<char>& constraint_type,\n    const IpxSolution& ipx_solution, HighsBasis& highs_basis,\n    HighsSolution& highs_solution);\n\nHighsStatus formSimplexLpBasisAndFactorReturn(\n    const HighsStatus return_status, HighsLpSolverObject& solver_object);\nHighsStatus formSimplexLpBasisAndFactor(\n    HighsLpSolverObject& solver_object,\n    const bool only_from_known_basis = false);\n\nvoid accommodateAlienBasis(HighsLpSolverObject& solver_object);\n\nvoid resetModelStatusAndHighsInfo(HighsLpSolverObject& solver_object);\nvoid resetModelStatusAndHighsInfo(HighsModelStatus& model_status,\n                                  HighsInfo& highs_info);\nbool isBasisConsistent(const HighsLp& lp, const HighsBasis& basis);\n\nbool isColPrimalSolutionRightSize(const HighsLp& lp,\n                                  const HighsSolution& solution);\nbool isRowPrimalSolutionRightSize(const HighsLp& lp,\n                                  const HighsSolution& solution);\nbool isPrimalSolutionRightSize(const HighsLp& lp,\n                               const HighsSolution& solution);\n\nbool isColDualSolutionRightSize(const HighsLp& lp,\n                                const HighsSolution& solution);\nbool isRowDualSolutionRightSize(const HighsLp& lp,\n                                const HighsSolution& solution);\nbool isDualSolutionRightSize(const HighsLp& lp, const HighsSolution& solution);\n\nbool isSolutionRightSize(const HighsLp& lp, const HighsSolution& solution);\nbool isBasisRightSize(const HighsLp& lp, const HighsBasis& basis);\n\nbool reportKktFailures(const HighsLp& lp, const HighsOptions& options,\n                       const HighsInfo& highs_info,\n                       const std::string& message = \"\");\n\n#endif  // LP_DATA_HIGHSSOLUTION_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsSolutionDebug.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsSolutionDebug.h\n * @brief\n */\n#ifndef SIMPLEX_HIGHSSOLUTIONDEBUG_H_\n#define SIMPLEX_HIGHSSOLUTIONDEBUG_H_\n\n#include \"lp_data/HighsInfo.h\"\n#include \"lp_data/HighsLp.h\"\n#include \"lp_data/HighsOptions.h\"\n#include \"lp_data/HighsSolution.h\"\n\nHighsDebugStatus debugHighsLpSolution(const std::string message,\n                                      const HighsLpSolverObject& solver_object);\n\nHighsDebugStatus debugHighsSolution(const string message,\n                                    const HighsOptions& options,\n                                    const HighsModel& model,\n                                    const HighsSolution& solution,\n                                    const HighsBasis& basis);\n\nHighsDebugStatus debugHighsSolution(\n    const string message, const HighsOptions& options, const HighsModel& model,\n    const HighsSolution& solution, const HighsBasis& basis,\n    const HighsModelStatus model_status, const HighsInfo& info);\n\nHighsDebugStatus debugHighsSolution(\n    const std::string message, const HighsOptions& options, const HighsLp& lp,\n    const HighsHessian& hessian, const HighsSolution& solution,\n    const HighsBasis& basis, const HighsModelStatus model_status,\n    const HighsInfo& highs_info, const bool check_model_status_and_highs_info);\n\nvoid debugReportHighsSolution(const string message,\n                              const HighsLogOptions& log_options,\n                              const HighsInfo& highs_info,\n                              const HighsModelStatus model_status);\n\nHighsDebugStatus debugBasisRightSize(const HighsOptions& options,\n                                     const HighsLp& lp,\n                                     const HighsBasis& basis);\n\nHighsDebugStatus debugPrimalSolutionRightSize(const HighsOptions& options,\n                                              const HighsLp& lp,\n                                              const HighsSolution& solution);\n\nHighsDebugStatus debugDualSolutionRightSize(const HighsOptions& options,\n                                            const HighsLp& lp,\n                                            const HighsSolution& solution);\n\nHighsDebugStatus debugHighsBasisConsistent(const HighsOptions& options,\n                                           const HighsLp& lp,\n                                           const HighsBasis& basis);\n\n// Methods below are not called externally\n\nHighsDebugStatus debugAnalysePrimalDualErrors(\n    const HighsOptions& options, HighsPrimalDualErrors& primal_dual_errors);\n\nHighsDebugStatus debugCompareHighsInfo(const HighsOptions& options,\n                                       const HighsInfo& highs_info0,\n                                       const HighsInfo& highs_info1);\nHighsDebugStatus debugCompareHighsInfoObjective(const HighsOptions& options,\n                                                const HighsInfo& highs_info0,\n                                                const HighsInfo& highs_info1);\nHighsDebugStatus debugCompareHighsInfoStatus(const HighsOptions& options,\n                                             const HighsInfo& highs_info0,\n                                             const HighsInfo& highs_info1);\nHighsDebugStatus debugCompareHighsInfoInfeasibility(\n    const HighsOptions& options, const HighsInfo& highs_info0,\n    const HighsInfo& highs_info1);\n\nHighsDebugStatus debugCompareHighsInfoDouble(const string name,\n                                             const HighsOptions& options,\n                                             const double v0, const double v1);\n\nHighsDebugStatus debugCompareHighsInfoInteger(const string name,\n                                              const HighsOptions& options,\n                                              const HighsInt v0,\n                                              const HighsInt v1);\n\n#endif  // SIMPLEX_HIGHSSOLUTIONDEBUG_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsSolve.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HighsSolve.h\n * @brief Class-independent utilities for HiGHS\n */\n#ifndef LP_DATA_HIGHSSOLVE_H_\n#define LP_DATA_HIGHSSOLVE_H_\n\n#include \"lp_data/HighsModelUtils.h\"\nHighsStatus solveLp(HighsLpSolverObject& solver_object, const string message);\nHighsStatus solveUnconstrainedLp(HighsLpSolverObject& solver_object);\nHighsStatus solveUnconstrainedLp(const HighsOptions& options, const HighsLp& lp,\n                                 HighsModelStatus& model_status,\n                                 HighsInfo& highs_info, HighsSolution& solution,\n                                 HighsBasis& basis);\nvoid assessExcessiveObjectiveBoundScaling(const HighsLogOptions log_options,\n                                          const HighsModel& model,\n                                          HighsUserScaleData& user_scale_data);\nbool useIpm(const std::string& solver);\nbool useHipo(const HighsOptions& options,\n             const std::string& specific_solver_option, const HighsLp& lp,\n             const bool logging = false);\n#endif  // LP_DATA_HIGHSSOLVE_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/lp_data/HighsStatus.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef LP_DATA_HIGHS_STATUS_H_\n#define LP_DATA_HIGHS_STATUS_H_\n\n#include <string>\n\n#include \"io/HighsIO.h\"\n\nenum class HighsStatus { kError = -1, kOk = 0, kWarning = 1 };\n\n// Return a string representation of HighsStatus.\nstd::string highsStatusToString(HighsStatus status);\n\n// Return the maximum of two HighsStatus and possibly report on\n// call_status not being HighsStatus::kOk\nHighsStatus interpretCallStatus(const HighsLogOptions log_options,\n                                const HighsStatus call_status,\n                                const HighsStatus from_return_status,\n                                const std::string& message = \"\");\n\n// Return the maximum of two HighsStatus\nHighsStatus worseStatus(HighsStatus status0, HighsStatus status1);\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsCliqueTable.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_CLIQUE_TABLE_H_\n#define HIGHS_CLIQUE_TABLE_H_\n\n#include <cstdint>\n#include <set>\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n#include \"util/HighsHash.h\"\n#include \"util/HighsHashTree.h\"\n#include \"util/HighsRandom.h\"\n\nclass HighsCutPool;\nclass HighsDomain;\nclass HighsMipSolver;\nclass HighsLp;\n\nnamespace presolve {\nclass HighsPostsolveStack;\n}\n\nclass HighsCliqueTable {\n public:\n  struct CliqueVar {\n#ifdef HIGHSINT64\n    HighsUInt col : 63;\n    HighsUInt val : 1;\n#else\n    HighsUInt col : 31;\n    HighsUInt val : 1;\n#endif\n\n    HighsInt index() const { return 2 * col + val; }\n\n    double weight(const std::vector<double>& sol) const {\n      return val ? sol[col] : 1.0 - sol[col];\n    }\n\n    CliqueVar complement() const { return CliqueVar(col, 1 - val); }\n\n    bool operator==(const CliqueVar& other) const {\n      return index() == other.index();\n    }\n\n    CliqueVar(HighsInt col, HighsInt val) : col(col), val(val) {}\n    CliqueVar() = default;\n  };\n  struct Clique {\n    HighsInt start;\n    HighsInt end;\n    HighsInt origin;\n    HighsInt numZeroFixed;\n    bool equality;\n  };\n\n  struct Substitution {\n    HighsInt substcol;\n    CliqueVar replace;\n  };\n\n private:\n  std::vector<CliqueVar> cliqueentries;\n\n  std::vector<HighsHashTree<HighsInt, HighsInt>> invertedHashList;\n  std::vector<HighsHashTree<HighsInt>> invertedHashListSizeTwo;\n  HighsHashTable<std::pair<CliqueVar, CliqueVar>, HighsInt> sizeTwoCliques;\n\n  std::set<std::pair<HighsInt, HighsInt>> freespaces;\n  std::vector<HighsInt> freeslots;\n  std::vector<Clique> cliques;\n  std::vector<HighsInt> numcliquesvar;\n  std::vector<CliqueVar> infeasvertexstack;\n\n  std::vector<HighsInt> colsubstituted;\n  std::vector<Substitution> substitutions;\n  std::vector<HighsInt> deletedrows;\n  std::vector<std::pair<HighsInt, CliqueVar>> cliqueextensions;\n  std::vector<uint8_t> iscandidate;\n  std::vector<uint8_t> colDeleted;\n  std::vector<uint32_t> cliquehits;\n  std::vector<HighsInt> cliquehitinds;\n\n  // HighsHashTable<std::pair<CliqueVar, CliqueVar>> invertedEdgeCache;\n\n  HighsRandom randgen;\n  HighsInt nfixings;\n  HighsInt numEntries;\n  HighsInt maxEntries;\n  HighsInt minEntriesForParallelism;\n  bool inPresolve;\n\n  void unlink(HighsInt pos, HighsInt cliqueid);\n\n  void link(HighsInt pos, HighsInt cliqueid);\n\n  HighsInt findCommonCliqueId(int64_t& numQueries, CliqueVar v1,\n                              CliqueVar v2) const;\n\n  HighsInt findCommonCliqueId(CliqueVar v1, CliqueVar v2) {\n    return findCommonCliqueId(numNeighbourhoodQueries, v1, v2);\n  }\n\n  HighsInt runCliqueSubsumption(const HighsDomain& globaldom,\n                                std::vector<CliqueVar>& clique);\n  struct BronKerboschData {\n    const std::vector<double>& sol;\n    std::vector<CliqueVar> P;\n    std::vector<CliqueVar> R;\n    std::vector<CliqueVar> Z;\n    std::vector<std::vector<CliqueVar>> cliques;\n    std::vector<HighsInt> neighbourhoodInds;\n\n    double wR = 0.0;\n    double minW = 1.05;\n    double feastol = 1e-6;\n    HighsInt ncalls = 0;\n    HighsInt maxcalls = 10000;\n    HighsInt maxcliques = 100;\n    int64_t maxNeighbourhoodQueries = std::numeric_limits<int64_t>::max();\n    int64_t numNeighbourhoodQueries = 0;\n\n    bool stop() const {\n      return maxcalls == ncalls || int(cliques.size()) == maxcliques ||\n             numNeighbourhoodQueries > maxNeighbourhoodQueries;\n    }\n\n    BronKerboschData(const std::vector<double>& sol) : sol(sol) {}\n  };\n\n  void bronKerboschRecurse(BronKerboschData& data, HighsInt Plen,\n                           const CliqueVar* X, HighsInt Xlen) const;\n\n  void extractCliques(const HighsMipSolver& mipsolver,\n                      std::vector<HighsInt>& inds, std::vector<double>& vals,\n                      std::vector<int8_t>& complementation, double rhs,\n                      HighsInt nbin, std::vector<HighsInt>& perm,\n                      std::vector<CliqueVar>& clique, double feastol);\n\n  void processInfeasibleVertices(HighsDomain& domain);\n\n  void propagateAndCleanup(HighsDomain& globaldom);\n\n  void queryNeighbourhood(std::vector<HighsInt>& neighbourhoodInds,\n                          int64_t& numNeighbourhoodqueries, CliqueVar v,\n                          CliqueVar* q, HighsInt N) const;\n\n public:\n  int64_t numNeighbourhoodQueries;\n\n  HighsCliqueTable(HighsInt ncols) {\n    invertedHashList.resize(2 * static_cast<size_t>(ncols));\n    invertedHashListSizeTwo.resize(2 * static_cast<size_t>(ncols));\n    numcliquesvar.resize(2 * static_cast<size_t>(ncols), 0);\n    colsubstituted.resize(ncols);\n    colDeleted.resize(ncols, false);\n    nfixings = 0;\n    numNeighbourhoodQueries = 0;\n    numEntries = 0;\n    maxEntries = kHighsIInf;\n    minEntriesForParallelism = kHighsIInf;\n    inPresolve = false;\n  }\n\n  void setPresolveFlag(bool inPresolve) { this->inPresolve = inPresolve; }\n\n  bool getPresolveFlag() const { return inPresolve; }\n\n  HighsInt getNumEntries() const { return numEntries; }\n\n  HighsInt partitionNeighbourhood(std::vector<HighsInt>& neighbourhoodInds,\n                                  int64_t& numNeighbourhoodqueries, CliqueVar v,\n                                  CliqueVar* q, HighsInt N) const;\n\n  HighsInt shrinkToNeighbourhood(std::vector<HighsInt>& neighbourhoodInds,\n                                 int64_t& numNeighbourhoodqueries, CliqueVar v,\n                                 CliqueVar* q, HighsInt N);\n\n  bool processNewEdge(HighsDomain& globaldom, CliqueVar v1, CliqueVar v2);\n\n  void doAddClique(const CliqueVar* cliquevars, HighsInt numcliquevars,\n                   bool equality = false, HighsInt origin = kHighsIInf);\n\n  void addClique(const HighsMipSolver& mipsolver, CliqueVar* cliquevars,\n                 HighsInt numcliquevars, bool equality = false,\n                 HighsInt origin = kHighsIInf);\n\n  void removeClique(HighsInt cliqueid);\n\n  void resolveSubstitution(CliqueVar& v) const;\n\n  void resolveSubstitution(HighsInt& col, double& val, double& rhs) const;\n\n  std::vector<HighsInt>& getDeletedRows() { return deletedrows; }\n\n  const std::vector<HighsInt>& getDeletedRows() const { return deletedrows; }\n\n  std::vector<Substitution>& getSubstitutions() { return substitutions; }\n\n  const std::vector<Substitution>& getSubstitutions() const {\n    return substitutions;\n  }\n\n  const Substitution* getSubstitution(HighsInt col) const {\n    return colsubstituted[col] ? &substitutions[colsubstituted[col] - 1]\n                               : nullptr;\n  }\n\n  std::vector<std::pair<HighsInt, CliqueVar>>& getCliqueExtensions() {\n    return cliqueextensions;\n  }\n\n  const std::vector<std::pair<HighsInt, CliqueVar>>& getCliqueExtensions()\n      const {\n    return cliqueextensions;\n  }\n\n  void setMaxEntries(HighsInt numNz) {\n    this->maxEntries = 2000000 + 10 * numNz;\n  }\n\n  void setMinEntriesForParallelism(HighsInt minEntriesForParallelism) {\n    this->minEntriesForParallelism = minEntriesForParallelism;\n  }\n\n  bool isFull() const { return numEntries >= maxEntries; }\n\n  HighsInt getNumFixings() const { return nfixings; }\n\n  void cliquePartition(std::vector<CliqueVar>& clqVars,\n                       std::vector<HighsInt>& partitionStart);\n\n  void cliquePartition(const std::vector<double>& objective,\n                       std::vector<CliqueVar>& clqVars,\n                       std::vector<HighsInt>& partitionStart);\n\n  bool foundCover(HighsDomain& globaldom, CliqueVar v1, CliqueVar v2);\n\n  void extractCliques(HighsMipSolver& mipsolver, bool transformRows = true);\n\n  void extractCliquesFromCut(const HighsMipSolver& mipsolver,\n                             const HighsInt* inds, const double* vals,\n                             HighsInt len, double rhs);\n\n  void extractObjCliques(HighsMipSolver& mipsolver);\n\n  void vertexInfeasible(HighsDomain& globaldom, HighsInt col, HighsInt val);\n\n  bool haveCommonClique(CliqueVar v1, CliqueVar v2) {\n    if (v1.col == v2.col) return false;\n    return findCommonCliqueId(v1, v2) != -1;\n  }\n\n  bool haveCommonClique(int64_t& numQueries, CliqueVar v1, CliqueVar v2) const {\n    if (v1.col == v2.col) return false;\n    return findCommonCliqueId(numQueries, v1, v2) != -1;\n  }\n\n  std::pair<const CliqueVar*, HighsInt> findCommonClique(CliqueVar v1,\n                                                         CliqueVar v2) {\n    std::pair<const CliqueVar*, HighsInt> c{nullptr, 0};\n    if (v1 == v2) return c;\n    HighsInt clq = findCommonCliqueId(v1, v2);\n    if (clq == -1) return c;\n\n    c.first = &cliqueentries[cliques[clq].start];\n    c.second = cliques[clq].end - cliques[clq].start;\n    return c;\n  }\n\n  void separateCliques(const HighsMipSolver& mipsolver,\n                       const std::vector<double>& sol, HighsCutPool& cutpool,\n                       double feastol);\n\n  std::vector<std::vector<CliqueVar>> separateCliques(\n      const std::vector<double>& sol, const HighsDomain& globaldom,\n      double feastol);\n\n  std::vector<std::vector<CliqueVar>> computeMaximalCliques(\n      const std::vector<CliqueVar>& vars, double feastol);\n\n  void cleanupFixed(HighsDomain& globaldom);\n\n  void addImplications(HighsDomain& domain, HighsInt col, HighsInt val);\n\n  HighsInt getNumImplications(HighsInt col);\n\n  HighsInt getNumImplications(HighsInt col, bool val);\n\n  void runCliqueMerging(HighsDomain& globaldomain);\n\n  void runCliqueMerging(HighsDomain& globaldomain,\n                        std::vector<CliqueVar>& clique, bool equation = false);\n\n  void rebuild(HighsInt ncols,\n               const presolve::HighsPostsolveStack& postSolveStack,\n               const HighsDomain& globaldomain,\n               const std::vector<HighsInt>& cIndex,\n               const std::vector<HighsInt>& rIndex);\n\n  void buildFrom(const HighsLp* origModel, const HighsCliqueTable& init);\n\n  HighsInt numCliques() const { return cliques.size() - freeslots.size(); }\n\n  HighsInt numCliques(CliqueVar v) const { return numcliquesvar[v.index()]; }\n\n  HighsInt numCliques(HighsInt col, bool val) const {\n    return numcliquesvar[CliqueVar(col, val).index()];\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsConflictPool.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_CONFLICTPOOL_H_\n#define HIGHS_CONFLICTPOOL_H_\n\n#include <set>\n#include <vector>\n\n#include \"mip/HighsDomain.h\"\n#include \"util/HighsInt.h\"\n\nclass HighsConflictPool {\n private:\n  HighsInt agelim_;\n  HighsInt softlimit_;\n  std::vector<HighsInt> ageDistribution_;\n  std::vector<int16_t> ages_;\n  std::vector<unsigned> modification_;\n\n  std::vector<HighsDomainChange> conflictEntries_;\n  std::vector<std::pair<HighsInt, HighsInt>> conflictRanges_;\n\n  /// keep an ordered set of free spaces in the row arrays so that they can be\n  /// reused efficiently\n  std::set<std::pair<HighsInt, HighsInt>> freeSpaces_;\n\n  /// vector of deleted conflicts so that their indices can be reused\n  std::vector<HighsInt> deletedConflicts_;\n\n  std::vector<HighsDomain::ConflictPoolPropagation*> propagationDomains;\n\n public:\n  HighsConflictPool(HighsInt agelim, HighsInt softlimit)\n      : agelim_(agelim),\n        softlimit_(softlimit),\n        ageDistribution_(),\n        ages_(),\n        modification_(),\n        conflictEntries_(),\n        conflictRanges_(),\n        freeSpaces_(),\n        deletedConflicts_(),\n        propagationDomains() {\n    ageDistribution_.resize(agelim_ + 1);\n  }\n\n  void addConflictCut(const HighsDomain& domain,\n                      const std::set<HighsDomain::ConflictSet::LocalDomChg>&\n                          reasonSideFrontier);\n\n  void addReconvergenceCut(\n      const HighsDomain& domain,\n      const std::set<HighsDomain::ConflictSet::LocalDomChg>&\n          reconvergenceFrontier,\n      const HighsDomainChange& reconvergenceDomchg);\n\n  void removeConflict(HighsInt conflict);\n\n  void performAging();\n\n  void resetAge(HighsInt conflict) {\n    if (ages_[conflict] > 0) {\n      ageDistribution_[ages_[conflict]] -= 1;\n      ageDistribution_[0] += 1;\n      ages_[conflict] = 0;\n    }\n  }\n\n  void setAgeLimit(HighsInt agelim) {\n    agelim_ = agelim;\n    ageDistribution_.resize(agelim_ + 1);\n  }\n\n  unsigned getModificationCount(HighsInt cut) const {\n    return modification_[cut];\n  }\n\n  void addPropagationDomain(HighsDomain::ConflictPoolPropagation* domain) {\n    propagationDomains.push_back(domain);\n  }\n\n  void removePropagationDomain(HighsDomain::ConflictPoolPropagation* domain) {\n    for (HighsInt k = propagationDomains.size() - 1; k >= 0; --k) {\n      if (propagationDomains[k] == domain) {\n        propagationDomains.erase(propagationDomains.begin() + k);\n        return;\n      }\n    }\n  }\n\n  const std::vector<HighsDomainChange>& getConflictEntryVector() const {\n    return conflictEntries_;\n  }\n\n  const std::vector<std::pair<HighsInt, HighsInt>>& getConflictRanges() const {\n    return conflictRanges_;\n  }\n\n  HighsInt getNumConflicts() const {\n    return conflictRanges_.size() - deletedConflicts_.size();\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsCutGeneration.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file mip/HighsCutGeneration.h\n * @brief Class that generates cuts from single row relaxations\n *\n *\n */\n\n#ifndef MIP_HIGHS_CUT_GENERATION_H_\n#define MIP_HIGHS_CUT_GENERATION_H_\n\n#include <cstdint>\n#include <vector>\n\n#include \"util/HighsCDouble.h\"\n#include \"util/HighsInt.h\"\n#include \"util/HighsRandom.h\"\n\nclass HighsLpRelaxation;\nclass HighsTransformedLp;\nclass HighsCutPool;\nclass HighsDomain;\n\n/// Helper class to compute single-row relaxations from the current LP\n/// relaxation by substituting bounds and aggregating rows\nclass HighsCutGeneration {\n private:\n  const HighsLpRelaxation& lpRelaxation;\n  HighsCutPool& cutpool;\n  HighsRandom randgen;\n  std::vector<HighsInt> cover;\n  HighsCDouble coverweight;\n  HighsCDouble lambda;\n  std::vector<double> upper;\n  std::vector<double> solval;\n  std::vector<uint8_t> complementation;\n  std::vector<uint8_t> isintegral;\n  const double feastol;\n  const double epsilon;\n\n  double* vals;\n  HighsInt* inds;\n  HighsCDouble rhs;\n  bool integralSupport;\n  bool integralCoefficients;\n  HighsInt rowlen;\n  double initialScale;\n\n  std::vector<HighsInt> integerinds;\n  std::vector<double> deltas;\n\n  bool determineCover(bool lpSol = true);\n\n  void separateLiftedKnapsackCover();\n\n  bool separateLiftedMixedBinaryCover();\n\n  bool separateLiftedMixedIntegerCover();\n\n  bool cmirCutGenerationHeuristic(double minEfficacy,\n                                  bool onlyInitialCMIRScale = false);\n\n  double scale(double val);\n\n  bool postprocessCut();\n\n  bool preprocessBaseInequality(bool& hasUnboundedInts, bool& hasGeneralInts,\n                                bool& hasContinuous);\n\n  void flipComplementation(HighsInt index);\n\n  void removeComplementation();\n\n  void updateViolationAndNorm(HighsInt index, double aj, double& violation,\n                              double& norm) const;\n\n  bool tryGenerateCut(std::vector<HighsInt>& inds, std::vector<double>& vals,\n                      bool hasUnboundedInts, bool hasGeneralInts,\n                      bool hasContinuous, double minEfficacy,\n                      bool onlyInitialCMIRScale = false,\n                      bool allowRejectCut = true, bool lpSol = true);\n\n public:\n  HighsCutGeneration(const HighsLpRelaxation& lpRelaxation,\n                     HighsCutPool& cutpool);\n\n  /// separates the LP solution for the given single row relaxation\n  bool generateCut(HighsTransformedLp& transLp, std::vector<HighsInt>& inds,\n                   std::vector<double>& vals, double& rhs,\n                   bool onlyInitialCMIRScale = false);\n\n  /// generate a conflict from the given proof constraint which cuts of the\n  /// given local domain\n  bool generateConflict(HighsDomain& localdom, std::vector<HighsInt>& proofinds,\n                        std::vector<double>& proofvals, double& proofrhs);\n\n  /// applies postprocessing to an externally generated cut and adds it to the\n  /// cutpool if it is violated enough\n  bool finalizeAndAddCut(std::vector<HighsInt>& inds, std::vector<double>& vals,\n                         double& rhs);\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsCutPool.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_CUTPOOL_H_\n#define HIGHS_CUTPOOL_H_\n\n#include <memory>\n#include <unordered_map>\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n#include \"mip/HighsDomain.h\"\n#include \"mip/HighsDynamicRowMatrix.h\"\n\nclass HighsLpRelaxation;\n\nstruct HighsCutSet {\n  std::vector<HighsInt> cutindices;\n  std::vector<HighsInt> ARstart_;\n  std::vector<HighsInt> ARindex_;\n  std::vector<double> ARvalue_;\n  std::vector<double> lower_;\n  std::vector<double> upper_;\n\n  HighsInt numCuts() const { return cutindices.size(); }\n\n  void resize(HighsInt nnz) {\n    HighsInt ncuts = numCuts();\n    lower_.resize(ncuts, -kHighsInf);\n    upper_.resize(ncuts);\n    ARstart_.resize(ncuts + 1);\n    ARindex_.resize(nnz);\n    ARvalue_.resize(nnz);\n  }\n\n  void clear() {\n    cutindices.clear();\n    upper_.clear();\n    ARstart_.clear();\n    ARindex_.clear();\n    ARvalue_.clear();\n  }\n\n  bool empty() const { return cutindices.empty(); }\n};\n\nclass HighsCutPool {\n private:\n  HighsDynamicRowMatrix matrix_;\n  std::vector<double> rhs_;\n  std::vector<int16_t> ages_;\n  std::vector<double> rownormalization_;\n  std::vector<double> maxabscoef_;\n  std::vector<uint8_t> rowintegral;\n  std::unordered_multimap<uint64_t, HighsInt> hashToCutMap;\n  std::vector<HighsDomain::CutpoolPropagation*> propagationDomains;\n  std::set<std::pair<HighsInt, HighsInt>> propRows;\n\n  double bestObservedScore;\n  double minScoreFactor;\n  double minDensityLim;\n\n  HighsInt agelim_;\n  HighsInt softlimit_;\n  HighsInt numLpCuts;\n  HighsInt numPropNzs;\n  HighsInt numPropRows;\n  std::vector<HighsInt> ageDistribution;\n  std::vector<std::pair<HighsInt, double>> sortBuffer;\n\n  bool isDuplicate(size_t hash, double norm, const HighsInt* Rindex,\n                   const double* Rvalue, HighsInt Rlen, double rhs);\n\n public:\n  HighsCutPool(HighsInt ncols, HighsInt agelim, HighsInt softlimit)\n      : matrix_(ncols),\n        agelim_(agelim),\n        softlimit_(softlimit),\n        numLpCuts(0),\n        numPropNzs(0),\n        numPropRows(0) {\n    ageDistribution.resize(agelim_ + 1);\n    minScoreFactor = 0.9;\n    bestObservedScore = 0.0;\n    minDensityLim = 0.1 * ncols;\n  }\n  const HighsDynamicRowMatrix& getMatrix() const { return matrix_; }\n\n  const std::vector<double>& getRhs() const { return rhs_; }\n\n  void resetAge(HighsInt cut) {\n    if (ages_[cut] > 0) {\n      if (matrix_.columnsLinked(cut)) {\n        propRows.erase(std::make_pair(ages_[cut], cut));\n        propRows.emplace(0, cut);\n      }\n      ageDistribution[ages_[cut]] -= 1;\n      ageDistribution[0] += 1;\n      ages_[cut] = 0;\n    }\n  }\n\n  double getParallelism(HighsInt row1, HighsInt row2) const;\n\n  void performAging();\n\n  void lpCutRemoved(HighsInt cut);\n\n  void addPropagationDomain(HighsDomain::CutpoolPropagation* domain) {\n    propagationDomains.push_back(domain);\n  }\n\n  void removePropagationDomain(HighsDomain::CutpoolPropagation* domain) {\n    for (HighsInt k = propagationDomains.size() - 1; k >= 0; --k) {\n      if (propagationDomains[k] == domain) {\n        propagationDomains.erase(propagationDomains.begin() + k);\n        return;\n      }\n    }\n  }\n\n  void setAgeLimit(HighsInt agelim) {\n    agelim_ = agelim;\n    ageDistribution.resize(agelim_ + 1);\n  }\n\n  void separate(const std::vector<double>& sol, HighsDomain& domprop,\n                HighsCutSet& cutset, double feastol);\n\n  void separateLpCutsAfterRestart(HighsCutSet& cutset);\n\n  bool cutIsIntegral(HighsInt cut) const { return (rowintegral[cut] != 0); }\n\n  HighsInt getNumCuts() const {\n    return matrix_.getNumRows() - matrix_.getNumDelRows();\n  }\n\n  HighsInt getNumAvailableCuts() const { return getNumCuts() - numLpCuts; }\n\n  double getMaxAbsCutCoef(HighsInt cut) const { return maxabscoef_[cut]; }\n\n  double getRowNormalization(HighsInt cut) const {\n    return rownormalization_[cut];\n  }\n\n  HighsInt addCut(const HighsMipSolver& mipsolver, HighsInt* Rindex,\n                  double* Rvalue, HighsInt Rlen, double rhs,\n                  bool integral = false, bool propagate = true,\n                  bool extractCliques = true, bool isConflict = false);\n\n  HighsInt getRowLength(HighsInt row) const {\n    return matrix_.getRowEnd(row) - matrix_.getRowStart(row);\n  }\n\n  void getCut(HighsInt cut, HighsInt& cutlen, const HighsInt*& cutinds,\n              const double*& cutvals) const {\n    HighsInt start = matrix_.getRowStart(cut);\n    cutlen = matrix_.getRowEnd(cut) - start;\n    cutinds = matrix_.getARindex() + start;\n    cutvals = matrix_.getARvalue() + start;\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsDebugSol.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file mip/HighsDebugSol.h\n * @brief Debug solution for MIP solver\n */\n\n#ifndef HIGHS_DEBUG_SOL_H_\n#define HIGHS_DEBUG_SOL_H_\n\nclass HighsDomain;\nclass HighsMipSolver;\nclass HighsLp;\n\n#include <set>\n#include <vector>\n\n#include \"mip/HighsCliqueTable.h\"\n#include \"mip/HighsDomain.h\"\n\n#ifdef HIGHS_DEBUGSOL\n\n#include <unordered_map>\n\nstruct HighsDebugSol {\n  const HighsMipSolver* mipsolver;\n  double debugSolObjective;\n  std::vector<double> debugOrigSolution;\n  std::vector<double> debugSolution;\n  bool debugSolActive;\n  std::unordered_map<const HighsDomain*, std::multiset<HighsDomainChange>>\n      conflictingBounds;\n\n  HighsDebugSol(HighsMipSolver& mipsolver);\n\n  void newIncumbentFound();\n\n  void activate();\n\n  void shrink(const std::vector<HighsInt>& newColIndex);\n\n  void registerDomain(const HighsDomain& domain);\n\n  void boundChangeAdded(const HighsDomain& domain,\n                        const HighsDomainChange& domchg,\n                        bool branching = false);\n\n  void boundChangeRemoved(const HighsDomain& domain,\n                          const HighsDomainChange& domchg);\n\n  void resetDomain(const HighsDomain& domain);\n\n  void nodePruned(const HighsDomain& localdomain);\n\n  void checkCut(const HighsInt* Rindex, const double* Rvalue, HighsInt Rlen,\n                double rhs);\n\n  void checkRow(const HighsInt* Rindex, const double* Rvalue, HighsInt Rlen,\n                double Rlower, double Rupper);\n\n  void checkRowAggregation(const HighsLp& lp, const HighsInt* Rindex,\n                           const double* Rvalue, HighsInt Rlen);\n\n  void checkClique(const HighsCliqueTable::CliqueVar* clq, HighsInt clqlen);\n\n  void checkVub(HighsInt col, HighsInt vubcol, double vubcoef,\n                double vubconstant) const;\n\n  void checkVlb(HighsInt col, HighsInt vlbcol, double vlbcoef,\n                double vlbconstant) const;\n\n  void checkConflictReasonFrontier(\n      const std::set<HighsDomain::ConflictSet::LocalDomChg>& reasonSideFrontier,\n      const std::vector<HighsDomainChange>& domchgstack) const;\n\n  void checkConflictReconvergenceFrontier(\n      const std::set<HighsDomain::ConflictSet::LocalDomChg>&\n          reconvergenceFrontier,\n      const HighsDomain::ConflictSet::LocalDomChg& reconvDomchgPos,\n      const std::vector<HighsDomainChange>& domchgstack) const;\n};\n\n#else\nstruct HighsDebugSol {\n  HighsDebugSol(HighsMipSolver&) {}\n\n  void newIncumbentFound() const {}\n\n  void activate() const {}\n\n  void shrink(const std::vector<HighsInt>&) const {}\n\n  void registerDomain(const HighsDomain&) const {}\n\n  void boundChangeAdded(const HighsDomain&, const HighsDomainChange&,\n                        bool = false) const {}\n\n  void boundChangeRemoved(const HighsDomain&, const HighsDomainChange&) const {}\n\n  void resetDomain(const HighsDomain&) const {}\n\n  void nodePruned(const HighsDomain&) const {}\n\n  void checkCut(const HighsInt*, const double*, HighsInt, double) const {}\n\n  void checkRow(const HighsInt*, const double*, HighsInt, double,\n                double) const {}\n\n  void checkRowAggregation(const HighsLp&, const HighsInt*, const double*,\n                           HighsInt) const {}\n\n  void checkClique(const HighsCliqueTable::CliqueVar*, HighsInt) const {}\n\n  void checkVub(HighsInt, HighsInt, double, double) const {}\n\n  void checkVlb(HighsInt, HighsInt, double, double) const {}\n\n  void checkConflictReasonFrontier(\n      const std::set<HighsDomain::ConflictSet::LocalDomChg>&,\n      const std::vector<HighsDomainChange>&) const {}\n\n  void checkConflictReconvergenceFrontier(\n      const std::set<HighsDomain::ConflictSet::LocalDomChg>&,\n      const HighsDomain::ConflictSet::LocalDomChg&,\n      const std::vector<HighsDomainChange>&) const {}\n};\n#endif\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsDomain.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_DOMAIN_H_\n#define HIGHS_DOMAIN_H_\n\n#include <cstdint>\n#include <deque>\n#include <memory>\n#include <set>\n#include <vector>\n\n#include \"mip/HighsDomainChange.h\"\n#include \"mip/HighsMipSolver.h\"\n#include \"util/HighsCDouble.h\"\n#include \"util/HighsRbTree.h\"\n\nclass HighsCutPool;\nclass HighsConflictPool;\nclass HighsObjectiveFunction;\n\nclass HighsDomain {\n public:\n  struct Reason {\n    HighsInt type;\n    HighsInt index;\n\n    enum {\n      kBranching = -1,\n      kUnknown = -2,\n      kModelRowUpper = -3,\n      kModelRowLower = -4,\n      kCliqueTable = -5,\n      kConflictingBounds = -6,\n      kObjective = -7,\n    };\n    static Reason branching() { return Reason{kBranching, 0}; }\n    static Reason unspecified() { return Reason{kUnknown, 0}; }\n    static Reason cliqueTable(HighsInt col, HighsInt val) {\n      return Reason{kCliqueTable, 2 * col + val};\n    }\n    static Reason modelRowUpper(HighsInt row) {\n      return Reason{kModelRowUpper, row};\n    }\n    static Reason modelRowLower(HighsInt row) {\n      return Reason{kModelRowLower, row};\n    }\n    static Reason cut(HighsInt cutpool, HighsInt cut) {\n      return Reason{cutpool, cut};\n    }\n    static Reason conflictingBounds(HighsInt pos) {\n      return Reason{kConflictingBounds, pos};\n    }\n    static Reason objective() { return Reason{kObjective, 0}; }\n  };\n\n  class ConflictSet {\n    friend class HighsDomain;\n    HighsDomain& localdom;\n    HighsDomain& globaldom;\n\n   public:\n    struct LocalDomChg {\n      HighsInt pos;\n      mutable HighsDomainChange domchg;\n\n      bool operator<(const LocalDomChg& other) const { return pos < other.pos; }\n    };\n\n    ConflictSet(HighsDomain& localdom);\n\n    void conflictAnalysis(HighsConflictPool& conflictPool);\n    void conflictAnalysis(const HighsInt* proofinds, const double* proofvals,\n                          HighsInt prooflen, double proofrhs,\n                          HighsConflictPool& conflictPool);\n\n   private:\n    std::set<LocalDomChg> reasonSideFrontier;\n    std::set<LocalDomChg> reconvergenceFrontier;\n    std::vector<std::set<LocalDomChg>::iterator> resolveQueue;\n    std::vector<LocalDomChg> resolvedDomainChanges;\n\n    struct ResolveCandidate {\n      double delta;\n      double baseBound;\n      double prio;\n      HighsInt boundPos;\n      HighsInt valuePos;\n\n      bool operator<(const ResolveCandidate& other) const {\n        if (prio > other.prio) return true;\n        if (other.prio > prio) return false;\n\n        return boundPos < other.boundPos;\n      }\n    };\n\n    std::vector<ResolveCandidate> resolveBuffer;\n\n    void pushQueue(std::set<LocalDomChg>::iterator domchgPos);\n    std::set<LocalDomChg>::iterator popQueue();\n    void clearQueue();\n    HighsInt queueSize() const;\n    bool resolvable(HighsInt domChgPos) const;\n\n    HighsInt resolveDepth(std::set<LocalDomChg>& frontier, HighsInt depthLevel,\n                          HighsInt stopSize, HighsInt minResolve = 0,\n                          bool increaseConflictScore = false);\n\n    HighsInt computeCuts(HighsInt depthLevel, HighsConflictPool& conflictPool);\n\n    bool explainInfeasibility();\n\n    bool explainInfeasibilityConflict(const HighsDomainChange* conflict,\n                                      HighsInt len);\n\n    bool explainInfeasibilityLeq(const HighsInt* inds, const double* vals,\n                                 HighsInt len, double rhs, double minActivity);\n\n    bool explainInfeasibilityGeq(const HighsInt* inds, const double* vals,\n                                 HighsInt len, double rhs, double maxActivity);\n\n    bool explainBoundChange(const std::set<LocalDomChg>& currentFrontier,\n                            LocalDomChg domchg);\n\n    // bool explainBoundChange(HighsInt pos) {\n    //   return explainBoundChange(LocalDomChg{pos,\n    //   localdom.domchgstack_[pos]});\n    // }\n\n    bool explainBoundChangeConflict(const LocalDomChg& domchg,\n                                    const HighsDomainChange* conflict,\n                                    HighsInt len);\n\n    bool explainBoundChangeLeq(const std::set<LocalDomChg>& currentFrontier,\n                               const LocalDomChg& domChg, const HighsInt* inds,\n                               const double* vals, HighsInt len, double rhs,\n                               double minActivity);\n\n    bool explainBoundChangeGeq(const std::set<LocalDomChg>& currentFrontier,\n                               const LocalDomChg& domChg, const HighsInt* inds,\n                               const double* vals, HighsInt len, double rhs,\n                               double maxActivity);\n\n    bool resolveLinearLeq(HighsCDouble M, double Mlower, const double* vals);\n\n    bool resolveLinearGeq(HighsCDouble M, double Mupper, const double* vals);\n  };\n\n  struct CutpoolPropagation {\n    HighsInt cutpoolindex;\n    HighsDomain* domain;\n    HighsCutPool* cutpool;\n    std::vector<HighsCDouble> activitycuts_;\n    std::vector<HighsInt> activitycutsinf_;\n    std::vector<uint8_t> propagatecutflags_;\n    std::vector<HighsInt> propagatecutinds_;\n    std::vector<double> capacityThreshold_;\n\n    CutpoolPropagation(HighsInt cutpoolindex, HighsDomain* domain,\n                       HighsCutPool& cutpool);\n\n    CutpoolPropagation(const CutpoolPropagation& other);\n\n    ~CutpoolPropagation();\n\n    void recomputeCapacityThreshold(HighsInt cut);\n\n    void cutAdded(HighsInt cut, bool propagate);\n\n    void cutDeleted(HighsInt cut, bool deletedOnlyForPropagation = false);\n\n    void markPropagateCut(HighsInt cut);\n\n    void updateActivityLbChange(HighsInt col, double oldbound, double newbound);\n\n    void updateActivityUbChange(HighsInt col, double oldbound, double newbound);\n  };\n\n  struct ConflictPoolPropagation {\n    HighsInt conflictpoolindex;\n    HighsDomain* domain;\n    HighsConflictPool* conflictpool_;\n    std::vector<HighsInt> colLowerWatched_;\n    std::vector<HighsInt> colUpperWatched_;\n    std::vector<uint8_t> conflictFlag_;\n    std::vector<HighsInt> propagateConflictInds_;\n\n    struct WatchedLiteral {\n      HighsDomainChange domchg = {0.0, -1, HighsBoundType::kLower};\n      HighsInt prev = -1;\n      HighsInt next = -1;\n    };\n\n    std::vector<WatchedLiteral> watchedLiterals_;\n\n    ConflictPoolPropagation(HighsInt conflictpoolindex, HighsDomain* domain,\n                            HighsConflictPool& cutpool);\n\n    ConflictPoolPropagation(const ConflictPoolPropagation& other);\n\n    ~ConflictPoolPropagation();\n\n    void linkWatchedLiteral(HighsInt linkPos);\n\n    void unlinkWatchedLiteral(HighsInt linkPos);\n\n    void conflictAdded(HighsInt conflict);\n\n    void conflictDeleted(HighsInt conflict);\n\n    void markPropagateConflict(HighsInt conflict);\n\n    void updateActivityLbChange(HighsInt col, double oldbound, double newbound);\n\n    void updateActivityUbChange(HighsInt col, double oldbound, double newbound);\n\n    void propagateConflict(HighsInt conflict);\n  };\n\n private:\n  struct ObjectivePropagation {\n    HighsDomain* domain = nullptr;\n    const HighsObjectiveFunction* objFunc;\n    const double* cost;\n    HighsCDouble objectiveLower;\n    HighsInt numInfObjLower;\n    double capacityThreshold;\n    bool isPropagated;\n\n    struct ObjectiveContribution {\n      double contribution;\n      HighsInt col;\n      HighsInt partition;\n      highs::RbTreeLinks<HighsInt> links;\n    };\n\n    class ObjectiveContributionTree;\n\n    std::vector<ObjectiveContribution> objectiveLowerContributions;\n    std::vector<std::pair<HighsInt, HighsInt>> contributionPartitionSets;\n    std::vector<double> propagationConsBuffer;\n    struct PartitionCliqueData {\n      double multiplier;\n      HighsInt rhs;\n      bool changed;\n    };\n\n    std::vector<PartitionCliqueData> partitionCliqueData;\n\n    ObjectivePropagation() {\n      objFunc = nullptr;\n      cost = nullptr;\n      objectiveLower = 0.0;\n      numInfObjLower = 0;\n      capacityThreshold = 0.0;\n      isPropagated = false;\n    }\n    ObjectivePropagation(HighsDomain* domain);\n\n    bool isActive() const { return domain != nullptr; }\n\n    void updateActivityLbChange(HighsInt col, double oldbound, double newbound);\n\n    void updateActivityUbChange(HighsInt col, double oldbound, double newbound);\n\n    bool shouldBePropagated() const;\n\n    void propagate();\n\n    void debugCheckObjectiveLower() const;\n\n    // construct the proot constraint at the time when the domain change stack\n    // had the given size\n    void getPropagationConstraint(HighsInt domchgStackSize, const double*& vals,\n                                  const HighsInt*& inds, HighsInt& len,\n                                  double& rhs, HighsInt domchgCol = -1);\n\n   private:\n    void recomputeCapacityThreshold();\n  };\n\n  std::vector<uint8_t> changedcolsflags_;\n  std::vector<HighsInt> changedcols_;\n\n  std::vector<std::pair<HighsInt, HighsInt>> propRowNumChangedBounds_;\n\n  std::vector<HighsDomainChange> domchgstack_;\n  std::vector<Reason> domchgreason_;\n  std::vector<std::pair<double, HighsInt>> prevboundval_;\n\n  std::vector<HighsCDouble> activitymin_;\n  std::vector<HighsCDouble> activitymax_;\n  std::vector<HighsInt> activitymininf_;\n  std::vector<HighsInt> activitymaxinf_;\n  std::vector<double> capacityThreshold_;\n  std::vector<uint8_t> propagateflags_;\n  std::vector<HighsInt> propagateinds_;\n  ObjectivePropagation objProp_;\n\n  HighsMipSolver* mipsolver;\n\n private:\n  std::deque<CutpoolPropagation> cutpoolpropagation;\n  std::deque<ConflictPoolPropagation> conflictPoolPropagation;\n\n  bool infeasible_ = false;\n  Reason infeasible_reason;\n  HighsInt infeasible_pos;\n\n  void updateActivityLbChange(HighsInt col, double oldbound, double newbound);\n\n  void updateActivityUbChange(HighsInt col, double oldbound, double newbound);\n\n  void updateThresholdLbChange(HighsInt col, double newbound, double val,\n                               double& threshold) const;\n\n  void updateThresholdUbChange(HighsInt col, double newbound, double val,\n                               double& threshold) const;\n\n  void recomputeCapacityThreshold(HighsInt row);\n\n  void updateRedundantRows(HighsInt row, HighsInt direction, HighsInt numInf,\n                           HighsCDouble activity, double bound);\n\n  double doChangeBound(const HighsDomainChange& boundchg);\n\n  std::vector<HighsInt> colLowerPos_;\n  std::vector<HighsInt> colUpperPos_;\n  std::vector<HighsInt> branchPos_;\n  HighsHashTable<HighsInt> redundantRows_;\n  bool recordRedundantRows_ = false;\n\n public:\n  std::vector<double> col_lower_;\n  std::vector<double> col_upper_;\n\n  HighsDomain(HighsMipSolver& mipsolver);\n\n  HighsDomain(const HighsDomain& other)\n      : changedcolsflags_(other.changedcolsflags_),\n        changedcols_(other.changedcols_),\n        domchgstack_(other.domchgstack_),\n        domchgreason_(other.domchgreason_),\n        prevboundval_(other.prevboundval_),\n        activitymin_(other.activitymin_),\n        activitymax_(other.activitymax_),\n        activitymininf_(other.activitymininf_),\n        activitymaxinf_(other.activitymaxinf_),\n        capacityThreshold_(other.capacityThreshold_),\n        propagateflags_(other.propagateflags_),\n        propagateinds_(other.propagateinds_),\n        objProp_(other.objProp_),\n        mipsolver(other.mipsolver),\n        cutpoolpropagation(other.cutpoolpropagation),\n        conflictPoolPropagation(other.conflictPoolPropagation),\n        infeasible_(other.infeasible_),\n        infeasible_reason(other.infeasible_reason),\n        infeasible_pos(other.infeasible_pos),\n        colLowerPos_(other.colLowerPos_),\n        colUpperPos_(other.colUpperPos_),\n        branchPos_(other.branchPos_),\n        col_lower_(other.col_lower_),\n        col_upper_(other.col_upper_) {\n    for (CutpoolPropagation& cutpoolprop : cutpoolpropagation)\n      cutpoolprop.domain = this;\n    for (ConflictPoolPropagation& conflictprop : conflictPoolPropagation)\n      conflictprop.domain = this;\n    if (objProp_.domain) objProp_.domain = this;\n  }\n\n  HighsDomain& operator=(const HighsDomain& other) {\n    changedcolsflags_ = other.changedcolsflags_;\n    changedcols_ = other.changedcols_;\n    domchgstack_ = other.domchgstack_;\n    domchgreason_ = other.domchgreason_;\n    prevboundval_ = other.prevboundval_;\n    activitymin_ = other.activitymin_;\n    activitymax_ = other.activitymax_;\n    activitymininf_ = other.activitymininf_;\n    activitymaxinf_ = other.activitymaxinf_;\n    capacityThreshold_ = other.capacityThreshold_;\n    propagateflags_ = other.propagateflags_;\n    propagateinds_ = other.propagateinds_;\n    objProp_ = other.objProp_;\n    mipsolver = other.mipsolver;\n    cutpoolpropagation = other.cutpoolpropagation;\n    conflictPoolPropagation = other.conflictPoolPropagation;\n    infeasible_ = other.infeasible_;\n    infeasible_reason = other.infeasible_reason;\n    colLowerPos_ = other.colLowerPos_;\n    colUpperPos_ = other.colUpperPos_;\n    branchPos_ = other.branchPos_;\n    col_lower_ = other.col_lower_;\n    col_upper_ = other.col_upper_;\n    for (CutpoolPropagation& cutpoolprop : cutpoolpropagation)\n      cutpoolprop.domain = this;\n    for (ConflictPoolPropagation& conflictprop : conflictPoolPropagation)\n      conflictprop.domain = this;\n    if (objProp_.domain) objProp_.domain = this;\n    return *this;\n  }\n\n  void computeMinActivity(HighsInt start, HighsInt end, const HighsInt* ARindex,\n                          const double* ARvalue, HighsInt& ninfmin,\n                          HighsCDouble& activitymin) const;\n\n  void computeMaxActivity(HighsInt start, HighsInt end, const HighsInt* ARindex,\n                          const double* ARvalue, HighsInt& ninfmax,\n                          HighsCDouble& activitymax) const;\n\n  double adjustedUb(HighsInt col, HighsCDouble boundVal, bool& accept) const;\n\n  double adjustedLb(HighsInt col, HighsCDouble boundVal, bool& accept) const;\n\n  HighsInt propagateRowUpper(const HighsInt* Rindex, const double* Rvalue,\n                             HighsInt Rlen, double Rupper,\n                             const HighsCDouble& minactivity, HighsInt ninfmin,\n                             HighsDomainChange* boundchgs) const;\n\n  HighsInt propagateRowLower(const HighsInt* Rindex, const double* Rvalue,\n                             HighsInt Rlen, double Rlower,\n                             const HighsCDouble& maxactivity, HighsInt ninfmax,\n                             HighsDomainChange* boundchgs) const;\n\n  const std::vector<HighsInt>& getChangedCols() const { return changedcols_; }\n\n  void addCutpool(HighsCutPool& cutpool);\n\n  void addConflictPool(HighsConflictPool& conflictPool);\n\n  void clearChangedCols() {\n    for (HighsInt i : changedcols_) changedcolsflags_[i] = 0;\n    changedcols_.clear();\n  }\n\n  void removeContinuousChangedCols() {\n    for (HighsInt i : changedcols_)\n      changedcolsflags_[i] =\n          mipsolver->variableType(i) != HighsVarType::kContinuous;\n\n    changedcols_.erase(\n        std::remove_if(changedcols_.begin(), changedcols_.end(),\n                       [&](HighsInt i) { return !changedcolsflags_[i]; }),\n        changedcols_.end());\n  }\n\n  void clearChangedCols(HighsInt start) {\n    HighsInt end = changedcols_.size();\n    for (HighsInt i = start; i != end; ++i)\n      changedcolsflags_[changedcols_[i]] = 0;\n\n    changedcols_.resize(start);\n  }\n\n  void markPropagate(HighsInt row);\n\n  bool isActive(const HighsDomainChange& domchg) const {\n    return domchg.boundtype == HighsBoundType::kLower\n               ? domchg.boundval <= col_lower_[domchg.column]\n               : domchg.boundval >= col_upper_[domchg.column];\n  }\n\n  void markPropagateCut(Reason reason);\n\n  void setupObjectivePropagation() { objProp_ = ObjectivePropagation(this); }\n\n  void computeRowActivities();\n\n  void markInfeasible(Reason reason = Reason::unspecified()) {\n    infeasible_ = true;\n    infeasible_pos = domchgstack_.size();\n    infeasible_reason = reason;\n  }\n\n  bool infeasible() const { return infeasible_; }\n\n  void changeBound(HighsDomainChange boundchg,\n                   Reason reason = Reason::branching());\n\n  void changeBound(HighsBoundType boundtype, HighsInt col, double boundval,\n                   Reason reason = Reason::branching()) {\n    changeBound({boundval, col, boundtype}, reason);\n  }\n\n  void fixCol(HighsInt col, double val, Reason reason = Reason::unspecified()) {\n    if (kAllowDeveloperAssert) {\n      assert(infeasible_ == 0);\n    }\n    if (col_lower_[col] < val) {\n      changeBound({val, col, HighsBoundType::kLower}, reason);\n      if (infeasible_ == 0) propagate();\n    }\n\n    if (infeasible_ == 0 && col_upper_[col] > val)\n      changeBound({val, col, HighsBoundType::kUpper}, reason);\n  }\n\n  void backtrackToGlobal();\n\n  HighsDomainChange backtrack();\n\n  const std::vector<HighsInt>& getBranchingPositions() const {\n    return branchPos_;\n  }\n\n  const std::vector<std::pair<double, HighsInt>>& getPreviousBounds() const {\n    return prevboundval_;\n  }\n\n  const std::vector<HighsDomainChange>& getDomainChangeStack() const {\n    return domchgstack_;\n  }\n\n  const std::vector<Reason>& getDomainChangeReason() const {\n    return domchgreason_;\n  }\n\n  double getObjectiveLowerBound() const {\n    if (objProp_.isActive() && objProp_.numInfObjLower == 0)\n      return double(objProp_.objectiveLower);\n\n    return -kHighsInf;\n  }\n\n  void getCutoffConstraint(const double*& vals, const HighsInt*& inds,\n                           HighsInt& len, double& rhs) {\n    objProp_.getPropagationConstraint(domchgstack_.size(), vals, inds, len,\n                                      rhs);\n  }\n\n  HighsInt getNumDomainChanges() const { return domchgstack_.size(); }\n\n  bool colBoundsAreGlobal(HighsInt col) const {\n    return colLowerPos_[col] == -1 && colUpperPos_[col] == -1;\n  }\n\n  HighsInt getBranchDepth() const { return branchPos_.size(); }\n\n  std::vector<HighsDomainChange> getReducedDomainChangeStack(\n      std::vector<HighsInt>& branchingPositions) const {\n    std::vector<HighsDomainChange> reducedstack;\n    reducedstack.reserve(domchgstack_.size());\n    branchingPositions.reserve(branchPos_.size());\n    for (HighsInt i = 0; i < (HighsInt)domchgstack_.size(); ++i) {\n      // keep only the tightest bound change for each variable\n      if ((domchgstack_[i].boundtype == HighsBoundType::kLower &&\n           colLowerPos_[domchgstack_[i].column] != i) ||\n          (domchgstack_[i].boundtype == HighsBoundType::kUpper &&\n           colUpperPos_[domchgstack_[i].column] != i))\n        continue;\n\n      if (domchgreason_[i].type == Reason::kBranching)\n        branchingPositions.push_back(reducedstack.size());\n      else {\n        HighsInt k = i;\n        while (prevboundval_[k].second != -1) {\n          k = prevboundval_[k].second;\n          if (domchgreason_[k].type == Reason::kBranching) {\n            branchingPositions.push_back(reducedstack.size());\n            break;\n          }\n        }\n      }\n\n      reducedstack.push_back(domchgstack_[i]);\n    }\n\n    reducedstack.shrink_to_fit();\n    return reducedstack;\n  }\n\n  void setDomainChangeStack(const std::vector<HighsDomainChange>& domchgstack);\n\n  void setDomainChangeStack(const std::vector<HighsDomainChange>& domchgstack,\n                            const std::vector<HighsInt>& branchingPositions);\n\n  bool propagate();\n\n  double getColLowerPos(HighsInt col, HighsInt stackpos, HighsInt& pos) const;\n\n  double getColUpperPos(HighsInt col, HighsInt stackpos, HighsInt& pos) const;\n\n  void conflictAnalysis(HighsConflictPool& conflictPool);\n\n  void conflictAnalysis(const HighsInt* proofinds, const double* proofvals,\n                        HighsInt prooflen, double proofrhs,\n                        HighsConflictPool& conflictPool);\n\n  void conflictAnalyzeReconvergence(const HighsDomainChange& domchg,\n                                    const HighsInt* proofinds,\n                                    const double* proofvals, HighsInt prooflen,\n                                    double proofrhs,\n                                    HighsConflictPool& conflictPool);\n\n  void tightenCoefficients(HighsInt* inds, double* vals, HighsInt len,\n                           double& rhs) const;\n\n  double getMinActivity(HighsInt row) const {\n    return activitymininf_[row] == 0 ? double(activitymin_[row]) : -kHighsInf;\n  }\n\n  double getMaxActivity(HighsInt row) const {\n    return activitymaxinf_[row] == 0 ? double(activitymax_[row]) : kHighsInf;\n  }\n\n  double getMinCutActivity(const HighsCutPool& cutpool, HighsInt cut) const;\n\n  bool isBinary(HighsInt col) const {\n    return mipsolver->variableType(col) != HighsVarType::kContinuous &&\n           col_lower_[col] == 0.0 && col_upper_[col] == 1.0;\n  }\n\n  bool isGlobalBinary(HighsInt col) const {\n    return mipsolver->variableType(col) != HighsVarType::kContinuous &&\n           mipsolver->model_->col_lower_[col] == 0.0 &&\n           mipsolver->model_->col_upper_[col] == 1.0;\n  }\n\n  HighsVarType variableType(HighsInt col) const {\n    return mipsolver->variableType(col);\n  }\n\n  bool isFixed(HighsInt col) const {\n    return col_lower_[col] == col_upper_[col];\n  }\n\n  bool isFixing(const HighsDomainChange& domchg) const;\n\n  HighsDomainChange flip(const HighsDomainChange& domchg) const;\n\n  double feastol() const;\n\n  HighsInt numModelNonzeros() const { return mipsolver->numNonzero(); }\n\n  bool inSubmip() const { return mipsolver->submip; }\n\n  void clearRedundantRows() { redundantRows_.clear(); };\n\n  const HighsHashTable<HighsInt>& getRedundantRows() const {\n    return redundantRows_;\n  };\n\n  double getRedundantRowValue(HighsInt row) const;\n\n  void setRecordRedundantRows(bool val) { recordRedundantRows_ = val; };\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsDomainChange.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n#ifndef HIGHS_DOMAIN_CHANGE_H_\n#define HIGHS_DOMAIN_CHANGE_H_\n\n#include \"util/HighsInt.h\"\n\nenum class HighsBoundType { kLower, kUpper };\n\nstruct HighsDomainChange {\n  double boundval;\n  HighsInt column;\n  HighsBoundType boundtype;\n\n  bool operator<(const HighsDomainChange& other) const {\n    if (column < other.column) return true;\n    if (other.column < column) return false;\n    if ((HighsInt)boundtype < (HighsInt)other.boundtype) return true;\n    if ((HighsInt)other.boundtype < (HighsInt)boundtype) return false;\n    if (boundval < other.boundval) return true;\n    return false;\n  }\n\n  bool operator==(const HighsDomainChange& other) const {\n    return boundtype == other.boundtype && column == other.column &&\n           boundval == other.boundval;\n  }\n\n  bool operator!=(const HighsDomainChange& other) const {\n    return boundtype != other.boundtype || column != other.column ||\n           boundval != other.boundval;\n  }\n};\n\nstruct HighsSubstitution {\n  HighsInt substcol;\n  HighsInt staycol;\n  double scale;\n  double offset;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsDynamicRowMatrix.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_DYNAMIC_ROW_MATRIX_H_\n#define HIGHS_DYNAMIC_ROW_MATRIX_H_\n\n#include <set>\n#include <utility>\n#include <vector>\n\n#include \"util/HighsInt.h\"\n\nclass HighsDynamicRowMatrix {\n private:\n  /// vector of index ranges in the index and value arrays of AR for each row\n  std::vector<std::pair<HighsInt, HighsInt>> ARrange_;\n\n  /// column indices for each nonzero in AR\n  std::vector<HighsInt> ARindex_;\n  /// values for each nonzero in AR\n  std::vector<double> ARvalue_;\n\n  std::vector<HighsInt> ARrowindex_;\n  std::vector<HighsInt> AnextPos_;\n  std::vector<HighsInt> AprevPos_;\n  std::vector<HighsInt> AnextNeg_;\n  std::vector<HighsInt> AprevNeg_;\n\n  /// vector of pointers to the head/tail of the nonzero block list for each\n  /// column\n  std::vector<HighsInt> AheadPos_;\n  std::vector<HighsInt> AheadNeg_;\n\n  std::vector<uint8_t> colsLinked;\n\n  /// vector of column sizes\n\n  /// keep an ordered set of free spaces in the row arrays so that they can be\n  /// reused efficiently\n  std::set<std::pair<HighsInt, HighsInt>> freespaces_;\n\n  /// vector of deleted rows so that their indices can be reused\n  std::vector<HighsInt> deletedrows_;\n\n public:\n  HighsDynamicRowMatrix(HighsInt ncols);\n\n  bool columnsLinked(HighsInt rowindex) const {\n    return (colsLinked[rowindex] != 0);\n  }\n\n  void unlinkColumns(HighsInt rowindex);\n\n  /// adds a row to the matrix with the given values and returns its index\n  HighsInt addRow(HighsInt* Rindex, double* Rvalue, HighsInt Rlen,\n                  bool linkCols = true);\n\n  /// removes the row with the given index from the matrix, afterwards the index\n  /// can be reused for new rows\n  void removeRow(HighsInt rowindex);\n\n  std::size_t nonzeroCapacity() const { return ARvalue_.size(); }\n\n  /// calls the given function object for each entry in the given column.\n  /// The function object should accept the row index as first argument and\n  /// the nonzero value of the column in that row as the second argument.\n  template <typename Func>\n  void forEachPositiveColumnEntry(HighsInt col, Func&& f) const {\n    HighsInt iter = AheadPos_[col];\n\n    while (iter != -1) {\n      if (!f(ARrowindex_[iter], ARvalue_[iter])) break;\n      iter = AnextPos_[iter];\n    }\n  }\n\n  template <typename Func>\n  void forEachNegativeColumnEntry(HighsInt col, Func&& f) const {\n    HighsInt iter = AheadNeg_[col];\n\n    while (iter != -1) {\n      if (!f(ARrowindex_[iter], ARvalue_[iter])) break;\n      iter = AnextNeg_[iter];\n    }\n  }\n\n  HighsInt getNumRows() const { return ARrange_.size(); }\n\n  HighsInt getNumDelRows() const { return deletedrows_.size(); }\n\n  HighsInt getRowStart(HighsInt row) const { return ARrange_[row].first; }\n\n  HighsInt getRowEnd(HighsInt row) const { return ARrange_[row].second; }\n\n  const HighsInt* getARindex() const { return ARindex_.data(); }\n\n  const double* getARvalue() const { return ARvalue_.data(); }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsGFkSolve.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file mip/HighsGFkLU.h\n * @brief linear system solve in GF(k) for mod-k cut separation\n */\n\n#ifndef HIGHS_GFk_SOLVE_H_\n#define HIGHS_GFk_SOLVE_H_\n\n#include <algorithm>\n#include <cassert>\n#include <queue>\n#include <tuple>\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n\n// helper struct to compute the multiplicative inverse by using fermats\n// theorem and recursive repeated squaring.\n// Under the assumption that k is a small prime and an 32bit HighsInt is enough\n// to hold the number (k-1)^(k-2) good compilers should be able to optimize this\n// code by inlining and unfolding the recursion to code that uses the fewest\n// amount of integer multiplications and optimize the single integer division\n// away as k is a compile time constant. Since the class was developed for the\n// purpose of separating maximally violated mod-k cuts the assumption that k is\n// a small constant prime number is not restrictive.\n\ntemplate <HighsInt k>\nstruct HighsGFk;\n\ntemplate <>\nstruct HighsGFk<2> {\n  static constexpr unsigned int powk(unsigned int a) { return a * a; }\n  static constexpr unsigned int inverse(unsigned int) { return 1; }\n};\n\ntemplate <>\nstruct HighsGFk<3> {\n  static constexpr unsigned int powk(unsigned int a) { return a * a * a; }\n  static constexpr unsigned int inverse(unsigned int a) { return a; }\n};\n\ntemplate <HighsInt k>\nstruct HighsGFk {\n  static constexpr unsigned int powk(unsigned int a) {\n    return (k & 1) == 0 ? HighsGFk<2>::powk(HighsGFk<k / 2>::powk(a))\n                        : HighsGFk<k - 1>::powk(a) * a;\n  }\n\n  static unsigned int inverse(unsigned int a) {\n    return HighsGFk<k - 2>::powk(a) % k;\n  }\n};\n\nclass HighsGFkSolve {\n  HighsInt numCol;\n  HighsInt numRow;\n\n  // triplet format\n  std::vector<HighsInt> Arow;\n  std::vector<HighsInt> Acol;\n  std::vector<unsigned int> Avalue;\n\n  // sizes of rows and columns\n  std::vector<HighsInt> rowsize;\n  std::vector<HighsInt> colsize;\n\n  // linked list links for column based links for each nonzero\n  std::vector<HighsInt> colhead;\n  std::vector<HighsInt> Anext;\n  std::vector<HighsInt> Aprev;\n\n  // splay tree links for row based iteration and lookup\n  std::vector<HighsInt> rowroot;\n  std::vector<HighsInt> ARleft;\n  std::vector<HighsInt> ARright;\n\n  // right hand side vector\n  std::vector<unsigned int> rhs;\n\n  // column permutation for the factorization required for backwards solve\n  std::vector<HighsInt> factorColPerm;\n  std::vector<HighsInt> factorRowPerm;\n  std::vector<int8_t> colBasisStatus;\n  std::vector<int8_t> rowUsed;\n\n  // working memory\n  std::vector<HighsInt> iterstack;\n  std::vector<HighsInt> rowpositions;\n  std::vector<HighsInt> rowposColsizes;\n\n  // priority queue to reuse free slots\n  std::priority_queue<HighsInt, std::vector<HighsInt>, std::greater<HighsInt>>\n      freeslots;\n\n  void link(HighsInt pos);\n\n  void unlink(HighsInt pos);\n\n  void dropIfZero(HighsInt pos) {\n    if (Avalue[pos] == 0) unlink(pos);\n  }\n\n  void storeRowPositions(HighsInt pos);\n\n  void addNonzero(HighsInt row, HighsInt col, unsigned int val);\n\n public:\n  struct SolutionEntry {\n    HighsInt index;\n    HighsUInt weight;\n\n    bool operator<(const SolutionEntry& other) const {\n      return index < other.index;\n    }\n  };\n\n  // access to triplets and find nonzero function for unit test\n  const std::vector<HighsInt>& getArow() const { return Arow; }\n  const std::vector<HighsInt>& getAcol() const { return Acol; }\n  const std::vector<unsigned>& getAvalue() const { return Avalue; }\n  HighsInt numNonzeros() const { return int(Avalue.size() - freeslots.size()); }\n  HighsInt findNonzero(HighsInt row, HighsInt col);\n\n  template <unsigned int k, int kNumRhs = 1, typename T>\n  void fromCSC(const std::vector<T>& Aval, const std::vector<HighsInt>& Aindex,\n               const std::vector<HighsInt>& Astart, HighsInt numRow) {\n    Avalue.clear();\n    Acol.clear();\n    Arow.clear();\n\n    freeslots = decltype(freeslots)();\n\n    numCol = Astart.size() - 1;\n    this->numRow = numRow;\n\n    colhead.assign(numCol, -1);\n    colsize.assign(numCol, 0);\n\n    rhs.assign(kNumRhs * numRow, 0);\n    rowroot.assign(numRow, -1);\n    rowsize.assign(numRow, 0);\n\n    Avalue.reserve(Aval.size());\n    Acol.reserve(Aval.size());\n    Arow.reserve(Aval.size());\n\n    for (HighsInt i = 0; i != numCol; ++i) {\n      for (HighsInt j = Astart[i]; j != Astart[i + 1]; ++j) {\n        assert(Aval[j] == (int64_t)Aval[j]);\n        int64_t val = ((int64_t)Aval[j]) % k;\n        if (val == 0) continue;\n\n        if (val < 0) val += k;\n        assert(val >= 0);\n\n        Avalue.push_back(val);\n        Acol.push_back(i);\n        Arow.push_back(Aindex[j]);\n      }\n    }\n\n    HighsInt nnz = Avalue.size();\n    Anext.resize(nnz);\n    Aprev.resize(nnz);\n    ARleft.resize(nnz);\n    ARright.resize(nnz);\n    for (HighsInt pos = 0; pos != nnz; ++pos) link(pos);\n  }\n\n  template <unsigned int k, int kNumRhs = 1, typename T>\n  void setRhs(HighsInt row, T val, int rhsIndex = 0) {\n    rhs[kNumRhs * row + rhsIndex] = ((unsigned int)std::abs(val)) % k;\n  }\n\n  template <unsigned int k, int kNumRhs = 1, typename ReportSolution>\n  void solve(ReportSolution&& reportSolution) {\n    auto cmpPrio = [](const std::pair<HighsInt, HighsInt>& a,\n                      const std::pair<HighsInt, HighsInt>& b) {\n      return a.first > b.first;\n    };\n    std::priority_queue<std::pair<HighsInt, HighsInt>,\n                        std::vector<std::pair<HighsInt, HighsInt>>,\n                        decltype(cmpPrio)>\n        pqueue(cmpPrio);\n\n    for (HighsInt i = 0; i != numCol; ++i) pqueue.emplace(colsize[i], i);\n\n    HighsInt maxPivot = std::min(numRow, numCol);\n    factorColPerm.clear();\n    factorRowPerm.clear();\n    factorColPerm.reserve(maxPivot);\n    factorRowPerm.reserve(maxPivot);\n    colBasisStatus.assign(numCol, 0);\n    rowUsed.assign(numRow, 0);\n    HighsInt numPivot = 0;\n\n    while (!pqueue.empty()) {\n      HighsInt pivotCol;\n      HighsInt oldColSize;\n\n      std::tie(oldColSize, pivotCol) = pqueue.top();\n      pqueue.pop();\n\n      if (colsize[pivotCol] == 0) continue;\n\n      assert(colBasisStatus[pivotCol] == 0);\n\n      if (colsize[pivotCol] != oldColSize) {\n        pqueue.emplace(colsize[pivotCol], pivotCol);\n        continue;\n      }\n\n      HighsInt pivot = -1;\n      HighsInt pivotRow = -1;\n      HighsInt pivotRowLen = kHighsIInf;\n      for (HighsInt coliter = colhead[pivotCol]; coliter != -1;\n           coliter = Anext[coliter]) {\n        HighsInt row = Arow[coliter];\n        if (rowUsed[row]) continue;\n        if (rowsize[row] < pivotRowLen) {\n          pivotRowLen = rowsize[row];\n          pivotRow = row;\n          pivot = coliter;\n        }\n      }\n\n      assert(pivot != -1);\n      assert(Acol[pivot] == pivotCol);\n      assert(Arow[pivot] == pivotRow);\n      assert(Avalue[pivot] > 0);\n      assert(Avalue[pivot] < k);\n\n      unsigned int pivotInverse = HighsGFk<k>::inverse(Avalue[pivot]);\n      assert((Avalue[pivot] * pivotInverse) % k == 1);\n\n      rowpositions.clear();\n      rowposColsizes.clear();\n      storeRowPositions(rowroot[pivotRow]);\n      assert(pivotRowLen == (HighsInt)rowpositions.size());\n      HighsInt next;\n      for (HighsInt coliter = colhead[pivotCol]; coliter != -1;\n           coliter = next) {\n        next = Anext[coliter];\n        if (coliter == pivot) continue;\n\n        assert(Acol[coliter] == pivotCol);\n        assert(Arow[coliter] != pivotRow);\n        assert(Avalue[coliter] != 0);\n\n        HighsInt row = Arow[coliter];\n        if (rowUsed[row]) continue;\n\n        unsigned int pivotRowScale = pivotInverse * (k - Avalue[coliter]);\n\n        for (HighsInt i = 0; i < kNumRhs; ++i)\n          rhs[kNumRhs * row + i] =\n              (rhs[kNumRhs * row + i] +\n               pivotRowScale * rhs[kNumRhs * pivotRow + i]) %\n              k;\n\n        for (HighsInt pivotRowPos : rowpositions) {\n          HighsInt nonzeroPos = findNonzero(Arow[coliter], Acol[pivotRowPos]);\n\n          if (nonzeroPos == -1) {\n            assert(Acol[pivotRowPos] != pivotCol);\n            unsigned int val = (pivotRowScale * Avalue[pivotRowPos]) % k;\n            if (val != 0) addNonzero(row, Acol[pivotRowPos], val);\n          } else {\n            Avalue[nonzeroPos] =\n                (Avalue[nonzeroPos] + pivotRowScale * Avalue[pivotRowPos]) % k;\n            assert(Acol[pivotRowPos] != pivotCol || Avalue[nonzeroPos] == 0);\n            dropIfZero(nonzeroPos);\n          }\n        }\n      }\n\n      ++numPivot;\n      factorColPerm.push_back(pivotCol);\n      factorRowPerm.push_back(pivotRow);\n      colBasisStatus[pivotCol] = 1;\n      rowUsed[pivotRow] = 1;\n      if (numPivot == maxPivot) break;\n\n      for (HighsInt i = 0; i != pivotRowLen; ++i) {\n        assert(Arow[rowpositions[i]] == pivotRow);\n        HighsInt col = Acol[rowpositions[i]];\n        HighsInt oldsize = rowposColsizes[i];\n\n        // we only want to count rows that are not used so far, so we need to\n        // decrease the counter for all columns in the pivot row by one\n        --colsize[col];\n\n        // the column size should never get negative\n        assert(colsize[col] >= 0);\n\n        if (colsize[col] == 0) continue;\n\n        // the pivot column should occur in zero unused rows\n        assert(col != pivotCol);\n\n        // only reinsert the column if the size is smaller, as it otherwise\n        // either is already at the correct position in the queue, or is at a\n        // too good position and will be lazily reinserted when it is extracted\n        // from the queue and the size does not match\n        if (colsize[col] < oldsize) pqueue.emplace(colsize[col], col);\n      }\n    }\n\n    // check if a solution exists by scanning the linearly dependent rows for\n    // nonzero right hand sides\n    std::array<bool, kNumRhs> hasSolution;\n    HighsInt numRhsWithSolution = 0;\n    for (int rhsIndex = 0; rhsIndex < kNumRhs; ++rhsIndex) {\n      hasSolution[rhsIndex] = true;\n      for (HighsInt i = 0; i != numRow; ++i) {\n        // if the row was used it is linearly independent\n        if (rowUsed[i] == 1) continue;\n\n        // if the row is linearly dependent, the right hand side must be zero,\n        // otherwise no solution exists\n        if (rhs[kNumRhs * i + rhsIndex] != 0) {\n          hasSolution[rhsIndex] = false;\n          break;\n        }\n      }\n\n      numRhsWithSolution += hasSolution[rhsIndex];\n    }\n\n    if (numRhsWithSolution == 0) return;\n\n    // now iterate a subset of the basic solutions.\n    // When a column leaves the basis we do not allow it to enter again so that\n    // we iterate at most one solution for each nonbasic column\n    std::array<std::vector<SolutionEntry>, kNumRhs> solution;\n    for (int rhsIndex = 0; rhsIndex < kNumRhs; ++rhsIndex)\n      if (hasSolution[rhsIndex]) solution[rhsIndex].reserve(numCol);\n\n    HighsInt numFactorRows = factorRowPerm.size();\n\n    // create vector for swapping different columns into the basis\n    // For each column we want to iterate one basic solution where the\n    // column is basic\n    std::vector<std::pair<HighsInt, HighsInt>> basisSwaps;\n    assert(iterstack.empty());\n    for (HighsInt i = numFactorRows - 1; i >= 0; --i) {\n      HighsInt row = factorRowPerm[i];\n      iterstack.push_back(rowroot[row]);\n\n      while (!iterstack.empty()) {\n        HighsInt rowpos = iterstack.back();\n        iterstack.pop_back();\n        assert(rowpos != -1);\n\n        if (ARleft[rowpos] != -1) iterstack.push_back(ARleft[rowpos]);\n        if (ARright[rowpos] != -1) iterstack.push_back(ARright[rowpos]);\n\n        HighsInt col = Acol[rowpos];\n        if (colBasisStatus[col] != 0) continue;\n\n        colBasisStatus[col] = -1;\n        basisSwaps.emplace_back(i, col);\n      }\n    }\n\n    HighsInt basisSwapPos = 0;\n\n    bool performedBasisSwap;\n    do {\n      performedBasisSwap = false;\n\n      for (int rhsIndex = 0; rhsIndex < kNumRhs; ++rhsIndex)\n        solution[rhsIndex].clear();\n\n      for (HighsInt i = numFactorRows - 1; i >= 0; --i) {\n        HighsInt row = factorRowPerm[i];\n\n        std::array<unsigned int, kNumRhs> solval;\n\n        for (int rhsIndex = 0; rhsIndex < kNumRhs; ++rhsIndex) {\n          if (!hasSolution[rhsIndex]) continue;\n          solval[rhsIndex] = 0;\n\n          for (const SolutionEntry& solentry : solution[rhsIndex]) {\n            HighsInt pos = findNonzero(row, solentry.index);\n            if (pos != -1) solval[rhsIndex] += Avalue[pos] * solentry.weight;\n          }\n\n          solval[rhsIndex] =\n              rhs[kNumRhs * row + rhsIndex] + k - (solval[rhsIndex] % k);\n        }\n\n        HighsInt col = factorColPerm[i];\n        HighsInt pos = findNonzero(row, col);\n        assert(pos != -1);\n        unsigned int colValInverse = HighsGFk<k>::inverse(Avalue[pos]);\n\n        for (int rhsIndex = 0; rhsIndex < kNumRhs; ++rhsIndex) {\n          if (!hasSolution[rhsIndex]) continue;\n          assert(solval[rhsIndex] >= 0);\n          assert(colValInverse != 0);\n\n          solval[rhsIndex] = (solval[rhsIndex] * colValInverse) % k;\n\n          assert(solval[rhsIndex] >= 0 && solval[rhsIndex] < k);\n\n          // only record nonzero solution values\n          if (solval[rhsIndex] != 0)\n            solution[rhsIndex].emplace_back(\n                SolutionEntry{col, solval[rhsIndex]});\n        }\n      }\n\n      for (int rhsIndex = 0; rhsIndex < kNumRhs; ++rhsIndex)\n        if (hasSolution[rhsIndex]) reportSolution(solution[rhsIndex], rhsIndex);\n\n      if (basisSwapPos < (HighsInt)basisSwaps.size()) {\n        HighsInt basisIndex = basisSwaps[basisSwapPos].first;\n        HighsInt enteringCol = basisSwaps[basisSwapPos].second;\n        HighsInt leavingCol = factorColPerm[basisIndex];\n        assert(colBasisStatus[leavingCol] == 1);\n        factorColPerm[basisIndex] = enteringCol;\n        colBasisStatus[enteringCol] = 1;\n        colBasisStatus[leavingCol] = 0;\n        performedBasisSwap = true;\n        ++basisSwapPos;\n      }\n    } while (performedBasisSwap);\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsImplications.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_IMPLICATIONS_H_\n#define HIGHS_IMPLICATIONS_H_\n\n#include <algorithm>\n#include <cassert>\n#include <utility>\n#include <vector>\n\n#include \"mip/HighsDomain.h\"\n#include \"mip/HighsDomainChange.h\"\n#include \"util/HighsHashTree.h\"\n\nclass HighsCliqueTable;\nclass HighsLpRelaxation;\n\nclass HighsImplications {\n  HighsInt nextCleanupCall;\n\n  struct Implics {\n    std::vector<HighsDomainChange> implics;\n    bool computed = false;\n  };\n  std::vector<Implics> implications;\n  int64_t numImplications;\n  int64_t numVarBounds;\n  int64_t maxVarBounds;\n\n  bool computeImplications(HighsInt col, bool val);\n\n public:\n  struct VarBound {\n    double coef;\n    double constant;\n\n    double minValue() const {\n      return static_cast<double>(static_cast<HighsCDouble>(constant) +\n                                 std::min(coef, 0.0));\n    }\n    double maxValue() const {\n      return static_cast<double>(static_cast<HighsCDouble>(constant) +\n                                 std::max(coef, 0.0));\n    }\n  };\n\n private:\n  std::vector<HighsHashTree<HighsInt, VarBound>> vubs;\n  std::vector<HighsHashTree<HighsInt, VarBound>> vlbs;\n\n public:\n  const HighsMipSolver& mipsolver;\n  std::vector<HighsSubstitution> substitutions;\n  std::vector<uint8_t> colsubstituted;\n  HighsImplications(const HighsMipSolver& mipsolver) : mipsolver(mipsolver) {\n    HighsInt numcol = mipsolver.numCol();\n    implications.resize(2 * static_cast<size_t>(numcol));\n    colsubstituted.resize(numcol);\n    vubs.resize(numcol);\n    vlbs.resize(numcol);\n    nextCleanupCall = mipsolver.numNonzero();\n    numImplications = 0;\n    numVarBounds = 0;\n    maxVarBounds = calcMaxVarBounds(numcol);\n  }\n\n  std::function<void(HighsInt, HighsInt, HighsInt, double)>\n      storeLiftingOpportunity;\n\n  void reset() {\n    colsubstituted.clear();\n    colsubstituted.shrink_to_fit();\n    implications.clear();\n    implications.shrink_to_fit();\n\n    HighsInt numcol = mipsolver.numCol();\n    implications.resize(2 * static_cast<size_t>(numcol));\n    colsubstituted.resize(numcol);\n    numImplications = 0;\n    vubs.clear();\n    vubs.shrink_to_fit();\n    vubs.resize(numcol);\n    vlbs.clear();\n    vlbs.shrink_to_fit();\n    vlbs.resize(numcol);\n    numVarBounds = 0;\n    maxVarBounds = calcMaxVarBounds(numcol);\n\n    nextCleanupCall = mipsolver.numNonzero();\n  }\n\n  constexpr static int64_t calcMaxVarBounds(HighsInt numcol) {\n    return int64_t{5000000} + 10 * static_cast<int64_t>(numcol);\n  };\n\n  HighsInt getNumImplications() const {\n    return static_cast<HighsInt>(numImplications);\n  }\n\n  const std::vector<HighsDomainChange>& getImplications(HighsInt col, bool val,\n                                                        bool& infeasible) {\n    HighsInt loc = 2 * col + val;\n    if (!implications[loc].computed)\n      infeasible = computeImplications(col, val);\n    else\n      infeasible = false;\n\n    assert(implications[loc].computed);\n\n    return implications[loc].implics;\n  }\n\n  bool implicationsCached(HighsInt col, bool val) {\n    HighsInt loc = 2 * col + val;\n    return implications[loc].computed;\n  }\n\n  bool tooManyVarBounds() const { return numVarBounds >= maxVarBounds; }\n\n  void addVUB(HighsInt col, HighsInt vubcol, double vubcoef,\n              double vubconstant);\n\n  void addVLB(HighsInt col, HighsInt vlbcol, double vlbcoef,\n              double vlbconstant);\n\n  void columnTransformed(HighsInt col, double scale, double constant) {\n    // Update variable bounds affected by transformation\n    if (scale < 0) std::swap(vubs[col], vlbs[col]);\n\n    auto transformVbd = [&](HighsInt, VarBound& vbd) {\n      vbd.constant -= constant;\n      vbd.constant /= scale;\n      vbd.coef /= scale;\n    };\n\n    vlbs[col].for_each(transformVbd);\n    vubs[col].for_each(transformVbd);\n\n    // Update substitutions affected by transformation\n    for (auto& substitution : substitutions) {\n      if (substitution.substcol == col) {\n        substitution.offset -= constant;\n        substitution.offset /= scale;\n        substitution.scale /= scale;\n      }\n    }\n  }\n\n  std::pair<HighsInt, VarBound> getBestVub(HighsInt col,\n                                           const HighsSolution& lpSolution,\n                                           double& bestUb) const;\n\n  std::pair<HighsInt, VarBound> getBestVlb(HighsInt col,\n                                           const HighsSolution& lpSolution,\n                                           double& bestLb) const;\n\n  bool runProbing(HighsInt col, HighsInt& numReductions);\n\n  void rebuild(HighsInt ncols, const std::vector<HighsInt>& cIndex,\n               const std::vector<HighsInt>& rIndex);\n\n  void buildFrom(const HighsImplications& init);\n\n  void separateImpliedBounds(const HighsLpRelaxation& lpRelaxation,\n                             const std::vector<double>& sol,\n                             HighsCutPool& cutpool, double feastol);\n\n  void cleanupVarbounds(HighsInt col);\n\n  void cleanupVlb(HighsInt col, HighsInt vlbCol,\n                  HighsImplications::VarBound& vlb, double lb, bool& redundant,\n                  bool& infeasible, bool allowBoundChanges = true) const;\n\n  void cleanupVub(HighsInt col, HighsInt vubCol,\n                  HighsImplications::VarBound& vub, double ub, bool& redundant,\n                  bool& infeasible, bool allowBoundChanges = true) const;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsLpAggregator.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file mip/HighsLpAggregator.h\n * @brief Class to aggregate rows of the LP\n *\n *\n */\n\n#ifndef MIP_HIGHS_LP_AGGREGATOR_H_\n#define MIP_HIGHS_LP_AGGREGATOR_H_\n\n#include <cstdint>\n#include <vector>\n\n#include \"util/HighsSparseVectorSum.h\"\n\nclass HighsLpRelaxation;\n\n/// Helper class to compute single-row relaxations from the current LP\n/// relaxation by substituting bounds and aggregating rows\nclass HighsLpAggregator {\n private:\n  const HighsLpRelaxation& lprelaxation;\n\n  HighsSparseVectorSum vectorsum;\n\n public:\n  HighsLpAggregator(const HighsLpRelaxation& lprelaxation);\n\n  /// add an LP row to the aggregation using the given weight\n  void addRow(HighsInt row, double weight);\n\n  /// returns the current aggregation of LP rows. The aggregation includes slack\n  /// variables so that it is always an equation with right hand side 0.\n  void getCurrentAggregation(std::vector<HighsInt>& inds,\n                             std::vector<double>& vals, bool negate);\n\n  /// clear the current aggregation\n  void clear();\n\n  /// checks whether the current aggregation is empty\n  bool isEmpty() { return vectorsum.nonzeroinds.empty(); }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsLpRelaxation.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_LP_RELAXATION_H_\n#define HIGHS_LP_RELAXATION_H_\n\n#include <cstdint>\n#include <memory>\n\n#include \"Highs.h\"\n#include \"mip/HighsMipSolver.h\"\n\nclass HighsDomain;\nstruct HighsCutSet;\nclass HighsPseudocost;\n\nclass HighsLpRelaxation {\n public:\n  enum class Status {\n    kNotSet,\n    kOptimal,\n    kInfeasible,\n    kUnscaledDualFeasible,\n    kUnscaledPrimalFeasible,\n    kUnscaledInfeasible,\n    kUnbounded,\n    kError,\n  };\n\n private:\n  struct LpRow {\n    enum Origin {\n      kModel,\n      kCutPool,\n    };\n\n    Origin origin;\n    HighsInt index;\n    HighsInt age;\n\n    void get(const HighsMipSolver& mipsolver, HighsInt& len,\n             const HighsInt*& inds, const double*& vals) const;\n\n    HighsInt getRowLen(const HighsMipSolver& mipsolver) const;\n\n    bool isIntegral(const HighsMipSolver& mipsolver) const;\n\n    double getMaxAbsVal(const HighsMipSolver& mipsolver) const;\n\n    static LpRow cut(HighsInt index) { return LpRow{kCutPool, index, 0}; }\n    static LpRow model(HighsInt index) { return LpRow{kModel, index, 0}; }\n  };\n\n  const HighsMipSolver& mipsolver;\n  Highs lpsolver;\n\n  std::vector<LpRow> lprows;\n\n  std::vector<std::pair<HighsInt, double>> fractionalints;\n  std::vector<double> dualproofvals;\n  std::vector<HighsInt> dualproofinds;\n  std::vector<double> dualproofbuffer;\n  std::vector<double> colLbBuffer;\n  std::vector<double> colUbBuffer;\n  HVector row_ep;\n  HighsSparseVectorSum row_ap;\n  double dualproofrhs;\n  bool hasdualproof;\n  double objective;\n  std::shared_ptr<const HighsBasis> basischeckpoint;\n  bool currentbasisstored;\n  int64_t numlpiters;\n  int64_t lastAgeCall;\n  double avgSolveIters;\n  int64_t numSolved;\n  size_t epochs;\n  HighsInt maxNumFractional;\n  Status status;\n  bool adjustSymBranchingCol;\n  bool solved_first_lp;\n\n  void storeDualInfProof();\n\n  void storeDualUBProof();\n\n  bool checkDualProof() const;\n\n public:\n  HighsLpRelaxation(const HighsMipSolver& mip);\n\n  HighsLpRelaxation(const HighsLpRelaxation& other);\n\n  void getCutPool(HighsInt& num_col, HighsInt& num_cut,\n                  std::vector<double>& cut_lower,\n                  std::vector<double>& cut_upper,\n                  HighsSparseMatrix& cut_matrix) const;\n\n  class Playground {\n    friend class HighsLpRelaxation;\n    HighsLpRelaxation* lp;\n    bool iterateStored;\n\n    Playground(HighsLpRelaxation* lp) : lp(lp), iterateStored(false) {}\n\n   public:\n    Playground(Playground&& other)\n        : lp(other.lp), iterateStored(other.iterateStored) {\n      other.iterateStored = false;\n    }\n\n    Playground& operator=(Playground&& other) {\n      std::swap(lp, other.lp);\n      std::swap(iterateStored, other.iterateStored);\n      return *this;\n    }\n\n    HighsLpRelaxation::Status solveLp(HighsDomain& localdom) {\n      if (iterateStored) {\n        lp->flushDomain(localdom);\n        lp->getLpSolver().getIterate();\n      } else {\n        assert(lp->getLpSolver().getInfo().valid);\n        lp->getLpSolver().putIterate();\n        lp->flushDomain(localdom);\n        iterateStored = true;\n      }\n\n      return lp->run(false);\n    }\n\n    Playground(const Playground& other) = delete;\n    Playground& operator=(const Playground& other) = delete;\n\n    ~Playground() {\n      if (iterateStored) {\n        lp->getLpSolver().getIterate();\n        lp->run();\n        // If desired, here is the place to clear the stored iterate\n      }\n    }\n  };\n\n  Playground playground() { return Playground(this); }\n\n  void loadModel();\n\n  void getRow(HighsInt row, HighsInt& len, const HighsInt*& inds,\n              const double*& vals) const {\n    if (row < mipsolver.numRow())\n      assert(lprows[row].origin == LpRow::Origin::kModel);\n    else\n      assert(lprows[row].origin == LpRow::Origin::kCutPool);\n    lprows[row].get(mipsolver, len, inds, vals);\n  }\n\n  bool isRowIntegral(HighsInt row) const {\n    assert(row < (HighsInt)lprows.size());\n    return lprows[row].isIntegral(mipsolver);\n  }\n\n  void setAdjustSymmetricBranchingCol(bool adjustSymBranchingCol) {\n    this->adjustSymBranchingCol = adjustSymBranchingCol;\n  }\n\n  void resetToGlobalDomain();\n\n  void computeBasicDegenerateDuals(double threshold,\n                                   HighsDomain* localdom = nullptr);\n\n  double getAvgSolveIters() { return avgSolveIters; }\n\n  HighsInt getRowLen(HighsInt row) const {\n    return lprows[row].getRowLen(mipsolver);\n  }\n\n  double getMaxAbsRowVal(HighsInt row) const {\n    return lprows[row].getMaxAbsVal(mipsolver);\n  }\n\n  const HighsLp& getLp() const { return lpsolver.getLp(); }\n\n  const HighsSolution& getSolution() const { return lpsolver.getSolution(); }\n\n  double slackUpper(HighsInt row) const;\n\n  double slackLower(HighsInt row) const;\n\n  double rowLower(HighsInt row) const {\n    return lpsolver.getLp().row_lower_[row];\n  }\n\n  double rowUpper(HighsInt row) const {\n    return lpsolver.getLp().row_upper_[row];\n  }\n\n  double colLower(HighsInt col) const {\n    return col < lpsolver.getLp().num_col_\n               ? lpsolver.getLp().col_lower_[col]\n               : slackLower(col - lpsolver.getLp().num_col_);\n  }\n\n  double colUpper(HighsInt col) const {\n    return col < lpsolver.getLp().num_col_\n               ? lpsolver.getLp().col_upper_[col]\n               : slackUpper(col - lpsolver.getLp().num_col_);\n  }\n\n  bool isColIntegral(HighsInt col) const {\n    return col < lpsolver.getLp().num_col_\n               ? mipsolver.variableType(col) != HighsVarType::kContinuous\n               : isRowIntegral(col - lpsolver.getLp().num_col_);\n  }\n\n  double solutionValue(HighsInt col) const {\n    return col < lpsolver.getLp().num_col_\n               ? getSolution().col_value[col]\n               : getSolution().row_value[col - lpsolver.getLp().num_col_];\n  }\n\n  Status getStatus() const { return status; }\n\n  const HighsInfo& getSolverInfo() const { return lpsolver.getInfo(); }\n\n  int64_t getNumLpIterations() const { return numlpiters; }\n\n  bool integerFeasible() const {\n    if ((status == Status::kOptimal ||\n         status == Status::kUnscaledPrimalFeasible) &&\n        fractionalints.empty())\n      return true;\n\n    return false;\n  }\n\n  double computeBestEstimate(const HighsPseudocost& ps) const;\n\n  double computeLPDegneracy(const HighsDomain& localdomain) const;\n\n  static bool scaledOptimal(Status status) {\n    switch (status) {\n      case Status::kOptimal:\n      case Status::kUnscaledDualFeasible:\n      case Status::kUnscaledPrimalFeasible:\n      case Status::kUnscaledInfeasible:\n        return true;\n      default:\n        return false;\n    }\n  }\n\n  static bool unscaledPrimalFeasible(Status status) {\n    switch (status) {\n      case Status::kOptimal:\n      case Status::kUnscaledPrimalFeasible:\n        return true;\n      default:\n        return false;\n    }\n  }\n\n  static bool unscaledDualFeasible(Status status) {\n    switch (status) {\n      case Status::kOptimal:\n      case Status::kUnscaledDualFeasible:\n        return true;\n      default:\n        return false;\n    }\n  }\n\n  void recoverBasis();\n\n  void setObjectiveLimit(double objlim = kHighsInf);\n\n  void storeBasis() {\n    if (!currentbasisstored && lpsolver.getBasis().valid) {\n      basischeckpoint = std::make_shared<HighsBasis>(lpsolver.getBasis());\n      currentbasisstored = true;\n    }\n  }\n\n  std::shared_ptr<const HighsBasis> getStoredBasis() const {\n    return basischeckpoint;\n  }\n\n  void setStoredBasis(std::shared_ptr<const HighsBasis> basis) {\n    basischeckpoint = std::move(basis);\n    currentbasisstored = false;\n  }\n\n  const HighsMipSolver& getMipSolver() const { return mipsolver; }\n\n  HighsInt getNumModelRows() const { return mipsolver.numRow(); }\n\n  HighsInt numRows() const { return lpsolver.getNumRow(); }\n\n  HighsInt numCols() const { return lpsolver.getNumCol(); }\n\n  HighsInt numNonzeros() const { return lpsolver.getNumNz(); }\n\n  void addCuts(HighsCutSet& cutset);\n\n  void performAging(bool deleteRows = false);\n\n  void resetAges();\n\n  void removeObsoleteRows(bool notifyPool = true);\n\n  void removeCuts(HighsInt ndelcuts, std::vector<HighsInt>& deletemask);\n\n  void removeCuts();\n\n  void flushDomain(HighsDomain& domain, bool continuous = false);\n\n  void getDualProof(const HighsInt*& inds, const double*& vals, double& rhs,\n                    HighsInt& len) {\n    inds = dualproofinds.data();\n    vals = dualproofvals.data();\n    rhs = dualproofrhs;\n    len = dualproofinds.size();\n  }\n\n  bool computeDualProof(const HighsDomain& globaldomain, double upperbound,\n                        std::vector<HighsInt>& inds, std::vector<double>& vals,\n                        double& rhs, bool extractCliques = true) const;\n\n  bool computeDualInfProof(const HighsDomain& globaldomain,\n                           std::vector<HighsInt>& inds,\n                           std::vector<double>& vals, double& rhs) const;\n\n  Status resolveLp(HighsDomain* domain = nullptr);\n\n  Status run(bool resolve_on_error = true);\n\n  Highs& getLpSolver() { return lpsolver; }\n  const Highs& getLpSolver() const { return lpsolver; }\n\n  const std::vector<std::pair<HighsInt, double>>& getFractionalIntegers()\n      const {\n    return fractionalints;\n  }\n\n  std::vector<std::pair<HighsInt, double>>& getFractionalIntegers() {\n    return fractionalints;\n  }\n\n  double getObjective() const { return objective; }\n\n  void setIterationLimit(HighsInt limit = kHighsIInf) {\n    lpsolver.setOptionValue(\"simplex_iteration_limit\", limit);\n  }\n  void setSolvedFirstLp(const bool solved_first_lp_) {\n    this->solved_first_lp = solved_first_lp_;\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsMipAnalysis.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file mip/HighsMipAnalysis.h\n * @brief Analyse MIP iterations, both for run-time control and data\n * gathering\n */\n#ifndef MIP_HIGHSMIPANALYSIS_H_\n#define MIP_HIGHSMIPANALYSIS_H_\n\n#include \"lp_data/HighsAnalysis.h\"\n#include \"lp_data/HighsLp.h\"\n#include \"util/HighsTimer.h\"\n\nclass HighsMipAnalysis {\n public:\n  HighsMipAnalysis()\n      : timer_(nullptr),\n        sub_solver_call_time_(nullptr),\n        analyse_mip_time(false) {}\n\n  HighsTimer* timer_;\n  HighsSubSolverCallTime* sub_solver_call_time_;\n  void setup(const HighsLp& lp, const HighsOptions& options);\n\n  void setupMipTime(const HighsOptions& options);\n  void mipTimerStart(const HighsInt mip_clock = 0\n                     //\t\t     , const HighsInt thread_id = 0\n  ) const;\n  void mipTimerStop(const HighsInt mip_clock = 0\n                    //\t\t    , const HighsInt thread_id = 0\n  ) const;\n  bool mipTimerRunning(const HighsInt mip_clock = 0\n                       //\t\t    , const HighsInt thread_id = 0\n  ) const;\n  double mipTimerRead(const HighsInt mip_clock = 0\n                      //\t\t    , const HighsInt thread_id = 0\n  ) const;\n  HighsInt mipTimerNumCall(const HighsInt mip_clock = 0\n                           // , const HighsInt thread_id\n  ) const;\n  void mipTimerAdd(const HighsInt mip_clock, const HighsInt num_call,\n                   const double time\n                   // , const HighsInt thread_id\n  ) const;\n  void mipTimerUpdate(const HighsSubSolverCallTime& sub_solver_call_time,\n                      const bool valid_basis, const bool presolve,\n                      const bool analytic_centre = false\n                      // , const HighsInt thread_id\n  ) const;\n  void reportMipSolveLpClock(const bool header);\n  void reportMipTimer();\n\n  HighsInt getSepaClockIndex(const std::string& name) const;\n  void addSubSolverCallTime(const HighsSubSolverCallTime& sub_solver_call_time,\n                            const bool analytic_centre = false) const;\n  void checkSubSolverCallTime(\n      const HighsSubSolverCallTime& sub_solver_call_time);\n  std::string model_name;\n  HighsTimerClock mip_clocks;\n  bool analyse_mip_time;\n  std::vector<double> dive_time;\n  std::vector<double> node_search_time;\n  std::vector<std::pair<std::string, HighsInt>> sepa_name_clock;\n};\n\n#endif /* MIP_HIGHSMIPANALYSIS_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsMipSolver.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef MIP_HIGHS_MIP_SOLVER_H_\n#define MIP_HIGHS_MIP_SOLVER_H_\n\n#include \"Highs.h\"\n#include \"lp_data/HighsCallback.h\"\n#include \"lp_data/HighsOptions.h\"\n#include \"mip/HighsMipAnalysis.h\"\n\nstruct HighsMipSolverData;\nclass HighsCutPool;\nstruct HighsPseudocostInitialization;\nclass HighsCliqueTable;\nclass HighsImplications;\n\nstruct HighsTerminator {\n  HighsInt num_instance;\n  HighsInt my_instance;\n  HighsModelStatus* record;\n  void clear();\n  void initialise(HighsInt num_instance_, HighsInt my_instance_,\n                  HighsModelStatus* record_);\n  HighsInt concurrency() const;\n  void terminate();\n  bool terminated() const;\n  HighsModelStatus terminationStatus() const;\n  void report(const HighsLogOptions log_options) const;\n};\n\nclass HighsMipSolver {\n public:\n  HighsCallback* callback_;\n  const HighsOptions* options_mip_;\n  const HighsLp* model_;\n  const HighsLp* orig_model_;\n  HighsModelStatus modelstatus_;\n  std::vector<double> solution_;\n  double solution_objective_;\n  double bound_violation_;\n  double integrality_violation_;\n  double row_violation_;\n  // The following are only to return data to HiGHS, and are set in\n  // HighsMipSolver::cleanupSolve\n  double dual_bound_;\n  double primal_bound_;\n  double gap_;\n  int64_t node_count_;\n  int64_t total_lp_iterations_;\n  double primal_dual_integral_;\n\n  FILE* improving_solution_file_;\n  std::vector<HighsObjectiveSolution> saved_objective_and_solution_;\n\n  bool submip;\n  HighsInt submip_level;\n  HighsInt max_submip_level;\n  const HighsBasis* rootbasis;\n  const HighsPseudocostInitialization* pscostinit;\n  const HighsCliqueTable* clqtableinit;\n  const HighsImplications* implicinit;\n\n  std::unique_ptr<HighsMipSolverData> mipdata_;\n\n  HighsMipAnalysis analysis_;\n\n  HighsModelStatus termination_status_;\n  HighsTerminator terminator_;\n\n  void run();\n\n  HighsInt numCol() const { return model_->num_col_; }\n\n  HighsInt numRow() const { return model_->num_row_; }\n\n  HighsInt numNonzero() const { return model_->a_matrix_.numNz(); }\n\n  const double* colCost() const { return model_->col_cost_.data(); }\n\n  double colCost(HighsInt col) const { return model_->col_cost_[col]; }\n\n  const double* rowLower() const { return model_->row_lower_.data(); }\n\n  double rowLower(HighsInt col) const { return model_->row_lower_[col]; }\n\n  const double* rowUpper() const { return model_->row_upper_.data(); }\n\n  double rowUpper(HighsInt col) const { return model_->row_upper_[col]; }\n\n  const HighsVarType* variableType() const {\n    return model_->integrality_.data();\n  }\n\n  HighsVarType variableType(HighsInt col) const {\n    return model_->integrality_[col];\n  }\n\n  HighsMipSolver(HighsCallback& callback, const HighsOptions& options,\n                 const HighsLp& lp, const HighsSolution& solution,\n                 bool submip = false, HighsInt submip_level = 0);\n\n  ~HighsMipSolver();\n\n  void setModel(const HighsLp& model) {\n    model_ = &model;\n    solution_objective_ = kHighsInf;\n  }\n\n  mutable HighsTimer timer_;\n  mutable HighsSubSolverCallTime sub_solver_call_time_;\n\n  void cleanupSolve();\n\n  void runMipPresolve(const HighsInt presolve_reduction_limit);\n  const HighsLp& getPresolvedModel() const;\n  HighsPresolveStatus getPresolveStatus() const;\n  presolve::HighsPostsolveStack getPostsolveStack() const;\n\n  void callbackGetCutPool() const;\n  bool solutionFeasible(const HighsLp* lp, const std::vector<double>& col_value,\n                        const std::vector<double>* pass_row_value,\n                        double& bound_violation, double& row_violation,\n                        double& integrality_violation, HighsCDouble& obj) const;\n\n  std::vector<HighsModelStatus> initialiseTerminatorRecord(\n      HighsInt num_instance) const;\n  void initialiseTerminator(HighsInt num_instance_ = 0,\n                            HighsInt my_instance_ = kNoThreadInstance,\n                            HighsModelStatus* record_ = nullptr);\n  void initialiseTerminator(const HighsMipSolver& mip_solver);\n  bool terminate() const {\n    return this->termination_status_ != HighsModelStatus::kNotset;\n  }\n  HighsModelStatus terminationStatus() const {\n    return this->termination_status_;\n  }\n};\n\nstd::array<char, 128> getGapString(const double gap_,\n                                   const double primal_bound_,\n                                   const HighsOptions* options_mip_);\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsMipSolverData.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n#ifndef HIGHS_MIP_SOLVER_DATA_H_\n#define HIGHS_MIP_SOLVER_DATA_H_\n\n#include <vector>\n\n#include \"mip/HighsCliqueTable.h\"\n#include \"mip/HighsConflictPool.h\"\n#include \"mip/HighsCutPool.h\"\n#include \"mip/HighsDebugSol.h\"\n#include \"mip/HighsDomain.h\"\n#include \"mip/HighsImplications.h\"\n#include \"mip/HighsLpRelaxation.h\"\n#include \"mip/HighsNodeQueue.h\"\n#include \"mip/HighsObjectiveFunction.h\"\n#include \"mip/HighsPrimalHeuristics.h\"\n#include \"mip/HighsPseudocost.h\"\n#include \"mip/HighsRedcostFixing.h\"\n#include \"mip/HighsSearch.h\"\n#include \"mip/HighsSeparation.h\"\n#include \"parallel/HighsParallel.h\"\n#include \"presolve/HighsPostsolveStack.h\"\n#include \"presolve/HighsSymmetry.h\"\n#include \"util/HighsTimer.h\"\n\nstruct HighsPrimaDualIntegral {\n  double value;\n  double prev_lb;\n  double prev_ub;\n  double prev_gap;\n  double prev_time;\n  void initialise();\n};\n\nenum MipSolutionSource : int {\n  kSolutionSourceNone = -1,\n  kSolutionSourceMin = kSolutionSourceNone,\n  //  kSolutionSourceInitial, // 0\n  kSolutionSourceBranching,           // B\n  kSolutionSourceCentralRounding,     // C\n  kSolutionSourceFeasibilityPump,     // F\n  kSolutionSourceHeuristic,           // H\n  kSolutionSourceShifting,            // I\n  kSolutionSourceFeasibilityJump,     // J\n  kSolutionSourceSubMip,              // L\n  kSolutionSourceEmptyMip,            // P\n  kSolutionSourceRandomizedRounding,  // R\n  kSolutionSourceSolveLp,             // S\n  kSolutionSourceEvaluateNode,        // T\n  kSolutionSourceUnbounded,           // U\n  kSolutionSourceUserSolution,        // X\n  kSolutionSourceHighsSolution,       // Y\n  kSolutionSourceZiRound,             // Z\n  kSolutionSourceTrivialL,            // l\n  kSolutionSourceTrivialP,            // p\n  kSolutionSourceTrivialU,            // u\n  kSolutionSourceTrivialZ,            // z\n  kSolutionSourceCleanup,\n  kSolutionSourceCount\n};\n\nstruct HighsMipSolverData {\n  HighsMipSolver& mipsolver;\n  HighsCutPool cutpool;\n  HighsConflictPool conflictPool;\n  HighsDomain domain;\n  HighsLpRelaxation lp;\n  HighsPseudocost pseudocost;\n  HighsCliqueTable cliquetable;\n  HighsImplications implications;\n  HighsPrimalHeuristics heuristics;\n  HighsRedcostFixing redcostfixing;\n  HighsObjectiveFunction objectiveFunction;\n  presolve::HighsPostsolveStack postSolveStack;\n  HighsPresolveStatus presolve_status;\n  HighsLp presolvedModel;\n  bool cliquesExtracted;\n  bool rowMatrixSet;\n  bool analyticCenterComputed;\n  HighsModelStatus analyticCenterStatus;\n  bool detectSymmetries;\n  HighsInt numRestarts;\n  HighsInt numRestartsRoot;\n  HighsInt numCliqueEntriesAfterPresolve;\n  HighsInt numCliqueEntriesAfterFirstPresolve;\n\n  std::vector<HighsInt> ARstart_;\n  std::vector<HighsInt> ARindex_;\n  std::vector<double> ARvalue_;\n  std::vector<double> maxAbsRowCoef;\n  std::vector<uint8_t> rowintegral;\n  std::vector<HighsInt> uplocks;\n  std::vector<HighsInt> downlocks;\n  std::vector<HighsInt> integer_cols;\n  std::vector<HighsInt> implint_cols;\n  std::vector<HighsInt> integral_cols;\n  std::vector<HighsInt> continuous_cols;\n\n  HighsSymmetries symmetries;\n  std::shared_ptr<const StabilizerOrbits> globalOrbits;\n\n  double feastol;\n  double epsilon;\n  double heuristic_effort;\n  int64_t dispfreq;\n  std::vector<double> analyticCenter;\n  std::vector<double> firstlpsol;\n  std::vector<double> rootlpsol;\n  double firstlpsolobj;\n  HighsBasis firstrootbasis;\n  double rootlpsolobj;\n  HighsInt numintegercols;\n  HighsInt maxTreeSizeLog2;\n\n  HighsCDouble pruned_treeweight;\n  double avgrootlpiters;\n  double disptime;\n  double last_disptime;\n  int64_t firstrootlpiters;\n  int64_t num_nodes;\n  int64_t num_leaves;\n  int64_t num_leaves_before_run;\n  int64_t num_nodes_before_run;\n  int64_t total_repair_lp;\n  int64_t total_repair_lp_feasible;\n  int64_t total_repair_lp_iterations;\n  int64_t total_lp_iterations;\n  int64_t heuristic_lp_iterations;\n  int64_t sepa_lp_iterations;\n  int64_t sb_lp_iterations;\n  int64_t total_lp_iterations_before_run;\n  int64_t heuristic_lp_iterations_before_run;\n  int64_t sepa_lp_iterations_before_run;\n  int64_t sb_lp_iterations_before_run;\n  int64_t num_disp_lines;\n\n  HighsInt numImprovingSols;\n  double lower_bound;\n  double upper_bound;\n  double upper_limit;\n  double optimality_limit;\n  std::vector<double> incumbent;\n\n  HighsNodeQueue nodequeue;\n\n  HighsPrimaDualIntegral primal_dual_integral;\n\n  HighsDebugSol debugSolution;\n\n  HighsMipSolverData(HighsMipSolver& mipsolver)\n      : mipsolver(mipsolver),\n        cutpool(mipsolver.numCol(), mipsolver.options_mip_->mip_pool_age_limit,\n                mipsolver.options_mip_->mip_pool_soft_limit),\n        conflictPool(5 * mipsolver.options_mip_->mip_pool_age_limit,\n                     mipsolver.options_mip_->mip_pool_soft_limit),\n        domain(mipsolver),\n        lp(mipsolver),\n        pseudocost(),\n        cliquetable(mipsolver.numCol()),\n        implications(mipsolver),\n        heuristics(mipsolver),\n        objectiveFunction(mipsolver),\n        presolve_status(HighsPresolveStatus::kNotSet),\n        cliquesExtracted(false),\n        rowMatrixSet(false),\n        analyticCenterComputed(false),\n        analyticCenterStatus(HighsModelStatus::kNotset),\n        detectSymmetries(false),\n        numRestarts(0),\n        numRestartsRoot(0),\n        numCliqueEntriesAfterPresolve(0),\n        numCliqueEntriesAfterFirstPresolve(0),\n        feastol(0.0),\n        epsilon(0.0),\n        heuristic_effort(0.0),\n        dispfreq(0),\n        firstlpsolobj(-kHighsInf),\n        rootlpsolobj(-kHighsInf),\n        numintegercols(0),\n        maxTreeSizeLog2(0),\n        pruned_treeweight(0),\n        avgrootlpiters(0.0),\n        disptime(0.0),\n        last_disptime(0.0),\n        firstrootlpiters(0),\n        num_nodes(0),\n        num_leaves(0),\n        num_leaves_before_run(0),\n        num_nodes_before_run(0),\n        total_repair_lp(0),\n        total_repair_lp_feasible(0),\n        total_repair_lp_iterations(0),\n        total_lp_iterations(0),\n        heuristic_lp_iterations(0),\n        sepa_lp_iterations(0),\n        sb_lp_iterations(0),\n        total_lp_iterations_before_run(0),\n        heuristic_lp_iterations_before_run(0),\n        sepa_lp_iterations_before_run(0),\n        sb_lp_iterations_before_run(0),\n        num_disp_lines(0),\n        numImprovingSols(0),\n        lower_bound(-kHighsInf),\n        upper_bound(kHighsInf),\n        upper_limit(kHighsInf),\n        optimality_limit(kHighsInf),\n        debugSolution(mipsolver) {\n    domain.addCutpool(cutpool);\n    domain.addConflictPool(conflictPool);\n  }\n\n  bool solutionRowFeasible(const std::vector<double>& solution) const;\n  HighsModelStatus feasibilityJump();\n  HighsModelStatus trivialHeuristics();\n\n  void startAnalyticCenterComputation(\n      const highs::parallel::TaskGroup& taskGroup);\n  void finishAnalyticCenterComputation(\n      const highs::parallel::TaskGroup& taskGroup);\n\n  struct SymmetryDetectionData {\n    HighsSymmetryDetection symDetection;\n    HighsSymmetries symmetries;\n    double detectionTime = 0.0;\n  };\n\n  void startSymmetryDetection(const highs::parallel::TaskGroup& taskGroup,\n                              std::unique_ptr<SymmetryDetectionData>& symData);\n  void finishSymmetryDetection(const highs::parallel::TaskGroup& taskGroup,\n                               std::unique_ptr<SymmetryDetectionData>& symData);\n\n  void updatePrimalDualIntegral(const double from_lower_bound,\n                                const double to_lower_bound,\n                                const double from_upper_bound,\n                                const double to_upper_bound,\n                                const bool check_bound_change = true,\n                                const bool check_prev_data = true);\n  double limitsToGap(const double use_lower_bound, const double use_upper_bound,\n                     double& lb, double& ub) const;\n\n  double computeNewUpperLimit(double upper_bound, double mip_abs_gap,\n                              double mip_rel_gap) const;\n  bool moreHeuristicsAllowed() const;\n  void removeFixedIndices();\n  void init();\n  void basisTransfer();\n  void checkObjIntegrality();\n  void runMipPresolve(const HighsInt presolve_reduction_limit);\n  void setupDomainPropagation();\n  void saveReportMipSolution(const double new_upper_limit = -kHighsInf);\n  void runSetup();\n  double transformNewIntegerFeasibleSolution(\n      const std::vector<double>& sol,\n      const bool possibly_store_as_new_incumbent = true);\n  double percentageInactiveIntegers() const;\n  void performRestart();\n  bool checkSolution(const std::vector<double>& solution) const;\n  std::vector<std::tuple<HighsInt, HighsInt, double>> getInfeasibleRows(\n      const std::vector<double>& solution) const;\n  bool trySolution(const std::vector<double>& solution,\n                   const int solution_source = kSolutionSourceNone);\n  bool rootSeparationRound(HighsSeparation& sepa, HighsInt& ncuts,\n                           HighsLpRelaxation::Status& status);\n  HighsLpRelaxation::Status evaluateRootLp();\n  void evaluateRootNode();\n  bool addIncumbent(const std::vector<double>& sol, double solobj,\n                    const int solution_source,\n                    const bool print_display_line = true,\n                    const bool is_user_solution = false);\n\n  const std::vector<double>& getSolution() const;\n\n  std::string solutionSourceToString(const int solution_source,\n                                     const bool code = true) const;\n  void printSolutionSourceKey() const;\n  void printDisplayLine(const int solution_source = kSolutionSourceNone);\n\n  void getRow(HighsInt row, HighsInt& rowlen, const HighsInt*& rowinds,\n              const double*& rowvals) const {\n    HighsInt start = ARstart_[row];\n    rowlen = ARstart_[row + 1] - start;\n    rowinds = ARindex_.data() + start;\n    rowvals = ARvalue_.data() + start;\n  }\n\n  bool checkLimits(int64_t nodeOffset = 0) const;\n  void limitsToBounds(double& dual_bound, double& primal_bound,\n                      double& mip_rel_gap) const;\n  void setCallbackDataOut(const double mipsolver_objective_value) const;\n  bool interruptFromCallbackWithData(const int callback_type,\n                                     const double mipsolver_objective_value,\n                                     const std::string message = \"\") const;\n  void queryExternalSolution(\n      const double mipsolver_objective_value,\n      const ExternalMipSolutionQueryOrigin external_solution_query_origin);\n\n  HighsInt terminatorConcurrency() const;\n  bool terminatorActive() const { return terminatorConcurrency() > 0; }\n  HighsInt terminatorMyInstance() const;\n  void terminatorTerminate();\n  bool terminatorTerminated() const;\n  void terminatorReport() const;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsModkSeparator.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file mip/HighsModkSeparator.h\n * @brief Class for separating maximally violated mod-k MIR cuts.\n *\n * Contrary to mod-k CG cuts as described in the literature, continuous\n * variables are allowed to appear in the rows used for separation. In case an\n * LP row is already an integral row it is included into the congruence system\n * in the same way as for mod-k CG cuts. Should the LP row contain continuous\n * variables that have a non-zero solution value after bound substitution, then\n * it is discarded, as it can not participate in a maximally violated mod-K MIR\n * cut.\n *\n * If a row contains continuous variables that sit at zero after bound\n * substitution, then those rows are included in the congruence system, as the\n * presence of such variables does not reduce the cuts violation when applying\n * the MIR procedure. In order to handle their presence the row must simply be\n * scaled, such that all integer variables that have a non-zero solution value\n * after bound substitution, as well as the right hand side value, attain an\n * integral value. If we succeed in finding such a scale that is not too large,\n * the resulting row might get a non-zero weight in the solution of the\n * congruence system. The aggregated row therefore can contain continuous\n * variables. These variables, however, all sit at zero in the current LP\n * solution. Using the weights from the solution of the congruence system all\n * integer variables with non-zero solution value will attain a coefficient that\n * is divisible by k, and the integral right hand side value will have a\n * remainder of k - 1 when dividing by k. All other variables do not contribute\n * to the activity of the cut in this LP solution, hence applying the MIR\n * procedure will yield a cut that is violated by (k-1)/k. However, we prefer to\n * generate inequalities with superadditive lifting from the aggregated row\n * whenever all integer variables are bounded.\n *\n */\n\n#ifndef MIP_HIGHS_MODK_SEPARATOR_H_\n#define MIP_HIGHS_MODK_SEPARATOR_H_\n\n#include <vector>\n\n#include \"mip/HighsSeparator.h\"\n\n/// Helper class to compute single-row relaxations from the current LP\n/// relaxation by substituting bounds and aggregating rows\nclass HighsModkSeparator : public HighsSeparator {\n public:\n  void separateLpSolution(HighsLpRelaxation& lpRelaxation,\n                          HighsLpAggregator& lpAggregator,\n                          HighsTransformedLp& transLp,\n                          HighsCutPool& cutpool) override;\n\n  HighsModkSeparator(const HighsMipSolver& mipsolver)\n      : HighsSeparator(mipsolver, kModKSepaString) {}\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsNodeQueue.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n#ifndef HIGHS_NODE_QUEUE_H_\n#define HIGHS_NODE_QUEUE_H_\n\n#include <cassert>\n#include <cstddef>\n#include <memory>\n#include <queue>\n#include <set>\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n#include \"mip/HighsDomainChange.h\"\n#include \"util/HighsCDouble.h\"\n#include \"util/HighsRbTree.h\"\n\nclass HighsDomain;\nclass HighsLpRelaxation;\n\nclass HighsNodeQueue {\n public:\n  template <int S>\n  struct ChunkWithSize {\n    ChunkWithSize* next;\n    typename std::aligned_storage<S, alignof(std::max_align_t)>::type storage;\n  };\n\n  using Chunk =\n      ChunkWithSize<4096 - offsetof(ChunkWithSize<sizeof(void*)>, storage)>;\n\n  struct AllocatorState {\n    void* freeListHead = nullptr;\n    char* currChunkStart = nullptr;\n    char* currChunkEnd = nullptr;\n    Chunk* chunkListHead = nullptr;\n\n    AllocatorState() = default;\n    AllocatorState(const AllocatorState&) = delete;\n    AllocatorState(AllocatorState&& other)\n        : freeListHead(other.freeListHead),\n          currChunkStart(other.currChunkStart),\n          currChunkEnd(other.currChunkEnd),\n          chunkListHead(other.chunkListHead) {\n      other.chunkListHead = nullptr;\n    }\n\n    AllocatorState& operator=(const AllocatorState&) = delete;\n\n    AllocatorState& operator=(AllocatorState&& other) {\n      freeListHead = other.freeListHead;\n      currChunkStart = other.currChunkStart;\n      currChunkEnd = other.currChunkEnd;\n      chunkListHead = other.chunkListHead;\n\n      other.chunkListHead = nullptr;\n      return *this;\n    }\n\n    ~AllocatorState() {\n      while (chunkListHead) {\n        Chunk* delChunk = chunkListHead;\n        chunkListHead = delChunk->next;\n        delete delChunk;\n      }\n    }\n  };\n\n  template <typename T>\n  class NodesetAllocator {\n    union FreelistNode {\n      FreelistNode* next;\n      typename std::aligned_storage<sizeof(T), alignof(T)>::type storage;\n    };\n\n   public:\n    AllocatorState* state;\n    using value_type = T;\n    using size_type = std::size_t;\n    using propagate_on_container_move_assignment = std::true_type;\n\n    NodesetAllocator(AllocatorState* state) : state(state) {}\n    NodesetAllocator(const NodesetAllocator& other) noexcept = default;\n    template <typename U>\n    NodesetAllocator(const NodesetAllocator<U>& other) noexcept\n        : state(other.state) {}\n    NodesetAllocator(NodesetAllocator&& other) noexcept = default;\n    NodesetAllocator& operator=(const NodesetAllocator&) noexcept = default;\n    NodesetAllocator& operator=(NodesetAllocator&& other) noexcept = default;\n    ~NodesetAllocator() noexcept = default;\n\n    T* allocate(size_type n) {\n      if (n == 1) {\n        T* ptr = reinterpret_cast<T*>(state->freeListHead);\n        if (ptr) {\n          state->freeListHead =\n              reinterpret_cast<FreelistNode*>(state->freeListHead)->next;\n        } else {\n          ptr = reinterpret_cast<T*>(state->currChunkStart);\n          if (!ptr || state->currChunkStart + sizeof(FreelistNode) >\n                          state->currChunkEnd) {\n            auto newChunk = new Chunk;\n            newChunk->next = state->chunkListHead;\n            state->chunkListHead = newChunk;\n            state->currChunkStart = reinterpret_cast<char*>(&newChunk->storage);\n            state->currChunkEnd =\n                state->currChunkStart + sizeof(newChunk->storage);\n            ptr = reinterpret_cast<T*>(state->currChunkStart);\n            state->currChunkStart += sizeof(FreelistNode);\n          } else {\n            state->currChunkStart += sizeof(FreelistNode);\n          }\n        }\n        return ptr;\n      }\n\n      return static_cast<T*>(::operator new(n * sizeof(T)));\n    }\n\n    void deallocate(T* ptr, size_type n) noexcept {\n      if (n == 1) {\n        FreelistNode* node = reinterpret_cast<FreelistNode*>(ptr);\n        node->next = reinterpret_cast<FreelistNode*>(state->freeListHead);\n        state->freeListHead = node;\n      } else {\n        ::operator delete(ptr);\n      }\n    }\n  };\n\n  using NodeSet = std::set<std::pair<double, int64_t>,\n                           std::less<std::pair<double, int64_t>>,\n                           NodesetAllocator<std::pair<double, int64_t>>>;\n\n  struct OpenNode {\n    std::vector<HighsDomainChange> domchgstack;\n    std::vector<HighsInt> branchings;\n    std::vector<NodeSet::iterator> domchglinks;\n    double lower_bound;\n    double estimate;\n    HighsInt depth;\n    highs::RbTreeLinks<int64_t> lowerLinks;\n    highs::RbTreeLinks<int64_t> hybridEstimLinks;\n\n    OpenNode()\n        : domchgstack(),\n          branchings(),\n          domchglinks(),\n          lower_bound(-kHighsInf),\n          estimate(-kHighsInf),\n          depth(0),\n          lowerLinks(),\n          hybridEstimLinks() {}\n\n    OpenNode(std::vector<HighsDomainChange>&& domchgstack,\n             std::vector<HighsInt>&& branchings, double lower_bound,\n             double estimate, HighsInt depth)\n        : domchgstack(domchgstack),\n          branchings(branchings),\n          lower_bound(lower_bound),\n          estimate(estimate),\n          depth(depth),\n          lowerLinks(),\n          hybridEstimLinks() {}\n\n    OpenNode& operator=(OpenNode&& other) = default;\n    OpenNode(OpenNode&&) = default;\n\n    OpenNode& operator=(const OpenNode& other) = delete;\n    OpenNode(const OpenNode&) = delete;\n  };\n\n  void checkGlobalBounds(HighsInt col, double lb, double ub, double feastol,\n                         HighsCDouble& treeweight);\n\n private:\n  class NodeLowerRbTree;\n  class NodeHybridEstimRbTree;\n  class SuboptimalNodeRbTree;\n\n  std::unique_ptr<AllocatorState> allocatorState;\n  std::vector<OpenNode> nodes;\n  std::priority_queue<int64_t, std::vector<int64_t>, std::greater<int64_t>>\n      freeslots;\n\n  struct GlobalOperatorDelete {\n    template <typename T>\n    void operator()(T* x) const {\n      ::operator delete(x);\n    }\n  };\n  using NodeSetArray = std::unique_ptr<NodeSet, GlobalOperatorDelete>;\n  NodeSetArray colLowerNodesPtr;\n  NodeSetArray colUpperNodesPtr;\n  int64_t lowerRoot = -1;\n  int64_t lowerMin = -1;\n  int64_t hybridEstimRoot = -1;\n  int64_t hybridEstimMin = -1;\n  int64_t suboptimalRoot = -1;\n  int64_t suboptimalMin = -1;\n  int64_t numSuboptimal = 0;\n  double optimality_limit = kHighsInf;\n  HighsInt numCol = 0;\n\n  void link_estim(int64_t node);\n\n  void unlink_estim(int64_t node);\n\n  void link_lower(int64_t node);\n\n  void unlink_lower(int64_t node);\n\n  void link_suboptimal(int64_t node);\n\n  void unlink_suboptimal(int64_t node);\n\n  void link_domchgs(int64_t node);\n\n  void unlink_domchgs(int64_t node);\n\n  double link(int64_t node);\n\n  void unlink(int64_t node);\n\n public:\n  void setOptimalityLimit(double optimality_limit) {\n    this->optimality_limit = optimality_limit;\n  }\n\n  double performBounding(double upper_limit);\n\n  void setNumCol(HighsInt numcol);\n\n  double emplaceNode(std::vector<HighsDomainChange>&& domchgs,\n                     std::vector<HighsInt>&& branchings, double lower_bound,\n                     double estimate, HighsInt depth);\n\n  OpenNode&& popBestNode();\n\n  OpenNode&& popBestBoundNode();\n\n  int64_t numNodesUp(HighsInt col) const {\n    return colLowerNodesPtr.get()[col].size();\n  }\n\n  int64_t numNodesDown(HighsInt col) const {\n    return colUpperNodesPtr.get()[col].size();\n  }\n\n  int64_t numNodesUp(HighsInt col, double val) const {\n    assert(numCol > col);\n    auto colLowerNodes = colLowerNodesPtr.get();\n    auto it = colLowerNodes[col].upper_bound(std::make_pair(val, kHighsIInf));\n    if (it == colLowerNodes[col].begin()) return colLowerNodes[col].size();\n    return std::distance(it, colLowerNodes[col].end());\n  }\n\n  int64_t numNodesDown(HighsInt col, double val) const {\n    assert(numCol > col);\n    auto colUpperNodes = colUpperNodesPtr.get();\n    auto it = colUpperNodes[col].lower_bound(std::make_pair(val, -1));\n    if (it == colUpperNodes[col].end()) return colUpperNodes[col].size();\n    return std::distance(colUpperNodes[col].begin(), it);\n  }\n\n  const NodeSet& getUpNodes(HighsInt col) const {\n    return colLowerNodesPtr.get()[col];\n  }\n\n  const NodeSet& getDownNodes(HighsInt col) const {\n    return colUpperNodesPtr.get()[col];\n  }\n\n  double pruneInfeasibleNodes(HighsDomain& globaldomain, double feastol);\n\n  double pruneNode(int64_t nodeId);\n\n  double getBestLowerBound() const;\n\n  HighsInt getBestBoundDomchgStackSize() const;\n\n  void clear();\n\n  int64_t numNodes() const { return nodes.size() - freeslots.size(); }\n\n  int64_t numActiveNodes() const {\n    return nodes.size() - freeslots.size() - numSuboptimal;\n  }\n\n  bool empty() const { return numActiveNodes() == 0; }\n};\n\ntemplate <typename T, typename U>\nbool operator==(const HighsNodeQueue::NodesetAllocator<T>&,\n                const HighsNodeQueue::NodesetAllocator<U>&) {\n  return true;\n}\n\ntemplate <typename T, typename U>\nbool operator!=(const HighsNodeQueue::NodesetAllocator<T>&,\n                const HighsNodeQueue::NodesetAllocator<U>&) {\n  return false;\n}\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsObjectiveFunction.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_OBJECTIVE_FUNCTION_H_\n#define HIGHS_OBJECTIVE_FUNCTION_H_\n\n#include <algorithm>\n#include <cassert>\n#include <vector>\n\n#include \"util/HighsInt.h\"\n\nclass HighsCliqueTable;\nclass HighsDomain;\nclass HighsLp;\nclass HighsMipSolver;\n\nclass HighsObjectiveFunction {\n  const HighsLp* model;\n  double objIntScale;\n  HighsInt numIntegral;\n  HighsInt numBinary;\n  std::vector<HighsInt> objectiveNonzeros;\n  std::vector<double> objectiveVals;\n  std::vector<HighsInt> cliquePartitionStart;\n  std::vector<HighsInt> colToPartition;\n\n public:\n  HighsObjectiveFunction(const HighsMipSolver& mipsolver);\n\n  void setupCliquePartition(const HighsDomain& globaldom,\n                            HighsCliqueTable& cliqueTable);\n\n  void checkIntegrality(double epsilon);\n\n  /// returns the vector of column indices with nonzero objective value\n  /// They will be ordered so that binary columns come first\n  const std::vector<HighsInt>& getObjectiveNonzeros() const {\n    return objectiveNonzeros;\n  }\n\n  const std::vector<double>& getObjectiveValuesPacked() const {\n    return objectiveVals;\n  }\n\n  HighsInt getNumBinariesInObjective() const { return numBinary; }\n\n  const std::vector<HighsInt>& getCliquePartitionStarts() const {\n    return cliquePartitionStart;\n  }\n\n  HighsInt getNumCliquePartitions() const {\n    return cliquePartitionStart.size() - 1;\n  }\n\n  HighsInt getColCliquePartition(HighsInt col) const {\n    return colToPartition[col];\n  }\n\n  double integralScale() const { return objIntScale; }\n\n  bool isIntegral() const { return objIntScale != 0.0; }\n\n  bool isZero() const { return objectiveNonzeros.empty(); }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsPathSeparator.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file mip/HighsPathSeparator.h\n * @brief Class for separating cuts from heuristically aggregating rows from the\n * LP to identify path's in a network\n *\n */\n\n#ifndef MIP_HIGHS_PATH_SEPARATOR_H_\n#define MIP_HIGHS_PATH_SEPARATOR_H_\n\n#include \"mip/HighsMipSolver.h\"\n#include \"mip/HighsSeparator.h\"\n#include \"util/HighsRandom.h\"\n\n/// Helper class to compute single-row relaxations from the current LP\n/// relaxation by substituting bounds and aggregating rows\nclass HighsPathSeparator : public HighsSeparator {\n private:\n  HighsRandom randgen;\n\n public:\n  void separateLpSolution(HighsLpRelaxation& lpRelaxation,\n                          HighsLpAggregator& lpAggregator,\n                          HighsTransformedLp& transLp,\n                          HighsCutPool& cutpool) override;\n\n  HighsPathSeparator(const HighsMipSolver& mipsolver)\n      : HighsSeparator(mipsolver, kPathAggrSepaString) {\n    randgen.initialise(mipsolver.options_mip_->random_seed);\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsPrimalHeuristics.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_PRIMAL_HEURISTICS_H_\n#define HIGHS_PRIMAL_HEURISTICS_H_\n\n#include <vector>\n\n#include \"lp_data/HStruct.h\"\n#include \"lp_data/HighsLp.h\"\n#include \"util/HighsRandom.h\"\n\nclass HighsMipSolver;\nclass HighsLpRelaxation;\n\nclass HighsPrimalHeuristics {\n private:\n  HighsMipSolver& mipsolver;\n  size_t total_repair_lp;\n  size_t total_repair_lp_feasible;\n  size_t total_repair_lp_iterations;\n  size_t lp_iterations;\n\n  double successObservations;\n  HighsInt numSuccessObservations;\n  double infeasObservations;\n  HighsInt numInfeasObservations;\n\n  HighsRandom randgen;\n\n  std::vector<HighsInt> intcols;\n\n public:\n  HighsPrimalHeuristics(HighsMipSolver& mipsolver);\n\n  void setupIntCols();\n\n  bool solveSubMip(const HighsLp& lp, const HighsBasis& basis,\n                   double fixingRate, std::vector<double> colLower,\n                   std::vector<double> colUpper, HighsInt maxleaves,\n                   HighsInt maxnodes, HighsInt stallnodes);\n\n  double determineTargetFixingRate();\n\n  void rootReducedCost();\n\n  void RENS(const std::vector<double>& relaxationsol);\n\n  void RINS(const std::vector<double>& relaxationsol);\n\n  void feasibilityPump();\n\n  void centralRounding();\n\n  void flushStatistics();\n\n  bool tryRoundedPoint(const std::vector<double>& point,\n                       const int solution_source);\n\n  bool linesearchRounding(const std::vector<double>& point1,\n                          const std::vector<double>& point2,\n                          const int solution_source);\n\n  void randomizedRounding(const std::vector<double>& relaxationsol);\n\n  void shifting(const std::vector<double>& relaxationsol);\n\n  void ziRound(const std::vector<double>& relaxationsol);\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsPseudocost.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n#ifndef HIGHS_PSEUDOCOST_H_\n#define HIGHS_PSEUDOCOST_H_\n\n#include <algorithm>\n#include <cassert>\n#include <cmath>\n#include <limits>\n#include <vector>\n\n#include \"util/HighsInt.h\"\n\nclass HighsMipSolver;\nnamespace presolve {\nclass HighsPostsolveStack;\n}\n\nclass HighsPseudocost;\n\nconstexpr double minThreshold = 1e-6;\n\nstruct HighsPseudocostInitialization {\n  std::vector<double> pseudocostup;\n  std::vector<double> pseudocostdown;\n  std::vector<HighsInt> nsamplesup;\n  std::vector<HighsInt> nsamplesdown;\n  std::vector<double> inferencesup;\n  std::vector<double> inferencesdown;\n  std::vector<HighsInt> ninferencesup;\n  std::vector<HighsInt> ninferencesdown;\n  std::vector<double> conflictscoreup;\n  std::vector<double> conflictscoredown;\n  double cost_total;\n  double inferences_total;\n  double conflict_avg_score;\n  int64_t nsamplestotal;\n  int64_t ninferencestotal;\n\n  HighsPseudocostInitialization(const HighsPseudocost& pscost,\n                                HighsInt maxCount);\n  HighsPseudocostInitialization(\n      const HighsPseudocost& pscost, HighsInt maxCount,\n      const presolve::HighsPostsolveStack& postsolveStack);\n};\n\nclass HighsPseudocost {\n  friend struct HighsPseudocostInitialization;\n  std::vector<double> pseudocostup;\n  std::vector<double> pseudocostdown;\n  std::vector<HighsInt> nsamplesup;\n  std::vector<HighsInt> nsamplesdown;\n  std::vector<double> inferencesup;\n  std::vector<double> inferencesdown;\n  std::vector<HighsInt> ninferencesup;\n  std::vector<HighsInt> ninferencesdown;\n  std::vector<HighsInt> ncutoffsup;\n  std::vector<HighsInt> ncutoffsdown;\n  std::vector<double> conflictscoreup;\n  std::vector<double> conflictscoredown;\n\n  double conflict_weight;\n  double conflict_avg_score;\n  double cost_total;\n  double inferences_total;\n  int64_t nsamplestotal;\n  int64_t ninferencestotal;\n  int64_t ncutoffstotal;\n  HighsInt minreliable;\n  double degeneracyFactor;\n\n public:\n  HighsPseudocost() = default;\n  HighsPseudocost(const HighsMipSolver& mipsolver);\n\n  void subtractBase(const HighsPseudocost& base) {\n    for (size_t i = 0; i != pseudocostup.size(); ++i) {\n      pseudocostup[i] -= base.pseudocostup[i];\n      pseudocostdown[i] -= base.pseudocostdown[i];\n      nsamplesup[i] -= base.nsamplesup[i];\n      nsamplesdown[i] -= base.nsamplesdown[i];\n    }\n  }\n\n  void increaseConflictWeight() {\n    conflict_weight *= 1.02;\n\n    if (conflict_weight > 1000.0) {\n      double scale = 1.0 / conflict_weight;\n      conflict_weight = 1.0;\n      conflict_avg_score *= scale;\n\n      for (size_t i = 0; i != conflictscoreup.size(); ++i) {\n        conflictscoreup[i] *= scale;\n        conflictscoredown[i] *= scale;\n      }\n    }\n  }\n\n  void setDegeneracyFactor(double degeneracyFactor) {\n    assert(degeneracyFactor >= 1.0);\n    this->degeneracyFactor = degeneracyFactor;\n  }\n\n  void increaseConflictScoreUp(HighsInt col) {\n    conflictscoreup[col] += conflict_weight;\n    conflict_avg_score += conflict_weight;\n  }\n\n  void increaseConflictScoreDown(HighsInt col) {\n    conflictscoredown[col] += conflict_weight;\n    conflict_avg_score += conflict_weight;\n  }\n\n  void setMinReliable(HighsInt minreliable) { this->minreliable = minreliable; }\n\n  HighsInt getMinReliable() const { return minreliable; }\n\n  HighsInt getNumObservations(HighsInt col) const {\n    return nsamplesup[col] + nsamplesdown[col];\n  }\n\n  HighsInt getNumObservationsUp(HighsInt col) const { return nsamplesup[col]; }\n\n  HighsInt getNumObservationsDown(HighsInt col) const {\n    return nsamplesdown[col];\n  }\n\n  void addCutoffObservation(HighsInt col, bool upbranch) {\n    ++ncutoffstotal;\n    if (upbranch)\n      ncutoffsup[col] += 1;\n    else\n      ncutoffsdown[col] += 1;\n  }\n\n  void addObservation(HighsInt col, double delta, double objdelta) {\n    assert(delta != 0.0);\n    assert(objdelta >= 0.0);\n    if (delta > 0.0) {\n      double unit_gain = objdelta / delta;\n      double d = unit_gain - pseudocostup[col];\n      nsamplesup[col] += 1;\n      pseudocostup[col] += d / nsamplesup[col];\n\n      d = unit_gain - cost_total;\n      ++nsamplestotal;\n      cost_total += d / static_cast<double>(nsamplestotal);\n    } else {\n      double unit_gain = -objdelta / delta;\n      double d = unit_gain - pseudocostdown[col];\n      nsamplesdown[col] += 1;\n      pseudocostdown[col] += d / nsamplesdown[col];\n\n      d = unit_gain - cost_total;\n      ++nsamplestotal;\n      cost_total += d / static_cast<double>(nsamplestotal);\n    }\n  }\n\n  void addInferenceObservation(HighsInt col, HighsInt ninferences,\n                               bool upbranch) {\n    double d = ninferences - inferences_total;\n    ++ninferencestotal;\n    inferences_total += d / static_cast<double>(ninferencestotal);\n    if (upbranch) {\n      d = ninferences - inferencesup[col];\n      ninferencesup[col] += 1;\n      inferencesup[col] += d / ninferencesup[col];\n    } else {\n      d = ninferences - inferencesdown[col];\n      ninferencesdown[col] += 1;\n      inferencesdown[col] += d / ninferencesdown[col];\n    }\n  }\n\n  bool isReliable(HighsInt col) const {\n    return std::min(nsamplesup[col], nsamplesdown[col]) >= minreliable;\n  }\n\n  bool isReliableUp(HighsInt col) const {\n    return nsamplesup[col] >= minreliable;\n  }\n\n  bool isReliableDown(HighsInt col) const {\n    return nsamplesdown[col] >= minreliable;\n  }\n\n  double getAvgPseudocost() const { return cost_total; }\n\n  double getPseudocostUp(HighsInt col, double frac, double offset) const {\n    double up = std::ceil(frac) - frac;\n    double cost;\n\n    if (nsamplesup[col] == 0 || nsamplesup[col] < minreliable) {\n      double weightPs =\n          nsamplesup[col] == 0\n              ? 0\n              : 0.9 + 0.1 * nsamplesup[col] / static_cast<double>(minreliable);\n      cost = weightPs * pseudocostup[col];\n      cost += (1.0 - weightPs) * getAvgPseudocost();\n    } else\n      cost = pseudocostup[col];\n    return up * (offset + cost);\n  }\n\n  double getPseudocostDown(HighsInt col, double frac, double offset) const {\n    double down = frac - std::floor(frac);\n    double cost;\n\n    if (nsamplesdown[col] == 0 || nsamplesdown[col] < minreliable) {\n      double weightPs = nsamplesdown[col] == 0\n                            ? 0\n                            : 0.9 + 0.1 * nsamplesdown[col] /\n                                        static_cast<double>(minreliable);\n      cost = weightPs * pseudocostdown[col];\n      cost += (1.0 - weightPs) * getAvgPseudocost();\n    } else\n      cost = pseudocostdown[col];\n\n    return down * (offset + cost);\n  }\n\n  double getPseudocostUp(HighsInt col, double frac) const {\n    double up = std::ceil(frac) - frac;\n    if (nsamplesup[col] == 0) return up * cost_total;\n    return up * pseudocostup[col];\n  }\n\n  double getPseudocostDown(HighsInt col, double frac) const {\n    double down = frac - std::floor(frac);\n    if (nsamplesdown[col] == 0) return down * cost_total;\n    return down * pseudocostdown[col];\n  }\n\n  double getConflictScoreUp(HighsInt col) const {\n    return conflictscoreup[col] / conflict_weight;\n  }\n\n  double getConflictScoreDown(HighsInt col) const {\n    return conflictscoredown[col] / conflict_weight;\n  }\n\n  double getScore(HighsInt col, double upcost, double downcost) const {\n    double costScore = std::max(upcost, minThreshold) *\n                       std::max(downcost, minThreshold) /\n                       std::max(minThreshold, cost_total * cost_total);\n    double inferenceScore =\n        std::max(inferencesup[col], minThreshold) *\n        std::max(inferencesdown[col], minThreshold) /\n        std::max(minThreshold, inferences_total * inferences_total);\n\n    double cutOffScoreUp =\n        ncutoffsup[col] /\n        std::max(1.0, static_cast<double>(ncutoffsup[col]) +\n                          static_cast<double>(nsamplesup[col]));\n    double cutOffScoreDown =\n        ncutoffsdown[col] /\n        std::max(1.0, static_cast<double>(ncutoffsdown[col]) +\n                          static_cast<double>(nsamplesdown[col]));\n    double avgCutoffs = static_cast<double>(ncutoffstotal) /\n                        std::max(1.0, static_cast<double>(ncutoffstotal) +\n                                          static_cast<double>(nsamplestotal));\n\n    double cutoffScore = std::max(cutOffScoreUp, minThreshold) *\n                         std::max(cutOffScoreDown, minThreshold) /\n                         std::max(minThreshold, avgCutoffs * avgCutoffs);\n\n    double conflictScoreUp = conflictscoreup[col] / conflict_weight;\n    double conflictScoreDown = conflictscoredown[col] / conflict_weight;\n    double conflictScoreAvg =\n        conflict_avg_score /\n        (conflict_weight * static_cast<double>(conflictscoreup.size()));\n    double conflictScore =\n        std::max(conflictScoreUp, minThreshold) *\n        std::max(conflictScoreDown, minThreshold) /\n        std::max(minThreshold, conflictScoreAvg * conflictScoreAvg);\n\n    auto mapScore = [](double score) { return 1.0 - 1.0 / (1.0 + score); };\n    return mapScore(costScore) / degeneracyFactor +\n           degeneracyFactor *\n               (1e-2 * mapScore(conflictScore) +\n                1e-4 * (mapScore(cutoffScore) + mapScore(inferenceScore)));\n  }\n\n  double getScore(HighsInt col, double frac) const {\n    double upcost = getPseudocostUp(col, frac);\n    double downcost = getPseudocostDown(col, frac);\n\n    return getScore(col, upcost, downcost);\n  }\n\n  double getScoreUp(HighsInt col, double frac) const {\n    double costScore =\n        getPseudocostUp(col, frac) / std::max(minThreshold, cost_total);\n    double inferenceScore =\n        inferencesup[col] / std::max(minThreshold, inferences_total);\n\n    double cutOffScoreUp =\n        ncutoffsup[col] /\n        std::max(1.0, static_cast<double>(ncutoffsup[col]) +\n                          static_cast<double>(nsamplesup[col]));\n    double avgCutoffs = static_cast<double>(ncutoffstotal) /\n                        std::max(1.0, static_cast<double>(ncutoffstotal) +\n                                          static_cast<double>(nsamplestotal));\n\n    double cutoffScore = cutOffScoreUp / std::max(minThreshold, avgCutoffs);\n\n    double conflictScoreUp = conflictscoreup[col] / conflict_weight;\n    double conflictScoreAvg =\n        conflict_avg_score /\n        (conflict_weight * static_cast<double>(conflictscoreup.size()));\n    double conflictScore =\n        conflictScoreUp / std::max(minThreshold, conflictScoreAvg);\n\n    auto mapScore = [](double score) { return 1.0 - 1.0 / (1.0 + score); };\n\n    return mapScore(costScore) +\n           (1e-2 * mapScore(conflictScore) +\n            1e-4 * (mapScore(cutoffScore) + mapScore(inferenceScore)));\n  }\n\n  double getScoreDown(HighsInt col, double frac) const {\n    double costScore =\n        getPseudocostDown(col, frac) / std::max(minThreshold, cost_total);\n    double inferenceScore =\n        inferencesdown[col] / std::max(minThreshold, inferences_total);\n\n    double cutOffScoreDown =\n        ncutoffsdown[col] /\n        std::max(1.0, static_cast<double>(ncutoffsdown[col]) +\n                          static_cast<double>(nsamplesdown[col]));\n    double avgCutoffs = static_cast<double>(ncutoffstotal) /\n                        std::max(1.0, static_cast<double>(ncutoffstotal) +\n                                          static_cast<double>(nsamplestotal));\n\n    double cutoffScore = cutOffScoreDown / std::max(minThreshold, avgCutoffs);\n\n    double conflictScoreDown = conflictscoredown[col] / conflict_weight;\n    double conflictScoreAvg =\n        conflict_avg_score /\n        (conflict_weight * static_cast<double>(conflictscoredown.size()));\n    double conflictScore =\n        conflictScoreDown / std::max(minThreshold, conflictScoreAvg);\n\n    auto mapScore = [](double score) { return 1.0 - 1.0 / (1.0 + score); };\n\n    return mapScore(costScore) +\n           (1e-2 * mapScore(conflictScore) +\n            1e-4 * (mapScore(cutoffScore) + mapScore(inferenceScore)));\n  }\n\n  double getAvgInferencesUp(HighsInt col) const { return inferencesup[col]; }\n\n  double getAvgInferencesDown(HighsInt col) const {\n    return inferencesdown[col];\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsRedcostFixing.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file mip/HighsRedcostFixing.h\n * @brief reduced cost fixing using the current cutoff bound\n */\n\n#ifndef HIGHS_REDCOST_FIXING_H_\n#define HIGHS_REDCOST_FIXING_H_\n\n#include <map>\n#include <vector>\n\n#include \"mip/HighsDomainChange.h\"\n\nclass HighsDomain;\nclass HighsMipSolver;\nclass HighsLpRelaxation;\n\nclass HighsRedcostFixing {\n  std::vector<std::multimap<double, HighsInt>> lurkingColUpper;\n  std::vector<std::multimap<double, HighsInt>> lurkingColLower;\n\n public:\n  std::vector<std::pair<double, HighsDomainChange>> getLurkingBounds(\n      const HighsMipSolver& mipsolver) const;\n\n  void propagateRootRedcost(const HighsMipSolver& mipsolver);\n\n  static void propagateRedCost(const HighsMipSolver& mipsolver,\n                               HighsDomain& localdomain,\n                               const HighsLpRelaxation& lp);\n\n  void addRootRedcost(const HighsMipSolver& mipsolver,\n                      const std::vector<double>& lpredcost, double lpobjective);\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsSearch.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_SEARCH_H_\n#define HIGHS_SEARCH_H_\n\n#include <cstdint>\n#include <queue>\n#include <vector>\n\n#include \"mip/HighsConflictPool.h\"\n#include \"mip/HighsDomain.h\"\n#include \"mip/HighsLpRelaxation.h\"\n#include \"mip/HighsMipSolver.h\"\n#include \"mip/HighsNodeQueue.h\"\n#include \"mip/HighsPseudocost.h\"\n#include \"mip/HighsSeparation.h\"\n#include \"presolve/HighsSymmetry.h\"\n#include \"util/HighsHash.h\"\n\nclass HighsMipSolver;\nclass HighsImplications;\nclass HighsCliqueTable;\n\nclass HighsSearch {\n  HighsMipSolver& mipsolver;\n  HighsLpRelaxation* lp;\n  HighsDomain localdom;\n  HighsPseudocost& pseudocost;\n  HighsRandom random;\n  int64_t nnodes;\n  int64_t lpiterations;\n  int64_t heurlpiterations;\n  int64_t sblpiterations;\n  double upper_limit;\n  HighsCDouble treeweight;\n  std::vector<HighsInt> inds;\n  std::vector<double> vals;\n  HighsInt depthoffset;\n  bool inbranching;\n  bool inheuristic;\n  bool countTreeWeight;\n\n public:\n  enum class ChildSelectionRule {\n    kUp,\n    kDown,\n    kRootSol,\n    kObj,\n    kRandom,\n    kBestCost,\n    kWorstCost,\n    kDisjunction,\n    kHybridInferenceCost,\n  };\n\n  enum class NodeResult {\n    kBoundExceeding,\n    kDomainInfeasible,\n    kLpInfeasible,\n    kBranched,\n    kSubOptimal,\n    kOpen,\n  };\n\n private:\n  ChildSelectionRule childselrule;\n\n  struct NodeData {\n    double lower_bound;\n    double estimate;\n    double branching_point;\n    // we store the lp objective separately to the lower bound since the lower\n    // bound could be above the LP objective when cuts age out or below when the\n    // LP is unscaled dual infeasible and it is not set. We still want to use\n    // the objective for pseudocost updates and tiebreaking of best bound node\n    // selection\n    double lp_objective;\n    double other_child_lb;\n    std::shared_ptr<const HighsBasis> nodeBasis;\n    std::shared_ptr<const StabilizerOrbits> stabilizerOrbits;\n    HighsDomainChange branchingdecision;\n    HighsInt domgchgStackPos;\n    uint8_t skipDepthCount;\n    uint8_t opensubtrees;\n\n    NodeData(double parentlb = -kHighsInf, double parentestimate = -kHighsInf,\n             std::shared_ptr<const HighsBasis> parentBasis = nullptr,\n             std::shared_ptr<const StabilizerOrbits> stabilizerOrbits = nullptr)\n        : lower_bound(parentlb),\n          estimate(parentestimate),\n          branching_point(0.0),\n          lp_objective(-kHighsInf),\n          other_child_lb(parentlb),\n          nodeBasis(std::move(parentBasis)),\n          stabilizerOrbits(std::move(stabilizerOrbits)),\n          branchingdecision{0.0, -1, HighsBoundType::kLower},\n          domgchgStackPos(-1),\n          skipDepthCount(0),\n          opensubtrees(2) {}\n  };\n\n  enum ReliableFlags {\n    kUpReliable = 1,\n    kDownReliable = 2,\n    kReliable = kDownReliable | kUpReliable,\n  };\n\n  std::vector<double> subrootsol;\n  std::vector<NodeData> nodestack;\n  HighsHashTable<HighsInt, int> reliableatnode;\n\n  int branchingVarReliableAtNodeFlags(HighsInt col) const {\n    auto it = reliableatnode.find(col);\n    if (it == nullptr) return 0;\n    return *it;\n  }\n\n  bool branchingVarReliableAtNode(HighsInt col) const {\n    auto it = reliableatnode.find(col);\n    if (it == nullptr || *it != kReliable) return false;\n\n    return true;\n  }\n\n  void markBranchingVarUpReliableAtNode(HighsInt col) {\n    reliableatnode[col] |= kUpReliable;\n  }\n\n  void markBranchingVarDownReliableAtNode(HighsInt col) {\n    reliableatnode[col] |= kDownReliable;\n  }\n\n  bool orbitsValidInChildNode(const HighsDomainChange& branchChg) const;\n\n public:\n  HighsSearch(HighsMipSolver& mipsolver, HighsPseudocost& pseudocost);\n\n  void setRINSNeighbourhood(const std::vector<double>& basesol,\n                            const std::vector<double>& relaxsol);\n\n  void setRENSNeighbourhood(const std::vector<double>& lpsol);\n\n  double getCutoffBound() const;\n\n  void setLpRelaxation(HighsLpRelaxation* lp) { this->lp = lp; }\n\n  double checkSol(const std::vector<double>& sol, bool& integerfeasible) const;\n\n  void createNewNode();\n\n  void cutoffNode();\n\n  void branchDownwards(HighsInt col, double newub, double branchpoint);\n\n  void branchUpwards(HighsInt col, double newlb, double branchpoint);\n\n  void setMinReliable(HighsInt minreliable);\n\n  void setHeuristic(bool inheuristic) {\n    this->inheuristic = inheuristic;\n    if (inheuristic) childselrule = ChildSelectionRule::kHybridInferenceCost;\n  }\n\n  void addBoundExceedingConflict();\n\n  void resetLocalDomain();\n\n  int64_t getHeuristicLpIterations() const;\n\n  int64_t getTotalLpIterations() const;\n\n  int64_t getLocalLpIterations() const;\n\n  int64_t getLocalNodes() const;\n\n  int64_t getStrongBranchingLpIterations() const;\n\n  bool hasNode() const { return !nodestack.empty(); }\n\n  bool currentNodePruned() const { return nodestack.back().opensubtrees == 0; }\n\n  double getCurrentEstimate() const { return nodestack.back().estimate; }\n\n  double getCurrentLowerBound() const { return nodestack.back().lower_bound; }\n\n  HighsInt getCurrentDepth() const { return nodestack.size() + depthoffset; }\n\n  void openNodesToQueue(HighsNodeQueue& nodequeue);\n\n  void currentNodeToQueue(HighsNodeQueue& nodequeue);\n\n  void flushStatistics();\n\n  void installNode(HighsNodeQueue::OpenNode&& node);\n\n  void addInfeasibleConflict();\n\n  HighsInt selectBranchingCandidate(int64_t maxSbIters, double& downNodeLb,\n                                    double& upNodeLb);\n\n  void evalUnreliableBranchCands();\n\n  const NodeData* getParentNodeData() const;\n\n  NodeResult evaluateNode();\n\n  NodeResult branch();\n\n  /// backtrack one level in DFS manner\n  bool backtrack(bool recoverBasis = true);\n\n  /// backtrack an unspecified amount of depth level until the next\n  /// node that seems worthwhile to continue the plunge. Put unpromising nodes\n  /// to the node queue\n  bool backtrackPlunge(HighsNodeQueue& nodequeue);\n\n  /// for heuristics. Will discard nodes above targetDepth regardless of their\n  /// status\n  bool backtrackUntilDepth(HighsInt targetDepth);\n\n  void printDisplayLine(char first, bool header = false);\n\n  NodeResult dive();\n\n  HighsDomain& getLocalDomain() { return localdom; }\n\n  const HighsDomain& getLocalDomain() const { return localdom; }\n\n  HighsPseudocost& getPseudoCost() { return pseudocost; }\n\n  const HighsPseudocost& getPseudoCost() const { return pseudocost; }\n\n  void solveDepthFirst(int64_t maxbacktracks = 1);\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsSeparation.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_SEPARATION_H_\n#define HIGHS_SEPARATION_H_\n\n#include <cstdint>\n#include <vector>\n\n#include \"mip/HighsCutPool.h\"\n#include \"mip/HighsLpRelaxation.h\"\n#include \"mip/HighsSeparator.h\"\n\nclass HighsMipSolver;\nclass HighsImplications;\nclass HighsCliqueTable;\n\nclass HighsSeparation {\n public:\n  HighsInt separationRound(HighsDomain& propdomain,\n                           HighsLpRelaxation::Status& status);\n\n  void separate(HighsDomain& propdomain);\n\n  void setLpRelaxation(HighsLpRelaxation* lp) { this->lp = lp; }\n\n  HighsSeparation(const HighsMipSolver& mipsolver);\n\n private:\n  HighsInt implBoundClock;\n  HighsInt cliqueClock;\n  std::vector<std::unique_ptr<HighsSeparator>> separators;\n  HighsCutSet cutset;\n  HighsLpRelaxation* lp;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsSeparator.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file mip/HighsSeparator.h\n * @brief Base class for separators\n *\n */\n\n#ifndef MIP_HIGHS_SEPARATOR_H_\n#define MIP_HIGHS_SEPARATOR_H_\n\n#include <string>\n\n#include \"util/HighsInt.h\"\n\nconst std::string kImplboundSepaString = \"Separation: Implied bounds\";\nconst std::string kCliqueSepaString = \"Separation: Clique\";\nconst std::string kTableauSepaString = \"Separation: Tableau\";\nconst std::string kPathAggrSepaString = \"Separation: Path aggregation\";\nconst std::string kModKSepaString = \"Separation: Mod-k\";\n\nclass HighsLpRelaxation;\nclass HighsTransformedLp;\nclass HighsCutPool;\nclass HighsLpAggregator;\nclass HighsMipSolver;\n\n/// Helper class to compute single-row relaxations from the current LP\n/// relaxation by substituting bounds and aggregating rows\nclass HighsSeparator {\n private:\n  HighsInt numCutsFound;\n  HighsInt numCalls;\n  int clockIndex;\n\n public:\n  HighsSeparator(const HighsMipSolver& mipsolver, const std::string& name);\n\n  virtual void separateLpSolution(HighsLpRelaxation& lpRelaxation,\n                                  HighsLpAggregator& lpAggregator,\n                                  HighsTransformedLp& transLp,\n                                  HighsCutPool& cutpool) = 0;\n\n  void run(HighsLpRelaxation& lpRelaxation, HighsLpAggregator& lpAggregator,\n           HighsTransformedLp& transLp, HighsCutPool& cutpool);\n\n  HighsInt getNumCutsFound() const { return numCutsFound; }\n\n  HighsInt getNumCalls() const { return numCalls; }\n\n  HighsInt getClockIndex() const { return clockIndex; }\n\n  virtual ~HighsSeparator() {}\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsTableauSeparator.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file mip/HighsTableauSeparator.h\n * @brief Class for separating cuts from the LP tableaux rows\n *\n */\n\n#ifndef MIP_HIGHS_TABLEAU_SEPARATOR_H_\n#define MIP_HIGHS_TABLEAU_SEPARATOR_H_\n\n#include \"mip/HighsSeparator.h\"\n\n/// Helper class to compute single-row relaxations from the current LP\n/// relaxation by substituting bounds and aggregating rows\nclass HighsTableauSeparator : public HighsSeparator {\n private:\n  int64_t numTries;\n\n public:\n  void separateLpSolution(HighsLpRelaxation& lpRelaxation,\n                          HighsLpAggregator& lpAggregator,\n                          HighsTransformedLp& transLp,\n                          HighsCutPool& cutpool) override;\n\n  HighsTableauSeparator(const HighsMipSolver& mipsolver)\n      : HighsSeparator(mipsolver, kTableauSepaString), numTries(0) {}\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/HighsTransformedLp.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file mip/HighsTransformedLp.h\n * @brief LP transformations useful for cutting plane separation. This includes\n * bound substitution with simple and variable bounds, handling of slack\n * variables, flipping the complementation of integers.\n */\n\n#ifndef MIP_HIGHS_TRANSFORMED_LP_H_\n#define MIP_HIGHS_TRANSFORMED_LP_H_\n\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n#include \"mip/HighsImplications.h\"\n#include \"util/HighsCDouble.h\"\n#include \"util/HighsInt.h\"\n#include \"util/HighsSparseVectorSum.h\"\n\nclass HighsLpRelaxation;\n\n/// Helper class to compute single-row relaxations from the current LP\n/// relaxation by substituting bounds and aggregating rows\nclass HighsTransformedLp {\n private:\n  const HighsLpRelaxation& lprelaxation;\n\n  std::vector<std::pair<HighsInt, HighsImplications::VarBound>> bestVub;\n  std::vector<std::pair<HighsInt, HighsImplications::VarBound>> bestVlb;\n  std::vector<double> simpleLbDist;\n  std::vector<double> simpleUbDist;\n  std::vector<double> lbDist;\n  std::vector<double> ubDist;\n  std::vector<double> boundDist;\n  enum class BoundType : uint8_t {\n    kSimpleUb,\n    kSimpleLb,\n    kVariableUb,\n    kVariableLb,\n  };\n  std::vector<BoundType> boundTypes;\n  HighsSparseVectorSum vectorsum;\n\n public:\n  HighsTransformedLp(const HighsLpRelaxation& lprelaxation,\n                     HighsImplications& implications);\n\n  double boundDistance(HighsInt col) const { return boundDist[col]; }\n\n  bool transform(std::vector<double>& vals, std::vector<double>& upper,\n                 std::vector<double>& solval, std::vector<HighsInt>& inds,\n                 double& rhs, bool& integralPositive, bool preferVbds = false);\n\n  bool untransform(std::vector<double>& vals, std::vector<HighsInt>& inds,\n                   double& rhs, bool integral = false);\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/MipTimer.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file mip/MipTimer.h\n * @brief Indices of mip iClocks\n */\n#ifndef MIP_MIPTIMER_H_\n#define MIP_MIPTIMER_H_\n\n// Clocks for profiling the MIP dual mip solver\nenum iClockMip {\n  kMipClockTotal = 0,\n  kMipClockPresolve,\n  kMipClockSolve,\n  kMipClockPostsolve,\n  // Level 1\n  kMipClockInit,\n  kMipClockRunPresolve,\n  kMipClockRunSetup,\n  kMipClockFeasibilityJump,\n  kMipClockTrivialHeuristics,\n  kMipClockEvaluateRootNode,\n  kMipClockPerformAging0,\n  kMipClockSearch,\n  // Search\n  kMipClockProbingPresolve,\n  kMipClockPerformAging1,\n  kMipClockDive,\n  kMipClockOpenNodesToQueue0,\n  kMipClockDomainPropgate,\n  kMipClockPruneInfeasibleNodes,\n  kMipClockUpdateLocalDomain,\n  kMipClockNodeSearch,\n\n  // Evaluate root node\n  kMipClockStartSymmetryDetection,\n  kMipClockStartAnalyticCentreComputation,\n  kMipClockEvaluateRootLp,\n  kMipClockSeparateLpCuts,\n  kMipClockRandomizedRounding,\n  kMipClockPerformRestart,\n  kMipClockRootSeparation,\n  kMipClockFinishAnalyticCentreComputation,\n  kMipClockRootCentralRounding,\n  kMipClockRootSeparationRound0,\n  kMipClockRootHeuristicsReducedCost,\n  kMipClockRootSeparationRound1,\n  kMipClockRootHeuristicsRens,\n  kMipClockRootSeparationRound2,\n  kMipClockRootFeasibilityPump,\n  kMipClockRootSeparationRound3,\n  //  kMipClock@,\n  //  kMipClock@,\n  //  kMipClock@,\n  //  kMipClock@,\n\n  kMipClockEvaluateRootNode0,\n  kMipClockEvaluateRootNode1,\n  kMipClockEvaluateRootNode2,\n\n  // Dive\n  kMipClockDiveEvaluateNode,\n  kMipClockDivePrimalHeuristics,\n  kMipClockTheDive,\n  kMipClockBacktrackPlunge,\n  kMipClockPerformAging2,\n\n  // Dive primal heuristics\n  kMipClockDiveRandomizedRounding,\n  kMipClockDiveRens,\n  kMipClockDiveRins,\n\n  // NodeSearch\n  kMipClockCurrentNodeToQueue,\n  kMipClockSearchBacktrack,\n  kMipClockNodePrunedLoop,\n  kMipClockOpenNodesToQueue1,\n  kMipClockEvaluateNode1,\n  kMipClockNodeSearchSeparation,\n  kMipClockStoreBasis,\n  //  kMipClock@,\n\n  // Separation\n  kMipClockRootSeparationRound,\n  kMipClockRootSeparationFinishAnalyticCentreComputation,\n  kMipClockRootSeparationCentralRounding,\n  kMipClockRootSeparationEvaluateRootLp,\n  kMipClockImplboundSepa,\n  kMipClockCliqueSepa,\n  kMipClockTableauSepa,\n  kMipClockPathAggrSepa,\n  kMipClockModKSepa,\n\n  // LP solves\n  kMipClockSimplexBasisSolveLp,\n  kMipClockSimplexNoBasisSolveLp,\n  kMipClockHipoSolveAnalyticCentreLp,\n  kMipClockIpxSolveAnalyticCentreLp,\n  kMipClockHipoSolveLp,\n  kMipClockIpxSolveLp,\n\n  // Sub-MIP solves\n  kMipClockSubMipSolve,\n\n  kMipClockProbingImplications,\n\n  kNumMipClock  //!< Number of MIP clocks\n};\n\nconst double tolerance_percent_report = 0.1;\n\nclass MipTimer {\n public:\n  void initialiseMipClocks(HighsTimerClock& mip_timer_clock) {\n    HighsTimer* timer_pointer = mip_timer_clock.timer_pointer_;\n    std::vector<HighsInt>& clock = mip_timer_clock.clock_;\n\n    clock.resize(kNumMipClock);\n    clock[kMipClockTotal] = 0;\n    clock[kMipClockPresolve] = timer_pointer->clock_def(\"MIP presolve\");\n    clock[kMipClockSolve] = timer_pointer->clock_def(\"MIP solve\");\n    clock[kMipClockPostsolve] = timer_pointer->clock_def(\"MIP postsolve\");\n\n    // Sometimes the analytic centre clock isn't stopped - because it\n    // runs on a separate thread. Although it would be good to\n    // understand this better, for now don't assert that this clock\n    // has stopped in HighsTimer.h. This is done with a hard-coded\n    // clock IDs that need to equal clock[kMipClockHipoSolveAnalyticCentreLp]\n    // and clock[kMipClockIpxSolveAnalyticCentreLp]\n    //\n    // Define the clocks for evaluating the LPs first, so that\n    // clock[kMipClockHipoSolveAnalyticCentreLp] and\n    // clock[kMipClockIpxSolveAnalyticCentreLp] aren't changed by inserting new\n    // clocks\n    clock[kMipClockSimplexBasisSolveLp] =\n        timer_pointer->clock_def(\"Solve LP - simplex basis\");\n    clock[kMipClockSimplexNoBasisSolveLp] =\n        timer_pointer->clock_def(\"Solve LP - simplex no basis\");\n    assert(clock[kMipClockSimplexNoBasisSolveLp] == 8);\n    clock[kMipClockHipoSolveAnalyticCentreLp] =\n        timer_pointer->clock_def(\"Solve LP: HiPO analytic centre\");\n    clock[kMipClockIpxSolveAnalyticCentreLp] =\n        timer_pointer->clock_def(\"Solve LP: IPX analytic centre\");\n    assert(clock[kMipClockHipoSolveAnalyticCentreLp] == 9);\n    assert(clock[kMipClockIpxSolveAnalyticCentreLp] == 10);\n    clock[kMipClockHipoSolveLp] = timer_pointer->clock_def(\"Solve LP: HiPO\");\n    clock[kMipClockIpxSolveLp] = timer_pointer->clock_def(\"Solve LP: IPX\");\n\n    // Level 1 - Should correspond to kMipClockTotal\n    clock[kMipClockInit] = timer_pointer->clock_def(\"Initialise\");\n    clock[kMipClockRunPresolve] = timer_pointer->clock_def(\"Run presolve\");\n    clock[kMipClockRunSetup] = timer_pointer->clock_def(\"Run setup\");\n    clock[kMipClockFeasibilityJump] =\n        timer_pointer->clock_def(\"Feasibility jump\");\n    clock[kMipClockTrivialHeuristics] =\n        timer_pointer->clock_def(\"Trivial heuristics\");\n    clock[kMipClockEvaluateRootNode] =\n        timer_pointer->clock_def(\"Evaluate root node\");\n    clock[kMipClockPerformAging0] = timer_pointer->clock_def(\"Perform aging 0\");\n    clock[kMipClockSearch] = timer_pointer->clock_def(\"Search\");\n    // kMipClockPostsolve\n\n    // Evaluate root node\n    clock[kMipClockStartSymmetryDetection] =\n        timer_pointer->clock_def(\"Start symmetry detection\");\n    clock[kMipClockStartAnalyticCentreComputation] =\n        timer_pointer->clock_def(\"A-centre - start\");\n    clock[kMipClockEvaluateRootLp] =\n        timer_pointer->clock_def(\"Evaluate root LP\");\n    clock[kMipClockSeparateLpCuts] =\n        timer_pointer->clock_def(\"Separate LP cuts\");\n    clock[kMipClockRandomizedRounding] =\n        timer_pointer->clock_def(\"Randomized rounding\");\n    clock[kMipClockPerformRestart] =\n        timer_pointer->clock_def(\"Perform restart\");\n    clock[kMipClockRootSeparation] =\n        timer_pointer->clock_def(\"Root separation\");\n    clock[kMipClockFinishAnalyticCentreComputation] =\n        timer_pointer->clock_def(\"A-centre - finish\");\n    clock[kMipClockRootCentralRounding] =\n        timer_pointer->clock_def(\"Root central rounding\");\n    clock[kMipClockRootSeparationRound0] =\n        timer_pointer->clock_def(\"Root separation round 0\");\n    clock[kMipClockRootHeuristicsReducedCost] =\n        timer_pointer->clock_def(\"Root heuristics reduced cost\");\n    clock[kMipClockRootSeparationRound1] =\n        timer_pointer->clock_def(\"Root separation round 1\");\n    clock[kMipClockRootHeuristicsRens] =\n        timer_pointer->clock_def(\"Root heuristics RENS\");\n    clock[kMipClockRootSeparationRound2] =\n        timer_pointer->clock_def(\"Root separation round 2\");\n    clock[kMipClockRootFeasibilityPump] =\n        timer_pointer->clock_def(\"Root feasibility pump\");\n    clock[kMipClockRootSeparationRound3] =\n        timer_pointer->clock_def(\"Root separation round 3\");\n    //    clock[kMipClock@] = timer_pointer->clock_def(\"@\");\n\n    clock[kMipClockEvaluateRootNode0] =\n        timer_pointer->clock_def(\"kMipClockEvaluateRootNode0\");\n    clock[kMipClockEvaluateRootNode1] =\n        timer_pointer->clock_def(\"kMipClockEvaluateRootNode1\");\n    clock[kMipClockEvaluateRootNode2] =\n        timer_pointer->clock_def(\"kMipClockEvaluateRootNode2\");\n\n    // Separation\n    clock[kMipClockRootSeparationRound] =\n        timer_pointer->clock_def(\"Separation\");\n    clock[kMipClockRootSeparationFinishAnalyticCentreComputation] =\n        timer_pointer->clock_def(\"A-centre - finish\");\n    clock[kMipClockRootSeparationCentralRounding] =\n        timer_pointer->clock_def(\"Central rounding\");\n    clock[kMipClockRootSeparationEvaluateRootLp] =\n        timer_pointer->clock_def(\"Evaluate root LP\");\n\n    clock[kMipClockImplboundSepa] =\n        timer_pointer->clock_def(kImplboundSepaString.c_str());\n    clock[kMipClockCliqueSepa] =\n        timer_pointer->clock_def(kCliqueSepaString.c_str());\n    clock[kMipClockTableauSepa] =\n        timer_pointer->clock_def(kTableauSepaString.c_str());\n    clock[kMipClockPathAggrSepa] =\n        timer_pointer->clock_def(kPathAggrSepaString.c_str());\n    clock[kMipClockModKSepa] =\n        timer_pointer->clock_def(kModKSepaString.c_str());\n\n    // Presolve - Should correspond to kMipClockRunPresolve\n    clock[kMipClockProbingPresolve] =\n        timer_pointer->clock_def(\"Probing - presolve\");\n\n    // Search - Should correspond to kMipClockSearch\n    clock[kMipClockPerformAging1] = timer_pointer->clock_def(\"Perform aging 1\");\n    clock[kMipClockDive] = timer_pointer->clock_def(\"Dive\");\n    clock[kMipClockOpenNodesToQueue0] =\n        timer_pointer->clock_def(\"Open nodes to queue 0\");\n    clock[kMipClockDomainPropgate] =\n        timer_pointer->clock_def(\"Domain propagate\");\n    clock[kMipClockPruneInfeasibleNodes] =\n        timer_pointer->clock_def(\"Prune infeasible nodes\");\n    clock[kMipClockUpdateLocalDomain] =\n        timer_pointer->clock_def(\"Update local domain\");\n    clock[kMipClockNodeSearch] = timer_pointer->clock_def(\"Node search\");\n    //    clock[kMipClock@] = timer_pointer->clock_def(\"@\");\n\n    // Dive - Should correspond to kMipClockDive\n    clock[kMipClockDiveEvaluateNode] =\n        timer_pointer->clock_def(\"Evaluate node\");\n    clock[kMipClockDivePrimalHeuristics] =\n        timer_pointer->clock_def(\"Dive primal heuristics\");\n    clock[kMipClockTheDive] = timer_pointer->clock_def(\"The dive\");\n    clock[kMipClockBacktrackPlunge] =\n        timer_pointer->clock_def(\"Backtrack plunge\");\n    clock[kMipClockPerformAging2] = timer_pointer->clock_def(\"Perform aging 2\");\n\n    // Primal heuristics - Should correspond to kMipDiveClockPrimalHeuristics\n    clock[kMipClockDiveRandomizedRounding] =\n        timer_pointer->clock_def(\"Dive Randomized rounding\");\n    clock[kMipClockDiveRens] = timer_pointer->clock_def(\"Dive RENS\");\n    clock[kMipClockDiveRins] = timer_pointer->clock_def(\"Dive RINS\");\n\n    // Node search\n    clock[kMipClockCurrentNodeToQueue] =\n        timer_pointer->clock_def(\"Current node to queue\");\n    clock[kMipClockSearchBacktrack] =\n        timer_pointer->clock_def(\"Search backtrack\");\n    clock[kMipClockNodePrunedLoop] =\n        timer_pointer->clock_def(\"Pruned loop search\");\n    clock[kMipClockOpenNodesToQueue1] =\n        timer_pointer->clock_def(\"Open nodes to queue 1\");\n    clock[kMipClockEvaluateNode1] = timer_pointer->clock_def(\"Evaluate node 1\");\n    clock[kMipClockNodeSearchSeparation] =\n        timer_pointer->clock_def(\"Node search separation\");\n    clock[kMipClockStoreBasis] = timer_pointer->clock_def(\"Store basis\");\n    //    clock[] = timer_pointer->clock_def(\"\");\n\n    // Sub-MIP clock\n    clock[kMipClockSubMipSolve] = timer_pointer->clock_def(\"Sub-MIP solves\");\n\n    clock[kMipClockProbingImplications] =\n        timer_pointer->clock_def(\"Probing - implications\");\n    //    clock[] = timer_pointer->clock_def(\"\");\n  };\n\n  bool reportMipClockList(const char* grepStamp,\n                          const std::vector<HighsInt> mip_clock_list,\n                          const HighsTimerClock& mip_timer_clock,\n                          const HighsInt kMipClockIdeal = kMipClockTotal,\n                          const double tolerance_percent_report_ = -1) {\n    HighsTimer* timer_pointer = mip_timer_clock.timer_pointer_;\n    if (!timer_pointer->printf_flag) return false;\n    const std::vector<HighsInt>& clock = mip_timer_clock.clock_;\n    HighsInt mip_clock_list_size = mip_clock_list.size();\n    std::vector<HighsInt> clockList;\n    clockList.resize(mip_clock_list_size);\n    for (HighsInt en = 0; en < mip_clock_list_size; en++) {\n      clockList[en] = clock[mip_clock_list[en]];\n    }\n    const double ideal_sum_time =\n        timer_pointer->clock_time[clock[kMipClockIdeal]];\n    const double tolerance_percent_report =\n        tolerance_percent_report_ >= 0 ? tolerance_percent_report_ : 1e-8;\n    return timer_pointer->reportOnTolerance(\n        grepStamp, clockList, ideal_sum_time, tolerance_percent_report);\n  };\n\n  void csvMipClockList(const std::string grep_query,\n                       const std::string model_name,\n                       const std::vector<HighsInt> mip_clock_list,\n                       const HighsTimerClock& mip_timer_clock,\n                       const HighsInt kMipClockIdeal, const bool header,\n                       const bool end_line) {\n    HighsTimer* timer_pointer = mip_timer_clock.timer_pointer_;\n    if (!timer_pointer->printf_flag) return;\n    const std::vector<HighsInt>& clock = mip_timer_clock.clock_;\n    const double ideal_sum_time =\n        timer_pointer->clock_time[clock[kMipClockIdeal]];\n    if (ideal_sum_time < 1e-2) return;\n    const HighsInt num_clock = mip_clock_list.size();\n    if (header) {\n      printf(\"grep_%s,model,ideal\", grep_query.c_str());\n      for (HighsInt iX = 0; iX < num_clock; iX++) {\n        HighsInt iclock = clock[mip_clock_list[iX]];\n        printf(\",%s\", timer_pointer->clock_names[iclock].c_str());\n      }\n      printf(\",Unaccounted\");\n      if (end_line) printf(\"\\n\");\n      return;\n    }\n    double sum_time = 0;\n    printf(\"grep_%s,%s,%11.4g\", grep_query.c_str(), model_name.c_str(),\n           ideal_sum_time);\n    for (HighsInt iX = 0; iX < num_clock; iX++) {\n      HighsInt iclock = clock[mip_clock_list[iX]];\n      double time = timer_pointer->read(iclock);\n      sum_time += time;\n      printf(\",%11.4g\", time);\n    }\n    printf(\",%11.4g\", ideal_sum_time - sum_time);\n    if (end_line) printf(\"\\n\");\n  }\n\n  void reportMipCoreClock(const HighsTimerClock& mip_timer_clock) {\n    //    const std::vector<HighsInt>& clock = mip_timer_clock.clock_;\n    const std::vector<HighsInt> mip_clock_list{\n        kMipClockPresolve, kMipClockSolve, kMipClockPostsolve};\n    reportMipClockList(\"MipCore_\", mip_clock_list, mip_timer_clock,\n                       kMipClockTotal);\n  };\n\n  void reportMipLevel1Clock(const HighsTimerClock& mip_timer_clock) {\n    const std::vector<HighsInt> mip_clock_list{kMipClockInit,\n                                               kMipClockRunPresolve,\n                                               kMipClockRunSetup,\n                                               kMipClockFeasibilityJump,\n                                               kMipClockTrivialHeuristics,\n                                               kMipClockEvaluateRootNode,\n                                               kMipClockPerformAging0,\n                                               kMipClockSearch,\n                                               kMipClockPostsolve};\n    reportMipClockList(\"MipLevl1\", mip_clock_list, mip_timer_clock,\n                       kMipClockTotal, tolerance_percent_report);\n  };\n\n  void reportMipSolveLpClock(const HighsTimerClock& mip_timer_clock) {\n    const std::vector<HighsInt> mip_clock_list{\n        kMipClockSimplexBasisSolveLp,\n        kMipClockSimplexNoBasisSolveLp,\n        kMipClockHipoSolveAnalyticCentreLp,\n        kMipClockIpxSolveAnalyticCentreLp,\n        kMipClockHipoSolveLp,\n        kMipClockIpxSolveLp};\n    reportMipClockList(\"MipSlvLp\", mip_clock_list, mip_timer_clock,\n                       kMipClockTotal);  //, tolerance_percent_report);\n  };\n\n  void reportMipSubMipSolveClock(const HighsTimerClock& mip_timer_clock) {\n    const std::vector<HighsInt> mip_clock_list{kMipClockSubMipSolve};\n    reportMipClockList(\"MipSlvLp\", mip_clock_list, mip_timer_clock,\n                       kMipClockTotal);  //, tolerance_percent_report);\n  };\n\n  void reportMipPresolveClock(const HighsTimerClock& mip_timer_clock) {\n    const std::vector<HighsInt> mip_clock_list{kMipClockProbingPresolve};\n    reportMipClockList(\"MipPrslv\", mip_clock_list, mip_timer_clock,\n                       kMipClockRunPresolve, tolerance_percent_report);\n  };\n\n  void reportAltEvaluateRootNodeClock(const HighsTimerClock& mip_timer_clock) {\n    const std::vector<HighsInt> mip_clock_list{kMipClockEvaluateRootNode0,\n                                               kMipClockEvaluateRootNode1,\n                                               kMipClockEvaluateRootNode2};\n    reportMipClockList(\n        \"AltEvaluateRootNode\", mip_clock_list, mip_timer_clock,\n        kMipClockEvaluateRootNode);  //, tolerance_percent_report);\n  };\n\n  void reportMipEvaluateRootNodeClock(const HighsTimerClock& mip_timer_clock) {\n    const std::vector<HighsInt> mip_clock_list{\n        kMipClockStartSymmetryDetection,\n        kMipClockStartAnalyticCentreComputation,\n        kMipClockEvaluateRootLp,\n        kMipClockSeparateLpCuts,\n        kMipClockRandomizedRounding,\n        kMipClockPerformRestart,\n        kMipClockRootSeparation,\n        kMipClockFinishAnalyticCentreComputation,\n        kMipClockRootCentralRounding,\n        kMipClockRootSeparationRound0,\n        kMipClockRootHeuristicsReducedCost,\n        kMipClockRootSeparationRound1,\n        kMipClockRootHeuristicsRens,\n        kMipClockRootSeparationRound2,\n        kMipClockRootFeasibilityPump,\n        kMipClockRootSeparationRound3\n        //\tkMipClock@,\n        //\tkMipClock@\n    };\n    reportMipClockList(\n        \"MipEvaluateRootNode\", mip_clock_list, mip_timer_clock,\n        kMipClockEvaluateRootNode);  //, tolerance_percent_report);\n  };\n\n  void reportMipRootSeparationClock(const HighsTimerClock& mip_timer_clock) {\n    const std::vector<HighsInt> mip_clock_list{\n        kMipClockRootSeparationRound,\n        kMipClockRootSeparationFinishAnalyticCentreComputation,\n        kMipClockRootSeparationCentralRounding,\n        kMipClockRootSeparationEvaluateRootLp};\n    reportMipClockList(\"MipRootSeparation\", mip_clock_list, mip_timer_clock,\n                       kMipClockRootSeparation);  //, tolerance_percent_report);\n  };\n\n  void reportMipSearchClock(const HighsTimerClock& mip_timer_clock) {\n    const std::vector<HighsInt> mip_clock_list{\n        kMipClockPerformAging1,        kMipClockDive,\n        kMipClockOpenNodesToQueue0,    kMipClockDomainPropgate,\n        kMipClockPruneInfeasibleNodes, kMipClockUpdateLocalDomain,\n        kMipClockNodeSearch,\n        //\tkMipClock@\n    };\n    reportMipClockList(\"MipSerch\", mip_clock_list, mip_timer_clock,\n                       kMipClockSearch, tolerance_percent_report);\n  };\n\n  void reportMipDiveClock(const HighsTimerClock& mip_timer_clock) {\n    const std::vector<HighsInt> mip_clock_list{\n        kMipClockDiveEvaluateNode, kMipClockDivePrimalHeuristics,\n        kMipClockTheDive, kMipClockBacktrackPlunge, kMipClockPerformAging2};\n    reportMipClockList(\"MipDive_\", mip_clock_list, mip_timer_clock,\n                       kMipClockDive, tolerance_percent_report);\n  };\n\n  void reportMipDivePrimalHeuristicsClock(\n      const HighsTimerClock& mip_timer_clock) {\n    const std::vector<HighsInt> mip_clock_list{\n        kMipClockDiveRandomizedRounding, kMipClockDiveRens, kMipClockDiveRins};\n    reportMipClockList(\"MipDivePrimalHeuristics\", mip_clock_list,\n                       mip_timer_clock, kMipClockDivePrimalHeuristics,\n                       tolerance_percent_report);\n  };\n\n  void reportMipNodeSearchClock(const HighsTimerClock& mip_timer_clock) {\n    const std::vector<HighsInt> mip_clock_list{\n        kMipClockCurrentNodeToQueue, kMipClockNodePrunedLoop,\n        //      kMipClockSearchBacktrack,\n        kMipClockOpenNodesToQueue1, kMipClockEvaluateNode1,\n        kMipClockNodeSearchSeparation};  //, kMipClockStoreBasis};\n    reportMipClockList(\"MipNodeSearch\", mip_clock_list, mip_timer_clock,\n                       kMipClockNodeSearch);  //, tolerance_percent_report);\n  };\n\n  void reportMipSeparationClock(const HighsTimerClock& mip_timer_clock) {\n    const std::vector<HighsInt> mip_clock_list{\n        kMipClockImplboundSepa, kMipClockCliqueSepa, kMipClockTableauSepa,\n        kMipClockPathAggrSepa, kMipClockModKSepa};\n    reportMipClockList(\"MipSeparation\", mip_clock_list, mip_timer_clock,\n                       kMipClockTotal);  //, tolerance_percent_report);\n  };\n\n  void csvMipClock(const std::string model_name,\n                   const HighsTimerClock& mip_timer_clock, const bool header,\n                   const bool end_line) {\n    const std::vector<HighsInt> mip_clock_list{\n        kMipClockRunPresolve, kMipClockEvaluateRootNode,\n        kMipClockDivePrimalHeuristics, kMipClockTheDive, kMipClockNodeSearch};\n    csvMipClockList(\"csvMIP\", model_name, mip_clock_list, mip_timer_clock,\n                    kMipClockTotal, header, end_line);\n  };\n\n  void csvEvaluateRootNodeClock(const std::string model_name,\n                                const HighsTimerClock& mip_timer_clock,\n                                const bool header, const bool end_line) {\n    const std::vector<HighsInt> mip_clock_list{\n        kMipClockStartSymmetryDetection,\n        kMipClockStartAnalyticCentreComputation,\n        kMipClockEvaluateRootLp,\n        kMipClockSeparateLpCuts,\n        kMipClockRandomizedRounding,\n        kMipClockPerformRestart,\n        kMipClockRootSeparation,\n        kMipClockFinishAnalyticCentreComputation,\n        kMipClockRootCentralRounding,\n        kMipClockRootSeparationRound0,\n        kMipClockRootHeuristicsReducedCost,\n        kMipClockRootSeparationRound1,\n        kMipClockRootHeuristicsRens,\n        kMipClockRootSeparationRound2,\n        kMipClockRootFeasibilityPump,\n        kMipClockRootSeparationRound3};\n    csvMipClockList(\"csvRootNode\", model_name, mip_clock_list, mip_timer_clock,\n                    kMipClockEvaluateRootNode, header, end_line);\n  };\n\n  void reportFjClock(std::string& model,\n                     const HighsTimerClock& mip_timer_clock) {\n    HighsTimer* timer_pointer = mip_timer_clock.timer_pointer_;\n    if (!timer_pointer->printf_flag) return;\n    HighsInt iClock = mip_timer_clock.clock_[kMipClockFeasibilityJump];\n    const double fj_time = timer_pointer->read(iClock);\n    const double total_time = timer_pointer->read();\n    const double pct = total_time > 0 ? 1e2 * fj_time / total_time : 0;\n    printf(\"grepFK,%s,%s,%d,%g,%g\\n\", model.c_str(),\n           timer_pointer->clock_names[iClock].c_str(),\n           int(timer_pointer->clock_num_call[iClock]), fj_time, pct);\n  }\n};\n\n#endif /* MIP_MIPTIMER_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/mip/feasibilityjump.hh",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#include <algorithm>\n#include <cassert>\n#include <climits>\n#include <cmath>\n#include <functional>\n#include <numeric>\n#include <random>\n#include <vector>\n\n#include \"io/HighsIO.h\"\n#include \"lp_data/HConst.h\"\n\n#define FJ_LOG_PREFIX \"Feasibility Jump: \"\n\n// TIP: clang-format the reference feasibilityjump.hh before diffing with this\nnamespace external_feasibilityjump {\n\nenum RowType {\n  Equal,\n  Lte,\n  Gte,\n};\n\nenum VarType { Continuous, Integer };\n\nenum CallbackControlFlow {\n  Terminate,\n  Continue,\n};\n\nstruct FJStatus {\n  size_t totalEffort;\n  size_t effortSinceLastImprovement;\n  int numVars;\n  double solutionObjectiveValue;\n  double* solution;\n};\n\n// Measures if two doubles are equal within a tolerance\nstatic bool eq(double a, double b, double tol) { return fabs(a - b) < tol; }\n\nstruct IdxCoeff {\n  uint32_t idx;\n  double coeff;\n\n  IdxCoeff(uint32_t idx, double coeff) : idx(idx), coeff(coeff) {}\n};\n\nstruct Var {\n  VarType vartype;\n  double lb;\n  double ub;\n  double objectiveCoeff;\n  std::vector<IdxCoeff> coeffs;\n};\n\nstruct Constraint {\n  RowType sense;\n  double rhs;\n  std::vector<IdxCoeff> coeffs;\n  double weight;\n  double incumbentLhs;\n  int32_t violatedIdx;\n\n  // Computes the constraint's contribution to the feasibility score:\n  // If the constraint is satisfied by the given LHS value, returns 0.\n  // If the constraint is violated by the given LHS value, returns -|lhs-rhs|.\n  double score(double lhs) {\n    if (sense == RowType::Equal)\n      return -fabs(lhs - rhs);\n    else if (sense == RowType::Lte)\n      return -(std::max(0., lhs - rhs));\n    else\n      return -(std::max(0., rhs - lhs));\n  }\n};\n\n// A potential new value for a varaiable, including its score.\nstruct Move {\n  double value;\n  double score;\n\n  static Move undef() {\n    Move move;\n    move.value = NAN;\n    move.score = -std::numeric_limits<double>::infinity();\n    return move;\n  }\n};\n\n// Represents a modification of the LHS in a constraint, for a specific\n// variable/constraint combination.The `modifyMove` function below is used to\n// update the score of a `Move` to reflect the LHS modification.\nstruct LhsModification {\n  uint32_t varIdx;\n  uint32_t constraintIdx;\n  double coeff;\n  double oldLhs;\n  double newLhs;\n};\n\n// Stores the MIP problem, an incumbent assignment, and the set of constraints\n// that are violated in the current incumbent assignment. This set is maintained\n// when changes are given to the incumbent assignment using `setValue`.\nclass Problem {\n  const double equalityTolerance;\n  const double violationTolerance;\n\n public:\n  Problem(double equalityTolerance, double violationTolerance)\n      : equalityTolerance(equalityTolerance),\n        violationTolerance(violationTolerance) {}\n  std::vector<Var> vars;\n  std::vector<Constraint> constraints;\n  std::vector<double> incumbentAssignment;\n  std::vector<uint32_t> violatedConstraints;\n  bool usedRelaxContinuous = false;\n\n  size_t nNonzeros = 0;\n  double incumbentObjective = NAN;\n\n  int addVar(VarType vartype, double lb, double ub, double objCoeff) {\n    auto idx = vars.size();\n    Var var;\n    var.vartype = vartype;\n    var.lb = lb;\n    var.ub = ub;\n    var.objectiveCoeff = objCoeff;\n    vars.push_back(var);\n    incumbentAssignment.push_back(lb);\n    return idx;\n  }\n\n  int addConstraint(RowType sense, double rhs, int numCoeffs, int* rowVarIdxs,\n                    double* rowCoeffs, int relax_continuous) {\n    if (relax_continuous) usedRelaxContinuous = true;\n\n    // If we are relaxing continuous variables, an equality needs to be split\n    // into Gte and Lte.\n    if (relax_continuous > 0 && sense == RowType::Equal)\n      if (std::any_of(rowVarIdxs, rowVarIdxs + numCoeffs, [&](double varIdx) {\n            return vars[varIdx].vartype == VarType::Continuous;\n          })) {\n        addConstraint(RowType::Gte, rhs, numCoeffs, rowVarIdxs, rowCoeffs,\n                      relax_continuous);\n        addConstraint(RowType::Lte, rhs, numCoeffs, rowVarIdxs, rowCoeffs,\n                      relax_continuous);\n        return INT_MAX;\n      }\n\n    std::vector<IdxCoeff> coeffs;\n    for (int i = 0; i < numCoeffs; i += 1) {\n      if (relax_continuous > 0 &&\n          vars[rowVarIdxs[i]].vartype == VarType::Continuous) {\n        if (sense == RowType::Lte) {\n          if (rowCoeffs[i] >= 0.)\n            rhs -= rowCoeffs[i] * vars[rowVarIdxs[i]].lb;\n          else\n            rhs -= rowCoeffs[i] * vars[rowVarIdxs[i]].ub;\n        } else if (sense == RowType::Gte) {\n          if (rowCoeffs[i] >= 0.)\n            rhs -= rowCoeffs[i] * vars[rowVarIdxs[i]].ub;\n          else\n            rhs -= rowCoeffs[i] * vars[rowVarIdxs[i]].lb;\n        } else\n          return INT_MIN;\n      } else\n        coeffs.emplace_back(rowVarIdxs[i], rowCoeffs[i]);\n    }\n\n    if (coeffs.empty()) {\n      bool ok;\n      if (sense == RowType::Lte)\n        ok = 0 <= rhs + equalityTolerance;\n      else if (sense == RowType::Gte)\n        ok = 0 + equalityTolerance >= rhs;\n      else\n        ok = eq(0, rhs, equalityTolerance);\n\n      return ok ? INT_MAX : INT_MIN;\n    }\n\n    int newConstraintIdx = constraints.size();\n    for (auto& c : coeffs) {\n      vars[c.idx].coeffs.emplace_back(newConstraintIdx, c.coeff);\n    }\n\n    nNonzeros += coeffs.size();\n    Constraint newConstraint;\n    newConstraint.coeffs = coeffs;\n    newConstraint.incumbentLhs = NAN;\n    newConstraint.violatedIdx = -1;\n    newConstraint.rhs = rhs;\n    newConstraint.sense = sense;\n    newConstraint.weight = 1.0;\n\n    constraints.push_back(newConstraint);\n    return newConstraintIdx;\n  }\n\n  void resetIncumbent(double* initialValues) {\n    // Set the initial values, if given.\n\n    if (initialValues)\n      for (size_t i = 0; i < vars.size(); i += 1)\n        incumbentAssignment[i] = initialValues[i];\n    // std::copy(initialValues, initialValues + vars.size(),\n    // incumbentAssignment);\n\n    // Reset the incumbent objective.\n    incumbentObjective = 0;\n    for (size_t i = 0; i < vars.size(); i += 1)\n      incumbentObjective += vars[i].objectiveCoeff * incumbentAssignment[i];\n\n    // Reset the constraint LHSs and the violatedConstraints list.\n    violatedConstraints.clear();\n    for (size_t cIdx = 0; cIdx < constraints.size(); cIdx += 1) {\n      Constraint& cstr = constraints[cIdx];\n\n      cstr.incumbentLhs = 0.0;\n      for (auto& vc : cstr.coeffs)\n        cstr.incumbentLhs += vc.coeff * incumbentAssignment[vc.idx];\n\n      if (cstr.score(cstr.incumbentLhs) < -violationTolerance) {\n        cstr.violatedIdx = violatedConstraints.size();\n        violatedConstraints.push_back(cIdx);\n      } else\n        cstr.violatedIdx = -1;\n    }\n  }\n\n  // Updates a variable assignment for `varIdx` to `newValue`.\n  // Takes a function parameter f that receives a LhsModification\n  // for every variable/constraint combination (except for `varIdx` itself)\n  // where the LHS of the constraint has changed.\n  template <typename F>\n  size_t setValue(uint32_t varIdx, double newValue, F f) {\n    size_t dt = 0;\n    double oldValue = incumbentAssignment[varIdx];\n    double delta = (newValue - oldValue);\n    incumbentAssignment[varIdx] = newValue;\n    incumbentObjective += vars[varIdx].objectiveCoeff * delta;\n    // printf(\"Setting v%d to from %g to value %g\\n\", varIdx, oldValue,\n    // newValue);\n\n    // Update the LHSs of all involved constraints.\n    for (auto& cstrCoeff : vars[varIdx].coeffs) {\n      double oldLhs = constraints[cstrCoeff.idx].incumbentLhs;\n      double newLhs = oldLhs + cstrCoeff.coeff * delta;\n      constraints[cstrCoeff.idx].incumbentLhs = newLhs;\n      double newCost = constraints[cstrCoeff.idx].score(newLhs);\n\n      // Add/remove from the violatedConstraints list.\n      if (newCost < -violationTolerance &&\n          constraints[cstrCoeff.idx].violatedIdx == -1) {\n        // Became violated.\n        constraints[cstrCoeff.idx].violatedIdx = violatedConstraints.size();\n        violatedConstraints.push_back(cstrCoeff.idx);\n      }\n      if (newCost >= -violationTolerance &&\n          constraints[cstrCoeff.idx].violatedIdx != -1) {\n        // Became satisfied.\n        auto lastViolatedIdx = violatedConstraints.size() - 1;\n        auto lastConstraintIdx = violatedConstraints[lastViolatedIdx];\n        auto thisViolatedIdx = constraints[cstrCoeff.idx].violatedIdx;\n        std::swap(violatedConstraints[thisViolatedIdx],\n                  violatedConstraints[lastViolatedIdx]);\n        constraints[lastConstraintIdx].violatedIdx = thisViolatedIdx;\n        constraints[cstrCoeff.idx].violatedIdx = -1;\n        violatedConstraints.pop_back();\n      }\n\n      // Now, report the changes in LHS for other variables.\n      dt += constraints[cstrCoeff.idx].coeffs.size();\n      for (auto& varCoeff : constraints[cstrCoeff.idx].coeffs) {\n        if (varCoeff.idx != varIdx) {\n          LhsModification m;\n          m.varIdx = varCoeff.idx;\n          m.constraintIdx = cstrCoeff.idx;\n          m.coeff = varCoeff.coeff;\n          m.oldLhs = oldLhs;\n          m.newLhs = newLhs;\n          f(m);\n        }\n      }\n    }\n\n    return dt;\n  }\n};\n\nstatic void modifyMove(LhsModification mod, Problem& problem, Move& move) {\n  Constraint& c = problem.constraints[mod.constraintIdx];\n  auto incumbent = problem.incumbentAssignment[mod.varIdx];\n  double oldModifiedLhs = mod.oldLhs + mod.coeff * (move.value - incumbent);\n  double oldScoreTerm =\n      c.weight * (c.score(oldModifiedLhs) - c.score(mod.oldLhs));\n  double newModifiedLhs = mod.newLhs + mod.coeff * (move.value - incumbent);\n  double newScoreTerm =\n      c.weight * (c.score(newModifiedLhs) - c.score(mod.newLhs));\n  move.score += newScoreTerm - oldScoreTerm;\n}\n\n// Stores current moves and computes updated jump values for\n// the \"Jump\" move type.\nclass JumpMove {\n  const double equalityTolerance;\n  std::vector<Move> moves;\n  std::vector<std::pair<double, double>> bestShiftBuffer;\n\n public:\n  JumpMove(double equalityTolerance) : equalityTolerance(equalityTolerance) {}\n  void init(Problem& problem) { moves.resize(problem.vars.size()); }\n\n  template <typename F>\n  void forEachVarMove(int32_t varIdx, F f) {\n    f(moves[varIdx]);\n  }\n\n  void updateValue(Problem& problem, uint32_t varIdx) {\n    bestShiftBuffer.clear();\n    auto varIncumbentValue = problem.incumbentAssignment[varIdx];\n    double lower = problem.vars[varIdx].lb;\n    double upper = problem.vars[varIdx].ub;\n    double currentValue = lower;  // can be -inf!\n\n    double currentSlope = 0.0;\n\n    // printf(\" updatevalue lb %g ub %g numcells %d\\n\",\n    //        lower,\n    //        upper, problem.vars[varIdx].coeffs.size());\n\n    for (auto& cell : problem.vars[varIdx].coeffs) {\n      auto& constraint = problem.constraints[cell.idx];\n\n      std::vector<std::pair<double, double>> constraintBounds;\n      if (constraint.sense == RowType::Lte)\n        constraintBounds.emplace_back(-std::numeric_limits<double>::infinity(),\n                                      constraint.rhs);\n      else if (constraint.sense == RowType::Gte)\n        constraintBounds.emplace_back(constraint.rhs,\n                                      std::numeric_limits<double>::infinity());\n      else {\n        constraintBounds.emplace_back(-std::numeric_limits<double>::infinity(),\n                                      constraint.rhs);\n        constraintBounds.emplace_back(constraint.rhs, constraint.rhs);\n        constraintBounds.emplace_back(constraint.rhs,\n                                      std::numeric_limits<double>::infinity());\n      }\n\n      for (auto& bound : constraintBounds) {\n        double residualIncumbent =\n            constraint.incumbentLhs - cell.coeff * varIncumbentValue;\n\n        std::pair<double, double> validRange = {\n            ((1.0 / cell.coeff) * (bound.first - residualIncumbent)),\n            ((1.0 / cell.coeff) * (bound.second - residualIncumbent)),\n        };\n\n        if (problem.vars[varIdx].vartype == VarType::Integer)\n          validRange = {\n              std::ceil(validRange.first - equalityTolerance),\n              std::floor(validRange.second + equalityTolerance),\n          };\n\n        if (validRange.first > validRange.second) continue;\n\n        if (validRange.first > currentValue) {\n          currentSlope -= constraint.weight;\n          if (validRange.first < upper)\n            bestShiftBuffer.emplace_back(validRange.first, constraint.weight);\n        }\n\n        if (validRange.second <= currentValue) {\n          currentSlope += constraint.weight;\n        } else if (validRange.second < upper)\n          bestShiftBuffer.emplace_back(validRange.second, constraint.weight);\n      }\n    }\n\n    if (std::isfinite(lower)) {\n      bestShiftBuffer.emplace_back(lower, 0);\n    }\n    if (std::isfinite(upper)) {\n      bestShiftBuffer.emplace_back(upper, 0);\n    }\n    std::sort(bestShiftBuffer.begin(), bestShiftBuffer.end());\n\n    // We only care about relative scores, so can pick an arbitrary start level\n    double currentScore = 0.0;\n    currentValue =\n        bestShiftBuffer.empty() ? varIncumbentValue : bestShiftBuffer[0].first;\n\n    double bestScore = currentScore;\n    double bestValue = currentValue;\n\n    // printf(\"evaluating best shift buffer size %d \\n\",\n    // bestShiftBuffer.size());\n    for (auto& item : bestShiftBuffer) {\n      currentScore += (item.first - currentValue) * currentSlope;\n      currentSlope += item.second;\n      currentValue = item.first;\n\n      // printf(\"bestshift cscore %g cslope %g cval %g bestval %g bestscore\n      // %g\\n\", currentScore,currentSlope, currentValue, bestScore, bestValue\n      // );\n\n      if (eq(bestValue, varIncumbentValue, equalityTolerance) ||\n          (!eq(currentValue, varIncumbentValue, equalityTolerance) &&\n           currentScore < bestScore)) {\n        bestScore = currentScore;\n        bestValue = currentValue;\n      }\n\n      // Slope is always increasing, so if we have a valid value, we can quit\n      // as soon as the slope turns nonnegative, since we must already have\n      // visited the minimum.\n      if (!eq(bestValue, varIncumbentValue, equalityTolerance) &&\n          currentSlope >= 0.)\n        break;\n    }\n\n    // printf(\"Setting jump for %d to from %g to %g\\n\", varIdx,\n    // varIncumbentValue, moves[varIdx].value);\n    moves[varIdx].value = bestValue;\n  }\n};\n\nclass FeasibilityJumpSolver {\n  Problem problem;\n  JumpMove jumpMove;\n\n  std::vector<uint32_t> goodVarsSet;\n  std::vector<int32_t> goodVarsSetIdx;\n\n  std::mt19937 rng;\n\n  double bestObjective = std::numeric_limits<double>::infinity();\n  double objectiveWeight = 0.0;\n  size_t bestViolationScore = SIZE_MAX;\n  size_t effortAtLastCallback = 0;\n  size_t effortAtLastImprovement = 0;\n  size_t effortAtLastLogging = 0;\n  size_t totalEffort = 0;\n\n  double weightUpdateDecay;\n  double weightUpdateIncrement = 1.0;\n\n  size_t nBumps = 0;\n\n  bool need_logging_header = true;\n\n  // The probability of choosing a random positive-score variable.\n  const double randomVarProbability = 0.001;\n\n  // The probability of choosing a variable using a random constraint's\n  // non-zero coefficient after updating weights.\n\n  const double randomCellProbability = 0.01;\n\n  // The number of moves to evaluate, if there are many positive-score\n  // variables available.\n  const size_t maxMovesToEvaluate = 25;\n\n  const int kLoggingFrequency = 100000;  // Originally 100000\n  const int kLoggingHeaderFrequency = 50;\n  const size_t kMinEffortToLogging = 500 * kLoggingFrequency;\n  const double kMinRelativeObjectiveImprovement = 1e-4;\n\n  const HighsLogOptions& logOptions;\n\n public:\n  FeasibilityJumpSolver(const HighsLogOptions& _logOptions, int seed = 0,\n                        double equalityTolerance = 1e-5,\n                        double violationTolerance = 1e-5,\n                        double _weightUpdateDecay = 1.0)\n      : problem(equalityTolerance, violationTolerance),\n        jumpMove(equalityTolerance),\n        logOptions(_logOptions) {\n    weightUpdateDecay = _weightUpdateDecay;\n    rng = std::mt19937(seed);\n  }\n\n  int addVar(VarType vartype, double lb, double ub, double objCoeff) {\n    goodVarsSetIdx.push_back(-1);\n    return problem.addVar(vartype, lb, ub, objCoeff);\n  }\n\n  int addConstraint(RowType sense, double rhs, int numCoeffs, int* rowVarIdxs,\n                    double* rowCoeffs, int relax_continuous) {\n    return problem.addConstraint(sense, rhs, numCoeffs, rowVarIdxs, rowCoeffs,\n                                 relax_continuous);\n  }\n\n  int solve(double* initialValues,\n            std::function<CallbackControlFlow(FJStatus)> callback) {\n    assert(callback);\n    highsLogDev(logOptions, HighsLogType::kInfo,\n                FJ_LOG_PREFIX\n                \"starting solve. weightUpdateDecay=%g, relaxContinuous=%d  \\n\",\n                weightUpdateDecay, problem.usedRelaxContinuous);\n\n    init(initialValues);\n\n    effortAtLastLogging = -kMinEffortToLogging;  // Enabling step=0 logging\n    int num_logging_lines_since_header = 0;\n    for (int step = 0; step < INT_MAX; step += 1) {\n      if (user_terminate(callback, nullptr)) break;\n\n      if (step % kLoggingFrequency == 0 &&\n          totalEffort > effortAtLastLogging + kMinEffortToLogging) {\n        if (need_logging_header) {\n          logging(0, true);\n          num_logging_lines_since_header = 0;\n        }\n        logging(step);\n        num_logging_lines_since_header++;\n        need_logging_header =\n            num_logging_lines_since_header == kLoggingHeaderFrequency;\n      }\n\n      if (problem.violatedConstraints.size() < bestViolationScore) {\n        effortAtLastImprovement = totalEffort;\n        bestViolationScore = problem.violatedConstraints.size();\n      }\n\n      if (problem.violatedConstraints.empty() &&\n          problem.incumbentObjective < bestObjective) {\n        double relative_objective_improvement =\n            (bestObjective - problem.incumbentObjective) /\n            std::max(1.0, std::fabs(problem.incumbentObjective));\n        if (relative_objective_improvement > kMinRelativeObjectiveImprovement) {\n          effortAtLastImprovement = totalEffort;\n          bestObjective = problem.incumbentObjective;\n          if (user_terminate(callback, problem.incumbentAssignment.data()))\n            break;\n          // Repeat the header in case user callback logs new solution\n          need_logging_header = true;\n        }\n      }\n\n      if (problem.vars.size() == 0) break;\n\n      uint32_t var = selectVariable();\n      doVariableMove(var);\n    }\n\n    return 0;\n  }\n\n private:\n  void logging(const int step, const bool header = false) {\n    const HighsLogType logType = HighsLogType::kDetailed;\n    if (header) {\n      highsLogDev(logOptions, logType,\n                  FJ_LOG_PREFIX\n                  \"       step  violations     good    bumps       effort (per \"\n                  \"step)          Objective\\n\");\n    } else {\n      highsLogDev(logOptions, logType,\n                  \" %10d    %8zd   %6zd %8zd %12zd    %6zd          %10.4g\\n\",\n                  step, problem.violatedConstraints.size(), goodVarsSet.size(),\n                  nBumps, totalEffort, step > 0 ? totalEffort / step : 0,\n                  problem.incumbentObjective);\n      effortAtLastLogging = totalEffort;\n    }\n  }\n\n  void init(double* initialValues) {\n    problem.resetIncumbent(initialValues);\n    jumpMove.init(problem);\n    totalEffort += problem.nNonzeros;\n\n    // Reset the variable scores.\n    goodVarsSet.clear();\n    for (size_t i = 0; i < problem.vars.size(); i += 1) resetMoves(i);\n  }\n\n  uint32_t selectVariable() {\n    if (!goodVarsSet.empty()) {\n      if (std::uniform_real_distribution<double>(0., 1.)(rng) <\n          randomVarProbability)\n        return goodVarsSet[rng() % goodVarsSet.size()];\n\n      auto sampleSize = std::min(maxMovesToEvaluate, goodVarsSet.size());\n      totalEffort += sampleSize;\n\n      double bestScore = -std::numeric_limits<double>::infinity();\n      uint32_t bestVar = UINT_MAX;\n      for (size_t i = 0; i < sampleSize; i++) {\n        auto setidx = rng() % goodVarsSet.size();\n        auto varIdx = goodVarsSet[setidx];\n        Move move = bestMove(varIdx);\n        if (move.score > bestScore) {\n          bestScore = move.score;\n          bestVar = varIdx;\n        }\n      }\n      assert(bestVar != UINT_MAX);\n      return bestVar;\n    }\n\n    // Local minimum, update weights.\n    updateWeights();\n\n    if (!problem.violatedConstraints.empty()) {\n      size_t cstrIdx =\n          problem\n              .violatedConstraints[rng() % problem.violatedConstraints.size()];\n      auto& constraint = problem.constraints[cstrIdx];\n\n      if (std::uniform_real_distribution<double>(0., 1.)(rng) <\n          randomCellProbability)\n        return constraint.coeffs[rng() % constraint.coeffs.size()].idx;\n\n      double bestScore = -std::numeric_limits<double>::infinity();\n      uint32_t bestVarIdx = UINT_MAX;\n\n      for (auto& cell : constraint.coeffs) {\n        Move move = bestMove(cell.idx);\n        if (move.score > bestScore) {\n          bestScore = move.score;\n          bestVarIdx = cell.idx;\n        }\n      }\n      return bestVarIdx;\n    }\n\n    // Fallback to random choice.\n    return rng() % problem.vars.size();\n  }\n\n  void updateWeights() {\n    highsLogDev(logOptions, HighsLogType::kVerbose,\n                FJ_LOG_PREFIX \"Reached a local minimum.\\n\");\n    nBumps += 1;\n    bool rescaleAllWeights = false;\n    size_t dt = 0;\n\n    if (problem.violatedConstraints.empty()) {\n      objectiveWeight += weightUpdateIncrement;\n      if (objectiveWeight > 1.0e20) rescaleAllWeights = true;\n\n      dt += problem.vars.size();\n      for (size_t varIdx = 0; varIdx < problem.vars.size(); varIdx += 1)\n        forEachMove(varIdx, [&](Move& move) {\n          move.score += weightUpdateIncrement *\n                        problem.vars[varIdx].objectiveCoeff *\n                        (move.value - problem.incumbentAssignment[varIdx]);\n        });\n    } else {\n      for (auto& cIdx : problem.violatedConstraints) {\n        auto& constraint = problem.constraints[cIdx];\n        constraint.weight += weightUpdateIncrement;\n        if (constraint.weight > 1.0e20) rescaleAllWeights = true;\n\n        dt += constraint.coeffs.size();\n        for (auto& cell : constraint.coeffs) {\n          forEachMove(cell.idx, [&](Move& move) {\n            double candidateLhs =\n                constraint.incumbentLhs +\n                cell.coeff *\n                    (move.value - problem.incumbentAssignment[cell.idx]);\n            double diff = weightUpdateIncrement *\n                          (constraint.score(candidateLhs) -\n                           constraint.score(constraint.incumbentLhs));\n            move.score += diff;\n          });\n\n          updateGoodMoves(cell.idx);\n        }\n      }\n    }\n\n    weightUpdateIncrement /= weightUpdateDecay;\n    if (rescaleAllWeights) {\n      weightUpdateIncrement *= 1.0e-20;\n      objectiveWeight *= 1.0e-20;\n\n      for (auto& c : problem.constraints) c.weight *= 1.0e-20;\n      dt += problem.constraints.size();\n\n      for (size_t i = 0; i < problem.vars.size(); i += 1) resetMoves(i);\n    }\n\n    totalEffort += dt;\n  }\n\n  Move bestMove(uint32_t varIdx) {\n    Move best = Move::undef();\n    forEachMove(varIdx, [&](Move& move) {\n      if (move.score > best.score) best = move;\n    });\n\n    return best;\n  }\n\n  void doVariableMove(uint32_t varIdx) {\n    // First, we get the best move for the variable;\n    auto m = bestMove(varIdx);\n    auto newValue = m.value;\n    // assert(!isnan(newValue));\n\n    // Update the incumbent solution.\n    // printf(\"Setting var %d from %g to %g for a score of %g\\n\", varIdx,\n    // oldValue, newValue, m.score);\n\n    totalEffort += problem.setValue(varIdx, newValue, [&](LhsModification mod) {\n      forEachMove(mod.varIdx, [&](Move& m) { modifyMove(mod, problem, m); });\n      updateGoodMoves(mod.varIdx);\n    });\n\n    resetMoves(varIdx);\n  }\n\n  void updateGoodMoves(int32_t varIdx) {\n    bool anyGoodMoves = bestMove(varIdx).score > 0.;\n    if (anyGoodMoves && goodVarsSetIdx[varIdx] == -1) {\n      // Became good, add to good set.\n      goodVarsSetIdx[varIdx] = goodVarsSet.size();\n      goodVarsSet.push_back(varIdx);\n    } else if (!anyGoodMoves && goodVarsSetIdx[varIdx] != -1) {\n      // Became bad, remove from good set.\n      auto lastSetIdx = goodVarsSet.size() - 1;\n      auto lastVarIdx = goodVarsSet[lastSetIdx];\n      auto thisSetIdx = goodVarsSetIdx[varIdx];\n      std::swap(goodVarsSet[thisSetIdx], goodVarsSet[lastSetIdx]);\n      goodVarsSetIdx[lastVarIdx] = thisSetIdx;\n      goodVarsSetIdx[varIdx] = -1;\n      goodVarsSet.pop_back();\n    }\n  }\n\n  template <typename F>\n  void forEachMove(int32_t varIdx, F f) {\n    jumpMove.forEachVarMove(varIdx, f);\n\n    // TODO: here, we can add more move types.\n    // upDownMove.forEachVarMove(varIdx, f);\n  }\n\n  void resetMoves(uint32_t varIdx) {\n    totalEffort += problem.vars[varIdx].coeffs.size();\n    jumpMove.updateValue(problem, varIdx);\n\n    forEachMove(varIdx, [&](Move& move) {\n      move.score = 0.0;\n      move.score += objectiveWeight * problem.vars[varIdx].objectiveCoeff *\n                    (move.value - problem.incumbentAssignment[varIdx]);\n\n      for (auto& cell : problem.vars[varIdx].coeffs) {\n        auto& constraint = problem.constraints[cell.idx];\n        auto candidateLhs =\n            constraint.incumbentLhs +\n            cell.coeff * (move.value - problem.incumbentAssignment[varIdx]);\n        move.score +=\n            constraint.weight * (constraint.score(candidateLhs) -\n                                 constraint.score(constraint.incumbentLhs));\n      }\n    });\n\n    updateGoodMoves(varIdx);\n  }\n\n  bool user_terminate(std::function<CallbackControlFlow(FJStatus)> callback,\n                      double* solution) {\n    const int CALLBACK_EFFORT = 500000;  // Originally 500000\n    if (solution != nullptr ||\n        totalEffort - effortAtLastCallback > CALLBACK_EFFORT) {\n      highsLogDev(logOptions, HighsLogType::kVerbose,\n                  FJ_LOG_PREFIX \"calling user termination.\\n\");\n      effortAtLastCallback = totalEffort;\n\n      FJStatus status;\n      status.totalEffort = totalEffort;\n      status.effortSinceLastImprovement = totalEffort - effortAtLastImprovement;\n\n      status.solution = solution;\n      status.numVars = problem.vars.size();\n      status.solutionObjectiveValue = problem.incumbentObjective;\n\n      auto result = callback(status);\n      if (result == CallbackControlFlow::Terminate) {\n        highsLogDev(logOptions, HighsLogType::kVerbose,\n                    FJ_LOG_PREFIX \"quitting.\\n\");\n        return true;\n      }\n    }\n    return false;\n  }\n};\n\n}  // namespace external_feasibilityjump\n"
  },
  {
    "path": "thirdparty/solvers/highs/model/HighsHessian.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file model/HighsHessian.h\n * @brief\n */\n#ifndef MODEL_HIGHS_HESSIAN_H_\n#define MODEL_HIGHS_HESSIAN_H_\n\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n#include \"util/HighsCDouble.h\"\n#include \"util/HighsUtils.h\"\n\n// class HighsHessian;\n\nclass HighsHessian {\n public:\n  HighsHessian() { clear(); }\n  HighsInt dim_;\n  HessianFormat format_;\n  std::vector<HighsInt> start_;\n  std::vector<HighsInt> index_;\n  std::vector<double> value_;\n  bool operator==(const HighsHessian& hessian) const;\n  void product(const std::vector<double>& solution,\n               std::vector<double>& product) const;\n  double objectiveValue(const std::vector<double>& solution) const;\n  HighsCDouble objectiveCDoubleValue(const std::vector<double>& solution) const;\n  void exactResize();\n  void deleteCols(const HighsIndexCollection& index_collection);\n  void clear();\n  bool formatOk() const {\n    return (this->format_ == HessianFormat::kTriangular ||\n            this->format_ == HessianFormat::kSquare);\n  };\n  bool scaleOk(const HighsInt cost_scale, const double small_matrix_value,\n               const double large_matrix_value) const;\n  HighsInt numNz() const;\n\n  void print() const;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/model/HighsHessianUtils.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file model/HighsHessianUtils.h\n * @brief Class-independent utilities for HiGHS\n */\n#ifndef MODEL_HIGHSHESSIANUTILS_H_\n#define MODEL_HIGHSHESSIANUTILS_H_\n\n#include <vector>\n\n#include \"lp_data/HighsOptions.h\"\n#include \"lp_data/HighsStatus.h\"\n#include \"model/HighsHessian.h\"\n\n// class HighsHessian;\n// class HighsOptions;\n\nusing std::vector;\n\nHighsStatus assessHessian(HighsHessian& hessian, const HighsOptions& options);\nHighsStatus assessHessianDimensions(const HighsOptions& options,\n                                    HighsHessian& hessian);\nvoid completeHessianDiagonal(const HighsOptions& options,\n                             HighsHessian& hessian);\nbool okHessianDiagonal(const HighsOptions& options, HighsHessian& hessian,\n                       const ObjSense sense = ObjSense::kMinimize);\nHighsStatus normaliseHessian(const HighsOptions& options,\n                             HighsHessian& hessian);\nHighsStatus extractTriangularHessian(const HighsOptions& options,\n                                     HighsHessian& hessian);\nvoid triangularToSquareHessian(const HighsHessian& hessian,\n                               vector<HighsInt>& start, vector<HighsInt>& index,\n                               vector<double>& value);\nvoid completeHessian(const HighsInt full_dim, HighsHessian& hessian);\n\nvoid reportHessian(const HighsLogOptions& log_options, const HighsInt dim,\n                   const HighsInt num_nz, const HighsInt* start,\n                   const HighsInt* index, const double* value);\n\nvoid userScaleHessian(HighsHessian& hessian, HighsUserScaleData& data,\n                      const bool apply = true);\n#endif  // MODEL_HIGHSHESSIANUTILS_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/model/HighsModel.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file model/HighsModel.h\n * @brief\n */\n#ifndef MODEL_HIGHS_MODEL_H_\n#define MODEL_HIGHS_MODEL_H_\n\n#include <vector>\n\n#include \"lp_data/HighsLp.h\"\n#include \"model/HighsHessian.h\"\n\nclass HighsModel;\n\nclass HighsModel {\n public:\n  HighsLp lp_;\n  HighsHessian hessian_;\n  bool operator==(const HighsModel& model) const;\n  bool equalButForNames(const HighsModel& model) const;\n  bool isQp() const { return (this->hessian_.dim_ != 0); }\n  bool isMip() const { return this->lp_.isMip(); }\n  bool isEmpty() const {\n    return (this->lp_.num_col_ == 0 && this->lp_.num_row_ == 0);\n  }\n  bool needsMods(const double infinite_cost) const {\n    return this->lp_.needsMods(infinite_cost);\n  }\n  bool hasMods() const { return this->lp_.hasMods(); }\n  void clear();\n  double objectiveValue(const std::vector<double>& solution) const;\n  void objectiveGradient(const std::vector<double>& solution,\n                         std::vector<double>& gradient) const;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/parallel/HighsBinarySemaphore.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n#ifndef HIGHS_BINARY_SEMAPHORE_H_\n#define HIGHS_BINARY_SEMAPHORE_H_\n\n#include <atomic>\n#include <chrono>\n#include <condition_variable>\n#include <mutex>\n#include <thread>\n\n#include \"parallel/HighsCacheAlign.h\"\n#include \"parallel/HighsSchedulerConstants.h\"\n#include \"parallel/HighsSpinMutex.h\"\n\nclass HighsBinarySemaphore {\n  struct Data {\n    std::atomic<int> count;\n    alignas(64) std::mutex mutex;\n    std::condition_variable condvar;\n\n    Data(int init) : count(init) {}\n  };\n\n  highs::cache_aligned::unique_ptr<Data> data_;\n\n public:\n  HighsBinarySemaphore(bool init = false)\n      : data_(highs::cache_aligned::make_unique<Data>(init)) {}\n\n  void release() {\n    int prev = data_->count.exchange(1, std::memory_order_release);\n    if (prev < 0) {\n      std::unique_lock<std::mutex> lg{data_->mutex};\n      data_->condvar.notify_one();\n    }\n  }\n\n  bool try_acquire() {\n    int expected = 1;\n    return data_->count.compare_exchange_weak(\n        expected, 0, std::memory_order_acquire, std::memory_order_relaxed);\n  }\n\n  void acquire() {\n    if (try_acquire()) return;\n\n    auto tStart = std::chrono::high_resolution_clock::now();\n    int spinIters = 10;\n    while (true) {\n      for (int i = 0; i < spinIters; ++i) {\n        if (data_->count.load(std::memory_order_relaxed) == 1) {\n          if (try_acquire()) return;\n        }\n        HighsSpinMutex::yieldProcessor();\n      }\n\n      auto numMicroSecs =\n          std::chrono::duration_cast<std::chrono::microseconds>(\n              std::chrono::high_resolution_clock::now() - tStart)\n              .count();\n\n      if (numMicroSecs < HighsSchedulerConstants::kMicroSecsBeforeSleep)\n        spinIters *= 2;\n      else\n        break;\n    }\n\n    std::unique_lock<std::mutex> lg{data_->mutex};\n    int prev = data_->count.exchange(-1, std::memory_order_relaxed);\n    if (prev == 1) {\n      data_->count.store(0, std::memory_order_relaxed);\n      return;\n    }\n\n    do {\n      data_->condvar.wait(lg);\n    } while (data_->count.load(std::memory_order_relaxed) != 1);\n\n    data_->count.store(0, std::memory_order_relaxed);\n  }\n\n  std::unique_lock<std::mutex> lockMutexForAcquire() {\n    return std::unique_lock<std::mutex>{data_->mutex};\n  }\n\n  void acquire(std::unique_lock<std::mutex> lockGuard) {\n    int prev = data_->count.exchange(-1, std::memory_order_relaxed);\n    if (prev == 1) {\n      data_->count.store(0, std::memory_order_relaxed);\n      return;\n    }\n\n    do {\n      data_->condvar.wait(lockGuard);\n    } while (data_->count.load(std::memory_order_relaxed) != 1);\n\n    data_->count.store(0, std::memory_order_relaxed);\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/parallel/HighsCacheAlign.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_CACHE_ALIGN_H_\n#define HIGHS_CACHE_ALIGN_H_\n\n#include <cstddef>\n#include <cstdint>\n#include <cstring>\n#include <memory>\n\nnamespace highs {\n\nstruct cache_aligned {\n  static constexpr std::size_t alignment() { return 64; }\n\n  static void* alloc(std::size_t size) {\n    using std::uintptr_t;\n\n    uintptr_t ptr =\n        reinterpret_cast<uintptr_t>(::operator new(size + alignment()));\n\n    char* aligned_ptr = reinterpret_cast<char*>((ptr | (alignment() - 1)) + 1);\n    std::memcpy(aligned_ptr - sizeof(uintptr_t), &ptr, sizeof(uintptr_t));\n    return reinterpret_cast<void*>(aligned_ptr);\n  }\n\n  static void free(void* aligned_ptr) {\n    using std::uintptr_t;\n\n    if (aligned_ptr) {\n      void* freeptr;\n      std::memcpy(&freeptr,\n                  reinterpret_cast<char*>(aligned_ptr) - sizeof(uintptr_t),\n                  sizeof(uintptr_t));\n      ::operator delete(freeptr);\n    }\n  }\n\n  template <typename T>\n  struct Deleter {\n    void operator()(T* ptr) const {\n      ptr->~T();\n      free(ptr);\n    }\n  };\n\n  template <typename T>\n  struct Deleter<T[]> {\n    void operator()(T* ptr) const { free(ptr); }\n  };\n\n  template <typename T>\n  using unique_ptr = std::unique_ptr<T, Deleter<T>>;\n\n  template <typename T>\n  using shared_ptr = std::shared_ptr<T>;\n\n  template <typename T, typename... Args>\n  static shared_ptr<T> make_shared(Args&&... args) {\n    return shared_ptr<T>(new (alloc(sizeof(T))) T(std::forward<Args>(args)...),\n                         Deleter<T>());\n  }\n\n  template <typename T, typename... Args>\n  static unique_ptr<T> make_unique(Args&&... args) {\n    return unique_ptr<T>(new (alloc(sizeof(T))) T(std::forward<Args>(args)...));\n  }\n\n  template <typename T, typename... Args>\n  static unique_ptr<T[]> make_unique_array(std::size_t N) {\n    return unique_ptr<T[]>(static_cast<T*>(alloc(sizeof(T) * N)));\n  }\n};\n\n}  // namespace highs\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/parallel/HighsCombinable.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n#ifndef HIGHS_COMBINABLE_H_\n#define HIGHS_COMBINABLE_H_\n\n#include <functional>\n\n#include \"parallel/HighsCacheAlign.h\"\n#include \"parallel/HighsTaskExecutor.h\"\n\ntemplate <typename T, typename FConstruct_ = std::function<T(void)>>\nclass HighsCombinable {\n  FConstruct_ construct_;\n  struct PaddedData {\n    alignas(highs::cache_aligned::alignment()) bool initialized_;\n    T data_;\n  };\n  int numThreads;\n  highs::cache_aligned::unique_ptr<PaddedData[]> threadCopies_;\n\n public:\n  HighsCombinable()\n      : construct_([]() { return T(); }),\n        numThreads(HighsTaskExecutor::getNumWorkerThreads()),\n        threadCopies_(\n            highs::cache_aligned::make_unique_array<PaddedData>(numThreads)) {\n    for (int i = 0; i < numThreads; ++i) threadCopies_[i].initialized_ = false;\n  }\n\n  template <typename FConstruct>\n  HighsCombinable(FConstruct&& fConstruct)\n      : construct_(std::forward<FConstruct>(fConstruct)),\n        numThreads(HighsTaskExecutor::getNumWorkerThreads()),\n        threadCopies_(\n            highs::cache_aligned::make_unique_array<PaddedData>(numThreads)) {\n    for (int i = 0; i < numThreads; ++i) threadCopies_[i].initialized_ = false;\n  }\n\n  HighsCombinable<T, FConstruct_>& operator=(\n      HighsCombinable<T, FConstruct_>&&) = default;\n  HighsCombinable(HighsCombinable<T, FConstruct_>&&) = default;\n\n  void clear() {\n    for (int i = 0; i < numThreads; ++i) {\n      if (threadCopies_[i].initialized_) {\n        threadCopies_[i].initialized_ = false;\n        threadCopies_[i].data_.~T();\n      }\n    }\n  }\n\n  T& local() {\n    int threadId = HighsTaskExecutor::getThisWorkerDeque()->getOwnerId();\n    if (!threadCopies_[threadId].initialized_) {\n      threadCopies_[threadId].initialized_ = true;\n      new (&threadCopies_[threadId].data_) T(construct_());\n    }\n\n    return threadCopies_[threadId].data_;\n  }\n\n  const T& local() const {\n    int threadId = HighsTaskExecutor::getThisWorkerDeque()->getOwnerId();\n    if (!threadCopies_[threadId].initialized_) {\n      threadCopies_[threadId].initialized_ = true;\n      new (&threadCopies_[threadId].data_) T(construct_());\n    }\n\n    return threadCopies_[threadId].data_;\n  }\n\n  template <typename FCombine>\n  void combine_each(FCombine&& combine) {\n    for (int i = 0; i < numThreads; ++i)\n      if (threadCopies_[i].initialized_) combine(threadCopies_[i].data_);\n  }\n\n  template <typename FCombine>\n  T combine(FCombine&& combine) {\n    T combined;\n    int i;\n    for (i = 0; i < numThreads; ++i) {\n      if (threadCopies_[i].initialized_) {\n        combined = std::move(threadCopies_[i].data_);\n        break;\n      }\n    }\n\n    for (++i; i < numThreads; ++i) {\n      if (threadCopies_[i].initialized_) {\n        combined =\n            combine(std::move(combined), std::move(threadCopies_[i].data_));\n        break;\n      }\n    }\n\n    return combined;\n  }\n\n  ~HighsCombinable() {\n    if (threadCopies_) clear();\n  }\n};\n\ntemplate <typename U, typename FConstruct>\nHighsCombinable<U, FConstruct> makeHighsCombinable(FConstruct&& fconstruct) {\n  return HighsCombinable<U, FConstruct>(std::forward<FConstruct>(fconstruct));\n}\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/parallel/HighsMutex.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n#ifndef HIGHS_MUTEX_H_\n#define HIGHS_MUTEX_H_\n\n#include \"parallel/HighsSpinMutex.h\"\n#include \"parallel/HighsTaskExecutor.h\"\n\nclass HighsMutex {\n  std::atomic<unsigned int> state{0u};\n  enum Constants { kNumSpinTries = 10 };\n\n public:\n  bool try_lock() {\n    unsigned int uncontendedState = 0;\n    return state.compare_exchange_weak(uncontendedState, 1,\n                                       std::memory_order_acquire,\n                                       std::memory_order_relaxed);\n  }\n\n  void lock() {\n    // First try to acquire the lock directly to have a fast path for\n    // uncontended access\n    if (try_lock()) return;\n\n    // Now spin a few times to check if the lock becomes available\n    for (int i = 0; i < kNumSpinTries; ++i) {\n      if (state.load(std::memory_order_relaxed) == 0) {\n        if (try_lock()) return;\n      }\n\n      HighsSpinMutex::yieldProcessor();\n    }\n\n    // Lock is still not available, so now start a loop where we yield\n    // to the scheduler after each time we observe the lock as unavailable\n    // so that we can see if there are other tasks and then check\n    // the lock again. We do so for some microseconds which we measure starting\n    // from now.\n    HighsSplitDeque* thisDeque = HighsTaskExecutor::getThisWorkerDeque();\n    auto tStart = std::chrono::high_resolution_clock::now();\n\n    while (true) {\n      int numTries = kNumSpinTries;\n\n      for (int i = 0; i < numTries; ++i) {\n        if (state.load(std::memory_order_relaxed) == 0) {\n          if (try_lock()) return;\n        }\n        thisDeque->yield();\n      }\n\n      auto numMicroSecs =\n          std::chrono::duration_cast<std::chrono::microseconds>(\n              std::chrono::high_resolution_clock::now() - tStart)\n              .count();\n\n      if (numMicroSecs < HighsSchedulerConstants::kMicroSecsBeforeGlobalSync)\n        numTries *= 2;\n      else\n        break;\n    }\n\n    // The lock is still not available, now we will try to set ourselves as the\n    // next worker to acquire the lock and start wait until we are\n    // notified by the current worker holding the lock.\n    unsigned int ownerId = (thisDeque->getOwnerId() + 1) << 1;\n    unsigned int s = state.load(std::memory_order_relaxed);\n    while (true) {\n      // as long as we observe that the lock is available we try to lock it, so\n      // that we are guaranteed to have a locked state stored within s.\n      while (s == 0)\n        if (state.compare_exchange_weak(s, 1, std::memory_order_acquire,\n                                        std::memory_order_relaxed))\n          return;\n\n      if (s & 1u) {\n        if (state.compare_exchange_weak(s, ownerId | 1,\n                                        std::memory_order_release,\n                                        std::memory_order_relaxed))\n          break;\n      } else {\n        // if we observe that the semaphore is unlocked but has its state not\n        // equal to zero it means another worker has just been notified to take\n        // the lock, but not yet taken it. Before we can set ourselves as the\n        // next worker we need to wait for its state to be in locked state.\n        HighsSpinMutex::yieldProcessor();\n        s = state.load(std::memory_order_relaxed);\n      }\n    }\n\n    // once we are here we have successfully set ourselves as the next worker\n    // and once the previous worker released the lock we will be notified. Hence\n    // we wait until a notify and then are free to acquire the lock\n    // unconditionally.\n    thisDeque->wait();\n\n    // set the state to have its locked bit set and store the previous next\n    // worker as the new next worker. As we only get here when the compare\n    // exchange in the loop above succeeds with s having its locked bit set we\n    // can simply store back s.\n    state.store(s, std::memory_order_relaxed);\n  }\n\n  void unlock() {\n    unsigned int prevState = state.fetch_add(\n        std::numeric_limits<unsigned int>::max(), std::memory_order_release);\n\n    if (prevState != 1) {\n      unsigned int notifyWorkerId = (prevState >> 1) - 1;\n      HighsTaskExecutor::getThisWorkerDeque()\n          ->getWorkerById(notifyWorkerId)\n          ->notify();\n    }\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/parallel/HighsParallel.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_PARALLEL_H_\n#define HIGHS_PARALLEL_H_\n\n#include \"parallel/HighsMutex.h\"\n#include \"parallel/HighsTaskExecutor.h\"\n\nnamespace highs {\n\nnamespace parallel {\n\nusing mutex = HighsMutex;\n\ninline void initialize_scheduler(int numThreads = 0) {\n  if (numThreads == 0) {\n#ifdef HIGHS_NO_DEFAULT_THREADS\n    numThreads = 1;\n#else\n    numThreads = (std::thread::hardware_concurrency() + 1) / 2;\n#endif\n  }\n  HighsTaskExecutor::initialize(numThreads);\n}\n\ninline int num_threads() {\n  return HighsTaskExecutor::getThisWorkerDeque()->getNumWorkers();\n}\n\ninline int thread_num() {\n  return HighsTaskExecutor::getThisWorkerDeque()->getOwnerId();\n}\n\ntemplate <typename F>\nvoid spawn(HighsSplitDeque* localDeque, F&& f) {\n  localDeque->push(std::forward<F>(f));\n}\n\ntemplate <typename F>\nvoid spawn(F&& f) {\n  spawn(HighsTaskExecutor::getThisWorkerDeque(), std::forward<F>(f));\n}\n\ninline void sync(HighsSplitDeque* localDeque) {\n  std::pair<HighsSplitDeque::Status, HighsTask*> popResult = localDeque->pop();\n  switch (popResult.first) {\n    case HighsSplitDeque::Status::kEmpty:\n      assert(false);\n      // fall through\n    case HighsSplitDeque::Status::kOverflown:\n      // when the local deque is overflown the task has been executed during\n      // spawn already\n      break;\n    case HighsSplitDeque::Status::kStolen:\n      HighsTaskExecutor::sync_stolen_task(localDeque, popResult.second);\n      break;\n    case HighsSplitDeque::Status::kWork:\n      popResult.second->run();\n  }\n}\n\ninline void sync() { sync(HighsTaskExecutor::getThisWorkerDeque()); }\nclass TaskGroup {\n  HighsSplitDeque* workerDeque;\n  int dequeHead;\n\n public:\n  TaskGroup() {\n    workerDeque = HighsTaskExecutor::getThisWorkerDeque();\n    dequeHead = workerDeque->getCurrentHead();\n  }\n\n  template <typename F>\n  void spawn(F&& f) const {\n    highs::parallel::spawn(workerDeque, std::forward<F>(f));\n  }\n\n  void sync() const {\n    assert(workerDeque->getCurrentHead() > dequeHead);\n    highs::parallel::sync(workerDeque);\n  }\n\n  void taskWait() const {\n    while (workerDeque->getCurrentHead() > dequeHead)\n      highs::parallel::sync(workerDeque);\n  }\n\n  void cancel() {\n    for (int i = dequeHead; i < workerDeque->getCurrentHead(); ++i)\n      workerDeque->cancelTask(i);\n  }\n\n  ~TaskGroup() {\n    cancel();\n    taskWait();\n  }\n};\n\ntemplate <typename F>\nvoid for_each(HighsInt start, HighsInt end, F&& f, HighsInt grainSize = 1) {\n  if (end - start <= grainSize) {\n    f(start, end);\n  } else {\n    TaskGroup tg;\n\n    do {\n      HighsInt split = (start + end) >> 1;\n      tg.spawn([split, end, grainSize, &f]() {\n        for_each(split, end, f, grainSize);\n      });\n      end = split;\n    } while (end - start > grainSize);\n\n    f(start, end);\n    tg.taskWait();\n  }\n}\n\n}  // namespace parallel\n\n}  // namespace highs\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/parallel/HighsRaceTimer.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n#ifndef HIGHS_RACE_TIMER_H_\n#define HIGHS_RACE_TIMER_H_\n\n#include <atomic>\n#include <limits>\n\ntemplate <typename T>\nclass HighsRaceTimer {\n  std::atomic<T> limit;\n\n public:\n  HighsRaceTimer() : limit(std::numeric_limits<T>::max()) {}\n\n  void decreaseLimit(T newLimit) {\n    T current = limit.load(std::memory_order_relaxed);\n\n    while (current > newLimit) {\n      if (limit.compare_exchange_weak(current, newLimit,\n                                      std::memory_order_relaxed,\n                                      std::memory_order_relaxed))\n        break;\n    }\n  }\n\n  bool limitReached(const T currentTime) const {\n    return currentTime > limit.load(std::memory_order_relaxed);\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/parallel/HighsSchedulerConstants.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_SCHEDULER_CONSTANTS_H_\n#define HIGHS_SCHEDULER_CONSTANTS_H_\n\nstruct HighsSchedulerConstants {\n  enum Constants {\n    kNumTryFac = 16,\n    kMicroSecsBeforeSleep = 5000,\n    kMicroSecsBeforeGlobalSync = 1000,\n  };\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/parallel/HighsSpinMutex.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n#ifndef HIGHS_SPIN_MUTEX_H_\n#define HIGHS_SPIN_MUTEX_H_\n\n#include <atomic>\n\n#include \"HConfig.h\"\n\n#ifdef HIGHS_HAVE_MM_PAUSE\n#include <immintrin.h>\n#else\n#include <thread>\n#endif\n\nclass HighsSpinMutex {\n  std::atomic<bool> flag{false};\n\n public:\n  static void yieldProcessor() {\n#ifdef HIGHS_HAVE_MM_PAUSE\n    _mm_pause();\n#else\n    // ToDo: See if this is OK on Mac M1\n    std::this_thread::yield();\n#endif\n  }\n\n  bool try_lock() { return !flag.exchange(true, std::memory_order_acquire); }\n\n  void lock() {\n    while (true) {\n      if (!flag.exchange(true, std::memory_order_acquire)) return;\n\n      while (flag.load(std::memory_order_relaxed)) yieldProcessor();\n    }\n  }\n\n  void unlock() { flag.store(false, std::memory_order_release); }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/parallel/HighsSplitDeque.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_SPLIT_DEQUE_H_\n#define HIGHS_SPLIT_DEQUE_H_\n\n#include <array>\n#include <atomic>\n#include <cassert>\n#include <chrono>\n#include <condition_variable>\n#include <cstddef>\n#include <mutex>\n#include <thread>\n\n#include \"parallel/HighsBinarySemaphore.h\"\n#include \"parallel/HighsCacheAlign.h\"\n#include \"parallel/HighsSpinMutex.h\"\n#include \"parallel/HighsTask.h\"\n#include \"util/HighsInt.h\"\n#include \"util/HighsRandom.h\"\n\n#ifdef __has_feature\n#if __has_feature(thread_sanitizer)\n#define TSAN_ENABLED\n#endif\n#endif\n\n#ifdef __SANITIZE_THREAD__\n#define TSAN_ENABLED\n#endif\n\n#ifdef TSAN_ENABLED\n#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) \\\n  AnnotateHappensBefore(__FILE__, __LINE__, (void*)(addr))\n#define TSAN_ANNOTATE_HAPPENS_AFTER(addr) \\\n  AnnotateHappensAfter(__FILE__, __LINE__, (void*)(addr))\nextern \"C\" void AnnotateHappensBefore(const char* f, int l, void* addr);\nextern \"C\" void AnnotateHappensAfter(const char* f, int l, void* addr);\n#else\n#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr)\n#define TSAN_ANNOTATE_HAPPENS_AFTER(addr)\n#endif\n\nclass HighsSplitDeque {\n  using cache_aligned = highs::cache_aligned;\n\n public:\n  enum Constants {\n    kTaskArraySize = 8192,\n  };\n  struct WorkerBunk;\n\n private:\n  struct OwnerData {\n    cache_aligned::shared_ptr<WorkerBunk> workerBunk = nullptr;\n    cache_aligned::unique_ptr<HighsSplitDeque>* workers = nullptr;\n    HighsRandom randgen;\n    uint32_t head = 0;\n    uint32_t splitCopy = 0;\n    int numWorkers = 0;\n    int ownerId = -1;\n    HighsTask* rootTask = nullptr;\n    bool allStolenCopy = true;\n  };\n\n  struct StealerData {\n    HighsBinarySemaphore semaphore{0};\n    HighsTask* injectedTask{nullptr};\n    std::atomic<uint64_t> ts{0};\n    std::atomic<bool> allStolen{true};\n  };\n\n  struct TaskMetadata {\n    std::atomic<HighsSplitDeque*> stealer;\n  };\n\n  static constexpr uint64_t makeTailSplit(uint32_t tail, uint32_t split) {\n    return (uint64_t(tail) << 32) | split;\n  }\n\n  static constexpr uint32_t tail(uint64_t tailSplit) { return tailSplit >> 32; }\n\n  static constexpr uint32_t split(uint64_t tailSplit) {\n    return static_cast<uint32_t>(tailSplit);\n  }\n  struct WorkerBunkData {\n    std::atomic<HighsSplitDeque*> nextSleeper{nullptr};\n    int ownerId;\n  };\n\n public:\n  struct WorkerBunk {\n    static constexpr uint64_t kAbaTagShift = 20;\n    static constexpr uint64_t kIndexMask = (uint64_t{1} << kAbaTagShift) - 1;\n    alignas(64) std::atomic<int> haveJobs;\n    alignas(64) std::atomic<uint64_t> sleeperStack;\n\n    WorkerBunk() : haveJobs{0}, sleeperStack(0) {}\n\n    void pushSleeper(HighsSplitDeque* deque) {\n      uint64_t stackState = sleeperStack.load(std::memory_order_relaxed);\n      uint64_t newStackState;\n      HighsSplitDeque* head;\n\n      do {\n        head =\n            stackState & kIndexMask\n                ? deque->ownerData.workers[(stackState & kIndexMask) - 1].get()\n                : nullptr;\n        deque->workerBunkData.nextSleeper.store(head,\n                                                std::memory_order_relaxed);\n\n        newStackState = (stackState >> kAbaTagShift) + 1;\n        newStackState = (newStackState << kAbaTagShift) |\n                        uint64_t(deque->workerBunkData.ownerId + 1);\n      } while (!sleeperStack.compare_exchange_weak(stackState, newStackState,\n                                                   std::memory_order_release,\n                                                   std::memory_order_relaxed));\n    }\n\n    HighsSplitDeque* popSleeper(HighsSplitDeque* localDeque) {\n      uint64_t stackState = sleeperStack.load(std::memory_order_relaxed);\n      HighsSplitDeque* head;\n      HighsSplitDeque* newHead;\n      uint64_t newStackState;\n\n      do {\n        if ((stackState & kIndexMask) == 0) return nullptr;\n        head =\n            localDeque->ownerData.workers[(stackState & kIndexMask) - 1].get();\n        newHead =\n            head->workerBunkData.nextSleeper.load(std::memory_order_relaxed);\n        int newHeadId =\n            newHead != nullptr ? newHead->workerBunkData.ownerId + 1 : 0;\n        newStackState = (stackState >> kAbaTagShift) + 1;\n        newStackState = (newStackState << kAbaTagShift) | uint64_t(newHeadId);\n      } while (!sleeperStack.compare_exchange_weak(stackState, newStackState,\n                                                   std::memory_order_acquire,\n                                                   std::memory_order_relaxed));\n\n      head->workerBunkData.nextSleeper.store(nullptr,\n                                             std::memory_order_relaxed);\n\n      return head;\n    }\n\n    void publishWork(HighsSplitDeque* localDeque) {\n      HighsSplitDeque* sleeper = popSleeper(localDeque);\n      while (sleeper) {\n        uint32_t t = localDeque->selfStealAndGetTail();\n        if (t == localDeque->ownerData.splitCopy) {\n          if (localDeque->ownerData.head == localDeque->ownerData.splitCopy) {\n            localDeque->ownerData.allStolenCopy = true;\n            localDeque->stealerData.allStolen.store(true,\n                                                    std::memory_order_relaxed);\n            haveJobs.fetch_add(-1, std::memory_order_release);\n          }\n          pushSleeper(sleeper);\n          return;\n        } else {\n          sleeper->injectTaskAndNotify(&localDeque->taskArray[t]);\n        }\n\n        if (t == localDeque->ownerData.splitCopy - 1) {\n          if (localDeque->ownerData.head == localDeque->ownerData.splitCopy) {\n            localDeque->ownerData.allStolenCopy = true;\n            localDeque->stealerData.allStolen.store(true,\n                                                    std::memory_order_relaxed);\n            haveJobs.fetch_add(-1, std::memory_order_release);\n          }\n          return;\n        }\n\n        sleeper = popSleeper(localDeque);\n      }\n    }\n\n    HighsTask* waitForNewTask(HighsSplitDeque* localDeque) {\n      pushSleeper(localDeque);\n      localDeque->stealerData.semaphore.acquire();\n\n      TSAN_ANNOTATE_HAPPENS_AFTER(&localDeque->stealerData.injectedTask);\n\n      return localDeque->stealerData.injectedTask;\n    }\n  };\n\n private:\n  static_assert(sizeof(OwnerData) <= 64,\n                \"sizeof(OwnerData) exceeds cache line size\");\n  static_assert(sizeof(StealerData) <= 64,\n                \"sizeof(StealerData) exceeds cache line size\");\n  static_assert(sizeof(WorkerBunkData) <= 64,\n                \"sizeof(WorkerBunkData) exceeds cache line size\");\n\n  alignas(64) OwnerData ownerData;\n  alignas(64) std::atomic<bool> splitRequest;\n  alignas(64) StealerData stealerData;\n  alignas(64) WorkerBunkData workerBunkData;\n  alignas(64) std::array<HighsTask, kTaskArraySize> taskArray;\n\n  void growShared() {\n    int haveJobs =\n        ownerData.workerBunk->haveJobs.load(std::memory_order_relaxed);\n    bool splitRq = false;\n    uint32_t newSplit;\n    if (haveJobs == ownerData.numWorkers) {\n      splitRq = splitRequest.load(std::memory_order_relaxed);\n      if (!splitRq) return;\n    }\n\n    newSplit = std::min(uint32_t{kTaskArraySize}, ownerData.head);\n\n    assert(newSplit > ownerData.splitCopy);\n\n    // we want to replace the old split point with the new splitPoint\n    // but not alter the upper 32 bits of tail.\n    // Hence with xor we can xor or the copy of the current split point\n    // to set the lower bits to zero and then xor the bits of the new split\n    // point to the lower bits that are then zero. First doing the xor of the\n    // old and new split point and then doing the xor with the stealerData\n    // will not alter the result. Also the upper 32 bits of the xor mask are\n    // zero and will therefore not alter the value of tail.\n    uint64_t xorMask = ownerData.splitCopy ^ newSplit;\n    // since we publish the task data here, we need to use\n    // std::memory_order_release which ensures all writes to set up the task\n    // are done\n    assert((xorMask >> 32) == 0);\n\n    stealerData.ts.fetch_xor(xorMask, std::memory_order_release);\n    ownerData.splitCopy = newSplit;\n    if (splitRq)\n      splitRequest.store(false, std::memory_order_relaxed);\n    else\n      ownerData.workerBunk->publishWork(this);\n  }\n\n  bool shrinkShared() {\n    uint32_t t = tail(stealerData.ts.load(std::memory_order_relaxed));\n    uint32_t s = ownerData.splitCopy;\n\n    if (t != s) {\n      ownerData.splitCopy = (t + s) / 2;\n      t = tail(stealerData.ts.fetch_add(uint64_t{ownerData.splitCopy} - s,\n                                        std::memory_order_acq_rel));\n      if (t != s) {\n        if (t > ownerData.splitCopy) {\n          ownerData.splitCopy = (t + s) / 2;\n          stealerData.ts.store(makeTailSplit(t, ownerData.splitCopy),\n                               std::memory_order_relaxed);\n        }\n\n        return false;\n      }\n    }\n\n    stealerData.allStolen.store(true, std::memory_order_relaxed);\n    ownerData.allStolenCopy = true;\n    ownerData.workerBunk->haveJobs.fetch_add(-1, std::memory_order_relaxed);\n    return true;\n  }\n\n public:\n  HighsSplitDeque(const cache_aligned::shared_ptr<WorkerBunk>& workerBunk,\n                  cache_aligned::unique_ptr<HighsSplitDeque>* workers,\n                  int ownerId, int numWorkers) {\n    ownerData.ownerId = ownerId;\n    ownerData.workers = workers;\n    ownerData.numWorkers = numWorkers;\n    workerBunkData.ownerId = ownerId;\n    ownerData.randgen.initialise(ownerId);\n    ownerData.workerBunk = workerBunk;\n    splitRequest.store(false, std::memory_order_relaxed);\n\n    assert((reinterpret_cast<uintptr_t>(this) & 63u) == 0);\n    static_assert(offsetof(HighsSplitDeque, splitRequest) == 64,\n                  \"alignas failed to guarantee 64 byte alignment\");\n    static_assert(offsetof(HighsSplitDeque, stealerData) == 128,\n                  \"alignas failed to guarantee 64 byte alignment\");\n    static_assert(offsetof(HighsSplitDeque, workerBunkData) == 192,\n                  \"alignas failed to guarantee 64 byte alignment\");\n    static_assert(offsetof(HighsSplitDeque, taskArray) == 256,\n                  \"alignas failed to guarantee 64 byte alignment\");\n  }\n\n  void checkInterrupt() {\n    if (ownerData.rootTask && ownerData.rootTask->isCancelled())\n      throw HighsTask::Interrupt();\n  }\n\n  void cancelTask(HighsInt taskIndex) {\n    assert(taskIndex < (HighsInt)ownerData.head);\n    assert(taskIndex >= 0);\n    taskArray[taskIndex].cancel();\n  }\n\n  template <typename F>\n  void push(F&& f) {\n    if (ownerData.head >= kTaskArraySize) {\n      // task queue is full, execute task directly\n      if (ownerData.splitCopy < kTaskArraySize && !ownerData.allStolenCopy)\n        growShared();\n\n      ownerData.head += 1;\n      f();\n      return;\n    }\n\n    taskArray[ownerData.head++].setTaskData(std::forward<F>(f));\n    if (ownerData.allStolenCopy) {\n      assert(ownerData.head > 0);\n      stealerData.ts.store(makeTailSplit(ownerData.head - 1, ownerData.head),\n                           std::memory_order_release);\n      stealerData.allStolen.store(false, std::memory_order_relaxed);\n      ownerData.splitCopy = ownerData.head;\n      ownerData.allStolenCopy = false;\n      if (splitRequest.load(std::memory_order_relaxed))\n        splitRequest.store(false, std::memory_order_relaxed);\n\n      int haveJobs = ownerData.workerBunk->haveJobs.fetch_add(\n          1, std::memory_order_release);\n      if (haveJobs < ownerData.numWorkers - 1)\n        ownerData.workerBunk->publishWork(this);\n    } else\n      growShared();\n  }\n\n  enum class Status {\n    kEmpty,\n    kStolen,\n    kWork,\n    kOverflown,\n  };\n\n  std::pair<Status, HighsTask*> pop() {\n    if (ownerData.head == 0) return std::make_pair(Status::kEmpty, nullptr);\n\n    if (ownerData.head > kTaskArraySize) {\n      // task queue was full and the overflown tasks have\n      // been directly executed\n      ownerData.head -= 1;\n      return std::make_pair(Status::kOverflown, nullptr);\n    }\n\n    if (ownerData.allStolenCopy)\n      return std::make_pair(Status::kStolen, &taskArray[ownerData.head - 1]);\n\n    if (ownerData.splitCopy == ownerData.head) {\n      if (shrinkShared())\n        return std::make_pair(Status::kStolen, &taskArray[ownerData.head - 1]);\n    }\n\n    ownerData.head -= 1;\n\n    if (ownerData.head == 0) {\n      if (!ownerData.allStolenCopy) {\n        ownerData.allStolenCopy = true;\n        stealerData.allStolen.store(true, std::memory_order_relaxed);\n        ownerData.workerBunk->haveJobs.fetch_add(-1, std::memory_order_release);\n      }\n    } else if (ownerData.head != ownerData.splitCopy)\n      growShared();\n\n    return std::make_pair(Status::kWork, &taskArray[ownerData.head]);\n  }\n\n  void popStolen() {\n    ownerData.head -= 1;\n    if (!ownerData.allStolenCopy) {\n      ownerData.allStolenCopy = true;\n      stealerData.allStolen.store(true, std::memory_order_relaxed);\n      ownerData.workerBunk->haveJobs.fetch_add(-1, std::memory_order_release);\n    }\n  }\n\n  HighsTask* steal() {\n    if (stealerData.allStolen.load(std::memory_order_relaxed)) return nullptr;\n\n    uint64_t ts = stealerData.ts.load(std::memory_order_relaxed);\n    uint32_t t = tail(ts);\n    uint32_t s = split(ts);\n    if (t < s) {\n      if (stealerData.ts.compare_exchange_weak(ts, makeTailSplit(t + 1, s),\n                                               std::memory_order_acquire,\n                                               std::memory_order_relaxed))\n        return &taskArray[t];\n\n      t = tail(ts);\n      s = split(ts);\n      if (t < s) {\n        return nullptr;\n      }\n    }\n\n    if (t < kTaskArraySize && !splitRequest.load(std::memory_order_relaxed))\n      splitRequest.store(true, std::memory_order_relaxed);\n\n    return nullptr;\n  }\n\n  HighsTask* stealWithRetryLoop() {\n    if (stealerData.allStolen.load(std::memory_order_relaxed)) return nullptr;\n\n    uint64_t ts = stealerData.ts.load(std::memory_order_relaxed);\n    uint32_t t = tail(ts);\n    uint32_t s = split(ts);\n\n    while (t < s) {\n      if (stealerData.ts.compare_exchange_weak(ts, makeTailSplit(t + 1, s),\n                                               std::memory_order_acquire,\n                                               std::memory_order_relaxed))\n        return &taskArray[t];\n\n      t = tail(ts);\n      s = split(ts);\n    }\n\n    if (t < kTaskArraySize && !splitRequest.load(std::memory_order_relaxed))\n      splitRequest.store(true, std::memory_order_relaxed);\n\n    return nullptr;\n  }\n\n  uint32_t selfStealAndGetTail() {\n    if (ownerData.allStolenCopy) return ownerData.splitCopy;\n\n    // when we steal from ourself we can simply do a fetch_add predictively\n    // instead of a cas loop. If the tail we read like this ends up to be\n    // above already equal to the splitPoint then we correct it with a simple\n    // store. When tail > split instead of tail == split no wrong result can\n    // occur as long as we know that the task at taskArray[split] is not\n    // actually considered to be stolen and tail is corrected before the owner\n    // enters shrinkShared.\n\n    uint32_t t = tail(stealerData.ts.fetch_add(makeTailSplit(1, 0),\n                                               std::memory_order_relaxed));\n\n    if (t == ownerData.splitCopy)\n      stealerData.ts.store(makeTailSplit(t, ownerData.splitCopy),\n                           std::memory_order_relaxed);\n\n    return t;\n  }\n\n  HighsTask* randomSteal() {\n    HighsInt next = ownerData.randgen.integer(ownerData.numWorkers - 1);\n    next += next >= ownerData.ownerId;\n    assert(next != ownerData.ownerId);\n    assert(next >= 0);\n    assert(next < ownerData.numWorkers);\n\n    return ownerData.workers[next]->steal();\n  }\n\n  void injectTaskAndNotify(HighsTask* t) {\n    stealerData.injectedTask = t;\n\n    TSAN_ANNOTATE_HAPPENS_BEFORE(&stealerData.injectedTask);\n\n    stealerData.semaphore.release();\n  }\n\n  void notify() { stealerData.semaphore.release(); }\n\n  /// wait until notified\n  void wait() { stealerData.semaphore.acquire(); }\n\n  void runStolenTask(HighsTask* task) {\n    HighsTask* prevRootTask = ownerData.rootTask;\n    ownerData.rootTask = task;\n    uint32_t currentHead = ownerData.head;\n    try {\n      HighsSplitDeque* owner = task->run(this);\n      if (owner) owner->notify();\n    } catch (const HighsTask::Interrupt&) {\n      // in case the task was interrupted we unwind and cancel all subtasks of\n      // the stolen task\n\n      // first cancel all tasks\n      for (uint32_t i = currentHead; i < ownerData.head; ++i)\n        taskArray[i].cancel();\n\n      // now remove them from our deque so that we arrive at the original state\n      // before the stolen task was executed\n      while (ownerData.head != currentHead) {\n        std::pair<Status, HighsTask*> popResult = pop();\n        assert(popResult.first != Status::kEmpty);\n        // if the task was not stolen it would be up to this worker to execute\n        // it now and we simply skip its execution as it is cancelled\n        if (popResult.first != Status::kStolen) continue;\n\n        // The task was stolen. Check if the stealer is already finished with\n        // its execution in which case we just remove it from the deque.\n        HighsSplitDeque* stealer = popResult.second->getStealerIfUnfinished();\n        if (stealer == nullptr) {\n          popStolen();\n          continue;\n        }\n\n        // The task was stolen and the stealer is still executing the task.\n        // We now wait in a spin loop until the task is marked as finished for\n        // some time. We do not proceed with stealing other tasks as when there\n        // is a cancelled task the likelihood of that task being cancelled too\n        // might be high and our priority is to finish unwinding the chain of\n        // cancelled tasks as fast as possible.\n        // When the spinning proceeds for too long we request a notification\n        // from the stealer when it is finished and yield control to the\n        // operating system until then.\n        int numTries = HighsSchedulerConstants::kNumTryFac;\n        auto tStart = std::chrono::high_resolution_clock::now();\n\n        bool isFinished = popResult.second->isFinished();\n\n        while (!isFinished) {\n          for (int i = 0; i < numTries; ++i) {\n            HighsSpinMutex::yieldProcessor();\n            isFinished = popResult.second->isFinished();\n            if (isFinished) break;\n          }\n\n          if (!isFinished) {\n            auto numMicroSecs =\n                std::chrono::duration_cast<std::chrono::microseconds>(\n                    std::chrono::high_resolution_clock::now() - tStart)\n                    .count();\n\n            if (numMicroSecs < HighsSchedulerConstants::kMicroSecsBeforeSleep)\n              numTries *= 2;\n            else {\n              waitForTaskToFinish(popResult.second, stealer);\n              break;\n            }\n          }\n        }\n\n        // the task is finished and we can safely proceed to unwind to the next\n        // task\n        popStolen();\n      }\n\n      // unwinding is finished for all subtasks and we can mark the task as\n      // finished and then notify the owner if it is waiting for a signal\n      HighsSplitDeque* owner = task->markAsFinished(this);\n      if (owner) owner->notify();\n    }\n\n    ownerData.rootTask = prevRootTask;\n    checkInterrupt();\n  }\n\n  // steal from the stealer until this task is finished or no more work can be\n  // stolen from the stealer. If the task is finished then true is returned,\n  // otherwise false is returned\n  bool leapfrogStolenTask(HighsTask* task, HighsSplitDeque*& stealer) {\n    bool cancelled;\n    stealer = task->getStealerIfUnfinished(&cancelled);\n\n    if (stealer == nullptr) return true;\n\n    if (!cancelled) {\n      do {\n        HighsTask* t = stealer->stealWithRetryLoop();\n        if (t == nullptr) break;\n        runStolenTask(t);\n      } while (!task->isFinished());\n    }\n\n    return task->isFinished();\n  }\n\n  void waitForTaskToFinish(HighsTask* t, HighsSplitDeque* stealer) {\n    std::unique_lock<std::mutex> lg =\n        stealerData.semaphore.lockMutexForAcquire();\n    // exchange the value stored in stealer with the pointer to owner\n    // so that the stealer will see this pointer instead of nullptr\n    // when it stores whether the task is finished. In that case the\n    // stealer will additionally acquire the wait mutex and signal the owner\n    // thread that the task is finished\n\n    if (!t->requestNotifyWhenFinished(this, stealer)) return;\n\n    stealerData.semaphore.acquire(std::move(lg));\n  }\n\n  void yield() {\n    HighsTask* t = randomSteal();\n    if (t) runStolenTask(t);\n  }\n\n  int getOwnerId() const { return ownerData.ownerId; }\n\n  int getNumWorkers() const { return ownerData.numWorkers; }\n\n  int getCurrentHead() const { return ownerData.head; }\n\n  HighsSplitDeque* getWorkerById(int id) const {\n    return ownerData.workers[id].get();\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/parallel/HighsTask.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_TASK_H_\n#define HIGHS_TASK_H_\n\n#include <atomic>\n#include <cassert>\n#include <cstring>\n#include <type_traits>\n\n#include \"parallel/HighsSpinMutex.h\"\n\nclass HighsSplitDeque;\n\nclass HighsTask {\n  friend class HighsSplitDeque;\n\n public:\n  enum Constants {\n    kMaxTaskSize = 64,\n  };\n\n  class Interrupt {};\n\n private:\n  static constexpr uint64_t kFinishedFlag = 1;\n  static constexpr uint64_t kCancelFlag = 2;\n  static constexpr uint64_t kPtrMask = ~(kFinishedFlag | kCancelFlag);\n  struct Metadata {\n    std::atomic<uintptr_t> stealer;\n  };\n\n  class CallableBase {\n   public:\n    virtual void operator()() = 0;\n  };\n\n  template <typename F>\n  class Callable : public CallableBase {\n    F functor;\n\n   public:\n    Callable(F&& functor) : functor(std::forward<F>(functor)) {}\n\n    virtual void operator()() override {\n      F callFunctor = std::move(functor);\n      callFunctor();\n    }\n  };\n\n  char taskData[kMaxTaskSize - sizeof(Metadata)];\n  Metadata metadata;\n\n  CallableBase& getCallable() {\n    union {\n      CallableBase* callablePtr;\n      char* storagePtr;\n    } u;\n\n    u.storagePtr = this->taskData;\n    return *u.callablePtr;\n  }\n\n  HighsSplitDeque* markAsFinished(HighsSplitDeque* stealer) {\n    uintptr_t state =\n        metadata.stealer.exchange(kFinishedFlag, std::memory_order_release);\n    HighsSplitDeque* waitingOwner =\n        reinterpret_cast<HighsSplitDeque*>(state & kPtrMask);\n    if (waitingOwner != stealer) return waitingOwner;\n\n    return nullptr;\n  }\n\n  /// run task as stealer and return the owner's split deque if the owner is\n  /// waiting and needs to be signaled\n  HighsSplitDeque* run(HighsSplitDeque* stealer) {\n    uintptr_t state = metadata.stealer.fetch_or(\n        reinterpret_cast<uintptr_t>(stealer), std::memory_order_acquire);\n    if (state == 0) getCallable()();\n\n    return markAsFinished(stealer);\n  }\n\n public:\n  /// initialize the task with given callable type. Task is considered\n  /// unfinished after setTaskData\n  template <typename F>\n  void setTaskData(F&& f) {\n    static_assert(sizeof(F) <= sizeof(taskData),\n                  \"given task type exceeds maximum size allowed for deque\\n\");\n    static_assert(std::is_trivially_destructible<F>::value,\n                  \"given task type must be trivially destructible\\n\");\n    metadata.stealer.store(0, std::memory_order_relaxed);\n\n    new (taskData) Callable<F>(std::forward<F>(f));\n\n    assert(static_cast<CallableBase*>(reinterpret_cast<Callable<F>*>(\n               taskData)) == reinterpret_cast<CallableBase*>(taskData));\n  }\n\n  void cancel() {\n    metadata.stealer.fetch_or(kCancelFlag, std::memory_order_release);\n  }\n\n  /// run task as owner, if not cancelled\n  void run() {\n    if (metadata.stealer.load(std::memory_order_relaxed) == 0) getCallable()();\n  }\n\n  /// request notification of the owner when the task is finished.\n  /// Should be called while the owner holds its wait mutex\n  /// and only after getStealerIfUnfinished() has been called.\n  /// Returns true if the notification was set and false if it was not set\n  /// because the task was finished in the meantime.\n  bool requestNotifyWhenFinished(HighsSplitDeque* owner,\n                                 HighsSplitDeque* stealer) {\n    uintptr_t xormask = reinterpret_cast<uintptr_t>(owner) ^\n                        reinterpret_cast<uintptr_t>(stealer);\n    uintptr_t state =\n        metadata.stealer.fetch_xor(xormask, std::memory_order_relaxed);\n\n    assert(stealer != nullptr);\n\n    return (state & kFinishedFlag) == 0;\n  }\n\n  /// check if task is finished\n  bool isFinished() const {\n    uintptr_t state = metadata.stealer.load(std::memory_order_acquire);\n    return state & kFinishedFlag;\n  }\n\n  /// check if task is cancelled\n  bool isCancelled() const {\n    uintptr_t state = metadata.stealer.load(std::memory_order_relaxed);\n    return state & kCancelFlag;\n  }\n\n  /// get the stealer of a stolen task, or nullptr if the stealer finished\n  /// executing the task. Spin waits for the stealer to have started executing\n  /// the task if necessary.\n  HighsSplitDeque* getStealerIfUnfinished(bool* cancelled = nullptr) {\n    uintptr_t state = metadata.stealer.load(std::memory_order_acquire);\n    if (state & kFinishedFlag)\n      return nullptr;\n    else {\n      while ((state & ~kCancelFlag) == 0) {\n        // the task has been stolen, but the stealer has not yet started\n        // executing the task in this case, yield and check again in a spin\n        // loop until the stealer executes the task and becomes visible to\n        // this thread\n        HighsSpinMutex::yieldProcessor();\n        state = metadata.stealer.load(std::memory_order_acquire);\n      }\n    }\n\n    if (state & kFinishedFlag) return nullptr;\n\n    if (cancelled) *cancelled = state & kCancelFlag;\n\n    return reinterpret_cast<HighsSplitDeque*>(state & kPtrMask);\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/parallel/HighsTaskExecutor.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_TASKEXECUTOR_H_\n#define HIGHS_TASKEXECUTOR_H_\n\n#include <cassert>\n#include <chrono>\n#include <condition_variable>\n#include <memory>\n#include <thread>\n#include <vector>\n\n#include \"parallel/HighsCacheAlign.h\"\n#include \"parallel/HighsSchedulerConstants.h\"\n#include \"parallel/HighsSplitDeque.h\"\n#include \"util/HighsInt.h\"\n#include \"util/HighsRandom.h\"\n\nclass HighsTaskExecutor {\n public:\n  using cache_aligned = highs::cache_aligned;\n  struct ExecutorHandle {\n    HighsTaskExecutor* ptr{nullptr};\n    bool isMain{false};\n\n    void dispose();\n    ~ExecutorHandle() { dispose(); }\n  };\n\n private:\n#ifdef _WIN32\n  static HighsSplitDeque*& threadLocalWorkerDeque();\n  static ExecutorHandle& threadLocalExecutorHandle();\n#else\n  static thread_local HighsSplitDeque* threadLocalWorkerDequePtr;\n  static thread_local ExecutorHandle globalExecutorHandle;\n\n  static HighsSplitDeque*& threadLocalWorkerDeque() {\n    return threadLocalWorkerDequePtr;\n  }\n\n  static ExecutorHandle& threadLocalExecutorHandle() {\n    return globalExecutorHandle;\n  }\n#endif\n\n  std::atomic<int> referenceCount;\n  std::atomic<bool> hasStopped{false};\n\n  cache_aligned::shared_ptr<HighsSplitDeque::WorkerBunk> workerBunk;\n  std::vector<cache_aligned::unique_ptr<HighsSplitDeque>> workerDeques;\n  std::vector<std::thread> workerThreads;\n\n  HighsTask* random_steal_loop(HighsSplitDeque* localDeque) {\n    const int numWorkers = static_cast<int>(workerDeques.size());\n\n    int numTries = 16 * (numWorkers - 1);\n\n    auto tStart = std::chrono::high_resolution_clock::now();\n\n    while (true) {\n      for (int s = 0; s < numTries; ++s) {\n        HighsTask* task = localDeque->randomSteal();\n        if (task) return task;\n      }\n\n      if (!workerBunk->haveJobs.load(std::memory_order_relaxed)) break;\n\n      auto numMicroSecs =\n          std::chrono::duration_cast<std::chrono::microseconds>(\n              std::chrono::high_resolution_clock::now() - tStart)\n              .count();\n\n      if (numMicroSecs < HighsSchedulerConstants::kMicroSecsBeforeGlobalSync)\n        numTries *= 2;\n      else\n        break;\n    }\n\n    return nullptr;\n  }\n\n  static void run_worker(int workerId, HighsTaskExecutor* ptr) {\n    auto& executorHandle = threadLocalExecutorHandle();\n    executorHandle.ptr = ptr;\n\n    if (!ptr->hasStopped) {\n      HighsSplitDeque* localDeque = ptr->workerDeques[workerId].get();\n      threadLocalWorkerDeque() = localDeque;\n\n      HighsTask* currentTask = ptr->workerBunk->waitForNewTask(localDeque);\n      while (currentTask != nullptr) {\n        localDeque->runStolenTask(currentTask);\n\n        currentTask = ptr->random_steal_loop(localDeque);\n        if (currentTask != nullptr) continue;\n\n        currentTask = ptr->workerBunk->waitForNewTask(localDeque);\n      }\n    }\n\n    executorHandle.dispose();\n  }\n\n public:\n  HighsTaskExecutor(int numThreads) {\n    assert(numThreads > 0);\n\n    workerDeques.resize(numThreads);\n    workerBunk = cache_aligned::make_shared<HighsSplitDeque::WorkerBunk>();\n    for (int i = 0; i < numThreads; ++i)\n      workerDeques[i] = cache_aligned::make_unique<HighsSplitDeque>(\n          workerBunk, workerDeques.data(), i, numThreads);\n\n    threadLocalWorkerDeque() = workerDeques[0].get();\n    workerThreads.reserve(numThreads - 1);\n    referenceCount.store(numThreads);\n\n    for (int i = 1, numThreads = static_cast<int>(workerDeques.size());\n         i < numThreads; ++i) {\n      workerThreads.emplace_back(&HighsTaskExecutor::run_worker, i, this);\n    }\n  }\n\n  void stopWorkerThreads(bool blocking = false) {\n    // Check if stop has been called already.\n    auto& executorHandle = threadLocalExecutorHandle();\n    if (executorHandle.ptr == nullptr || hasStopped.exchange(true)) return;\n\n    // now inject the null task as termination signal to every worker\n    for (auto& workerDeque : workerDeques) {\n      workerDeque->injectTaskAndNotify(nullptr);\n    }\n\n    // only block if called on main thread, otherwise deadlock may occur\n    if (blocking && executorHandle.isMain) {\n      for (auto& workerThread : workerThreads) {\n        workerThread.join();\n      }\n    } else {\n      for (auto& workerThread : workerThreads) {\n        workerThread.detach();\n      }\n    }\n  }\n\n  static HighsSplitDeque* getThisWorkerDeque() {\n    return threadLocalWorkerDeque();\n  }\n\n  static int getNumWorkerThreads() {\n    return threadLocalWorkerDeque()->getNumWorkers();\n  }\n\n  static void initialize(int numThreads) {\n    auto& executorHandle = threadLocalExecutorHandle();\n    if (executorHandle.ptr == nullptr) {\n      executorHandle.isMain = true;\n      executorHandle.ptr = new (cache_aligned::alloc(sizeof(HighsTaskExecutor)))\n          HighsTaskExecutor(numThreads);\n    }\n  }\n\n  // can be called on main or worker threads\n  // blocking ignored unless called on main thread\n  static void shutdown(bool blocking = false) {\n    auto& executorHandle = threadLocalExecutorHandle();\n\n    if (executorHandle.ptr != nullptr) {\n      executorHandle.ptr->stopWorkerThreads(blocking);\n      executorHandle.dispose();\n    }\n  }\n\n  static void sync_stolen_task(HighsSplitDeque* localDeque,\n                               HighsTask* stolenTask) {\n    HighsSplitDeque* stealer;\n    if (!localDeque->leapfrogStolenTask(stolenTask, stealer)) {\n      const int numWorkers = localDeque->getNumWorkers();\n      int numTries = HighsSchedulerConstants::kNumTryFac * (numWorkers - 1);\n\n      auto tStart = std::chrono::high_resolution_clock::now();\n\n      while (true) {\n        for (int s = 0; s < numTries; ++s) {\n          if (stolenTask->isFinished()) {\n            localDeque->popStolen();\n            return;\n          }\n          localDeque->yield();\n        }\n\n        auto numMicroSecs =\n            std::chrono::duration_cast<std::chrono::microseconds>(\n                std::chrono::high_resolution_clock::now() - tStart)\n                .count();\n\n        if (numMicroSecs < HighsSchedulerConstants::kMicroSecsBeforeSleep)\n          numTries *= 2;\n        else\n          break;\n      }\n\n      if (!stolenTask->isFinished())\n        localDeque->waitForTaskToFinish(stolenTask, stealer);\n    }\n\n    localDeque->popStolen();\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/pdlp/CupdlpWrapper.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file pdlp/CupdlpWrapper.h\n * @brief\n */\n#ifndef PDLP_CUPDLP_WRAPPER_H_\n#define PDLP_CUPDLP_WRAPPER_H_\n\n#include <algorithm>\n#include <cassert>\n\n#include \"lp_data/HighsSolution.h\"\n#include \"pdlp/cupdlp/cupdlp.h\"\n\n#ifdef CUPDLP_GPU\n#include <cuda_runtime.h>\n#endif\n\n// #define CUPDLP_CPP_INIT(var, type, size)                                \\\n//   {                                                                     \\\n//     (var) = (type *)malloc((size) * sizeof(type));                      \\\n//     if ((var) == NULL) {                                                \\\n//       retcode = 1;                                                      \\\n//       goto exit_cleanup;                                                \\\n//     }                                                                   \\\n//   }\n\ntypedef enum CONSTRAINT_TYPE { EQ = 0, LEQ, GEQ, BOUND } constraint_type;\n\n#define cupdlp_init_int(var, size) \\\n  { (var) = (int*)malloc((size) * sizeof(int)); }\n\n#define cupdlp_init_double(var, size) \\\n  { (var) = (double*)malloc((size) * sizeof(double)); }\n\n#define cupdlp_init_work(var, size) \\\n  { (var) = (CUPDLPwork*)malloc((size) * sizeof(CUPDLPwork)); }\n\n#define cupdlp_init_problem(var, size) \\\n  { (var) = (CUPDLPproblem*)malloc((size) * sizeof(CUPDLPproblem)); }\n\n#define cupdlp_init_data(var, size) \\\n  { (var) = (CUPDLPdata*)malloc((size) * sizeof(CUPDLPdata)); }\n\n#ifdef CUPDLP_CPU\n\n#define cupdlp_init_vec_double(var, size) \\\n  { (var) = (double*)malloc((size) * sizeof(double)); }\n\n#define cupdlp_copy_vec(dst, src, type, size) \\\n  memcpy(dst, src, sizeof(type) * (size))\n\n#endif\n\n//#define cupdlp_init_csc_cpu(var, size)\t\\\n//   {\\\n//     (var) = (CUPDLPcsc*)malloc((size) * sizeof(CUPDLPcsc));\\\n//   }\n\ncupdlp_retcode problem_create(CUPDLPproblem** prob);\n// cupdlp_retcode csc_create(CUPDLPcsc **csc_cpu);\n\ncupdlp_retcode problem_alloc(\n    CUPDLPproblem* prob, cupdlp_int nRows, cupdlp_int nCols, cupdlp_int nEqs,\n    cupdlp_float* cost, cupdlp_float offset, cupdlp_float sign_origin,\n    void* matrix, CUPDLP_MATRIX_FORMAT src_matrix_format,\n    CUPDLP_MATRIX_FORMAT dst_matrix_format, cupdlp_float* rhs,\n    cupdlp_float* lower, cupdlp_float* upper, cupdlp_float* alloc_matrix_time,\n    cupdlp_float* copy_vec_time);\n\ncupdlp_retcode data_alloc(CUPDLPdata* data, cupdlp_int nRows, cupdlp_int nCols,\n                          void* matrix, CUPDLP_MATRIX_FORMAT src_matrix_format,\n                          CUPDLP_MATRIX_FORMAT dst_matrix_format);\n\ndouble infNorm(double* x, cupdlp_int n);\n\nvoid cupdlp_hasLower(cupdlp_float* haslb, const cupdlp_float* lb,\n                     const cupdlp_float bound, const cupdlp_int len);\n\nvoid cupdlp_hasUpper(cupdlp_float* hasub, const cupdlp_float* ub,\n                     const cupdlp_float bound, const cupdlp_int len);\n\nvoid cupdlp_haslb(cupdlp_float* haslb, const cupdlp_float* lb,\n                  const cupdlp_float bound, const cupdlp_int len);\n\nvoid cupdlp_hasub(cupdlp_float* hasub, const cupdlp_float* ub,\n                  const cupdlp_float bound, const cupdlp_int len);\n\nHighsStatus solveLpCupdlp(HighsLpSolverObject& solver_object);\n\nHighsStatus solveLpCupdlp(const HighsOptions& options, HighsTimer& timer,\n                          const HighsLp& lp, HighsBasis& highs_basis,\n                          HighsSolution& highs_solution,\n                          HighsModelStatus& model_status, HighsInfo& highs_info,\n                          HighsCallback& callback);\nint formulateLP_highs(const cupdlp_int local_log_level, const HighsLp& lp,\n                      double** cost, int* nCols, int* nRows, int* nnz,\n                      int* nEqs, int** csc_beg, int** csc_idx, double** csc_val,\n                      double** rhs, double** lower, double** upper,\n                      double* offset, double* sign_origin, int* nCols_origin,\n                      int** constraint_new_idx, int** constraint_type);\n\ncupdlp_int getCupdlpLogLevel(const HighsOptions& options);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/pdlp/cupdlp/cupdlp_cs.h",
    "content": "#ifndef CUPDLP_CS_H\n#define CUPDLP_CS_H\n\n#include \"pdlp/cupdlp/cupdlp_defs.h\"\n\n/* sparse matrix in column-oriented form used in reading mps*/\ntypedef struct cupdlp_cs_sparse {\n  int nzmax;\n  int m;     /* number of rows */\n  int n;     /* number of columns */\n  int *p;    /* column pointers (size n+1) or col indices (size nzmax) */\n  int *i;    /* row indices, size nzmax */\n  double *x; /* numerical values, size nzmax */\n  int nz;    /* # of entries in triplet matrix, -1 for compressed-col */\n} cupdlp_dcs;\n\nint cupdlp_dcs_entry(cupdlp_dcs *T, int i, int j, double x);\ncupdlp_dcs *cupdlp_dcs_compress(const cupdlp_dcs *T);\ndouble cupdlp_dcs_norm(const cupdlp_dcs *A);\nint cupdlp_dcs_print(const cupdlp_dcs *A, int brief);\n\n/* utilities */\nvoid *cupdlp_dcs_calloc(int n, size_t size);\nvoid *cupdlp_dcs_free(void *p);\nvoid *cupdlp_dcs_realloc(void *p, int n, size_t size, int *ok);\ncupdlp_dcs *cupdlp_dcs_spalloc(int m, int n, int nzmax, int values, int t);\ncupdlp_dcs *cupdlp_dcs_spfree(cupdlp_dcs *A);\nint cupdlp_dcs_sprealloc(cupdlp_dcs *A, int nzmax);\nvoid *cupdlp_dcs_malloc(int n, size_t size);\n\n/* utilities */\ndouble cupdlp_dcs_cumsum(int *p, int *c, int n);\ncupdlp_dcs *cupdlp_dcs_done(cupdlp_dcs *C, void *w, void *x, int ok);\ncupdlp_dcs *cupdlp_dcs_transpose(const cupdlp_dcs *A, int values);\n\n#define IS_CSC(A) (A && (A->nz == -1))\n#define IS_TRIPLET(A) (A && (A->nz >= 0))\n/*--------------------------------------------------------------------------*/\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/pdlp/cupdlp/cupdlp_defs.h",
    "content": "#ifndef CUPDLP_H_GUARD\n#define CUPDLP_H_GUARD\n\n// The below already defined in CMake.\n// #define CUPDLP_CPU\n// #define CUPDLP_DEBUG (1)\n#define CUPDLP_TIMER\n\n#include \"HConfig.h\"\n\n#ifdef CUPDLP_GPU\n#include \"cuda/cupdlp_cuda_kernels.cuh\"\n#include \"cuda/cupdlp_cudalinalg.cuh\"\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <math.h>\n#include <string.h>\n\n#include \"glbopts.h\"\n\n#define PDHG_USE_TIMERS (1)\n#define USE_MY_BLAS (1)\n#define USE_KERNELS (1)\n\n#define PDHG_STEPSIZE_REDUCTION_EXP \\\n  (0.3)  // Parameters in PDLP adaptive linesearch\n#define PDHG_STEPSIZE_GROWTH_EXP (0.6)\n#define PDHG_USE_TIMERS (1)\n#define PDHG_DISPLAY_TERMINATION_CHECK (1)\n\n#define PDHG_PROJECT_INITIAL_X (0)\n#define SHOW_DEFINE(x) printf(\"%s=%s\\n\", #x, STR(x))\n\n#define CUPDLP_DEBUG_INTERVAL (40)\n#define CUPDLP_RELEASE_INTERVAL (40)\n#define CUPDLP_DUMP_ITERATES_STATS (1)\n#define CUPDLP_DUMP_LINESEARCH_STATS (1)\n#define CUPDLP_INEXACT_EPS (1e-4)\n\ntypedef struct CUPDLP_CUDA_DENSE_VEC CUPDLPvec;\ntypedef struct CUPDLP_DENSE_MATRIX CUPDLPdense;\ntypedef struct CUPDLP_CSR_MATRIX CUPDLPcsr;\ntypedef struct CUPDLP_CSC_MATRIX CUPDLPcsc;\ntypedef struct CUPDLP_DATA CUPDLPdata;\ntypedef struct CUPDLP_SETTINGS CUPDLPsettings;\ntypedef struct CUPDLP_PROBLEM CUPDLPproblem;\ntypedef struct CUPDLP_RES_OBJ CUPDLPresobj;\ntypedef struct CUPDLP_ITERATES CUPDLPiterates;\ntypedef struct CUPDLP_STEPSIZE CUPDLPstepsize;\ntypedef struct CUPDLP_SCALING CUPDLPscaling;\ntypedef struct CUPDLP_TIMERS CUPDLPtimers;\ntypedef struct CUPDLP_WORK CUPDLPwork;\ntypedef cupdlp_int cupdlp_retcode;\n\ntypedef enum {\n  OPTIMAL = 0,\n  INFEASIBLE,\n  UNBOUNDED,\n  INFEASIBLE_OR_UNBOUNDED,\n  TIMELIMIT_OR_ITERLIMIT,\n  FEASIBLE,\n} termination_code;\n\ntypedef enum {\n  LAST_ITERATE = 0,\n  AVERAGE_ITERATE,\n} termination_iterate;\n\ntypedef enum {\n  PDHG_FIXED_LINESEARCH = 0,\n  PDHG_MALITSKY_POCK_LINESEARCH,\n  PDHG_ADAPTIVE_LINESEARCH\n} pdhg_linesearch;\n\ntypedef enum {\n  PDHG_WITHOUT_RESTART = 0,\n  PDHG_GPU_RESTART,\n  PDHG_CPU_RESTART,\n} pdhg_restart;\n\ntypedef enum {\n  CPU = 0,\n  SINGLE_GPU,\n  MULTI_GPU,\n} CUPDLP_DEVICE;\n\ntypedef enum {\n  DENSE = 0,\n  CSR,\n  CSC,\n  CSR_CSC,\n} CUPDLP_MATRIX_FORMAT;\n\ntypedef enum {\n  N_ITER_LIM = 0,\n  IF_SCALING,\n  I_SCALING_METHOD,\n  E_LINE_SEARCH_METHOD,\n  E_RESTART_METHOD,\n  IF_RUIZ_SCALING,\n  IF_L2_SCALING,\n  IF_PC_SCALING,\n  N_LOG_LEVEL,\n  N_LOG_INTERVAL,\n  IF_PRESOLVE,\n  I_INF_NORM_ABS_LOCAL_TERMINATION,\n  N_INT_USER_PARAM\n} CUPDLP_INT_USER_PARAM_INDEX;\n  //#define N_INT_USER_PARAM 12\ntypedef enum {\n  D_SCALING_LIMIT = 0,\n  D_PRIMAL_TOL,\n  D_DUAL_TOL,\n  D_GAP_TOL,\n  D_FEAS_TOL,\n  D_TIME_LIM,\n  N_FLOAT_USER_PARAM\n} CUPDLP_FLOAT_USER_PARAM_INDEX;\n  //#define N_FLOAT_USER_PARAM 6\n\n// used in sparse matrix-dense vector multiplication\nstruct CUPDLP_CUDA_DENSE_VEC {\n  cupdlp_int len;\n  cupdlp_float *data;\n#ifndef CUPDLP_CPU\n  cusparseDnVecDescr_t cuda_vec;\n#endif\n};\n\nstruct CUPDLP_DENSE_MATRIX {\n  cupdlp_int nRows;\n  cupdlp_int nCols;\n  cupdlp_float *data;\n};\n\nstruct CUPDLP_CSR_MATRIX {\n  cupdlp_int nRows;\n  cupdlp_int nCols;\n  cupdlp_int nMatElem;\n  cupdlp_int *rowMatBeg;\n  cupdlp_int *rowMatIdx;\n  cupdlp_float *rowMatElem;\n#ifndef CUPDLP_CPU\n  // Pointers to GPU vectors\n  cusparseSpMatDescr_t cuda_csr;\n#endif\n};\n\nstruct CUPDLP_CSC_MATRIX {\n  cupdlp_int nRows;\n  cupdlp_int nCols;\n  cupdlp_int nMatElem;\n  cupdlp_int *colMatBeg;\n  cupdlp_int *colMatIdx;\n  cupdlp_float *colMatElem;\n\n  // Used to avoid implementing NormInf on cuda\n  cupdlp_float MatElemNormInf;\n#ifndef CUPDLP_CPU\n  // Pointers to GPU vectors\n  cusparseSpMatDescr_t cuda_csc;\n#endif\n};\n\nstruct CUPDLP_DATA {\n  cupdlp_int nRows;\n  cupdlp_int nCols;\n  CUPDLP_MATRIX_FORMAT matrix_format;\n  CUPDLPdense *dense_matrix;\n  CUPDLPcsr *csr_matrix;\n  CUPDLPcsc *csc_matrix;\n  CUPDLP_DEVICE device;\n};\n\nstruct CUPDLP_SETTINGS {\n  // scaling\n  cupdlp_int ifScaling;\n  cupdlp_int iScalingMethod;\n  cupdlp_float dScalingLimit;\n\n  // termination criteria\n  cupdlp_float dPrimalTol;\n  cupdlp_float dDualTol;\n  cupdlp_float dGapTol;\n\n  // max iter and time\n  cupdlp_int nIterLim;\n  cupdlp_float dTimeLim;\n\n  // Logging\n  cupdlp_int nLogLevel;\n  cupdlp_int nLogInterval;\n\n  // restart\n  pdhg_restart eRestartMethod;\n};\n\n// some elements are duplicated from CUPDLP_DATA\nstruct CUPDLP_PROBLEM {\n  /* Copy of LP problem with permuted columns. */\n  CUPDLPdata *data;\n  // cupdlp_int nMatElem;\n  // cupdlp_int *colMatBeg;\n  // cupdlp_int *colMatIdx;\n  // cupdlp_float *colMatElem;\n  // cupdlp_int *rowMatBeg;\n  // cupdlp_int *rowMatIdx;\n  // cupdlp_float *rowMatElem;\n  cupdlp_float *lower;\n  cupdlp_float *upper;\n  cupdlp_float *cost;  // cost for minimization\n  cupdlp_float *rhs;\n  cupdlp_float dMaxCost;\n  cupdlp_float dMaxRhs;\n  cupdlp_float dMaxRowBound;\n  cupdlp_int nRows;\n  cupdlp_int nCols;\n  cupdlp_int nEqs;\n  cupdlp_float *hasLower;\n  cupdlp_float *hasUpper;\n  cupdlp_float\n      offset;  // true objVal = c'x * sig + offset, sig = 1 (min) or -1 (max)\n  cupdlp_float sense_origin;  // sig = 1 (min) or -1 (max)\n};\n\nstruct CUPDLP_RES_OBJ {\n  /* residuals and objectives */\n  cupdlp_float dFeasTol;\n  cupdlp_float dPrimalObj;\n  cupdlp_float dDualObj;\n  cupdlp_float dDualityGap;\n  cupdlp_float dComplementarity;\n  cupdlp_float dPrimalFeas;\n  cupdlp_float dDualFeas;\n  cupdlp_float dRelObjGap;\n  cupdlp_float *primalResidual;\n  cupdlp_float *dualResidual;\n  cupdlp_float *dSlackPos;\n  cupdlp_float *dSlackNeg;\n  cupdlp_float *dSlackPosAverage;\n  cupdlp_float *dSlackNegAverage;\n  cupdlp_float *dLowerFiltered;\n  cupdlp_float *dUpperFiltered;\n\n  /* for infeasibility detection */\n  termination_code primalCode;\n  termination_code dualCode;\n  termination_iterate termInfeasIterate;\n\n  cupdlp_float dPrimalInfeasObj;\n  cupdlp_float dDualInfeasObj;\n  cupdlp_float dPrimalInfeasRes;\n  cupdlp_float dDualInfeasRes;\n\n  cupdlp_float dPrimalInfeasObjAverage;\n  cupdlp_float dDualInfeasObjAverage;\n  cupdlp_float dPrimalInfeasResAverage;\n  cupdlp_float dDualInfeasResAverage;\n\n  // buffers\n  cupdlp_float *primalInfeasRay;     // x / norm(x)\n  cupdlp_float *primalInfeasConstr;  // [Ax, min(Gx, 0)]\n  cupdlp_float *primalInfeasBound;   // primal bound violation\n  cupdlp_float *dualInfeasRay;       // y / norm(y, lbd)\n  cupdlp_float *dualInfeasLbRay;     // lbd^+ / norm(y, lbd)\n  cupdlp_float *dualInfeasUbRay;     // lbd^- / norm(y, lbd)\n  cupdlp_float *dualInfeasConstr;    // ATy1 + GTy2 + lambda\n  // cupdlp_float *dualInfeasBound;     // dual bound violation\n\n  cupdlp_float dPrimalObjAverage;\n  cupdlp_float dDualObjAverage;\n  cupdlp_float dDualityGapAverage;\n  cupdlp_float dComplementarityAverage;\n  cupdlp_float dPrimalFeasAverage;\n  cupdlp_float dDualFeasAverage;\n  cupdlp_float dRelObjGapAverage;\n  cupdlp_float *primalResidualAverage;\n  cupdlp_float *dualResidualAverage;\n\n  cupdlp_float dPrimalFeasLastRestart;\n  cupdlp_float dDualFeasLastRestart;\n  cupdlp_float dDualityGapLastRestart;\n\n  cupdlp_float dPrimalFeasLastCandidate;\n  cupdlp_float dDualFeasLastCandidate;\n  cupdlp_float dDualityGapLastCandidate;\n\n  termination_code termCode;\n  termination_iterate termIterate;\n};\n\nstruct CUPDLP_ITERATES {\n  /* iterates */\n  cupdlp_int nRows;\n  cupdlp_int nCols;\n  //  todo, CPU VERSION, check\n  //        cupdlp_float *x;\n  //        cupdlp_float *y;\n  //        cupdlp_float *xUpdate;\n  //        cupdlp_float *yUpdate;\n  //\n  //        cupdlp_int iLastRestartIter;\n  //        cupdlp_float dLastRestartDualityGap;\n  //        cupdlp_float dLastRestartBeta;\n  //        cupdlp_float *xSum;\n  //        cupdlp_float *ySum;\n  //        cupdlp_float *xAverage;\n  //        cupdlp_float *yAverage;\n  //        cupdlp_float *xLastRestart;\n  //        cupdlp_float *yLastRestart;\n  //\n  //        cupdlp_float *ax;\n  //        cupdlp_float *axUpdate;\n  //        cupdlp_float *axAverage;\n  //        cupdlp_float *aty;\n  //        cupdlp_float *atyUpdate;\n  //        cupdlp_float *atyAverage;\n\n  cupdlp_int iLastRestartIter;\n  cupdlp_float dLastRestartDualityGap;\n  cupdlp_float dLastRestartBeta;\n  cupdlp_float *xSum;\n  cupdlp_float *ySum;\n\n  cupdlp_float *xLastRestart;\n  cupdlp_float *yLastRestart;\n\n  CUPDLPvec *x[2]; // in iteration k, x^k stored in x[k % 2], x^{k+1} created in x[k + 1 % 2]\n  CUPDLPvec *y[2];\n  CUPDLPvec *ax[2];\n  CUPDLPvec *aty[2];\n  CUPDLPvec *xAverage, *yAverage, *axAverage, *atyAverage;\n\n};\n\nstruct CUPDLP_STEPSIZE {\n  /* stepsize */\n  pdhg_linesearch eLineSearchMethod;  // 0 = FixedStep\n  cupdlp_float dPrimalStep;\n  cupdlp_float dDualStep;\n  cupdlp_float dSumPrimalStep;\n  cupdlp_float dSumDualStep;\n  // Stepsize ratio,\n  //  \\beta = dBeta = dDualStep / dPrimalStep,\n  //    in the paper, primal weight is the \\omega:\n  //    \\omega = \\sqrt\\beta\n  cupdlp_float dBeta;\n  cupdlp_float dTheta;  // Used in Malitsky-Pock stepsize\n  cupdlp_int nStepSizeIter;\n};\n\nstruct CUPDLP_SCALING {\n  /* scaling */\n  cupdlp_int ifScaled;\n  cupdlp_float *rowScale;\n  cupdlp_float *colScale;\n\n  /*new scaling*/\n  cupdlp_int ifRuizScaling;\n  cupdlp_int ifL2Scaling;\n  cupdlp_int ifPcScaling;\n  cupdlp_int RuizTimes;\n  cupdlp_float RuizNorm;\n  cupdlp_float PcAlpha;\n\n  /* original 2 norm */\n  cupdlp_float dNormCost;\n  cupdlp_float dNormRhs;\n};\n\nstruct CUPDLP_TIMERS {\n  /* timers */\n  cupdlp_int nIter;\n  cupdlp_float dSolvingTime;\n  cupdlp_float dSolvingBeg;\n  cupdlp_float dScalingTime;\n  cupdlp_float dPresolveTime;\n#if PDHG_USE_TIMERS\n  cupdlp_float dAtyTime;\n  cupdlp_float dAxTime;\n  cupdlp_float dComputeResidualsTime;\n  cupdlp_float dUpdateIterateTime;\n  cupdlp_int nAtyCalls;\n  cupdlp_int nAxCalls;\n  cupdlp_int nComputeResidualsCalls;\n  cupdlp_int nUpdateIterateCalls;\n#endif\n#ifndef CUPDLP_CPU\n  // GPU timers\n  cupdlp_float AllocMem_CopyMatToDeviceTime;\n  cupdlp_float CopyVecToDeviceTime;\n  cupdlp_float DeviceMatVecProdTime;\n  cupdlp_float CopyVecToHostTime;\n  cupdlp_float FreeDeviceMemTime;\n  cupdlp_float CudaPrepareTime;\n#endif\n};\n\nstruct CUPDLP_WORK {\n  CUPDLPproblem *problem;\n  CUPDLPsettings *settings;\n  CUPDLPresobj *resobj;\n  CUPDLPiterates *iterates;\n  CUPDLPstepsize *stepsize;\n  CUPDLPscaling *scaling;\n  CUPDLPtimers *timers;\n  // cupdlp_float *buffer;\n  CUPDLPvec *buffer;\n  cupdlp_float *buffer2;\n  cupdlp_float *buffer3;\n\n  cupdlp_float *rowScale;\n  cupdlp_float *colScale;\n#ifndef CUPDLP_CPU\n  // CUDAmv *MV;\n  cusparseHandle_t cusparsehandle;\n  void *dBuffer_csc_ATy;\n  void *dBuffer_csr_Ax;\n\n  // cusparseDnVecDescr_t vecbuffer;\n  cublasHandle_t cublashandle;\n#endif\n};\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/pdlp/cupdlp/cupdlp_linalg.h",
    "content": "#ifndef CUPDLP_CUPDLP_LINALG_H\n#define CUPDLP_CUPDLP_LINALG_H\n\n#include \"cupdlp_defs.h\"\n#include \"cupdlp_utils.h\"\n\n#ifndef CUPDLP_CPU\n#include \"cuda/cupdlp_cudalinalg.cuh\"\n#endif\n\nvoid ScatterCol(CUPDLPwork *w, cupdlp_int iCol, cupdlp_float multiplier,\n                cupdlp_float *target);\n\nvoid ScatterRow(CUPDLPwork *w, cupdlp_int iRow, cupdlp_float multiplier,\n                cupdlp_float *target);\n\nvoid AxCPU(CUPDLPwork *w, cupdlp_float *ax, const cupdlp_float *x);\n\nvoid ATyCPU(CUPDLPwork *w, cupdlp_float *aty, const cupdlp_float *y);\n\nextern double nrm2(cupdlp_int n, const double *x, cupdlp_int incx);\n\nextern double nrminf(cupdlp_int n, const double *x, cupdlp_int incx);\n\ndouble twoNorm(double *x, cupdlp_int n);\n\ndouble twoNormSquared(double *x, cupdlp_int n);\n\ndouble infNorm(double *x, cupdlp_int n);\n\ncupdlp_int infNormIndex(double *x, cupdlp_int n);\n\n/*------------------------ new added --------------------*/\n\ndouble GenNorm(double *x, cupdlp_int n, cupdlp_float p);\n\nvoid cupdlp_cdot(cupdlp_float *x, const cupdlp_float *y, const cupdlp_int len);\n\nvoid cupdlp_cdiv(cupdlp_float *x, const cupdlp_float *y, const cupdlp_int len);\n\n// void cupdlp_scaleVector(cupdlp_float *xout, cupdlp_float *x, cupdlp_float\n// weight, const cupdlp_int len);\nvoid cupdlp_projLowerBound(cupdlp_float *x, const cupdlp_float *lb,\n                           const cupdlp_int len);\nvoid cupdlp_projUpperBound(cupdlp_float *x, const cupdlp_float *ub,\n                           const cupdlp_int len);\nvoid cupdlp_projSameLowerBound(cupdlp_float *x, const cupdlp_float lb,\n                               const cupdlp_int len);\nvoid cupdlp_projSameUpperBound(cupdlp_float *x, const cupdlp_float ub,\n                               const cupdlp_int len);\nvoid cupdlp_projPositive(cupdlp_float *x, const cupdlp_int len);\nvoid cupdlp_projNegative(cupdlp_float *x, const cupdlp_int len);\n\n// void cupdlp_projLowerBound(cupdlp_float *xout, cupdlp_float *x, cupdlp_float\n// *lb, const cupdlp_int len); void cupdlp_projUpperBound(cupdlp_float *xout,\n// cupdlp_float *x, cupdlp_float *ub, const cupdlp_int len); void\n// cupdlp_projSameLowerBound(cupdlp_float *xout, cupdlp_float *x, cupdlp_float\n// lb, const cupdlp_int len); void cupdlp_projSameUpperBound(cupdlp_float *xout,\n// cupdlp_float *x, cupdlp_float ub, const cupdlp_int len); void\n// cupdlp_projPositive(cupdlp_float *xout, cupdlp_float *x, const cupdlp_int\n// len); void cupdlp_projNegative(cupdlp_float *xout, cupdlp_float *x, const\n// cupdlp_int len); cupdlp_float cupdlp_diffTwoNormSquared(cupdlp_float *x,\n// cupdlp_float *y, const cupdlp_int len); cupdlp_float\n// cupdlp_diffTwoNorm(cupdlp_float *x, cupdlp_float *y, const cupdlp_int len);\n// cupdlp_float cupdlp_diffInfNorm(cupdlp_float *x, cupdlp_float *y, const\n// cupdlp_int len); cupdlp_float cupdlp_diffDotDiff(cupdlp_float *x1,\n// cupdlp_float *x2, cupdlp_float *y1, cupdlp_float *y2, const cupdlp_int len);\n// void cupdlp_cdot_fb(cupdlp_float *x, const cupdlp_bool *y, const cupdlp_int\n// len);\n\n/*------------------------ new added --------------------*/\n\nextern double dot(cupdlp_int n, const cupdlp_float *x, cupdlp_int incx,\n                  const cupdlp_float *y, cupdlp_int incy);\n\nextern double Dotprod(const cupdlp_float *x, const cupdlp_float *y, cupdlp_int n);\n\n// todo, add this\nextern double Dotprod_Neumaier(const cupdlp_float *x, const cupdlp_float *y, cupdlp_int n);\n\n/* x = x + weight * y */\nvoid AddToVector(cupdlp_float *x, const cupdlp_float weight,\n                 const cupdlp_float *y, const cupdlp_int n);\n\nvoid ScaleVector(cupdlp_float weight, cupdlp_float *x, cupdlp_int n);\n\n// The main matrix-vector multiplication routines\n// #ifndef CUPDLP_CPU\n// Ax currently only works for CSC matrix multiply dense vector\n// void Ax(CUPDLPwork *w, cupdlp_float *ax, const cupdlp_float *x);\n// void Ax(CUPDLPwork *w, cupdlp_float *ax, void* vecAx, const cupdlp_float *x,\n// void *vecX);\nvoid Ax(CUPDLPwork *w, CUPDLPvec *ax, const CUPDLPvec *x);\n\n// ATy currently only works for CSR matrix multiply dense vector\n// void ATy(CUPDLPwork *w, cupdlp_float *aty, const cupdlp_float *y);\n// void ATy(CUPDLPwork *w, cupdlp_float *aty, void *vecATy, const cupdlp_float\n// *y, void *vecY);\nvoid ATy(CUPDLPwork *w, CUPDLPvec *aty, const CUPDLPvec *y);\n\n// #endif\n\n/*-------------- Apis compatible with both CPU and GPU -------------------*/\n// only implemented the APis need to be used on GPU\n\n// functions in cublas\ncupdlp_int cupdlp_axpy(CUPDLPwork *w, const cupdlp_int n,\n                       const cupdlp_float *alpha, const cupdlp_float *x,\n                       cupdlp_float *y);\n\ncupdlp_int cupdlp_dot(CUPDLPwork *w, const cupdlp_int n, const cupdlp_float *x,\n                      const cupdlp_float *y, cupdlp_float *res);\n\ncupdlp_int cupdlp_twoNorm(CUPDLPwork *w, const cupdlp_int n,\n                          const cupdlp_float *x, cupdlp_float *res);\n\ncupdlp_int cupdlp_infNorm(CUPDLPwork *w, const cupdlp_int n,\n                          const cupdlp_float *x, cupdlp_float *res);\n\ncupdlp_int cupdlp_infNormIndex(CUPDLPwork *w, const cupdlp_int n,\n                               const cupdlp_float *x, cupdlp_int *res);\n\ncupdlp_int cupdlp_scaleVector(CUPDLPwork *w, const cupdlp_float weight,\n                              cupdlp_float *x, const cupdlp_int n);\n\nvoid cupdlp_twoNormSquared(CUPDLPwork *w, const cupdlp_int n,\n                           const cupdlp_float *x, cupdlp_float *res);\n\nvoid cupdlp_diffTwoNormSquared(CUPDLPwork *w, const cupdlp_float *x,\n                               const cupdlp_float *y, const cupdlp_int len,\n                               cupdlp_float *res);\n\nvoid cupdlp_diffTwoNorm(CUPDLPwork *w, const cupdlp_float *x,\n                        const cupdlp_float *y, const cupdlp_int len,\n                        cupdlp_float *res);\n\nvoid cupdlp_diffDotDiff(CUPDLPwork *w, const cupdlp_float *x1,\n                        const cupdlp_float *x2, const cupdlp_float *y1,\n                        const cupdlp_float *y2, const cupdlp_int len,\n                        cupdlp_float *res);\n\n// functions not in cublas\n/* element wise dot: x = x .* y*/\nvoid cupdlp_edot(cupdlp_float *x, const cupdlp_float *y, const cupdlp_int len);\n/* element wise div: x = x ./ y*/\nvoid cupdlp_ediv(cupdlp_float *x, const cupdlp_float *y, const cupdlp_int len);\n\nvoid cupdlp_projlb(cupdlp_float *x, const cupdlp_float *lb,\n                   const cupdlp_int len);\n\nvoid cupdlp_projub(cupdlp_float *x, const cupdlp_float *ub,\n                   const cupdlp_int len);\n\nvoid cupdlp_projSamelb(cupdlp_float *x, const cupdlp_float lb,\n                       const cupdlp_int len);\n\nvoid cupdlp_projSameub(cupdlp_float *x, const cupdlp_float ub,\n                       const cupdlp_int len);\n\n/* xout = max(x, 0) */\nvoid cupdlp_projPos(cupdlp_float *x, const cupdlp_int len);\n\n/* xout = min(x, 0) */\nvoid cupdlp_projNeg(cupdlp_float *x, const cupdlp_int len);\n\n// void cupdlp_haslb(cupdlp_float *haslb, const cupdlp_float *lb,\n//                   const cupdlp_float bound, const cupdlp_int len);\n\n// void cupdlp_hasub(cupdlp_float *hasub, const cupdlp_float *ub,\n//                   const cupdlp_float bound, const cupdlp_int len);\n\nvoid cupdlp_filterlb(cupdlp_float *x, const cupdlp_float *lb,\n                     const cupdlp_float bound, const cupdlp_int len);\n\nvoid cupdlp_filterub(cupdlp_float *x, const cupdlp_float *ub,\n                     const cupdlp_float bound, const cupdlp_int len);\n\nvoid cupdlp_initvec(cupdlp_float *x, const cupdlp_float val,\n                    const cupdlp_int len);\n\nvoid cupdlp_compute_interaction_and_movement(CUPDLPwork *w,\n                                             cupdlp_float *dMovement,\n                                             cupdlp_float *dIteraction);\n\n// WIP\n// double get_fabs_value(double* vec, int index);\n// double get_fabs_value(double* vec, int index, int N);\n\n#endif  // CUPDLP_CUPDLP_LINALG_H\n"
  },
  {
    "path": "thirdparty/solvers/highs/pdlp/cupdlp/cupdlp_proj.h",
    "content": "//\n// Created by chuwen on 23-11-28.\n//\n\n#ifndef CUPDLP_CUPDLP_PROJ_H\n#define CUPDLP_CUPDLP_PROJ_H\n\n#include \"pdlp/cupdlp/cupdlp_defs.h\"\n#include \"pdlp/cupdlp/glbopts.h\"\n\nvoid PDHG_Project_Bounds(CUPDLPwork *work, double *r);\n\n// void PDHG_Project_Row_Duals(CUPDLPwork *work, double *r);\n\nvoid PDHG_Restart_Iterate(CUPDLPwork *pdhg);\n\nvoid PDHG_Restart_Iterate_GPU(CUPDLPwork *pdhg);\n\n#endif  // CUPDLP_CUPDLP_PROJ_H\n"
  },
  {
    "path": "thirdparty/solvers/highs/pdlp/cupdlp/cupdlp_restart.h",
    "content": "//\n// Created by chuwen on 23-11-28.\n//\n\n#ifndef CUPDLP_CUPDLP_RESTART_H\n#define CUPDLP_CUPDLP_RESTART_H\n\n#include \"pdlp/cupdlp/cupdlp_defs.h\"\n#include \"pdlp/cupdlp/cupdlp_linalg.h\"\n#include \"pdlp/cupdlp/cupdlp_proj.h\"\n// #include \"cupdlp_scaling.h\"\n#include \"pdlp/cupdlp/cupdlp_step.h\"\n#include \"pdlp/cupdlp/cupdlp_utils.h\"\n#include \"pdlp/cupdlp/glbopts.h\"\n\ntypedef enum {\n  PDHG_NO_RESTART = 0,\n  PDHG_RESTART_TO_CURRENT,\n  PDHG_RESTART_TO_AVERAGE\n} PDHG_restart_choice;\n\ncupdlp_bool PDHG_Check_Restart_Merit_Function(CUPDLPwork *work);\n\nPDHG_restart_choice PDHG_Check_Restart_GPU(CUPDLPwork *work);\n\ncupdlp_float PDHG_Restart_Score_GPU(cupdlp_float weightSquared,\n                                    cupdlp_float dPrimalFeas,\n                                    cupdlp_float dDualFeas,\n                                    cupdlp_float dDualityGap);\n\n#endif  // CUPDLP_CUPDLP_RESTART_H\n"
  },
  {
    "path": "thirdparty/solvers/highs/pdlp/cupdlp/cupdlp_scaling.h",
    "content": "//\n// Created by LJS on 23-11-30.\n//\n\n#ifndef CUPDLP_SCALING_H\n#define CUPDLP_SCALING_H\n\n#include \"cupdlp_defs.h\"\n#include \"glbopts.h\"\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ncupdlp_retcode PDHG_Scale_Data(cupdlp_int log_level, CUPDLPcsc* csc,\n                               cupdlp_int ifScaling, CUPDLPscaling* scaling,\n                               cupdlp_float* cost, cupdlp_float* lower,\n                               cupdlp_float* upper, cupdlp_float* rhs);\n\ncupdlp_retcode Init_Scaling(cupdlp_int log_level, CUPDLPscaling* scaling,\n                            cupdlp_int ncols, cupdlp_int nrows,\n                            cupdlp_float* cost, cupdlp_float* rhs);\n\n#ifdef __cplusplus\n}\n#endif\n#endif  // CUPDLP_CUPDLP_SCALING_H\n"
  },
  {
    "path": "thirdparty/solvers/highs/pdlp/cupdlp/cupdlp_solver.h",
    "content": "//\n// Created by chuwen on 23-11-27.\n//\n\n#ifndef CUPDLP_CUPDLP_SOLVER_H\n#define CUPDLP_CUPDLP_SOLVER_H\n\n#include \"pdlp/cupdlp/cupdlp_defs.h\"\n#include \"pdlp/cupdlp/glbopts.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n#define CUPDLP_CHECK_TIMEOUT(pdhg)                               \\\n  {                                                              \\\n    PDHG_Compute_SolvingTime(pdhg);                              \\\n    if (pdhg->timers->dSolvingTime > pdhg->settings->dTimeLim) { \\\n      retcode = RETCODE_FAILED;                                  \\\n      goto exit_cleanup;                                         \\\n    }                                                            \\\n  }\n\nvoid PDHG_Compute_Primal_Feasibility(CUPDLPwork *work, cupdlp_float *primalResidual,\n                                     const cupdlp_float *ax, const cupdlp_float *x,\n                                     cupdlp_float *dPrimalFeasibility,\n                                     cupdlp_float *dPrimalObj);\n\nvoid PDHG_Compute_Dual_Feasibility(CUPDLPwork *work, cupdlp_float *dualResidual,\n                                   const cupdlp_float *aty, const cupdlp_float *x,\n                                   const cupdlp_float *y, cupdlp_float *dDualFeasibility,\n                                   cupdlp_float *dDualObj, cupdlp_float *dComplementarity,\n                                   cupdlp_float *dSlackPos, cupdlp_float *dSlackNeg);\n\nvoid PDHG_Compute_Residuals(CUPDLPwork *work);\n\nvoid PDHG_Compute_Primal_Infeasibility(CUPDLPwork *work, const cupdlp_float *y,\n                                       const cupdlp_float *dSlackPos,\n                                       const cupdlp_float *dSlackNeg,\n                                       const cupdlp_float *aty,\n                                       const cupdlp_float dualObj,\n                                       cupdlp_float *dPrimalInfeasObj,\n                                       cupdlp_float *dPrimalInfeasRes);\n\nvoid PDHG_Compute_Dual_Infeasibility(CUPDLPwork *work, const cupdlp_float *x,\n                                     const cupdlp_float *ax,\n                                     const cupdlp_float primalObj,\n                                     cupdlp_float *dDualInfeasObj,\n                                     cupdlp_float *dDualInfeasRes);\n\nvoid PDHG_Compute_Infeas_Residuals(CUPDLPwork *work);\n\nvoid PDHG_Init_Variables(const cupdlp_int* has_variables, CUPDLPwork *work);\n\nvoid PDHG_Check_Data(CUPDLPwork *work);\n\ncupdlp_bool PDHG_Check_Termination(CUPDLPwork *pdhg, int bool_print);\n\ncupdlp_bool PDHG_Check_Termination_Average(CUPDLPwork *pdhg, int bool_print);\n\ntermination_code PDHG_Check_Infeasibility(CUPDLPwork *pdhg, int bool_print);\n\ntermination_code PDHG_Check_Primal_Infeasibility(CUPDLPwork *pdhg,\n                                                 cupdlp_float dPrimalInfeasObj,\n                                                 cupdlp_float dPrimalInfeasRes);\ntermination_code PDHG_Check_Dual_Infeasibility(CUPDLPwork *pdhg,\n                                               cupdlp_float dDualInfeasObj,\n                                               cupdlp_float dDualInfeasRes);\n\nvoid PDHG_Print_Header(CUPDLPwork *pdhg);\n\nvoid PDHG_Print_Iter(CUPDLPwork *pdhg);\n\nvoid PDHG_Print_Iter_Average(CUPDLPwork *pdhg);\n\nvoid PDHG_Compute_SolvingTime(CUPDLPwork *pdhg);\n\ncupdlp_retcode PDHG_Solve(const cupdlp_int* has_variables, CUPDLPwork *pdhg);\n\ncupdlp_retcode PDHG_PostSolve(CUPDLPwork *pdhg, cupdlp_int nCols_origin,\n                              cupdlp_int *constraint_new_idx,\n                              cupdlp_int *constraint_type,\n                              cupdlp_float *col_value, cupdlp_float *col_dual,\n                              cupdlp_float *row_value, cupdlp_float *row_dual,\n                              cupdlp_int *value_valid, cupdlp_int *dual_valid);\n\ncupdlp_retcode PDHG_PreSolve(CUPDLPwork *pdhg, cupdlp_int nCols_origin,\n\t\t\t     cupdlp_int *constraint_new_idx,\n\t\t\t     cupdlp_int *constraint_type,\n\t\t\t     cupdlp_float *col_value, cupdlp_float *col_dual,\n\t\t\t     cupdlp_float *row_value, cupdlp_float *row_dual,\n\t\t\t     cupdlp_int *value_valid, cupdlp_int *dual_valid);\n\ncupdlp_retcode LP_SolvePDHG(\n    CUPDLPwork *pdhg, cupdlp_bool *ifChangeIntParam, cupdlp_int *intParam,\n    cupdlp_bool *ifChangeFloatParam, cupdlp_float *floatParam, char *fp,\n    cupdlp_int nCols_origin, cupdlp_float *col_value, cupdlp_float *col_dual,\n    cupdlp_float *row_value, cupdlp_float *row_dual, cupdlp_int *value_valid,\n    cupdlp_int *dual_valid, cupdlp_bool ifSaveSol, char *fp_sol,\n    cupdlp_int *constraint_new_idx, cupdlp_int *constraint_type,\n    cupdlp_int *model_status, cupdlp_int* num_iter);\n\n#ifdef __cplusplus\n}\n#endif\n#endif  // CUPDLP_CUPDLP_SOLVER_H\n"
  },
  {
    "path": "thirdparty/solvers/highs/pdlp/cupdlp/cupdlp_step.h",
    "content": "//\n// Created by chuwen on 23-11-28.\n//\n\n#ifndef CUPDLP_CUPDLP_STEP_H\n#define CUPDLP_CUPDLP_STEP_H\n\n#include \"pdlp/cupdlp/cupdlp_defs.h\"\n// #include \"cupdlp_scaling.h\"\n#include \"pdlp/cupdlp/glbopts.h\"\n\ncupdlp_retcode PDHG_Power_Method(CUPDLPwork *work, double *lambda);\n\nvoid PDHG_Compute_Step_Size_Ratio(CUPDLPwork *pdhg);\n\nvoid PDHG_Update_Iterate_Constant_Step_Size(CUPDLPwork *pdhg);\n\nvoid PDHG_Update_Iterate_Malitsky_Pock(CUPDLPwork *pdhg);\n\ncupdlp_retcode PDHG_Update_Iterate_Adaptive_Step_Size(CUPDLPwork *pdhg);\n\ncupdlp_retcode PDHG_Init_Step_Sizes(CUPDLPwork *pdhg);\n\nvoid PDHG_Compute_Average_Iterate(CUPDLPwork *work);\n\nvoid PDHG_Update_Average(CUPDLPwork *work);\n\ncupdlp_retcode PDHG_Update_Iterate(CUPDLPwork *pdhg);\n\nvoid PDHG_primalGradientStep(CUPDLPwork *work, CUPDLPvec *xUpdate,\n                             const CUPDLPvec *x, const CUPDLPvec *ATy,\n                             cupdlp_float dPrimalStepSize);\nvoid PDHG_dualGradientStep(CUPDLPwork *work, CUPDLPvec *yUpdate,\n                           const CUPDLPvec *y, const CUPDLPvec *Ax,\n                           const CUPDLPvec *AxUpdate, cupdlp_float dDualStepSize);\n\n#endif  // CUPDLP_CUPDLP_STEP_H\n"
  },
  {
    "path": "thirdparty/solvers/highs/pdlp/cupdlp/cupdlp_utils.c",
    "content": "//\n// Created by chuwen on 23-11-26.\n//\n\n#include \"pdlp/cupdlp/cupdlp_utils.h\"\n\n#include <limits.h>\n#include <stdio.h>\n\n#include <time.h>\n\n#include \"pdlp/cupdlp/cupdlp_cs.h\"\n#include \"pdlp/cupdlp/cupdlp_linalg.h\"\n#include \"pdlp/cupdlp/glbopts.h\"\n\n#ifndef CUPDLP_CPU\n\n#include \"cuda/cupdlp_cudalinalg.cuh\"\n\n#endif\n\nvoid dense_clear(CUPDLPdense *dense) {\n  if (dense) {\n    if (dense->data) {\n      cupdlp_free(dense->data);\n    }\n    cupdlp_free(dense);\n  }\n}\n\ncupdlp_int csc_clear(CUPDLPcsc *csc) {\n  if (csc) {\n#ifndef CUPDLP_CPU\n    if (csc->cuda_csc != NULL) {\n      CHECK_CUSPARSE(cusparseDestroySpMat(csc->cuda_csc))\n    }\n#endif\n    if (csc->colMatBeg) {\n      CUPDLP_FREE_VEC(csc->colMatBeg);\n    }\n    if (csc->colMatIdx) {\n      CUPDLP_FREE_VEC(csc->colMatIdx);\n    }\n    if (csc->colMatElem) {\n      CUPDLP_FREE_VEC(csc->colMatElem);\n    }\n      cupdlp_free(csc);\n  }\n  return 0;\n}\n\ncupdlp_int csc_clear_host(CUPDLPcsc *csc) {\n  if (csc) {\n    if (csc->colMatBeg) {\n      cupdlp_free(csc->colMatBeg);\n    }\n    if (csc->colMatIdx) {\n      cupdlp_free(csc->colMatIdx);\n    }\n    if (csc->colMatElem) {\n      cupdlp_free(csc->colMatElem);\n    }\n    cupdlp_free(csc);\n  }\n  return 0;\n}\n\ncupdlp_int csr_clear(CUPDLPcsr *csr) {\n  if (csr) {\n#ifndef CUPDLP_CPU\n    if (csr->cuda_csr != NULL) {\n      CHECK_CUSPARSE(cusparseDestroySpMat(csr->cuda_csr))\n    }\n#endif\n    if (csr->rowMatBeg) {\n      CUPDLP_FREE_VEC(csr->rowMatBeg);\n    }\n    if (csr->rowMatIdx) {\n      CUPDLP_FREE_VEC(csr->rowMatIdx);\n    }\n    if (csr->rowMatElem) {\n      CUPDLP_FREE_VEC(csr->rowMatElem);\n    }\n    cupdlp_free(csr);\n  }\n  return 0;\n}\n\nvoid data_clear(CUPDLPdata *data) {\n  if (data) {\n    switch (data->matrix_format) {\n      case DENSE:\n        dense_clear(data->dense_matrix);\n        break;\n      case CSR:\n        csr_clear(data->csr_matrix);\n        break;\n      case CSC:\n        csc_clear(data->csc_matrix);\n        break;\n      case CSR_CSC:\n        csr_clear(data->csr_matrix);\n        csc_clear(data->csc_matrix);\n        break;\n    }\n    cupdlp_free(data);\n  }\n}\n\nvoid problem_clear(CUPDLPproblem *problem) {\n  if (problem) {\n    if (problem->data) {\n      data_clear(problem->data);\n    }\n    //        if (problem->colMatBeg) {\n    //            cupdlp_free(problem->colMatBeg);\n    //        }\n    //        if (problem->colMatIdx) {\n    //            cupdlp_free(problem->colMatIdx);\n    //        }\n    //        if (problem->colMatElem) {\n    //            cupdlp_free(problem->colMatElem);\n    //        }\n    //        if (problem->rowMatBeg) {\n    //            cupdlp_free(problem->rowMatBeg);\n    //        }\n    //        if (problem->rowMatIdx) {\n    //            cupdlp_free(problem->rowMatIdx);\n    //        }\n    //        if (problem->rowMatElem) {\n    //            cupdlp_free(problem->rowMatElem);\n    //        }\n    if (problem->lower) {\n      CUPDLP_FREE_VEC(problem->lower);\n    }\n    if (problem->upper) {\n      CUPDLP_FREE_VEC(problem->upper);\n    }\n    if (problem->cost) {\n      CUPDLP_FREE_VEC(problem->cost);\n    }\n    if (problem->rhs) {\n      CUPDLP_FREE_VEC(problem->rhs);\n    }\n    if (problem->hasLower) {\n      CUPDLP_FREE_VEC(problem->hasLower);\n    }\n    if (problem->hasUpper) {\n      CUPDLP_FREE_VEC(problem->hasUpper);\n    }\n    cupdlp_free(problem);\n  }\n}\n\nvoid settings_clear(CUPDLPsettings *settings) {\n  if (settings) {\n    cupdlp_free(settings);\n  }\n}\n\ncupdlp_int vec_clear(CUPDLPvec *vec) {\n  if (vec) {\n    if (vec->data) {\n      CUPDLP_FREE_VEC(vec->data);\n    }\n#ifndef CUPDLP_CPU\n    CHECK_CUSPARSE(cusparseDestroyDnVec(vec->cuda_vec))\n#endif\n    cupdlp_free(vec);\n  }\n\n  return 0;\n}\n\nvoid iterates_clear(CUPDLPiterates *iterates) {\n  if (iterates) {\n    if (iterates->x[0]) {\n      // CUPDLP_FREE_VEC(iterates->x[0]);\n      vec_clear(iterates->x[0]);\n    }\n    if (iterates->x[1]) {\n      // CUPDLP_FREE_VEC(iterates->x[1]);\n      vec_clear(iterates->x[1]);\n    }\n    if (iterates->y[0]) {\n      // CUPDLP_FREE_VEC(iterates->y[0]);\n      vec_clear(iterates->y[0]);\n    }\n    if (iterates->y[1]) {\n      // CUPDLP_FREE_VEC(iterates->y[1]);\n      vec_clear(iterates->y[1]);\n    }\n    if (iterates->xSum) {\n      CUPDLP_FREE_VEC(iterates->xSum);\n    }\n    if (iterates->ySum) {\n      CUPDLP_FREE_VEC(iterates->ySum);\n    }\n    if (iterates->xAverage) {\n      // CUPDLP_FREE_VEC(iterates->xAverage);\n      vec_clear(iterates->xAverage);\n    }\n    if (iterates->yAverage) {\n      // CUPDLP_FREE_VEC(iterates->yAverage);\n      vec_clear(iterates->yAverage);\n    }\n    if (iterates->xLastRestart) {\n      CUPDLP_FREE_VEC(iterates->xLastRestart);\n    }\n    if (iterates->yLastRestart) {\n      CUPDLP_FREE_VEC(iterates->yLastRestart);\n    }\n    if (iterates->ax[0]) {\n      // CUPDLP_FREE_VEC(iterates->ax[0]);\n      vec_clear(iterates->ax[0]);\n    }\n    if (iterates->ax[1]) {\n      // CUPDLP_FREE_VEC(iterates->ax[1]);\n      vec_clear(iterates->ax[1]);\n    }\n    if (iterates->axAverage) {\n      // CUPDLP_FREE_VEC(iterates->axAverage);\n      vec_clear(iterates->axAverage);\n    }\n    if (iterates->aty[0]) {\n      // CUPDLP_FREE_VEC(iterates->aty[0]);\n      vec_clear(iterates->aty[0]);\n    }\n    if (iterates->aty[1]) {\n      // CUPDLP_FREE_VEC(iterates->aty[1]);\n      vec_clear(iterates->aty[1]);\n    }\n    if (iterates->atyAverage) {\n      // CUPDLP_FREE_VEC(iterates->atyAverage);\n      vec_clear(iterates->atyAverage);\n    }\n    cupdlp_free(iterates);\n  }\n}\n\nvoid resobj_clear(CUPDLPresobj *resobj) {\n  if (resobj) {\n    if (resobj->primalResidual) {\n      CUPDLP_FREE_VEC(resobj->primalResidual);\n    }\n    if (resobj->dualResidual) {\n      CUPDLP_FREE_VEC(resobj->dualResidual);\n    }\n    if (resobj->primalResidualAverage) {\n      CUPDLP_FREE_VEC(resobj->primalResidualAverage);\n    }\n    if (resobj->dualResidualAverage) {\n      CUPDLP_FREE_VEC(resobj->dualResidualAverage);\n    }\n    if (resobj->dSlackPos) {\n      CUPDLP_FREE_VEC(resobj->dSlackPos);\n    }\n    if (resobj->dSlackNeg) {\n      CUPDLP_FREE_VEC(resobj->dSlackNeg);\n    }\n    if (resobj->dSlackPosAverage) {\n      CUPDLP_FREE_VEC(resobj->dSlackPosAverage);\n    }\n    if (resobj->dSlackNegAverage) {\n      CUPDLP_FREE_VEC(resobj->dSlackNegAverage);\n    }\n    if (resobj->dLowerFiltered) {\n      CUPDLP_FREE_VEC(resobj->dLowerFiltered);\n    }\n    if (resobj->dUpperFiltered) {\n      CUPDLP_FREE_VEC(resobj->dUpperFiltered);\n    }\n    if (resobj->primalInfeasRay) {\n      CUPDLP_FREE_VEC(resobj->primalInfeasRay);\n    }\n    if (resobj->primalInfeasConstr) {\n      CUPDLP_FREE_VEC(resobj->primalInfeasConstr);\n    }\n    if (resobj->primalInfeasBound) {\n      CUPDLP_FREE_VEC(resobj->primalInfeasBound);\n    }\n    if (resobj->dualInfeasRay) {\n      CUPDLP_FREE_VEC(resobj->dualInfeasRay);\n    }\n    if (resobj->dualInfeasLbRay) {\n      CUPDLP_FREE_VEC(resobj->dualInfeasLbRay);\n    }\n    if (resobj->dualInfeasUbRay) {\n      CUPDLP_FREE_VEC(resobj->dualInfeasUbRay);\n    }\n    if (resobj->dualInfeasConstr) {\n      CUPDLP_FREE_VEC(resobj->dualInfeasConstr);\n    }\n    // if (resobj->dualInfeasBound) {\n    //   CUPDLP_FREE_VEC(resobj->dualInfeasBound);\n    // }\n    cupdlp_free(resobj);\n  }\n}\n\nvoid stepsize_clear(CUPDLPstepsize *stepsize) {\n  if (stepsize) {\n    cupdlp_free(stepsize);\n  }\n}\n\nvoid timers_clear(int log_level, CUPDLPtimers *timers) {\n#ifndef CUPDLP_CPU\nif (log_level > 1)\n  cupdlp_printf(\"%20s %e\\n\\n\", \"Free Device memory\", timers->FreeDeviceMemTime);\n#endif\n\n\n  if (timers) {\n    cupdlp_free(timers);\n  }\n}\n\nvoid scaling_clear(CUPDLPscaling *scaling) {\n  if (scaling) {\n    if (scaling->colScale) {\n      cupdlp_free(scaling->colScale);\n    }\n    if (scaling->rowScale) {\n      cupdlp_free(scaling->rowScale);\n    }\n    cupdlp_free(scaling);\n  }\n}\n\ncupdlp_int PDHG_Clear(CUPDLPwork *w) {\n  CUPDLPproblem *problem = w->problem;\n  CUPDLPsettings *settings = w->settings;\n  CUPDLPiterates *iterates = w->iterates;\n  CUPDLPresobj *resobj = w->resobj;\n  CUPDLPstepsize *stepsize = w->stepsize;\n  CUPDLPtimers *timers = w->timers;\n  CUPDLPscaling *scaling = w->scaling;\n\n\n  cupdlp_float begin = getTimeStamp();\n#ifndef CUPDLP_CPU\n\n  // CUDAmv *MV = w->MV;\n  // if (MV)\n  // {\n  //     cupdlp_float begin = getTimeStamp();\n  //     cuda_free_mv(MV);\n  //     timers->FreeDeviceMemTime += getTimeStamp() - begin;\n  // }\n  CHECK_CUBLAS(cublasDestroy(w->cublashandle))\n  CHECK_CUSPARSE(cusparseDestroy(w->cusparsehandle))\n  CHECK_CUDA(cudaFree(w->dBuffer_csc_ATy))\n  CHECK_CUDA(cudaFree(w->dBuffer_csr_Ax))\n  if (w->buffer2) CUPDLP_FREE_VEC(w->buffer2);\n  if (w->buffer3) CUPDLP_FREE_VEC(w->buffer3);\n#endif\n  if (w->colScale) CUPDLP_FREE_VEC(w->colScale);\n  if (w->rowScale) CUPDLP_FREE_VEC(w->rowScale);\n\n  if (w->buffer) {\n    // CUPDLP_FREE_VEC(w->buffer);\n    vec_clear(w->buffer);\n  }\n\n  if (w->buffer2 != NULL) {\n    // CUPDLP_FREE_VEC(w->buffer);\n    free(w->buffer2);\n  }\n\n  if (w->buffer3) {\n    // CUPDLP_FREE_VEC(w->buffer);\n    free(w->buffer3);\n  }\n\n  if (problem) {\n    // problem_clear(problem);\n    problem = cupdlp_NULL;\n  }\n\n  if (iterates) {\n    iterates_clear(iterates);\n  }\n\n  if (resobj) {\n    resobj_clear(resobj);\n  }\n\n#ifndef CUPDLP_CPU\n  timers->FreeDeviceMemTime += getTimeStamp() - begin;\n#endif\n\n  // Call timers_clear, before clearing settings\n  if (timers) {\n    timers_clear(settings->nLogLevel, timers);\n  }\n  if (settings) {\n    settings_clear(settings);\n  }\n  if (stepsize) {\n    stepsize_clear(stepsize);\n  }\n  if (scaling) {\n    // scaling_clear(scaling);\n    // if (scaling->colScale) {\n    //    cupdlp_free(scaling->colScale);\n    // }\n    // if (scaling->rowScale) {\n    //    cupdlp_free(scaling->rowScale);\n    // }\n    // cupdlp_free(scaling);\n    scaling = cupdlp_NULL;\n  }\n  cupdlp_free(w);\n\n  return 0;\n}\n\nvoid PDHG_PrintPDHGParam(CUPDLPwork *w) {\n  if (w->settings->nLogLevel < 2) return;\n  CUPDLPsettings *settings = w->settings;\n  CUPDLPstepsize *stepsize = w->stepsize;\n  CUPDLPresobj *resobj = w->resobj;\n  CUPDLPiterates *iterates = w->iterates;\n  CUPDLPscaling *scaling = w->scaling;\n  CUPDLPtimers *timers = w->timers;\n\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"\\n\");\n  cupdlp_printf(\"--------------------------------------------------\\n\");\n  cupdlp_printf(\"CUPDHG Parameters:\\n\");\n  cupdlp_printf(\"--------------------------------------------------\\n\");\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"    nIterLim:          %d\\n\", settings->nIterLim);\n  cupdlp_printf(\"    dTimeLim (sec):    %.2f\\n\", settings->dTimeLim);\n  cupdlp_printf(\"    ifScaling:         %d\\n\", settings->ifScaling);\n  // cupdlp_printf(\"    iScalingMethod:    %d\\n\", settings->iScalingMethod);)\n  cupdlp_printf(\"    ifRuizScaling:     %d\\n\", scaling->ifRuizScaling);\n  cupdlp_printf(\"    ifL2Scaling:       %d\\n\", scaling->ifL2Scaling);\n  cupdlp_printf(\"    ifPcScaling:       %d\\n\", scaling->ifPcScaling);\n  cupdlp_printf(\"    eLineSearchMethod: %d\\n\", stepsize->eLineSearchMethod);\n  // cupdlp_printf(\"    dScalingLimit:     %.4e\\n\", settings->dScalingLimit);\n  cupdlp_printf(\"    dPrimalTol:        %.4e\\n\", settings->dPrimalTol);\n  cupdlp_printf(\"    dDualTol:          %.4e\\n\", settings->dDualTol);\n  cupdlp_printf(\"    dGapTol:           %.4e\\n\", settings->dGapTol);\n  cupdlp_printf(\"    dFeasTol:          %.4e\\n\", resobj->dFeasTol);\n  cupdlp_printf(\"    eRestartMethod:    %d\\n\", settings->eRestartMethod);\n  cupdlp_printf(\"    nLogLevel:    %d\\n\", settings->nLogLevel);\n  cupdlp_printf(\"    nLogInterval:    %d\\n\", settings->nLogInterval);\n  cupdlp_printf(\"\\n\");\n  cupdlp_printf(\"--------------------------------------------------\\n\");\n  cupdlp_printf(\"\\n\");\n}\n\nvoid PDHG_PrintHugeCUPDHG(void) {\n  cupdlp_printf(\"\\n\");\n  cupdlp_printf(\"  ____ _   _ ____  ____  _     ____\\n\");\n  cupdlp_printf(\" / ___| | | |  _ \\\\|  _ \\\\| |   |  _ \\\\\\n\");\n  cupdlp_printf(\"| |   | | | | |_) | | | | |   | |_) |\\n\");\n  cupdlp_printf(\"| |___| |_| |  __/| |_| | |___|  __/\\n\");\n  cupdlp_printf(\" \\\\____|\\\\___/|_|   |____/|_____|_|\\n\");\n  cupdlp_printf(\"\\n\");\n}\n\nvoid PDHG_PrintUserParamHelper(void) {\n  PDHG_PrintHugeCUPDHG();\n\n  cupdlp_printf(\"CUPDHG User Parameters:\\n\");\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"    -h: print this helper\\n\");\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"    -nIterLim:  maximum iteration number\\n\");\n  cupdlp_printf(\"                type:    int\\n\");\n  cupdlp_printf(\"                default: INT_MAX\\n\");\n  cupdlp_printf(\"                range:   >= 0\\n\");\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"    -ifScaling: whether to use scaling\\n\");\n  cupdlp_printf(\"                type:    bool\\n\");\n  cupdlp_printf(\"                default: true\\n\");\n  cupdlp_printf(\"                range:   true or false\\n\");\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"    -eLineSearchMethod: which line search method to use\\n\");\n  cupdlp_printf(\n      \"                        0-Fixed, 1-Malitsky (not support), \"\n      \"2-Adaptive\\n\");\n  cupdlp_printf(\"                type:    int\\n\");\n  cupdlp_printf(\"                default: 2\\n\");\n  cupdlp_printf(\"                range:   0 to 2\\n\");\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"    -dPrimalTol: primal tolerance\\n\");\n  cupdlp_printf(\"                type:    double\\n\");\n  cupdlp_printf(\"                default: 1e-4\\n\");\n  cupdlp_printf(\"                range:   >= 0\\n\");\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"    -dDualTol: dual tolerance\\n\");\n  cupdlp_printf(\"                type:    double\\n\");\n  cupdlp_printf(\"                default: 1e-4\\n\");\n  cupdlp_printf(\"                range:   >= 0\\n\");\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"    -dGapTol: gap tolerance\\n\");\n  cupdlp_printf(\"                type:    double\\n\");\n  cupdlp_printf(\"                default: 1e-4\\n\");\n  cupdlp_printf(\"                range:   >= 0\\n\");\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"    -dFeasTol: feasibility tolerance\\n\");\n  cupdlp_printf(\"                type:    double\\n\");\n  cupdlp_printf(\"                default: 1e-8\\n\");\n  cupdlp_printf(\"                range:   >= 0\\n\");\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"    -dTimeLim: time limit (in seconds)\\n\");\n  cupdlp_printf(\"                type:    double\\n\");\n  cupdlp_printf(\"                default: 3600\\n\");\n  cupdlp_printf(\"                range:   >= 0\\n\");\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"    -eRestartMethod: which restart method to use\\n\");\n  cupdlp_printf(\"                     0-None, 1-KKTversion\\n\");\n  cupdlp_printf(\"                type:    int\\n\");\n  cupdlp_printf(\"                default: 1\\n\");\n  cupdlp_printf(\"                range:   0 to 1\\n\");\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"    -ifRuizScaling: whether to use Ruiz scaling\\n\");\n  cupdlp_printf(\"                type:    bool\\n\");\n  cupdlp_printf(\"                default: true\\n\");\n  cupdlp_printf(\"                range:   true or false\\n\");\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"    -ifL2Scaling: whether to use L2 scaling\\n\");\n  cupdlp_printf(\"                type:    bool\\n\");\n  cupdlp_printf(\"                default: false\\n\");\n  cupdlp_printf(\"                range:   true or false\\n\");\n  cupdlp_printf(\"\\n\");\n\n  cupdlp_printf(\"    -ifPcScaling: whether to use Pock-Chambolle scaling\\n\");\n  cupdlp_printf(\"                type:    bool\\n\");\n  cupdlp_printf(\"                default: true\\n\");\n  cupdlp_printf(\"                range:   true or false\\n\");\n  cupdlp_printf(\"\\n\");\n\n  // cupdlp_printf(\n  //     \"    -ifPre: whether to use HiGHS presolver (and thus postsolver)\\n\");\n  // cupdlp_printf(\"                type:    bool\\n\");\n  // cupdlp_printf(\"                default: true\\n\");\n  // cupdlp_printf(\"                range:   true or false\\n\");\n  // cupdlp_printf(\"\\n\");\n}\n\ncupdlp_retcode getUserParam(int argc, char **argv,\n                            cupdlp_bool *ifChangeIntParam, cupdlp_int *intParam,\n                            cupdlp_bool *ifChangeFloatParam,\n                            cupdlp_float *floatParam) {\n  cupdlp_retcode retcode = RETCODE_OK;\n\n  // set ifChangeIntParam and ifChangeFloatParam to false\n  for (cupdlp_int i = 0; i < N_INT_USER_PARAM; ++i) {\n    ifChangeIntParam[i] = false;\n  }\n\n  for (cupdlp_int i = 0; i < N_FLOAT_USER_PARAM; ++i) {\n    ifChangeFloatParam[i] = false;\n  }\n\n  // parse command line arguments\n  for (cupdlp_int i = 0; i < argc - 1; ++i) {\n    if (strcmp(argv[i], \"-h\") == 0) {\n      PDHG_PrintUserParamHelper();\n\n      retcode = RETCODE_FAILED;\n      goto exit_cleanup;\n    }\n\n    if (strcmp(argv[i], \"-nIterLim\") == 0) {\n      ifChangeIntParam[N_ITER_LIM] = true;\n      intParam[N_ITER_LIM] = atoi(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-ifScaling\") == 0) {\n      ifChangeIntParam[IF_SCALING] = true;\n      intParam[IF_SCALING] = atoi(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-iScalingMethod\") == 0) {\n      ifChangeIntParam[I_SCALING_METHOD] = true;\n      intParam[I_SCALING_METHOD] = atoi(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-eLineSearchMethod\") == 0) {\n      ifChangeIntParam[E_LINE_SEARCH_METHOD] = true;\n      intParam[E_LINE_SEARCH_METHOD] = atoi(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-dScalingLimit\") == 0) {\n      ifChangeFloatParam[D_SCALING_LIMIT] = true;\n      floatParam[D_SCALING_LIMIT] = atof(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-dPrimalTol\") == 0) {\n      ifChangeFloatParam[D_PRIMAL_TOL] = true;\n      floatParam[D_PRIMAL_TOL] = atof(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-dDualTol\") == 0) {\n      ifChangeFloatParam[D_DUAL_TOL] = true;\n      floatParam[D_DUAL_TOL] = atof(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-dGapTol\") == 0) {\n      ifChangeFloatParam[D_GAP_TOL] = true;\n      floatParam[D_GAP_TOL] = atof(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-dFeasTol\") == 0) {\n      ifChangeFloatParam[D_FEAS_TOL] = true;\n      floatParam[D_FEAS_TOL] = atof(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-dTimeLim\") == 0) {\n      ifChangeFloatParam[D_TIME_LIM] = true;\n      floatParam[D_TIME_LIM] = atof(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-eRestartMethod\") == 0) {\n      ifChangeIntParam[E_RESTART_METHOD] = true;\n      intParam[E_RESTART_METHOD] = atoi(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-ifRuizScaling\") == 0) {\n      ifChangeIntParam[IF_RUIZ_SCALING] = true;\n      intParam[IF_RUIZ_SCALING] = atoi(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-ifL2Scaling\") == 0) {\n      ifChangeIntParam[IF_L2_SCALING] = true;\n      intParam[IF_L2_SCALING] = atoi(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-ifPcScaling\") == 0) {\n      ifChangeIntParam[IF_PC_SCALING] = true;\n      intParam[IF_PC_SCALING] = atoi(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-nLogLevel\") == 0) {\n      ifChangeIntParam[N_LOG_LEVEL] = true;\n      intParam[N_LOG_LEVEL] = atoi(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-nLogInt\") == 0) {\n      ifChangeIntParam[N_LOG_INTERVAL] = true;\n      intParam[N_LOG_INTERVAL] = atoi(argv[i + 1]);\n    } else if (strcmp(argv[i], \"-ifPre\") == 0) {\n      ifChangeIntParam[IF_PRESOLVE] = true;\n      intParam[IF_PRESOLVE] = atoi(argv[i + 1]);\n    }\n  }\n\n  // if (argc>0) {\n  //   if (strcmp(argv[argc - 1], \"-h\") == 0) {\n  //     PDHG_PrintUserParamHelper();\n      \n  //     retcode = RETCODE_FAILED;\n  //     goto exit_cleanup;\n  //   }\n  // }\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode settings_SetUserParam(CUPDLPsettings *settings,\n                                     cupdlp_bool *ifChangeIntParam,\n                                     cupdlp_int *intParam,\n                                     cupdlp_bool *ifChangeFloatParam,\n                                     cupdlp_float *floatParam) {\n  cupdlp_retcode retcode = RETCODE_OK;\n\n  if (ifChangeIntParam[N_ITER_LIM]) {\n    settings->nIterLim = intParam[N_ITER_LIM];\n  }\n\n  if (ifChangeIntParam[N_LOG_LEVEL]) {\n    settings->nLogLevel = intParam[N_LOG_LEVEL];\n  }\n\n  if (ifChangeIntParam[N_LOG_INTERVAL]) {\n    settings->nLogInterval = intParam[N_LOG_INTERVAL];\n  }\n\n  if (ifChangeIntParam[IF_SCALING]) {\n    settings->ifScaling = intParam[IF_SCALING];\n  }\n\n  if (ifChangeIntParam[I_SCALING_METHOD]) {\n    settings->iScalingMethod = intParam[I_SCALING_METHOD];\n  }\n\n  if (ifChangeFloatParam[D_SCALING_LIMIT]) {\n    settings->dScalingLimit = floatParam[D_SCALING_LIMIT];\n  }\n\n  if (ifChangeFloatParam[D_PRIMAL_TOL]) {\n    settings->dPrimalTol = floatParam[D_PRIMAL_TOL];\n  }\n\n  if (ifChangeFloatParam[D_DUAL_TOL]) {\n    settings->dDualTol = floatParam[D_DUAL_TOL];\n  }\n\n  if (ifChangeFloatParam[D_GAP_TOL]) {\n    settings->dGapTol = floatParam[D_GAP_TOL];\n  }\n\n  if (ifChangeFloatParam[D_TIME_LIM]) {\n    settings->dTimeLim = floatParam[D_TIME_LIM];\n  }\n\n  if (ifChangeIntParam[E_RESTART_METHOD]) {\n    settings->eRestartMethod = intParam[E_RESTART_METHOD];\n  }\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode resobj_SetUserParam(CUPDLPresobj *resobj,\n                                   cupdlp_bool *ifChangeIntParam,\n                                   cupdlp_int *intParam,\n                                   cupdlp_bool *ifChangeFloatParam,\n                                   cupdlp_float *floatParam) {\n  cupdlp_retcode retcode = RETCODE_OK;\n\n  if (ifChangeFloatParam[D_FEAS_TOL]) {\n    resobj->dFeasTol = floatParam[D_FEAS_TOL];\n  }\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode iterates_SetUserParam(CUPDLPiterates *iterates,\n                                     cupdlp_bool *ifChangeIntParam,\n                                     cupdlp_int *intParam,\n                                     cupdlp_bool *ifChangeFloatParam,\n                                     cupdlp_float *floatParam) {\n  cupdlp_retcode retcode = RETCODE_OK;\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode stepsize_SetUserParam(CUPDLPstepsize *stepsize,\n                                     cupdlp_bool *ifChangeIntParam,\n                                     cupdlp_int *intParam,\n                                     cupdlp_bool *ifChangeFloatParam,\n                                     cupdlp_float *floatParam) {\n  cupdlp_retcode retcode = RETCODE_OK;\n\n  if (ifChangeIntParam[E_LINE_SEARCH_METHOD]) {\n    stepsize->eLineSearchMethod = intParam[E_LINE_SEARCH_METHOD];\n  }\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode scaling_SetUserParam(CUPDLPscaling *scaling,\n                                    cupdlp_bool *ifChangeIntParam,\n                                    cupdlp_int *intParam,\n                                    cupdlp_bool *ifChangeFloatParam,\n                                    cupdlp_float *floatParam) {\n  cupdlp_retcode retcode = RETCODE_OK;\n\n  if (ifChangeIntParam[IF_RUIZ_SCALING]) {\n    scaling->ifRuizScaling = intParam[IF_RUIZ_SCALING];\n  }\n\n  if (ifChangeIntParam[IF_L2_SCALING]) {\n    scaling->ifL2Scaling = intParam[IF_L2_SCALING];\n  }\n\n  if (ifChangeIntParam[IF_PC_SCALING]) {\n    scaling->ifPcScaling = intParam[IF_PC_SCALING];\n  }\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode timers_SetUserParam(CUPDLPtimers *timers,\n                                   cupdlp_bool *ifChangeIntParam,\n                                   cupdlp_int *intParam,\n                                   cupdlp_bool *ifChangeFloatParam,\n                                   cupdlp_float *floatParam) {\n  cupdlp_retcode retcode = RETCODE_OK;\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode PDHG_SetUserParam(CUPDLPwork *w, cupdlp_bool *ifChangeIntParam,\n                                 cupdlp_int *intParam,\n                                 cupdlp_bool *ifChangeFloatParam,\n                                 cupdlp_float *floatParam) {\n  cupdlp_retcode retcode = RETCODE_OK;\n\n  CUPDLPsettings *settings = w->settings;\n  CUPDLPstepsize *stepsize = w->stepsize;\n  CUPDLPresobj *resobj = w->resobj;\n  CUPDLPiterates *iterates = w->iterates;\n  CUPDLPscaling *scaling = w->scaling;\n  CUPDLPtimers *timers = w->timers;\n\n  CUPDLP_CALL(settings_SetUserParam(settings, ifChangeIntParam, intParam,\n                                    ifChangeFloatParam, floatParam));\n  CUPDLP_CALL(stepsize_SetUserParam(stepsize, ifChangeIntParam, intParam,\n                                    ifChangeFloatParam, floatParam));\n  CUPDLP_CALL(resobj_SetUserParam(resobj, ifChangeIntParam, intParam,\n                                  ifChangeFloatParam, floatParam));\n  CUPDLP_CALL(iterates_SetUserParam(iterates, ifChangeIntParam, intParam,\n                                    ifChangeFloatParam, floatParam));\n  CUPDLP_CALL(scaling_SetUserParam(scaling, ifChangeIntParam, intParam,\n                                   ifChangeFloatParam, floatParam));\n  CUPDLP_CALL(timers_SetUserParam(timers, ifChangeIntParam, intParam,\n                                  ifChangeFloatParam, floatParam));\n\n  PDHG_PrintPDHGParam(w);\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode settings_Alloc(CUPDLPsettings *settings) {\n  cupdlp_retcode retcode = RETCODE_OK;\n  // settings->nIterLim = INFINITY;\n  settings->nIterLim = INT_MAX;  // INFINITY cause bug on MacOS\n  settings->nLogLevel = 2; // Ensures that, by default, cuPDLP-C printing is unchanged\n  settings->nLogInterval = 100;\n  // settings->dTimeLim = INFINITY;\n  settings->dTimeLim = 3600;\n  settings->ifScaling = true;\n  settings->iScalingMethod = 3;  // no use\n  settings->dScalingLimit = 5;   // no use\n  settings->eRestartMethod = PDHG_GPU_RESTART;\n\n  // termination criteria\n  settings->dPrimalTol = 1e-4;\n  settings->dDualTol = 1e-4;\n  settings->dGapTol = 1e-4;\n\n  return retcode;\n}\n\ncupdlp_retcode resobj_Alloc(CUPDLPresobj *resobj, CUPDLPproblem *problem,\n                            cupdlp_int ncols, cupdlp_int nrows) {\n  cupdlp_retcode retcode = RETCODE_OK;\n\n#if !defined(CUPDLP_CPU) && USE_KERNELS\n  resobj->primalResidual = NULL;\n  resobj->dualResidual = NULL;\n  resobj->primalResidualAverage = NULL;\n  resobj->dualResidualAverage = NULL;\n#else\n\n  cupdlp_init_zero_vec_double(resobj->primalResidual, nrows);\n  cupdlp_init_zero_vec_double(resobj->dualResidual, ncols);\n  cupdlp_init_zero_vec_double(resobj->primalResidualAverage, nrows);\n  cupdlp_init_zero_vec_double(resobj->dualResidualAverage, ncols);\n\n#endif\n\n  cupdlp_init_zero_vec_double(resobj->dSlackPos, ncols);\n  cupdlp_init_zero_vec_double(resobj->dSlackNeg, ncols);\n  cupdlp_init_zero_vec_double(resobj->dSlackPosAverage, ncols);\n  cupdlp_init_zero_vec_double(resobj->dSlackNegAverage, ncols);\n  cupdlp_init_zero_vec_double(resobj->dLowerFiltered, ncols);\n  cupdlp_init_zero_vec_double(resobj->dUpperFiltered, ncols);\n\n#if !defined(CUPDLP_CPU) && USE_KERNELS\n  resobj->primalInfeasRay = NULL;\n  resobj->primalInfeasConstr = NULL;\n  resobj->primalInfeasBound = NULL;\n  resobj->dualInfeasRay = NULL;\n  resobj->dualInfeasLbRay = NULL;\n  resobj->dualInfeasUbRay = NULL;\n#else\n\n  cupdlp_init_zero_vec_double(resobj->primalInfeasRay, ncols);\n  cupdlp_init_zero_vec_double(resobj->primalInfeasConstr, nrows);\n  cupdlp_init_zero_vec_double(resobj->primalInfeasBound, ncols);\n  cupdlp_init_zero_vec_double(resobj->dualInfeasRay, nrows);\n  cupdlp_init_zero_vec_double(resobj->dualInfeasLbRay, ncols);\n  cupdlp_init_zero_vec_double(resobj->dualInfeasUbRay, ncols);\n#endif\n\n\n#if !defined(CUPDLP_CPU) && USE_KERNELS\n  resobj->dualInfeasConstr = NULL;\n#else\n  cupdlp_init_zero_vec_double(resobj->dualInfeasConstr, ncols);\n#endif\n\n  // CUPDLP_INIT_DOUBLE_ZERO_VEC(resobj->dualInfeasBound, nrows);\n\n  cupdlp_filterlb(resobj->dLowerFiltered, problem->lower, -INFINITY, ncols);\n  cupdlp_filterub(resobj->dUpperFiltered, problem->upper, +INFINITY, ncols);\n\n  // initialization\n  resobj->dFeasTol = 1e-8;\n  resobj->dPrimalObj = 0.0;\n  resobj->dDualObj = 0.0;\n  resobj->dDualityGap = 0.0;\n  resobj->dComplementarity = 0.0;\n  resobj->dPrimalFeas = 0.0;\n  resobj->dDualFeas = 0.0;\n  resobj->dRelObjGap = 0.0;\n  resobj->dPrimalObjAverage = 0.0;\n  resobj->dDualObjAverage = 0.0;\n  resobj->dDualityGapAverage = 0.0;\n  resobj->dComplementarityAverage = 0.0;\n  resobj->dPrimalFeasAverage = 0.0;\n  resobj->dDualFeasAverage = 0.0;\n  resobj->dRelObjGapAverage = 0.0;\n  resobj->dPrimalFeasLastRestart = 0.0;\n  resobj->dDualFeasLastRestart = 0.0;\n  resobj->dDualityGapLastRestart = 0.0;\n  resobj->dPrimalFeasLastCandidate = 0.0;\n  resobj->dDualFeasLastCandidate = 0.0;\n  resobj->dDualityGapLastCandidate = 0.0;\n\n  resobj->primalCode = FEASIBLE;\n  resobj->dualCode = FEASIBLE;\n  resobj->termInfeasIterate = LAST_ITERATE;\n  resobj->dPrimalInfeasObj = 0.0;\n  resobj->dDualInfeasObj = 0.0;\n  resobj->dPrimalInfeasRes = 1.0;\n  resobj->dDualInfeasRes = 1.0;\n  resobj->dPrimalInfeasObjAverage = 0.0;\n  resobj->dDualInfeasObjAverage = 0.0;\n  resobj->dPrimalInfeasResAverage = 1.0;\n  resobj->dDualInfeasResAverage = 1.0;\n\n  resobj->termCode = TIMELIMIT_OR_ITERLIMIT;\n  resobj->termIterate = LAST_ITERATE;\n\n  // todo, pass work\n  //   cupdlp_twoNorm(problem->cost, ncols, &resobj->dNormCost);\n  //   twoNorm(problem->rhs, nrows);\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode iterates_Alloc(CUPDLPiterates *iterates, cupdlp_int ncols,\n                              cupdlp_int nrows) {\n  cupdlp_retcode retcode = RETCODE_OK;\n\n  iterates->nCols = ncols;\n  iterates->nRows = nrows;\n\n  cupdlp_init_zero_vec_double(iterates->xSum, ncols);\n  cupdlp_init_zero_vec_double(iterates->ySum, nrows);\n  cupdlp_init_zero_vec_double(iterates->xLastRestart, ncols);\n  cupdlp_init_zero_vec_double(iterates->yLastRestart, nrows);\n\n  CUPDLP_INIT_CUPDLP_VEC(iterates->x[0], 1);\n  CUPDLP_INIT_CUPDLP_VEC(iterates->x[1], 1);\n  CUPDLP_INIT_CUPDLP_VEC(iterates->xAverage, 1);\n  CUPDLP_INIT_CUPDLP_VEC(iterates->y[0], 1);\n  CUPDLP_INIT_CUPDLP_VEC(iterates->y[1], 1);\n  CUPDLP_INIT_CUPDLP_VEC(iterates->yAverage, 1);\n  CUPDLP_INIT_CUPDLP_VEC(iterates->ax[0], 1);\n  CUPDLP_INIT_CUPDLP_VEC(iterates->ax[1], 1);\n  CUPDLP_INIT_CUPDLP_VEC(iterates->axAverage, 1);\n  CUPDLP_INIT_CUPDLP_VEC(iterates->aty[0], 1);\n  CUPDLP_INIT_CUPDLP_VEC(iterates->aty[1], 1);\n  CUPDLP_INIT_CUPDLP_VEC(iterates->atyAverage, 1);\n\n  CUPDLP_CALL(vec_Alloc(iterates->x[0], ncols));\n  CUPDLP_CALL(vec_Alloc(iterates->x[1], ncols));\n  CUPDLP_CALL(vec_Alloc(iterates->xAverage, ncols));\n  CUPDLP_CALL(vec_Alloc(iterates->y[0], nrows));\n  CUPDLP_CALL(vec_Alloc(iterates->y[1], nrows));\n  CUPDLP_CALL(vec_Alloc(iterates->yAverage, nrows));\n  CUPDLP_CALL(vec_Alloc(iterates->ax[0], nrows));\n  CUPDLP_CALL(vec_Alloc(iterates->ax[1], nrows));\n  CUPDLP_CALL(vec_Alloc(iterates->axAverage, nrows));\n  CUPDLP_CALL(vec_Alloc(iterates->aty[0], ncols));\n  CUPDLP_CALL(vec_Alloc(iterates->aty[1], ncols));\n  CUPDLP_CALL(vec_Alloc(iterates->atyAverage, ncols));\n\n  // initialization\n  iterates->iLastRestartIter = 0;\n  iterates->dLastRestartDualityGap = 0.0;\n  iterates->dLastRestartBeta = 0.0;\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode stepsize_Alloc(CUPDLPstepsize *stepsize) {\n  cupdlp_retcode retcode = RETCODE_OK;\n\n  stepsize->eLineSearchMethod = PDHG_ADAPTIVE_LINESEARCH;\n\n  // initialization\n  stepsize->nStepSizeIter = 0;\n  stepsize->dPrimalStep = 0.0;\n  stepsize->dDualStep = 0.0;\n  stepsize->dSumPrimalStep = 0.0;\n  stepsize->dSumDualStep = 0.0;\n  stepsize->dBeta = 0.0;\n  stepsize->dTheta = 0.0;\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode timers_Alloc(CUPDLPtimers *timers) {\n  cupdlp_retcode retcode = RETCODE_OK;\n\n  timers->nIter = 0;\n  timers->dSolvingTime = 0.0;\n  timers->dSolvingBeg = 0.0;\n  timers->dScalingTime = 0.0;\n  timers->dPresolveTime = 0.0;\n\n#if PDHG_USE_TIMERS\n  timers->dAtyTime = 0.0;\n  timers->dAxTime = 0.0;\n  timers->dComputeResidualsTime = 0.0;\n  timers->dUpdateIterateTime = 0.0;\n  timers->nAtyCalls = 0;\n  timers->nAxCalls = 0;\n  timers->nComputeResidualsCalls = 0;\n  timers->nUpdateIterateCalls = 0;\n#endif\n#ifndef CUPDLP_CPU\n  // GPU timers\n  timers->AllocMem_CopyMatToDeviceTime = 0.0;\n  timers->CopyVecToDeviceTime = 0.0;\n  timers->DeviceMatVecProdTime = 0.0;\n  timers->CopyVecToHostTime = 0.0;\n  timers->FreeDeviceMemTime = 0.0;\n  timers->CudaPrepareTime = 0.0;\n#endif\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode vec_Alloc(CUPDLPvec *vec, cupdlp_int n) {\n  cupdlp_retcode retcode = RETCODE_OK;\n  cupdlp_init_zero_vec_double(vec->data, n);\n  vec->len = n;\n#ifndef CUPDLP_CPU\n  CHECK_CUSPARSE(\n      cusparseCreateDnVec(&vec->cuda_vec, n, vec->data, CudaComputeType))\n#endif\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode PDHG_Alloc(CUPDLPwork *w) {\n  cupdlp_retcode retcode = RETCODE_OK;\n\n  CUPDLP_INIT_SETTINGS(w->settings, 1);\n  CUPDLP_INIT_RESOBJ(w->resobj, 1);\n  CUPDLP_INIT_ITERATES(w->iterates, 1);\n  CUPDLP_INIT_STEPSIZE(w->stepsize, 1);\n\n  CUPDLP_INIT_TIMERS(w->timers, 1);\n  CUPDLP_CALL(timers_Alloc(w->timers));\n\n  cupdlp_float begin = getTimeStamp();\n  // buffer\n  CUPDLP_INIT_CUPDLP_VEC(w->buffer, 1);\n  CUPDLP_CALL(vec_Alloc(w->buffer, w->problem->data->nRows));\n\n\n  cupdlp_init_zero_vec_double(w->buffer2,\n                       MAX(2048, MAX(w->problem->data->nCols, w->problem->data->nRows)));\n#if defined(CUPDLP_CPU) || !(USE_KERNELS) || (CUPDLP_DUMP_LINESEARCH_STATS && CUPDLP_DEBUG)\n  cupdlp_init_zero_vec_double(w->buffer3,\n                       MAX(2048, MAX(w->problem->data->nCols, w->problem->data->nRows)));\n#else\n  w->buffer3 = NULL;\n#endif\n\n  // for scaling\n  cupdlp_init_zero_vec_double(w->colScale, w->problem->data->nCols);\n  cupdlp_init_zero_vec_double(w->rowScale, w->problem->data->nRows);\n\n  CUPDLP_CALL(settings_Alloc(w->settings));\n  CUPDLP_CALL(resobj_Alloc(w->resobj, w->problem, w->problem->data->nCols,\n                           w->problem->data->nRows));\n  CUPDLP_CALL(iterates_Alloc(w->iterates, w->problem->data->nCols,\n                             w->problem->data->nRows));\n  CUPDLP_CALL(stepsize_Alloc(w->stepsize));\n\n#ifndef CUPDLP_CPU\n  //   CHECK_CUSPARSE(cusparseCreate(&w->cusparsehandle));\n  //   CHECK_CUBLAS(cublasCreate(&w->cublashandle));\n  CUPDLP_CALL(cuda_alloc_MVbuffer(\n      //   w->problem->data->matrix_format,\n      w->cusparsehandle, w->problem->data->csc_matrix->cuda_csc,\n      w->iterates->x[0]->cuda_vec, w->iterates->ax[0]->cuda_vec,\n      w->problem->data->csr_matrix->cuda_csr, w->iterates->y[0]->cuda_vec,\n      w->iterates->aty[0]->cuda_vec, &w->dBuffer_csc_ATy, &w->dBuffer_csr_Ax))\n  w->timers->AllocMem_CopyMatToDeviceTime += getTimeStamp() - begin;\n#endif\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode PDHG_Create(CUPDLPwork **ww, CUPDLPproblem *lp,\n                           CUPDLPscaling *scaling) {\n  cupdlp_retcode retcode = RETCODE_OK;\n  CUPDLP_INIT_ZERO_CUPDLP_WORK(*ww, 1);\n\n  CUPDLPwork *w = *ww;\n  w->problem = lp;\n  w->scaling = scaling;\n\nexit_cleanup:\n  return retcode;\n}\n\nvoid PDHG_Destroy(CUPDLPwork **w) {\n  if (w && *w) {\n    PDHG_Clear(*w);\n  }\n}\n\nvoid PDHG_Init_Data(CUPDLPwork *work) {}\n\n// double my_clock(void) {\n\n// #ifdef CUPDLP_TIMER\n\n// #if defined(_WIN32) || defined(_WIN64)\n//   return (double)clock() / CLOCKS_PER_SEC;\n// #else\n//   struct timeval t;\n//   gettimeofday(&t, NULL);\n//   return (1e-06 * t.tv_usec + t.tv_sec);\n// #endif\n\n// #else\n//   return 0;\n// #endif\n\n// }\n\n\ndouble my_clock(void) {\n#ifdef CUPDLP_TIMER\n  // struct timeval t;\n  // clock_gettime(&t, NULL);\n  // gettimeofday(&t, NULL);\n  double timeee = 0;\n\n#ifndef WIN32\n  timeee = time(NULL);\n#else\n  timeee = clock();\n#endif\n\n  return timeee;\n  // return (1e-06 * t.tv_usec + t.tv_sec);\n#else\n  return 0;\n#endif\n}\n\ndouble getTimeStamp(void) { return my_clock(); }\n\nvoid dense_copy(CUPDLPdense *dst, CUPDLPdense *src) {\n  dst->nRows = src->nRows;\n  dst->nCols = src->nCols;\n  cupdlp_copy(dst->data, src->data, cupdlp_float, src->nRows * src->nCols);\n\n  return;\n}\n\nvoid csr_copy(CUPDLPcsr *dst, CUPDLPcsr *src) {\n  dst->nRows = src->nRows;\n  dst->nCols = src->nCols;\n  dst->nMatElem = src->nMatElem;\n  cupdlp_copy(dst->rowMatBeg, src->rowMatBeg, cupdlp_int, src->nRows + 1);\n  cupdlp_copy(dst->rowMatIdx, src->rowMatIdx, cupdlp_int, src->nMatElem);\n  cupdlp_copy(dst->rowMatElem, src->rowMatElem, cupdlp_float, src->nMatElem);\n\n  return;\n}\n\ncupdlp_int csc_copy(CUPDLPcsc *dst, CUPDLPcsc *src) {\n  dst->nRows = src->nRows;\n  dst->nCols = src->nCols;\n  dst->nMatElem = src->nMatElem;\n  CUPDLP_COPY_VEC(dst->colMatBeg, src->colMatBeg, cupdlp_int, src->nCols + 1);\n  CUPDLP_COPY_VEC(dst->colMatIdx, src->colMatIdx, cupdlp_int, src->nMatElem);\n  CUPDLP_COPY_VEC(dst->colMatElem, src->colMatElem, cupdlp_float,\n                  src->nMatElem);\n\n#ifndef CUPDLP_CPU\n  // Pointer to GPU csc matrix\n  CHECK_CUSPARSE(cusparseCreateCsc(\n      &dst->cuda_csc, src->nRows, src->nCols, src->nMatElem, dst->colMatBeg,\n      dst->colMatIdx, dst->colMatElem, CUSPARSE_INDEX_32I, CUSPARSE_INDEX_32I,\n      CUSPARSE_INDEX_BASE_ZERO, CudaComputeType));\n#endif\n\n  return 0;\n}\n\nvoid csr2csc(CUPDLPcsc *csc, CUPDLPcsr *csr) {\n  cupdlp_dcs *cs_csr =\n      cupdlp_dcs_spalloc(csr->nCols, csc->nRows, csc->nMatElem, 1, 0);\n  cupdlp_copy(cs_csr->p, csr->rowMatBeg, cupdlp_int, csr->nRows + 1);\n  cupdlp_copy(cs_csr->i, csr->rowMatIdx, cupdlp_int, csr->nMatElem);\n  cupdlp_copy(cs_csr->x, csr->rowMatElem, cupdlp_float, csr->nMatElem);\n\n  cupdlp_dcs *cs_csc = cupdlp_dcs_transpose(cs_csr, 1);\n  csc->nCols = cs_csc->m;\n  csc->nRows = cs_csc->n;\n  csc->nMatElem = cs_csc->nzmax;\n  cupdlp_copy(csc->colMatBeg, cs_csc->p, cupdlp_int, cs_csc->n + 1);\n  cupdlp_copy(csc->colMatIdx, cs_csc->i, cupdlp_int, cs_csc->nzmax);\n  cupdlp_copy(csc->colMatElem, cs_csc->x, cupdlp_float, cs_csc->nzmax);\n\n  // cupdlp_dcs_free(cs_csc);\n  // cupdlp_dcs_free(cs_csr);\n  cupdlp_dcs_spfree(cs_csc);\n  cupdlp_dcs_spfree(cs_csr);\n\n  return;\n}\n\ncupdlp_int csc2csr(CUPDLPcsr *csr, CUPDLPcsc *csc) {\n  // The transpose may need to be done on the GPU\n  // Currently, it is done on the CPU\n\n  cupdlp_dcs *cs_csc =\n      cupdlp_dcs_spalloc(csc->nRows, csc->nCols, csc->nMatElem, 1, 0);\n  cupdlp_copy(cs_csc->p, csc->colMatBeg, cupdlp_int, csc->nCols + 1);\n  cupdlp_copy(cs_csc->i, csc->colMatIdx, cupdlp_int, csc->nMatElem);\n  cupdlp_copy(cs_csc->x, csc->colMatElem, cupdlp_float, csc->nMatElem);\n\n  cupdlp_dcs *cs_csr = cupdlp_dcs_transpose(cs_csc, 1);\n  csr->nCols = cs_csr->m;\n  csr->nRows = cs_csr->n;\n  csr->nMatElem = cs_csr->nzmax;\n  CUPDLP_COPY_VEC(csr->rowMatBeg, cs_csr->p, cupdlp_int, cs_csr->n + 1);\n  CUPDLP_COPY_VEC(csr->rowMatIdx, cs_csr->i, cupdlp_int, cs_csr->nzmax);\n  CUPDLP_COPY_VEC(csr->rowMatElem, cs_csr->x, cupdlp_float, cs_csr->nzmax);\n\n  // cupdlp_dcs_free(cs_csc);\n  // cupdlp_dcs_free(cs_csr);\n  cupdlp_dcs_spfree(cs_csc);\n  cupdlp_dcs_spfree(cs_csr);\n\n#ifndef CUPDLP_CPU\n  // Pointer to GPU csc matrix\n  CHECK_CUSPARSE(cusparseCreateCsr(\n      &csr->cuda_csr, csr->nRows, csr->nCols, csr->nMatElem, csr->rowMatBeg,\n      csr->rowMatIdx, csr->rowMatElem, CUSPARSE_INDEX_32I, CUSPARSE_INDEX_32I,\n      CUSPARSE_INDEX_BASE_ZERO, CudaComputeType));\n#endif\n\n  return 0;\n}\n\nvoid dense2csr(CUPDLPcsr *csr, CUPDLPdense *dense) {\n  csr->nRows = dense->nRows;\n  csr->nCols = dense->nCols;\n\n  cupdlp_int nnz = 0;\n  cupdlp_int iCol = 0;\n  cupdlp_int iRow = 0;\n  csr->rowMatBeg[0] = 0;\n  for (iRow = 0; iRow < csr->nRows; ++iRow) {\n    for (iCol = 0; iCol < csr->nCols; ++iCol) {\n      if (dense->data[iCol * csr->nRows + iRow] != 0) {\n        csr->rowMatIdx[nnz] = iCol;\n        csr->rowMatElem[nnz] = dense->data[iCol * csr->nRows + iRow];\n        ++nnz;\n      }\n    }\n    csr->rowMatBeg[iRow + 1] = nnz;\n  }\n  csr->nMatElem = nnz;\n\n  return;\n}\n\nvoid dense2csc(CUPDLPcsc *csc, CUPDLPdense *dense) {\n  csc->nRows = dense->nRows;\n  csc->nCols = dense->nCols;\n\n  cupdlp_int nnz = 0;\n  cupdlp_int iCol = 0;\n  cupdlp_int iRow = 0;\n  csc->colMatBeg[0] = 0;\n  for (iCol = 0; iCol < csc->nCols; ++iCol) {\n    for (iRow = 0; iRow < csc->nRows; ++iRow) {\n      if (dense->data[iCol * csc->nRows + iRow] != 0) {\n        csc->colMatIdx[nnz] = iRow;\n        csc->colMatElem[nnz] = dense->data[iCol * csc->nRows + iRow];\n        ++nnz;\n      }\n    }\n    csc->colMatBeg[iCol + 1] = nnz;\n  }\n\n  csc->nMatElem = nnz;\n\n  return;\n}\n\nvoid csr2dense(CUPDLPdense *dense, CUPDLPcsr *csr) {\n  dense->nRows = csr->nRows;\n  dense->nCols = csr->nCols;\n\n  cupdlp_int iRow = 0;\n  cupdlp_int iCol = 0;\n  cupdlp_int iMatElem = 0;\n  for (iRow = 0; iRow < dense->nRows; ++iRow)\n    for (iCol = 0; iCol < dense->nCols; ++iCol) {\n      if (iCol == csr->rowMatIdx[iMatElem]) {\n        dense->data[iRow * dense->nCols + iCol] = csr->rowMatElem[iMatElem];\n        ++iMatElem;\n      } else {\n        dense->data[iRow * dense->nCols + iCol] = 0;\n      }\n    }\n\n  return;\n}\n\nvoid csc2dense(CUPDLPdense *dense, CUPDLPcsc *csc) {\n  dense->nRows = csc->nRows;\n  dense->nCols = csc->nCols;\n\n  cupdlp_int iRow = 0;\n  cupdlp_int iCol = 0;\n  cupdlp_int iMatElem = 0;\n  for (iCol = 0; iCol < dense->nCols; ++iCol)\n    for (iRow = 0; iRow < dense->nRows; ++iRow) {\n      if (iRow == csc->colMatIdx[iMatElem]) {\n        dense->data[iRow * dense->nCols + iCol] = csc->colMatElem[iMatElem];\n        ++iMatElem;\n      } else {\n        dense->data[iRow * dense->nCols + iCol] = 0;\n      }\n    }\n\n  return;\n}\n\ncupdlp_retcode dense_create(CUPDLPdense **dense) {\n  cupdlp_retcode retcode = RETCODE_OK;\n  CUPDLP_INIT_DENSE_MATRIX(*dense, 1);\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode csr_create(CUPDLPcsr **csr) {\n  cupdlp_retcode retcode = RETCODE_OK;\n  CUPDLP_INIT_CSR_MATRIX(*csr, 1);\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode csc_create(CUPDLPcsc **csc) {\n  cupdlp_retcode retcode = RETCODE_OK;\n\n  CUPDLP_INIT_CSC_MATRIX(*csc, 1);\n\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode dense_alloc_matrix(CUPDLPdense *dense, cupdlp_int nRows,\n                                  cupdlp_int nCols, void *src,\n                                  CUPDLP_MATRIX_FORMAT src_matrix_format) {\n  cupdlp_retcode retcode = RETCODE_OK;\n  cupdlp_init_zero_vec_double(dense->data, nRows * nCols);\n\n  switch (src_matrix_format) {\n    case DENSE:\n      dense_copy(dense, (CUPDLPdense *)src);\n      break;\n    case CSR:\n      csr2dense(dense, (CUPDLPcsr *)src);\n      break;\n    case CSC:\n      csc2dense(dense, (CUPDLPcsc *)src);\n      break;\n    default:\n      break;\n  }\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode csr_alloc_matrix(CUPDLPcsr *csr, cupdlp_int nRows,\n                                cupdlp_int nCols, void *src,\n                                CUPDLP_MATRIX_FORMAT src_matrix_format) {\n  cupdlp_retcode retcode = RETCODE_OK;\n  cupdlp_int nnz = 0;\n  switch (src_matrix_format) {\n    case DENSE:\n      nnz = nRows * nCols;\n      break;\n    case CSR:\n      nnz = ((CUPDLPcsr *)src)->nMatElem;\n      break;\n    case CSC:\n      nnz = ((CUPDLPcsc *)src)->nMatElem;\n      break;\n    default:\n      break;\n  }\n  // todo make sure this is right\n  cupdlp_init_zero_vec_int(csr->rowMatBeg, nRows + 1);\n  cupdlp_init_zero_vec_int(csr->rowMatIdx, nnz);\n  cupdlp_init_zero_vec_double(csr->rowMatElem, nnz);\n\n  switch (src_matrix_format) {\n    case DENSE:\n      dense2csr(csr, (CUPDLPdense *)src);\n      break;\n    case CSR:\n      csr_copy(csr, (CUPDLPcsr *)src);\n      break;\n    case CSC:\n      csc2csr(csr, (CUPDLPcsc *)src);\n      break;\n    default:\n      break;\n  }\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode csc_alloc_matrix(CUPDLPcsc *csc, cupdlp_int nRows,\n                                cupdlp_int nCols, void *src,\n                                CUPDLP_MATRIX_FORMAT src_matrix_format) {\n  cupdlp_retcode retcode = RETCODE_OK;\n  cupdlp_int nnz = 0;\n  switch (src_matrix_format) {\n    case DENSE:\n      nnz = nRows * nCols;\n      break;\n    case CSR:\n      nnz = ((CUPDLPcsr *)src)->nMatElem;\n      break;\n    case CSC:\n      nnz = ((CUPDLPcsc *)src)->nMatElem;\n      break;\n    default:\n      break;\n  }\n\n  cupdlp_init_zero_vec_int(csc->colMatBeg, nCols + 1);\n  cupdlp_init_zero_vec_int(csc->colMatIdx, nnz);\n  cupdlp_init_zero_vec_double(csc->colMatElem, nnz);\n\n  switch (src_matrix_format) {\n    case DENSE:\n      dense2csc(csc, (CUPDLPdense *)src);\n      break;\n    case CSR:\n      csr2csc(csc, (CUPDLPcsr *)src);\n      break;\n    case CSC:\n      csc_copy(csc, (CUPDLPcsc *)src);\n      break;\n    default:\n      break;\n  }\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode dense_alloc(CUPDLPdense *dense, cupdlp_int nRows,\n                           cupdlp_int nCols, cupdlp_float *val) {\n  cupdlp_retcode retcode = RETCODE_OK;\n  dense->nRows = nRows;\n  dense->nCols = nCols;\n  dense->data = cupdlp_NULL;\n  cupdlp_init_zero_vec_double(dense->data, nRows * nCols);\n\n  CUPDLP_COPY_VEC(dense->data, val, cupdlp_float, nRows * nCols);\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode csr_alloc(CUPDLPcsr *csr, cupdlp_int nRows, cupdlp_int nCols,\n                         cupdlp_int nnz, cupdlp_int *row_ptr,\n                         cupdlp_int *col_ind, cupdlp_float *val) {\n  cupdlp_retcode retcode = RETCODE_OK;\n  csr->nRows = nRows;\n  csr->nCols = nCols;\n  csr->nMatElem = nnz;\n  csr->rowMatBeg = cupdlp_NULL;\n  csr->rowMatIdx = cupdlp_NULL;\n  csr->rowMatElem = cupdlp_NULL;\n\n  cupdlp_init_zero_vec_int(csr->rowMatBeg, nRows + 1);\n  cupdlp_init_zero_vec_int(csr->rowMatIdx, nnz);\n  cupdlp_init_zero_vec_double(csr->rowMatElem, nnz);\n\n  CUPDLP_COPY_VEC(csr->rowMatBeg, row_ptr, cupdlp_int, nRows + 1);\n  CUPDLP_COPY_VEC(csr->rowMatIdx, col_ind, cupdlp_int, nnz);\n  CUPDLP_COPY_VEC(csr->rowMatElem, val, cupdlp_float, nnz);\nexit_cleanup:\n  return retcode;\n}\n\ncupdlp_retcode csc_alloc(CUPDLPcsc *csc, cupdlp_int nRows, cupdlp_int nCols,\n                         cupdlp_int nnz, cupdlp_int *col_ptr,\n                         cupdlp_int *row_ind, cupdlp_float *val) {\n  cupdlp_retcode retcode = RETCODE_OK;\n  csc->nRows = nRows;\n  csc->nCols = nCols;\n  csc->nMatElem = nnz;\n  csc->colMatBeg = cupdlp_NULL;\n  csc->colMatIdx = cupdlp_NULL;\n  csc->colMatElem = cupdlp_NULL;\n  cupdlp_init_zero_vec_int(csc->colMatBeg, nCols + 1);\n  cupdlp_init_zero_vec_int(csc->colMatIdx, nnz);\n  cupdlp_init_zero_vec_double(csc->colMatElem, nnz);\n\n  CUPDLP_COPY_VEC(csc->colMatBeg, col_ptr, cupdlp_int, nCols + 1);\n  CUPDLP_COPY_VEC(csc->colMatIdx, row_ind, cupdlp_int, nnz);\n  CUPDLP_COPY_VEC(csc->colMatElem, val, cupdlp_float, nnz);\nexit_cleanup:\n  return retcode;\n}\n\nvoid vecPrint(const char *s, const cupdlp_float *a, cupdlp_int n) {\n  cupdlp_printf(\"%s: \", s);\n  for (cupdlp_int i = 0; i < n; ++i) {\n    cupdlp_printf(\"%.3f \", a[i]);\n  }\n  cupdlp_printf(\"\\n\");\n}\n\nvoid vecIntPrint(const char *s, const cupdlp_int *a, cupdlp_int n) {\n  cupdlp_printf(\"%s: \", s);\n  for (cupdlp_int i = 0; i < n; ++i) {\n    cupdlp_printf(\"%d \", a[i]);\n  }\n  cupdlp_printf(\"\\n\");\n}\n\nvoid PDHG_Dump_Stats(CUPDLPwork *w) {\n  cupdlp_int nCols = w->iterates->nCols;\n  cupdlp_int nRows = w->iterates->nRows;\n  CUPDLPiterates *iterates = w->iterates;\n  CUPDLPstepsize *stepsize = w->stepsize;\n\n  cupdlp_printf(\"------------------------------------------------\\n\");\n  cupdlp_printf(\"Iteration % 3d\\n\", w->timers->nIter);\n#if CUPDLP_DUMP_ITERATES\n  cupdlp_int iter = w->timers->nIter;\n  CUPDLPvec *x = iterates->x[iter % 2];\n  CUPDLPvec *y = iterates->y[iter % 2];\n  CUPDLPvec *aty = iterates->aty[iter % 2];\n\n  vecPrint(\"x\", x->data, nCols);\n  vecPrint(\"y\", y->data, nRows);\n  vecPrint(\"xSum\", iterates->xSum, nCols);\n  vecPrint(\"ySum\", iterates->ySum, nRows);\n  vecPrint(\"Ax \", ax->data, nRows);\n  vecPrint(\"A'y\", aty->data, nCols);\n  vecPrint(\"xLastRestart\", iterates->xLastRestart, nCols);\n  vecPrint(\"yLastRestart\", iterates->yLastRestart, nRows);\n#endif\n  cupdlp_printf(\n      \"PrimalStep: %e, SumPrimalStep: %e, DualStep: %e, SumDualStep: %e\\n\",\n      stepsize->dPrimalStep, stepsize->dSumPrimalStep, stepsize->dDualStep,\n      stepsize->dSumDualStep);\n  cupdlp_printf(\"Stepsize: %e, Primal weight: %e Ratio: %e\\n\",\n                sqrt(stepsize->dPrimalStep * stepsize->dDualStep),\n                sqrt(stepsize->dBeta), stepsize->dTheta);\n}\n\nvoid csrPrintDense(const char *s, CUPDLPcsr *csr) {\n  cupdlp_printf(\"------------------------------------------------\\n\");\n  cupdlp_printf(\"%s:\\n\", s);\n  cupdlp_int deltaCol = 0;\n  for (cupdlp_int iRow = 0; iRow < csr->nRows; ++iRow) {\n    for (cupdlp_int iElem = csr->rowMatBeg[iRow];\n         iElem < csr->rowMatBeg[iRow + 1]; ++iElem) {\n      if (iElem == csr->rowMatBeg[iRow])\n        deltaCol = csr->rowMatIdx[iElem];\n      else\n        deltaCol = csr->rowMatIdx[iElem] - csr->rowMatIdx[iElem - 1] - 1;\n      for (cupdlp_int i = 0; i < deltaCol; ++i) {\n        cupdlp_printf(\"       \");\n      }\n      cupdlp_printf(\"%6.3f \", csr->rowMatElem[iElem]);\n    }\n    cupdlp_printf(\"\\n\");\n  }\n  cupdlp_printf(\"------------------------------------------------\\n\");\n}\n\nvoid cscPrintDense(const char *s, CUPDLPcsc *csc) {\n  cupdlp_printf(\"------------------------------------------------\\n\");\n  cupdlp_printf(\"%s (Trans):\\n\", s);\n  cupdlp_int deltaRow = 0;\n  for (cupdlp_int iCol = 0; iCol < csc->nCols; ++iCol) {\n    for (cupdlp_int iElem = csc->colMatBeg[iCol];\n         iElem < csc->colMatBeg[iCol + 1]; ++iElem) {\n      if (iElem == csc->colMatBeg[iCol])\n        deltaRow = csc->colMatIdx[iElem];\n      else\n        deltaRow = csc->colMatIdx[iElem] - csc->colMatIdx[iElem - 1] - 1;\n      for (cupdlp_int i = 0; i < deltaRow; ++i) {\n        cupdlp_printf(\"       \");\n      }\n      cupdlp_printf(\"%6.3f \", csc->colMatElem[iElem]);\n    }\n    cupdlp_printf(\"\\n\");\n  }\n  cupdlp_printf(\"------------------------------------------------\\n\");\n}\n\n#ifndef CUPDLP_OUTPUT_NAMES\nconst char *termCodeNames[] = {\"OPTIMAL\",\n                               \"INFEASIBLE\",\n                               \"UNBOUNDED\",\n                               \"INFEASIBLE_OR_UNBOUNDED\",\n                               \"TIMELIMIT_OR_ITERLIMIT\",\n                               \"FEASIBLE\"};\nconst char *termIterateNames[] = {\n    \"LAST_ITERATE\",\n    \"AVERAGE_ITERATE\",\n};\n#endif\n\nvoid writeJson(const char *fout, CUPDLPwork *work) {\n  FILE *fptr;\n\n  cupdlp_printf(\"--------------------------------\\n\");\n  cupdlp_printf(\"--- saving to %s\\n\", fout);\n  cupdlp_printf(\"--------------------------------\\n\");\n  // Open a file in writing mode\n  fptr = fopen(fout, \"w\");\n\n  fprintf(fptr, \"{\");\n\n  // solver\n  fprintf(fptr, \"\\\"solver\\\":\\\"%s\\\",\", \"cuPDLP-C\");\n\n  // timers\n  fprintf(fptr, \"\\\"nIter\\\":%d,\", work->timers->nIter);\n  fprintf(fptr, \"\\\"nAtyCalls\\\":%d,\", work->timers->nAtyCalls);\n  fprintf(fptr, \"\\\"nAxCalls\\\":%d,\", work->timers->nAxCalls);\n  fprintf(fptr, \"\\\"dSolvingBeg\\\":%f,\", work->timers->dSolvingBeg);\n  fprintf(fptr, \"\\\"dSolvingTime\\\":%f,\", work->timers->dSolvingTime);\n  fprintf(fptr, \"\\\"dPresolveTime\\\":%f,\", work->timers->dPresolveTime);\n  fprintf(fptr, \"\\\"dScalingTime\\\":%f,\", work->timers->dScalingTime);\n#ifndef CUPDLP_CPU\n  fprintf(fptr, \"\\\"AllocMem_CopyMatToDeviceTime\\\":%f,\",\n          work->timers->AllocMem_CopyMatToDeviceTime);\n  fprintf(fptr, \"\\\"CopyVecToDeviceTime\\\":%f,\",\n          work->timers->CopyVecToDeviceTime);\n  fprintf(fptr, \"\\\"CopyVecToHostTime\\\":%f,\", work->timers->CopyVecToHostTime);\n  fprintf(fptr, \"\\\"DeviceMatVecProdTime\\\":%f,\",\n          work->timers->DeviceMatVecProdTime);\n#endif\n  // residuals\n  fprintf(fptr, \"\\\"dPrimalObj\\\":%.14f,\", work->resobj->dPrimalObj);\n  fprintf(fptr, \"\\\"dDualObj\\\":%.14f,\", work->resobj->dDualObj);\n  fprintf(fptr, \"\\\"dPrimalFeas\\\":%.14f,\", work->resobj->dPrimalFeas);\n  fprintf(fptr, \"\\\"dDualFeas\\\":%.14f,\", work->resobj->dDualFeas);\n  fprintf(fptr, \"\\\"dPrimalObjAverage\\\":%.14f,\",\n          work->resobj->dPrimalObjAverage);\n  fprintf(fptr, \"\\\"dDualObjAverage\\\":%.14f,\", work->resobj->dDualObjAverage);\n  fprintf(fptr, \"\\\"dPrimalFeasAverage\\\":%.14f,\",\n          work->resobj->dPrimalFeasAverage);\n  fprintf(fptr, \"\\\"dDualFeasAverage\\\":%.14f,\", work->resobj->dDualFeasAverage);\n  fprintf(fptr, \"\\\"dDualityGap\\\":%.14f,\", work->resobj->dDualityGap);\n  fprintf(fptr, \"\\\"dDualityGapAverage\\\":%.14f,\",\n          work->resobj->dDualityGapAverage);\n  // fprintf(fptr, \"\\\"dComplementarity\\\":%.14f,\",\n  // work->resobj->dComplementarity); fprintf(fptr,\n  // \"\\\"dComplementarityAverage\\\":%.14f,\",\n  //         work->resobj->dComplementarityAverage);\n\n  //  todo should this be added to postsolve?\n  // todo, fix dNormCost and this\n  if (work->resobj->termIterate == AVERAGE_ITERATE) {\n    fprintf(fptr, \"\\\"dRelPrimalFeas\\\":%.14f,\",\n            work->resobj->dPrimalFeasAverage / (1.0 + work->scaling->dNormRhs));\n    fprintf(fptr, \"\\\"dRelDualFeas\\\":%.14f,\",\n            work->resobj->dDualFeasAverage / (1.0 + work->scaling->dNormCost));\n    fprintf(fptr, \"\\\"dRelDualityGap\\\":%.14f,\", work->resobj->dRelObjGapAverage);\n  } else {\n    fprintf(fptr, \"\\\"dRelPrimalFeas\\\":%.14f,\",\n            work->resobj->dPrimalFeas / (1.0 + work->scaling->dNormRhs));\n    fprintf(fptr, \"\\\"dRelDualFeas\\\":%.14f,\",\n            work->resobj->dDualFeas / (1.0 + work->scaling->dNormCost));\n    fprintf(fptr, \"\\\"dRelDualityGap\\\":%.14f,\", work->resobj->dRelObjGap);\n  }\n  fprintf(fptr, \"\\\"terminationCode\\\":\\\"%s\\\",\",\n          termCodeNames[work->resobj->termCode]);\n  fprintf(fptr, \"\\\"terminationIterate\\\":\\\"%s\\\",\",\n          termIterateNames[work->resobj->termIterate]);\n  fprintf(fptr, \"\\\"primalCode\\\":\\\"%s\\\",\",\n          termCodeNames[work->resobj->primalCode]);\n  fprintf(fptr, \"\\\"dualCode\\\":\\\"%s\\\",\", termCodeNames[work->resobj->dualCode]);\n  fprintf(fptr, \"\\\"terminationInfeasIterate\\\":\\\"%s\\\"\",\n          termIterateNames[work->resobj->termInfeasIterate]);\n\n  fprintf(fptr, \"}\");\n  // Close the file\n  fclose(fptr);\n}\n\nvoid writeSol(const char *fout, cupdlp_int nCols, cupdlp_int nRows,\n              cupdlp_float *col_value, cupdlp_float *col_dual,\n              cupdlp_float *row_value, cupdlp_float *row_dual) {\n  FILE *fptr;\n\n  cupdlp_printf(\"--------------------------------\\n\");\n  cupdlp_printf(\"--- saving sol to %s\\n\", fout);\n  cupdlp_printf(\"--------------------------------\\n\");\n  // Open a file in writing mode\n  fptr = fopen(fout, \"w\");\n  fprintf(fptr, \"{\");\n\n  // nCols\n  fprintf(fptr, \"\\n\");\n\n  fprintf(fptr, \"\\\"nCols\\\": %d\", nCols);\n\n  // nRows\n  fprintf(fptr, \",\\n\");\n\n  fprintf(fptr, \"\\\"nRows\\\": %d\", nRows);\n\n  // col value\n  fprintf(fptr, \",\\n\");\n\n  fprintf(fptr, \"\\\"col_value\\\": [\");\n  if (col_value && nCols) {\n    for (int i = 0; i < nCols - 1; ++i) {\n      fprintf(fptr, \"%.14f,\", col_value[i]);\n    }\n    fprintf(fptr, \"%.14f\", col_value[nCols - 1]);\n  }\n  fprintf(fptr, \"]\");\n\n  // col dual\n  fprintf(fptr, \",\\n\");\n  fprintf(fptr, \"\\\"col_dual\\\": [\");\n  if (col_dual && nCols) {\n    for (int i = 0; i < nCols - 1; ++i) {\n      fprintf(fptr, \"%.14f,\", col_dual[i]);\n    }\n    fprintf(fptr, \"%.14f\", col_dual[nCols - 1]);\n  }\n  fprintf(fptr, \"]\");\n\n  // row value\n  fprintf(fptr, \",\\n\");\n  fprintf(fptr, \"\\\"row_value\\\": [\");\n  if (row_value && nRows) {\n    for (int i = 0; i < nRows - 1; ++i) {\n      fprintf(fptr, \"%.14f,\", row_value[i]);\n    }\n    fprintf(fptr, \"%.14f\", row_value[nRows - 1]);\n  }\n  fprintf(fptr, \"]\");\n\n  // row dual\n  fprintf(fptr, \",\\n\");\n  fprintf(fptr, \"\\\"row_dual\\\": [\");\n  if (row_dual && nRows) {\n    for (int i = 0; i < nRows - 1; ++i) {\n      fprintf(fptr, \"%.14f,\", row_dual[i]);\n    }\n    fprintf(fptr, \"%.14f\", row_dual[nRows - 1]);\n  }\n  fprintf(fptr, \"]\");\n\n  // end writing\n  fprintf(fptr, \"\\n\");\n  fprintf(fptr, \"}\");\n\n  // Close the file\n  fclose(fptr);\n}\n"
  },
  {
    "path": "thirdparty/solvers/highs/pdqsort/pdqsort.h",
    "content": "/*\n    pdqsort.h - Pattern-defeating quicksort.\n\n    Copyright (c) 2021 Orson Peters\n\n    This software is provided 'as-is', without any express or implied warranty. In no event will the\n    authors be held liable for any damages arising from the use of this software.\n\n    Permission is granted to anyone to use this software for any purpose, including commercial\n    applications, and to alter it and redistribute it freely, subject to the following restrictions:\n\n    1. The origin of this software must not be misrepresented; you must not claim that you wrote the\n       original software. If you use this software in a product, an acknowledgment in the product\n       documentation would be appreciated but is not required.\n\n    2. Altered source versions must be plainly marked as such, and must not be misrepresented as\n       being the original software.\n\n    3. This notice may not be removed or altered from any source distribution.\n*/\n\n\n#ifndef PDQSORT_H\n#define PDQSORT_H\n\n#include <algorithm>\n#include <cstddef>\n#include <functional>\n#include <utility>\n#include <iterator>\n\n#if __cplusplus >= 201103L\n    #include <cstdint>\n    #include <type_traits>\n    #define PDQSORT_PREFER_MOVE(x) std::move(x)\n#else\n    #define PDQSORT_PREFER_MOVE(x) (x)\n#endif\n\n\nnamespace pdqsort_detail {\n    enum {\n        // Partitions below this size are sorted using insertion sort.\n        insertion_sort_threshold = 24,\n\n        // Partitions above this size use Tukey's ninther to select the pivot.\n        ninther_threshold = 128,\n\n        // When we detect an already sorted partition, attempt an insertion sort that allows this\n        // amount of element moves before giving up.\n        partial_insertion_sort_limit = 8,\n\n        // Must be multiple of 8 due to loop unrolling, and < 256 to fit in unsigned char.\n        block_size = 64,\n\n        // Cacheline size, assumes power of two.\n        cacheline_size = 64\n\n    };\n\n#if __cplusplus >= 201103L\n    template<class T> struct is_default_compare : std::false_type { };\n    template<class T> struct is_default_compare<std::less<T>> : std::true_type { };\n    template<class T> struct is_default_compare<std::greater<T>> : std::true_type { };\n#endif\n\n    // Returns floor(log2(n)), assumes n > 0.\n    template<class T>\n    inline int log2(T n) {\n        int log = 0;\n        while (n >>= 1) ++log;\n        return log;\n    }\n\n    // Sorts [begin, end) using insertion sort with the given comparison function.\n    template<class Iter, class Compare>\n    inline void insertion_sort(Iter begin, Iter end, Compare comp) {\n        typedef typename std::iterator_traits<Iter>::value_type T;\n        if (begin == end) return;\n\n        for (Iter cur = begin + 1; cur != end; ++cur) {\n            Iter sift = cur;\n            Iter sift_1 = cur - 1;\n\n            // Compare first so we can avoid 2 moves for an element already positioned correctly.\n            if (comp(*sift, *sift_1)) {\n                T tmp = PDQSORT_PREFER_MOVE(*sift);\n\n                do { *sift-- = PDQSORT_PREFER_MOVE(*sift_1); }\n                while (sift != begin && comp(tmp, *--sift_1));\n\n                *sift = PDQSORT_PREFER_MOVE(tmp);\n            }\n        }\n    }\n\n    // Sorts [begin, end) using insertion sort with the given comparison function. Assumes\n    // *(begin - 1) is an element smaller than or equal to any element in [begin, end).\n    template<class Iter, class Compare>\n    inline void unguarded_insertion_sort(Iter begin, Iter end, Compare comp) {\n        typedef typename std::iterator_traits<Iter>::value_type T;\n        if (begin == end) return;\n\n        for (Iter cur = begin + 1; cur != end; ++cur) {\n            Iter sift = cur;\n            Iter sift_1 = cur - 1;\n\n            // Compare first so we can avoid 2 moves for an element already positioned correctly.\n            if (comp(*sift, *sift_1)) {\n                T tmp = PDQSORT_PREFER_MOVE(*sift);\n\n                do { *sift-- = PDQSORT_PREFER_MOVE(*sift_1); }\n                while (comp(tmp, *--sift_1));\n\n                *sift = PDQSORT_PREFER_MOVE(tmp);\n            }\n        }\n    }\n\n    // Attempts to use insertion sort on [begin, end). Will return false if more than\n    // partial_insertion_sort_limit elements were moved, and abort sorting. Otherwise it will\n    // successfully sort and return true.\n    template<class Iter, class Compare>\n    inline bool partial_insertion_sort(Iter begin, Iter end, Compare comp) {\n        typedef typename std::iterator_traits<Iter>::value_type T;\n        if (begin == end) return true;\n        \n        std::size_t limit = 0;\n        for (Iter cur = begin + 1; cur != end; ++cur) {\n            Iter sift = cur;\n            Iter sift_1 = cur - 1;\n\n            // Compare first so we can avoid 2 moves for an element already positioned correctly.\n            if (comp(*sift, *sift_1)) {\n                T tmp = PDQSORT_PREFER_MOVE(*sift);\n\n                do { *sift-- = PDQSORT_PREFER_MOVE(*sift_1); }\n                while (sift != begin && comp(tmp, *--sift_1));\n\n                *sift = PDQSORT_PREFER_MOVE(tmp);\n                limit += cur - sift;\n            }\n            \n            if (limit > partial_insertion_sort_limit) return false;\n        }\n\n        return true;\n    }\n\n    template<class Iter, class Compare>\n    inline void sort2(Iter a, Iter b, Compare comp) {\n        if (comp(*b, *a)) std::iter_swap(a, b);\n    }\n\n    // Sorts the elements *a, *b and *c using comparison function comp.\n    template<class Iter, class Compare>\n    inline void sort3(Iter a, Iter b, Iter c, Compare comp) {\n        sort2(a, b, comp);\n        sort2(b, c, comp);\n        sort2(a, b, comp);\n    }\n\n    template<class T>\n    inline T* align_cacheline(T* p) {\n#if defined(UINTPTR_MAX) && __cplusplus >= 201103L\n        std::uintptr_t ip = reinterpret_cast<std::uintptr_t>(p);\n#else\n        std::size_t ip = reinterpret_cast<std::size_t>(p);\n#endif\n        ip = (ip + cacheline_size - 1) & -cacheline_size;\n        return reinterpret_cast<T*>(ip);\n    }\n\n    template<class Iter>\n    inline void swap_offsets(Iter first, Iter last,\n                             unsigned char* offsets_l, unsigned char* offsets_r,\n                             size_t num, bool use_swaps) {\n        typedef typename std::iterator_traits<Iter>::value_type T;\n        if (use_swaps) {\n            // This case is needed for the descending distribution, where we need\n            // to have proper swapping for pdqsort to remain O(n).\n            for (size_t i = 0; i < num; ++i) {\n                std::iter_swap(first + offsets_l[i], last - offsets_r[i]);\n            }\n        } else if (num > 0) {\n            Iter l = first + offsets_l[0]; Iter r = last - offsets_r[0];\n            T tmp(PDQSORT_PREFER_MOVE(*l)); *l = PDQSORT_PREFER_MOVE(*r);\n            for (size_t i = 1; i < num; ++i) {\n                l = first + offsets_l[i]; *r = PDQSORT_PREFER_MOVE(*l);\n                r = last - offsets_r[i]; *l = PDQSORT_PREFER_MOVE(*r);\n            }\n            *r = PDQSORT_PREFER_MOVE(tmp);\n        }\n    }\n\n    // Partitions [begin, end) around pivot *begin using comparison function comp. Elements equal\n    // to the pivot are put in the right-hand partition. Returns the position of the pivot after\n    // partitioning and whether the passed sequence already was correctly partitioned. Assumes the\n    // pivot is a median of at least 3 elements and that [begin, end) is at least\n    // insertion_sort_threshold long. Uses branchless partitioning.\n    template<class Iter, class Compare>\n    inline std::pair<Iter, bool> partition_right_branchless(Iter begin, Iter end, Compare comp) {\n        typedef typename std::iterator_traits<Iter>::value_type T;\n\n        // Move pivot into local for speed.\n        T pivot(PDQSORT_PREFER_MOVE(*begin));\n        Iter first = begin;\n        Iter last = end;\n\n        // Find the first element greater than or equal than the pivot (the median of 3 guarantees\n        // this exists).\n        while (comp(*++first, pivot));\n\n        // Find the first element strictly smaller than the pivot. We have to guard this search if\n        // there was no element before *first.\n        if (first - 1 == begin) while (first < last && !comp(*--last, pivot));\n        else                    while (                !comp(*--last, pivot));\n\n        // If the first pair of elements that should be swapped to partition are the same element,\n        // the passed in sequence already was correctly partitioned.\n        bool already_partitioned = first >= last;\n        if (!already_partitioned) {\n            std::iter_swap(first, last);\n            ++first;\n\n            // The following branchless partitioning is derived from \"BlockQuicksort: How Branch\n            // Mispredictions don’t affect Quicksort\" by Stefan Edelkamp and Armin Weiss, but\n            // heavily micro-optimized.\n            unsigned char offsets_l_storage[block_size + cacheline_size];\n            unsigned char offsets_r_storage[block_size + cacheline_size];\n            unsigned char* offsets_l = align_cacheline(offsets_l_storage);\n            unsigned char* offsets_r = align_cacheline(offsets_r_storage);\n\n            Iter offsets_l_base = first;\n            Iter offsets_r_base = last;\n            size_t num_l, num_r, start_l, start_r;\n            num_l = num_r = start_l = start_r = 0;\n            \n            while (first < last) {\n                // Fill up offset blocks with elements that are on the wrong side.\n                // First we determine how much elements are considered for each offset block.\n                size_t num_unknown = last - first;\n                size_t left_split = num_l == 0 ? (num_r == 0 ? num_unknown / 2 : num_unknown) : 0;\n                size_t right_split = num_r == 0 ? (num_unknown - left_split) : 0;\n\n                // Fill the offset blocks.\n                if (left_split >= block_size) {\n                    for (size_t i = 0; i < block_size;) {\n                        offsets_l[num_l] = i++; num_l += !comp(*first, pivot); ++first;\n                        offsets_l[num_l] = i++; num_l += !comp(*first, pivot); ++first;\n                        offsets_l[num_l] = i++; num_l += !comp(*first, pivot); ++first;\n                        offsets_l[num_l] = i++; num_l += !comp(*first, pivot); ++first;\n                        offsets_l[num_l] = i++; num_l += !comp(*first, pivot); ++first;\n                        offsets_l[num_l] = i++; num_l += !comp(*first, pivot); ++first;\n                        offsets_l[num_l] = i++; num_l += !comp(*first, pivot); ++first;\n                        offsets_l[num_l] = i++; num_l += !comp(*first, pivot); ++first;\n                    }\n                } else {\n                    for (size_t i = 0; i < left_split;) {\n                        offsets_l[num_l] = i++; num_l += !comp(*first, pivot); ++first;\n                    }\n                }\n\n                if (right_split >= block_size) {\n                    for (size_t i = 0; i < block_size;) {\n                        offsets_r[num_r] = ++i; num_r += comp(*--last, pivot);\n                        offsets_r[num_r] = ++i; num_r += comp(*--last, pivot);\n                        offsets_r[num_r] = ++i; num_r += comp(*--last, pivot);\n                        offsets_r[num_r] = ++i; num_r += comp(*--last, pivot);\n                        offsets_r[num_r] = ++i; num_r += comp(*--last, pivot);\n                        offsets_r[num_r] = ++i; num_r += comp(*--last, pivot);\n                        offsets_r[num_r] = ++i; num_r += comp(*--last, pivot);\n                        offsets_r[num_r] = ++i; num_r += comp(*--last, pivot);\n                    }\n                } else {\n                    for (size_t i = 0; i < right_split;) {\n                        offsets_r[num_r] = ++i; num_r += comp(*--last, pivot);\n                    }\n                }\n\n                // Swap elements and update block sizes and first/last boundaries.\n                size_t num = std::min(num_l, num_r);\n                swap_offsets(offsets_l_base, offsets_r_base,\n                             offsets_l + start_l, offsets_r + start_r,\n                             num, num_l == num_r);\n                num_l -= num; num_r -= num;\n                start_l += num; start_r += num;\n\n                if (num_l == 0) {\n                    start_l = 0;\n                    offsets_l_base = first;\n                }\n                \n                if (num_r == 0) {\n                    start_r = 0;\n                    offsets_r_base = last;\n                }\n            }\n\n            // We have now fully identified [first, last)'s proper position. Swap the last elements.\n            if (num_l) {\n                offsets_l += start_l;\n                while (num_l--) std::iter_swap(offsets_l_base + offsets_l[num_l], --last);\n                first = last;\n            }\n            if (num_r) {\n                offsets_r += start_r;\n                while (num_r--) std::iter_swap(offsets_r_base - offsets_r[num_r], first), ++first;\n                last = first;\n            }\n        }\n\n        // Put the pivot in the right place.\n        Iter pivot_pos = first - 1;\n        *begin = PDQSORT_PREFER_MOVE(*pivot_pos);\n        *pivot_pos = PDQSORT_PREFER_MOVE(pivot);\n\n        return std::make_pair(pivot_pos, already_partitioned);\n    }\n\n\n\n    // Partitions [begin, end) around pivot *begin using comparison function comp. Elements equal\n    // to the pivot are put in the right-hand partition. Returns the position of the pivot after\n    // partitioning and whether the passed sequence already was correctly partitioned. Assumes the\n    // pivot is a median of at least 3 elements and that [begin, end) is at least\n    // insertion_sort_threshold long.\n    template<class Iter, class Compare>\n    inline std::pair<Iter, bool> partition_right(Iter begin, Iter end, Compare comp) {\n        typedef typename std::iterator_traits<Iter>::value_type T;\n        \n        // Move pivot into local for speed.\n        T pivot(PDQSORT_PREFER_MOVE(*begin));\n\n        Iter first = begin;\n        Iter last = end;\n\n        // Find the first element greater than or equal than the pivot (the median of 3 guarantees\n        // this exists).\n        while (comp(*++first, pivot));\n\n        // Find the first element strictly smaller than the pivot. We have to guard this search if\n        // there was no element before *first.\n        if (first - 1 == begin) while (first < last && !comp(*--last, pivot));\n        else                    while (                !comp(*--last, pivot));\n\n        // If the first pair of elements that should be swapped to partition are the same element,\n        // the passed in sequence already was correctly partitioned.\n        bool already_partitioned = first >= last;\n        \n        // Keep swapping pairs of elements that are on the wrong side of the pivot. Previously\n        // swapped pairs guard the searches, which is why the first iteration is special-cased\n        // above.\n        while (first < last) {\n            std::iter_swap(first, last);\n            while (comp(*++first, pivot));\n            while (!comp(*--last, pivot));\n        }\n\n        // Put the pivot in the right place.\n        Iter pivot_pos = first - 1;\n        *begin = PDQSORT_PREFER_MOVE(*pivot_pos);\n        *pivot_pos = PDQSORT_PREFER_MOVE(pivot);\n\n        return std::make_pair(pivot_pos, already_partitioned);\n    }\n\n    // Similar function to the one above, except elements equal to the pivot are put to the left of\n    // the pivot and it doesn't check or return if the passed sequence already was partitioned.\n    // Since this is rarely used (the many equal case), and in that case pdqsort already has O(n)\n    // performance, no block quicksort is applied here for simplicity.\n    template<class Iter, class Compare>\n    inline Iter partition_left(Iter begin, Iter end, Compare comp) {\n        typedef typename std::iterator_traits<Iter>::value_type T;\n\n        T pivot(PDQSORT_PREFER_MOVE(*begin));\n        Iter first = begin;\n        Iter last = end;\n        \n        while (comp(pivot, *--last));\n\n        if (last + 1 == end) while (first < last && !comp(pivot, *++first));\n        else                 while (                !comp(pivot, *++first));\n\n        while (first < last) {\n            std::iter_swap(first, last);\n            while (comp(pivot, *--last));\n            while (!comp(pivot, *++first));\n        }\n\n        Iter pivot_pos = last;\n        *begin = PDQSORT_PREFER_MOVE(*pivot_pos);\n        *pivot_pos = PDQSORT_PREFER_MOVE(pivot);\n\n        return pivot_pos;\n    }\n\n\n    template<class Iter, class Compare, bool Branchless>\n    inline void pdqsort_loop(Iter begin, Iter end, Compare comp, int bad_allowed, bool leftmost = true) {\n        typedef typename std::iterator_traits<Iter>::difference_type diff_t;\n\n        // Use a while loop for tail recursion elimination.\n        while (true) {\n            diff_t size = end - begin;\n\n            // Insertion sort is faster for small arrays.\n            if (size < insertion_sort_threshold) {\n                if (leftmost) insertion_sort(begin, end, comp);\n                else unguarded_insertion_sort(begin, end, comp);\n                return;\n            }\n\n            // Choose pivot as median of 3 or pseudomedian of 9.\n            diff_t s2 = size / 2;\n            if (size > ninther_threshold) {\n                sort3(begin, begin + s2, end - 1, comp);\n                sort3(begin + 1, begin + (s2 - 1), end - 2, comp);\n                sort3(begin + 2, begin + (s2 + 1), end - 3, comp);\n                sort3(begin + (s2 - 1), begin + s2, begin + (s2 + 1), comp);\n                std::iter_swap(begin, begin + s2);\n            } else sort3(begin + s2, begin, end - 1, comp);\n\n            // If *(begin - 1) is the end of the right partition of a previous partition operation\n            // there is no element in [begin, end) that is smaller than *(begin - 1). Then if our\n            // pivot compares equal to *(begin - 1) we change strategy, putting equal elements in\n            // the left partition, greater elements in the right partition. We do not have to\n            // recurse on the left partition, since it's sorted (all equal).\n            if (!leftmost && !comp(*(begin - 1), *begin)) {\n                begin = partition_left(begin, end, comp) + 1;\n                continue;\n            }\n\n            // Partition and get results.\n            std::pair<Iter, bool> part_result =\n                Branchless ? partition_right_branchless(begin, end, comp)\n                           : partition_right(begin, end, comp);\n            Iter pivot_pos = part_result.first;\n            bool already_partitioned = part_result.second;\n\n            // Check for a highly unbalanced partition.\n            diff_t l_size = pivot_pos - begin;\n            diff_t r_size = end - (pivot_pos + 1);\n            bool highly_unbalanced = l_size < size / 8 || r_size < size / 8;\n\n            // If we got a highly unbalanced partition we shuffle elements to break many patterns.\n            if (highly_unbalanced) {\n                // If we had too many bad partitions, switch to heapsort to guarantee O(n log n).\n                if (--bad_allowed == 0) {\n                    std::make_heap(begin, end, comp);\n                    std::sort_heap(begin, end, comp);\n                    return;\n                }\n\n                if (l_size >= insertion_sort_threshold) {\n                    std::iter_swap(begin,             begin + l_size / 4);\n                    std::iter_swap(pivot_pos - 1, pivot_pos - l_size / 4);\n\n                    if (l_size > ninther_threshold) {\n                        std::iter_swap(begin + 1,         begin + (l_size / 4 + 1));\n                        std::iter_swap(begin + 2,         begin + (l_size / 4 + 2));\n                        std::iter_swap(pivot_pos - 2, pivot_pos - (l_size / 4 + 1));\n                        std::iter_swap(pivot_pos - 3, pivot_pos - (l_size / 4 + 2));\n                    }\n                }\n                \n                if (r_size >= insertion_sort_threshold) {\n                    std::iter_swap(pivot_pos + 1, pivot_pos + (1 + r_size / 4));\n                    std::iter_swap(end - 1,                   end - r_size / 4);\n                    \n                    if (r_size > ninther_threshold) {\n                        std::iter_swap(pivot_pos + 2, pivot_pos + (2 + r_size / 4));\n                        std::iter_swap(pivot_pos + 3, pivot_pos + (3 + r_size / 4));\n                        std::iter_swap(end - 2,             end - (1 + r_size / 4));\n                        std::iter_swap(end - 3,             end - (2 + r_size / 4));\n                    }\n                }\n            } else {\n                // If we were decently balanced and we tried to sort an already partitioned\n                // sequence try to use insertion sort.\n                if (already_partitioned && partial_insertion_sort(begin, pivot_pos, comp)\n                                        && partial_insertion_sort(pivot_pos + 1, end, comp)) return;\n            }\n                \n            // Sort the left partition first using recursion and do tail recursion elimination for\n            // the right-hand partition.\n            pdqsort_loop<Iter, Compare, Branchless>(begin, pivot_pos, comp, bad_allowed, leftmost);\n            begin = pivot_pos + 1;\n            leftmost = false;\n        }\n    }\n}\n\n\ntemplate<class Iter, class Compare>\ninline void pdqsort(Iter begin, Iter end, Compare comp) {\n    if (begin == end) return;\n\n#if __cplusplus >= 201103L\n    pdqsort_detail::pdqsort_loop<Iter, Compare,\n        pdqsort_detail::is_default_compare<typename std::decay<Compare>::type>::value &&\n        std::is_arithmetic<typename std::iterator_traits<Iter>::value_type>::value>(\n        begin, end, comp, pdqsort_detail::log2(end - begin));\n#else\n    pdqsort_detail::pdqsort_loop<Iter, Compare, false>(\n        begin, end, comp, pdqsort_detail::log2(end - begin));\n#endif\n}\n\ntemplate<class Iter>\ninline void pdqsort(Iter begin, Iter end) {\n    typedef typename std::iterator_traits<Iter>::value_type T;\n    pdqsort(begin, end, std::less<T>());\n}\n\ntemplate<class Iter, class Compare>\ninline void pdqsort_branchless(Iter begin, Iter end, Compare comp) {\n    if (begin == end) return;\n    pdqsort_detail::pdqsort_loop<Iter, Compare, true>(\n        begin, end, comp, pdqsort_detail::log2(end - begin));\n}\n\ntemplate<class Iter>\ninline void pdqsort_branchless(Iter begin, Iter end) {\n    typedef typename std::iterator_traits<Iter>::value_type T;\n    pdqsort_branchless(begin, end, std::less<T>());\n}\n\n\n#undef PDQSORT_PREFER_MOVE\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/presolve/HPresolve.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file presolve/HPresolve.h\n * @brief\n */\n#ifndef PRESOLVE_HIGHS_PRESOLVE_H_\n#define PRESOLVE_HIGHS_PRESOLVE_H_\n#include <cassert>\n#include <cmath>\n#include <list>\n#include <queue>\n#include <set>\n#include <unordered_map>\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n#include \"lp_data/HStruct.h\"\n#include \"lp_data/HighsLp.h\"\n#include \"lp_data/HighsOptions.h\"\n#include \"mip/HighsMipSolver.h\"\n#include \"presolve/HPresolveAnalysis.h\"\n#include \"util/HighsCDouble.h\"\n#include \"util/HighsHash.h\"\n#include \"util/HighsHashTree.h\"\n#include \"util/HighsLinearSumBounds.h\"\n#include \"util/HighsMatrixSlice.h\"\n\nnamespace presolve {\n\nclass HighsPostsolveStack;\n\nclass HPresolve {\n  // pointer to model and options that where presolved\n  HighsLp* model;\n  const HighsOptions* options;\n  HighsTimer* timer;\n  HighsMipSolver* mipsolver = nullptr;\n  double primal_feastol;\n\n  // triplet storage\n  std::vector<double> Avalue;\n  std::vector<HighsInt> Arow;\n  std::vector<HighsInt> Acol;\n\n  // linked list links for column based links for each nonzero\n  std::vector<HighsInt> colhead;\n  std::vector<HighsInt> Anext;\n  std::vector<HighsInt> Aprev;\n\n  // splay tree links for row based iteration and nonzero lookup\n  std::vector<HighsInt> rowroot;\n  std::vector<HighsInt> ARleft;\n  std::vector<HighsInt> ARright;\n\n  // length of rows and columns\n  std::vector<HighsInt> rowsize;\n  std::vector<HighsInt> rowsizeInteger;\n  std::vector<HighsInt> rowsizeImplInt;\n  std::vector<HighsInt> colsize;\n\n  // vector to store the nonzero positions of a row\n  std::vector<HighsInt> rowpositions;\n\n  // stack to reuse free slots\n  std::vector<HighsInt> freeslots;\n\n  // vectors holding implied bounds on primal and dual variables as well as\n  // their origins\n  std::vector<double> implColLower;\n  std::vector<double> implColUpper;\n  std::vector<HighsInt> colLowerSource;\n  std::vector<HighsInt> colUpperSource;\n  std::vector<double> rowDualLower;\n  std::vector<double> rowDualUpper;\n  std::vector<double> implRowDualLower;\n  std::vector<double> implRowDualUpper;\n  std::vector<HighsInt> rowDualLowerSource;\n  std::vector<HighsInt> rowDualUpperSource;\n  std::vector<std::set<HighsInt>> colImplSourceByRow;\n  std::vector<std::set<HighsInt>> implRowDualSourceByCol;\n\n  // implied bounds on values of primal and dual rows computed from the bounds\n  // of primal and dual variables\n  HighsLinearSumBounds impliedRowBounds;\n  HighsLinearSumBounds impliedDualRowBounds;\n\n  std::vector<HighsInt> changedRowIndices;\n  std::vector<uint8_t> changedRowFlag;\n  std::vector<HighsInt> changedColIndices;\n  std::vector<uint8_t> changedColFlag;\n\n  std::vector<std::pair<HighsInt, HighsInt>> substitutionOpportunities;\n\n  std::unordered_map<HighsInt,\n                     HighsHashTree<std::pair<HighsInt, HighsInt>, double>>\n      liftingOpportunities;\n\n  // set with the sizes and indices of equation rows sorted by the size and a\n  // vector to access there iterator positions in the set by index for quick\n  // removal\n  std::set<std::pair<HighsInt, HighsInt>> equations;\n  std::vector<std::set<std::pair<HighsInt, HighsInt>>::iterator> eqiters;\n\n  bool shrinkProblemEnabled;\n  size_t reductionLimit;\n\n  // vectors storing singleton rows and columns\n  std::vector<HighsInt> singletonRows;\n  std::vector<HighsInt> singletonColumns;\n\n  // flags to mark rows/columns as deleted\n  std::vector<uint8_t> rowDeleted;\n  std::vector<uint8_t> colDeleted;\n\n  std::vector<uint16_t> numProbes;\n\n  int64_t probingContingent;\n  HighsInt probingNumDelCol;\n  HighsInt numProbed;\n\n  // counters for number of deleted rows and columns\n  HighsInt numDeletedRows;\n  HighsInt numDeletedCols;\n\n  // store old problem sizes to compute percentage reductions in\n  // presolve loop\n  HighsInt oldNumCol;\n  HighsInt oldNumRow;\n  bool probingEarlyAbort;\n\n  enum class Result {\n    kOk,\n    kPrimalInfeasible,\n    kDualInfeasible,\n    kStopped,\n  };\n\n  struct StatusResult {\n   private:\n    bool my_flag;\n    Result my_result;\n\n   public:\n    // clang-format off\n    StatusResult(bool flag) : my_flag(flag), my_result(Result::kOk) {};\n    // clang-format on\n    StatusResult(Result result) : my_result(result) {\n      my_flag = (result == Result::kOk);\n    };\n    explicit operator bool() const { return my_flag; };\n    explicit operator Result() const { return my_result; };\n  };\n\n  HighsPresolveStatus presolve_status_;\n  HPresolveAnalysis analysis_;\n\n  // private functions for different shared functionality and matrix\n  // modification\n\n  void link(HighsInt pos);\n\n  void unlink(HighsInt pos);\n\n  void markChangedRow(HighsInt row);\n\n  void markChangedCol(HighsInt col);\n\n  double getMaxAbsColVal(HighsInt col) const;\n\n  double getMaxAbsRowVal(HighsInt row) const;\n\n  bool checkUpdateColImpliedBounds(HighsInt row, double* rowLower = nullptr,\n                                   double* rowUpper = nullptr) const;\n\n  void updateColImpliedBounds(HighsInt row, HighsInt col, double val);\n\n  void updateColImpliedBounds(HighsInt row);\n\n  bool checkUpdateRowDualImpliedBounds(HighsInt col,\n                                       double* dualRowLower = nullptr,\n                                       double* dualRowUpper = nullptr) const;\n\n  void updateRowDualImpliedBounds(HighsInt row, HighsInt col, double val);\n\n  void updateRowDualImpliedBounds(HighsInt col);\n\n  void resetColImpliedBounds(HighsInt col, HighsInt row = -1);\n\n  void resetRowDualImpliedBounds(HighsInt row, HighsInt col = -1);\n\n  void resetColImpliedBoundsDerivedFromRow(HighsInt row);\n\n  void resetRowDualImpliedBoundsDerivedFromCol(HighsInt col);\n\n  bool rowCoefficientsIntegral(HighsInt row, double scale) const;\n\n  bool isImpliedFree(HighsInt col) const;\n\n  bool isDualImpliedFree(HighsInt row) const;\n\n  void dualImpliedFreeGetRhsAndRowType(HighsInt row, double& rhs,\n                                       HighsPostsolveStack::RowType& rowType,\n                                       bool relaxRowDualBounds = false);\n\n  bool isEquation(HighsInt row) const;\n\n  bool isRanged(HighsInt row) const;\n\n  bool isRedundant(HighsInt row) const;\n\n  bool yieldsImpliedLowerBound(HighsInt row, double val) const;\n\n  bool yieldsImpliedUpperBound(HighsInt row, double val) const;\n\n  bool isImpliedEquationAtLower(HighsInt row) const;\n\n  bool isImpliedEquationAtUpper(HighsInt row) const;\n\n  StatusResult isImpliedIntegral(HighsInt col);\n\n  StatusResult isImpliedInteger(HighsInt col) const;\n\n  StatusResult convertImpliedInteger(HighsInt col, HighsInt row = -1,\n                                     bool skipInputChecks = false);\n\n  bool isLowerImplied(HighsInt col) const;\n\n  bool isLowerStrictlyImplied(HighsInt col, double* tolerance = nullptr) const;\n\n  bool isUpperImplied(HighsInt col) const;\n\n  bool isUpperStrictlyImplied(HighsInt col, double* tolerance = nullptr) const;\n\n  HighsInt countFillin(HighsInt row);\n\n  bool checkFillin(HighsHashTable<HighsInt, HighsInt>& fillinCache,\n                   HighsInt row, HighsInt col);\n\n  void reinsertEquation(HighsInt row);\n\n  void clearLiftingOpportunities(HighsInt row) {\n    auto search = liftingOpportunities.find(row);\n    if (search != liftingOpportunities.end()) search->second.clear();\n  };\n\n#ifndef NDEBUG\n  void debugPrintRow(HighsPostsolveStack& postsolve_stack, HighsInt row);\n#endif\n\n  HighsInt findNonzero(HighsInt row, HighsInt col);\n\n  bool okFromCSC(const std::vector<double>& Aval,\n                 const std::vector<HighsInt>& Aindex,\n                 const std::vector<HighsInt>& Astart);\n\n  bool okFromCSR(const std::vector<double>& ARval,\n                 const std::vector<HighsInt>& ARindex,\n                 const std::vector<HighsInt>& ARstart);\n\n  void toCSC(std::vector<double>& Aval, std::vector<HighsInt>& Aindex,\n             std::vector<HighsInt>& Astart);\n\n  void toCSR(std::vector<double>& ARval, std::vector<HighsInt>& ARindex,\n             std::vector<HighsInt>& ARstart);\n\n  void getRowPositions(HighsInt row,\n                       std::vector<HighsInt>& myrowpositions) const;\n\n  void storeRow(HighsInt row);\n\n  HighsTripletPositionSlice getStoredRow() const;\n\n  HighsTripletListSlice getColumnVector(HighsInt col) const;\n\n  HighsTripletTreeSlicePreOrder getRowVector(HighsInt row) const;\n\n  HighsTripletTreeSliceInOrder getSortedRowVector(HighsInt row) const;\n\n  void markRowDeleted(HighsInt row);\n\n  void markColDeleted(HighsInt col);\n\n  Result fixColToLower(HighsPostsolveStack& postsolve_stack, HighsInt col);\n\n  Result fixColToUpper(HighsPostsolveStack& postsolve_stack, HighsInt col);\n\n  void fixColToZero(HighsPostsolveStack& postsolve_stack, HighsInt col);\n\n  void transformColumn(HighsPostsolveStack& postsolve_stack, HighsInt col,\n                       double scale, double constant);\n\n  void scaleRow(HighsInt row, double scale, bool integral = false);\n\n  void scaleStoredRow(HighsInt row, double scale, bool integral = false);\n\n  void substitute(HighsInt row, HighsInt col, double rhs);\n\n  void changeColUpper(HighsInt col, double newUpper);\n\n  void changeColLower(HighsInt col, double newLower);\n\n  void changeRowDualUpper(HighsInt row, double newUpper);\n\n  void changeRowDualLower(HighsInt row, double newLower);\n\n  void changeImplColUpper(HighsInt col, double newUpper, HighsInt originRow);\n\n  void changeImplColLower(HighsInt col, double newLower, HighsInt originRow);\n\n  void changeImplRowDualUpper(HighsInt row, double newUpper,\n                              HighsInt originCol);\n\n  void changeImplRowDualLower(HighsInt row, double newLower,\n                              HighsInt originCol);\n\n  void scaleMIP(HighsPostsolveStack& postsolve_stack);\n\n  Result applyConflictGraphSubstitutions(HighsPostsolveStack& postsolve_stack);\n\n  Result fastPresolveLoop(HighsPostsolveStack& postsolve_stack);\n\n  Result presolve(HighsPostsolveStack& postsolve_stack);\n\n  Result removeSlacks(HighsPostsolveStack& postsolve_stack);\n\n  Result checkTimeLimit();\n\n  Result checkLimits(HighsPostsolveStack& postsolve_stack);\n\n  void storeCurrentProblemSize();\n\n  double problemSizeReduction() const;\n\n  void computeColBounds(HighsInt col, HighsInt boundCol = -1,\n                        double boundColValue = -kHighsInf,\n                        HighsInt boundColCoeffPattern = 0,\n                        double* lowerBound = nullptr,\n                        double* upperBound = nullptr,\n                        double* worstCaseLowerBound = nullptr,\n                        double* worstCaseUpperBound = nullptr);\n\n public:\n  // for LP presolve\n  bool okSetInput(HighsLp& model_, const HighsOptions& options_,\n                  const HighsInt presolve_reduction_limit,\n                  HighsTimer* timer = nullptr);\n\n  // for MIP presolve\n  bool okSetInput(HighsMipSolver& mipsolver,\n                  const HighsInt presolve_reduction_limit);\n\n  void setReductionLimit(size_t reductionLimit) {\n    this->reductionLimit = reductionLimit;\n  }\n\n  HighsInt numNonzeros() const { return int(Avalue.size() - freeslots.size()); }\n\n  void shrinkProblem(HighsPostsolveStack& postsolve_stack);\n\n  void addToMatrix(const HighsInt row, const HighsInt col, const double val);\n\n  Result runProbing(HighsPostsolveStack& postsolve_stack);\n\n  Result liftingForProbing(HighsPostsolveStack& postsolve_stack);\n\n  Result dominatedColumns(HighsPostsolveStack& postsolve_stack);\n\n  Result doubletonEq(HighsPostsolveStack& postsolve_stack, HighsInt row,\n                     HighsPostsolveStack::RowType rowType);\n\n  Result singletonRow(HighsPostsolveStack& postsolve_stack, HighsInt row);\n\n  Result emptyCol(HighsPostsolveStack& postsolve_stack, HighsInt col);\n\n  Result singletonCol(HighsPostsolveStack& postsolve_stack, HighsInt col);\n\n  void substituteFreeCol(HighsPostsolveStack& postsolve_stack, HighsInt row,\n                         HighsInt col, bool relaxRowDualBounds = false);\n\n  Result rowPresolve(HighsPostsolveStack& postsolve_stack, HighsInt row);\n\n  Result colPresolve(HighsPostsolveStack& postsolve_stack, HighsInt col);\n\n  Result detectDominatedCol(HighsPostsolveStack& postsolve_stack, HighsInt col,\n                            bool handleSingletonRows = true);\n\n  Result dualFixing(HighsPostsolveStack& postsolve_stack, HighsInt col);\n\n  double computeImpliedLowerBound(HighsInt col, HighsInt boundCol = -1,\n                                  double boundColValue = kHighsInf,\n                                  HighsInt boundColCoeffPattern = 0);\n\n  double computeImpliedUpperBound(HighsInt col, HighsInt boundCol = -1,\n                                  double boundColValue = kHighsInf,\n                                  HighsInt boundColCoeffPattern = 0);\n\n  double computeWorstCaseLowerBound(HighsInt col, HighsInt boundCol = -1,\n                                    double boundColValue = kHighsInf,\n                                    HighsInt boundColCoeffPattern = 0);\n\n  double computeWorstCaseUpperBound(HighsInt col, HighsInt boundCol = -1,\n                                    double boundColValue = kHighsInf,\n                                    HighsInt boundColCoeffPattern = 0);\n\n  Result initialRowAndColPresolve(HighsPostsolveStack& postsolve_stack);\n\n  HighsModelStatus run(HighsPostsolveStack& postsolve_stack);\n\n  void computeIntermediateMatrix(std::vector<HighsInt>& flagRow,\n                                 std::vector<HighsInt>& flagCol,\n                                 size_t& numreductions);\n\n  void substitute(HighsInt substcol, HighsInt staycol, double offset,\n                  double scale);\n\n  void removeFixedCol(HighsInt col);\n\n  void removeRow(HighsInt row);\n\n  Result removeDependentEquations(HighsPostsolveStack& postsolve_stack);\n\n  Result removeDependentFreeCols(HighsPostsolveStack& postsolve_stack);\n\n  Result aggregator(HighsPostsolveStack& postsolve_stack);\n\n  Result removeRowSingletons(HighsPostsolveStack& postsolve_stack);\n\n  Result presolveColSingletons(HighsPostsolveStack& postsolve_stack);\n\n  Result presolveChangedRows(HighsPostsolveStack& postsolve_stack);\n\n  Result presolveChangedCols(HighsPostsolveStack& postsolve_stack);\n\n  Result removeDoubletonEquations(HighsPostsolveStack& postsolve_stack);\n\n  Result strengthenInequalities(HighsPostsolveStack& postsolve_stack,\n                                HighsInt& num_strenghtened);\n\n  Result detectImpliedIntegers();\n\n  Result detectParallelRowsAndCols(HighsPostsolveStack& postsolve_stack);\n\n  template <typename RowStorageFormat>\n  Result equalityRowAddition(HighsPostsolveStack& postsolve_stack,\n                             HighsInt stayrow, HighsInt removerow, double scale,\n                             const HighsMatrixSlice<RowStorageFormat>& vector);\n\n  Result sparsify(HighsPostsolveStack& postsolve_stack);\n\n  void setRelaxedImpliedBounds();\n\n  const HighsPresolveLog& getPresolveLog() const {\n    return analysis_.presolve_log_;\n  }\n\n  HighsPresolveStatus getPresolveStatus() const { return presolve_status_; }\n\n  bool zeroRowActivityFeasible() const;\n\n  HighsInt debugGetCheckCol() const;\n  HighsInt debugGetCheckRow() const;\n\n  // Not currently called\n  static void debug(const HighsLp& lp, const HighsOptions& options);\n};\n\n}  // namespace presolve\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/presolve/HPresolveAnalysis.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file presolve/HPresolveAnalysis.h\n * @brief\n */\n#ifndef PRESOLVE_HIGHS_PRESOLVE_ANALYSIS_H_\n#define PRESOLVE_HIGHS_PRESOLVE_ANALYSIS_H_\n\nclass HPresolveAnalysis {\n  const HighsLp* model;\n  const HighsOptions* options;\n  const bool* allow_rule;\n  const HighsInt* numDeletedRows;\n  const HighsInt* numDeletedCols;\n\n  // store original problem sizes for reference\n  HighsInt original_num_col_;\n  HighsInt original_num_row_;\n\n public:\n  std::vector<bool> allow_rule_;\n\n  bool allow_logging_;\n  bool logging_on_;\n\n  int log_rule_type_;\n  HighsInt num_deleted_rows0_;\n  HighsInt num_deleted_cols0_;\n  HighsPresolveLog presolve_log_;\n\n  // for LP presolve\n  //\n  // Transform options->presolve_rule_off into logical settings in\n  // allow_rule_[*], commenting on the rules switched off\n  void setup(const HighsLp* model_, const HighsOptions* options_,\n             const HighsInt& numDeletedRows_, const HighsInt& numDeletedCols_);\n  void resetNumDeleted();\n\n  std::string presolveReductionTypeToString(const HighsInt reduction_type);\n  void startPresolveRuleLog(const HighsInt rule_type);\n  void stopPresolveRuleLog(const HighsInt rule_type);\n  bool analysePresolveRuleLog(const bool report = false);\n  friend class HPresolve;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/presolve/HighsPostsolveStack.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file HighsPostsolveStack.h\n * @brief Class to hold all information for postsolve and can transform back\n * primal and dual solutions.\n */\n\n#ifndef PRESOLVE_HIGHS_POSTSOLVE_STACK_H_\n#define PRESOLVE_HIGHS_POSTSOLVE_STACK_H_\n\n#include <algorithm>\n#include <cassert>\n#include <cmath>\n#include <numeric>\n#include <tuple>\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n#include \"lp_data/HStruct.h\"\n#include \"lp_data/HighsOptions.h\"\n#include \"util/HighsCDouble.h\"\n#include \"util/HighsDataStack.h\"\n#include \"util/HighsMatrixSlice.h\"\n\n// class HighsOptions;\nnamespace presolve {\nclass HighsPostsolveStack {\n  // now a section of individual classes for each type of each transformation\n  // step that requires postsolve starts each class gets as first argument the\n  // current stack of ReductionValues and custom arguments that contain the\n  // necessary information that is required to undo the transformation. The\n  // constructor is responsible for storing all necessary information in class\n  // members and the reduction value stack. The class members should be as slim\n  // as possible and putting values on the reduction value stack should be\n  // preferred, because the classes are stored in a discriminated union and the\n  // largest size counts. The classes should implement an undo() function which\n  // gets the ReductionValues as argument and can be expected to be called such\n  // that the stack is in the state as after the constructor has been called.\n  // The undo() call must pop all values from the stack that were added during\n  // the constructor call, and should restore primal/dual solution values, as\n  // well as the basis status as appropriate.\n public:\n  enum class RowType {\n    kGeq,\n    kLeq,\n    kEq,\n  };\n  struct Nonzero {\n    HighsInt index;\n    double value;\n\n    Nonzero(HighsInt index_, double value_) : index(index_), value(value_) {}\n    Nonzero() = default;\n  };\n\n  size_t debug_prev_numreductions = 0;\n  double debug_prev_col_lower = 0;\n  double debug_prev_col_upper = 0;\n  double debug_prev_row_lower = 0;\n  double debug_prev_row_upper = 0;\n\n private:\n  /// transform a column x by a linear mapping with a new column x'.\n  /// I.e. substitute x = a * x' + b\n  struct LinearTransform {\n    double scale;\n    double constant;\n    HighsInt col;\n\n    void undo(const HighsOptions& options, HighsSolution& solution) const;\n\n    void transformToPresolvedSpace(std::vector<double>& primalSol) const;\n  };\n\n  struct FreeColSubstitution {\n    double rhs;\n    double colCost;\n    HighsInt row;\n    HighsInt col;\n    RowType rowType;\n\n    void undo(const HighsOptions& options,\n              const std::vector<Nonzero>& rowValues,\n              const std::vector<Nonzero>& colValues, HighsSolution& solution,\n              HighsBasis& basis);\n  };\n\n  struct DoubletonEquation {\n    double coef;\n    double coefSubst;\n    double rhs;\n    double substLower;\n    double substUpper;\n    double substCost;\n    HighsInt row;\n    HighsInt colSubst;\n    HighsInt col;\n    bool lowerTightened;\n    bool upperTightened;\n    RowType rowType;\n\n    void undo(const HighsOptions& options,\n              const std::vector<Nonzero>& colValues, HighsSolution& solution,\n              HighsBasis& basis) const;\n  };\n\n  struct EqualityRowAddition {\n    HighsInt row;\n    HighsInt addedEqRow;\n    double eqRowScale;\n\n    void undo(const HighsOptions& options,\n              const std::vector<Nonzero>& eqRowValues, HighsSolution& solution,\n              HighsBasis& basis) const;\n  };\n\n  struct EqualityRowAdditions {\n    HighsInt addedEqRow;\n\n    void undo(const HighsOptions& options,\n              const std::vector<Nonzero>& eqRowValues,\n              const std::vector<Nonzero>& targetRows, HighsSolution& solution,\n              HighsBasis& basis) const;\n  };\n  struct SingletonRow {\n    double coef;\n    HighsInt row;\n    HighsInt col;\n    bool colLowerTightened;\n    bool colUpperTightened;\n\n    void undo(const HighsOptions& options, HighsSolution& solution,\n              HighsBasis& basis) const;\n  };\n\n  // column fixed to lower or upper bound\n  struct FixedCol {\n    double fixValue;\n    double colCost;\n    HighsInt col;\n    HighsBasisStatus fixType;\n\n    void undo(const HighsOptions& options,\n              const std::vector<Nonzero>& colValues, HighsSolution& solution,\n              HighsBasis& basis) const;\n  };\n\n  struct RedundantRow {\n    HighsInt row;\n\n    void undo(const HighsOptions& options, HighsSolution& solution,\n              HighsBasis& basis) const;\n  };\n\n  struct ForcingRow {\n    double side;\n    HighsInt row;\n    RowType rowType;\n\n    void undo(const HighsOptions& options,\n              const std::vector<Nonzero>& rowValues, HighsSolution& solution,\n              HighsBasis& basis) const;\n  };\n\n  struct ForcingColumn {\n    double colCost;\n    double colBound;\n    HighsInt col;\n    bool atInfiniteUpper;\n    bool colIntegral;\n\n    void undo(const HighsOptions& options,\n              const std::vector<Nonzero>& colValues, HighsSolution& solution,\n              HighsBasis& basis) const;\n  };\n\n  struct ForcingColumnRemovedRow {\n    double rhs;\n    HighsInt row;\n    void undo(const HighsOptions& options,\n              const std::vector<Nonzero>& rowValues, HighsSolution& solution,\n              HighsBasis& basis) const;\n  };\n\n  struct DuplicateRow {\n    double duplicateRowScale;\n    HighsInt duplicateRow;\n    HighsInt row;\n    bool rowLowerTightened;\n    bool rowUpperTightened;\n\n    void undo(const HighsOptions& options, HighsSolution& solution,\n              HighsBasis& basis) const;\n  };\n\n  struct DuplicateColumn {\n    double colScale;\n    double colLower;\n    double colUpper;\n    double duplicateColLower;\n    double duplicateColUpper;\n    HighsInt col;\n    HighsInt duplicateCol;\n    bool colIntegral;\n    bool duplicateColIntegral;\n\n    void undo(const HighsOptions& options, HighsSolution& solution,\n              HighsBasis& basis) const;\n    bool okMerge(const double tolerance) const;\n    void undoFix(const HighsOptions& options, HighsSolution& solution,\n                 const double mergeValue) const;\n    void transformToPresolvedSpace(std::vector<double>& primalSol) const;\n  };\n\n  struct SlackColSubstitution {\n    double rhs;\n    HighsInt row;\n    HighsInt col;\n\n    void undo(const HighsOptions& options,\n              const std::vector<Nonzero>& rowValues, HighsSolution& solution,\n              HighsBasis& basis);\n  };\n\n  /// tags for reduction\n  enum class ReductionType : uint8_t {\n    kLinearTransform,\n    kFreeColSubstitution,\n    kDoubletonEquation,\n    kEqualityRowAddition,\n    kEqualityRowAdditions,\n    kSingletonRow,\n    kFixedCol,\n    kRedundantRow,\n    kForcingRow,\n    kForcingColumn,\n    kForcingColumnRemovedRow,\n    kDuplicateRow,\n    kDuplicateColumn,\n    kSlackColSubstitution,\n  };\n\n  HighsDataStack reductionValues;\n  std::vector<std::pair<ReductionType, size_t>> reductions;\n  std::vector<HighsInt> origColIndex;\n  std::vector<HighsInt> origRowIndex;\n  std::vector<uint8_t> linearlyTransformable;\n\n  std::vector<Nonzero> rowValues;\n  std::vector<Nonzero> colValues;\n  HighsInt origNumCol = -1;\n  HighsInt origNumRow = -1;\n\n  void reductionAdded(ReductionType type) {\n    size_t position = reductionValues.getCurrentDataSize();\n    reductions.emplace_back(type, position);\n  }\n\n public:\n  const HighsInt* getOrigRowsIndex() const { return origRowIndex.data(); }\n\n  const HighsInt* getOrigColsIndex() const { return origColIndex.data(); }\n\n  HighsInt getOrigRowIndex(HighsInt row) const {\n    assert(row < (HighsInt)origRowIndex.size());\n    return origRowIndex[row];\n  }\n\n  HighsInt getOrigColIndex(HighsInt col) const {\n    assert(col < (HighsInt)origColIndex.size());\n    return origColIndex[col];\n  }\n\n  void appendCutsToModel(HighsInt numCuts) {\n    size_t currNumRow = origRowIndex.size();\n    size_t newNumRow = currNumRow + numCuts;\n    origRowIndex.resize(newNumRow);\n    for (size_t i = currNumRow; i != newNumRow; ++i)\n      origRowIndex[i] = origNumRow++;\n  }\n\n  void removeCutsFromModel(HighsInt numCuts) {\n    origNumRow -= numCuts;\n\n    size_t origRowIndexSize = origRowIndex.size();\n    for (size_t i = origRowIndex.size(); i > 0; --i) {\n      if (origRowIndex[i - 1] < origNumRow) break;\n      --origRowIndexSize;\n    }\n\n    origRowIndex.resize(origRowIndexSize);\n  }\n\n  HighsInt getOrigNumRow() const { return origNumRow; }\n\n  HighsInt getOrigNumCol() const { return origNumCol; }\n\n  void initializeIndexMaps(HighsInt numRow, HighsInt numCol);\n\n  void compressIndexMaps(const std::vector<HighsInt>& newRowIndex,\n                         const std::vector<HighsInt>& newColIndex);\n\n  /// transform a column x by a linear mapping with a new column x'.\n  /// I.e. substitute x = scale * x' + constant\n  void linearTransform(HighsInt col, double scale, double constant) {\n    reductionValues.push(LinearTransform{scale, constant, origColIndex[col]});\n    reductionAdded(ReductionType::kLinearTransform);\n  }\n\n  template <typename RowStorageFormat, typename ColStorageFormat>\n  void freeColSubstitution(HighsInt row, HighsInt col, double rhs,\n                           double colCost, RowType rowType,\n                           const HighsMatrixSlice<RowStorageFormat>& rowVec,\n                           const HighsMatrixSlice<ColStorageFormat>& colVec) {\n    rowValues.clear();\n    for (const HighsSliceNonzero& rowVal : rowVec)\n      rowValues.emplace_back(origColIndex[rowVal.index()], rowVal.value());\n\n    colValues.clear();\n    for (const HighsSliceNonzero& colVal : colVec)\n      colValues.emplace_back(origRowIndex[colVal.index()], colVal.value());\n\n    reductionValues.push(FreeColSubstitution{rhs, colCost, origRowIndex[row],\n                                             origColIndex[col], rowType});\n    reductionValues.push(rowValues);\n    reductionValues.push(colValues);\n    reductionAdded(ReductionType::kFreeColSubstitution);\n  }\n\n  template <typename RowStorageFormat>\n  void slackColSubstitution(HighsInt row, HighsInt col, double rhs,\n                            const HighsMatrixSlice<RowStorageFormat>& rowVec) {\n    rowValues.clear();\n    for (const HighsSliceNonzero& rowVal : rowVec)\n      rowValues.emplace_back(origColIndex[rowVal.index()], rowVal.value());\n\n    reductionValues.push(\n        SlackColSubstitution{rhs, origRowIndex[row], origColIndex[col]});\n    reductionValues.push(rowValues);\n    reductionAdded(ReductionType::kSlackColSubstitution);\n  }\n\n  template <typename ColStorageFormat>\n  void doubletonEquation(HighsInt row, HighsInt colSubst, HighsInt col,\n                         double coefSubst, double coef, double rhs,\n                         double substLower, double substUpper, double substCost,\n                         bool lowerTightened, bool upperTightened,\n                         RowType rowType,\n                         const HighsMatrixSlice<ColStorageFormat>& colVec) {\n    colValues.clear();\n    for (const HighsSliceNonzero& colVal : colVec)\n      colValues.emplace_back(origRowIndex[colVal.index()], colVal.value());\n\n    reductionValues.push(DoubletonEquation{\n        coef, coefSubst, rhs, substLower, substUpper, substCost,\n        row == -1 ? -1 : origRowIndex[row], origColIndex[colSubst],\n        origColIndex[col], lowerTightened, upperTightened, rowType});\n    reductionValues.push(colValues);\n    reductionAdded(ReductionType::kDoubletonEquation);\n  }\n\n  template <typename RowStorageFormat>\n  void equalityRowAddition(HighsInt row, HighsInt addedEqRow, double eqRowScale,\n                           const HighsMatrixSlice<RowStorageFormat>& eqRowVec) {\n    rowValues.clear();\n    for (const HighsSliceNonzero& rowVal : eqRowVec)\n      rowValues.emplace_back(origColIndex[rowVal.index()], rowVal.value());\n\n    reductionValues.push(EqualityRowAddition{\n        origRowIndex[row], origRowIndex[addedEqRow], eqRowScale});\n    reductionValues.push(rowValues);\n    reductionAdded(ReductionType::kEqualityRowAddition);\n  }\n\n  template <typename RowStorageFormat>\n  void equalityRowAdditions(HighsInt addedEqRow,\n                            const HighsMatrixSlice<RowStorageFormat>& eqRowVec,\n                            const std::vector<Nonzero>& targetRows) {\n    rowValues.clear();\n    for (const HighsSliceNonzero& rowVal : eqRowVec)\n      rowValues.emplace_back(origColIndex[rowVal.index()], rowVal.value());\n\n    reductionValues.push(EqualityRowAdditions{origRowIndex[addedEqRow]});\n    reductionValues.push(rowValues);\n    reductionValues.push(targetRows);\n    reductionAdded(ReductionType::kEqualityRowAdditions);\n  }\n\n  void singletonRow(HighsInt row, HighsInt col, double coef,\n                    bool tightenedColLower, bool tightenedColUpper) {\n    reductionValues.push(SingletonRow{coef, origRowIndex[row],\n                                      origColIndex[col], tightenedColLower,\n                                      tightenedColUpper});\n    reductionAdded(ReductionType::kSingletonRow);\n  }\n\n  template <typename ColStorageFormat>\n  void fixedColAtLower(HighsInt col, double fixValue, double colCost,\n                       const HighsMatrixSlice<ColStorageFormat>& colVec) {\n    assert(std::isfinite(fixValue));\n    colValues.clear();\n    for (const HighsSliceNonzero& colVal : colVec)\n      colValues.emplace_back(origRowIndex[colVal.index()], colVal.value());\n\n    reductionValues.push(FixedCol{fixValue, colCost, origColIndex[col],\n                                  HighsBasisStatus::kLower});\n    reductionValues.push(colValues);\n    reductionAdded(ReductionType::kFixedCol);\n  }\n\n  template <typename ColStorageFormat>\n  void fixedColAtUpper(HighsInt col, double fixValue, double colCost,\n                       const HighsMatrixSlice<ColStorageFormat>& colVec) {\n    assert(std::isfinite(fixValue));\n    colValues.clear();\n    for (const HighsSliceNonzero& colVal : colVec)\n      colValues.emplace_back(origRowIndex[colVal.index()], colVal.value());\n\n    reductionValues.push(FixedCol{fixValue, colCost, origColIndex[col],\n                                  HighsBasisStatus::kUpper});\n    reductionValues.push(colValues);\n    reductionAdded(ReductionType::kFixedCol);\n  }\n\n  template <typename ColStorageFormat>\n  void fixedColAtZero(HighsInt col, double colCost,\n                      const HighsMatrixSlice<ColStorageFormat>& colVec) {\n    colValues.clear();\n    for (const HighsSliceNonzero& colVal : colVec)\n      colValues.emplace_back(origRowIndex[colVal.index()], colVal.value());\n\n    reductionValues.push(\n        FixedCol{0.0, colCost, origColIndex[col], HighsBasisStatus::kZero});\n    reductionValues.push(colValues);\n    reductionAdded(ReductionType::kFixedCol);\n  }\n\n  template <typename ColStorageFormat>\n  void removedFixedCol(HighsInt col, double fixValue, double colCost,\n                       const HighsMatrixSlice<ColStorageFormat>& colVec) {\n    assert(std::isfinite(fixValue));\n    colValues.clear();\n    for (const HighsSliceNonzero& colVal : colVec)\n      colValues.emplace_back(origRowIndex[colVal.index()], colVal.value());\n\n    reductionValues.push(FixedCol{fixValue, colCost, origColIndex[col],\n                                  HighsBasisStatus::kNonbasic});\n    reductionValues.push(colValues);\n    reductionAdded(ReductionType::kFixedCol);\n  }\n\n  void redundantRow(HighsInt row) {\n    reductionValues.push(RedundantRow{origRowIndex[row]});\n    reductionAdded(ReductionType::kRedundantRow);\n  }\n\n  template <typename RowStorageFormat>\n  void forcingRow(HighsInt row,\n                  const HighsMatrixSlice<RowStorageFormat>& rowVec, double side,\n                  RowType rowType) {\n    rowValues.clear();\n    for (const HighsSliceNonzero& rowVal : rowVec)\n      rowValues.emplace_back(origColIndex[rowVal.index()], rowVal.value());\n\n    reductionValues.push(ForcingRow{side, origRowIndex[row], rowType});\n    reductionValues.push(rowValues);\n    reductionAdded(ReductionType::kForcingRow);\n  }\n\n  template <typename ColStorageFormat>\n  void forcingColumn(HighsInt col,\n                     const HighsMatrixSlice<ColStorageFormat>& colVec,\n                     double cost, double boundVal, bool atInfiniteUpper,\n                     bool colIntegral) {\n    colValues.clear();\n    for (const HighsSliceNonzero& colVal : colVec)\n      colValues.emplace_back(origRowIndex[colVal.index()], colVal.value());\n\n    reductionValues.push(ForcingColumn{cost, boundVal, origColIndex[col],\n                                       atInfiniteUpper, colIntegral});\n    reductionValues.push(colValues);\n    reductionAdded(ReductionType::kForcingColumn);\n  }\n\n  template <typename RowStorageFormat>\n  void forcingColumnRemovedRow(\n      HighsInt forcingCol, HighsInt row, double rhs,\n      const HighsMatrixSlice<RowStorageFormat>& rowVec) {\n    rowValues.clear();\n    for (const HighsSliceNonzero& rowVal : rowVec)\n      if (rowVal.index() != forcingCol)\n        rowValues.emplace_back(origColIndex[rowVal.index()], rowVal.value());\n\n    reductionValues.push(ForcingColumnRemovedRow{rhs, origRowIndex[row]});\n    reductionValues.push(rowValues);\n    reductionAdded(ReductionType::kForcingColumnRemovedRow);\n  }\n\n  void duplicateRow(HighsInt row, bool rowUpperTightened,\n                    bool rowLowerTightened, HighsInt duplicateRow,\n                    double duplicateRowScale) {\n    reductionValues.push(\n        DuplicateRow{duplicateRowScale, origRowIndex[duplicateRow],\n                     origRowIndex[row], rowLowerTightened, rowUpperTightened});\n    reductionAdded(ReductionType::kDuplicateRow);\n  }\n\n  bool duplicateColumn(double colScale, double colLower, double colUpper,\n                       double duplicateColLower, double duplicateColUpper,\n                       HighsInt col, HighsInt duplicateCol, bool colIntegral,\n                       bool duplicateColIntegral,\n                       const double ok_merge_tolerance) {\n    const HighsInt origCol = origColIndex[col];\n    const HighsInt origDuplicateCol = origColIndex[duplicateCol];\n    DuplicateColumn debug_values = {\n        colScale,          colLower,          colUpper,\n        duplicateColLower, duplicateColUpper, origCol,\n        origDuplicateCol,  colIntegral,       duplicateColIntegral};\n    const bool ok_merge = debug_values.okMerge(ok_merge_tolerance);\n    const bool prevent_illegal_merge = true;\n    if (!ok_merge && prevent_illegal_merge) return false;\n    reductionValues.push(debug_values);\n    //    reductionValues.push(DuplicateColumn{\n    //        colScale, colLower, colUpper, duplicateColLower,\n    //        duplicateColUpper, origCol, origDuplicateCol, colIntegral,\n    //        duplicateColIntegral});\n\n    reductionAdded(ReductionType::kDuplicateColumn);\n\n    // mark columns as not linearly transformable\n    linearlyTransformable[origCol] = false;\n    linearlyTransformable[origDuplicateCol] = false;\n    return true;\n  }\n\n  std::vector<double> getReducedPrimalSolution(\n      const std::vector<double>& origPrimalSolution) {\n    std::vector<double> reducedSolution = origPrimalSolution;\n\n    for (const std::pair<ReductionType, size_t>& primalColTransformation :\n         reductions) {\n      switch (primalColTransformation.first) {\n        case ReductionType::kDuplicateColumn: {\n          DuplicateColumn duplicateColReduction;\n          reductionValues.setPosition(primalColTransformation.second);\n          reductionValues.pop(duplicateColReduction);\n          duplicateColReduction.transformToPresolvedSpace(reducedSolution);\n          break;\n        }\n        case ReductionType::kLinearTransform: {\n          reductionValues.setPosition(primalColTransformation.second);\n          LinearTransform linearTransform;\n          reductionValues.pop(linearTransform);\n          linearTransform.transformToPresolvedSpace(reducedSolution);\n          break;\n        }\n        default:\n          continue;\n      }\n    }\n\n    size_t reducedNumCol = origColIndex.size();\n    for (size_t i = 0; i < reducedNumCol; ++i)\n      reducedSolution[i] = reducedSolution[origColIndex[i]];\n\n    reducedSolution.resize(reducedNumCol);\n    return reducedSolution;\n  }\n\n  bool isColLinearlyTransformable(HighsInt col) const {\n    assert(col >= 0);\n    assert(static_cast<size_t>(col) < origColIndex.size());\n    return (linearlyTransformable[origColIndex[col]] != 0);\n  }\n\n  template <typename T>\n  void undoIterateBackwards(std::vector<T>& values,\n                            const std::vector<HighsInt>& index,\n                            HighsInt origSize) {\n    values.resize(origSize);\n#ifdef DEBUG_EXTRA\n    // Fill vector with NaN for debugging purposes\n    std::vector<T> valuesNew;\n    valuesNew.resize(origSize, std::numeric_limits<T>::signaling_NaN());\n    for (size_t i = index.size(); i > 0; --i) {\n      assert(static_cast<size_t>(index[i - 1]) >= i - 1);\n      valuesNew[index[i - 1]] = values[i - 1];\n    }\n    std::copy(valuesNew.cbegin(), valuesNew.cend(), values.begin());\n#else\n    for (size_t i = index.size(); i > 0; --i) {\n      assert(static_cast<size_t>(index[i - 1]) >= i - 1);\n      values[index[i - 1]] = values[i - 1];\n    }\n#endif\n  }\n\n  /// check if vector contains NaN or Inf\n  bool containsNanOrInf(const std::vector<double>& v) const {\n    return std::find_if(v.cbegin(), v.cend(), [](const double& d) {\n             return (std::isnan(d) || std::isinf(d));\n           }) != v.cend();\n  }\n\n  /// undo presolve steps for primal dual solution and basis\n  void undo(const HighsOptions& options, HighsSolution& solution,\n            HighsBasis& basis, const HighsInt report_col = -1) {\n    reductionValues.resetPosition();\n\n    // Verify that undo can be performed\n    assert(solution.value_valid);\n    bool perform_dual_postsolve = solution.dual_valid;\n    bool perform_basis_postsolve = basis.valid;\n\n    // expand solution to original index space\n    assert(origNumCol > 0);\n    undoIterateBackwards(solution.col_value, origColIndex, origNumCol);\n\n    assert(origNumRow >= 0);\n    undoIterateBackwards(solution.row_value, origRowIndex, origNumRow);\n\n    if (perform_dual_postsolve) {\n      // if dual solution is given, expand dual solution and basis to original\n      // index space\n      undoIterateBackwards(solution.col_dual, origColIndex, origNumCol);\n\n      undoIterateBackwards(solution.row_dual, origRowIndex, origNumRow);\n    }\n\n    if (perform_basis_postsolve) {\n      // if basis is given, expand basis status values to original index space\n      undoIterateBackwards(basis.col_status, origColIndex, origNumCol);\n\n      undoIterateBackwards(basis.row_status, origRowIndex, origNumRow);\n    }\n\n    // now undo the changes\n    for (size_t i = reductions.size(); i > 0; --i) {\n      if (report_col >= 0)\n        printf(\"Before  reduction %2d (type %2d): col_value[%2d] = %g\\n\",\n               int(i - 1), int(reductions[i - 1].first), int(report_col),\n               solution.col_value[report_col]);\n      switch (reductions[i - 1].first) {\n        case ReductionType::kLinearTransform: {\n          LinearTransform reduction;\n          reductionValues.pop(reduction);\n          reduction.undo(options, solution);\n          break;\n        }\n        case ReductionType::kFreeColSubstitution: {\n          FreeColSubstitution reduction;\n          reductionValues.pop(colValues);\n          reductionValues.pop(rowValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, rowValues, colValues, solution, basis);\n          break;\n        }\n        case ReductionType::kDoubletonEquation: {\n          DoubletonEquation reduction;\n          reductionValues.pop(colValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, colValues, solution, basis);\n          break;\n        }\n        case ReductionType::kEqualityRowAddition: {\n          EqualityRowAddition reduction;\n          reductionValues.pop(rowValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, rowValues, solution, basis);\n          break;\n        }\n        case ReductionType::kEqualityRowAdditions: {\n          EqualityRowAdditions reduction;\n          reductionValues.pop(colValues);\n          reductionValues.pop(rowValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, rowValues, colValues, solution, basis);\n          break;\n        }\n        case ReductionType::kSingletonRow: {\n          SingletonRow reduction;\n          reductionValues.pop(reduction);\n          reduction.undo(options, solution, basis);\n          break;\n        }\n        case ReductionType::kFixedCol: {\n          FixedCol reduction;\n          reductionValues.pop(colValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, colValues, solution, basis);\n          break;\n        }\n        case ReductionType::kRedundantRow: {\n          RedundantRow reduction;\n          reductionValues.pop(reduction);\n          reduction.undo(options, solution, basis);\n          break;\n        }\n        case ReductionType::kForcingRow: {\n          ForcingRow reduction;\n          reductionValues.pop(rowValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, rowValues, solution, basis);\n          break;\n        }\n        case ReductionType::kForcingColumn: {\n          ForcingColumn reduction;\n          reductionValues.pop(colValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, colValues, solution, basis);\n          break;\n        }\n        case ReductionType::kForcingColumnRemovedRow: {\n          ForcingColumnRemovedRow reduction;\n          reductionValues.pop(rowValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, rowValues, solution, basis);\n          break;\n        }\n        case ReductionType::kDuplicateRow: {\n          DuplicateRow reduction;\n          reductionValues.pop(reduction);\n          reduction.undo(options, solution, basis);\n          break;\n        }\n        case ReductionType::kDuplicateColumn: {\n          DuplicateColumn reduction;\n          reductionValues.pop(reduction);\n          reduction.undo(options, solution, basis);\n          break;\n        }\n        case ReductionType::kSlackColSubstitution: {\n          SlackColSubstitution reduction;\n          reductionValues.pop(rowValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, rowValues, solution, basis);\n          break;\n        }\n        default:\n          printf(\"Reduction case %d not handled\\n\",\n                 int(reductions[i - 1].first));\n          if (kAllowDeveloperAssert) assert(1 == 0);\n      }\n    }\n    if (report_col >= 0)\n      printf(\"After last reduction: col_value[%2d] = %g\\n\", int(report_col),\n             solution.col_value[report_col]);\n\n#ifdef DEBUG_EXTRA\n    // solution should not contain NaN or Inf\n    assert(!containsNanOrInf(solution.col_value));\n    // row values are not determined by postsolve\n    // assert(!containsNanOrInf(solution.row_value));\n    assert(!containsNanOrInf(solution.col_dual));\n    assert(!containsNanOrInf(solution.row_dual));\n#endif\n  }\n\n  /// undo presolve steps for primal solution\n  void undoPrimal(const HighsOptions& options, HighsSolution& solution,\n                  const HighsInt report_col = -1) {\n    // Call to reductionValues.resetPosition(); seems unnecessary as\n    // it's the first thing done in undo\n    reductionValues.resetPosition();\n    HighsBasis basis;\n    basis.valid = false;\n    solution.dual_valid = false;\n    undo(options, solution, basis, report_col);\n  }\n\n  /*\n    // Not used\n  /// undo presolve steps for primal and dual solution\n  void undoPrimalDual(const HighsOptions& options, HighsSolution& solution) {\n    reductionValues.resetPosition();\n    HighsBasis basis;\n    basis.valid = false;\n    assert(solution.value_valid);\n    assert(solution.dual_valid);\n    undo(options, solution, basis);\n  }\n  */\n\n  // Only used for debugging\n  void undoUntil(const HighsOptions& options, HighsSolution& solution,\n                 HighsBasis& basis, size_t numReductions) {\n    reductionValues.resetPosition();\n\n    // Do these returns ever happen? How is it known that undo has not\n    // been performed?\n    assert(solution.col_value.size() == origColIndex.size());\n    assert(solution.row_value.size() == origRowIndex.size());\n    // This should be a better measure of whether undo can be\n    // performed\n    assert(solution.value_valid);\n    if (solution.col_value.size() != origColIndex.size()) return;\n    if (solution.row_value.size() != origRowIndex.size()) return;\n\n    bool perform_dual_postsolve = solution.dual_valid;\n    assert((solution.col_dual.size() == solution.col_value.size()) ==\n           perform_dual_postsolve);\n    bool perform_basis_postsolve = basis.valid;\n\n    // expand solution to original index space\n    undoIterateBackwards(solution.col_value, origColIndex, origNumCol);\n\n    undoIterateBackwards(solution.row_value, origRowIndex, origNumRow);\n\n    if (perform_dual_postsolve) {\n      // if dual solution is given, expand dual solution and basis to original\n      // index space\n      undoIterateBackwards(solution.col_dual, origColIndex, origNumCol);\n\n      undoIterateBackwards(solution.row_dual, origRowIndex, origNumRow);\n    }\n\n    if (perform_basis_postsolve) {\n      // if basis is given, expand basis status values to original index space\n      undoIterateBackwards(basis.col_status, origColIndex, origNumCol);\n\n      undoIterateBackwards(basis.row_status, origRowIndex, origNumRow);\n    }\n\n    // now undo the changes\n    for (size_t i = reductions.size(); i > numReductions; --i) {\n      switch (reductions[i - 1].first) {\n        case ReductionType::kLinearTransform: {\n          LinearTransform reduction;\n          reductionValues.pop(reduction);\n          reduction.undo(options, solution);\n          break;\n        }\n        case ReductionType::kFreeColSubstitution: {\n          FreeColSubstitution reduction;\n          reductionValues.pop(colValues);\n          reductionValues.pop(rowValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, rowValues, colValues, solution, basis);\n          break;\n        }\n        case ReductionType::kDoubletonEquation: {\n          DoubletonEquation reduction;\n          reductionValues.pop(colValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, colValues, solution, basis);\n          break;\n        }\n        case ReductionType::kEqualityRowAddition: {\n          EqualityRowAddition reduction;\n          reductionValues.pop(rowValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, rowValues, solution, basis);\n          break;\n        }\n        case ReductionType::kEqualityRowAdditions: {\n          EqualityRowAdditions reduction;\n          reductionValues.pop(colValues);\n          reductionValues.pop(rowValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, rowValues, colValues, solution, basis);\n          break;\n        }\n        case ReductionType::kSingletonRow: {\n          SingletonRow reduction;\n          reductionValues.pop(reduction);\n          reduction.undo(options, solution, basis);\n          break;\n        }\n        case ReductionType::kFixedCol: {\n          FixedCol reduction;\n          reductionValues.pop(colValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, colValues, solution, basis);\n          break;\n        }\n        case ReductionType::kRedundantRow: {\n          RedundantRow reduction;\n          reductionValues.pop(reduction);\n          reduction.undo(options, solution, basis);\n          break;\n        }\n        case ReductionType::kForcingRow: {\n          ForcingRow reduction;\n          reductionValues.pop(rowValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, rowValues, solution, basis);\n          break;\n        }\n        case ReductionType::kForcingColumn: {\n          ForcingColumn reduction;\n          reductionValues.pop(colValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, colValues, solution, basis);\n          break;\n        }\n        case ReductionType::kForcingColumnRemovedRow: {\n          ForcingColumnRemovedRow reduction;\n          reductionValues.pop(rowValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, rowValues, solution, basis);\n          break;\n        }\n        case ReductionType::kDuplicateRow: {\n          DuplicateRow reduction;\n          reductionValues.pop(reduction);\n          reduction.undo(options, solution, basis);\n          break;\n        }\n        case ReductionType::kDuplicateColumn: {\n          DuplicateColumn reduction;\n          reductionValues.pop(reduction);\n          reduction.undo(options, solution, basis);\n        }\n        case ReductionType::kSlackColSubstitution: {\n          SlackColSubstitution reduction;\n          reductionValues.pop(rowValues);\n          reductionValues.pop(reduction);\n          reduction.undo(options, rowValues, solution, basis);\n          break;\n        }\n      }\n    }\n#ifdef DEBUG_EXTRA\n    // solution should not contain NaN or Inf\n    assert(!containsNanOrInf(solution.col_value));\n    // row values are not determined by postsolve\n    // assert(!containsNanOrInf(solution.row_value));\n    assert(!containsNanOrInf(solution.col_dual));\n    assert(!containsNanOrInf(solution.row_dual));\n#endif\n  }\n\n  size_t numReductions() const { return reductions.size(); }\n};\n\n}  // namespace presolve\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/presolve/HighsSymmetry.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file HighsSymmetry.h\n * @brief Facilities for symmetry detection\n * @author Leona Gottwald\n */\n\n#ifndef PRESOLVE_HIGHS_SYMMETRY_H_\n#define PRESOLVE_HIGHS_SYMMETRY_H_\n\n#include <algorithm>\n#include <map>\n#include <vector>\n\n#include \"lp_data/HighsLp.h\"\n#include \"util/HighsDisjointSets.h\"\n#include \"util/HighsHash.h\"\n#include \"util/HighsInt.h\"\n\n/// class that is responsible for assigning distinct colors for each distinct\n/// double value\nclass HighsMatrixColoring {\n  using u32 = std::uint32_t;\n\n  std::map<double, u32> colorMap;\n  double tolerance;\n\n public:\n  // initialize with exact 0.0 and 1.0, to not have differing results due tiny\n  // numerical differences on those values\n  HighsMatrixColoring(double tolerance)\n      : colorMap({{0.0, 1}, {1.0, 2}, {-kHighsInf, 3}, {kHighsInf, 4}}),\n        tolerance(tolerance) {}\n\n  u32 color(double value) {\n    // iterator points to smallest element in map which fulfills key >= value -\n    // tolerance\n    auto it = colorMap.lower_bound(value - tolerance);\n    // check if there is no such element, or if this element has a key value +\n    // tolerance in which case we create a new color and store it with the key\n    // value\n    if (it == colorMap.end() || it->first > value + tolerance)\n      it = colorMap.emplace_hint(it, value,\n                                 static_cast<u32>(colorMap.size()) + 1);\n    return it->second;\n  }\n};\n\nclass HighsDomain;\nclass HighsCliqueTable;\nstruct HighsSymmetries;\nstruct StabilizerOrbits {\n  std::vector<HighsInt> orbitCols;\n  std::vector<HighsInt> orbitStarts;\n  std::vector<HighsInt> stabilizedCols;\n  const HighsSymmetries* symmetries;\n\n  HighsInt orbitalFixing(HighsDomain& domain) const;\n\n  bool isStabilized(HighsInt col) const;\n};\n\nstruct HighsOrbitopeMatrix {\n  enum Type {\n    kFull,\n    kPacking,\n  };\n  HighsInt rowLength;\n  HighsInt numRows;\n  HighsInt numSetPackingRows;\n  HighsHashTable<HighsInt, HighsInt> columnToRow;\n  std::vector<int8_t> rowIsSetPacking;\n  std::vector<HighsInt> matrix;\n\n  HighsInt& entry(HighsInt i, HighsInt j) {\n    return matrix[i + static_cast<size_t>(j) * numRows];\n  }\n\n  const HighsInt& entry(HighsInt i, HighsInt j) const {\n    return matrix[i + static_cast<size_t>(j) * numRows];\n  }\n\n  HighsInt& operator()(HighsInt i, HighsInt j) { return entry(i, j); }\n\n  const HighsInt& operator()(HighsInt i, HighsInt j) const {\n    return entry(i, j);\n  }\n\n  HighsInt orbitalFixing(HighsDomain& domain) const;\n\n  void determineOrbitopeType(HighsCliqueTable& cliquetable);\n\n  HighsInt getBranchingColumn(const std::vector<double>& colLower,\n                              const std::vector<double>& colUpper,\n                              HighsInt col) const;\n\n private:\n  HighsInt orbitalFixingForFullOrbitope(const std::vector<HighsInt>& rows,\n                                        HighsDomain& domain) const;\n\n  HighsInt orbitalFixingForPackingOrbitope(const std::vector<HighsInt>& rows,\n                                           HighsDomain& domain) const;\n};\n\nstruct HighsSymmetries {\n  std::vector<HighsInt> permutationColumns;\n  std::vector<HighsInt> permutations;\n  std::vector<HighsInt> orbitPartition;\n  std::vector<HighsInt> orbitSize;\n  std::vector<HighsInt> columnPosition;\n  std::vector<HighsInt> linkCompressionStack;\n  std::vector<HighsOrbitopeMatrix> orbitopes;\n  HighsHashTable<HighsInt, HighsInt> columnToOrbitope;\n  HighsInt numPerms = 0;\n  HighsInt numGenerators = 0;\n\n  void clear();\n  void mergeOrbits(HighsInt col1, HighsInt col2);\n  HighsInt getOrbit(HighsInt col);\n\n  HighsInt propagateOrbitopes(HighsDomain& domain) const;\n\n  HighsInt getBranchingColumn(const std::vector<double>& colLower,\n                              const std::vector<double>& colUpper,\n                              HighsInt col) const {\n    if (columnToOrbitope.size() == 0) return col;\n    const HighsInt* orbitope = columnToOrbitope.find(col);\n    if (!orbitope || orbitopes[*orbitope].numSetPackingRows == 0) return col;\n\n    return orbitopes[*orbitope].getBranchingColumn(colLower, colUpper, col);\n  }\n\n  std::shared_ptr<const StabilizerOrbits> computeStabilizerOrbits(\n      const HighsDomain& localdom);\n};\n\nclass HighsSymmetryDetection {\n  using u64 = std::uint64_t;\n  using u32 = std::uint32_t;\n\n  const HighsLp* model;\n  // compressed graph storage\n  std::vector<HighsInt> Gstart;\n  std::vector<HighsInt> Gend;\n  std::vector<std::pair<HighsInt, HighsUInt>> Gedge;\n\n  std::vector<std::pair<HighsInt, HighsUInt>> edgeBuffer;\n\n  std::vector<HighsInt> currentPartition;\n  std::vector<HighsInt> currentPartitionLinks;\n  std::vector<HighsInt> vertexToCell;\n  std::vector<HighsInt> vertexPosition;\n  std::vector<HighsInt> vertexGroundSet;\n  std::vector<HighsInt> orbitPartition;\n  std::vector<HighsInt> orbitSize;\n\n  std::vector<HighsInt> cellCreationStack;\n  std::vector<std::uint8_t> cellInRefinementQueue;\n  std::vector<HighsInt> refinementQueue;\n  std::vector<HighsInt*> distinguishCands;\n  std::vector<HighsInt> automorphisms;\n\n  std::vector<HighsInt> linkCompressionStack;\n\n  std::vector<u32> currNodeCertificate;\n  std::vector<u32> firstLeaveCertificate;\n  std::vector<u32> bestLeaveCertificate;\n  std::vector<HighsInt> firstLeavePartition;\n  std::vector<HighsInt> bestLeavePartition;\n\n  HighsHashTable<HighsInt, u32> vertexHash;\n  HighsHashTable<std::tuple<HighsInt, HighsInt, HighsUInt>> firstLeaveGraph;\n  HighsHashTable<std::tuple<HighsInt, HighsInt, HighsUInt>> bestLeaveGraph;\n\n  HighsInt firstLeavePrefixLen;\n  HighsInt bestLeavePrefixLen;\n  HighsInt firstPathDepth;\n  HighsInt bestPathDepth;\n\n  HighsInt numAutomorphisms;\n  HighsInt numCol;\n  HighsInt numRow;\n  HighsInt numVertices;\n  HighsInt numActiveCols;\n\n  // node in the search tree for finding automorphisms\n  struct Node {\n    HighsInt stackStart;\n    HighsInt certificateEnd;\n    HighsInt targetCell;\n    HighsInt lastDistiguished;\n  };\n\n  std::vector<Node> nodeStack;\n\n  HighsInt getCellStart(HighsInt pos);\n\n  void backtrack(HighsInt backtrackStackNewEnd, HighsInt backtrackStackEnd);\n  void cleanupBacktrack(HighsInt cellCreationStackPos);\n\n  void switchToNextNode(HighsInt backtrackDepth);\n\n  bool compareCurrentGraph(\n      const HighsHashTable<std::tuple<HighsInt, HighsInt, HighsUInt>>&\n          otherGraph,\n      HighsInt& wrongCell) const;\n\n  void removeFixPoints();\n  void initializeGroundSet();\n  HighsHashTable<std::tuple<HighsInt, HighsInt, HighsUInt>> dumpCurrentGraph();\n  bool mergeOrbits(HighsInt v1, HighsInt v2);\n  HighsInt getOrbit(HighsInt vertex);\n\n  void initializeHashValues();\n  bool isomorphicToFirstLeave();\n  bool partitionRefinement();\n  bool checkStoredAutomorphism(HighsInt vertex) const;\n  u32 getVertexHash(HighsInt vertex);\n  HighsInt selectTargetCell() const;\n\n  bool updateCellMembership(HighsInt vertex, HighsInt cell,\n                            bool markForRefinement = true);\n  bool splitCell(HighsInt cell, HighsInt splitPoint);\n  void markCellForRefinement(HighsInt cell);\n\n  bool distinguishVertex(HighsInt targetCell);\n  bool determineNextToDistinguish();\n  void createNode();\n\n  HighsInt cellSize(HighsInt cell) const {\n    return currentPartitionLinks[cell] - cell;\n  }\n\n  bool isFromBinaryColumn(HighsInt vertex) const;\n\n  struct ComponentData {\n    HighsDisjointSets<> components;\n    std::vector<HighsInt> componentStarts;\n    std::vector<HighsInt> componentSets;\n    std::vector<HighsInt> componentNumOrbits;\n    std::vector<HighsInt> componentNumber;\n    std::vector<HighsInt> permComponentStarts;\n    std::vector<HighsInt> permComponents;\n    std::vector<HighsInt> firstUnfixed;\n    std::vector<HighsInt> numUnfixed;\n\n    HighsInt getComponentByIndex(HighsInt compIndex) const {\n      return componentNumber[compIndex];\n    }\n    HighsInt numComponents() const {\n      return static_cast<HighsInt>(componentStarts.size()) - 1;\n    }\n    HighsInt componentSize(HighsInt component) const {\n      return componentStarts[component + 1] - componentStarts[component];\n    }\n\n    HighsInt getVertexComponent(HighsInt vertexPosition) {\n      return components.getSet(vertexPosition);\n    }\n\n    HighsInt getPermuationComponent(HighsInt permIndex) {\n      return components.getSet(firstUnfixed[permIndex]);\n    }\n  };\n\n  ComponentData computeComponentData(const HighsSymmetries& symmetries);\n\n  bool isFullOrbitope(const ComponentData& componentData, HighsInt component,\n                      HighsSymmetries& symmetries);\n\n public:\n  void loadModelAsGraph(const HighsLp& model, double epsilon);\n\n  bool initializeDetection();\n\n  void run(HighsSymmetries& symmetries);\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/presolve/ICrash.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file presolve/ICrash.h\n * @brief\n * @author Julian Hall, Ivet Galabova, Qi Huangfu and Michael Feldmeier\n */\n#ifndef PRESOLVE_QUADRATIC_CRASH_H_\n#define PRESOLVE_QUADRATIC_CRASH_H_\n\n#include <vector>\n\n#include \"io/HighsIO.h\"\n#include \"lp_data/HStruct.h\"\n#include \"lp_data/HighsLp.h\"\n#include \"lp_data/HighsOptions.h\"\n#include \"lp_data/HighsStatus.h\"\n\nenum class ICrashStrategy {\n  kPenalty,\n  kAdmm,\n  kICA,\n  kUpdatePenalty,\n  kUpdateAdmm\n};\n\nstruct ICrashIterationDetails {\n  int num;\n  double weight;\n  double lambda_norm_2;\n\n  double lp_objective;\n  double quadratic_objective;\n  double residual_norm_2;\n\n  double time;\n};\n\nstruct ICrashInfo {\n  int num_iterations;\n\n  double final_lp_objective;\n  double final_quadratic_objective;\n  double final_residual_norm_2;\n\n  double starting_weight;\n  double final_weight;\n\n  std::vector<ICrashIterationDetails> details;\n  std::vector<double> x_values;\n\n  double total_time;\n};\n\nstruct ICrashOptions {\n  bool dualize;\n  ICrashStrategy strategy;\n  double starting_weight;\n  HighsInt iterations;\n  HighsInt approximate_minimization_iterations;\n  bool exact;\n  bool breakpoints;  // gets ignored if exact is set to true\n  HighsLogOptions log_options;\n};\n\nstruct Quadratic {\n  const HighsLp lp;\n  const ICrashOptions options;\n  std::vector<ICrashIterationDetails> details;\n\n  HighsSolution xk;\n\n  double lp_objective;\n  double quadratic_objective;\n  std::vector<double> residual;\n  double residual_norm_2;\n\n  double mu;\n  std::vector<double> lambda;\n\n  Quadratic(HighsLp lp_, ICrashOptions options_)\n      : lp(lp_),\n        options(options_),\n        lp_objective(0.0),\n        quadratic_objective(0.0),\n        residual_norm_2(0.0),\n        mu(0.0) {}\n};\n\n// Functions: Call.\nHighsStatus callICrash(const HighsLp& lp, const ICrashOptions& options,\n                       ICrashInfo& result);\n\n// Functions: Options.\nbool checkOptions(const HighsLp& lp, const ICrashOptions options);\nQuadratic parseOptions(const HighsLp& lp, const ICrashOptions options);\nbool parseICrashStrategy(const std::string& strategy,\n                         ICrashStrategy& icrash_strategy);\nstd::string ICrashtrategyToString(const ICrashStrategy strategy);\n\n// Functions: Crash.\nbool initialize(Quadratic& idata, const ICrashOptions& options);\nvoid update(Quadratic& idata);\nvoid updateParameters(Quadratic& idata, const ICrashOptions& options,\n                      const int iteration);\nbool solveSubproblem(Quadratic& idata, const ICrashOptions& options);\n\n// Functions: Util.\ndouble getQuadraticObjective(const Quadratic& idata);\nICrashIterationDetails fillDetails(const int num, const Quadratic& idata);\nvoid fillICrashInfo(const int n_iterations, ICrashInfo& result);\nvoid reportSubproblem(const ICrashOptions options, const Quadratic& idata,\n                      const int iteration);\nvoid reportOptions(const ICrashOptions& options);\n\nbool callCrossover(const HighsLp& lp, const HighsOptions& options,\n                   const std::vector<double>& x_values, HighsSolution& solution,\n                   HighsBasis& basis, HighsCallback& callback);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/presolve/ICrashUtil.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file presolve/ICrashUtil.h\n * @brief\n * @author Julian Hall, Ivet Galabova, Qi Huangfu and Michael Feldmeier\n */\n#ifndef PRESOLVE_ICRASH_UTIL_H_\n#define PRESOLVE_ICRASH_UTIL_H_\n\n#include <vector>\n\n#include \"io/HighsIO.h\"\n\nclass HighsLp;\nstruct HighsSolution;\n\nvoid convertToMinimization(HighsLp& lp);\n\nbool isEqualityProblem(const HighsLp& lp);\n\ndouble vectorProduct(const std::vector<double>& v1,\n                     const std::vector<double>& v2);\n\n// Calculates value of A^t*v in result.\nvoid muptiplyByTranspose(const HighsLp& lp, const std::vector<double>& v,\n                         std::vector<double>& result);\n\nvoid printMinorIterationDetails(const double iteration, const double col,\n                                const double old_value, const double update,\n                                const double ctx, const std::vector<double>& r,\n                                const double quadratic_objective,\n                                HighsLogOptions options);\n\nbool initialize(const HighsLp& lp, HighsSolution& solution,\n                std::vector<double>& lambda);\n\ndouble minimizeComponentQP(const int col, const double mu, const HighsLp& lp,\n                           double& objective, std::vector<double>& residual,\n                           HighsSolution& sol);\n\ndouble minimizeComponentIca(const int col, const double mu,\n                            const std::vector<double>& lambda,\n                            const HighsLp& lp, double& objective,\n                            std::vector<double>& residual, HighsSolution& sol);\n\n// todo:\ndouble minimizeComponentBreakpoints();\n\nvoid updateResidual(bool piecewise, const HighsLp& lp, const HighsSolution& sol,\n                    std::vector<double>& residual);\nvoid updateResidualFast(const HighsLp& lp, const HighsSolution& sol,\n                        std::vector<double>& residual);\n\n// Allows negative residuals\nvoid updateResidualIca(const HighsLp& lp, const HighsSolution& sol,\n                       std::vector<double>& residual);\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/presolve/ICrashX.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef PRESOLVE_ICRASHX_H_\n#define PRESOLVE_ICRASHX_H_\n\n#include <iostream>\n\n#include \"HConfig.h\"\n#include \"lp_data/HighsLp.h\"\n#include \"lp_data/HighsSolution.h\"\n\nHighsStatus callCrossover(const HighsOptions& options, const HighsLp& lp,\n                          HighsBasis& highs_basis,\n                          HighsSolution& highs_solution,\n                          HighsModelStatus& model_status, HighsInfo& highs_info,\n                          HighsCallback& highs_callback);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/presolve/PresolveComponent.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file PresolveComponent.h\n * @brief The HiGHS class\n */\n#ifndef PRESOLVE_PRESOLVE_COMPONENT_H_\n#define PRESOLVE_PRESOLVE_COMPONENT_H_\n\n// Not all necessary, but copied from Presolve.h to avoid non-Linux\n// failures\n#include <list>\n#include <map>\n#include <stack>\n#include <string>\n#include <utility>\n\n#include \"lp_data/HighsLp.h\"\n#include \"presolve/HighsPostsolveStack.h\"\n#include \"util/HighsComponent.h\"\n#include \"util/HighsTimer.h\"\n\n// Class defining the Presolve Component to be used in HiGHS.\n// What used to be in Presolve.h but allowing for further testing and dev.\n\n// The structure of component is general, of the presolve component - presolve\n// specific.\n\nstruct PresolveComponentData : public HighsComponentData {\n  HighsLp reduced_lp_;\n  presolve::HighsPostsolveStack postSolveStack;\n  HighsSolution recovered_solution_;\n  HighsBasis recovered_basis_;\n  HighsPresolveLog presolve_log_;\n\n  void clear() {\n    is_valid = false;\n\n    postSolveStack = presolve::HighsPostsolveStack();\n\n    reduced_lp_.clear();\n    recovered_solution_.clear();\n    recovered_basis_.clear();\n  }\n\n  virtual ~PresolveComponentData() = default;\n};\n\n// HighsComponentInfo is a placeholder for details we want to query from outside\n// of HiGHS like execution information. Times are recorded at the end of\n// Highs::run()\nstruct PresolveComponentInfo : public HighsComponentInfo {\n  HighsInt n_rows_removed = 0;\n  HighsInt n_cols_removed = 0;\n  HighsInt n_nnz_removed = 0;\n\n  double presolve_time = 0;\n  double postsolve_time = 0;\n\n  virtual ~PresolveComponentInfo() = default;\n};\n\nclass PresolveComponent : public HighsComponent {\n public:\n  void clear() override;\n\n  HighsStatus init(const HighsLp& lp, HighsTimer& timer, bool mip = false);\n\n  HighsPresolveStatus run();\n\n  HighsLp& getReducedProblem() { return data_.reduced_lp_; }\n  HighsPresolveLog& getPresolveLog() { return data_.presolve_log_; }\n\n  void negateReducedLpColDuals();\n\n  PresolveComponentInfo info_;\n  PresolveComponentData data_;\n  const HighsOptions* options_;\n  HighsTimer* timer;\n\n  HighsPresolveStatus presolve_status_ = HighsPresolveStatus::kNotPresolved;\n  HighsPostsolveStatus postsolve_status_ = HighsPostsolveStatus::kNotPresolved;\n\n  virtual ~PresolveComponent() = default;\n};\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/a_asm.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_QPSOLVER_ASM_HPP__\n#define __SRC_LIB_QPSOLVER_ASM_HPP__\n\n#include \"qpsolver/instance.hpp\"\n#include \"qpsolver/qpconst.hpp\"\n#include \"qpsolver/settings.hpp\"\n#include \"qpsolver/statistics.hpp\"\n#include \"util/HighsTimer.h\"\n\nenum class QpAsmStatus {\n  kOk,\n  kWarning,\n  kError\n  //  NEGATIVEEIGENVALUEINREDUCEDHESSIAN,\n  //  BASISRANKDEFICIENT\n};\n\nstruct QpSolution {\n  QpVector primal;\n  QpVector rowactivity;\n  QpVector dualvar;\n  QpVector dualcon;\n\n  std::vector<BasisStatus> status_var;\n  std::vector<BasisStatus> status_con;\n\n  QpSolution(Instance& instance)\n      : primal(QpVector(instance.num_var)),\n        rowactivity(QpVector(instance.num_con)),\n        dualvar(instance.num_var),\n        dualcon(instance.num_con),\n        status_var(instance.num_var),\n        status_con(instance.num_con) {}\n};\n\nstruct QpHotstartInformation {\n  std::vector<HighsInt> active;\n  std::vector<HighsInt> inactive;\n  std::vector<BasisStatus> status;\n  QpVector primal;\n  QpVector rowact;\n\n  QpHotstartInformation(HighsInt num_var, HighsInt num_row)\n      : primal(QpVector(num_var)), rowact(QpVector(num_row)) {}\n};\n\n// the purpose of this is the pure algorithmic solution of a QP instance with\n// given hotstart information. scenarios: 1) start from a given phase1 solution\n// 2) start from a user-given hotstart solution\n// 3) start from a qp solution that was attained from a scaled instance and\n// cleanup 4) start from a qp solution that was attained from a perturbed\n// instance and cleanup 5) start from a qp solution and cleanup after\n// recomputing basis and reduced hessian factorization\n\nstd::string qpBasisStatusToString(const BasisStatus qp_basis_status);\nstd::string qpModelStatusToString(const QpModelStatus qp_model_status);\nvoid assessQpPrimalFeasibility(\n    const Instance& instance, const double primal_feasibility_tolerance,\n    const std::vector<double>& var_value, const std::vector<double>& con_value,\n    HighsInt& num_var_infeasibilities, double& max_var_infeasibility,\n    double& sum_var_infeasibilities, HighsInt& num_con_infeasibilities,\n    double& max_con_infeasibility, double& sum_con_infeasibilities,\n    double& max_con_residual, double& sum_con_residuals);\n\nQpAsmStatus solveqp_actual(Instance& instance, Settings& settings,\n                           QpHotstartInformation& startinfo, Statistics& stats,\n                           QpModelStatus& status, QpSolution& solution,\n                           HighsTimer& qp_timer);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/a_quass.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_QPSOLVER_QUASS_HPP__\n#define __SRC_LIB_QPSOLVER_QUASS_HPP__\n\n#include \"Highs.h\"\n#include \"qpsolver/a_asm.hpp\"\n#include \"qpsolver/instance.hpp\"\n#include \"qpsolver/qpconst.hpp\"\n#include \"qpsolver/settings.hpp\"\n\nQpAsmStatus solveqp(Instance& instance, Settings& settings, Statistics& stats,\n                    HighsModelStatus& highs_model_status,\n                    HighsBasis& highs_basis, HighsSolution& highs_solution,\n                    HighsTimer& timer);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/basis.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#pragma once\n#ifndef __SRC_LIB_BASIS_HPP__\n#define __SRC_LIB_BASIS_HPP__\n\n#include <map>\n#include <vector>\n\n#include \"qpsolver/instance.hpp\"\n#include \"qpsolver/pricing.hpp\"\n#include \"qpsolver/qpconst.hpp\"\n#include \"qpsolver/runtime.hpp\"\n#include \"qpsolver/snippets.hpp\"\n#include \"util/HFactor.h\"\n#include \"util/HVector.h\"\n#include \"util/HVectorBase.h\"\n\nclass Basis {\n  HVector buffer_vec2hvec;\n  QpVector Ztprod_res;\n  QpVector buffer_Zprod;\n\n  HVector& vec2hvec(const QpVector& vec) {\n    buffer_vec2hvec.clear();\n    for (HighsInt i = 0; i < vec.num_nz; i++) {\n      buffer_vec2hvec.index[i] = vec.index[i];\n      buffer_vec2hvec.array[vec.index[i]] = vec.value[vec.index[i]];\n    }\n    buffer_vec2hvec.count = vec.num_nz;\n    buffer_vec2hvec.packFlag = true;\n    return buffer_vec2hvec;\n  }\n\n  QpVector& hvec2vec(const HVector& hvec, QpVector& target) {\n    target.reset();\n    for (HighsInt i = 0; i < hvec.count; i++) {\n      target.index[i] = hvec.index[i];\n      target.value[target.index[i]] = hvec.array[hvec.index[i]];\n    }\n    // for (HighsInt i = 0; i < hvec.size; i++) {\n    //   target.index[i] = hvec.index[i];\n    //   target.value[i] = hvec.array[i];\n    // }\n    target.num_nz = hvec.count;\n    return target;\n  }\n\n  QpVector hvec2vec(const HVector& hvec) {\n    QpVector vec(hvec.size);\n\n    return hvec2vec(hvec, vec);\n  }\n\n  Runtime& runtime;\n  HFactor basisfactor;\n  HighsInt updatessinceinvert = 0;\n\n  MatrixBase Atran;\n\n  // indices of active constraints in basis\n  std::vector<HighsInt> active_constraint_index;\n\n  // ids of constraints that are in the basis but not active\n  // I need to extract those columns to get Z\n  std::vector<HighsInt> non_active_constraint_index;\n\n  // ids of constraints that are in the basis\n  std::vector<HighsInt> baseindex;\n\n  std::map<int, BasisStatus> basisstatus;\n\n  // index i: -1 if constraint not in basis, [0, num_var] if\n  // constraint in basis (active or not)\n  std::vector<HighsInt> constraintindexinbasisfactor;\n\n  void build();\n\n  // buffer to avoid recreating vectors\n  QpVector buffer_column_aq;\n  QpVector buffer_row_ep;\n\n  // buffers to prevent multiple btran/ftran\n  HighsInt buffered_q = -1;\n  HighsInt buffered_p = -1;\n  HVector row_ep;\n  HVector col_aq;\n\n  bool reinversion_hint = false;\n\n public:\n  Basis(Runtime& rt, std::vector<HighsInt> active,\n        std::vector<BasisStatus> atlower, std::vector<HighsInt> inactive);\n\n  bool getreinversionhint() { return reinversion_hint; }\n\n  void rebuild();\n\n  HighsInt getnupdatessinceinvert() { return updatessinceinvert; }\n\n  HighsInt getnumactive() const { return active_constraint_index.size(); };\n\n  HighsInt getnuminactive() const {\n    return non_active_constraint_index.size();\n  };\n\n  const std::vector<HighsInt>& getactive() const {\n    return active_constraint_index;\n  };\n\n  const std::vector<HighsInt>& getinactive() const {\n    return non_active_constraint_index;\n  };\n\n  const std::vector<HighsInt>& getindexinfactor() const {\n    return constraintindexinbasisfactor;\n  };\n\n  BasisStatus getstatus(HighsInt conid) { return basisstatus[conid]; };\n\n  void report();\n\n  // move that constraint into V section basis (will correspond to\n  // Nullspace from now on)\n  void deactivate(HighsInt conid);\n\n  QpSolverStatus activate(const Settings& settings, HighsInt conid,\n                          BasisStatus atlower, HighsInt nonactivetoremove,\n                          Pricing* pricing);\n\n  void updatebasis(const Settings& settings, HighsInt newactivecon,\n                   HighsInt droppedcon, Pricing* pricing);\n\n  QpVector btran(const QpVector& rhs, bool buffer = false, HighsInt p = -1);\n\n  QpVector ftran(const QpVector& rhs, bool buffer = false, HighsInt q = -1);\n\n  QpVector& btran(const QpVector& rhs, QpVector& target, bool buffer = false,\n                  HighsInt p = -1);\n\n  QpVector& ftran(const QpVector& rhs, QpVector& target, bool buffer = false,\n                  HighsInt q = -1);\n\n  QpVector recomputex(const Instance& inst);\n\n  void write(std::string filename);\n\n  QpVector& Ztprod(const QpVector& rhs, QpVector& target, bool buffer = false,\n                   HighsInt q = -1);\n\n  QpVector& Zprod(const QpVector& rhs, QpVector& target);\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/crashsolution.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_CRASHSOLUTION_HPP__\n#define __SRC_LIB_CRASHSOLUTION_HPP__\n\n#include <cstdlib>\n\n#include \"runtime.hpp\"\n\ninline bool isfreevar(Instance& instance, HighsInt idx) {\n  return instance.var_lo[idx] == -std::numeric_limits<double>::infinity() &&\n         instance.var_up[idx] == std::numeric_limits<double>::infinity();\n}\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/dantzigpricing.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_PRICING_DANTZIGPRICING_HPP__\n#define __SRC_LIB_PRICING_DANTZIGPRICING_HPP__\n\n#include \"basis.hpp\"\n#include \"pricing.hpp\"\n#include \"reducedcosts.hpp\"\n#include \"runtime.hpp\"\n\n// 51561, 78965838.346823, 559, 213.280772, 0.000812, 801\n\nclass DantzigPricing : public Pricing {\n private:\n  Runtime& runtime;\n  Basis& basis;\n  ReducedCosts& redcosts;\n\n  HighsInt chooseconstrainttodrop(const QpVector& lambda) {\n    auto active_constraint_index = basis.getactive();\n    auto constraintindexinbasisfactor = basis.getindexinfactor();\n\n    HighsInt minidx = -1;\n    double maxabslambda = 0.0;\n    for (size_t i = 0; i < active_constraint_index.size(); i++) {\n      HighsInt indexinbasis =\n          constraintindexinbasisfactor[active_constraint_index[i]];\n      if (indexinbasis == -1) {\n        printf(\"error\\n\");\n      }\n      assert(indexinbasis != -1);\n\n      if (basis.getstatus(active_constraint_index[i]) ==\n              BasisStatus::kActiveAtLower &&\n          -lambda.value[indexinbasis] > maxabslambda) {\n        minidx = active_constraint_index[i];\n        maxabslambda = -lambda.value[indexinbasis];\n      } else if (basis.getstatus(active_constraint_index[i]) ==\n                     BasisStatus::kActiveAtUpper &&\n                 lambda.value[indexinbasis] > maxabslambda) {\n        minidx = active_constraint_index[i];\n        maxabslambda = lambda.value[indexinbasis];\n      } else {\n        // TODO\n      }\n    }\n\n    if (maxabslambda <= runtime.settings.lambda_zero_threshold) {\n      // printf(\"maxabslambda %lf\\n\", log(maxabslambda));\n      return -1;\n    }\n    return minidx;\n  }\n\n public:\n  DantzigPricing(Runtime& rt, Basis& bas, ReducedCosts& rc)\n      // clang-format off\n      : runtime(rt), basis(bas), redcosts(rc) {};\n  // clang-format on\n  HighsInt price(const QpVector& x, const QpVector& gradient) {\n    HighsInt minidx = chooseconstrainttodrop(redcosts.getReducedCosts());\n    return minidx;\n  }\n\n  void recompute() {\n    // do nothing\n  }\n\n  void update_weights(const QpVector& aq, const QpVector& ep, HighsInt p,\n                      HighsInt q) {\n    // does nothing\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/devexpricing.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_PRICING_DEVEXPRICING_HPP__\n#define __SRC_LIB_PRICING_DEVEXPRICING_HPP__\n\n#include \"qpsolver/basis.hpp\"\n#include \"qpsolver/pricing.hpp\"\n#include \"qpsolver/reducedcosts.hpp\"\n#include \"qpsolver/runtime.hpp\"\n\n// 42726, 78965776.391299, 559, 104.321553, 0.000669, 7937\n\nclass DevexPricing : public Pricing {\n private:\n  Runtime& runtime;\n  Basis& basis;\n  ReducedCosts& redcosts;\n\n  std::vector<double> weights;\n\n  HighsInt chooseconstrainttodrop(const QpVector& lambda) {\n    auto active_constraint_index = basis.getactive();\n    auto constraintindexinbasisfactor = basis.getindexinfactor();\n\n    HighsInt minidx = -1;\n    double maxabslambda = 0.0;\n    for (size_t i = 0; i < active_constraint_index.size(); i++) {\n      HighsInt indexinbasis =\n          constraintindexinbasisfactor[active_constraint_index[i]];\n      if (indexinbasis == -1) {\n        printf(\"error\\n\");\n      }\n      assert(indexinbasis != -1);\n\n      double val = lambda.value[indexinbasis] * lambda.value[indexinbasis] /\n                   weights[indexinbasis];\n      if (val > maxabslambda && fabs(lambda.value[indexinbasis]) >\n                                    runtime.settings.lambda_zero_threshold) {\n        if (basis.getstatus(active_constraint_index[i]) ==\n                BasisStatus::kActiveAtLower &&\n            -lambda.value[indexinbasis] > 0) {\n          minidx = active_constraint_index[i];\n          maxabslambda = val;\n        } else if (basis.getstatus(active_constraint_index[i]) ==\n                       BasisStatus::kActiveAtUpper &&\n                   lambda.value[indexinbasis] > 0) {\n          minidx = active_constraint_index[i];\n          maxabslambda = val;\n        } else {\n          // TODO\n        }\n      }\n    }\n\n    return minidx;\n  }\n\n public:\n  DevexPricing(Runtime& rt, Basis& bas, ReducedCosts& rc)\n      : runtime(rt),\n        basis(bas),\n        redcosts(rc),\n        // clang-format off\n        weights(std::vector<double>(rt.instance.num_var, 1.0)) {};\n  // clang-format on\n\n  // B lambda = g\n  // lambda = inv(B)g\n  // lambda = Z'g == reduced gradient ??\n  // no: lambda = Y'g !!\n  // dual values updated as:\n  // c_N^T  += alpha_D * a_p^T (pivotal row)\n  // alpha_D = -c_q / a_pq\n  HighsInt price(const QpVector& x, const QpVector& gradient) {\n    QpVector& lambda = redcosts.getReducedCosts();\n    HighsInt minidx = chooseconstrainttodrop(lambda);\n    return minidx;\n  }\n\n  void recompute() {\n    // do nothing\n  }\n\n  void update_weights(const QpVector& aq, const QpVector& ep, HighsInt p,\n                      HighsInt q) {\n    HighsInt rowindex_p = basis.getindexinfactor()[p];\n    double weight_p = weights[rowindex_p];\n    for (HighsInt i = 0; i < runtime.instance.num_var; i++) {\n      if (i == rowindex_p) {\n        weights[i] = weight_p / (aq.value[rowindex_p] * aq.value[rowindex_p]);\n      } else {\n        weights[i] += (aq.value[i] * aq.value[i]) /\n                      (aq.value[rowindex_p] * aq.value[rowindex_p]) * weight_p *\n                      weight_p;\n      }\n      if (weights[i] > 1e7) {\n        weights[i] = 1.0;\n      }\n    }\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/eventhandler.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_EVENTHANDLER_HPP__\n#define __SRC_LIB_EVENTHANDLER_HPP__\n\n#include <functional>\n#include <vector>\n\ntemplate <typename T>  // T: void (*fncptr)(int, double)\nclass Eventhandler {\n  std::vector<std::function<void(T)>> subscribers;\n\n public:\n  void subscribe(std::function<void(T)> subscriber) {\n    subscribers.push_back(subscriber);\n  }\n\n  void fire(T args) {\n    for (std::function<void(T)> fun : subscribers) {\n      fun(args);\n    }\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/factor.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_NEWFACTOR_HPP__\n#define __SRC_LIB_NEWFACTOR_HPP__\n\n#include <cassert>\n#include <vector>\n\n#include \"matrix.hpp\"\n#include \"qpconst.hpp\"\n#include \"runtime.hpp\"\n\nusing std::min;\n\nclass CholeskyFactor {\n private:\n  bool uptodate = false;\n  HighsInt numberofreduces = 0;\n\n  Runtime& runtime;\n\n  Basis& basis;\n\n  HighsInt current_k = 0;\n  HighsInt current_k_max;\n  std::vector<double> L;\n\n  bool has_negative_eigenvalue = false;\n  std::vector<double> a;\n\n  void resize(HighsInt new_k_max) {\n    std::vector<double> L_old = L;\n    L.clear();\n    L.resize((new_k_max) * (new_k_max));\n    const HighsInt l_size = L.size();\n    // Driven by #958, changes made in following lines to avoid array\n    // bound error when new_k_max < current_k_max\n    HighsInt min_k_max = min(new_k_max, current_k_max);\n    for (HighsInt i = 0; i < min_k_max; i++) {\n      for (HighsInt j = 0; j < min_k_max; j++) {\n        assert(i * (new_k_max) + j < l_size);\n        L[i * (new_k_max) + j] = L_old[i * current_k_max + j];\n      }\n    }\n    current_k_max = new_k_max;\n  }\n\n public:\n  CholeskyFactor(Runtime& rt, Basis& bas) : runtime(rt), basis(bas) {\n    uptodate = false;\n    current_k_max =\n        max(min((HighsInt)ceil(rt.instance.num_var / 16.0), (HighsInt)1000),\n            basis.getnuminactive());\n    L.resize(current_k_max * current_k_max);\n  }\n\n  void recompute() {\n    std::vector<std::vector<double>> orig;\n    HighsInt dim_ns = basis.getinactive().size();\n    numberofreduces = 0;\n\n    orig.assign(dim_ns, std::vector<double>(dim_ns, 0.0));\n    resize(dim_ns);\n\n    Matrix temp(dim_ns, 0);\n\n    QpVector buffer_Qcol(runtime.instance.num_var);\n    QpVector buffer_ZtQi(dim_ns);\n    for (HighsInt i = 0; i < runtime.instance.num_var; i++) {\n      runtime.instance.Q.mat.extractcol(i, buffer_Qcol);\n      basis.Ztprod(buffer_Qcol, buffer_ZtQi);\n      temp.append(buffer_ZtQi);\n    }\n    MatrixBase& temp_t = temp.t();\n    for (HighsInt i = 0; i < dim_ns; i++) {\n      basis.Ztprod(temp_t.extractcol(i, buffer_Qcol), buffer_ZtQi);\n      for (HighsInt j = 0; j < buffer_ZtQi.num_nz; j++) {\n        orig[i][buffer_ZtQi.index[j]] = buffer_ZtQi.value[buffer_ZtQi.index[j]];\n      }\n    }\n\n    for (size_t col = 0; col < orig.size(); col++) {\n      for (size_t row = 0; row <= col; row++) {\n        double sum = 0;\n        if (row == col) {\n          for (size_t k = 0; k < row; k++)\n            sum += L[k * current_k_max + row] * L[k * current_k_max + row];\n          L[row * current_k_max + row] = sqrt(orig[row][row] - sum);\n        } else {\n          for (size_t k = 0; k < row; k++)\n            sum += (L[k * current_k_max + col] * L[k * current_k_max + row]);\n          L[row * current_k_max + col] =\n              (orig[col][row] - sum) / L[row * current_k_max + row];\n        }\n      }\n    }\n    current_k = dim_ns;\n    uptodate = true;\n  }\n\n  QpSolverStatus expand(const QpVector& yp, QpVector& gyp, QpVector& l,\n                        QpVector& m) {\n    if (!uptodate) {\n      return QpSolverStatus::OK;\n    }\n    double mu = gyp * yp;\n    l.resparsify();\n    double lambda = mu - l.norm2();\n    if (lambda > 0.0) {\n      if (current_k_max <= current_k + 1) {\n        resize(current_k_max * 2);\n      }\n\n      for (HighsInt i = 0; i < current_k; i++) {\n        L[i * current_k_max + current_k] = l.value[i];\n      }\n      L[current_k * current_k_max + current_k] = sqrt(lambda);\n\n      current_k++;\n    } else {\n      return QpSolverStatus::NOTPOSITIVDEFINITE;\n\n      //     |LL' 0|\n      // M = |0'  0| + bb' -aa'\n      // a = (k * m, alpha), b = (k * m, beta)\n      // b*b -a*a = mu\n      // k(b-a) = 1\n      // b + a = k*mu\n      // Commented out unreachable code\n      //      const double tolerance = 0.001;\n      //\n      //      double beta = max(tolerance, sqrt(m.norm2() / L[0] + fabs(mu)));\n      //      double k = 1 / (beta + sqrt(beta * beta - mu));\n      //      double alpha = k * mu - beta;\n      //\n      //      printf(\"k = %d, alpha = %lf, beta = %lf, k = %lf\\n\",\n      //      (int)current_k, alpha,\n      //             beta, k);\n      //\n      //      a.clear();\n      //      a.resize(current_k + 1);\n      //      for (HighsInt i = 0; i < current_k; i++) {\n      //        a[i] = k * m.value[i];\n      //      }\n      //      a[current_k] = alpha;\n      //\n      //      std::vector<double> b(current_k + 1);\n      //      for (HighsInt i = 0; i < current_k; i++) {\n      //        b[i] = k * m.value[i];\n      //      }\n      //      b[current_k] = beta;\n      //\n      //      if (current_k_max <= current_k + 1) {\n      //        resize(current_k_max * 2);\n      //      }\n      //\n      //      // append b to the left of L\n      //      for (HighsInt row = current_k; row > 0; row--) {\n      //        // move row one position down\n      //        for (HighsInt i = 0; i < current_k; i++) {\n      //          L[row * current_k_max + i] = L[(row - 1) * current_k_max + i];\n      //        }\n      //      }\n      //      for (HighsInt i = 0; i < current_k + 1; i++) {\n      //        L[i] = b[i];\n      //      }\n      //\n      //      // re-triangulize\n      //      for (HighsInt i = 0; i < current_k + 1; i++) {\n      //        eliminate(L, i, i + 1, current_k_max, current_k + 1);\n      //      }\n      //\n      //      current_k = current_k + 1;\n    }\n    return QpSolverStatus::OK;\n  }\n\n  void solveL(QpVector& rhs) {\n    if (!uptodate) {\n      recompute();\n    }\n\n    if (current_k != rhs.dim) {\n      printf(\"dimension mismatch\\n\");\n      return;\n    }\n\n    for (HighsInt r = 0; r < rhs.dim; r++) {\n      for (HighsInt j = 0; j < r; j++) {\n        rhs.value[r] -= rhs.value[j] * L[j * current_k_max + r];\n      }\n\n      rhs.value[r] /= L[r * current_k_max + r];\n    }\n  }\n\n  // solve L' u = v\n  void solveLT(QpVector& rhs) {\n    for (HighsInt i = rhs.dim - 1; i >= 0; i--) {\n      double sum = 0.0;\n      for (HighsInt j = rhs.dim - 1; j > i; j--) {\n        sum += rhs.value[j] * L[i * current_k_max + j];\n      }\n      rhs.value[i] = (rhs.value[i] - sum) / L[i * current_k_max + i];\n    }\n  }\n\n  void solve(QpVector& rhs) {\n    if (!uptodate || (numberofreduces >= runtime.instance.num_var / 2 &&\n                      !has_negative_eigenvalue)) {\n      recompute();\n    }\n    solveL(rhs);\n    solveLT(rhs);\n\n    rhs.resparsify();\n  }\n\n  void eliminate(std::vector<double>& m, HighsInt i, HighsInt j, HighsInt kmax,\n                 HighsInt currentk) {\n    // i = col, j = row\n    if (m[j * kmax + i] == 0.0) {\n      return;\n    }\n    double z = sqrt(m[i * kmax + i] * m[i * kmax + i] +\n                    m[j * kmax + i] * m[j * kmax + i]);\n    double cos_, sin_;\n    if (z == 0) {\n      cos_ = 1.0;\n      sin_ = 0.0;\n    } else {\n      cos_ = m[i * kmax + i] / z;\n      sin_ = -m[j * kmax + i] / z;\n    }\n\n    if (sin_ == 0.0) {\n      if (cos_ > 0.0) {\n        // nothing\n      } else {\n        for (HighsInt k = 0; k < current_k; k++) {\n          // update entry i and j of column k\n          double a_ik = m[i * kmax + k];\n          // entry i\n          m[i * kmax + k] = -a_ik;\n          m[j * kmax + k] = -m[j * kmax + k];\n        }\n      }\n    } else if (cos_ == 0.0) {\n      if (sin_ > 0.0) {\n        for (HighsInt k = 0; k < current_k; k++) {\n          // update entry i and j of column k\n          double a_ik = m[i * kmax + k];\n          // entry i\n          m[i * kmax + k] = -m[j * kmax + k];\n          m[j * kmax + k] = a_ik;\n        }\n      } else {\n        for (HighsInt k = 0; k < current_k; k++) {\n          // update entry i and j of column k\n          double a_ik = m[i * kmax + k];\n          // entry i\n          m[i * kmax + k] = m[j * kmax + k];\n          m[j * kmax + k] = -a_ik;\n        }\n      }\n    } else {\n      // #pragma omp parallel for\n      for (HighsInt k = 0; k < current_k; k++) {\n        // update entry i and j of column k\n        double a_ik = m[i * kmax + k];\n        // entry i\n        m[i * kmax + k] = cos_ * a_ik - sin_ * m[j * kmax + k];\n        m[j * kmax + k] = sin_ * a_ik + cos_ * m[j * kmax + k];\n      }\n    }\n    m[j * kmax + i] = 0.0;\n  }\n\n  void reduce(const QpVector& buffer_d, const HighsInt maxabsd, bool p_in_v) {\n    if (current_k == 0) {\n      return;\n    }\n    if (!uptodate) {\n      return;\n    }\n    numberofreduces++;\n\n    unsigned p = maxabsd;  // col we push to the right and remove\n\n    // start situation: p=3, current_k = 5\n    // |1 x  | |x    |       |1   | |xxxxx|\n    // | 1x  | |xx   |  ===  | 1  | | xxxx|\n    // |  x1 | |xxx  |       |xxxx| |  xxx|\n    // |  x 1| |xxxx |       |  1 | |   xx|\n    //         |xxxxx|       |   1| |    x|\n    // next step: move row/col p to the bottom/right\n\n    //> save row p\n    std::vector<double> row_p(current_k, 0.0);\n    for (HighsInt i = 0; i < current_k; i++) {\n      row_p[i] = L[p * current_k_max + i];\n    }\n\n    //> move all rows > p up by one row\n    for (HighsInt row = p; row < current_k - 1; row++) {\n      for (HighsInt i = 0; i < current_k; i++) {\n        L[row * current_k_max + i] = L[(row + 1) * current_k_max + i];\n      }\n    }\n\n    //> load row p\n    for (HighsInt i = 0; i < current_k; i++) {\n      L[(current_k - 1) * current_k_max + i] = row_p[i];\n    }\n\n    //> now move col p to the right in each row\n    for (HighsInt row = 0; row < current_k; row++) {\n      double p_entry = L[row * current_k_max + p];\n      for (HighsInt col = p; col < current_k - 1; col++) {\n        L[row * current_k_max + col] = L[row * current_k_max + col + 1];\n      }\n      L[row * current_k_max + current_k - 1] = p_entry;\n    }\n\n    if (current_k == 1) {\n      current_k--;\n      return;\n    }\n\n    if (!p_in_v) {\n      // situation now:\n      // |1   x| |x    |       |1   | |xxxxx|\n      // | 1  x| |xx   |  ===  | 1  | | xxxx|\n      // |  1 x| |xxx x|       |  1 | |  xx |\n      // |   1x| |xxxxx|       |   1| |   x |\n      //         |xx  x|       |xxxx| |  xxx|\n      // next: remove nonzero entries in last column except for diagonal element\n      for (HighsInt r = (HighsInt)p - 1; r >= 0; r--) {  // to current_k-1\n        eliminate(L, current_k - 1, r, current_k_max, current_k);\n      }\n\n      // situation now:\n      // |1   x| |x   x|        |xxxx | |1   |\n      // | 1  x| |xx  x|  ===   | xxx | | 1  |\n      // |  1 x| |xxx x|        |  xx | |  1 |\n      // |   1x| |xxxxx|        |   x | |   1|\n      //         |    x|        |xxxxx| |xxxx|\n      // next: multiply product\n      // new last row: old last row (first current_k-1 elements) + r *\n      // R_current_k_current_k\n\n      for (HighsInt i = 0; i < buffer_d.num_nz; i++) {\n        HighsInt idx = buffer_d.index[i];\n        if (idx == maxabsd) {\n          continue;\n        }\n        if (idx < maxabsd) {\n          L[(current_k - 1) * current_k_max + idx] +=\n              -buffer_d.value[idx] / buffer_d.value[maxabsd] *\n              L[(current_k - 1) * current_k_max + current_k - 1];\n        } else {\n          L[(current_k - 1) * current_k_max + idx - 1] +=\n              -buffer_d.value[idx] / buffer_d.value[maxabsd] *\n              L[(current_k - 1) * current_k_max + current_k - 1];\n        }\n      }\n      // situation now: as above, but no more product\n    }\n    // next: eliminate last row\n    for (HighsInt i = 0; i < current_k - 1; i++) {\n      eliminate(L, i, current_k - 1, current_k_max, current_k);\n    }\n    current_k--;\n  }\n\n  void report(std::string name = \"\") {\n    printf(\"%s\\n\", name.c_str());\n    for (HighsInt i = 0; i < current_k; i++) {\n      for (HighsInt j = 0; j < current_k; j++) {\n        printf(\"%lf \", L[i * current_k_max + j]);\n      }\n      printf(\"\\n\");\n    }\n  }\n\n  double density() {\n    if (current_k == 0) {\n      return 0.0;\n    }\n\n    HighsInt num_nz = 0;\n    for (HighsInt i = 0; i < current_k; i++) {\n      for (HighsInt j = 0; j < current_k; j++) {\n        if (fabs(L[i * current_k_max + j]) > 1e-7) {\n          num_nz++;\n        }\n      }\n    }\n    return (double)num_nz / (current_k * (current_k + 1) / 2.0);\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/feasibility_bounded.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_FEASIBILITYBOUNDED_HPP__\n#define __SRC_LIB_FEASIBILITYBOUNDED_HPP__\n\n#include \"Highs.h\"\n#include \"qpsolver/a_asm.hpp\"\n#include \"qpsolver/crashsolution.hpp\"\n\nstatic void computeStartingPointBounded(Instance& instance, Settings& settings,\n                                        Statistics& stats,\n                                        QpModelStatus& modelstatus,\n                                        QpHotstartInformation& result,\n                                        HighsTimer& timer) {\n  // compute initial feasible point for problems with bounds only (no general\n  // linear constraints)\n\n  // compute  Qx + c = 0 --> x = Q^-1c\n  std::vector<double> L;\n  L.resize(instance.num_var * instance.num_var);\n\n  // compute cholesky factorization of Q\n  for (size_t col = 0; col < (size_t)instance.num_var; col++) {\n    for (size_t idx = instance.Q.mat.start[col];\n         idx < (size_t)instance.Q.mat.start[col + 1]; idx++) {\n      double sum = 0;\n      size_t row = instance.Q.mat.index[idx];\n      if (row == col) {\n        for (size_t k = 0; k < row; k++)\n          sum += L[k * instance.num_var + row] * L[k * instance.num_var + row];\n        L[row * instance.num_var + row] = sqrt(instance.Q.mat.value[idx] - sum);\n      } else {\n        for (size_t k = 0; k < row; k++)\n          sum +=\n              (L[k * instance.num_var + col] * L[k * instance.num_var + row]);\n        L[row * instance.num_var + col] =\n            (instance.Q.mat.value[idx] - sum) / L[row * instance.num_var + row];\n      }\n    }\n  }\n\n  // solve for c\n  QpVector res = -instance.c;\n  for (HighsInt r = 0; r < res.dim; r++) {\n    for (HighsInt j = 0; j < r; j++) {\n      res.value[r] -= res.value[j] * L[j * instance.num_var + r];\n    }\n    res.value[r] /= L[r * instance.num_var + r];\n  }\n\n  for (HighsInt i = res.dim - 1; i >= 0; i--) {\n    double sum = 0.0;\n    for (HighsInt j = res.dim - 1; j > i; j--) {\n      sum += res.value[j] * L[i * instance.num_var + j];\n    }\n    res.value[i] = (res.value[i] - sum) / L[i * instance.num_var + i];\n  }\n\n  // project solution to bounds and collect active bounds\n  QpVector x0(instance.num_var);\n  QpVector ra(instance.num_con);\n  std::vector<HighsInt> initialactive;\n  std::vector<HighsInt> initialinactive;\n  std::vector<BasisStatus> atlower;\n\n  for (int i = 0; i < instance.num_var; i++) {\n    if (res.value[i] > 0.5 / settings.hessian_regularization_value &&\n        instance.var_up[i] == std::numeric_limits<double>::infinity() &&\n        instance.c.value[i] < 0.0) {\n      modelstatus = QpModelStatus::kUnbounded;\n      return;\n    } else if (res.value[i] < 0.5 / settings.hessian_regularization_value &&\n               instance.var_lo[i] == std::numeric_limits<double>::infinity() &&\n               instance.c.value[i] > 0.0) {\n      modelstatus = QpModelStatus::kUnbounded;\n      return;\n    } else if (res.value[i] <= instance.var_lo[i]) {\n      res.value[i] = instance.var_lo[i];\n      initialactive.push_back(i + instance.num_con);\n      atlower.push_back(BasisStatus::kActiveAtLower);\n    } else if (res.value[i] >= instance.var_up[i]) {\n      res.value[i] = instance.var_up[i];\n      initialactive.push_back(i + instance.num_con);\n      atlower.push_back(BasisStatus::kActiveAtUpper);\n    } else {\n      initialinactive.push_back(i + instance.num_con);\n    }\n    if (fabs(res.value[i]) > 1e-4) {\n      x0.value[i] = res.value[i];\n      x0.index[x0.num_nz++] = i;\n    }\n  }\n\n  // if no bounds are active, solution lies in the interior -> optimal\n  if (initialactive.size() == 0) {\n    modelstatus = QpModelStatus::kOptimal;\n  }\n\n  assert((HighsInt)(initialactive.size() + initialinactive.size()) ==\n         instance.num_var);\n\n  result.status = atlower;\n  result.active = initialactive;\n  result.inactive = initialinactive;\n  result.primal = x0;\n  result.rowact = ra;\n}\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/feasibility_highs.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_FEASIBILITYHIGHS_HPP__\n#define __SRC_LIB_FEASIBILITYHIGHS_HPP__\n\n#include \"Highs.h\"\n#include \"qpsolver/a_asm.hpp\"\n#include \"qpsolver/crashsolution.hpp\"\n\nstatic void computeStartingPointHighs(\n    Instance& instance, Settings& settings, Statistics& stats,\n    QpModelStatus& modelstatus, QpHotstartInformation& result,\n    HighsModelStatus& highs_model_status, HighsBasis& highs_basis,\n    HighsSolution& highs_solution, HighsTimer& timer) {\n  bool have_starting_point = false;\n  const bool debug_report = false;\n  if (highs_solution.value_valid) {\n    // #1350 add primal_feasibility_tolerance to settings\n    const double primal_feasibility_tolerance = settings.lambda_zero_threshold;\n\n    HighsInt num_var_infeasibilities = 0;\n    double max_var_infeasibility = 0;\n    double sum_var_infeasibilities = 0;\n    HighsInt num_con_infeasibilities = 0;\n    double max_con_infeasibility = 0;\n    double sum_con_infeasibilities = 0;\n    double max_con_residual = 0;\n    double sum_con_residuals = 0;\n\n    assessQpPrimalFeasibility(\n        instance, primal_feasibility_tolerance, highs_solution.col_value,\n        highs_solution.row_value, num_var_infeasibilities,\n        max_var_infeasibility, sum_var_infeasibilities, num_con_infeasibilities,\n        max_con_infeasibility, sum_con_infeasibilities, max_con_residual,\n        sum_con_residuals);\n\n    if (debug_report)\n      printf(\n          \"computeStartingPointHighs highs_solution has (num / max / sum) \"\n          \"var (%d / %g / %g) and \"\n          \"con (%d / %g / %g) infeasibilities \"\n          \"with (max = %g; sum = %g) residuals\\n\",\n          int(num_var_infeasibilities), max_var_infeasibility,\n          sum_var_infeasibilities, int(num_con_infeasibilities),\n          max_con_infeasibility, sum_con_infeasibilities, max_con_residual,\n          sum_con_residuals);\n    have_starting_point = num_var_infeasibilities == 0 &&\n                          num_con_infeasibilities == 0 && highs_basis.valid;\n  }\n  // compute initial feasible point\n  HighsBasis use_basis;\n  HighsSolution use_solution;\n  if (have_starting_point) {\n    use_basis = highs_basis;\n    use_solution = highs_solution;\n    // Have to assume that the supplied basis is feasible\n    modelstatus = QpModelStatus::kNotset;\n  } else {\n    Highs highs;\n\n    // set HiGHS to be silent\n    highs.setOptionValue(\"output_flag\", false);\n    highs.setOptionValue(\"presolve\", kHighsOnString);\n    // Set the residual time limit\n    const double use_time_limit =\n        std::max(settings.time_limit - timer.read(), 0.001);\n    highs.setOptionValue(\"time_limit\", use_time_limit);\n\n    HighsLp lp;\n    lp.a_matrix_.index_ = instance.A.mat.index;\n    lp.a_matrix_.start_ = instance.A.mat.start;\n    lp.a_matrix_.value_ = instance.A.mat.value;\n    lp.a_matrix_.format_ = MatrixFormat::kColwise;\n    lp.col_cost_.assign(instance.num_var, 0.0);\n    // lp.col_cost_ = runtime.instance.c.value;\n    lp.col_lower_ = instance.var_lo;\n    lp.col_upper_ = instance.var_up;\n    lp.row_lower_ = instance.con_lo;\n    lp.row_upper_ = instance.con_up;\n    lp.num_col_ = instance.num_var;\n    lp.num_row_ = instance.num_con;\n\n    // create artificial bounds for free variables: false by default\n    assert(!settings.phase1boundfreevars);\n    if (settings.phase1boundfreevars) {\n      for (HighsInt i = 0; i < instance.num_var; i++) {\n        if (isfreevar(instance, i)) {\n          lp.col_lower_[i] = -1E5;\n          lp.col_upper_[i] = 1E5;\n        }\n      }\n    }\n\n    highs.passModel(lp);\n    // Make free variables basic: false by default\n    assert(!settings.phase1movefreevarsbasic);\n    if (settings.phase1movefreevarsbasic) {\n      HighsBasis basis;\n      basis.alien = true;  // Set true when basis is instantiated\n      for (HighsInt i = 0; i < instance.num_con; i++) {\n        basis.row_status.push_back(HighsBasisStatus::kNonbasic);\n      }\n\n      for (HighsInt i = 0; i < instance.num_var; i++) {\n        // make free variables basic\n        if (instance.var_lo[i] == -kHighsInf &&\n            instance.var_up[i] == kHighsInf) {\n          // free variable\n          basis.col_status.push_back(HighsBasisStatus::kBasic);\n        } else {\n          basis.col_status.push_back(HighsBasisStatus::kNonbasic);\n        }\n      }\n\n      highs.setBasis(basis);\n\n      highs.setOptionValue(\"simplex_strategy\", kSimplexStrategyPrimal);\n    }\n\n    HighsStatus status = highs.run();\n    if (status == HighsStatus::kError) {\n      modelstatus = QpModelStatus::kError;\n      return;\n    }\n\n    HighsModelStatus phase1stat = highs.getModelStatus();\n    switch (phase1stat) {\n      case HighsModelStatus::kOptimal:\n        modelstatus = QpModelStatus::kNotset;\n        break;\n      case HighsModelStatus::kInfeasible:\n        modelstatus = QpModelStatus::kInfeasible;\n        break;\n      case HighsModelStatus::kTimeLimit:\n        modelstatus = QpModelStatus::kTimeLimit;\n        break;\n      case HighsModelStatus::kInterrupt:\n        modelstatus = QpModelStatus::kInterrupt;\n        break;\n      default:\n        modelstatus = QpModelStatus::kError;\n    }\n\n    stats.phase1_iterations = highs.getInfo().simplex_iteration_count;\n\n    if (modelstatus != QpModelStatus::kNotset) return;\n\n    // Should only get here if feasibility problem is solved to\n    // optimality - hence there is a feasible basis\n    assert(phase1stat == HighsModelStatus::kOptimal);\n\n    use_basis = highs.getBasis();\n    use_solution = highs.getSolution();\n  }\n\n  HighsInt num_small_x0 = 0;\n  HighsInt num_small_ra = 0;\n  const double zero_activity_tolerance = have_starting_point ? 0 : 1e-4;\n  QpVector x0(instance.num_var);\n  QpVector ra(instance.num_con);\n  for (HighsInt i = 0; i < x0.dim; i++) {\n    if (fabs(use_solution.col_value[i]) > zero_activity_tolerance) {\n      x0.value[i] = use_solution.col_value[i];\n      x0.index[x0.num_nz++] = i;\n    } else if (fabs(use_solution.col_value[i]) > 0) {\n      num_small_x0++;\n    }\n  }\n\n  for (HighsInt i = 0; i < ra.dim; i++) {\n    if (fabs(use_solution.row_value[i]) > zero_activity_tolerance) {\n      ra.value[i] = use_solution.row_value[i];\n      ra.index[ra.num_nz++] = i;\n    } else if (fabs(use_solution.row_value[i]) > 0) {\n      num_small_ra++;\n    }\n  }\n  if (debug_report && num_small_x0 + num_small_ra)\n    printf(\n        \"feasibility_highs has %d small col values and %d small row values\\n\",\n        int(num_small_x0), int(num_small_ra));\n  std::vector<HighsInt> initial_active;\n  std::vector<HighsInt> initial_inactive;\n  std::vector<BasisStatus> initial_status;\n\n  const HighsInt num_highs_basis_status =\n      HighsInt(HighsBasisStatus::kNonbasic) + 1;\n  std::vector<HighsInt> debug_row_status_count;\n  debug_row_status_count.assign(num_highs_basis_status, 0);\n  for (HighsInt i = 0; i < HighsInt(use_basis.row_status.size()); i++) {\n    HighsBasisStatus status = use_basis.row_status[i];\n    debug_row_status_count[HighsInt(status)]++;\n    if (status == HighsBasisStatus::kLower) {\n      initial_active.push_back(i);\n      initial_status.push_back(BasisStatus::kActiveAtLower);\n    } else if (status == HighsBasisStatus::kUpper) {\n      initial_active.push_back(i);\n      initial_status.push_back(BasisStatus::kActiveAtUpper);\n    } else if (status == HighsBasisStatus::kZero) {\n      // Shouldn't happen, since free rows are basic in a logical\n      // basis and remain basic, or are removed by presolve and\n      // restored as basic in postsolve\n      assert(111 == 222);\n      // That said, a free row that is nonbasic in the Highs basis\n      // must be counted as inactive in the QP basis for accounting\n      // purposes\n      initial_inactive.push_back(i);\n    } else if (status != HighsBasisStatus::kBasic) {\n      assert(status == HighsBasisStatus::kNonbasic);\n      // Surely an error, but not a problem before, since simplex\n      // solver cannot return a HighsBasisStatus::kNonbasic\n      // variable. Does matter now, since a saved QP basis will\n      // generally have such variables.\n      //\n      //      initial_inactive.push_back(instance.num_con + i);\n      //\n      // A HighsBasisStatus::kNonbasic variable corresponds one-to-one\n      // with being inactive in the QP basis\n      initial_inactive.push_back(i);\n    } else {\n      assert(status == HighsBasisStatus::kBasic);\n    }\n  }\n\n  std::vector<HighsInt> debug_col_status_count;\n  debug_col_status_count.assign(num_highs_basis_status, 0);\n  for (HighsInt i = 0; i < HighsInt(use_basis.col_status.size()); i++) {\n    HighsBasisStatus status = use_basis.col_status[i];\n    debug_col_status_count[HighsInt(status)]++;\n    if (status == HighsBasisStatus::kLower) {\n      if (isfreevar(instance, i)) {\n        initial_inactive.push_back(instance.num_con + i);\n      } else {\n        initial_active.push_back(instance.num_con + i);\n        initial_status.push_back(BasisStatus::kActiveAtLower);\n      }\n\n    } else if (status == HighsBasisStatus::kUpper) {\n      if (isfreevar(instance, i)) {\n        initial_inactive.push_back(instance.num_con + i);\n      } else {\n        initial_active.push_back(instance.num_con + i);\n        initial_status.push_back(BasisStatus::kActiveAtUpper);\n      }\n\n    } else if (status == HighsBasisStatus::kZero) {\n      initial_inactive.push_back(instance.num_con + i);\n    } else if (status != HighsBasisStatus::kBasic) {\n      assert(status == HighsBasisStatus::kNonbasic);\n      initial_inactive.push_back(instance.num_con + i);\n    } else {\n      assert(status == HighsBasisStatus::kBasic);\n    }\n  }\n\n  if (debug_report) {\n    printf(\"QP solver initial basis: (Lo / Bs / Up / Ze / Nb) for cols (\");\n    for (HighsInt k = 0; k < num_highs_basis_status; k++)\n      printf(\"%s%d\", k == 0 ? \"\" : \" / \", int(debug_col_status_count[k]));\n    printf(\") and rows (\");\n    for (HighsInt k = 0; k < num_highs_basis_status; k++)\n      printf(\"%s%d\", k == 0 ? \"\" : \" / \", int(debug_row_status_count[k]));\n    printf(\")\\n\");\n  }\n\n  // This used to be an assert\n  if ((HighsInt)(initial_active.size() + initial_inactive.size()) !=\n      instance.num_var) {\n    modelstatus = QpModelStatus::kError;\n    return;\n  }\n\n  if (!have_starting_point) {\n    // When starting from a feasible basis, there will generally be\n    // inactive variables in the basis that aren't free\n    for (HighsInt ia : initial_inactive) {\n      if (ia < instance.num_con) {\n        // printf(\"free row %d\\n\", (int)ia);\n        assert(instance.con_lo[ia] == -kHighsInf);\n        assert(instance.con_up[ia] == kHighsInf);\n      } else {\n        // printf(\"free col %d\\n\", (int)ia);\n        assert(instance.var_lo[ia - instance.num_con] == -kHighsInf);\n        assert(instance.var_up[ia - instance.num_con] == kHighsInf);\n      }\n    }\n  }\n\n  result.status = initial_status;\n  result.active = initial_active;\n  result.inactive = initial_inactive;\n  result.primal = x0;\n  result.rowact = ra;\n}\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/gradient.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_GRADIENT_HPP__\n#define __SRC_LIB_GRADIENT_HPP__\n\n#include \"qpvector.hpp\"\n#include \"runtime.hpp\"\n\nclass Gradient {\n  Runtime& runtime;\n\n  QpVector gradient;\n  bool uptodate;\n  HighsInt numupdates = 0;\n\n public:\n  Gradient(Runtime& rt)\n      : runtime(rt), gradient(QpVector(rt.instance.num_var)), uptodate(false) {}\n\n  void recompute() {\n    runtime.instance.Q.vec_mat(runtime.primal, gradient);\n    gradient += runtime.instance.c;\n    uptodate = true;\n    numupdates = 0;\n  }\n\n  QpVector& getGradient() {\n    if (!uptodate ||\n        numupdates >= runtime.settings.gradientrecomputefrequency) {\n      recompute();\n    }\n    return gradient;\n  }\n\n  void update(QpVector& buffer_Qp, double stepsize) {\n    gradient.saxpy(stepsize, buffer_Qp);\n    numupdates++;\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/instance.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_INSTANCE_HPP__\n#define __SRC_LIB_INSTANCE_HPP__\n\n#include <vector>\n\n#include \"matrix.hpp\"\n#include \"qpvector.hpp\"\n\nstruct SumNum {\n  double sum = 0.0;\n  HighsInt num = 0;\n};\n\nstruct Instance {\n  HighsInt sense = 1;  // Minimization\n  HighsInt num_var = 0;\n  HighsInt num_con = 0;\n  double offset = 0;\n  QpVector c;\n  Matrix Q;\n  std::vector<double> con_lo;\n  std::vector<double> con_up;\n  Matrix A;\n  std::vector<double> var_lo;\n  std::vector<double> var_up;\n\n  Instance(HighsInt nv = 0, HighsInt nc = 0)\n      : num_var(nv),\n        num_con(nc),\n        c(QpVector(nv)),\n        Q(Matrix(nv, nv)),\n        A(Matrix(nc, nv)) {}\n\n  double objval(const QpVector& x) {\n    return c * x + 0.5 * (Q.vec_mat(x) * x) + offset;\n  }\n\n  SumNum sumnumprimalinfeasibilities(const QpVector& x,\n                                     const QpVector& rowactivity) {\n    SumNum res;\n    for (HighsInt row = 0; row < num_con; row++) {\n      if (rowactivity.value[row] < con_lo[row]) {\n        res.sum += (con_lo[row] - rowactivity.value[row]);\n        res.num++;\n      } else if (rowactivity.value[row] > con_up[row]) {\n        res.sum += (rowactivity.value[row] - con_up[row]);\n        res.num++;\n      }\n    }\n    for (HighsInt var = 0; var < num_var; var++) {\n      if (x.value[var] < var_lo[var]) {\n        res.sum += (var_lo[var] - x.value[var]);\n        res.num++;\n      } else if (x.value[var] > var_up[var]) {\n        res.sum += (x.value[var] - var_up[var]);\n        res.num++;\n      }\n    }\n    return res;\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/matrix.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_MATRIX_HPP__\n#define __SRC_LIB_MATRIX_HPP__\n\n#include <cassert>\n#include <vector>\n\n#include \"qpvector.hpp\"\n\nstruct MatrixBase {\n  HighsInt num_row;\n  HighsInt num_col;\n  std::vector<HighsInt> start;\n  std::vector<HighsInt> index;\n  std::vector<double> value;\n\n  QpVector& mat_vec(const QpVector& other, QpVector& target) const {\n    return mat_vec_seq(other, target);\n  }\n\n  QpVector& mat_vec_seq(const QpVector& other, QpVector& target) const {\n    target.reset();\n    for (HighsInt i = 0; i < other.num_nz; i++) {\n      HighsInt col = other.index[i];\n      for (HighsInt idx = start[col]; idx < start[col + 1]; idx++) {\n        HighsInt row = index[idx];\n        target.value[row] += value[idx] * other.value[col];\n      }\n    }\n    target.resparsify();\n    return target;\n  }\n\n  QpVector mat_vec(const QpVector& other) {\n    QpVector result(num_row);\n    mat_vec(other, result);\n    return result;\n  }\n\n  QpVector vec_mat(HighsInt* idx, double* val, HighsInt nnz) {\n    QpVector result(num_col);\n    for (HighsInt i = 0; i < num_col; i++) {\n      double dot = 0.0;\n      // HighsInt idx_other = 0;\n      // HighsInt idx_this = start[i];\n      // while (idx_this < start[i+1] && idx_other < nnz) {\n      //    if (idx[idx_other] == index[idx_this]) {\n      //       dot += val[idx_other] * value[idx_this];\n      //    } else if (idx[idx_other] < index[idx_this]) {\n      //       idx_other++;\n      //    } else {\n      //       idx_this++;\n      //    }\n      // }\n\n      for (HighsInt j = start[i]; j < start[i + 1]; j++) {\n        // does the vector have an entry for index index[j]?\n        double other_value = 0.0;\n        for (HighsInt k = 0; k < nnz; k++) {\n          if (idx[k] == index[j]) {\n            other_value = val[k];\n            break;\n          }\n        }\n\n        dot += other_value * value[j];\n      }\n\n      if (dot != 0.0) {\n        result.value[i] = dot;\n        result.index[result.num_nz] = i;\n        result.num_nz++;\n      }\n    }\n    return result;\n  }\n\n  QpVector& vec_mat(const QpVector& other, QpVector& target) const {\n    return vec_mat_1(other, target);\n  }\n\n  QpVector& vec_mat_1(const QpVector& other, QpVector& target) const {\n    target.reset();\n    for (HighsInt col = 0; col < num_col; col++) {\n      double dot = 0.0;\n      for (HighsInt j = start[col]; j < start[col + 1]; j++) {\n        dot += other.value[index[j]] * value[j];\n      }\n      target.value[col] = dot;\n    }\n\n    target.resparsify();\n    return target;\n  }\n\n  QpVector vec_mat(const QpVector& other) const {\n    QpVector result(num_col);\n\n    return vec_mat(other, result);\n  }\n\n  // computes this * mat, where \"this\" is a tranposed matrix\n  MatrixBase tran_mat_(const MatrixBase& other) {\n    MatrixBase res;\n    res.num_row = num_col;\n    res.num_col = other.num_col;\n\n    res.start.push_back(0);\n    QpVector buffer_col(other.num_row);\n    QpVector buffer_col_res(num_col);\n    for (HighsInt r = 0; r < other.num_col; r++) {\n      other.extractcol(r, buffer_col);\n\n      vec_mat(buffer_col, buffer_col_res);\n      for (HighsInt i = 0; i < buffer_col_res.num_nz; i++) {\n        res.index.push_back(buffer_col_res.index[i]);\n        res.value.push_back(buffer_col_res.value[buffer_col_res.index[i]]);\n      }\n      res.start.push_back(res.start[r] + buffer_col_res.num_nz);\n    }\n\n    return res;\n  }\n\n  QpVector& extractcol(HighsInt col, QpVector& target) const {\n    assert(target.dim == num_row);\n    target.reset();\n\n    if (col >= num_col) {\n      target.index[0] = col - num_col;\n      target.value[col - num_col] = 1.0;\n      target.num_nz = 1;\n    } else {\n      for (HighsInt i = 0; i < start[col + 1] - start[col]; i++) {\n        target.index[i] = index[start[col] + i];\n        target.value[target.index[i]] = value[start[col] + i];\n      }\n      target.num_nz = start[col + 1] - start[col];\n    }\n\n    return target;\n  }\n\n  QpVector extractcol(HighsInt col) const {\n    QpVector res(num_row);\n\n    return extractcol(col, res);\n  }\n};\n\nstruct Matrix {\n private:\n  MatrixBase tran;\n  bool has_transpose = false;\n\n  void transpose() {\n    if (!has_transpose) {\n      std::vector<std::vector<HighsInt>> row_indices(mat.num_row);\n      std::vector<std::vector<double>> row_values(mat.num_row);\n\n      for (HighsInt col = 0; col < mat.num_col; col++) {\n        for (HighsInt entry = mat.start[col]; entry < mat.start[col + 1];\n             entry++) {\n          HighsInt row = mat.index[entry];\n          double val = mat.value[entry];\n          row_indices[row].push_back(col);\n          row_values[row].push_back(val);\n        }\n      }\n      tran.start.clear();\n      tran.index.clear();\n      tran.value.clear();\n      tran.start.reserve(mat.num_row + 1);\n      tran.index.reserve(mat.index.size());\n      tran.value.reserve(mat.value.size());\n\n      tran.start.push_back(0);\n      for (HighsInt row = 0; row < mat.num_row; row++) {\n        tran.index.insert(tran.index.end(), row_indices[row].begin(),\n                          row_indices[row].end());\n        tran.value.insert(tran.value.end(), row_values[row].begin(),\n                          row_values[row].end());\n\n        tran.start.push_back(tran.start[row] + row_indices[row].size());\n      }\n\n      tran.num_col = mat.num_row;\n      tran.num_row = mat.num_col;\n    }\n  }\n\n public:\n  MatrixBase mat;\n\n  Matrix(HighsInt nr, HighsInt nc) {\n    mat.num_row = nr;\n    mat.num_col = nc;\n  };\n\n  Matrix(const MatrixBase& m, bool needstran) {\n    mat = m;\n    // if (needstran) {\n    //    transpose();\n    // }\n  }\n\n  void append(const QpVector& vec) {\n    if (mat.num_col == 0 && mat.start.size() == 0) {\n      mat.start.push_back(0);\n    }\n    for (HighsInt i = 0; i < vec.num_nz; i++) {\n      mat.index.push_back(vec.index[i]);\n      mat.value.push_back(vec.value[vec.index[i]]);\n    }\n    mat.start.push_back(mat.start[mat.num_col] + vec.num_nz);\n    mat.num_col++;\n    has_transpose = false;\n  }\n\n  void append(HighsInt* idx, double* val, HighsInt nnz) {\n    if (mat.num_col == 0 && mat.start.size() == 0) {\n      mat.start.push_back(0);\n    }\n    for (HighsInt i = 0; i < nnz; i++) {\n      mat.index.push_back(idx[i]);\n      mat.value.push_back(val[i]);\n    }\n    mat.start.push_back(mat.start[mat.num_col] + nnz);\n    mat.num_col++;\n    has_transpose = false;\n  }\n\n  void append(HighsInt num_nz, HighsInt* index, double* value) {\n    if (mat.num_col == 0 && mat.start.size() == 0) {\n      mat.start.push_back(0);\n    }\n    for (HighsInt i = 0; i < num_nz; i++) {\n      mat.index.push_back(index[i]);\n      mat.value.push_back(value[i]);\n    }\n    mat.start.push_back(mat.start[mat.num_col] + num_nz);\n    mat.num_col++;\n    has_transpose = false;\n  }\n\n  void dropcol(HighsInt col) {\n    assert(col < mat.num_col);\n    has_transpose = false;\n\n    mat.index.erase(mat.index.begin() + mat.start[col],\n                    mat.index.begin() + mat.start[col + 1]);\n    mat.value.erase(mat.value.begin() + mat.start[col],\n                    mat.value.begin() + mat.start[col + 1]);\n\n    HighsInt num_elements_in_col = mat.start[col + 1] - mat.start[col];\n    for (; col < mat.num_col; col++) {\n      mat.start[col] = mat.start[col + 1] - num_elements_in_col;\n    }\n    mat.start.pop_back();\n    mat.num_col--;\n  }\n\n  MatrixBase& t() {\n    if (!has_transpose) {\n      transpose();\n      has_transpose = true;\n    }\n    return tran;\n  }\n\n  Matrix mat_mat(Matrix& other) {\n    Matrix res(mat.num_row, 0);\n\n    QpVector buffer(other.mat.num_row);\n    QpVector buffer2(mat.num_col);\n    for (HighsInt col = 0; col < other.mat.num_col; col++) {\n      res.append(vec_mat(other.mat.extractcol(col, buffer), buffer2));\n    }\n\n    return res;\n  }\n\n  Matrix tran_mat(Matrix& other) {\n    Matrix res(mat.num_col, 0);\n\n    QpVector buffer(other.mat.num_row);\n    QpVector buffer2(mat.num_row);\n    for (HighsInt col = 0; col < other.mat.num_col; col++) {\n      res.append(mat_vec(other.mat.extractcol(col, buffer), buffer2));\n    }\n    return res;\n  }\n\n  QpVector& mat_vec(const QpVector& other, QpVector& target) {\n    return mat.mat_vec(other, target);\n  }\n\n  QpVector mat_vec(const QpVector& other) { return mat.mat_vec(other); }\n\n  QpVector vec_mat(const QpVector& other) const { return mat.vec_mat(other); }\n\n  QpVector& vec_mat(const QpVector& other, QpVector& target) const {\n    return mat.vec_mat(other, target);\n  }\n\n  QpVector vec_mat(HighsInt* index, double* value, HighsInt num_nz) {\n    return mat.vec_mat(index, value, num_nz);\n  }\n\n  void report(std::string name = \"\") const {\n    if (name != \"\") {\n      printf(\"%s:\", name.c_str());\n    }\n    printf(\"[%\" HIGHSINT_FORMAT \" x %\" HIGHSINT_FORMAT \"]\\n\", mat.num_row,\n           mat.num_col);\n    printf(\"start: \");\n    for (HighsInt i : mat.start) {\n      printf(\"%\" HIGHSINT_FORMAT \" \", i);\n    }\n    printf(\"\\n\");\n\n    printf(\"index: \");\n    for (HighsInt i : mat.index) {\n      printf(\"%\" HIGHSINT_FORMAT \" \", i);\n    }\n    printf(\"\\n\");\n\n    printf(\"value: \");\n    for (double d : mat.value) {\n      printf(\"%lf \", d);\n    }\n    printf(\"\\n\");\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/perturbation.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_PERTURBATION_HPP__\n#define __SRC_LIB_PERTURBATION_HPP__\n\n#include \"runtime.hpp\"\n\nvoid perturb(Runtime& rt);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/pricing.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_PRICING_HPP__\n#define __SRC_LIB_PRICING_HPP__\n\n#include \"qpvector.hpp\"\n\nclass Pricing {\n public:\n  virtual HighsInt price(const QpVector& x, const QpVector& gradient) = 0;\n  virtual void update_weights(const QpVector& aq, const QpVector& ep,\n                              HighsInt p, HighsInt q) = 0;\n  virtual void recompute() = 0;\n  virtual ~Pricing() {}\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/qpconst.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#pragma once\n#ifndef __SRC_LIB_QPCONST_HPP__\n#define __SRC_LIB_QPCONST_HPP__\n\nenum class QpSolverStatus { OK, NOTPOSITIVDEFINITE, DEGENERATE };\n\nenum class QpModelStatus {\n  kNotset,  // 0\n  kUndetermined,\n  kOptimal,\n  kUnbounded,\n  kInfeasible,\n  kIterationLimit,\n  kTimeLimit,\n  kLargeNullspace,\n  kInterrupt,\n  kError\n};\n\nenum class BasisStatus {\n  kInactive,\n  kActiveAtLower = 1,\n  kActiveAtUpper,\n  kInactiveInBasis\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/qpvector.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_VECTOR_HPP__\n#define __SRC_LIB_VECTOR_HPP__\n\n#include <util/HighsInt.h>\n\n#include <cmath>\n#include <cstdio>\n#include <string>\n#include <vector>\n\nstruct QpVector {\n  HighsInt num_nz;\n  HighsInt dim;\n  std::vector<HighsInt> index;\n  std::vector<double> value;\n\n  QpVector(HighsInt d) : dim(d) {\n    index.resize(dim);\n    value.resize(dim, 0.0);\n    num_nz = 0;\n  }\n\n  QpVector(const QpVector& vec)\n      : num_nz(vec.num_nz), dim(vec.dim), index(vec.index), value(vec.value) {}\n\n  void reset() {\n    for (HighsInt i = 0; i < num_nz; i++) {\n      value[index[i]] = 0;\n      index[i] = 0;\n    }\n    num_nz = 0;\n  }\n\n  QpVector& repopulate(const QpVector& other) {\n    reset();\n    for (HighsInt i = 0; i < other.num_nz; i++) {\n      index[i] = other.index[i];\n      value[index[i]] = other.value[index[i]];\n    }\n    num_nz = other.num_nz;\n    return *this;\n  }\n\n  QpVector& operator=(const QpVector& other) {\n    num_nz = other.num_nz;\n    dim = other.dim;\n    index = other.index;\n    value = other.value;\n    return *this;\n  }\n\n  static QpVector& unit(HighsInt dim, HighsInt u, QpVector& target) {\n    target.reset();\n    target.index[0] = u;\n    target.value[u] = 1.0;\n    target.num_nz = 1;\n    return target;\n  }\n\n  static QpVector unit(HighsInt dim, HighsInt u) {\n    QpVector vec(dim);\n    vec.index[0] = u;\n    vec.value[u] = 1.0;\n    vec.num_nz = 1;\n    return vec;\n  }\n\n  void report(std::string name = \"\") const {\n    if (name != \"\") {\n      printf(\"%s: \", name.c_str());\n    }\n    for (HighsInt i = 0; i < num_nz; i++) {\n      printf(\"[%\" HIGHSINT_FORMAT \"] %lf \", index[i], value[index[i]]);\n    }\n    printf(\"\\n\");\n  }\n\n  double norm2() {\n    double val = 0.0;\n\n    for (HighsInt i = 0; i < num_nz; i++) {\n      val += value[index[i]] * value[index[i]];\n    }\n\n    return val;\n  }\n\n  void sanitize(double threshold = 1e-14) {\n    HighsInt new_idx = 0;\n\n    for (HighsInt i = 0; i < num_nz; i++) {\n      if (fabs(value[index[i]]) > threshold) {\n        index[new_idx++] = index[i];\n      } else {\n        value[index[i]] = 0.0;\n        index[i] = 0;\n      }\n    }\n    num_nz = new_idx;\n  }\n\n  void resparsify() {\n    num_nz = 0;\n    for (HighsInt i = 0; i < dim; i++) {\n      if (value[i] != 0.0) {\n        index[num_nz++] = i;\n      }\n    }\n  }\n\n  QpVector& scale(double a) {\n    for (HighsInt i = 0; i < num_nz; i++) {\n      value[index[i]] *= a;\n    }\n    return *this;\n  }\n\n  QpVector& saxpy(double a, double b, const QpVector& x) {\n    scale(a);\n    saxpy(b, x);\n    return *this;\n  }\n\n  QpVector& saxpy(double a, const QpVector& x) {\n    sanitize(0.0);\n    for (HighsInt i = 0; i < x.num_nz; i++) {\n      if (value[x.index[i]] == 0.0) {\n        index[num_nz++] = x.index[i];\n      }\n      value[x.index[i]] += a * x.value[x.index[i]];\n    }\n    resparsify();\n    // sanitize(0.0);\n    return *this;\n  }\n\n  // void saxpy(double a, HighsInt* idx, double* val, HighsInt nnz) {\n  //    for (HighsInt i=0; i<nnz; i++) {\n  //       value[idx[i]] += a * val[i];\n  //    }\n  //    resparsify();\n  // }\n\n  QpVector operator+(const QpVector& other) const {\n    QpVector result(dim);\n\n    for (HighsInt i = 0; i < dim; i++) {\n      result.value[i] = value[i] + other.value[i];\n      if (result.value[i] != 0.0) {\n        result.index[result.num_nz++] = i;\n      }\n    }\n\n    return result;\n  }\n\n  QpVector operator-(const QpVector& other) const {\n    QpVector result(dim);\n\n    for (HighsInt i = 0; i < dim; i++) {\n      result.value[i] = value[i] - other.value[i];\n      if (result.value[i] != 0.0) {\n        result.index[result.num_nz++] = i;\n      }\n    }\n\n    return result;\n  }\n\n  QpVector operator-() const {\n    QpVector result(dim);\n\n    for (HighsInt i = 0; i < num_nz; i++) {\n      result.index[i] = index[i];\n      result.value[index[i]] = -value[index[i]];\n    }\n    result.num_nz = num_nz;\n\n    return result;\n  }\n\n  QpVector operator*(const double d) const {\n    QpVector result(dim);\n\n    for (HighsInt i = 0; i < num_nz; i++) {\n      result.index[i] = index[i];\n      result.value[index[i]] = d * value[index[i]];\n    }\n    result.num_nz = num_nz;\n\n    return result;\n  }\n\n  double dot(const QpVector& other) const {\n    double dot = 0.0;\n    for (HighsInt i = 0; i < num_nz; i++) {\n      dot += value[index[i]] * other.value[index[i]];\n    }\n\n    return dot;\n  }\n\n  double operator*(const QpVector& other) const { return dot(other); }\n\n  double dot(const HighsInt* idx, const double* val, HighsInt nnz) const {\n    double dot = 0.0;\n    for (HighsInt i = 0; i < nnz; i++) {\n      dot += value[idx[i]] * val[i];\n    }\n\n    return dot;\n  }\n\n  QpVector& operator+=(const QpVector& other) {\n    // sanitize();\n    for (HighsInt i = 0; i < other.num_nz; i++) {\n      // if (value[other.index[i]] == 0.0) {\n      //    index[num_nz++] = other.index[i];\n      // }\n      value[other.index[i]] += other.value[other.index[i]];\n    }\n    resparsify();\n    return *this;\n  }\n\n  QpVector& operator*=(const double d) {\n    for (HighsInt i = 0; i < num_nz; i++) {\n      value[index[i]] *= d;\n    }\n\n    return *this;\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/quass.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_QUASS_HPP__\n#define __SRC_LIB_QUASS_HPP__\n\n#include \"qpsolver/basis.hpp\"\n#include \"qpsolver/eventhandler.hpp\"\n#include \"qpsolver/factor.hpp\"\n#include \"qpsolver/instance.hpp\"\n#include \"qpsolver/runtime.hpp\"\n\nstruct Quass {\n  Quass(Runtime& rt);\n\n  void solve(const QpVector& x0, const QpVector& ra, Basis& b0,\n             HighsTimer& timer);\n\n private:\n  Runtime& runtime;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/ratiotest.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_RATIOTEST_HPP__\n#define __SRC_LIB_RATIOTEST_HPP__\n\n#include <limits>\n\n#include \"runtime.hpp\"\n\nstruct RatiotestResult {\n  double alpha;\n  HighsInt limitingconstraint;\n  bool nowactiveatlower;\n};\n\nRatiotestResult ratiotest(Runtime& runtime, const QpVector& p,\n                          const QpVector& rowmove, double alphastart);\n\nInstance ratiotest_relax_instance(Runtime& runtime);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/runtime.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_RUNTIME_HPP__\n#define __SRC_LIB_RUNTIME_HPP__\n\n#include \"instance.hpp\"\n#include \"qpsolver/qpconst.hpp\"\n#include \"settings.hpp\"\n#include \"statistics.hpp\"\n#include \"util/HighsTimer.h\"\n\nstruct Runtime {\n  Instance instance;\n  Instance relaxed_for_ratiotest;\n  Instance scaled;\n  Instance perturbed;\n  Settings settings;\n  Statistics& statistics;\n\n  QpVector primal;\n  QpVector rowactivity;\n  QpVector dualvar;\n  QpVector dualcon;\n  QpModelStatus status = QpModelStatus::kUndetermined;\n\n  std::vector<BasisStatus> status_var;\n  std::vector<BasisStatus> status_con;\n\n  Runtime(Instance& inst, Statistics& stats)\n      : instance(inst),\n        statistics(stats),\n        primal(QpVector(instance.num_var)),\n        rowactivity(QpVector(instance.num_con)),\n        dualvar(instance.num_var),\n        dualcon(instance.num_con),\n        status_var(instance.num_var),\n        status_con(instance.num_con) {}\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/scaling.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_SCALING_HPP__\n#define __SRC_LIB_SCALING_HPP__\n\n#include \"runtime.hpp\"\n\nvoid scale(Runtime& rt);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/settings.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_SETTINGS_HPP__\n#define __SRC_LIB_SETTINGS_HPP__\n\n#include \"eventhandler.hpp\"\n#include \"qpconst.hpp\"\n#include \"statistics.hpp\"\n\nenum class RatiotestStrategy { TwoPass, Textbook };\n\nenum class PricingStrategy { SteepestEdge, DantzigWolfe, Devex };\n\nenum class Phase1Strategy { HIGHS, QUASS, BOUNDED };\n\nstruct Settings {\n  RatiotestStrategy ratiotest = RatiotestStrategy::TwoPass;\n  double ratiotest_t = 1e-9;\n  double ratiotest_d = 1e-8;\n\n  PricingStrategy pricing = PricingStrategy::Devex;\n\n  double pnorm_zero_threshold =\n      1e-11;  // if ||p|| < this threshold, p is determined to not be an\n              // improving search direction\n  double improvement_zero_threshold =\n      1e-4;  // if p^t gradient < this threshold, p is determined to not be an\n             // improving search direction\n  double d_zero_threshold = 1e-12;  // minimal value for pivot, will declare\n                                    // degeneracy if no larger pivot is found\n  double lambda_zero_threshold =\n      1e-9;  // used for pricing / optimality checking\n  double pQp_zero_threshold =\n      1e-7;  // if p'Qp < this, p is determined to not have curvature, a\n             // simplex-like iteration is performed.\n\n  bool hessian_regularization_on =\n      false;  // if true, a small multiple of the identity matrix will be added\n              // to the Hessian.\n              //\n              // This is always false, so regularization in\n              // regularize(Runtime& rt) never happens, but\n              // regularization in solveqp is _always_ performed\n              //\n              // This explains the \"perturbed\" solutions of problems\n              // in TestQpSolver.cpp\n  double hessian_regularization_value =\n      1e-7;  // multiple of identity matrix added to Hessian in case of\n             // regularization\n\n  Phase1Strategy phase1strategy = Phase1Strategy::HIGHS;\n  bool phase1movefreevarsbasic = false;\n  bool phase1boundfreevars = false;\n\n  HighsInt reportingfequency = 1;\n  Eventhandler<Statistics&> iteration_log;\n  Eventhandler<QpModelStatus&> qp_model_status_log;\n  Eventhandler<HighsInt&> nullspace_limit_log;\n\n  HighsInt nullspace_limit = 4000;\n\n  HighsInt reinvertfrequency = 1000;\n  HighsInt gradientrecomputefrequency = 100;\n  HighsInt reducedgradientrecomputefrequency =\n      std::numeric_limits<HighsInt>::infinity();\n  HighsInt reducedhessianrecomputefrequency =\n      std::numeric_limits<HighsInt>::infinity();\n\n  HighsInt iteration_limit = std::numeric_limits<HighsInt>::infinity();\n  double time_limit = std::numeric_limits<double>::infinity();\n\n  bool rowscaling = true;\n  bool varscaling = true;\n\n  bool perturbation = false;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/snippets.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_SNIPPETS_HPP__\n#define __SRC_LIB_SNIPPETS_HPP__\n\n#include <algorithm>\n#include <vector>\n\ntemplate <typename T>\nbool contains(const std::vector<T>& vec, const T& element) {\n  return std::find(vec.begin(), vec.end(), element) != vec.end();\n}\n\ntemplate <typename T>\nbool remove(std::vector<T>& vec, const T& element) {\n  auto rem = std::remove(vec.begin(), vec.end(), element);\n  auto rem2 = vec.erase(rem, vec.end());\n  return rem2 != vec.end();\n}\n\ntemplate <typename T>\nHighsInt indexof(const std::vector<T>& vec, const T& element) {\n  auto it = std::find(vec.begin(), vec.end(), element);\n  if (it != vec.end()) {\n    return distance(vec.begin(), it);\n  } else {\n    return -1;\n  }\n}\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/statistics.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_STATISTICS_HPP__\n#define __SRC_LIB_STATISTICS_HPP__\n\n#include <chrono>\n#include <vector>\n\nstruct Statistics {\n  HighsInt phase1_iterations = 0;\n  HighsInt num_iterations = 0;\n  std::chrono::high_resolution_clock::time_point time_start;\n  std::chrono::high_resolution_clock::time_point time_end;\n\n  std::vector<HighsInt> iteration;\n  std::vector<HighsInt> nullspacedimension;\n  std::vector<double> objval;\n  std::vector<double> time;\n  std::vector<double> sum_primal_infeasibilities;\n  std::vector<HighsInt> num_primal_infeasibilities;\n  std::vector<double> density_nullspace;\n  std::vector<double> density_factor;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/qpsolver/steepestedgepricing.hpp",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef __SRC_LIB_PRICING_STEEPESTEDGEPRICING_HPP__\n#define __SRC_LIB_PRICING_STEEPESTEDGEPRICING_HPP__\n\n#include \"qpsolver/basis.hpp\"\n#include \"qpsolver/pricing.hpp\"\n#include \"qpsolver/runtime.hpp\"\n\n//\n\nclass SteepestEdgePricing : public Pricing {\n private:\n  Runtime& runtime;\n  Basis& basis;\n  ReducedCosts& redcosts;\n  std::vector<double> weights;\n\n  HighsInt chooseconstrainttodrop(const QpVector& lambda) {\n    auto active_constraint_index = basis.getactive();\n    auto constraintindexinbasisfactor = basis.getindexinfactor();\n\n    HighsInt minidx = -1;\n    double maxval = 0.0;\n    for (size_t i = 0; i < active_constraint_index.size(); i++) {\n      HighsInt indexinbasis =\n          constraintindexinbasisfactor[active_constraint_index[i]];\n      if (indexinbasis == -1) {\n        printf(\"error\\n\");\n      }\n      assert(indexinbasis != -1);\n\n      double val = lambda.value[indexinbasis] * lambda.value[indexinbasis] /\n                   weights[indexinbasis];\n      if (val > maxval && fabs(lambda.value[indexinbasis]) >\n                              runtime.settings.lambda_zero_threshold) {\n        if (basis.getstatus(active_constraint_index[i]) ==\n                BasisStatus::kActiveAtLower &&\n            -lambda.value[indexinbasis] > 0) {\n          minidx = active_constraint_index[i];\n          maxval = val;\n        } else if (basis.getstatus(active_constraint_index[i]) ==\n                       BasisStatus::kActiveAtUpper &&\n                   lambda.value[indexinbasis] > 0) {\n          minidx = active_constraint_index[i];\n          maxval = val;\n        } else {\n          // TODO\n        }\n      }\n    }\n\n    return minidx;\n  }\n\n public:\n  SteepestEdgePricing(Runtime& rt, Basis& bas, ReducedCosts& rc)\n      : runtime(rt),\n        basis(bas),\n        redcosts(rc),\n        weights(std::vector<double>(rt.instance.num_var, 1.0)) {\n    compute_exact_weights();\n  };\n\n  HighsInt price(const QpVector& x, const QpVector& gradient) {\n    HighsInt minidx = chooseconstrainttodrop(redcosts.getReducedCosts());\n    return minidx;\n  }\n\n  double compute_exact_weight(HighsInt i) {\n    QpVector y_i = basis.btran(QpVector::unit(runtime.instance.num_var, i));\n    return y_i.dot(y_i);\n  }\n\n  void compute_exact_weights() {\n    for (int i = 0; i < runtime.instance.num_var; i++) {\n      weights[i] = compute_exact_weight(i);\n    }\n  }\n\n  bool check_weight(HighsInt i) {\n    double weight_is = weights[i];\n    double weight_comp = compute_exact_weight(i);\n    if (fabs(weight_comp - weight_is) > 1e-2) {\n      // printf(\"weights[%d] = %lf, should be %lf\\n\", i, weight_is,\n      // weight_comp);\n      return false;\n    }\n    return true;\n  }\n\n  bool check_weights() {\n    std::vector<int> correct_weights;\n    std::vector<int> incorrect_weights;\n    for (int i = 0; i < runtime.instance.num_var; i++) {\n      bool correct = check_weight(i);\n      if (correct) {\n        correct_weights.push_back(i);\n      } else {\n        incorrect_weights.push_back(i);\n      }\n    }\n\n    printf(\"correct weights: \");\n    for (int& i : correct_weights) {\n      printf(\"%d \", i);\n    }\n    printf(\"\\n\");\n\n    printf(\"incorrect weights: \");\n    for (int& i : incorrect_weights) {\n      printf(\"%d \", i);\n    }\n    printf(\"\\n\");\n\n    return incorrect_weights.size() == 0;\n  }\n\n  void recompute() { compute_exact_weights(); }\n\n  void update_weights(const QpVector& aq, const QpVector& ep, HighsInt p,\n                      HighsInt q) {\n    HighsInt rowindex_p = basis.getindexinfactor()[p];\n    // printf(\"Update weights, p = %d, rowindex = %d, q = %d\\n\", p, rowindex_p,\n    // q);\n\n    // if (!check_weights()) {\n    //   printf(\"weight check failed\\n\");\n    //   exit(1);\n    // }\n\n    QpVector delta = basis.ftran(aq);\n\n    // double old_weight_p_updated = weights[rowindex_p];\n    //  exact weight coming in needs to come in before update.\n    double old_weight_p_computed = ep.dot(ep);\n\n    // if (fabs(old_weight_p_computed - old_weight_p_updated) >= 1e-2) {\n    //   printf(\"old weight[p] discrepancy: updated = %lf, computed=%lf\\n\",\n    //   old_weight_p_updated, old_weight_p_computed);\n    // }\n\n    double weight_p = old_weight_p_computed;\n\n    double t_p = aq.value[rowindex_p];\n    for (HighsInt i = 0; i < runtime.instance.num_var; i++) {\n      if (i != rowindex_p) {\n        double t_i = aq.value[i];\n        weights[i] = weights[i] - 2 * (t_i / t_p) * delta.value[i] +\n                     ((t_i * t_i) / (t_p * t_p)) * weight_p;\n        // printf(\"weights[%d] = %lf\\n\", i, weights[i]);\n      }\n    }\n    // QpVector new_ep = basis.btran(QpVector::unit(runtime.instance.num_var,\n    // rowindex_p)); double computed_weight = new_ep.dot(new_ep);\n    double new_weight_p_updated = weight_p / (t_p * t_p);\n\n    // if (fabs(updated_weight - computed_weight) > 1e-4) {\n    //   printf(\"updated weight %lf vs computed weight %lf. aq[p] = %lf\\n\",\n    //   updated_weight, computed_weight, t_p); printf(\"old weight = %lf, aq[p]\n    //   = %lf, ^2 = %lf, new weight = %lf\\n\", weight_p, t_p, t_p*t_p,\n    //   updated_weight);\n    // }\n    weights[rowindex_p] = new_weight_p_updated;\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/simplex/HApp.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef SIMPLEX_HAPP_H_\n#define SIMPLEX_HAPP_H_\n\n// todo: clear includes.\n// #include <cstring>\n// #include <fstream>\n// #include <iomanip>\n// #include <iostream>\n// #include <map>\n// #include <set>\n// #include <vector>\n\n#include \"lp_data/HighsLpSolverObject.h\"\n#include \"lp_data/HighsLpUtils.h\"\n#include \"lp_data/HighsSolution.h\"\n#include \"lp_data/HighsSolve.h\"\n#include \"simplex/HEkk.h\"\n#include \"simplex/HSimplex.h\"\n\n// Single method to solve an LP with the simplex method. Solves the\n// scaled LP then analyses the unscaled solution. If it doesn't satisfy\n// the required tolerances, tolerances for the scaled LP are\n// identified which, if used, might yield an unscaled solution that\n// satisfies the required tolerances.\n//\n// If possible, it sets the HiGHS basis and solution\n\ninline HighsStatus returnFromSolveLpSimplex(HighsLpSolverObject& solver_object,\n                                            HighsStatus return_status) {\n  HighsOptions& options = solver_object.options_;\n  HEkk& ekk_instance = solver_object.ekk_instance_;\n  HighsLp& incumbent_lp = solver_object.lp_;\n  // Copy the simplex iteration count to highs_info_ from ekk_instance\n  solver_object.highs_info_.simplex_iteration_count =\n      ekk_instance.iteration_count_;\n  // Identify which clock to stop. Can't inspect the basis, as there\n  // will generally be one after simplex, so have to deduce whether\n  // there was one before\n  const HighsInt sub_solver_ix =\n      solver_object.sub_solver_call_time_.run_time[kSubSolverSimplexBasis] < 0\n          ? kSubSolverSimplexBasis\n          : kSubSolverSimplexNoBasis;\n  const HighsInt sub_solver_not_ix = sub_solver_ix == kSubSolverSimplexBasis\n                                         ? kSubSolverSimplexNoBasis\n                                         : kSubSolverSimplexBasis;\n  assert(solver_object.sub_solver_call_time_.run_time[sub_solver_not_ix] >= 0);\n  (void)sub_solver_not_ix;\n  assert(solver_object.sub_solver_call_time_.run_time[sub_solver_ix] < 0);\n  // Update the call count and run time\n  solver_object.sub_solver_call_time_.num_call[sub_solver_ix]++;\n  solver_object.sub_solver_call_time_.run_time[sub_solver_ix] +=\n      solver_object.timer_.read();\n  // Ensure that the incumbent LP is neither moved, nor scaled\n  assert(!incumbent_lp.is_moved_);\n  assert(!incumbent_lp.is_scaled_);\n  // Cannot expect any more with an error return, and safer to clear\n  // HEkk than try to retain any data\n  if (return_status == HighsStatus::kError) {\n    ekk_instance.clear();\n    return return_status;\n  }\n  //\n  // Ensure that there is an invert for the current LP\n  assert(ekk_instance.status_.has_invert);\n  // Ensure that simplex NLA is set up\n  assert(ekk_instance.status_.has_nla);\n  // Set the simplex NLA scaling\n  ekk_instance.setNlaPointersForLpAndScale(incumbent_lp);\n  assert(ekk_instance.debugNlaScalingOk(incumbent_lp));\n  HighsInt alt_debug_level = -1;\n  // Forced expensive debug for development work\n  //  alt_debug_level = kHighsDebugLevelExpensive;\n  if (ekk_instance.debugNlaCheckInvert(\"HApp: returnFromSolveLpSimplex\",\n                                       alt_debug_level) ==\n      HighsDebugStatus::kError) {\n    highsLogUser(options.log_options, HighsLogType::kError,\n                 \"Error in basis matrix inverse after solving the LP\\n\");\n    return_status = HighsStatus::kError;\n  }\n  if (solver_object.model_status_ == HighsModelStatus::kOptimal) {\n    solver_object.highs_info_.num_complementarity_violations = 0;\n    solver_object.highs_info_.max_complementarity_violation = 0;\n  }\n  return return_status;\n}\n\ninline HighsStatus solveLpSimplex(HighsLpSolverObject& solver_object) {\n  HighsStatus return_status = HighsStatus::kOk;\n  HighsStatus call_status;\n  HighsOptions& options = solver_object.options_;\n  HighsLp& incumbent_lp = solver_object.lp_;\n  HighsSolution& solution = solver_object.solution_;\n  HighsModelStatus& model_status = solver_object.model_status_;\n  HighsModelStatus scaled_model_status = HighsModelStatus::kUnknown;\n  HighsInfo& highs_info = solver_object.highs_info_;\n  HighsBasis& basis = solver_object.basis_;\n\n  HEkk& ekk_instance = solver_object.ekk_instance_;\n  HighsLp& ekk_lp = ekk_instance.lp_;\n  HighsSimplexInfo& ekk_info = ekk_instance.info_;\n  SimplexBasis& ekk_basis = ekk_instance.basis_;\n  HighsSimplexStatus& status = ekk_instance.status_;\n\n  // Check that any retained Ekk data - basis and NLA - are OK on entry\n  bool retained_ekk_data_ok = ekk_instance.debugRetainedDataOk(incumbent_lp) !=\n                              HighsDebugStatus::kLogicalError;\n  if (!retained_ekk_data_ok) {\n    highsLogUser(options.log_options, HighsLogType::kError,\n                 \"solveLpSimplex: Retained Ekk data not OK on entry\\n\");\n    assert(retained_ekk_data_ok);\n    return_status = HighsStatus::kError;\n  }\n  const HighsInt sub_solver_ix =\n      basis.valid ? kSubSolverSimplexBasis : kSubSolverSimplexNoBasis;\n  assert(solver_object.sub_solver_call_time_.run_time.size() > 0);\n  solver_object.sub_solver_call_time_.run_time[sub_solver_ix] =\n      -solver_object.timer_.read();\n  // Copy the simplex iteration count from highs_info_ to ekk_instance, just for\n  // convenience\n  ekk_instance.iteration_count_ = highs_info.simplex_iteration_count;\n\n  // Reset the model status and HighsInfo values in case of premature\n  // return\n  resetModelStatusAndHighsInfo(solver_object);\n\n  // Initialise the simplex stats\n  ekk_instance.initialiseSimplexStats();\n\n  // Assumes that the LP has a positive number of rows, since\n  // unconstrained LPs should be solved in solveLp\n  bool positive_num_row = solver_object.lp_.num_row_ > 0;\n  assert(positive_num_row);\n  if (!positive_num_row) {\n    highsLogUser(\n        options.log_options, HighsLogType::kError,\n        \"solveLpSimplex called for LP with non-positive (%\" HIGHSINT_FORMAT\n        \") \"\n        \"number of constraints\\n\",\n        incumbent_lp.num_row_);\n    return returnFromSolveLpSimplex(solver_object, HighsStatus::kError);\n  }\n  // On entry to solveLpSimplex, the incumbent LP is assumed to be\n  // unscaled and not moved\n  assert(!incumbent_lp.is_scaled_);\n  assert(!incumbent_lp.is_moved_);\n  // Consider scaling the LP - either with any existing scaling, or by\n  // considering computing scaling factors if there are none - and\n  // then move to EKK\n  considerScaling(options, incumbent_lp);\n  //\n  const bool was_scaled = incumbent_lp.is_scaled_;\n  if (!status.has_basis && !basis.valid && basis.useful) {\n    // There is no simplex basis, but there is a useful HiGHS basis\n    // that is not validated\n    assert(basis.col_status.size() ==\n           static_cast<size_t>(incumbent_lp.num_col_));\n    assert(basis.row_status.size() ==\n           static_cast<size_t>(incumbent_lp.num_row_));\n    HighsStatus return_status = formSimplexLpBasisAndFactor(solver_object);\n    if (return_status != HighsStatus::kOk)\n      return returnFromSolveLpSimplex(solver_object, HighsStatus::kError);\n    // formSimplexLpBasisAndFactor may introduce variables with\n    // HighsBasisStatus::kNonbasic, so refine it\n    refineBasis(incumbent_lp, solution, basis);\n    basis.valid = true;\n  }\n  // Check that scaling has not been removed\n  assert(incumbent_lp.is_scaled_ == was_scaled);\n  // Move the LP to EKK, updating other EKK pointers and any simplex\n  // NLA pointers, since they may have moved if the LP has been\n  // modified\n  ekk_instance.moveLp(solver_object);\n  if (!status.has_basis) {\n    // There is no simplex basis, so use any HiGHS basis\n    if (basis.valid) {\n      call_status = ekk_instance.setBasis(basis);\n      if (call_status == HighsStatus::kError) {\n        incumbent_lp.moveBackLpAndUnapplyScaling(ekk_lp);\n        return returnFromSolveLpSimplex(solver_object, call_status);\n      }\n    } else {\n      // Starting from a logical basis, so consider dualizing and/or\n      // permuting the LP\n      if (options.simplex_dualize_strategy == kHighsOptionChoose ||\n          options.simplex_dualize_strategy == kHighsOptionOn) {\n        // Dualize unless we choose not to\n        bool dualize_lp = true;\n        if (options.simplex_dualize_strategy == kHighsOptionChoose) {\n          if (incumbent_lp.num_row_ < 10 * incumbent_lp.num_col_)\n            dualize_lp = false;\n        }\n        if (dualize_lp) ekk_instance.dualize();\n      }\n      if (options.simplex_permute_strategy == kHighsOptionChoose ||\n          options.simplex_permute_strategy == kHighsOptionOn) {\n        // Permute the LP\n        ekk_instance.permute();\n      }\n    }\n  }\n  // These local illegal values are over-written with correct values\n  // if the scaled LP is solved in order to take correct algorithmic\n  // decisions if the unscaled LP is solved later\n  HighsInt num_unscaled_primal_infeasibilities =\n      kHighsIllegalInfeasibilityCount;\n  HighsInt num_unscaled_dual_infeasibilities = kHighsIllegalInfeasibilityCount;\n  // Record whether the unscaled LP is to be solved, and has been\n  // solved. It's not solved if it's proved to be infeasible using the\n  // ray from the scaled LP, in which case the solution (FWIW) and\n  // basis are taken from the unscaled solution of the scaled LP.\n  bool solve_unscaled_lp = false;\n  bool solved_unscaled_lp = false;\n  if (!incumbent_lp.scale_.has_scaling) {\n    //\n    // Solve the unscaled LP with unscaled NLA\n    //\n    solve_unscaled_lp = true;\n    return_status = ekk_instance.solve();\n    solved_unscaled_lp = true;\n    ekk_instance.unpermute();\n    ekk_instance.undualize();\n    assert(!ekk_instance.status_.is_permuted &&\n           !ekk_instance.status_.is_dualized);\n    if (options.cost_scale_factor) {\n      double cost_scale_factor = pow(2.0, -options.cost_scale_factor);\n      highsLogDev(options.log_options, HighsLogType::kInfo,\n                  \"Objective = %11.4g\\n\",\n                  cost_scale_factor * ekk_instance.info_.dual_objective_value);\n      ekk_instance.model_status_ = HighsModelStatus::kNotset;\n      return_status = HighsStatus::kError;\n    }\n    //\n  } else {\n    // Indicate that there is no (current) need to refine the solution\n    // by solving the unscaled LP with scaled NLA\n    bool refine_solution = false;\n    if (options.simplex_unscaled_solution_strategy ==\n            kSimplexUnscaledSolutionStrategyNone ||\n        options.simplex_unscaled_solution_strategy ==\n            kSimplexUnscaledSolutionStrategyRefine) {\n      // Check that the incumbent LP has scaling and is scaled\n      assert(incumbent_lp.scale_.has_scaling);\n      assert(incumbent_lp.is_scaled_);\n      //\n      // Solve the scaled LP!\n      //\n      return_status = ekk_instance.solve();\n      ekk_instance.unpermute();\n      ekk_instance.undualize();\n      assert(!ekk_instance.status_.is_permuted &&\n             !ekk_instance.status_.is_dualized);\n      //\n      if (options.cost_scale_factor) {\n        double cost_scale_factor = pow(2.0, -options.cost_scale_factor);\n        highsLogDev(\n            options.log_options, HighsLogType::kInfo, \"Objective = %11.4g\\n\",\n            cost_scale_factor * ekk_instance.info_.dual_objective_value);\n        ekk_instance.model_status_ = HighsModelStatus::kNotset;\n        return_status = HighsStatus::kError;\n      }\n      if (return_status == HighsStatus::kError) {\n        incumbent_lp.moveBackLpAndUnapplyScaling(ekk_lp);\n        return returnFromSolveLpSimplex(solver_object, return_status);\n      }\n      // Copy solution data from the EKK instance\n      scaled_model_status = ekk_instance.model_status_;\n      highs_info.objective_function_value = ekk_info.primal_objective_value;\n      highs_info.simplex_iteration_count = ekk_instance.iteration_count_;\n      solution = ekk_instance.getSolution();\n      basis = ekk_instance.getHighsBasis(ekk_lp);\n      assert(basis.valid);\n      highs_info.basis_validity = kBasisValidityValid;\n      incumbent_lp.moveBackLpAndUnapplyScaling(ekk_lp);\n      // Now that the incumbent LP is unscaled, to use the simplex NLA\n      // requires scaling to be applied\n      ekk_instance.setNlaPointersForLpAndScale(incumbent_lp);\n      unscaleSolution(solution, incumbent_lp.scale_);\n      // Determine whether the unscaled LP has been solved\n      getUnscaledInfeasibilities(options, incumbent_lp.scale_, ekk_basis,\n                                 ekk_info, highs_info);\n      num_unscaled_primal_infeasibilities =\n          highs_info.num_primal_infeasibilities;\n      num_unscaled_dual_infeasibilities = highs_info.num_dual_infeasibilities;\n      // Determine whether the unscaled solution has infeasibilities\n      // after the scaled LP has been solved to optimality\n      const bool scaled_optimality_but_unscaled_infeasibilities =\n          scaled_model_status == HighsModelStatus::kOptimal &&\n          (num_unscaled_primal_infeasibilities ||\n           num_unscaled_dual_infeasibilities);\n      // Determine whether the unscaled solution has primal\n      // infeasibilities after the scaled LP has been solved to the\n      // objective target\n      const bool scaled_objective_target_but_unscaled_primal_infeasibilities =\n          scaled_model_status == HighsModelStatus::kObjectiveTarget &&\n          highs_info.num_primal_infeasibilities > 0;\n      // Determine whether the unscaled solution has dual\n      // infeasibilities after the scaled LP has been solved to the\n      // objective bound\n      const bool scaled_objective_bound_but_unscaled_dual_infeasibilities =\n          scaled_model_status == HighsModelStatus::kObjectiveBound &&\n          highs_info.num_dual_infeasibilities > 0;\n      if (scaled_optimality_but_unscaled_infeasibilities ||\n          scaled_objective_target_but_unscaled_primal_infeasibilities ||\n          scaled_objective_bound_but_unscaled_dual_infeasibilities)\n        highsLogDev(options.log_options, HighsLogType::kInfo,\n                    \"After unscaling with status %s, have num/max/sum primal \"\n                    \"(%\" HIGHSINT_FORMAT \"/%g/%g) and dual (%\" HIGHSINT_FORMAT\n                    \"/%g/%g) \"\n                    \"unscaled infeasibilities\\n\",\n                    utilModelStatusToString(scaled_model_status).c_str(),\n                    highs_info.num_primal_infeasibilities,\n                    highs_info.max_primal_infeasibility,\n                    highs_info.sum_primal_infeasibilities,\n                    highs_info.num_dual_infeasibilities,\n                    highs_info.max_dual_infeasibility,\n                    highs_info.sum_dual_infeasibilities);\n      // Determine whether refinement will take place\n      refine_solution =\n          options.simplex_unscaled_solution_strategy ==\n              kSimplexUnscaledSolutionStrategyRefine &&\n          (scaled_optimality_but_unscaled_infeasibilities ||\n           scaled_model_status == HighsModelStatus::kInfeasible ||\n           scaled_model_status == HighsModelStatus::kUnboundedOrInfeasible ||\n           scaled_model_status == HighsModelStatus::kUnbounded ||\n           scaled_objective_bound_but_unscaled_dual_infeasibilities ||\n           scaled_objective_target_but_unscaled_primal_infeasibilities ||\n           scaled_model_status == HighsModelStatus::kUnknown);\n      // Handle the case when refinement will not take place\n      if (!refine_solution) {\n        model_status = scaled_model_status;\n        return_status = highsStatusFromHighsModelStatus(model_status);\n        return returnFromSolveLpSimplex(solver_object, return_status);\n      }\n    } else {\n      // LP is scaled, but simplex_unscaled_solution_strategy is\n      // kSimplexUnscaledSolutionStrategyDirect, so have to move back\n      // the LP and unscale it\n      assert(options.simplex_unscaled_solution_strategy ==\n             kSimplexUnscaledSolutionStrategyDirect);\n      incumbent_lp.moveBackLpAndUnapplyScaling(ekk_lp);\n    }\n    assert(options.simplex_unscaled_solution_strategy ==\n               kSimplexUnscaledSolutionStrategyDirect ||\n           refine_solution);\n    // Solve the unscaled LP using scaled NLA. This requires pointers of\n    // a scaled matrix to be passed to the HFactor instance. Use the\n    // incumbent LP for this.\n    //\n    // Check that the incumbent LP has been moved back and is unscaled\n    assert(!incumbent_lp.is_moved_);\n    assert(!incumbent_lp.is_scaled_);\n    // Move the incumbent LP\n    ekk_instance.moveLp(solver_object);\n    // If refining after proving primal infeasibility of the scaled\n    // LP, see whether the proof still holds for the unscaled LP. If\n    // it does, then there's no need to solve the unscaled LP\n    solve_unscaled_lp = true;\n    // ToDo: ekk_instance.dual_ray_record_.index != kNoRayIndex should\n    // now be true if scaled_model_status ==\n    // HighsModelStatus::kInfeasible and dual simplex was the exit\n    // algorithm since this model status depends on the infeasibility\n    // proof being true\n    if (scaled_model_status == HighsModelStatus::kInfeasible &&\n        ekk_instance.exit_algorithm_ == SimplexAlgorithm::kDual)\n      assert(ekk_instance.dual_ray_record_.index != kNoRayIndex);\n    if (scaled_model_status == HighsModelStatus::kInfeasible &&\n        ekk_instance.dual_ray_record_.index != kNoRayIndex) {\n      ekk_instance.setNlaPointersForLpAndScale(ekk_lp);\n      if (ekk_instance.proofOfPrimalInfeasibility()) solve_unscaled_lp = false;\n    }\n    if (solve_unscaled_lp) {\n      // Save options/strategies that may be changed\n      HighsInt simplex_strategy = options.simplex_strategy;\n      double dual_simplex_cost_perturbation_multiplier =\n          options.dual_simplex_cost_perturbation_multiplier;\n      HighsInt simplex_dual_edge_weight_strategy =\n          ekk_info.dual_edge_weight_strategy;\n      // #1865 exposed that this should not be\n      // HighsModelStatus::kObjectiveBound, but\n      // HighsModelStatus::kObjectiveTarget, since if the latter is\n      // the model status for the scaled LP, any primal\n      // infeasibilities should be small, but must be cleaned up\n      // before (hopefully) a few phase 2 primal simplex iterations\n      // are required to attain the target for the unscaled LP\n      //\n      // In #1865, phase 2 primal simplex was forced with large primal\n      // infeasibilities\n      if (num_unscaled_primal_infeasibilities == 0 ||\n          scaled_model_status == HighsModelStatus::kObjectiveTarget) {\n        // Only dual infeasibilities, or objective target reached (in\n        // primal phase 2) - so primal infeasibilities should be small\n        // - so use primal simplex phase 2\n        options.simplex_strategy = kSimplexStrategyPrimal;\n        if (scaled_model_status == HighsModelStatus::kObjectiveTarget) {\n          highsLogDev(options.log_options, HighsLogType::kInfo,\n                      \"solveLpSimplex: Calling primal simplex after \"\n                      \"scaled_model_status == \"\n                      \"HighsModelStatus::kObjectiveTarget: solve \"\n                      \"= %d; tick = %d; iter = %d\\n\",\n                      (int)ekk_instance.debug_solve_call_num_,\n                      (int)ekk_instance.debug_initial_build_synthetic_tick_,\n                      (int)ekk_instance.iteration_count_);\n        }\n      } else {\n        // Using dual simplex, so force Devex if starting from an advanced\n        // basis with no steepest edge weights\n        if ((status.has_basis || basis.valid) &&\n            !status.has_dual_steepest_edge_weights) {\n          ekk_info.dual_edge_weight_strategy = kSimplexEdgeWeightStrategyDevex;\n        }\n      }\n      //\n      // Solve the unscaled LP with scaled NLA\n      //\n      // Force the simplex solver to start in phase 1 if solving the\n      // LP directly as unscaled, or using primal simplex to clean up\n      // small dual infeasibilities after the scaled LP yielded model\n      // status HighsModelStatus::kObjectiveTarget. Otherwise force\n      // the simplex solver to start in phase 2\n      //\n      const bool force_phase1 =\n          (options.simplex_unscaled_solution_strategy ==\n           kSimplexUnscaledSolutionStrategyDirect) ||\n          (scaled_model_status == HighsModelStatus::kObjectiveTarget);\n      const bool force_phase2 =\n          (options.simplex_unscaled_solution_strategy !=\n           kSimplexUnscaledSolutionStrategyDirect) &&\n          (scaled_model_status != HighsModelStatus::kObjectiveTarget);\n      assert(force_phase2 == !force_phase1);\n      return_status = ekk_instance.solve(force_phase2);\n      solved_unscaled_lp = true;\n      if (scaled_model_status != HighsModelStatus::kObjectiveBound &&\n          ekk_instance.model_status_ == HighsModelStatus::kObjectiveBound) {\n        // it may happen that the unscaled LP detected status kObjectiveBound\n        // for the first time in which case we again call solve with primal\n        // simplex if not dual feasible\n        const bool objective_bound_refinement =\n            ekk_info.num_dual_infeasibilities > 0;\n        if (objective_bound_refinement) {\n          options.simplex_strategy = kSimplexStrategyPrimal;\n          return_status = ekk_instance.solve(force_phase2);\n        }\n      }\n      // Restore the options/strategies that may have been changed\n      options.simplex_strategy = simplex_strategy;\n      options.dual_simplex_cost_perturbation_multiplier =\n          dual_simplex_cost_perturbation_multiplier;\n      ekk_info.dual_edge_weight_strategy = simplex_dual_edge_weight_strategy;\n    }\n  }\n  if (solved_unscaled_lp) {\n    // Copy solution data from the EKK istance\n    scaled_model_status = ekk_instance.model_status_;\n    highs_info.objective_function_value = ekk_info.primal_objective_value;\n    highs_info.simplex_iteration_count = ekk_instance.iteration_count_;\n    solution = ekk_instance.getSolution();\n    basis = ekk_instance.getHighsBasis(ekk_lp);\n    assert(basis.valid);\n    highs_info.basis_validity = kBasisValidityValid;\n  }\n  // Move the incumbent LP back from Ekk\n  incumbent_lp = std::move(ekk_lp);\n  incumbent_lp.is_moved_ = false;\n  ekk_instance.setNlaPointersForLpAndScale(incumbent_lp);\n  if (return_status == HighsStatus::kError) {\n    // Error return, so make sure that the unscaled and scaled model\n    // status values are the same, and that they correspond to an\n    // error return\n    model_status = scaled_model_status;\n    return_status = highsStatusFromHighsModelStatus(model_status);\n    assert(return_status == HighsStatus::kError);\n    return returnFromSolveLpSimplex(solver_object, HighsStatus::kError);\n  }\n  if (solved_unscaled_lp) {\n    // The unscaled LP has been solved - either directly, or because\n    // there was no scaling. Copy values into HighsInfo from solving\n    // the scaled LP.\n    assert(solve_unscaled_lp);\n    highs_info.num_primal_infeasibilities = ekk_info.num_primal_infeasibilities;\n    highs_info.max_primal_infeasibility = ekk_info.max_primal_infeasibility;\n    highs_info.sum_primal_infeasibilities = ekk_info.sum_primal_infeasibilities;\n    highs_info.num_dual_infeasibilities = ekk_info.num_dual_infeasibilities;\n    highs_info.max_dual_infeasibility = ekk_info.max_dual_infeasibility;\n    highs_info.sum_dual_infeasibilities = ekk_info.sum_dual_infeasibilities;\n  } else {\n    // The unscaled LP has not been solved because the scaled LP was\n    // infeasible and the proof of infeasibility held for the unscaled\n    // LP. Hence the values in HighsInfo that are set (above) by the\n    // call to getUnscaledInfeasibilities are correct\n    assert(!solve_unscaled_lp);\n    assert(scaled_model_status == HighsModelStatus::kInfeasible);\n  }\n  setSolutionStatus(highs_info);\n  model_status = scaled_model_status;\n  return_status = highsStatusFromHighsModelStatus(model_status);\n  return returnFromSolveLpSimplex(solver_object, return_status);\n}\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/simplex/HEkk.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file simplex/HEkk.h\n * @brief Primal simplex solver for HiGHS\n */\n#ifndef SIMPLEX_HEKK_H_\n#define SIMPLEX_HEKK_H_\n\n#include \"lp_data/HighsCallback.h\"\n#include \"simplex/HSimplexNla.h\"\n#include \"simplex/HighsSimplexAnalysis.h\"\n#include \"util/HSet.h\"\n#include \"util/HighsHash.h\"\n#include \"util/HighsRandom.h\"\n\nclass HighsLpSolverObject;\n\nclass HEkk {\n public:\n  HEkk()\n      : callback_(nullptr),\n        options_(nullptr),\n        timer_(nullptr),\n        lp_name_(\"\"),\n        model_status_(HighsModelStatus::kNotset),\n        simplex_in_scaled_space_(false),\n        cost_scale_(1.0),\n        cost_perturbation_base_(0.0),\n        cost_perturbation_max_abs_cost_(0.0),\n        iteration_count_(0),\n        dual_simplex_cleanup_level_(0),\n        dual_simplex_phase1_cleanup_level_(0),\n        previous_iteration_cycling_detected(-kHighsIInf),\n        solve_bailout_(false),\n        called_return_from_solve_(false),\n        exit_algorithm_(SimplexAlgorithm::kNone),\n        return_primal_solution_status_(0),\n        return_dual_solution_status_(0),\n        original_num_col_(0),\n        original_num_row_(0),\n        original_num_nz_(0),\n        original_offset_(0.0),\n        edge_weight_error_(0.0),\n        build_synthetic_tick_(0.0),\n        total_synthetic_tick_(0.0),\n        debug_solve_call_num_(0),\n        debug_basis_id_(0),\n        time_report_(false),\n        debug_initial_build_synthetic_tick_(0),\n        debug_solve_report_(false),\n        debug_iteration_report_(false),\n        debug_basis_report_(false),\n        debug_dual_feasible(false),\n        debug_max_relative_dual_steepest_edge_weight_error(0) {}\n  /**\n   * @brief Interface to simplex solvers\n   */\n  void clear();\n  void clearEkkLp();\n  void clearEkkData();\n  void clearEkkDualize();\n  void clearEkkDualEdgeWeightData();\n  void clearEkkPointers();\n  void clearEkkDataInfo();\n  void clearEkkControlInfo();\n  void clearEkkNlaInfo();\n  void clearEkkAllStatus();\n  void clearEkkDataStatus();\n  void clearNlaStatus();\n  void clearNlaInvertStatus();\n  void clearRayRecords();\n\n  void invalidate();\n  void invalidateBasisMatrix();\n  void invalidateBasis();\n  void invalidateBasisArtifacts();\n\n  void updateStatus(LpAction action);\n  void setNlaPointersForLpAndScale(const HighsLp& lp);\n  void setNlaPointersForTrans(const HighsLp& lp);\n  void setNlaRefactorInfo();\n  void btran(HVector& rhs, const double expected_density);\n  void ftran(HVector& rhs, const double expected_density);\n\n  void moveLp(HighsLpSolverObject& solver_object);\n  void setPointers(HighsCallback* callback, HighsOptions* options,\n                   HighsTimer* timer);\n  HighsSparseMatrix* getScaledAMatrixPointer();\n  HighsScale* getScalePointer();\n\n  void initialiseEkk();\n  HighsStatus dualize();\n  HighsStatus undualize();\n  HighsStatus permute();\n  HighsStatus unpermute();\n  HighsStatus solve(const bool force_phase2 = false);\n  HighsStatus setBasis();\n  HighsStatus setBasis(const HighsBasis& highs_basis);\n\n  void putIterate();\n  HighsStatus getIterate();\n\n  void addCols(const HighsLp& lp, const HighsSparseMatrix& scaled_a_matrix);\n  void addRows(const HighsLp& lp, const HighsSparseMatrix& scaled_ar_matrix);\n  void deleteCols(const HighsIndexCollection& index_collection);\n  void deleteRows(const HighsIndexCollection& index_collection);\n  void unscaleSimplex(const HighsLp& incumbent_lp);\n  double factorSolveError();\n\n  bool proofOfPrimalInfeasibility();\n  bool proofOfPrimalInfeasibility(HVector& row_ep, const HighsInt move_out,\n                                  const HighsInt row_out);\n\n  double getValueScale(const HighsInt count, const vector<double>& value) const;\n  double getMaxAbsRowValue(HighsInt row);\n\n  void unitBtranIterativeRefinement(const HighsInt row_out, HVector& row_ep);\n  void unitBtranResidual(const HighsInt row_out, const HVector& row_ep,\n                         HVector& residual, double& residual_norm);\n\n  HighsSolution getSolution();\n  HighsBasis getHighsBasis(HighsLp& use_lp) const;\n\n  const SimplexBasis& getSimplexBasis() { return basis_; }\n  double computeBasisCondition(const HighsLp& lp, const bool exact = false,\n                               const bool report = false) const;\n  double computeBasisCondition() const {\n    return computeBasisCondition(this->lp_, false, false);\n  }\n\n  HighsStatus initialiseSimplexLpBasisAndFactor(\n      const bool only_from_known_basis = false);\n  void handleRankDeficiency();\n  void initialisePartitionedRowwiseMatrix();\n  bool lpFactorRowCompatible() const;\n  bool lpFactorRowCompatible(const HighsInt expectedNumRow) const;\n\n  // Interface methods\n  void appendColsToVectors(const HighsInt num_new_col,\n                           const vector<double>& colCost,\n                           const vector<double>& colLower,\n                           const vector<double>& colUpper);\n  void appendRowsToVectors(const HighsInt num_new_row,\n                           const vector<double>& rowLower,\n                           const vector<double>& rowUpper);\n\n  const HighsSimplexStats& getSimplexStats() const { return simplex_stats_; }\n  void initialiseSimplexStats() { simplex_stats_.initialise(iteration_count_); }\n  void reportSimplexStats(FILE* file, const std::string message = \"\") const {\n    simplex_stats_.report(file, message);\n  }\n\n  // Make this private later\n  void chooseSimplexStrategyThreads(const HighsOptions& options,\n                                    HighsSimplexInfo& info);\n  // Debug methods\n  void debugInitialise();\n  void debugReportInitialBasis();\n  void debugReporting(\n      const HighsInt save_mod_recover,\n      const HighsInt log_dev_level_ = kHighsLogDevLevelDetailed);\n  void timeReporting(const HighsInt save_mod_recover);\n  HighsDebugStatus debugRetainedDataOk(const HighsLp& lp) const;\n  HighsDebugStatus debugNlaCheckInvert(\n      const std::string message, const HighsInt alt_debug_level = -1) const;\n  bool debugNlaScalingOk(const HighsLp& lp) const;\n\n  // Data members\n  HighsCallback* callback_;\n  HighsOptions* options_;\n  HighsTimer* timer_;\n  HighsSimplexAnalysis analysis_;\n\n  HighsLp lp_;\n  std::string lp_name_;\n  HighsSimplexStatus status_;\n  HighsSimplexInfo info_;\n  HighsModelStatus model_status_;\n  SimplexBasis basis_;\n  HighsHashTable<uint64_t> visited_basis_;\n  HighsRandom random_;\n  std::vector<double> dual_edge_weight_;\n  std::vector<double> scattered_dual_edge_weight_;\n\n  bool simplex_in_scaled_space_;\n  HighsSparseMatrix ar_matrix_;\n  HighsSparseMatrix scaled_a_matrix_;\n  HSimplexNla simplex_nla_;\n\n  // Unused, but retained since there is a const reference to this in\n  // a deprecated method\n  HotStart hot_start_;\n\n  double cost_scale_;\n  double cost_perturbation_base_;\n  double cost_perturbation_max_abs_cost_;\n  HighsInt iteration_count_;\n  HighsInt dual_simplex_cleanup_level_;\n  HighsInt dual_simplex_phase1_cleanup_level_;\n\n  HighsInt previous_iteration_cycling_detected;\n\n  bool solve_bailout_;\n  bool called_return_from_solve_;\n  SimplexAlgorithm exit_algorithm_;\n  HighsInt return_primal_solution_status_;\n  HighsInt return_dual_solution_status_;\n\n  // Data to be retained after proving primal infeasibility\n  vector<HighsInt> proof_index_;\n  vector<double> proof_value_;\n\n  // Data to be retained after computing primal or dual ray\n  HighsRayRecord dual_ray_record_;\n  HighsRayRecord primal_ray_record_;\n\n  // Data to be retained when dualizing\n  HighsInt original_num_col_;\n  HighsInt original_num_row_;\n  HighsInt original_num_nz_;\n  double original_offset_;\n  vector<double> original_col_cost_;\n  vector<double> original_col_lower_;\n  vector<double> original_col_upper_;\n  vector<double> original_row_lower_;\n  vector<double> original_row_upper_;\n  //\n  // The upper_bound_col vector accumulates the indices of boxed\n  // variables, whose upper bounds are treated as additional\n  // constraints.\n  //\n  // The upper_bound_row vector accumulates the indices of boxed\n  // constraints, whose upper bounds are treated as additional\n  // constraints.\n  vector<HighsInt> upper_bound_col_;\n  vector<HighsInt> upper_bound_row_;\n\n  double edge_weight_error_;\n\n  double build_synthetic_tick_;\n  double total_synthetic_tick_;\n  HighsInt debug_solve_call_num_;\n  HighsInt debug_basis_id_;\n  bool time_report_;\n  HighsInt debug_initial_build_synthetic_tick_;\n  bool debug_solve_report_;\n  bool debug_iteration_report_;\n  bool debug_basis_report_;\n  bool debug_dual_feasible;\n  double debug_max_relative_dual_steepest_edge_weight_error;\n\n  std::vector<HighsSimplexBadBasisChangeRecord> bad_basis_change_;\n  std::vector<double> primal_phase1_dual_;\n\n  HighsSimplexStats simplex_stats_;\n\n private:\n  bool isUnconstrainedLp() const;\n  void initialiseForSolve();\n  void setSimplexOptions();\n  void updateSimplexOptions();\n  void initialiseSimplexLpRandomVectors();\n  void setNonbasicMove();\n  bool getNonsingularInverse(const HighsInt solve_phase = 0);\n  bool getBacktrackingBasis();\n  void putBacktrackingBasis();\n  void putBacktrackingBasis(\n      const vector<HighsInt>& basicIndex_before_compute_factor);\n  void computePrimalObjectiveValue();\n  void computeDualObjectiveValue(const HighsInt phase = 2);\n  bool rebuildRefactor(HighsInt rebuild_reason);\n  HighsInt computeFactor();\n  void computeDualSteepestEdgeWeights(const bool initial = false);\n  double computeDualSteepestEdgeWeight(const HighsInt iRow, HVector& row_ep);\n  void updateDualSteepestEdgeWeights(const HighsInt row_out,\n                                     const HighsInt variable_in,\n                                     const HVector* column,\n                                     const double new_pivotal_edge_weight,\n                                     const double Kai,\n                                     const double* dual_steepest_edge_array);\n  void updateDualDevexWeights(const HVector* column,\n                              const double new_pivotal_edge_weight);\n  void resetSyntheticClock();\n  void allocateWorkAndBaseArrays();\n  void initialiseCost(const SimplexAlgorithm algorithm,\n                      const HighsInt solve_phase, const bool perturb = false);\n  void initialiseBound(const SimplexAlgorithm algorithm,\n                       const HighsInt solve_phase, const bool perturb = false);\n  void initialiseLpColCost();\n  void initialiseLpRowCost();\n  void initialiseLpColBound();\n  void initialiseLpRowBound();\n  void initialiseNonbasicValueAndMove();\n  void pivotColumnFtran(const HighsInt iCol, HVector& col_aq);\n  void unitBtran(const HighsInt iRow, HVector& row_ep);\n  void fullBtran(HVector& buffer);\n  void choosePriceTechnique(const HighsInt price_strategy,\n                            const double row_ep_density, bool& use_col_price,\n                            bool& use_row_price_w_switch) const;\n  void tableauRowPrice(const bool quad_precision, const HVector& row_ep,\n                       HVector& row_ap,\n                       const HighsInt debug_report = kDebugReportOff);\n  void fullPrice(const HVector& full_col, HVector& full_row);\n  void computePrimal();\n  void computeDual();\n  double computeDualForTableauColumn(const HighsInt iVar,\n                                     const HVector& tableau_column) const;\n  bool reinvertOnNumericalTrouble(const std::string method_name,\n                                  double& numerical_trouble_measure,\n                                  const double alpha_from_col,\n                                  const double alpha_from_row,\n                                  const double numerical_trouble_tolerance);\n\n  void flipBound(const HighsInt iCol);\n  void updateFactor(HVector* column, HVector* row_ep, HighsInt* iRow,\n                    HighsInt* hint);\n\n  void transformForUpdate(HVector* column, HVector* row_ep,\n                          const HighsInt variable_in, HighsInt* row_out);\n\n  void updatePivots(const HighsInt variable_in, const HighsInt row_out,\n                    const HighsInt move_out);\n  bool isBadBasisChange(const SimplexAlgorithm algorithm,\n                        const HighsInt variable_in, const HighsInt row_out,\n                        const HighsInt rebuild_reason);\n  void updateMatrix(const HighsInt variable_in, const HighsInt variable_out);\n\n  void computeInfeasibilitiesForReporting(\n      const SimplexAlgorithm algorithm,\n      const HighsInt solve_phase = kSolvePhase2);\n  void computeSimplexInfeasible();\n  void computeSimplexPrimalInfeasible();\n  void computeSimplexDualInfeasible();\n  void computeSimplexLpDualInfeasible();\n\n  void invalidatePrimalInfeasibilityRecord();\n  void invalidatePrimalMaxSumInfeasibilityRecord();\n  void invalidateDualInfeasibilityRecord();\n  void invalidateDualMaxSumInfeasibilityRecord();\n  bool bailout();\n  HighsStatus returnFromEkkSolve(const HighsStatus return_status);\n  HighsStatus returnFromSolve(const HighsStatus return_status);\n\n  void initialiseAnalysis();\n  std::string rebuildReason(const HighsInt rebuild_reason) const;\n\n  void clearBadBasisChange(\n      const BadBasisChangeReason reason = BadBasisChangeReason::kAll);\n  void updateBadBasisChange(const HVector& col_aq, double theta_primal);\n\n  HighsInt addBadBasisChange(const HighsInt row_out,\n                             const HighsInt variable_out,\n                             const HighsInt variable_in,\n                             const BadBasisChangeReason reason,\n                             const bool taboo = false);\n  void clearBadBasisChangeTabooFlag();\n  bool tabooBadBasisChange() const;\n  void applyTabooRowOut(vector<double>& values, const double overwrite_with);\n  void unapplyTabooRowOut(vector<double>& values);\n  void applyTabooVariableIn(vector<double>& values,\n                            const double overwrite_with);\n  void unapplyTabooVariableIn(vector<double>& values);\n  bool logicalBasis() const;\n  // Methods in HEkkControl\n  void initialiseControl();\n  void assessDSEWeightError(const double computed_edge_weight,\n                            const double updated_edge_weight);\n  void updateOperationResultDensity(const double local_density,\n                                    double& density) const;\n  bool switchToDevex();\n\n  // private debug methods\n  HighsDebugStatus debugSimplex(const std::string message,\n                                const SimplexAlgorithm algorithm,\n                                const HighsInt phase,\n                                const bool initialise = false) const;\n  void debugReportReinvertOnNumericalTrouble(\n      const std::string method_name, const double numerical_trouble_measure,\n      const double alpha_from_col, const double alpha_from_row,\n      const double numerical_trouble_tolerance, const bool reinvert) const;\n\n  HighsDebugStatus debugUpdatedDual(const double updated_dual,\n                                    const double computed_dual) const;\n\n  HighsDebugStatus debugBasisCorrect(const HighsLp* lp = NULL) const;\n  HighsDebugStatus debugBasisConsistent() const;\n  HighsDebugStatus debugNonbasicFlagConsistent() const;\n  HighsDebugStatus debugNonbasicMove(const HighsLp* lp = NULL) const;\n  HighsDebugStatus debugOkForSolve(const SimplexAlgorithm algorithm,\n                                   const HighsInt phase) const;\n  bool debugWorkArraysOk(const SimplexAlgorithm algorithm,\n                         const HighsInt phase) const;\n  bool debugOneNonbasicMoveVsWorkArraysOk(const HighsInt var) const;\n\n  HighsDebugStatus debugNonbasicFreeColumnSet(\n      const HighsInt num_free_col, const HSet nonbasic_free_col_set) const;\n  HighsDebugStatus debugRowMatrix() const;\n  HighsDebugStatus devDebugDualSteepestEdgeWeights(const std::string message);\n  HighsDebugStatus debugDualSteepestEdgeWeights(\n      const HighsInt alt_debug_level = -1);\n  HighsDebugStatus debugSimplexDualInfeasible(const std::string message,\n                                              const bool force_report = false);\n  HighsDebugStatus debugComputeDual(const bool initialise = false) const;\n\n  friend class HEkkPrimal;\n  friend class HEkkDual;\n  friend class HEkkDualRow;\n  friend class HEkkDualRHS;  // For  HEkkDualRHS::assessOptimality\n};\n\n#endif /* SIMPLEX_HEKK_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/simplex/HEkkDual.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file simplex/HEkkDual.h\n * @brief Dual simplex solver for HiGHS\n */\n#ifndef SIMPLEX_HEKKDUAL_H_\n#define SIMPLEX_HEKKDUAL_H_\n\n#include <set>\n#include <string>\n#include <vector>\n\n#include \"simplex/HEkk.h\"\n#include \"simplex/HEkkDualRHS.h\"\n#include \"simplex/HEkkDualRow.h\"\n#include \"simplex/HSimplex.h\"\n#include \"util/HVector.h\"\n#include \"util/HVectorBase.h\"\n\n// Limit on the number of column slices for parallel calculations. SIP\n// uses num_threads-2 slices; PAMI uses num_threads-1 slices\nconst HighsInt kHighsSlicedLimit = kSimplexConcurrencyLimit;\n// Was 100, but can't see why this should be higher than\n// kSimplexConcurrencyLimit; const double kMaxOkGrowth = 1e4;\n\n/**\n * @brief Dual simplex solver for HiGHS\n */\nclass HEkkDual {\n public:\n  HEkkDual(HEkk& simplex)\n      : ekk_instance_(simplex), dualRow(simplex), dualRHS(simplex) {\n    initialiseInstance();\n    dualRow.setup();\n    dualRHS.setup();\n    if (!(ekk_instance_.info_.simplex_strategy == kSimplexStrategyDualPlain))\n      initialiseInstanceParallel(simplex);\n  }\n\n  /**\n   * @brief Solve a model instance\n   */\n  HighsStatus solve(const bool force_phase2 = false);\n\n  const SimplexAlgorithm algorithm = SimplexAlgorithm::kDual;\n\n public:\n  /**\n   * @brief Initialise a dual simplex instance\n   *\n   * Copy dimensions and pointers to matrix, factor and solver-related\n   * model data, plus tolerances. Sets up local std::vectors\n   * (columnDSE, columnBFRT, column, row_ep and row_ap), and buffers\n   * for dualRow and dualRHS.\n   */\n  void initialiseInstance();\n\n  /**\n   * @brief Initialise parallel aspects of a dual simplex instance\n   *\n   * Sets up data structures for SIP or PAMI\n   */\n  void initialiseInstanceParallel(HEkk& simplex);\n\n  /**\n   * @brief Initialise matrix slices and slices of row_ap or dualRow for SIP or\n   * PAMI\n   *\n   * TODO generalise call slice_matrix[i].setup_lgBs so slice can be\n   * used with non-logical initial basis\n   */\n  void initSlice(\n      const HighsInt init_sliced_num  //!< Ideal number of slices - true number\n                                      //!< is modified in light of limits\n  );\n\n  /**\n   * @brief Initialise a dual simplex solve\n   */\n  void initialiseSolve();\n\n  /**\n   * @brief Perform Phase 1 dual simplex iterations\n   */\n  void solvePhase1();\n\n  /**\n   * @brief Perform Phase 2 dual simplex iterations\n   */\n  void solvePhase2();\n\n  /**\n   * @brief Reinvert if INVERT not fresh, then recompute dual and primal values\n   *\n   * Also collects primal infeasibilities and computes the dual objective value\n   */\n\n  void rebuild();\n\n  /**\n   * @brief Remove perturbation and recompute the dual solution\n   *\n   * Also collects primal infeasibilities and computes the dual objective value\n   */\n  void cleanup();\n\n  /**\n   * @brief Perform a single serial dual simplex iteration\n   *\n   * All the methods it calls have as their first line \"if (rebuild_reason)\n   * return;\", where rebuild_reason is, for example, set to 1 when CHUZR\n   * finds no candidate. This causes a break from the inner loop of\n   * solvePhase% and, hence, a call to rebuild().\n   */\n  void iterate();\n\n  /**\n   * @brief Perform a single SIP dual simplex iteration\n   */\n  void iterateTasks();\n\n  /**\n   * @brief Perform a single PAMI dual simplex iteration - source code in\n   * HEkkDualMulti.cpp\n   */\n  void iterateMulti();  // in HEkkDualMulti.cpp\n\n  /**\n   * @brief Pass the data for the serial iteration analysis, report and rebuild\n   * report\n   */\n  void iterationAnalysisData();\n\n  /**\n   * @brief Perform the serial iteration analysis\n   */\n  void iterationAnalysis();\n\n  /**\n   * @brief Pass the data for the PAMI iteration analysis for a minor iteration,\n   * report and rebuild report\n   */\n  void iterationAnalysisMinorData();\n\n  /**\n   * @brief Perform the PAMI iteration analysis for a minor iteration\n   */\n  void iterationAnalysisMinor();\n\n  /**\n   * @brief Pass the data for the PAMI iteration analysis for a major iteration\n   */\n  void iterationAnalysisMajorData();\n\n  /**\n   * @brief Perform the PAMI iteration analysis for a major iteration\n   */\n  void iterationAnalysisMajor();\n\n  /**\n   * @brief Single line report after rebuild or cleanup\n   */\n  void reportRebuild(const HighsInt reason_for_rebuild);\n\n  /**\n   * @brief Choose the index of a good row to leave the basis (CHUZR)\n   */\n  void chooseRow();\n\n  /**\n   * @brief Determine whether the updated_edge_weight is accurate enough to\n   * be accepted, and update the analysis of weight errors\n   */\n  bool acceptDualSteepestEdgeWeight(const double updated_edge_weight);\n\n  /**\n   * @brief Determine whether the updated_edge_weight error should trigger a new\n   * Devex framework\n   */\n  bool newDevexFramework(const double updated_edge_weight);\n\n  /**\n   * @brief Compute pivot row (PRICE) and choose the index of a good column to\n   * enter the basis (CHUZC)\n   */\n  void chooseColumn(HVector* row_ep);\n  void improveChooseColumnRow(HVector* row_ep);\n\n  /**\n   * @brief Choose the index of a good column to enter the basis (CHUZC) by\n   * exploiting slices of the pivotal row - for SIP and PAMI\n   */\n  void chooseColumnSlice(HVector* row_ep);\n\n  /**\n   * @brief Compute the pivotal column (FTRAN)\n   */\n  void updateFtran();\n\n  /**\n   * @brief Compute the RHS changes corresponding to the BFRT\n   * (FTRAN-BFRT)\n   */\n  void updateFtranBFRT();\n\n  /**\n   * @brief Compute the std::vector required to update DSE weights - being\n   * FTRAN applied to the pivotal column (FTRAN-DSE)\n   */\n  void updateFtranDSE(HVector* DSE_Vector  //!< Pivotal column as RHS for FTRAN\n  );\n  /**\n   * @brief Compare the pivot value computed row-wise and column-wise\n   * and determine whether reinversion is advisable\n   */\n  void updateVerify();\n\n  /**\n   * @brief Update the dual values\n   */\n  void updateDual();\n\n  /**\n   * @brief Update the primal values and any edge weights\n   */\n  void updatePrimal(HVector* DSE_Vector  //!< FTRANned pivotal column\n  );\n\n  /**\n   * @brief Update the basic and nonbasic variables, iteration count,\n   * invertible representation of the basis matrix and row-wise\n   * representation of the nonbasic columns, delete the Freelist entry\n   * for the entering column, update the primal value for the row\n   * where the basis change has occurred, and set the corresponding\n   * primal infeasibility value in dualRHS.work_infeasibility, and\n   * then determine whether to reinvert according to the synthetic\n   * clock\n   */\n  void updatePivots();\n\n  void shiftCost(const HighsInt iCol, const double amount);\n  void shiftBack(const HighsInt iCol);\n\n  /**\n   * @brief Initialise a Devex framework: reference set is all basic\n   * variables\n   */\n  void initialiseDevexFramework();\n\n  /**\n   * @brief Interpret the dual edge weight strategy as setting of a mode and\n   * other actions\n   */\n  void interpretDualEdgeWeightStrategy(\n      const HighsInt simplex_dual_edge_weight_strategy);\n\n  bool reachedExactObjectiveBound();\n  double computeExactDualObjectiveValue(HVector& dual_col, HVector& dual_row);\n\n  /**\n   * @brief PAMI: Choose the indices of a good set of rows to leave the\n   * basis (CHUZR)\n   */\n  void majorChooseRow();\n\n  /**\n   * @brief PAMI: Perform multiple BTRAN\n   */\n  void majorChooseRowBtran();\n\n  /**\n   * @brief PAMI: Choose the index (from the set of indices) of a good\n   * row to leave the basis (CHUZR-MI)\n   */\n  void minorChooseRow();\n\n  /**\n   * @brief PAMI: Update the data during minor iterations\n   */\n  void minorUpdate();\n\n  /**\n   * @brief PAMI: Update the dual values during minor iterations\n   */\n  void minorUpdateDual();\n\n  /**\n   * @brief PAMI: Update the primal values during minor iterations\n   */\n  void minorUpdatePrimal();\n\n  /**\n   * @brief PAMI: Perform a basis change during minor iterations\n   */\n  void minorUpdatePivots();\n\n  /**\n   * @brief PAMI: Update the tableau rows during minor iterations\n   */\n  void minorUpdateRows();\n\n  /**\n   * @brief PAMI: Initialise a new Devex framework during minor iterations\n   */\n  void minorInitialiseDevexFramework();\n\n  /**\n   * @brief PAMI: Perform updates after a set of minor iterations\n   */\n  void majorUpdate();\n\n  /**\n   * @brief PAMI: Prepare for the FTRANs after a set of minor iterations\n   */\n  void majorUpdateFtranPrepare();\n\n  /**\n   * @brief PAMI: Perform the parallel part of multiple FTRANs after a\n   * set of minor iterations\n   */\n  void majorUpdateFtranParallel();\n\n  /**\n   * @brief PAMI: Perform the final part of multiple FTRANs after a set\n   * of minor iterations\n   */\n  void majorUpdateFtranFinal();\n\n  /**\n   * @brief PAMI: Update the primal values after a set of minor\n   * iterations\n   */\n  void majorUpdatePrimal();\n\n  /**\n   * @brief PAMI: Update the invertible representation of the basis\n   * matrix after a set of minor iterations\n   */\n  void majorUpdateFactor();\n\n  /**\n   * @brief PAMI: Roll back some iterations if numerical trouble\n   * detected when updating the invertible representation of the basis\n   * matrix after a set of minor iterations\n   */\n  void majorRollback();\n\n  // private:\n  void possiblyUseLiDualSteepestEdge();\n  void computeDualInfeasibilitiesWithFixedVariableFlips();\n  void correctDualInfeasibilities(HighsInt& free_infeasibility_count);\n\n  bool proofOfPrimalInfeasibility();\n  void saveDualRay();\n  void assessPhase1Optimality();\n  void assessPhase1OptimalityUnperturbed();\n  void exitPhase1ResetDuals();\n  void reportOnPossibleLpDualInfeasibility();\n\n  bool checkNonUnitWeightError(std::string message) const;\n  bool dualInfoOk(const HighsLp& lp) const;\n  bool bailoutOnDualObjective();\n  HighsDebugStatus debugDualSimplex(const std::string message,\n                                    const bool initialise = false);\n\n  bool isBadBasisChange();\n  void assessPossiblyDualUnbounded();\n\n  // Devex scalars\n  HighsInt num_devex_iterations =\n      0;  //!< Number of Devex iterations with the current framework\n  bool new_devex_framework = false;  //!< Set a new Devex framework\n  bool minor_new_devex_framework =\n      false;  //!< Set a new Devex framework in PAMI minor iterations\n\n  // References:\n  HEkk& ekk_instance_;\n\n  // Model\n  HighsInt solver_num_row;\n  HighsInt solver_num_col;\n  HighsInt solver_num_tot;\n  double inv_solver_num_row;  // 1.0 / solver_num_row\n\n  const HighsSparseMatrix* a_matrix;\n  const HSimplexNla* simplex_nla;\n  HighsSimplexAnalysis* analysis;\n\n  const int8_t* jMove;\n  const double* workRange;\n  const double* baseLower;\n  const double* baseUpper;\n  double* baseValue;\n  double* workDual;\n  double* workValue;\n  double* colLower;\n  double* colUpper;\n  double* rowLower;\n  double* rowUpper;\n  int8_t* nonbasicFlag;\n\n  // Retained value\n  bool initial_basis_is_logical_;\n\n  // Options\n  EdgeWeightMode edge_weight_mode;\n  bool allow_dual_steepest_edge_to_devex_switch;\n\n  double Tp;  // Tolerance for primal\n  double primal_feasibility_tolerance;\n\n  double Td;  // Tolerance for dual\n  double dual_feasibility_tolerance;\n  double objective_bound;\n\n  bool force_phase2;\n  HighsInt solve_phase;\n  HighsInt rebuild_reason;\n\n  HVector row_ep;\n  HVector row_ap;\n  HVector col_aq;\n  HVector col_BFRT;\n  HVector col_DSE;\n\n  HVector dev_row_ep;\n  HVector dev_col_DSE;\n\n  HEkkDualRow dualRow;\n\n  // Solving related buffers\n  HighsInt dualInfeasCount;\n\n  HEkkDualRHS dualRHS;\n\n  // Simplex pivotal information\n  HighsInt row_out;\n  HighsInt variable_out;\n  HighsInt move_out;  // -1 from small to lower, +1 to upper\n  HighsInt variable_in;\n  double delta_primal;\n  double theta_dual;\n  double theta_primal;\n  double alpha_col;\n  double alpha_row;\n  double numericalTrouble;\n  // (Local) value of computed weight\n  double computed_edge_weight;\n\n  bool check_invert_condition = false;\n\n  // Partitioned coefficient matrix\n  HighsInt slice_num;\n  HighsInt slice_PRICE;\n  HighsInt slice_start[kHighsSlicedLimit + 1];\n  HighsSparseMatrix slice_a_matrix[kHighsSlicedLimit];\n  HighsSparseMatrix slice_ar_matrix[kHighsSlicedLimit];\n  HVector slice_row_ap[kHighsSlicedLimit];\n  std::vector<HEkkDualRow> slice_dualRow;\n\n  /**\n   * @brief Multiple CHUZR data\n   */\n  struct MChoice {\n    HighsInt row_out;\n    double baseValue;\n    double baseLower;\n    double baseUpper;\n    double infeasValue;\n    double infeasEdWt;\n    double infeasLimit;\n    HVector row_ep;\n    HVector col_aq;\n    HVector col_BFRT;\n  };\n\n  /**\n   * @brief Multiple minor iteration data\n   */\n  struct MFinish {\n    int8_t move_in;\n    double shiftOut;\n    std::vector<HighsInt> flipList;\n\n    HighsInt row_out;\n    HighsInt variable_out;\n    HighsInt variable_in;\n    double alpha_row;\n    double theta_primal;\n    double basicBound;\n    double basicValue;\n    double EdWt;\n    HVector_ptr row_ep;\n    HVector_ptr col_aq;\n    HVector_ptr col_BFRT;\n  };\n\n  HighsInt multi_num;\n  HighsInt multi_chosen;\n  HighsInt multi_iChoice;\n  HighsInt multi_nFinish;\n  HighsInt multi_iteration;\n  HighsInt multi_chooseAgain;\n  MChoice multi_choice[kSimplexConcurrencyLimit];\n  MFinish multi_finish[kSimplexConcurrencyLimit];\n};\n\n#endif /* SIMPLEX_HEKKDUAL_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/simplex/HEkkDualRHS.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file simplex/HEkkDualRHS.h\n * @brief Dual simplex optimality test for HiGHS\n */\n#ifndef SIMPLEX_HEKKDUALRHS_H_\n#define SIMPLEX_HEKKDUALRHS_H_\n\n#include <vector>\n\n#include \"simplex/HEkk.h\"\n#include \"util/HVector.h\"\n\n/**\n * @brief Dual simplex optimality test for HiGHS\n *\n * Performs the optimality test and some update primal/weight tasks\n */\nclass HEkkDualRHS {\n public:\n  HEkkDualRHS(HEkk& simplex) : ekk_instance_(simplex) {}\n\n  /**\n   * @brief Defines space for Mark, Index and Array, EdWt and EdWtFull\n   *\n   * Mark (markers of primal infeasibilities?)\n   * Index and Array (for ??)\n   * EdWt (for gathered DSE weights)\n   * EdWtFull (for scattered SED weights)\n   */\n  void setup();\n\n  /**\n   * @brief Choose the row index of a good variable to leave the basis (CHUZR)\n   */\n  void chooseNormal(\n      HighsInt* chIndex  //!< Row index of variable chosen to leave the basis\n  );\n\n  /**\n   * @brief Choose a set of row indices of good variables to leave the basis\n   * (Multiple CHUZR)\n   */\n  void chooseMultiGlobal(HighsInt* chIndex,  //!< Set of indices of chosen rows\n                         HighsInt* chCount,  //!< Number of chosen rows\n                         HighsInt chLimit    //!< Limit on number of chosen rows\n  );\n\n  /**\n   * @brief Choose a set of row indices of good variables to leave the basis\n   * (Multiple CHUZR)\n   */\n  void chooseMultiHyperGraphAuto(\n      HighsInt* chIndex,  //!< Set of indices of chosen rows\n      HighsInt* chCount,  //!< Number of chosen rows\n      HighsInt chLimit    //!< Limit on number of chosen rows\n  );\n\n  /**\n   * @brief Choose a set of row indices of good variables to leave the basis\n   * (Multiple CHUZR)\n   */\n  void chooseMultiHyperGraphPart(\n      HighsInt* chIndex,  //!< Set of indices of chosen rows\n      HighsInt* chCount,  //!< Number of chosen rows\n      HighsInt chLimit    //!< Limit on number of chosen rows\n  );\n\n  /**\n   * @brief Update the primal values by adding a multiple of a given\n   * std::vector, returning false if infinite values are created\n   */\n  bool updatePrimal(\n      HVector* column,  //!< Column to add into primal values\n      double theta      //!< Multiple of column to add into primal values\n  );\n\n  /**\n   * @brief Update the primal value for the row where the basis change has\n   * occurred\n   */\n  void updatePivots(\n      const HighsInt iRow,  //!< row where the basis change has occurred\n      const double value    //!< New primal value in this row\n  );\n\n  /**\n   * @brief Update the list of primal infeasibilities using indices of primal\n   * values which have changed\n   */\n  void updateInfeasList(HVector* column  //!< Changes in primal values\n  );\n\n  /**\n   * @brief Create the list of greatest primal infeasibilities for efficient\n   * CHUZR\n   */\n  void createInfeasList(double columnDensity);\n  /**\n   * @brief Create the std::vector of primal infeasibilities\n   *\n   */\n  void createArrayOfPrimalInfeasibilities();\n\n  void assessOptimality();\n\n  // References:\n  HEkk& ekk_instance_;\n\n  double workCutoff;   //!< Limit for row to be in list with greatest primal\n                       //!< infeasibilities\n  HighsInt workCount;  //!< Number of rows in list with greatest primal\n                       //!< infeasibilities\n  std::vector<char> workMark;  //!< Flag set if row is in list of those with\n                               //!< greatest primal infeasibilities\n  std::vector<HighsInt>\n      workIndex;  //!< List of rows with greatest primal infeasibilities\n  std::vector<double> work_infeasibility;\n\n  HighsInt partNum;\n  HighsInt partNumRow;\n  HighsInt partNumCol;\n  HighsInt partNumCut;\n  HighsInt partSwitch;\n  std::vector<HighsInt> workPartition;\n  HighsSimplexAnalysis* analysis;\n};\n\n#endif /* SIMPLEX_HEKKDUALRHS_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/simplex/HEkkDualRow.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file simplex/HEkkDualRow.h\n * @brief Dual simplex ratio test for HiGHS\n */\n#ifndef SIMPLEX_HEKKDUALROW_H_\n#define SIMPLEX_HEKKDUALROW_H_\n\n#include <set>\n#include <vector>\n\n#include \"simplex/HEkk.h\"\n#include \"util/HVector.h\"\n\nconst double kInitialTotalChange = 1e-12;\nconst double kInitialRemainTheta = 1e100;\nconst double kMaxSelectTheta = 1e18;\n\n/**\n * @brief Dual simplex ratio test for HiGHS\n *\n * Performs the dual bound-flipping ratio test and some update\n * dual/flip tasks\n */\nclass HEkkDualRow {\n public:\n  HEkkDualRow(HEkk& simplex) : ekk_instance_(simplex) {}\n\n  /**\n   * @brief Calls setupSlice to set up the packed indices and values for\n   * the dual ratio test\n   */\n  void setup();\n\n  /**\n   * @brief Set up the packed indices and values for the dual ratio test\n   *\n   * Done either for the whole pivotal row (see HEkkDualRow::setup), or\n   * just for a slice (see HEkkDual::initSlice)\n   */\n  void setupSlice(HighsInt size  //!< Dimension of slice\n  );\n  /**\n   * @brief Clear the packed data by zeroing packCount and workCount\n   */\n  void clear();\n\n  /**\n   * @brief Pack the indices and values for the row.\n   *\n   * Offset of numCol is used when packing row_ep\n   */\n  void chooseMakepack(const HVector* row,    //!< Row to be packed\n                      const HighsInt offset  //!< Offset for indices\n  );\n  /**\n   * @brief Determine the possible variables - candidates for CHUZC\n   *\n   * TODO: Check with Qi what this is doing\n   */\n  void choosePossible();\n\n  /**\n   * @brief Join pack of possible candidates in this row with possible\n   * candidates in otherRow\n   */\n  void chooseJoinpack(\n      const HEkkDualRow* otherRow  //!< Other row to join with this\n  );\n  /**\n   * @brief Chooses the entering variable via BFRT and EXPAND\n   *\n   * Can fail when there are excessive dual values due to EXPAND\n   * perturbation not being relatively too small, returns positive if\n   * dual unboundedness is suspected\n   */\n  HighsInt chooseFinal();\n\n  /**\n   * @brief Identifies the groups of degenerate nodes in BFRT after a\n   * heap sort of ratios\n   */\n  bool chooseFinalWorkGroupQuad();\n  bool quadChooseFinalWorkGroupQuad();\n  bool chooseFinalWorkGroupHeap();\n\n  void chooseFinalLargeAlpha(\n      HighsInt& breakIndex, HighsInt& breakGroup, HighsInt pass_workCount,\n      const std::vector<std::pair<HighsInt, double>>& pass_workData,\n      const std::vector<HighsInt>& pass_workGroup);\n\n  void reportWorkDataAndGroup(\n      const std::string message, const HighsInt reportWorkCount,\n      const std::vector<std::pair<HighsInt, double>>& reportWorkData,\n      const std::vector<HighsInt>& reportWorkGroup);\n  bool compareWorkDataAndGroup();\n\n  /**\n   * @brief Update bounds when flips have occurred, and accumulate the\n   * RHS for the FTRAN required to update the primal values after BFRT\n   */\n  void updateFlip(HVector* bfrtColumn  //!< RHS for FTRAN BFRT\n  );\n  /**\n   * @brief Update the dual values\n   */\n  void updateDual(\n      double theta  //!< Multiple of pivotal row to add HighsInt to duals\n                    //      HighsInt variable_out  //!< Index of leaving column\n  );\n  /**\n   * @brief Create a list of nonbasic free columns\n   */\n  void createFreelist();\n\n  /**\n   * @brief Set a value of nonbasicMove for all free columns to\n   * prevent their dual values from being changed\n   */\n  void createFreemove(HVector* row_ep  //!< Row of \\f$B^{-1}\\f$ to be used to\n                                       //!< compute pivotal row entry\n  );\n  /**\n   * @brief Reset the nonbasicMove values for free columns\n   */\n  void deleteFreemove();\n\n  /**\n   * @brief Delete the list of nonbasic free columns\n   */\n  void deleteFreelist(\n      HighsInt iColumn  //!< Index of column to remove from Freelist\n  );\n\n  /**\n   * @brief Compute (contribution to) the Devex weight\n   */\n  void computeDevexWeight(const HighsInt slice = -1);\n\n  HighsInt debugFindInWorkData(\n      const HighsInt iCol, const HighsInt count,\n      const std::vector<std::pair<HighsInt, double>>& workData_) const;\n  HighsInt debugChooseColumnInfeasibilities() const;\n  void debugReportBfrtVar(\n      const HighsInt ix,\n      const std::vector<std::pair<HighsInt, double>>& pass_workData) const;\n  // References:\n  HEkk& ekk_instance_;\n\n  HighsInt workSize = -1;  //!< Size of the HEkkDualRow slice: Initialise it\n                           //!< here to avoid compiler warning\n  const HighsInt* workNumTotPermutation =\n      nullptr;  //!< Pointer to ekk_instance_.numTotPermutation();\n  const int8_t* workMove =\n      nullptr;  //!< Pointer to ekk_instance_.basis_.nonbasicMove_;\n  const double* workDual =\n      nullptr;  //!< Pointer to ekk_instance_.info_.workDual_;\n  const double* workRange =\n      nullptr;  //!< Pointer to ekk_instance_.info_.workRange_;\n  const HighsInt* work_devex_index =\n      nullptr;  //!< Pointer to\n                //!< ekk_instance_.info_.devex_index_;\n\n  // Freelist:\n  std::set<HighsInt> freeList;  //!< Freelist itself\n\n  // packed data:\n  HighsInt packCount = 0;           //!< number of packed indices/values\n  std::vector<HighsInt> packIndex;  //!< Packed indices\n  std::vector<double> packValue;    //!< Packed values\n\n  // (Local) value of computed weight\n  double computed_edge_weight = 0.;\n\n  double workDelta = 0.;   //!< Local copy of dual.delta_primal\n  double workAlpha = 0.;   //!< Original copy of pivotal computed row-wise\n  double workTheta = 0.;   //!< Original copy of dual step workDual[workPivot] /\n                           //!< workAlpha;\n  HighsInt workPivot = 0;  //!< Index of the column entering the basis\n  HighsInt workCount = 0;  //!< Number of BFRT flips\n\n  std::vector<std::pair<HighsInt, double>>\n      workData;  //!< Index-Value pairs for ratio test\n  std::vector<HighsInt>\n      workGroup;  //!< Pointers into workData for degenerate nodes in BFRT\n\n  // Independent identifiers for heap-based sort in BFRT\n  HighsInt alt_workCount = 0;\n  std::vector<std::pair<HighsInt, double>> original_workData;\n  std::vector<std::pair<HighsInt, double>> sorted_workData;\n  std::vector<HighsInt> alt_workGroup;\n\n  HighsSimplexAnalysis* analysis = nullptr;\n};\n\n#endif /* SIMPLEX_HEKKDUALROW_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/simplex/HEkkPrimal.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file simplex/HEkkPrimal.h\n * @brief Phase 2 primal simplex solver for HiGHS\n */\n#ifndef SIMPLEX_HEKKPRIMAL_H_\n#define SIMPLEX_HEKKPRIMAL_H_\n\n#include <utility>\n\n#include \"simplex/HEkk.h\"\n#include \"util/HSet.h\"\n\nusing std::pair;\n\nconst SimplexAlgorithm algorithm = SimplexAlgorithm::kPrimal;\n\n/**\n * @brief Primal simplex solver for HiGHS\n */\n\nclass HEkkPrimal {\n public:\n  HEkkPrimal(HEkk& simplex) : ekk_instance_(simplex) { initialiseInstance(); }\n  /**\n   * @brief Solve a model instance\n   */\n  HighsStatus solve(const bool force_phase2 = false);\n\n private:\n  /**\n   * @brief Initialise a primal simplex instance\n   */\n  void initialiseInstance();\n  /**\n   * @brief Initialise a primal simplex solve\n   */\n  void initialiseSolve();\n  void solvePhase1();\n  void solvePhase2();\n  void cleanup();\n  void rebuild();\n\n  void iterate();\n  void chuzc();\n  void chooseColumn(const bool hyper_sparse = false);\n  bool useVariableIn();\n  void phase1ChooseRow();\n  void chooseRow();\n\n  void considerBoundSwap();\n  void assessPivot();\n\n  void update();\n\n  void updateDual();\n\n  void hyperChooseColumn();\n  void hyperChooseColumnStart();\n  void hyperChooseColumnClear();\n  void hyperChooseColumnChangedInfeasibility(const double infeasibility,\n                                             const HighsInt iCol);\n  void hyperChooseColumnBasicFeasibilityChange();\n  void hyperChooseColumnDualChange();\n\n  void phase1ComputeDual();\n  void phase1UpdatePrimal();\n  void basicFeasibilityChangeBtran();\n  void basicFeasibilityChangePrice();\n  void basicFeasibilityChangeUpdateDual();\n\n  void phase2UpdatePrimal(const bool initialise = false);\n\n  void considerInfeasibleValueIn();\n\n  void initialiseDevexFramework();\n  void updateDevex();\n  void computePrimalSteepestEdgeWeights();\n  double computePrimalSteepestEdgeWeight(const HighsInt iVar,\n                                         HVector& local_col_aq);\n  void updatePrimalSteepestEdgeWeights();\n  void updateDualSteepestEdgeWeights();\n  void updateFtranDSE(HVector& col_steepest_edge);\n  void updateBtranPSE(HVector& col_steepest_edge);\n\n  void updateVerify();\n\n  void iterationAnalysisData();\n  void iterationAnalysis();\n  void localReportIterHeader();\n  void localReportIter(const bool header = false);\n  void reportRebuild(const HighsInt reason_for_rebuild = -1);\n  void getNonbasicFreeColumnSet();\n  void removeNonbasicFreeColumn();\n  void adjustPerturbedEquationOut();\n  void getBasicPrimalInfeasibility();\n  bool correctPrimal(const bool initialise = false);\n  void shiftBound(const bool lower, const HighsInt iVar, const double value,\n                  const double random_value, double& bound, double& shift);\n  void savePrimalRay();\n  HighsDebugStatus debugPrimalSimplex(const std::string message,\n                                      const bool initialise = false);\n  HighsDebugStatus debugPrimalSteepestEdgeWeights(const std::string message);\n  HighsDebugStatus debugPrimalSteepestEdgeWeights(\n      const HighsInt alt_debug_level = -1);\n\n  bool isBadBasisChange();\n\n  // References:\n  HEkk& ekk_instance_;\n\n  // Pointers:\n  HighsSimplexAnalysis* analysis;\n\n  // Class data members\n  HighsInt num_col;\n  HighsInt num_row;\n  HighsInt num_tot;\n  HighsInt solve_phase;\n  EdgeWeightMode edge_weight_mode;\n  double primal_feasibility_tolerance;\n  double dual_feasibility_tolerance;\n  double objective_target;\n  HighsInt rebuild_reason;\n  // Pivot related\n  HighsInt variable_in;\n  HighsInt move_in;\n  HighsInt row_out;\n  HighsInt variable_out;\n  HighsInt move_out;\n  double theta_dual;\n  double theta_primal;\n  double value_in;\n  double alpha_col;\n  double alpha_row;\n  double numericalTrouble;\n\n  HighsInt num_flip_since_rebuild;\n  // Primal phase 1 tools\n  vector<pair<double, HighsInt>> ph1SorterR;\n  vector<pair<double, HighsInt>> ph1SorterT;\n  // Edge weights\n  // Edge weight\n  vector<double> edge_weight_;\n  HighsInt num_devex_iterations_;\n  HighsInt num_bad_devex_weight_;\n  vector<HighsInt> devex_index_;\n  // Nonbasic free column data.\n  HighsInt num_free_col;\n  HSet nonbasic_free_col_set;\n  // Hyper-sparse CHUZC data\n  bool use_hyper_chuzc = false;\n  bool initialise_hyper_chuzc;\n  bool done_next_chuzc;\n  const HighsInt max_num_hyper_chuzc_candidates = 50;\n  HighsInt num_hyper_chuzc_candidates;\n  vector<HighsInt> hyper_chuzc_candidate;\n  vector<double> hyper_chuzc_measure;\n  HSet hyper_chuzc_candidate_set;\n  double max_hyper_chuzc_non_candidate_measure;\n  double max_changed_measure_value;\n  HighsInt max_changed_measure_column;\n  const bool report_hyper_chuzc = false;\n  // Solve buffer\n  HVector row_ep;\n  HVector row_ap;\n  HVector col_aq;\n  HVector col_basic_feasibility_change;\n  HVector row_basic_feasibility_change;\n  HVector col_steepest_edge;\n  HighsRandom random_;  // Just for checking PSE weights\n\n  double max_max_local_primal_infeasibility_;\n  double max_max_ignored_violation_;\n  double max_max_primal_correction_;\n  HighsInt last_header_iteration_count_;\n\n  const HighsInt primal_correction_strategy =\n      kSimplexPrimalCorrectionStrategyAlways;\n  double debug_max_relative_primal_steepest_edge_weight_error = 0;\n\n  const HighsInt check_iter = 9999999;\n  const HighsInt check_column = -2133;\n};\n\n#endif /* SIMPLEX_HEKKPRIMAL_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/simplex/HSimplex.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HSimplex.h\n * @brief\n */\n#ifndef SIMPLEX_HSIMPLEX_H_\n#define SIMPLEX_HSIMPLEX_H_\n\n#include \"lp_data/HighsInfo.h\"\n#include \"lp_data/HighsLp.h\"\n\nvoid appendNonbasicColsToBasis(HighsLp& lp, HighsBasis& highs_basis,\n                               HighsInt XnumNewCol);\nvoid appendNonbasicColsToBasis(HighsLp& lp, SimplexBasis& basis,\n                               HighsInt XnumNewCol);\n\nvoid appendBasicRowsToBasis(HighsLp& lp, HighsBasis& highs_basis,\n                            HighsInt XnumNewRow);\nvoid appendBasicRowsToBasis(HighsLp& lp, SimplexBasis& basis,\n                            HighsInt XnumNewRow);\n\nvoid getUnscaledInfeasibilities(const HighsOptions& options,\n                                const HighsScale& scale,\n                                const SimplexBasis& basis,\n                                const HighsSimplexInfo& info,\n                                HighsInfo& highs_info);\n\nvoid setSolutionStatus(HighsInfo& highs_info);\n// SCALE:\n\nvoid scaleSimplexCost(const HighsOptions& options, HighsLp& lp,\n                      double& cost_scale);\nvoid unscaleSimplexCost(HighsLp& lp, double cost_scale);\n\nbool isBasisRightSize(const HighsLp& lp, const SimplexBasis& basis);\n\n#endif  // SIMPLEX_HSIMPLEX_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/simplex/HSimplexDebug.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HSimplexDebug.h\n * @brief\n */\n#ifndef SIMPLEX_HSIMPLEXDEBUG_H_\n#define SIMPLEX_HSIMPLEXDEBUG_H_\n\n#include <set>\n\n#include \"lp_data/HighsLpSolverObject.h\"\n\n// Methods for Ekk\n\nvoid debugDualChuzcFailNorms(\n    const HighsInt workCount,\n    const std::vector<std::pair<HighsInt, double>>& workData,\n    double& workDataNorm, const HighsInt numVar, const double* workDual,\n    double& workDualNorm);\n\nHighsDebugStatus debugDualChuzcFailQuad0(\n    const HighsOptions& options, const HighsInt workCount,\n    const std::vector<std::pair<HighsInt, double>>& workData,\n    const HighsInt numVar, const double* workDual, const double selectTheta,\n    const double remainTheta, const bool force = false);\n\nHighsDebugStatus debugDualChuzcFailQuad1(\n    const HighsOptions& options, const HighsInt workCount,\n    const std::vector<std::pair<HighsInt, double>>& workData,\n    const HighsInt numVar, const double* workDual, const double selectTheta,\n    const bool force = false);\n\nHighsDebugStatus debugDualChuzcFailHeap(\n    const HighsOptions& options, const HighsInt workCount,\n    const std::vector<std::pair<HighsInt, double>>& workData,\n    const HighsInt numVar, const double* workDual, const double selectTheta,\n    const bool force = false);\n\nHighsDebugStatus debugNonbasicFlagConsistent(const HighsOptions& options,\n                                             const HighsLp& lp,\n                                             const SimplexBasis& basis);\n\n#endif  // SIMPLEX_HSIMPLEXDEBUG_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/simplex/HSimplexNla.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file simplex/HSimplexNla.h\n *\n * @brief Interface to HFactor allowing non-HFactor updates, NLA-only\n * scaling and shifting of NLA analysis below simplex level.\n */\n#ifndef HSIMPLEXNLA_H_\n#define HSIMPLEXNLA_H_\n\n#include \"lp_data/HighsDebug.h\"\n#include \"simplex/HighsSimplexAnalysis.h\"\n#include \"simplex/SimplexStruct.h\"\n#include \"util/HFactor.h\"\n\nconst HighsInt kReportItemLimit = 25;\nconst double kDensityForIndexing = 0.4;\n\nstruct ProductFormUpdate {\n  bool valid_ = false;\n  HighsInt num_row_;\n  HighsInt update_count_;\n  vector<HighsInt> pivot_index_;\n  vector<double> pivot_value_;\n  vector<HighsInt> start_;\n  vector<HighsInt> index_;\n  vector<double> value_;\n  void clear();\n  void setup(const HighsInt num_row, const double expected_density);\n  HighsInt update(HVector* aq, HighsInt* iRow);\n  void btran(HVector& rhs) const;\n  void ftran(HVector& rhs) const;\n};\n\nstruct SimplexIterate {\n  bool valid_ = false;\n  SimplexBasis basis_;\n  InvertibleRepresentation invert_;\n  std::vector<double> dual_edge_weight_;\n  void clear();\n};\n\nclass HSimplexNla {\n private:\n  void setup(const HighsLp* lp, HighsInt* basic_index,\n             const HighsOptions* options, HighsTimer* timer,\n             HighsSimplexAnalysis* analysis,\n             const HighsSparseMatrix* factor_a_matrix,\n             const double factor_pivot_threshold);\n\n  void setLpAndScalePointers(const HighsLp* lp);\n  void setBasicIndexPointers(HighsInt* basic_index);\n  void setPointers(const HighsLp* for_lp,\n                   const HighsSparseMatrix* factor_a_matrix = NULL,\n                   HighsInt* basic_index = NULL,\n                   const HighsOptions* options = NULL, HighsTimer* timer = NULL,\n                   HighsSimplexAnalysis* analysis = NULL);\n  void clear();\n  HighsInt invert();\n  void btran(HVector& rhs, const double expected_density,\n             HighsTimerClock* factor_timer_clock_pointer = NULL) const;\n  void ftran(HVector& rhs, const double expected_density,\n             HighsTimerClock* factor_timer_clock_pointer = NULL) const;\n  void btranInScaledSpace(\n      HVector& rhs, const double expected_density,\n      HighsTimerClock* factor_timer_clock_pointer = NULL) const;\n  void ftranInScaledSpace(\n      HVector& rhs, const double expected_density,\n      HighsTimerClock* factor_timer_clock_pointer = NULL) const;\n  void update(HVector* aq, HVector* ep, HighsInt* iRow, HighsInt* hint);\n\n  void putInvert();\n  void getInvert();\n\n  void transformForUpdate(HVector* column, HVector* row_ep,\n                          const HighsInt variable_in, const HighsInt row_out);\n  double variableScaleFactor(const HighsInt iVar) const;\n  double basicColScaleFactor(const HighsInt iCol) const;\n  double pivotInScaledSpace(const HVector* aq, const HighsInt variable_in,\n                            const HighsInt row_out) const;\n  void setPivotThreshold(const double new_pivot_threshold);\n\n  void passLpPointer(const HighsLp* lp);\n  void passScalePointer(const HighsScale* scale);\n  void applyBasisMatrixColScale(HVector& rhs) const;\n  void applyBasisMatrixRowScale(HVector& rhs) const;\n  void unapplyBasisMatrixRowScale(HVector& rhs) const;\n  double rowEp2NormInScaledSpace(const HighsInt iRow,\n                                 const HVector& row_ep) const;\n  void addCols(const HighsLp* updated_lp);\n  void addRows(const HighsLp* updated_lp, HighsInt* basic_index,\n               const HighsSparseMatrix* scaled_ar_matrix);\n  bool sparseLoopStyle(const HighsInt count, const HighsInt dim,\n                       HighsInt& to_entry) const;\n  void reportVector(const std::string message, const HighsInt num_index,\n                    const vector<double> vector_value,\n                    const vector<HighsInt> vector_index,\n                    const bool force) const;\n  void reportArray(const std::string message, const HVector* vector,\n                   const bool force = false) const;\n  void reportArray(const std::string message, const HighsInt offset,\n                   const HVector* vector, const bool force = false) const;\n  void reportArraySparse(const std::string message, const HVector* vector,\n                         const bool force = false) const;\n  void reportArraySparse(const std::string message, const HighsInt offset,\n                         const HVector* vector, const bool force = false) const;\n  void reportPackValue(const std::string message, const HVector* vector,\n                       const bool force = false) const;\n  // Debug methods\n  HighsDebugStatus debugCheckData(const std::string message = \"\") const;\n  HighsDebugStatus debugCheckInvert(const std::string message,\n                                    const HighsInt alt_debug_level = -1) const;\n  double debugInvertResidualError(const bool transposed,\n                                  const HVector& solution,\n                                  HVector& residual) const;\n  HighsDebugStatus debugReportInvertSolutionError(const bool transposed,\n                                                  const HVector& true_solution,\n                                                  const HVector& solution,\n                                                  HVector& residual,\n                                                  const bool force) const;\n  HighsDebugStatus debugReportInvertSolutionError(\n      const std::string source, const bool transposed,\n      const double solve_error_norm, const double residual_error_norm,\n      const bool force) const;\n\n  // References:\n  //\n  // Pointers:\n\n  // Class data members\n  const HighsLp* lp_;\n  const HighsScale* scale_;\n  HighsInt* basic_index_;\n  const HighsOptions* options_;\n  HighsTimer* timer_;\n  HighsSimplexAnalysis* analysis_;\n\n  HFactor factor_;\n\n  bool report_;\n  double build_synthetic_tick_;\n\n  ProductFormUpdate update_;\n\n  // Simplex iterate data\n  SimplexIterate simplex_iterate_;\n\n  friend class HEkk;\n  friend class HEkkPrimal;\n  friend class HEkkDual;\n};\n\n#endif /* HSIMPLEXNLA_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/simplex/HSimplexReport.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/HSimplexReport.h\n * @brief\n */\n#ifndef SIMPLEX_HSIMPLEXREPORT_H_\n#define SIMPLEX_HSIMPLEXREPORT_H_\n\n#include \"lp_data/HighsOptions.h\"\n#include \"simplex/HSimplex.h\"\n\nvoid reportSimplexPhaseIterations(const HighsLogOptions& log_options,\n                                  const HighsInt iteration_count,\n                                  HighsSimplexInfo& info,\n                                  const bool initialise = false);\n#endif  // SIMPLEX_HSIMPLEXREPORT_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/simplex/HighsSimplexAnalysis.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file simplex/HighsSimplexAnalysis.h\n * @brief Analyse simplex iterations, both for run-time control and data\n * gathering\n */\n#ifndef SIMPLEX_HIGHSSIMPLEXANALYSIS_H_\n#define SIMPLEX_HIGHSSIMPLEXANALYSIS_H_\n\n#include <cassert>\n#include <memory>\n#include <sstream>\n\n#include \"lp_data/HighsLp.h\"\n#include \"lp_data/HighsOptions.h\"\n#include \"simplex/SimplexConst.h\"\n#include \"util/HFactor.h\"\n\nenum TRAN_STAGE {\n  TRAN_STAGE_FTRAN_LOWER = 0,\n  TRAN_STAGE_FTRAN_UPPER_FT,\n  TRAN_STAGE_FTRAN_UPPER,\n  TRAN_STAGE_BTRAN_UPPER,\n  TRAN_STAGE_BTRAN_UPPER_FT,\n  TRAN_STAGE_BTRAN_LOWER,\n  NUM_TRAN_STAGE_TYPE,\n};\n\nstruct TranStageAnalysis {\n  std::string name_;\n  HighsScatterData rhs_density_;\n  HighsInt num_decision_;\n  HighsInt num_wrong_original_sparse_decision_;\n  HighsInt num_wrong_original_hyper_decision_;\n  HighsInt num_wrong_new_sparse_decision_;\n  HighsInt num_wrong_new_hyper_decision_;\n};\n\nconst HighsInt kAnIterTraceMaxNumRec = 20;\nconst HighsLogType kIterationReportLogType = HighsLogType::kVerbose;\n\n/**\n * @brief Analyse simplex iterations, both for run-time control and data\n * gathering\n */\nclass HighsSimplexAnalysis {\n public:\n  HighsSimplexAnalysis()\n      : timer_(nullptr),\n        pointer_serial_factor_clocks(nullptr),\n        numRow(0),\n        numCol(0),\n        numTot(0),\n        model_name_(\"\"),\n        lp_name_(\"\"),\n        analyse_lp_data(false),\n        analyse_simplex_summary_data(false),\n        analyse_simplex_runtime_data(false),\n        analyse_simplex_time(false),\n        analyse_factor_data(false),\n        analyse_factor_time(false),\n        analyse_simplex_data(false),\n        simplex_strategy(0),\n        edge_weight_mode(EdgeWeightMode::kSteepestEdge),\n        solve_phase(0),\n        simplex_iteration_count(0),\n        devex_iteration_count(0),\n        pivotal_row_index(0),\n        leaving_variable(0),\n        entering_variable(0),\n        rebuild_reason(0),\n        rebuild_reason_string(\"\"),\n        reduced_rhs_value(0.0),\n        reduced_cost_value(0.0),\n        edge_weight(0.0),\n        edge_weight_error(0.0),\n        primal_delta(0.0),\n        primal_step(0.0),\n        dual_step(0.0),\n        pivot_value_from_column(0.0),\n        pivot_value_from_row(0.0),\n        factor_pivot_threshold(0.0),\n        numerical_trouble(0.0),\n        objective_value(0.0),\n        num_primal_infeasibility(0),\n        num_dual_infeasibility(0),\n        sum_primal_infeasibility(0.0),\n        sum_dual_infeasibility(0.0),\n        num_dual_phase_1_lp_dual_infeasibility(0),\n        max_dual_phase_1_lp_dual_infeasibility(0.0),\n        sum_dual_phase_1_lp_dual_infeasibility(0.0),\n        num_devex_framework(0),\n        col_aq_density(0.0),\n        row_ep_density(0.0),\n        row_ap_density(0.0),\n        row_DSE_density(0.0),\n        col_steepest_edge_density(0.0),\n        col_basic_feasibility_change_density(0.0),\n        row_basic_feasibility_change_density(0.0),\n        col_BFRT_density(0.0),\n        primal_col_density(0.0),\n        dual_col_density(0.0),\n        num_costly_DSE_iteration(0),\n        costly_DSE_measure(0.0),\n        multi_iteration_count(0),\n        multi_chosen(0),\n        multi_finished(0),\n        min_concurrency(0),\n        num_concurrency(0),\n        max_concurrency(0),\n        num_col_price(0),\n        num_row_price(0),\n        num_row_price_with_switch(0),\n        num_primal_cycling_detections(0),\n        num_dual_cycling_detections(0),\n        num_quad_chuzc(0),\n        num_heap_chuzc(0),\n        sum_quad_chuzc_size(0.0),\n        sum_heap_chuzc_size(0.0),\n        max_quad_chuzc_size(0),\n        max_heap_chuzc_size(0),\n        num_improve_choose_column_row_call(0),\n        num_remove_pivot_from_pack(0),\n        num_correct_dual_primal_flip(0),\n        min_correct_dual_primal_flip_dual_infeasibility(kHighsInf),\n        max_correct_dual_primal_flip(0.0),\n        num_correct_dual_cost_shift(0),\n        max_correct_dual_cost_shift_dual_infeasibility(0.0),\n        max_correct_dual_cost_shift(0.0),\n        net_num_single_cost_shift(0),\n        num_single_cost_shift(0),\n        max_single_cost_shift(0.0),\n        sum_single_cost_shift(0.0),\n        num_dual_steepest_edge_weight_check(0),\n        num_dual_steepest_edge_weight_reject(0),\n        num_wrong_low_dual_steepest_edge_weight(0),\n        num_wrong_high_dual_steepest_edge_weight(0),\n        average_frequency_low_dual_steepest_edge_weight(0.0),\n        average_frequency_high_dual_steepest_edge_weight(0.0),\n        average_log_low_dual_steepest_edge_weight_error(0.0),\n        average_log_high_dual_steepest_edge_weight_error(0.0),\n        max_average_frequency_low_dual_steepest_edge_weight(0.0),\n        max_average_frequency_high_dual_steepest_edge_weight(0.0),\n        max_sum_average_frequency_extreme_dual_steepest_edge_weight(0.0),\n        max_average_log_low_dual_steepest_edge_weight_error(0.0),\n        max_average_log_high_dual_steepest_edge_weight_error(0.0),\n        max_sum_average_log_extreme_dual_steepest_edge_weight_error(0.0),\n        num_invert_report_since_last_header(-1),\n        num_iteration_report_since_last_header(-1),\n        highs_run_time(0.0),\n        last_user_log_time(-kHighsInf),\n        delta_user_log_time(1e0),\n        timeless_log(false),\n        average_concurrency(0.0),\n        average_fraction_of_possible_minor_iterations_performed(0.0),\n        sum_multi_chosen(0),\n        sum_multi_finished(0),\n        num_invert(0),\n        num_kernel(0),\n        num_major_kernel(0),\n        max_kernel_dim(0.0),\n        sum_kernel_dim(0.0),\n        running_average_kernel_dim(0.0),\n        sum_invert_fill_factor(0.0),\n        sum_kernel_fill_factor(0.0),\n        sum_major_kernel_fill_factor(0.0),\n        running_average_invert_fill_factor(1.0),\n        running_average_kernel_fill_factor(1.0),\n        running_average_major_kernel_fill_factor(1.0),\n        AnIterIt0(0),\n        AnIterPrevIt(0),\n        AnIterOp{},\n        AnIterTraceNumRec(0),\n        AnIterTraceIterDl(0),\n        AnIterTrace{},\n        AnIterNumInvert{},\n        AnIterNumEdWtIt{} {}\n\n  // Pointer to timer\n  HighsTimer* timer_;\n\n  void setup(const std::string lp_name, const HighsLp& lp,\n             const HighsOptions& options,\n             const HighsInt simplex_iteration_count);\n  void setupSimplexTime(const HighsOptions& options);\n  void setupFactorTime(const HighsOptions& options);\n  void messaging(const HighsLogOptions& log_options_);\n  void iterationReport();\n  void invertReport();\n  void invertReport(const bool header);\n  void userInvertReport(const bool force);\n  void userInvertReport(const bool header, const bool force);\n  bool predictEndDensity(const HighsInt tran_stage_id,\n                         const double start_density, double& end_density) const;\n  void afterTranStage(const HighsInt tran_stage_id, const double start_density,\n                      const double end_density, const double historical_density,\n                      const double predicted_end_density,\n                      const bool use_solve_sparse_original_HFactor_logic,\n                      const bool use_solve_sparse_new_HFactor_logic);\n\n  void simplexTimerStart(const HighsInt simplex_clock,\n                         const HighsInt thread_id = 0);\n  void simplexTimerStop(const HighsInt simplex_clock,\n                        const HighsInt thread_id = 0);\n  bool simplexTimerRunning(const HighsInt simplex_clock,\n                           const HighsInt thread_id = 0) const;\n  HighsInt simplexTimerNumCall(const HighsInt simplex_clock,\n                               const HighsInt thread_id = 0) const;\n  double simplexTimerRead(const HighsInt simplex_clock,\n                          const HighsInt thread_id = 0) const;\n\n  HighsTimerClock* getThreadFactorTimerClockPointer();\n\n  const std::vector<HighsTimerClock>& getThreadSimplexTimerClocks() {\n    return thread_simplex_clocks;\n  }\n  HighsTimerClock* getThreadSimplexTimerClockPtr(HighsInt i) {\n    assert(i >= 0 && i < (HighsInt)thread_simplex_clocks.size());\n    return &thread_simplex_clocks[i];\n  }\n\n  const std::vector<HighsTimerClock>& getThreadFactorTimerClocks() {\n    return thread_factor_clocks;\n  }\n  HighsTimerClock* getThreadFactorTimerClockPtr(HighsInt i) {\n    assert(i >= 0 && i < (HighsInt)thread_factor_clocks.size());\n    return &thread_factor_clocks[i];\n  }\n\n  void iterationRecord();\n  void iterationRecordMajor();\n  void operationRecordBefore(const HighsInt operation_type,\n                             const HVector& vector,\n                             const double historical_density);\n  void operationRecordBefore(const HighsInt operation_type,\n                             const HighsInt current_count,\n                             const double historical_density);\n  void operationRecordAfter(const HighsInt operation_type,\n                            const HVector& vector);\n  void operationRecordAfter(const HighsInt operation_type,\n                            const HighsInt result_count);\n  void summaryReport();\n  void summaryReportFactor() const;\n  void reportSimplexTimer() const;\n  void reportFactorTimer();\n  void updateInvertFormData(const HFactor& factor);\n  void reportInvertFormData() const;\n  HighsInt numInvert() const { return num_invert; }\n\n  // Control methods to be moved to HEkkControl\n  void dualSteepestEdgeWeightError(const double computed_edge_weight,\n                                   const double updated_edge_weight);\n  //  bool switchToDevex();\n\n  std::vector<HighsTimerClock> thread_simplex_clocks;\n  std::vector<HighsTimerClock> thread_factor_clocks;\n  HighsTimerClock* pointer_serial_factor_clocks;\n\n  // Local copies of LP data\n  HighsInt numRow;\n  HighsInt numCol;\n  HighsInt numTot;\n  std::string model_name_;\n  std::string lp_name_;\n\n  // Local copies of IO data\n  HighsLogOptions log_options;\n\n  // Interpreted shortcuts from bit settings in highs_analysis_level\n  bool analyse_lp_data;\n  bool analyse_simplex_summary_data;\n  bool analyse_simplex_runtime_data;\n  bool analyse_simplex_time;\n  bool analyse_factor_data;\n  bool analyse_factor_time;\n  bool analyse_simplex_data;\n\n  // Control parameters moving to info\n  //  bool allow_dual_steepest_edge_to_devex_switch;\n  //  double dual_steepest_edge_weight_log_error_threshold;\n\n  // Local copies of simplex data for reporting\n  HighsInt simplex_strategy;\n  EdgeWeightMode edge_weight_mode;\n  HighsInt solve_phase;\n  HighsInt simplex_iteration_count;\n  HighsInt devex_iteration_count;\n  HighsInt pivotal_row_index;\n  HighsInt leaving_variable;\n  HighsInt entering_variable;\n  HighsInt rebuild_reason;\n  std::string rebuild_reason_string;\n  double reduced_rhs_value;\n  double reduced_cost_value;\n  double edge_weight;\n  double edge_weight_error;\n  double primal_delta;\n  double primal_step;\n  double dual_step;\n  double pivot_value_from_column;\n  double pivot_value_from_row;\n  double factor_pivot_threshold;\n  double numerical_trouble;\n  double objective_value;\n  HighsInt num_primal_infeasibility;\n  HighsInt num_dual_infeasibility;\n  double sum_primal_infeasibility;\n  double sum_dual_infeasibility;\n  // This triple is an original infeasibility record, so it includes max,\n  // but it's only used for reporting\n  HighsInt num_dual_phase_1_lp_dual_infeasibility;\n  double max_dual_phase_1_lp_dual_infeasibility;\n  double sum_dual_phase_1_lp_dual_infeasibility;\n  HighsInt num_devex_framework;\n  double col_aq_density;\n  double row_ep_density;\n  double row_ap_density;\n  double row_DSE_density;\n  double col_steepest_edge_density;\n  double col_basic_feasibility_change_density;\n  double row_basic_feasibility_change_density;\n  double col_BFRT_density;\n  double primal_col_density;\n  double dual_col_density;\n  HighsInt num_costly_DSE_iteration;\n  double costly_DSE_measure;\n\n  // Local copies of parallel simplex data for reporting\n  HighsInt multi_iteration_count;\n  HighsInt multi_chosen;\n  HighsInt multi_finished;\n  HighsInt min_concurrency;\n  HighsInt num_concurrency;\n  HighsInt max_concurrency;\n\n  // Unused\n  //  HighsInt multi_num = 0; // Useless\n  //  double basis_condition = 0; // Maybe useful\n\n  // Records of how pivotal row PRICE was done\n  HighsInt num_col_price;\n  HighsInt num_row_price;\n  HighsInt num_row_price_with_switch;\n\n  HighsValueDistribution before_ftran_upper_sparse_density;\n  HighsValueDistribution ftran_upper_sparse_density;\n  HighsValueDistribution before_ftran_upper_hyper_density;\n  HighsValueDistribution ftran_upper_hyper_density;\n  HighsValueDistribution cost_perturbation1_distribution;\n  HighsValueDistribution cost_perturbation2_distribution;\n  HighsValueDistribution cleanup_dual_change_distribution;\n  HighsValueDistribution cleanup_primal_step_distribution;\n  HighsValueDistribution cleanup_dual_step_distribution;\n  HighsValueDistribution cleanup_primal_change_distribution;\n\n  HighsInt num_primal_cycling_detections;\n  HighsInt num_dual_cycling_detections;\n\n  HighsInt num_quad_chuzc;\n  HighsInt num_heap_chuzc;\n  double sum_quad_chuzc_size;\n  double sum_heap_chuzc_size;\n  HighsInt max_quad_chuzc_size;\n  HighsInt max_heap_chuzc_size;\n\n  HighsInt num_improve_choose_column_row_call;\n  HighsInt num_remove_pivot_from_pack;\n\n  HighsInt num_correct_dual_primal_flip;\n  double min_correct_dual_primal_flip_dual_infeasibility;\n  double max_correct_dual_primal_flip;\n  HighsInt num_correct_dual_cost_shift;\n  double max_correct_dual_cost_shift_dual_infeasibility;\n  double max_correct_dual_cost_shift;\n  HighsInt net_num_single_cost_shift;\n  HighsInt num_single_cost_shift;\n  double max_single_cost_shift;\n  double sum_single_cost_shift;\n\n  // Tolerances for analysis of TRAN stages - could be needed for\n  // control if this is ever used again!\n  vector<double> original_start_density_tolerance;\n  vector<double> new_start_density_tolerance;\n  vector<double> historical_density_tolerance;\n  vector<double> predicted_density_tolerance;\n  vector<TranStageAnalysis> tran_stage;\n\n  std::unique_ptr<std::stringstream> analysis_log;\n\n private:\n  void iterationReport(const bool header);\n  void reportAlgorithmPhase(const bool header);\n  void reportIterationObjective(const bool header);\n  void reportInfeasibility(const bool header);\n  void reportThreads(const bool header);\n  void reportMulti(const bool header);\n  void reportOneDensity(const double density);\n  void printOneDensity(const double density) const;\n  void reportDensity(const bool header);\n  void reportInvert(const bool header);\n  //  void reportCondition(const bool header);\n  void reportIterationData(const bool header);\n  void reportRunTime(const bool header, const double run_time);\n  void reportFreeListSize(const bool header);\n  HighsInt intLog10(const double v) const;\n  bool dualAlgorithm() const;\n\n  //  double AnIterCostlyDseFq;  //!< Frequency of iterations when DSE is costly\n  //  double AnIterCostlyDseMeasure;\n\n  HighsInt num_dual_steepest_edge_weight_check;\n  HighsInt num_dual_steepest_edge_weight_reject;\n  HighsInt num_wrong_low_dual_steepest_edge_weight;\n  HighsInt num_wrong_high_dual_steepest_edge_weight;\n  double average_frequency_low_dual_steepest_edge_weight;\n  double average_frequency_high_dual_steepest_edge_weight;\n  double average_log_low_dual_steepest_edge_weight_error;\n  double average_log_high_dual_steepest_edge_weight_error;\n  double max_average_frequency_low_dual_steepest_edge_weight;\n  double max_average_frequency_high_dual_steepest_edge_weight;\n  double max_sum_average_frequency_extreme_dual_steepest_edge_weight;\n  double max_average_log_low_dual_steepest_edge_weight_error;\n  double max_average_log_high_dual_steepest_edge_weight_error;\n  double max_sum_average_log_extreme_dual_steepest_edge_weight_error;\n\n  HighsInt num_invert_report_since_last_header;\n  HighsInt num_iteration_report_since_last_header;\n  double highs_run_time;\n  double last_user_log_time;\n  double delta_user_log_time;\n  bool timeless_log;\n\n  double average_concurrency;\n  double average_fraction_of_possible_minor_iterations_performed;\n  HighsInt sum_multi_chosen;\n  HighsInt sum_multi_finished;\n\n  // Analysis of INVERT form\n  HighsInt num_invert;\n  HighsInt num_kernel;\n  HighsInt num_major_kernel;\n  double max_kernel_dim;\n  double sum_kernel_dim;\n  double running_average_kernel_dim;\n  double sum_invert_fill_factor;\n  double sum_kernel_fill_factor;\n  double sum_major_kernel_fill_factor;\n  double running_average_invert_fill_factor;\n  double running_average_kernel_fill_factor;\n  double running_average_major_kernel_fill_factor;\n\n  HighsInt AnIterIt0;\n  HighsInt AnIterPrevIt;\n\n  // Major operation analysis struct\n  struct AnIterOpRec {\n    double AnIterOpHyperCANCEL;\n    double AnIterOpHyperTRAN;\n    HighsInt AnIterOpRsDim;\n    HighsInt AnIterOpNumCa;\n    HighsInt AnIterOpNumHyperOp;\n    HighsInt AnIterOpNumHyperRs;\n    double AnIterOpSumLog10RsDensity;\n    HighsInt AnIterOpRsMxNNZ;\n    std::string AnIterOpName;\n    HighsValueDistribution AnIterOp_density;\n  };\n  AnIterOpRec AnIterOp[kNumSimplexNlaOperation];\n\n  struct AnIterTraceRec {\n    double AnIterTraceTime;\n    double AnIterTraceMulti;\n    double AnIterTraceDensity[kNumSimplexNlaOperation];\n    double AnIterTraceCostlyDse;\n    HighsInt AnIterTraceIter;\n    HighsInt AnIterTrace_simplex_strategy;\n    HighsInt AnIterTrace_edge_weight_mode;\n  };\n\n  HighsInt AnIterTraceNumRec;\n  HighsInt AnIterTraceIterDl;\n  AnIterTraceRec AnIterTrace[1 + kAnIterTraceMaxNumRec + 1];\n\n  HighsInt AnIterNumInvert[kRebuildReasonCount];\n  HighsInt AnIterNumEdWtIt[(HighsInt)EdgeWeightMode::kCount];\n\n  HighsValueDistribution primal_step_distribution;\n  HighsValueDistribution dual_step_distribution;\n  HighsValueDistribution simplex_pivot_distribution;\n  HighsValueDistribution numerical_trouble_distribution;\n  HighsValueDistribution factor_pivot_threshold_distribution;\n  HighsValueDistribution edge_weight_error_distribution;\n};\n\n#endif /* SIMPLEX_HIGHSSIMPLEXANALYSIS_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/simplex/SimplexConst.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/SimplexConst.h\n * @brief Constants for HiGHS simplex solvers\n */\n#ifndef SIMPLEX_SIMPLEXCONST_H_\n#define SIMPLEX_SIMPLEXCONST_H_\n\n#include \"util/HighsInt.h\"\n\nenum class SimplexAlgorithm { kNone = 0, kPrimal, kDual };\n\nenum SimplexStrategy {\n  kSimplexStrategyMin = 0,\n  kSimplexStrategyChoose = kSimplexStrategyMin,      // 0\n  kSimplexStrategyDual,                              // 1\n  kSimplexStrategyDualPlain = kSimplexStrategyDual,  // 1\n  kSimplexStrategyDualTasks,                         // 2\n  kSimplexStrategyDualMulti,                         // 3\n  kSimplexStrategyPrimal,                            // 4\n  kSimplexStrategyMax = kSimplexStrategyPrimal,\n  kSimplexStrategyNum\n};\n\nenum SimplexUnscaledSolutionStrategy {\n  kSimplexUnscaledSolutionStrategyMin = 0,\n  kSimplexUnscaledSolutionStrategyNone =\n      kSimplexUnscaledSolutionStrategyMin,  // 0\n  kSimplexUnscaledSolutionStrategyRefine,   // 1\n  kSimplexUnscaledSolutionStrategyDirect,   // 2\n  kSimplexUnscaledSolutionStrategyMax = kSimplexUnscaledSolutionStrategyDirect,\n  kSimplexUnscaledSolutionStrategyNum\n};\n\nenum SimplexSolvePhase {\n  kSolvePhaseMin = -3,\n  kSolvePhaseError = kSolvePhaseMin,   // -3\n  kSolvePhaseExit,                     // -2,\n  kSolvePhaseUnknown,                  // -1\n  kSolvePhaseOptimal,                  // 0\n  kSolvePhase1,                        // 1\n  kSolvePhase2,                        // 2\n  kSolvePhasePrimalInfeasibleCleanup,  // 3\n  kSolvePhaseOptimalCleanup,           // 4\n  kSolvePhaseTabooBasis,               // 5\n  kSolvePhaseMax = kSolvePhaseTabooBasis\n};\n\nenum SimplexCrashStrategy {\n  kSimplexCrashStrategyMin = 0,\n  kSimplexCrashStrategyOff = kSimplexCrashStrategyMin,\n  kSimplexCrashStrategyLtssfK,\n  kSimplexCrashStrategyLtssf = kSimplexCrashStrategyLtssfK,\n  kSimplexCrashStrategyBixby,\n  kSimplexCrashStrategyLtssfPri,\n  kSimplexCrashStrategyLtsfK,\n  kSimplexCrashStrategyLtsfPri,\n  kSimplexCrashStrategyLtsf,\n  kSimplexCrashStrategyBixbyNoNonzeroColCosts,\n  kSimplexCrashStrategyBasic,\n  kSimplexCrashStrategyTestSing,\n  kSimplexCrashStrategyMax = kSimplexCrashStrategyTestSing\n};\n\nenum SimplexEdgeWeightStrategy {\n  kSimplexEdgeWeightStrategyMin = -1,\n  kSimplexEdgeWeightStrategyChoose = kSimplexEdgeWeightStrategyMin,\n  kSimplexEdgeWeightStrategyDantzig,\n  kSimplexEdgeWeightStrategyDevex,\n  kSimplexEdgeWeightStrategySteepestEdge,\n  kSimplexEdgeWeightStrategyMax = kSimplexEdgeWeightStrategySteepestEdge\n};\n\nenum SimplexPriceStrategy {\n  kSimplexPriceStrategyMin = 0,\n  kSimplexPriceStrategyCol = kSimplexPriceStrategyMin,\n  kSimplexPriceStrategyRow,\n  kSimplexPriceStrategyRowSwitch,\n  kSimplexPriceStrategyRowSwitchColSwitch,\n  kSimplexPriceStrategyMax = kSimplexPriceStrategyRowSwitchColSwitch\n};\n\nenum SimplexPivotalRowRefinementStrategy {\n  kSimplexInfeasibilityProofRefinementMin = 0,\n  kSimplexInfeasibilityProofRefinementNo =\n      kSimplexInfeasibilityProofRefinementMin,\n  kSimplexInfeasibilityProofRefinementUnscaledLp,    // 1\n  kSimplexInfeasibilityProofRefinementAlsoScaledLp,  // 2\n  kSimplexInfeasibilityProofRefinementMax =\n      kSimplexInfeasibilityProofRefinementAlsoScaledLp\n};\n\nenum SimplexPrimalCorrectionStrategy {\n  kSimplexPrimalCorrectionStrategyNone = 0,\n  kSimplexPrimalCorrectionStrategyInRebuild,\n  kSimplexPrimalCorrectionStrategyAlways,\n  //  kSimplexPrimalCorrectionStrategyRefined\n};\n\n// Not an enum class since rebuild_reason is used in so many places\nenum RebuildReason {\n  kRebuildReasonCleanup = -1,\n  kRebuildReasonNo = 0,\n  kRebuildReasonUpdateLimitReached,               // 1\n  kRebuildReasonSyntheticClockSaysInvert,         // 2\n  kRebuildReasonPossiblyOptimal,                  // 3\n  kRebuildReasonPossiblyPhase1Feasible,           // 4\n  kRebuildReasonPossiblyPrimalUnbounded,          // 5\n  kRebuildReasonPossiblyDualUnbounded,            // 6\n  kRebuildReasonPossiblySingularBasis,            // 7\n  kRebuildReasonPrimalInfeasibleInPrimalSimplex,  // 8\n  kRebuildReasonChooseColumnFail,                 // 9\n  kRebuildReasonForceRefactor,                    // 10\n  kRebuildReasonExcessivePrimalValue,             // 11\n  kRebuildReasonCount\n};\n\nenum SimplexNlaOperation {\n  kSimplexNlaNull = -1,\n  kSimplexNlaBtranFull = 0,\n  kSimplexNlaPriceFull,\n  kSimplexNlaBtranBasicFeasibilityChange,\n  kSimplexNlaPriceBasicFeasibilityChange,\n  kSimplexNlaBtranEp,\n  kSimplexNlaPriceAp,\n  kSimplexNlaFtran,\n  kSimplexNlaFtranBfrt,\n  kSimplexNlaFtranDse,\n  kSimplexNlaBtranPse,\n  kNumSimplexNlaOperation\n};\n\nenum class EdgeWeightMode { kDantzig = 0, kDevex, kSteepestEdge, kCount };\n\nconst HighsInt kDualTasksMinConcurrency = 3;\nconst HighsInt kDualMultiMinConcurrency = 1;  // 2;\n\n// Simplex nonbasicFlag status for columns and rows. Don't use enum\n// class since they are used as HighsInt to replace conditional\n// statements by multiplication\nconst int8_t kNonbasicFlagTrue = 1;   // Nonbasic\nconst int8_t kNonbasicFlagFalse = 0;  // Basic\nconst int8_t kIllegalFlagValue =\n    -99;  // Used to see whether valid flag value has been set\n\n// Simplex nonbasicMove status for columns and rows. Don't use enum\n// class since they are used in conditional statements\nconst int8_t kNonbasicMoveUp = 1;   // Free to move (only) up\nconst int8_t kNonbasicMoveDn = -1;  // Free to move (only) down\nconst int8_t kNonbasicMoveZe = 0;   // Fixed or free to move up and down\nconst int8_t kIllegalMoveValue =\n    -99;  // Used to see whether valid move value has been set\n\n// Threshold for accepting updated DSE weight\nconst double kAcceptDseWeightThreshold = 0.25;\n\nconst double kMinDualSteepestEdgeWeight = 1e-4;\n\nconst HighsInt kNoRowSought = -2;\nconst HighsInt kNoRowChosen = -1;\n\nconst HighsInt kNoRayIndex = -1;\nconst HighsInt kNoRaySign = 0;\n\n// Switch to use code to check that, unless the basis supplied by the\n// MIP solver was alien, the simplex solver starts from dual\n// feasibility.\nconst bool kDebugMipNodeDualFeasible = false;\n\nenum class LpAction {\n  kScale = 0,\n  kNewCosts,\n  kNewBounds,\n  kNewBasis,\n  kNewCols,\n  kNewRows,\n  kDelCols,\n  kDelNonbasicCols,\n  kDelRows,\n  kDelRowsBasisOk,\n  kScaledCol,\n  kScaledRow,\n  kBacktracking\n};\n\nenum class BadBasisChangeReason {\n  kAll = 0,\n  kSingular,\n  kCycling,\n  kFailedInfeasibilityProof\n};\n\nconst HighsInt kAllowedNumBadDevexWeight = 3;\nconst double kBadDevexWeightFactor = 3;\n\n//\n// Relation between HiGHS basis and Simplex basis\n//\n// Data structures\n// ===============\n//\n// HiGHS basis consists of vectors\n//\n// * col_status[numCol]\n// * row_status[numRow]\n//\n// Simplex basis consists of vectors\n//\n// * nonbasicMove[numTot]\n// * basicIndex[numRow]\n// * nonbasicFlag[numTot]\n//\n// where nonbasicFlag is duplicate information but is used to identify\n// whether a particular variable is basic or nonbasic.\n//\n// Basic variables\n// ===============\n//\n// Highs: *_status value of BASIC\n//\n// <=>\n//\n// Simplex: nonbasicFlag value of kNonbasicFlagFalse\n//\n// Nonbasic variables\n// ==================\n//\n// Relations complicated by the fact that\n//\n// * HiGHS   rows have bounds [ l,  u]\n// * Simplex rows have bounds [-u, -l]\n//\n// Nonbasic columns\n// ================\n//\n// Highs: col_status value of LOWER - at lower bound\n// <=>\n// Simplex: nonbasicMove value of kNonbasicMoveUp - [l, Inf] column free to\n// move up and negative dual\n//\n// Highs: col_status value of ZERO - at zero\n// =>\n// Simplex: nonbasicMove value of kNonbasicMoveZe - free variable treated\n// specially in simplex\n//\n// Highs: col_status value of UPPER - at upper bound\n// =>\n// Simplex: Either\n// * nonbasicMove value of kNonbasicMoveDn - [-Inf, u] column free to move down\n// and positive dual\n// * nonbasicMove value of kNonbasicMoveZe - [   l, u] column ?? and free dual\n//\n// Simplex: nonbasicMove value of kNonbasicMoveDn - [-Inf, u] column free to\n// move down and positive dual\n// =>\n// Highs: col_status value of UPPER - at upper bound\n//\n// Simplex: nonbasicMove value of kNonbasicMoveZe - [l, u] column ?? and free\n// dual\n// =>\n// Highs: Either\n// * col_status value of UPPER - at upper bound\n// * col_status value of ZERO - at zero\n//\n// Nonbasic rows\n// =============\n//\n#endif /* SIMPLEX_SIMPLEXCONST_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/simplex/SimplexStruct.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file lp_data/SimplexStruct.h\n * @brief Structs for HiGHS simplex solvers\n */\n#ifndef SIMPLEX_SIMPLEXSTRUCT_H_\n#define SIMPLEX_SIMPLEXSTRUCT_H_\n\n#include <cstdint>\n#include <vector>\n\n// #include \"lp_data/HighsLp.h\"\n#include \"lp_data/HConst.h\"\n#include \"simplex/SimplexConst.h\"\n\nstruct SimplexBasis {\n  // The basis for the simplex method consists of basicIndex,\n  // nonbasicFlag and nonbasicMove. If HighsSimplexStatus has_basis\n  // is true then it is assumed that basicIndex_ and nonbasicFlag_ are\n  // self-consistent and correspond to the dimensions of an associated\n  // HighsLp, but the basis matrix B is not necessarily nonsingular.\n  std::vector<HighsInt> basicIndex_;\n  std::vector<int8_t> nonbasicFlag_;\n  std::vector<int8_t> nonbasicMove_;\n  //  std::vector<double> debug_dual;\n  uint64_t hash;\n  HighsInt debug_id = -1;\n  HighsInt debug_update_count = -1;\n  std::string debug_origin_name = \"\";\n  void clear();\n  void setup(const HighsInt num_col, const HighsInt num_row);\n};\n\nstruct HighsSimplexStatus {\n  // Status of LP solved by the simplex method and its data\n  bool initialised_for_new_lp = false;\n  bool is_dualized = false;\n  bool is_permuted = false;\n  bool initialised_for_solve = false;\n  bool has_basis = false;      // The simplex LP has a valid simplex basis\n  bool has_ar_matrix = false;  // HEkk has the row-wise matrix\n  bool has_nla = false;        // SimplexNla is set up\n  bool has_dual_steepest_edge_weights = false;  // The DSE weights are known\n  bool has_invert =\n      false;  // The representation of B^{-1} corresponds to the current basis\n  bool has_fresh_invert = false;  // The representation of B^{-1} corresponds to\n                                  // the current basis and is fresh\n  bool has_fresh_rebuild = false;  // The data are fresh from rebuild\n  bool has_dual_objective_value =\n      false;  // The dual objective function value is known\n  bool has_primal_objective_value =\n      false;  // The dual objective function value is known\n};\n\nstruct HighsSimplexInfo {\n  // Simplex information regarding primal solution, dual solution and\n  // objective for this Highs Model Object. This is information which\n  // should be retained from one run to the next in order to provide\n  // hot starts.\n  //\n  // Part of working model which are assigned and populated as much as\n  // possible when a model is being defined\n\n  // workCost: Originally just costs from the model but, in solve(), may\n  // be perturbed or set to alternative values in Phase I??\n  //\n  // workDual: Values of the dual variables corresponding to\n  // workCost. Latter not known until solve() is called since B^{-1}\n  // is required to compute them.\n  //\n  // workShift: Values added to workCost in order that workDual\n  // remains feasible, thereby remaining dual feasible in phase 2\n  //\n  std::vector<double> workCost_;\n  std::vector<double> workDual_;\n  std::vector<double> workShift_;\n\n  // workLower/workUpper: Originally just lower (upper) bounds from\n  // the model but, in solve(), may be perturbed or set to\n  // alternative values in Phase I??\n  //\n  // workRange: Distance between lower and upper bounds\n  //\n  // workValue: Values of the nonbasic variables corresponding to\n  // workLower/workUpper and the basis. Always known.\n  //\n  std::vector<double> workLower_;\n  std::vector<double> workUpper_;\n  std::vector<double> workRange_;\n  std::vector<double> workValue_;\n  std::vector<double> workLowerShift_;\n  std::vector<double> workUpperShift_;\n  //\n  // baseLower/baseUpper/baseValue: Lower and upper bounds on the\n  // basic variables and their values. Latter not known until solve()\n  // is called since B^{-1} is required to compute them.\n  //\n  std::vector<double> baseLower_;\n  std::vector<double> baseUpper_;\n  std::vector<double> baseValue_;\n  //\n  // Vectors of random reals for column cost perturbation, a random\n  // permutation of all indices for CHUZR and a random permutation of\n  // column indices for permuting the columns\n  std::vector<double> numTotRandomValue_;\n  std::vector<HighsInt> numTotPermutation_;\n  std::vector<HighsInt> numColPermutation_;\n\n  std::vector<HighsInt> devex_index_;\n\n  // Records of the row chosen by dual simplex or column chosen by\n  // primal simplex, plus the pivot values - since last revinversion\n  std::vector<HighsInt> index_chosen_;\n  std::vector<double> pivot_;\n\n  // Data for backtracking in the event of a singular basis\n  HighsInt phase1_backtracking_test_done = false;\n  HighsInt phase2_backtracking_test_done = false;\n  bool backtracking_ = false;\n  bool valid_backtracking_basis_ = false;\n  SimplexBasis backtracking_basis_;\n  HighsInt backtracking_basis_costs_shifted_;\n  HighsInt backtracking_basis_costs_perturbed_;\n  HighsInt backtracking_basis_bounds_perturbed_;\n  std::vector<double> backtracking_basis_workShift_;\n  std::vector<double> backtracking_basis_workLowerShift_;\n  std::vector<double> backtracking_basis_workUpperShift_;\n  std::vector<double> backtracking_basis_edge_weight_;\n\n  // Options from HighsOptions for the simplex solver\n  HighsInt simplex_strategy;\n  HighsInt dual_edge_weight_strategy;\n  HighsInt primal_edge_weight_strategy;\n  HighsInt price_strategy;\n\n  double dual_simplex_cost_perturbation_multiplier;\n  double primal_simplex_phase1_cost_perturbation_multiplier = 1;\n  double primal_simplex_bound_perturbation_multiplier;\n  double factor_pivot_threshold;\n  HighsInt update_limit;\n\n  // Simplex control parameters from HSA\n  HighsInt control_iteration_count0;\n  double col_aq_density;\n  double row_ep_density;\n  double row_ap_density;\n  double row_DSE_density;\n  double col_steepest_edge_density;\n  double col_basic_feasibility_change_density;\n  double row_basic_feasibility_change_density;\n  double col_BFRT_density;\n  double primal_col_density;\n  double dual_col_density;\n  // For control of switch from DSE to Devex in dual simplex\n  bool allow_dual_steepest_edge_to_devex_switch;\n  double dual_steepest_edge_weight_log_error_threshold;\n  double costly_DSE_frequency;\n  HighsInt num_costly_DSE_iteration;\n  double costly_DSE_measure;\n\n  double average_log_low_DSE_weight_error;\n  double average_log_high_DSE_weight_error;\n  // Needed globally??\n\n  // Internal options - can't be changed externally\n  bool run_quiet = false;\n  bool store_squared_primal_infeasibility = false;\n\n  //  bool analyse_lp_solution = true;\n  // Options for reporting timing\n  bool report_simplex_inner_clock = false;\n  bool report_simplex_outer_clock = false;\n  bool report_simplex_phases_clock = false;\n  bool report_HFactor_clock = false;\n  // Option for analysing the LP simplex iterations, INVERT time and rebuild\n  // time\n  bool analyse_lp = false;\n  bool analyse_iterations = false;\n  bool analyse_invert_form = false;\n  //  bool analyse_invert_condition = false;\n  //  bool analyse_invert_time = false;\n  //  bool analyse_rebuild_time = false;\n\n  // Simplex runtime information\n  bool allow_cost_shifting = true;\n  bool allow_cost_perturbation = true;\n  bool allow_bound_perturbation = true;\n  bool costs_shifted = false;\n  bool costs_perturbed = false;\n  bool bounds_perturbed = false;\n\n  HighsInt num_primal_infeasibilities = -1;\n  double max_primal_infeasibility;\n  double sum_primal_infeasibilities;\n  HighsInt num_dual_infeasibilities = -1;\n  double max_dual_infeasibility;\n  double sum_dual_infeasibilities;\n\n  // Records of cumulative iteration counts - updated at the end of a phase\n  HighsInt dual_phase1_iteration_count = 0;\n  HighsInt dual_phase2_iteration_count = 0;\n  HighsInt primal_phase1_iteration_count = 0;\n  HighsInt primal_phase2_iteration_count = 0;\n  HighsInt primal_bound_swap = 0;\n\n  // Starting values for use in reportSimplexPhaseIterations\n  HighsInt iteration_count0 = 0;\n  HighsInt dual_phase1_iteration_count0 = 0;\n  HighsInt dual_phase2_iteration_count0 = 0;\n  HighsInt primal_phase1_iteration_count0 = 0;\n  HighsInt primal_phase2_iteration_count0 = 0;\n  HighsInt primal_bound_swap0 = 0;\n\n  HighsInt min_concurrency = 1;\n  HighsInt num_concurrency = 1;\n  HighsInt max_concurrency = kSimplexConcurrencyLimit;\n\n  // Info on PAMI iterations\n  HighsInt multi_iteration = 0;\n\n  // Number of UPDATE operations performed - should be zeroed when INVERT is\n  // performed\n  HighsInt update_count;\n  // Value of dual objective - only set when computed from scratch in dual\n  // rebuild()\n  double dual_objective_value;\n  // Value of primal objective - only set when computed from scratch in primal\n  // rebuild()\n  double primal_objective_value;\n\n  // Value of dual objective that is updated in dual simplex solver\n  double updated_dual_objective_value;\n  // Value of primal objective that is updated in primal simplex solver\n  double updated_primal_objective_value;\n  // Number of logical variables in the basis\n  HighsInt num_basic_logicals;\n};\n\nstruct HighsSimplexBadBasisChangeRecord {\n  bool taboo;\n  HighsInt row_out;\n  HighsInt variable_out;\n  HighsInt variable_in;\n  BadBasisChangeReason reason;\n  double save_value;\n};\n\nstruct HighsRayRecord {\n  HighsInt index;\n  HighsInt sign;\n  std::vector<double> value;\n  HighsRayRecord getRayRecord() const;\n  void setRayRecord(const HighsRayRecord& from_record);\n  void clear();\n};\n#endif /* SIMPLEX_SIMPLEXSTRUCT_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/simplex/SimplexTimer.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file simplex/SimplexTimer.h\n * @brief Indices of simplex iClocks\n */\n#ifndef SIMPLEX_SIMPLEXTIMER_H_\n#define SIMPLEX_SIMPLEXTIMER_H_\n\n// Clocks for profiling the dual simplex solver\nenum iClockSimplex {\n  SimplexTotalClock = 0,     //!< Total time for simplex\n  SimplexIzDseWtClock,       //!< Total time to initialise DSE weights\n  SimplexDualPhase1Clock,    //!< Total time for dual simplex phase 1\n  SimplexDualPhase2Clock,    //!< Total time for dual simplex phase 2\n  SimplexPrimalPhase1Clock,  //!< Total time for primal simplex phase 1\n  SimplexPrimalPhase2Clock,  //!< Total time for primal simplex phase 2\n  Group1Clock,               //!< Group for SIP\n\n  IterateClock,               //!< Top level timing of HDual::solvePhase1() and\n                              //!< HDual::solvePhase2()\n  IterateDualRebuildClock,    //!< Second level timing of dual rebuild()\n  IteratePrimalRebuildClock,  //!< Second level timing of primal rebuild()\n  IterateChuzrClock,          //!< Second level timing of CHUZR\n  IterateChuzcClock,          //!< Second level timing of CHUZC\n  IterateFtranClock,          //!< Second level timing of FTRAN\n  IterateVerifyClock,         //!< Second level timing of numerical check\n  IterateDualClock,           //!< Second level timing of dual update\n  IteratePrimalClock,         //!< Second level timing of primal update\n  IterateDevexIzClock,        //!< Second level timing of initialise Devex\n  IteratePivotsClock,         //!< Second level timing of pivoting\n\n  initialiseSimplexLpBasisAndFactorClock,  //!< initialise Simplex LP, its basis\n                                           //!< and factor\n  ScaleClock,                              //!< Scale\n  CrashClock,                              //!< Crash\n  BasisConditionClock,                     //!< Basis condition estimation\n  matrixSetupClock,                        //!< HMatrix setup\n  setNonbasicMoveClock,                    //!< set nonbasicMove\n  allocateSimplexArraysClock,              //!< allocate simplex arrays\n  initialiseSimplexCostBoundsClock,  //!< initialise simplex cost and bounds\n\n  DseIzClock,        //!< DSE weight initialisation\n  InvertClock,       //!< Invert in dual rebuild()\n  PermWtClock,       //!< Permutation of SED weights each side of INVERT in dual\n                     //!< rebuild()\n  ComputeDualClock,  //!< Computation of dual values in dual rebuild()\n  CorrectDualClock,  //!< Correction of dual values in dual rebuild()\n  CollectPrIfsClock,   //!< Identification of primal infeasibilities in dual\n                       //!< rebuild()\n  ComputePrIfsClock,   //!< Computation of num/max/sum of primal infeasibilities\n  ComputeDuIfsClock,   //!< Computation of num/max/sum of dual infeasibilities\n  ComputePrimalClock,  //!< Computation of primal values in dual rebuild()\n  ComputeDuObjClock,  //!< Computation of dual objective value in dual rebuild()\n  ComputePrObjClock,  //!< Computation of primalal objective value in primal\n                      //!< rebuild()\n  ReportRebuildClock,          //!< Reporting of log line in dual rebuild()\n  ChuzrDualClock,              //!< CHUZR - Dual\n  Chuzr1Clock,                 //!< CHUZR - Primal stage 1\n  Chuzr2Clock,                 //!< CHUZR - Primal stage 2\n  ChuzcPrimalClock,            //!< CHUZC - Primal\n  ChuzcHyperInitialiselClock,  //!< CHUZC - Hyper-sparse initialisation\n  ChuzcHyperBasicFeasibilityChangeClock,  //!< CHUZC - Hyper-sparse after phase\n                                          //!< 1 basic feasibility changes\n  ChuzcHyperDualClock,  //!< CHUZC - Hyper-sparse after dual update\n  ChuzcHyperClock,      //!< CHUZC - Hyper-sparse\n  Chuzc0Clock,          //!< CHUZC - Dual stage 0\n  PriceChuzc1Clock,     //!< PRICE + CHUZC - Dual stage 1: parallel\n  Chuzc1Clock,          //!< CHUZC - Dual stage 1\n  Chuzc2Clock,          //!< CHUZC - Dual stage 2\n  Chuzc3Clock,          //!< CHUZC - Dual stage 3\n  Chuzc4Clock,          //!< CHUZC - Dual stage 4\n\n  Chuzc4a0Clock,  //!< CHUZC - Dual stage 4a0\n  Chuzc4a1Clock,  //!< CHUZC - Dual stage 4a1\n  Chuzc4bClock,   //!< CHUZC - Dual stage 4b\n  Chuzc4cClock,   //!< CHUZC - Dual stage 4c\n  Chuzc4dClock,   //!< CHUZC - Dual stage 4d\n  Chuzc4eClock,   //!< CHUZC - Dual stage 4e\n\n  Chuzc5Clock,   //!< CHUZC - Dual stage 5\n  DevexWtClock,  //!< Calculation of Devex weight of entering variable\n  BtranClock,    //!< BTRAN - row p of inverse\n  BtranBasicFeasibilityChangeClock,       //!< BTRAN - primal simplex phase 1\n  BtranFullClock,                         //!< BTRAN - full RHS\n  PriceClock,                             //!< PRICE - row p of tableau\n  PriceBasicFeasibilityChangeClock,       //!< PRICE - primal simplex phase 1\n  PriceFullClock,                         //!< PRICE - full\n  FtranClock,                             //!< FTRAN - pivotal column\n  FtranDseClock,                          //!< FTRAN for DSE weights\n  BtranPseClock,                          //!< BTRAN for PSE weights\n  FtranMixParClock,                       //!< FTRAN for PAMI - parallel\n  FtranMixFinalClock,                     //!< FTRAN for PAMI - final\n  FtranBfrtClock,                         //!< FTRAN for BFRT\n  UpdateRowClock,                         //!< Update of dual values\n  UpdateDualClock,                        //!< Update of dual values\n  UpdateDualBasicFeasibilityChangeClock,  //!< Update of dual values in primal\n                                          //!< phase 1\n  UpdatePrimalClock,                      //!< Update of primal values\n  DevexIzClock,            //!< Initialisation of new Devex framework\n  DevexUpdateWeightClock,  //!< Update Devex weights\n  DseUpdateWeightClock,    //!< Update DSE weights\n  UpdatePivotsClock,       //!< Update indices of basic and nonbasic after basis\n                           //!< change\n  UpdateFactorClock,       //!< Update the representation of \\f$B^{-1}\\f$\n  UpdateMatrixClock,  //!< Update the row-wise copy of the constraint matrix for\n                      //!< nonbasic columns\n  UpdateRowEpClock,   //!< Update the tableau rows in PAMI\n\n  SimplexNumClock  //!< Number of simplex clocks\n};\n\nclass SimplexTimer {\n public:\n  void initialiseSimplexClocks(HighsTimerClock& simplex_timer_clock) {\n    HighsTimer* timer_pointer = simplex_timer_clock.timer_pointer_;\n    std::vector<HighsInt>& clock = simplex_timer_clock.clock_;\n    clock.resize(SimplexNumClock);\n    clock[SimplexTotalClock] = timer_pointer->clock_def(\"Simplex total\");\n    clock[SimplexIzDseWtClock] = timer_pointer->clock_def(\"Iz DSE Wt\");\n    clock[SimplexDualPhase1Clock] = timer_pointer->clock_def(\"Dual Phase 1\");\n    clock[SimplexDualPhase2Clock] = timer_pointer->clock_def(\"Dual Phase 2\");\n    clock[SimplexPrimalPhase1Clock] =\n        timer_pointer->clock_def(\"Primal Phase 1\");\n    clock[SimplexPrimalPhase2Clock] =\n        timer_pointer->clock_def(\"Primal Phase 2\");\n    clock[Group1Clock] = timer_pointer->clock_def(\"GROUP1\");\n    clock[IterateClock] = timer_pointer->clock_def(\"ITERATE\");\n    clock[IterateDualRebuildClock] = timer_pointer->clock_def(\"DUAL REBUILD\");\n    clock[IteratePrimalRebuildClock] =\n        timer_pointer->clock_def(\"PRIMAL REBUILD\");\n    clock[IterateChuzrClock] = timer_pointer->clock_def(\"CHUZR\");\n    clock[IterateChuzcClock] = timer_pointer->clock_def(\"CHUZC\");\n    clock[IterateFtranClock] = timer_pointer->clock_def(\"FTRAN\");\n    clock[IterateVerifyClock] = timer_pointer->clock_def(\"VERIFY\");\n    clock[IterateDualClock] = timer_pointer->clock_def(\"DUAL\");\n    clock[IteratePrimalClock] = timer_pointer->clock_def(\"PRIMAL\");\n    clock[IterateDevexIzClock] = timer_pointer->clock_def(\"DEVEX_IZ\");\n    clock[IteratePivotsClock] = timer_pointer->clock_def(\"PIVOTS\");\n    clock[initialiseSimplexLpBasisAndFactorClock] =\n        timer_pointer->clock_def(\"IZ_SIMPLEX_LP_DEF\");\n    clock[allocateSimplexArraysClock] =\n        timer_pointer->clock_def(\"ALLOC_SIMPLEX_ARRS\");\n    clock[initialiseSimplexCostBoundsClock] =\n        timer_pointer->clock_def(\"IZ_SIMPLEX_CO_BD\");\n    clock[ScaleClock] = timer_pointer->clock_def(\"SCALE\");\n    clock[CrashClock] = timer_pointer->clock_def(\"CRASH\");\n    clock[BasisConditionClock] = timer_pointer->clock_def(\"BASIS_CONDITION\");\n    clock[matrixSetupClock] = timer_pointer->clock_def(\"MATRIX_SETUP\");\n    clock[setNonbasicMoveClock] = timer_pointer->clock_def(\"SET_NONBASICMOVE\");\n    clock[DseIzClock] = timer_pointer->clock_def(\"DSE_IZ\");\n    clock[InvertClock] = timer_pointer->clock_def(\"INVERT\");\n    clock[PermWtClock] = timer_pointer->clock_def(\"PERM_WT\");\n    clock[ComputeDualClock] = timer_pointer->clock_def(\"COMPUTE_DUAL\");\n    clock[CorrectDualClock] = timer_pointer->clock_def(\"CORRECT_DUAL\");\n    clock[ComputePrimalClock] = timer_pointer->clock_def(\"COMPUTE_PRIMAL\");\n    clock[CollectPrIfsClock] = timer_pointer->clock_def(\"COLLECT_PR_IFS\");\n    clock[ComputePrIfsClock] = timer_pointer->clock_def(\"COMPUTE_PR_IFS\");\n    clock[ComputeDuIfsClock] = timer_pointer->clock_def(\"COMPUTE_DU_IFS\");\n    clock[ComputeDuObjClock] = timer_pointer->clock_def(\"COMPUTE_DU_OBJ\");\n    clock[ComputePrObjClock] = timer_pointer->clock_def(\"COMPUTE_PR_OBJ\");\n    clock[ReportRebuildClock] = timer_pointer->clock_def(\"REPORT_REBUILD\");\n    clock[ChuzrDualClock] = timer_pointer->clock_def(\"CHUZR_DUAL\");\n    clock[Chuzr1Clock] = timer_pointer->clock_def(\"CHUZR1\");\n    clock[Chuzr2Clock] = timer_pointer->clock_def(\"CHUZR2\");\n    clock[ChuzcPrimalClock] = timer_pointer->clock_def(\"CHUZC_PRIMAL\");\n    clock[ChuzcHyperInitialiselClock] =\n        timer_pointer->clock_def(\"CHUZC_HYPER_IZ\");\n    clock[ChuzcHyperBasicFeasibilityChangeClock] =\n        timer_pointer->clock_def(\"CHUZC_HYPER_FEAS\");\n    clock[ChuzcHyperDualClock] = timer_pointer->clock_def(\"CHUZC_HYPER_DUAL\");\n    clock[ChuzcHyperClock] = timer_pointer->clock_def(\"CHUZC_HYPER\");\n    clock[Chuzc0Clock] = timer_pointer->clock_def(\"CHUZC0\");\n    clock[PriceChuzc1Clock] = timer_pointer->clock_def(\"PRICE_CHUZC1\");\n    clock[Chuzc1Clock] = timer_pointer->clock_def(\"CHUZC1\");\n    clock[Chuzc2Clock] = timer_pointer->clock_def(\"CHUZC2\");\n    clock[Chuzc3Clock] = timer_pointer->clock_def(\"CHUZC3\");\n    clock[Chuzc4Clock] = timer_pointer->clock_def(\"CHUZC4\");\n    clock[Chuzc4a0Clock] = timer_pointer->clock_def(\"CHUZC4a0\");\n    clock[Chuzc4a1Clock] = timer_pointer->clock_def(\"CHUZC4a1\");\n    clock[Chuzc4bClock] = timer_pointer->clock_def(\"CHUZC4b\");\n    clock[Chuzc4cClock] = timer_pointer->clock_def(\"CHUZC4c\");\n    clock[Chuzc4dClock] = timer_pointer->clock_def(\"CHUZC4d\");\n    clock[Chuzc4eClock] = timer_pointer->clock_def(\"CHUZC4e\");\n    clock[Chuzc5Clock] = timer_pointer->clock_def(\"CHUZC5\");\n    clock[DevexWtClock] = timer_pointer->clock_def(\"DEVEX_WT\");\n    clock[BtranClock] = timer_pointer->clock_def(\"BTRAN\");\n    clock[BtranBasicFeasibilityChangeClock] =\n        timer_pointer->clock_def(\"BTRAN_FEAS\");\n    clock[BtranFullClock] = timer_pointer->clock_def(\"BTRAN_FULL\");\n    clock[PriceClock] = timer_pointer->clock_def(\"PRICE\");\n    clock[PriceBasicFeasibilityChangeClock] =\n        timer_pointer->clock_def(\"PRICE_FEAS\");\n    clock[PriceFullClock] = timer_pointer->clock_def(\"PRICE_FULL\");\n    clock[FtranClock] = timer_pointer->clock_def(\"FTRAN\");\n    clock[FtranDseClock] = timer_pointer->clock_def(\"FTRAN_DSE\");\n    clock[BtranPseClock] = timer_pointer->clock_def(\"BTRAN_PSE\");\n    clock[FtranMixParClock] = timer_pointer->clock_def(\"FTRAN_MIX_PAR\");\n    clock[FtranMixFinalClock] = timer_pointer->clock_def(\"FTRAN_MIX_FINAL\");\n    clock[FtranBfrtClock] = timer_pointer->clock_def(\"FTRAN_BFRT\");\n    clock[UpdateRowClock] = timer_pointer->clock_def(\"UPDATE_ROW\");\n    clock[UpdateDualClock] = timer_pointer->clock_def(\"UPDATE_DUAL\");\n    clock[UpdateDualBasicFeasibilityChangeClock] =\n        timer_pointer->clock_def(\"UPDATE_DUAL_FEAS\");\n    clock[UpdatePrimalClock] = timer_pointer->clock_def(\"UPDATE_PRIMAL\");\n    clock[DevexIzClock] = timer_pointer->clock_def(\"DEVEX_IZ\");\n    clock[DevexUpdateWeightClock] =\n        timer_pointer->clock_def(\"UPDATE_DVX_WEIGHT\");\n    clock[DseUpdateWeightClock] = timer_pointer->clock_def(\"UPDATE_DSE_WEIGHT\");\n    clock[UpdatePivotsClock] = timer_pointer->clock_def(\"UPDATE_PIVOTS\");\n    clock[UpdateFactorClock] = timer_pointer->clock_def(\"UPDATE_FACTOR\");\n    clock[UpdateMatrixClock] = timer_pointer->clock_def(\"UPDATE_MATRIX\");\n    clock[UpdateRowEpClock] = timer_pointer->clock_def(\"UPDATE_ROW_EP\");\n  }\n\n  bool reportSimplexClockList(\n      const char* grepStamp, const std::vector<HighsInt> simplex_clock_list,\n      const HighsTimerClock& simplex_timer_clock,\n      const double tolerance_percent_report_ = -1) const {\n    HighsTimer* timer_pointer = simplex_timer_clock.timer_pointer_;\n    const std::vector<HighsInt>& clock = simplex_timer_clock.clock_;\n    HighsInt simplex_clock_list_size = simplex_clock_list.size();\n    std::vector<HighsInt> clockList;\n    clockList.resize(simplex_clock_list_size);\n    for (HighsInt en = 0; en < simplex_clock_list_size; en++) {\n      clockList[en] = clock[simplex_clock_list[en]];\n    }\n    const double ideal_sum_time =\n        timer_pointer->clock_time[clock[SimplexTotalClock]];\n    const double tolerance_percent_report =\n        tolerance_percent_report_ >= 0 ? tolerance_percent_report_ : 1e-8;\n    return timer_pointer->reportOnTolerance(\n        grepStamp, clockList, ideal_sum_time, tolerance_percent_report);\n  };\n\n  void reportChuzc4ClockList(const std::vector<HighsInt> simplex_clock_list,\n                             const HighsTimerClock& simplex_timer_clock) const {\n    HighsTimer* timer_pointer = simplex_timer_clock.timer_pointer_;\n    const std::vector<HighsInt>& clock = simplex_timer_clock.clock_;\n    HighsInt simplex_clock_list_size = simplex_clock_list.size();\n    std::vector<HighsInt> clockList;\n    clockList.resize(simplex_clock_list_size);\n    for (HighsInt en = 0; en < simplex_clock_list_size; en++) {\n      clockList[en] = clock[simplex_clock_list[en]];\n    }\n    const double ideal_sum_time = timer_pointer->read(clock[Chuzc4Clock]);\n    printf(\"reportChuzc4ClockList: ideal_sum_time = %g\\n\", ideal_sum_time);\n    timer_pointer->reportOnTolerance(\"CHUZC4:\", clockList, ideal_sum_time,\n                                     1e-8);\n  };\n\n  void reportSimplexTotalClock(\n      const HighsTimerClock& simplex_timer_clock) const {\n    const std::vector<HighsInt> simplex_clock_list{SimplexTotalClock};\n    reportSimplexClockList(\"SimplexTotal\", simplex_clock_list,\n                           simplex_timer_clock);\n  };\n\n  void reportSimplexPhasesClock(\n      const HighsTimerClock& simplex_timer_clock) const {\n    const std::vector<HighsInt> simplex_clock_list{\n        SimplexIzDseWtClock, SimplexDualPhase1Clock, SimplexDualPhase2Clock,\n        SimplexPrimalPhase2Clock};\n    reportSimplexClockList(\"SimplexPhases\", simplex_clock_list,\n                           simplex_timer_clock);\n  };\n\n  void reportDualSimplexIterateClock(\n      const HighsTimerClock& simplex_timer_clock) const {\n    const std::vector<HighsInt> simplex_clock_list{IterateClock};\n    reportSimplexClockList(\"SimplexIterate\", simplex_clock_list,\n                           simplex_timer_clock);\n  };\n\n  void reportDualSimplexOuterClock(\n      const HighsTimerClock& simplex_timer_clock) const {\n    const std::vector<HighsInt> simplex_clock_list{\n        IterateDualRebuildClock, IterateChuzrClock,   IterateChuzcClock,\n        IterateFtranClock,       IterateVerifyClock,  IterateDualClock,\n        IteratePrimalClock,      IterateDevexIzClock, IteratePivotsClock};\n    reportSimplexClockList(\"SimplexOuter\", simplex_clock_list,\n                           simplex_timer_clock);\n  };\n\n  bool reportSimplexInnerClock(\n      const HighsTimerClock& simplex_timer_clock,\n      const double tolerance_percent_report_ = -1) const {\n    const std::vector<HighsInt> simplex_clock_list{\n        initialiseSimplexLpBasisAndFactorClock,\n        allocateSimplexArraysClock,\n        initialiseSimplexCostBoundsClock,\n        setNonbasicMoveClock,\n        DevexIzClock,\n        DseIzClock,\n        ComputeDualClock,\n        CorrectDualClock,\n        ComputePrimalClock,\n        CollectPrIfsClock,\n        ComputePrIfsClock,\n        ComputeDuIfsClock,\n        ComputeDuObjClock,\n        ComputePrObjClock,\n        InvertClock,\n        ReportRebuildClock,\n        PermWtClock,\n        ChuzcPrimalClock,\n        ChuzcHyperInitialiselClock,\n        ChuzcHyperBasicFeasibilityChangeClock,\n        ChuzcHyperDualClock,\n        ChuzcHyperClock,\n        Chuzc0Clock,\n        Chuzc1Clock,\n        Chuzc2Clock,\n        Chuzc3Clock,\n        Chuzc4Clock,\n        Chuzc5Clock,\n        FtranClock,\n        ChuzrDualClock,\n        Chuzr1Clock,\n        Chuzr2Clock,\n        BtranClock,\n        PriceClock,\n        BtranBasicFeasibilityChangeClock,\n        PriceBasicFeasibilityChangeClock,\n        UpdateDualBasicFeasibilityChangeClock,\n        FtranBfrtClock,\n        FtranDseClock,\n        BtranPseClock,\n        BtranFullClock,\n        PriceFullClock,\n        DevexWtClock,\n        DevexUpdateWeightClock,\n        DseUpdateWeightClock,\n        UpdatePrimalClock,\n        UpdateDualClock,\n        UpdatePivotsClock,\n        UpdateFactorClock,\n        UpdateMatrixClock};\n    return reportSimplexClockList(\"SimplexInner\", simplex_clock_list,\n                                  simplex_timer_clock,\n                                  tolerance_percent_report_);\n  };\n\n  void reportSimplexChuzc4Clock(\n      const HighsTimerClock& simplex_timer_clock) const {\n    const std::vector<HighsInt> simplex_clock_list{Chuzc4a0Clock, Chuzc4a1Clock,\n                                                   Chuzc4bClock,  Chuzc4cClock,\n                                                   Chuzc4dClock,  Chuzc4eClock};\n    reportChuzc4ClockList(simplex_clock_list, simplex_timer_clock);\n  };\n\n  void reportSimplexMultiInnerClock(\n      const HighsTimerClock& simplex_timer_clock) const {\n    const std::vector<HighsInt> simplex_clock_list{\n        ScaleClock,\n        CrashClock,\n        BasisConditionClock,\n        DseIzClock,\n        InvertClock,\n        PermWtClock,\n        ComputeDualClock,\n        CorrectDualClock,\n        ComputePrimalClock,\n        CollectPrIfsClock,\n        ComputePrIfsClock,\n        ComputeDuIfsClock,\n        ComputeDuObjClock,\n        ComputePrObjClock,\n        ReportRebuildClock,\n        ChuzrDualClock,\n        Chuzr1Clock,\n        Chuzr2Clock,\n        BtranClock,\n        BtranBasicFeasibilityChangeClock,\n        BtranFullClock,\n        PriceClock,\n        PriceBasicFeasibilityChangeClock,\n        PriceFullClock,\n        ChuzcPrimalClock,\n        ChuzcHyperInitialiselClock,\n        ChuzcHyperClock,\n        Chuzc0Clock,\n        PriceChuzc1Clock,\n        Chuzc1Clock,\n        Chuzc2Clock,\n        Chuzc3Clock,\n        Chuzc4Clock,\n        Chuzc5Clock,\n        DevexWtClock,\n        FtranClock,\n        FtranBfrtClock,\n        FtranDseClock,\n        BtranPseClock,\n        FtranMixParClock,\n        FtranMixFinalClock,\n        UpdateRowClock,\n        UpdateDualClock,\n        UpdateDualBasicFeasibilityChangeClock,\n        UpdatePrimalClock,\n        DevexUpdateWeightClock,\n        DseUpdateWeightClock,\n        DevexIzClock,\n        UpdatePivotsClock,\n        UpdateFactorClock,\n        UpdateMatrixClock};\n    reportSimplexClockList(\"SimplexMultiInner\", simplex_clock_list,\n                           simplex_timer_clock);\n  };\n};\n#endif /* SIMPLEX_SIMPLEXTIMER_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/test_kkt/DevKkt.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file test_kkt/DevKkt.h\n * @brief\n */\n#ifndef TEST_KKT_DEV_KKT_H_\n#define TEST_KKT_DEV_KKT_H_\n\n#include <map>\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n\nnamespace presolve {\nnamespace dev_kkt_check {\n\nstruct State {\n  State(\n      const HighsInt numCol_, const HighsInt numRow_,\n      const std::vector<HighsInt>& Astart_, const std::vector<HighsInt>& Aend_,\n      const std::vector<HighsInt>& Aindex_, const std::vector<double>& Avalue_,\n      const std::vector<HighsInt>& ARstart_,\n      const std::vector<HighsInt>& ARindex_,\n      const std::vector<double>& ARvalue_, const std::vector<double>& colCost_,\n      const std::vector<double>& colLower_,\n      const std::vector<double>& colUpper_,\n      const std::vector<double>& rowLower_,\n      const std::vector<double>& rowUpper_,\n      const std::vector<HighsInt>& flagCol_,\n      const std::vector<HighsInt>& flagRow_,\n      const std::vector<double>& colValue_, const std::vector<double>& colDual_,\n      const std::vector<double>& rowValue_, const std::vector<double>& rowDual_,\n      const std::vector<HighsBasisStatus>& col_status_,\n      const std::vector<HighsBasisStatus>& row_status_)\n      : numCol(numCol_),\n        numRow(numRow_),\n        Astart(Astart_),\n        Aend(Aend_),\n        Aindex(Aindex_),\n        Avalue(Avalue_),\n        ARstart(ARstart_),\n        ARindex(ARindex_),\n        ARvalue(ARvalue_),\n        colCost(colCost_),\n        colLower(colLower_),\n        colUpper(colUpper_),\n        rowLower(rowLower_),\n        rowUpper(rowUpper_),\n        flagCol(flagCol_),\n        flagRow(flagRow_),\n        colValue(colValue_),\n        colDual(colDual_),\n        rowValue(rowValue_),\n        rowDual(rowDual_),\n        col_status(col_status_),\n        row_status(row_status_) {}\n\n  const HighsInt numCol;\n  const HighsInt numRow;\n\n  const std::vector<HighsInt>& Astart;\n  const std::vector<HighsInt>& Aend;\n  const std::vector<HighsInt>& Aindex;\n  const std::vector<double>& Avalue;\n\n  const std::vector<HighsInt>& ARstart;\n  const std::vector<HighsInt>& ARindex;\n  const std::vector<double>& ARvalue;\n\n  const std::vector<double>& colCost;\n  const std::vector<double>& colLower;\n  const std::vector<double>& colUpper;\n  const std::vector<double>& rowLower;\n  const std::vector<double>& rowUpper;\n\n  const std::vector<HighsInt>& flagCol;\n  const std::vector<HighsInt>& flagRow;\n\n  // solution\n  const std::vector<double>& colValue;\n  const std::vector<double>& colDual;\n  const std::vector<double>& rowValue;\n  const std::vector<double>& rowDual;\n\n  // basis\n  const std::vector<HighsBasisStatus>& col_status;\n  const std::vector<HighsBasisStatus>& row_status;\n};\n\nenum class KktCondition {\n  kColBounds,\n  kPrimalFeasibility,\n  kDualFeasibility,\n  kComplementarySlackness,\n  kStationarityOfLagrangian,\n  kBasicFeasibleSolution,\n  kUnset,\n};\n\nstruct KktConditionDetails {\n  KktConditionDetails() {}\n  KktConditionDetails(KktCondition type_) : type(type_) {}\n\n  KktCondition type = KktCondition::kUnset;\n  double max_violation = 0.0;\n  double sum_violation_2 = 0.0;\n  HighsInt checked = 0;\n  HighsInt violated = 0;\n};\n\nstruct KktInfo {\n  std::map<KktCondition, KktConditionDetails> rules;\n  bool pass_col_bounds = false;\n  bool pass_primal_feas_matrix = false;\n  bool pass_dual_feas = false;\n  bool pass_st_of_L = false;\n  bool pass_comp_slackness = false;\n  bool pass_bfs = false;\n};\n\nKktInfo initInfo();\n\nbool checkKkt(const State& state, KktInfo& info);\n\nvoid checkPrimalBounds(const State& state, KktConditionDetails& details);\nvoid checkPrimalFeasMatrix(const State& state, KktConditionDetails& details);\nvoid checkDualFeasibility(const State& state, KktConditionDetails& details);\nvoid checkComplementarySlackness(const State& state,\n                                 KktConditionDetails& details);\nvoid checkStationarityOfLagrangian(const State& state,\n                                   KktConditionDetails& details);\nvoid checkBasicFeasibleSolution(const State& state,\n                                KktConditionDetails& details);\n\n}  // namespace dev_kkt_check\n}  // namespace presolve\n\n#endif /* TEST_KKTCHSTEP_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/test_kkt/KktCh2.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file test_kkt/KktChStep.h\n * @brief\n */\n#ifndef TEST_KKTCH2_H_\n#define TEST_KKTCH2_H_\n\n#include <cmath>\n#include <fstream>\n#include <iomanip>\n#include <iostream>\n#include <stack>\n#include <string>\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n#include \"test_kkt/DevKkt.h\"\n#include \"util/HighsInt.h\"\n\nnamespace presolve {\n\nnamespace dev_kkt_check {\n\nclass KktCheck;\n\nclass KktChStep {\n public:\n  KktChStep() {}\n  virtual ~KktChStep() {}\n\n  std::vector<double> RcolCost;\n  std::vector<double> RcolLower;\n  std::vector<double> RcolUpper;\n  std::vector<double> RrowLower;\n  std::vector<double> RrowUpper;\n\n  int print = 1;\n\n  std::stack<std::vector<std::pair<HighsInt, double> > > rLowers;\n  std::stack<std::vector<std::pair<HighsInt, double> > > rUppers;\n  std::stack<std::vector<std::pair<HighsInt, double> > > cLowers;\n  std::stack<std::vector<std::pair<HighsInt, double> > > cUppers;\n  std::stack<std::vector<std::pair<HighsInt, double> > > costs;\n\n  // full matrix\n  void setBoundsCostRHS(const std::vector<double>& colUpper_,\n                        const std::vector<double>& colLower_,\n                        const std::vector<double>& cost,\n                        const std::vector<double>& rowLower_,\n                        const std::vector<double>& rowUpper_);\n  void addChange(int type, HighsInt row, HighsInt col, double valC,\n                 double dualC, double dualR);\n  void addCost(HighsInt col, double value);\n\n  dev_kkt_check::State initState(\n      const HighsInt numCol_, const HighsInt numRow_,\n      const std::vector<HighsInt>& Astart_, const std::vector<HighsInt>& Aend_,\n      const std::vector<HighsInt>& Aindex_, const std::vector<double>& Avalue_,\n      const std::vector<HighsInt>& ARstart_,\n      const std::vector<HighsInt>& ARindex_,\n      const std::vector<double>& ARvalue_,\n      const std::vector<HighsInt>& flagCol_,\n      const std::vector<HighsInt>& flagRow_,\n      const std::vector<double>& colValue_, const std::vector<double>& colDual_,\n      const std::vector<double>& rowValue_, const std::vector<double>& rowDual_,\n      const std::vector<HighsBasisStatus>& col_status_,\n      const std::vector<HighsBasisStatus>& row_status_);\n};\n\n}  // namespace dev_kkt_check\n\n}  // namespace presolve\n#endif /* TEST_KKTCHSTEP_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/FactorTimer.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/FactorTimer.h\n * @brief Indices of factor iClocks\n */\n#ifndef UTIL_FACTORTIMER_H_\n#define UTIL_FACTORTIMER_H_\n\n#include \"HConfig.h\"\n#include \"lp_data/HighsAnalysis.h\"\n#include \"util/HighsTimer.h\"\n\n// Clocks for profiling the dual simplex solver\nenum iClockFactor {\n  FactorInvert = 0,        //!< INVERT\n  FactorInvertSimple,      //!< INVERT simple\n  FactorInvertKernel,      //!< INVERT kernel\n  FactorInvertDeficient,   //!< INVERT deficient\n  FactorInvertFinish,      //!< INVERT finish\n  FactorFtran,             //!< FTRAN\n  FactorFtranLower,        //!< FTRAN Lower part\n  FactorFtranLowerAPF,     //!< FTRAN Lower part APF\n  FactorFtranLowerDse,     //!< FTRAN Lower part dense\n  FactorFtranLowerSps,     //!< FTRAN Lower part sparse\n  FactorFtranLowerHyper,   //!< FTRAN Lower part hyper-sparse\n  FactorFtranUpper,        //!< FTRAN Upper part\n  FactorFtranUpperFT,      //!< FTRAN Upper part FT\n  FactorFtranUpperMPF,     //!< FTRAN Upper part MPF\n  FactorFtranUpperDse,     //!< FTRAN Upper part dense\n  FactorFtranUpperSps0,    //!< FTRAN Upper part sparse\n  FactorFtranUpperSps1,    //!< FTRAN Upper part sparse\n  FactorFtranUpperSps2,    //!< FTRAN Upper part sparse\n  FactorFtranUpperHyper0,  //!< FTRAN Upper part hyper-sparse\n  FactorFtranUpperHyper1,  //!< FTRAN Upper part hyper-sparse\n  FactorFtranUpperHyper2,  //!< FTRAN Upper part hyper-sparse\n  FactorFtranUpperHyper3,  //!< FTRAN Upper part hyper-sparse\n  FactorFtranUpperHyper4,  //!< FTRAN Upper part hyper-sparse\n  FactorFtranUpperHyper5,  //!< FTRAN Upper part hyper-sparse\n  FactorFtranUpperPF,      //!< FTRAN Upper part PF\n  FactorBtran,             //!< BTRAN\n  FactorBtranLower,        //!< BTRAN Lower part\n  FactorBtranLowerDse,     //!< BTRAN Lower part dense\n  FactorBtranLowerSps,     //!< BTRAN Lower part sparse\n  FactorBtranLowerHyper,   //!< BTRAN Lower part hyper-sparse\n  FactorBtranLowerAPF,     //!< BTRAN Lower part APF\n  FactorBtranUpper,        //!< BTRAN Upper part\n  FactorBtranUpperPF,      //!< BTRAN Upper part PF\n  FactorBtranUpperDse,     //!< BTRAN Upper part dense\n  FactorBtranUpperSps,     //!< BTRAN Upper part sparse\n  FactorBtranUpperHyper,   //!< BTRAN Upper part hyper-sparse\n  FactorBtranUpperFT,      //!< BTRAN Upper part FT\n  FactorBtranUpperMPF,     //!< BTRAN Upper part MPF\n  FactorReinvert,          //!< INVERT using refactorization information\n  FactorNumClock           //!< Number of factor clocks\n};\n\nclass FactorTimer {\n public:\n  void start(const HighsInt factor_clock,\n             HighsTimerClock* factor_timer_clock_pointer) {\n    if (factor_timer_clock_pointer != NULL)\n      factor_timer_clock_pointer->timer_pointer_->start(\n          factor_timer_clock_pointer->clock_[factor_clock]);\n  };\n\n  void stop(const HighsInt factor_clock,\n            HighsTimerClock* factor_timer_clock_pointer) {\n    if (factor_timer_clock_pointer != NULL)\n      factor_timer_clock_pointer->timer_pointer_->stop(\n          factor_timer_clock_pointer->clock_[factor_clock]);\n  };\n\n  double read(const HighsInt factor_clock,\n              HighsTimerClock* factor_timer_clock_pointer) {\n    double argument = 0;\n    if (factor_timer_clock_pointer != NULL)\n      argument = factor_timer_clock_pointer->timer_pointer_->read(\n          factor_timer_clock_pointer->clock_[factor_clock]);\n    return argument;\n  };\n\n  void initialiseFactorClocks(HighsTimerClock& factor_timer_clock) {\n    HighsTimer* timer_pointer = factor_timer_clock.timer_pointer_;\n    std::vector<HighsInt>& clock = factor_timer_clock.clock_;\n    clock.resize(FactorNumClock);\n    clock[FactorInvert] = timer_pointer->clock_def(\"INVERT\");\n    clock[FactorInvertSimple] = timer_pointer->clock_def(\"INVERT Simple\");\n    clock[FactorInvertKernel] = timer_pointer->clock_def(\"INVERT Kernel\");\n    clock[FactorInvertDeficient] = timer_pointer->clock_def(\"INVERT Deficient\");\n    clock[FactorInvertFinish] = timer_pointer->clock_def(\"INVERT Finish\");\n    clock[FactorFtran] = timer_pointer->clock_def(\"FTRAN\");\n    clock[FactorFtranLower] = timer_pointer->clock_def(\"FTRAN Lower\");\n    clock[FactorFtranLowerAPF] = timer_pointer->clock_def(\"FTRAN Lower APF\");\n    clock[FactorFtranLowerDse] = timer_pointer->clock_def(\"FTRAN Lower Dse\");\n    clock[FactorFtranLowerSps] = timer_pointer->clock_def(\"FTRAN Lower Sps\");\n    clock[FactorFtranLowerHyper] =\n        timer_pointer->clock_def(\"FTRAN Lower Hyper\");\n    clock[FactorFtranUpper] = timer_pointer->clock_def(\"FTRAN Upper\");\n    clock[FactorFtranUpperFT] = timer_pointer->clock_def(\"FTRAN Upper FT\");\n    clock[FactorFtranUpperMPF] = timer_pointer->clock_def(\"FTRAN Upper MPF\");\n    clock[FactorFtranUpperDse] = timer_pointer->clock_def(\"FTRAN Upper Dse\");\n    clock[FactorFtranUpperSps0] = timer_pointer->clock_def(\"FTRAN Upper Sps0\");\n    clock[FactorFtranUpperSps1] = timer_pointer->clock_def(\"FTRAN Upper Sps1\");\n    clock[FactorFtranUpperSps2] = timer_pointer->clock_def(\"FTRAN Upper Sps2\");\n    clock[FactorFtranUpperHyper0] =\n        timer_pointer->clock_def(\"FTRAN Upper Hyper0\");\n    clock[FactorFtranUpperHyper1] =\n        timer_pointer->clock_def(\"FTRAN Upper Hyper1\");\n    clock[FactorFtranUpperHyper2] =\n        timer_pointer->clock_def(\"FTRAN Upper Hyper2\");\n    clock[FactorFtranUpperHyper3] =\n        timer_pointer->clock_def(\"FTRAN Upper Hyper3\");\n    clock[FactorFtranUpperHyper4] =\n        timer_pointer->clock_def(\"FTRAN Upper Hyper4\");\n    clock[FactorFtranUpperHyper5] =\n        timer_pointer->clock_def(\"FTRAN Upper Hyper5\");\n    clock[FactorFtranUpperPF] = timer_pointer->clock_def(\"FTRAN Upper PF\");\n    clock[FactorBtran] = timer_pointer->clock_def(\"BTRAN\");\n    clock[FactorBtranLower] = timer_pointer->clock_def(\"BTRAN Lower\");\n    clock[FactorBtranLowerDse] = timer_pointer->clock_def(\"BTRAN Lower Dse\");\n    clock[FactorBtranLowerSps] = timer_pointer->clock_def(\"BTRAN Lower Sps\");\n    clock[FactorBtranLowerHyper] =\n        timer_pointer->clock_def(\"BTRAN Lower Hyper\");\n    clock[FactorBtranLowerAPF] = timer_pointer->clock_def(\"BTRAN Lower APF\");\n    clock[FactorBtranUpper] = timer_pointer->clock_def(\"BTRAN Upper\");\n    clock[FactorBtranUpperPF] = timer_pointer->clock_def(\"BTRAN Upper PF\");\n    clock[FactorBtranUpperDse] = timer_pointer->clock_def(\"BTRAN Upper Dse\");\n    clock[FactorBtranUpperSps] = timer_pointer->clock_def(\"BTRAN Upper Sps\");\n    clock[FactorBtranUpperHyper] =\n        timer_pointer->clock_def(\"BTRAN Upper Hyper\");\n    clock[FactorBtranUpperFT] = timer_pointer->clock_def(\"BTRAN Upper FT\");\n    clock[FactorBtranUpperMPF] = timer_pointer->clock_def(\"BTRAN Upper MPS\");\n    clock[FactorReinvert] = timer_pointer->clock_def(\"ReINVERT\");\n  };\n\n  void reportFactorClockList(const char* grepStamp,\n                             HighsTimerClock& factor_timer_clock,\n                             std::vector<HighsInt> factor_clock_list) {\n    HighsTimer* timer_pointer = factor_timer_clock.timer_pointer_;\n    std::vector<HighsInt>& clock = factor_timer_clock.clock_;\n    HighsInt factor_clock_list_size = factor_clock_list.size();\n    std::vector<HighsInt> clockList;\n    clockList.resize(factor_clock_list_size);\n    for (HighsInt en = 0; en < factor_clock_list_size; en++) {\n      clockList[en] = clock[factor_clock_list[en]];\n    }\n    double ideal_sum_time = 0;\n    ideal_sum_time += timer_pointer->read(clock[FactorInvert]);\n    ideal_sum_time += timer_pointer->read(clock[FactorFtran]);\n    ideal_sum_time += timer_pointer->read(clock[FactorBtran]);\n    timer_pointer->reportOnTolerance(grepStamp, clockList, ideal_sum_time,\n                                     1e-8);\n  };\n\n  void reportFactorLevel0Clock(HighsTimerClock& factor_timer_clock) {\n    std::vector<HighsInt> factor_clock_list{FactorInvert, FactorReinvert,\n                                            FactorFtran, FactorBtran};\n    reportFactorClockList(\"FactorLevel0\", factor_timer_clock,\n                          factor_clock_list);\n  };\n\n  void reportFactorLevel1Clock(HighsTimerClock& factor_timer_clock) {\n    std::vector<HighsInt> factor_clock_list{\n        FactorInvertSimple, FactorInvertKernel, FactorInvertDeficient,\n        FactorInvertFinish, FactorFtranLower,   FactorFtranUpper,\n        FactorBtranLower,   FactorBtranUpper};\n    reportFactorClockList(\"FactorLevel1\", factor_timer_clock,\n                          factor_clock_list);\n  };\n\n  void reportFactorLevel2Clock(HighsTimerClock& factor_timer_clock) {\n    std::vector<HighsInt> factor_clock_list{\n        FactorInvertSimple,     FactorInvertKernel,     FactorInvertDeficient,\n        FactorInvertFinish,     FactorFtranLowerAPF,    FactorFtranLowerDse,\n        FactorFtranLowerSps,    FactorFtranLowerHyper,  FactorFtranUpperFT,\n        FactorFtranUpperMPF,    FactorFtranUpperDse,    FactorFtranUpperSps0,\n        FactorFtranUpperSps1,   FactorFtranUpperSps2,   FactorFtranUpperHyper0,\n        FactorFtranUpperHyper1, FactorFtranUpperHyper2, FactorFtranUpperHyper3,\n        FactorFtranUpperHyper4, FactorFtranUpperHyper5, FactorFtranUpperPF,\n        FactorBtranLowerDse,    FactorBtranLowerSps,    FactorBtranLowerHyper,\n        FactorBtranLowerAPF,    FactorBtranUpperPF,     FactorBtranUpperDse,\n        FactorBtranUpperSps,    FactorBtranUpperHyper,  FactorBtranUpperFT,\n        FactorBtranUpperMPF};\n    reportFactorClockList(\"FactorLevel2\", factor_timer_clock,\n                          factor_clock_list);\n  };\n\n  void reportFactorClock(HighsTimerClock& factor_timer_clock) {\n    reportFactorLevel0Clock(factor_timer_clock);\n    reportFactorLevel1Clock(factor_timer_clock);\n    reportFactorLevel2Clock(factor_timer_clock);\n  }\n};\n#endif /* UTIL_FACTORTIMER_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HFactor.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HFactor.h\n * @brief Basis matrix factorization, update and solves for HiGHS\n */\n#ifndef HFACTOR_H_\n#define HFACTOR_H_\n\n#include <algorithm>\n#include <cmath>\n#include <memory>\n#include <vector>\n\n#include \"io/HighsIO.h\"\n#include \"lp_data/HConst.h\"\n#include \"lp_data/HighsAnalysis.h\"\n#include \"util/HVector.h\"\n#include \"util/HighsSparseMatrix.h\"\n\n// Uses max and min for local in-line functions\nusing std::max;\n// using std::min;\nusing std::vector;\n\nconst HighsInt kBuildKernelReturnTimeout = -1;\n\nstruct InvertibleRepresentation {\n  // Factor L\n  std::vector<HighsInt> l_pivot_index;\n  std::vector<HighsInt> l_pivot_lookup;\n  std::vector<HighsInt> l_start;\n  std::vector<HighsInt> l_index;\n  std::vector<double> l_value;\n  std::vector<HighsInt> lr_start;\n  std::vector<HighsInt> lr_index;\n  std::vector<double> lr_value;\n\n  // Factor U\n  std::vector<HighsInt> u_pivot_lookup;\n  std::vector<HighsInt> u_pivot_index;\n  std::vector<double> u_pivot_value;\n\n  //  HighsInt u_total_x;\n  std::vector<HighsInt> u_start;\n  std::vector<HighsInt> u_last_p;\n  std::vector<HighsInt> u_index;\n  std::vector<double> u_value;\n\n  std::vector<HighsInt> ur_start;\n  std::vector<HighsInt> ur_lastp;\n  std::vector<HighsInt> ur_space;\n  std::vector<HighsInt> ur_index;\n  std::vector<double> ur_value;\n  std::vector<HighsInt> pf_start;\n  std::vector<HighsInt> pf_index;\n  std::vector<double> pf_value;\n  std::vector<HighsInt> pf_pivot_index;\n  std::vector<double> pf_pivot_value;\n  void clear();\n};\n\n/**\n * @brief Basis matrix factorization, update and solves for HiGHS\n *\n * Class for the following\n *\n * Basis matrix factorization \\f$PBQ=LU\\f$\n *\n * Update according to \\f$B'=B+(\\mathbf{a}_q-B\\mathbf{e}_p)\\mathbf{e}_p^T\\f$\n *\n * Solves \\f$B\\mathbf{x}=\\mathbf{b}\\f$ (FTRAN) and\n * \\f$B^T\\mathbf{x}=\\mathbf{b}\\f$ (BTRAN)\n *\n * HFactor is initialised using HFactor::setup, which takes copies of\n * the pointers to the constraint matrix starts, indices, values and\n * basic column indices.\n *\n * Forming \\f$PBQ=LU\\f$ (INVERT) is performed using HFactor::build\n *\n * Solving \\f$B\\mathbf{x}=\\mathbf{b}\\f$ (FTRAN) is performed using\n * HFactor::ftran\n *\n * Solving \\f$B^T\\mathbf{x}=\\mathbf{b}\\f$ (BTRAN) is performed using\n * HFactor::btran\n *\n * Updating the invertible representation of the basis matrix\n * according to \\f$B'=B+(\\mathbf{a}_q-B\\mathbf{e}_p)\\mathbf{e}_p^T\\f$\n * is performed by HFactor::update. UPDATE requires vectors\n * \\f$B^{-1}\\mathbf{a}_q\\f$ and \\f$B^{-T}\\mathbf{e}_q\\f$, together\n * with the index of the pivotal row.\n *\n * HFactor assumes that the basic column indices are kept up-to-date\n * externally as basis changes take place. INVERT permutes the basic\n * column indices, since these define the order of the solution values\n * after FTRAN, and the assumed order of the RHS before BTRAN\n *\n */\nclass HFactor {\n public:\n  HFactor()\n      : build_realTick(0.0),\n        build_synthetic_tick(0.0),\n        rank_deficiency(0),\n        basis_matrix_num_el(0),\n        invert_num_el(0),\n        kernel_dim(0),\n        kernel_num_el(0),\n        num_row(0),\n        num_col(0),\n        num_basic(0),\n        a_matrix_valid(false),\n        a_start(nullptr),\n        a_index(nullptr),\n        a_value(nullptr),\n        basic_index(nullptr),\n        pivot_threshold(0.0),\n        pivot_tolerance(0.0),\n        highs_debug_level(0),\n        time_limit_(0.0),\n        use_original_HFactor_logic(false),\n        debug_report_(false),\n        basis_matrix_limit_size(0),\n        update_method(0),\n        build_timer_(nullptr),\n        nwork(0),\n        u_merit_x(0),\n        // clang-format off\n        u_total_x(0) {};\n  // clang-format on\n\n  /**\n   * @brief Copy problem size and pointers of constraint matrix, and set\n   * up space for INVERT\n   *\n   * Copy problem size and pointers to coefficient matrix, allocate\n   * working buffer for INVERT, allocate space for basis matrix, L, U\n   * factor and Update buffer, allocated space for Markowitz matrices,\n   * count-link-list, L factor and U factor\n   */\n\n  void setup(const HighsSparseMatrix& a_matrix,\n             std::vector<HighsInt>& basic_index,\n             const double pivot_threshold = kDefaultPivotThreshold,\n             const double pivot_tolerance = kDefaultPivotTolerance,\n             const HighsInt highs_debug_level = kHighsDebugLevelMin,\n             const HighsLogOptions* log_options = NULL);\n\n  void setupGeneral(const HighsSparseMatrix* a_matrix, HighsInt num_basic,\n                    HighsInt* basic_index,\n                    const double pivot_threshold = kDefaultPivotThreshold,\n                    const double pivot_tolerance = kDefaultPivotTolerance,\n                    const HighsInt highs_debug_level = kHighsDebugLevelMin,\n                    const HighsLogOptions* log_options = NULL);\n\n  void setup(const HighsInt num_col,   //!< Number of columns\n             const HighsInt num_row,   //!< Number of rows\n             const HighsInt* a_start,  //!< Column starts of constraint matrix\n             const HighsInt* a_index,  //!< Row indices of constraint matrix\n             const double* a_value,    //!< Row values of constraint matrix\n             HighsInt* basic_index,    //!< Indices of basic variables\n             const double pivot_threshold =\n                 kDefaultPivotThreshold,  //!< Pivoting threshold\n             const double pivot_tolerance =\n                 kDefaultPivotTolerance,  //!< Min absolute pivot\n             const HighsInt highs_debug_level = kHighsDebugLevelMin,\n             const HighsLogOptions* log_options = NULL,\n             const bool use_original_HFactor_logic = true,\n             const HighsInt update_method = kUpdateMethodFt);\n\n  void setupGeneral(\n      const HighsInt num_col,    //!< Number of columns\n      const HighsInt num_row,    //!< Number of rows\n      const HighsInt num_basic,  //!< Number of indices in basic_index\n      const HighsInt* a_start,   //!< Column starts of constraint matrix\n      const HighsInt* a_index,   //!< Row indices of constraint matrix\n      const double* a_value,     //!< Row values of constraint matrix\n      HighsInt* basic_index,     //!< Indices of \"basic\" variables\n      const double pivot_threshold =\n          kDefaultPivotThreshold,  //!< Pivoting threshold\n      const double pivot_tolerance =\n          kDefaultPivotTolerance,  //!< Min absolute pivot\n      const HighsInt highs_debug_level = kHighsDebugLevelMin,\n      const HighsLogOptions* log_options = NULL,\n      const bool use_original_HFactor_logic = true,\n      const HighsInt update_method = kUpdateMethodFt);\n\n  void setupMatrix(\n      const HighsInt* a_start,  //!< Column starts of constraint matrix\n      const HighsInt* a_index,  //!< Row indices of constraint matrix\n      const double* a_value);   //!< Row values of constraint matrix\n  void setupMatrix(const HighsSparseMatrix* a_matrix);\n  /**\n   * @brief Form \\f$PBQ=LU\\f$ for basis matrix \\f$B\\f$ or report degree of rank\n   * deficiency.\n   *\n   * @return 0 if successful, otherwise rank_deficiency>0\n   *\n   */\n  HighsInt build(HighsTimerClock* factor_timer_clock_pointer = NULL);\n\n  /**\n   * @brief Solve \\f$B\\mathbf{x}=\\mathbf{b}\\f$ (FTRAN)\n   */\n  void ftranCall(\n      HVector& vector,                //!< RHS vector \\f$\\mathbf{b}\\f$\n      const double expected_density,  //!< Expected density of the result\n      HighsTimerClock* factor_timer_clock_pointer = NULL) const;\n\n  void ftranCall(std::vector<double>& vector,\n                 HighsTimerClock* factor_timer_clock_pointer = NULL);\n\n  /**\n   * @brief Solve \\f$B^T\\mathbf{x}=\\mathbf{b}\\f$ (BTRAN)\n   */\n  void btranCall(\n      HVector& vector,                //!< RHS vector \\f$\\mathbf{b}\\f$\n      const double expected_density,  //!< Expected density of the result\n      HighsTimerClock* factor_timer_clock_pointer = NULL) const;\n\n  void btranCall(std::vector<double>& vector,\n                 HighsTimerClock* factor_timer_clock_pointer = NULL);\n\n  /**\n   * @brief Update according to\n   * \\f$B'=B+(\\mathbf{a}_q-B\\mathbf{e}_p)\\mathbf{e}_p^T\\f$\n   */\n  void update(HVector* aq,     //!< Vector \\f$B^{-1}\\mathbf{a}_q\\f$\n              HVector* ep,     //!< Vector \\f$B^{-T}\\mathbf{e}_p\\f$\n              HighsInt* iRow,  //!< Index of pivotal row\n              HighsInt* hint   //!< Reinversion status\n  );\n\n  /**\n   * @brief Sets pivoting threshold\n   */\n  bool setPivotThreshold(\n      const double new_pivot_threshold = kDefaultPivotThreshold);\n\n  /**\n   * @brief Sets a time limit\n   */\n  void setTimeLimit(const double time_limit);\n\n  /**\n   * @brief Updates instance with respect to new columns in the\n   * constraint matrix (assuming columns are nonbasic)\n   */\n  void addCols(const HighsInt num_new_col);\n\n  /**\n   * @brief Updates instance with respect to nonbasic columns in the\n   * constraint matrix being deleted\n   */\n  void deleteNonbasicCols(const HighsInt num_deleted_col);\n\n  /**\n   * @brief Updates instance with respect to new rows in the\n   * constraint matrix (assuming slacks are basic)\n   */\n  void addRows(const HighsSparseMatrix* ar_matrix);\n\n  /**\n   * @brief Wall clock time for INVERT\n   */\n  double build_realTick;\n\n  /**\n   * @brief The synthetic clock for INVERT\n   */\n  double build_synthetic_tick;\n\n  // Rank deficiency information\n\n  /**\n   * @brief Degree of rank deficiency in \\f$B\\f$\n   */\n  HighsInt rank_deficiency;\n\n  /**\n   * @brief Rows not pivoted on\n   */\n  vector<HighsInt> row_with_no_pivot;\n\n  /**\n   * @brief (Basis matrix) columns not pivoted on\n   */\n  vector<HighsInt> col_with_no_pivot;\n\n  /**\n   * @brief Variables not pivoted on\n   */\n  vector<HighsInt> var_with_no_pivot;\n\n  /**\n   * @brief Gets basic_index since it is private\n   */\n  const HighsInt* getBaseIndex() const { return basic_index; }\n\n  /**\n   * @brief Gets a_start since it is private\n   */\n  const HighsInt* getAstart() const { return a_start; }\n\n  /**\n   * @brief Gets a_index since it is private\n   */\n  const HighsInt* getAindex() const { return a_index; }\n\n  /**\n   * @brief Gets a_value since it is private\n   */\n  const double* getAvalue() const { return a_value; }\n\n  void reportLu(const HighsInt l_u_or_both = kReportLuBoth,\n                const bool full = true) const;\n  void reportAsm() const;\n\n  InvertibleRepresentation getInvert() const;\n  void setInvert(const InvertibleRepresentation& invert);\n\n  void setDebugReport(const bool debug_report) {\n    this->debug_report_ = debug_report;\n  }\n\n  // Information required to perform refactorization of the current\n  // basis\n  RefactorInfo refactor_info_;\n\n  // Properties of data held in HFactor.h\n  HighsInt basis_matrix_num_el;\n  HighsInt invert_num_el;\n  HighsInt kernel_dim;\n  HighsInt kernel_num_el;\n\n  /**\n   * Data of the factor\n   */\n\n  // private:\n  // Problem size, coefficient matrix and update method\n  HighsInt num_row;\n  HighsInt num_col;\n  HighsInt num_basic;\n  double inv_num_row;  // 1.0/num_row\n\n private:\n  bool a_matrix_valid;\n  const HighsInt* a_start;\n  const HighsInt* a_index;\n  const double* a_value;\n  HighsInt* basic_index;\n  double pivot_threshold;\n  double pivot_tolerance;\n  HighsInt highs_debug_level;\n  double time_limit_;\n\n  struct LogData {\n    bool output_flag;\n    bool log_to_console;\n    HighsInt log_dev_level;\n  };\n  std::unique_ptr<LogData> log_data;\n  HighsLogOptions log_options;\n\n  bool use_original_HFactor_logic;\n  bool debug_report_;\n  HighsInt basis_matrix_limit_size;\n  HighsInt update_method;\n\n  // Internal timing\n  HighsTimer* build_timer_;\n\n  // Working buffer\n  HighsInt nwork;\n  vector<HighsInt> iwork;\n  vector<double> dwork;\n\n  // Basis matrix\n  vector<HighsInt> b_var;  // Temp\n  vector<HighsInt> b_start;\n  vector<HighsInt> b_index;\n  vector<double> b_value;\n\n  // Permutation\n  vector<HighsInt> permute;\n\n  // Kernel matrix\n  vector<HighsInt> mc_var;  // Temp\n  vector<HighsInt> mc_start;\n  vector<HighsInt> mc_count_a;\n  vector<HighsInt> mc_count_n;\n  vector<HighsInt> mc_space;\n  vector<HighsInt> mc_index;\n  vector<double> mc_value;\n  vector<double> mc_min_pivot;\n\n  // Row wise kernel matrix\n  vector<HighsInt> mr_start;\n  vector<HighsInt> mr_count;\n  vector<HighsInt> mr_space;\n  vector<HighsInt> mr_count_before;\n  vector<HighsInt> mr_index;\n\n  // Kernel column buffer\n  vector<HighsInt> mwz_column_index;\n  vector<char> mwz_column_mark;\n  vector<double> mwz_column_array;\n\n  // Count link list\n  vector<HighsInt> col_link_first;\n  vector<HighsInt> col_link_next;\n  vector<HighsInt> col_link_last;\n\n  vector<HighsInt> row_link_first;\n  vector<HighsInt> row_link_next;\n  vector<HighsInt> row_link_last;\n\n  // Factor L\n  vector<HighsInt> l_pivot_lookup;\n  vector<HighsInt> l_pivot_index;\n\n  vector<HighsInt> l_start;\n  vector<HighsInt> l_index;\n  vector<double> l_value;\n  vector<HighsInt> lr_start;\n  vector<HighsInt> lr_index;\n  vector<double> lr_value;\n\n  // Factor U\n  vector<HighsInt> u_pivot_lookup;\n  vector<HighsInt> u_pivot_index;\n  vector<double> u_pivot_value;\n\n  HighsInt u_merit_x;  // Only in PF and MPF\n  HighsInt u_total_x;  // Only in PF and MPF\n  vector<HighsInt> u_start;\n  vector<HighsInt> u_last_p;\n  vector<HighsInt> u_index;\n  vector<double> u_value;\n  vector<HighsInt> ur_start;\n  vector<HighsInt> ur_lastp;\n  vector<HighsInt> ur_space;\n  vector<HighsInt> ur_index;\n  vector<double> ur_value;\n\n  // Update buffer\n  vector<double> pf_pivot_value;\n  vector<HighsInt> pf_pivot_index;\n  vector<HighsInt> pf_start;\n  vector<HighsInt> pf_index;\n  vector<double> pf_value;\n\n  HVector rhs_;\n\n  // Implementation\n  void buildSimple();\n  //    void buildKernel();\n  HighsInt buildKernel();\n  void buildHandleRankDeficiency();\n  void buildReportRankDeficiency();\n  void buildMarkSingC();\n  void buildFinish();\n  void zeroCol(const HighsInt iCol);\n  void luClear();\n  // Rebuild using refactor information\n  HighsInt rebuild(HighsTimerClock* factor_timer_clock_pointer);\n\n  // Action to take when pointers to the A matrix are no longer valid\n  void invalidAMatrixAction();\n\n  void reportIntVector(const std::string name,\n                       const vector<HighsInt> entry) const;\n  void reportDoubleVector(const std::string name,\n                          const vector<double> entry) const;\n\n  void ftranL(HVector& vector, const double expected_density,\n              HighsTimerClock* factor_timer_clock_pointer = NULL) const;\n  void btranL(HVector& vector, const double expected_density,\n              HighsTimerClock* factor_timer_clock_pointer = NULL) const;\n  void ftranU(HVector& vector, const double expected_density,\n              HighsTimerClock* factor_timer_clock_pointer = NULL) const;\n  void btranU(HVector& vector, const double expected_density,\n              HighsTimerClock* factor_timer_clock_pointer = NULL) const;\n\n  void ftranFT(HVector& vector) const;\n  void btranFT(HVector& vector) const;\n  void ftranPF(HVector& vector) const;\n  void btranPF(HVector& vector) const;\n  void ftranMPF(HVector& vector) const;\n  void btranMPF(HVector& vector) const;\n  void ftranAPF(HVector& vector) const;\n  void btranAPF(HVector& vector) const;\n\n  void updateCFT(HVector* aq, HVector* ep, HighsInt* iRow);\n  void updateFT(HVector* aq, HVector* ep, HighsInt iRow);\n  void updatePF(HVector* aq, HighsInt iRow, HighsInt* hint);\n  void updateMPF(HVector* aq, HVector* ep, HighsInt iRow, HighsInt* hint);\n  void updateAPF(HVector* aq, HVector* ep, HighsInt iRow);\n\n  /**\n   * Local in-line functions\n   */\n  void colInsert(const HighsInt iCol, const HighsInt iRow, const double value) {\n    const HighsInt iput = mc_start[iCol] + mc_count_a[iCol]++;\n    mc_index[iput] = iRow;\n    mc_value[iput] = value;\n  }\n  void colStoreN(const HighsInt iCol, const HighsInt iRow, const double value) {\n    const HighsInt iput =\n        mc_start[iCol] + mc_space[iCol] - (++mc_count_n[iCol]);\n    mc_index[iput] = iRow;\n    mc_value[iput] = value;\n  }\n  void colFixMax(const HighsInt iCol) {\n    double max_value = 0;\n    for (HighsInt k = mc_start[iCol]; k < mc_start[iCol] + mc_count_a[iCol];\n         k++)\n      max_value = max(max_value, fabs(mc_value[k]));\n    mc_min_pivot[iCol] = max_value * pivot_threshold;\n  }\n\n  double colDelete(const HighsInt iCol, const HighsInt iRow) {\n    HighsInt idel = mc_start[iCol];\n    HighsInt imov = idel + (--mc_count_a[iCol]);\n    while (mc_index[idel] != iRow) idel++;\n    double pivot_multiplier = mc_value[idel];\n    mc_index[idel] = mc_index[imov];\n    mc_value[idel] = mc_value[imov];\n    return pivot_multiplier;\n  }\n\n  void rowInsert(const HighsInt iCol, const HighsInt iRow) {\n    HighsInt iput = mr_start[iRow] + mr_count[iRow]++;\n    mr_index[iput] = iCol;\n  }\n\n  void rowDelete(const HighsInt iCol, const HighsInt iRow) {\n    HighsInt idel = mr_start[iRow];\n    HighsInt imov = idel + (--mr_count[iRow]);\n    while (mr_index[idel] != iCol) idel++;\n    mr_index[idel] = mr_index[imov];\n  }\n\n  void clinkAdd(const HighsInt index, const HighsInt count) {\n    const HighsInt mover = col_link_first[count];\n    col_link_last[index] = -2 - count;\n    col_link_next[index] = mover;\n    col_link_first[count] = index;\n    if (mover >= 0) col_link_last[mover] = index;\n  }\n\n  void clinkDel(const HighsInt index) {\n    const HighsInt xlast = col_link_last[index];\n    const HighsInt xnext = col_link_next[index];\n    if (xlast >= 0)\n      col_link_next[xlast] = xnext;\n    else\n      col_link_first[-xlast - 2] = xnext;\n    if (xnext >= 0) col_link_last[xnext] = xlast;\n  }\n\n  void rlinkAdd(const HighsInt index, const HighsInt count) {\n    const HighsInt mover = row_link_first[count];\n    row_link_last[index] = -2 - count;\n    row_link_next[index] = mover;\n    row_link_first[count] = index;\n    if (mover >= 0) row_link_last[mover] = index;\n  }\n\n  void rlinkDel(const HighsInt index) {\n    const HighsInt xlast = row_link_last[index];\n    const HighsInt xnext = row_link_next[index];\n    if (xlast >= 0)\n      row_link_next[xlast] = xnext;\n    else\n      row_link_first[-xlast - 2] = xnext;\n    if (xnext >= 0) row_link_last[xnext] = xlast;\n  }\n  friend class HSimplexNla;\n};\n\n#endif /* HFACTOR_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HFactorConst.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HFactorConst.h\n * @brief Constants for basis matrix factorization, update and solves for HiGHS\n */\n#ifndef HFACTORCONST_H_\n#define HFACTORCONST_H_\n\n#include \"util/HighsInt.h\"\n\nenum UPDATE_METHOD {\n  kUpdateMethodFt = 1,\n  kUpdateMethodPf = 2,\n  kUpdateMethodMpf = 3,\n  kUpdateMethodApf = 4\n};\n/**\n * Limits and default value of pivoting threshold\n */\nconst double kMinPivotThreshold = 8e-4;\nconst double kDefaultPivotThreshold = 0.1;\nconst double kPivotThresholdChangeFactor = 5.0;\nconst double kMaxPivotThreshold = 0.5;\n/**\n * Limits and default value of minimum absolute pivot\n */\nconst double kMinPivotTolerance = 0;\nconst double kDefaultPivotTolerance = 1e-10;\nconst double kMaxPivotTolerance = 1.0;\n/**\n * Necessary thresholds for expected density to trigger\n * hyper-sparse TRANs,\n */\nconst double kHyperFtranL = 0.15;\nconst double kHyperFtranU = 0.10;\nconst double kHyperBtranL = 0.10;\nconst double kHyperBtranU = 0.15;\n/**\n * Necessary threshold for RHS density to trigger hyper-sparse TRANs,\n */\nconst double kHyperCancel = 0.05;\n/**\n * Threshold for result density for it to be considered as\n * hyper-sparse - only for reporting\n */\nconst double kHyperResult = 0.10;\n\n/**\n * Parameters for reinversion on synthetic clock\n */\nconst double kMultiBuildSyntheticTickMu = 1.0;\nconst double kNumericalTroubleTolerance = 1e-7;\nconst double kMultiNumericalTroubleTolerance = 1e-7;\n\nconst HighsInt kSyntheticTickReinversionMinUpdateCount = 50;\nconst HighsInt kMultiSyntheticTickReinversionMinUpdateCount =\n    kSyntheticTickReinversionMinUpdateCount;\n\n// Constants defining the space available for dimension-related\n// identifiers like starts, and multipliers (of\n// basis_matrix_limit_size, the basis matrix limit size) for\n// fill-related identifiers like indices/values in Markowitz, and\n// update.\nconst HighsInt kMCExtraEntriesMultiplier = 2;\nconst HighsInt kMRExtraEntriesMultiplier = 2;\nconst HighsInt kLFactorExtraEntriesMultiplier = 3;\nconst HighsInt kUFactorExtraVectors = 1000;\nconst HighsInt kUFactorExtraEntriesMultiplier = 3;\nconst HighsInt kPFFPivotEntries = 1000;\nconst HighsInt kPFVectors = 2000;\nconst HighsInt kPFEntriesMultiplier = 4;\nconst HighsInt kNewLRRowsExtraNz = 100;\n\nenum ReportLuOption { kReportLuJustL = 1, kReportLuJustU, kReportLuBoth };\n\n#endif /* HFACTORCONST_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HFactorDebug.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HFactorDebug.h\n * @brief\n */\n#ifndef UTIL_HFACTORDEBUG_H_\n#define UTIL_HFACTORDEBUG_H_\n\n#include <vector>\n\n#include \"lp_data/HighsOptions.h\"\n\nusing std::vector;\n\nvoid debugReportRankDeficiency(\n    const HighsInt call_id, const HighsInt highs_debug_level,\n    const HighsLogOptions& log_options, const HighsInt num_row,\n    const vector<HighsInt>& permute, const vector<HighsInt>& iwork,\n    const HighsInt* basic_index, const HighsInt rank_deficiency,\n    const vector<HighsInt>& row_with_no_pivot,\n    const vector<HighsInt>& col_with_no_pivot);\n\nvoid debugReportRankDeficientASM(\n    const HighsInt highs_debug_level, const HighsLogOptions& log_options,\n    const HighsInt num_row, const vector<HighsInt>& mc_start,\n    const vector<HighsInt>& mc_count_a, const vector<HighsInt>& mc_index,\n    const vector<double>& mc_value, const vector<HighsInt>& iwork,\n    const HighsInt rank_deficiency, const vector<HighsInt>& col_with_no_pivot,\n    const vector<HighsInt>& row_with_no_pivot);\n\nvoid debugReportMarkSingC(const HighsInt call_id,\n                          const HighsInt highs_debug_level,\n                          const HighsLogOptions& log_options,\n                          const HighsInt num_row, const vector<HighsInt>& iwork,\n                          const HighsInt* basic_index);\n\nvoid debugLogRankDeficiency(const HighsInt highs_debug_level,\n                            const HighsLogOptions& log_options,\n                            const HighsInt rank_deficiency,\n                            const HighsInt basis_matrix_num_el,\n                            const HighsInt invert_num_el,\n                            const HighsInt& kernel_dim,\n                            const HighsInt kernel_num_el, const HighsInt nwork);\n\nvoid debugPivotValueAnalysis(const HighsInt highs_debug_level,\n                             const HighsLogOptions& log_options,\n                             const HighsInt num_row,\n                             const vector<double>& u_pivot_value);\n\n#endif  // UTIL_HFACTORDEBUG_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HSet.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HSet.h\n * @brief Set structure for HiGHS.\n */\n\n// Maintains an unordered set of distinct non-negative integer entries,\n// allowing entries to be removed from the set at cost O(1)\n#ifndef UTIL_HSET_H_\n#define UTIL_HSET_H_\n\n#include <cstdio>\n#include <vector>\n\n#include \"util/HighsInt.h\"\n\n// #include <iostream>\n\nusing std::vector;\n\nconst HighsInt min_entry = 0;\nconst HighsInt no_pointer = min_entry - 1;\n/**\n * @brief Class for the set structure for HiGHS\n */\nclass HSet {\n public:\n  /**\n   * @brief Initialise a set. Neither limit is binding, but more\n   * efficient memory-wise if known in advance\n   */\n  bool setup(const HighsInt size,  //!< Dimension of the set to be initialised\n             const HighsInt max_entry,  //!< Maximum entry to be in the set.\n             const bool output_flag = false,  //!< Option for output\n             FILE* log_stream = NULL,         //!< File stream for output\n             const bool debug = false,        //!< Debug mode\n             const bool allow_assert = true   //!< Allow asserts in debug\n  );\n\n  /**\n   * @brief Clear the set\n   */\n  void clear();\n  /**\n   * @brief Add entry to the set\n   */\n  bool add(const HighsInt entry);\n  /**\n   * @brief Remove entry from the set\n   */\n  bool remove(const HighsInt entry);\n  /**\n   * @brief Returns whether entry is in the set\n   */\n  bool in(const HighsInt entry) const;\n  /**\n   * @brief Returns the number of entries in the set\n   */\n  const HighsInt& count() const { return count_; }\n  /**\n   * @brief Returns the entries in the set\n   */\n  const vector<HighsInt>& entry() const { return entry_; }\n  /**\n   * @brief Print out the set and pointer entries not set to no_pointer\n   */\n  void print() const;\n  /**\n   * @brief Debug the set\n   */\n  bool debug() const;\n\n private:\n  HighsInt count_ = 0;      //!< Number of entries\n  vector<HighsInt> entry_;  //!< Entries\n  bool setup_ = false;\n  bool debug_ = false;\n  bool allow_assert_ = true;\n  bool output_flag_ = false;\n  FILE* log_file_;\n  HighsInt max_entry_;        //!< Maximum entry to be in the set.\n  vector<HighsInt> pointer_;  //!< Set of pointers into the set\n};\n#endif /* UTIL_HSET_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HVector.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HVector.h\n * @brief Vector structure for HiGHS\n */\n#ifndef UTIL_HVECTOR_H_\n#define UTIL_HVECTOR_H_\n\n#include \"util/HVectorBase.h\"\n#include \"util/HighsCDouble.h\"\n\nusing HVector = HVectorBase<double>;\nusing HVectorQuad = HVectorBase<HighsCDouble>;\nusing HVector_ptr = HVector*;\nusing HVectorQuad_ptr = HVectorQuad*;\n\n#endif /* UTIL_HVECTOR_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HVectorBase.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HVector.h\n * @brief Vector structure for HiGHS\n */\n#ifndef UTIL_HVECTOR_BASE_H_\n#define UTIL_HVECTOR_BASE_H_\n\n#include <vector>\n\n#include \"util/HighsInt.h\"\n\n// using std::map;\nusing std::vector;\n\n/**\n * @brief Class for the vector structure for HiGHS\n */\ntemplate <typename Real>\nclass HVectorBase {\n public:\n  /**\n   * @brief Initialise a vector\n   */\n  void setup(HighsInt size_  //!< Dimension of the vector to be initialised\n  );\n\n  /**\n   * @brief Clear the vector - or just its scalars\n   *\n   */\n  void clear();\n  void clearScalars();\n\n  HighsInt size;           //!< Dimension of the vector\n  HighsInt count;          //!< Number of nonzeros\n  vector<HighsInt> index;  //!< Packed indices of nonzeros\n  vector<Real> array;      //!< Full-length array of values\n\n  double synthetic_tick;  //!< Synthetic clock for operations with this vector\n\n  // For update\n  vector<char> cwork;       //!< char working buffer for UPDATE\n  vector<HighsInt> iwork;   //!< integer working buffer for UPDATE\n  HVectorBase<Real>* next;  //!< Allows vectors to be linked for PAMI\n\n  /*\n   * Zero values in Vector.array that exceed kHighsTiny in magnitude\n   */\n  void tight();\n\n  /**\n   * @brief Packing (if packFlag set): Pack values/indices in Vector.array into\n   * packValue/Index\n   *\n   */\n  void pack();\n\n  /**\n   * @brief Possibly determine the indices from scratch by passing\n   * through the array\n   *\n   */\n  void reIndex();\n\n  bool packFlag;               //!< Flag to indicate whether to pack or not\n  HighsInt packCount;          //!< Number of nonzeros packed\n  vector<HighsInt> packIndex;  //!< Packed indices\n  vector<Real> packValue;      //!< Packed values\n\n  /**\n   * @brief Copy from another HVector structure to this instance\n   */\n  template <typename FromReal>\n  void copy(const HVectorBase<FromReal>*\n                from  //!< Source of HVector structure to be copied\n  );\n\n  /**\n   * @brief Compute the squared 2-norm of the vector\n   */\n  Real norm2() const;\n\n  /**\n   * @brief Add a multiple pivotX of *pivot into this vector,\n   * maintaining indices of nonzeros but not tracking cancellation\n   */\n  template <typename RealPivX, typename RealPiv>\n  void saxpy(const RealPivX pivotX,  //!< The multiple of *pivot to be added\n             const HVectorBase<RealPiv>*\n                 pivot  //!< The vector whose multiple is to be added\n  );\n\n  bool isEqual(const HVectorBase<Real>& v0);\n};\n\n#endif /* UTIL_HVECTOR_BASE_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsCDouble.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/**@file util/HighsCDouble.h\n * @brief Quad precision type implemented with two standard double precision\n *        representing the value and a compensation term\n */\n#ifndef UTIL_HIGHSCDOUBLE_H_\n#define UTIL_HIGHSCDOUBLE_H_\n\n#include <cmath>\n#include <cstdint>\n\n/// A compensated double number achieving roughly quad precision on the\n/// supported operations\n\nclass HighsCDouble {\n private:\n  double hi;\n  double lo;\n\n  // The following functions are implemented as described in:\n  // Rump, Siegfried M. \"High precision evaluation of nonlinear functions.\"\n  // Proceedings of. 2005.\n\n  /// performs an exact transformation such that x + y = a + b\n  /// and x = double(a + b). The operation uses 6 flops (addition/subtraction).\n  static void two_sum(double& x, double& y, double a, double b) {\n    x = a + b;\n    double z = x - a;\n    y = (a - (x - z)) + (b - z);\n  }\n\n  /// splits a 53 bit double precision number into two 26 bit parts\n  /// such that x + y = a holds exactly\n  static void split(double& x, double& y, double a) {\n    constexpr double factor = double((1 << 27) + 1);\n    double c = factor * a;\n    x = c - (c - a);\n    y = a - x;\n  }\n\n  /// performs an exact transformation such that x + y = a * b\n  /// and x = double(a * b). The operation uses 10 flops for\n  /// addition/subtraction and 7 flops for multiplication.\n  static void two_product(double& x, double& y, double a, double b) {\n    x = a * b;\n    double a1, a2, b1, b2;\n    split(a1, a2, a);\n    split(b1, b2, b);\n    y = a2 * b2 - (((x - a1 * b1) - a2 * b1) - a1 * b2);\n  }\n\n  HighsCDouble(double hi_, double lo_) : hi(hi_), lo(lo_) {}\n\n public:\n  HighsCDouble() = default;\n\n  HighsCDouble(double val) : hi(val), lo(0.0) {}\n\n  explicit operator double() const { return hi + lo; }\n\n  HighsCDouble& operator+=(double v) {\n    double c;\n    two_sum(hi, c, v, hi);\n    lo += c;\n    return *this;\n  }\n\n  HighsCDouble& operator+=(const HighsCDouble& v) {\n    (*this) += v.hi;\n    lo += v.lo;\n    return *this;\n  }\n\n  HighsCDouble& operator-=(double v) {\n    (*this) += -v;\n    return *this;\n  }\n\n  HighsCDouble& operator-=(const HighsCDouble& v) {\n    (*this) -= v.hi;\n    lo -= v.lo;\n    return *this;\n  }\n\n  HighsCDouble& operator*=(double v) {\n    double c = lo * v;\n    two_product(hi, lo, hi, v);\n    *this += c;\n    return *this;\n  }\n\n  HighsCDouble& operator*=(const HighsCDouble& v) {\n    double c1 = hi * v.lo;\n    double c2 = lo * v.hi;\n    two_product(hi, lo, hi, v.hi);\n    *this += c1;\n    *this += c2;\n    return *this;\n  }\n\n  HighsCDouble& operator/=(double v) {\n    HighsCDouble d(hi / v, lo / v);\n    HighsCDouble c = d * v - (*this);\n    c.hi /= v;\n    c.lo /= v;\n    *this = d - c;\n    return *this;\n  }\n\n  HighsCDouble& operator/=(const HighsCDouble& v) {\n    double vdbl = v.hi + v.lo;\n    HighsCDouble d(hi / vdbl, lo / vdbl);\n    HighsCDouble c = d * v - (*this);\n    c.hi /= vdbl;\n    c.lo /= vdbl;\n    *this = d - c;\n    return *this;\n  }\n\n  HighsCDouble operator-() const { return HighsCDouble(-hi, -lo); }\n\n  HighsCDouble operator+(double v) const {\n    HighsCDouble res;\n\n    two_sum(res.hi, res.lo, hi, v);\n    res.lo += lo;\n\n    return res;\n  }\n\n  HighsCDouble operator+(const HighsCDouble& v) const {\n    HighsCDouble res = (*this) + v.hi;\n    res.lo += v.lo;\n\n    return res;\n  }\n\n  friend HighsCDouble operator+(double a, const HighsCDouble& b) {\n    return b + a;\n  }\n\n  HighsCDouble operator-(double v) const {\n    HighsCDouble res;\n\n    two_sum(res.hi, res.lo, hi, -v);\n    res.lo += lo;\n\n    return res;\n  }\n\n  HighsCDouble operator-(const HighsCDouble& v) const {\n    HighsCDouble res = (*this) - v.hi;\n    res.lo -= v.lo;\n\n    return res;\n  }\n\n  friend HighsCDouble operator-(double a, const HighsCDouble& b) {\n    return -b + a;\n  }\n\n  HighsCDouble operator*(double v) const {\n    HighsCDouble res;\n\n    two_product(res.hi, res.lo, hi, v);\n    res += lo * v;\n\n    return res;\n  }\n\n  HighsCDouble operator*(const HighsCDouble& v) const {\n    HighsCDouble res = (*this) * v.hi;\n    res += hi * v.lo;\n\n    return res;\n  }\n\n  friend HighsCDouble operator*(double a, const HighsCDouble& b) {\n    return b * a;\n  }\n\n  HighsCDouble operator/(double v) const {\n    HighsCDouble res = *this;\n\n    res /= v;\n\n    return res;\n  }\n\n  HighsCDouble operator/(const HighsCDouble& v) const {\n    HighsCDouble res = (*this);\n\n    res /= v;\n\n    return res;\n  }\n\n  friend HighsCDouble operator/(double a, const HighsCDouble& b) {\n    return HighsCDouble(a) / b;\n  }\n\n  bool operator>(const HighsCDouble& other) const {\n    return double(*this) > double(other);\n  }\n\n  bool operator>(double other) const { return double(*this) > other; }\n\n  friend bool operator>(double a, const HighsCDouble& b) {\n    return a > double(b);\n  }\n\n  bool operator<(const HighsCDouble& other) const {\n    return double(*this) < double(other);\n  }\n\n  bool operator<(double other) const { return double(*this) < other; }\n\n  friend bool operator<(double a, const HighsCDouble& b) {\n    return a < double(b);\n  }\n\n  bool operator>=(const HighsCDouble& other) const {\n    return double(*this) >= double(other);\n  }\n\n  bool operator>=(double other) const { return double(*this) >= other; }\n\n  friend bool operator>=(double a, const HighsCDouble& b) {\n    return a >= double(b);\n  }\n\n  bool operator<=(const HighsCDouble& other) const {\n    return double(*this) <= double(other);\n  }\n\n  bool operator<=(double other) const { return double(*this) <= other; }\n\n  friend bool operator<=(double a, const HighsCDouble& b) {\n    return a <= double(b);\n  }\n\n  bool operator==(const HighsCDouble& other) const {\n    return double(*this) == double(other);\n  }\n\n  bool operator==(double other) const { return double(*this) == other; }\n\n  friend bool operator==(double a, const HighsCDouble& b) {\n    return a == double(b);\n  }\n\n  bool operator!=(const HighsCDouble& other) const {\n    return double(*this) != double(other);\n  }\n\n  bool operator!=(double other) const { return double(*this) != other; }\n\n  friend bool operator!=(double a, const HighsCDouble& b) {\n    return a != double(b);\n  }\n\n  void renormalize() { two_sum(hi, lo, hi, lo); }\n\n  friend HighsCDouble abs(const HighsCDouble& v) { return v < 0 ? -v : v; }\n\n  friend HighsCDouble sqrt(const HighsCDouble& v) {\n    double c = std::sqrt(v.hi + v.lo);\n\n    // guard against division by zero\n    if (c == 0.0) return 0.0;\n\n    // calculate precise square root by newton step\n    HighsCDouble res = v / c;\n    res += c;\n    // multiplication by 0.5 is exact\n    res.hi *= 0.5;\n    res.lo *= 0.5;\n    return res;\n  }\n\n  friend HighsCDouble floor(const HighsCDouble& x) {\n    // Treat |x| < 1 as special case, as per (for example)\n    // https://github.com/shibatch/tlfloat: see #2041\n    if (abs(x) < 1) {\n      if (x == 0 || x > 0) return HighsCDouble(0.0);\n      return HighsCDouble(-1.0);\n    }\n    double floor_x = std::floor(double(x));\n    HighsCDouble res;\n\n    two_sum(res.hi, res.lo, floor_x, std::floor(double(x - floor_x)));\n    return res;\n  }\n\n  friend HighsCDouble ceil(const HighsCDouble& x) {\n    // Treat |x| < 1 as special case, as per (for example)\n    // https://github.com/shibatch/tlfloat: see #2041\n    if (abs(x) < 1) {\n      if (x == 0 || x < 0) return HighsCDouble(0.0);\n      return HighsCDouble(1.0);\n    }\n    double ceil_x = std::ceil(double(x));\n    HighsCDouble res;\n\n    two_sum(res.hi, res.lo, ceil_x, std::ceil(double(x - ceil_x)));\n    return res;\n  }\n\n  friend HighsCDouble round(const HighsCDouble& x) { return floor(x + 0.5); }\n\n  friend HighsCDouble ldexp(const HighsCDouble& v, int exp) {\n    return HighsCDouble(std::ldexp(v.hi, exp), std::ldexp(v.lo, exp));\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsComponent.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file HighsComponent.h\n * @brief The HiGHS class\n */\n#ifndef UTIL_HIGHS_COMPONENT_H_\n#define UTIL_HIGHS_COMPONENT_H_\n\n#include \"lp_data/HighsOptions.h\"\n\n// HighsComponentData is a placeholder for structs which we will keep after\n// run() is done, internally.\nstruct HighsComponentData {\n  bool is_valid = false;\n};\n\n// HighsComponentInfo is a placeholder for details we want to query from outside\n// of HiGHS like execution information.\nstruct HighsComponentInfo {\n  bool is_valid = false;\n};\n\n// HighsComponentOptions is a placeholder for options specific to this component\nstruct HighsComponentOptions {\n  bool is_valid = false;\n};\n\nclass HighsComponent {\n public:\n  virtual void clear() = 0;\n  HighsStatus run();\n  HighsStatus setOptions(const HighsOptions& options);\n\n  const HighsComponentInfo& getInfo() { return info_; }\n  const HighsComponentData& getData() { return data_; }\n  const HighsComponentOptions& getOptions() { return options_; }\n\n  virtual ~HighsComponent() = default;\n\n private:\n  //  bool has_run_ = false;\n\n  HighsComponentInfo info_;\n  HighsComponentData data_;\n  HighsComponentOptions options_;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsDataStack.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HighsDataStack.h\n * @brief A stack of unstructured data stored as bytes\n */\n\n#ifndef UTIL_HIGHS_DATA_STACK_H_\n#define UTIL_HIGHS_DATA_STACK_H_\n\n#include <cstring>\n#include <type_traits>\n#include <vector>\n\n#include \"util/HighsInt.h\"\n\n#if __GNUG__ && __GNUC__ < 5 && !defined(__clang__)\n#define IS_TRIVIALLY_COPYABLE(T) __has_trivial_copy(T)\n#else\n#define IS_TRIVIALLY_COPYABLE(T) std::is_trivially_copyable<T>::value\n#endif\n\nclass HighsDataStack {\n  std::vector<char> data;\n  std::size_t position;\n\n public:\n  void resetPosition() { position = data.size(); }\n\n  template <typename T,\n            typename std::enable_if<IS_TRIVIALLY_COPYABLE(T), int>::type = 0>\n  void push(const T& r) {\n    std::size_t dataSize = data.size();\n    data.resize(dataSize + sizeof(T));\n    std::memcpy(data.data() + dataSize, &r, sizeof(T));\n  }\n\n  template <typename T,\n            typename std::enable_if<IS_TRIVIALLY_COPYABLE(T), int>::type = 0>\n  void pop(T& r) {\n    position -= sizeof(T);\n    std::memcpy(&r, data.data() + position, sizeof(T));\n  }\n\n  template <typename T>\n  void push(const std::vector<T>& r) {\n    std::size_t offset = data.size();\n    std::size_t numData = r.size();\n    // store the data\n    data.resize(offset + numData * sizeof(T) + sizeof(std::size_t));\n    if (!r.empty())\n      std::memcpy(data.data() + offset, r.data(), numData * sizeof(T));\n    // store the vector size\n    offset += numData * sizeof(T);\n    std::memcpy(data.data() + offset, &numData, sizeof(std::size_t));\n  }\n\n  template <typename T>\n  void pop(std::vector<T>& r) {\n    // pop the vector size\n    position -= sizeof(std::size_t);\n    std::size_t numData;\n    std::memcpy(&numData, &data[position], sizeof(std::size_t));\n    // pop the data\n    if (numData == 0) {\n      r.clear();\n    } else {\n      r.resize(numData);\n      position -= numData * sizeof(T);\n      std::memcpy(r.data(), data.data() + position, numData * sizeof(T));\n    }\n  }\n\n  void setPosition(size_t position_) { this->position = position_; }\n\n  size_t getCurrentDataSize() const { return data.size(); }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsDisjointSets.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_UTIL_DISJOINT_SETS_H_\n#define HIGHS_UTIL_DISJOINT_SETS_H_\n\n#include <array>\n#include <cassert>\n#include <cmath>\n#include <cstddef>\n#include <cstdint>\n#include <cstring>\n#include <functional>\n#include <iterator>\n#include <memory>\n#include <numeric>\n#include <type_traits>\n#include <utility>\n#include <vector>\n\n#include \"util/HighsInt.h\"\n\ntemplate <bool kMinimalRepresentative = false>\nclass HighsDisjointSets {\n  std::vector<HighsInt> sizes;\n  std::vector<HighsInt> sets;\n  std::vector<HighsInt> linkCompressionStack;\n\n public:\n  HighsDisjointSets() = default;\n  HighsDisjointSets(HighsInt numItems) { reset(numItems); }\n\n  void reset(HighsInt numItems) {\n    sizes.assign(numItems, 1);\n    sets.resize(numItems);\n    std::iota(sets.begin(), sets.end(), 0);\n  }\n\n  HighsInt getSet(HighsInt item) {\n    assert(item >= 0 && item < (HighsInt)sets.size());\n    HighsInt repr = sets[item];\n    assert(repr >= 0 && repr < (HighsInt)sets.size());\n\n    if (repr != sets[repr]) {\n      do {\n        linkCompressionStack.push_back(item);\n        item = repr;\n        repr = sets[repr];\n      } while (repr != sets[repr]);\n\n      do {\n        HighsInt i = linkCompressionStack.back();\n        linkCompressionStack.pop_back();\n        sets[i] = repr;\n      } while (!linkCompressionStack.empty());\n\n      sets[item] = repr;\n    }\n\n    return repr;\n  }\n\n  HighsInt getSetSize(HighsInt set) const {\n    assert(sets[set] == set);\n    return sizes[set];\n  }\n\n  void merge(HighsInt item1, HighsInt item2) {\n    assert(item1 >= 0 && item1 < (HighsInt)sets.size());\n    assert(item2 >= 0 && item2 < (HighsInt)sets.size());\n\n    HighsInt repr1 = getSet(item1);\n    assert(sets[repr1] == repr1);\n    assert(repr1 >= 0 && repr1 < (HighsInt)sets.size());\n\n    HighsInt repr2 = getSet(item2);\n    assert(sets[repr2] == repr2);\n    assert(repr2 >= 0 && repr2 < (HighsInt)sets.size());\n    assert(sizes.size() == sets.size());\n\n    if (repr1 == repr2) return;\n\n    if (kMinimalRepresentative) {\n      if (repr2 > repr1) {\n        sets[repr2] = repr1;\n        sizes[repr1] += sizes[repr2];\n      } else {\n        sets[repr1] = repr2;\n        sizes[repr2] += sizes[repr1];\n      }\n    } else {\n      if (sizes[repr1] > sizes[repr2]) {\n        sets[repr2] = repr1;\n        sizes[repr1] += sizes[repr2];\n      } else {\n        sets[repr1] = repr2;\n        sizes[repr2] += sizes[repr1];\n      }\n    }\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsHash.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_UTIL_HASH_H_\n#define HIGHS_UTIL_HASH_H_\n\n#include <array>\n#include <cassert>\n#include <cmath>\n#include <cstddef>\n#include <cstdint>\n#include <cstring>\n#include <functional>\n#include <iterator>\n#include <memory>\n#include <type_traits>\n#include <utility>\n#include <vector>\n\n#include \"util/HighsInt.h\"\n\n#ifdef HIGHS_HAVE_BITSCAN_REVERSE\n#include <intrin.h>\n#pragma intrinsic(_BitScanReverse)\n#ifdef _WIN64\n#pragma intrinsic(_BitScanReverse64)\n#pragma intrinsic(__popcnt64)\n#else\n#pragma intrinsic(__popcnt)\n#endif\n#endif\n\n#if __GNUG__ && __GNUC__ < 5 && !defined(__clang__)\n#define IS_TRIVIALLY_COPYABLE(T) __has_trivial_copy(T)\n#else\n#define IS_TRIVIALLY_COPYABLE(T) std::is_trivially_copyable<T>::value\n#endif\n\ntemplate <typename T>\nstruct HighsHashable : std::integral_constant<bool, IS_TRIVIALLY_COPYABLE(T)> {\n};\n\ntemplate <typename U, typename V>\nstruct HighsHashable<std::pair<U, V>>\n    : public std::integral_constant<bool, HighsHashable<U>::value &&\n                                              HighsHashable<V>::value> {};\n\ntemplate <typename U, typename V>\nstruct HighsHashable<std::tuple<U, V>> : public HighsHashable<std::pair<U, V>> {\n};\ntemplate <typename U, typename V, typename W, typename... Args>\nstruct HighsHashable<std::tuple<U, V, W, Args...>>\n    : public std::integral_constant<\n          bool, HighsHashable<U>::value &&\n                    HighsHashable<std::tuple<V, W, Args...>>::value> {};\n\nstruct HighsHashHelpers {\n  using u8 = std::uint8_t;\n  using i8 = std::int8_t;\n\n  using u16 = std::uint16_t;\n  using i16 = std::int16_t;\n\n  using u32 = std::uint32_t;\n  using i32 = std::int32_t;\n\n  using u64 = std::uint64_t;\n  using i64 = std::uint64_t;\n\n  static constexpr u64 c[] = {\n      u64{0xc8497d2a400d9551}, u64{0x80c8963be3e4c2f3}, u64{0x042d8680e260ae5b},\n      u64{0x8a183895eeac1536}, u64{0xa94e9c75f80ad6de}, u64{0x7e92251dec62835e},\n      u64{0x07294165cb671455}, u64{0x89b0f6212b0a4292}, u64{0x31900011b96bf554},\n      u64{0xa44540f8eee2094f}, u64{0xce7ffd372e4c64fc}, u64{0x51c9d471bfe6a10f},\n      u64{0x758c2a674483826f}, u64{0xf91a20abe63f8b02}, u64{0xc2a069024a1fcc6f},\n      u64{0xd5bb18b70c5dbd59}, u64{0xd510adac6d1ae289}, u64{0x571d069b23050a79},\n      u64{0x60873b8872933e06}, u64{0x780481cc19670350}, u64{0x7a48551760216885},\n      u64{0xb5d68b918231e6ca}, u64{0xa7e5571699aa5274}, u64{0x7b6d309b2cfdcf01},\n      u64{0x04e77c3d474daeff}, u64{0x4dbf099fd7247031}, u64{0x5d70dca901130beb},\n      u64{0x9f8b5f0df4182499}, u64{0x293a74c9686092da}, u64{0xd09bdab6840f52b3},\n      u64{0xc05d47f3ab302263}, u64{0x6b79e62b884b65d6}, u64{0xa581106fc980c34d},\n      u64{0xf081b7145ea2293e}, u64{0xfb27243dd7c3f5ad}, u64{0x5211bf8860ea667f},\n      u64{0x9455e65cb2385e7f}, u64{0x0dfaf6731b449b33}, u64{0x4ec98b3c6f5e68c7},\n      u64{0x007bfd4a42ae936b}, u64{0x65c93061f8674518}, u64{0x640816f17127c5d1},\n      u64{0x6dd4bab17b7c3a74}, u64{0x34d9268c256fa1ba}, u64{0x0b4d0c6b5b50d7f4},\n      u64{0x30aa965bc9fadaff}, u64{0xc0ac1d0c2771404d}, u64{0xc5e64509abb76ef2},\n      u64{0xd606b11990624a36}, u64{0x0d3f05d242ce2fb7}, u64{0x469a803cb276fe32},\n      u64{0xa4a44d177a3e23f4}, u64{0xb9d9a120dcc1ca03}, u64{0x2e15af8165234a2e},\n      u64{0x10609ba2720573d4}, u64{0xaa4191b60368d1d5}, u64{0x333dd2300bc57762},\n      u64{0xdf6ec48f79fb402f}, u64{0x5ed20fcef1b734fa}, u64{0x4c94924ec8be21ee},\n      u64{0x5abe6ad9d131e631}, u64{0xbe10136a522e602d}, u64{0x53671115c340e779},\n      u64{0x9f392fe43e2144da}};\n\n  /// mersenne prime 2^61 - 1\n  static constexpr u64 M61() { return u64{0x1fffffffffffffff}; };\n\n#ifdef HIGHS_HAVE_BUILTIN_CLZ\n  static int log2i(uint64_t n) { return 63 - __builtin_clzll(n); }\n\n  static int log2i(uint32_t n) { return 31 - __builtin_clz(n); }\n\n  static int popcnt(uint64_t x) { return __builtin_popcountll(x); }\n\n#elif defined(HIGHS_HAVE_BITSCAN_REVERSE)\n  static int log2i(uint64_t n) {\n    unsigned long result;\n#ifdef _WIN64\n    _BitScanReverse64(&result, n);\n#else\n    if (_BitScanReverse(&result, (n >> 32)))\n      result += 32;\n    else\n      _BitScanReverse(&result, (n & 0xffffffffu));\n#endif\n    return static_cast<int>(result);\n  }\n\n  static int log2i(uint32_t n) {\n    unsigned long result;\n    _BitScanReverse(&result, static_cast<unsigned long>(n));\n    return static_cast<int>(result);\n  }\n\n  static int popcnt(uint64_t x) {\n#ifdef _WIN64\n    return static_cast<int>(__popcnt64(x));\n#else\n    return __popcnt(x & 0xffffffffu) + __popcnt(x >> 32);\n#endif\n  }\n#else\n  // integer log2 algorithm without floating point arithmetic. It uses an\n  // unrolled loop and requires few instructions that can be well optimized.\n  static int log2i(uint64_t n) {\n    int x = 0;\n\n    auto log2Iteration = [&](int p) {\n      if (n >= uint64_t{1} << p) {\n        x += p;\n        n >>= p;\n      }\n    };\n\n    log2Iteration(32);\n    log2Iteration(16);\n    log2Iteration(8);\n    log2Iteration(4);\n    log2Iteration(2);\n    log2Iteration(1);\n\n    return x;\n  }\n\n  static int log2i(uint32_t n) {\n    int x = 0;\n\n    auto log2Iteration = [&](int p) {\n      if (n >= 1u << p) {\n        x += p;\n        n >>= p;\n      }\n    };\n\n    log2Iteration(16);\n    log2Iteration(8);\n    log2Iteration(4);\n    log2Iteration(2);\n    log2Iteration(1);\n\n    return x;\n  }\n\n  static int popcnt(uint64_t x) {\n    constexpr uint64_t m1 = 0x5555555555555555ull;\n    constexpr uint64_t m2 = 0x3333333333333333ull;\n    constexpr uint64_t m4 = 0x0f0f0f0f0f0f0f0full;\n    constexpr uint64_t h01 = 0x0101010101010101ull;\n\n    x -= (x >> 1) & m1;\n    x = (x & m2) + ((x >> 2) & m2);\n    x = (x + (x >> 4)) & m4;\n\n    return (x * h01) >> 56;\n  }\n\n#endif\n\n  /// compute a * b mod 2^61-1\n  static u64 multiply_modM61(u64 a, u64 b) {\n    u64 ahi = a >> 32;\n    u64 bhi = b >> 32;\n    u64 alo = a & 0xffffffffu;\n    u64 blo = b & 0xffffffffu;\n\n    // compute the different order terms with adicities 2^64, 2^32, 2^0\n    u64 term_64 = ahi * bhi;\n    u64 term_32 = ahi * blo + bhi * alo;\n    u64 term_0 = alo * blo;\n\n    // Partially reduce term_0 and term_32 modulo M61() individually to not deal\n    // with a possible carry bit (thanks @https://github.com/WTFHCN for catching\n    // the bug with this). We do not need to completely reduce by an additional\n    // check for the range of the resulting term as this is done in the end in\n    // any case and the reduced sizes do not cause troubles with the available\n    // 64 bits.\n    term_0 = (term_0 & M61()) + (term_0 >> 61);\n    term_0 += ((term_32 >> 29) + (term_32 << 32)) & M61();\n\n    // The lower 61 bits of term_0 are now the lower 61 bits of the result that\n    // we need. Now extract the upper 61 of the result so that we can compute\n    // the result of the multiplication modulo M61()\n    u64 ab61 = (term_64 << 3) | (term_0 >> 61);\n\n    // finally take the result modulo M61 which is computed by exploiting\n    // that M61 is a mersenne prime, particularly, if a * b = q * 2^61 + r\n    // then a * b = (q + r) (mod 2^61 - 1)\n    u64 result = (term_0 & M61()) + ab61;\n    if (result >= M61()) result -= M61();\n    return result;\n  }\n\n  static u64 modexp_M61(u64 a, u64 e) {\n    // the exponent need to be greater than zero\n    assert(e > 0);\n    u64 result = a;\n\n    while (e != 1) {\n      // square\n      result = multiply_modM61(result, result);\n\n      // multiply with a if exponent is odd\n      if (e & 1) result = multiply_modM61(result, a);\n\n      // shift to next bit\n      e = e >> 1;\n    }\n\n    return result;\n  }\n\n  /// mersenne prime 2^31 - 1\n  static constexpr u64 M31() { return u32{0x7fffffff}; };\n\n  /// compute a * b mod 2^31-1\n  static u32 multiply_modM31(u32 a, u32 b) {\n    u64 result = u64(a) * u64(b);\n    result = (result >> 31) + (result & M31());\n    if (result >= M31()) result -= M31();\n    return static_cast<u32>(result);\n  }\n\n  static u32 modexp_M31(u32 a, u64 e) {\n    // the exponent need to be greater than zero\n    assert(e > 0);\n    u32 result = a;\n\n    while (e != 1) {\n      // square\n      result = multiply_modM31(result, result);\n\n      // multiply with a if exponent is odd\n      if (e & 1) result = multiply_modM31(result, a);\n\n      // shift to next bit\n      e = e >> 1;\n    }\n\n    return result;\n  }\n\n  template <HighsInt k>\n  static u64 pair_hash(u32 a, u32 b) {\n    return (static_cast<u64>(a) + c[2 * k]) *\n           (static_cast<u64>(b) + c[2 * k + 1]);\n  }\n\n  static void sparse_combine(u64& hash, HighsInt index, u64 value) {\n    // we take each value of the sparse hash as coefficient for a polynomial\n    // of the finite field modulo the mersenne prime 2^61-1 where the monomial\n    // for a sparse entry has the degree of its index. We evaluate the\n    // polynomial at a random constant. This allows to compute the hashes of\n    // sparse vectors independently of each others nonzero contribution and\n    // therefore allows to use the order of best access patterns for cache\n    // performance. E.g. we can compute a strong hash value for parallel row and\n    // column detection and only need to loop over the nonzeros once in\n    // arbitrary order. This comes at the expense of more expensive hash\n    // calculations as it would be more efficient to evaluate the polynomial\n    // with horners scheme, but allows for parallelization and arbitrary order.\n    // Since we have 64 random constants available, we slightly improve\n    // the scheme by using a lower degree polynomial with 64 variables\n    // which we evaluate at the random vector of 64.\n\n    // make sure input value is never zero and at most 61bits are used\n    value = ((value << 1) & M61()) | 1;\n\n    // make sure that the constant has at most 61 bits, as otherwise the modulo\n    // algorithm for multiplication mod M61 might not work properly due to\n    // overflow\n    u64 a = c[index & 63] & M61();\n    u64 degree = (static_cast<u64>(index) >> 6) + 1;\n\n    hash += multiply_modM61(value, modexp_M61(a, degree));\n    hash = (hash >> 61) + (hash & M61());\n    if (hash >= M61()) hash -= M61();\n    assert(hash < M61());\n  }\n\n  static void sparse_inverse_combine(u64& hash, HighsInt index, u64 value) {\n    // same hash algorithm as sparse_combine(), but for updating a hash value to\n    // the state before it was changed with a call to sparse_combine(). This is\n    // easily possible as the hash value just uses finite field arithmetic. We\n    // can simply add the additive inverse of the previous hash value. This is a\n    // very useful routine for symmetry detection. During partition refinement\n    // the hashes do not need to be recomputed but can be updated with this\n    // procedure.\n\n    // make sure input value is never zero and at most 61bits are used\n    value = ((value << 1) & M61()) | 1;\n\n    u64 a = c[index & 63] & M61();\n    u64 degree = (static_cast<u64>(index) >> 6) + 1;\n    // add the additive inverse (M61() - hashvalue) instead of the hash value\n    // itself\n    hash += M61() - multiply_modM61(value, modexp_M61(a, degree));\n    hash = (hash >> 61) + (hash & M61());\n    if (hash >= M61()) hash -= M61();\n    assert(hash < M61());\n  }\n\n  /// overload that is not taking a value and saves one multiplication call\n  /// useful for sparse hashing of bit vectors\n  static void sparse_combine(u64& hash, HighsInt index) {\n    u64 a = c[index & 63] & M61();\n    u64 degree = (static_cast<u64>(index) >> 6) + 1;\n\n    hash += modexp_M61(a, degree);\n    hash = (hash >> 61) + (hash & M61());\n    if (hash >= M61()) hash -= M61();\n    assert(hash < M61());\n  }\n\n  /// overload that is not taking a value and saves one multiplication call\n  /// useful for sparse hashing of bit vectors\n  static void sparse_inverse_combine(u64& hash, HighsInt index) {\n    // same hash algorithm as sparse_combine(), but for updating a hash value to\n    // the state before it was changed with a call to sparse_combine(). This is\n    // easily possible as the hash value just uses finite field arithmetic. We\n    // can simply add the additive inverse of the previous hash value. This is a\n    // very useful routine for symmetry detection. During partition refinement\n    // the hashes do not need to be recomputed but can be updated with this\n    // procedure.\n\n    u64 a = c[index & 63] & M61();\n    u64 degree = (static_cast<u64>(index) >> 6) + 1;\n    // add the additive inverse (M61() - hashvalue) instead of the hash value\n    // itself\n    hash += M61() - modexp_M61(a, degree);\n    hash = (hash >> 61) + (hash & M61());\n    if (hash >= M61()) hash -= M61();\n    assert(hash < M61());\n  }\n\n  static void sparse_combine32(u32& hash, HighsInt index, u64 value) {\n    // we take each value of the sparse hash as coefficient for a polynomial\n    // of the finite field modulo the mersenne prime 2^61-1 where the monomial\n    // for a sparse entry has the degree of its index. We evaluate the\n    // polynomial at a random constant. This allows to compute the hashes of\n    // sparse vectors independently of each others nonzero contribution and\n    // therefore allows to use the order of best access patterns for cache\n    // performance. E.g. we can compute a strong hash value for parallel row and\n    // column detection and only need to loop over the nonzeros once in\n    // arbitrary order. This comes at the expense of more expensive hash\n    // calculations as it would be more efficient to evaluate the polynomial\n    // with horners scheme, but allows for parallelization and arbitrary order.\n    // Since we have 16 random constants available, we slightly improve\n    // the scheme by using a lower degree polynomial with 16 variables\n    // which we evaluate at the random vector of 16.\n\n    // make sure input value is never zero and at most 31bits are used\n    value = (pair_hash<0>(static_cast<u32>(value), value >> 32) >> 33) | 1;\n\n    // make sure that the constant has at most 31 bits, as otherwise the modulo\n    // algorithm for multiplication mod M31 might not work properly due to\n    // overflow\n    u32 a = static_cast<u32>(c[index & 63] & M31());\n    u64 degree = (static_cast<u64>(index) >> 6) + 1;\n\n    u64 result = hash;\n    result += multiply_modM31(static_cast<u32>(value), modexp_M31(a, degree));\n    result = (result >> 31) + (result & M31());\n    if (result >= M31()) result -= M31();\n    assert(result < M31());\n    hash = static_cast<u32>(result);\n  }\n\n  static void sparse_inverse_combine32(u32& hash, HighsInt index, u64 value) {\n    // same hash algorithm as sparse_combine(), but for updating a hash value to\n    // the state before it was changed with a call to sparse_combine(). This is\n    // easily possible as the hash value just uses finite field arithmetic. We\n    // can simply add the additive inverse of the previous hash value. This is a\n    // very useful routine for symmetry detection. During partition refinement\n    // the hashes do not need to be recomputed but can be updated with this\n    // procedure.\n\n    // make sure input value is never zero and at most 31bits are used\n    value = (pair_hash<0>(static_cast<u32>(value), value >> 32) >> 33) | 1;\n\n    u32 a = static_cast<u32>(c[index & 63] & M31());\n    u64 degree = (static_cast<u64>(index) >> 6) + 1;\n    // add the additive inverse (M31() - hashvalue) instead of the hash value\n    // itself\n    u64 result = hash;\n    result +=\n        M31() - multiply_modM31(static_cast<u32>(value), modexp_M31(a, degree));\n    result = (result >> 31) + (result & M31());\n    if (result >= M31()) result -= M31();\n    assert(result < M31());\n    hash = static_cast<u32>(result);\n  }\n\n  static constexpr u64 fibonacci_muliplier() { return u64{0x9e3779b97f4a7c15}; }\n\n  template <typename T,\n            typename std::enable_if<HighsHashable<T>::value, int>::type = 0>\n  static u64 vector_hash(const T* vals, size_t numvals) {\n    std::array<u32, 2> pair{};\n    u64 hash = 0;\n    HighsInt k = 0;\n\n    const char* dataptr = (const char*)vals;\n    const char* dataend = (const char*)(vals + numvals);\n\n    while (dataptr != dataend) {\n      using std::size_t;\n      size_t numBytes = std::min(size_t(dataend - dataptr), size_t{256});\n      size_t numPairs = (numBytes + 7) / 8;\n      size_t lastPairBytes = numBytes - (numPairs - 1) * 8;\n      u64 chunkhash[] = {u64{0}, u64{0}};\n\n#define HIGHS_VECHASH_CASE_N(N, B)                         \\\n  std::memcpy(&pair[0], dataptr, B);                       \\\n  chunkhash[N & 1] += pair_hash<32 - N>(pair[0], pair[1]); \\\n  dataptr += B;\n\n      switch (numPairs) {\n        case 32:\n          if (hash != 0) {\n            // make sure hash is reduced mod M61() before multiplying with the\n            // next random constant. For vectors at most 240 bytes we never\n            // get here and only use the fast pair hashing scheme\n            // for vectors with 240 bytes to 256 bytes we do have the one\n            // additional check for hash != 0 above which will return false\n            // and only for longer vectors we ever reduce modulo M61\n            if (hash >= M61()) hash -= M61();\n            hash = multiply_modM61(hash, c[(k++) & 63] & M61());\n          }\n          HIGHS_VECHASH_CASE_N(32, 8)\n          // fall through\n        case 31:\n          HIGHS_VECHASH_CASE_N(31, 8)\n          // fall through\n        case 30:\n          HIGHS_VECHASH_CASE_N(30, 8)\n          // fall through\n        case 29:\n          HIGHS_VECHASH_CASE_N(29, 8)\n          // fall through\n        case 28:\n          HIGHS_VECHASH_CASE_N(28, 8)\n          // fall through\n        case 27:\n          HIGHS_VECHASH_CASE_N(27, 8)\n          // fall through\n        case 26:\n          HIGHS_VECHASH_CASE_N(26, 8)\n          // fall through\n        case 25:\n          HIGHS_VECHASH_CASE_N(25, 8)\n          // fall through\n        case 24:\n          HIGHS_VECHASH_CASE_N(24, 8)\n          // fall through\n        case 23:\n          HIGHS_VECHASH_CASE_N(23, 8)\n          // fall through\n        case 22:\n          HIGHS_VECHASH_CASE_N(22, 8)\n          // fall through\n        case 21:\n          HIGHS_VECHASH_CASE_N(21, 8)\n          // fall through\n        case 20:\n          HIGHS_VECHASH_CASE_N(20, 8)\n          // fall through\n        case 19:\n          HIGHS_VECHASH_CASE_N(19, 8)\n          // fall through\n        case 18:\n          HIGHS_VECHASH_CASE_N(18, 8)\n          // fall through\n        case 17:\n          HIGHS_VECHASH_CASE_N(17, 8)\n          // fall through\n        case 16:\n          HIGHS_VECHASH_CASE_N(16, 8)\n          // fall through\n        case 15:\n          HIGHS_VECHASH_CASE_N(15, 8)\n          // fall through\n        case 14:\n          HIGHS_VECHASH_CASE_N(14, 8)\n          // fall through\n        case 13:\n          HIGHS_VECHASH_CASE_N(13, 8)\n          // fall through\n        case 12:\n          HIGHS_VECHASH_CASE_N(12, 8)\n          // fall through\n        case 11:\n          HIGHS_VECHASH_CASE_N(11, 8)\n          // fall through\n        case 10:\n          HIGHS_VECHASH_CASE_N(10, 8)\n          // fall through\n        case 9:\n          HIGHS_VECHASH_CASE_N(9, 8)\n          // fall through\n        case 8:\n          HIGHS_VECHASH_CASE_N(8, 8)\n          // fall through\n        case 7:\n          HIGHS_VECHASH_CASE_N(7, 8)\n          // fall through\n        case 6:\n          HIGHS_VECHASH_CASE_N(6, 8)\n          // fall through\n        case 5:\n          HIGHS_VECHASH_CASE_N(5, 8)\n          // fall through\n        case 4:\n          HIGHS_VECHASH_CASE_N(4, 8)\n          // fall through\n        case 3:\n          HIGHS_VECHASH_CASE_N(3, 8)\n          // fall through\n        case 2:\n          HIGHS_VECHASH_CASE_N(2, 8)\n          // fall through\n        case 1:\n          HIGHS_VECHASH_CASE_N(1, lastPairBytes)\n      }\n\n      hash += (chunkhash[0] >> 3) ^ (chunkhash[1] >> 32);\n    }\n\n#undef HIGHS_VECHASH_CASE_N\n\n    return hash * fibonacci_muliplier();\n  }\n\n  template <typename T,\n            typename std::enable_if<HighsHashable<T>::value &&\n                                        (sizeof(T) <= 8) && (sizeof(T) >= 1),\n                                    int>::type = 0>\n  static u64 hash(const T& val) {\n    std::array<u32, 2> bytes;\n    if (sizeof(T) < 4) bytes[0] = 0;\n    if (sizeof(T) < 8) bytes[1] = 0;\n    std::memcpy(&bytes[0], &val, sizeof(T));\n    return pair_hash<1>(bytes[0], bytes[1]) ^\n           pair_hash<0>(bytes[0], bytes[1]) >> 32;\n  }\n\n  template <typename T,\n            typename std::enable_if<HighsHashable<T>::value &&\n                                        (sizeof(T) >= 9) && (sizeof(T) <= 16),\n                                    int>::type = 0>\n  static u64 hash(const T& val) {\n    std::array<u32, 4> bytes;\n    if (sizeof(T) < 12) bytes[2] = 0;\n    if (sizeof(T) < 16) bytes[3] = 0;\n    std::memcpy(&bytes[0], &val, sizeof(T));\n    return (pair_hash<0>(bytes[0], bytes[1]) ^\n            (pair_hash<1>(bytes[2], bytes[3]) >> 32)) *\n           fibonacci_muliplier();\n  }\n\n  template <typename T,\n            typename std::enable_if<HighsHashable<T>::value &&\n                                        (sizeof(T) >= 17) && (sizeof(T) <= 24),\n                                    int>::type = 0>\n  static u64 hash(const T& val) {\n    std::array<u32, 6> bytes;\n    if (sizeof(T) < 20) bytes[4] = 0;\n    if (sizeof(T) < 24) bytes[5] = 0;\n    std::memcpy(&bytes[0], &val, sizeof(T));\n    return (pair_hash<0>(bytes[0], bytes[1]) ^\n            ((pair_hash<1>(bytes[2], bytes[3]) +\n              pair_hash<2>(bytes[4], bytes[5])) >>\n             32)) *\n           fibonacci_muliplier();\n  }\n\n  template <typename T,\n            typename std::enable_if<HighsHashable<T>::value &&\n                                        (sizeof(T) >= 25) && (sizeof(T) <= 32),\n                                    int>::type = 0>\n  static u64 hash(const T& val) {\n    std::array<u32, 8> bytes;\n    if (sizeof(T) < 28) bytes[6] = 0;\n    if (sizeof(T) < 32) bytes[7] = 0;\n    std::memcpy(&bytes[0], &val, sizeof(T));\n    return ((pair_hash<0>(bytes[0], bytes[1]) +\n             pair_hash<1>(bytes[2], bytes[3])) ^\n            ((pair_hash<2>(bytes[4], bytes[5]) +\n              pair_hash<3>(bytes[6], bytes[7])) >>\n             32)) *\n           fibonacci_muliplier();\n  }\n\n  template <typename T,\n            typename std::enable_if<HighsHashable<T>::value &&\n                                        (sizeof(T) >= 33) && (sizeof(T) <= 40),\n                                    int>::type = 0>\n  static u64 hash(const T& val) {\n    std::array<u32, 10> bytes;\n    if (sizeof(T) < 36) bytes[8] = 0;\n    if (sizeof(T) < 40) bytes[9] = 0;\n    std::memcpy(&bytes[0], &val, sizeof(T));\n    return ((pair_hash<0>(bytes[0], bytes[1]) +\n             pair_hash<1>(bytes[2], bytes[3])) ^\n            ((pair_hash<2>(bytes[4], bytes[5]) +\n              pair_hash<3>(bytes[6], bytes[7]) +\n              pair_hash<4>(bytes[8], bytes[9])) >>\n             32)) *\n           fibonacci_muliplier();\n  }\n\n  template <typename T,\n            typename std::enable_if<HighsHashable<T>::value &&\n                                        (sizeof(T) >= 41) && (sizeof(T) <= 48),\n                                    int>::type = 0>\n  static u64 hash(const T& val) {\n    std::array<u32, 12> bytes;\n    if (sizeof(T) < 44) bytes[10] = 0;\n    if (sizeof(T) < 48) bytes[11] = 0;\n    std::memcpy(&bytes[0], &val, sizeof(T));\n    return ((pair_hash<0>(bytes[0], bytes[1]) +\n             pair_hash<1>(bytes[2], bytes[3]) +\n             pair_hash<2>(bytes[4], bytes[5])) ^\n            ((pair_hash<3>(bytes[6], bytes[7]) +\n              pair_hash<4>(bytes[8], bytes[9]) +\n              pair_hash<5>(bytes[10], bytes[11])) >>\n             32)) *\n           fibonacci_muliplier();\n  }\n\n  template <typename T,\n            typename std::enable_if<HighsHashable<T>::value &&\n                                        (sizeof(T) >= 49) && (sizeof(T) <= 56),\n                                    int>::type = 0>\n  static u64 hash(const T& val) {\n    std::array<u32, 14> bytes;\n    if (sizeof(T) < 52) bytes[12] = 0;\n    if (sizeof(T) < 56) bytes[13] = 0;\n    std::memcpy(&bytes[0], &val, sizeof(T));\n    return ((pair_hash<0>(bytes[0], bytes[1]) +\n             pair_hash<1>(bytes[2], bytes[3]) +\n             pair_hash<2>(bytes[4], bytes[5])) ^\n            ((pair_hash<3>(bytes[6], bytes[7]) +\n              pair_hash<4>(bytes[8], bytes[9]) +\n              pair_hash<5>(bytes[10], bytes[11]) +\n              pair_hash<6>(bytes[12], bytes[13])) >>\n             32)) *\n           fibonacci_muliplier();\n  }\n\n  template <typename T,\n            typename std::enable_if<HighsHashable<T>::value &&\n                                        (sizeof(T) >= 57) && (sizeof(T) <= 64),\n                                    int>::type = 0>\n  static u64 hash(const T& val) {\n    std::array<u32, 16> bytes;\n    if (sizeof(T) < 60) bytes[14] = 0;\n    if (sizeof(T) < 64) bytes[15] = 0;\n    std::memcpy(&bytes[0], &val, sizeof(T));\n    return ((pair_hash<0>(bytes[0], bytes[1]) +\n             pair_hash<1>(bytes[2], bytes[3]) +\n             pair_hash<2>(bytes[4], bytes[5]) +\n             pair_hash<3>(bytes[6], bytes[7])) ^\n            ((pair_hash<4>(bytes[8], bytes[9]) +\n              pair_hash<5>(bytes[10], bytes[11]) +\n              pair_hash<6>(bytes[12], bytes[13]) +\n              pair_hash<7>(bytes[14], bytes[15])) >>\n             32)) *\n           fibonacci_muliplier();\n  }\n\n  template <typename T,\n            typename std::enable_if<HighsHashable<T>::value && (sizeof(T) > 64),\n                                    int>::type = 0>\n  static u64 hash(const T& val) {\n    return vector_hash(&val, 1);\n  }\n\n  template <typename T,\n            typename std::enable_if<HighsHashable<T>::value, int>::type = 0>\n  static u64 hash(const std::vector<T>& val) {\n    return vector_hash(val.data(), val.size());\n  }\n\n  template <typename T, typename std::enable_if<\n                            std::is_same<decltype(*reinterpret_cast<T*>(0) ==\n                                                  *reinterpret_cast<T*>(0)),\n                                         bool>::value,\n                            int>::type = 0>\n  static bool equal(const T& a, const T& b) {\n    return a == b;\n  }\n\n  template <typename T,\n            typename std::enable_if<HighsHashable<T>::value, int>::type = 0>\n  static bool equal(const std::vector<T>& a, const std::vector<T>& b) {\n    if (a.size() != b.size()) return false;\n    return std::memcmp(a.data(), b.data(), sizeof(T) * a.size()) == 0;\n  }\n\n  static constexpr double golden_ratio_reciprocal() {\n    return 0.61803398874989484;\n  }\n\n  static u32 double_hash_code(double val) {\n    // we multiply by some irrational number, so that the buckets in which we\n    // put the real numbers do not break on a power of two pattern. E.g.\n    // consider the use case for detecting parallel rows when we have two\n    // parallel rows scaled to have their largest coefficient 1.0 and another\n    // coefficient which is 0.5\n    // +- epsilon. Clearly we want to detect those rows as parallel and give\n    // them the same hash value for small enough epsilon. The exponent,\n    // however will switch to -2 for the value just below 0.5 and the hashcodes\n    // will differ. when multiplying with the reciprocal of the golden ratio the\n    // exact 0.5 will yield 0.30901699437494742 and 0.5 - 1e-9 will yield\n    // 0.3090169937569134 which has the same exponent and matches in the most\n    // significant bits. Hence it yields the same hashcode. Obviously there will\n    // now be different values which exhibit the same pattern as the 0.5 case,\n    // but they do not have a small denominator like 1/2 in their rational\n    // representation but are power of two multiples of the golden ratio and\n    // therefore irrational, which we do not expect in non-artificial input\n    // data.\n    int exponent;\n    double hashbits = std::frexp(val * golden_ratio_reciprocal(), &exponent);\n\n    // some extra casts to be more verbose about what is happening.\n    // We want the exponent to use only 16bits so that the remaining 16 bits\n    // are used for the most significant bits of the mantissa and the sign bit.\n    // casting to unsigned 16bits first ensures that the value after the cast is\n    // defined to be UINT16_MAX - |exponent| when the exponent is negative.\n    // casting the exponent to a uint32_t directly would give wrong promotion\n    // of negative exponents as UINT32_MAX - |exponent| and take up to many bits\n    // or possibly lose information after the 16 bit shift. For the mantissa we\n    // take the 15 most significant bits, even though we could squeeze out a few\n    // more of the exponent. We don't need more bits as this would make the\n    // buckets very small and might miss more values that are equal within\n    // epsilon. Therefore the most significant 15 bits of the mantissa and the\n    // sign is encoded in the 16 lower bits of the hashcode and the upper 16bits\n    // encode the sign and value of the exponent.\n    u32 hashvalue = (u32)(u16)(i16)exponent;\n    hashvalue = (hashvalue << 16) | (u32)(u16)(i16)std::ldexp(hashbits, 15);\n\n    return hashvalue;\n  }\n};\n\nstruct HighsHasher {\n  template <typename T>\n  size_t operator()(const T& x) const {\n    return HighsHashHelpers::hash(x);\n  }\n};\n\nstruct HighsVectorHasher {\n  template <typename T>\n  size_t operator()(const std::vector<T>& vec) const {\n    return HighsHashHelpers::vector_hash(vec.data(), vec.size());\n  }\n};\n\nstruct HighsVectorEqual {\n  template <typename T>\n  bool operator()(const std::vector<T>& vec1,\n                  const std::vector<T>& vec2) const {\n    if (vec1.size() != vec2.size()) return false;\n    return std::equal(vec1.begin(), vec1.end(), vec2.begin());\n  }\n};\n\ntemplate <typename K, typename V = void>\nstruct HighsHashTableEntry {\n private:\n  K key_;\n  V value_;\n\n public:\n  HighsHashTableEntry(HighsHashTableEntry<K, V>&&) = default;\n  HighsHashTableEntry(const HighsHashTableEntry<K, V>&) = default;\n  ~HighsHashTableEntry() = default;\n  HighsHashTableEntry() = default;\n  HighsHashTableEntry<K, V>& operator=(HighsHashTableEntry<K, V>&&) = default;\n  HighsHashTableEntry<K, V>& operator=(const HighsHashTableEntry<K, V>&) =\n      default;\n\n  // add a constructor to pass an argument to initialize the key with a value\n  // and the value as default\n  // the enable if statement makes sure this overload is never selected\n  // when the type of the single argument is HighsHashTableEntry<K,V> so that\n  // the default move and copy constructors are preferred when they match\n  // and this is only used to initialize the key type from a single argument.\n  template <\n      typename K_,\n      typename std::enable_if<\n          !std::is_same<typename std::remove_cv<\n                            typename std::remove_reference<K_>::type>::type,\n                        HighsHashTableEntry<K, V>>::value,\n          int>::type = 0>\n  HighsHashTableEntry(K_&& k) : key_(std::forward<K_>(k)), value_() {}\n\n  template <typename K_, typename V_>\n  HighsHashTableEntry(K_&& k, V_&& v)\n      : key_(std::forward<K_>(k)), value_(std::forward<V_>(v)) {}\n\n  const K& key() const { return key_; }\n  const V& value() const { return value_; }\n  V& value() { return value_; }\n\n  template <typename Func>\n  auto forward(Func&& f) -> decltype(f(key_, value_)) {\n    const K& keyRef = key_;\n    return f(keyRef, value_);\n  }\n\n  template <typename Func>\n  auto forward(Func&& f) const -> decltype(f(key_)) {\n    const K& keyRef = key_;\n    return f(keyRef);\n  }\n\n  template <typename Func>\n  auto forward(Func&& f) const -> decltype(f(key_, value_)) {\n    return f(key_, value_);\n  }\n};\n\ntemplate <typename T>\nstruct HighsHashTableEntry<T, void> {\n private:\n  T value_;\n\n public:\n  HighsHashTableEntry(HighsHashTableEntry<T, void>&&) = default;\n  HighsHashTableEntry(const HighsHashTableEntry<T, void>&) = default;\n  ~HighsHashTableEntry() = default;\n  HighsHashTableEntry() = default;\n  HighsHashTableEntry<T, void>& operator=(HighsHashTableEntry<T, void>&&) =\n      default;\n  HighsHashTableEntry<T, void>& operator=(const HighsHashTableEntry<T, void>&) =\n      default;\n\n  // Add a constructor to accept an arbitrary argument pack for initialize the\n  // underlying value of type T. The enable if statement makes sure this\n  // overload is never selected when the type of the single argument is\n  // HighsHashTableEntry<T,void> so that the default move and copy constructors\n  // are preferred when they match and this is only used to initialize the value\n  // of type from a set of arguments which are properly forwarded.\n  // The std::tuple usage in enable_if is a work-around to make the statement\n  // legal when multiple arguments are passed in, since std::is_same expects a\n  // single type. In that case is_same will obviously return false and the\n  // overload is appropriate to initialize the value_ with multiple forwarded\n  // arguments.\n  template <typename... Args,\n            typename std::enable_if<\n                !std::is_same<\n                    std::tuple<typename std::remove_cv<\n                        typename std::remove_reference<Args>::type>::type...>,\n                    std::tuple<HighsHashTableEntry<T, void>>>::value,\n                int>::type = 0>\n  HighsHashTableEntry(Args&&... args) : value_(std::forward<Args>(args)...) {}\n\n  const T& key() const { return value_; }\n  const T& value() const { return value_; }\n\n  template <typename Func>\n  auto forward(Func&& f) -> decltype(f(value_)) {\n    return f(value_);\n  }\n\n  template <typename Func>\n  auto forward(Func&& f) const -> decltype(f(value_)) {\n    return f(value_);\n  }\n};\n\ntemplate <typename K, typename V = void>\nclass HighsHashTable {\n  struct OpNewDeleter {\n    void operator()(void* ptr) { ::operator delete(ptr); }\n  };\n\n public:\n  using u8 = std::uint8_t;\n  using i8 = std::int8_t;\n\n  using u16 = std::uint16_t;\n  using i16 = std::int16_t;\n\n  using u32 = std::uint32_t;\n  using i32 = std::int32_t;\n\n  using u64 = std::uint64_t;\n  using i64 = std::int64_t;\n\n  using Entry = HighsHashTableEntry<K, V>;\n  using KeyType = K;\n  using ValueType =\n      typename std::remove_reference<decltype(Entry().value())>::type;\n\n  std::unique_ptr<Entry, OpNewDeleter> entries;\n  std::unique_ptr<u8[]> metadata;\n  u64 tableSizeMask;\n  u64 numHashShift;\n  u64 numElements = 0;\n\n  template <typename IterType>\n  class HashTableIterator {\n    u8* pos;\n    u8* end;\n    Entry* entryEnd;\n\n   public:\n    using difference_type = std::ptrdiff_t;\n    using value_type = IterType;\n    using pointer = IterType*;\n    using reference = IterType&;\n    using iterator_category = std::forward_iterator_tag;\n    HashTableIterator(u8* pos_, u8* end_, Entry* entryEnd_)\n        : pos(pos_), end(end_), entryEnd(entryEnd_) {}\n    HashTableIterator() = default;\n\n    HashTableIterator<IterType> operator++(int) {\n      // postfix\n      HashTableIterator<IterType> oldpos = *this;\n      for (++pos; pos != end; ++pos)\n        if ((*pos) & 0x80u) break;\n\n      return oldpos;\n    }\n\n    HashTableIterator<IterType>& operator++() {\n      // prefix\n      for (++pos; pos != end; ++pos)\n        if ((*pos) & 0x80u) break;\n\n      return *this;\n    }\n\n    reference operator*() const { return *(entryEnd - (end - pos)); }\n    pointer operator->() const { return (entryEnd - (end - pos)); }\n    HashTableIterator<IterType> operator+(difference_type v) const {\n      for (difference_type k = 0; k != v; ++k) ++(*this);\n    }\n\n    bool operator==(const HashTableIterator<IterType>& rhs) const {\n      return pos == rhs.pos;\n    }\n    bool operator!=(const HashTableIterator<IterType>& rhs) const {\n      return pos != rhs.pos;\n    }\n  };\n\n  using const_iterator = HashTableIterator<const Entry>;\n  using iterator = HashTableIterator<Entry>;\n\n  HighsHashTable() { makeEmptyTable(128); }\n  HighsHashTable(u64 minCapacity) {\n    u64 initCapacity = u64{1} << (u64)std::ceil(std::log2(std::max(\n                           128.0, 8 * static_cast<double>(minCapacity) / 7)));\n    makeEmptyTable(initCapacity);\n  }\n\n  iterator end() {\n    u64 capacity = tableSizeMask + 1;\n    return iterator{metadata.get() + capacity, metadata.get() + capacity,\n                    entries.get() + capacity};\n  };\n\n  const_iterator end() const {\n    u64 capacity = tableSizeMask + 1;\n    return const_iterator{metadata.get() + capacity, metadata.get() + capacity,\n                          entries.get() + capacity};\n  };\n\n  const_iterator begin() const {\n    if (numElements == 0) return end();\n    u64 capacity = tableSizeMask + 1;\n    const_iterator iter{metadata.get(), metadata.get() + capacity,\n                        entries.get() + capacity};\n    if (!occupied(metadata[0])) ++iter;\n\n    return iter;\n  };\n\n  iterator begin() {\n    if (numElements == 0) return end();\n    u64 capacity = tableSizeMask + 1;\n    iterator iter{metadata.get(), metadata.get() + capacity,\n                  entries.get() + capacity};\n    if (!occupied(metadata[0])) ++iter;\n\n    return iter;\n  };\n\n private:\n  u8 toMetadata(u64 hash) const { return (hash >> numHashShift) | 0x80u; }\n\n  static constexpr u64 maxDistance() { return 127; }\n\n  void makeEmptyTable(u64 capacity) {\n    tableSizeMask = capacity - 1;\n    numHashShift = 64 - HighsHashHelpers::log2i(capacity);\n    assert(capacity == (u64{1} << (64 - numHashShift)));\n    numElements = 0;\n\n    metadata = decltype(metadata)(new u8[capacity]{});\n    entries =\n        decltype(entries)((Entry*)::operator new(sizeof(Entry) * capacity));\n  }\n\n  bool occupied(u8 meta) const { return meta & 0x80; }\n\n  u64 distanceFromIdealSlot(u64 pos) const {\n    // we store 7 bits of the hash in the metadata. Assuming a decent\n    // hashfunction it is practically never happening that an item travels more\n    // than 127 slots from its ideal position, therefore, we can compute the\n    // distance from the ideal position just as it would normally be done\n    // assuming there is at most one overflow. Consider using 3 bits which gives\n    // values from 0 to 7. When an item is at a position with lower bits 7 and\n    // is placed 3 positions after its ideal position, the lower bits of the\n    // hash value will overflow and yield the value 2. With the assumption that\n    // an item never cycles through one full cycle of the range 0 to 7, its\n    // position would never be placed in a position with lower bits 7 other than\n    // its ideal position. This allows us to compute the distance from its ideal\n    // position by simply ignoring an overflow. In our case the correct answer\n    // would be 3, but we get (2 - 7)=-5. This, however, is the correct result 3\n    // when promoting to an unsigned value and looking at the lower 3 bits.\n\n    return ((pos - metadata[pos])) & 0x7f;\n  }\n\n  void growTable() {\n    decltype(entries) oldEntries = std::move(entries);\n    decltype(metadata) oldMetadata = std::move(metadata);\n    u64 oldCapactiy = tableSizeMask + 1;\n\n    makeEmptyTable(2 * oldCapactiy);\n\n    for (u64 i = 0; i != oldCapactiy; ++i)\n      if (occupied(oldMetadata[i])) insert(std::move(oldEntries.get()[i]));\n  }\n\n  void shrinkTable() {\n    decltype(entries) oldEntries = std::move(entries);\n    decltype(metadata) oldMetadata = std::move(metadata);\n    u64 oldCapactiy = tableSizeMask + 1;\n\n    makeEmptyTable(oldCapactiy / 2);\n\n    for (u64 i = 0; i != oldCapactiy; ++i)\n      if (occupied(oldMetadata[i])) insert(std::move(oldEntries.get()[i]));\n  }\n\n  bool findPosition(const KeyType& key, u8& meta, u64& startPos, u64& maxPos,\n                    u64& pos) const {\n    u64 hash = HighsHashHelpers::hash(key);\n    startPos = hash >> numHashShift;\n    maxPos = (startPos + maxDistance()) & tableSizeMask;\n    meta = toMetadata(hash);\n\n    const Entry* entryArray = entries.get();\n    pos = startPos;\n    do {\n      if (!occupied(metadata[pos])) return false;\n      if (metadata[pos] == meta &&\n          HighsHashHelpers::equal(key, entryArray[pos].key()))\n        return true;\n\n      u64 currentDistance = (pos - startPos) & tableSizeMask;\n      if (currentDistance > distanceFromIdealSlot(pos)) return false;\n\n      pos = (pos + 1) & tableSizeMask;\n    } while (pos != maxPos);\n\n    return false;\n  }\n\n public:\n  void clear() {\n    if (numElements) {\n      u64 capacity = tableSizeMask + 1;\n      if (!std::is_trivially_destructible<Entry>::value) {\n        for (u64 i = 0; i < capacity; ++i)\n          if (occupied(metadata[i])) entries.get()[i].~Entry();\n      }\n      if (capacity == 128) {\n        std::memset(metadata.get(), 0, 128);\n        numElements = 0;\n      } else\n        makeEmptyTable(128);\n    }\n  }\n\n  const ValueType* find(const KeyType& key) const {\n    u64 pos, startPos, maxPos;\n    u8 meta;\n    if (findPosition(key, meta, startPos, maxPos, pos))\n      return &(entries.get()[pos].value());\n\n    return nullptr;\n  }\n\n  ValueType* find(const KeyType& key) {\n    u64 pos, startPos, maxPos;\n    u8 meta;\n    if (findPosition(key, meta, startPos, maxPos, pos))\n      return &(entries.get()[pos].value());\n\n    return nullptr;\n  }\n\n  ValueType& operator[](const KeyType& key) {\n    Entry* entryArray = entries.get();\n    u64 pos, startPos, maxPos;\n    u8 meta;\n    if (findPosition(key, meta, startPos, maxPos, pos))\n      return entryArray[pos].value();\n\n    if (numElements == ((tableSizeMask + 1) * 7) / 8 || pos == maxPos) {\n      growTable();\n      return (*this)[key];\n    }\n\n    using std::swap;\n    ValueType& insertLocation = entryArray[pos].value();\n    Entry entry(key);\n    ++numElements;\n\n    do {\n      if (!occupied(metadata[pos])) {\n        metadata[pos] = meta;\n        new (&entryArray[pos]) Entry{std::move(entry)};\n        return insertLocation;\n      }\n\n      u64 currentDistance = (pos - startPos) & tableSizeMask;\n      u64 distanceOfCurrentOccupant = distanceFromIdealSlot(pos);\n      if (currentDistance > distanceOfCurrentOccupant) {\n        // steal the position\n        swap(entry, entryArray[pos]);\n        swap(meta, metadata[pos]);\n\n        startPos = (pos - distanceOfCurrentOccupant) & tableSizeMask;\n        maxPos = (startPos + maxDistance()) & tableSizeMask;\n      }\n      pos = (pos + 1) & tableSizeMask;\n    } while (pos != maxPos);\n\n    growTable();\n    insert(std::move(entry));\n    return (*this)[key];\n  }\n\n  template <typename... Args>\n  bool insert(Args&&... args) {\n    Entry entry(std::forward<Args>(args)...);\n\n    u64 pos, startPos, maxPos;\n    u8 meta;\n    if (findPosition(entry.key(), meta, startPos, maxPos, pos)) return false;\n\n    if (numElements == ((tableSizeMask + 1) * 7) / 8 || pos == maxPos) {\n      growTable();\n      return insert(std::move(entry));\n    }\n\n    using std::swap;\n    Entry* entryArray = entries.get();\n    ++numElements;\n\n    do {\n      if (!occupied(metadata[pos])) {\n        metadata[pos] = meta;\n        new (&entryArray[pos]) Entry{std::move(entry)};\n        return true;\n      }\n\n      u64 currentDistance = (pos - startPos) & tableSizeMask;\n      u64 distanceOfCurrentOccupant = distanceFromIdealSlot(pos);\n      if (currentDistance > distanceOfCurrentOccupant) {\n        // steal the position\n        swap(entry, entryArray[pos]);\n        swap(meta, metadata[pos]);\n\n        startPos = (pos - distanceOfCurrentOccupant) & tableSizeMask;\n        maxPos = (startPos + maxDistance()) & tableSizeMask;\n      }\n      pos = (pos + 1) & tableSizeMask;\n    } while (pos != maxPos);\n\n    growTable();\n    insert(std::move(entry));\n    return true;\n  }\n\n  bool erase(const KeyType& key) {\n    u64 pos, startPos, maxPos;\n    u8 meta;\n    if (!findPosition(key, meta, startPos, maxPos, pos)) return false;\n    // delete element at position pos\n    Entry* entryArray = entries.get();\n    entryArray[pos].~Entry();\n    metadata[pos] = 0;\n\n    // retain at least a quarter of slots occupied, otherwise shrink the table\n    // if its not at its minimum size already\n    --numElements;\n    u64 capacity = tableSizeMask + 1;\n    if (capacity != 128 && numElements < capacity / 4) {\n      shrinkTable();\n      return true;\n    }\n\n    // shift elements after pos backwards\n    while (true) {\n      u64 shift = (pos + 1) & tableSizeMask;\n      if (!occupied(metadata[shift])) return true;\n\n      u64 dist = distanceFromIdealSlot(shift);\n      if (dist == 0) return true;\n\n      entryArray[pos] = std::move(entryArray[shift]);\n      metadata[pos] = metadata[shift];\n      metadata[shift] = 0;\n      pos = shift;\n    }\n  }\n\n  i64 size() const { return numElements; }\n\n  HighsHashTable(HighsHashTable<K, V>&&) = default;\n  HighsHashTable<K, V>& operator=(HighsHashTable<K, V>&&) = default;\n\n  ~HighsHashTable() {\n    if (!std::is_trivially_destructible<Entry>::value && metadata) {\n      u64 capacity = tableSizeMask + 1;\n      for (u64 i = 0; i < capacity; ++i) {\n        if (occupied(metadata[i])) entries.get()[i].~Entry();\n      }\n    }\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsHashTree.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_UTIL_HASH_TREE_H_\n#define HIGHS_UTIL_HASH_TREE_H_\n\n#include <stdexcept>\n\n#include \"util/HighsHash.h\"\n\nusing std::memcpy;\nusing std::memmove;\n\ntemplate <typename K, typename V = void>\nclass HighsHashTree {\n  using Entry = HighsHashTableEntry<K, V>;\n  using ValueType =\n      typename std::remove_reference<decltype(Entry().value())>::type;\n\n  enum Type {\n    kEmpty = 0,\n    kListLeaf = 1,\n    kInnerLeafSizeClass1 = 2,\n    kInnerLeafSizeClass2 = 3,\n    kInnerLeafSizeClass3 = 4,\n    kInnerLeafSizeClass4 = 5,\n    kBranchNode = 6,\n  };\n\n  enum Constants {\n    kBitsPerLevel = 6,\n    kBranchFactor = 1 << kBitsPerLevel,\n    // even though we could use up to 64 bits of the hash this would require\n    // additional handling in the last levels to avoid negative shift values\n    // up to 9 depth levels are Ok though as up to index 8 the\n    // get_hash_chunks16() function shifts right by a non-negative amount\n    kMaxDepth = 9,\n    kMinLeafSize = 6,\n    kLeafBurstThreshold = 54,\n  };\n\n  static uint64_t compute_hash(const K& key) {\n    return HighsHashHelpers::hash(key);\n  }\n\n  static uint8_t get_hash_chunk(uint64_t hash, int pos) {\n    return (hash >> (64 - kBitsPerLevel - pos * kBitsPerLevel)) &\n           (kBranchFactor - 1);\n  }\n\n  static uint16_t get_hash_chunks16(uint64_t hash, int pos) {\n    return (hash >> (48 - pos * kBitsPerLevel));\n  }\n\n  static uint8_t get_first_chunk16(uint16_t chunks) {\n    return chunks >> (16 - kBitsPerLevel);\n  }\n\n  static void set_hash_chunk(uint64_t& hash, uint64_t chunk, int chunkPos) {\n    const int shiftAmount = (60 - kBitsPerLevel - chunkPos * kBitsPerLevel);\n    chunk ^= (hash >> shiftAmount) & (kBranchFactor - 1);\n    hash ^= chunk << shiftAmount;\n  }\n\n  struct Occupation {\n    uint64_t occupation;\n\n    Occupation() {}\n    Occupation(uint64_t occupation) : occupation(occupation) {}\n    operator uint64_t() const { return occupation; }\n\n    void set(uint8_t pos) { occupation |= uint64_t{1} << (pos); }\n\n    void flip(uint8_t pos) { occupation ^= uint64_t{1} << (pos); }\n\n    bool test(uint8_t pos) const { return occupation & (uint64_t{1} << pos); }\n\n    int num_set_until(uint8_t pos) const {\n      return HighsHashHelpers::popcnt(occupation >> pos);\n    }\n\n    int num_set_after(uint8_t pos) const {\n      return HighsHashHelpers::popcnt(occupation << (63 - (pos)));\n    }\n\n    int num_set() const { return HighsHashHelpers::popcnt(occupation); }\n  };\n\n  static constexpr int entries_to_size_class(unsigned int numEntries) {\n    return 1 + unsigned(numEntries + ((kLeafBurstThreshold - kMinLeafSize) / 3 -\n                                      kMinLeafSize - 1)) /\n                   ((kLeafBurstThreshold - kMinLeafSize) / 3);\n  }\n\n  template <int kSizeClass>\n  struct InnerLeaf {\n    static constexpr int capacity() {\n      return kMinLeafSize +\n             (kSizeClass - 1) * (kLeafBurstThreshold - kMinLeafSize) / 3;\n    }\n    // the leaf stores entries the same way as inner nodes\n    // but handles collisions on the occupation flag like a\n    // linear probing hash table.\n    // Since the occupation flag has 64 bits and we only use\n    // 15 collisions should be rare and most often we won't need\n    // to do a linear scan and key comparisons at all\n    Occupation occupation;\n    int size;\n    std::array<uint64_t, capacity() + 1> hashes;\n    std::array<Entry, capacity()> entries;\n\n    InnerLeaf() : occupation(0), size(0) { hashes[0] = 0; }\n\n    template <int kOtherSize>\n    InnerLeaf(InnerLeaf<kOtherSize>&& other) {\n      assert(other.size <= capacity());\n      occupation = other.occupation;\n      size = other.size;\n      std::copy(other.hashes.cbegin(),\n                std::next(other.hashes.cbegin(), size + 1), hashes.begin());\n      std::move(other.entries.begin(), std::next(other.entries.begin(), size),\n                entries.begin());\n    }\n\n    int get_num_entries() const { return size; }\n\n    std::pair<ValueType*, bool> insert_entry(uint64_t fullHash, int hashPos,\n                                             Entry& entry) {\n      assert(size < capacity());\n      uint16_t hash = get_hash_chunks16(fullHash, hashPos);\n      uint8_t hashChunk = get_first_chunk16(hash);\n\n      int pos = occupation.num_set_until(hashChunk);\n\n      if (occupation.test(hashChunk)) {\n        // since the occupation flag is set we need to start searching from\n        // pos-1 and can rely on a hash chunk with the same value existing for\n        // the scan\n        --pos;\n        while (hashes[pos] > hash) ++pos;\n\n        if (find_key(entry.key(), hash, pos))\n          return std::make_pair(&entries[pos].value(), false);\n\n      } else {\n        occupation.set(hashChunk);\n\n        if (pos < size)\n          while (hashes[pos] > hash) ++pos;\n      }\n\n      if (pos < size) move_backward(pos, size);\n      entries[pos] = std::move(entry);\n      hashes[pos] = hash;\n      ++size;\n      hashes[size] = 0;\n\n      return std::make_pair(&entries[pos].value(), true);\n    }\n\n    ValueType* find_entry(uint64_t fullHash, int hashPos, const K& key) {\n      uint16_t hash = get_hash_chunks16(fullHash, hashPos);\n      uint8_t hashChunk = get_first_chunk16(hash);\n      if (!occupation.test(hashChunk)) return nullptr;\n\n      int pos = occupation.num_set_until(hashChunk) - 1;\n      while (hashes[pos] > hash) ++pos;\n\n      if (find_key(key, hash, pos)) return &entries[pos].value();\n\n      return nullptr;\n    }\n\n    bool erase_entry(uint64_t fullHash, int hashPos, const K& key) {\n      uint16_t hash = get_hash_chunks16(fullHash, hashPos);\n      uint8_t hashChunk = get_first_chunk16(hash);\n      if (!occupation.test(hashChunk)) return false;\n\n      int startPos = occupation.num_set_until(hashChunk) - 1;\n      while (get_first_chunk16(hashes[startPos]) > hashChunk) ++startPos;\n\n      int pos = startPos;\n      while (hashes[pos] > hash) ++pos;\n\n      if (!find_key(key, hash, pos)) return false;\n\n      --size;\n      if (pos < size) {\n        std::move(std::next(entries.begin(), pos + 1),\n                  std::next(entries.begin(), size + 1),\n                  std::next(entries.begin(), pos));\n        memmove(&hashes[pos], &hashes[pos + 1],\n                sizeof(hashes[0]) * (size - pos));\n        if (get_first_chunk16(hashes[startPos]) != hashChunk)\n          occupation.flip(hashChunk);\n      } else if (startPos == pos)\n        occupation.flip(hashChunk);\n\n      hashes[size] = 0;\n      return true;\n    }\n\n    void rehash(int hashPos) {\n      // function needs to possibly reorder elements by a different hash value\n      // chances are very high we are already ordered correctly as we use 16\n      // bits of the hash and one level is uses 6 bits, so the new values\n      // are guaranteed to be ordered correctly by their 10 most significant\n      // bits if increasing the hash position by 1 and only if the 10 bits of\n      // the hash had a collision the new 6 bits might break a tie differently.\n      // It is, however, important to maintain the exact ordering as otherwise\n      // elements may not be found.\n      occupation = 0;\n      for (int i = 0; i < size; ++i) {\n        hashes[i] = get_hash_chunks16(compute_hash(entries[i].key()), hashPos);\n        occupation.set(get_first_chunk16(hashes[i]));\n      }\n\n      int i = 0;\n      while (i < size) {\n        uint8_t hashChunk = get_first_chunk16(hashes[i]);\n        int pos = occupation.num_set_until(hashChunk) - 1;\n\n        // if the position is after i the element definitely comes later, so we\n        // swap it to that position and proceed without increasing i until\n        // eventually an element appears that comes at position i or before\n        if (pos > i) {\n          std::swap(hashes[pos], hashes[i]);\n          std::swap(entries[pos], entries[i]);\n          continue;\n        }\n\n        // the position is before or at i, now check where the exact location\n        // should be for the ordering by hash so that the invariant is that all\n        // elements up to i are properly sorted. Essentially insertion sort but\n        // with the modification of having a high chance to guess the correct\n        // position already using the occupation flags.\n        while (pos < i && hashes[pos] >= hashes[i]) ++pos;\n\n        // if the final position is before i we need to move elements to\n        // make space at that position, otherwise nothing needs to be done but\n        // incrementing i increasing the sorted range by 1.\n        if (pos < i) {\n          uint64_t hash = hashes[i];\n          auto entry = std::move(entries[i]);\n          move_backward(pos, i);\n          hashes[pos] = hash;\n          entries[pos] = std::move(entry);\n        }\n        ++i;\n      }\n    }\n\n    void move_backward(const int& first, const int& last) {\n      // move elements backwards\n      std::move_backward(std::next(entries.begin(), first),\n                         std::next(entries.begin(), last),\n                         std::next(entries.begin(), last + 1));\n      memmove(&hashes[first + 1], &hashes[first],\n              sizeof(hashes[0]) * (last - first));\n    }\n\n    bool find_key(const K& key, const uint16_t& hash, int& pos) const {\n      // find key\n      while (pos != size && hashes[pos] == hash) {\n        if (key == entries[pos].key()) return true;\n        ++pos;\n      }\n      return false;\n    }\n  };\n\n  struct ListNode {\n    ListNode* next;\n    HighsHashTableEntry<K, V> entry;\n    ListNode(HighsHashTableEntry<K, V>&& entry)\n        : next(nullptr), entry(std::move(entry)) {}\n  };\n  struct ListLeaf {\n    ListNode first;\n    int count;\n\n    ListLeaf(HighsHashTableEntry<K, V>&& entry)\n        : first(std::move(entry)), count(1) {}\n  };\n\n  struct BranchNode;\n\n  struct NodePtr {\n    uintptr_t ptrAndType;\n\n    NodePtr() : ptrAndType(kEmpty) {}\n    NodePtr(std::nullptr_t) : ptrAndType(kEmpty) {}\n    NodePtr(ListLeaf* ptr)\n        : ptrAndType(reinterpret_cast<uintptr_t>(ptr) | kListLeaf) {}\n    NodePtr(InnerLeaf<1>* ptr)\n        : ptrAndType(reinterpret_cast<uintptr_t>(ptr) | kInnerLeafSizeClass1) {}\n    NodePtr(InnerLeaf<2>* ptr)\n        : ptrAndType(reinterpret_cast<uintptr_t>(ptr) | kInnerLeafSizeClass2) {}\n    NodePtr(InnerLeaf<3>* ptr)\n        : ptrAndType(reinterpret_cast<uintptr_t>(ptr) | kInnerLeafSizeClass3) {}\n    NodePtr(InnerLeaf<4>* ptr)\n        : ptrAndType(reinterpret_cast<uintptr_t>(ptr) | kInnerLeafSizeClass4) {}\n    NodePtr(BranchNode* ptr)\n        : ptrAndType(reinterpret_cast<uintptr_t>(ptr) | kBranchNode) {\n      assert(ptr != nullptr);\n    }\n\n    Type getType() const { return Type(ptrAndType & 7u); }\n\n    int numEntriesEstimate() const {\n      switch (getType()) {\n        case kEmpty:\n          return 0;\n        case kListLeaf:\n          return 1;\n        case kInnerLeafSizeClass1:\n          return InnerLeaf<1>::capacity();\n        case kInnerLeafSizeClass2:\n          return InnerLeaf<2>::capacity();\n        case kInnerLeafSizeClass3:\n          return InnerLeaf<3>::capacity();\n        case kInnerLeafSizeClass4:\n          return InnerLeaf<4>::capacity();\n        case kBranchNode:\n          // something large should be returned so that the number of entries\n          // is estimated above the threshold to merge when the parent checks\n          // its children after deletion\n          return kBranchFactor;\n        default:\n          throw std::logic_error(\"Unexpected type in hash tree\");\n      }\n    }\n\n    int numEntries() const {\n      switch (getType()) {\n        case kEmpty:\n          return 0;\n        case kListLeaf:\n          return getListLeaf()->count;\n        case kInnerLeafSizeClass1:\n          return getInnerLeafSizeClass1()->size;\n        case kInnerLeafSizeClass2:\n          return getInnerLeafSizeClass2()->size;\n        case kInnerLeafSizeClass3:\n          return getInnerLeafSizeClass3()->size;\n        case kInnerLeafSizeClass4:\n          return getInnerLeafSizeClass4()->size;\n        case kBranchNode:\n          // something large should be returned so that the number of entries\n          // is estimated above the threshold to merge when the parent checks\n          // its children after deletion\n          return kBranchFactor;\n        default:\n          throw std::logic_error(\"Unexpected type in hash tree\");\n      }\n    }\n\n    ListLeaf* getListLeaf() const {\n      assert(getType() == kListLeaf);\n      return reinterpret_cast<ListLeaf*>(ptrAndType & ~uintptr_t{7});\n    }\n\n    InnerLeaf<1>* getInnerLeafSizeClass1() const {\n      assert(getType() == kInnerLeafSizeClass1);\n      return reinterpret_cast<InnerLeaf<1>*>(ptrAndType & ~uintptr_t{7});\n    }\n    InnerLeaf<2>* getInnerLeafSizeClass2() const {\n      assert(getType() == kInnerLeafSizeClass2);\n      return reinterpret_cast<InnerLeaf<2>*>(ptrAndType & ~uintptr_t{7});\n    }\n\n    InnerLeaf<3>* getInnerLeafSizeClass3() const {\n      assert(getType() == kInnerLeafSizeClass3);\n      return reinterpret_cast<InnerLeaf<3>*>(ptrAndType & ~uintptr_t{7});\n    }\n\n    InnerLeaf<4>* getInnerLeafSizeClass4() const {\n      assert(getType() == kInnerLeafSizeClass4);\n      return reinterpret_cast<InnerLeaf<4>*>(ptrAndType & ~uintptr_t{7});\n    }\n\n    BranchNode* getBranchNode() const {\n      assert(getType() == kBranchNode);\n      return reinterpret_cast<BranchNode*>(ptrAndType & ~uintptr_t{7});\n    }\n  };\n\n  struct BranchNode {\n    Occupation occupation;\n    NodePtr child[1];\n  };\n\n  // allocate branch nodes in multiples of 64 bytes to reduce allocator stress\n  // with different sizes and reduce reallocations of nodes\n  static constexpr size_t getBranchNodeSize(int numChilds) {\n    return (sizeof(BranchNode) + size_t(numChilds - 1) * sizeof(NodePtr) + 63) &\n           ~63;\n  };\n\n  static BranchNode* createBranchingNode(int numChilds) {\n    BranchNode* branch =\n        (BranchNode*)::operator new(getBranchNodeSize(numChilds));\n    branch->occupation = 0;\n    return branch;\n  }\n\n  static void destroyBranchingNode(void* innerNode) {\n    ::operator delete(innerNode);\n  }\n\n  static BranchNode* addChildToBranchNode(BranchNode* branch, uint8_t hashValue,\n                                          int location) {\n    int rightChilds = branch->occupation.num_set_after(hashValue);\n    assert(rightChilds + location == branch->occupation.num_set());\n\n    size_t newSize = getBranchNodeSize(location + rightChilds + 1);\n    size_t rightSize = rightChilds * sizeof(NodePtr);\n\n    if (newSize == getBranchNodeSize(location + rightChilds)) {\n      memmove(&branch->child[location + 1], &branch->child[location],\n              rightSize);\n\n      return branch;\n    }\n\n    BranchNode* newBranch = (BranchNode*)::operator new(newSize);\n    // sizeof(Branch) already contains the size for 1 pointer. So we just\n    // need to add the left and right sizes up for the number of\n    // additional pointers\n    size_t leftSize = sizeof(BranchNode) + (location - 1) * sizeof(NodePtr);\n\n    memcpy(newBranch, branch, leftSize);\n    memcpy(&newBranch->child[location + 1], &branch->child[location],\n           rightSize);\n\n    destroyBranchingNode(branch);\n\n    return newBranch;\n  }\n\n  template <int SizeClass1, int SizeClass2>\n  static void mergeIntoLeaf(InnerLeaf<SizeClass1>* leaf,\n                            InnerLeaf<SizeClass2>* mergeLeaf, int hashPos) {\n    for (int i = 0; i < mergeLeaf->size; ++i)\n      leaf->insert_entry(compute_hash(mergeLeaf->entries[i].key()), hashPos,\n                         mergeLeaf->entries[i]);\n  }\n\n  template <int SizeClass>\n  static void mergeIntoLeaf(InnerLeaf<SizeClass>* leaf, int hashPos,\n                            NodePtr mergeNode) {\n    switch (mergeNode.getType()) {\n      case kListLeaf: {\n        ListLeaf* mergeLeaf = mergeNode.getListLeaf();\n        leaf->insert_entry(compute_hash(mergeLeaf->first.entry.key()), hashPos,\n                           mergeLeaf->first.entry);\n        ListNode* iter = mergeLeaf->first.next;\n        while (iter != nullptr) {\n          ListNode* next = iter->next;\n          leaf->insert_entry(compute_hash(iter->entry.key()), hashPos,\n                             iter->entry);\n          delete iter;\n          iter = next;\n        }\n        break;\n      }\n      case kInnerLeafSizeClass1:\n        mergeIntoLeaf(leaf, mergeNode.getInnerLeafSizeClass1(), hashPos);\n        delete mergeNode.getInnerLeafSizeClass1();\n        break;\n      case kInnerLeafSizeClass2:\n        mergeIntoLeaf(leaf, mergeNode.getInnerLeafSizeClass2(), hashPos);\n        delete mergeNode.getInnerLeafSizeClass2();\n        break;\n      case kInnerLeafSizeClass3:\n        mergeIntoLeaf(leaf, mergeNode.getInnerLeafSizeClass3(), hashPos);\n        delete mergeNode.getInnerLeafSizeClass3();\n        break;\n      case kInnerLeafSizeClass4:\n        mergeIntoLeaf(leaf, mergeNode.getInnerLeafSizeClass4(), hashPos);\n        delete mergeNode.getInnerLeafSizeClass4();\n        break;\n      default:\n        break;\n    }\n  }\n\n  template <int SizeClass1, int SizeClass2>\n  static HighsHashTableEntry<K, V>* findCommonInLeaf(\n      InnerLeaf<SizeClass1>* leaf1, InnerLeaf<SizeClass2>* leaf2, int hashPos) {\n    uint64_t matchMask = leaf1->occupation & leaf2->occupation;\n    if (matchMask == 0) return nullptr;\n\n    int offset1 = -1;\n    int offset2 = -1;\n    while (matchMask) {\n      int pos = HighsHashHelpers::log2i(matchMask);\n      matchMask ^= (uint64_t{1} << pos);\n\n      int i =\n          leaf1->occupation.num_set_until(static_cast<uint8_t>(pos)) + offset1;\n      while (get_first_chunk16(leaf1->hashes[i]) != pos) {\n        ++i;\n        ++offset1;\n      }\n\n      int j =\n          leaf2->occupation.num_set_until(static_cast<uint8_t>(pos)) + offset2;\n      while (get_first_chunk16(leaf2->hashes[j]) != pos) {\n        ++j;\n        ++offset2;\n      }\n\n      while (true) {\n        if (leaf1->hashes[i] > leaf2->hashes[j]) {\n          ++i;\n          if (i == leaf1->size || get_first_chunk16(leaf1->hashes[i]) != pos)\n            break;\n        } else if (leaf2->hashes[j] > leaf1->hashes[i]) {\n          ++j;\n          if (j == leaf2->size || get_first_chunk16(leaf2->hashes[j]) != pos)\n            break;\n        } else {\n          if (leaf1->entries[i].key() == leaf2->entries[j].key())\n            return &leaf1->entries[i];\n\n          ++i;\n          if (i == leaf1->size || get_first_chunk16(leaf1->hashes[i]) != pos)\n            break;\n          ++j;\n          if (j == leaf2->size || get_first_chunk16(leaf2->hashes[j]) != pos)\n            break;\n        }\n      };\n    }\n\n    return nullptr;\n  }\n\n  template <int SizeClass>\n  static HighsHashTableEntry<K, V>* findCommonInLeaf(InnerLeaf<SizeClass>* leaf,\n                                                     NodePtr n2, int hashPos) {\n    switch (n2.getType()) {\n      case kInnerLeafSizeClass1:\n        return findCommonInLeaf(leaf, n2.getInnerLeafSizeClass1(), hashPos);\n      case kInnerLeafSizeClass2:\n        return findCommonInLeaf(leaf, n2.getInnerLeafSizeClass2(), hashPos);\n      case kInnerLeafSizeClass3:\n        return findCommonInLeaf(leaf, n2.getInnerLeafSizeClass3(), hashPos);\n      case kInnerLeafSizeClass4:\n        return findCommonInLeaf(leaf, n2.getInnerLeafSizeClass4(), hashPos);\n      case kBranchNode: {\n        BranchNode* branch = n2.getBranchNode();\n        uint64_t matchMask = branch->occupation & leaf->occupation;\n\n        int offset = -1;\n        while (matchMask) {\n          int pos = HighsHashHelpers::log2i(matchMask);\n          matchMask ^= (uint64_t{1} << pos);\n\n          int i = leaf->occupation.num_set_until(static_cast<uint8_t>(pos)) +\n                  offset;\n          while (get_first_chunk16(leaf->hashes[i]) != pos) {\n            ++i;\n            ++offset;\n          }\n\n          int j =\n              branch->occupation.num_set_until(static_cast<uint8_t>(pos)) - 1;\n\n          do {\n            if (find_recurse(branch->child[j],\n                             compute_hash(leaf->entries[i].key()), hashPos + 1,\n                             leaf->entries[i].key()))\n              return &leaf->entries[i];\n            ++i;\n          } while (i < leaf->size && get_first_chunk16(leaf->hashes[i]) == pos);\n        }\n        break;\n      }\n      default:\n        break;\n    }\n\n    return nullptr;\n  }\n\n  static NodePtr removeChildFromBranchNode(BranchNode* branch, int location,\n                                           uint64_t hash, int hashPos) {\n    NodePtr newNode;\n    int newNumChild = branch->occupation.num_set();\n\n    // first check if we might be able to merge all children into one new leaf\n    // based on the node numbers and assuming all of them might be in the\n    // smallest size class\n    if (newNumChild * InnerLeaf<1>::capacity() <= kLeafBurstThreshold) {\n      // since we have a good chance of merging we now check the actual size\n      // classes to see if that yields a number of entries at most the burst\n      // threshold\n      int childEntries = 0;\n      for (int i = 0; i <= newNumChild; ++i) {\n        childEntries += branch->child[i].numEntriesEstimate();\n        if (childEntries > kLeafBurstThreshold) break;\n      }\n\n      if (childEntries < kLeafBurstThreshold) {\n        // create a new merged inner leaf node containing all entries of\n        // children first recompute the number of entries, but this time access\n        // each child to get the actual number of entries needed and determine\n        // this nodes size class since before we estimated the number of child\n        // entries from the capacities of our child leaf node types which are\n        // stored in the branch nodes pointers directly and avoid unnecessary\n        // accesses of nodes that are not in cache.\n        childEntries = 0;\n        for (int i = 0; i <= newNumChild; ++i)\n          childEntries += branch->child[i].numEntries();\n\n        // check again if we exceed due to the extremely unlikely case\n        // of having less than 5 list nodes with together more than 30 entries\n        // as list nodes are only created in the last depth level\n        if (childEntries < kLeafBurstThreshold) {\n          switch (entries_to_size_class(childEntries)) {\n            case 1: {\n              InnerLeaf<1>* newLeafSize1 = new InnerLeaf<1>;\n              newNode = newLeafSize1;\n              for (int i = 0; i <= newNumChild; ++i)\n                mergeIntoLeaf(newLeafSize1, hashPos, branch->child[i]);\n              break;\n            }\n            case 2: {\n              InnerLeaf<2>* newLeafSize2 = new InnerLeaf<2>;\n              newNode = newLeafSize2;\n              for (int i = 0; i <= newNumChild; ++i)\n                mergeIntoLeaf(newLeafSize2, hashPos, branch->child[i]);\n              break;\n            }\n            case 3: {\n              InnerLeaf<3>* newLeafSize3 = new InnerLeaf<3>;\n              newNode = newLeafSize3;\n              for (int i = 0; i <= newNumChild; ++i)\n                mergeIntoLeaf(newLeafSize3, hashPos, branch->child[i]);\n              break;\n            }\n            case 4: {\n              InnerLeaf<4>* newLeafSize4 = new InnerLeaf<4>;\n              newNode = newLeafSize4;\n              for (int i = 0; i <= newNumChild; ++i)\n                mergeIntoLeaf(newLeafSize4, hashPos, branch->child[i]);\n              break;\n            }\n            default:\n              // Unexpected result from 'entries_to_size_class'\n              assert(false);\n          }\n\n          destroyBranchingNode(branch);\n          return newNode;\n        }\n      }\n    }\n\n    size_t newSize = getBranchNodeSize(newNumChild);\n    size_t rightSize = (newNumChild - location) * sizeof(NodePtr);\n    if (newSize == getBranchNodeSize(newNumChild + 1)) {\n      // allocated size class is the same, so we do not allocate a new node\n      memmove(&branch->child[location], &branch->child[location + 1],\n              rightSize);\n      newNode = branch;\n    } else {\n      // allocated size class changed, so we allocate a smaller branch node\n      BranchNode* compressedBranch = (BranchNode*)::operator new(newSize);\n      newNode = compressedBranch;\n\n      size_t leftSize =\n          offsetof(BranchNode, child) + location * sizeof(NodePtr);\n      memcpy(compressedBranch, branch, leftSize);\n      memcpy(&compressedBranch->child[location], &branch->child[location + 1],\n             rightSize);\n\n      destroyBranchingNode(branch);\n    }\n\n    return newNode;\n  }\n\n  NodePtr root;\n\n  template <int SizeClass>\n  static std::pair<ValueType*, bool> insert_into_leaf(\n      NodePtr* insertNode, InnerLeaf<SizeClass>* leaf, uint64_t hash,\n      int hashPos, HighsHashTableEntry<K, V>& entry) {\n    if (leaf->size == InnerLeaf<SizeClass>::capacity()) {\n      auto existingEntry = leaf->find_entry(hash, hashPos, entry.key());\n      if (existingEntry) return std::make_pair(existingEntry, false);\n\n      InnerLeaf<SizeClass + 1>* newLeaf =\n          new InnerLeaf<SizeClass + 1>(std::move(*leaf));\n      *insertNode = newLeaf;\n      delete leaf;\n      return newLeaf->insert_entry(hash, hashPos, entry);\n    }\n\n    return leaf->insert_entry(hash, hashPos, entry);\n  }\n\n  static std::pair<ValueType*, bool> insert_recurse(\n      NodePtr* insertNode, uint64_t hash, int hashPos,\n      HighsHashTableEntry<K, V>& entry) {\n    switch (insertNode->getType()) {\n      case kEmpty: {\n        if (hashPos == kMaxDepth) {\n          ListLeaf* leaf = new ListLeaf(std::move(entry));\n          *insertNode = leaf;\n          return std::make_pair(&leaf->first.entry.value(), true);\n        } else {\n          InnerLeaf<1>* leaf = new InnerLeaf<1>;\n          *insertNode = leaf;\n          return leaf->insert_entry(hash, hashPos, entry);\n        }\n      }\n      case kListLeaf: {\n        ListLeaf* leaf = insertNode->getListLeaf();\n        ListNode* iter = &leaf->first;\n        while (true) {\n          // check for existing key\n          if (iter->entry.key() == entry.key())\n            return std::make_pair(&iter->entry.value(), false);\n\n          if (iter->next == nullptr) {\n            // reached the end of the list and key is not duplicate, so insert\n            iter->next = new ListNode(std::move(entry));\n            ++leaf->count;\n            return std::make_pair(&iter->next->entry.value(), true);\n          }\n          iter = iter->next;\n        }\n\n        break;\n      }\n      case kInnerLeafSizeClass1:\n        return insert_into_leaf(insertNode,\n                                insertNode->getInnerLeafSizeClass1(), hash,\n                                hashPos, entry);\n        break;\n      case kInnerLeafSizeClass2:\n        return insert_into_leaf(insertNode,\n                                insertNode->getInnerLeafSizeClass2(), hash,\n                                hashPos, entry);\n        break;\n      case kInnerLeafSizeClass3:\n        return insert_into_leaf(insertNode,\n                                insertNode->getInnerLeafSizeClass3(), hash,\n                                hashPos, entry);\n        break;\n      case kInnerLeafSizeClass4: {\n        InnerLeaf<4>* leaf = insertNode->getInnerLeafSizeClass4();\n        if (leaf->size < InnerLeaf<4>::capacity())\n          return leaf->insert_entry(hash, hashPos, entry);\n\n        auto existingEntry = leaf->find_entry(hash, hashPos, entry.key());\n        if (existingEntry) return std::make_pair(existingEntry, false);\n        Occupation occupation = leaf->occupation;\n\n        uint8_t hashChunk = get_hash_chunk(hash, hashPos);\n        occupation.set(hashChunk);\n\n        int branchSize = occupation.num_set();\n\n        BranchNode* branch = createBranchingNode(branchSize);\n        *insertNode = branch;\n        branch->occupation = occupation;\n\n        if (hashPos + 1 == kMaxDepth) {\n          for (int i = 0; i < branchSize; ++i) branch->child[i] = nullptr;\n\n          for (int i = 0; i < leaf->size; ++i) {\n            int pos =\n                occupation.num_set_until(get_first_chunk16(leaf->hashes[i])) -\n                1;\n            if (branch->child[pos].getType() == kEmpty)\n              branch->child[pos] = new ListLeaf(std::move(leaf->entries[i]));\n            else {\n              ListLeaf* listLeaf = branch->child[pos].getListLeaf();\n              ListNode* newNode = new ListNode(std::move(listLeaf->first));\n              listLeaf->first.next = newNode;\n              listLeaf->first.entry = std::move(leaf->entries[i]);\n              ++listLeaf->count;\n            }\n          }\n\n          delete leaf;\n\n          ListLeaf* listLeaf;\n\n          int pos = occupation.num_set_until(get_hash_chunk(hash, hashPos)) - 1;\n          if (branch->child[pos].getType() == kEmpty) {\n            listLeaf = new ListLeaf(std::move(entry));\n            branch->child[pos] = listLeaf;\n          } else {\n            listLeaf = branch->child[pos].getListLeaf();\n            ListNode* newNode = new ListNode(std::move(listLeaf->first));\n            listLeaf->first.next = newNode;\n            listLeaf->first.entry = std::move(entry);\n            ++listLeaf->count;\n          }\n\n          return std::make_pair(&listLeaf->first.entry.value(), true);\n        }\n\n        if (branchSize > 1) {\n          // maxsize in one bucket = number of items - (num buckets-1)\n          // since each bucket has at least 1 item the largest one can only\n          // have all remaining ones After adding the item: If it does not\n          // collide\n          int maxEntriesPerLeaf = 2 + leaf->size - branchSize;\n\n          if (maxEntriesPerLeaf <= InnerLeaf<1>::capacity()) {\n            // all items can go into the smallest leaf size\n            for (int i = 0; i < branchSize; ++i)\n              branch->child[i] = new InnerLeaf<1>;\n\n            for (int i = 0; i < leaf->size; ++i) {\n              int pos =\n                  occupation.num_set_until(get_first_chunk16(leaf->hashes[i])) -\n                  1;\n              branch->child[pos].getInnerLeafSizeClass1()->insert_entry(\n                  compute_hash(leaf->entries[i].key()), hashPos + 1,\n                  leaf->entries[i]);\n            }\n\n            delete leaf;\n\n            int pos =\n                occupation.num_set_until(get_hash_chunk(hash, hashPos)) - 1;\n            return branch->child[pos].getInnerLeafSizeClass1()->insert_entry(\n                hash, hashPos + 1, entry);\n          } else {\n            // there are many collisions, determine the exact sizes first\n            std::array<uint8_t, InnerLeaf<4>::capacity() + 1> sizes = {};\n            sizes[occupation.num_set_until(hashChunk) - 1] += 1;\n            for (int i = 0; i < leaf->size; ++i) {\n              int pos =\n                  occupation.num_set_until(get_first_chunk16(leaf->hashes[i])) -\n                  1;\n              sizes[pos] += 1;\n            }\n\n            for (int i = 0; i < branchSize; ++i) {\n              switch (entries_to_size_class(sizes[i])) {\n                case 1:\n                  branch->child[i] = new InnerLeaf<1>;\n                  break;\n                case 2:\n                  branch->child[i] = new InnerLeaf<2>;\n                  break;\n                case 3:\n                  branch->child[i] = new InnerLeaf<3>;\n                  break;\n                case 4:\n                  branch->child[i] = new InnerLeaf<4>;\n                  break;\n                default:\n                  // Unexpected result from 'entries_to_size_class'\n                  assert(false);\n              }\n            }\n\n            for (int i = 0; i < leaf->size; ++i) {\n              int pos =\n                  occupation.num_set_until(get_first_chunk16(leaf->hashes[i])) -\n                  1;\n\n              switch (branch->child[pos].getType()) {\n                case kInnerLeafSizeClass1:\n                  branch->child[pos].getInnerLeafSizeClass1()->insert_entry(\n                      compute_hash(leaf->entries[i].key()), hashPos + 1,\n                      leaf->entries[i]);\n                  break;\n                case kInnerLeafSizeClass2:\n                  branch->child[pos].getInnerLeafSizeClass2()->insert_entry(\n                      compute_hash(leaf->entries[i].key()), hashPos + 1,\n                      leaf->entries[i]);\n                  break;\n                case kInnerLeafSizeClass3:\n                  branch->child[pos].getInnerLeafSizeClass3()->insert_entry(\n                      compute_hash(leaf->entries[i].key()), hashPos + 1,\n                      leaf->entries[i]);\n                  break;\n                case kInnerLeafSizeClass4:\n                  branch->child[pos].getInnerLeafSizeClass4()->insert_entry(\n                      compute_hash(leaf->entries[i].key()), hashPos + 1,\n                      leaf->entries[i]);\n                  break;\n                default:\n                  break;\n              }\n            }\n          }\n\n          delete leaf;\n\n          int pos = occupation.num_set_until(hashChunk) - 1;\n          insertNode = &branch->child[pos];\n          ++hashPos;\n        } else {\n          // extremely unlikely that the new branch node only gets one\n          // child in that case create it and defer the insertion into\n          // the next depth\n          branch->child[0] = leaf;\n          insertNode = &branch->child[0];\n          ++hashPos;\n          leaf->rehash(hashPos);\n        }\n\n        break;\n      }\n      case kBranchNode: {\n        BranchNode* branch = insertNode->getBranchNode();\n\n        int location =\n            branch->occupation.num_set_until(get_hash_chunk(hash, hashPos));\n\n        if (branch->occupation.test(get_hash_chunk(hash, hashPos))) {\n          --location;\n        } else {\n          branch = addChildToBranchNode(branch, get_hash_chunk(hash, hashPos),\n                                        location);\n\n          branch->child[location] = nullptr;\n          branch->occupation.set(get_hash_chunk(hash, hashPos));\n        }\n\n        *insertNode = branch;\n        insertNode = &branch->child[location];\n        ++hashPos;\n      }\n    }\n\n    return insert_recurse(insertNode, hash, hashPos, entry);\n  }\n\n  static void erase_recurse(NodePtr* erase_node, uint64_t hash, int hashPos,\n                            const K& key) {\n    switch (erase_node->getType()) {\n      case kEmpty: {\n        return;\n      }\n      case kListLeaf: {\n        ListLeaf* leaf = erase_node->getListLeaf();\n\n        // check for existing key\n        ListNode* iter = &leaf->first;\n\n        do {\n          ListNode* next = iter->next;\n          if (iter->entry.key() == key) {\n            // key found, decrease count\n            --leaf->count;\n            if (next != nullptr) {\n              // if we have a next node after replace the entry in iter by\n              // moving that node into it\n              *iter = std::move(*next);\n              // delete memory of that node\n              delete next;\n            }\n\n            break;\n          }\n\n          iter = next;\n        } while (iter != nullptr);\n\n        if (leaf->count == 0) {\n          delete leaf;\n          *erase_node = nullptr;\n        }\n\n        return;\n      }\n      case kInnerLeafSizeClass1: {\n        InnerLeaf<1>* leaf = erase_node->getInnerLeafSizeClass1();\n        if (leaf->erase_entry(hash, hashPos, key)) {\n          if (leaf->size == 0) {\n            delete leaf;\n            *erase_node = nullptr;\n          }\n        }\n\n        return;\n      }\n      case kInnerLeafSizeClass2: {\n        InnerLeaf<2>* leaf = erase_node->getInnerLeafSizeClass2();\n\n        if (leaf->erase_entry(hash, hashPos, key)) {\n          if (leaf->size == InnerLeaf<1>::capacity()) {\n            InnerLeaf<1>* newLeaf = new InnerLeaf<1>(std::move(*leaf));\n            *erase_node = newLeaf;\n            delete leaf;\n          }\n        }\n\n        return;\n      }\n      case kInnerLeafSizeClass3: {\n        InnerLeaf<3>* leaf = erase_node->getInnerLeafSizeClass3();\n\n        if (leaf->erase_entry(hash, hashPos, key)) {\n          if (leaf->size == InnerLeaf<2>::capacity()) {\n            InnerLeaf<2>* newLeaf = new InnerLeaf<2>(std::move(*leaf));\n            *erase_node = newLeaf;\n            delete leaf;\n          }\n        }\n\n        return;\n      }\n      case kInnerLeafSizeClass4: {\n        InnerLeaf<4>* leaf = erase_node->getInnerLeafSizeClass4();\n\n        if (leaf->erase_entry(hash, hashPos, key)) {\n          if (leaf->size == InnerLeaf<3>::capacity()) {\n            InnerLeaf<3>* newLeaf = new InnerLeaf<3>(std::move(*leaf));\n            *erase_node = newLeaf;\n            delete leaf;\n          }\n        }\n\n        return;\n      }\n      case kBranchNode: {\n        BranchNode* branch = erase_node->getBranchNode();\n\n        if (!branch->occupation.test(get_hash_chunk(hash, hashPos))) return;\n\n        int location =\n            branch->occupation.num_set_until(get_hash_chunk(hash, hashPos)) - 1;\n        erase_recurse(&branch->child[location], hash, hashPos + 1, key);\n\n        if (branch->child[location].getType() != kEmpty) return;\n\n        branch->occupation.flip(get_hash_chunk(hash, hashPos));\n\n        *erase_node =\n            removeChildFromBranchNode(branch, location, hash, hashPos);\n        break;\n      }\n    }\n  }\n\n  static const ValueType* find_recurse(NodePtr node, uint64_t hash, int hashPos,\n                                       const K& key) {\n    int startPos = hashPos;\n    switch (node.getType()) {\n      case kEmpty:\n        return nullptr;\n      case kListLeaf: {\n        ListLeaf* leaf = node.getListLeaf();\n        ListNode* iter = &leaf->first;\n        do {\n          if (iter->entry.key() == key) return &iter->entry.value();\n          iter = iter->next;\n        } while (iter != nullptr);\n        return nullptr;\n      }\n      case kInnerLeafSizeClass1: {\n        InnerLeaf<1>* leaf = node.getInnerLeafSizeClass1();\n        return leaf->find_entry(hash, hashPos, key);\n      }\n      case kInnerLeafSizeClass2: {\n        InnerLeaf<2>* leaf = node.getInnerLeafSizeClass2();\n        return leaf->find_entry(hash, hashPos, key);\n      }\n      case kInnerLeafSizeClass3: {\n        InnerLeaf<3>* leaf = node.getInnerLeafSizeClass3();\n        return leaf->find_entry(hash, hashPos, key);\n      }\n      case kInnerLeafSizeClass4: {\n        InnerLeaf<4>* leaf = node.getInnerLeafSizeClass4();\n        return leaf->find_entry(hash, hashPos, key);\n      }\n      case kBranchNode: {\n        BranchNode* branch = node.getBranchNode();\n        if (!branch->occupation.test(get_hash_chunk(hash, hashPos)))\n          return nullptr;\n        int location =\n            branch->occupation.num_set_until(get_hash_chunk(hash, hashPos)) - 1;\n        node = branch->child[location];\n        ++hashPos;\n      }\n    }\n\n    assert(hashPos > startPos);\n\n    return find_recurse(node, hash, hashPos, key);\n  }\n\n  static const HighsHashTableEntry<K, V>* find_common_recurse(NodePtr n1,\n                                                              NodePtr n2,\n                                                              int hashPos) {\n    if (n1.getType() > n2.getType()) std::swap(n1, n2);\n\n    switch (n1.getType()) {\n      case kEmpty:\n        return nullptr;\n      case kListLeaf: {\n        ListLeaf* leaf = n1.getListLeaf();\n        ListNode* iter = &leaf->first;\n        do {\n          if (find_recurse(n2, compute_hash(iter->entry.key()), hashPos,\n                           iter->entry.key()))\n            return &iter->entry;\n          iter = iter->next;\n        } while (iter != nullptr);\n        return nullptr;\n      }\n      case kInnerLeafSizeClass1:\n        return findCommonInLeaf(n1.getInnerLeafSizeClass1(), n2, hashPos);\n      case kInnerLeafSizeClass2:\n        return findCommonInLeaf(n1.getInnerLeafSizeClass2(), n2, hashPos);\n      case kInnerLeafSizeClass3:\n        return findCommonInLeaf(n1.getInnerLeafSizeClass3(), n2, hashPos);\n      case kInnerLeafSizeClass4:\n        return findCommonInLeaf(n1.getInnerLeafSizeClass4(), n2, hashPos);\n      case kBranchNode: {\n        BranchNode* branch1 = n1.getBranchNode();\n        BranchNode* branch2 = n2.getBranchNode();\n\n        uint64_t matchMask = branch1->occupation & branch2->occupation;\n\n        while (matchMask) {\n          int pos = HighsHashHelpers::log2i(matchMask);\n          assert((branch1->occupation >> pos) & 1);\n          assert((branch2->occupation >> pos) & 1);\n          assert((matchMask >> pos) & 1);\n\n          matchMask ^= (uint64_t{1} << pos);\n\n          assert(((matchMask >> pos) & 1) == 0);\n\n          int location1 =\n              branch1->occupation.num_set_until(static_cast<uint8_t>(pos)) - 1;\n          int location2 =\n              branch2->occupation.num_set_until(static_cast<uint8_t>(pos)) - 1;\n\n          const HighsHashTableEntry<K, V>* match =\n              find_common_recurse(branch1->child[location1],\n                                  branch2->child[location2], hashPos + 1);\n          if (match != nullptr) return match;\n        }\n\n        return nullptr;\n      }\n      default:\n        throw std::logic_error(\"Unexpected type in hash tree\");\n    }\n  }\n\n  static void destroy_recurse(NodePtr node) {\n    switch (node.getType()) {\n      case kEmpty:\n        break;\n      case kListLeaf: {\n        ListLeaf* leaf = node.getListLeaf();\n        ListNode* iter = leaf->first.next;\n        delete leaf;\n        while (iter != nullptr) {\n          ListNode* next = iter->next;\n          delete iter;\n          iter = next;\n        }\n\n        break;\n      }\n      case kInnerLeafSizeClass1:\n        delete node.getInnerLeafSizeClass1();\n        break;\n      case kInnerLeafSizeClass2:\n        delete node.getInnerLeafSizeClass2();\n        break;\n      case kInnerLeafSizeClass3:\n        delete node.getInnerLeafSizeClass3();\n        break;\n      case kInnerLeafSizeClass4:\n        delete node.getInnerLeafSizeClass4();\n        break;\n      case kBranchNode: {\n        BranchNode* branch = node.getBranchNode();\n        int size = branch->occupation.num_set();\n\n        for (int i = 0; i < size; ++i) destroy_recurse(branch->child[i]);\n\n        destroyBranchingNode(branch);\n      }\n    }\n  }\n\n  static NodePtr copy_recurse(NodePtr node) {\n    switch (node.getType()) {\n      case kEmpty:\n        throw std::logic_error(\"Unexpected node type in empty in hash tree\");\n      case kListLeaf: {\n        ListLeaf* leaf = node.getListLeaf();\n\n        ListLeaf* copyLeaf = new ListLeaf(*leaf);\n\n        ListNode* iter = &leaf->first;\n        ListNode* copyIter = &copyLeaf->first;\n        do {\n          copyIter->next = new ListNode(*iter->next);\n          iter = iter->next;\n          copyIter = copyIter->next;\n        } while (iter->next != nullptr);\n\n        return copyLeaf;\n      }\n      case kInnerLeafSizeClass1: {\n        InnerLeaf<1>* leaf = node.getInnerLeafSizeClass1();\n        return new InnerLeaf<1>(*leaf);\n      }\n      case kInnerLeafSizeClass2: {\n        InnerLeaf<2>* leaf = node.getInnerLeafSizeClass2();\n        return new InnerLeaf<2>(*leaf);\n      }\n      case kInnerLeafSizeClass3: {\n        InnerLeaf<3>* leaf = node.getInnerLeafSizeClass3();\n        return new InnerLeaf<3>(*leaf);\n      }\n      case kInnerLeafSizeClass4: {\n        InnerLeaf<4>* leaf = node.getInnerLeafSizeClass4();\n        return new InnerLeaf<4>(*leaf);\n      }\n      case kBranchNode: {\n        BranchNode* branch = node.getBranchNode();\n        int size = branch->occupation.num_set();\n        BranchNode* newBranch =\n            (BranchNode*)::operator new(getBranchNodeSize(size));\n        newBranch->occupation = branch->occupation;\n        for (int i = 0; i < size; ++i)\n          newBranch->child[i] = copy_recurse(branch->child[i]);\n\n        return newBranch;\n      }\n      default:\n        throw std::logic_error(\"Unexpected type in hash tree\");\n    }\n  }\n\n  template <typename R, typename F,\n            typename std::enable_if<std::is_void<R>::value, int>::type = 0>\n  static void for_each_recurse(NodePtr node, F&& f) {\n    switch (node.getType()) {\n      case kEmpty:\n        break;\n      case kListLeaf: {\n        ListLeaf* leaf = node.getListLeaf();\n        ListNode* iter = &leaf->first;\n        do {\n          iter->entry.forward(f);\n          iter = iter->next;\n        } while (iter != nullptr);\n        break;\n      }\n      case kInnerLeafSizeClass1: {\n        InnerLeaf<1>* leaf = node.getInnerLeafSizeClass1();\n        for (int i = 0; i < leaf->size; ++i) leaf->entries[i].forward(f);\n\n        break;\n      }\n      case kInnerLeafSizeClass2: {\n        InnerLeaf<2>* leaf = node.getInnerLeafSizeClass2();\n        for (int i = 0; i < leaf->size; ++i) leaf->entries[i].forward(f);\n\n        break;\n      }\n      case kInnerLeafSizeClass3: {\n        InnerLeaf<3>* leaf = node.getInnerLeafSizeClass3();\n        for (int i = 0; i < leaf->size; ++i) leaf->entries[i].forward(f);\n\n        break;\n      }\n      case kInnerLeafSizeClass4: {\n        InnerLeaf<4>* leaf = node.getInnerLeafSizeClass4();\n        for (int i = 0; i < leaf->size; ++i) leaf->entries[i].forward(f);\n\n        break;\n      }\n      case kBranchNode: {\n        BranchNode* branch = node.getBranchNode();\n        int size = branch->occupation.num_set();\n\n        for (int i = 0; i < size; ++i) for_each_recurse<R>(branch->child[i], f);\n      }\n    }\n  }\n\n  template <typename R, typename F,\n            typename std::enable_if<!std::is_void<R>::value, int>::type = 0>\n  static R for_each_recurse(NodePtr node, F&& f) {\n    switch (node.getType()) {\n      case kEmpty:\n        break;\n      case kListLeaf: {\n        ListLeaf* leaf = node.getListLeaf();\n        ListNode* iter = &leaf->first;\n        do {\n          auto x = iter->entry.forward(f);\n          if (x) return x;\n          iter = iter->next;\n        } while (iter != nullptr);\n        break;\n      }\n      case kInnerLeafSizeClass1: {\n        InnerLeaf<1>* leaf = node.getInnerLeafSizeClass1();\n        for (int i = 0; i < leaf->size; ++i) {\n          auto x = leaf->entries[i].forward(f);\n          if (x) return x;\n        }\n\n        break;\n      }\n      case kInnerLeafSizeClass2: {\n        InnerLeaf<2>* leaf = node.getInnerLeafSizeClass2();\n        for (int i = 0; i < leaf->size; ++i) {\n          auto x = leaf->entries[i].forward(f);\n          if (x) return x;\n        }\n\n        break;\n      }\n      case kInnerLeafSizeClass3: {\n        InnerLeaf<3>* leaf = node.getInnerLeafSizeClass3();\n        for (int i = 0; i < leaf->size; ++i) {\n          auto x = leaf->entries[i].forward(f);\n          if (x) return x;\n        }\n\n        break;\n      }\n      case kInnerLeafSizeClass4: {\n        InnerLeaf<4>* leaf = node.getInnerLeafSizeClass4();\n        for (int i = 0; i < leaf->size; ++i) {\n          auto x = leaf->entries[i].forward(f);\n          if (x) return x;\n        }\n\n        break;\n      }\n      case kBranchNode: {\n        BranchNode* branch = node.getBranchNode();\n        int size = branch->occupation.num_set();\n\n        for (int i = 0; i < size; ++i) {\n          auto x = for_each_recurse<R>(branch->child[i], f);\n          if (x) return x;\n        }\n      }\n    }\n\n    return R();\n  }\n\n public:\n  template <typename... Args>\n  bool insert(Args&&... args) {\n    HighsHashTableEntry<K, V> entry(std::forward<Args>(args)...);\n    uint64_t hash = compute_hash(entry.key());\n    return insert_recurse(&root, hash, 0, entry).second;\n  }\n\n  template <typename... Args>\n  std::pair<ValueType*, bool> insert_or_get(Args&&... args) {\n    HighsHashTableEntry<K, V> entry(std::forward<Args>(args)...);\n    uint64_t hash = compute_hash(entry.key());\n    return insert_recurse(&root, hash, 0, entry);\n  }\n\n  void erase(const K& key) {\n    uint64_t hash = compute_hash(key);\n\n    erase_recurse(&root, hash, 0, key);\n  }\n\n  bool contains(const K& key) const {\n    uint64_t hash = compute_hash(key);\n    return find_recurse(root, hash, 0, key) != nullptr;\n  }\n\n  const ValueType* find(const K& key) const {\n    uint64_t hash = compute_hash(key);\n\n    return find_recurse(root, hash, 0, key);\n  }\n\n  ValueType* find(const K& key) {\n    uint64_t hash = compute_hash(key);\n\n    return find_recurse(root, hash, 0, key);\n  }\n\n  const HighsHashTableEntry<K, V>* find_common(\n      const HighsHashTree<K, V>& other) const {\n    return find_common_recurse(root, other.root, 0);\n  }\n\n  bool empty() const { return root.getType() == kEmpty; }\n\n  void clear() {\n    destroy_recurse(root);\n    root = nullptr;\n  }\n\n  template <typename F>\n  auto for_each(F&& f) const\n      -> decltype(HighsHashTableEntry<K, V>().forward(f)) {\n    using R = decltype(for_each(f));\n    return for_each_recurse<R>(root, f);\n  }\n\n  HighsHashTree() = default;\n\n  HighsHashTree(HighsHashTree&& other) : root(other.root) {\n    other.root = nullptr;\n  }\n\n  HighsHashTree(const HighsHashTree& other) : root(copy_recurse(other.root)) {}\n\n  HighsHashTree& operator=(HighsHashTree&& other) {\n    destroy_recurse(root);\n    root = other.root;\n    other.root = nullptr;\n    return *this;\n  }\n\n  HighsHashTree& operator=(const HighsHashTree& other) {\n    destroy_recurse(root);\n    root = copy_recurse(other.root);\n    return *this;\n  }\n\n  ~HighsHashTree() { destroy_recurse(root); }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsInt.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file HighsInt.h\n * @brief The definition for the integer type to use\n */\n\n#ifndef UTIL_HIGHS_INT_H_\n#define UTIL_HIGHS_INT_H_\n\n#include <stdint.h>\n\n#ifdef __cplusplus\n#ifndef __STDC_FORMAT_MACROS\n#define __STDC_FORMAT_MACROS\n#endif\n#endif\n#include <inttypes.h>\n\n#include \"HConfig.h\"\n\n#ifdef HIGHSINT64\ntypedef int64_t HighsInt;\ntypedef uint64_t HighsUInt;\n#define HIGHSINT_FORMAT PRId64\n#else\ntypedef int HighsInt;\ntypedef unsigned int HighsUInt;\n#define HIGHSINT_FORMAT \"d\"\n#endif\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsIntegers.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_UTIL_INTEGERS_H_\n#define HIGHS_UTIL_INTEGERS_H_\n\n#include <algorithm>\n#include <cassert>\n#include <cmath>\n#include <cstdint>\n#include <limits>\n#include <vector>\n\n#include \"util/HighsCDouble.h\"\n#include \"util/HighsInt.h\"\n\nclass HighsIntegers {\n public:\n  static int64_t mod(int64_t a, int64_t m) {\n    int64_t r = a % m;\n    return r + (r < 0) * m;\n  }\n\n  static double mod(double a, double m) {\n    return std::trunc(std::fmod(a, m)) + (a < 0) * m;\n  }\n\n  static int64_t nearestInteger(double x) {\n    return (int64_t)(x + std::copysign(0.5, x));\n  }\n\n  static bool isIntegral(double x, double eps) {\n    double y = std::fabs(x - std::trunc(x));\n    return std::min(y, 1.0 - y) <= eps;\n  }\n\n  static int64_t modularInverse(int64_t a, int64_t m) {\n    int64_t y = 0;\n    int64_t x = 1;\n\n    if (m == 1) return 0;\n\n    a = mod(a, m);\n\n    while (a > 1) {\n      // compute quotient q = a / m and remainder r = a % m\n      int64_t q = a / m;\n      int64_t r = a - q * m;\n\n      // update (a,m) = (m,r)\n      a = m;\n      m = r;\n\n      // update x and y of extended euclidean algorithm\n      r = x - q * y;\n      x = y;\n      y = r;\n    }\n\n    return x;\n  }\n\n  static int64_t gcd(int64_t a, int64_t b) {\n    assert(a != std::numeric_limits<int64_t>::min());\n    assert(b != std::numeric_limits<int64_t>::min());\n\n    int64_t h;\n    if (a < 0) a = -a;\n    if (b < 0) b = -b;\n\n    if (a == 0) return b;\n    if (b == 0) return a;\n\n    do {\n      h = a % b;\n      a = b;\n      b = h;\n    } while (b != 0);\n\n    return a;\n  }\n\n  // computes a rational approximation with given maximal denominator\n  static int64_t denominator(double x, double eps, int64_t maxdenom) {\n    int64_t ai = (int64_t)x;\n    int64_t m[] = {ai, 1, 1, 0};\n\n    HighsCDouble xi = x;\n    HighsCDouble fraction = xi - double(ai);\n\n    while (fraction > eps) {\n      xi = 1.0 / fraction;\n      if (double(xi) > double(int64_t{1} << 53)) break;\n\n      ai = (int64_t)(double)xi;\n      int64_t t = m[2] * ai + m[3];\n      if (t > maxdenom) break;\n\n      m[3] = m[2];\n      m[2] = t;\n\n      t = m[0] * ai + m[1];\n      m[1] = m[0];\n      m[0] = t;\n\n      fraction = xi - ai;\n    }\n\n    ai = (maxdenom - m[3]) / m[2];\n    m[1] += m[0] * ai;\n    m[3] += m[2] * ai;\n\n    double x0 = static_cast<double>(m[0]) / static_cast<double>(m[2]);\n    double x1 = static_cast<double>(m[1]) / static_cast<double>(m[3]);\n    x = std::abs(x);\n    double err0 = std::abs(x - x0);\n    double err1 = std::abs(x - x1);\n\n    if (err0 < err1) return m[2];\n    return m[3];\n  }\n\n  static double integralScale(const double* vals, HighsInt numVals,\n                              double deltadown, double deltaup) {\n    if (numVals == 0) return 0.0;\n\n    auto minmax = std::minmax_element(\n        vals, vals + numVals,\n        [](double a, double b) { return std::abs(a) < std::abs(b); });\n    const double minval = *minmax.first;\n    const double maxval = *minmax.second;\n\n    int expshift = 0;\n\n    // to cover many small denominators at once use a denominator of 75 * 2^n\n    // with n-3 being large enough so that the smallest value is not below 0.5\n    // but ignore tiny values bew deltadown/deltaup.\n    if (minval < -deltadown || minval > deltaup) std::frexp(minval, &expshift);\n    expshift = std::max(-expshift, 0) + 3;\n\n    // guard against making the largest value too big which may cause overflows\n    // with intermediate gcd values\n    int expMaxVal;\n    std::frexp(maxval, &expMaxVal);\n    expMaxVal = std::min(expMaxVal, 32);\n    if (expMaxVal + expshift > 32) expshift = 32 - expMaxVal;\n\n    uint64_t denom = uint64_t{75} << expshift;\n    int64_t startdenom = denom;\n    // now check if the values are integral and if not compute a common\n    // denominator for their remaining fraction\n    HighsCDouble val = startdenom * HighsCDouble(vals[0]);\n    HighsCDouble downval = floor(val + deltaup);\n    HighsCDouble fraction = val - downval;\n\n    if (fraction > deltadown) {\n      // use a continued fraction algorithm to compute small missing\n      // denominators for the remaining fraction\n      denom *= denominator(double(fraction), deltaup, 1000);\n      val = denom * HighsCDouble(vals[0]);\n      downval = floor(val + deltaup);\n      fraction = val - downval;\n\n      // if this is not sufficient for reaching integrality, we stop here\n      if (fraction > deltadown) return 0.0;\n    }\n\n    uint64_t currgcd = (uint64_t)std::abs(double(downval));\n\n    for (HighsInt i = 1; i != numVals; ++i) {\n      val = denom * HighsCDouble(vals[i]);\n      downval = floor(val + deltaup);\n      fraction = val - downval;\n\n      if (fraction > deltadown) {\n        val = startdenom * HighsCDouble(vals[i]);\n        fraction = val - floor(val);\n        denom *= denominator(double(fraction), deltaup, 1000);\n        val = denom * HighsCDouble(vals[i]);\n        downval = floor(val + deltaup);\n        fraction = val - downval;\n\n        if (fraction > deltadown) return 0.0;\n      }\n\n      if (currgcd != 1) {\n        currgcd = gcd(currgcd, (int64_t) double(downval));\n\n        // if the denominator is large, divide by the current gcd to prevent\n        // unnecessary overflows\n        if (denom > std::numeric_limits<unsigned int>::max()) {\n          denom /= currgcd;\n          if (startdenom != 1) startdenom /= gcd(currgcd, startdenom);\n          currgcd = 1;\n        }\n      }\n    }\n\n    return static_cast<double>(denom) / static_cast<double>(currgcd);\n  }\n\n  static double integralScale(const std::vector<double>& vals, double deltadown,\n                              double deltaup) {\n    return integralScale(vals.data(), vals.size(), deltadown, deltaup);\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsLinearSumBounds.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HighsLinearSumBounds.h\n * @brief Data structure to compute and update bounds on a linear sum of\n * variables with finite or infinite bounds\n */\n\n#ifndef HIGHS_LINEAR_SUM_BOUNDS_H_\n#define HIGHS_LINEAR_SUM_BOUNDS_H_\n\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n#include \"util/HighsCDouble.h\"\n\nclass HighsLinearSumBounds {\n  std::vector<HighsCDouble> sumLowerOrig;\n  std::vector<HighsCDouble> sumUpperOrig;\n  std::vector<HighsInt> numInfSumLowerOrig;\n  std::vector<HighsInt> numInfSumUpperOrig;\n  std::vector<HighsCDouble> sumLower;\n  std::vector<HighsCDouble> sumUpper;\n  std::vector<HighsInt> numInfSumLower;\n  std::vector<HighsInt> numInfSumUpper;\n  const double* varLower;\n  const double* varUpper;\n  const double* implVarLower;\n  const double* implVarUpper;\n  const HighsInt* implVarLowerSource;\n  const HighsInt* implVarUpperSource;\n\n public:\n  void setNumSums(HighsInt numSums) {\n    numInfSumLower.resize(numSums);\n    numInfSumUpper.resize(numSums);\n    sumLower.resize(numSums);\n    sumUpper.resize(numSums);\n    numInfSumLowerOrig.resize(numSums);\n    numInfSumUpperOrig.resize(numSums);\n    sumLowerOrig.resize(numSums);\n    sumUpperOrig.resize(numSums);\n  }\n\n  void setBoundArrays(const double* varLower, const double* varUpper,\n                      const double* implVarLower, const double* implVarUpper,\n                      const HighsInt* implVarLowerSource,\n                      const HighsInt* implVarUpperSource) {\n    this->varLower = varLower;\n    this->varUpper = varUpper;\n    this->implVarLower = implVarLower;\n    this->implVarUpper = implVarUpper;\n    this->implVarLowerSource = implVarLowerSource;\n    this->implVarUpperSource = implVarUpperSource;\n  }\n\n  void sumScaled(HighsInt sum, double scale) {\n    sumLowerOrig[sum] *= scale;\n    sumUpperOrig[sum] *= scale;\n    sumLower[sum] *= scale;\n    sumUpper[sum] *= scale;\n\n    if (scale < 0) {\n      std::swap(sumLower[sum], sumUpper[sum]);\n      std::swap(sumLowerOrig[sum], sumUpperOrig[sum]);\n      std::swap(numInfSumLower[sum], numInfSumUpper[sum]);\n      std::swap(numInfSumLowerOrig[sum], numInfSumUpperOrig[sum]);\n    }\n  }\n\n  void add(HighsInt sum, HighsInt var, double coefficient);\n\n  void remove(HighsInt sum, HighsInt var, double coefficient);\n\n  void updatedVarUpper(HighsInt sum, HighsInt var, double coefficient,\n                       double oldVarUpper);\n\n  void updatedVarLower(HighsInt sum, HighsInt var, double coefficient,\n                       double oldVarLower);\n\n  void updatedImplVarUpper(HighsInt sum, HighsInt var, double coefficient,\n                           double oldImplVarUpper,\n                           HighsInt oldImplVarUpperSource);\n\n  void updatedImplVarLower(HighsInt sum, HighsInt var, double coefficient,\n                           double oldImplVarLower,\n                           HighsInt oldImplVarLowerSource);\n\n  double getResidualSumLower(HighsInt sum, HighsInt var, double coefficient,\n                             HighsInt boundVar = -1,\n                             double boundVarCoefficient = -kHighsInf,\n                             double boundVarValue = -kHighsInf) const;\n\n  double getResidualSumUpper(HighsInt sum, HighsInt var, double coefficient,\n                             HighsInt boundVar = -1,\n                             double boundVarCoefficient = -kHighsInf,\n                             double boundVarValue = -kHighsInf) const;\n\n  double getResidualSumLowerOrig(HighsInt sum, HighsInt var, double coefficient,\n                                 HighsInt boundVar = -1,\n                                 double boundVarCoefficient = -kHighsInf,\n                                 double boundVarValue = -kHighsInf) const;\n\n  double getResidualSumUpperOrig(HighsInt sum, HighsInt var, double coefficient,\n                                 HighsInt boundVar = -1,\n                                 double boundVarCoefficient = -kHighsInf,\n                                 double boundVarValue = -kHighsInf) const;\n\n  template <typename T = double>\n  double getSumLowerOrig(HighsInt sum, T offset = T()) const {\n    return numInfSumLowerOrig[sum] == 0\n               ? static_cast<double>(sumLowerOrig[sum] +\n                                     static_cast<HighsCDouble>(offset))\n               : -kHighsInf;\n  }\n\n  template <typename T = double>\n  double getSumUpperOrig(HighsInt sum, T offset = T()) const {\n    return numInfSumUpperOrig[sum] == 0\n               ? static_cast<double>(sumUpperOrig[sum] +\n                                     static_cast<HighsCDouble>(offset))\n               : kHighsInf;\n  }\n\n  template <typename T = double>\n  double getSumLower(HighsInt sum, T offset = T()) const {\n    return numInfSumLower[sum] == 0\n               ? static_cast<double>(sumLower[sum] +\n                                     static_cast<HighsCDouble>(offset))\n               : -kHighsInf;\n  }\n\n  template <typename T = double>\n  double getSumUpper(HighsInt sum, T offset = T()) const {\n    return numInfSumUpper[sum] == 0\n               ? static_cast<double>(sumUpper[sum] +\n                                     static_cast<HighsCDouble>(offset))\n               : kHighsInf;\n  }\n\n  HighsInt getNumInfSumLower(HighsInt sum) const { return numInfSumLower[sum]; }\n\n  HighsInt getNumInfSumUpper(HighsInt sum) const { return numInfSumUpper[sum]; }\n\n  HighsInt getNumInfSumLowerOrig(HighsInt sum) const {\n    return numInfSumLowerOrig[sum];\n  }\n\n  HighsInt getNumInfSumUpperOrig(HighsInt sum) const {\n    return numInfSumUpperOrig[sum];\n  }\n\n  void shrink(const std::vector<HighsInt>& newIndices, HighsInt newSize);\n\n  double getImplVarUpper(HighsInt sum, HighsInt var) const;\n\n  double getImplVarLower(HighsInt sum, HighsInt var) const;\n\n private:\n  double getImplVarUpper(HighsInt sum, double myVarUpper, double myImplVarUpper,\n                         HighsInt myImplVarUpperSource) const;\n\n  double getImplVarLower(HighsInt sum, double myVarLower, double myImplVarLower,\n                         HighsInt myImplVarLowerSource) const;\n\n  void update(HighsInt& numInf, HighsCDouble& activity, HighsInt direction,\n              double bound, double coefficient) const;\n\n  void update(HighsInt& numInfs, HighsCDouble& activity, double oldBound,\n              double newBound, double coefficient) const;\n\n  void residual(HighsInt& numInfs, HighsCDouble& activity, double oldVarBound,\n                double coefficient, HighsInt boundVar = -1,\n                double boundVarCoefficient = kHighsInf,\n                double oldBoundVarBound = kHighsInf,\n                double newBoundVarBound = kHighsInf) const;\n\n  void handleVarUpper(HighsInt sum, double coefficient, double myVarUpper,\n                      HighsInt direction);\n\n  void handleVarLower(HighsInt sum, double coefficient, double myVarLower,\n                      HighsInt direction);\n\n  void handleImplVarUpper(HighsInt sum, double coefficient,\n                          double myImplVarUpper, HighsInt direction);\n\n  void handleImplVarLower(HighsInt sum, double coefficient,\n                          double myImplVarLower, HighsInt direction);\n\n  void updatedImplVarUpper(HighsInt sum, HighsInt var, double coefficient,\n                           double oldVarUpper, double oldImplVarUpper,\n                           HighsInt oldImplVarUpperSource);\n\n  void updatedImplVarLower(HighsInt sum, HighsInt var, double coefficient,\n                           double oldVarLower, double oldImplVarLower,\n                           HighsInt oldImplVarLowerSource);\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsMatrixPic.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HighsMatrixPic.h\n * @brief Class-independent utilities for HiGHS\n */\n#ifndef UTIL_HIGHSMATRIXPIC_H_\n#define UTIL_HIGHSMATRIXPIC_H_\n\n#include <string>\n#include <vector>\n\n#include \"HConfig.h\"\n#include \"lp_data/HighsLp.h\"\n#include \"lp_data/HighsOptions.h\"\n\nHighsStatus writeLpMatrixPicToFile(const HighsOptions& options,\n                                   const std::string fileprefix,\n                                   const HighsLp& lp);\n\nHighsStatus writeMatrixPicToFile(const HighsOptions& options,\n                                 const std::string fileprefix,\n                                 const HighsInt numRow, const HighsInt numCol,\n                                 const std::vector<HighsInt>& Astart,\n                                 const std::vector<HighsInt>& Aindex);\n\nHighsStatus writeRmatrixPicToFile(const HighsOptions& options,\n                                  const std::string fileprefix,\n                                  const HighsInt numRow, const HighsInt numCol,\n                                  const std::vector<HighsInt>& ARstart,\n                                  const std::vector<HighsInt>& ARindex);\n\n#endif  // UTIL_HIGHSMATRIXPIC_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsMatrixSlice.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HighsMatrixSlice.h\n * @brief Provides a uniform interface to iterate rows and columns in different\n * underlying matrix storage formats\n */\n\n#ifndef UTIL_HIGHS_MATRIX_SLICE_H_\n#define UTIL_HIGHS_MATRIX_SLICE_H_\n\n#include <cstddef>\n#include <iterator>\n#include <vector>\n\n#include \"util/HighsInt.h\"\n\ntemplate <typename StorageFormat>\nclass HighsMatrixSlice;\n\nstruct HighsEmptySlice;\nstruct HighsCompressedSlice;\nstruct HighsIndexedSlice;\nstruct HighsTripletListSlice;\nstruct HighsTripletTreeSliceInOrder;\nstruct HighsTripletTreeSlicePreOrder;\nstruct HighsTripletPositionSlice;\n\nclass HighsSliceNonzero {\n  template <typename>\n  friend class HighsMatrixSlice;\n\n private:\n  const HighsInt* index_;\n  const double* value_;\n\n public:\n  HighsSliceNonzero() = default;\n  HighsSliceNonzero(const HighsInt* index, const double* value)\n      : index_(index), value_(value) {}\n  HighsInt index() const { return *index_; }\n  double value() const { return *value_; }\n};\n\ntemplate <>\nclass HighsMatrixSlice<HighsEmptySlice> {\n public:\n  using iterator = const HighsSliceNonzero*;\n  static constexpr const HighsSliceNonzero* begin() { return nullptr; }\n  static constexpr const HighsSliceNonzero* end() { return nullptr; }\n};\n\ntemplate <>\nclass HighsMatrixSlice<HighsCompressedSlice> {\n  const HighsInt* index;\n  const double* value;\n  HighsInt len;\n\n public:\n  class iterator {\n    HighsSliceNonzero pos_;\n\n   public:\n    using iterator_category = std::forward_iterator_tag;\n    using value_type = HighsSliceNonzero;\n    using difference_type = std::ptrdiff_t;\n    using pointer = const HighsSliceNonzero*;\n    using reference = const HighsSliceNonzero&;\n\n    iterator(const HighsInt* index, const double* value) : pos_(index, value) {}\n    iterator() = default;\n\n    iterator operator++(int) {\n      iterator prev = *this;\n      ++pos_.index_;\n      ++pos_.value_;\n      return prev;\n    }\n    iterator& operator++() {\n      ++pos_.index_;\n      ++pos_.value_;\n      return *this;\n    }\n    reference operator*() const { return pos_; }\n    pointer operator->() const { return &pos_; }\n    iterator operator+(difference_type v) const {\n      iterator i = *this;\n      i.pos_.index_ += v;\n      i.pos_.value_ += v;\n      return i;\n    }\n\n    bool operator==(const iterator& rhs) const {\n      return pos_.index_ == rhs.pos_.index_;\n    }\n    bool operator!=(const iterator& rhs) const {\n      return pos_.index_ != rhs.pos_.index_;\n    }\n  };\n\n  HighsMatrixSlice(const HighsInt* index_, const double* value_, HighsInt len_)\n      : index(index_), value(value_), len(len_) {}\n  iterator begin() const { return iterator{index, value}; }\n  iterator end() const { return iterator{index + len, nullptr}; }\n};\n\ntemplate <>\nclass HighsMatrixSlice<HighsIndexedSlice> {\n  const HighsInt* index;\n  const double* denseValues;\n  HighsInt len;\n\n public:\n  class iterator {\n    HighsSliceNonzero pos_;\n    const double* denseValues;\n\n   public:\n    using iterator_category = std::forward_iterator_tag;\n    using value_type = HighsSliceNonzero;\n    using difference_type = std::ptrdiff_t;\n    using pointer = const HighsSliceNonzero*;\n    using reference = const HighsSliceNonzero&;\n\n    iterator(const HighsInt* index_, const double* denseValues_)\n        : pos_(index_, denseValues_), denseValues(denseValues_) {}\n    iterator() = default;\n\n    iterator operator++(int) {\n      iterator prev = *this;\n      ++pos_.index_;\n      return prev;\n    }\n    iterator& operator++() {\n      ++pos_.index_;\n      return *this;\n    }\n    reference operator*() {\n      pos_.value_ = &denseValues[*pos_.index_];\n      return pos_;\n    }\n    pointer operator->() {\n      pos_.value_ = &denseValues[*pos_.index_];\n      return &pos_;\n    }\n    iterator operator+(difference_type v) const {\n      iterator i = *this;\n\n      while (v > 0) {\n        --v;\n        ++i;\n      }\n\n      return i;\n    }\n\n    bool operator==(const iterator& rhs) const {\n      return pos_.index_ == rhs.pos_.index_;\n    }\n    bool operator!=(const iterator& rhs) const {\n      return pos_.index_ != rhs.pos_.index_;\n    }\n  };\n\n  HighsMatrixSlice(const HighsInt* index, const double* denseValues,\n                   HighsInt len)\n      : index(index), denseValues(denseValues), len(len) {}\n  iterator begin() const { return iterator{index, denseValues}; }\n  iterator end() const { return iterator{index + len, nullptr}; }\n};\n\ntemplate <>\nclass HighsMatrixSlice<HighsTripletListSlice> {\n  const HighsInt* nodeIndex;\n  const double* nodeValue;\n  const HighsInt* nodeNext;\n  HighsInt head;\n\n public:\n  class iterator {\n    HighsSliceNonzero pos_;\n    const HighsInt* nodeNext;\n    HighsInt currentNode;\n\n   public:\n    using iterator_category = std::forward_iterator_tag;\n    using value_type = HighsSliceNonzero;\n    using difference_type = std::ptrdiff_t;\n    using pointer = const HighsSliceNonzero*;\n    using reference = const HighsSliceNonzero&;\n\n    iterator(HighsInt node) : pos_(), nodeNext(nullptr), currentNode(node) {}\n    iterator(const HighsInt* nodeIndex, const double* nodeValue,\n             const HighsInt* nodeNext, HighsInt node)\n        : pos_(node == -1 ? nullptr : nodeIndex + node,\n               node == -1 ? nullptr : nodeValue + node),\n          nodeNext(nodeNext),\n          currentNode(node) {}\n    iterator() = default;\n\n    iterator& operator++() {\n      pos_.index_ -= currentNode;\n      pos_.value_ -= currentNode;\n      currentNode = nodeNext[currentNode];\n      pos_.index_ += currentNode;\n      pos_.value_ += currentNode;\n      return *this;\n    }\n    iterator operator++(int) {\n      iterator prev = *this;\n      ++(*this);\n      return prev;\n    }\n    reference operator*() { return pos_; }\n    pointer operator->() { return &pos_; }\n    iterator operator+(difference_type v) const {\n      iterator i = *this;\n\n      while (v > 0) {\n        --v;\n        ++i;\n      }\n\n      return i;\n    }\n\n    HighsInt position() const { return currentNode; }\n\n    bool operator==(const iterator& rhs) const {\n      return currentNode == rhs.currentNode;\n    }\n    bool operator!=(const iterator& rhs) const {\n      return currentNode != rhs.currentNode;\n    }\n  };\n\n  HighsMatrixSlice(const HighsInt* nodeIndex, const double* nodeValue,\n                   const HighsInt* nodeNext, HighsInt head)\n      : nodeIndex(nodeIndex),\n        nodeValue(nodeValue),\n        nodeNext(nodeNext),\n        head(head) {}\n  iterator begin() const {\n    return iterator{nodeIndex, nodeValue, nodeNext, head};\n  }\n  iterator end() const { return iterator{-1}; }\n};\n\ntemplate <>\nclass HighsMatrixSlice<HighsTripletTreeSlicePreOrder> {\n  const HighsInt* nodeIndex;\n  const double* nodeValue;\n  const HighsInt* nodeLeft;\n  const HighsInt* nodeRight;\n  HighsInt root;\n\n public:\n  class iterator {\n    HighsSliceNonzero pos_;\n    const HighsInt* nodeLeft;\n    const HighsInt* nodeRight;\n    std::vector<HighsInt> stack;\n    HighsInt currentNode;\n\n   public:\n    using iterator_category = std::forward_iterator_tag;\n    using value_type = HighsSliceNonzero;\n    using difference_type = std::ptrdiff_t;\n    using pointer = const HighsSliceNonzero*;\n    using reference = const HighsSliceNonzero&;\n\n    iterator(HighsInt node)\n        : pos_(), nodeLeft(nullptr), nodeRight(nullptr), currentNode(node) {}\n    iterator(const HighsInt* nodeIndex, const double* nodeValue,\n             const HighsInt* nodeLeft, const HighsInt* nodeRight, HighsInt node)\n        : pos_(nodeIndex + node, nodeValue + node),\n          nodeLeft(nodeLeft),\n          nodeRight(nodeRight),\n          currentNode(node) {\n      stack.reserve(16);\n      stack.push_back(-1);\n    }\n    iterator() = default;\n\n    iterator& operator++() {\n      HighsInt offset = -currentNode;\n      if (nodeLeft[currentNode] != -1) {\n        if (nodeRight[currentNode] != -1)\n          stack.push_back(nodeRight[currentNode]);\n        currentNode = nodeLeft[currentNode];\n      } else if (nodeRight[currentNode] != -1) {\n        currentNode = nodeRight[currentNode];\n      } else {\n        currentNode = stack.back();\n        stack.pop_back();\n      }\n      offset += currentNode;\n      pos_.index_ += offset;\n      pos_.value_ += offset;\n      return *this;\n    }\n\n    iterator operator++(int) {\n      iterator prev = *this;\n      ++(*this);\n      return prev;\n    }\n    reference operator*() { return pos_; }\n    pointer operator->() { return &pos_; }\n    iterator operator+(difference_type v) const {\n      iterator i = *this;\n\n      while (v > 0) {\n        --v;\n        ++i;\n      }\n\n      return i;\n    }\n\n    HighsInt position() const { return currentNode; }\n\n    bool operator==(const iterator& rhs) const {\n      return currentNode == rhs.currentNode;\n    }\n    bool operator!=(const iterator& rhs) const {\n      return currentNode != rhs.currentNode;\n    }\n  };\n\n  HighsMatrixSlice(const HighsInt* nodeIndex, const double* nodeValue,\n                   const HighsInt* nodeLeft, const HighsInt* nodeRight,\n                   HighsInt root)\n      : nodeIndex(nodeIndex),\n        nodeValue(nodeValue),\n        nodeLeft(nodeLeft),\n        nodeRight(nodeRight),\n        root(root) {}\n\n  iterator end() const { return iterator{-1}; }\n  iterator begin() const {\n    // avoid allocation if there are no elements\n    if (root == -1) return end();\n    return iterator{nodeIndex, nodeValue, nodeLeft, nodeRight, root};\n  }\n};\n\ntemplate <>\nclass HighsMatrixSlice<HighsTripletTreeSliceInOrder> {\n  const HighsInt* nodeIndex;\n  const double* nodeValue;\n  const HighsInt* nodeLeft;\n  const HighsInt* nodeRight;\n  HighsInt root;\n\n public:\n  class iterator {\n    HighsSliceNonzero pos_;\n    const HighsInt* nodeLeft;\n    const HighsInt* nodeRight;\n    std::vector<HighsInt> stack;\n    HighsInt currentNode;\n\n   public:\n    using iterator_category = std::forward_iterator_tag;\n    using value_type = HighsSliceNonzero;\n    using difference_type = std::ptrdiff_t;\n    using pointer = const HighsSliceNonzero*;\n    using reference = const HighsSliceNonzero&;\n\n    iterator(HighsInt node)\n        : pos_(), nodeLeft(nullptr), nodeRight(nullptr), currentNode(node) {}\n    iterator(const HighsInt* nodeIndex, const double* nodeValue,\n             const HighsInt* nodeLeft, const HighsInt* nodeRight, HighsInt node)\n        : pos_(nodeIndex, nodeValue),\n          nodeLeft(nodeLeft),\n          nodeRight(nodeRight),\n          currentNode(node) {\n      stack.reserve(16);\n      stack.push_back(-1);\n      if (currentNode == -1) return;\n      while (nodeLeft[currentNode] != -1) {\n        stack.push_back(currentNode);\n        currentNode = nodeLeft[currentNode];\n      }\n\n      pos_.index_ += currentNode;\n      pos_.value_ += currentNode;\n    }\n    iterator() = default;\n\n    iterator& operator++() {\n      HighsInt offset = -currentNode;\n      if (nodeRight[currentNode] != -1) {\n        currentNode = nodeRight[currentNode];\n        while (nodeLeft[currentNode] != -1) {\n          stack.push_back(currentNode);\n          currentNode = nodeLeft[currentNode];\n        }\n      } else {\n        currentNode = stack.back();\n        stack.pop_back();\n      }\n      offset += currentNode;\n      pos_.index_ += offset;\n      pos_.value_ += offset;\n      return *this;\n    }\n\n    iterator operator++(int) {\n      iterator prev = *this;\n      ++(*this);\n      return prev;\n    }\n    reference operator*() { return pos_; }\n    pointer operator->() { return &pos_; }\n    iterator operator+(difference_type v) const {\n      iterator i = *this;\n\n      while (v > 0) {\n        --v;\n        ++i;\n      }\n\n      return i;\n    }\n\n    HighsInt position() const { return currentNode; }\n\n    bool operator==(const iterator& rhs) const {\n      return currentNode == rhs.currentNode;\n    }\n    bool operator!=(const iterator& rhs) const {\n      return currentNode != rhs.currentNode;\n    }\n  };\n\n  HighsMatrixSlice(const HighsInt* nodeIndex, const double* nodeValue,\n                   const HighsInt* nodeLeft, const HighsInt* nodeRight,\n                   HighsInt root)\n      : nodeIndex(nodeIndex),\n        nodeValue(nodeValue),\n        nodeLeft(nodeLeft),\n        nodeRight(nodeRight),\n        root(root) {}\n\n  iterator end() const { return iterator{-1}; }\n  iterator begin() const {\n    // avoid allocation if there are no elements\n    if (root == -1) return end();\n    return iterator{nodeIndex, nodeValue, nodeLeft, nodeRight, root};\n  }\n};\n\ntemplate <>\nclass HighsMatrixSlice<HighsTripletPositionSlice> {\n  const HighsInt* nodeIndex;\n  const double* nodeValue;\n  const HighsInt* nodePositions;\n  HighsInt len;\n\n public:\n  class iterator {\n    HighsSliceNonzero pos_;\n    const HighsInt* node;\n    HighsInt currentNode;\n\n   public:\n    using iterator_category = std::forward_iterator_tag;\n    using value_type = HighsSliceNonzero;\n    using difference_type = std::ptrdiff_t;\n    using pointer = const HighsSliceNonzero*;\n    using reference = const HighsSliceNonzero&;\n\n    iterator(const HighsInt* node) : pos_(), node(node), currentNode(0) {}\n    iterator(const HighsInt* nodeIndex, const double* nodeValue,\n             const HighsInt* node)\n        : pos_(nodeIndex, nodeValue), node(node), currentNode(0) {}\n    iterator() = default;\n\n    iterator& operator++() {\n      ++node;\n      return *this;\n    }\n\n    iterator operator++(int) {\n      iterator prev = *this;\n      ++(*this);\n      return prev;\n    }\n    reference operator*() {\n      HighsInt offset = -currentNode + *node;\n      currentNode = *node;\n      pos_.index_ += offset;\n      pos_.value_ += offset;\n      return pos_;\n    }\n    pointer operator->() {\n      HighsInt offset = -currentNode + *node;\n      currentNode = *node;\n      pos_.index_ += offset;\n      pos_.value_ += offset;\n      return &pos_;\n    }\n    iterator operator+(difference_type v) const {\n      iterator i = *this;\n      i.node += v;\n      return i;\n    }\n\n    HighsInt position() const { return currentNode; }\n\n    bool operator==(const iterator& rhs) const { return node == rhs.node; }\n\n    bool operator!=(const iterator& rhs) const { return node != rhs.node; }\n  };\n\n  HighsMatrixSlice(const HighsInt* nodeIndex, const double* nodeValue,\n                   const HighsInt* nodePositions, HighsInt len)\n      : nodeIndex(nodeIndex),\n        nodeValue(nodeValue),\n        nodePositions(nodePositions),\n        len(len) {}\n\n  iterator begin() const {\n    return iterator{nodeIndex, nodeValue, nodePositions};\n  }\n\n  iterator end() const { return iterator{nodePositions + len}; }\n};\n\nstruct HighsEmptySlice : public HighsMatrixSlice<HighsEmptySlice> {\n  using HighsMatrixSlice<HighsEmptySlice>::HighsMatrixSlice;\n};\nstruct HighsCompressedSlice : public HighsMatrixSlice<HighsCompressedSlice> {\n  using HighsMatrixSlice<HighsCompressedSlice>::HighsMatrixSlice;\n};\nstruct HighsIndexedSlice : public HighsMatrixSlice<HighsIndexedSlice> {\n  using HighsMatrixSlice<HighsIndexedSlice>::HighsMatrixSlice;\n};\nstruct HighsTripletListSlice : public HighsMatrixSlice<HighsTripletListSlice> {\n  using HighsMatrixSlice<HighsTripletListSlice>::HighsMatrixSlice;\n};\nstruct HighsTripletTreeSliceInOrder\n    : public HighsMatrixSlice<HighsTripletTreeSliceInOrder> {\n  using HighsMatrixSlice<HighsTripletTreeSliceInOrder>::HighsMatrixSlice;\n};\nstruct HighsTripletTreeSlicePreOrder\n    : public HighsMatrixSlice<HighsTripletTreeSlicePreOrder> {\n  using HighsMatrixSlice<HighsTripletTreeSlicePreOrder>::HighsMatrixSlice;\n};\nstruct HighsTripletPositionSlice\n    : public HighsMatrixSlice<HighsTripletPositionSlice> {\n  using HighsMatrixSlice<HighsTripletPositionSlice>::HighsMatrixSlice;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsMatrixUtils.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HighsMatrixUtils.h\n * @brief Class-independent utilities for HiGHS\n */\n#ifndef UTIL_HIGHSMATRIXUTILS_H_\n#define UTIL_HIGHSMATRIXUTILS_H_\n\n#include <cassert>\n#include <vector>\n\n// #include \"lp_data/HighsStatus.h\"\n#include \"lp_data/HighsOptions.h\"\n\nusing std::vector;\n\nHighsStatus assessMatrix(const HighsLogOptions& log_options,\n                         const std::string matrix_name, const HighsInt vec_dim,\n                         const HighsInt num_vec, vector<HighsInt>& matrix_start,\n                         vector<HighsInt>& matrix_index,\n                         vector<double>& matrix_value,\n                         const double small_matrix_value,\n                         const double large_matrix_value);\n\nHighsStatus assessMatrix(const HighsLogOptions& log_options,\n                         const std::string matrix_name, const HighsInt vec_dim,\n                         const HighsInt num_vec, vector<HighsInt>& matrix_start,\n                         vector<HighsInt>& matrix_p_end,\n                         vector<HighsInt>& matrix_index,\n                         vector<double>& matrix_value,\n                         const double small_matrix_value,\n                         const double large_matrix_value);\n\nHighsStatus assessMatrix(\n    const HighsLogOptions& log_options, const std::string matrix_name,\n    const HighsInt vec_dim, const HighsInt num_vec, const bool partitioned,\n    vector<HighsInt>& matrix_start, vector<HighsInt>& matrix_p_end,\n    vector<HighsInt>& matrix_index, vector<double>& matrix_value,\n    const double small_matrix_value, const double large_matrix_value);\n\nHighsStatus assessMatrixDimensions(const HighsLogOptions& log_options,\n                                   const HighsInt num_vec,\n                                   const bool partitioned,\n                                   const vector<HighsInt>& matrix_start,\n                                   const vector<HighsInt>& matrix_p_end,\n                                   const vector<HighsInt>& matrix_index,\n                                   const vector<double>& matrix_value);\n\n#endif  // UTIL_HIGHSMATRIXUTILS_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsMemoryAllocation.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file HighsMemoryAllocation.h\n * @brief Utilities for memory allocation that return true if successful\n */\n\n#ifndef UTIL_HIGHS_MEMORY_ALLOCATION_H_\n#define UTIL_HIGHS_MEMORY_ALLOCATION_H_\n\n#include <vector>\n\n#include \"util/HighsInt.h\"\n\ntemplate <typename T>\nbool okResize(std::vector<T>& use_vector, HighsInt dimension, T value = T{}) {\n  try {\n    use_vector.resize(dimension, value);\n  } catch (const std::bad_alloc& e) {\n    printf(\"HighsMemoryAllocation::okResize fails with %s\\n\", e.what());\n    return false;\n  }\n  return true;\n}\n\ntemplate <typename T>\nbool okReserve(std::vector<T>& use_vector, HighsInt dimension) {\n  try {\n    use_vector.reserve(dimension);\n  } catch (const std::bad_alloc& e) {\n    printf(\"HighsMemoryAllocation::okReserve fails with %s\\n\", e.what());\n    return false;\n  }\n  return true;\n}\n\ntemplate <typename T, typename T2>\nbool okReserve(std::unordered_map<T, T2>& use_map, HighsInt dimension) {\n  try {\n    use_map.reserve(dimension);\n  } catch (const std::bad_alloc& e) {\n    printf(\"HighsMemoryAllocation::okReserve fails with %s\\n\", e.what());\n    return false;\n  }\n  return true;\n}\n\ntemplate <typename T>\nbool okAssign(std::vector<T>& use_vector, HighsInt dimension, T value = T{}) {\n  try {\n    use_vector.assign(dimension, value);\n  } catch (const std::bad_alloc& e) {\n    printf(\"HighsMemoryAllocation::okAssign fails with %s\\n\", e.what());\n    return false;\n  }\n  return true;\n}\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsRandom.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HighsRandom.h\n * @brief Random number generators for HiGHS\n */\n#ifndef UTIL_HIGHSRANDOM_H_\n#define UTIL_HIGHSRANDOM_H_\n\n#include <cassert>\n\n#include \"util/HighsHash.h\"\n\n/**\n * @brief Class for HiGHS random number generators\n */\nclass HighsRandom {\n private:\n  uint32_t drawUniform(uint32_t sup, int nbits) {\n    // draw uniformly in interval [0,sup) where nbits is the maximal number of\n    // bits the results can have we draw random numbers with nbits many bits\n    // until we get one that is in the desired range we first use all available\n    // output functions for the same state before we advance the state again. We\n    // expect nbits to be at most 32 for this 32 bit version.\n    assert(sup <= uint32_t{1} << nbits);\n    while (true) {\n      advance();\n      uint32_t lo = static_cast<uint32_t>(state);\n      uint32_t hi = state >> 32;\n\n      uint32_t val;\n\n#define HIGHS_RAND_TRY_OUTPUT(n)                                        \\\n  val = static_cast<uint32_t>(HighsHashHelpers::pair_hash<n>(lo, hi) >> \\\n                              (64 - nbits));                            \\\n  if (val < sup) return val;\n\n      HIGHS_RAND_TRY_OUTPUT(0);\n      HIGHS_RAND_TRY_OUTPUT(1);\n      HIGHS_RAND_TRY_OUTPUT(2);\n      HIGHS_RAND_TRY_OUTPUT(3);\n      HIGHS_RAND_TRY_OUTPUT(4);\n      HIGHS_RAND_TRY_OUTPUT(5);\n      HIGHS_RAND_TRY_OUTPUT(6);\n      HIGHS_RAND_TRY_OUTPUT(7);\n      HIGHS_RAND_TRY_OUTPUT(9);\n      HIGHS_RAND_TRY_OUTPUT(10);\n      HIGHS_RAND_TRY_OUTPUT(11);\n      HIGHS_RAND_TRY_OUTPUT(12);\n      HIGHS_RAND_TRY_OUTPUT(13);\n      HIGHS_RAND_TRY_OUTPUT(14);\n      HIGHS_RAND_TRY_OUTPUT(15);\n      HIGHS_RAND_TRY_OUTPUT(16);\n      HIGHS_RAND_TRY_OUTPUT(17);\n      HIGHS_RAND_TRY_OUTPUT(18);\n      HIGHS_RAND_TRY_OUTPUT(19);\n      HIGHS_RAND_TRY_OUTPUT(20);\n      HIGHS_RAND_TRY_OUTPUT(21);\n      HIGHS_RAND_TRY_OUTPUT(22);\n      HIGHS_RAND_TRY_OUTPUT(23);\n      HIGHS_RAND_TRY_OUTPUT(24);\n      HIGHS_RAND_TRY_OUTPUT(25);\n      HIGHS_RAND_TRY_OUTPUT(26);\n      HIGHS_RAND_TRY_OUTPUT(27);\n      HIGHS_RAND_TRY_OUTPUT(28);\n      HIGHS_RAND_TRY_OUTPUT(29);\n      HIGHS_RAND_TRY_OUTPUT(30);\n      HIGHS_RAND_TRY_OUTPUT(31);\n\n#undef HIGHS_RAND_TRY_OUTPUT\n    }\n  }\n\n  uint64_t drawUniform(uint64_t sup, int nbits) {\n    // 64 bit version for drawUniform. If result fits in 32 bits use 32 bit\n    // version above so that it is only called when we actually need more than\n    // 32 bits\n    if (nbits <= 32) return drawUniform(uint32_t(sup), nbits);\n\n    assert(sup <= uint64_t{1} << nbits);\n    while (true) {\n      advance();\n      uint32_t lo = static_cast<uint32_t>(state);\n      uint32_t hi = state >> 32;\n\n      uint64_t val;\n\n#define HIGHS_RAND_TRY_OUTPUT(n)                                       \\\n  val = (HighsHashHelpers::pair_hash<2 * n>(lo, hi) >> (64 - nbits)) ^ \\\n        (HighsHashHelpers::pair_hash<2 * n + 1>(lo, hi) >> 32);        \\\n  if (val < sup) return val;\n\n      HIGHS_RAND_TRY_OUTPUT(0);\n      HIGHS_RAND_TRY_OUTPUT(1);\n      HIGHS_RAND_TRY_OUTPUT(2);\n      HIGHS_RAND_TRY_OUTPUT(3);\n      HIGHS_RAND_TRY_OUTPUT(4);\n      HIGHS_RAND_TRY_OUTPUT(5);\n      HIGHS_RAND_TRY_OUTPUT(6);\n      HIGHS_RAND_TRY_OUTPUT(7);\n      HIGHS_RAND_TRY_OUTPUT(9);\n      HIGHS_RAND_TRY_OUTPUT(10);\n      HIGHS_RAND_TRY_OUTPUT(11);\n      HIGHS_RAND_TRY_OUTPUT(12);\n      HIGHS_RAND_TRY_OUTPUT(13);\n      HIGHS_RAND_TRY_OUTPUT(14);\n      HIGHS_RAND_TRY_OUTPUT(15);\n\n#undef HIGHS_RAND_TRY_OUTPUT\n    }\n  }\n\n public:\n  /**\n   * @brief Initialisations\n   */\n  HighsRandom(HighsUInt seed = 0) { initialise(seed); }\n\n  /**\n   * @brief (Re-)initialise the random number generator\n   */\n  void initialise(HighsUInt seed = 0) {\n    state = seed;\n    do {\n      state = HighsHashHelpers::pair_hash<0>(static_cast<uint32_t>(state),\n                                             state >> 32);\n      state ^= (HighsHashHelpers::pair_hash<1>(state >> 32, seed) >> 32);\n    } while (state == 0);\n  }\n\n  void advance() {\n    // advance state with simple xorshift the outputs are produced by applying\n    // strongly universal hash functions to the state so that the least\n    // significant bits are as well distributed as the most significant bits.\n    state ^= state >> 12;\n    state ^= state << 25;\n    state ^= state >> 27;\n  }\n\n  /**\n   * @brief Return a random integer between 0 and 2147483647\n   */\n  HighsInt integer() {\n    advance();\n#ifdef HIGHSINT64\n    // use 63 bits of the first hash result and use second hash for lower half\n    // of bits\n    return (HighsHashHelpers::pair_hash<0>(state, state >> 32) >> 1) ^\n           (HighsHashHelpers::pair_hash<1>(state, state >> 32) >> 32);\n#else\n    // use 31 bits of the 64 bit result\n    return HighsHashHelpers::pair_hash<0>(static_cast<uint32_t>(state),\n                                          state >> 32) >>\n           33;\n#endif\n  }\n\n  /**\n   * @brief Return a random integer between [0,sup)\n   */\n  HighsInt integer(HighsInt sup) {  // let overload resolution select the 32bit\n                                    // or the 64bit version\n    if (sup <= 1) return 0;\n    int nbits = HighsHashHelpers::log2i(HighsUInt(sup - 1)) + 1;\n    return static_cast<HighsInt>(drawUniform(HighsUInt(sup), nbits));\n  }\n\n  /**\n   * @brief Return a random integer between [min,sup)\n   */\n  HighsInt integer(HighsInt min, HighsInt sup) {\n    return min + integer(sup - min);\n  }\n\n  /**\n   * @brief Return a random fraction - real in (0, 1)\n   */\n  double fraction() {\n    advance();\n    // 52 bit output is in interval [0,2^52-1]\n    uint64_t output = (HighsHashHelpers::pair_hash<0>(\n                           static_cast<uint32_t>(state), state >> 32) >>\n                       (64 - 52)) ^\n                      (HighsHashHelpers::pair_hash<1>(\n                           static_cast<uint32_t>(state), state >> 32) >>\n                       (64 - 26));\n    // compute (1+output) / (2^52+1) which is strictly between 0 and 1\n    return static_cast<double>(1 + output) * 2.2204460492503125e-16;\n  }\n\n  /**\n   * @brief Return a random fraction - real in [0, 1]\n   */\n  double closedFraction() {\n    advance();\n    // 53 bit result is in interval [0,2^53-1]\n    uint64_t output = (HighsHashHelpers::pair_hash<0>(\n                           static_cast<uint32_t>(state), state >> 32) >>\n                       (64 - 53)) ^\n                      (HighsHashHelpers::pair_hash<1>(\n                           static_cast<uint32_t>(state), state >> 32) >>\n                       32);\n    // compute output / (2^53-1) in double precision which is in the closed\n    // interval [0,1]\n    return static_cast<double>(output) * 1.1102230246251566e-16;\n  }\n\n  /**\n   * @brief Return a random real value in the interval [a,b]\n   */\n  double real(double a, double b) { return a + (b - a) * closedFraction(); }\n\n  /**\n   * @brief Return a random bit\n   */\n  bool bit() {\n    advance();\n    return HighsHashHelpers::pair_hash<0>(static_cast<uint32_t>(state),\n                                          state >> 32) >>\n           63;\n  }\n\n  /**\n   * @brief shuffle the given data array\n   */\n  template <typename T>\n  void shuffle(T* data, HighsInt N) {\n    for (HighsInt i = N; i > 1; --i) {\n      HighsInt pos = integer(i);\n      std::swap(data[pos], data[i - 1]);\n    }\n  }\n\n private:\n  uint64_t state;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsRbTree.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_RBTREE_H_\n#define HIGHS_RBTREE_H_\n\n#include <algorithm>\n#include <cassert>\n#include <type_traits>\n\n#include \"util/HighsInt.h\"\n\nnamespace highs {\n\ntemplate <typename T>\nstruct RbTreeLinks {\n  enum Direction {\n    kLeft = 0,\n    kRight = 1,\n  };\n\n  T child[2];\n\n  using ParentStorageType =\n      typename std::make_unsigned<typename std::conditional<\n          std::is_pointer<T>::value, uintptr_t, T>::type>::type;\n\n  static constexpr int colorBitPos() {\n    return std::is_pointer<T>::value ? 0 : sizeof(ParentStorageType) * 8 - 1;\n  }\n\n  static constexpr ParentStorageType colorBitMask() {\n    return ParentStorageType{1} << colorBitPos();\n  }\n\n  ParentStorageType parentAndColor;\n\n  template <typename U = T,\n            typename std::enable_if<std::is_integral<U>::value, int>::type = 0>\n  static constexpr T noLink() {\n    return -1;\n  }\n\n  template <typename U = T,\n            typename std::enable_if<std::is_pointer<U>::value, int>::type = 0>\n  static constexpr T noLink() {\n    return nullptr;\n  }\n\n  bool getColor() const { return (parentAndColor >> colorBitPos()); }\n\n  bool isBlack() const { return getColor() == 0; }\n\n  bool isRed() const { return getColor() == 1; }\n\n  void makeRed() { parentAndColor |= colorBitMask(); }\n\n  void makeBlack() { parentAndColor &= ~colorBitMask(); }\n\n  void setColor(bool color) {\n    makeBlack();\n    parentAndColor |= ParentStorageType(color) << colorBitPos();\n  }\n\n  void setParent(T p) {\n    if (std::is_pointer<T>::value)\n      parentAndColor =\n          (colorBitMask() & parentAndColor) | (ParentStorageType)(p);\n    else\n      parentAndColor =\n          (colorBitMask() & parentAndColor) | (ParentStorageType)(p + 1);\n  }\n\n  T getParent() const {\n    if (std::is_pointer<T>::value)\n      return (T)(parentAndColor & ~colorBitMask());\n    else\n      return ((T)(parentAndColor & ~colorBitMask())) - 1;\n  }\n};\n\ntemplate <typename Impl>\nstruct RbTreeTraits;\n\ntemplate <typename Impl>\nclass RbTree {\n  enum Dir {\n    kLeft = 0,\n    kRight = 1,\n  };\n\n  using KeyType = typename RbTreeTraits<Impl>::KeyType;\n  using LinkType = typename RbTreeTraits<Impl>::LinkType;\n\n  LinkType& rootNode;\n  // static_assert(\n  //     std::is_same<RbTreeLinks&, decltype(static_cast<Impl*>(nullptr)\n  //                                             ->getRbTreeLinks(0))>::value,\n  //     \"RbTree implementation must provide a getRbTreeLinks() function that \"\n  //     \"returns a non-const reference of RbTreeLinks given the index of a\n  //     node\");\n\n  // static_assert(std::is_same<const RbTreeLinks&,\n  //                           decltype(static_cast<const Impl*>(nullptr)\n  //                                        ->getRbTreeLinks(0))>::value,\n  //              \"RbTree implementation must provide a getRbTreeLinks() const \"\n  //              \"function that returns a const reference of RbTreeLinks given\n  //              \" \"the index of a node\");\n  // static_assert(\n  //    std::is_same<bool, decltype((*static_cast<KeyType*>(nullptr)) <\n  //                                (*static_cast<KeyType*>(nullptr)))>::value,\n  //    \"RbTree implementation must provide a getKey() function that, given the\n  //    \" \"index of a node, returns its key which must have a type that has \"\n  //    \"operator< defined\");\n\n  static constexpr LinkType kNoLink = RbTreeLinks<LinkType>::noLink();\n\n  bool isRed(LinkType node) const {\n    return node != kNoLink &&\n           static_cast<const Impl*>(this)->getRbTreeLinks(node).isRed();\n  }\n\n  bool isBlack(LinkType node) const {\n    return node == kNoLink ||\n           static_cast<const Impl*>(this)->getRbTreeLinks(node).isBlack();\n  }\n\n  void makeRed(LinkType node) {\n    static_cast<Impl*>(this)->getRbTreeLinks(node).makeRed();\n  }\n\n  void makeBlack(LinkType node) {\n    static_cast<Impl*>(this)->getRbTreeLinks(node).makeBlack();\n  }\n\n  void setColor(LinkType node, HighsUInt color) {\n    static_cast<Impl*>(this)->getRbTreeLinks(node).setColor(color != 0);\n  }\n\n  HighsUInt getColor(LinkType node) const {\n    return static_cast<const Impl*>(this)->getRbTreeLinks(node).getColor();\n  }\n\n  void setParent(LinkType node, LinkType parent) {\n    static_cast<Impl*>(this)->getRbTreeLinks(node).setParent(parent);\n  }\n\n  LinkType getParent(LinkType node) const {\n    return static_cast<const Impl*>(this)->getRbTreeLinks(node).getParent();\n  }\n\n  KeyType getKey(LinkType node) const {\n    return static_cast<const Impl*>(this)->getKey(node);\n  }\n\n  static constexpr Dir opposite(Dir dir) { return Dir(1 - dir); }\n\n  LinkType getChild(LinkType node, Dir dir) const {\n    return static_cast<const Impl*>(this)->getRbTreeLinks(node).child[dir];\n  }\n\n  void setChild(LinkType node, Dir dir, LinkType child) {\n    static_cast<Impl*>(this)->getRbTreeLinks(node).child[dir] = child;\n  }\n\n  void rotate(LinkType x, Dir dir) {\n    LinkType y = getChild(x, opposite(dir));\n    LinkType yDir = getChild(y, dir);\n    setChild(x, opposite(dir), yDir);\n    if (yDir != kNoLink) setParent(yDir, x);\n\n    LinkType pX = getParent(x);\n    setParent(y, pX);\n\n    if (pX == kNoLink)\n      rootNode = y;\n    else\n      setChild(pX, Dir((x != getChild(pX, dir)) ^ dir), y);\n\n    setChild(y, dir, x);\n    setParent(x, y);\n  }\n\n  void insertFixup(LinkType z) {\n    LinkType pZ = getParent(z);\n    while (isRed(pZ)) {\n      LinkType zGrandParent = getParent(pZ);\n      assert(zGrandParent != kNoLink);\n\n      Dir dir = Dir(getChild(zGrandParent, kLeft) == pZ);\n\n      LinkType y = getChild(zGrandParent, dir);\n      if (isRed(y)) {\n        makeBlack(pZ);\n        makeBlack(y);\n        makeRed(zGrandParent);\n        z = zGrandParent;\n      } else {\n        if (z == getChild(pZ, dir)) {\n          z = pZ;\n          rotate(z, opposite(dir));\n          pZ = getParent(z);\n          zGrandParent = getParent(pZ);\n          assert(zGrandParent != kNoLink);\n        }\n\n        makeBlack(pZ);\n        makeRed(zGrandParent);\n        rotate(zGrandParent, dir);\n      }\n\n      pZ = getParent(z);\n    }\n\n    makeBlack(rootNode);\n  }\n\n  void transplant(LinkType u, LinkType v, LinkType& nilParent) {\n    LinkType p = getParent(u);\n\n    if (p == kNoLink)\n      rootNode = v;\n    else\n      setChild(p, Dir(u != getChild(p, kLeft)), v);\n\n    if (v == kNoLink)\n      nilParent = p;\n    else\n      setParent(v, p);\n  }\n\n  void deleteFixup(LinkType x, const LinkType nilParent) {\n    while (x != rootNode && isBlack(x)) {\n      Dir dir;\n\n      LinkType p = x == kNoLink ? nilParent : getParent(x);\n      dir = Dir(x == getChild(p, kLeft));\n      LinkType w = getChild(p, dir);\n      assert(w != kNoLink);\n\n      if (isRed(w)) {\n        makeBlack(w);\n        makeRed(p);\n        rotate(p, opposite(dir));\n        assert((x == kNoLink && p == nilParent) ||\n               (x != kNoLink && p == getParent(x)));\n        w = getChild(p, dir);\n        assert(w != kNoLink);\n      }\n\n      if (isBlack(getChild(w, kLeft)) && isBlack(getChild(w, kRight))) {\n        makeRed(w);\n        x = p;\n      } else {\n        if (isBlack(getChild(w, dir))) {\n          makeBlack(getChild(w, opposite(dir)));\n          makeRed(w);\n          rotate(w, dir);\n          assert((x == kNoLink && p == nilParent) ||\n                 (x != kNoLink && p == getParent(x)));\n          w = getChild(p, dir);\n        }\n        setColor(w, getColor(p));\n        makeBlack(p);\n        makeBlack(getChild(w, dir));\n        rotate(p, opposite(dir));\n        x = rootNode;\n      }\n    }\n\n    if (x != kNoLink) makeBlack(x);\n  }\n\n public:\n  RbTree(LinkType& rootNode) : rootNode(rootNode) {}\n\n  bool empty() const { return rootNode == kNoLink; }\n\n  LinkType first(LinkType x) const {\n    if (x == kNoLink) return kNoLink;\n\n    while (true) {\n      LinkType lX = getChild(x, kLeft);\n      if (lX == kNoLink) return x;\n      x = lX;\n    }\n  }\n\n  LinkType last(LinkType x) const {\n    if (x == kNoLink) return kNoLink;\n\n    while (true) {\n      LinkType rX = getChild(x, kRight);\n      if (rX == kNoLink) return x;\n      x = rX;\n    }\n  }\n\n  LinkType first() const { return first(rootNode); }\n\n  LinkType last() const { return last(rootNode); }\n\n  LinkType successor(LinkType x) const {\n    LinkType y = getChild(x, kRight);\n    if (y != kNoLink) return first(y);\n\n    y = getParent(x);\n    while (y != kNoLink && x == getChild(y, kRight)) {\n      x = y;\n      y = getParent(x);\n    }\n\n    return y;\n  }\n\n  LinkType predecessor(LinkType x) const {\n    LinkType y = getChild(x, kLeft);\n    if (y != kNoLink) return last(y);\n\n    y = getParent(x);\n    while (y != kNoLink && x == getChild(y, kLeft)) {\n      x = y;\n      y = getParent(x);\n    }\n\n    return y;\n  }\n\n  std::pair<LinkType, bool> find(const KeyType& key, LinkType treeRoot) {\n    LinkType y = kNoLink;\n    LinkType x = treeRoot;\n    while (x != kNoLink) {\n      HighsInt cmp = 1 - (getKey(x) < key) + (key < getKey(x));\n      switch (cmp) {\n        case 0:\n          y = x;\n          x = getChild(y, kRight);\n          break;\n        case 1:\n          return std::make_pair(x, true);\n        case 2:\n          y = x;\n          x = getChild(y, kLeft);\n      }\n    }\n\n    return std::make_pair(y, false);\n  }\n\n  std::pair<LinkType, bool> find(const KeyType& key) {\n    return find(key, rootNode);\n  }\n\n  void link(LinkType z, LinkType parent) {\n    setParent(z, parent);\n    if (parent == kNoLink)\n      rootNode = z;\n    else\n      setChild(parent, Dir(getKey(parent) < getKey(z)), z);\n\n    setChild(z, kLeft, kNoLink);\n    setChild(z, kRight, kNoLink);\n    makeRed(z);\n    insertFixup(z);\n  }\n\n  void link(LinkType z) {\n    LinkType y = kNoLink;\n    LinkType x = rootNode;\n    while (x != kNoLink) {\n      y = x;\n      x = getChild(y, Dir(getKey(x) < getKey(z)));\n    }\n\n    static_cast<Impl*>(this)->link(z, y);\n  }\n\n  void unlink(LinkType z) {\n    LinkType nilParent = kNoLink;\n    LinkType y = z;\n    bool yWasBlack = isBlack(y);\n    LinkType x;\n\n    if (getChild(z, kLeft) == kNoLink) {\n      x = getChild(z, kRight);\n      transplant(z, x, nilParent);\n    } else if (getChild(z, kRight) == kNoLink) {\n      x = getChild(z, kLeft);\n      transplant(z, x, nilParent);\n    } else {\n      y = first(getChild(z, kRight));\n      yWasBlack = isBlack(y);\n      x = getChild(y, kRight);\n      if (getParent(y) == z) {\n        if (x == kNoLink)\n          nilParent = y;\n        else\n          setParent(x, y);\n      } else {\n        transplant(y, getChild(y, kRight), nilParent);\n        LinkType zRight = getChild(z, kRight);\n        setChild(y, kRight, zRight);\n        setParent(zRight, y);\n      }\n      transplant(z, y, nilParent);\n      LinkType zLeft = getChild(z, kLeft);\n      setChild(y, kLeft, zLeft);\n      setParent(zLeft, y);\n      setColor(y, getColor(z));\n    }\n\n    if (yWasBlack) deleteFixup(x, nilParent);\n  }\n};\n\ntemplate <typename Impl>\nclass CacheMinRbTree : public RbTree<Impl> {\n  using LinkType = typename RbTreeTraits<Impl>::LinkType;\n  LinkType& first_;\n\n public:\n  CacheMinRbTree(LinkType& rootNode, LinkType& first)\n      : RbTree<Impl>(rootNode), first_(first) {}\n\n  LinkType first() const { return first_; };\n  using RbTree<Impl>::first;\n\n  void link(LinkType z, LinkType parent) {\n    if (first_ == parent) {\n      if (parent == RbTreeLinks<LinkType>::noLink() ||\n          static_cast<const Impl*>(this)->getKey(z) <\n              static_cast<const Impl*>(this)->getKey(parent))\n        first_ = z;\n    }\n\n    RbTree<Impl>::link(z, parent);\n  }\n  using RbTree<Impl>::link;\n\n  void unlink(LinkType z) {\n    if (z == first_) first_ = this->successor(first_);\n    RbTree<Impl>::unlink(z);\n  }\n};\n\n}  // namespace highs\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsSort.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HighsSort.h\n * @brief Sorting routines for HiGHS\n */\n#ifndef UTIL_HIGHSSORT_H_\n#define UTIL_HIGHSSORT_H_\n\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n\nusing std::vector;\n\nvoid addToDecreasingHeap(HighsInt& n, HighsInt mx_n, vector<double>& heap_v,\n                         vector<HighsInt>& heap_ix, double v, HighsInt ix);\nvoid sortDecreasingHeap(const HighsInt n, vector<double>& heap_v,\n                        vector<HighsInt>& heap_ix);\n/**\n * @brief Sort values[1..n] of an array by increasing value\n */\nvoid maxheapsort(HighsInt* heap_v,  //!< HighsInt values to be sorted\n                 HighsInt n         //!< Number of values to be sorted\n);\n/**\n * @brief Sort values[1..n] of an array by increasing value with corresponding\n * indices\n */\nvoid maxheapsort(\n    HighsInt* heap_v,  //!< Values to be sorted\n    HighsInt* heap_i,  //!< Indices corresponding to (sorted) values\n    HighsInt n         //!< Number of values to be sorted\n);\n/**\n * @brief Sort values[1..n] of an array by increasing value with corresponding\n * indices\n */\nvoid maxheapsort(\n    double* heap_v,    //!< Values to be sorted\n    HighsInt* heap_i,  //!< Indices corresponding to (sorted) values\n    HighsInt n         //!< Number of values to be sorted\n);\n/**\n * @brief Build a value heap for sorting values[1..n] of an array by increasing\n * value\n */\nvoid buildMaxheap(HighsInt* heap_v,  //!< HighsInt values to be sorted\n                  HighsInt n         //!< Number of values to be sorted\n);\n/**\n * @brief Build a value-index heap for sorting values[1..n] of an array by\n * increasing value\n */\nvoid buildMaxheap(\n    HighsInt* heap_v,  //!< Values to be sorted\n    HighsInt* heap_i,  //!< Indices corresponding to (sorted) values\n    HighsInt n         //!< Number of values to be sorted\n);\n/**\n * @brief Build a value-index heap for sorting values[1..n] of an array by\n * increasing value\n */\nvoid buildMaxheap(\n    double* heap_v,    //!< Values to be sorted\n    HighsInt* heap_i,  //!< Indices corresponding to (sorted) values\n    HighsInt n         //!< Number of values to be sorted\n);\n/**\n * @brief Sort by increasing value a heap built with buildMaxheap\n */\nvoid maxHeapsort(HighsInt* heap_v,  //!< HighsInt values to be sorted\n                 HighsInt n         //!< Number of values to be sorted\n);\n/**\n * @brief Sort by increasing value a heap built with buildMaxheap\n */\nvoid maxHeapsort(\n    HighsInt* heap_v,  //!< Values to be sorted\n    HighsInt* heap_i,  //!< Indices corresponding to (sorted) values\n    HighsInt n         //!< Number of values to be sorted\n);\n/**\n * @brief Sort by increasing value a heap built with buildMaxheap\n */\nvoid maxHeapsort(\n    double* heap_v,    //!< Values to be sorted\n    HighsInt* heap_i,  //!< Indices corresponding to (sorted) values\n    HighsInt n         //!< Number of values to be sorted\n);\n/**\n * @brief Heapify function for sorting by increasing value\n */\nvoid maxHeapify(HighsInt* heap_v, HighsInt i, HighsInt n);\n\n/**\n * @brief Heapify function for sorting by increasing value\n */\nvoid maxHeapify(HighsInt* heap_v, HighsInt* heap_i, HighsInt i, HighsInt n);\n\n/**%\n * @brief Heapify function for sorting by increasing value\n */\nvoid maxHeapify(double* heap_v, HighsInt* heap_i, HighsInt i, HighsInt n);\n\n/**\n * @brief Check that a set of integers is in increasing order and in bounds\n */\nbool increasingSetOk(const vector<HighsInt>& set,\n                     const HighsInt set_entry_lower,\n                     const HighsInt set_entry_upper, bool strict);\n\n/**\n * @brief Check that a set of doubles is in increasing order and in bounds\n */\nbool increasingSetOk(const vector<double>& set, const double set_entry_lower,\n                     const double set_entry_upper, bool strict);\n\nvoid sortSetData(const HighsInt num_entries, vector<HighsInt>& set,\n                 const double* data0, const double* data1, const double* data2,\n                 double* sorted_data0, double* sorted_data1,\n                 double* sorted_data2);\n\nvoid sortSetData(const HighsInt num_entries, vector<HighsInt>& set,\n                 const HighsVarType* data0, HighsVarType* sorted_data0);\n\n#endif /* UTIL_HIGHSSORT_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsSparseMatrix.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HighsSparseMatrix.h\n * @brief\n */\n#ifndef LP_DATA_HIGHS_SPARSE_MATRIX_H_\n#define LP_DATA_HIGHS_SPARSE_MATRIX_H_\n\n#include <vector>\n\n#include \"lp_data/HConst.h\"\n#include \"lp_data/HStruct.h\"  //For  HighsScale\n#include \"lp_data/HighsStatus.h\"\n#include \"simplex/SimplexStruct.h\"  //For SimplexScale until scaling is HighsScale\n#include \"util/HVector.h\"\n#include \"util/HVectorBase.h\"\n#include \"util/HighsSparseVectorSum.h\"\n#include \"util/HighsUtils.h\"\n\nconst double kHyperPriceDensity = 0.1;\nconst HighsInt kDebugReportOff = -2;\nconst HighsInt kDebugReportAll = -1;\n\nclass HighsSparseMatrix {\n public:\n  HighsSparseMatrix() { clear(); }\n  MatrixFormat format_;\n  HighsInt num_col_;\n  HighsInt num_row_;\n  std::vector<HighsInt> start_;\n  std::vector<HighsInt> p_end_;\n  std::vector<HighsInt> index_;\n  std::vector<double> value_;\n\n  bool operator==(const HighsSparseMatrix& matrix) const;\n  bool equivalent(const HighsSparseMatrix& matrix) const;\n  void clear();\n  void exactResize();\n  bool formatOk() const { return (this->isColwise() || this->isRowwise()); };\n  bool isRowwise() const;\n  bool isColwise() const;\n  HighsInt numNz() const;\n  void range(double& min_value, double& max_value) const;\n  void setFormat(const MatrixFormat desired_format);\n  void ensureColwise();\n  void ensureRowwise();\n\n  void addVec(const HighsInt num_nz, const HighsInt* index, const double* value,\n              const double multiple = 1);\n  void addCols(const HighsSparseMatrix new_cols,\n               const int8_t* in_partition = NULL);\n  void addRows(const HighsSparseMatrix new_rows,\n               const int8_t* in_partition = NULL);\n  void getRow(const HighsInt iRow, HighsInt& num_nz, HighsInt* index,\n              double* value) const;\n  void getCol(const HighsInt iCol, HighsInt& num_nz, HighsInt* index,\n              double* value) const;\n  void deleteCols(const HighsIndexCollection& index_collection);\n  void deleteRows(const HighsIndexCollection& index_collection);\n  HighsStatus assessDimensions(const HighsLogOptions& log_options,\n                               const std::string matrix_name);\n  HighsStatus assessStart(const HighsLogOptions& log_options);\n  HighsStatus assessIndexBounds(const HighsLogOptions& log_options);\n\n  HighsStatus assess(const HighsLogOptions& log_options,\n                     const std::string matrix_name,\n                     const double small_matrix_value,\n                     const double large_matrix_value);\n  void assessSmallValues(const HighsLogOptions& log_options,\n                         const double small_matrix_value);\n  bool hasLargeValue(const double large_matrix_value);\n  void considerColScaling(const HighsInt max_scale_factor_exponent,\n                          double* col_scale);\n  void considerRowScaling(const HighsInt max_scale_factor_exponent,\n                          double* row_scale);\n  void scaleCol(const HighsInt col, const double colScale);\n  void scaleRow(const HighsInt row, const double rowScale);\n  void applyScale(const HighsScale& scale);\n  void applyRowScale(const HighsScale& scale);\n  void applyColScale(const HighsScale& scale);\n  void unapplyScale(const HighsScale& scale);\n  void createSlice(const HighsSparseMatrix& matrix, const HighsInt from_col,\n                   const HighsInt to_col);\n  void createColwise(const HighsSparseMatrix& matrix);\n  void createRowwise(const HighsSparseMatrix& matrix);\n  void alphaProductPlusY(const double alpha, const std::vector<double>& x,\n                         std::vector<double>& y,\n                         const bool transpose = false) const;\n  void product(vector<double>& result, const vector<double>& x) const;\n  void productTranspose(vector<double>& result, const vector<double>& x) const;\n  void productQuad(vector<double>& result, const vector<double>& x,\n                   const HighsInt debug_report = kDebugReportOff) const;\n  void productTransposeQuad(\n      vector<double>& result_value, const vector<double>& x,\n      const HighsInt debug_report = kDebugReportOff) const;\n  void productTransposeQuad(\n      vector<double>& result_value, vector<HighsInt>& result_index,\n      const HVector& x, const HighsInt debug_report = kDebugReportOff) const;\n  // Methods for PRICE, including the creation and updating of the\n  // partitioned row-wise matrix\n  void createRowwisePartitioned(const HighsSparseMatrix& matrix,\n                                const int8_t* in_partition = NULL);\n  bool debugPartitionOk(const int8_t* in_partition) const;\n  void priceByColumn(const bool quad_precision, HVector& result,\n                     const HVector& column,\n                     const HighsInt debug_report = kDebugReportOff) const;\n  void priceByRow(const bool quad_precision, HVector& result,\n                  const HVector& column,\n                  const HighsInt debug_report = kDebugReportOff) const;\n  void priceByRowWithSwitch(\n      const bool quad_precision, HVector& result, const HVector& column,\n      const double expected_density, const HighsInt from_index,\n      const double switch_density,\n      const HighsInt debug_report = kDebugReportOff) const;\n  void update(const HighsInt var_in, const HighsInt var_out,\n              const HighsSparseMatrix& matrix);\n  double computeDot(const HVector& column, const HighsInt use_col) const {\n    return computeDot(column.array, use_col);\n  }\n\n  double computeDot(const std::vector<double>& array,\n                    const HighsInt use_col) const;\n  void collectAj(HVector& column, const HighsInt use_col,\n                 const double multiplier) const;\n\n private:\n  void priceByRowDenseResult(\n      std::vector<double>& result, const HVector& column,\n      const HighsInt from_index,\n      const HighsInt debug_report = kDebugReportOff) const;\n  void priceByRowDenseResult(\n      std::vector<HighsCDouble>& result, const HVector& column,\n      const HighsInt from_index,\n      const HighsInt debug_report = kDebugReportOff) const;\n  void debugReportRowPrice(const HighsInt iRow, const double multiplier,\n                           const HighsInt to_iEl,\n                           const vector<double>& result) const;\n  void debugReportRowPrice(const HighsInt iRow, const double multiplier,\n                           const HighsInt to_iEl,\n                           const vector<HighsCDouble>& result) const;\n  void debugReportRowPrice(const HighsInt iRow, const double multiplier,\n                           const HighsInt to_iEl,\n                           HighsSparseVectorSum& sum) const;\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsSparseVectorSum.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_SPARSE_VECTOR_SUM_H_\n#define HIGHS_SPARSE_VECTOR_SUM_H_\n\n#include <algorithm>\n#include <cassert>\n#include <limits>\n#include <vector>\n\n#include \"util/HighsCDouble.h\"\n#include \"util/HighsInt.h\"\n\nclass HighsSparseVectorSum {\n public:\n  std::vector<HighsCDouble> values;\n  std::vector<HighsInt> nonzeroinds;\n  HighsSparseVectorSum() = default;\n\n  HighsSparseVectorSum(HighsInt dimension) { setDimension(dimension); }\n\n  void setDimension(HighsInt dimension) {\n    values.resize(dimension);\n    nonzeroinds.reserve(dimension);\n  }\n\n  void add(HighsInt index, double value) {\n    assert(index >= 0 && index < (HighsInt)values.size());\n    if (values[index] != 0.0) {\n      values[index] += value;\n    } else {\n      values[index] = value;\n      nonzeroinds.push_back(index);\n    }\n\n    if (values[index] == 0.0)\n      values[index] = std::numeric_limits<double>::min();\n  }\n\n  void add(HighsInt index, HighsCDouble value) {\n    if (values[index] != 0.0) {\n      values[index] += value;\n    } else {\n      values[index] = value;\n      nonzeroinds.push_back(index);\n    }\n\n    if (values[index] == 0.0)\n      values[index] = std::numeric_limits<double>::min();\n  }\n\n  const std::vector<HighsInt>& getNonzeros() const { return nonzeroinds; }\n\n  double getValue(HighsInt index) const { return double(values[index]); }\n\n  void clear() {\n    if (10 * nonzeroinds.size() < 3 * values.size())\n      for (HighsInt i : nonzeroinds) values[i] = 0.0;\n    else\n      values.assign(values.size(), false);\n\n    nonzeroinds.clear();\n  }\n\n  template <typename Pred>\n  HighsInt partition(Pred&& pred) {\n    return std::partition(nonzeroinds.begin(), nonzeroinds.end(), pred) -\n           nonzeroinds.begin();\n  }\n\n  template <typename IsZero>\n  void cleanup(IsZero&& isZero) {\n    HighsInt numNz = static_cast<HighsInt>(nonzeroinds.size());\n\n    for (HighsInt i = numNz - 1; i >= 0; --i) {\n      HighsInt pos = nonzeroinds[i];\n      double val = double(values[pos]);\n\n      if (isZero(pos, val)) {\n        values[pos] = 0.0;\n        --numNz;\n        std::swap(nonzeroinds[numNz], nonzeroinds[i]);\n      }\n    }\n\n    nonzeroinds.resize(numNz);\n  }\n};\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsSplay.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef HIGHS_SPLAY_H_\n#define HIGHS_SPLAY_H_\n\n#include <cassert>\n\n#include \"util/HighsInt.h\"\n\n/// top down splay operation to maintain a binary search tree. The search tree\n/// is assumed to be stored in an array/vector and therefore uses integers\n/// instead of pointers to link nodes. The splay operation on a given key will\n/// return the new root node index. The new root node will be the node with the\n/// given key, if it exists in the tree, and otherwise it is the node traversed\n/// last in a binary tree search for the key.\n///\n/// The GetLeft/GetRight lambdas receive an index of a node and must\n/// return references to an integer holding the left and the right child node\n/// indices. The GetKey lambda must return a type that is comparable\n/// to KeyT.\ntemplate <typename KeyT, typename GetLeft, typename GetRight, typename GetKey>\nHighsInt highs_splay(const KeyT& key, HighsInt root, GetLeft&& get_left,\n                     GetRight&& get_right, GetKey&& get_key) {\n  if (root == -1) return -1;\n\n  HighsInt Nleft = -1;\n  HighsInt Nright = -1;\n  HighsInt* lright = &Nright;\n  HighsInt* rleft = &Nleft;\n\n  while (true) {\n    if (key < get_key(root)) {\n      HighsInt left = get_left(root);\n      if (left == -1) break;\n      if (key < get_key(left)) {\n        HighsInt y = left;\n        get_left(root) = get_right(y);\n        get_right(y) = root;\n        root = y;\n        if (get_left(root) == -1) break;\n      }\n\n      *rleft = root;\n      rleft = &get_left(root);\n      root = get_left(root);\n    } else if (key > get_key(root)) {\n      HighsInt right = get_right(root);\n      if (right == -1) break;\n      if (key > get_key(right)) {\n        HighsInt y = right;\n        get_right(root) = get_left(y);\n        get_left(y) = root;\n        root = y;\n        if (get_right(root) == -1) break;\n      }\n\n      *lright = root;\n      lright = &get_right(root);\n      root = get_right(root);\n    } else\n      break;\n  }\n\n  *lright = get_left(root);\n  *rleft = get_right(root);\n  get_left(root) = Nright;\n  get_right(root) = Nleft;\n\n  return root;\n}\n\n/// links a new node into the binary tree rooted at the given reference to the\n/// root node. Lambdas must behave as described in highs_splay above.\n/// Equal keys are put to the right subtree.\ntemplate <typename GetLeft, typename GetRight, typename GetKey>\nvoid highs_splay_link(HighsInt linknode, HighsInt& root, GetLeft&& get_left,\n                      GetRight&& get_right, GetKey&& get_key) {\n  if (root == -1) {\n    get_left(linknode) = -1;\n    get_right(linknode) = -1;\n    root = linknode;\n    return;\n  }\n\n  root = highs_splay(get_key(linknode), root, get_left, get_right, get_key);\n\n  if (get_key(linknode) < get_key(root)) {\n    get_left(linknode) = get_left(root);\n    get_right(linknode) = root;\n    get_left(root) = -1;\n  } else {\n    assert(get_key(linknode) > get_key(root));\n    get_right(linknode) = get_right(root);\n    get_left(linknode) = root;\n    get_right(root) = -1;\n  }\n\n  root = linknode;\n}\n\n/// unlinks a new node into the binary tree rooted at the given reference to the\n/// root node. Lambdas must behave as described in highs_splay above.\ntemplate <typename GetLeft, typename GetRight, typename GetKey>\nvoid highs_splay_unlink(HighsInt unlinknode, HighsInt& root, GetLeft&& get_left,\n                        GetRight&& get_right, GetKey&& get_key) {\n  assert(root != -1);\n  root = highs_splay(get_key(unlinknode), root, get_left, get_right, get_key);\n  assert(get_key(root) == get_key(unlinknode));\n\n  // in case keys can be equal it might happen that we did not splay the correct\n  // node to the top since equal keys are put to the right subtree, we recurse\n  // into that part of the tree\n  if (root != unlinknode) {\n    highs_splay_unlink(unlinknode, get_right(root), get_left, get_right,\n                       get_key);\n    return;\n  }\n\n  assert(root == unlinknode);\n\n  if (get_left(unlinknode) == -1) {\n    root = get_right(unlinknode);\n  } else {\n    root = highs_splay(get_key(unlinknode), get_left(unlinknode), get_left,\n                       get_right, get_key);\n    get_right(root) = get_right(unlinknode);\n  }\n}\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsTimer.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HighsTimer.h\n * @brief Profiling facility for computational components in HiGHS\n */\n#ifndef UTIL_HIGHSTIMER_H_\n#define UTIL_HIGHSTIMER_H_\n\n#include <algorithm>\n#include <cassert>\n#include <chrono>\n#include <cstdio>\n#include <cstdlib>\n#include <string>\n#include <vector>\n\n#include \"util/HighsInt.h\"\n\nconst HighsInt check_clock = -46;\nconst HighsInt simplex_no_basis_clock = 8;\nconst HighsInt hipo_analytic_centre_clock = 9;\nconst HighsInt ipx_analytic_centre_clock = 10;\nconst bool kNoClockCalls = false;\n\n/**\n * @brief Class for profiling facility for computational components in HiGHS\n */\nclass HighsTimer {\n public:\n  HighsTimer() {\n    num_clock = 0;\n    HighsInt i_clock = clock_def(\"Run HiGHS\");\n    assert(i_clock == 0);\n    (void)i_clock;\n\n    presolve_clock = clock_def(\"Presolve\");\n    solve_clock = clock_def(\"Solve\");\n    postsolve_clock = clock_def(\"Postsolve\");\n    printf_flag = true;\n  }\n\n  /**\n   * @brief Set the printf flag\n   */\n  void setPrintfFlag(const bool output_flag, const bool log_to_console) {\n    this->printf_flag = output_flag ? log_to_console : false;\n  }\n\n  /**\n   * @brief Define a clock\n   */\n  HighsInt clock_def(\n      const char* name)  //!< Full-length name (<=16 characters) for the clock\n  {\n    HighsInt i_clock = num_clock;\n    clock_num_call.push_back(0);\n    clock_start.push_back(initial_clock_start);\n    clock_time.push_back(0);\n    clock_names.push_back(name);\n    num_clock++;\n    return i_clock;\n  }\n\n  /**\n   * @brief Reset a HighsTimer instance to its state after the\n   * constructor\n   */\n  void resetHighsTimer() {\n    this->num_clock = 0;\n    this->clock_num_call.clear();\n    this->clock_start.clear();\n    this->clock_names.clear();\n    HighsInt i_clock = clock_def(\"Run HiGHS\");\n    assert(i_clock == 0);\n    (void)i_clock;\n    this->presolve_clock = clock_def(\"Presolve\");\n    this->solve_clock = clock_def(\"Solve\");\n    this->postsolve_clock = clock_def(\"Postsolve\");\n    this->printf_flag = true;\n  }\n\n  /**\n   * @brief Zero the data for all clocks\n   */\n  void zeroAllClocks() {\n    for (HighsInt i = 0; i < num_clock; i++) {\n      clock_num_call[i] = 0;\n      clock_start[i] = initial_clock_start;\n      clock_time[i] = 0;\n    }\n  }\n\n  /**\n   * @brief write all clocks\n   */\n  void writeAllClocks() {\n    for (HighsInt i = 0; i < num_clock; i++)\n      if (clock_num_call[i])\n        if (printf_flag)\n          printf(\"Time %7.5f for %9d calls of clock %3d: %s\\n\", clock_time[i],\n                 int(clock_num_call[i]), int(i), clock_names[i].c_str());\n  }\n\n  /**\n   * @brief Start a clock\n   */\n  void start(const HighsInt i_clock = 0  //!< Index of the clock to be started\n  ) {\n    assert(i_clock >= 0);\n    assert(i_clock < num_clock);\n    // Check that the clock's been stopped. It should be set to\n    // getWallTime() >= 0 (or initialised to initial_clock_start > 0)\n    const bool clock_stopped = clock_start[i_clock] > 0;\n    if (i_clock != hipo_analytic_centre_clock &&\n        i_clock != ipx_analytic_centre_clock) {\n      // Sometimes the analytic centre clock isn't stopped - because\n      // it runs on a separate thread. Although it would be good to\n      // understand this better, for now don't assert that this clock\n      // has stopped\n      if (!clock_stopped) {\n        if (printf_flag)\n          printf(\"Clock %d - %s - still running\\n\", int(i_clock),\n                 clock_names[i_clock].c_str());\n      }\n      assert(clock_stopped);\n    }\n    // Set the start to be the negation of the WallTick to check that\n    // the clock's been started when it's next stopped\n    if (i_clock == check_clock) {\n      if (printf_flag)\n        printf(\"HighsTimer: starting clock %d: %s\\n\", int(check_clock),\n               this->clock_names[check_clock].c_str());\n    }\n    clock_start[i_clock] = -getWallTime();\n  }\n\n  /**\n   * @brief Stop a clock\n   */\n  void stop(const HighsInt i_clock = 0  //!< Index of the clock to be stopped\n  ) {\n    assert(i_clock >= 0);\n    assert(i_clock < num_clock);\n    // Check that the clock's been started. It should be set to\n    // -getWallTime() <= 0\n    const bool clock_stopped = clock_start[i_clock] > 0;\n    if (clock_stopped) {\n      if (printf_flag)\n        printf(\"Clock %d - %s - not running\\n\", int(i_clock),\n               clock_names[i_clock].c_str());\n    }\n    assert(!clock_stopped);\n    double wall_time = getWallTime();\n    double callClockTimes = wall_time + clock_start[i_clock];\n    clock_time[i_clock] += callClockTimes;\n    clock_num_call[i_clock]++;\n    // Set the start to be the WallTick to check that the clock's been\n    // stopped when it's next started\n    if (i_clock == check_clock) {\n      if (printf_flag)\n        printf(\"HighsTimer: stopping clock %d: %s\\n\", int(check_clock),\n               this->clock_names[check_clock].c_str());\n    }\n    clock_start[i_clock] = wall_time;\n  }\n\n  /**\n   * @brief Read the time of a clock\n   */\n  double read(const HighsInt i_clock = 0  //!< Index of the clock to be read\n  ) const {\n    assert(i_clock >= 0);\n    assert(i_clock < num_clock);\n    if (i_clock == check_clock) {\n      std::string clock_name = this->clock_names[check_clock];\n      if (printf_flag)\n        printf(\"HighsTimer: reading clock %d: %s\\n\", int(check_clock),\n               clock_name.c_str());\n    }\n    double read_time;\n    if (clock_start[i_clock] < 0) {\n      // The clock's been started, so find the current time\n      double wall_time = getWallTime();\n      read_time = clock_time[i_clock] + wall_time + clock_start[i_clock];\n    } else {\n      // The clock is currently stopped, so read the current time\n      read_time = clock_time[i_clock];\n    }\n    return read_time;\n  }\n\n  /**\n   * @brief Return whether a clock is running\n   */\n  bool running(const HighsInt i_clock = 0  //!< Index of the clock to be read\n  ) const {\n    assert(i_clock >= 0);\n    assert(i_clock < num_clock);\n    if (i_clock == check_clock) {\n      if (printf_flag)\n        printf(\"HighsTimer: querying clock %d: %s - with start record %g\\n\",\n               int(check_clock), this->clock_names[check_clock].c_str(),\n               clock_start[i_clock]);\n    }\n    return clock_start[i_clock] < 0;\n  }\n\n  /**\n   * @brief Return number of calls to a clock\n   */\n  HighsInt numCall(\n      const HighsInt i_clock = 0  //!< Index of the clock to be read\n  ) const {\n    assert(i_clock >= 0);\n    assert(i_clock < num_clock);\n    return clock_num_call[i_clock];\n  }\n\n  /**\n   * @brief Add number of calls and time to a clock\n   */\n  void add(const HighsInt i_clock,  //!< Index of the clock to be read\n           const HighsInt num_call, const double time = 0) {\n    assert(i_clock >= 0);\n    assert(i_clock < num_clock);\n    clock_num_call[i_clock] += num_call;\n    clock_time[i_clock] += time;\n  }\n\n  /**\n   * @brief Report timing information for the clock indices in the list\n   */\n  bool report(const char* grep_stamp,  //!< Character string used to extract\n                                       //!< output using grep\n              std::vector<HighsInt>& clock_list,  //!< List of indices to report\n              double ideal_sum_time = 0  //!< Ideal value for times to sum to\n  ) const {\n    const double tolerance_percent_report = 1.0;\n    return reportOnTolerance(grep_stamp, clock_list, ideal_sum_time,\n                             tolerance_percent_report);\n  }\n\n  bool reportOnTolerance(\n      const char*\n          grep_stamp,  //!< Character string used to extract output using grep\n      std::vector<HighsInt>& clock_list,  //!< List of indices to report\n      double ideal_sum_time = 0,          //!< Ideal value for times to sum to\n      double tolerance_percent_report =\n          0  //!< Lower bound on percentage of total time\n             //!< before an individual clock is reported\n  ) const {\n    size_t num_clock_list_entries = clock_list.size();\n    double current_run_highs_time = read();\n    bool non_null_report = false;\n    if (!printf_flag) return non_null_report;\n    // Check validity of the clock list and check no clocks are still\n    // running, determine whether there are any times to report and\n    // determine the total clock times\n    HighsInt sum_calls = 0;\n    double sum_clock_times = 0;\n    for (size_t i = 0; i < num_clock_list_entries; i++) {\n      HighsInt iClock = clock_list[i];\n      assert(iClock >= 0);\n      assert(iClock < num_clock);\n      // Check that the clock's not still running. It should be set to\n      // getWallTime() >= 0 (or initialised to initial_clock_start > 0)\n      const bool clock_stopped = clock_start[iClock] > 0;\n      if (iClock != hipo_analytic_centre_clock &&\n          iClock != ipx_analytic_centre_clock) {\n        // Sometimes the analytic centre clock isn't stopped - because\n        // it runs on a separate thread. Although it would be good to\n        // understand this better, for now don't assert that this clock\n        // has stopped\n        if (!clock_stopped) {\n          printf(\"Clock %d - %s - still running\\n\", int(iClock),\n                 clock_names[iClock].c_str());\n        }\n        assert(clock_stopped);\n      }\n      sum_calls += clock_num_call[iClock];\n      sum_clock_times += clock_time[iClock];\n    }\n    if (!sum_calls) return non_null_report;\n    if (sum_clock_times < 0) return non_null_report;\n\n    std::vector<double> percent_sum_clock_times(num_clock_list_entries);\n    double max_percent_sum_clock_times = 0;\n    for (size_t i = 0; i < num_clock_list_entries; i++) {\n      HighsInt iClock = clock_list[i];\n      percent_sum_clock_times[i] = 100.0 * clock_time[iClock] / sum_clock_times;\n      max_percent_sum_clock_times =\n          std::max(percent_sum_clock_times[i], max_percent_sum_clock_times);\n    }\n    if (max_percent_sum_clock_times < tolerance_percent_report)\n      return non_null_report;\n\n    non_null_report = true;\n\n    // Report one line per clock, the time, number of calls and time per call\n    printf(\"\\n%s-time  Operation                       :    Time     ( Total\",\n           grep_stamp);\n    if (ideal_sum_time > 0) printf(\";  Ideal\");\n    printf(\";  Local):    Calls  Time/Call\\n\");\n    // Convert approximate seconds\n    double sum_time = 0;\n    for (size_t i = 0; i < num_clock_list_entries; i++) {\n      HighsInt iClock = clock_list[i];\n      double time = clock_time[iClock];\n      double percent_run_highs = 100.0 * time / current_run_highs_time;\n      double time_per_call = 0;\n      if (clock_num_call[iClock] > 0) {\n        time_per_call = time / clock_num_call[iClock];\n        const bool report_time =\n            tolerance_percent_report > 0\n                ? percent_sum_clock_times[i] >= tolerance_percent_report\n                : clock_num_call[iClock] > 0;\n        if (report_time) {\n          printf(\"%s-time  %-32s: %11.4e (%5.1f%%\", grep_stamp,\n                 clock_names[iClock].c_str(), time, percent_run_highs);\n          if (ideal_sum_time > 0) {\n            double percent_ideal = 100.0 * time / ideal_sum_time;\n            printf(\"; %5.1f%%\", percent_ideal);\n          }\n          printf(\"; %5.1f%%):%9ld %11.4e\\n\", percent_sum_clock_times[i],\n                 static_cast<long int>(clock_num_call[iClock]), time_per_call);\n        }\n      }\n      sum_time += time;\n    }\n    double percent_sum_clock_times_all = 100.0;\n    assert(sum_time == sum_clock_times);\n    double percent_run_highs = 100.0 * sum_time / current_run_highs_time;\n    printf(\"%s-time  SUM                             : %11.4e (%5.1f%%\",\n           grep_stamp, sum_time, percent_run_highs);\n    if (ideal_sum_time > 0) {\n      double percent_ideal = 100.0 * sum_time / ideal_sum_time;\n      printf(\"; %5.1f%%\", percent_ideal);\n    }\n    printf(\"; %5.1f%%)\\n\", percent_sum_clock_times_all);\n    printf(\"%s-time  TOTAL                           : %11.4e\\n\", grep_stamp,\n           current_run_highs_time);\n    return non_null_report;\n  }\n\n  /**\n   * @brief Return the current wall-clock time\n   */\n  double getWallTime() const {\n    using namespace std::chrono;\n    const double wall_time = kNoClockCalls\n                                 ? 0\n                                 : duration_cast<duration<double> >(\n                                       wall_clock::now().time_since_epoch())\n                                       .count();\n    return wall_time;\n  }\n\n  virtual ~HighsTimer() = default;\n\n  // private:\n  using wall_clock = std::chrono::high_resolution_clock;\n  using time_point = wall_clock::time_point;\n\n  // Dummy positive start time for clocks - so they can be checked as\n  // having been stopped\n  const double initial_clock_start = 1.0;\n\n  HighsInt num_clock = 0;\n  std::vector<HighsInt> clock_num_call;\n  std::vector<double> clock_start;\n  std::vector<double> clock_time;\n  std::vector<std::string> clock_names;\n  // Fundamental clocks\n  HighsInt presolve_clock;\n  HighsInt solve_clock;\n  HighsInt postsolve_clock;\n  bool printf_flag;\n};\n\n#endif /* UTIL_HIGHSTIMER_H_ */\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/HighsUtils.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/**@file util/HUtils.h\n * @brief Class-independent utilities for HiGHS\n */\n#ifndef UTIL_HIGHSUTILS_H_\n#define UTIL_HIGHSUTILS_H_\n\n#include <cassert>\n#include <string>\n#include <vector>\n\n#include \"lp_data/HighsOptions.h\"\n\nconst HighsInt kIndexCollectionCreateOk = 0;\nconst HighsInt kIndexCollectionCreateIllegalInterval = 1;\nconst HighsInt kIndexCollectionCreateIllegalSetSize = 1;\nconst HighsInt kIndexCollectionCreateIllegalSetDimension = 2;\nconst HighsInt kIndexCollectionCreateIllegalSetOrder = 3;\nconst HighsInt kIndexCollectionCreateIllegalMaskSize = 1;\n\nvoid highsSparseTranspose(HighsInt numRow, HighsInt numCol,\n                          const std::vector<HighsInt>& Astart,\n                          const std::vector<HighsInt>& Aindex,\n                          const std::vector<double>& Avalue,\n                          std::vector<HighsInt>& ARstart,\n                          std::vector<HighsInt>& ARindex,\n                          std::vector<double>& ARvalue);\n\nstruct HighsIndexCollection {\n  HighsInt dimension_ = -1;\n  bool is_interval_ = false;\n  HighsInt from_ = -1;\n  HighsInt to_ = -2;\n  bool is_set_ = false;\n  HighsInt set_num_entries_ = -1;\n  std::vector<HighsInt> set_;\n  bool is_mask_ = false;\n  std::vector<HighsInt> mask_;\n};\n\nstruct HighsValueDistribution {\n  std::string distribution_name_;\n  std::string value_name_;\n  HighsInt num_count_;\n  HighsInt num_zero_;\n  HighsInt num_one_;\n  double min_value_;\n  double max_value_;\n  std::vector<double> limit_;\n  std::vector<HighsInt> count_;\n  HighsInt sum_count_;\n};\n\nstruct HighsScatterData {\n  HighsInt max_num_point_;\n  HighsInt num_point_;\n  HighsInt last_point_;\n  std::vector<double> value0_;\n  std::vector<double> value1_;\n  bool have_regression_coeff_;\n  double linear_coeff0_;\n  double linear_coeff1_;\n  double linear_regression_error_;\n  double log_coeff0_;\n  double log_coeff1_;\n  double log_regression_error_;\n  HighsInt num_error_comparison_;\n  HighsInt num_awful_linear_;\n  HighsInt num_awful_log_;\n  HighsInt num_bad_linear_;\n  HighsInt num_bad_log_;\n  HighsInt num_fair_linear_;\n  HighsInt num_fair_log_;\n  HighsInt num_better_linear_;\n  HighsInt num_better_log_;\n};\n\nconst double awful_regression_error = 2.0;\nconst double bad_regression_error = 0.2;\nconst double fair_regression_error = 0.02;\n\nHighsInt create(HighsIndexCollection& index_collection, const HighsInt from_col,\n                const HighsInt to_col, const HighsInt dimension);\n\nHighsInt create(HighsIndexCollection& index_collection,\n                const HighsInt num_set_entries, const HighsInt* set,\n                const HighsInt dimension);\n\nHighsInt create(HighsIndexCollection& index_collection, const HighsInt* mask,\n                const HighsInt dimension);\n\nbool ok(const HighsIndexCollection& index_collection);\n\nvoid limits(const HighsIndexCollection& index_collection, HighsInt& from_k,\n            HighsInt& to_k);\n\nvoid updateOutInIndex(const HighsIndexCollection& index_collection,\n                      HighsInt& out_from_ix, HighsInt& out_to_ix,\n                      HighsInt& in_from_ix, HighsInt& in_to_ix,\n                      HighsInt& current_set_entry);\n\nHighsInt dataSize(const HighsIndexCollection& index_collection);\n\nbool highsVarTypeUserDataNotNull(const HighsLogOptions& log_options,\n                                 const HighsVarType* user_data,\n                                 const std::string name);\nbool intUserDataNotNull(const HighsLogOptions& log_options,\n                        const HighsInt* user_data, const std::string name);\nbool doubleUserDataNotNull(const HighsLogOptions& log_options,\n                           const double* user_data, const std::string name);\n\ndouble getNorm2(const std::vector<double> values);\n\n/**\n * @brief Logical check of double being +Infinity\n */\nbool highs_isInfinity(double val  //!< Value being tested against +Infinity\n);\n/**\n * @brief Returns the relative difference of two doubles\n */\ndouble highsRelativeDifference(const double v0, const double v1);\n\n/**\n * @brief Analyse the values of a vector, assessing how many are in\n * each power of ten, and possibly analyse the distribution of\n * different values\n *\n * NB If log_options is a null pointer then printf is used\n */\nvoid analyseVectorValues(\n    const HighsLogOptions* log_options,\n    const std::string message,       //!< Message to be printed\n    HighsInt vecDim,                 //!< Dimension of vector\n    const std::vector<double>& vec,  //!< Vector of values\n    bool analyseValueList = false,   //!< Possibly analyse the distribution of\n                                     //!< different values in the vector\n    std::string model_name =\n        \"Unknown\"  //!< Model name to report if analysing distribution of\n                   //!< different values in the vector\n);\n\nvoid analyseVectorValues(\n    const HighsLogOptions* log_options,\n    const std::string message,         //!< Message to be printed\n    HighsInt vecDim,                   //!< Dimension of vector\n    const std::vector<HighsInt>& vec,  //!< Vector of values\n    std::string model_name =\n        \"Unknown\"  //!< Model name to report if analysing distribution of\n                   //!< different values in the vector\n);\n\nvoid analyseMatrixSparsity(\n    const HighsLogOptions& log_options,\n    const char* message,                  //!< Message to be printed\n    HighsInt numCol,                      //!< Number of columns\n    HighsInt numRow,                      //!< Number of rows\n    const std::vector<HighsInt>& Astart,  //!< Matrix column starts\n    const std::vector<HighsInt>& Aindex   //!< Matrix row indices\n);\n\nbool initialiseValueDistribution(const std::string distribution_name,\n                                 const std::string value_name,\n                                 const double min_value_limit,\n                                 const double max_value_limit,\n                                 const double base_value_limit,\n                                 HighsValueDistribution& value_distribution);\n\nbool updateValueDistribution(const double value,\n                             HighsValueDistribution& value_distribution);\n\nHighsInt integerPercentage(const HighsInt of, const HighsInt in);\ndouble doublePercentage(const HighsInt of, const HighsInt in);\n\nbool logValueDistribution(const HighsLogOptions& log_options,\n                          const HighsValueDistribution& value_distribution,\n                          const HighsInt mu = 0);\nbool initialiseScatterData(const HighsInt max_num_point,\n                           HighsScatterData& scatter_data);\nbool updateScatterData(const double value0, const double value1,\n                       HighsScatterData& scatter_data);\nbool regressScatterData(HighsScatterData& scatter_data);\nbool predictFromScatterData(const HighsScatterData& scatter_data,\n                            const double value0, double& predicted_value1,\n                            const bool log_regression = false);\nbool printScatterData(std::string name, const HighsScatterData& scatter_data);\nvoid printScatterDataRegressionComparison(std::string name,\n                                          const HighsScatterData& scatter_data);\nbool computeScatterDataRegressionError(HighsScatterData& scatter_data,\n                                       const bool print = false);\n\ndouble nearestPowerOfTwoScale(const double value);\n\n// If assert_condition is false then, if NDEBUG is defined message is\n// printed and abort() is called, otherwise assert is called\nvoid highsAssert(const bool assert_condition, const std::string message = \"\");\n\n// If pause_condition is true, then keyboard input is required. Allows\n// breakpoints in VScode where optimization might prevent them.\nbool highsPause(const bool pause_condition, const std::string message = \"\");\n\n// Utility for computing fractional part\ntemplate <typename T>\ninline T fractionality(T input, T* intval = nullptr) {\n  using std::abs;\n  using std::round;\n  T val = round(input);\n  if (intval != nullptr) *intval = val;\n  return abs(input - val);\n}\n#endif  // UTIL_HIGHSUTILS_H_\n"
  },
  {
    "path": "thirdparty/solvers/highs/util/stringutil.h",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n/*                                                                       */\n/*    This file is part of the HiGHS linear optimization suite           */\n/*                                                                       */\n/*    Available as open-source under the MIT License                     */\n/*                                                                       */\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n#ifndef STRINGUTIL_H\n#define STRINGUTIL_H\n\n#include <ctype.h>\n\n#include <cstring>\n#include <string>\n\n/*\nvoid strRemoveWhitespace(char* str);\nchar* strClone(const char* str);\nint strIsWhitespace(const char* str);\nvoid strToLower(char* str);\nvoid strTrim(char* str);\n*/\n// std::string& str_tolower(std::string s);\n\nvoid tolower(std::string& str);\nvoid toupper(std::string& str);\n\nconst std::string default_non_chars = \"\\t\\n\\v\\f\\r \";\nstd::string& ltrim(std::string& str,\n                   const std::string& chars = default_non_chars);\nstd::string& rtrim(std::string& str,\n                   const std::string& chars = default_non_chars);\nstd::string& trim(std::string& str,\n                  const std::string& chars = default_non_chars);\n\nbool is_empty(std::string& str, const std::string& chars = default_non_chars);\nbool is_empty(char c, const std::string& chars = default_non_chars);\nbool is_end(std::string& str, size_t end,\n            const std::string& chars = default_non_chars);\n\n// todo: replace with pair of references rather than string ret value to avoid\n// copy and also using function below. or do it properly with iterators.\nstd::string first_word(std::string& str, size_t start);\nsize_t first_word_end(std::string& str, size_t start);\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/highs/zstr/strict_fstream.hpp",
    "content": "#pragma once\n\n#include <cassert>\n#include <fstream>\n#include <cstring>\n#include <string>\n#include <vector>\n\n/**\n * This namespace defines wrappers for std::ifstream, std::ofstream, and\n * std::fstream objects. The wrappers perform the following steps:\n * - check the open modes make sense\n * - check that the call to open() is successful\n * - (for input streams) check that the opened file is peek-able\n * - turn on the badbit in the exception mask\n */\nnamespace strict_fstream\n{\n\n// Help people out a bit, it seems like this is a common recommendation since\n// musl breaks all over the place.\n#if defined(__NEED_size_t) && !defined(__MUSL__)\n#warning \"It seems to be recommended to patch in a define for __MUSL__ if you use musl globally: https://www.openwall.com/lists/musl/2013/02/10/5\"\n#define __MUSL__\n#endif\n\n// Workaround for broken musl implementation\n// Since musl insists that they are perfectly compatible, ironically enough,\n// they don't officially have a __musl__ or similar. But __NEED_size_t is defined in their\n// relevant header (and not in working implementations), so we can use that.\n#ifdef __MUSL__\n#warning \"Working around broken strerror_r() implementation in musl, remove when musl is fixed\"\n#endif\n\n// Non-gnu variants of strerror_* don't necessarily null-terminate if\n// truncating, so we have to do things manually.\ninline std::string trim_to_null(const std::vector<char> &buff)\n{\n    std::string ret(buff.begin(), buff.end());\n\n    const std::string::size_type pos = ret.find('\\0');\n    if (pos == std::string::npos) {\n        ret += \" [...]\"; // it has been truncated\n    } else {\n        ret.resize(pos);\n    }\n    return ret;\n}\n\n/// Overload of error-reporting function, to enable use with VS and non-GNU\n/// POSIX libc's\n/// Ref:\n///   - http://stackoverflow.com/a/901316/717706\nstatic std::string strerror()\n{\n    // Can't use std::string since we're pre-C++17\n    std::vector<char> buff(256, '\\0');\n\n#ifdef _WIN32\n    // Since strerror_s might set errno itself, we need to store it.\n    const int err_num = errno;\n    if (strerror_s(buff.data(), buff.size(), err_num) != 0) {\n        return trim_to_null(buff);\n    } else {\n        return \"Unknown error (\" + std::to_string(err_num) + \")\";\n    }\n#elif ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600 || defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)) && ! _GNU_SOURCE) || defined(__MUSL__)\n// XSI-compliant strerror_r()\n    const int err_num = errno; // See above\n    if (strerror_r(err_num, buff.data(), buff.size()) == 0) {\n        return trim_to_null(buff);\n    } else {\n        return \"Unknown error (\" + std::to_string(err_num) + \")\";\n    }\n#else\n// GNU-specific strerror_r()\n    char * p = strerror_r(errno, &buff[0], buff.size());\n    return std::string(p, std::strlen(p));\n#endif\n}\n\n/// Exception class thrown by failed operations.\nclass Exception\n    : public std::exception\n{\npublic:\n    Exception(const std::string& msg) : _msg(msg) {}\n    const char * what() const noexcept { return _msg.c_str(); }\nprivate:\n    std::string _msg;\n}; // class Exception\n\nnamespace detail\n{\n\nstruct static_method_holder\n{\n    static std::string mode_to_string(std::ios_base::openmode mode)\n    {\n        static const int n_modes = 6;\n        static const std::ios_base::openmode mode_val_v[n_modes] =\n            {\n                std::ios_base::in,\n                std::ios_base::out,\n                std::ios_base::app,\n                std::ios_base::ate,\n                std::ios_base::trunc,\n                std::ios_base::binary\n            };\n\n        static const char * mode_name_v[n_modes] =\n            {\n                \"in\",\n                \"out\",\n                \"app\",\n                \"ate\",\n                \"trunc\",\n                \"binary\"\n            };\n        std::string res;\n        for (int i = 0; i < n_modes; ++i)\n        {\n            if (mode & mode_val_v[i])\n            {\n                res += (! res.empty()? \"|\" : \"\");\n                res += mode_name_v[i];\n            }\n        }\n        if (res.empty()) res = \"none\";\n        return res;\n    }\n    static void check_mode(const std::string& filename, std::ios_base::openmode mode)\n    {\n        if ((mode & std::ios_base::trunc) && ! (mode & std::ios_base::out))\n        {\n            throw Exception(std::string(\"strict_fstream: open('\") + filename + \"'): mode error: trunc and not out\");\n        }\n        else if ((mode & std::ios_base::app) && ! (mode & std::ios_base::out))\n        {\n            throw Exception(std::string(\"strict_fstream: open('\") + filename + \"'): mode error: app and not out\");\n        }\n        else if ((mode & std::ios_base::trunc) && (mode & std::ios_base::app))\n        {\n            throw Exception(std::string(\"strict_fstream: open('\") + filename + \"'): mode error: trunc and app\");\n        }\n     }\n    static void check_open(std::ios * s_p, const std::string& filename, std::ios_base::openmode mode)\n    {\n        if (s_p->fail())\n        {\n            throw Exception(std::string(\"strict_fstream: open('\")\n                            + filename + \"',\" + mode_to_string(mode) + \"): open failed: \"\n                            + strerror());\n        }\n    }\n    static void check_peek(std::istream * is_p, const std::string& filename, std::ios_base::openmode mode)\n    {\n        bool peek_failed = true;\n        try\n        {\n            is_p->peek();\n            peek_failed = is_p->fail();\n        }\n        catch (const std::ios_base::failure &) {}\n        if (peek_failed)\n        {\n            throw Exception(std::string(\"strict_fstream: open('\")\n                            + filename + \"',\" + mode_to_string(mode) + \"): peek failed: \"\n                            + strerror());\n        }\n        is_p->clear();\n    }\n}; // struct static_method_holder\n\n} // namespace detail\n\nclass ifstream\n    : public std::ifstream\n{\npublic:\n    ifstream() = default;\n    ifstream(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in)\n    {\n        open(filename, mode);\n    }\n    void open(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in)\n    {\n        mode |= std::ios_base::in;\n        exceptions(std::ios_base::badbit);\n        detail::static_method_holder::check_mode(filename, mode);\n        std::ifstream::open(filename, mode);\n        detail::static_method_holder::check_open(this, filename, mode);\n        detail::static_method_holder::check_peek(this, filename, mode);\n    }\n}; // class ifstream\n\nclass ofstream\n    : public std::ofstream\n{\npublic:\n    ofstream() = default;\n    ofstream(const std::string& filename, std::ios_base::openmode mode = std::ios_base::out)\n    {\n        open(filename, mode);\n    }\n    void open(const std::string& filename, std::ios_base::openmode mode = std::ios_base::out)\n    {\n        mode |= std::ios_base::out;\n        exceptions(std::ios_base::badbit);\n        detail::static_method_holder::check_mode(filename, mode);\n        std::ofstream::open(filename, mode);\n        detail::static_method_holder::check_open(this, filename, mode);\n    }\n}; // class ofstream\n\nclass fstream\n    : public std::fstream\n{\npublic:\n    fstream() = default;\n    fstream(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in)\n    {\n        open(filename, mode);\n    }\n    void open(const std::string& filename, std::ios_base::openmode mode = std::ios_base::in)\n    {\n        if (! (mode & std::ios_base::out)) mode |= std::ios_base::in;\n        exceptions(std::ios_base::badbit);\n        detail::static_method_holder::check_mode(filename, mode);\n        std::fstream::open(filename, mode);\n        detail::static_method_holder::check_open(this, filename, mode);\n        detail::static_method_holder::check_peek(this, filename, mode);\n    }\n}; // class fstream\n\n} // namespace strict_fstream\n\n"
  },
  {
    "path": "thirdparty/solvers/highs/zstr/zstr.hpp",
    "content": "//---------------------------------------------------------\n// Copyright 2015 Ontario Institute for Cancer Research\n// Written by Matei David (matei@cs.toronto.edu)\n//---------------------------------------------------------\n\n// Reference:\n// http://stackoverflow.com/questions/14086417/how-to-write-custom-input-stream-in-c\n\n#pragma once\n\n#include <zlib.h>\n\n#include <cassert>\n#include <cstdint>\n#include <fstream>\n#include <iostream>\n#include <memory>\n#include <sstream>\n\n#include \"../extern/zstr/strict_fstream.hpp\"\n\nnamespace zstr {\n\nstatic const std::size_t default_buff_size = static_cast<std::size_t>(1 << 20);\n\n/// Exception class thrown by failed zlib operations.\nclass Exception : public std::ios_base::failure {\n public:\n  static std::string error_to_message(z_stream* zstrm_p, int ret) {\n    std::string msg = \"zlib: \";\n    switch (ret) {\n      case Z_STREAM_ERROR:\n        msg += \"Z_STREAM_ERROR: \";\n        break;\n      case Z_DATA_ERROR:\n        msg += \"Z_DATA_ERROR: \";\n        break;\n      case Z_MEM_ERROR:\n        msg += \"Z_MEM_ERROR: \";\n        break;\n      case Z_VERSION_ERROR:\n        msg += \"Z_VERSION_ERROR: \";\n        break;\n      case Z_BUF_ERROR:\n        msg += \"Z_BUF_ERROR: \";\n        break;\n      default:\n        std::ostringstream oss;\n        oss << ret;\n        msg += \"[\" + oss.str() + \"]: \";\n        break;\n    }\n    if (zstrm_p->msg) {\n      msg += zstrm_p->msg;\n    }\n    msg +=\n        \" (\"\n        \"next_in: \" +\n        std::to_string(uintptr_t(zstrm_p->next_in)) +\n        \", avail_in: \" + std::to_string(uintptr_t(zstrm_p->avail_in)) +\n        \", next_out: \" + std::to_string(uintptr_t(zstrm_p->next_out)) +\n        \", avail_out: \" + std::to_string(uintptr_t(zstrm_p->avail_out)) + \")\";\n    return msg;\n  }\n\n  Exception(z_stream* zstrm_p, int ret)\n      : std::ios_base::failure(error_to_message(zstrm_p, ret)) {}\n};  // class Exception\n\nnamespace detail {\n\nclass z_stream_wrapper : public z_stream {\n public:\n  z_stream_wrapper(bool _is_input, int _level, int _window_bits)\n      : is_input(_is_input) {\n    this->zalloc = nullptr;  // Z_NULL\n    this->zfree = nullptr;   // Z_NULL\n    this->opaque = nullptr;  // Z_NULL\n    int ret;\n    if (is_input) {\n      this->avail_in = 0;\n      this->next_in = nullptr;  // Z_NULL\n      ret = inflateInit2(this, _window_bits ? _window_bits : 15 + 32);\n    } else {\n      ret = deflateInit2(this, _level, Z_DEFLATED,\n                         _window_bits ? _window_bits : 15 + 16, 8,\n                         Z_DEFAULT_STRATEGY);\n    }\n    if (ret != Z_OK) throw Exception(this, ret);\n  }\n  ~z_stream_wrapper() {\n    if (is_input) {\n      inflateEnd(this);\n    } else {\n      deflateEnd(this);\n    }\n  }\n\n private:\n  bool is_input;\n};  // class z_stream_wrapper\n\n}  // namespace detail\n\nclass istreambuf : public std::streambuf {\n public:\n  istreambuf(std::streambuf* _sbuf_p,\n             std::size_t _buff_size = default_buff_size,\n             bool _auto_detect = true, int _window_bits = 0)\n      : sbuf_p(_sbuf_p),\n        in_buff(),\n        in_buff_start(nullptr),\n        in_buff_end(nullptr),\n        out_buff(),\n        zstrm_p(nullptr),\n        buff_size(_buff_size),\n        auto_detect(_auto_detect),\n        auto_detect_run(false),\n        is_text(false),\n        window_bits(_window_bits) {\n    assert(sbuf_p);\n    in_buff = std::unique_ptr<char[]>(new char[buff_size]);\n    in_buff_start = in_buff.get();\n    in_buff_end = in_buff.get();\n    out_buff = std::unique_ptr<char[]>(new char[buff_size]);\n    setg(out_buff.get(), out_buff.get(), out_buff.get());\n  }\n\n  istreambuf(const istreambuf&) = delete;\n  istreambuf& operator=(const istreambuf&) = delete;\n\n  pos_type seekoff(off_type off, std::ios_base::seekdir dir,\n                   std::ios_base::openmode which) override {\n    if (off != 0 || dir != std::ios_base::cur) {\n      return std::streambuf::seekoff(off, dir, which);\n    }\n\n    if (!zstrm_p) {\n      return 0;\n    }\n\n    return static_cast<long int>(zstrm_p->total_out -\n                                 static_cast<uLong>(in_avail()));\n  }\n\n  std::streambuf::int_type underflow() override {\n    if (this->gptr() == this->egptr()) {\n      // pointers for free region in output buffer\n      char* out_buff_free_start = out_buff.get();\n      int tries = 0;\n      do {\n        if (++tries > 1000) {\n          throw std::ios_base::failure(\n              \"Failed to fill buffer after 1000 tries\");\n        }\n\n        // read more input if none available\n        if (in_buff_start == in_buff_end) {\n          // empty input buffer: refill from the start\n          in_buff_start = in_buff.get();\n          std::streamsize sz = sbuf_p->sgetn(\n              in_buff.get(), static_cast<std::streamsize>(buff_size));\n          in_buff_end = in_buff_start + sz;\n          if (in_buff_end == in_buff_start) break;  // end of input\n        }\n        // auto detect if the stream contains text or deflate data\n        if (auto_detect && !auto_detect_run) {\n          auto_detect_run = true;\n          unsigned char b0 = *reinterpret_cast<unsigned char*>(in_buff_start);\n          unsigned char b1 =\n              *reinterpret_cast<unsigned char*>(in_buff_start + 1);\n          // Ref:\n          // http://en.wikipedia.org/wiki/Gzip\n          // http://stackoverflow.com/questions/9050260/what-does-a-zlib-header-look-like\n          is_text = !(in_buff_start + 2 <= in_buff_end &&\n                      ((b0 == 0x1F && b1 == 0x8B)     // gzip header\n                       || (b0 == 0x78 && (b1 == 0x01  // zlib header\n                                          || b1 == 0x9C || b1 == 0xDA))));\n        }\n        if (is_text) {\n          // simply swap in_buff and out_buff, and adjust pointers\n          assert(in_buff_start == in_buff.get());\n          std::swap(in_buff, out_buff);\n          out_buff_free_start = in_buff_end;\n          in_buff_start = in_buff.get();\n          in_buff_end = in_buff.get();\n        } else {\n          // run inflate() on input\n          if (!zstrm_p)\n            zstrm_p = std::unique_ptr<detail::z_stream_wrapper>(\n                new detail::z_stream_wrapper(true, Z_DEFAULT_COMPRESSION,\n                                             window_bits));\n          zstrm_p->next_in =\n              reinterpret_cast<decltype(zstrm_p->next_in)>(in_buff_start);\n          zstrm_p->avail_in = uint32_t(in_buff_end - in_buff_start);\n          zstrm_p->next_out = reinterpret_cast<decltype(zstrm_p->next_out)>(\n              out_buff_free_start);\n          zstrm_p->avail_out =\n              uint32_t((out_buff.get() + buff_size) - out_buff_free_start);\n          int ret = inflate(zstrm_p.get(), Z_NO_FLUSH);\n          // process return code\n          if (ret != Z_OK && ret != Z_STREAM_END)\n            throw Exception(zstrm_p.get(), ret);\n          // update in&out pointers following inflate()\n          in_buff_start =\n              reinterpret_cast<decltype(in_buff_start)>(zstrm_p->next_in);\n          in_buff_end = in_buff_start + zstrm_p->avail_in;\n          out_buff_free_start = reinterpret_cast<decltype(out_buff_free_start)>(\n              zstrm_p->next_out);\n          assert(out_buff_free_start + zstrm_p->avail_out ==\n                 out_buff.get() + buff_size);\n\n          if (ret == Z_STREAM_END) {\n            // if stream ended, deallocate inflator\n            zstrm_p.reset();\n          }\n        }\n      } while (out_buff_free_start == out_buff.get());\n      // 2 exit conditions:\n      // - end of input: there might or might not be output available\n      // - out_buff_free_start != out_buff: output available\n      this->setg(out_buff.get(), out_buff.get(), out_buff_free_start);\n    }\n    return this->gptr() == this->egptr()\n               ? traits_type::eof()\n               : traits_type::to_int_type(*this->gptr());\n  }\n\n private:\n  std::streambuf* sbuf_p;\n  std::unique_ptr<char[]> in_buff;\n  char* in_buff_start;\n  char* in_buff_end;\n  std::unique_ptr<char[]> out_buff;\n  std::unique_ptr<detail::z_stream_wrapper> zstrm_p;\n  std::size_t buff_size;\n  bool auto_detect;\n  bool auto_detect_run;\n  bool is_text;\n  int window_bits;\n\n};  // class istreambuf\n\nclass ostreambuf : public std::streambuf {\n public:\n  ostreambuf(std::streambuf* _sbuf_p,\n             std::size_t _buff_size = default_buff_size,\n             int _level = Z_DEFAULT_COMPRESSION, int _window_bits = 0)\n      : sbuf_p(_sbuf_p),\n        in_buff(),\n        out_buff(),\n        zstrm_p(new detail::z_stream_wrapper(false, _level, _window_bits)),\n        buff_size(_buff_size) {\n    assert(sbuf_p);\n    in_buff = std::unique_ptr<char[]>(new char[buff_size]);\n    out_buff = std::unique_ptr<char[]>(new char[buff_size]);\n    setp(in_buff.get(), in_buff.get() + buff_size);\n  }\n\n  ostreambuf(const ostreambuf&) = delete;\n  ostreambuf& operator=(const ostreambuf&) = delete;\n\n  int deflate_loop(int flush) {\n    while (true) {\n      zstrm_p->next_out =\n          reinterpret_cast<decltype(zstrm_p->next_out)>(out_buff.get());\n      zstrm_p->avail_out = uint32_t(buff_size);\n      int ret = deflate(zstrm_p.get(), flush);\n      if (ret != Z_OK && ret != Z_STREAM_END && ret != Z_BUF_ERROR) {\n        failed = true;\n        throw Exception(zstrm_p.get(), ret);\n      }\n      std::streamsize sz = sbuf_p->sputn(\n          out_buff.get(),\n          reinterpret_cast<decltype(out_buff.get())>(zstrm_p->next_out) -\n              out_buff.get());\n      if (sz != reinterpret_cast<decltype(out_buff.get())>(zstrm_p->next_out) -\n                    out_buff.get()) {\n        // there was an error in the sink stream\n        return -1;\n      }\n      if (ret == Z_STREAM_END || ret == Z_BUF_ERROR || sz == 0) {\n        break;\n      }\n    }\n    return 0;\n  }\n\n  virtual ~ostreambuf() {\n    // flush the zlib stream\n    //\n    // NOTE: Errors here (sync() return value not 0) are ignored, because we\n    // cannot throw in a destructor. This mirrors the behaviour of\n    // std::basic_filebuf::~basic_filebuf(). To see an exception on error,\n    // close the ofstream with an explicit call to close(), and do not rely\n    // on the implicit call in the destructor.\n    //\n    if (!failed) try {\n        sync();\n      } catch (...) {\n      }\n  }\n  std::streambuf::int_type overflow(\n      std::streambuf::int_type c = traits_type::eof()) override {\n    zstrm_p->next_in = reinterpret_cast<decltype(zstrm_p->next_in)>(pbase());\n    zstrm_p->avail_in = uint32_t(pptr() - pbase());\n    while (zstrm_p->avail_in > 0) {\n      int r = deflate_loop(Z_NO_FLUSH);\n      if (r != 0) {\n        setp(nullptr, nullptr);\n        return traits_type::eof();\n      }\n    }\n    setp(in_buff.get(), in_buff.get() + buff_size);\n    return traits_type::eq_int_type(c, traits_type::eof())\n               ? traits_type::eof()\n               : sputc(char_type(c));\n  }\n  int sync() override {\n    // first, call overflow to clear in_buff\n    overflow();\n    if (!pptr()) return -1;\n    // then, call deflate asking to finish the zlib stream\n    zstrm_p->next_in = nullptr;\n    zstrm_p->avail_in = 0;\n    if (deflate_loop(Z_FINISH) != 0) return -1;\n    deflateReset(zstrm_p.get());\n    return 0;\n  }\n\n private:\n  std::streambuf* sbuf_p = nullptr;\n  std::unique_ptr<char[]> in_buff;\n  std::unique_ptr<char[]> out_buff;\n  std::unique_ptr<detail::z_stream_wrapper> zstrm_p;\n  std::size_t buff_size;\n  bool failed = false;\n\n};  // class ostreambuf\n\nclass istream : public std::istream {\n public:\n  istream(std::istream& is, std::size_t _buff_size = default_buff_size,\n          bool _auto_detect = true, int _window_bits = 0)\n      : std::istream(new istreambuf(is.rdbuf(), _buff_size, _auto_detect,\n                                    _window_bits)) {\n    exceptions(std::ios_base::badbit);\n  }\n  explicit istream(std::streambuf* sbuf_p)\n      : std::istream(new istreambuf(sbuf_p)) {\n    exceptions(std::ios_base::badbit);\n  }\n  virtual ~istream() { delete rdbuf(); }\n};  // class istream\n\nclass ostream : public std::ostream {\n public:\n  ostream(std::ostream& os, std::size_t _buff_size = default_buff_size,\n          int _level = Z_DEFAULT_COMPRESSION, int _window_bits = 0)\n      : std::ostream(\n            new ostreambuf(os.rdbuf(), _buff_size, _level, _window_bits)) {\n    exceptions(std::ios_base::badbit);\n  }\n  explicit ostream(std::streambuf* sbuf_p)\n      : std::ostream(new ostreambuf(sbuf_p)) {\n    exceptions(std::ios_base::badbit);\n  }\n  virtual ~ostream() { delete rdbuf(); }\n};  // class ostream\n\nnamespace detail {\n\ntemplate <typename FStream_Type>\nstruct strict_fstream_holder {\n  strict_fstream_holder(const std::string& filename,\n                        std::ios_base::openmode mode = std::ios_base::in)\n      : _fs(filename, mode) {}\n  strict_fstream_holder() = default;\n  FStream_Type _fs{};\n};  // class strict_fstream_holder\n\n}  // namespace detail\n\nclass ifstream\n    : private detail::strict_fstream_holder<strict_fstream::ifstream>,\n      public std::istream {\n public:\n  explicit ifstream(const std::string filename,\n                    std::ios_base::openmode mode = std::ios_base::in,\n                    size_t buff_size = default_buff_size)\n      : detail::strict_fstream_holder<strict_fstream::ifstream>(\n            filename, mode\n#ifdef _WIN32  // to avoid problems with conversion of \\r\\n, only windows as\n               // otherwise there are problems on mac\n                          | std::ios_base::binary\n#endif\n            ),\n        std::istream(new istreambuf(_fs.rdbuf(), buff_size)) {\n    exceptions(std::ios_base::badbit);\n  }\n  explicit ifstream()\n      : detail::strict_fstream_holder<strict_fstream::ifstream>(),\n        std::istream(new istreambuf(_fs.rdbuf())) {}\n  void close() { _fs.close(); }\n  void open(const std::string filename,\n            std::ios_base::openmode mode = std::ios_base::in) {\n    _fs.open(filename, mode\n#ifdef _WIN32  // to avoid problems with conversion of \\r\\n, only windows as\n               // otherwise there are problems on mac\n                           | std::ios_base::binary\n#endif\n    );\n    // make sure the previous buffer is deleted by putting it into a unique_ptr\n    // and set a new one after opening file\n    std::unique_ptr<std::streambuf> oldbuf(rdbuf(new istreambuf(_fs.rdbuf())));\n    // call move assignment operator on istream which does not alter the stream\n    // buffer\n    std::istream::operator=(std::istream(rdbuf()));\n  }\n  bool is_open() const { return _fs.is_open(); }\n  virtual ~ifstream() {\n    if (_fs.is_open()) close();\n    if (rdbuf()) delete rdbuf();\n  }\n\n  /// Return the position within the compressed file (wrapped filestream)\n  std::streampos compressed_tellg() { return _fs.tellg(); }\n};  // class ifstream\n\nclass ofstream\n    : private detail::strict_fstream_holder<strict_fstream::ofstream>,\n      public std::ostream {\n public:\n  explicit ofstream(const std::string filename,\n                    std::ios_base::openmode mode = std::ios_base::out,\n                    int level = Z_DEFAULT_COMPRESSION,\n                    size_t buff_size = default_buff_size)\n      : detail::strict_fstream_holder<strict_fstream::ofstream>(\n            filename, mode | std::ios_base::binary),\n        std::ostream(new ostreambuf(_fs.rdbuf(), buff_size, level)) {\n    exceptions(std::ios_base::badbit);\n  }\n  explicit ofstream()\n      : detail::strict_fstream_holder<strict_fstream::ofstream>(),\n        std::ostream(new ostreambuf(_fs.rdbuf())) {}\n  void close() {\n    std::ostream::flush();\n    _fs.close();\n  }\n  void open(const std::string filename,\n            std::ios_base::openmode mode = std::ios_base::out,\n            int level = Z_DEFAULT_COMPRESSION) {\n    flush();\n    _fs.open(filename, mode | std::ios_base::binary);\n    std::ostream::operator=(\n        std::ostream(new ostreambuf(_fs.rdbuf(), default_buff_size, level)));\n  }\n  bool is_open() const { return _fs.is_open(); }\n  ofstream& flush() {\n    std::ostream::flush();\n    _fs.flush();\n    return *this;\n  }\n  virtual ~ofstream() {\n    if (_fs.is_open()) close();\n    if (rdbuf()) delete rdbuf();\n  }\n\n  // Return the position within the compressed file (wrapped filestream)\n  std::streampos compressed_tellp() { return _fs.tellp(); }\n};  // class ofstream\n\n}  // namespace zstr\n"
  },
  {
    "path": "thirdparty/solvers/ipopt/IpReturnCodes.h",
    "content": "/* Copyright (C) 2004, 2006 International Business Machines and others.\n * All Rights Reserved.\n * This code is published under the Eclipse Public License.\n *\n * Authors:  Carl Laird, Andreas Waechter     IBM    2004-08-13\n */\n\n#ifndef __IPRETURNCODES_H__\n#define __IPRETURNCODES_H__\n\n/* include from a common include file */\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n#include \"IpReturnCodes_inc.h\"\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/ipopt/IpReturnCodes.inc",
    "content": "C Copyright (C) 2005, 2009 International Business Machines and others.\nC All Rights Reserved.\nC This code is published under the Eclipse Public License.\nC\nC Author:   Andreas Waechter    IBM      2005-08-11\nC\n      INTEGER IP_SOLVE_SUCCEEDED\n      PARAMETER( IP_SOLVE_SUCCEEDED = 0 )\n\n      INTEGER IP_ACCEPTABLE_LEVEL\n      PARAMETER( IP_ACCEPTABLE_LEVEL = 1 )\n\n      INTEGER IP_INFEASIBLE_PROBLEM\n      PARAMETER( IP_INFEASIBLE_PROBLEM = 2 )\n\n      INTEGER IP_SEARCH_DIRECTION_TOO_SMALL\n      PARAMETER( IP_SEARCH_DIRECTION_TOO_SMALL = 3 )\n\n      INTEGER IP_DIVERGING_ITERATES\n      PARAMETER( IP_DIVERGING_ITERATES = 4 )\n\n      INTEGER IP_USER_REQUESTED_STOP\n      PARAMETER( IP_USER_REQUESTED_STOP = 5 )\n\n      INTEGER IP_FEASIBLE_POINT_FOUND\n      PARAMETER( IP_FEASIBLE_POINT_FOUND = 6 )\n\n      INTEGER IP_ITERATION_EXCEEDED\n      PARAMETER( IP_ITERATION_EXCEEDED = -1 )\n\n      INTEGER IP_RESTORATION_FAILED\n      PARAMETER( IP_RESTORATION_FAILED = -2 )\n\n      INTEGER IP_ERROR_IN_STEP_COMPUTATION\n      PARAMETER( IP_ERROR_IN_STEP_COMPUTATION = -3 )\n\n      INTEGER IP_CPUTIME_EXCEEDED\n      PARAMETER( IP_CPUTIME_EXCEEDED = -4 )\n\n      INTEGER IP_WALLTIME_EXCEEDED\n      PARAMETER( IP_WALLTIME_EXCEEDED = -5 )\n\n      INTEGER IP_NOT_ENOUGH_DEGREES_OF_FRE\n      PARAMETER( IP_NOT_ENOUGH_DEGREES_OF_FRE = -10 )\n\n      INTEGER IP_INVALID_PROBLEM_DEFINITION\n      PARAMETER( IP_INVALID_PROBLEM_DEFINITION = -11)\n\n      INTEGER IP_INVALID_OPTION\n      PARAMETER( IP_INVALID_OPTION = -12 )\n\n      INTEGER IP_INVALID_NUMBER_DETECTED\n      PARAMETER( IP_INVALID_NUMBER_DETECTED = -13 )\n\n      INTEGER IP_UNRECOVERABLE_EXCEPTION\n      PARAMETER( IP_UNRECOVERABLE_EXCEPTION = -100 )\n\n      INTEGER IP_NON_IPOPT_EXCEPTION\n      PARAMETER( IP_NON_IPOPT_EXCEPTION = -101 )\n\n      INTEGER IP_INSUFFICIENT_MEMORY\n      PARAMETER( IP_INSUFFICIENT_MEMORY = -102 )\n\n      INTEGER IP_INTERNAL_ERROR\n      PARAMETER( IP_INTERNAL_ERROR = -199 )\n\n      INTEGER IP_REGULAR_MODE\n      PARAMETER( IP_REGULAR_MODE = 0 )\n\n      INTEGER IP_RESTORATION_PHASE_MODE\n      PARAMETER( IP_RESTORATION_PHASE_MODE = 1 )\n"
  },
  {
    "path": "thirdparty/solvers/ipopt/IpReturnCodes_inc.h",
    "content": "/* Copyright (C) 2004, 2009 International Business Machines and others.\n * All Rights Reserved.\n * This code is published under the Eclipse Public License.\n *\n * Authors:  Carl Laird, Andreas Waechter     IBM    2004-08-13\n */\n\n/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */\n/* !!!!!!!!! REMEMBER TO UPDATE IpReturnCodes.inc and Ipopt.java !!!!!!!! */\n/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */\n\n/** Return codes for the Optimize call for an application */\nenum ApplicationReturnStatus\n{\n   Solve_Succeeded                    = 0,\n   Solved_To_Acceptable_Level         = 1,\n   Infeasible_Problem_Detected        = 2,\n   Search_Direction_Becomes_Too_Small = 3,\n   Diverging_Iterates                 = 4,\n   User_Requested_Stop                = 5,\n   Feasible_Point_Found               = 6,\n\n   Maximum_Iterations_Exceeded        = -1,\n   Restoration_Failed                 = -2,\n   Error_In_Step_Computation          = -3,\n   Maximum_CpuTime_Exceeded           = -4,\n   Maximum_WallTime_Exceeded          = -5,   ///< @since 3.14.0\n\n   Not_Enough_Degrees_Of_Freedom      = -10,\n   Invalid_Problem_Definition         = -11,\n   Invalid_Option                     = -12,\n   Invalid_Number_Detected            = -13,\n\n   Unrecoverable_Exception            = -100,\n   NonIpopt_Exception_Thrown          = -101,\n   Insufficient_Memory                = -102,\n   Internal_Error                     = -199\n};\n\n/** enum to indicate the mode in which the algorithm is */\nenum AlgorithmMode\n{\n   RegularMode          = 0,\n   RestorationPhaseMode = 1\n};\n"
  },
  {
    "path": "thirdparty/solvers/ipopt/IpStdCInterface.h",
    "content": "/* Copyright (C) 2004, 2010 International Business Machines and others.\n * All Rights Reserved.\n * This code is published under the Eclipse Public License.\n *\n * Authors:  Carl Laird, Andreas Waechter     IBM    2004-09-02\n */\n\n#ifndef __IPSTDCINTERFACE_H__\n#define __IPSTDCINTERFACE_H__\n\n#include <stdbool.h>\n\n#include \"IpoptConfig.h\"\n#include \"IpTypes.h\"\n#include \"IpReturnCodes.h\"\n\n#ifndef IPOPT_EXPORT\n/** @deprecated Use IPOPT_CALLCONV instead. */\n#define IPOPT_EXPORT(type) type IPOPT_CALLCONV\n#endif\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n/** Type for all number.\n * @deprecated Use ipnumber instead.\n */\nIPOPT_DEPRECATED\ntypedef ipnumber Number;\n\n/** Type for all indices.\n * @deprecated Use ipindex instead.\n */\nIPOPT_DEPRECATED\ntypedef int Index;\n\n/** Type for all integers.\n * @deprecated Use int instead.\n */\nIPOPT_DEPRECATED\ntypedef int Int;\n\n/** Structure collecting all information about the problem definition and solve statistics etc. */\nstruct IpoptProblemInfo;\n\n/** Pointer to an Ipopt Problem. */\ntypedef struct IpoptProblemInfo* IpoptProblem;\n\n/** define a boolean type for C\n * @deprecated Use bool instead.\n */\ntypedef bool Bool;\n#ifndef TRUE\n/* @deprecated Use true instead. */\n# define TRUE (1)\n#endif\n/* @deprecated Use false instead. */\n#ifndef FALSE\n# define FALSE (0)\n#endif\n\n/** A pointer for anything that is to be passed between the called and individual callback function */\ntypedef void* UserDataPtr;\n\n/** Type defining the callback function for evaluating the value of the objective function.\n *\n *  Return value should be set to false if there was a problem doing the evaluation.\n *\n *  See also Ipopt::TNLP::eval_f.\n */\ntypedef bool (*Eval_F_CB)(\n   ipindex     n,\n   ipnumber*   x,\n   bool        new_x,\n   ipnumber*   obj_value,\n   UserDataPtr user_data\n);\n\n/** Type defining the callback function for evaluating the gradient of the objective function.\n *\n *  Return value should be set to false if there was a problem doing the evaluation.\n *\n *  See also Ipopt::TNLP::eval_grad_f.\n */\ntypedef bool (*Eval_Grad_F_CB)(\n   ipindex     n,\n   ipnumber*   x,\n   bool        new_x,\n   ipnumber*   grad_f,\n   UserDataPtr user_data\n);\n\n/** Type defining the callback function for evaluating the value of the constraint functions.\n *\n *  Return value should be set to false if there was a problem doing the evaluation.\n *\n *  See also Ipopt::TNLP::eval_g.\n */\ntypedef bool (*Eval_G_CB)(\n   ipindex     n,\n   ipnumber*   x,\n   bool        new_x,\n   ipindex     m,\n   ipnumber*   g,\n   UserDataPtr user_data\n);\n\n/** Type defining the callback function for evaluating the Jacobian of the constrant functions.\n *\n *  Return value should be set to false if there was a problem doing the evaluation.\n *\n *  See also Ipopt::TNLP::eval_jac_g.\n */\ntypedef bool (*Eval_Jac_G_CB)(\n   ipindex     n,\n   ipnumber*   x,\n   bool        new_x,\n   ipindex     m,\n   ipindex     nele_jac,\n   ipindex*    iRow,\n   ipindex*    jCol,\n   ipnumber*   values,\n   UserDataPtr user_data\n);\n\n/** Type defining the callback function for evaluating the Hessian of the Lagrangian function.\n *\n *  Return value should be set to false if there was a problem doing the evaluation.\n *\n *  See also Ipopt::TNLP::eval_h.\n */\ntypedef bool (*Eval_H_CB)(\n   ipindex     n,\n   ipnumber*   x,\n   bool        new_x,\n   ipnumber    obj_factor,\n   ipindex     m,\n   ipnumber*   lambda,\n   bool        new_lambda,\n   ipindex     nele_hess,\n   ipindex*    iRow,\n   ipindex*    jCol,\n   ipnumber*   values,\n   UserDataPtr user_data\n);\n\n/** Type defining the callback function for giving intermediate execution control to the user.\n *\n *  If set, it is called once per iteration, providing the user\n *  with some information on the state of the optimization.\n *  This can be used to print some user-defined output.\n *  It also gives the user a way to terminate the optimization prematurely.\n *  If this method returns false, Ipopt will terminate the optimization.\n *\n *  See also Ipopt::TNLP::intermediate_callback.\n */\ntypedef bool (*Intermediate_CB)(\n   ipindex     alg_mod,   /**< algorithm mode: 0 is regular, 1 is restoration */\n   ipindex     iter_count,/**< iteration number */\n   ipnumber    obj_value, /**< objective function value */\n   ipnumber    inf_pr,    /**< primal infeasibility */\n   ipnumber    inf_du,    /**< dual infeasibility */\n   ipnumber    mu,        /**< barrier parameter */\n   ipnumber    d_norm,    /**< infinity-norm of primal step */\n   ipnumber    regularization_size,  /**< size of regularization of Hessian of Lagrangian */\n   ipnumber    alpha_du,  /**< step length for dual variables */\n   ipnumber    alpha_pr,  /**< step length for primal variables */\n   ipindex     ls_trials, /**< number of backtracking line search steps */\n   UserDataPtr user_data  /**< user data */\n);\n\n/** Function for creating a new Ipopt Problem object.\n *\n *  This function returns an object that can be passed to the IpoptSolve call.\n *  It contains the basic definition of the optimization problem, such\n *  as number of variables and constraints, bounds on variables and\n *  constraints, information about the derivatives, and the callback\n *  function for the computation of the optimization problem\n *  functions and derivatives.  During this call, the options file\n *  PARAMS.DAT is read as well.\n *\n *  If NULL is returned, there was a problem with one of the inputs\n *  or reading the options file.\n *\n *  See also Ipopt::TNLP::get_nlp_info and Ipopt::TNLP::get_bounds_info.\n */\nIPOPTLIB_EXPORT IpoptProblem IPOPT_CALLCONV CreateIpoptProblem(\n   ipindex       n,           /**< Number of optimization variables */\n   ipnumber*     x_L,         /**< Lower bounds on variables\n                               *\n                               * This array of size n is copied internally, so that the\n                               * caller can change the incoming data after\n                               * return without that IpoptProblem is modified.\n                               * Any value less or equal than the number specified by option\n                               * 'nlp_lower_bound_inf' is interpreted to be minus infinity.\n                               */\n   ipnumber*      x_U,         /**< Upper bounds on variables\n                               *\n                               * This array of size n is copied internally,\n                               * so that the caller can change the incoming data after\n                               * return without that IpoptProblem is modified.\n                               * Any value greater or equal than the number specified by option\n                               * 'nlp_upper_bound_inf' is interpreted to be plus infinity.\n                               */\n   ipindex        m,           /**< Number of constraints */\n   ipnumber*      g_L,         /**< Lower bounds on constraints\n                               *\n                               * This array of size m is copied internally,\n                               * so that the caller can change the incoming data after\n                               * return without that IpoptProblem is modified.\n                               * Any value less or equal than the number specified by option\n                               * 'nlp_lower_bound_inf' is interpreted to be minus infinity.\n                               */\n   ipnumber*      g_U,         /**< Upper bounds on constraints\n                               *\n                               * This array of size m is copied internally,\n                               * so that the caller can change the incoming data after\n                               * return without that IpoptProblem is modified.\n                               * Any value greater or equal than the number specified by option\n                               * 'nlp_upper_bound_inf' is interpreted to be plus infinity.\n                               */\n   ipindex        nele_jac,    /**< Number of non-zero elements in constraint Jacobian */\n   ipindex        nele_hess,   /**< Number of non-zero elements in Hessian of Lagrangian */\n   ipindex        index_style, /**< Indexing style for iRow & jCol, 0 for C style, 1 for Fortran style */\n   Eval_F_CB      eval_f,      /**< Callback function for evaluating objective function */\n   Eval_G_CB      eval_g,      /**< Callback function for evaluating constraint functions */\n   Eval_Grad_F_CB eval_grad_f, /**< Callback function for evaluating gradient of objective function */\n   Eval_Jac_G_CB  eval_jac_g,  /**< Callback function for evaluating Jacobian of constraint functions */\n   Eval_H_CB      eval_h       /**< Callback function for evaluating Hessian of Lagrangian function */\n);\n\n/** Method for freeing a previously created IpoptProblem.\n *\n * After freeing an IpoptProblem, it cannot be used anymore.\n */\nIPOPTLIB_EXPORT void IPOPT_CALLCONV FreeIpoptProblem(\n   IpoptProblem ipopt_problem\n);\n\n/** Function for adding a string option.\n *\n * @return false, if the option could not be set (e.g., if keyword is unknown)\n */\nIPOPTLIB_EXPORT bool IPOPT_CALLCONV AddIpoptStrOption(\n   IpoptProblem ipopt_problem,\n   char*        keyword,\n   char*        val\n);\n\n/** Function for adding a Number option.\n *\n * @return false, if the option could not be set (e.g., if keyword is unknown)\n */\nIPOPTLIB_EXPORT bool IPOPT_CALLCONV AddIpoptNumOption(\n   IpoptProblem ipopt_problem,\n   char*        keyword,\n   ipnumber     val\n);\n\n/** Function for adding an Integer option.\n *\n * @return false, if the option  could not be set (e.g., if keyword is unknown)\n @*/\nIPOPTLIB_EXPORT bool IPOPT_CALLCONV AddIpoptIntOption(\n   IpoptProblem ipopt_problem,\n   char*        keyword,\n   ipindex      val\n);\n\n/** Function for opening an output file for a given name with given printlevel.\n *\n * @return false, if there was a problem opening the file.\n */\nIPOPTLIB_EXPORT bool IPOPT_CALLCONV OpenIpoptOutputFile(\n   IpoptProblem ipopt_problem,\n   char*        file_name,\n   int          print_level\n);\n\n/** Optional function for setting scaling parameter for the NLP.\n *\n *  This corresponds to the TNLP::get_scaling_parameters method.\n *  If the pointers x_scaling or g_scaling are NULL, then no scaling\n *  for x resp. g is done.\n */\nIPOPTLIB_EXPORT bool IPOPT_CALLCONV SetIpoptProblemScaling(\n   IpoptProblem ipopt_problem,\n   ipnumber     obj_scaling,\n   ipnumber*    x_scaling,\n   ipnumber*    g_scaling\n);\n\n/** Setting a callback function for the \"intermediate callback\" method in the TNLP.\n *\n *  This gives control back to the user once\n *  per iteration.  If set, it provides the user with some\n *  information on the state of the optimization.  This can be used\n *  to print some user-defined output.  It also gives the user a way\n *  to terminate the optimization prematurely.  If the callback\n *  method returns false, Ipopt will terminate the optimization.\n *  Calling this set method to set the CB pointer to NULL disables\n *  the intermediate callback functionality. */\nIPOPTLIB_EXPORT bool IPOPT_CALLCONV SetIntermediateCallback(\n   IpoptProblem    ipopt_problem,\n   Intermediate_CB intermediate_cb\n);\n\n/** Function calling the Ipopt optimization algorithm for a problem\n * previously defined with CreateIpoptProblem.\n *\n * @return outcome of the optimization procedure (e.g., success, failure etc).\n */\nIPOPTLIB_EXPORT enum ApplicationReturnStatus IPOPT_CALLCONV IpoptSolve(\n   IpoptProblem ipopt_problem, /**< Problem that is to be optimized.\n                                *\n                                * Ipopt will use the options previously specified with\n                                * AddIpoptOption (etc) for this problem.\n                                */\n   ipnumber*    x,             /**< Input: Starting point; Output: Optimal solution */\n   ipnumber*    g,             /**< Values of constraint at final point (output only; ignored if set to NULL) */\n   ipnumber*    obj_val,       /**< Final value of objective function (output only; ignored if set to NULL) */\n   ipnumber*    mult_g,        /**< Input: Initial values for the constraint multipliers (only if warm start option is chosen);\n                                *  Output: Final multipliers for constraints (ignored if set to NULL)\n                                */\n   ipnumber*    mult_x_L,      /**< Input: Initial values for the multipliers for lower variable bounds (only if warm start option is chosen);\n                                *  Output: Final multipliers for lower variable bounds (ignored if set to NULL)\n                                */\n   ipnumber*    mult_x_U,      /**< Input: Initial values for the multipliers for upper variable bounds (only if warm start option is chosen);\n                                *  Output: Final multipliers for upper variable bounds (ignored if set to NULL)\n                                */\n   UserDataPtr  user_data      /**< Pointer to user data.\n                                *\n                                * This will be passed unmodified to the callback functions.\n                                */\n);\n\n/** Get primal and dual variable values of the current iterate.\n *\n * This method can be used to get the values of the current iterate during the intermediate callback set by SetIntermediateCallback().\n * The method expects the number of variables (dimension of x), number of constraints (dimension of g(x)),\n * and allocated arrays of appropriate lengths as input.\n *\n * The method translates the x(), c(), d(), y_c(), y_d(), z_L(), and z_U() vectors from Ipopt::IpoptData::curr()\n * of the internal NLP representation into the form used by the TNLP.\n * For the correspondence between scaled and unscaled solutions, see the detailed description of Ipopt::OrigIpoptNLP.\n * If %Ipopt is in restoration mode, it maps the current iterate of restoration %NLP (see Ipopt::RestoIpoptNLP) back to the original TNLP.\n *\n * If there are fixed variables and fixed_variable_treatment=make_parameter, then requesting z_L and z_U can trigger a reevaluation of\n * the Gradient of the objective function and the Jacobian of the constraint functions.\n *\n * @param ipopt_problem (in) Problem that is currently optimized.\n * @param n       (in)  the number of variables \\f$x\\f$ in the problem; can be arbitrary if skipping x, z_L, and z_U\n * @param scaled  (in)  whether to retrieve scaled or unscaled iterate\n * @param x       (out) buffer to store value of primal variables \\f$x\\f$, must have length at least n; pass NULL to skip retrieving x\n * @param z_L     (out) buffer to store the lower bound multipliers \\f$z_L\\f$, must have length at least n; pass NULL to skip retrieving z_L and Z_U\n * @param z_U     (out) buffer to store the upper bound multipliers \\f$z_U\\f$, must have length at least n; pass NULL to skip retrieving z_L and Z_U\n * @param m       (in)  the number of constraints \\f$g(x)\\f$; can be arbitrary if skipping g and lambda\n * @param g       (out) buffer to store the constraint values \\f$g(x)\\f$, must have length at least m; pass NULL to skip retrieving g\n * @param lambda  (out) buffer to store the constraint multipliers \\f$\\lambda\\f$, must have length at least m; pass NULL to skip retrieving lambda\n *\n * @return Whether Ipopt has successfully filled the given arrays\n * @since 3.14.0\n */\nIPOPTLIB_EXPORT bool IPOPT_CALLCONV GetIpoptCurrentIterate(\n   IpoptProblem    ipopt_problem,\n   bool            scaled,\n   ipindex         n,\n   ipnumber*       x,\n   ipnumber*       z_L,\n   ipnumber*       z_U,\n   ipindex         m,\n   ipnumber*       g,\n   ipnumber*       lambda\n);\n\n/** Get primal and dual infeasibility of the current iterate.\n *\n * This method can be used to get the violations of constraints and optimality conditions\n * at the current iterate during the intermediate callback set by SetIntermediateCallback().\n * The method expects the number of variables (dimension of x), number of constraints (dimension of g(x)),\n * and allocated arrays of appropriate lengths as input.\n *\n * The method makes the vectors behind (unscaled_)curr_orig_bounds_violation(), (unscaled_)curr_nlp_constraint_violation(), (unscaled_)curr_dual_infeasibility(),\n * (unscaled_)curr_complementarity() from Ipopt::IpoptCalculatedQuantities of the internal NLP representation available into the form used by the TNLP.\n * If %Ipopt is in restoration mode, it maps the current iterate of restoration %NLP (see Ipopt::RestoIpoptNLP) back to the original TNLP.\n *\n * @note If in restoration phase, then requesting grad_lag_x can trigger a call to Eval_F_CB.\n *\n * @note Ipopt by default relaxes variable bounds (option bound_relax_factor > 0.0).\n *   x_L_violation and x_U_violation report the violation of a solution w.r.t. the original unrelaxed bounds.\n *   However, compl_x_L and compl_x_U use the relaxed variable bounds to calculate the complementarity.\n *\n * @param ipopt_problem (in) Problem that is currently optimized.\n * @param scaled     (in)  whether to retrieve scaled or unscaled violations\n * @param n          (in)  the number of variables \\f$x\\f$ in the problem; can be arbitrary if skipping compl_x_L, compl_x_U, and grad_lag_x\n * @param x_L_violation (out) buffer to store violation of original lower bounds on variables (max(orig_x_L-x,0)), must have length at least n; pass NULL to skip retrieving orig_x_L\n * @param x_U_violation (out) buffer to store violation of original upper bounds on variables (max(x-orig_x_U,0)), must have length at least n; pass NULL to skip retrieving orig_x_U\n * @param compl_x_L  (out) buffer to store violation of complementarity for lower bounds on variables (\\f$(x-x_L)z_L\\f$), must have length at least n; pass NULL to skip retrieving compl_x_L\n * @param compl_x_U  (out) buffer to store violation of complementarity for upper bounds on variables (\\f$(x_U-x)z_U\\f$), must have length at least n; pass NULL to skip retrieving compl_x_U\n * @param grad_lag_x (out) buffer to store gradient of Lagrangian w.r.t. variables \\f$x\\f$, must have length at least n; pass NULL to skip retrieving grad_lag_x\n * @param m          (in)  the number of constraints \\f$g(x)\\f$; can be arbitrary if skipping lambda\n * @param nlp_constraint_violation (out) buffer to store violation of constraints \\f$max(g_l-g(x),g(x)-g_u,0)\\f$, must have length at least m; pass NULL to skip retrieving constraint_violation\n * @param compl_g    (out) buffer to store violation of complementarity of constraint (\\f$(g(x)-g_l)*\\lambda^+ + (g_l-g(x))*\\lambda^-\\f$, where \\f$\\lambda^+=max(0,\\lambda)\\f$ and \\f$\\lambda^-=max(0,-\\lambda)\\f$ (componentwise)), must have length at least m; pass NULL to skip retrieving compl_g\n *\n * @return Whether Ipopt has successfully filled the given arrays\n * @since 3.14.0\n */\nIPOPTLIB_EXPORT bool IPOPT_CALLCONV GetIpoptCurrentViolations(\n   IpoptProblem  ipopt_problem,\n   bool          scaled,\n   ipindex       n,\n   ipnumber*     x_L_violation,\n   ipnumber*     x_U_violation,\n   ipnumber*     compl_x_L,\n   ipnumber*     compl_x_U,\n   ipnumber*     grad_lag_x,\n   ipindex       m,\n   ipnumber*     nlp_constraint_violation,\n   ipnumber*     compl_g\n);\n\n#ifdef __cplusplus\n} /* extern \"C\" { */\n#endif\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/ipopt/IpTypes.h",
    "content": "// Copyright (C) 2020 COIN-OR Foundation\n// All Rights Reserved.\n// This code is published under the Eclipse Public License.\n\n#ifndef __IPTYPES_H__\n#define __IPTYPES_H__\n\n#include \"IpoptConfig.h\"\n\n#ifndef IPOPT_DEPRECATED\n#if defined(_MSC_VER)\n/** macro to declare symbols as deprecated\n * @since Ipopt 3.14.0\n */\n#  define IPOPT_DEPRECATED __declspec(deprecated)\n#elif defined(__GNUC__)\n/** macro to declare symbols as deprecated\n * @since Ipopt 3.14.0\n */\n#  define IPOPT_DEPRECATED __attribute__ ((deprecated))\n#else\n/** macro to declare symbols as deprecated\n * @since Ipopt 3.14.0\n */\n#  define IPOPT_DEPRECATED\n#endif\n#endif\n\n#ifdef __GNUC__\n#  define IPOPT_UNUSED __attribute__((unused))\n#else\n#  define IPOPT_UNUSED\n#endif\n\n#ifndef IPOPT_CALLCONV\n#ifdef _MSC_VER\n/** @since Ipopt 3.14.0 */\n#define IPOPT_CALLCONV __cdecl\n#else\n/** @since Ipopt 3.14.0 */\n#define IPOPT_CALLCONV\n#endif\n#endif\n\n/** Type for floating-point numbers\n * @since 3.14.0\n */\n#ifdef IPOPT_SINGLE\ntypedef float ipnumber;\n#else\ntypedef double ipnumber;\n#endif\n\n#ifdef IPOPT_INT64\n#include <inttypes.h>\n/** Type of all indices of vectors, matrices etc\n * @since 3.14.0\n */\ntypedef int64_t ipindex;\n/** Format specifier to use for ipindex in printf-format strings\n * @since 3.14.0\n */\n#define IPOPT_INDEX_FORMAT PRId64\n#else\n/** Type of all indices of vectors, matrices etc\n * @since 3.14.0\n */\ntypedef int ipindex;\n/** Format specifier to use for ipindex in printf-format strings\n * @since 3.14.0\n */\n#define IPOPT_INDEX_FORMAT \"d\"\n#endif\n\n/** Type of Fortran integer translated into C\n * @deprecated Use ipindex instead.\n */\nIPOPT_DEPRECATED\ntypedef ipindex ipfint;\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/ipopt/IpoptConfig.h",
    "content": "/* src/Common/config_ipopt.h.  Generated from config_ipopt.h.in by configure.  */\n/* src/Common/config_ipopt.h.in. */\n\n#ifndef __CONFIG_IPOPT_H__\n#define __CONFIG_IPOPT_H__\n\n/* Version number of project */\n#define IPOPT_VERSION \"3.14.14\"\n\n/* Major Version number of project */\n#define IPOPT_VERSION_MAJOR 3\n\n/* Minor Version number of project */\n#define IPOPT_VERSION_MINOR 14\n\n/* Release Version number of project */\n#define IPOPT_VERSION_RELEASE 14\n\n/* Define to the debug sanity check level (0 is no test) */\n#define IPOPT_CHECKLEVEL 0\n\n/* Define to the debug verbosity level (0 is no output) */\n#define IPOPT_VERBOSITY 0\n\n/* Define to 1 if using single precision floating point */\n/* #undef IPOPT_SINGLE */\n\n/* Define to 1 if Ipopt index type is int64_t */\n/* #undef IPOPT_INT64 */\n\n#if defined(_MSC_VER)\n\n/* Library Visibility Attribute */\n#define IPOPTAMPLINTERFACELIB_EXPORT __declspec(dllimport)\n\n/* Library Visibility Attribute */\n#define IPOPTLIB_EXPORT __declspec(dllimport)\n\n/* Library Visibility Attribute */\n#define SIPOPTLIB_EXPORT __declspec(dllimport)\n\n#else\n\n#define IPOPTAMPLINTERFACELIB_EXPORT\n#define IPOPTLIB_EXPORT\n#define SIPOPTLIB_EXPORT\n\n#endif\n\n/** type corresponding to integers in Fortran\n * @deprecated Use ipindex instead.\n */\n#define IPOPT_FORTRAN_INTEGER_TYPE ipindex\n\n#endif\n"
  },
  {
    "path": "thirdparty/solvers/knitro/knitro.h",
    "content": "/*******************************************************/\n/* Copyright (c) 2025 by Artelys                       */\n/* All Rights Reserved                                 */\n/*******************************************************/\n\n/* Artelys Knitro 15.1.0 application interface header file. */\n\n#ifndef KNITRO_H__\n#define KNITRO_H__\n\n#ifndef TRUE\n#define TRUE 1\n#endif\n#ifndef FALSE\n#define FALSE 0\n#endif\n\n#include <stddef.h>\n#include <float.h>\n\n/*------------------------------------------------------------------*/\n/*     EXPORT MACROS                                                */\n/*------------------------------------------------------------------*/\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifdef _WIN32\n  #ifdef MAKE_KNITRO_DLL\n    #define KNITRO_API __declspec(dllexport) __stdcall\n  #else\n    #define KNITRO_API __stdcall\n  #endif\n#else\n  #if (__GNUC__ >= 4) || (__INTEL_COMPILER)\n    #define KNITRO_API __attribute__ ((visibility (\"default\")))\n  #else\n    #define KNITRO_API\n  #endif\n#endif\n\n/* Define Knitro integer types.  Use KNLONG to support 64-bit integers. */\ntypedef int KNINT;\n#ifdef _WIN64\n    typedef __int64 KNLONG;\n#elif _WIN32\n    typedef int KNLONG;\n#else\n    typedef long long KNLONG;\n#endif\ntypedef KNINT   KNBOOL;\n#define KNTRUE  1\n#define KNFALSE 0\n\n/*------------------------------------------------------------------*/\n/*     FORWARD DECLARATION TYPE DEFINITIONS                         */\n/*------------------------------------------------------------------*/\n\n/** Type declaration for the Knitro solver context object.\n *  All methods pass a pointer to the solver.\n *  Applications must not modify any part of the solver context,\n *  except by making Knitro API calls.\n */\ntypedef struct KN_context KN_context, *KN_context_ptr;\n\n/** Type declaration for the Artelys License Manager context object.\n *  Applications must not modify any part of the context.\n */\ntypedef struct LM_context LM_context, *LM_context_ptr;\n\n/*------------------------------------------------------------------*/\n/*     FUNCTION DECLARATIONS                                        */\n/*------------------------------------------------------------------*/\n\n/** Copy the Knitro release name into \"release\".  This variable must be\n *  preallocated to have \"length\" elements, including the string termination\n *  character.  For compatibility with future releases, please allocate at\n *  least 15 characters.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_release (const int           length,\n                                      char * const  release);\n\n/* -----  Creating and destroying solver objects ----- */\n\n/** Call KN_new first.  This routine returns a pointer to the\n *  solver object that is used in all other Knitro API calls in the\n *  argument \"kc\". The \"kc\" pointer is set to NULL if there is an error.\n *  A new Knitro license is acquired and held until KN_free has been\n *  called, or until the calling program ends.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_new (KN_context_ptr * kc);\n\n\n/** Free all memory and release any Knitro license acquired by calling\n *  KN_new.  The address of the pointer is set to NULL after freeing\n *  memory, to help avoid mistakes.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_free (KN_context_ptr * kc);\n\n/* -----  Creating and destroying solvers in high volume ----- */\n\n/** High volume applications construct new Knitro instances repeatedly,\n *  each lasting only a short time.  Special functions allow a single\n *  license to be checked out once for a sequence of Knitro instances.\n *  Re-using a license saves time in the Knitro solver, and improves the\n *  performance of the Artelys License Manager server.\n *\n *  The typical calling sequence is:\n *    KN_checkout_license\n *      KN_new_lm\n *        KN_add* (setup problem structure)\n *        KN_solve\n *      KN_free\n *      KN_new_lm\n *        KN_add* (setup problem structure)\n *        KN_solve\n *      KN_free\n *      ...\n *    KN_release_license\n *\n *  Please see the Artelys License Manager user manual for more information.\n */\n\n/** Allocate memory for a license from the Artelys License Manager for high\n *  volume Knitro applications.  The license object is returned in the \"lmc\"\n *  argument and will be set to NULL if there is an error.  Otherwise, the\n *  license will be checked out the first time KN_new_lm is called.  The\n *  license must be checked in later by calling KN_release_license.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_checkout_license (LM_context_ptr * lmc);\n\n/** Returns a pointer to the solver object that is used in all other Knitro\n *  API calls in the argument \"kc\". The \"kc\" pointer is set to NULL if\n *  there is an error. Pass in the license object \"lmc\" acquired by first\n *  calling KN_checkout_license.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_new_lm (LM_context_ptr   lmc,\n                           KN_context_ptr * kc);\n\n/** Release the Knitro license and free allocated memory.\n *  Knitro will set the address of the pointer to NULL after freeing\n *  memory, to help avoid mistakes.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_release_license (LM_context_ptr * lmc);\n\n\n/* ----- Changing and reading solver parameters ----- */\n\n/** All methods return 0 if OK, nonzero if there was an error.\n *  In most cases, parameter values are not validated until\n *  KN_solve is called.\n */\n\n/** Reset all parameters to default values.\n */\nint  KNITRO_API KN_reset_params_to_defaults (KN_context_ptr  kc);\n\n\n/** Set all parameters specified in the given file. */\nint  KNITRO_API KN_load_param_file\n    (KN_context_ptr  kc, const char * const  filename);\n\n/** Similar to KN_load_param_file (defined above) but specifically allows\n *  the user to specify a file of options (and option values) to explore for\n *  the Knitro-Tuner.\n */\nint  KNITRO_API KN_load_tuner_file\n    (KN_context_ptr  kc, const char * const  filename);\n\n/** Write all current parameter values to a file. */\nint  KNITRO_API KN_save_param_file\n    (KN_context_ptr  kc, const char * const  filename);\n\n/** Set a parameter using its string name. */\nint  KNITRO_API KN_set_int_param_by_name\n    (KN_context_ptr  kc, const char * const  name, const int  value);\nint  KNITRO_API KN_set_char_param_by_name\n    (KN_context_ptr  kc, const char * const  name, const char * const  value);\nint  KNITRO_API KN_set_double_param_by_name\n    (KN_context_ptr  kc, const char * const  name, const double  value);\n/** Set an integer or double parameter by name. */\nint  KNITRO_API KN_set_param_by_name\n    (KN_context_ptr  kc, const char * const  name, const double  value);\n\n/** Set a parameter using its integer identifier KN_PARAM_x\n *  (defined at the end of this file). */\nint  KNITRO_API KN_set_int_param\n    (KN_context_ptr  kc, const int  param_id, const int  value);\nint  KNITRO_API KN_set_char_param\n    (KN_context_ptr  kc, const int  param_id, const char * const  value);\nint  KNITRO_API KN_set_double_param\n    (KN_context_ptr  kc, const int  param_id, const double  value);\n\n/** Get a parameter using its string name. */\nint  KNITRO_API KN_get_int_param_by_name\n    (KN_context_ptr  kc, const char * const  name, int * const  value);\nint  KNITRO_API KN_get_double_param_by_name\n    (KN_context_ptr  kc, const char * const  name, double * const  value);\n\n/** Get a parameter using its integer identifier KN_PARAM_x\n *  (defined at the end of this file). */\nint  KNITRO_API KN_get_int_param\n    (KN_context_ptr  kc, const int  param_id, int * const  value);\nint  KNITRO_API KN_get_double_param\n    (KN_context_ptr  kc, const int  param_id, double * const  value);\n\n/** Sets the string param_name with the name of parameter indexed by\n *  param_id and returns 0. Returns an error if param_id does not\n *  correspond to any parameter, or if the parameter output_size\n *  (the size of char array param_name) is less than the size of the\n *  parameter's description.\n */\nint KNITRO_API KN_get_param_name(      KN_context_ptr  kc,\n                                 const int             param_id,\n                                       char * const    param_name,\n                                 const size_t          output_size);\n\n/** Sets the string description with the description of the parameter\n *  indexed by param_id and its possible values and returns 0. Returns an\n *  error if param_id does not correspond to any parameter, or if the\n *  parameter output_size (the size of char array description) is less than\n *  the size of the parameter's description.\n */\nint KNITRO_API KN_get_param_doc(      KN_context_ptr  kc,\n                                const int             param_id,\n                                      char * const    description,\n                                const size_t          output_size);\n\n/** Sets the int * param_type to the parameter type of parameter indexed\n *  by param_id. Possible values are KN_PARAMTYPE_INTEGER, KN_PARAMTYPE_FLOAT,\n *  KN_PARAMTYPE_STRING. Returns an error if param_id does not correspond to\n *  any parameter.\n */\nint KNITRO_API KN_get_param_type(      KN_context_ptr  kc,\n                                 const int             param_id,\n                                       int * const     param_type);\n\n/** Set the int * num_param_values to the number of possible parameter\n *  values for parameter indexed by param_id and returns 0. If there is\n *  not a finite number of possible values, num_param_values will be zero.\n *  Returns an error if param_id does not correspond to any parameter.\n */\nint KNITRO_API KN_get_num_param_values(      KN_context_ptr  kc,\n                                       const int             param_id,\n                                             int * const     num_param_values);\n\n/** Set string param_value_string to the description of value value_id for the\n *  parameter param_id. Returns an error if param_id does not\n *  correspond to any parameter, or if value_id is not among possible parameter\n *  values, or if there are not a finite number of possible parameter values,\n *  or if the parameter output_size (the size of char array param_value_string)\n *  is less than the size of the parameter's description.\n */\nint KNITRO_API KN_get_param_value_doc(      KN_context_ptr  kc,\n                                      const int             param_id,\n                                      const int             value_id,\n                                            char * const    param_value_string,\n                                      const size_t          output_size);\n\n/** Set string param_value_string to the description of the i-th possible value\n *  for the parameter param_id. Returns an error if param_id does not\n *  correspond to any parameter, or if value_index is greater than the number\n *  of possible parameter values (see KN_get_num_param_values), or if there are\n *  not a finite number of possible parameter values, or if the parameter\n *  output_size (the size of char array param_value_string) is less than the\n *  size of the parameter's description.\n */\nint KNITRO_API KN_get_param_value_doc_from_index(      KN_context_ptr  kc,\n                                                 const int             param_id,\n                                                 const int             value_index,\n                                                       char * const    param_value_string,\n                                                 const size_t          output_size);\n\n/** Gets the integer value corresponding to the parameter name input and\n *  copies it into param_id input. Returns zero if successful and an error\n *  code otherwise.\n */\nint KNITRO_API KN_get_param_id(      KN_context_ptr  kc,\n                               const char * const    name,\n                                     int  * const    param_id);\n\n/**\n * Sets the integer param_id with the id of the parameter indexed by param_index\n * (between 0 and the number of existing parameters). Returns an error if the\n * param_index is non-positive or greater or equal than the number of existing\n * parameters.\n */\nint KNITRO_API KN_get_param_id_from_index(      KN_context_ptr  kc,\n                                                int*            param_id,\n                                          const int             param_index);\n\n/**\n * Write a JSON file describing all available parameters.\n * Returns zero if successful and an error code otherwise.\n */\nint KNITRO_API KN_write_param_desc_file(      KN_context_ptr  kc,\n                                        const char * const    filepath);\n\n\n/* ----- Problem construction ----- */\n\n/** The Knitro API is designed to provide the user maximum flexibility and\n *  ease-of-use in building a model.  In addition, it is designed to provide\n *  Knitro detailed structural information about the user model, so that\n *  Knitro can exploit special structures wherever possible to improve\n *  performance.  The user can use the API to build up a model in pieces in\n *  the way that is most convenient and intuitive for the user.\n *\n *  The API is designed so the user can load constant, linear, quadratic,\n *  and conic structures as well as complementarity constraints separately.\n *  This allows Knitro to mark these structure types internally and provide\n *  special care to different structure types. In addition, the more\n *  structural information Knitro has, the more extensive presolve operations\n *  Knitro can perform to try to simplify the model internally. For this\n *  reason we always recommend making use of the API functions below to provide\n *  as much fine-grained structural information as possible to Knitro.  More\n *  general nonlinear structure must be handled through callback evaluation\n *  routines.\n *\n *  Structures of the same type can be added in individual pieces, in groups,\n *  or all together.  Likewise, general nonlinear structures can all be handled\n *  by one callback object or broken up into separate callback objects if there\n *  are natural groupings that the user wants to treat differently.\n *\n *  The overhead costs for loading the user model by pieces using the API\n *  functions that follow should be trivial in most cases -- even for large\n *  models.  However, if not, it is always possible, and most efficient, to load\n *  all the structures of one type together in one API function call.\n *\n *  Problem structure is passed to Knitro using KN API functions.\n *  The problem is solved by calling KN_solve.  Applications must\n *  provide a means of evaluating the nonlinear objective, constraints,\n *  first derivatives, and (optionally) second derivatives.  (First\n *  derivatives are also optional, but highly recommended.)\n *\n *  The typical calling sequence is:\n *    KN_new\n *    KN_add_vars/KN_add_cons/KN_set_*bnds, etc. (problem setup)\n *    KN_add_*_linear_struct/KN_add_*_quadratic_struct (add special structures)\n *    KN_add_eval_callback (add callback for nonlinear evaluations if needed)\n *    KN_set_cb_* (set properties for nonlinear evaluation callbacks)\n *    KN_set_xxx_param (set any number of parameters/user options)\n *    KN_solve\n *    KN_free\n *\n *  Generally, as long as no nonlinear structural changes are made to the\n *  model, KN_solve can be called in succession to re-solve a model after\n *  changes.  For example, user options, variable bounds, and constraint\n *  bounds can be changed between calls to KN_solve, without having to call\n *  KN_free and reload the model from scratch.  In addition, constant and\n *  linear structures in the model may be added, deleted, or changed without\n *  having to reconstruct the model.  More extensive additions or changes to\n *  the model (such as adding quadratic structures or callbacks) require\n *  freeing the existing Knitro solver object and rebuilding the model from\n *  scratch.\n */\n\n/** Add variables to the model.  The parameter indexVars may be set to NULL.\n *  Otherwise, on return it holds the global indices associated with the\n *  variables that were added (indices are typically allocated sequentially).\n *  Parameter indexVars can then be passed into other API routines that operate\n *  on the set of variables added through a particular call to KN_add_var*.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_add_vars (      KN_context_ptr  kc,\n                             const KNINT           nV,\n                                   KNINT * const   indexVars);\nint  KNITRO_API KN_add_var  (      KN_context_ptr  kc,\n                                   KNINT * const   indexVar);\n\n/** Add constraints to the model.  The parameter indexCons may be set to NULL.\n *  Otherwise, on return it holds the global indices associated with the\n *  constraints that were added (indices are typically allocated sequentially).\n *  Parameter indexCons can then be passed into other API routines that operate\n *  on the set of constraints added through a particular call to KN_add_con*.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_add_cons (      KN_context_ptr  kc,\n                             const KNINT           nC,\n                                   KNINT * const   indexCons);\nint  KNITRO_API KN_add_con  (      KN_context_ptr  kc,\n                                   KNINT * const   indexCon);\n\n/** Add residuals for least squares optimization.  The parameter indexRsds may\n *  be set to NULL.  Otherwise, on return it holds the global indices associated\n *  with the residuals that were added  (indices are typically allocated sequentially).\n *  Parameter indexRsds can then be passed into other API routines that operate\n *  on the set of residuals added through a particular call to KN_add_rsd*.\n *  Note that the current Knitro API does not support adding both constraints\n *  and residuals.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_add_rsds (      KN_context_ptr  kc,\n                             const KNINT           nR,\n                                   KNINT * const   indexRsds);\nint  KNITRO_API KN_add_rsd  (      KN_context_ptr  kc,\n                                   KNINT * const   indexRsd);\n\n/** Set lower, upper or fixed bounds on variables.\n *  If not set, variables are assumed to be unbounded (e.g. lower bounds\n *  are assumed to be -KN_INFINITY and upper bounds are assumed to be\n *  KN_INFINITY).\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_var_lobnds (      KN_context_ptr  kc,\n                                   const KNINT           nV,\n                                   const KNINT  * const  indexVars,\n                                   const double * const  xLoBnds);\nint  KNITRO_API KN_set_var_lobnds_all (      KN_context_ptr  kc,\n                                       const double * const  xLoBnds);\nint  KNITRO_API KN_set_var_lobnd (      KN_context_ptr  kc,\n                                  const KNINT           indexVar,\n                                  const double          xLoBnd);\nint  KNITRO_API KN_set_var_upbnds (      KN_context_ptr  kc,\n                                   const KNINT           nV,\n                                   const KNINT  * const  indexVars,\n                                   const double * const  xUpBnds);\nint  KNITRO_API KN_set_var_upbnds_all (      KN_context_ptr  kc,\n                                       const double * const  xUpBnds);\nint  KNITRO_API KN_set_var_upbnd (      KN_context_ptr  kc,\n                                  const KNINT           indexVar,\n                                  const double          xUpBnd);\nint  KNITRO_API KN_set_var_fxbnds (      KN_context_ptr  kc,\n                                   const KNINT           nV,\n                                   const KNINT  * const  indexVars,\n                                   const double * const  xFxBnds);\nint  KNITRO_API KN_set_var_fxbnds_all (      KN_context_ptr  kc,\n                                       const double * const  xFxBnds);\nint  KNITRO_API KN_set_var_fxbnd (      KN_context_ptr  kc,\n                                  const KNINT           indexVar,\n                                  const double          xFxBnd);\n\n/** Get lower, upper or fixed bounds on variables.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_var_lobnds (const KN_context_ptr  kc,\n                                   const KNINT           nV,\n                                   const KNINT  * const  indexVars,\n                                         double * const  xLoBnds);\nint  KNITRO_API KN_get_var_lobnds_all (const KN_context_ptr  kc,\n                                             double * const  xLoBnds);\nint  KNITRO_API KN_get_var_lobnd (const KN_context_ptr  kc,\n                                  const KNINT           indexVar,\n                                        double * const  xLoBnd);\n\nint  KNITRO_API KN_get_var_upbnds (const KN_context_ptr  kc,\n                                   const KNINT           nV,\n                                   const KNINT  * const  indexVars,\n                                         double * const  xUpBnds);\nint  KNITRO_API KN_get_var_upbnds_all (const KN_context_ptr  kc,\n                                             double * const  xUpBnds);\nint  KNITRO_API KN_get_var_upbnd (const KN_context_ptr  kc,\n                                  const KNINT           indexVar,\n                                        double * const  xUpBnd);\nint  KNITRO_API KN_get_var_fxbnds (const KN_context_ptr  kc,\n                                   const KNINT           nV,\n                                   const KNINT  * const  indexVars,\n                                         double * const  xFxBnds);\nint  KNITRO_API KN_get_var_fxbnds_all (const KN_context_ptr  kc,\n                                             double * const  xFxBnds);\nint  KNITRO_API KN_get_var_fxbnd (const KN_context_ptr  kc,\n                                  const KNINT           indexVar,\n                                        double * const  xFxBnd);\n\n/** Set variable types (e.g. KN_VARTYPE_CONTINUOUS, KN_VARTYPE_BINARY,\n *  KN_VARTYPE_INTEGER). If not set, variables are assumed to be continuous.\n *  When a variable is set as binary, its lower bound is automatically\n *  set to 0 and its upper bound is automatically set to 1 at the same time.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_var_types (      KN_context_ptr  kc,\n                                  const KNINT           nV,\n                                  const KNINT  * const  indexVars,\n                                  const int    * const  xTypes);\nint  KNITRO_API KN_set_var_types_all (      KN_context_ptr  kc,\n                                      const int    * const  xTypes);\nint  KNITRO_API KN_set_var_type (      KN_context_ptr  kc,\n                                 const KNINT           indexVar,\n                                 const int             xType);\n\n/** Return the variable types. The array \"xTypes\" must be allocated\n *  by the user.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_var_types (const KN_context_ptr  kc,\n                                  const KNINT           nV,\n                                  const KNINT  * const  indexVars,\n                                        int    * const  xTypes);\nint  KNITRO_API KN_get_var_types_all (const KN_context_ptr  kc,\n                                            int    * const  xTypes);\nint  KNITRO_API KN_get_var_type (const KN_context_ptr  kc,\n                                 const KNINT           indexVar,\n                                       int    * const  xType);\n\n/** Specify some properties of the variables.  Currently\n *  this API routine is only used to mark variables as linear,\n *  but other variable properties will be added in the future.\n *  Note: use bit-wise specification of the features:\n *  bit value   meaning\n *    0     1   KN_VAR_LINEAR\n *  default = 0 (variables are assumed to be nonlinear)\n *\n *  If a variable only appears linearly in the model, it can be very\n *  helpful to mark this by enabling bit 0.  This information can then\n *  be used by Knitro to perform more extensive preprocessing. If a\n *  variable appears nonlinearly in any constraint or the objective (or\n *  if the user does not know) then it should not be marked as linear.\n *  Variables are assumed to be nonlinear variables by default.\n *  Knitro makes a local copy of all inputs, so the application may\n *  free memory after the call.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_var_properties (      KN_context_ptr  kc,\n                                       const KNINT           nV,\n                                       const KNINT  * const  indexVars,\n                                       const int    * const  xProperties);\nint  KNITRO_API KN_set_var_properties_all (      KN_context_ptr  kc,\n                                           const int    * const  xProperties);\nint  KNITRO_API KN_set_var_property (      KN_context_ptr  kc,\n                                     const KNINT           indexVar,\n                                     const int             xProperty);\n\n/** Set lower, upper or equality bounds on constraints.\n *  If not set, constraints are assumed to be unbounded (e.g. lower bounds\n *  are assumed to be -KN_INFINITY and upper bounds are assumed to be\n *  KN_INFINITY).\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_con_lobnds (      KN_context_ptr  kc,\n                                   const KNINT           nC,\n                                   const KNINT  * const  indexCons,\n                                   const double * const  cLoBnds);\nint  KNITRO_API KN_set_con_lobnds_all (      KN_context_ptr  kc,\n                                       const double * const  cLoBnds);\nint  KNITRO_API KN_set_con_lobnd (      KN_context_ptr  kc,\n                                  const KNINT           indexCon,\n                                  const double          cLoBnd);\nint  KNITRO_API KN_set_con_upbnds (      KN_context_ptr  kc,\n                                   const KNINT           nC,\n                                   const KNINT  * const  indexCons,\n                                   const double * const  cUpBnds);\nint  KNITRO_API KN_set_con_upbnds_all (      KN_context_ptr  kc,\n                                       const double * const  cUpBnds);\nint  KNITRO_API KN_set_con_upbnd (      KN_context_ptr  kc,\n                                  const KNINT           indexCon,\n                                  const double          cUpBnd);\nint  KNITRO_API KN_set_con_eqbnds (      KN_context_ptr  kc,\n                                   const KNINT           nC,\n                                   const KNINT  * const  indexCons,\n                                   const double * const  cEqBnds);\nint  KNITRO_API KN_set_con_eqbnds_all (      KN_context_ptr  kc,\n                                       const double * const  cEqBnds);\nint  KNITRO_API KN_set_con_eqbnd (      KN_context_ptr  kc,\n                                  const KNINT           indexCon,\n                                  const double          cEqBnd);\n\n/** Get lower, upper or equality bounds on constraints.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_con_lobnds (const KN_context_ptr  kc,\n                                   const KNINT           nC,\n                                   const KNINT  * const  indexCons,\n                                         double * const  cLoBnds);\nint  KNITRO_API KN_get_con_lobnds_all (const KN_context_ptr  kc,\n                                             double * const  cLoBnds);\nint  KNITRO_API KN_get_con_lobnd (const KN_context_ptr  kc,\n                                  const KNINT           indexCon,\n                                        double * const  cLoBnd);\nint  KNITRO_API KN_get_con_upbnds (const KN_context_ptr  kc,\n                                   const KNINT           nC,\n                                   const KNINT  * const  indexCons,\n                                         double * const  cUpBnds);\nint  KNITRO_API KN_get_con_upbnds_all (const KN_context_ptr  kc,\n                                             double * const  cUpBnds);\nint  KNITRO_API KN_get_con_upbnd (const KN_context_ptr  kc,\n                                  const KNINT           indexCon,\n                                        double * const  cUpBnd);\nint  KNITRO_API KN_get_con_eqbnds (const KN_context_ptr  kc,\n                                   const KNINT           nC,\n                                   const KNINT  * const  indexCons,\n                                         double * const  cEqBnds);\nint  KNITRO_API KN_get_con_eqbnds_all (const KN_context_ptr  kc,\n                                             double * const  cEqBnds);\nint  KNITRO_API KN_get_con_eqbnd (const KN_context_ptr  kc,\n                                  const KNINT           indexCon,\n                                        double * const  cEqBnd);\n\n/** Specify some properties of the objective and constraint functions.\n *  Note: use bit-wise specification of the features:\n *  bit value   meaning\n *    0     1   KN_OBJ_CONVEX/KN_CON_CONVEX\n *    1     2   KN_OBJ_CONCAVE/KN_CON_CONCAVE\n *    2     4   KN_OBJ_CONTINUOUS/KN_CON_CONTINUOUS\n *    3     8   KN_OBJ_DIFFERENTIABLE/KN_CON_DIFFERENTIABLE\n *    4    16   KN_OBJ_TWICE_DIFFERENTIABLE/KN_CON_TWICE_DIFFERENTIABLE\n *    5    32   KN_OBJ_NOISY/KN_CON_NOISY\n *    6    64   KN_OBJ_NONDETERMINISTIC/KN_CON_NONDETERMINISTIC\n * default = 28 (bits 2-4 enabled: e.g. continuous, differentiable, twice-differentiable)\n */\nint  KNITRO_API KN_set_obj_property (      KN_context_ptr  kc,\n                                     const int             objProperty);\nint  KNITRO_API KN_set_con_properties (      KN_context_ptr  kc,\n                                       const KNINT           nC,\n                                       const KNINT  * const  indexCons,\n                                       const int    * const  cProperties);\nint  KNITRO_API KN_set_con_properties_all (      KN_context_ptr  kc,\n                                           const int    * const  cProperties);\nint  KNITRO_API KN_set_con_property (      KN_context_ptr  kc,\n                                     const KNINT           indexCon,\n                                     const int             cProperty);\n\n/** Set the objective goal (KN_OBJGOAL_MINIMIZE or KN_OBJGOAL_MAXIMIZE).\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_obj_goal (      KN_context_ptr  kc,\n                                 const int             objGoal);\n\n/** Get the objective goal (KN_OBJGOAL_MINIMIZE or KN_OBJGOAL_MAXIMIZE).\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_obj_goal (      KN_context_ptr  kc,\n                                       int * const     objGoal);\n\n/** Set initial values for primal variables.  If not set, variables\n *  may be initialized as 0 or initialized by Knitro based on some\n *  initialization strategy (perhaps determined by a user option).\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_var_primal_init_values (      KN_context_ptr  kc,\n                                               const KNINT           nV,\n                                               const KNINT  * const  indexVars,\n                                               const double * const  xInitVals);\nint  KNITRO_API KN_set_var_primal_init_values_all (      KN_context_ptr  kc,\n                                                   const double * const  xInitVals);\nint  KNITRO_API KN_set_var_primal_init_value (      KN_context_ptr  kc,\n                                              const KNINT           indexVar,\n                                              const double          xInitVal);\n\n/** Set initial values for dual variables (i.e. the Lagrange multipliers\n *  corresponding to the potentially bounded variables).  If not set, dual\n *  variables may be initialized as 0 or initialized by Knitro based on some\n *  initialization strategy (perhaps determined by a user option).\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_var_dual_init_values (      KN_context_ptr  kc,\n                                             const KNINT           nV,\n                                             const KNINT  * const  indexVars,\n                                             const double * const  lambdaInitVals);\nint  KNITRO_API KN_set_var_dual_init_values_all (      KN_context_ptr  kc,\n                                                 const double * const  lambdaInitVals);\nint  KNITRO_API KN_set_var_dual_init_value (      KN_context_ptr  kc,\n                                            const KNINT           indexVar,\n                                            const double          lambdaInitVal);\n\n/** Set initial values for constraint dual variables (i.e. the Lagrange\n *  multipliers for the constraints).  If not set, constraint dual\n *  variables may be initialized as 0 or initialized by Knitro based on some\n *  initialization strategy (perhaps determined by a user option).\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_con_dual_init_values (      KN_context_ptr  kc,\n                                             const KNINT           nC,\n                                             const KNINT  * const  indexCons,\n                                             const double * const  lambdaInitVals);\nint  KNITRO_API KN_set_con_dual_init_values_all (      KN_context_ptr  kc,\n                                                 const double * const  lambdaInitVals);\nint  KNITRO_API KN_set_con_dual_init_value (      KN_context_ptr  kc,\n                                            const KNINT           indexCon,\n                                            const double          lambdaInitVal);\n\n/*----- Adding/removing/changing constant structure ----- */\n\n/** Add a constant to the objective function. */\nint  KNITRO_API KN_add_obj_constant (      KN_context_ptr  kc,\n                                     const double          constant);\n\n/** Delete all constant terms from the objective function.\n *  Only constant terms existing from a previous solve (i.e. added before the most\n *  recent call to \"KN_solve\") may be removed.\n */\nint  KNITRO_API KN_del_obj_constant (      KN_context_ptr  kc);\n\n/** Change constant term in the objective function.\n *  Equivalent to calling KN_del_obj_constant() + KN_add_obj_constant().\n */\nint  KNITRO_API KN_chg_obj_constant (      KN_context_ptr  kc,\n                                     const double          constant);\n\n/** Add constants to the body of constraint functions.\n *  Each component i of arrays indexCons and constants adds a constant term\n *  constants[i] to the constraint c[indexCons[i]].\n */\nint  KNITRO_API KN_add_con_constants (      KN_context_ptr  kc,\n                                      const KNINT           nC,\n                                      const KNINT  * const  indexCons,       /* size = nC */\n                                      const double * const  constants);      /* size = nC */\nint  KNITRO_API KN_add_con_constants_all (      KN_context_ptr  kc,\n                                          const double * const  constants);\nint  KNITRO_API KN_add_con_constant (      KN_context_ptr  kc,\n                                     const KNINT           indexCon,\n                                     const double          constant);\n\n/** Delete constant terms from the body of constraint functions.\n *  Each component i of array indexCons deletes all constant terms\n *  from the constraint c[indexCons[i]].\n *  Only constant terms existing from a previous solve (i.e. added before the most\n *  recent call to \"KN_solve\") may be removed.\n */\nint  KNITRO_API KN_del_con_constants (      KN_context_ptr  kc,\n                                      const KNINT           nC,\n                                      const KNINT  * const  indexCons);      /* size = nC */\nint  KNITRO_API KN_del_con_constants_all (      KN_context_ptr  kc);\nint  KNITRO_API KN_del_con_constant (      KN_context_ptr  kc,\n                                     const KNINT           indexCon);\n\n/** Change constant terms in the body of constraint functions.\n *  Each component i of arrays indexCons and constants changes the constant term\n *  in the constraint c[indexCons[i]] to constants[i].\n *  Equivalent to calling KN_del_con_constants() + KN_add_con_constants().\n */\nint  KNITRO_API KN_chg_con_constants (      KN_context_ptr  kc,\n                                      const KNINT           nC,\n                                      const KNINT  * const  indexCons,       /* size = nC */\n                                      const double * const  constants);      /* size = nC */\nint  KNITRO_API KN_chg_con_constants_all (      KN_context_ptr  kc,\n                                          const double * const  constants);\nint  KNITRO_API KN_chg_con_constant (      KN_context_ptr  kc,\n                                     const KNINT           indexCon,\n                                     const double          constant);\n\n/** Add constants to the body of residual functions.\n *  Each component i of arrays indexRsds and constants adds a constant term\n *  constants[i] to the residual r[indexRsds[i]].\n */\nint  KNITRO_API KN_add_rsd_constants (      KN_context_ptr  kc,\n                                      const KNINT           nR,\n                                      const KNINT  * const  indexRsds,       /* size = nR */\n                                      const double * const  constants);      /* size = nR */\nint  KNITRO_API KN_add_rsd_constants_all (      KN_context_ptr  kc,\n                                          const double * const  constants);\nint  KNITRO_API KN_add_rsd_constant (      KN_context_ptr  kc,\n                                     const KNINT           indexRsd,\n                                     const double          constant);\n\n/*----- Adding/removing/changing linear structure ----- */\n\n/** Add linear structure to the objective function.\n *  Each component i of arrays indexVars and coefs adds a linear term\n *     coefs[i]*x[indexVars[i]]\n *  to the objective.\n *\n *  Use \"KN_add_obj_linear_struct()\" to add several linear objective structures\n *  at once, and \"KN_add_obj_linear_term()\" to add a single linear objective\n *  term.\n */\nint  KNITRO_API KN_add_obj_linear_struct (      KN_context_ptr  kc,\n                                          const KNINT           nnz,\n                                          const KNINT  * const  indexVars,   /* size = nnz */\n                                          const double * const  coefs);      /* size = nnz */\nint  KNITRO_API KN_add_obj_linear_term (      KN_context_ptr  kc,\n                                        const KNINT           indexVar,\n                                        const double          coef);\n\n/** Delete linear structure from the objective function.\n *  Each component i of array indexVars removes the linear objective terms\n *  corresponding to variable x[indexVars[i]].\n *  Only linear terms existing from the latest model update (i.e. added before\n *  the most recent call to \"KN_solve\" or \"KN_update\") will be removed.\n *\n *  Use \"KN_del_obj_linear_struct()\" to delete several linear objective structures\n *  at once, \"KN_del_obj_linear_term()\" to delete a single linear objective\n *  term, \"KN_del_obj_linear_struct_all()\" to delete all linear objective terms.\n */\nint  KNITRO_API KN_del_obj_linear_struct (      KN_context_ptr  kc,\n                                          const KNINT           nnz,\n                                          const KNINT  * const  indexVars);   /* size = nnz */\nint  KNITRO_API KN_del_obj_linear_term (      KN_context_ptr  kc,\n                                        const KNINT           indexVar);\nint  KNITRO_API KN_del_obj_linear_struct_all (KN_context_ptr  kc);\n\n/** Change linear structure in the objective function.\n *  Each component i of arrays indexVars and coefs changes the coefficient\n *  value of the linear term\n *     coefs[i]*x[indexVars[i]]\n *  in the objective.\n *  Equivalent to calling KN_del_obj_linear_struct() + KN_add_obj_linear_struct().\n *\n *  Use \"KN_chg_obj_linear_struct()\" to change several linear objective structures\n *  at once, and \"KN_chg_obj_linear_term()\" to change a single linear objective\n *  term.\n */\nint  KNITRO_API KN_chg_obj_linear_struct (      KN_context_ptr  kc,\n                                          const KNINT           nnz,\n                                          const KNINT  * const  indexVars,   /* size = nnz */\n                                          const double * const  coefs);      /* size = nnz */\nint  KNITRO_API KN_chg_obj_linear_term (      KN_context_ptr  kc,\n                                        const KNINT           indexVar,\n                                        const double          coef);\n\n/** Add linear structure to the constraint functions.\n *  Each component i of arrays indexCons, indexVars and coefs adds a linear\n *  term:\n *     coefs[i]*x[indexVars[i]]\n *  to constraint c[indexCons[i]].\n *\n *  Use \"KN_add_con_linear_struct()\" to add linear structure for a group of\n *  constraints at once, \"KN_add_con_linear_struct_one()\" to add linear\n *  structure for just one constraint, and \"KN_add_con_linear_term()\" to\n *  add a single linear constraint term.\n */\nint  KNITRO_API KN_add_con_linear_struct (      KN_context_ptr  kc,\n                                          const KNLONG          nnz,\n                                          const KNINT  * const  indexCons,      /* size = nnz */\n                                          const KNINT  * const  indexVars,      /* size = nnz */\n                                          const double * const  coefs);         /* size = nnz */\nint  KNITRO_API KN_add_con_linear_struct_one (      KN_context_ptr  kc,\n                                              const KNLONG          nnz,\n                                              const KNINT           indexCon,\n                                              const KNINT  * const  indexVars,  /* size = nnz */\n                                              const double * const  coefs);     /* size = nnz */\nint  KNITRO_API KN_add_con_linear_term (      KN_context_ptr  kc,\n                                        const KNINT           indexCon,\n                                        const KNINT           indexVar,\n                                        const double          coef);\n\n/** Delete linear structure from the constraint functions.\n *  Each component i of arrays indexCons and indexVars removes the linear constraint\n *  terms corresponding to variable x[indexVars[i]] in constraint c[indexCons[i]].\n *  Only linear terms existing from the latest model update (i.e. added before\n *  the most recent call to \"KN_solve\" or \"KN_update\") will be removed.\n *\n *  Use \"KN_del_con_linear_struct()\" to delete linear structure from a group of\n *  constraints at once, \"KN_del_con_linear_struct_one()\" to delete linear\n *  structure from just one constraint, \"KN_del_con_linear_term()\" to\n *  delete a single linear constraint term and KN_del_con_linear_struct_all()\n *  to delete all linear terms from a set of constraints.\n */\nint  KNITRO_API KN_del_con_linear_struct (      KN_context_ptr  kc,\n                                          const KNLONG          nnz,\n                                          const KNINT  * const  indexCons,      /* size = nnz */\n                                          const KNINT  * const  indexVars);     /* size = nnz */\nint  KNITRO_API KN_del_con_linear_struct_one (      KN_context_ptr  kc,\n                                              const KNLONG          nnz,\n                                              const KNINT           indexCon,\n                                              const KNINT  * const  indexVars); /* size = nnz */\nint  KNITRO_API KN_del_con_linear_struct_all (      KN_context_ptr  kc,\n                                              const KNINT           nC,\n                                              const KNINT  * const  indexCons); /* size = nC */\nint  KNITRO_API KN_del_con_linear_term (      KN_context_ptr  kc,\n                                        const KNINT           indexCon,\n                                        const KNINT           indexVar);\n\n/** Change linear structure in the constraint functions.\n *  Each component i of arrays indexCons, indexVars and coefs changes the coefficient\n *  value of the linear term:\n *     coefs[i]*x[indexVars[i]]\n *  in constraint c[indexCons[i]].\n *  Equivalent to calling KN_del_con_linear_struct() + KN_add_con_linear_struct().\n *\n *  Use \"KN_chg_con_linear_struct()\" to change linear structure for a group of\n *  constraints at once, \"KN_chg_con_linear_struct_one()\" to change linear\n *  structure for just one constraint, and \"KN_chg_con_linear_term()\" to\n *  change a single linear constraint term.\n */\nint  KNITRO_API KN_chg_con_linear_struct (      KN_context_ptr  kc,\n                                          const KNLONG          nnz,\n                                          const KNINT  * const  indexCons,      /* size = nnz */\n                                          const KNINT  * const  indexVars,      /* size = nnz */\n                                          const double * const  coefs);         /* size = nnz */\nint  KNITRO_API KN_chg_con_linear_struct_one (      KN_context_ptr  kc,\n                                              const KNLONG          nnz,\n                                              const KNINT           indexCon,\n                                              const KNINT  * const  indexVars,  /* size = nnz */\n                                              const double * const  coefs);     /* size = nnz */\nint  KNITRO_API KN_chg_con_linear_term (      KN_context_ptr  kc,\n                                        const KNINT           indexCon,\n                                        const KNINT           indexVar,\n                                        const double          coef);\n\n/** Add linear structure to the residual functions.\n *  Each component i of arrays indexRsds, indexVars and coefs adds a linear\n *  term:\n *     coefs[i]*x[indexVars[i]]\n *  to residual r[indexRsds[i]].\n *\n *  Use \"KN_add_rsd_linear_struct()\" to add linear structure for a group of\n *  residuals at once, \"KN_add_rsd_linear_struct_one()\" to add linear\n *  structure for just one residual, and \"KN_add_rsd_linear_term()\" to\n *  add a single linear residual term.\n */\nint  KNITRO_API KN_add_rsd_linear_struct (      KN_context_ptr  kc,\n                                          const KNLONG          nnz,\n                                          const KNINT  * const  indexRsds,      /* size = nnz */\n                                          const KNINT  * const  indexVars,      /* size = nnz */\n                                          const double * const  coefs);         /* size = nnz */\nint  KNITRO_API KN_add_rsd_linear_struct_one (      KN_context_ptr  kc,\n                                              const KNLONG          nnz,\n                                              const KNINT           indexRsd,\n                                              const KNINT  * const  indexVars,  /* size = nnz */\n                                              const double * const  coefs);     /* size = nnz */\nint  KNITRO_API KN_add_rsd_linear_term (      KN_context_ptr  kc,\n                                        const KNINT           indexRsd,\n                                        const KNINT           indexVar,\n                                        const double          coef);\n\n/*----- Adding quadratic structure ----- */\n\n/** Add quadratic structure to the objective function.\n *  Each component i of arrays indexVars1, indexVars2 and coefs adds a\n *  quadratic term\n *     coefs[i]*x[indexVars1[i]]*x[indexVars2[i]]\n *  to the objective.\n *\n *  Use \"KN_add_obj_quadratic_struct()\" to add several quadratic objective\n *  structures at once, and \"KN_add_obj_quadratic_term()\" to add a single\n *  quadratic objective term.\n *\n *  Note: if indexVars2[i] is < 0 then it adds a linear term\n *        coefs[i]*x[indexVars1[i]] instead.\n */\nint  KNITRO_API KN_add_obj_quadratic_struct (      KN_context_ptr  kc,\n                                             const KNLONG          nnz,\n                                             const KNINT  * const  indexVars1,  /* size = nnz */\n                                             const KNINT  * const  indexVars2,  /* size = nnz */\n                                             const double * const  coefs);      /* size = nnz */\nint  KNITRO_API KN_add_obj_quadratic_term (      KN_context_ptr  kc,\n                                           const KNINT           indexVar1,\n                                           const KNINT           indexVar2,\n                                           const double          coef);\n\n/** Delete quadratic structure from the objective function.\n *\n *  \"KN_del_obj_quadratic_struct\" will remove each component i of arrays\n *  indexVars1 and indexVars2 from the objective. That is any coefficient c:\n *     c*indexVars1[i]*indexVars2[i]\n *  \"KN_del_obj_quadratic_struct_all\" will delete all quadratic structure from\n *  the objective function.\n *\n *  Only quadratic terms existing from the latest model update (i.e. added\n *  before the most recent call to \"KN_solve\" or \"KN_update\") will be removed.\n */\nint  KNITRO_API KN_del_obj_quadratic_struct(      KN_context_ptr  kc,\n                                            const KNLONG          nnz,\n                                            const KNINT  * const  indexVars1,  /* size = nnz */\n                                            const KNINT  * const  indexVars2); /* size = nnz */\nint  KNITRO_API KN_del_obj_quadratic_struct_all (KN_context_ptr  kc);\n\n/** Add quadratic structure to the constraint functions.\n *  Each component i of arrays indexCons, indexVars1, indexVars2 and coefs adds a\n *  quadratic term:\n *     coefs[i]*x[indexVars1[i]]*x[indexVars2[i]]\n *  to the constraint c[indexCons[i]].\n *\n *  Use \"KN_add_con_quadratic_struct()\" to add quadratic structure for a group of\n *  constraints at once, \"KN_add_con_quadratic_struct_one()\" to add quadratic\n *  structure for just one constraint, and \"KN_add_con_quadratic_term()\" to\n *  add a single quadratic constraint term.\n *\n *  Note: if indexVars2[i] is < 0 then it adds a linear term\n *        coefs[i]*x[indexVars1[i]] instead.\n */\nint  KNITRO_API KN_add_con_quadratic_struct (      KN_context_ptr  kc,\n                                             const KNLONG          nnz,\n                                             const KNINT  * const  indexCons,   /* size = nnz */\n                                             const KNINT  * const  indexVars1,  /* size = nnz */\n                                             const KNINT  * const  indexVars2,  /* size = nnz */\n                                             const double * const  coefs);      /* size = nnz */\nint  KNITRO_API KN_add_con_quadratic_struct_one (      KN_context_ptr  kc,\n                                                 const KNLONG          nnz,\n                                                 const KNINT           indexCon,\n                                                 const KNINT  * const  indexVars1,  /* size = nnz */\n                                                 const KNINT  * const  indexVars2,  /* size = nnz */\n                                                 const double * const  coefs);      /* size = nnz */\nint  KNITRO_API KN_add_con_quadratic_term (      KN_context_ptr  kc,\n                                           const KNINT           indexCon,\n                                           const KNINT           indexVar1,\n                                           const KNINT           indexVar2,\n                                           const double          coef);\n\n/** Delete quadratric structure from the constraint functions.\n *  Each component i of arrays indexCons, indexVars1 and indexVars2 removes the\n *  quadratic constraint terms corresponding to variables x[indexVars1[i]] and\n *  x[indexVars2[i]] in constraint c[indexCons[i]].\n *  Only quadratic terms existing from the latest model update (i.e. added\n *  before the most recent call to \"KN_solve\" or \"KN_update\") will be removed.\n */\nint  KNITRO_API KN_del_con_quadratic_struct(      KN_context_ptr  kc,\n                                            const KNLONG          nnz,\n                                            const KNINT  * const  indexCons,   /* size = nnz */\n                                            const KNINT  * const  indexVars1,  /* size = nnz */\n                                            const KNINT  * const  indexVars2); /* size = nnz */\n\n/*----- Adding conic structure ----- */\n\n/** Add L2 norm structure of the form ||Ax + b||_2 to a constraint.\n *    indexCon:    The constraint index that the L2 norm term will be added to.\n *    nCoords:     The number of rows in \"A\" (or dimension of \"b\")\n *    nnz:         The number of sparse non-zero elements in \"A\"\n *    indexCoords: The coordinate (row) index for each non-zero element in \"A\".\n *    indexVars:   The variable (column) index for each non-zero element in \"A\"\n *    coefs:       The coefficient value for each non-zero element in \"A\"\n *    constants:   The array \"b\" - may be set to NULL to ignore \"b\"\n *\n *  Note: L2 norm structure can currently only be added to constraints that\n *        otherwise only have linear (or constant) structure.  In this way\n *        they can be used to define conic constraints of the form\n *        ||Ax + b|| <= c'x + d.  The \"c\" coefficients should be added through\n *        \"KN_add_con_linear_struct()\" and \"d\" can be set as a constraint bound\n *        or through \"KN_add_con_constants()\".\n *\n *  Note: Models with L2 norm structure are currently only handled by the\n *        Interior/Direct (KN_ALG_BAR_DIRECT) algorithm in Knitro.  Any model\n *        with structure defined with KN_add_con_L2norm() will automatically be\n *        forced to use this algorithm.\n */\nint  KNITRO_API KN_add_con_L2norm (      KN_context_ptr  kc,\n                                   const KNINT           indexCon,\n                                   const KNINT           nCoords,\n                                   const KNLONG          nnz,\n                                   const KNINT  * const  indexCoords,  /* size = nnz */\n                                   const KNINT  * const  indexVars,    /* size = nnz */\n                                   const double * const  coefs,        /* size = nnz */\n                                   const double * const  constants);   /* size = nCoords or NULL */\n\n/*----- Adding complementarity constraints ----- */\n\n/** This function adds complementarity constraints to the problem.\n *  The parameter indexCompCons may be set to NULL. Otherwise, on return it\n *  holds the global indices associated with the complementarity constraints\n *  that were added (indices are typically allocated sequentially). Parameter\n *  indexCompCons can then be passed into other API routines that operate\n *  on the set of complementarity constraints added through a particular call\n *  to KN_add_compcon*.\n *  The two lists indexComps1/indexComps2 are of equal length, and contain\n *  nCC matching pairs of variable indices.  Each pair defines a complementarity\n *  constraint between the two variables.\n *  The array ccTypes specifies the type of complementarity:\n *     KN_CCTYPE_VARVAR: two (non-negative) variables\n *     KN_CCTYPE_VARCON: a variable and a constraint\n *     KN_CCTYPE_CONCON: two constraints\n *  Note: Currently only KN_CCTYPE_VARVAR is supported.  The other\n *        ccTypes will be added in future releases.\n *  Returns 0 if OK, or a negative value on error.\n */\nint  KNITRO_API KN_add_compcons (      KN_context_ptr  kc,\n                                 const KNINT           nCC,\n                                 const int    * const  ccTypes,\n                                 const KNINT  * const  indexComps1,\n                                 const KNINT  * const  indexComps2,\n                                       KNINT  * const  indexCompCons);\nint  KNITRO_API KN_add_compcon  (      KN_context_ptr  kc,\n                                 const int             ccType,\n                                 const KNINT           indexComp1,\n                                 const KNINT           indexComp2,\n                                       KNINT  * const  indexCompCon);\n\n/** This function sets all the complementarity constraints for the\n *  problem in one call. The function can only be called once.\n *  Returns 0 if OK, or a negative value on error.\n *  This function has been superseded by the KN_add_compcons function.\n */\nint  KNITRO_API KN_set_compcons (      KN_context_ptr  kc,\n                                 const KNINT           nCC,\n                                 const int    * const  ccTypes,\n                                 const KNINT  * const  indexComps1,\n                                 const KNINT  * const  indexComps2);\n\n/* ----- Loading MPS file ----- */\n\n/** This function loads the problem specified in the MPS file \"filename\".\n *  The number of variables and constraints is specified in the MPS file,\n *  as well as the nature of the objective and the different constraints\n *  (should they be linear or quadratic).\n *  Return 0 if OK, or a negative value on error.\n */\nint KNITRO_API KN_load_mps_file (    KN_context_ptr kc,\n                                 const char * const filename);\n\nint KNITRO_API KN_write_mps_file (KN_context_ptr kc,\n                                    const char * filename);\n\n/**\n * This function loads a problem from a file. The file format is deduced from\n * the file extension (case insensitive) or from the \"read_options\" flags.\n * Supported file formats are:\n *     MPS files with extension \".mps\"\n *     CBF files with extension \".cbf\" (experimental)\n *     LP files with extension \".lp\"\n * Additional reading options can be given as a list of characters with\n * \"read_options\":\n *     'm': parsing MPS file without interpreting file extension\n *     'c': parsing CBF file without interpreting file extension\n *     'l': parsing LP file without interpreting file extension\n *\n *  Return 0 if OK, or a negative value on error.\n */\nint KNITRO_API KN_read_problem(    KN_context_ptr kc,\n                               const char * const filename,\n                               const char * const read_options);\n\n\n/**\n * This function writes a problem to a file. The file format is deduced from\n * the file extension (case insensitive) or from the \"write_options\" flags.\n * Supported file formats are:\n *     MPS files with extension \".mps\"\n * Additional writing options can be given as a list of characters with\n * \"write_options\":\n *     'm': write in MPS format without interpreting file extension\n *     'l': write in LP format without interpreting file extension\n *     'b': write bounds at the beginning of the file. This option is only\n *          available when writing in LP format.\n *\n *  Return 0 if OK, or a negative value on error.\n */\nint KNITRO_API KN_write_problem(    KN_context_ptr kc,\n                               const char * const filename,\n                               const char * const write_options);\n\n/* ----- Callbacks ----- */\n\n/** Applications may define functions for evaluating problem elements\n *  at a trial point.  The functions must match the prototype defined\n *  below, and passed to Knitro with the appropriate KN_set_cb_* call.\n *  Knitro may request different types of evaluation information,\n *  as specified in \"evalRequest.type\":\n *    KN_RC_EVALFC   - return objective and constraint function values\n *    KN_RC_EVALGA   - return first derivative values in \"objGrad\" and \"jac\"\n *    KN_RC_EVALFCGA - return objective and constraint function values\n *                     AND first derivative \"objGrad\" and \"jac\"\n *    KN_RC_EVALH    - return second derivative values in \"hessian\"\n *    KN_RC_EVALH_NO_F  (this version excludes the objective term)\n *    KN_RC_EVALHV   - return a Hessian-vector product in \"hessVector\"\n *    KN_RC_EVALHV_NO_F (this version excludes the objective term)\n *    KN_RC_EVALR    - return residual function values for least squares\n *    KN_RC_EVALRJ   - return residual Jacobian values for least squares\n *\n *  The argument \"lambda\" is not defined when requesting EVALFC, EVALGA,\n *  EVALFCGA, EVALR or EVALRJ.\n *    Usually, applications for standard optimization models define three\n *  callback functions: one for EVALFC, one for EVALGA, and one for EVALH / EVALHV.\n *  The last function is only used when providing the Hessian (as opposed to\n *  using one of the Knitro options to approximate it) and evaluates H or HV\n *  depending on the value of \"evalRequest.type\".  For least squares models,\n *  the application defines the two callback functions for EVALR and EVALRJ\n *  (instead of EVALFC and EVALGA).  Least squares applications do not provide\n *  a callback for the Hessian as it is always approximated.\n *    It is possible in most cases to combine EVALFC and EVALGA into a single\n *  callback function.  This may be advantageous if the application evaluates\n *  functions and their derivatives at the same time.  In order to do this, set\n *  the user option eval_fcga=KN_EVAL_FCGA_YES, and define one callback set in\n *  \"KN_add_eval_callback()\" that evaluates BOTH the functions and gradients\n *  (i.e. have it populate \"obj\", \"c\", \"objGrad\", and \"jac\" in the \"evalResult\"\n *  structure), and do not set a callback in \"KN_set_cb_grad()\".  Whenever Knitro\n *  needs a function + gradient evaluation, it will callback to the function\n *  passed to \"KN_add_eval_callback()\" with an EVALFCGA request.\n *    Combining function and gradient evaluations in one callback is not currently\n *  allowed if hessopt=KN_HESSOPT_PRODUCT_FINDIFF. It is not possible to combine\n *  EVALH / EVALHV because \"lambda\" may change after the EVALFC call.  Generally\n *  it is most efficient to separate function and gradient callbacks, since a\n *  gradient evaluation is not needed at every \"x\" value where functions are\n *  evaluated.\n *\n *  The \"userParams\" argument is an arbitrary pointer passed from the Knitro\n *  KN_solve call to the callback.  It should be used to pass parameters\n *  defined and controlled by the application, or left null if not used.\n *  Knitro does not modify or dereference the \"userParams\" pointer.\n *\n *  For simplicity, the following user-defined evaluation callback functions\n *  all use the same \"KN_eval_callback()\" function prototype defined below.\n *\n *      funcCallback\n *      gradCallback\n *      hessCallback\n *      rsdCallback    (for least squares)\n *      rsdJacCallback (for least squares)\n *\n *  Other user callbacks that aren't involved in evaluations use the\n *  \"KN_user_callback\" function prototype or some other function protoype\n *  defined below that is specific to that callback. These include:\n *\n *      KN_set_newpt_callback\n *      KN_set_mip_node_callback\n *      KN_set_mip_usercuts_callback\n *      KN_set_mip_lazyconstraints_callback\n *      KN_set_ms_callback\n *      KN_set_ms_process_callback\n *      KN_set_ms_initpt_callback\n *      KN_set_puts_callback\n *      KN_set_linsolver_callback\n *\n *  Callbacks should return 0 if successful, a negative error code if not.\n *  Possible unsuccessful (negative) error codes for the func/grad/hess/rsd/rsdJac\n *  callback functions include:\n *\n *      KN_RC_CALLBACK_ERR       (for generic callback errors)\n *      KN_RC_EVAL_ERR           (for evaluation errors, e.g log(-1))\n *\n *  The \"linsolver\" callback may use the return code\n *\n *      KN_RC_LINEAR_SOLVER_ERR\n *\n *  if it encounters a linear system it is unable to solve or prefers Knitro\n *  to handle.  In this case, Knitro will revert to its own internal linear\n *  solver for that linear system.\n *\n *  In addition, for the \"func\", \"newpoint\", \"ms_process\", \"mip_node\",\n *  \"mip_usercuts\" and \"mip_lazyconstraints\" callbacks, the user may set the\n *  following return code to force Knitro\n *  to terminate based on some user-defined condition.\n *\n *      KN_RC_USER_TERMINATION   (to use a callback routine\n *                                for user specified termination)\n */\n\n/** Structure used to pass back evaluation information for evaluation callbacks.\n *\n *    type:      - indicates the type of evaluation requested\n *    threadID:  - the thread ID associated with this evaluation request;\n *                 useful for multi-threaded, concurrent evaluations\n *    x:         - values of unknown (primal) variables used for all evaluations\n *    lambda:    - values of unknown dual variables/Lagrange multipliers\n *                 used for the evaluation of the Hessian\n *    sigma:     - scalar multiplier for the objective component of the Hessian\n *    vec:       - vector array value for Hessian-vector products (only used\n *                 when user option hessopt=KN_HESSOPT_PRODUCT)\n */\ntypedef struct KN_eval_request {\n          int      type;\n          int      threadID;\n    const double * x;\n    const double * lambda;\n    const double * sigma;\n    const double * vec;\n} KN_eval_request, *KN_eval_request_ptr;\n\n/** Structure used to return results information for evaluation callbacks.\n *  The arrays (and their indices and sizes) returned in this structure are\n *  local to the specific callback structure used for the evaluation.\n *\n *    obj:             - objective function evaluated at \"x\" for EVALFC or\n *                       EVALFCGA request (funcCallback)\n *    c:               - (length nC) constraint values evaluated at \"x\" for\n *                       EVALFC or EVALFCGA request (funcCallback)\n *    objGrad:         - (length nV) objective gradient evaluated at \"x\" for\n *                       EVALGA request (gradCallback) or EVALFCGA request (funcCallback)\n *    jac:             - (length nnzJ) constraint Jacobian evaluated at \"x\" for\n *                       EVALGA request (gradCallback) or EVALFCGA request (funcCallback)\n *    hess:            - (length nnzH) Hessian evaluated at \"x\", \"lambda\", \"sigma\"\n *                       for EVALH or EVALH_NO_F request (hessCallback)\n *    hessVec:         - (length n=number variables in the model) Hessian-vector\n *                       product evaluated at \"x\", \"lambda\", \"sigma\"\n *                       for EVALHV or EVALHV_NO_F request (hessCallback)\n *    rsd:             - (length nR) residual values evaluated at \"x\" for EVALR\n *                       request (rsdCallback)\n *    rsdJac:          - (length nnzJ) residual Jacobian evaluated at \"x\" for\n *                       EVALRJ request (rsdJacCallback)\n */\ntypedef struct KN_eval_result {\n    double * obj;\n    double * c;\n    double * objGrad;\n    double * jac;\n    double * hess;\n    double * hessVec;\n    double * rsd;\n    double * rsdJac;\n} KN_eval_result, *KN_eval_result_ptr;\n\n/** The callback structure/object.  Note the CB_context_ptr is allocated and\n *  managed by Knitro: the user does not have to free it.\n */\ntypedef struct CB_context CB_context, *CB_context_ptr;\n\n/** Function prototype for evaluation callbacks. */\ntypedef int KN_eval_callback (KN_context_ptr             kc,\n                              CB_context_ptr             cb,\n                              KN_eval_request_ptr const  evalRequest,\n                              KN_eval_result_ptr  const  evalResult,\n                              void              * const  userParams);\n\n/** This is the routine for adding a callback for (nonlinear) evaluations\n *  of objective and constraint functions.  This routine can be called\n *  multiple times to add more than one callback structure (e.g. to create\n *  different callback structures to handle different blocks of constraints).\n *  This routine specifies the minimal information needed for a callback, and\n *  creates the callback structure \"cb\", which can then be passed to other\n *  callback functions to set additional information for that callback.\n *\n *    evalObj       - boolean indicating whether or not any part of the objective\n *                    function is evaluated in the callback\n *    nC            - number of constraints evaluated in the callback\n *    indexCons     - (length nC) index of constraints evaluated in the callback\n *                    (set to NULL if nC=0)\n *    funcCallback  - a pointer to a function that evaluates the objective parts\n *                    (if evalObj=KNTRUE) and any constraint parts (specified by\n *                    nC and indexCons) involved in this callback; when\n *                    eval_fcga=KN_EVAL_FCGA_YES, this callback should also evaluate\n *                    the relevant first derivatives/gradients\n *    cb            - (output) the callback structure that gets created by\n *                    calling this function; all the memory for this structure is\n *                    handled by Knitro\n *\n *  After a callback is created by \"KN_add_eval_callback()\", the user can then specify\n *  gradient information and structure through \"KN_set_cb_grad()\" and Hessian\n *  information and structure through \"KN_set_cb_hess()\".  If not set, Knitro will\n *  approximate these.  However, it is highly recommended to provide a callback routine\n *  to specify the gradients if at all possible as this will greatly improve the\n *  performance of Knitro.  Even if a gradient callback is not provided, it is still\n *  helpful to provide the sparse Jacobian structure through \"KN_set_cb_grad()\" to\n *  improve the efficiency of the finite-difference gradient approximations.\n *  Other optional information can also be set via \"KN_set_cb_*() functions as\n *  detailed below.\n *\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_add_eval_callback (      KN_context_ptr            kc,\n                                      const KNBOOL                    evalObj,\n                                      const KNINT                     nC,\n                                      const KNINT            * const  indexCons,    /* nullable if nC=0 */\n                                            KN_eval_callback * const  funcCallback,\n                                            CB_context_ptr   * const  cb);\n\n/** Version of KN_add_eval_callback to create a callback that applies to the\n *  objective function and all constraints.\n */\nint  KNITRO_API KN_add_eval_callback_all (      KN_context_ptr            kc,\n                                                KN_eval_callback * const  funcCallback,\n                                                CB_context_ptr   * const  cb);\n\n/** Version of KN_add_eval_callback to create a callback that only applies to a\n *  single objective function or constraint.  Set index to the corresponding\n *  constraint index or use -1 for the objective.\n */\nint  KNITRO_API KN_add_eval_callback_one (      KN_context_ptr            kc,\n                                          const KNINT                     index,    /* -1 for obj */\n                                                KN_eval_callback * const  funcCallback,\n                                                CB_context_ptr   * const  cb);\n\n/** Add an evaluation callback for a least-squares models.  Similar to KN_add_eval_callback()\n *  above, but for least-squares models.\n *\n *    nR            - number of residuals evaluated in the callback\n *    indexRsds     - (length nR) index of residuals evaluated in the callback\n *    rsdCallback   - a pointer to a function that evaluates any residual parts\n *                    (specified by nR and indexRsds) involved in this callback\n *    cb            - (output) the callback structure that gets created by\n *                    calling this function; all the memory for this structure is\n *                    handled by Knitro\n *\n *  After a callback is created by \"KN_add_lsq_eval_callback()\", the user can then\n *  specify residual Jacobian information and structure through \"KN_set_cb_rsd_jac()\".\n *  If not set, Knitro will approximate the residual Jacobian.  However, it is highly\n *  recommended to provide a callback routine to specify the residual Jacobian if at all\n *  possible as this will greatly improve the performance of Knitro.  Even if a callback\n *  for the residual Jacobian is not provided, it is still helpful to provide the sparse\n *  Jacobian structure for the residuals through \"KN_set_cb_rsd_jac()\" to improve the\n *  efficiency of the finite-difference Jacobian approximation.  Other optional\n *  information can also be set via \"KN_set_cb_*() functions as detailed below.\n *\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_add_lsq_eval_callback (      KN_context_ptr            kc,\n                                          const KNINT                     nR,\n                                          const KNINT            * const  indexRsds,\n                                                KN_eval_callback * const  rsdCallback,\n                                                CB_context_ptr   * const  cb);\n\n/** Version of KN_add_lsq_eval_callback to create a callback that applies to\n *  all residual functions.\n */\nint  KNITRO_API KN_add_lsq_eval_callback_all (      KN_context_ptr            kc,\n                                                    KN_eval_callback * const  rsdCallback,\n                                                    CB_context_ptr   * const  cb);\n\n/** Version of KN_add_lsq_eval_callback to create a callback that only applies to\n *  a single residual function.  Set indexRsd to the corresponding residual index.\n */\nint  KNITRO_API KN_add_lsq_eval_callback_one (      KN_context_ptr            kc,\n                                              const KNINT                     indexRsd,\n                                                    KN_eval_callback * const  rsdCallback,\n                                                    CB_context_ptr   * const  cb);\n\n/** This API function is used to set the objective gradient and constraint Jacobian\n *  structure and also (optionally) a callback function to evaluate the objective\n *  gradient and constraint Jacobian provided through this callback.\n *\n *    cb               - a callback structure created from a previous call to\n *                       KN_add_eval_callback()\n *    nV               - number of nonzero components in the objective gradient\n *                       for this callback if providing in sparse form; set to\n *                       KN_DENSE to provide the full objective gradient\n *    objGradIndexVars - (length nV) the nonzero indices of the objective gradient;\n *                       set to NULL if nV=KN_DENSE or nV=0 (i.e. evalObj=KNFALSE)\n *    nnzJ             - number of nonzeroes in the sparse constraint Jacobian\n *                       computed through this callback; set to KN_DENSE_ROWMAJOR to\n *                       provide the full Jacobian in row major order (i.e. ordered\n *                       by rows/constraints), or KN_DENSE_COLMAJOR to provide the full\n *                       Jacobian in column major order (i.e. ordered by columns/\n *                       variables)\n *    jacIndexCons     - (length nnzJ) constraint index (row) of each nonzero;\n *                       set to NULL if nnzJ=KN_DENSE_ROWMAJOR/KN_DENSE_COLMAJOR or nnzJ=0\n *    jacIndexVars     - (length nnzJ) variable index (column) of each nonzero;\n *                       set to NULL if nnzJ=KN_DENSE_ROWMAJOR/KN_DENSE_COLMAJOR or nnzJ=0\n *    gradCallback     - a pointer to a function that evaluates the objective gradient\n *                       parts and any constraint Jacobian parts involved in this\n *                       callback; set to NULL if using finite-difference gradient\n *                       approximations (specified via KN_set_cb_gradopt()), or if\n *                       gradients and functions are provided together in the\n *                       funcCallback (i.e. eval_fcga=KN_EVAL_FCGA_YES).\n *\n *  The user should generally always try to define the sparsity structure\n *  for the Jacobian (\"nnzJ\", \"jacIndexCons\", \"jacIndexVars\").  Even when\n *  using finite-difference approximations to compute the gradients, knowing the\n *  sparse structure of the Jacobian can allow Knitro to compute these\n *  finite-difference approximations faster.  However, if the user is unable to\n *  provide this sparsity structure, then one can set \"nnzJ\" to KN_DENSE_ROWMAJOR or\n *  KN_DENSE_COLMAJOR and set \"jacIndexCons\" and \"jacIndexVars\" to NULL.\n */\nint  KNITRO_API KN_set_cb_grad (      KN_context_ptr            kc,\n                                      CB_context_ptr            cb,\n                                const KNINT                     nV,   /* or KN_DENSE */\n                                const KNINT            * const  objGradIndexVars,\n                                const KNLONG                    nnzJ, /* or KN_DENSE_* */\n                                const KNINT            * const  jacIndexCons,\n                                const KNINT            * const  jacIndexVars,\n                                      KN_eval_callback * const  gradCallback); /* nullable */\n\n/** This API function is used to set the structure and a callback function to\n *  evaluate the components of the Hessian of the Lagrangian provided through this\n *  callback.  KN_set_cb_hess() should only be used when defining a user-supplied\n *  Hessian callback function (via the \"hessopt=KN_HESSOPT_EXACT\" user option), or\n *  a callback function to compute the Hessian-vector product array (via the\n *  \"hessopt=KN_HESSOPT_PRODUCT\" user option).  When providing a callback function\n *  for Hessian-vector products, the Hessian is not stored or used internally, so\n *  in this case set \"nnzH\"=0, \"hessIndexVars1\"=NULL, and \"hessIndexVars2\"=NULL.\n *  When Knitro is approximating the Hessian, it cannot make use of the Hessian\n *  sparsity structure.\n *\n *    cb               - a callback structure created from a previous call to\n *                       KN_add_eval_callback()\n *    nnzH             - number of nonzeroes in the sparse Hessian of the Lagrangian\n *                       computed through this callback; set to KN_DENSE_ROWMAJOR to\n *                       provide the full upper triangular Hessian in row major order,\n *                       or KN_DENSE_COLMAJOR to provide the full upper triangular Hessian\n *                       in column major order.  Note that the Hessian is symmetric, so\n *                       the lower triangular components are the same as the upper\n *                       triangular components with row and column indices swapped.\n *    hessIndexVars1   - (length nnzH) first variable index of each nonzero;\n *                       set to NULL if nnzH=KN_DENSE_ROWMAJOR/KN_DENSE_COLMAJOR\n *    hessIndexVars2   - (length nnzH) second variable index of each nonzero;\n *                       set to NULL if nnzH=KN_DENSE_ROWMAJOR/KN_DENSE_COLMAJOR\n *    hessCallback     - a pointer to a function that evaluates the components of the\n *                       Hessian of the Lagrangian (or Hessian-vector product array)\n *                       provided in this callback\n */\nint  KNITRO_API KN_set_cb_hess (      KN_context_ptr            kc,\n                                      CB_context_ptr            cb,\n                                const KNLONG                    nnzH, /* or KN_DENSE_* */\n                                const KNINT            * const  hessIndexVars1,\n                                const KNINT            * const  hessIndexVars2,\n                                      KN_eval_callback * const  hessCallback);\n\n\n/** This API function is used to set the residual Jacobian structure and also\n *  (optionally) a callback function to evaluate the residual Jacobian provided\n *  through this callback.\n *\n *    cb               - a callback structure created from a previous call to\n *                       KN_add_lsq_eval_callback()\n *    nnzJ             - number of nonzeroes in the sparse residual Jacobian\n *                       computed through this callback; set to KN_DENSE_ROWMAJOR to\n *                       provide the full Jacobian in row major order (i.e. ordered\n *                       by rows/residuals), or KN_DENSE_COLMAJOR to provide the full\n *                       Jacobian in column major order (i.e. ordered by columns/\n *                       variables)\n *    jacIndexRsds     - (length nnzJ) residual index (row) of each nonzero;\n *                       set to NULL if nnzJ=KN_DENSE_ROWMAJOR/KN_DENSE_COLMAJOR or nnzJ=0\n *    jacIndexVars     - (length nnzJ) variable index (column) of each nonzero;\n *                       set to NULL if nnzJ=KN_DENSE_ROWMAJOR/KN_DENSE_COLMAJOR or nnzJ=0\n *    rsdJacCallback   - a pointer to a function that evaluates any residual Jacobian\n *                       parts involved in this callback; set to NULL if using a finite-\n *                       difference Jacobian approximation (specified via KN_set_cb_gradopt())\n *\n *  The user should generally always try to define the sparsity structure\n *  for the Jacobian (\"nnzJ\", \"jacIndexRsds\", \"jacIndexVars\").  Even when\n *  using a finite-difference approximation to compute the Jacobian, knowing the\n *  sparse structure of the Jacobian can allow Knitro to compute this\n *  finite-difference approximation faster.  However, if the user is unable to\n *  provide this sparsity structure, then one can set \"nnzJ\" to KN_DENSE_ROWMAJOR or\n *  KN_DENSE_COLMAJOR and set \"jacIndexRsds\" and \"jacIndexVars\" to NULL.\n */\nint  KNITRO_API KN_set_cb_rsd_jac (      KN_context_ptr            kc,\n                                         CB_context_ptr            cb,\n                                   const KNLONG                    nnzJ, /* or KN_DENSE_* */\n                                   const KNINT            * const  jacIndexRsds,\n                                   const KNINT            * const  jacIndexVars,\n                                         KN_eval_callback * const  rsdJacCallback); /* nullable */\n\n\n/** Define a userParams structure for an evaluation callback. */\nint  KNITRO_API KN_set_cb_user_params (KN_context_ptr  kc,\n                                       CB_context_ptr  cb,\n                                       void   * const  userParams);\n\n/** Specify which gradient option \"gradopt\" will be used to evaluate\n *  the first derivatives of the callback functions.  If gradopt=KN_GRADOPT_EXACT\n *  then a gradient evaluation callback must be set by \"KN_set_cb_grad()\"\n *  (or \"KN_set_cb_rsd_jac()\" for least squares).\n */\nint  KNITRO_API KN_set_cb_gradopt (      KN_context_ptr  kc,\n                                         CB_context_ptr  cb,\n                                   const int             gradopt);\n\n/** Set an array of relative stepsizes to use for the finite-difference\n *  gradient/Jacobian computations when using finite-difference\n *  first derivatives.  The user option KN_PARAM_FINDIFF_RELSTEPSIZE\n *  can be used to set the relative stepsizes for ALL variables.  This\n *  routine takes precedence over the setting of KN_PARAM_FINDIFF_RELSTEPSIZE\n *  and is used to customize the settings for individual variables.\n *  Finite-difference step sizes \"delta\" in Knitro are computed as:\n *       delta[i] = relStepSizes[i]*max(abs(x[i]),1);\n *  The default relative step sizes for each component of \"x\" are sqrt(eps)\n *  for forward finite differences, and eps^(1/3) for central finite\n *  differences.  Use this function to overwrite the default values.\n *  Any zero values will use Knitro default values, while non-zero values\n *  will overwrite default values. Knitro makes a local copy of all inputs,\n *  so the application may free memory after the call.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_cb_relstepsizes (      KN_context_ptr  kc,\n                                              CB_context_ptr  cb,\n                                        const KNINT           nV,\n                                        const KNINT  * const  indexVars,\n                                        const double * const  xRelStepSizes);\nint  KNITRO_API KN_set_cb_relstepsizes_all (      KN_context_ptr  kc,\n                                                  CB_context_ptr  cb,\n                                            const double * const  xRelStepSizes);\nint  KNITRO_API KN_set_cb_relstepsize (      KN_context_ptr  kc,\n                                             CB_context_ptr  cb,\n                                       const KNINT           indexVar,\n                                       const double          xRelStepSize);\n\n/** These API functions can be used to retrieve some information specific to evaluation\n *  callbacks. */\n\n/** Retrieve the number of constraints \"nC\" being evaluated through callback \"cb\".\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_cb_number_cons (const KN_context_ptr  kc,\n                                       const CB_context_ptr  cb,\n                                             KNINT * const   nC);\n\n/** Retrieve the number of residuals \"nR\" being evaluated through callback \"cb\".\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_cb_number_rsds (const KN_context_ptr  kc,\n                                       const CB_context_ptr  cb,\n                                             KNINT * const   nR);\n\n/** Retrieve the number of non-zero objective gradient elements \"nnz\"\n *  evaluated through callback \"cb\".\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_cb_objgrad_nnz (const KN_context_ptr  kc,\n                                       const CB_context_ptr  cb,\n                                             KNINT * const   nnz);\n\n/** Retrieve the number of non-zero Jacobian elements \"nnz\"\n *  evaluated through callback \"cb\".\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_cb_jacobian_nnz (const KN_context_ptr  kc,\n                                        const CB_context_ptr  cb,\n                                              KNLONG * const  nnz);\n\n/** Retrieve the number of non-zero residual Jacobian elements \"nnz\"\n *  evaluated through callback \"cb\".\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_cb_rsd_jacobian_nnz (const KN_context_ptr  kc,\n                                            const CB_context_ptr  cb,\n                                                  KNLONG * const  nnz);\n\n/** Retrieve the number of non-zero Hessian elements \"nnz\" being\n *  evaluated through callback \"cb\".\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_cb_hessian_nnz (const KN_context_ptr  kc,\n                                       const CB_context_ptr  cb,\n                                             KNLONG * const  nnz);\n\n/** Delete all evaluation callbacks previously added with KN_add_eval_callback.\n *\n * Note: all previously used CB_context_ptr will automatically be freed and must\n * not be used after this call.\n */\nint  KNITRO_API KN_del_eval_callbacks(const KN_context_ptr kc);\n\n/** Delete the objective terms of an evaluation callback.\n *\n * The callback functions are not modified and will still be called, but the\n * objective components will not be used in the evaluations.\n *\n * Note: For the Hessian evaluations, the associated callback must multiply the\n * objective components of the hessian by the evalRequest.sigma value\n * given in the KN_eval_request struct or use the evalRequest.type (\n * KN_RC_EVALH_NO_F or KN_RC_EVALHV_NO_F) to omit the objective components of\n * the hessian.\n *\n * KN_del_obj_eval_callback will remove the objective term of one particular\n * callback while KN_del_obj_eval_callback_all will remove objective terms for\n * all callbacks.\n */\nint  KNITRO_API KN_del_obj_eval_callback(const KN_context_ptr kc,\n                                         const CB_context_ptr cb);\nint  KNITRO_API KN_del_obj_eval_callback_all(const KN_context_ptr kc);\n\n/** Type declaration for several non-evaluation user callbacks defined\n *  below.\n */\ntypedef int  KN_user_callback (      KN_context_ptr  kc,\n                               const double * const  x,\n                               const double * const  lambda,\n                                     void   * const  userParams);\n\n/** Set the callback function that is invoked after Knitro computes a\n *  new estimate of the solution point (i.e., after every iteration).\n *  The function should not modify any Knitro arguments.\n *  Argument \"kc\" passed to the callback from inside Knitro is the\n *  context pointer for the current problem being solved inside Knitro\n *  (either the main single-solve problem, or a subproblem when using\n *  multi-start, Tuner, etc.).\n *  Arguments \"x\" and \"lambda\" contain the latest solution estimates.\n *  Other values (such as objective, constraint, jacobian, etc.) can be\n *  queried using the corresponding KN_get_XXX_values methods.\n *  Note: Currently only active for continuous models.\n *  Return 0 if successful, a negative error code if not.\n */\nint  KNITRO_API KN_set_newpt_callback (KN_context_ptr            kc,\n                                       KN_user_callback * const  fnPtr,\n                                       void             * const  userParams);\n\n/** This callback function is for mixed integer (MIP) problems only.\n *  Set the callback function that is invoked after Knitro finishes\n *  processing a node on the branch-and-bound tree (i.e., after a relaxed\n *  subproblem solve in the branch-and-bound procedure).\n *  Argument \"kc\" passed to the callback from inside Knitro is the\n *  context pointer for the last node subproblem solved inside Knitro.\n *  The function should not modify any Knitro arguments.\n *  Arguments \"x\" and \"lambda\" contain the solution from the node solve.\n *  Return 0 if successful, a negative error code if not.\n */\nint  KNITRO_API KN_set_mip_node_callback (KN_context_ptr            kc,\n                                          KN_user_callback * const  fnPtr,\n                                          void             * const  userParams);\n\n/** This callback function is for mixed integer (MIP) problems only.\n *  Set the callback function that returns user cuts.\n *  This callback is invoked when Knitro search for cutting planes.\n *  It needs to add new cutting planes to argument \"kc\".\n *  Only linear cutting planes are supported.\n *  Arguments \"x\" and \"lambda\" contain the solution from the node solve.\n */\nint  KNITRO_API KN_set_mip_usercuts_callback (KN_context_ptr            kc,\n                                              KN_user_callback * const  fnPtr,\n                                              void             * const  userParams);\n\n/** This callback function is for mixed integer (MIP) problems only.\n *  Set the callback function that returns lazy constraints.\n *  This callback is invoked after all subproblem solves.\n *  It needs to add new (lazy) constraints to argument \"kc\".\n *  Only linear cutting planes are supported.\n *  Arguments \"x\" and \"lambda\" contain the solution from the node solve.\n */\nint  KNITRO_API KN_set_mip_lazyconstraints_callback (KN_context_ptr            kc,\n                                                     KN_user_callback * const  fnPtr,\n                                                     void             * const  userParams);\n\n/** This callback function is for multistart (MS) problems only.\n *  Set the callback function that is invoked regularly during the search.\n *  With parallelization, this callback is never called multiple times\n *  simultaneously. Argument \"kc\" passed to the callback from inside\n *  Knitro is the original context. The function should not modify any Knitro\n *  arguments. Arguments \"x\" and \"lambda\" contain the solution from the\n *  current best solve.\n *  Return 0 if successful, a negative error code if not.\n */\nint  KNITRO_API KN_set_ms_callback (KN_context_ptr            kc,\n                                    KN_user_callback * const  fnPtr,\n                                    void             * const  userParams);\n\n/** This callback function is for multistart (MS) problems only.\n *  Set the callback function that is invoked after Knitro finishes\n *  processing a multistart solve. Argument \"kc\" passed to the callback\n *  from inside Knitro is the context pointer for the last multistart\n *  subproblem solved inside Knitro.  The function should not modify any\n *  Knitro arguments.  Arguments \"x\" and \"lambda\" contain the solution from\n *  the last solve.\n *  Return 0 if successful, a negative error code if not.\n */\nint  KNITRO_API KN_set_ms_process_callback (KN_context_ptr            kc,\n                                            KN_user_callback * const  fnPtr,\n                                            void             * const  userParams);\n\n/** Type declaration for the callback that allows applications to\n *  specify an initial point before each local solve in the multistart\n *  procedure.  On input, arguments \"x\" and \"lambda\" are the randomly\n *  generated initial points determined by Knitro, which can be overwritten\n *  by the user.  The argument \"nSolveNumber\" is the number of the\n *  multistart solve.  Return 0 if successful, a negative error code if not.\n *  Use KN_set_ms_initpt_callback to set this callback function.\n */\ntypedef int  KN_ms_initpt_callback (      KN_context_ptr  kc,\n                                    const KNINT           nSolveNumber,\n                                          double * const  x,\n                                          double * const  lambda,\n                                          void   * const  userParams);\n\n/** Return 0 if successful, a negative error code if not.\n */\nint  KNITRO_API KN_set_ms_initpt_callback (KN_context_ptr                 kc,\n                                           KN_ms_initpt_callback * const  fnPtr,\n                                           void                  * const  userParams);\n\n/** Type declaration for the callback that allows applications to handle\n *  output. Applications can set a \"put string\" callback function to handle\n *  output generated by the Knitro solver.  By default Knitro prints to\n *  stdout or a file named \"knitro.log\", as determined by KN_PARAM_OUTMODE.\n *  The KN_puts function takes a \"userParams\" argument which is a pointer\n *  passed directly from KN_solve. The function should return the number of\n *  characters that were printed.\n *  Use KN_set_puts_callback to set this callback function.\n */\ntypedef int  KN_puts (const char * const  str,\n                            void * const  userParams);\n\n/**  Return 0 if successful, a negative error code if not.\n */\nint  KNITRO_API KN_set_puts_callback (KN_context_ptr   kc,\n                                      KN_puts * const  fnPtr,\n                                      void    * const  userParams);\n\n/* ----- Callback for linear system solves ----- */\n\n/** Applications may define a function for solving sparse linear systems\n *  of equations M*x=b, which need to be solved internally by Knitro.  The\n *  solution of these linear systems may be a significant cost for some\n *  algorithms (e.g. interior-point algorithms), especially for large\n *  problems.  The symmetric n-by-n coefficient matrix \"M\" for the linear system\n *  uses compressed sparse column (CSC) format and only the lower triangle\n *  plus diagonal is stored.  Row indices are not necessarily ordered within\n *  each column.  The matrix M may often have the following generic 2-by-2 block\n *  structure:\n *\n *    M = | H  A' |\n *        | A  D  |\n *\n *  where H is a n11-by-n11 symmetric matrix, A is a (n-n11)-by-n11 matrix,\n *  A' is the transpose of A, and D is a diagonal matrix of dimension (n-n11).\n *  The Knitro callback for linear system solves provides the sparse structure\n *  for the full matrix \"M\", and also provides the (1,1) block dimension n11,\n *  which can be used to access sub-blocks.\n */\n\n/** Possible linsolver phases.\n */\n#define KN_LINSOLVER_PHASE_INIT    0\n#define KN_LINSOLVER_PHASE_ANALYZE 1\n#define KN_LINSOLVER_PHASE_FACTOR  2\n#define KN_LINSOLVER_PHASE_SOLVE   3\n#define KN_LINSOLVER_PHASE_FREE    4\n\n/** Structure used to pass back information for linear system solver callbacks.\n *\n *    phase:     - indicates the linear system solve phase\n *                 (e.g., init, analyze, factor, solve, free)\n *    linsysID:  - the linear system ID associated with the request\n *                 in the current local optimization\n *    threadID:  - the thread ID associated with this request;\n *                 threadID (along with linsysID) can be used to\n *                 identify a unique linear system, which can be\n *                 useful for multi-threaded, concurrent solves\n *    n:         - dimension of M\n *    n11:       - dimension of (1,1) block H inside M; useful for\n *                 extracting submatrices H, A, and D for 2-by-2\n *                 block structure (n11=n if no block structure)\n *    rhs:       - right-hand-side values needed for \"solve\" phase only\n *    values:    - coefficient matrix values\n *    indexRows: - coefficient matrix row indices\n *    ptrCols:   - coefficient matrix column pointers;\n *                 number of nonzero elements (nnz) = ptrCols[n]\n */\ntypedef struct KN_linsolver_request {\n          int      phase;\n          int      linsysID;\n          int      threadID;\n          KNINT    n;         /* dimension of coef matrix */\n          KNINT    n11;       /* dimension of (1,1) block */\n    const double * rhs;       /* right-hand side vector (size = n) */\n    const double * values;    /* coefficient matrix values (size = nnz) */\n    const KNINT  * indexRows; /* coefficient matrix row indices (size = nnz) */\n    const KNLONG * ptrCols;   /* coefficient matrix column pointers (size = n+1) */\n} KN_linsolver_request, *KN_linsolver_request_ptr;\n\n/** Structure used to return results for linear system solver callbacks.\n *\n *    solution: - solution values (required for \"solve\" phase)\n *    negeig:   - number of negative eigenvalues (required for \"factor\" phase)\n *    poseig:   - number of positive eigenvalues (optional for \"factor\" phase)\n *    rank:     - coefficient matrix rank (optional for \"factor\" phase)\n */\ntypedef struct KN_linsolver_result {\n          double * solution;\n          KNINT    negeig;\n          KNINT    poseig;\n          KNINT    rank;\n} KN_linsolver_result, *KN_linsolver_result_ptr;\n\n/** Function prototype for linear system solve callbacks.\n *  Information/values needed for the linear system solve are provided in\n *  \"linsolverRequest\".  Solution values should be returned in \"linsolverResult\".\n *\n *  Return 0 if successful, a negative error code if not.\n *      KN_RC_CALLBACK_ERR       (use for fatal callback errors)\n *      KN_RC_LINEAR_SOLVER_ERR  (non-fatal for analyze phase;\n *                                causes Knitro to revert to one\n *                                of its own internal linear solvers)\n */\ntypedef int KN_linsolver_callback (KN_context_ptr                  kc,\n                                   KN_linsolver_request_ptr const  linsolverRequest,\n                                   KN_linsolver_result_ptr  const  linsolverResult,\n                                   void                   * const  userParams);\n\n/** This callback function is for solving linear systems inside Knitro.\n *  Return 0 if successful, a negative error code if not.\n */\nint  KNITRO_API KN_set_linsolver_callback (KN_context_ptr                 kc,\n                                           KN_linsolver_callback * const  fnPtr,\n                                           void                  * const  userParams);\n\n\n/* ----- Loading full models ----- */\n\n/** This function loads all the basic data for a linear program (LP)\n *  in a single function call.  It can only be called on a newly created\n *  Knitro problem object. After calling this function, the model may\n *  be augmented through additional Knitro API calls before solving.\n *  Returns 0 if OK, or a negative value on error.\n */\nint  KNITRO_API KN_load_lp (      KN_context_ptr  kc,\n                            const KNINT           n,\n                            const double * const  lobjCoefs,      /* size = n */\n                            const double * const  xLoBnds,        /* size = n */\n                            const double * const  xUpBnds,        /* size = n */\n                            const KNINT           m,\n                            const double * const  cLoBnds,        /* size = m */\n                            const double * const  cUpBnds,        /* size = m */\n                            const KNLONG          nnzJ,\n                            const KNINT  * const  ljacIndexCons,  /* size = nnzJ */\n                            const KNINT  * const  ljacIndexVars,  /* size = nnzJ */\n                            const double * const  ljacCoefs);     /* size = nnzJ */\n\n/** This function loads all the data for a quadratic program (QP)\n *  in a single function call.  It can only be called on a newly created\n *  Knitro problem object. After calling this function, the model may\n *  be augmented through additional Knitro API calls before solving.\n *  Returns 0 if OK, or a negative value on error.\n */\nint  KNITRO_API KN_load_qp (      KN_context_ptr  kc,\n                            const KNINT           n,\n                            const double * const  lobjCoefs,      /* size = n */\n                            const double * const  xLoBnds,        /* size = n */\n                            const double * const  xUpBnds,        /* size = n */\n                            const KNINT           m,\n                            const double * const  cLoBnds,        /* size = m */\n                            const double * const  cUpBnds,        /* size = m */\n                            const KNLONG          nnzJ,\n                            const KNINT  * const  ljacIndexCons,  /* size = nnzJ */\n                            const KNINT  * const  ljacIndexVars,  /* size = nnzJ */\n                            const double * const  ljacCoefs,      /* size = nnzJ */\n                            const KNLONG          nnzH,\n                            const KNINT  * const  qobjIndexVars1, /* size = nnzH */\n                            const KNINT  * const  qobjIndexVars2, /* size = nnzH */\n                            const double * const  qobjCoefs);     /* size = nnzH */\n\n/** This function loads all the data for a quadratically constrained\n *  quadratic program (QCQP) in a single function call. It can only\n *  be called on a newly created Knitro problem object. After calling\n *  this function, the model may be augmented through additional\n *  Knitro API calls before solving.\n *  Returns 0 if OK, or a negative value on error.\n */\nint  KNITRO_API KN_load_qcqp (      KN_context_ptr  kc,\n                              const KNINT           n,\n                              const double * const  lobjCoefs,      /* size = n */\n                              const double * const  xLoBnds,        /* size = n */\n                              const double * const  xUpBnds,        /* size = n */\n                              const KNINT           m,\n                              const double * const  cLoBnds,        /* size = m */\n                              const double * const  cUpBnds,        /* size = m */\n                              const KNLONG          nnzJ,\n                              const KNINT  * const  ljacIndexCons,  /* size = nnzJ */\n                              const KNINT  * const  ljacIndexVars,  /* size = nnzJ */\n                              const double * const  ljacCoefs,      /* size = nnzJ */\n                              const KNLONG          nnzH,\n                              const KNINT  * const  qobjIndexVars1, /* size = nnzH */\n                              const KNINT  * const  qobjIndexVars2, /* size = nnzH */\n                              const double * const  qobjCoefs,      /* size = nnzH */\n                              const KNLONG          nnzQ,\n                              const KNINT  * const  qconIndexCons,  /* size = nnzQ */\n                              const KNINT  * const  qconIndexVars1, /* size = nnzQ */\n                              const KNINT  * const  qconIndexVars2, /* size = nnzQ */\n                              const double * const  qconCoefs);     /* size = nnzQ */\n\n/* ----- Algorithmic/modeling features ----- */\n\n/** Set custom absolute feasibility tolerances to use for the\n *  termination tests.\n *  The user options KN_PARAM_FEASTOL/KN_PARAM_FEASTOLABS define\n *  a single tolerance that is applied equally to every constraint\n *  and variable.  This API function allows the user to specify\n *  separate feasibility termination tolerances for each constraint\n *  and variable.  Values specified through this function will override\n *  the value determined by KN_PARAM_FEASTOL/KN_PARAM_FEASTOLABS. The\n *  tolerances should be positive values.  If a non-positive value is\n *  specified, that constraint or variable will use the standard tolerances\n *  based on  KN_PARAM_FEASTOL/KN_PARAM_FEASTOLABS.\n *  The variables are considered to be satisfied when\n *      x[i] - xUpBnds[i] <= xFeasTols[i]  for all i=1..n, and\n *      xLoBnds[i] - x[i] <= xFeasTols[i]  for all i=1..n\n *  The regular constraints are considered to be satisfied when\n *      c[i] - cUpBnds[i] <= cFeasTols[i]  for all i=1..m, and\n *      cLoBnds[i] - c[i] <= cFeasTols[i]  for all i=1..m\n *  The complementarity constraints are considered to be satisfied when\n *      min(x1_i, x2_i) <= ccFeasTols[i]  for all i=1..ncc,\n *  where x1 and x2 are the arrays of complementary pairs.\n *  Knitro makes a local copy of all inputs, so the application\n *  may free memory after the call.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_var_feastols (      KN_context_ptr  kc,\n                                     const KNINT           nV,\n                                     const KNINT  * const  indexVars,\n                                     const double * const  xFeasTols);\nint  KNITRO_API KN_set_var_feastols_all (      KN_context_ptr  kc,\n                                         const double * const  xFeasTols);\nint  KNITRO_API KN_set_var_feastol (      KN_context_ptr  kc,\n                                    const KNINT           indexVar,\n                                    const double          xFeasTol);\n\nint  KNITRO_API KN_set_con_feastols (      KN_context_ptr  kc,\n                                     const KNINT           nC,\n                                     const KNINT  * const  indexCons,\n                                     const double * const  cFeasTols);\nint  KNITRO_API KN_set_con_feastols_all (      KN_context_ptr  kc,\n                                         const double * const  cFeasTols);\nint  KNITRO_API KN_set_con_feastol (      KN_context_ptr  kc,\n                                    const KNINT           indexCon,\n                                    const double          cFeasTol);\n\nint  KNITRO_API KN_set_compcon_feastols (      KN_context_ptr  kc,\n                                         const KNINT           nCC,\n                                         const KNINT  * const  indexCompCons,\n                                         const double * const  ccFeasTols);\nint  KNITRO_API KN_set_compcon_feastols_all (      KN_context_ptr  kc,\n                                             const double * const  ccFeasTols);\nint  KNITRO_API KN_set_compcon_feastol (      KN_context_ptr  kc,\n                                        const KNINT           indexCompCon,\n                                        const double          ccFeasTol);\n\n/** Set an array of variable scaling and centering values to\n *  perform a linear scaling\n *    x[i] = xScaleFactors[i] * xScaled[i] + xScaleCenters[i]\n *  for each variable. These scaling factors should try to\n *  represent the \"typical\" values of the \"x\" variables so that the\n *  scaled variables (\"xScaled\") used internally by Knitro are close\n *  to one.  The values for xScaleFactors should be positive.\n *  If a non-positive value is specified, that variable will not\n *  be scaled.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_var_scalings (      KN_context_ptr  kc,\n                                     const KNINT           nV,\n                                     const KNINT  * const  indexVars,\n                                     const double * const  xScaleFactors,\n                                     const double * const  xScaleCenters);\nint  KNITRO_API KN_set_var_scalings_all (      KN_context_ptr  kc,\n                                         const double * const  xScaleFactors,\n                                         const double * const  xScaleCenters);\nint  KNITRO_API KN_set_var_scaling (      KN_context_ptr  kc,\n                                    const KNINT           indexVar,\n                                    const double          xScaleFactor,\n                                    const double          xScaleCenter);\n\n/** Set an array of constraint scaling values to perform a scaling\n *    cScaled[i] = cScaleFactors[i] * c[i]\n *  for each constraint. These scaling factors should try to\n *  represent the \"typical\" values of the inverse of the constraint\n *  values \"c\" so that the scaled constraints (\"cScaled\") used\n *  internally by Knitro are close to one.  Scaling factors for\n *  standard constraints can be provided with \"cScaleFactors\", while\n *  scalings for complementarity constraints can be specified with\n *  \"ccScaleFactors\".  The values for cScaleFactors/ccScaleFactors\n *  should be positive.  If a non-positive value is specified, that\n *  constraint will use either the standard Knitro scaling\n *  (KN_SCALE_USER_INTERNAL), or no scaling (KN_SCALE_USER_NONE).\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_con_scalings (      KN_context_ptr  kc,\n                                     const KNINT           nC,\n                                     const KNINT  * const  indexCons,\n                                     const double * const  cScaleFactors);\nint  KNITRO_API KN_set_con_scalings_all (      KN_context_ptr  kc,\n                                         const double * const  cScaleFactors);\nint  KNITRO_API KN_set_con_scaling (      KN_context_ptr  kc,\n                                    const KNINT           indexCon,\n                                    const double          cScaleFactor);\n\nint  KNITRO_API KN_set_compcon_scalings (      KN_context_ptr  kc,\n                                         const KNINT           nCC,\n                                         const KNINT  * const  indexCompCons,\n                                         const double * const  ccScaleFactors);\nint  KNITRO_API KN_set_compcon_scalings_all (      KN_context_ptr  kc,\n                                             const double * const  ccScaleFactors);\nint  KNITRO_API KN_set_compcon_scaling (      KN_context_ptr  kc,\n                                        const KNINT           indexCompCons,\n                                        const double          ccScaleFactor);\n\n/** Set a scaling value for the objective function\n *    objScaled = objScaleFactor * obj\n *  This scaling factor should try to represent the \"typical\"\n *  value of the inverse of the objective function value \"obj\" so\n *  that the scaled objective (\"objScaled\") used internally by\n *  Knitro is close to one. The value for objScaleFactor\n *  should be positive.  If a non-positive value is specified, then\n *  the objective will use either the standard Knitro scaling\n *  (KN_SCALE_USER_INTERNAL), or no scaling (KN_SCALE_USER_NONE).\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_obj_scaling (      KN_context_ptr  kc,\n                                    const double          objScaleFactor);\n\n/** Set names for model components passed in by the user/modeling\n *  language so that Knitro can internally print out these names.\n *  Knitro makes a local copy of all inputs, so the application may\n *  free memory after the call.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_var_names (      KN_context_ptr  kc,\n                                  const KNINT           nV,\n                                  const KNINT * const   indexVars,\n                                  const char  * const   xNames[]);\nint  KNITRO_API KN_set_var_names_all (      KN_context_ptr  kc,\n                                      const char * const    xNames[]);\nint  KNITRO_API KN_set_var_name (      KN_context_ptr  kc,\n                                 const KNINT           indexVars,\n                                 const char  * const   xName);\n\nint  KNITRO_API KN_set_con_names (      KN_context_ptr  kc,\n                                  const KNINT           nC,\n                                  const KNINT * const   indexCons,\n                                  const char  * const   cNames[]);\nint  KNITRO_API KN_set_con_names_all (      KN_context_ptr  kc,\n                                      const char  * const   cNames[]);\nint  KNITRO_API KN_set_con_name (      KN_context_ptr  kc,\n                                 const KNINT           indexCon,\n                                 const char  * const   cName);\n\nint  KNITRO_API KN_set_compcon_names (      KN_context_ptr  kc,\n                                      const KNINT           nCC,\n                                      const KNINT * const   indexCompCons,\n                                      const char  * const   ccNames[]);\nint  KNITRO_API KN_set_compcon_names_all (      KN_context_ptr  kc,\n                                          const char  * const   ccNames[]);\nint  KNITRO_API KN_set_compcon_name (      KN_context_ptr  kc,\n                                     const int             indexCompCon,\n                                     const char  * const   ccName);\n\nint  KNITRO_API KN_set_obj_name (      KN_context_ptr  kc,\n                                 const char  * const   objName);\n\n/** Get names for model components.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_var_names (const KN_context_ptr  kc,\n                                  const KNINT           nV,\n                                  const KNINT * const   indexVars,\n                                  const KNINT           nBufferSize,\n                                        char  * const   xNames[]);\nint  KNITRO_API KN_get_var_names_all (const KN_context_ptr  kc,\n                                      const KNINT           nBufferSize,\n                                            char * const    xNames[]);\nint  KNITRO_API KN_get_var_name (const KN_context_ptr  kc,\n                                 const KNINT           indexVars,\n                                 const KNINT           nBufferSize,\n                                       char  * const   xName);\n\nint  KNITRO_API KN_get_con_names (const KN_context_ptr  kc,\n                                  const KNINT           nC,\n                                  const KNINT * const   indexCons,\n                                  const KNINT           nBufferSize,\n                                        char  * const   cNames[]);\nint  KNITRO_API KN_get_con_names_all (const KN_context_ptr  kc,\n                                      const KNINT           nBufferSize,\n                                            char * const    cNames[]);\nint  KNITRO_API KN_get_con_name (const KN_context_ptr  kc,\n                                 const KNINT           indexCons,\n                                 const KNINT           nBufferSize,\n                                       char  * const   cName);\nint  KNITRO_API KN_get_obj_name (const KN_context_ptr  kc,\n                                 const KNINT           nBufferSize,\n                                       char  * const   objName);\n\n/** This API function can be used to identify which variables\n *  should satisfy their variable bounds throughout the optimization\n *  process (KN_HONORBNDS_ALWAYS).  The user option KN_PARAM_HONORBNDS\n *  can be used to set ALL variables to honor their bounds.  This\n *  routine takes precedence over the setting of KN_PARAM_HONORBNDS\n *  and is used to customize the settings for individual variables.\n *  Knitro makes a local copy of all inputs, so the application may\n *  free memory after the call.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_var_honorbnds (      KN_context_ptr  kc,\n                                      const KNINT           nV,\n                                      const KNINT  * const  indexVars,\n                                      const int    * const  xHonorBnds);\nint  KNITRO_API KN_set_var_honorbnds_all (      KN_context_ptr  kc,\n                                          const int    * const  xHonorBnds);\nint  KNITRO_API KN_set_var_honorbnd (      KN_context_ptr  kc,\n                                     const KNINT           indexVar,\n                                     const int             xHonorBnd);\n\n/** This API function can be used to identify which constraints\n *  should satisfy their bounds throughout the optimization process.\n *  Note that this feature currently only applies to INEQUALITY\n *  constraints when using one of the barrier/interior-point algorithms.\n *  The user option KN_PARAM_BAR_FEASIBLE can be used to set ALL\n *  inequality constraints to honor their bounds (i.e. stay feasible).\n *  This routine takes precedence over the setting of KN_PARAM_BAR_FEASIBLE\n *  and is used to customize the settings for individual inequality\n *  constraints.\n *\n *  The initial point must satisfy the inequality constraints specified\n *  through this API function to a sufficient degree; if not, Knitro may\n *  generate infeasible iterates and does not enable the \"honorbnds\"\n *  procedure until a sufficiently feasible point is found. Sufficient\n *  satisfaction occurs at a point x if it is true for all specified\n *  inequalities constraints that\n *      cl + tol \\leq c(x) \\leq cu - tol\n *  The constant \"tol\" is determined by the user option bar_feasmodetol.\n *\n *  Knitro makes a local copy of all inputs, so the application may\n *  free memory after the call.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_con_honorbnds (      KN_context_ptr  kc,\n                                      const KNINT           nC,\n                                      const KNINT  * const  indexCons,\n                                      const int    * const  cHonorBnds);\nint  KNITRO_API KN_set_con_honorbnds_all (      KN_context_ptr  kc,\n                                          const int    * const  cHonorBnds);\nint  KNITRO_API KN_set_con_honorbnd (      KN_context_ptr  kc,\n                                     const KNINT           indexCon,\n                                     const int             cHonorBnd);\n\n/* ----- MIP-specific settings ----- */\n\n/** Set initial primal variables values for MIP.  This point may be used to\n *  search for an initial feasible point and may be different from the starting\n *  point for the root relaxation subproblem.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_mip_var_primal_init_values (      KN_context_ptr  kc,\n                                                   const KNINT           nV,\n                                                   const KNINT  * const  indexVars,\n                                                   const double * const  xInitVals);\nint  KNITRO_API KN_set_mip_var_primal_init_values_all (      KN_context_ptr  kc,\n                                                       const double * const  xInitVals);\nint  KNITRO_API KN_set_mip_var_primal_init_value (      KN_context_ptr  kc,\n                                                  const KNINT           indexVar,\n                                                  const double          xInitVal);\n\n/** Set the branching priorities for integer variables. Must first\n *  set the types of variables (e.g. by calling KN_set_var_types) before\n *  calling this function. Priorities must be positive numbers\n *  (variables with non-positive values are ignored).  Variables with\n *  higher priority values will be considered for branching before\n *  variables with lower priority values.  When priorities for a subset\n *  of variables are equal, the branching rule is applied as a tiebreaker.\n *  Values for continuous variables are ignored.  Knitro makes a local\n *  copy of all inputs, so the application may free memory after the call.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_mip_branching_priorities\n    (      KN_context_ptr  kc,\n     const KNINT           nV,\n     const KNINT * const   indexVars,\n     const int   * const   xPriorities);\nint  KNITRO_API KN_set_mip_branching_priorities_all\n    (      KN_context_ptr  kc,\n     const int   * const   xPriorities);\nint  KNITRO_API KN_set_mip_branching_priority\n    (      KN_context_ptr  kc,\n     const KNINT           indexVar,\n     const int             xPriority);\n\n/** Set strategies for dealing with individual integer variables. Possible\n *  strategy values include:\n *    KN_MIP_INTVAR_STRATEGY_NONE    0 (default)\n *    KN_MIP_INTVAR_STRATEGY_RELAX   1\n *    KN_MIP_INTVAR_STRATEGY_MPEC    2 (binary variables only)\n *  indexVars should be an index value corresponding to an integer variable\n *  (nothing is done if the index value corresponds to a continuous variable),\n *  and xStrategies should correspond to one of the strategy values listed above.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_set_mip_intvar_strategies\n    (      KN_context_ptr  kc,\n     const KNINT           nV,\n     const KNINT * const   indexVars,\n     const int   * const   xStrategies);\nint  KNITRO_API KN_set_mip_intvar_strategies_all\n    (      KN_context_ptr  kc,\n     const int * const     xStrategies);\nint  KNITRO_API KN_set_mip_intvar_strategy\n    (      KN_context_ptr  kc,\n     const KNINT           indexVar,\n     const int             xStrategy);\n\n/* ----- Solving ----- */\n\n/** Call Knitro to solve the problem.  The return value indicates\n *  the solution status:\n *              0: the final solution is optimal to specified tolerances;\n *   -100 to -109: a feasible solution was found (but not verified optimal);\n *   -200 to -209: Knitro terminated at an infeasible point;\n *   -300 to -301: the problem was determined to be unbounded;\n *   -400 to -409: Knitro terminated because it reached a pre-defined limit\n *                (a feasible point was found before reaching the limit);\n *   -410 to -419: Knitro terminated because it reached a pre-defined limit\n *                (no feasible point was found before reaching the limit);\n *   -500 to -599: Knitro terminated with an input error or some non-standard error.\n *  Refer to the Knitro manual section on Return Codes for more details.  All\n *  possible return code values are defined at the bottom of this file.\n */\nint  KNITRO_API KN_solve (KN_context_ptr  kc);\n\n/** Call Knitro to update the problem.\n *  If the model has been modified (e.g. via adding, changing, deleting\n *  structures), since the last solve, calling KN_update will update the\n *  internal model to incorporate all the changes since the most recent\n *  solve, but will not proceed with solving. Typically, for efficiency,\n *  the model is not actually updated with the most recent modifications\n *  until KN_solve is called, but KN_update allows for updating of the model\n *  without solving.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_update (KN_context_ptr  kc);\n\n/* ----- Reading model/solution properties ----- */\n\n/** Retrieve the number of variables \"nV\" in the model.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_number_vars (const KN_context_ptr  kc,\n                                          KNINT * const   nV);\n\n/** Retrieve the number of constraints \"nC\" in the model.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_number_cons (const KN_context_ptr  kc,\n                                          KNINT * const   nC);\n\n/** Retrieve the number of complementarity constraints \"nCC\" in the model.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_number_compcons (const KN_context_ptr  kc,\n                                              KNINT * const   nCC);\n\n/** Retrieve the number of residuals \"nR\" in the model.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_number_rsds (const KN_context_ptr  kc,\n                                          KNINT * const   nR);\n\n/** Return the number of function callback evaluations requested by KN_solve\n *  in \"numFCevals\". One evaluation count includes a single evaluation of the\n *  objective and all the constraints defined via callbacks (whether evaluated\n *  altogether in one callback or evaluated using several separate callbacks).\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_number_FC_evals (const KN_context_ptr  kc,\n                                              int * const     numFCevals);\n\n/** Return the number of gradient callback evaluations requested by KN_solve\n *  in \"numGAevals\". One evaluation count includes a single evaluation of the\n *  first derivatives of the objective and all the constraints defined via\n *  gradient callbacks (whether evaluated altogether in one callback or\n *  evaluated using several separate callbacks).\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_number_GA_evals (const KN_context_ptr  kc,\n                                              int * const     numGAevals);\n\n/** Return the number of Hessian callback evaluations requested by KN_solve\n *  in \"numHevals\". One evaluation count includes a single evaluation of all\n *  the components of the Hessian of the Lagrangian matrix defined via\n *  callbacks (whether evaluated altogether in one callback or evaluated using\n *  several separate callbacks).\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_number_H_evals (const KN_context_ptr  kc,\n                                             int * const     numHevals);\n\n/** Return the number of Hessian-vector callback evaluations requested\n *  by KN_solve in \"numHVevals\". One evaluation count includes a single\n *  evaluation of the product of the Hessian of the Lagrangian matrix with a\n *  vector submitted by Knitro (whether evaluated altogether in one callback\n *  or evaluated using several separate callbacks).\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_number_HV_evals (const KN_context_ptr  kc,\n                                              int * const     numHVevals);\n\n/** Retrieve the Knitro solve time either as CPU time or real time.\n */\nint  KNITRO_API KN_get_solve_time_cpu(const KN_context_ptr  kc,\n                                            double * const  time);\nint  KNITRO_API KN_get_solve_time_real(const KN_context_ptr  kc,\n                                             double * const  time);\n\n/** Return the solution status, objective, primal and dual variables.\n *  The status and objective value scalars are returned as pointers\n *  that need to be de-referenced to get their values.  The arrays\n *  \"x\" and \"lambda\" must be allocated by the user.\n *  Returns 0 if call is successful;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_solution (const KN_context_ptr  kc,\n                                       int    * const  status,\n                                       double * const  obj,\n                                       double * const  x,\n                                       double * const  lambda);\n\n/** Return the objective, primal and dual variables, and constraint\n *  values for the best feasible iterate encountered throughout the\n *  optimization (i.e. the feasible iterate with the best objective\n *  value).  The (absolute) feasibility error computed at this point\n *  is also returned.  This point may not always correspond to the\n *  default final solution returned by Knitro. If no feasible point was\n *  found, then the least infeasible point found is returned.\n *  The \"feasError\" and \"obj\" value scalars are returned as pointers\n *  that need to be de-referenced to get their values.  The arrays\n *  \"x\", \"lambda\", and \"c\" must be allocated by the user.\n *  Returns 0 if feasible point found and call is successful;\n *          1 if no feasible point was found;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_best_feasible_iterate (const KN_context_ptr  kc,\n                                                    double * const  feasError,\n                                                    double * const  obj,\n                                                    double * const  x,\n                                                    double * const  lambda,\n                                                    double * const  c);\n\n/** Return the value of the objective obj(x) in \"obj\".\n *  Returns 0 if call is successful;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_obj_value (const KN_context_ptr  kc,\n                                        double * const  obj);\n\n/** Return the type (e.g. KN_OBJTYPE_GENERAL, KN_OBJTYPE_LINEAR,\n *  KN_OBJTYPE_QUADRATIC, etc.) of the objective obj(x) in \"objType\".\n *  Returns 0 if call is successful;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_obj_type (const KN_context_ptr  kc,\n                                       int    * const  objType);\n\n/** Return the primal (\"x\") or dual (\"lambda\") variables.\n *  Returns 0 if call is successful;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_var_primal_values (const KN_context_ptr  kc,\n                                          const KNINT           nV,\n                                          const KNINT  * const  indexVars,\n                                                double * const  x);\nint  KNITRO_API KN_get_var_primal_values_all (const KN_context_ptr  kc,\n                                                    double * const  x);\nint  KNITRO_API KN_get_var_primal_value (const KN_context_ptr  kc,\n                                         const KNINT           indexVar,\n                                               double * const  x);\n\nint  KNITRO_API KN_get_var_dual_values (const KN_context_ptr  kc,\n                                        const KNINT           nV,\n                                        const KNINT  * const  indexVars,\n                                              double * const  lambda);\nint  KNITRO_API KN_get_var_dual_values_all (const KN_context_ptr  kc,\n                                                double * const  lambda);\nint  KNITRO_API KN_get_var_dual_value (const KN_context_ptr  kc,\n                                       const KNINT           indexVar,\n                                             double * const  lambda);\n\nint  KNITRO_API KN_get_con_dual_values (const KN_context_ptr  kc,\n                                        const KNINT           nC,\n                                        const KNINT  * const  indexCons,\n                                              double * const  lambda);\nint  KNITRO_API KN_get_con_dual_values_all (const KN_context_ptr  kc,\n                                                  double * const  lambda);\nint  KNITRO_API KN_get_con_dual_value (const KN_context_ptr  kc,\n                                       const KNINT           indexCons,\n                                             double * const  lambda);\n\n/** Return the values of the constraint vector c(x) in \"c\".\n *  The array \"c\" must be allocated by the user.\n *  Returns 0 if call is successful;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_con_values (const KN_context_ptr  kc,\n                                   const KNINT           nC,\n                                   const KNINT  * const  indexCons,\n                                         double * const  c);\nint  KNITRO_API KN_get_con_values_all (const KN_context_ptr  kc,\n                                             double * const  c);\nint  KNITRO_API KN_get_con_value (const KN_context_ptr  kc,\n                                  const KNINT           indexCon,\n                                        double * const  c);\n\n/** Return the types (e.g. KN_CONTYPE_GENERAL, KN_CONTYPE_LINEAR,\n *  KN_CONTYPE_QUADRATIC, etc.) of the constraint vector c(x) in \"cTypes\".\n *  The array \"cTypes\" must be allocated by the user.\n *  Returns 0 if call is successful;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_con_types (const KN_context_ptr  kc,\n                                  const KNINT           nC,\n                                  const KNINT  * const  indexCons,\n                                        int    * const  cTypes);\nint  KNITRO_API KN_get_con_types_all (const KN_context_ptr  kc,\n                                            int    * const  cTypes);\nint  KNITRO_API KN_get_con_type (const KN_context_ptr  kc,\n                                 const KNINT           indexCon,\n                                       int    * const  cType);\n\n/** Return the values of the residual vector r(x) in \"r\".\n *  The array \"r\" must be allocated by the user.\n *  Returns 0 if call is successful;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_rsd_values (const KN_context_ptr  kc,\n                                   const KNINT           nR,\n                                   const KNINT  * const  indexRsds,\n                                         double * const  r);\nint  KNITRO_API KN_get_rsd_values_all (const KN_context_ptr  kc,\n                                             double * const  r);\nint  KNITRO_API KN_get_rsd_value (const KN_context_ptr  kc,\n                                  const KNINT           indexRsd,\n                                        double * const  r);\n\n/** Return information about the feasibility of the variables x after\n *  solving.\n *\n *  The integer array \"bndInfeas\" indicates whether or not the variable\n *  was deemed to be infeasible with respect to its bounds by the Knitro\n *  termination test.\n *  Possible values of \"bndInfeas\" are:\n *     -1: The variable is considered infeasible with respect to\n *         its lower bound (or is less than its fixed value if fixed).\n *      0: The variable is considered feasible with respect to the\n *         feasibility tolerances.\n *      1: The variable is considered infeasible with respect to\n *         its upper bound (or is greater than its fixed value if fixed).\n *  Note that even if the variable is deemed feasible it may still have a\n *  non-zero violation returned in \"viols\" since the feasibility\n *  tolerances allow for small violations.\n *\n *  The integer array \"intInfeas\" indicates whether or not an integer\n *  variable was deemed to be infeasible with respect to integrality.\n *  Possible values of \"intInfeas\" are:\n *     -1: The integer variable is considered infeasible with respect to\n *         the integrality tolerance and is closer to its floor.\n *      0: The integer variable is considered feasible with respect to\n *         the integrality tolerance (or the variable is continuous).\n *      1: The integer variable is considered infeasible with respect to\n *         the integrality tolerance and is closer to its ceiling.\n *\n *  The non-negative array \"viols\" returns the amount by which the\n *  variable violates its lower or upper bound.  If the variable is an\n *  integer variable that satisfies its lower and upper bounds, \"viols\"\n *  returns the integrality error (i.e. the distance to the nearest\n *  integer value inside its bounds).\n *\n *  The arrays \"bndInfeas\", \"intInfeas\" and \"viols\" must be allocated by\n *  the user to retrieve these values.  Any of these arrays set to NULL\n *  will not be returned.\n *\n *  Returns 0 if call is successful;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_var_viols (const KN_context_ptr  kc,\n                                  const KNINT           nV,\n                                  const KNINT  * const  indexVars,\n                                        KNINT  * const  bndInfeas,\n                                        KNINT  * const  intInfeas,\n                                        double * const  viols);\nint  KNITRO_API KN_get_var_viols_all (const KN_context_ptr  kc,\n                                            KNINT  * const  bndInfeas,\n                                            KNINT  * const  intInfeas,\n                                            double * const  viols);\nint  KNITRO_API KN_get_var_viol (const KN_context_ptr  kc,\n                                 const KNINT           indexVar,\n                                       KNINT  * const  bndInfeas,\n                                       KNINT  * const  intInfeas,\n                                       double * const  viol);\n\n/** Return information about the feasibility of the constraints c(x)\n *  after solving.\n *\n *  The integer array \"infeas\" indicates whether or not the constraint\n *  was deemed to be infeasible by the Knitro termination test.\n *  Possible values of \"infeas\" are:\n *     -1: The constraint is considered infeasible with respect to\n *         its lower bound (or is less than the right-hand side if\n *         it is an equality).\n *      0: The constraint is considered feasible with respect to the\n *         feasibility tolerances.\n *      1: The constraint is considered infeasible with respect to\n *         its upper bound (or is greater than the right-hand side if\n *         it is an equality).\n *  Note that even if the constraint is deemed feasible it may still\n *  have a non-zero violation returned in \"viols\" since the feasibility\n *  tolerances allow for small violations.\n *\n *  The non-negative array \"viols\" returns the amount by which the\n *  constraint violates its lower or upper bound.\n *\n *  The arrays \"infeas\" and \"viols\" must be allocated by the user to\n *  retrieve these values.  Any of these arrays set to NULL will not be\n *  returned.\n *\n *  Returns 0 if call is successful;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_con_viols (const KN_context_ptr  kc,\n                                  const KNINT           nC,\n                                  const KNINT  * const  indexCons,\n                                        KNINT  * const  infeas,\n                                        double * const  viols);\nint  KNITRO_API KN_get_con_viols_all (const KN_context_ptr  kc,\n                                            KNINT  * const  infeas,\n                                            double * const  viols);\nint  KNITRO_API KN_get_con_viol (const KN_context_ptr  kc,\n                                 const KNINT           indexCon,\n                                       KNINT  * const  infeas,\n                                       double * const  viol);\n\n/** Return information about any errors detected by the Knitro presolver.\n *  Parameters have the following values.\n *\n *  component: The component involved in the error\n *             (e.g., KN_COMPONENT_VAR, KN_COMPONENT_OBJ\n *             KN_COMPONENT_CON, KN_COMPONENT_RSD).\n *             Return value of 0 if no error.\n *\n *  index: The component index involved in the error (is set to -1 if no\n *         error).\n *\n *  error: Return code associated with the error\n *         (e.g., KN_RC_INFEAS_VAR_BOUNDS, KN_RC_INFEAS_CON_BOUNDS,\n *         KN_RC_UNBOUNDED_OR_INFEAS).  Return value of 0 if no error.\n *\n *  viol: If there was an infeasibility error, it returns the\n *        amount of infeasibility deduced by the presolve for the\n *        given component (otherwise is set to 0).\n *\n *  Returns 0 if no presolve errors were detected;\n *          1 if an error was detected in the presolve phase;\n *         <0 if there is an error in the function call.\n */\nint  KNITRO_API KN_get_presolve_error (const KN_context_ptr  kc,\n                                             KNINT  * const  component,\n                                             KNINT  * const  index,\n                                             KNINT  * const  error,\n                                             double * const  viol);\n\n/* ----- Solution properties for continuous problems only ----- */\n\n/** Return the number of iterations made by KN_solve in \"numIters\".\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_number_iters (const KN_context_ptr  kc,\n                                           int * const     numIters);\n\n/** Return the number of conjugate gradient (CG) iterations made by\n *  KN_solve in \"numCGiters\".\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_number_cg_iters (const KN_context_ptr  kc,\n                                              int * const     numCGiters);\n\n/** Return the absolute feasibility error at the solution in \"absFeasError\".\n *  Refer to the Knitro manual section on Termination Tests for a\n *  detailed definition of this quantity.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_abs_feas_error (const KN_context_ptr  kc,\n                                             double * const  absFeasError);\n\n/** Return the relative feasibility error at the solution in \"relFeasError\".\n *  Refer to the Knitro manual section on Termination Tests for a\n *  detailed definition of this quantity.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_rel_feas_error (const KN_context_ptr  kc,\n                                             double * const  relFeasError);\n\n/** Return the absolute optimality error at the solution in \"absOptError\".\n *  Refer to the Knitro manual section on Termination Tests for a\n *  detailed definition of this quantity.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_abs_opt_error (const KN_context_ptr  kc,\n                                            double * const  absOptError);\n\n/** Return the relative optimality error at the solution in \"relOptError\".\n *  Refer to the Knitro manual section on Termination Tests for a\n *  detailed definition of this quantity.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_rel_opt_error (const KN_context_ptr  kc,\n                                            double * const  relOptError);\n\n/** Return the values of the objective gradient vector in \"indexVars\"\n *  and \"objGrad\".  The objective gradient values returned correspond\n *  to the non-zero sparse objective gradient indices provided by the user.\n *  The arrays \"indexVars\" and \"objGrad\" must be allocated by the user.\n *  The size of these arrays is obtained by first calling\n *  \"KN_get_objgrad_nnz()\".\n *  Returns 0 if call is successful;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_objgrad_nnz  (const KN_context_ptr  kc,\n                                           KNINT  * const  nnz);\nint  KNITRO_API KN_get_objgrad_values (const KN_context_ptr  kc,\n                                             KNINT  * const  indexVars,\n                                             double * const  objGrad);\n/** Return the values of the full (dense) objective gradient in \"objGrad\".\n *  The array \"objGrad\" must be allocated by the user (the size is equal\n *  to the total number of variables in the problem).\n *  Returns 0 if call is successful;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_objgrad_values_all (const KN_context_ptr  kc,\n                                                 double * const  objGrad);\n\n/** Return the values of the constraint Jacobian in \"indexCons\", \"indexVars\",\n *  and \"jac\".  The Jacobian values returned correspond to the non-zero\n *  sparse Jacobian indices provided by the user.\n *  The arrays \"indexCons\", \"indexVars\", and \"jac\" must be allocated by\n *  the user.  The size of these arrays is obtained by first calling\n *  \"KN_get_jacobian_nnz()\".\n *\n *  Use \"KN_get_jacobian_nnz_one()\" / \"KN_get_jacobian_values_one()\" to\n *  get the gradient/Jacobian values corresponding to just one constraint.\n *\n *  Returns 0 if call is successful;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_jacobian_nnz    (const KN_context_ptr  kc,\n                                              KNLONG * const  nnz);\nint  KNITRO_API KN_get_jacobian_values (const KN_context_ptr  kc,\n                                              KNINT  * const  indexCons,\n                                              KNINT  * const  indexVars,\n                                              double * const  jac);\nint  KNITRO_API KN_get_jacobian_nnz_one    (const KN_context_ptr  kc,\n                                                  KNINT           indexCon,\n                                                  KNINT * const   nnz);\nint  KNITRO_API KN_get_jacobian_values_one (const KN_context_ptr  kc,\n                                                  KNINT           indexCon,\n                                                  KNINT  * const  indexVars,\n                                                  double * const  jac);\n\n/** Return the values of the residual Jacobian in \"indexRsds\", \"indexVars\",\n *  and \"rsdJac\".  The Jacobian values returned correspond to the non-zero\n *  sparse Jacobian indices provided by the user.\n *  The arrays \"indexRsds\", \"indexVars\" and \"rsdJac\" must be allocated\n *  by the user.  The size of these arrays is obtained by first calling\n *  \"KN_get_rsd_jacobian_nnz()\".\n *  Returns 0 if call is successful;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_rsd_jacobian_nnz    (const KN_context_ptr  kc,\n                                                  KNLONG * const  nnz);\nint  KNITRO_API KN_get_rsd_jacobian_values (const KN_context_ptr  kc,\n                                                  KNINT  * const  indexRsds,\n                                                  KNINT  * const  indexVars,\n                                                  double * const  rsdJac);\n\n/** Return the values of the Hessian (or possibly Hessian\n *  approximation) in \"hess\".  This routine is currently only valid\n *  if one of the following cases holds:\n *  1) KN_HESSOPT_EXACT (presolver on or off), or;\n *  2) KN_HESSOPT_BFGS or KN_HESSOPT_SR1, but only with the\n *     Knitro presolver off (i.e. KN_PRESOLVE_NONE).\n *  3) Solving a least squares model with the Gauss-Newton Hessian\n *     and the Gauss-Newton Hessian is explicitly computed and\n *     stored in Knitro.\n *\n *  In all other cases, either Knitro does not have an internal\n *  representation of the Hessian (or Hessian approximation),\n *  or the internal Hessian approximation corresponds only to\n *  the presolved problem form and may not be valid for the\n *  original problem form.  In these cases \"indexVars1\", \"indexVars2\",\n *  and \"hess\" are left unmodified, and the routine has return code 1.\n *\n *  Note that in case 2 above (KN_HESSOPT_BFGS or KN_HESSOPT_SR1)\n *  the values returned in \"hess\" are the upper triangular values\n *  of the dense quasi-Newton Hessian approximation stored row-wise.\n *  There are ((n*n - n)/2 + n) such values (where \"n\" is the number\n *  of variables in the problem. These values may be quite different\n *  from the values of the exact Hessian.\n *\n *  When KN_HESSOPT_EXACT (case 1 above) the Hessian values\n *  returned correspond to the non-zero sparse Hessian indices\n *  provided by the user.\n *\n *  The arrays \"indexVars1\", \"indexVars2\" and \"hess\" must be allocated\n *  by the user.  The size of these arrays is obtained by first calling\n *  \"KN_get_hessian_nnz()\".\n *  Returns 0 if call is successful;\n *          1 if \"hess\" was not set because Knitro does not\n *            have a valid Hessian for the model stored.\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_hessian_nnz    (const KN_context_ptr  kc,\n                                             KNLONG * const  nnz);\nint  KNITRO_API KN_get_hessian_values (const KN_context_ptr  kc,\n                                             KNINT  * const  indexVars1,\n                                             KNINT  * const  indexVars2,\n                                             double * const  hess);\n\n\n/* ----- Solution properties for MIP problems only ----- */\n\n/** Return the number of nodes processed in the MIP solve\n *  in \"numNodes\".\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_mip_number_nodes (const KN_context_ptr  kc,\n                                               int * const     numNodes);\n\n/** Return the number of continuous subproblems processed in the\n *  MIP solve in \"numSolves\".\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_mip_number_solves (const KN_context_ptr  kc,\n                                                int * const     numSolves);\n\n/** Return the final absolute optimality gap in the MIP solve\n *  in \"absGap\". Refer to the Knitro manual section on Termination\n *  Tests for a detailed definition of this quantity. Set to\n *  KN_INFINITY if no incumbent (i.e., integer feasible) point found.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_mip_abs_gap (const KN_context_ptr  kc,\n                                          double * const  absGap);\n\n/** Return the final absolute optimality gap in the MIP solve\n *  int \"relGap\". Refer to the Knitro manual section on Termination\n *  Tests for a detailed definition of this quantity.  Set to\n *  KN_INFINITY if no incumbent (i.e., integer feasible) point found.\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_mip_rel_gap (const KN_context_ptr  kc,\n                                          double * const  relGap);\n\n/** Return the objective value of the MIP incumbent solution in\n *  \"incumbentObj\". Set to KN_INFINITY if no incumbent (i.e., integer\n *  feasible) point found.\n *  Returns 0 if incumbent solution exists and call is successful;\n *          1 if no incumbent (i.e., integer feasible) exists;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_mip_incumbent_obj (const KN_context_ptr  kc,\n                                                double * const  incumbentObj);\n\n/** Return the value of the current MIP relaxation bound in \"relaxBound\".\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_mip_relaxation_bnd (const KN_context_ptr  kc,\n                                                 double * const relaxBound);\n\n/** Return the objective value of the most recently solved MIP\n *  node subproblem in \"lastNodeObj\".\n *  Returns 0 if OK, nonzero if error.\n */\nint  KNITRO_API KN_get_mip_lastnode_obj (const KN_context_ptr  kc,\n                                               double * const lastNodeObj);\n\n/** Return the MIP incumbent solution in \"x\" if one exists.\n *  Returns 0 if incumbent solution exists and call is successful;\n *          1 if no incumbent (i.e., integer feasible) point exists\n *              and leaves \"x\" unmodified;\n *         <0 if there is an error.\n */\nint  KNITRO_API KN_get_mip_incumbent_x (const KN_context_ptr  kc,\n                                              double * const  x);\n\n\n/*------------------------------------------------------------------*/\n/*     DEFINES                                                      */\n/*------------------------------------------------------------------*/\n\n/** Use KN_INFINITY to set infinite variable and constraint bounds\n *  in Knitro.\n */\n#define KN_INFINITY DBL_MAX\n\n/** Possible parameter types.\n */\n#define KN_PARAMTYPE_INTEGER 0\n#define KN_PARAMTYPE_FLOAT   1\n#define KN_PARAMTYPE_STRING  2\n\n/** Possible model components.\n */\n#define KN_COMPONENT_VAR     1\n#define KN_COMPONENT_OBJ     2\n#define KN_COMPONENT_CON     3\n#define KN_COMPONENT_RSD     4\n\n/** Possible objective goals for the solver (objGoal in KN_set_obj_goal).\n */\n#define KN_OBJGOAL_MINIMIZE    0\n#define KN_OBJGOAL_MAXIMIZE    1\n\n/** Possible values for the objective type.\n */\n#define KN_OBJTYPE_CONSTANT  -1\n#define KN_OBJTYPE_GENERAL    0\n#define KN_OBJTYPE_LINEAR     1\n#define KN_OBJTYPE_QUADRATIC  2\n\n/** Possible values for the constraint type.\n */\n#define KN_CONTYPE_CONSTANT  -1\n#define KN_CONTYPE_GENERAL    0\n#define KN_CONTYPE_LINEAR     1\n#define KN_CONTYPE_QUADRATIC  2\n#define KN_CONTYPE_CONIC      3\n\n/** Possible values for the residual type.\n */\n#define KN_RSDTYPE_CONSTANT  -1\n#define KN_RSDTYPE_GENERAL    0\n#define KN_RSDTYPE_LINEAR     1\n\n/** Possible values for the complementarity constraint type\n *  (ccTypes in KN_set_compcons).  Currently only KN_CCTYPE_VARVAR\n *  is supported.\n */\n#define KN_CCTYPE_VARVAR      0\n#define KN_CCTYPE_VARCON      1 /* NOT SUPPORTED YET */\n#define KN_CCTYPE_CONCON      2 /* NOT SUPPORTED YET */\n\n/** Possible values for the variable type (xTypes in KN_set_var_types).\n */\n#define KN_VARTYPE_CONTINUOUS  0\n#define KN_VARTYPE_INTEGER     1\n#define KN_VARTYPE_BINARY      2\n\n/** Possible values for enabling bits to set variable properties\n *  via KN_set_var_properties().\n */\n#define KN_VAR_LINEAR                   1 /*-- LINEAR ONLY EVERYWHERE */\n\n/** Possible values for bit flags used to set objective and\n *  constraint function properties via KN_set_obj_properties()\n *  and KN_set_con_properties().\n */\n#define KN_OBJ_CONVEX                   1 /*-- CONVEX OBJECTIVE */\n#define KN_OBJ_CONCAVE                  2 /*-- CONCAVE OBJECTIVE */\n#define KN_OBJ_CONTINUOUS               4 /*-- OBJECTIVE IS CONTINUOUS */\n#define KN_OBJ_DIFFERENTIABLE           8 /*-- (ONCE) DIFFERENTIABLE OBJECTIVE */\n#define KN_OBJ_TWICE_DIFFERENTIABLE    16 /*-- TWICE DIFFERENTIABLE OBJECTIVE */\n#define KN_OBJ_NOISY                   32 /*-- OBJECTIVE FUNCTION IS NOISY */\n#define KN_OBJ_NONDETERMINISTIC        64 /*-- OBJECTIVE IS NONDETERMINISTIC */\n\n#define KN_CON_CONVEX                   1 /*-- CONVEX CONSTRAINT */\n#define KN_CON_CONCAVE                  2 /*-- CONCAVE CONSTRAINT */\n#define KN_CON_CONTINUOUS               4 /*-- CONSTRAINT IS CONTINUOUS */\n#define KN_CON_DIFFERENTIABLE           8 /*-- (ONCE) DIFFERENTIABLE CONSTRAINT */\n#define KN_CON_TWICE_DIFFERENTIABLE    16 /*-- TWICE DIFFERENTIABLE CONSTRAINT */\n#define KN_CON_NOISY                   32 /*-- CONSTRAINT FUNCTION IS NOISY */\n#define KN_CON_NONDETERMINISTIC        64 /*-- CONSTRAINT IS NONDETERMINISTIC */\n\n/** Possible values for dense arrays or matrices.\n */\n#define KN_DENSE             -1 /*-- GENERIC DENSE (e.g. FOR ARRAYS) */\n#define KN_DENSE_ROWMAJOR    -2 /*-- DENSE MATRIX IN ROW MAJOR ORDER  */\n#define KN_DENSE_COLMAJOR    -3 /*-- DENSE MATRIX IN COLUMN MAJOR ORDER  */\n\n/** Evaluation request codes\n */\n#define KN_RC_EVALFC          1  /*-- OBJECTIVE AND CONSTRAINT FUNCTIONS */\n#define KN_RC_EVALGA          2  /*-- OBJ. GRADIENT AND CONSTRAINT JACOBIAN */\n#define KN_RC_EVALH           3  /*-- HESSIAN OF THE LAGRANGIAN */\n#define KN_RC_EVALHV          7  /*-- HESSIAN-VECTOR PRODUCT */\n#define KN_RC_EVALH_NO_F      8  /*-- NO OBJECTIVE COMPONENT INCLUDED */\n#define KN_RC_EVALHV_NO_F     9  /*-- NO OBJECTIVE COMPONENT INCLUDED */\n#define KN_RC_EVALR          10  /*-- RESIDUAL FUNCTIONS (LEAST SQUARES) */\n#define KN_RC_EVALRJ         11  /*-- RESIDUAL JACOBIAN (LEAST SQUARES) */\n#define KN_RC_EVALFCGA       12  /*-- BOTH FUNCTIONS AND GRADIENTS  */\n\n/** Return codes when Knitro terminates.\n */\n#define KN_RC_OPTIMAL_OR_SATISFACTORY 0   /*-- OPTIMAL CODE */\n#define KN_RC_OPTIMAL                 0\n#define KN_RC_NEAR_OPT               -100 /*-- FEASIBLE CODES */\n#define KN_RC_FEAS_XTOL              -101\n#define KN_RC_FEAS_NO_IMPROVE        -102\n#define KN_RC_FEAS_FTOL              -103\n#define KN_RC_FEAS_BEST              -104\n#define KN_RC_FEAS_MULTISTART        -105\n#define KN_RC_INFEASIBLE             -200 /*-- INFEASIBLE CODES */\n#define KN_RC_INFEAS_XTOL            -201\n#define KN_RC_INFEAS_NO_IMPROVE      -202\n#define KN_RC_INFEAS_MULTISTART      -203\n#define KN_RC_INFEAS_CON_BOUNDS      -204\n#define KN_RC_INFEAS_VAR_BOUNDS      -205\n#define KN_RC_UNBOUNDED              -300 /*-- UNBOUNDED CODES */\n#define KN_RC_UNBOUNDED_OR_INFEAS    -301\n#define KN_RC_ITER_LIMIT_FEAS        -400 /*-- LIMIT EXCEEDED CODES (FEASIBLE) */\n#define KN_RC_TIME_LIMIT_FEAS        -401\n#define KN_RC_FEVAL_LIMIT_FEAS       -402\n#define KN_RC_MIP_EXH_FEAS           -403\n#define KN_RC_MIP_TERM_FEAS          -404\n#define KN_RC_MIP_SOLVE_LIMIT_FEAS   -405\n#define KN_RC_MIP_NODE_LIMIT_FEAS    -406\n#define KN_RC_ITER_LIMIT_INFEAS      -410 /*-- LIMIT EXCEEDED CODES (INFEASIBLE) */\n#define KN_RC_TIME_LIMIT_INFEAS      -411\n#define KN_RC_FEVAL_LIMIT_INFEAS     -412\n#define KN_RC_MIP_EXH_INFEAS         -413\n#define KN_RC_MIP_SOLVE_LIMIT_INFEAS -415\n#define KN_RC_MIP_NODE_LIMIT_INFEAS  -416\n#define KN_RC_CALLBACK_ERR           -500 /*-- OTHER FAILURES */\n#define KN_RC_LP_SOLVER_ERR          -501\n#define KN_RC_EVAL_ERR               -502\n#define KN_RC_OUT_OF_MEMORY          -503\n#define KN_RC_USER_TERMINATION       -504\n#define KN_RC_OPEN_FILE_ERR          -505\n#define KN_RC_BAD_N_OR_F             -506 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_BAD_CONSTRAINT         -507 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_BAD_JACOBIAN           -508 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_BAD_HESSIAN            -509 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_BAD_CON_INDEX          -510 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_BAD_JAC_INDEX          -511 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_BAD_HESS_INDEX         -512 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_BAD_CON_BOUNDS         -513 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_BAD_VAR_BOUNDS         -514 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_ILLEGAL_CALL           -515 /*-- KNITRO CALL IS OUT OF SEQUENCE */\n#define KN_RC_BAD_KCPTR              -516 /*-- KNITRO PASSED A BAD KC POINTER */\n#define KN_RC_NULL_POINTER           -517 /*-- KNITRO PASSED A NULL ARGUMENT */\n#define KN_RC_BAD_INIT_VALUE         -518 /*-- APPLICATION INITIAL POINT IS BAD */\n#define KN_RC_LICENSE_ERROR          -520 /*-- LICENSE CHECK FAILED */\n#define KN_RC_BAD_PARAMINPUT         -521 /*-- INVALID PARAMETER INPUT DETECTED */\n#define KN_RC_LINEAR_SOLVER_ERR      -522 /*-- ERROR IN LINEAR SOLVER */\n#define KN_RC_DERIV_CHECK_FAILED     -523 /*-- DERIVATIVE CHECK FAILED */\n#define KN_RC_DERIV_CHECK_TERMINATE  -524 /*-- DERIVATIVE CHECK TERMINATE */\n#define KN_RC_OVERFLOW_ERR           -525 /*-- INTEGER OVERFLOW ERROR */\n#define KN_RC_BAD_SIZE               -526 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_BAD_VARIABLE           -527 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_BAD_VAR_INDEX          -528 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_BAD_OBJECTIVE          -529 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_BAD_OBJ_INDEX          -530 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_BAD_RESIDUAL           -531 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_BAD_RSD_INDEX          -532 /*-- PROBLEM DEFINITION ERROR */\n#define KN_RC_INTERNAL_ERROR         -600 /*-- CONTACT ARTELYS SUPPORT */\n\n/** Parameter IDs used in functions KN_get_xxx_param and KN_set_xxx_param.\n *  In some cases, parameter values are defined underneath the parameter ID.\n */\n#define KN_PARAM_NEWPOINT             1001\n#  define KN_NEWPOINT_NONE               0\n#  define KN_NEWPOINT_SAVEONE            1\n#  define KN_NEWPOINT_SAVEALL            2\n#define KN_PARAM_HONORBNDS            1002\n#  define KN_HONORBNDS_AUTO             -1\n#  define KN_HONORBNDS_NO                0\n#  define KN_HONORBNDS_ALWAYS            1\n#  define KN_HONORBNDS_INITPT            2\n#define KN_PARAM_NLP_ALGORITHM        1003\n#  define KN_NLP_ALG_AUTOMATIC           0\n#  define KN_NLP_ALG_AUTO                0\n#  define KN_NLP_ALG_BAR_DIRECT          1\n#  define KN_NLP_ALG_BAR_CG              2\n#  define KN_NLP_ALG_ACT_CG              3\n#  define KN_NLP_ALG_ACT_SQP             4\n#  define KN_NLP_ALG_MULTI               5\n#  define KN_NLP_ALG_AL                  6\n#define KN_PARAM_ALGORITHM            1003 /** PRE-15.0 OPTION NAME */\n#define KN_PARAM_ALG                  1003\n#  define KN_ALG_AUTOMATIC               0\n#  define KN_ALG_AUTO                    0\n#  define KN_ALG_BAR_DIRECT              1\n#  define KN_ALG_BAR_CG                  2\n#  define KN_ALG_ACT_CG                  3\n#  define KN_ALG_ACT_SQP                 4\n#  define KN_ALG_MULTI                   5\n#  define KN_ALG_AL                      6\n#define KN_PARAM_BAR_MURULE           1004\n#  define KN_BAR_MURULE_AUTOMATIC        0\n#  define KN_BAR_MURULE_AUTO             0\n#  define KN_BAR_MURULE_MONOTONE         1\n#  define KN_BAR_MURULE_ADAPTIVE         2\n#  define KN_BAR_MURULE_PROBING          3\n#  define KN_BAR_MURULE_DAMPMPC          4\n#  define KN_BAR_MURULE_FULLMPC          5\n#  define KN_BAR_MURULE_QUALITY          6\n#define KN_PARAM_BAR_FEASIBLE         1006\n#  define KN_BAR_FEASIBLE_NO             0\n#  define KN_BAR_FEASIBLE_STAY           1\n#  define KN_BAR_FEASIBLE_GET            2\n#  define KN_BAR_FEASIBLE_GET_STAY       3\n#define KN_PARAM_GRADOPT              1007\n#  define KN_GRADOPT_EXACT               1\n#  define KN_GRADOPT_FORWARD             2\n#  define KN_GRADOPT_CENTRAL             3\n#  define KN_GRADOPT_USER_FORWARD        4\n#  define KN_GRADOPT_USER_CENTRAL        5\n#define KN_PARAM_HESSOPT              1008\n#  define KN_HESSOPT_AUTO                0\n#  define KN_HESSOPT_EXACT               1\n#  define KN_HESSOPT_BFGS                2\n#  define KN_HESSOPT_SR1                 3\n#  define KN_HESSOPT_PRODUCT_FINDIFF     4\n#  define KN_HESSOPT_PRODUCT             5\n#  define KN_HESSOPT_LBFGS               6\n#  define KN_HESSOPT_GAUSS_NEWTON        7\n#define KN_PARAM_BAR_INITPT           1009\n#  define KN_BAR_INITPT_AUTO             0\n#  define KN_BAR_INITPT_CONVEX           1\n#  define KN_BAR_INITPT_NEARBND          2\n#  define KN_BAR_INITPT_CENTRAL          3\n#define KN_PARAM_ACT_LPSOLVER         1012\n#  define KN_ACT_LPSOLVER_INTERNAL       1\n#  define KN_ACT_LPSOLVER_CPLEX          2\n#  define KN_ACT_LPSOLVER_XPRESS         3\n#define KN_PARAM_CG_MAXIT             1013\n#define KN_PARAM_MAXIT                1014\n#define KN_PARAM_OUTLEV               1015\n#  define KN_OUTLEV_NONE                 0\n#  define KN_OUTLEV_SUMMARY              1\n#  define KN_OUTLEV_ITER_10              2\n#  define KN_OUTLEV_ITER                 3\n#  define KN_OUTLEV_ITER_VERBOSE         4\n#  define KN_OUTLEV_ITER_X               5\n#  define KN_OUTLEV_ALL                  6\n#define KN_PARAM_OUTMODE              1016\n#  define KN_OUTMODE_SCREEN              0\n#  define KN_OUTMODE_FILE                1\n#  define KN_OUTMODE_BOTH                2\n#define KN_PARAM_SCALE                1017\n#  define KN_SCALE_NEVER                 0\n#  define KN_SCALE_NO                    0\n#  define KN_SCALE_USER_INTERNAL         1\n#  define KN_SCALE_USER_NONE             2\n#  define KN_SCALE_INTERNAL              3\n#define KN_PARAM_SOC                  1019\n#  define KN_SOC_NO                      0\n#  define KN_SOC_MAYBE                   1\n#  define KN_SOC_YES                     2\n#define KN_PARAM_DELTA                1020\n#define KN_PARAM_BAR_FEASMODETOL      1021\n#define KN_PARAM_FEASTOL              1022\n#define KN_PARAM_FEASTOLABS           1023\n#define KN_PARAM_MAXTIMECPU           1024\n#define KN_PARAM_BAR_INITMU           1025\n#define KN_PARAM_OBJRANGE             1026\n#define KN_PARAM_OPTTOL               1027\n#define KN_PARAM_OPTTOLABS            1028\n#define KN_PARAM_LINSOLVER_PIVOTTOL   1029\n#define KN_PARAM_XTOL                 1030\n#define KN_PARAM_DEBUG                1031\n#  define KN_DEBUG_NONE                  0\n#  define KN_DEBUG_PROBLEM               1\n#  define KN_DEBUG_EXECUTION             2\n#define KN_PARAM_MULTISTART           1033\n#define KN_PARAM_MSENABLE             1033\n#define KN_PARAM_MS_ENABLE            1033\n#  define KN_MULTISTART_NO               0\n#  define KN_MS_ENABLE_NO                0\n#  define KN_MULTISTART_YES              1\n#  define KN_MS_ENABLE_YES               1\n#define KN_PARAM_MSMAXSOLVES          1034\n#define KN_PARAM_MS_MAXSOLVES         1034\n#define KN_PARAM_MSMAXBNDRANGE        1035\n#define KN_PARAM_MS_MAXBNDRANGE       1035\n#define KN_PARAM_MSMAXTIMECPU         1036\n#define KN_PARAM_MS_MAXTIMECPU        1036\n#define KN_PARAM_MSMAXTIMEREAL        1037\n#define KN_PARAM_MS_MAXTIMEREAL       1037\n#define KN_PARAM_LMSIZE               1038\n#define KN_PARAM_BAR_MAXCROSSIT       1039\n#define KN_PARAM_MAXTIMEREAL          1040\n#define KN_PARAM_CG_PRECOND           1041\n#  define KN_CG_PRECOND_NONE             0\n#  define KN_CG_PRECOND_CHOL             1\n#define KN_PARAM_BLASOPTION           1042\n#  define KN_BLASOPTION_AUTO            -1\n#  define KN_BLASOPTION_KNITRO           0\n#  define KN_BLASOPTION_INTEL            1\n#  define KN_BLASOPTION_DYNAMIC          2\n#  define KN_BLASOPTION_BLIS             3\n#  define KN_BLASOPTION_APPLE            4\n#define KN_PARAM_BAR_MAXREFACTOR      1043\n#define KN_PARAM_LINESEARCH_MAXTRIALS 1044\n#define KN_PARAM_BLASOPTIONLIB        1045\n#define KN_PARAM_OUTAPPEND            1046\n#  define KN_OUTAPPEND_NO                0\n#  define KN_OUTAPPEND_YES               1\n#define KN_PARAM_OUTDIR               1047\n#define KN_PARAM_CPLEXLIB             1048\n#define KN_PARAM_BAR_PENRULE          1049\n#  define KN_BAR_PENRULE_AUTO            0\n#  define KN_BAR_PENRULE_SINGLE          1\n#  define KN_BAR_PENRULE_FLEX            2\n#define KN_PARAM_BAR_PENCONS          1050\n#  define KN_BAR_PENCONS_AUTO           -1\n#  define KN_BAR_PENCONS_NONE            0\n#  define KN_BAR_PENCONS_ALL             2\n#  define KN_BAR_PENCONS_EQUALITIES      3\n#  define KN_BAR_PENCONS_INFEAS          4 /*-- DEPRECATED */\n#define KN_PARAM_MSNUMTOSAVE          1051\n#define KN_PARAM_MS_NUMTOSAVE         1051\n#define KN_PARAM_MSSAVETOL            1052\n#define KN_PARAM_MS_SAVETOL           1052\n#define KN_PARAM_PRESOLVEDEBUG        1053 /*-- FOR AMPL ONLY */\n#  define KN_PRESOLVEDBG_NONE            0\n#  define KN_PRESOLVEDBG_BASIC           1\n#  define KN_PRESOLVEDBG_VERBOSE         2\n#  define KN_PRESOLVEDBG_DETAIL          3\n#define KN_PARAM_MSTERMINATE          1054\n#define KN_PARAM_MS_TERMINATE         1054\n#  define KN_MSTERMINATE_MAXSOLVES       0\n#  define KN_MS_TERMINATE_MAXSOLVES      0\n#  define KN_MSTERMINATE_OPTIMAL         1\n#  define KN_MS_TERMINATE_OPTIMAL        1\n#  define KN_MSTERMINATE_FEASIBLE        2\n#  define KN_MS_TERMINATE_FEASIBLE       2\n#  define KN_MSTERMINATE_ANY             3\n#  define KN_MS_TERMINATE_ANY            3\n#  define KN_MSTERMINATE_RULEBASED       4\n#  define KN_MS_TERMINATE_RULEBASED      4\n#define KN_PARAM_MSSTARTPTRANGE       1055\n#define KN_PARAM_MS_STARTPTRANGE      1055\n#define KN_PARAM_INFEASTOL            1056\n#define KN_PARAM_LINSOLVER            1057\n#  define KN_LINSOLVER_AUTO              0\n#  define KN_LINSOLVER_INTERNAL          1\n#  define KN_LINSOLVER_HYBRID            2\n#  define KN_LINSOLVER_DENSEQR           3\n#  define KN_LINSOLVER_MA27              4\n#  define KN_LINSOLVER_MA57              5\n#  define KN_LINSOLVER_MKLPARDISO        6\n#  define KN_LINSOLVER_MA97              7\n#  define KN_LINSOLVER_MA86              8\n#  define KN_LINSOLVER_APPLE             9\n#define KN_PARAM_BAR_DIRECTINTERVAL   1058\n#define KN_PARAM_PRESOLVE             1059\n#  define KN_PRESOLVE_NO                 0\n#  define KN_PRESOLVE_NONE               0 /*-- DEPRECATED */\n#  define KN_PRESOLVE_YES                1\n#  define KN_PRESOLVE_BASIC              1 /*-- DEPRECATED */\n#  define KN_PRESOLVE_ADVANCED           2 /*-- DEPRECATED */\n#define KN_PARAM_PRESOLVE_TOL         1060\n#define KN_PARAM_BAR_SWITCHRULE       1061\n#  define KN_BAR_SWITCHRULE_AUTO        -1\n#  define KN_BAR_SWITCHRULE_NEVER        0\n#  define KN_BAR_SWITCHRULE_MODERATE     2\n#  define KN_BAR_SWITCHRULE_AGGRESSIVE   3\n#define KN_PARAM_HESSIAN_NO_F         1062\n#  define KN_HESSIAN_NO_F_FORBID         0\n#  define KN_HESSIAN_NO_F_ALLOW          1\n#define KN_PARAM_MA_TERMINATE         1063\n#  define KN_MA_TERMINATE_ALL            0\n#  define KN_MA_TERMINATE_OPTIMAL        1\n#  define KN_MA_TERMINATE_FEASIBLE       2\n#  define KN_MA_TERMINATE_ANY            3\n#define KN_PARAM_MA_MAXTIMECPU        1064\n#define KN_PARAM_MA_MAXTIMEREAL       1065\n#define KN_PARAM_MSSEED               1066\n#define KN_PARAM_MS_SEED              1066\n#define KN_PARAM_MA_OUTSUB            1067\n#  define KN_MA_OUTSUB_NONE              0\n#  define KN_MA_OUTSUB_YES               1\n#define KN_PARAM_MS_OUTSUB            1068\n#  define KN_MS_OUTSUB_NONE              0\n#  define KN_MS_OUTSUB_YES               1\n#define KN_PARAM_XPRESSLIB            1069\n#define KN_PARAM_TUNER                1070\n#  define KN_TUNER_OFF                   0\n#  define KN_TUNER_ON                    1\n#define KN_PARAM_TUNER_OPTIONSFILE    1071\n#define KN_PARAM_TUNER_MAXTIMECPU     1072\n#define KN_PARAM_TUNER_MAXTIMEREAL    1073\n#define KN_PARAM_TUNER_OUTSUB         1074\n#  define KN_TUNER_OUTSUB_NONE           0\n#  define KN_TUNER_OUTSUB_SUMMARY        1\n#  define KN_TUNER_OUTSUB_ALL            2\n#define KN_PARAM_TUNER_TERMINATE      1075\n#  define KN_TUNER_TERMINATE_ALL         0\n#  define KN_TUNER_TERMINATE_OPTIMAL     1\n#  define KN_TUNER_TERMINATE_FEASIBLE    2\n#  define KN_TUNER_TERMINATE_ANY         3\n#define KN_PARAM_LINSOLVER_OOC        1076\n#  define KN_LINSOLVER_OOC_NO            0\n#  define KN_LINSOLVER_OOC_MAYBE         1\n#  define KN_LINSOLVER_OOC_YES           2\n#define KN_PARAM_BAR_RELAXCONS        1077\n#  define KN_BAR_RELAXCONS_NONE          0\n#  define KN_BAR_RELAXCONS_EQS           1\n#  define KN_BAR_RELAXCONS_INEQS         2\n#  define KN_BAR_RELAXCONS_ALL           3\n#define KN_PARAM_MSDETERMINISTIC      1078\n#define KN_PARAM_MS_DETERMINISTIC     1078\n#  define KN_MSDETERMINISTIC_NO          0\n#  define KN_MS_DETERMINISTIC_NO         0\n#  define KN_MSDETERMINISTIC_YES         1\n#  define KN_MS_DETERMINISTIC_YES        1\n#define KN_PARAM_BAR_REFINEMENT       1079\n#  define KN_BAR_REFINEMENT_NO           0\n#  define KN_BAR_REFINEMENT_YES          1\n#define KN_PARAM_DERIVCHECK           1080\n#  define KN_DERIVCHECK_NONE             0\n#  define KN_DERIVCHECK_FIRST            1\n#  define KN_DERIVCHECK_SECOND           2\n#  define KN_DERIVCHECK_ALL              3\n#define KN_PARAM_DERIVCHECK_TYPE      1081\n#  define KN_DERIVCHECK_FORWARD          1\n#  define KN_DERIVCHECK_CENTRAL          2\n#define KN_PARAM_DERIVCHECK_TOL       1082\n#define KN_PARAM_LINSOLVER_INEXACT    1083 /*-- UNDOCUMENTED/EXPERIMENTAL */\n#  define KN_LINSOLVER_INEXACT_NO        0\n#  define KN_LINSOLVER_INEXACT_YES       1\n#define KN_PARAM_LINSOLVER_INEXACTTOL 1084 /*-- UNDOCUMENTED/EXPERIMENTAL */\n#define KN_PARAM_MAXFEVALS            1085\n#define KN_PARAM_FSTOPVAL             1086\n#define KN_PARAM_DATACHECK            1087\n#  define KN_DATACHECK_NO                0\n#  define KN_DATACHECK_YES               1\n#define KN_PARAM_DERIVCHECK_TERMINATE 1088\n#  define KN_DERIVCHECK_STOPERROR        1\n#  define KN_DERIVCHECK_STOPALWAYS       2\n#define KN_PARAM_BAR_WATCHDOG         1089\n#  define KN_BAR_WATCHDOG_NO             0\n#  define KN_BAR_WATCHDOG_YES            1\n#define KN_PARAM_FTOL                 1090\n#define KN_PARAM_FTOL_ITERS           1091\n#define KN_PARAM_ACT_QPALG            1092\n#  define KN_ACT_QPALG_AUTO              0\n#  define KN_ACT_QPALG_BAR_DIRECT        1\n#  define KN_ACT_QPALG_BAR_CG            2\n#  define KN_ACT_QPALG_ACT_CG            3\n#define KN_PARAM_BAR_INITPI_MPEC      1093\n#define KN_PARAM_XTOL_ITERS           1094\n#define KN_PARAM_LINESEARCH           1095\n#  define KN_LINESEARCH_AUTO             0\n#  define KN_LINESEARCH_BACKTRACK        1\n#  define KN_LINESEARCH_INTERPOLATE      2\n#  define KN_LINESEARCH_WEAKWOLFE        3\n#define KN_PARAM_OUT_CSVINFO          1096\n#  define KN_OUT_CSVINFO_NO              0\n#  define KN_OUT_CSVINFO_YES             1\n#define KN_PARAM_INITPENALTY          1097\n#define KN_PARAM_ACT_LPFEASTOL        1098\n#define KN_PARAM_CG_STOPTOL           1099\n#define KN_PARAM_RESTARTS             1100\n#define KN_PARAM_RESTARTS_MAXIT       1101\n#define KN_PARAM_BAR_SLACKBOUNDPUSH   1102\n#define KN_PARAM_CG_PMEM              1103\n#define KN_PARAM_BAR_SWITCHOBJ        1104\n#  define KN_BAR_SWITCHOBJ_NONE          0\n#  define KN_BAR_SWITCHOBJ_SCALARPROX    1\n#  define KN_BAR_SWITCHOBJ_DIAGPROX      2\n#define KN_PARAM_OUTNAME              1105\n#define KN_PARAM_OUT_CSVNAME          1106\n#define KN_PARAM_ACT_PARAMETRIC       1107\n#  define KN_ACT_PARAMETRIC_NO           0\n#  define KN_ACT_PARAMETRIC_MAYBE        1\n#  define KN_ACT_PARAMETRIC_YES          2\n#define KN_PARAM_ACT_LPDUMPMPS        1108\n#  define KN_ACT_LPDUMPMPS_NO            0\n#  define KN_ACT_LPDUMPMPS_YES           1\n#define KN_PARAM_ACT_LPALG            1109\n#  define KN_ACT_LPALG_DEFAULT           0\n#  define KN_ACT_LPALG_PRIMAL            1\n#  define KN_ACT_LPALG_PRIMALSIMPLEX     1\n#  define KN_ACT_LPALG_DUAL              2\n#  define KN_ACT_LPALG_DUALSIMPLEX       2\n#  define KN_ACT_LPALG_BARRIER           3\n#define KN_PARAM_ACT_LPPRESOLVE       1110\n#  define KN_ACT_LPPRESOLVE_OFF          0\n#  define KN_ACT_LPPRESOLVE_ON           1\n#define KN_PARAM_ACT_LPPENALTY        1111\n#  define KN_ACT_LPPENALTY_ALL           1\n#  define KN_ACT_LPPENALTY_NONLINEAR     2\n#  define KN_ACT_LPPENALTY_DYNAMIC       3\n#define KN_PARAM_BNDRANGE             1112\n#define KN_PARAM_BAR_CONIC_ENABLE     1113\n#  define KN_BAR_CONIC_ENABLE_AUTO      -1\n#  define KN_BAR_CONIC_ENABLE_NONE       0\n#  define KN_BAR_CONIC_ENABLE_SOC        1\n#define KN_PARAM_CONVEX               1114\n#  define KN_CONVEX_AUTO                -1\n#  define KN_CONVEX_NO                   0\n#  define KN_CONVEX_YES                  1\n#define KN_PARAM_OUT_HINTS            1115\n#  define KN_OUT_HINTS_NO                0\n#  define KN_OUT_HINTS_YES               1\n#define KN_PARAM_EVAL_FCGA            1116\n#  define KN_EVAL_FCGA_NO                0\n#  define KN_EVAL_FCGA_YES               1\n#define KN_PARAM_BAR_MAXCORRECTORS    1117\n#define KN_PARAM_STRAT_WARM_START     1118\n#  define KN_STRAT_WARM_START_NO         0\n#  define KN_STRAT_WARM_START_YES        1\n#define KN_PARAM_FINDIFF_TERMINATE    1119\n#  define KN_FINDIFF_TERMINATE_NONE      0\n#  define KN_FINDIFF_TERMINATE_ERREST    1\n#define KN_PARAM_CPUPLATFORM          1120\n#  define KN_CPUPLATFORM_AUTO           -1\n#  define KN_CPUPLATFORM_COMPATIBLE      1\n#  define KN_CPUPLATFORM_SSE2            2\n#  define KN_CPUPLATFORM_AVX             3\n#  define KN_CPUPLATFORM_AVX2            4\n#  define KN_CPUPLATFORM_AVX512          5 /*-- EXPERIMENTAL */\n#define KN_PARAM_PRESOLVE_PASSES      1121\n#define KN_PARAM_PRESOLVE_LEVEL       1122\n#  define KN_PRESOLVE_LEVEL_AUTO        -1\n#  define KN_PRESOLVE_LEVEL_1            1\n#  define KN_PRESOLVE_LEVEL_2            2\n#define KN_PARAM_FINDIFF_RELSTEPSIZE  1123\n#define KN_PARAM_INFEASTOL_ITERS      1124\n#define KN_PARAM_PRESOLVEOP_TIGHTEN   1125\n#  define KN_PRESOLVEOP_TIGHTEN_AUTO    -1\n#  define KN_PRESOLVEOP_TIGHTEN_NONE     0\n#  define KN_PRESOLVEOP_TIGHTEN_VARBND   1\n#  define KN_PRESOLVEOP_TIGHTEN_COEF     2 /*-- DEPRECATED */\n#  define KN_PRESOLVEOP_TIGHTEN_ALL      3 /*-- DEPRECATED */\n#define KN_PARAM_BAR_LINSYS           1126\n#  define KN_BAR_LINSYS_AUTO            -1\n#  define KN_BAR_LINSYS_FULL             0\n#  define KN_BAR_LINSYS_COMPACT1         1 /*-- DEPRECATED */\n#  define KN_BAR_LINSYS_ELIMINATE_SLACKS 1\n#  define KN_BAR_LINSYS_COMPACT2         2 /*-- DEPRECATED */\n#  define KN_BAR_LINSYS_ELIMINATE_BOUNDS 2\n#  define KN_BAR_LINSYS_ELIMINATE_INEQS  3\n#define KN_PARAM_PRESOLVE_INITPT      1127\n#  define KN_PRESOLVE_INITPT_AUTO       -1\n#  define KN_PRESOLVE_INITPT_NOSHIFT     0\n#  define KN_PRESOLVE_INITPT_LINSHIFT    1\n#  define KN_PRESOLVE_INITPT_ANYSHIFT    2\n#define KN_PARAM_ACT_QPPENALTY        1128\n#  define KN_ACT_QPPENALTY_AUTO         -1\n#  define KN_ACT_QPPENALTY_NONE          0\n#  define KN_ACT_QPPENALTY_ALL           1\n#define KN_PARAM_BAR_LINSYS_STORAGE   1129\n#  define KN_BAR_LINSYS_STORAGE_AUTO    -1\n#  define KN_BAR_LINSYS_STORAGE_LOWMEM   1\n#  define KN_BAR_LINSYS_STORAGE_NORMAL   2\n#define KN_PARAM_LINSOLVER_MAXITREF   1130\n#define KN_PARAM_BFGS_SCALING         1131\n#  define KN_BFGS_SCALING_DYNAMIC        0\n#  define KN_BFGS_SCALING_INVHESS        1\n#  define KN_BFGS_SCALING_HESS           2\n#define KN_PARAM_BAR_INITSHIFTTOL     1132\n#define KN_PARAM_NUMTHREADS           1133\n#define KN_PARAM_CONCURRENT_EVALS     1134\n#  define KN_CONCURRENT_EVALS_NO         0\n#  define KN_CONCURRENT_EVALS_YES        1\n#define KN_PARAM_BLAS_NUMTHREADS      1135\n#define KN_PARAM_LINSOLVER_NUMTHREADS 1136\n#define KN_PARAM_MS_NUMTHREADS        1137\n#define KN_PARAM_CONIC_NUMTHREADS     1138\n#define KN_PARAM_NCVX_QCQP_INIT       1139\n#  define KN_NCVX_QCQP_INIT_AUTO        -1\n#  define KN_NCVX_QCQP_INIT_NONE         0\n#  define KN_NCVX_QCQP_INIT_LINEAR       1\n#  define KN_NCVX_QCQP_INIT_HYBRID       2\n#  define KN_NCVX_QCQP_INIT_PENALTY      3\n#  define KN_NCVX_QCQP_INIT_CVXQUAD      4\n#define KN_PARAM_FINDIFF_ESTNOISE     1140\n#  define KN_FINDIFF_ESTNOISE_NO         0\n#  define KN_FINDIFF_ESTNOISE_YES        1\n#  define KN_FINDIFF_ESTNOISE_WITHCURV   2\n#define KN_PARAM_FINDIFF_NUMTHREADS   1141\n#define KN_PARAM_BAR_MPEC_HEURISTIC   1142\n#  define KN_BAR_MPEC_HEURISTIC_NO       0\n#  define KN_BAR_MPEC_HEURISTIC_YES      1\n#define KN_PARAM_PRESOLVEOP_REDUNDANT 1143\n#  define KN_PRESOLVEOP_REDUNDANT_NONE   0\n#  define KN_PRESOLVEOP_REDUNDANT_DUPCON 1\n#  define KN_PRESOLVEOP_REDUNDANT_DEPCON 2\n#define KN_PARAM_LINSOLVER_ORDERING   1144\n#  define KN_LINSOLVER_ORDERING_AUTO    -1\n#  define KN_LINSOLVER_ORDERING_BEST     0\n#  define KN_LINSOLVER_ORDERING_AMD      1\n#  define KN_LINSOLVER_ORDERING_METIS    2\n#define KN_PARAM_LINSOLVER_NODEAMALG  1145\n#define KN_PARAM_PRESOLVEOP_SUBSTITUTION 1146\n#  define KN_PRESOLVEOP_SUBSTITUTION_AUTO  -1\n#  define KN_PRESOLVEOP_SUBSTITUTION_NONE   0\n#  define KN_PRESOLVEOP_SUBSTITUTION_SIMPLE 1\n#  define KN_PRESOLVEOP_SUBSTITUTION_ALL    2\n#define KN_PARAM_PRESOLVEOP_SUBSTITUTION_TOL 1147\n#define KN_PARAM_MS_INITPT_CLUSTER    1149\n#  define KN_MS_INITPT_CLUSTER_NONE      0\n#  define KN_MS_INITPT_CLUSTER_SL        1\n#define KN_PARAM_SCALE_VARS           1153\n#  define KN_SCALE_VARS_NONE             0\n#  define KN_SCALE_VARS_BNDS             1\n#define KN_PARAM_BAR_MAXMU            1154\n#define KN_PARAM_BAR_GLOBALIZE        1155\n#  define KN_BAR_GLOBALIZE_NONE          0\n#  define KN_BAR_GLOBALIZE_KKT           1\n#  define KN_BAR_GLOBALIZE_FILTER        2\n#define KN_PARAM_LINSOLVER_SCALING    1156\n#  define KN_LINSOLVER_SCALING_NONE      0\n#  define KN_LINSOLVER_SCALING_ALWAYS    1\n#  define KN_LINSOLVER_SCALING_DYNAMIC   2\n#define KN_PARAM_INITPT_STRATEGY      1158\n#  define KN_INITPT_STRATEGY_AUTO       -1\n#  define KN_INITPT_STRATEGY_BASIC       1\n#  define KN_INITPT_STRATEGY_ADVANCED    2\n#define KN_PARAM_EVAL_COST            1159\n#  define KN_EVAL_COST_UNSPECIFIED       0\n#  define KN_EVAL_COST_INEXPENSIVE       1\n#  define KN_EVAL_COST_EXPENSIVE         2\n#define KN_PARAM_MS_TERMINATERULE_TOL 1160\n#define KN_PARAM_SOLTYPE              1161\n#  define KN_SOLTYPE_FINAL               0\n#  define KN_SOLTYPE_BESTFEAS            1\n#define KN_PARAM_MAXTIME              1163\n#define KN_PARAM_MA_SUB_MAXTIME       1164\n#define KN_PARAM_MS_SUB_MAXTIME       1165\n#define KN_PARAM_TUNER_SUB_MAXTIME    1166\n#define KN_PARAM_INITPTFILE           1167\n#define KN_PARAM_LP_ALGORITHM         1170\n#define KN_PARAM_LP_ALG               1170\n#  define KN_LP_ALG_AUTO                -1\n#  define KN_LP_ALG_NLPALGORITHM         0\n#  define KN_LP_ALG_PRIMALSIMPLEX        1\n#  define KN_LP_ALG_DUALSIMPLEX          2\n#  define KN_LP_ALG_BARRIER              3\n#  define KN_LP_ALG_PDLP                 4\n#define KN_PARAM_AL_INITPENALTY       1171\n#define KN_PARAM_AL_MAXPENALTY        1172\n#define KN_PARAM_PRESOLVEOP_PROBING   1174\n#  define KN_PRESOLVEOP_PROBING_AUTO    -1\n#  define KN_PRESOLVEOP_PROBING_OFF      0\n#  define KN_PRESOLVEOP_PROBING_LIGHT    1\n#  define KN_PRESOLVEOP_PROBING_FULL     2\n#define KN_PARAM_PRESOLVEOP_CLIQUE_MERGING  1176\n#  define KN_PRESOLVEOP_CLIQUE_MERGING_AUTO   -1\n#  define KN_PRESOLVEOP_CLIQUE_MERGING_OFF     0\n#  define KN_PRESOLVEOP_CLIQUE_MERGING_ON      1\n\n/* ----- MIP-specific parameters ----- */\n#define KN_PARAM_MIP_METHOD           2001\n#  define KN_MIP_METHOD_AUTO             0\n#  define KN_MIP_METHOD_BB               1\n#  define KN_MIP_METHOD_HQG              2\n#  define KN_MIP_METHOD_MISQP            3\n#define KN_PARAM_MIP_BRANCHRULE       2002\n#  define KN_MIP_BRANCH_AUTO             0\n#  define KN_MIP_BRANCH_MOSTFRAC         1\n#  define KN_MIP_BRANCH_PSEUDOCOST       2\n#  define KN_MIP_BRANCH_STRONG           3\n#define KN_PARAM_MIP_SELECTRULE       2003\n#  define KN_MIP_SEL_AUTO                0\n#  define KN_MIP_SEL_DEPTHFIRST          1\n#  define KN_MIP_SEL_BESTBOUND           2\n#  define KN_MIP_SEL_COMBO_1             3\n#define KN_PARAM_MIP_INTGAPABS        2004 /*-- DEPRECATED */\n#define KN_PARAM_MIP_OPTGAPABS        2004\n#define KN_PARAM_MIP_INTGAPREL        2005 /*-- DEPRECATED */\n#define KN_PARAM_MIP_OPTGAPREL        2005\n#define KN_PARAM_MIP_MAXTIMECPU       2006\n#define KN_PARAM_MIP_MAXTIMEREAL      2007\n#define KN_PARAM_MIP_MAXSOLVES        2008\n#define KN_PARAM_MIP_INTEGERTOL       2009\n#define KN_PARAM_MIP_OUTLEVEL         2010\n#  define KN_MIP_OUTLEVEL_NONE           0\n#  define KN_MIP_OUTLEVEL_ITERS          1\n#  define KN_MIP_OUTLEVEL_ITERSTIME      2\n#  define KN_MIP_OUTLEVEL_ROOT           3\n#define KN_PARAM_MIP_OUTINTERVAL      2011\n#define KN_PARAM_MIP_OUTSUB           2012\n#  define KN_MIP_OUTSUB_NONE             0\n#  define KN_MIP_OUTSUB_YES              1\n#  define KN_MIP_OUTSUB_YESPROB          2\n#define KN_PARAM_MIP_DEBUG            2013\n#  define KN_MIP_DEBUG_NONE              0\n#  define KN_MIP_DEBUG_ALL               1\n#define KN_PARAM_MIP_IMPLICATNS       2014  /*-- USE LOGICAL IMPLICATIONS */\n#define KN_PARAM_MIP_IMPLICATIONS     2014\n#  define KN_MIP_IMPLICATNS_NO           0\n#  define KN_MIP_IMPLICATIONS_NO         0\n#  define KN_MIP_IMPLICATNS_YES          1\n#  define KN_MIP_IMPLICATIONS_YES        1\n#define KN_PARAM_MIP_GUB_BRANCH       2015  /*-- BRANCH ON GENERALIZED BOUNDS */\n#  define KN_MIP_GUB_BRANCH_NO           0\n#  define KN_MIP_GUB_BRANCH_YES          1\n#define KN_PARAM_MIP_KNAPSACK         2016  /*-- KNAPSACK CUTS */\n#  define KN_MIP_KNAPSACK_AUTO          -1\n#  define KN_MIP_KNAPSACK_NO             0\n#  define KN_MIP_KNAPSACK_NONE           0  /*--   NONE */\n#  define KN_MIP_KNAPSACK_ROOT           1  /*--   IN THE ROOT */\n#  define KN_MIP_KNAPSACK_TREE           2  /*--   IN THE WHOLE TREE */\n#  define KN_MIP_KNAPSACK_INEQ           1  /*--   DEPRECATED */\n#  define KN_MIP_KNAPSACK_LIFTED         2  /*--   DEPRECATED */\n#  define KN_MIP_KNAPSACK_ALL            3  /*--   DEPRECATED */\n#define KN_PARAM_MIP_ROUNDING         2017\n#  define KN_MIP_ROUND_AUTO             -1\n#  define KN_MIP_ROUND_NONE              0  /*-- DO NOT ATTEMPT ROUNDING */\n#  define KN_MIP_ROUND_HEURISTIC         2  /*-- USE FAST HEURISTIC */\n#  define KN_MIP_ROUND_NLP_SOME          3  /*-- SOLVE NLP IF LIKELY TO WORK */\n#  define KN_MIP_ROUND_NLP_ALWAYS        4  /*-- SOLVE NLP ALWAYS */\n#define KN_PARAM_MIP_ROOT_NLPALG      2018\n#define KN_PARAM_MIP_ROOTALG          2018  /*-- DEPRECATED */\n#  define KN_MIP_ROOT_NLPALG_AUTO        0\n#  define KN_MIP_ROOTALG_AUTO            0  /*-- DEPRECATED */\n#  define KN_MIP_ROOT_NLPALG_BAR_DIRECT  1\n#  define KN_MIP_ROOTALG_BAR_DIRECT      1  /*-- DEPRECATED */\n#  define KN_MIP_ROOT_NLPALG_BAR_CG      2\n#  define KN_MIP_ROOTALG_BAR_CG          2  /*-- DEPRECATED */\n#  define KN_MIP_ROOT_NLPALG_ACT_CG      3\n#  define KN_MIP_ROOTALG_ACT_CG          3  /*-- DEPRECATED */\n#  define KN_MIP_ROOT_NLPALG_ACT_SQP     4\n#  define KN_MIP_ROOTALG_ACT_SQP         4  /*-- DEPRECATED */\n#  define KN_MIP_ROOTALG_MULTI           5  /*-- DEPRECATED */\n#define KN_PARAM_MIP_LPALG            2019  /*-- DEPRECATED: USE */\n#  define KN_MIP_LPALG_AUTO              0  /*-- KN_PARAM_MIP_ROOT_LPALG OR */\n#  define KN_MIP_LPALG_BAR_DIRECT        1  /*-- KN_PARAM_MIP_NODE_LPALG */\n#  define KN_MIP_LPALG_BAR_CG            2\n#  define KN_MIP_LPALG_ACT_CG            3\n#define KN_PARAM_MIP_TERMINATE        2020\n#  define KN_MIP_TERMINATE_OPTIMAL       0\n#  define KN_MIP_TERMINATE_FEASIBLE      1\n#define KN_PARAM_MIP_MAXNODES         2021\n#define KN_PARAM_MIP_HEURISTIC        2022 /*-- DEPRECATED */\n#define KN_PARAM_MIP_HEUR_MAXIT       2023\n#define KN_PARAM_MIP_HEUR_MAXTIMECPU  2024  /*-- INACTIVE */\n#define KN_PARAM_MIP_HEUR_MAXTIMEREAL 2025  /*-- INACTIVE */\n#define KN_PARAM_MIP_PSEUDOINIT       2026\n#  define KN_MIP_PSEUDOINIT_AUTO         0\n#  define KN_MIP_PSEUDOINIT_AVE          1\n#  define KN_MIP_PSEUDOINIT_STRONG       2\n#define KN_PARAM_MIP_STRONG_MAXIT     2027\n#define KN_PARAM_MIP_STRONG_CANDLIM   2028\n#define KN_PARAM_MIP_STRONG_LEVEL     2029\n#define KN_PARAM_MIP_INTVAR_STRATEGY  2030\n#  define KN_MIP_INTVAR_STRATEGY_NONE    0\n#  define KN_MIP_INTVAR_STRATEGY_RELAX   1\n#  define KN_MIP_INTVAR_STRATEGY_MPEC    2\n#define KN_PARAM_MIP_RELAXABLE        2031\n#  define KN_MIP_RELAXABLE_NONE          0\n#  define KN_MIP_RELAXABLE_ALL           1\n#define KN_PARAM_MIP_NODE_NLPALG      2032\n#define KN_PARAM_MIP_NODEALG          2032  /*-- DEPRECATED */\n#  define KN_MIP_NODE_NLPALG_AUTO        0\n#  define KN_MIP_NODEALG_AUTO            0  /*-- DEPRECATED */\n#  define KN_MIP_NODE_NLPALG_BAR_DIRECT  1\n#  define KN_MIP_NODEALG_BAR_DIRECT      1  /*-- DEPRECATED */\n#  define KN_MIP_NODE_NLPALG_BAR_CG      2\n#  define KN_MIP_NODEALG_BAR_CG          2  /*-- DEPRECATED */\n#  define KN_MIP_NODE_NLPALG_ACT_CG      3\n#  define KN_MIP_NODEALG_ACT_CG          3  /*-- DEPRECATED */\n#  define KN_MIP_NODE_NLPALG_ACT_SQP     4\n#  define KN_MIP_NODEALG_ACT_SQP         4  /*-- DEPRECATED */\n#  define KN_MIP_NODEALG_MULTI           5  /*-- DEPRECATED */\n#define KN_PARAM_MIP_HEUR_TERMINATE   2033\n#  define KN_MIP_HEUR_TERMINATE_FEASIBLE 1\n#  define KN_MIP_HEUR_TERMINATE_LIMIT    2\n#define KN_PARAM_MIP_SELECTDIR        2034\n#  define KN_MIP_SELECTDIR_DOWN          0\n#  define KN_MIP_SELECTDIR_UP            1\n#define KN_PARAM_MIP_CUTFACTOR        2035\n#define KN_PARAM_MIP_ZEROHALF         2036  /*-- ZEROHALF CUTS */\n#  define KN_MIP_ZEROHALF_AUTO          -1\n#  define KN_MIP_ZEROHALF_NONE           0  /*--   NONE */\n#  define KN_MIP_ZEROHALF_ROOT           1  /*--   IN THE ROOT */\n#  define KN_MIP_ZEROHALF_TREE           2  /*--   IN THE WHOLE TREE */\n#  define KN_MIP_ZEROHALF_ALL            3  /*--   DEPRECATED */\n#define KN_PARAM_MIP_MIR              2037  /*-- MIR CUTS */\n#  define KN_MIP_MIR_AUTO               -1\n#  define KN_MIP_MIR_NONE                0  /*--   NONE */\n#  define KN_MIP_MIR_ROOT                1  /*--   IN THE ROOT */\n#  define KN_MIP_MIR_TREE                2  /*--   IN THE WHOLE TREE */\n#  define KN_MIP_MIR_NLP                 2  /*--   DEPRECATED*/\n#define KN_PARAM_MIP_CLIQUE           2038  /*-- CLIQUE CUTS */\n#  define KN_MIP_CLIQUE_AUTO            -1\n#  define KN_MIP_CLIQUE_NONE             0  /*--   NONE */\n#  define KN_MIP_CLIQUE_ROOT             1  /*--   IN THE ROOT */\n#  define KN_MIP_CLIQUE_TREE             2  /*--   IN THE WHOLE TREE */\n#  define KN_MIP_CLIQUE_ALL              3  /*--   DEPRECATED */\n#define KN_PARAM_MIP_HEUR_STRATEGY    2039\n#  define KN_MIP_HEUR_STRATEGY_AUTO     -1\n#  define KN_MIP_HEUR_STRATEGY_NONE      0\n#  define KN_MIP_HEUR_STRATEGY_BASIC     1\n#  define KN_MIP_HEUR_STRATEGY_ADVANCED  2\n#  define KN_MIP_HEUR_STRATEGY_EXTENSIVE 3\n#define KN_PARAM_MIP_HEUR_FEASPUMP    2040\n#  define KN_MIP_HEUR_FEASPUMP_AUTO     -1\n#  define KN_MIP_HEUR_FEASPUMP_OFF       0\n#  define KN_MIP_HEUR_FEASPUMP_ON        1\n#define KN_PARAM_MIP_HEUR_MPEC        2041\n#  define KN_MIP_HEUR_MPEC_AUTO         -1\n#  define KN_MIP_HEUR_MPEC_OFF           0\n#  define KN_MIP_HEUR_MPEC_ON            1\n#define KN_PARAM_MIP_HEUR_DIVING      2042\n#define KN_PARAM_MIP_CUTTINGPLANE     2043  /*-- CUTTING PLANE */\n#  define KN_MIP_CUTTINGPLANE_NONE       0  /*--   NONE */\n#  define KN_MIP_CUTTINGPLANE_ROOT       1  /*--   IN THE ROOT */\n#define KN_PARAM_MIP_CUTOFF           2044\n#define KN_PARAM_MIP_HEUR_LNS         2045\n#define KN_PARAM_MIP_MULTISTART       2046\n#  define KN_MIP_MULTISTART_OFF          0\n#  define KN_MIP_MULTISTART_ON           1\n#define KN_PARAM_MIP_LIFTPROJECT      2047  /*-- LIFT&PROJECT CUTS */\n#  define KN_MIP_LIFTPROJECT_AUTO       -1\n#  define KN_MIP_LIFTPROJECT_NONE        0  /*--   NONE */\n#  define KN_MIP_LIFTPROJECT_ROOT        1  /*--   IN THE ROOT */\n#define KN_PARAM_MIP_NUMTHREADS       2048\n#define KN_PARAM_MIP_HEUR_MISQP       2049\n#  define KN_MIP_HEUR_MISQP_AUTO        -1\n#  define KN_MIP_HEUR_MISQP_OFF          0\n#  define KN_MIP_HEUR_MISQP_ON           1\n#define KN_PARAM_MIP_RESTART          2050\n#  define KN_MIP_RESTART_OFF             0\n#  define KN_MIP_RESTART_ON              1\n#define KN_PARAM_MIP_GOMORY           2051  /*-- GOMORY CUTS */\n#  define KN_MIP_GOMORY_AUTO            -1\n#  define KN_MIP_GOMORY_NONE             0  /*--   NONE */\n#  define KN_MIP_GOMORY_ROOT             1  /*--   IN THE ROOT ONLY */\n#  define KN_MIP_GOMORY_TREE             2  /*--   IN THE WHOLE TREE */\n#define KN_PARAM_MIP_CUT_PROBING      2052  /*-- PROBING CUTS */\n#  define KN_MIP_CUT_PROBING_AUTO       -1\n#  define KN_MIP_CUT_PROBING_NONE        0  /*--   NONE */\n#  define KN_MIP_CUT_PROBING_ROOT        1  /*--   IN THE ROOT ONLY */\n#  define KN_MIP_CUT_PROBING_TREE        2  /*--   IN THE WHOLE TREE */\n#define KN_PARAM_MIP_CUT_FLOWCOVER    2053  /*-- FLOW COVER CUTS */\n#  define KN_MIP_CUT_FLOWCOVER_AUTO     -1\n#  define KN_MIP_CUT_FLOWCOVER_NONE      0  /*--   NONE */\n#  define KN_MIP_CUT_FLOWCOVER_ROOT      1  /*--   IN THE ROOT ONLY */\n#  define KN_MIP_CUT_FLOWCOVER_TREE      2  /*--   IN THE WHOLE TREE */\n#define KN_PARAM_MIP_HEUR_LOCALSEARCH 2054\n#  define KN_MIP_HEUR_LOCALSEARCH_AUTO  -1\n#  define KN_MIP_HEUR_LOCALSEARCH_OFF    0\n#  define KN_MIP_HEUR_LOCALSEARCH_ON     1\n#define KN_PARAM_MIP_SUB_MAXTIME      2055\n#define KN_PARAM_MIP_INITPTFILE       2056\n#define KN_PARAM_MIP_ROOT_LPALG        2057\n#  define KN_MIP_ROOT_LPALG_AUTO         -1\n#  define KN_MIP_ROOT_LPALG_NLPALGORITHM  0\n#  define KN_MIP_ROOT_LPALG_PRIMALSIMPLEX 1\n#  define KN_MIP_ROOT_LPALG_DUALSIMPLEX   2\n#  define KN_MIP_ROOT_LPALG_BARRIER       3\n#  define KN_MIP_ROOT_LPALG_PDLP          4\n#define KN_PARAM_MIP_NODE_LPALG        2058\n#  define KN_MIP_NODE_LPALG_AUTO         -1\n#  define KN_MIP_NODE_LPALG_NLPALGORITHM  0\n#  define KN_MIP_NODE_LPALG_PRIMALSIMPLEX 1\n#  define KN_MIP_NODE_LPALG_DUALSIMPLEX   2\n#  define KN_MIP_NODE_LPALG_BARRIER       3\n#  define KN_MIP_NODE_LPALG_PDLP          4\n#define KN_PARAM_MIP_CUTOFFABS        2059\n#define KN_PARAM_MIP_CUTOFFREL        2060\n#define KN_PARAM_MIP_HEUR_FIXPROPAGATE 2061\n#  define KN_MIP_HEUR_FIXPROPAGATE_AUTO  -1\n#  define KN_MIP_HEUR_FIXPROPAGATE_OFF    0\n#  define KN_MIP_HEUR_FIXPROPAGATE_ON     1\n\n/*-- THE BELOW ARE DEPRECATED! */\n#define KN_PARAM_PAR_NUMTHREADS       3001 /*-- USE KN_PARAM_NUMTHREADS */\n#define KN_PARAM_PAR_CONCURRENT_EVALS 3002 /*-- USE KN_PARAM_CONCURRENT_EVALS */\n#  define KN_PAR_CONCURRENT_EVALS_NO     0 /*-- USE KN_CONCURRENT_EVALS_NO */\n#  define KN_PAR_CONCURRENT_EVALS_YES    1 /*-- USE KN_CONCURRENT_EVALS_YES */\n#define KN_PARAM_PAR_BLASNUMTHREADS   3003 /*-- USE KN_PARAM_BLAS_NUMTHREADS */\n#define KN_PARAM_PAR_LSNUMTHREADS     3004 /*-- USE KN_PARAM_LINSOLVER_NUMTHREADS */\n#define KN_PARAM_PAR_MSNUMTHREADS     3005 /*-- USE KN_PARAM_MS_NUMTHREADS */\n#  define KN_PAR_MSNUMTHREADS_AUTO       0 /*-- DEPRECATED */\n#define KN_PARAM_PAR_CONICNUMTHREADS  3006 /*-- USE KN_PARAM_CONIC_NUMTHREADS */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif     /*-- KNITRO_H__ */\n"
  },
  {
    "path": "thirdparty/solvers/mosek/mosek_linux.h",
    "content": "#ifndef MOSEK_H\n#define MOSEK_H\n\n/******************************************************************************\n ** Module : mosek.h\n **\n ** Generated 2025\n **\n ** Copyright (c) MOSEK ApS, Denmark.\n **\n ** All rights reserved\n **\n ******************************************************************************/\n/*\n The content of this file is subject to copyright. However, it may free\n of charge be redistributed in identical form --- i.e. with no changes of\n the wording --- for any legitimate purpose.\n*/\n\n\n#include <stdlib.h>\n#include <stdio.h>\n#include <stdint.h>\n\n#define MSK_VERSION_MAJOR    11\n#define MSK_VERSION_MINOR    0\n#define MSK_VERSION_REVISION 4\n#define MSK_VERSION_STATE    \"\"\n\n#define MSK_INFINITY 1.0e30\n\n/* BEGIN PLATFORM SPECIFIC DEFINITIONS (linux64x86) */\n#define MSKAPI   \n#define MSKAPIVA \n/* END   PLATFORM SPECIFIC DEFINITIONS (linux64x86) */\n\n\n/* Enums and constants */\n/* namespace mosek { */\nenum MSKbasindtype_enum {\n  MSK_BI_NEVER       = 0,\n  MSK_BI_ALWAYS      = 1,\n  MSK_BI_NO_ERROR    = 2,\n  MSK_BI_IF_FEASIBLE = 3,\n  MSK_BI_RESERVERED  = 4\n};\n#define MSK_BI_BEGIN MSK_BI_NEVER\n#define MSK_BI_END   (1+MSK_BI_RESERVERED)\n\n\nenum MSKboundkey_enum {\n  MSK_BK_LO = 0,\n  MSK_BK_UP = 1,\n  MSK_BK_FX = 2,\n  MSK_BK_FR = 3,\n  MSK_BK_RA = 4\n};\n#define MSK_BK_BEGIN MSK_BK_LO\n#define MSK_BK_END   (1+MSK_BK_RA)\n\n\nenum MSKmark_enum {\n  MSK_MARK_LO = 0,\n  MSK_MARK_UP = 1\n};\n#define MSK_MARK_BEGIN MSK_MARK_LO\n#define MSK_MARK_END   (1+MSK_MARK_UP)\n\n\nenum MSKsimprecision_enum {\n  MSK_SIM_PRECISION_NORMAL   = 0,\n  MSK_SIM_PRECISION_EXTENDED = 1\n};\n#define MSK_SIM_PRECISION_BEGIN MSK_SIM_PRECISION_NORMAL\n#define MSK_SIM_PRECISION_END   (1+MSK_SIM_PRECISION_EXTENDED)\n\n\nenum MSKsimdegen_enum {\n  MSK_SIM_DEGEN_NONE       = 0,\n  MSK_SIM_DEGEN_FREE       = 1,\n  MSK_SIM_DEGEN_AGGRESSIVE = 2,\n  MSK_SIM_DEGEN_MODERATE   = 3,\n  MSK_SIM_DEGEN_MINIMUM    = 4\n};\n#define MSK_SIM_DEGEN_BEGIN MSK_SIM_DEGEN_NONE\n#define MSK_SIM_DEGEN_END   (1+MSK_SIM_DEGEN_MINIMUM)\n\n\nenum MSKtranspose_enum {\n  MSK_TRANSPOSE_NO  = 0,\n  MSK_TRANSPOSE_YES = 1\n};\n#define MSK_TRANSPOSE_BEGIN MSK_TRANSPOSE_NO\n#define MSK_TRANSPOSE_END   (1+MSK_TRANSPOSE_YES)\n\n\nenum MSKuplo_enum {\n  MSK_UPLO_LO = 0,\n  MSK_UPLO_UP = 1\n};\n#define MSK_UPLO_BEGIN MSK_UPLO_LO\n#define MSK_UPLO_END   (1+MSK_UPLO_UP)\n\n\nenum MSKsimreform_enum {\n  MSK_SIM_REFORMULATION_OFF        = 0,\n  MSK_SIM_REFORMULATION_ON         = 1,\n  MSK_SIM_REFORMULATION_FREE       = 2,\n  MSK_SIM_REFORMULATION_AGGRESSIVE = 3\n};\n#define MSK_SIM_REFORMULATION_BEGIN MSK_SIM_REFORMULATION_OFF\n#define MSK_SIM_REFORMULATION_END   (1+MSK_SIM_REFORMULATION_AGGRESSIVE)\n\n\nenum MSKsimdupvec_enum {\n  MSK_SIM_EXPLOIT_DUPVEC_OFF  = 0,\n  MSK_SIM_EXPLOIT_DUPVEC_ON   = 1,\n  MSK_SIM_EXPLOIT_DUPVEC_FREE = 2\n};\n#define MSK_SIM_EXPLOIT_DUPVEC_BEGIN MSK_SIM_EXPLOIT_DUPVEC_OFF\n#define MSK_SIM_EXPLOIT_DUPVEC_END   (1+MSK_SIM_EXPLOIT_DUPVEC_FREE)\n\n\nenum MSKsimhotstart_enum {\n  MSK_SIM_HOTSTART_NONE        = 0,\n  MSK_SIM_HOTSTART_FREE        = 1,\n  MSK_SIM_HOTSTART_STATUS_KEYS = 2\n};\n#define MSK_SIM_HOTSTART_BEGIN MSK_SIM_HOTSTART_NONE\n#define MSK_SIM_HOTSTART_END   (1+MSK_SIM_HOTSTART_STATUS_KEYS)\n\n\nenum MSKintpnthotstart_enum {\n  MSK_INTPNT_HOTSTART_NONE        = 0,\n  MSK_INTPNT_HOTSTART_PRIMAL      = 1,\n  MSK_INTPNT_HOTSTART_DUAL        = 2,\n  MSK_INTPNT_HOTSTART_PRIMAL_DUAL = 3\n};\n#define MSK_INTPNT_HOTSTART_BEGIN MSK_INTPNT_HOTSTART_NONE\n#define MSK_INTPNT_HOTSTART_END   (1+MSK_INTPNT_HOTSTART_PRIMAL_DUAL)\n\n\nenum MSKcallbackcode_enum {\n  MSK_CALLBACK_BEGIN_BI                    = 0,\n  MSK_CALLBACK_BEGIN_CONIC                 = 1,\n  MSK_CALLBACK_BEGIN_DUAL_BI               = 2,\n  MSK_CALLBACK_BEGIN_DUAL_SENSITIVITY      = 3,\n  MSK_CALLBACK_BEGIN_DUAL_SETUP_BI         = 4,\n  MSK_CALLBACK_BEGIN_DUAL_SIMPLEX          = 5,\n  MSK_CALLBACK_BEGIN_DUAL_SIMPLEX_BI       = 6,\n  MSK_CALLBACK_BEGIN_FOLDING               = 7,\n  MSK_CALLBACK_BEGIN_FOLDING_BI            = 8,\n  MSK_CALLBACK_BEGIN_FOLDING_BI_DUAL       = 9,\n  MSK_CALLBACK_BEGIN_FOLDING_BI_INITIALIZE = 10,\n  MSK_CALLBACK_BEGIN_FOLDING_BI_OPTIMIZER  = 11,\n  MSK_CALLBACK_BEGIN_FOLDING_BI_PRIMAL     = 12,\n  MSK_CALLBACK_BEGIN_INFEAS_ANA            = 13,\n  MSK_CALLBACK_BEGIN_INITIALIZE_BI         = 14,\n  MSK_CALLBACK_BEGIN_INTPNT                = 15,\n  MSK_CALLBACK_BEGIN_LICENSE_WAIT          = 16,\n  MSK_CALLBACK_BEGIN_MIO                   = 17,\n  MSK_CALLBACK_BEGIN_OPTIMIZE_BI           = 18,\n  MSK_CALLBACK_BEGIN_OPTIMIZER             = 19,\n  MSK_CALLBACK_BEGIN_PRESOLVE              = 20,\n  MSK_CALLBACK_BEGIN_PRIMAL_BI             = 21,\n  MSK_CALLBACK_BEGIN_PRIMAL_REPAIR         = 22,\n  MSK_CALLBACK_BEGIN_PRIMAL_SENSITIVITY    = 23,\n  MSK_CALLBACK_BEGIN_PRIMAL_SETUP_BI       = 24,\n  MSK_CALLBACK_BEGIN_PRIMAL_SIMPLEX        = 25,\n  MSK_CALLBACK_BEGIN_PRIMAL_SIMPLEX_BI     = 26,\n  MSK_CALLBACK_BEGIN_QCQO_REFORMULATE      = 27,\n  MSK_CALLBACK_BEGIN_READ                  = 28,\n  MSK_CALLBACK_BEGIN_ROOT_CUTGEN           = 29,\n  MSK_CALLBACK_BEGIN_SIMPLEX               = 30,\n  MSK_CALLBACK_BEGIN_SOLVE_ROOT_RELAX      = 31,\n  MSK_CALLBACK_BEGIN_TO_CONIC              = 32,\n  MSK_CALLBACK_BEGIN_WRITE                 = 33,\n  MSK_CALLBACK_CONIC                       = 34,\n  MSK_CALLBACK_DECOMP_MIO                  = 35,\n  MSK_CALLBACK_DUAL_SIMPLEX                = 36,\n  MSK_CALLBACK_END_BI                      = 37,\n  MSK_CALLBACK_END_CONIC                   = 38,\n  MSK_CALLBACK_END_DUAL_BI                 = 39,\n  MSK_CALLBACK_END_DUAL_SENSITIVITY        = 40,\n  MSK_CALLBACK_END_DUAL_SETUP_BI           = 41,\n  MSK_CALLBACK_END_DUAL_SIMPLEX            = 42,\n  MSK_CALLBACK_END_DUAL_SIMPLEX_BI         = 43,\n  MSK_CALLBACK_END_FOLDING                 = 44,\n  MSK_CALLBACK_END_FOLDING_BI              = 45,\n  MSK_CALLBACK_END_FOLDING_BI_DUAL         = 46,\n  MSK_CALLBACK_END_FOLDING_BI_INITIALIZE   = 47,\n  MSK_CALLBACK_END_FOLDING_BI_OPTIMIZER    = 48,\n  MSK_CALLBACK_END_FOLDING_BI_PRIMAL       = 49,\n  MSK_CALLBACK_END_INFEAS_ANA              = 50,\n  MSK_CALLBACK_END_INITIALIZE_BI           = 51,\n  MSK_CALLBACK_END_INTPNT                  = 52,\n  MSK_CALLBACK_END_LICENSE_WAIT            = 53,\n  MSK_CALLBACK_END_MIO                     = 54,\n  MSK_CALLBACK_END_OPTIMIZE_BI             = 55,\n  MSK_CALLBACK_END_OPTIMIZER               = 56,\n  MSK_CALLBACK_END_PRESOLVE                = 57,\n  MSK_CALLBACK_END_PRIMAL_BI               = 58,\n  MSK_CALLBACK_END_PRIMAL_REPAIR           = 59,\n  MSK_CALLBACK_END_PRIMAL_SENSITIVITY      = 60,\n  MSK_CALLBACK_END_PRIMAL_SETUP_BI         = 61,\n  MSK_CALLBACK_END_PRIMAL_SIMPLEX          = 62,\n  MSK_CALLBACK_END_PRIMAL_SIMPLEX_BI       = 63,\n  MSK_CALLBACK_END_QCQO_REFORMULATE        = 64,\n  MSK_CALLBACK_END_READ                    = 65,\n  MSK_CALLBACK_END_ROOT_CUTGEN             = 66,\n  MSK_CALLBACK_END_SIMPLEX                 = 67,\n  MSK_CALLBACK_END_SIMPLEX_BI              = 68,\n  MSK_CALLBACK_END_SOLVE_ROOT_RELAX        = 69,\n  MSK_CALLBACK_END_TO_CONIC                = 70,\n  MSK_CALLBACK_END_WRITE                   = 71,\n  MSK_CALLBACK_FOLDING_BI_DUAL             = 72,\n  MSK_CALLBACK_FOLDING_BI_OPTIMIZER        = 73,\n  MSK_CALLBACK_FOLDING_BI_PRIMAL           = 74,\n  MSK_CALLBACK_HEARTBEAT                   = 75,\n  MSK_CALLBACK_IM_DUAL_SENSIVITY           = 76,\n  MSK_CALLBACK_IM_DUAL_SIMPLEX             = 77,\n  MSK_CALLBACK_IM_LICENSE_WAIT             = 78,\n  MSK_CALLBACK_IM_LU                       = 79,\n  MSK_CALLBACK_IM_MIO                      = 80,\n  MSK_CALLBACK_IM_MIO_DUAL_SIMPLEX         = 81,\n  MSK_CALLBACK_IM_MIO_INTPNT               = 82,\n  MSK_CALLBACK_IM_MIO_PRIMAL_SIMPLEX       = 83,\n  MSK_CALLBACK_IM_ORDER                    = 84,\n  MSK_CALLBACK_IM_PRIMAL_SENSIVITY         = 85,\n  MSK_CALLBACK_IM_PRIMAL_SIMPLEX           = 86,\n  MSK_CALLBACK_IM_READ                     = 87,\n  MSK_CALLBACK_IM_ROOT_CUTGEN              = 88,\n  MSK_CALLBACK_IM_SIMPLEX                  = 89,\n  MSK_CALLBACK_INTPNT                      = 90,\n  MSK_CALLBACK_NEW_INT_MIO                 = 91,\n  MSK_CALLBACK_OPTIMIZE_BI                 = 92,\n  MSK_CALLBACK_PRIMAL_SIMPLEX              = 93,\n  MSK_CALLBACK_QO_REFORMULATE              = 94,\n  MSK_CALLBACK_READ_OPF                    = 95,\n  MSK_CALLBACK_READ_OPF_SECTION            = 96,\n  MSK_CALLBACK_RESTART_MIO                 = 97,\n  MSK_CALLBACK_SOLVING_REMOTE              = 98,\n  MSK_CALLBACK_UPDATE_DUAL_BI              = 99,\n  MSK_CALLBACK_UPDATE_DUAL_SIMPLEX         = 100,\n  MSK_CALLBACK_UPDATE_DUAL_SIMPLEX_BI      = 101,\n  MSK_CALLBACK_UPDATE_PRESOLVE             = 102,\n  MSK_CALLBACK_UPDATE_PRIMAL_BI            = 103,\n  MSK_CALLBACK_UPDATE_PRIMAL_SIMPLEX       = 104,\n  MSK_CALLBACK_UPDATE_PRIMAL_SIMPLEX_BI    = 105,\n  MSK_CALLBACK_UPDATE_SIMPLEX              = 106,\n  MSK_CALLBACK_WRITE_OPF                   = 107\n};\n#define MSK_CALLBACK_BEGIN MSK_CALLBACK_BEGIN_BI\n#define MSK_CALLBACK_END   (1+MSK_CALLBACK_WRITE_OPF)\n\n\nenum MSKcompresstype_enum {\n  MSK_COMPRESS_NONE = 0,\n  MSK_COMPRESS_FREE = 1,\n  MSK_COMPRESS_GZIP = 2,\n  MSK_COMPRESS_ZSTD = 3\n};\n#define MSK_COMPRESS_BEGIN MSK_COMPRESS_NONE\n#define MSK_COMPRESS_END   (1+MSK_COMPRESS_ZSTD)\n\n\nenum MSKconetype_enum {\n  MSK_CT_QUAD  = 0,\n  MSK_CT_RQUAD = 1,\n  MSK_CT_PEXP  = 2,\n  MSK_CT_DEXP  = 3,\n  MSK_CT_PPOW  = 4,\n  MSK_CT_DPOW  = 5,\n  MSK_CT_ZERO  = 6\n};\n#define MSK_CT_BEGIN MSK_CT_QUAD\n#define MSK_CT_END   (1+MSK_CT_ZERO)\n\n\nenum MSKdomaintype_enum {\n  MSK_DOMAIN_R                    = 0,\n  MSK_DOMAIN_RZERO                = 1,\n  MSK_DOMAIN_RPLUS                = 2,\n  MSK_DOMAIN_RMINUS               = 3,\n  MSK_DOMAIN_QUADRATIC_CONE       = 4,\n  MSK_DOMAIN_RQUADRATIC_CONE      = 5,\n  MSK_DOMAIN_PRIMAL_EXP_CONE      = 6,\n  MSK_DOMAIN_DUAL_EXP_CONE        = 7,\n  MSK_DOMAIN_PRIMAL_POWER_CONE    = 8,\n  MSK_DOMAIN_DUAL_POWER_CONE      = 9,\n  MSK_DOMAIN_PRIMAL_GEO_MEAN_CONE = 10,\n  MSK_DOMAIN_DUAL_GEO_MEAN_CONE   = 11,\n  MSK_DOMAIN_SVEC_PSD_CONE        = 12\n};\n#define MSK_DOMAIN_BEGIN MSK_DOMAIN_R\n#define MSK_DOMAIN_END   (1+MSK_DOMAIN_SVEC_PSD_CONE)\n\n\nenum MSKnametype_enum {\n  MSK_NAME_TYPE_GEN = 0,\n  MSK_NAME_TYPE_MPS = 1,\n  MSK_NAME_TYPE_LP  = 2\n};\n#define MSK_NAME_TYPE_BEGIN MSK_NAME_TYPE_GEN\n#define MSK_NAME_TYPE_END   (1+MSK_NAME_TYPE_LP)\n\n\nenum MSKsymmattype_enum {\n  MSK_SYMMAT_TYPE_SPARSE = 0\n};\n#define MSK_SYMMAT_TYPE_BEGIN MSK_SYMMAT_TYPE_SPARSE\n#define MSK_SYMMAT_TYPE_END   (1+MSK_SYMMAT_TYPE_SPARSE)\n\n\nenum MSKdataformat_enum {\n  MSK_DATA_FORMAT_EXTENSION = 0,\n  MSK_DATA_FORMAT_MPS       = 1,\n  MSK_DATA_FORMAT_LP        = 2,\n  MSK_DATA_FORMAT_OP        = 3,\n  MSK_DATA_FORMAT_FREE_MPS  = 4,\n  MSK_DATA_FORMAT_TASK      = 5,\n  MSK_DATA_FORMAT_PTF       = 6,\n  MSK_DATA_FORMAT_CB        = 7,\n  MSK_DATA_FORMAT_JSON_TASK = 8\n};\n#define MSK_DATA_FORMAT_BEGIN MSK_DATA_FORMAT_EXTENSION\n#define MSK_DATA_FORMAT_END   (1+MSK_DATA_FORMAT_JSON_TASK)\n\n\nenum MSKsolformat_enum {\n  MSK_SOL_FORMAT_EXTENSION = 0,\n  MSK_SOL_FORMAT_B         = 1,\n  MSK_SOL_FORMAT_TASK      = 2,\n  MSK_SOL_FORMAT_JSON_TASK = 3\n};\n#define MSK_SOL_FORMAT_BEGIN MSK_SOL_FORMAT_EXTENSION\n#define MSK_SOL_FORMAT_END   (1+MSK_SOL_FORMAT_JSON_TASK)\n\n\nenum MSKdinfitem_enum {\n  MSK_DINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_DENSITY   = 0,\n  MSK_DINF_BI_CLEAN_TIME                                  = 1,\n  MSK_DINF_BI_DUAL_TIME                                   = 2,\n  MSK_DINF_BI_PRIMAL_TIME                                 = 3,\n  MSK_DINF_BI_TIME                                        = 4,\n  MSK_DINF_FOLDING_BI_OPTIMIZE_TIME                       = 5,\n  MSK_DINF_FOLDING_BI_UNFOLD_DUAL_TIME                    = 6,\n  MSK_DINF_FOLDING_BI_UNFOLD_INITIALIZE_TIME              = 7,\n  MSK_DINF_FOLDING_BI_UNFOLD_PRIMAL_TIME                  = 8,\n  MSK_DINF_FOLDING_BI_UNFOLD_TIME                         = 9,\n  MSK_DINF_FOLDING_FACTOR                                 = 10,\n  MSK_DINF_FOLDING_TIME                                   = 11,\n  MSK_DINF_INTPNT_DUAL_FEAS                               = 12,\n  MSK_DINF_INTPNT_DUAL_OBJ                                = 13,\n  MSK_DINF_INTPNT_FACTOR_NUM_FLOPS                        = 14,\n  MSK_DINF_INTPNT_OPT_STATUS                              = 15,\n  MSK_DINF_INTPNT_ORDER_TIME                              = 16,\n  MSK_DINF_INTPNT_PRIMAL_FEAS                             = 17,\n  MSK_DINF_INTPNT_PRIMAL_OBJ                              = 18,\n  MSK_DINF_INTPNT_TIME                                    = 19,\n  MSK_DINF_MIO_CLIQUE_SELECTION_TIME                      = 20,\n  MSK_DINF_MIO_CLIQUE_SEPARATION_TIME                     = 21,\n  MSK_DINF_MIO_CMIR_SELECTION_TIME                        = 22,\n  MSK_DINF_MIO_CMIR_SEPARATION_TIME                       = 23,\n  MSK_DINF_MIO_CONSTRUCT_SOLUTION_OBJ                     = 24,\n  MSK_DINF_MIO_DUAL_BOUND_AFTER_PRESOLVE                  = 25,\n  MSK_DINF_MIO_GMI_SELECTION_TIME                         = 26,\n  MSK_DINF_MIO_GMI_SEPARATION_TIME                        = 27,\n  MSK_DINF_MIO_IMPLIED_BOUND_SELECTION_TIME               = 28,\n  MSK_DINF_MIO_IMPLIED_BOUND_SEPARATION_TIME              = 29,\n  MSK_DINF_MIO_INITIAL_FEASIBLE_SOLUTION_OBJ              = 30,\n  MSK_DINF_MIO_KNAPSACK_COVER_SELECTION_TIME              = 31,\n  MSK_DINF_MIO_KNAPSACK_COVER_SEPARATION_TIME             = 32,\n  MSK_DINF_MIO_LIPRO_SELECTION_TIME                       = 33,\n  MSK_DINF_MIO_LIPRO_SEPARATION_TIME                      = 34,\n  MSK_DINF_MIO_OBJ_ABS_GAP                                = 35,\n  MSK_DINF_MIO_OBJ_BOUND                                  = 36,\n  MSK_DINF_MIO_OBJ_INT                                    = 37,\n  MSK_DINF_MIO_OBJ_REL_GAP                                = 38,\n  MSK_DINF_MIO_PROBING_TIME                               = 39,\n  MSK_DINF_MIO_ROOT_CUT_SELECTION_TIME                    = 40,\n  MSK_DINF_MIO_ROOT_CUT_SEPARATION_TIME                   = 41,\n  MSK_DINF_MIO_ROOT_OPTIMIZER_TIME                        = 42,\n  MSK_DINF_MIO_ROOT_PRESOLVE_TIME                         = 43,\n  MSK_DINF_MIO_ROOT_TIME                                  = 44,\n  MSK_DINF_MIO_SYMMETRY_DETECTION_TIME                    = 45,\n  MSK_DINF_MIO_SYMMETRY_FACTOR                            = 46,\n  MSK_DINF_MIO_TIME                                       = 47,\n  MSK_DINF_MIO_USER_OBJ_CUT                               = 48,\n  MSK_DINF_OPTIMIZER_TICKS                                = 49,\n  MSK_DINF_OPTIMIZER_TIME                                 = 50,\n  MSK_DINF_PRESOLVE_ELI_TIME                              = 51,\n  MSK_DINF_PRESOLVE_LINDEP_TIME                           = 52,\n  MSK_DINF_PRESOLVE_TIME                                  = 53,\n  MSK_DINF_PRESOLVE_TOTAL_PRIMAL_PERTURBATION             = 54,\n  MSK_DINF_PRIMAL_REPAIR_PENALTY_OBJ                      = 55,\n  MSK_DINF_QCQO_REFORMULATE_MAX_PERTURBATION              = 56,\n  MSK_DINF_QCQO_REFORMULATE_TIME                          = 57,\n  MSK_DINF_QCQO_REFORMULATE_WORST_CHOLESKY_COLUMN_SCALING = 58,\n  MSK_DINF_QCQO_REFORMULATE_WORST_CHOLESKY_DIAG_SCALING   = 59,\n  MSK_DINF_READ_DATA_TIME                                 = 60,\n  MSK_DINF_REMOTE_TIME                                    = 61,\n  MSK_DINF_SIM_DUAL_TIME                                  = 62,\n  MSK_DINF_SIM_FEAS                                       = 63,\n  MSK_DINF_SIM_OBJ                                        = 64,\n  MSK_DINF_SIM_PRIMAL_TIME                                = 65,\n  MSK_DINF_SIM_TIME                                       = 66,\n  MSK_DINF_SOL_BAS_DUAL_OBJ                               = 67,\n  MSK_DINF_SOL_BAS_DVIOLCON                               = 68,\n  MSK_DINF_SOL_BAS_DVIOLVAR                               = 69,\n  MSK_DINF_SOL_BAS_NRM_BARX                               = 70,\n  MSK_DINF_SOL_BAS_NRM_SLC                                = 71,\n  MSK_DINF_SOL_BAS_NRM_SLX                                = 72,\n  MSK_DINF_SOL_BAS_NRM_SUC                                = 73,\n  MSK_DINF_SOL_BAS_NRM_SUX                                = 74,\n  MSK_DINF_SOL_BAS_NRM_XC                                 = 75,\n  MSK_DINF_SOL_BAS_NRM_XX                                 = 76,\n  MSK_DINF_SOL_BAS_NRM_Y                                  = 77,\n  MSK_DINF_SOL_BAS_PRIMAL_OBJ                             = 78,\n  MSK_DINF_SOL_BAS_PVIOLCON                               = 79,\n  MSK_DINF_SOL_BAS_PVIOLVAR                               = 80,\n  MSK_DINF_SOL_ITG_NRM_BARX                               = 81,\n  MSK_DINF_SOL_ITG_NRM_XC                                 = 82,\n  MSK_DINF_SOL_ITG_NRM_XX                                 = 83,\n  MSK_DINF_SOL_ITG_PRIMAL_OBJ                             = 84,\n  MSK_DINF_SOL_ITG_PVIOLACC                               = 85,\n  MSK_DINF_SOL_ITG_PVIOLBARVAR                            = 86,\n  MSK_DINF_SOL_ITG_PVIOLCON                               = 87,\n  MSK_DINF_SOL_ITG_PVIOLCONES                             = 88,\n  MSK_DINF_SOL_ITG_PVIOLDJC                               = 89,\n  MSK_DINF_SOL_ITG_PVIOLITG                               = 90,\n  MSK_DINF_SOL_ITG_PVIOLVAR                               = 91,\n  MSK_DINF_SOL_ITR_DUAL_OBJ                               = 92,\n  MSK_DINF_SOL_ITR_DVIOLACC                               = 93,\n  MSK_DINF_SOL_ITR_DVIOLBARVAR                            = 94,\n  MSK_DINF_SOL_ITR_DVIOLCON                               = 95,\n  MSK_DINF_SOL_ITR_DVIOLCONES                             = 96,\n  MSK_DINF_SOL_ITR_DVIOLVAR                               = 97,\n  MSK_DINF_SOL_ITR_NRM_BARS                               = 98,\n  MSK_DINF_SOL_ITR_NRM_BARX                               = 99,\n  MSK_DINF_SOL_ITR_NRM_SLC                                = 100,\n  MSK_DINF_SOL_ITR_NRM_SLX                                = 101,\n  MSK_DINF_SOL_ITR_NRM_SNX                                = 102,\n  MSK_DINF_SOL_ITR_NRM_SUC                                = 103,\n  MSK_DINF_SOL_ITR_NRM_SUX                                = 104,\n  MSK_DINF_SOL_ITR_NRM_XC                                 = 105,\n  MSK_DINF_SOL_ITR_NRM_XX                                 = 106,\n  MSK_DINF_SOL_ITR_NRM_Y                                  = 107,\n  MSK_DINF_SOL_ITR_PRIMAL_OBJ                             = 108,\n  MSK_DINF_SOL_ITR_PVIOLACC                               = 109,\n  MSK_DINF_SOL_ITR_PVIOLBARVAR                            = 110,\n  MSK_DINF_SOL_ITR_PVIOLCON                               = 111,\n  MSK_DINF_SOL_ITR_PVIOLCONES                             = 112,\n  MSK_DINF_SOL_ITR_PVIOLVAR                               = 113,\n  MSK_DINF_TO_CONIC_TIME                                  = 114,\n  MSK_DINF_WRITE_DATA_TIME                                = 115\n};\n#define MSK_DINF_BEGIN MSK_DINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_DENSITY\n#define MSK_DINF_END   (1+MSK_DINF_WRITE_DATA_TIME)\n\n\nenum MSKfeature_enum {\n  MSK_FEATURE_PTS  = 0,\n  MSK_FEATURE_PTON = 1\n};\n#define MSK_FEATURE_BEGIN MSK_FEATURE_PTS\n#define MSK_FEATURE_END   (1+MSK_FEATURE_PTON)\n\n\nenum MSKdparam_enum {\n  MSK_DPAR_ANA_SOL_INFEAS_TOL                      = 0,\n  MSK_DPAR_BASIS_REL_TOL_S                         = 1,\n  MSK_DPAR_BASIS_TOL_S                             = 2,\n  MSK_DPAR_BASIS_TOL_X                             = 3,\n  MSK_DPAR_DATA_SYM_MAT_TOL                        = 4,\n  MSK_DPAR_DATA_SYM_MAT_TOL_HUGE                   = 5,\n  MSK_DPAR_DATA_SYM_MAT_TOL_LARGE                  = 6,\n  MSK_DPAR_DATA_TOL_AIJ_HUGE                       = 7,\n  MSK_DPAR_DATA_TOL_AIJ_LARGE                      = 8,\n  MSK_DPAR_DATA_TOL_BOUND_INF                      = 9,\n  MSK_DPAR_DATA_TOL_BOUND_WRN                      = 10,\n  MSK_DPAR_DATA_TOL_C_HUGE                         = 11,\n  MSK_DPAR_DATA_TOL_CJ_LARGE                       = 12,\n  MSK_DPAR_DATA_TOL_QIJ                            = 13,\n  MSK_DPAR_DATA_TOL_X                              = 14,\n  MSK_DPAR_FOLDING_TOL_EQ                          = 15,\n  MSK_DPAR_INTPNT_CO_TOL_DFEAS                     = 16,\n  MSK_DPAR_INTPNT_CO_TOL_INFEAS                    = 17,\n  MSK_DPAR_INTPNT_CO_TOL_MU_RED                    = 18,\n  MSK_DPAR_INTPNT_CO_TOL_NEAR_REL                  = 19,\n  MSK_DPAR_INTPNT_CO_TOL_PFEAS                     = 20,\n  MSK_DPAR_INTPNT_CO_TOL_REL_GAP                   = 21,\n  MSK_DPAR_INTPNT_QO_TOL_DFEAS                     = 22,\n  MSK_DPAR_INTPNT_QO_TOL_INFEAS                    = 23,\n  MSK_DPAR_INTPNT_QO_TOL_MU_RED                    = 24,\n  MSK_DPAR_INTPNT_QO_TOL_NEAR_REL                  = 25,\n  MSK_DPAR_INTPNT_QO_TOL_PFEAS                     = 26,\n  MSK_DPAR_INTPNT_QO_TOL_REL_GAP                   = 27,\n  MSK_DPAR_INTPNT_TOL_DFEAS                        = 28,\n  MSK_DPAR_INTPNT_TOL_DSAFE                        = 29,\n  MSK_DPAR_INTPNT_TOL_INFEAS                       = 30,\n  MSK_DPAR_INTPNT_TOL_MU_RED                       = 31,\n  MSK_DPAR_INTPNT_TOL_PATH                         = 32,\n  MSK_DPAR_INTPNT_TOL_PFEAS                        = 33,\n  MSK_DPAR_INTPNT_TOL_PSAFE                        = 34,\n  MSK_DPAR_INTPNT_TOL_REL_GAP                      = 35,\n  MSK_DPAR_INTPNT_TOL_REL_STEP                     = 36,\n  MSK_DPAR_INTPNT_TOL_STEP_SIZE                    = 37,\n  MSK_DPAR_LOWER_OBJ_CUT                           = 38,\n  MSK_DPAR_LOWER_OBJ_CUT_FINITE_TRH                = 39,\n  MSK_DPAR_MIO_CLIQUE_TABLE_SIZE_FACTOR            = 40,\n  MSK_DPAR_MIO_DJC_MAX_BIGM                        = 41,\n  MSK_DPAR_MIO_MAX_TIME                            = 42,\n  MSK_DPAR_MIO_REL_GAP_CONST                       = 43,\n  MSK_DPAR_MIO_TOL_ABS_GAP                         = 44,\n  MSK_DPAR_MIO_TOL_ABS_RELAX_INT                   = 45,\n  MSK_DPAR_MIO_TOL_FEAS                            = 46,\n  MSK_DPAR_MIO_TOL_REL_DUAL_BOUND_IMPROVEMENT      = 47,\n  MSK_DPAR_MIO_TOL_REL_GAP                         = 48,\n  MSK_DPAR_OPTIMIZER_MAX_TICKS                     = 49,\n  MSK_DPAR_OPTIMIZER_MAX_TIME                      = 50,\n  MSK_DPAR_PRESOLVE_TOL_ABS_LINDEP                 = 51,\n  MSK_DPAR_PRESOLVE_TOL_PRIMAL_INFEAS_PERTURBATION = 52,\n  MSK_DPAR_PRESOLVE_TOL_REL_LINDEP                 = 53,\n  MSK_DPAR_PRESOLVE_TOL_S                          = 54,\n  MSK_DPAR_PRESOLVE_TOL_X                          = 55,\n  MSK_DPAR_QCQO_REFORMULATE_REL_DROP_TOL           = 56,\n  MSK_DPAR_SEMIDEFINITE_TOL_APPROX                 = 57,\n  MSK_DPAR_SIM_LU_TOL_REL_PIV                      = 58,\n  MSK_DPAR_SIM_PRECISION_SCALING_EXTENDED          = 59,\n  MSK_DPAR_SIM_PRECISION_SCALING_NORMAL            = 60,\n  MSK_DPAR_SIMPLEX_ABS_TOL_PIV                     = 61,\n  MSK_DPAR_UPPER_OBJ_CUT                           = 62,\n  MSK_DPAR_UPPER_OBJ_CUT_FINITE_TRH                = 63\n};\n#define MSK_DPAR_BEGIN MSK_DPAR_ANA_SOL_INFEAS_TOL\n#define MSK_DPAR_END   (1+MSK_DPAR_UPPER_OBJ_CUT_FINITE_TRH)\n\n\nenum MSKliinfitem_enum {\n  MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_COLUMNS = 0,\n  MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_NZ      = 1,\n  MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_ROWS    = 2,\n  MSK_LIINF_BI_CLEAN_ITER                                    = 3,\n  MSK_LIINF_BI_DUAL_ITER                                     = 4,\n  MSK_LIINF_BI_PRIMAL_ITER                                   = 5,\n  MSK_LIINF_FOLDING_BI_DUAL_ITER                             = 6,\n  MSK_LIINF_FOLDING_BI_OPTIMIZER_ITER                        = 7,\n  MSK_LIINF_FOLDING_BI_PRIMAL_ITER                           = 8,\n  MSK_LIINF_INTPNT_FACTOR_NUM_NZ                             = 9,\n  MSK_LIINF_MIO_ANZ                                          = 10,\n  MSK_LIINF_MIO_FINAL_ANZ                                    = 11,\n  MSK_LIINF_MIO_INTPNT_ITER                                  = 12,\n  MSK_LIINF_MIO_NUM_DUAL_ILLPOSED_CER                        = 13,\n  MSK_LIINF_MIO_NUM_PRIM_ILLPOSED_CER                        = 14,\n  MSK_LIINF_MIO_PRESOLVED_ANZ                                = 15,\n  MSK_LIINF_MIO_SIMPLEX_ITER                                 = 16,\n  MSK_LIINF_RD_NUMACC                                        = 17,\n  MSK_LIINF_RD_NUMANZ                                        = 18,\n  MSK_LIINF_RD_NUMDJC                                        = 19,\n  MSK_LIINF_RD_NUMQNZ                                        = 20,\n  MSK_LIINF_SIMPLEX_ITER                                     = 21\n};\n#define MSK_LIINF_BEGIN MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_COLUMNS\n#define MSK_LIINF_END   (1+MSK_LIINF_SIMPLEX_ITER)\n\n\nenum MSKiinfitem_enum {\n  MSK_IINF_ANA_PRO_NUM_CON                       = 0,\n  MSK_IINF_ANA_PRO_NUM_CON_EQ                    = 1,\n  MSK_IINF_ANA_PRO_NUM_CON_FR                    = 2,\n  MSK_IINF_ANA_PRO_NUM_CON_LO                    = 3,\n  MSK_IINF_ANA_PRO_NUM_CON_RA                    = 4,\n  MSK_IINF_ANA_PRO_NUM_CON_UP                    = 5,\n  MSK_IINF_ANA_PRO_NUM_VAR                       = 6,\n  MSK_IINF_ANA_PRO_NUM_VAR_BIN                   = 7,\n  MSK_IINF_ANA_PRO_NUM_VAR_CONT                  = 8,\n  MSK_IINF_ANA_PRO_NUM_VAR_EQ                    = 9,\n  MSK_IINF_ANA_PRO_NUM_VAR_FR                    = 10,\n  MSK_IINF_ANA_PRO_NUM_VAR_INT                   = 11,\n  MSK_IINF_ANA_PRO_NUM_VAR_LO                    = 12,\n  MSK_IINF_ANA_PRO_NUM_VAR_RA                    = 13,\n  MSK_IINF_ANA_PRO_NUM_VAR_UP                    = 14,\n  MSK_IINF_FOLDING_APPLIED                       = 15,\n  MSK_IINF_INTPNT_FACTOR_DIM_DENSE               = 16,\n  MSK_IINF_INTPNT_ITER                           = 17,\n  MSK_IINF_INTPNT_NUM_THREADS                    = 18,\n  MSK_IINF_INTPNT_SOLVE_DUAL                     = 19,\n  MSK_IINF_MIO_ABSGAP_SATISFIED                  = 20,\n  MSK_IINF_MIO_CLIQUE_TABLE_SIZE                 = 21,\n  MSK_IINF_MIO_CONSTRUCT_SOLUTION                = 22,\n  MSK_IINF_MIO_FINAL_NUMBIN                      = 23,\n  MSK_IINF_MIO_FINAL_NUMBINCONEVAR               = 24,\n  MSK_IINF_MIO_FINAL_NUMCON                      = 25,\n  MSK_IINF_MIO_FINAL_NUMCONE                     = 26,\n  MSK_IINF_MIO_FINAL_NUMCONEVAR                  = 27,\n  MSK_IINF_MIO_FINAL_NUMCONT                     = 28,\n  MSK_IINF_MIO_FINAL_NUMCONTCONEVAR              = 29,\n  MSK_IINF_MIO_FINAL_NUMDEXPCONES                = 30,\n  MSK_IINF_MIO_FINAL_NUMDJC                      = 31,\n  MSK_IINF_MIO_FINAL_NUMDPOWCONES                = 32,\n  MSK_IINF_MIO_FINAL_NUMINT                      = 33,\n  MSK_IINF_MIO_FINAL_NUMINTCONEVAR               = 34,\n  MSK_IINF_MIO_FINAL_NUMPEXPCONES                = 35,\n  MSK_IINF_MIO_FINAL_NUMPPOWCONES                = 36,\n  MSK_IINF_MIO_FINAL_NUMQCONES                   = 37,\n  MSK_IINF_MIO_FINAL_NUMRQCONES                  = 38,\n  MSK_IINF_MIO_FINAL_NUMVAR                      = 39,\n  MSK_IINF_MIO_INITIAL_FEASIBLE_SOLUTION         = 40,\n  MSK_IINF_MIO_NODE_DEPTH                        = 41,\n  MSK_IINF_MIO_NUM_ACTIVE_NODES                  = 42,\n  MSK_IINF_MIO_NUM_ACTIVE_ROOT_CUTS              = 43,\n  MSK_IINF_MIO_NUM_BLOCKS_SOLVED_IN_BB           = 44,\n  MSK_IINF_MIO_NUM_BLOCKS_SOLVED_IN_PRESOLVE     = 45,\n  MSK_IINF_MIO_NUM_BRANCH                        = 46,\n  MSK_IINF_MIO_NUM_INT_SOLUTIONS                 = 47,\n  MSK_IINF_MIO_NUM_RELAX                         = 48,\n  MSK_IINF_MIO_NUM_REPEATED_PRESOLVE             = 49,\n  MSK_IINF_MIO_NUM_RESTARTS                      = 50,\n  MSK_IINF_MIO_NUM_ROOT_CUT_ROUNDS               = 51,\n  MSK_IINF_MIO_NUM_SELECTED_CLIQUE_CUTS          = 52,\n  MSK_IINF_MIO_NUM_SELECTED_CMIR_CUTS            = 53,\n  MSK_IINF_MIO_NUM_SELECTED_GOMORY_CUTS          = 54,\n  MSK_IINF_MIO_NUM_SELECTED_IMPLIED_BOUND_CUTS   = 55,\n  MSK_IINF_MIO_NUM_SELECTED_KNAPSACK_COVER_CUTS  = 56,\n  MSK_IINF_MIO_NUM_SELECTED_LIPRO_CUTS           = 57,\n  MSK_IINF_MIO_NUM_SEPARATED_CLIQUE_CUTS         = 58,\n  MSK_IINF_MIO_NUM_SEPARATED_CMIR_CUTS           = 59,\n  MSK_IINF_MIO_NUM_SEPARATED_GOMORY_CUTS         = 60,\n  MSK_IINF_MIO_NUM_SEPARATED_IMPLIED_BOUND_CUTS  = 61,\n  MSK_IINF_MIO_NUM_SEPARATED_KNAPSACK_COVER_CUTS = 62,\n  MSK_IINF_MIO_NUM_SEPARATED_LIPRO_CUTS          = 63,\n  MSK_IINF_MIO_NUM_SOLVED_NODES                  = 64,\n  MSK_IINF_MIO_NUMBIN                            = 65,\n  MSK_IINF_MIO_NUMBINCONEVAR                     = 66,\n  MSK_IINF_MIO_NUMCON                            = 67,\n  MSK_IINF_MIO_NUMCONE                           = 68,\n  MSK_IINF_MIO_NUMCONEVAR                        = 69,\n  MSK_IINF_MIO_NUMCONT                           = 70,\n  MSK_IINF_MIO_NUMCONTCONEVAR                    = 71,\n  MSK_IINF_MIO_NUMDEXPCONES                      = 72,\n  MSK_IINF_MIO_NUMDJC                            = 73,\n  MSK_IINF_MIO_NUMDPOWCONES                      = 74,\n  MSK_IINF_MIO_NUMINT                            = 75,\n  MSK_IINF_MIO_NUMINTCONEVAR                     = 76,\n  MSK_IINF_MIO_NUMPEXPCONES                      = 77,\n  MSK_IINF_MIO_NUMPPOWCONES                      = 78,\n  MSK_IINF_MIO_NUMQCONES                         = 79,\n  MSK_IINF_MIO_NUMRQCONES                        = 80,\n  MSK_IINF_MIO_NUMVAR                            = 81,\n  MSK_IINF_MIO_OBJ_BOUND_DEFINED                 = 82,\n  MSK_IINF_MIO_PRESOLVED_NUMBIN                  = 83,\n  MSK_IINF_MIO_PRESOLVED_NUMBINCONEVAR           = 84,\n  MSK_IINF_MIO_PRESOLVED_NUMCON                  = 85,\n  MSK_IINF_MIO_PRESOLVED_NUMCONE                 = 86,\n  MSK_IINF_MIO_PRESOLVED_NUMCONEVAR              = 87,\n  MSK_IINF_MIO_PRESOLVED_NUMCONT                 = 88,\n  MSK_IINF_MIO_PRESOLVED_NUMCONTCONEVAR          = 89,\n  MSK_IINF_MIO_PRESOLVED_NUMDEXPCONES            = 90,\n  MSK_IINF_MIO_PRESOLVED_NUMDJC                  = 91,\n  MSK_IINF_MIO_PRESOLVED_NUMDPOWCONES            = 92,\n  MSK_IINF_MIO_PRESOLVED_NUMINT                  = 93,\n  MSK_IINF_MIO_PRESOLVED_NUMINTCONEVAR           = 94,\n  MSK_IINF_MIO_PRESOLVED_NUMPEXPCONES            = 95,\n  MSK_IINF_MIO_PRESOLVED_NUMPPOWCONES            = 96,\n  MSK_IINF_MIO_PRESOLVED_NUMQCONES               = 97,\n  MSK_IINF_MIO_PRESOLVED_NUMRQCONES              = 98,\n  MSK_IINF_MIO_PRESOLVED_NUMVAR                  = 99,\n  MSK_IINF_MIO_RELGAP_SATISFIED                  = 100,\n  MSK_IINF_MIO_TOTAL_NUM_SELECTED_CUTS           = 101,\n  MSK_IINF_MIO_TOTAL_NUM_SEPARATED_CUTS          = 102,\n  MSK_IINF_MIO_USER_OBJ_CUT                      = 103,\n  MSK_IINF_OPT_NUMCON                            = 104,\n  MSK_IINF_OPT_NUMVAR                            = 105,\n  MSK_IINF_OPTIMIZE_RESPONSE                     = 106,\n  MSK_IINF_PRESOLVE_NUM_PRIMAL_PERTURBATIONS     = 107,\n  MSK_IINF_PURIFY_DUAL_SUCCESS                   = 108,\n  MSK_IINF_PURIFY_PRIMAL_SUCCESS                 = 109,\n  MSK_IINF_RD_NUMBARVAR                          = 110,\n  MSK_IINF_RD_NUMCON                             = 111,\n  MSK_IINF_RD_NUMCONE                            = 112,\n  MSK_IINF_RD_NUMINTVAR                          = 113,\n  MSK_IINF_RD_NUMQ                               = 114,\n  MSK_IINF_RD_NUMVAR                             = 115,\n  MSK_IINF_RD_PROTYPE                            = 116,\n  MSK_IINF_SIM_DUAL_DEG_ITER                     = 117,\n  MSK_IINF_SIM_DUAL_HOTSTART                     = 118,\n  MSK_IINF_SIM_DUAL_HOTSTART_LU                  = 119,\n  MSK_IINF_SIM_DUAL_INF_ITER                     = 120,\n  MSK_IINF_SIM_DUAL_ITER                         = 121,\n  MSK_IINF_SIM_NUMCON                            = 122,\n  MSK_IINF_SIM_NUMVAR                            = 123,\n  MSK_IINF_SIM_PRIMAL_DEG_ITER                   = 124,\n  MSK_IINF_SIM_PRIMAL_HOTSTART                   = 125,\n  MSK_IINF_SIM_PRIMAL_HOTSTART_LU                = 126,\n  MSK_IINF_SIM_PRIMAL_INF_ITER                   = 127,\n  MSK_IINF_SIM_PRIMAL_ITER                       = 128,\n  MSK_IINF_SIM_SOLVE_DUAL                        = 129,\n  MSK_IINF_SOL_BAS_PROSTA                        = 130,\n  MSK_IINF_SOL_BAS_SOLSTA                        = 131,\n  MSK_IINF_SOL_ITG_PROSTA                        = 132,\n  MSK_IINF_SOL_ITG_SOLSTA                        = 133,\n  MSK_IINF_SOL_ITR_PROSTA                        = 134,\n  MSK_IINF_SOL_ITR_SOLSTA                        = 135,\n  MSK_IINF_STO_NUM_A_REALLOC                     = 136\n};\n#define MSK_IINF_BEGIN MSK_IINF_ANA_PRO_NUM_CON\n#define MSK_IINF_END   (1+MSK_IINF_STO_NUM_A_REALLOC)\n\n\nenum MSKinftype_enum {\n  MSK_INF_DOU_TYPE  = 0,\n  MSK_INF_INT_TYPE  = 1,\n  MSK_INF_LINT_TYPE = 2\n};\n#define MSK_INF_BEGIN MSK_INF_DOU_TYPE\n#define MSK_INF_END   (1+MSK_INF_LINT_TYPE)\n\n\nenum MSKiomode_enum {\n  MSK_IOMODE_READ      = 0,\n  MSK_IOMODE_WRITE     = 1,\n  MSK_IOMODE_READWRITE = 2\n};\n#define MSK_IOMODE_BEGIN MSK_IOMODE_READ\n#define MSK_IOMODE_END   (1+MSK_IOMODE_READWRITE)\n\n\nenum MSKiparam_enum {\n  MSK_IPAR_ANA_SOL_BASIS                      = 0,\n  MSK_IPAR_ANA_SOL_PRINT_VIOLATED             = 1,\n  MSK_IPAR_AUTO_SORT_A_BEFORE_OPT             = 2,\n  MSK_IPAR_AUTO_UPDATE_SOL_INFO               = 3,\n  MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE           = 4,\n  MSK_IPAR_BI_CLEAN_OPTIMIZER                 = 5,\n  MSK_IPAR_BI_IGNORE_MAX_ITER                 = 6,\n  MSK_IPAR_BI_IGNORE_NUM_ERROR                = 7,\n  MSK_IPAR_BI_MAX_ITERATIONS                  = 8,\n  MSK_IPAR_CACHE_LICENSE                      = 9,\n  MSK_IPAR_COMPRESS_STATFILE                  = 10,\n  MSK_IPAR_FOLDING_USE                        = 11,\n  MSK_IPAR_GETDUAL_CONVERT_LMIS               = 12,\n  MSK_IPAR_HEARTBEAT_SIM_FREQ_TICKS           = 13,\n  MSK_IPAR_INFEAS_GENERIC_NAMES               = 14,\n  MSK_IPAR_INFEAS_REPORT_AUTO                 = 15,\n  MSK_IPAR_INFEAS_REPORT_LEVEL                = 16,\n  MSK_IPAR_INTPNT_BASIS                       = 17,\n  MSK_IPAR_INTPNT_DIFF_STEP                   = 18,\n  MSK_IPAR_INTPNT_HOTSTART                    = 19,\n  MSK_IPAR_INTPNT_MAX_ITERATIONS              = 20,\n  MSK_IPAR_INTPNT_MAX_NUM_COR                 = 21,\n  MSK_IPAR_INTPNT_OFF_COL_TRH                 = 22,\n  MSK_IPAR_INTPNT_ORDER_GP_NUM_SEEDS          = 23,\n  MSK_IPAR_INTPNT_ORDER_METHOD                = 24,\n  MSK_IPAR_INTPNT_REGULARIZATION_USE          = 25,\n  MSK_IPAR_INTPNT_SCALING                     = 26,\n  MSK_IPAR_INTPNT_SOLVE_FORM                  = 27,\n  MSK_IPAR_INTPNT_STARTING_POINT              = 28,\n  MSK_IPAR_LICENSE_DEBUG                      = 29,\n  MSK_IPAR_LICENSE_PAUSE_TIME                 = 30,\n  MSK_IPAR_LICENSE_SUPPRESS_EXPIRE_WRNS       = 31,\n  MSK_IPAR_LICENSE_TRH_EXPIRY_WRN             = 32,\n  MSK_IPAR_LICENSE_WAIT                       = 33,\n  MSK_IPAR_LOG                                = 34,\n  MSK_IPAR_LOG_ANA_PRO                        = 35,\n  MSK_IPAR_LOG_BI                             = 36,\n  MSK_IPAR_LOG_BI_FREQ                        = 37,\n  MSK_IPAR_LOG_CUT_SECOND_OPT                 = 38,\n  MSK_IPAR_LOG_EXPAND                         = 39,\n  MSK_IPAR_LOG_FEAS_REPAIR                    = 40,\n  MSK_IPAR_LOG_FILE                           = 41,\n  MSK_IPAR_LOG_INCLUDE_SUMMARY                = 42,\n  MSK_IPAR_LOG_INFEAS_ANA                     = 43,\n  MSK_IPAR_LOG_INTPNT                         = 44,\n  MSK_IPAR_LOG_LOCAL_INFO                     = 45,\n  MSK_IPAR_LOG_MIO                            = 46,\n  MSK_IPAR_LOG_MIO_FREQ                       = 47,\n  MSK_IPAR_LOG_ORDER                          = 48,\n  MSK_IPAR_LOG_PRESOLVE                       = 49,\n  MSK_IPAR_LOG_SENSITIVITY                    = 50,\n  MSK_IPAR_LOG_SENSITIVITY_OPT                = 51,\n  MSK_IPAR_LOG_SIM                            = 52,\n  MSK_IPAR_LOG_SIM_FREQ                       = 53,\n  MSK_IPAR_LOG_SIM_FREQ_GIGA_TICKS            = 54,\n  MSK_IPAR_LOG_STORAGE                        = 55,\n  MSK_IPAR_MAX_NUM_WARNINGS                   = 56,\n  MSK_IPAR_MIO_BRANCH_DIR                     = 57,\n  MSK_IPAR_MIO_CONFLICT_ANALYSIS_LEVEL        = 58,\n  MSK_IPAR_MIO_CONIC_OUTER_APPROXIMATION      = 59,\n  MSK_IPAR_MIO_CONSTRUCT_SOL                  = 60,\n  MSK_IPAR_MIO_CROSSOVER_MAX_NODES            = 61,\n  MSK_IPAR_MIO_CUT_CLIQUE                     = 62,\n  MSK_IPAR_MIO_CUT_CMIR                       = 63,\n  MSK_IPAR_MIO_CUT_GMI                        = 64,\n  MSK_IPAR_MIO_CUT_IMPLIED_BOUND              = 65,\n  MSK_IPAR_MIO_CUT_KNAPSACK_COVER             = 66,\n  MSK_IPAR_MIO_CUT_LIPRO                      = 67,\n  MSK_IPAR_MIO_CUT_SELECTION_LEVEL            = 68,\n  MSK_IPAR_MIO_DATA_PERMUTATION_METHOD        = 69,\n  MSK_IPAR_MIO_DUAL_RAY_ANALYSIS_LEVEL        = 70,\n  MSK_IPAR_MIO_FEASPUMP_LEVEL                 = 71,\n  MSK_IPAR_MIO_HEURISTIC_LEVEL                = 72,\n  MSK_IPAR_MIO_INDEPENDENT_BLOCK_LEVEL        = 73,\n  MSK_IPAR_MIO_MAX_NUM_BRANCHES               = 74,\n  MSK_IPAR_MIO_MAX_NUM_RELAXS                 = 75,\n  MSK_IPAR_MIO_MAX_NUM_RESTARTS               = 76,\n  MSK_IPAR_MIO_MAX_NUM_ROOT_CUT_ROUNDS        = 77,\n  MSK_IPAR_MIO_MAX_NUM_SOLUTIONS              = 78,\n  MSK_IPAR_MIO_MEMORY_EMPHASIS_LEVEL          = 79,\n  MSK_IPAR_MIO_MIN_REL                        = 80,\n  MSK_IPAR_MIO_MODE                           = 81,\n  MSK_IPAR_MIO_NODE_OPTIMIZER                 = 82,\n  MSK_IPAR_MIO_NODE_SELECTION                 = 83,\n  MSK_IPAR_MIO_NUMERICAL_EMPHASIS_LEVEL       = 84,\n  MSK_IPAR_MIO_OPT_FACE_MAX_NODES             = 85,\n  MSK_IPAR_MIO_PERSPECTIVE_REFORMULATE        = 86,\n  MSK_IPAR_MIO_PRESOLVE_AGGREGATOR_USE        = 87,\n  MSK_IPAR_MIO_PROBING_LEVEL                  = 88,\n  MSK_IPAR_MIO_PROPAGATE_OBJECTIVE_CONSTRAINT = 89,\n  MSK_IPAR_MIO_QCQO_REFORMULATION_METHOD      = 90,\n  MSK_IPAR_MIO_RENS_MAX_NODES                 = 91,\n  MSK_IPAR_MIO_RINS_MAX_NODES                 = 92,\n  MSK_IPAR_MIO_ROOT_OPTIMIZER                 = 93,\n  MSK_IPAR_MIO_SEED                           = 94,\n  MSK_IPAR_MIO_SYMMETRY_LEVEL                 = 95,\n  MSK_IPAR_MIO_VAR_SELECTION                  = 96,\n  MSK_IPAR_MIO_VB_DETECTION_LEVEL             = 97,\n  MSK_IPAR_MT_SPINCOUNT                       = 98,\n  MSK_IPAR_NG                                 = 99,\n  MSK_IPAR_NUM_THREADS                        = 100,\n  MSK_IPAR_OPF_WRITE_HEADER                   = 101,\n  MSK_IPAR_OPF_WRITE_HINTS                    = 102,\n  MSK_IPAR_OPF_WRITE_LINE_LENGTH              = 103,\n  MSK_IPAR_OPF_WRITE_PARAMETERS               = 104,\n  MSK_IPAR_OPF_WRITE_PROBLEM                  = 105,\n  MSK_IPAR_OPF_WRITE_SOL_BAS                  = 106,\n  MSK_IPAR_OPF_WRITE_SOL_ITG                  = 107,\n  MSK_IPAR_OPF_WRITE_SOL_ITR                  = 108,\n  MSK_IPAR_OPF_WRITE_SOLUTIONS                = 109,\n  MSK_IPAR_OPTIMIZER                          = 110,\n  MSK_IPAR_PARAM_READ_CASE_NAME               = 111,\n  MSK_IPAR_PARAM_READ_IGN_ERROR               = 112,\n  MSK_IPAR_PRESOLVE_ELIMINATOR_MAX_FILL       = 113,\n  MSK_IPAR_PRESOLVE_ELIMINATOR_MAX_NUM_TRIES  = 114,\n  MSK_IPAR_PRESOLVE_LINDEP_ABS_WORK_TRH       = 115,\n  MSK_IPAR_PRESOLVE_LINDEP_NEW                = 116,\n  MSK_IPAR_PRESOLVE_LINDEP_REL_WORK_TRH       = 117,\n  MSK_IPAR_PRESOLVE_LINDEP_USE                = 118,\n  MSK_IPAR_PRESOLVE_MAX_NUM_PASS              = 119,\n  MSK_IPAR_PRESOLVE_MAX_NUM_REDUCTIONS        = 120,\n  MSK_IPAR_PRESOLVE_USE                       = 121,\n  MSK_IPAR_PRIMAL_REPAIR_OPTIMIZER            = 122,\n  MSK_IPAR_PTF_WRITE_PARAMETERS               = 123,\n  MSK_IPAR_PTF_WRITE_SINGLE_PSD_TERMS         = 124,\n  MSK_IPAR_PTF_WRITE_SOLUTIONS                = 125,\n  MSK_IPAR_PTF_WRITE_TRANSFORM                = 126,\n  MSK_IPAR_READ_ASYNC                         = 127,\n  MSK_IPAR_READ_DEBUG                         = 128,\n  MSK_IPAR_READ_KEEP_FREE_CON                 = 129,\n  MSK_IPAR_READ_MPS_FORMAT                    = 130,\n  MSK_IPAR_READ_MPS_WIDTH                     = 131,\n  MSK_IPAR_READ_TASK_IGNORE_PARAM             = 132,\n  MSK_IPAR_REMOTE_USE_COMPRESSION             = 133,\n  MSK_IPAR_REMOVE_UNUSED_SOLUTIONS            = 134,\n  MSK_IPAR_SENSITIVITY_ALL                    = 135,\n  MSK_IPAR_SENSITIVITY_TYPE                   = 136,\n  MSK_IPAR_SIM_BASIS_FACTOR_USE               = 137,\n  MSK_IPAR_SIM_DEGEN                          = 138,\n  MSK_IPAR_SIM_DETECT_PWL                     = 139,\n  MSK_IPAR_SIM_DUAL_CRASH                     = 140,\n  MSK_IPAR_SIM_DUAL_PHASEONE_METHOD           = 141,\n  MSK_IPAR_SIM_DUAL_RESTRICT_SELECTION        = 142,\n  MSK_IPAR_SIM_DUAL_SELECTION                 = 143,\n  MSK_IPAR_SIM_EXPLOIT_DUPVEC                 = 144,\n  MSK_IPAR_SIM_HOTSTART                       = 145,\n  MSK_IPAR_SIM_HOTSTART_LU                    = 146,\n  MSK_IPAR_SIM_MAX_ITERATIONS                 = 147,\n  MSK_IPAR_SIM_MAX_NUM_SETBACKS               = 148,\n  MSK_IPAR_SIM_NON_SINGULAR                   = 149,\n  MSK_IPAR_SIM_PRECISION                      = 150,\n  MSK_IPAR_SIM_PRECISION_BOOST                = 151,\n  MSK_IPAR_SIM_PRIMAL_CRASH                   = 152,\n  MSK_IPAR_SIM_PRIMAL_PHASEONE_METHOD         = 153,\n  MSK_IPAR_SIM_PRIMAL_RESTRICT_SELECTION      = 154,\n  MSK_IPAR_SIM_PRIMAL_SELECTION               = 155,\n  MSK_IPAR_SIM_REFACTOR_FREQ                  = 156,\n  MSK_IPAR_SIM_REFORMULATION                  = 157,\n  MSK_IPAR_SIM_SAVE_LU                        = 158,\n  MSK_IPAR_SIM_SCALING                        = 159,\n  MSK_IPAR_SIM_SCALING_METHOD                 = 160,\n  MSK_IPAR_SIM_SEED                           = 161,\n  MSK_IPAR_SIM_SOLVE_FORM                     = 162,\n  MSK_IPAR_SIM_SWITCH_OPTIMIZER               = 163,\n  MSK_IPAR_SOL_FILTER_KEEP_BASIC              = 164,\n  MSK_IPAR_SOL_READ_NAME_WIDTH                = 165,\n  MSK_IPAR_SOL_READ_WIDTH                     = 166,\n  MSK_IPAR_TIMING_LEVEL                       = 167,\n  MSK_IPAR_WRITE_ASYNC                        = 168,\n  MSK_IPAR_WRITE_BAS_CONSTRAINTS              = 169,\n  MSK_IPAR_WRITE_BAS_HEAD                     = 170,\n  MSK_IPAR_WRITE_BAS_VARIABLES                = 171,\n  MSK_IPAR_WRITE_COMPRESSION                  = 172,\n  MSK_IPAR_WRITE_FREE_CON                     = 173,\n  MSK_IPAR_WRITE_GENERIC_NAMES                = 174,\n  MSK_IPAR_WRITE_IGNORE_INCOMPATIBLE_ITEMS    = 175,\n  MSK_IPAR_WRITE_INT_CONSTRAINTS              = 176,\n  MSK_IPAR_WRITE_INT_HEAD                     = 177,\n  MSK_IPAR_WRITE_INT_VARIABLES                = 178,\n  MSK_IPAR_WRITE_JSON_INDENTATION             = 179,\n  MSK_IPAR_WRITE_LP_FULL_OBJ                  = 180,\n  MSK_IPAR_WRITE_LP_LINE_WIDTH                = 181,\n  MSK_IPAR_WRITE_MPS_FORMAT                   = 182,\n  MSK_IPAR_WRITE_MPS_INT                      = 183,\n  MSK_IPAR_WRITE_SOL_BARVARIABLES             = 184,\n  MSK_IPAR_WRITE_SOL_CONSTRAINTS              = 185,\n  MSK_IPAR_WRITE_SOL_HEAD                     = 186,\n  MSK_IPAR_WRITE_SOL_IGNORE_INVALID_NAMES     = 187,\n  MSK_IPAR_WRITE_SOL_VARIABLES                = 188\n};\n#define MSK_IPAR_BEGIN MSK_IPAR_ANA_SOL_BASIS\n#define MSK_IPAR_END   (1+MSK_IPAR_WRITE_SOL_VARIABLES)\n\n\nenum MSKbranchdir_enum {\n  MSK_BRANCH_DIR_FREE       = 0,\n  MSK_BRANCH_DIR_UP         = 1,\n  MSK_BRANCH_DIR_DOWN       = 2,\n  MSK_BRANCH_DIR_NEAR       = 3,\n  MSK_BRANCH_DIR_FAR        = 4,\n  MSK_BRANCH_DIR_ROOT_LP    = 5,\n  MSK_BRANCH_DIR_GUIDED     = 6,\n  MSK_BRANCH_DIR_PSEUDOCOST = 7\n};\n#define MSK_BRANCH_DIR_BEGIN MSK_BRANCH_DIR_FREE\n#define MSK_BRANCH_DIR_END   (1+MSK_BRANCH_DIR_PSEUDOCOST)\n\n\nenum MSKmiqcqoreformmethod_enum {\n  MSK_MIO_QCQO_REFORMULATION_METHOD_FREE             = 0,\n  MSK_MIO_QCQO_REFORMULATION_METHOD_NONE             = 1,\n  MSK_MIO_QCQO_REFORMULATION_METHOD_LINEARIZATION    = 2,\n  MSK_MIO_QCQO_REFORMULATION_METHOD_EIGEN_VAL_METHOD = 3,\n  MSK_MIO_QCQO_REFORMULATION_METHOD_DIAG_SDP         = 4,\n  MSK_MIO_QCQO_REFORMULATION_METHOD_RELAX_SDP        = 5\n};\n#define MSK_MIO_QCQO_REFORMULATION_METHOD_BEGIN MSK_MIO_QCQO_REFORMULATION_METHOD_FREE\n#define MSK_MIO_QCQO_REFORMULATION_METHOD_END   (1+MSK_MIO_QCQO_REFORMULATION_METHOD_RELAX_SDP)\n\n\nenum MSKmiodatapermmethod_enum {\n  MSK_MIO_DATA_PERMUTATION_METHOD_NONE         = 0,\n  MSK_MIO_DATA_PERMUTATION_METHOD_CYCLIC_SHIFT = 1,\n  MSK_MIO_DATA_PERMUTATION_METHOD_RANDOM       = 2\n};\n#define MSK_MIO_DATA_PERMUTATION_METHOD_BEGIN MSK_MIO_DATA_PERMUTATION_METHOD_NONE\n#define MSK_MIO_DATA_PERMUTATION_METHOD_END   (1+MSK_MIO_DATA_PERMUTATION_METHOD_RANDOM)\n\n\nenum MSKmiocontsoltype_enum {\n  MSK_MIO_CONT_SOL_NONE    = 0,\n  MSK_MIO_CONT_SOL_ROOT    = 1,\n  MSK_MIO_CONT_SOL_ITG     = 2,\n  MSK_MIO_CONT_SOL_ITG_REL = 3\n};\n#define MSK_MIO_CONT_SOL_BEGIN MSK_MIO_CONT_SOL_NONE\n#define MSK_MIO_CONT_SOL_END   (1+MSK_MIO_CONT_SOL_ITG_REL)\n\n\nenum MSKmiomode_enum {\n  MSK_MIO_MODE_IGNORED   = 0,\n  MSK_MIO_MODE_SATISFIED = 1\n};\n#define MSK_MIO_MODE_BEGIN MSK_MIO_MODE_IGNORED\n#define MSK_MIO_MODE_END   (1+MSK_MIO_MODE_SATISFIED)\n\n\nenum MSKmionodeseltype_enum {\n  MSK_MIO_NODE_SELECTION_FREE   = 0,\n  MSK_MIO_NODE_SELECTION_FIRST  = 1,\n  MSK_MIO_NODE_SELECTION_BEST   = 2,\n  MSK_MIO_NODE_SELECTION_PSEUDO = 3\n};\n#define MSK_MIO_NODE_SELECTION_BEGIN MSK_MIO_NODE_SELECTION_FREE\n#define MSK_MIO_NODE_SELECTION_END   (1+MSK_MIO_NODE_SELECTION_PSEUDO)\n\n\nenum MSKmiovarseltype_enum {\n  MSK_MIO_VAR_SELECTION_FREE       = 0,\n  MSK_MIO_VAR_SELECTION_PSEUDOCOST = 1,\n  MSK_MIO_VAR_SELECTION_STRONG     = 2\n};\n#define MSK_MIO_VAR_SELECTION_BEGIN MSK_MIO_VAR_SELECTION_FREE\n#define MSK_MIO_VAR_SELECTION_END   (1+MSK_MIO_VAR_SELECTION_STRONG)\n\n\nenum MSKmpsformat_enum {\n  MSK_MPS_FORMAT_STRICT  = 0,\n  MSK_MPS_FORMAT_RELAXED = 1,\n  MSK_MPS_FORMAT_FREE    = 2,\n  MSK_MPS_FORMAT_CPLEX   = 3\n};\n#define MSK_MPS_FORMAT_BEGIN MSK_MPS_FORMAT_STRICT\n#define MSK_MPS_FORMAT_END   (1+MSK_MPS_FORMAT_CPLEX)\n\n\nenum MSKobjsense_enum {\n  MSK_OBJECTIVE_SENSE_MINIMIZE = 0,\n  MSK_OBJECTIVE_SENSE_MAXIMIZE = 1\n};\n#define MSK_OBJECTIVE_SENSE_BEGIN MSK_OBJECTIVE_SENSE_MINIMIZE\n#define MSK_OBJECTIVE_SENSE_END   (1+MSK_OBJECTIVE_SENSE_MAXIMIZE)\n\n\nenum MSKonoffkey_enum {\n  MSK_OFF = 0,\n  MSK_ON  = 1\n};\n#define MSK_BEGIN MSK_OFF\n#define MSK_END   (1+MSK_ON)\n\n\nenum MSKoptimizertype_enum {\n  MSK_OPTIMIZER_CONIC              = 0,\n  MSK_OPTIMIZER_DUAL_SIMPLEX       = 1,\n  MSK_OPTIMIZER_FREE               = 2,\n  MSK_OPTIMIZER_FREE_SIMPLEX       = 3,\n  MSK_OPTIMIZER_INTPNT             = 4,\n  MSK_OPTIMIZER_MIXED_INT          = 5,\n  MSK_OPTIMIZER_NEW_DUAL_SIMPLEX   = 6,\n  MSK_OPTIMIZER_NEW_PRIMAL_SIMPLEX = 7,\n  MSK_OPTIMIZER_PRIMAL_SIMPLEX     = 8\n};\n#define MSK_OPTIMIZER_BEGIN MSK_OPTIMIZER_CONIC\n#define MSK_OPTIMIZER_END   (1+MSK_OPTIMIZER_PRIMAL_SIMPLEX)\n\n\nenum MSKorderingtype_enum {\n  MSK_ORDER_METHOD_FREE           = 0,\n  MSK_ORDER_METHOD_APPMINLOC      = 1,\n  MSK_ORDER_METHOD_EXPERIMENTAL   = 2,\n  MSK_ORDER_METHOD_TRY_GRAPHPAR   = 3,\n  MSK_ORDER_METHOD_FORCE_GRAPHPAR = 4,\n  MSK_ORDER_METHOD_NONE           = 5\n};\n#define MSK_ORDER_METHOD_BEGIN MSK_ORDER_METHOD_FREE\n#define MSK_ORDER_METHOD_END   (1+MSK_ORDER_METHOD_NONE)\n\n\nenum MSKpresolvemode_enum {\n  MSK_PRESOLVE_MODE_OFF  = 0,\n  MSK_PRESOLVE_MODE_ON   = 1,\n  MSK_PRESOLVE_MODE_FREE = 2\n};\n#define MSK_PRESOLVE_MODE_BEGIN MSK_PRESOLVE_MODE_OFF\n#define MSK_PRESOLVE_MODE_END   (1+MSK_PRESOLVE_MODE_FREE)\n\n\nenum MSKfoldingmode_enum {\n  MSK_FOLDING_MODE_OFF               = 0,\n  MSK_FOLDING_MODE_FREE              = 1,\n  MSK_FOLDING_MODE_FREE_UNLESS_BASIC = 2,\n  MSK_FOLDING_MODE_FORCE             = 3\n};\n#define MSK_FOLDING_MODE_BEGIN MSK_FOLDING_MODE_OFF\n#define MSK_FOLDING_MODE_END   (1+MSK_FOLDING_MODE_FORCE)\n\n\nenum MSKparametertype_enum {\n  MSK_PAR_INVALID_TYPE = 0,\n  MSK_PAR_DOU_TYPE     = 1,\n  MSK_PAR_INT_TYPE     = 2,\n  MSK_PAR_STR_TYPE     = 3\n};\n#define MSK_PAR_BEGIN MSK_PAR_INVALID_TYPE\n#define MSK_PAR_END   (1+MSK_PAR_STR_TYPE)\n\n\nenum MSKproblemitem_enum {\n  MSK_PI_VAR  = 0,\n  MSK_PI_CON  = 1,\n  MSK_PI_CONE = 2\n};\n#define MSK_PI_BEGIN MSK_PI_VAR\n#define MSK_PI_END   (1+MSK_PI_CONE)\n\n\nenum MSKproblemtype_enum {\n  MSK_PROBTYPE_LO    = 0,\n  MSK_PROBTYPE_QO    = 1,\n  MSK_PROBTYPE_QCQO  = 2,\n  MSK_PROBTYPE_CONIC = 3,\n  MSK_PROBTYPE_MIXED = 4\n};\n#define MSK_PROBTYPE_BEGIN MSK_PROBTYPE_LO\n#define MSK_PROBTYPE_END   (1+MSK_PROBTYPE_MIXED)\n\n\nenum MSKprosta_enum {\n  MSK_PRO_STA_UNKNOWN                  = 0,\n  MSK_PRO_STA_PRIM_AND_DUAL_FEAS       = 1,\n  MSK_PRO_STA_PRIM_FEAS                = 2,\n  MSK_PRO_STA_DUAL_FEAS                = 3,\n  MSK_PRO_STA_PRIM_INFEAS              = 4,\n  MSK_PRO_STA_DUAL_INFEAS              = 5,\n  MSK_PRO_STA_PRIM_AND_DUAL_INFEAS     = 6,\n  MSK_PRO_STA_ILL_POSED                = 7,\n  MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED = 8\n};\n#define MSK_PRO_STA_BEGIN MSK_PRO_STA_UNKNOWN\n#define MSK_PRO_STA_END   (1+MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED)\n\n\nenum MSKrescode_enum {\n  MSK_RES_OK                                                   = 0,\n  MSK_RES_WRN_OPEN_PARAM_FILE                                  = 50,\n  MSK_RES_WRN_LARGE_BOUND                                      = 51,\n  MSK_RES_WRN_LARGE_LO_BOUND                                   = 52,\n  MSK_RES_WRN_LARGE_UP_BOUND                                   = 53,\n  MSK_RES_WRN_LARGE_CON_FX                                     = 54,\n  MSK_RES_WRN_LARGE_CJ                                         = 57,\n  MSK_RES_WRN_LARGE_AIJ                                        = 62,\n  MSK_RES_WRN_ZERO_AIJ                                         = 63,\n  MSK_RES_WRN_NAME_MAX_LEN                                     = 65,\n  MSK_RES_WRN_SPAR_MAX_LEN                                     = 66,\n  MSK_RES_WRN_MPS_SPLIT_RHS_VECTOR                             = 70,\n  MSK_RES_WRN_MPS_SPLIT_RAN_VECTOR                             = 71,\n  MSK_RES_WRN_MPS_SPLIT_BOU_VECTOR                             = 72,\n  MSK_RES_WRN_LP_OLD_QUAD_FORMAT                               = 80,\n  MSK_RES_WRN_LP_DROP_VARIABLE                                 = 85,\n  MSK_RES_WRN_NZ_IN_UPR_TRI                                    = 200,\n  MSK_RES_WRN_DROPPED_NZ_QOBJ                                  = 201,\n  MSK_RES_WRN_IGNORE_INTEGER                                   = 250,\n  MSK_RES_WRN_NO_GLOBAL_OPTIMIZER                              = 251,\n  MSK_RES_WRN_MIO_INFEASIBLE_FINAL                             = 270,\n  MSK_RES_WRN_SOL_FILTER                                       = 300,\n  MSK_RES_WRN_UNDEF_SOL_FILE_NAME                              = 350,\n  MSK_RES_WRN_SOL_FILE_IGNORED_CON                             = 351,\n  MSK_RES_WRN_SOL_FILE_IGNORED_VAR                             = 352,\n  MSK_RES_WRN_TOO_FEW_BASIS_VARS                               = 400,\n  MSK_RES_WRN_TOO_MANY_BASIS_VARS                              = 405,\n  MSK_RES_WRN_LICENSE_EXPIRE                                   = 500,\n  MSK_RES_WRN_LICENSE_SERVER                                   = 501,\n  MSK_RES_WRN_EMPTY_NAME                                       = 502,\n  MSK_RES_WRN_USING_GENERIC_NAMES                              = 503,\n  MSK_RES_WRN_INVALID_MPS_NAME                                 = 504,\n  MSK_RES_WRN_INVALID_MPS_OBJ_NAME                             = 505,\n  MSK_RES_WRN_LICENSE_FEATURE_EXPIRE                           = 509,\n  MSK_RES_WRN_PARAM_NAME_DOU                                   = 510,\n  MSK_RES_WRN_PARAM_NAME_INT                                   = 511,\n  MSK_RES_WRN_PARAM_NAME_STR                                   = 512,\n  MSK_RES_WRN_PARAM_STR_VALUE                                  = 515,\n  MSK_RES_WRN_PARAM_IGNORED_CMIO                               = 516,\n  MSK_RES_WRN_ZEROS_IN_SPARSE_ROW                              = 705,\n  MSK_RES_WRN_ZEROS_IN_SPARSE_COL                              = 710,\n  MSK_RES_WRN_INCOMPLETE_LINEAR_DEPENDENCY_CHECK               = 800,\n  MSK_RES_WRN_ELIMINATOR_SPACE                                 = 801,\n  MSK_RES_WRN_PRESOLVE_OUTOFSPACE                              = 802,\n  MSK_RES_WRN_PRESOLVE_PRIMAL_PERTURBATIONS                    = 803,\n  MSK_RES_WRN_WRITE_CHANGED_NAMES                              = 830,\n  MSK_RES_WRN_WRITE_DISCARDED_CFIX                             = 831,\n  MSK_RES_WRN_DUPLICATE_CONSTRAINT_NAMES                       = 850,\n  MSK_RES_WRN_DUPLICATE_VARIABLE_NAMES                         = 851,\n  MSK_RES_WRN_DUPLICATE_BARVARIABLE_NAMES                      = 852,\n  MSK_RES_WRN_DUPLICATE_CONE_NAMES                             = 853,\n  MSK_RES_WRN_ANA_LARGE_BOUNDS                                 = 900,\n  MSK_RES_WRN_ANA_C_ZERO                                       = 901,\n  MSK_RES_WRN_ANA_EMPTY_COLS                                   = 902,\n  MSK_RES_WRN_ANA_CLOSE_BOUNDS                                 = 903,\n  MSK_RES_WRN_ANA_ALMOST_INT_BOUNDS                            = 904,\n  MSK_RES_WRN_NO_INFEASIBILITY_REPORT_WHEN_MATRIX_VARIABLES    = 930,\n  MSK_RES_WRN_GETDUAL_IGNORES_INTEGRALITY                      = 940,\n  MSK_RES_WRN_NO_DUALIZER                                      = 950,\n  MSK_RES_WRN_SYM_MAT_LARGE                                    = 960,\n  MSK_RES_WRN_MODIFIED_DOUBLE_PARAMETER                        = 970,\n  MSK_RES_WRN_LARGE_FIJ                                        = 980,\n  MSK_RES_WRN_PTF_UNKNOWN_SECTION                              = 981,\n  MSK_RES_ERR_LICENSE                                          = 1000,\n  MSK_RES_ERR_LICENSE_EXPIRED                                  = 1001,\n  MSK_RES_ERR_LICENSE_VERSION                                  = 1002,\n  MSK_RES_ERR_LICENSE_OLD_SERVER_VERSION                       = 1003,\n  MSK_RES_ERR_SIZE_LICENSE                                     = 1005,\n  MSK_RES_ERR_PROB_LICENSE                                     = 1006,\n  MSK_RES_ERR_FILE_LICENSE                                     = 1007,\n  MSK_RES_ERR_MISSING_LICENSE_FILE                             = 1008,\n  MSK_RES_ERR_SIZE_LICENSE_CON                                 = 1010,\n  MSK_RES_ERR_SIZE_LICENSE_VAR                                 = 1011,\n  MSK_RES_ERR_SIZE_LICENSE_INTVAR                              = 1012,\n  MSK_RES_ERR_OPTIMIZER_LICENSE                                = 1013,\n  MSK_RES_ERR_FLEXLM                                           = 1014,\n  MSK_RES_ERR_LICENSE_SERVER                                   = 1015,\n  MSK_RES_ERR_LICENSE_MAX                                      = 1016,\n  MSK_RES_ERR_LICENSE_MOSEKLM_DAEMON                           = 1017,\n  MSK_RES_ERR_LICENSE_FEATURE                                  = 1018,\n  MSK_RES_ERR_PLATFORM_NOT_LICENSED                            = 1019,\n  MSK_RES_ERR_LICENSE_CANNOT_ALLOCATE                          = 1020,\n  MSK_RES_ERR_LICENSE_CANNOT_CONNECT                           = 1021,\n  MSK_RES_ERR_LICENSE_INVALID_HOSTID                           = 1025,\n  MSK_RES_ERR_LICENSE_SERVER_VERSION                           = 1026,\n  MSK_RES_ERR_LICENSE_NO_SERVER_SUPPORT                        = 1027,\n  MSK_RES_ERR_LICENSE_NO_SERVER_LINE                           = 1028,\n  MSK_RES_ERR_OLDER_DLL                                        = 1035,\n  MSK_RES_ERR_NEWER_DLL                                        = 1036,\n  MSK_RES_ERR_LINK_FILE_DLL                                    = 1040,\n  MSK_RES_ERR_THREAD_MUTEX_INIT                                = 1045,\n  MSK_RES_ERR_THREAD_MUTEX_LOCK                                = 1046,\n  MSK_RES_ERR_THREAD_MUTEX_UNLOCK                              = 1047,\n  MSK_RES_ERR_THREAD_CREATE                                    = 1048,\n  MSK_RES_ERR_THREAD_COND_INIT                                 = 1049,\n  MSK_RES_ERR_UNKNOWN                                          = 1050,\n  MSK_RES_ERR_SPACE                                            = 1051,\n  MSK_RES_ERR_FILE_OPEN                                        = 1052,\n  MSK_RES_ERR_FILE_READ                                        = 1053,\n  MSK_RES_ERR_FILE_WRITE                                       = 1054,\n  MSK_RES_ERR_DATA_FILE_EXT                                    = 1055,\n  MSK_RES_ERR_INVALID_FILE_NAME                                = 1056,\n  MSK_RES_ERR_INVALID_SOL_FILE_NAME                            = 1057,\n  MSK_RES_ERR_END_OF_FILE                                      = 1059,\n  MSK_RES_ERR_NULL_ENV                                         = 1060,\n  MSK_RES_ERR_NULL_TASK                                        = 1061,\n  MSK_RES_ERR_INVALID_STREAM                                   = 1062,\n  MSK_RES_ERR_NO_INIT_ENV                                      = 1063,\n  MSK_RES_ERR_INVALID_TASK                                     = 1064,\n  MSK_RES_ERR_NULL_POINTER                                     = 1065,\n  MSK_RES_ERR_LIVING_TASKS                                     = 1066,\n  MSK_RES_ERR_READ_GZIP                                        = 1067,\n  MSK_RES_ERR_READ_ZSTD                                        = 1068,\n  MSK_RES_ERR_READ_ASYNC                                       = 1069,\n  MSK_RES_ERR_BLANK_NAME                                       = 1070,\n  MSK_RES_ERR_DUP_NAME                                         = 1071,\n  MSK_RES_ERR_FORMAT_STRING                                    = 1072,\n  MSK_RES_ERR_SPARSITY_SPECIFICATION                           = 1073,\n  MSK_RES_ERR_MISMATCHING_DIMENSION                            = 1074,\n  MSK_RES_ERR_INVALID_OBJ_NAME                                 = 1075,\n  MSK_RES_ERR_INVALID_CON_NAME                                 = 1076,\n  MSK_RES_ERR_INVALID_VAR_NAME                                 = 1077,\n  MSK_RES_ERR_INVALID_CONE_NAME                                = 1078,\n  MSK_RES_ERR_INVALID_BARVAR_NAME                              = 1079,\n  MSK_RES_ERR_SPACE_LEAKING                                    = 1080,\n  MSK_RES_ERR_SPACE_NO_INFO                                    = 1081,\n  MSK_RES_ERR_DIMENSION_SPECIFICATION                          = 1082,\n  MSK_RES_ERR_AXIS_NAME_SPECIFICATION                          = 1083,\n  MSK_RES_ERR_READ_PREMATURE_EOF                               = 1089,\n  MSK_RES_ERR_READ_FORMAT                                      = 1090,\n  MSK_RES_ERR_WRITE_LP_INVALID_VAR_NAMES                       = 1091,\n  MSK_RES_ERR_WRITE_LP_DUPLICATE_VAR_NAMES                     = 1092,\n  MSK_RES_ERR_WRITE_LP_INVALID_CON_NAMES                       = 1093,\n  MSK_RES_ERR_WRITE_LP_DUPLICATE_CON_NAMES                     = 1094,\n  MSK_RES_ERR_MPS_FILE                                         = 1100,\n  MSK_RES_ERR_MPS_INV_FIELD                                    = 1101,\n  MSK_RES_ERR_MPS_INV_MARKER                                   = 1102,\n  MSK_RES_ERR_MPS_NULL_CON_NAME                                = 1103,\n  MSK_RES_ERR_MPS_NULL_VAR_NAME                                = 1104,\n  MSK_RES_ERR_MPS_UNDEF_CON_NAME                               = 1105,\n  MSK_RES_ERR_MPS_UNDEF_VAR_NAME                               = 1106,\n  MSK_RES_ERR_MPS_INVALID_CON_KEY                              = 1107,\n  MSK_RES_ERR_MPS_INVALID_BOUND_KEY                            = 1108,\n  MSK_RES_ERR_MPS_INVALID_SEC_NAME                             = 1109,\n  MSK_RES_ERR_MPS_NO_OBJECTIVE                                 = 1110,\n  MSK_RES_ERR_MPS_SPLITTED_VAR                                 = 1111,\n  MSK_RES_ERR_MPS_MUL_CON_NAME                                 = 1112,\n  MSK_RES_ERR_MPS_MUL_QSEC                                     = 1113,\n  MSK_RES_ERR_MPS_MUL_QOBJ                                     = 1114,\n  MSK_RES_ERR_MPS_INV_SEC_ORDER                                = 1115,\n  MSK_RES_ERR_MPS_MUL_CSEC                                     = 1116,\n  MSK_RES_ERR_MPS_CONE_TYPE                                    = 1117,\n  MSK_RES_ERR_MPS_CONE_OVERLAP                                 = 1118,\n  MSK_RES_ERR_MPS_CONE_REPEAT                                  = 1119,\n  MSK_RES_ERR_MPS_NON_SYMMETRIC_Q                              = 1120,\n  MSK_RES_ERR_MPS_DUPLICATE_Q_ELEMENT                          = 1121,\n  MSK_RES_ERR_MPS_INVALID_OBJSENSE                             = 1122,\n  MSK_RES_ERR_MPS_TAB_IN_FIELD2                                = 1125,\n  MSK_RES_ERR_MPS_TAB_IN_FIELD3                                = 1126,\n  MSK_RES_ERR_MPS_TAB_IN_FIELD5                                = 1127,\n  MSK_RES_ERR_MPS_INVALID_OBJ_NAME                             = 1128,\n  MSK_RES_ERR_MPS_INVALID_KEY                                  = 1129,\n  MSK_RES_ERR_MPS_INVALID_INDICATOR_CONSTRAINT                 = 1130,\n  MSK_RES_ERR_MPS_INVALID_INDICATOR_VARIABLE                   = 1131,\n  MSK_RES_ERR_MPS_INVALID_INDICATOR_VALUE                      = 1132,\n  MSK_RES_ERR_MPS_INVALID_INDICATOR_QUADRATIC_CONSTRAINT       = 1133,\n  MSK_RES_ERR_OPF_SYNTAX                                       = 1134,\n  MSK_RES_ERR_OPF_PREMATURE_EOF                                = 1136,\n  MSK_RES_ERR_OPF_MISMATCHED_TAG                               = 1137,\n  MSK_RES_ERR_OPF_DUPLICATE_BOUND                              = 1138,\n  MSK_RES_ERR_OPF_DUPLICATE_CONSTRAINT_NAME                    = 1139,\n  MSK_RES_ERR_OPF_INVALID_CONE_TYPE                            = 1140,\n  MSK_RES_ERR_OPF_INCORRECT_TAG_PARAM                          = 1141,\n  MSK_RES_ERR_OPF_INVALID_TAG                                  = 1142,\n  MSK_RES_ERR_OPF_DUPLICATE_CONE_ENTRY                         = 1143,\n  MSK_RES_ERR_OPF_TOO_LARGE                                    = 1144,\n  MSK_RES_ERR_OPF_DUAL_INTEGER_SOLUTION                        = 1146,\n  MSK_RES_ERR_LP_EMPTY                                         = 1151,\n  MSK_RES_ERR_WRITE_MPS_INVALID_NAME                           = 1153,\n  MSK_RES_ERR_LP_INVALID_VAR_NAME                              = 1154,\n  MSK_RES_ERR_WRITE_OPF_INVALID_VAR_NAME                       = 1156,\n  MSK_RES_ERR_LP_FILE_FORMAT                                   = 1157,\n  MSK_RES_ERR_LP_EXPECTED_NUMBER                               = 1158,\n  MSK_RES_ERR_READ_LP_MISSING_END_TAG                          = 1159,\n  MSK_RES_ERR_LP_INDICATOR_VAR                                 = 1160,\n  MSK_RES_ERR_LP_EXPECTED_OBJECTIVE                            = 1161,\n  MSK_RES_ERR_LP_EXPECTED_CONSTRAINT_RELATION                  = 1162,\n  MSK_RES_ERR_LP_AMBIGUOUS_CONSTRAINT_BOUND                    = 1163,\n  MSK_RES_ERR_LP_DUPLICATE_SECTION                             = 1164,\n  MSK_RES_ERR_READ_LP_DELAYED_ROWS_NOT_SUPPORTED               = 1165,\n  MSK_RES_ERR_WRITING_FILE                                     = 1166,\n  MSK_RES_ERR_WRITE_ASYNC                                      = 1167,\n  MSK_RES_ERR_INVALID_NAME_IN_SOL_FILE                         = 1170,\n  MSK_RES_ERR_JSON_SYNTAX                                      = 1175,\n  MSK_RES_ERR_JSON_STRING                                      = 1176,\n  MSK_RES_ERR_JSON_NUMBER_OVERFLOW                             = 1177,\n  MSK_RES_ERR_JSON_FORMAT                                      = 1178,\n  MSK_RES_ERR_JSON_DATA                                        = 1179,\n  MSK_RES_ERR_JSON_MISSING_DATA                                = 1180,\n  MSK_RES_ERR_PTF_INCOMPATIBILITY                              = 1181,\n  MSK_RES_ERR_PTF_UNDEFINED_ITEM                               = 1182,\n  MSK_RES_ERR_PTF_INCONSISTENCY                                = 1183,\n  MSK_RES_ERR_PTF_FORMAT                                       = 1184,\n  MSK_RES_ERR_ARGUMENT_LENNEQ                                  = 1197,\n  MSK_RES_ERR_ARGUMENT_TYPE                                    = 1198,\n  MSK_RES_ERR_NUM_ARGUMENTS                                    = 1199,\n  MSK_RES_ERR_IN_ARGUMENT                                      = 1200,\n  MSK_RES_ERR_ARGUMENT_DIMENSION                               = 1201,\n  MSK_RES_ERR_SHAPE_IS_TOO_LARGE                               = 1202,\n  MSK_RES_ERR_INDEX_IS_TOO_SMALL                               = 1203,\n  MSK_RES_ERR_INDEX_IS_TOO_LARGE                               = 1204,\n  MSK_RES_ERR_INDEX_IS_NOT_UNIQUE                              = 1205,\n  MSK_RES_ERR_PARAM_NAME                                       = 1206,\n  MSK_RES_ERR_PARAM_NAME_DOU                                   = 1207,\n  MSK_RES_ERR_PARAM_NAME_INT                                   = 1208,\n  MSK_RES_ERR_PARAM_NAME_STR                                   = 1209,\n  MSK_RES_ERR_PARAM_INDEX                                      = 1210,\n  MSK_RES_ERR_PARAM_IS_TOO_LARGE                               = 1215,\n  MSK_RES_ERR_PARAM_IS_TOO_SMALL                               = 1216,\n  MSK_RES_ERR_PARAM_VALUE_STR                                  = 1217,\n  MSK_RES_ERR_PARAM_TYPE                                       = 1218,\n  MSK_RES_ERR_INF_DOU_INDEX                                    = 1219,\n  MSK_RES_ERR_INF_INT_INDEX                                    = 1220,\n  MSK_RES_ERR_INDEX_ARR_IS_TOO_SMALL                           = 1221,\n  MSK_RES_ERR_INDEX_ARR_IS_TOO_LARGE                           = 1222,\n  MSK_RES_ERR_INF_LINT_INDEX                                   = 1225,\n  MSK_RES_ERR_ARG_IS_TOO_SMALL                                 = 1226,\n  MSK_RES_ERR_ARG_IS_TOO_LARGE                                 = 1227,\n  MSK_RES_ERR_INVALID_WHICHSOL                                 = 1228,\n  MSK_RES_ERR_INF_DOU_NAME                                     = 1230,\n  MSK_RES_ERR_INF_INT_NAME                                     = 1231,\n  MSK_RES_ERR_INF_TYPE                                         = 1232,\n  MSK_RES_ERR_INF_LINT_NAME                                    = 1234,\n  MSK_RES_ERR_INDEX                                            = 1235,\n  MSK_RES_ERR_WHICHSOL                                         = 1236,\n  MSK_RES_ERR_SOLITEM                                          = 1237,\n  MSK_RES_ERR_WHICHITEM_NOT_ALLOWED                            = 1238,\n  MSK_RES_ERR_MAXNUMCON                                        = 1240,\n  MSK_RES_ERR_MAXNUMVAR                                        = 1241,\n  MSK_RES_ERR_MAXNUMBARVAR                                     = 1242,\n  MSK_RES_ERR_MAXNUMQNZ                                        = 1243,\n  MSK_RES_ERR_TOO_SMALL_MAX_NUM_NZ                             = 1245,\n  MSK_RES_ERR_INVALID_IDX                                      = 1246,\n  MSK_RES_ERR_INVALID_MAX_NUM                                  = 1247,\n  MSK_RES_ERR_UNALLOWED_WHICHSOL                               = 1248,\n  MSK_RES_ERR_NUMCONLIM                                        = 1250,\n  MSK_RES_ERR_NUMVARLIM                                        = 1251,\n  MSK_RES_ERR_TOO_SMALL_MAXNUMANZ                              = 1252,\n  MSK_RES_ERR_INV_APTRE                                        = 1253,\n  MSK_RES_ERR_MUL_A_ELEMENT                                    = 1254,\n  MSK_RES_ERR_INV_BK                                           = 1255,\n  MSK_RES_ERR_INV_BKC                                          = 1256,\n  MSK_RES_ERR_INV_BKX                                          = 1257,\n  MSK_RES_ERR_INV_VAR_TYPE                                     = 1258,\n  MSK_RES_ERR_SOLVER_PROBTYPE                                  = 1259,\n  MSK_RES_ERR_OBJECTIVE_RANGE                                  = 1260,\n  MSK_RES_ERR_INV_RESCODE                                      = 1261,\n  MSK_RES_ERR_INV_IINF                                         = 1262,\n  MSK_RES_ERR_INV_LIINF                                        = 1263,\n  MSK_RES_ERR_INV_DINF                                         = 1264,\n  MSK_RES_ERR_BASIS                                            = 1266,\n  MSK_RES_ERR_INV_SKC                                          = 1267,\n  MSK_RES_ERR_INV_SKX                                          = 1268,\n  MSK_RES_ERR_INV_SK_STR                                       = 1269,\n  MSK_RES_ERR_INV_SK                                           = 1270,\n  MSK_RES_ERR_INV_CONE_TYPE_STR                                = 1271,\n  MSK_RES_ERR_INV_CONE_TYPE                                    = 1272,\n  MSK_RES_ERR_INV_SKN                                          = 1274,\n  MSK_RES_ERR_INVALID_SURPLUS                                  = 1275,\n  MSK_RES_ERR_INV_NAME_ITEM                                    = 1280,\n  MSK_RES_ERR_PRO_ITEM                                         = 1281,\n  MSK_RES_ERR_INVALID_FORMAT_TYPE                              = 1283,\n  MSK_RES_ERR_FIRSTI                                           = 1285,\n  MSK_RES_ERR_LASTI                                            = 1286,\n  MSK_RES_ERR_FIRSTJ                                           = 1287,\n  MSK_RES_ERR_LASTJ                                            = 1288,\n  MSK_RES_ERR_MAX_LEN_IS_TOO_SMALL                             = 1289,\n  MSK_RES_ERR_NONLINEAR_EQUALITY                               = 1290,\n  MSK_RES_ERR_NONCONVEX                                        = 1291,\n  MSK_RES_ERR_NONLINEAR_RANGED                                 = 1292,\n  MSK_RES_ERR_CON_Q_NOT_PSD                                    = 1293,\n  MSK_RES_ERR_CON_Q_NOT_NSD                                    = 1294,\n  MSK_RES_ERR_OBJ_Q_NOT_PSD                                    = 1295,\n  MSK_RES_ERR_OBJ_Q_NOT_NSD                                    = 1296,\n  MSK_RES_ERR_ARGUMENT_PERM_ARRAY                              = 1299,\n  MSK_RES_ERR_CONE_INDEX                                       = 1300,\n  MSK_RES_ERR_CONE_SIZE                                        = 1301,\n  MSK_RES_ERR_CONE_OVERLAP                                     = 1302,\n  MSK_RES_ERR_CONE_REP_VAR                                     = 1303,\n  MSK_RES_ERR_MAXNUMCONE                                       = 1304,\n  MSK_RES_ERR_CONE_TYPE                                        = 1305,\n  MSK_RES_ERR_CONE_TYPE_STR                                    = 1306,\n  MSK_RES_ERR_CONE_OVERLAP_APPEND                              = 1307,\n  MSK_RES_ERR_REMOVE_CONE_VARIABLE                             = 1310,\n  MSK_RES_ERR_APPENDING_TOO_BIG_CONE                           = 1311,\n  MSK_RES_ERR_CONE_PARAMETER                                   = 1320,\n  MSK_RES_ERR_SOL_FILE_INVALID_NUMBER                          = 1350,\n  MSK_RES_ERR_HUGE_C                                           = 1375,\n  MSK_RES_ERR_HUGE_AIJ                                         = 1380,\n  MSK_RES_ERR_DUPLICATE_AIJ                                    = 1385,\n  MSK_RES_ERR_LOWER_BOUND_IS_A_NAN                             = 1390,\n  MSK_RES_ERR_UPPER_BOUND_IS_A_NAN                             = 1391,\n  MSK_RES_ERR_INFINITE_BOUND                                   = 1400,\n  MSK_RES_ERR_INV_QOBJ_SUBI                                    = 1401,\n  MSK_RES_ERR_INV_QOBJ_SUBJ                                    = 1402,\n  MSK_RES_ERR_INV_QOBJ_VAL                                     = 1403,\n  MSK_RES_ERR_INV_QCON_SUBK                                    = 1404,\n  MSK_RES_ERR_INV_QCON_SUBI                                    = 1405,\n  MSK_RES_ERR_INV_QCON_SUBJ                                    = 1406,\n  MSK_RES_ERR_INV_QCON_VAL                                     = 1407,\n  MSK_RES_ERR_QCON_SUBI_TOO_SMALL                              = 1408,\n  MSK_RES_ERR_QCON_SUBI_TOO_LARGE                              = 1409,\n  MSK_RES_ERR_QOBJ_UPPER_TRIANGLE                              = 1415,\n  MSK_RES_ERR_QCON_UPPER_TRIANGLE                              = 1417,\n  MSK_RES_ERR_FIXED_BOUND_VALUES                               = 1420,\n  MSK_RES_ERR_TOO_SMALL_A_TRUNCATION_VALUE                     = 1421,\n  MSK_RES_ERR_INVALID_OBJECTIVE_SENSE                          = 1445,\n  MSK_RES_ERR_UNDEFINED_OBJECTIVE_SENSE                        = 1446,\n  MSK_RES_ERR_Y_IS_UNDEFINED                                   = 1449,\n  MSK_RES_ERR_NAN_IN_DOUBLE_DATA                               = 1450,\n  MSK_RES_ERR_INF_IN_DOUBLE_DATA                               = 1451,\n  MSK_RES_ERR_NAN_IN_BLC                                       = 1461,\n  MSK_RES_ERR_NAN_IN_BUC                                       = 1462,\n  MSK_RES_ERR_INVALID_CFIX                                     = 1469,\n  MSK_RES_ERR_NAN_IN_C                                         = 1470,\n  MSK_RES_ERR_NAN_IN_BLX                                       = 1471,\n  MSK_RES_ERR_NAN_IN_BUX                                       = 1472,\n  MSK_RES_ERR_INVALID_AIJ                                      = 1473,\n  MSK_RES_ERR_INVALID_CJ                                       = 1474,\n  MSK_RES_ERR_SYM_MAT_INVALID                                  = 1480,\n  MSK_RES_ERR_SYM_MAT_HUGE                                     = 1482,\n  MSK_RES_ERR_INV_PROBLEM                                      = 1500,\n  MSK_RES_ERR_MIXED_CONIC_AND_NL                               = 1501,\n  MSK_RES_ERR_GLOBAL_INV_CONIC_PROBLEM                         = 1503,\n  MSK_RES_ERR_INV_OPTIMIZER                                    = 1550,\n  MSK_RES_ERR_MIO_NO_OPTIMIZER                                 = 1551,\n  MSK_RES_ERR_NO_OPTIMIZER_VAR_TYPE                            = 1552,\n  MSK_RES_ERR_FINAL_SOLUTION                                   = 1560,\n  MSK_RES_ERR_FIRST                                            = 1570,\n  MSK_RES_ERR_LAST                                             = 1571,\n  MSK_RES_ERR_SLICE_SIZE                                       = 1572,\n  MSK_RES_ERR_NEGATIVE_SURPLUS                                 = 1573,\n  MSK_RES_ERR_NEGATIVE_APPEND                                  = 1578,\n  MSK_RES_ERR_POSTSOLVE                                        = 1580,\n  MSK_RES_ERR_OVERFLOW                                         = 1590,\n  MSK_RES_ERR_NO_BASIS_SOL                                     = 1600,\n  MSK_RES_ERR_BASIS_FACTOR                                     = 1610,\n  MSK_RES_ERR_BASIS_SINGULAR                                   = 1615,\n  MSK_RES_ERR_FACTOR                                           = 1650,\n  MSK_RES_ERR_FEASREPAIR_CANNOT_RELAX                          = 1700,\n  MSK_RES_ERR_FEASREPAIR_SOLVING_RELAXED                       = 1701,\n  MSK_RES_ERR_FEASREPAIR_INCONSISTENT_BOUND                    = 1702,\n  MSK_RES_ERR_REPAIR_INVALID_PROBLEM                           = 1710,\n  MSK_RES_ERR_REPAIR_OPTIMIZATION_FAILED                       = 1711,\n  MSK_RES_ERR_NAME_MAX_LEN                                     = 1750,\n  MSK_RES_ERR_NAME_IS_NULL                                     = 1760,\n  MSK_RES_ERR_INVALID_COMPRESSION                              = 1800,\n  MSK_RES_ERR_INVALID_IOMODE                                   = 1801,\n  MSK_RES_ERR_NO_PRIMAL_INFEAS_CER                             = 2000,\n  MSK_RES_ERR_NO_DUAL_INFEAS_CER                               = 2001,\n  MSK_RES_ERR_NO_SOLUTION_IN_CALLBACK                          = 2500,\n  MSK_RES_ERR_INV_MARKI                                        = 2501,\n  MSK_RES_ERR_INV_MARKJ                                        = 2502,\n  MSK_RES_ERR_INV_NUMI                                         = 2503,\n  MSK_RES_ERR_INV_NUMJ                                         = 2504,\n  MSK_RES_ERR_TASK_INCOMPATIBLE                                = 2560,\n  MSK_RES_ERR_TASK_INVALID                                     = 2561,\n  MSK_RES_ERR_TASK_WRITE                                       = 2562,\n  MSK_RES_ERR_READ_WRITE                                       = 2563,\n  MSK_RES_ERR_TASK_PREMATURE_EOF                               = 2564,\n  MSK_RES_ERR_LU_MAX_NUM_TRIES                                 = 2800,\n  MSK_RES_ERR_INVALID_UTF8                                     = 2900,\n  MSK_RES_ERR_INVALID_WCHAR                                    = 2901,\n  MSK_RES_ERR_NO_DUAL_FOR_ITG_SOL                              = 2950,\n  MSK_RES_ERR_NO_SNX_FOR_BAS_SOL                               = 2953,\n  MSK_RES_ERR_INTERNAL                                         = 3000,\n  MSK_RES_ERR_API_ARRAY_TOO_SMALL                              = 3001,\n  MSK_RES_ERR_API_CB_CONNECT                                   = 3002,\n  MSK_RES_ERR_API_FATAL_ERROR                                  = 3005,\n  MSK_RES_ERR_SEN_FORMAT                                       = 3050,\n  MSK_RES_ERR_SEN_UNDEF_NAME                                   = 3051,\n  MSK_RES_ERR_SEN_INDEX_RANGE                                  = 3052,\n  MSK_RES_ERR_SEN_BOUND_INVALID_UP                             = 3053,\n  MSK_RES_ERR_SEN_BOUND_INVALID_LO                             = 3054,\n  MSK_RES_ERR_SEN_INDEX_INVALID                                = 3055,\n  MSK_RES_ERR_SEN_INVALID_REGEXP                               = 3056,\n  MSK_RES_ERR_SEN_SOLUTION_STATUS                              = 3057,\n  MSK_RES_ERR_SEN_NUMERICAL                                    = 3058,\n  MSK_RES_ERR_SEN_UNHANDLED_PROBLEM_TYPE                       = 3080,\n  MSK_RES_ERR_UNB_STEP_SIZE                                    = 3100,\n  MSK_RES_ERR_IDENTICAL_TASKS                                  = 3101,\n  MSK_RES_ERR_AD_INVALID_CODELIST                              = 3102,\n  MSK_RES_ERR_INTERNAL_TEST_FAILED                             = 3500,\n  MSK_RES_ERR_INT64_TO_INT32_CAST                              = 3800,\n  MSK_RES_ERR_INFEAS_UNDEFINED                                 = 3910,\n  MSK_RES_ERR_NO_BARX_FOR_SOLUTION                             = 3915,\n  MSK_RES_ERR_NO_BARS_FOR_SOLUTION                             = 3916,\n  MSK_RES_ERR_BAR_VAR_DIM                                      = 3920,\n  MSK_RES_ERR_SYM_MAT_INVALID_ROW_INDEX                        = 3940,\n  MSK_RES_ERR_SYM_MAT_INVALID_COL_INDEX                        = 3941,\n  MSK_RES_ERR_SYM_MAT_NOT_LOWER_TRINGULAR                      = 3942,\n  MSK_RES_ERR_SYM_MAT_INVALID_VALUE                            = 3943,\n  MSK_RES_ERR_SYM_MAT_DUPLICATE                                = 3944,\n  MSK_RES_ERR_INVALID_SYM_MAT_DIM                              = 3950,\n  MSK_RES_ERR_API_INTERNAL                                     = 3999,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_SYM_MAT                  = 4000,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_CFIX                     = 4001,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_RANGED_CONSTRAINTS       = 4002,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_FREE_CONSTRAINTS         = 4003,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_CONES                    = 4005,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_QUADRATIC_TERMS          = 4006,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_NONLINEAR                = 4010,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_DISJUNCTIVE_CONSTRAINTS  = 4011,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_AFFINE_CONIC_CONSTRAINTS = 4012,\n  MSK_RES_ERR_DUPLICATE_CONSTRAINT_NAMES                       = 4500,\n  MSK_RES_ERR_DUPLICATE_VARIABLE_NAMES                         = 4501,\n  MSK_RES_ERR_DUPLICATE_BARVARIABLE_NAMES                      = 4502,\n  MSK_RES_ERR_DUPLICATE_CONE_NAMES                             = 4503,\n  MSK_RES_ERR_DUPLICATE_DOMAIN_NAMES                           = 4504,\n  MSK_RES_ERR_DUPLICATE_DJC_NAMES                              = 4505,\n  MSK_RES_ERR_NON_UNIQUE_ARRAY                                 = 5000,\n  MSK_RES_ERR_ARGUMENT_IS_TOO_SMALL                            = 5004,\n  MSK_RES_ERR_ARGUMENT_IS_TOO_LARGE                            = 5005,\n  MSK_RES_ERR_MIO_INTERNAL                                     = 5010,\n  MSK_RES_ERR_INVALID_PROBLEM_TYPE                             = 6000,\n  MSK_RES_ERR_UNHANDLED_SOLUTION_STATUS                        = 6010,\n  MSK_RES_ERR_UPPER_TRIANGLE                                   = 6020,\n  MSK_RES_ERR_LAU_SINGULAR_MATRIX                              = 7000,\n  MSK_RES_ERR_LAU_NOT_POSITIVE_DEFINITE                        = 7001,\n  MSK_RES_ERR_LAU_INVALID_LOWER_TRIANGULAR_MATRIX              = 7002,\n  MSK_RES_ERR_LAU_UNKNOWN                                      = 7005,\n  MSK_RES_ERR_LAU_ARG_M                                        = 7010,\n  MSK_RES_ERR_LAU_ARG_N                                        = 7011,\n  MSK_RES_ERR_LAU_ARG_K                                        = 7012,\n  MSK_RES_ERR_LAU_ARG_TRANSA                                   = 7015,\n  MSK_RES_ERR_LAU_ARG_TRANSB                                   = 7016,\n  MSK_RES_ERR_LAU_ARG_UPLO                                     = 7017,\n  MSK_RES_ERR_LAU_ARG_TRANS                                    = 7018,\n  MSK_RES_ERR_LAU_INVALID_SPARSE_SYMMETRIC_MATRIX              = 7019,\n  MSK_RES_ERR_CBF_PARSE                                        = 7100,\n  MSK_RES_ERR_CBF_OBJ_SENSE                                    = 7101,\n  MSK_RES_ERR_CBF_NO_VARIABLES                                 = 7102,\n  MSK_RES_ERR_CBF_TOO_MANY_CONSTRAINTS                         = 7103,\n  MSK_RES_ERR_CBF_TOO_MANY_VARIABLES                           = 7104,\n  MSK_RES_ERR_CBF_NO_VERSION_SPECIFIED                         = 7105,\n  MSK_RES_ERR_CBF_SYNTAX                                       = 7106,\n  MSK_RES_ERR_CBF_DUPLICATE_OBJ                                = 7107,\n  MSK_RES_ERR_CBF_DUPLICATE_CON                                = 7108,\n  MSK_RES_ERR_CBF_DUPLICATE_VAR                                = 7110,\n  MSK_RES_ERR_CBF_DUPLICATE_INT                                = 7111,\n  MSK_RES_ERR_CBF_INVALID_VAR_TYPE                             = 7112,\n  MSK_RES_ERR_CBF_INVALID_CON_TYPE                             = 7113,\n  MSK_RES_ERR_CBF_INVALID_DOMAIN_DIMENSION                     = 7114,\n  MSK_RES_ERR_CBF_DUPLICATE_OBJACOORD                          = 7115,\n  MSK_RES_ERR_CBF_DUPLICATE_BCOORD                             = 7116,\n  MSK_RES_ERR_CBF_DUPLICATE_ACOORD                             = 7117,\n  MSK_RES_ERR_CBF_TOO_FEW_VARIABLES                            = 7118,\n  MSK_RES_ERR_CBF_TOO_FEW_CONSTRAINTS                          = 7119,\n  MSK_RES_ERR_CBF_TOO_FEW_INTS                                 = 7120,\n  MSK_RES_ERR_CBF_TOO_MANY_INTS                                = 7121,\n  MSK_RES_ERR_CBF_INVALID_INT_INDEX                            = 7122,\n  MSK_RES_ERR_CBF_UNSUPPORTED                                  = 7123,\n  MSK_RES_ERR_CBF_DUPLICATE_PSDVAR                             = 7124,\n  MSK_RES_ERR_CBF_INVALID_PSDVAR_DIMENSION                     = 7125,\n  MSK_RES_ERR_CBF_TOO_FEW_PSDVAR                               = 7126,\n  MSK_RES_ERR_CBF_INVALID_EXP_DIMENSION                        = 7127,\n  MSK_RES_ERR_CBF_DUPLICATE_POW_CONES                          = 7130,\n  MSK_RES_ERR_CBF_DUPLICATE_POW_STAR_CONES                     = 7131,\n  MSK_RES_ERR_CBF_INVALID_POWER                                = 7132,\n  MSK_RES_ERR_CBF_POWER_CONE_IS_TOO_LONG                       = 7133,\n  MSK_RES_ERR_CBF_INVALID_POWER_CONE_INDEX                     = 7134,\n  MSK_RES_ERR_CBF_INVALID_POWER_STAR_CONE_INDEX                = 7135,\n  MSK_RES_ERR_CBF_UNHANDLED_POWER_CONE_TYPE                    = 7136,\n  MSK_RES_ERR_CBF_UNHANDLED_POWER_STAR_CONE_TYPE               = 7137,\n  MSK_RES_ERR_CBF_POWER_CONE_MISMATCH                          = 7138,\n  MSK_RES_ERR_CBF_POWER_STAR_CONE_MISMATCH                     = 7139,\n  MSK_RES_ERR_CBF_INVALID_NUMBER_OF_CONES                      = 7140,\n  MSK_RES_ERR_CBF_INVALID_DIMENSION_OF_CONES                   = 7141,\n  MSK_RES_ERR_CBF_INVALID_NUM_OBJACOORD                        = 7150,\n  MSK_RES_ERR_CBF_INVALID_NUM_OBJFCOORD                        = 7151,\n  MSK_RES_ERR_CBF_INVALID_NUM_ACOORD                           = 7152,\n  MSK_RES_ERR_CBF_INVALID_NUM_BCOORD                           = 7153,\n  MSK_RES_ERR_CBF_INVALID_NUM_FCOORD                           = 7155,\n  MSK_RES_ERR_CBF_INVALID_NUM_HCOORD                           = 7156,\n  MSK_RES_ERR_CBF_INVALID_NUM_DCOORD                           = 7157,\n  MSK_RES_ERR_CBF_EXPECTED_A_KEYWORD                           = 7158,\n  MSK_RES_ERR_CBF_INVALID_NUM_PSDCON                           = 7200,\n  MSK_RES_ERR_CBF_DUPLICATE_PSDCON                             = 7201,\n  MSK_RES_ERR_CBF_INVALID_DIMENSION_OF_PSDCON                  = 7202,\n  MSK_RES_ERR_CBF_INVALID_PSDCON_INDEX                         = 7203,\n  MSK_RES_ERR_CBF_INVALID_PSDCON_VARIABLE_INDEX                = 7204,\n  MSK_RES_ERR_CBF_INVALID_PSDCON_BLOCK_INDEX                   = 7205,\n  MSK_RES_ERR_CBF_UNSUPPORTED_CHANGE                           = 7210,\n  MSK_RES_ERR_MIO_INVALID_ROOT_OPTIMIZER                       = 7700,\n  MSK_RES_ERR_MIO_INVALID_NODE_OPTIMIZER                       = 7701,\n  MSK_RES_ERR_MPS_WRITE_CPLEX_INVALID_CONE_TYPE                = 7750,\n  MSK_RES_ERR_TOCONIC_CONSTR_Q_NOT_PSD                         = 7800,\n  MSK_RES_ERR_TOCONIC_CONSTRAINT_FX                            = 7801,\n  MSK_RES_ERR_TOCONIC_CONSTRAINT_RA                            = 7802,\n  MSK_RES_ERR_TOCONIC_CONSTR_NOT_CONIC                         = 7803,\n  MSK_RES_ERR_TOCONIC_OBJECTIVE_NOT_PSD                        = 7804,\n  MSK_RES_ERR_GETDUAL_NOT_AVAILABLE                            = 7820,\n  MSK_RES_ERR_SERVER_CONNECT                                   = 8000,\n  MSK_RES_ERR_SERVER_PROTOCOL                                  = 8001,\n  MSK_RES_ERR_SERVER_STATUS                                    = 8002,\n  MSK_RES_ERR_SERVER_TOKEN                                     = 8003,\n  MSK_RES_ERR_SERVER_ADDRESS                                   = 8004,\n  MSK_RES_ERR_SERVER_CERTIFICATE                               = 8005,\n  MSK_RES_ERR_SERVER_TLS_CLIENT                                = 8006,\n  MSK_RES_ERR_SERVER_ACCESS_TOKEN                              = 8007,\n  MSK_RES_ERR_SERVER_PROBLEM_SIZE                              = 8008,\n  MSK_RES_ERR_SERVER_HARD_TIMEOUT                              = 8009,\n  MSK_RES_ERR_DUPLICATE_INDEX_IN_A_SPARSE_MATRIX               = 20050,\n  MSK_RES_ERR_DUPLICATE_INDEX_IN_AFEIDX_LIST                   = 20060,\n  MSK_RES_ERR_DUPLICATE_FIJ                                    = 20100,\n  MSK_RES_ERR_INVALID_FIJ                                      = 20101,\n  MSK_RES_ERR_HUGE_FIJ                                         = 20102,\n  MSK_RES_ERR_INVALID_G                                        = 20103,\n  MSK_RES_ERR_INVALID_B                                        = 20150,\n  MSK_RES_ERR_DOMAIN_INVALID_INDEX                             = 20400,\n  MSK_RES_ERR_DOMAIN_DIMENSION                                 = 20401,\n  MSK_RES_ERR_DOMAIN_DIMENSION_PSD                             = 20402,\n  MSK_RES_ERR_NOT_POWER_DOMAIN                                 = 20403,\n  MSK_RES_ERR_DOMAIN_POWER_INVALID_ALPHA                       = 20404,\n  MSK_RES_ERR_DOMAIN_POWER_NEGATIVE_ALPHA                      = 20405,\n  MSK_RES_ERR_DOMAIN_POWER_NLEFT                               = 20406,\n  MSK_RES_ERR_AFE_INVALID_INDEX                                = 20500,\n  MSK_RES_ERR_ACC_INVALID_INDEX                                = 20600,\n  MSK_RES_ERR_ACC_INVALID_ENTRY_INDEX                          = 20601,\n  MSK_RES_ERR_ACC_AFE_DOMAIN_MISMATCH                          = 20602,\n  MSK_RES_ERR_DJC_INVALID_INDEX                                = 20700,\n  MSK_RES_ERR_DJC_UNSUPPORTED_DOMAIN_TYPE                      = 20701,\n  MSK_RES_ERR_DJC_AFE_DOMAIN_MISMATCH                          = 20702,\n  MSK_RES_ERR_DJC_INVALID_TERM_SIZE                            = 20703,\n  MSK_RES_ERR_DJC_DOMAIN_TERMSIZE_MISMATCH                     = 20704,\n  MSK_RES_ERR_DJC_TOTAL_NUM_TERMS_MISMATCH                     = 20705,\n  MSK_RES_ERR_UNDEF_SOLUTION                                   = 22000,\n  MSK_RES_ERR_NO_DOTY                                          = 22010,\n  MSK_RES_TRM_MAX_ITERATIONS                                   = 100000,\n  MSK_RES_TRM_MAX_TIME                                         = 100001,\n  MSK_RES_TRM_OBJECTIVE_RANGE                                  = 100002,\n  MSK_RES_TRM_STALL                                            = 100006,\n  MSK_RES_TRM_USER_CALLBACK                                    = 100007,\n  MSK_RES_TRM_MIO_NUM_RELAXS                                   = 100008,\n  MSK_RES_TRM_MIO_NUM_BRANCHES                                 = 100009,\n  MSK_RES_TRM_NUM_MAX_NUM_INT_SOLUTIONS                        = 100015,\n  MSK_RES_TRM_MAX_NUM_SETBACKS                                 = 100020,\n  MSK_RES_TRM_NUMERICAL_PROBLEM                                = 100025,\n  MSK_RES_TRM_LOST_RACE                                        = 100027,\n  MSK_RES_TRM_INTERNAL                                         = 100030,\n  MSK_RES_TRM_INTERNAL_STOP                                    = 100031,\n  MSK_RES_TRM_SERVER_MAX_TIME                                  = 100032,\n  MSK_RES_TRM_SERVER_MAX_MEMORY                                = 100033\n};\n\n\nenum MSKrescodetype_enum {\n  MSK_RESPONSE_OK  = 0,\n  MSK_RESPONSE_WRN = 1,\n  MSK_RESPONSE_TRM = 2,\n  MSK_RESPONSE_ERR = 3,\n  MSK_RESPONSE_UNK = 4\n};\n#define MSK_RESPONSE_BEGIN MSK_RESPONSE_OK\n#define MSK_RESPONSE_END   (1+MSK_RESPONSE_UNK)\n\n\nenum MSKscalingtype_enum {\n  MSK_SCALING_FREE = 0,\n  MSK_SCALING_NONE = 1\n};\n#define MSK_SCALING_BEGIN MSK_SCALING_FREE\n#define MSK_SCALING_END   (1+MSK_SCALING_NONE)\n\n\nenum MSKscalingmethod_enum {\n  MSK_SCALING_METHOD_POW2 = 0,\n  MSK_SCALING_METHOD_FREE = 1\n};\n#define MSK_SCALING_METHOD_BEGIN MSK_SCALING_METHOD_POW2\n#define MSK_SCALING_METHOD_END   (1+MSK_SCALING_METHOD_FREE)\n\n\nenum MSKsensitivitytype_enum {\n  MSK_SENSITIVITY_TYPE_BASIS = 0\n};\n#define MSK_SENSITIVITY_TYPE_BEGIN MSK_SENSITIVITY_TYPE_BASIS\n#define MSK_SENSITIVITY_TYPE_END   (1+MSK_SENSITIVITY_TYPE_BASIS)\n\n\nenum MSKsimseltype_enum {\n  MSK_SIM_SELECTION_FREE    = 0,\n  MSK_SIM_SELECTION_FULL    = 1,\n  MSK_SIM_SELECTION_ASE     = 2,\n  MSK_SIM_SELECTION_DEVEX   = 3,\n  MSK_SIM_SELECTION_SE      = 4,\n  MSK_SIM_SELECTION_PARTIAL = 5\n};\n#define MSK_SIM_SELECTION_BEGIN MSK_SIM_SELECTION_FREE\n#define MSK_SIM_SELECTION_END   (1+MSK_SIM_SELECTION_PARTIAL)\n\n\nenum MSKsolitem_enum {\n  MSK_SOL_ITEM_XC  = 0,\n  MSK_SOL_ITEM_XX  = 1,\n  MSK_SOL_ITEM_Y   = 2,\n  MSK_SOL_ITEM_SLC = 3,\n  MSK_SOL_ITEM_SUC = 4,\n  MSK_SOL_ITEM_SLX = 5,\n  MSK_SOL_ITEM_SUX = 6,\n  MSK_SOL_ITEM_SNX = 7\n};\n#define MSK_SOL_ITEM_BEGIN MSK_SOL_ITEM_XC\n#define MSK_SOL_ITEM_END   (1+MSK_SOL_ITEM_SNX)\n\n\nenum MSKsolsta_enum {\n  MSK_SOL_STA_UNKNOWN            = 0,\n  MSK_SOL_STA_OPTIMAL            = 1,\n  MSK_SOL_STA_PRIM_FEAS          = 2,\n  MSK_SOL_STA_DUAL_FEAS          = 3,\n  MSK_SOL_STA_PRIM_AND_DUAL_FEAS = 4,\n  MSK_SOL_STA_PRIM_INFEAS_CER    = 5,\n  MSK_SOL_STA_DUAL_INFEAS_CER    = 6,\n  MSK_SOL_STA_PRIM_ILLPOSED_CER  = 7,\n  MSK_SOL_STA_DUAL_ILLPOSED_CER  = 8,\n  MSK_SOL_STA_INTEGER_OPTIMAL    = 9\n};\n#define MSK_SOL_STA_BEGIN MSK_SOL_STA_UNKNOWN\n#define MSK_SOL_STA_END   (1+MSK_SOL_STA_INTEGER_OPTIMAL)\n\n\nenum MSKsoltype_enum {\n  MSK_SOL_ITR = 0,\n  MSK_SOL_BAS = 1,\n  MSK_SOL_ITG = 2\n};\n#define MSK_SOL_BEGIN MSK_SOL_ITR\n#define MSK_SOL_END   (1+MSK_SOL_ITG)\n\n\nenum MSKsolveform_enum {\n  MSK_SOLVE_FREE   = 0,\n  MSK_SOLVE_PRIMAL = 1,\n  MSK_SOLVE_DUAL   = 2\n};\n#define MSK_SOLVE_BEGIN MSK_SOLVE_FREE\n#define MSK_SOLVE_END   (1+MSK_SOLVE_DUAL)\n\n\nenum MSKsparam_enum {\n  MSK_SPAR_BAS_SOL_FILE_NAME         = 0,\n  MSK_SPAR_DATA_FILE_NAME            = 1,\n  MSK_SPAR_DEBUG_FILE_NAME           = 2,\n  MSK_SPAR_INT_SOL_FILE_NAME         = 3,\n  MSK_SPAR_ITR_SOL_FILE_NAME         = 4,\n  MSK_SPAR_MIO_DEBUG_STRING          = 5,\n  MSK_SPAR_PARAM_COMMENT_SIGN        = 6,\n  MSK_SPAR_PARAM_READ_FILE_NAME      = 7,\n  MSK_SPAR_PARAM_WRITE_FILE_NAME     = 8,\n  MSK_SPAR_READ_MPS_BOU_NAME         = 9,\n  MSK_SPAR_READ_MPS_OBJ_NAME         = 10,\n  MSK_SPAR_READ_MPS_RAN_NAME         = 11,\n  MSK_SPAR_READ_MPS_RHS_NAME         = 12,\n  MSK_SPAR_REMOTE_OPTSERVER_HOST     = 13,\n  MSK_SPAR_REMOTE_TLS_CERT           = 14,\n  MSK_SPAR_REMOTE_TLS_CERT_PATH      = 15,\n  MSK_SPAR_SENSITIVITY_FILE_NAME     = 16,\n  MSK_SPAR_SENSITIVITY_RES_FILE_NAME = 17,\n  MSK_SPAR_SOL_FILTER_XC_LOW         = 18,\n  MSK_SPAR_SOL_FILTER_XC_UPR         = 19,\n  MSK_SPAR_SOL_FILTER_XX_LOW         = 20,\n  MSK_SPAR_SOL_FILTER_XX_UPR         = 21,\n  MSK_SPAR_STAT_KEY                  = 22,\n  MSK_SPAR_STAT_NAME                 = 23\n};\n#define MSK_SPAR_BEGIN MSK_SPAR_BAS_SOL_FILE_NAME\n#define MSK_SPAR_END   (1+MSK_SPAR_STAT_NAME)\n\n\nenum MSKstakey_enum {\n  MSK_SK_UNK    = 0,\n  MSK_SK_BAS    = 1,\n  MSK_SK_SUPBAS = 2,\n  MSK_SK_LOW    = 3,\n  MSK_SK_UPR    = 4,\n  MSK_SK_FIX    = 5,\n  MSK_SK_INF    = 6\n};\n#define MSK_SK_BEGIN MSK_SK_UNK\n#define MSK_SK_END   (1+MSK_SK_INF)\n\n\nenum MSKstartpointtype_enum {\n  MSK_STARTING_POINT_FREE     = 0,\n  MSK_STARTING_POINT_GUESS    = 1,\n  MSK_STARTING_POINT_CONSTANT = 2\n};\n#define MSK_STARTING_POINT_BEGIN MSK_STARTING_POINT_FREE\n#define MSK_STARTING_POINT_END   (1+MSK_STARTING_POINT_CONSTANT)\n\n\nenum MSKstreamtype_enum {\n  MSK_STREAM_LOG = 0,\n  MSK_STREAM_MSG = 1,\n  MSK_STREAM_ERR = 2,\n  MSK_STREAM_WRN = 3\n};\n#define MSK_STREAM_BEGIN MSK_STREAM_LOG\n#define MSK_STREAM_END   (1+MSK_STREAM_WRN)\n\n\nenum MSKvalue_enum {\n  MSK_LICENSE_BUFFER_LENGTH = 21,\n  MSK_MAX_STR_LEN           = 1024\n};\n\n\nenum MSKvariabletype_enum {\n  MSK_VAR_TYPE_CONT = 0,\n  MSK_VAR_TYPE_INT  = 1\n};\n#define MSK_VAR_BEGIN MSK_VAR_TYPE_CONT\n#define MSK_VAR_END   (1+MSK_VAR_TYPE_INT)\n\n\n/* } namespace mosek; */\n/**************************************************/\n#define MSK_FIRST_ERR_CODE 1000 \n#define MSK_LAST_ERR_CODE  9999 \n/**************************************************/\ntypedef enum MSK_whichenum_enum {\n  MSK_WHICHENUM_LANGUAGE,\n  MSK_WHICHENUM_BASINDTYPE,\n  MSK_WHICHENUM_BOUNDKEY,\n  MSK_WHICHENUM_MARK,\n  MSK_WHICHENUM_SIMPRECISION,\n  MSK_WHICHENUM_SIMDEGEN,\n  MSK_WHICHENUM_TRANSPOSE,\n  MSK_WHICHENUM_UPLO,\n  MSK_WHICHENUM_SIMREFORM,\n  MSK_WHICHENUM_SIMDUPVEC,\n  MSK_WHICHENUM_SIMHOTSTART,\n  MSK_WHICHENUM_INTPNTHOTSTART,\n  MSK_WHICHENUM_CALLBACKCODE,\n  MSK_WHICHENUM_COMPRESSTYPE,\n  MSK_WHICHENUM_CONETYPE,\n  MSK_WHICHENUM_DOMAINTYPE,\n  MSK_WHICHENUM_NAMETYPE,\n  MSK_WHICHENUM_SYMMATTYPE,\n  MSK_WHICHENUM_DATAFORMAT,\n  MSK_WHICHENUM_SOLFORMAT,\n  MSK_WHICHENUM_DINFITEM,\n  MSK_WHICHENUM_FEATURE,\n  MSK_WHICHENUM_DPARAM,\n  MSK_WHICHENUM_LIINFITEM,\n  MSK_WHICHENUM_INTERNAL_LIINF,\n  MSK_WHICHENUM_IINFITEM,\n  MSK_WHICHENUM_INFTYPE,\n  MSK_WHICHENUM_INTERNAL_DINF,\n  MSK_WHICHENUM_INTERNAL_IINF,\n  MSK_WHICHENUM_IOMODE,\n  MSK_WHICHENUM_IPARAM,\n  MSK_WHICHENUM_BRANCHDIR,\n  MSK_WHICHENUM_MIQCQOREFORMMETHOD,\n  MSK_WHICHENUM_MIODATAPERMMETHOD,\n  MSK_WHICHENUM_MIOCONTSOLTYPE,\n  MSK_WHICHENUM_MIOMODE,\n  MSK_WHICHENUM_MIONODESELTYPE,\n  MSK_WHICHENUM_MIOVARSELTYPE,\n  MSK_WHICHENUM_MPSFORMAT,\n  MSK_WHICHENUM_OBJSENSE,\n  MSK_WHICHENUM_ONOFFKEY,\n  MSK_WHICHENUM_OPTIMIZERTYPE,\n  MSK_WHICHENUM_ORDERINGTYPE,\n  MSK_WHICHENUM_PRESOLVEMODE,\n  MSK_WHICHENUM_FOLDINGMODE,\n  MSK_WHICHENUM_PARAMETERTYPE,\n  MSK_WHICHENUM_PROBLEMITEM,\n  MSK_WHICHENUM_PROBLEMTYPE,\n  MSK_WHICHENUM_PROSTA,\n  MSK_WHICHENUM_RESCODE,\n  MSK_WHICHENUM_RESCODETYPE,\n  MSK_WHICHENUM_SCALINGTYPE,\n  MSK_WHICHENUM_SCALINGMETHOD,\n  MSK_WHICHENUM_SENSITIVITYTYPE,\n  MSK_WHICHENUM_SIMSELTYPE,\n  MSK_WHICHENUM_SOLITEM,\n  MSK_WHICHENUM_SOLSTA,\n  MSK_WHICHENUM_SOLTYPE,\n  MSK_WHICHENUM_SOLVEFORM,\n  MSK_WHICHENUM_SPARAM,\n  MSK_WHICHENUM_STAKEY,\n  MSK_WHICHENUM_STARTPOINTTYPE,\n  MSK_WHICHENUM_STREAMTYPE,\n  MSK_WHICHENUM_VARIABLETYPE,\n  MSK_WHICHENUM_LAST\n} /* MSKwhichenum_enum */\nMSKwhichenume;\n\n\n\n#define MSK_SPAR_BAS_SOL_FILE_NAME_                         \"MSK_SPAR_BAS_SOL_FILE_NAME\"\n#define MSK_SPAR_DATA_FILE_NAME_                            \"MSK_SPAR_DATA_FILE_NAME\"\n#define MSK_SPAR_DEBUG_FILE_NAME_                           \"MSK_SPAR_DEBUG_FILE_NAME\"\n#define MSK_SPAR_INT_SOL_FILE_NAME_                         \"MSK_SPAR_INT_SOL_FILE_NAME\"\n#define MSK_SPAR_ITR_SOL_FILE_NAME_                         \"MSK_SPAR_ITR_SOL_FILE_NAME\"\n#define MSK_SPAR_MIO_DEBUG_STRING_                          \"MSK_SPAR_MIO_DEBUG_STRING\"\n#define MSK_SPAR_PARAM_COMMENT_SIGN_                        \"MSK_SPAR_PARAM_COMMENT_SIGN\"\n#define MSK_SPAR_PARAM_READ_FILE_NAME_                      \"MSK_SPAR_PARAM_READ_FILE_NAME\"\n#define MSK_SPAR_PARAM_WRITE_FILE_NAME_                     \"MSK_SPAR_PARAM_WRITE_FILE_NAME\"\n#define MSK_SPAR_READ_MPS_BOU_NAME_                         \"MSK_SPAR_READ_MPS_BOU_NAME\"\n#define MSK_SPAR_READ_MPS_OBJ_NAME_                         \"MSK_SPAR_READ_MPS_OBJ_NAME\"\n#define MSK_SPAR_READ_MPS_RAN_NAME_                         \"MSK_SPAR_READ_MPS_RAN_NAME\"\n#define MSK_SPAR_READ_MPS_RHS_NAME_                         \"MSK_SPAR_READ_MPS_RHS_NAME\"\n#define MSK_SPAR_REMOTE_OPTSERVER_HOST_                     \"MSK_SPAR_REMOTE_OPTSERVER_HOST\"\n#define MSK_SPAR_REMOTE_TLS_CERT_                           \"MSK_SPAR_REMOTE_TLS_CERT\"\n#define MSK_SPAR_REMOTE_TLS_CERT_PATH_                      \"MSK_SPAR_REMOTE_TLS_CERT_PATH\"\n#define MSK_SPAR_SENSITIVITY_FILE_NAME_                     \"MSK_SPAR_SENSITIVITY_FILE_NAME\"\n#define MSK_SPAR_SENSITIVITY_RES_FILE_NAME_                 \"MSK_SPAR_SENSITIVITY_RES_FILE_NAME\"\n#define MSK_SPAR_SOL_FILTER_XC_LOW_                         \"MSK_SPAR_SOL_FILTER_XC_LOW\"\n#define MSK_SPAR_SOL_FILTER_XC_UPR_                         \"MSK_SPAR_SOL_FILTER_XC_UPR\"\n#define MSK_SPAR_SOL_FILTER_XX_LOW_                         \"MSK_SPAR_SOL_FILTER_XX_LOW\"\n#define MSK_SPAR_SOL_FILTER_XX_UPR_                         \"MSK_SPAR_SOL_FILTER_XX_UPR\"\n#define MSK_SPAR_STAT_KEY_                                  \"MSK_SPAR_STAT_KEY\"\n#define MSK_SPAR_STAT_NAME_                                 \"MSK_SPAR_STAT_NAME\"\n\n#define MSK_DPAR_ANA_SOL_INFEAS_TOL_                        \"MSK_DPAR_ANA_SOL_INFEAS_TOL\"\n#define MSK_DPAR_BASIS_REL_TOL_S_                           \"MSK_DPAR_BASIS_REL_TOL_S\"\n#define MSK_DPAR_BASIS_TOL_S_                               \"MSK_DPAR_BASIS_TOL_S\"\n#define MSK_DPAR_BASIS_TOL_X_                               \"MSK_DPAR_BASIS_TOL_X\"\n#define MSK_DPAR_DATA_SYM_MAT_TOL_                          \"MSK_DPAR_DATA_SYM_MAT_TOL\"\n#define MSK_DPAR_DATA_SYM_MAT_TOL_HUGE_                     \"MSK_DPAR_DATA_SYM_MAT_TOL_HUGE\"\n#define MSK_DPAR_DATA_SYM_MAT_TOL_LARGE_                    \"MSK_DPAR_DATA_SYM_MAT_TOL_LARGE\"\n#define MSK_DPAR_DATA_TOL_AIJ_HUGE_                         \"MSK_DPAR_DATA_TOL_AIJ_HUGE\"\n#define MSK_DPAR_DATA_TOL_AIJ_LARGE_                        \"MSK_DPAR_DATA_TOL_AIJ_LARGE\"\n#define MSK_DPAR_DATA_TOL_BOUND_INF_                        \"MSK_DPAR_DATA_TOL_BOUND_INF\"\n#define MSK_DPAR_DATA_TOL_BOUND_WRN_                        \"MSK_DPAR_DATA_TOL_BOUND_WRN\"\n#define MSK_DPAR_DATA_TOL_C_HUGE_                           \"MSK_DPAR_DATA_TOL_C_HUGE\"\n#define MSK_DPAR_DATA_TOL_CJ_LARGE_                         \"MSK_DPAR_DATA_TOL_CJ_LARGE\"\n#define MSK_DPAR_DATA_TOL_QIJ_                              \"MSK_DPAR_DATA_TOL_QIJ\"\n#define MSK_DPAR_DATA_TOL_X_                                \"MSK_DPAR_DATA_TOL_X\"\n#define MSK_DPAR_FOLDING_TOL_EQ_                            \"MSK_DPAR_FOLDING_TOL_EQ\"\n#define MSK_DPAR_INTPNT_CO_TOL_DFEAS_                       \"MSK_DPAR_INTPNT_CO_TOL_DFEAS\"\n#define MSK_DPAR_INTPNT_CO_TOL_INFEAS_                      \"MSK_DPAR_INTPNT_CO_TOL_INFEAS\"\n#define MSK_DPAR_INTPNT_CO_TOL_MU_RED_                      \"MSK_DPAR_INTPNT_CO_TOL_MU_RED\"\n#define MSK_DPAR_INTPNT_CO_TOL_NEAR_REL_                    \"MSK_DPAR_INTPNT_CO_TOL_NEAR_REL\"\n#define MSK_DPAR_INTPNT_CO_TOL_PFEAS_                       \"MSK_DPAR_INTPNT_CO_TOL_PFEAS\"\n#define MSK_DPAR_INTPNT_CO_TOL_REL_GAP_                     \"MSK_DPAR_INTPNT_CO_TOL_REL_GAP\"\n#define MSK_DPAR_INTPNT_QO_TOL_DFEAS_                       \"MSK_DPAR_INTPNT_QO_TOL_DFEAS\"\n#define MSK_DPAR_INTPNT_QO_TOL_INFEAS_                      \"MSK_DPAR_INTPNT_QO_TOL_INFEAS\"\n#define MSK_DPAR_INTPNT_QO_TOL_MU_RED_                      \"MSK_DPAR_INTPNT_QO_TOL_MU_RED\"\n#define MSK_DPAR_INTPNT_QO_TOL_NEAR_REL_                    \"MSK_DPAR_INTPNT_QO_TOL_NEAR_REL\"\n#define MSK_DPAR_INTPNT_QO_TOL_PFEAS_                       \"MSK_DPAR_INTPNT_QO_TOL_PFEAS\"\n#define MSK_DPAR_INTPNT_QO_TOL_REL_GAP_                     \"MSK_DPAR_INTPNT_QO_TOL_REL_GAP\"\n#define MSK_DPAR_INTPNT_TOL_DFEAS_                          \"MSK_DPAR_INTPNT_TOL_DFEAS\"\n#define MSK_DPAR_INTPNT_TOL_DSAFE_                          \"MSK_DPAR_INTPNT_TOL_DSAFE\"\n#define MSK_DPAR_INTPNT_TOL_INFEAS_                         \"MSK_DPAR_INTPNT_TOL_INFEAS\"\n#define MSK_DPAR_INTPNT_TOL_MU_RED_                         \"MSK_DPAR_INTPNT_TOL_MU_RED\"\n#define MSK_DPAR_INTPNT_TOL_PATH_                           \"MSK_DPAR_INTPNT_TOL_PATH\"\n#define MSK_DPAR_INTPNT_TOL_PFEAS_                          \"MSK_DPAR_INTPNT_TOL_PFEAS\"\n#define MSK_DPAR_INTPNT_TOL_PSAFE_                          \"MSK_DPAR_INTPNT_TOL_PSAFE\"\n#define MSK_DPAR_INTPNT_TOL_REL_GAP_                        \"MSK_DPAR_INTPNT_TOL_REL_GAP\"\n#define MSK_DPAR_INTPNT_TOL_REL_STEP_                       \"MSK_DPAR_INTPNT_TOL_REL_STEP\"\n#define MSK_DPAR_INTPNT_TOL_STEP_SIZE_                      \"MSK_DPAR_INTPNT_TOL_STEP_SIZE\"\n#define MSK_DPAR_LOWER_OBJ_CUT_                             \"MSK_DPAR_LOWER_OBJ_CUT\"\n#define MSK_DPAR_LOWER_OBJ_CUT_FINITE_TRH_                  \"MSK_DPAR_LOWER_OBJ_CUT_FINITE_TRH\"\n#define MSK_DPAR_MIO_CLIQUE_TABLE_SIZE_FACTOR_              \"MSK_DPAR_MIO_CLIQUE_TABLE_SIZE_FACTOR\"\n#define MSK_DPAR_MIO_DJC_MAX_BIGM_                          \"MSK_DPAR_MIO_DJC_MAX_BIGM\"\n#define MSK_DPAR_MIO_MAX_TIME_                              \"MSK_DPAR_MIO_MAX_TIME\"\n#define MSK_DPAR_MIO_REL_GAP_CONST_                         \"MSK_DPAR_MIO_REL_GAP_CONST\"\n#define MSK_DPAR_MIO_TOL_ABS_GAP_                           \"MSK_DPAR_MIO_TOL_ABS_GAP\"\n#define MSK_DPAR_MIO_TOL_ABS_RELAX_INT_                     \"MSK_DPAR_MIO_TOL_ABS_RELAX_INT\"\n#define MSK_DPAR_MIO_TOL_FEAS_                              \"MSK_DPAR_MIO_TOL_FEAS\"\n#define MSK_DPAR_MIO_TOL_REL_DUAL_BOUND_IMPROVEMENT_        \"MSK_DPAR_MIO_TOL_REL_DUAL_BOUND_IMPROVEMENT\"\n#define MSK_DPAR_MIO_TOL_REL_GAP_                           \"MSK_DPAR_MIO_TOL_REL_GAP\"\n#define MSK_DPAR_OPTIMIZER_MAX_TICKS_                       \"MSK_DPAR_OPTIMIZER_MAX_TICKS\"\n#define MSK_DPAR_OPTIMIZER_MAX_TIME_                        \"MSK_DPAR_OPTIMIZER_MAX_TIME\"\n#define MSK_DPAR_PRESOLVE_TOL_ABS_LINDEP_                   \"MSK_DPAR_PRESOLVE_TOL_ABS_LINDEP\"\n#define MSK_DPAR_PRESOLVE_TOL_PRIMAL_INFEAS_PERTURBATION_   \"MSK_DPAR_PRESOLVE_TOL_PRIMAL_INFEAS_PERTURBATION\"\n#define MSK_DPAR_PRESOLVE_TOL_REL_LINDEP_                   \"MSK_DPAR_PRESOLVE_TOL_REL_LINDEP\"\n#define MSK_DPAR_PRESOLVE_TOL_S_                            \"MSK_DPAR_PRESOLVE_TOL_S\"\n#define MSK_DPAR_PRESOLVE_TOL_X_                            \"MSK_DPAR_PRESOLVE_TOL_X\"\n#define MSK_DPAR_QCQO_REFORMULATE_REL_DROP_TOL_             \"MSK_DPAR_QCQO_REFORMULATE_REL_DROP_TOL\"\n#define MSK_DPAR_SEMIDEFINITE_TOL_APPROX_                   \"MSK_DPAR_SEMIDEFINITE_TOL_APPROX\"\n#define MSK_DPAR_SIM_LU_TOL_REL_PIV_                        \"MSK_DPAR_SIM_LU_TOL_REL_PIV\"\n#define MSK_DPAR_SIM_PRECISION_SCALING_EXTENDED_            \"MSK_DPAR_SIM_PRECISION_SCALING_EXTENDED\"\n#define MSK_DPAR_SIM_PRECISION_SCALING_NORMAL_              \"MSK_DPAR_SIM_PRECISION_SCALING_NORMAL\"\n#define MSK_DPAR_SIMPLEX_ABS_TOL_PIV_                       \"MSK_DPAR_SIMPLEX_ABS_TOL_PIV\"\n#define MSK_DPAR_UPPER_OBJ_CUT_                             \"MSK_DPAR_UPPER_OBJ_CUT\"\n#define MSK_DPAR_UPPER_OBJ_CUT_FINITE_TRH_                  \"MSK_DPAR_UPPER_OBJ_CUT_FINITE_TRH\"\n\n#define MSK_IPAR_ANA_SOL_BASIS_                             \"MSK_IPAR_ANA_SOL_BASIS\"\n#define MSK_IPAR_ANA_SOL_PRINT_VIOLATED_                    \"MSK_IPAR_ANA_SOL_PRINT_VIOLATED\"\n#define MSK_IPAR_AUTO_SORT_A_BEFORE_OPT_                    \"MSK_IPAR_AUTO_SORT_A_BEFORE_OPT\"\n#define MSK_IPAR_AUTO_UPDATE_SOL_INFO_                      \"MSK_IPAR_AUTO_UPDATE_SOL_INFO\"\n#define MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_                  \"MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE\"\n#define MSK_IPAR_BI_CLEAN_OPTIMIZER_                        \"MSK_IPAR_BI_CLEAN_OPTIMIZER\"\n#define MSK_IPAR_BI_IGNORE_MAX_ITER_                        \"MSK_IPAR_BI_IGNORE_MAX_ITER\"\n#define MSK_IPAR_BI_IGNORE_NUM_ERROR_                       \"MSK_IPAR_BI_IGNORE_NUM_ERROR\"\n#define MSK_IPAR_BI_MAX_ITERATIONS_                         \"MSK_IPAR_BI_MAX_ITERATIONS\"\n#define MSK_IPAR_CACHE_LICENSE_                             \"MSK_IPAR_CACHE_LICENSE\"\n#define MSK_IPAR_COMPRESS_STATFILE_                         \"MSK_IPAR_COMPRESS_STATFILE\"\n#define MSK_IPAR_FOLDING_USE_                               \"MSK_IPAR_FOLDING_USE\"\n#define MSK_IPAR_GETDUAL_CONVERT_LMIS_                      \"MSK_IPAR_GETDUAL_CONVERT_LMIS\"\n#define MSK_IPAR_HEARTBEAT_SIM_FREQ_TICKS_                  \"MSK_IPAR_HEARTBEAT_SIM_FREQ_TICKS\"\n#define MSK_IPAR_INFEAS_GENERIC_NAMES_                      \"MSK_IPAR_INFEAS_GENERIC_NAMES\"\n#define MSK_IPAR_INFEAS_REPORT_AUTO_                        \"MSK_IPAR_INFEAS_REPORT_AUTO\"\n#define MSK_IPAR_INFEAS_REPORT_LEVEL_                       \"MSK_IPAR_INFEAS_REPORT_LEVEL\"\n#define MSK_IPAR_INTPNT_BASIS_                              \"MSK_IPAR_INTPNT_BASIS\"\n#define MSK_IPAR_INTPNT_DIFF_STEP_                          \"MSK_IPAR_INTPNT_DIFF_STEP\"\n#define MSK_IPAR_INTPNT_HOTSTART_                           \"MSK_IPAR_INTPNT_HOTSTART\"\n#define MSK_IPAR_INTPNT_MAX_ITERATIONS_                     \"MSK_IPAR_INTPNT_MAX_ITERATIONS\"\n#define MSK_IPAR_INTPNT_MAX_NUM_COR_                        \"MSK_IPAR_INTPNT_MAX_NUM_COR\"\n#define MSK_IPAR_INTPNT_OFF_COL_TRH_                        \"MSK_IPAR_INTPNT_OFF_COL_TRH\"\n#define MSK_IPAR_INTPNT_ORDER_GP_NUM_SEEDS_                 \"MSK_IPAR_INTPNT_ORDER_GP_NUM_SEEDS\"\n#define MSK_IPAR_INTPNT_ORDER_METHOD_                       \"MSK_IPAR_INTPNT_ORDER_METHOD\"\n#define MSK_IPAR_INTPNT_REGULARIZATION_USE_                 \"MSK_IPAR_INTPNT_REGULARIZATION_USE\"\n#define MSK_IPAR_INTPNT_SCALING_                            \"MSK_IPAR_INTPNT_SCALING\"\n#define MSK_IPAR_INTPNT_SOLVE_FORM_                         \"MSK_IPAR_INTPNT_SOLVE_FORM\"\n#define MSK_IPAR_INTPNT_STARTING_POINT_                     \"MSK_IPAR_INTPNT_STARTING_POINT\"\n#define MSK_IPAR_LICENSE_DEBUG_                             \"MSK_IPAR_LICENSE_DEBUG\"\n#define MSK_IPAR_LICENSE_PAUSE_TIME_                        \"MSK_IPAR_LICENSE_PAUSE_TIME\"\n#define MSK_IPAR_LICENSE_SUPPRESS_EXPIRE_WRNS_              \"MSK_IPAR_LICENSE_SUPPRESS_EXPIRE_WRNS\"\n#define MSK_IPAR_LICENSE_TRH_EXPIRY_WRN_                    \"MSK_IPAR_LICENSE_TRH_EXPIRY_WRN\"\n#define MSK_IPAR_LICENSE_WAIT_                              \"MSK_IPAR_LICENSE_WAIT\"\n#define MSK_IPAR_LOG_                                       \"MSK_IPAR_LOG\"\n#define MSK_IPAR_LOG_ANA_PRO_                               \"MSK_IPAR_LOG_ANA_PRO\"\n#define MSK_IPAR_LOG_BI_                                    \"MSK_IPAR_LOG_BI\"\n#define MSK_IPAR_LOG_BI_FREQ_                               \"MSK_IPAR_LOG_BI_FREQ\"\n#define MSK_IPAR_LOG_CUT_SECOND_OPT_                        \"MSK_IPAR_LOG_CUT_SECOND_OPT\"\n#define MSK_IPAR_LOG_EXPAND_                                \"MSK_IPAR_LOG_EXPAND\"\n#define MSK_IPAR_LOG_FEAS_REPAIR_                           \"MSK_IPAR_LOG_FEAS_REPAIR\"\n#define MSK_IPAR_LOG_FILE_                                  \"MSK_IPAR_LOG_FILE\"\n#define MSK_IPAR_LOG_INCLUDE_SUMMARY_                       \"MSK_IPAR_LOG_INCLUDE_SUMMARY\"\n#define MSK_IPAR_LOG_INFEAS_ANA_                            \"MSK_IPAR_LOG_INFEAS_ANA\"\n#define MSK_IPAR_LOG_INTPNT_                                \"MSK_IPAR_LOG_INTPNT\"\n#define MSK_IPAR_LOG_LOCAL_INFO_                            \"MSK_IPAR_LOG_LOCAL_INFO\"\n#define MSK_IPAR_LOG_MIO_                                   \"MSK_IPAR_LOG_MIO\"\n#define MSK_IPAR_LOG_MIO_FREQ_                              \"MSK_IPAR_LOG_MIO_FREQ\"\n#define MSK_IPAR_LOG_ORDER_                                 \"MSK_IPAR_LOG_ORDER\"\n#define MSK_IPAR_LOG_PRESOLVE_                              \"MSK_IPAR_LOG_PRESOLVE\"\n#define MSK_IPAR_LOG_SENSITIVITY_                           \"MSK_IPAR_LOG_SENSITIVITY\"\n#define MSK_IPAR_LOG_SENSITIVITY_OPT_                       \"MSK_IPAR_LOG_SENSITIVITY_OPT\"\n#define MSK_IPAR_LOG_SIM_                                   \"MSK_IPAR_LOG_SIM\"\n#define MSK_IPAR_LOG_SIM_FREQ_                              \"MSK_IPAR_LOG_SIM_FREQ\"\n#define MSK_IPAR_LOG_SIM_FREQ_GIGA_TICKS_                   \"MSK_IPAR_LOG_SIM_FREQ_GIGA_TICKS\"\n#define MSK_IPAR_LOG_STORAGE_                               \"MSK_IPAR_LOG_STORAGE\"\n#define MSK_IPAR_MAX_NUM_WARNINGS_                          \"MSK_IPAR_MAX_NUM_WARNINGS\"\n#define MSK_IPAR_MIO_BRANCH_DIR_                            \"MSK_IPAR_MIO_BRANCH_DIR\"\n#define MSK_IPAR_MIO_CONFLICT_ANALYSIS_LEVEL_               \"MSK_IPAR_MIO_CONFLICT_ANALYSIS_LEVEL\"\n#define MSK_IPAR_MIO_CONIC_OUTER_APPROXIMATION_             \"MSK_IPAR_MIO_CONIC_OUTER_APPROXIMATION\"\n#define MSK_IPAR_MIO_CONSTRUCT_SOL_                         \"MSK_IPAR_MIO_CONSTRUCT_SOL\"\n#define MSK_IPAR_MIO_CROSSOVER_MAX_NODES_                   \"MSK_IPAR_MIO_CROSSOVER_MAX_NODES\"\n#define MSK_IPAR_MIO_CUT_CLIQUE_                            \"MSK_IPAR_MIO_CUT_CLIQUE\"\n#define MSK_IPAR_MIO_CUT_CMIR_                              \"MSK_IPAR_MIO_CUT_CMIR\"\n#define MSK_IPAR_MIO_CUT_GMI_                               \"MSK_IPAR_MIO_CUT_GMI\"\n#define MSK_IPAR_MIO_CUT_IMPLIED_BOUND_                     \"MSK_IPAR_MIO_CUT_IMPLIED_BOUND\"\n#define MSK_IPAR_MIO_CUT_KNAPSACK_COVER_                    \"MSK_IPAR_MIO_CUT_KNAPSACK_COVER\"\n#define MSK_IPAR_MIO_CUT_LIPRO_                             \"MSK_IPAR_MIO_CUT_LIPRO\"\n#define MSK_IPAR_MIO_CUT_SELECTION_LEVEL_                   \"MSK_IPAR_MIO_CUT_SELECTION_LEVEL\"\n#define MSK_IPAR_MIO_DATA_PERMUTATION_METHOD_               \"MSK_IPAR_MIO_DATA_PERMUTATION_METHOD\"\n#define MSK_IPAR_MIO_DUAL_RAY_ANALYSIS_LEVEL_               \"MSK_IPAR_MIO_DUAL_RAY_ANALYSIS_LEVEL\"\n#define MSK_IPAR_MIO_FEASPUMP_LEVEL_                        \"MSK_IPAR_MIO_FEASPUMP_LEVEL\"\n#define MSK_IPAR_MIO_HEURISTIC_LEVEL_                       \"MSK_IPAR_MIO_HEURISTIC_LEVEL\"\n#define MSK_IPAR_MIO_INDEPENDENT_BLOCK_LEVEL_               \"MSK_IPAR_MIO_INDEPENDENT_BLOCK_LEVEL\"\n#define MSK_IPAR_MIO_MAX_NUM_BRANCHES_                      \"MSK_IPAR_MIO_MAX_NUM_BRANCHES\"\n#define MSK_IPAR_MIO_MAX_NUM_RELAXS_                        \"MSK_IPAR_MIO_MAX_NUM_RELAXS\"\n#define MSK_IPAR_MIO_MAX_NUM_RESTARTS_                      \"MSK_IPAR_MIO_MAX_NUM_RESTARTS\"\n#define MSK_IPAR_MIO_MAX_NUM_ROOT_CUT_ROUNDS_               \"MSK_IPAR_MIO_MAX_NUM_ROOT_CUT_ROUNDS\"\n#define MSK_IPAR_MIO_MAX_NUM_SOLUTIONS_                     \"MSK_IPAR_MIO_MAX_NUM_SOLUTIONS\"\n#define MSK_IPAR_MIO_MEMORY_EMPHASIS_LEVEL_                 \"MSK_IPAR_MIO_MEMORY_EMPHASIS_LEVEL\"\n#define MSK_IPAR_MIO_MIN_REL_                               \"MSK_IPAR_MIO_MIN_REL\"\n#define MSK_IPAR_MIO_MODE_                                  \"MSK_IPAR_MIO_MODE\"\n#define MSK_IPAR_MIO_NODE_OPTIMIZER_                        \"MSK_IPAR_MIO_NODE_OPTIMIZER\"\n#define MSK_IPAR_MIO_NODE_SELECTION_                        \"MSK_IPAR_MIO_NODE_SELECTION\"\n#define MSK_IPAR_MIO_NUMERICAL_EMPHASIS_LEVEL_              \"MSK_IPAR_MIO_NUMERICAL_EMPHASIS_LEVEL\"\n#define MSK_IPAR_MIO_OPT_FACE_MAX_NODES_                    \"MSK_IPAR_MIO_OPT_FACE_MAX_NODES\"\n#define MSK_IPAR_MIO_PERSPECTIVE_REFORMULATE_               \"MSK_IPAR_MIO_PERSPECTIVE_REFORMULATE\"\n#define MSK_IPAR_MIO_PRESOLVE_AGGREGATOR_USE_               \"MSK_IPAR_MIO_PRESOLVE_AGGREGATOR_USE\"\n#define MSK_IPAR_MIO_PROBING_LEVEL_                         \"MSK_IPAR_MIO_PROBING_LEVEL\"\n#define MSK_IPAR_MIO_PROPAGATE_OBJECTIVE_CONSTRAINT_        \"MSK_IPAR_MIO_PROPAGATE_OBJECTIVE_CONSTRAINT\"\n#define MSK_IPAR_MIO_QCQO_REFORMULATION_METHOD_             \"MSK_IPAR_MIO_QCQO_REFORMULATION_METHOD\"\n#define MSK_IPAR_MIO_RENS_MAX_NODES_                        \"MSK_IPAR_MIO_RENS_MAX_NODES\"\n#define MSK_IPAR_MIO_RINS_MAX_NODES_                        \"MSK_IPAR_MIO_RINS_MAX_NODES\"\n#define MSK_IPAR_MIO_ROOT_OPTIMIZER_                        \"MSK_IPAR_MIO_ROOT_OPTIMIZER\"\n#define MSK_IPAR_MIO_SEED_                                  \"MSK_IPAR_MIO_SEED\"\n#define MSK_IPAR_MIO_SYMMETRY_LEVEL_                        \"MSK_IPAR_MIO_SYMMETRY_LEVEL\"\n#define MSK_IPAR_MIO_VAR_SELECTION_                         \"MSK_IPAR_MIO_VAR_SELECTION\"\n#define MSK_IPAR_MIO_VB_DETECTION_LEVEL_                    \"MSK_IPAR_MIO_VB_DETECTION_LEVEL\"\n#define MSK_IPAR_MT_SPINCOUNT_                              \"MSK_IPAR_MT_SPINCOUNT\"\n#define MSK_IPAR_NG_                                        \"MSK_IPAR_NG\"\n#define MSK_IPAR_NUM_THREADS_                               \"MSK_IPAR_NUM_THREADS\"\n#define MSK_IPAR_OPF_WRITE_HEADER_                          \"MSK_IPAR_OPF_WRITE_HEADER\"\n#define MSK_IPAR_OPF_WRITE_HINTS_                           \"MSK_IPAR_OPF_WRITE_HINTS\"\n#define MSK_IPAR_OPF_WRITE_LINE_LENGTH_                     \"MSK_IPAR_OPF_WRITE_LINE_LENGTH\"\n#define MSK_IPAR_OPF_WRITE_PARAMETERS_                      \"MSK_IPAR_OPF_WRITE_PARAMETERS\"\n#define MSK_IPAR_OPF_WRITE_PROBLEM_                         \"MSK_IPAR_OPF_WRITE_PROBLEM\"\n#define MSK_IPAR_OPF_WRITE_SOL_BAS_                         \"MSK_IPAR_OPF_WRITE_SOL_BAS\"\n#define MSK_IPAR_OPF_WRITE_SOL_ITG_                         \"MSK_IPAR_OPF_WRITE_SOL_ITG\"\n#define MSK_IPAR_OPF_WRITE_SOL_ITR_                         \"MSK_IPAR_OPF_WRITE_SOL_ITR\"\n#define MSK_IPAR_OPF_WRITE_SOLUTIONS_                       \"MSK_IPAR_OPF_WRITE_SOLUTIONS\"\n#define MSK_IPAR_OPTIMIZER_                                 \"MSK_IPAR_OPTIMIZER\"\n#define MSK_IPAR_PARAM_READ_CASE_NAME_                      \"MSK_IPAR_PARAM_READ_CASE_NAME\"\n#define MSK_IPAR_PARAM_READ_IGN_ERROR_                      \"MSK_IPAR_PARAM_READ_IGN_ERROR\"\n#define MSK_IPAR_PRESOLVE_ELIMINATOR_MAX_FILL_              \"MSK_IPAR_PRESOLVE_ELIMINATOR_MAX_FILL\"\n#define MSK_IPAR_PRESOLVE_ELIMINATOR_MAX_NUM_TRIES_         \"MSK_IPAR_PRESOLVE_ELIMINATOR_MAX_NUM_TRIES\"\n#define MSK_IPAR_PRESOLVE_LINDEP_ABS_WORK_TRH_              \"MSK_IPAR_PRESOLVE_LINDEP_ABS_WORK_TRH\"\n#define MSK_IPAR_PRESOLVE_LINDEP_NEW_                       \"MSK_IPAR_PRESOLVE_LINDEP_NEW\"\n#define MSK_IPAR_PRESOLVE_LINDEP_REL_WORK_TRH_              \"MSK_IPAR_PRESOLVE_LINDEP_REL_WORK_TRH\"\n#define MSK_IPAR_PRESOLVE_LINDEP_USE_                       \"MSK_IPAR_PRESOLVE_LINDEP_USE\"\n#define MSK_IPAR_PRESOLVE_MAX_NUM_PASS_                     \"MSK_IPAR_PRESOLVE_MAX_NUM_PASS\"\n#define MSK_IPAR_PRESOLVE_MAX_NUM_REDUCTIONS_               \"MSK_IPAR_PRESOLVE_MAX_NUM_REDUCTIONS\"\n#define MSK_IPAR_PRESOLVE_USE_                              \"MSK_IPAR_PRESOLVE_USE\"\n#define MSK_IPAR_PRIMAL_REPAIR_OPTIMIZER_                   \"MSK_IPAR_PRIMAL_REPAIR_OPTIMIZER\"\n#define MSK_IPAR_PTF_WRITE_PARAMETERS_                      \"MSK_IPAR_PTF_WRITE_PARAMETERS\"\n#define MSK_IPAR_PTF_WRITE_SINGLE_PSD_TERMS_                \"MSK_IPAR_PTF_WRITE_SINGLE_PSD_TERMS\"\n#define MSK_IPAR_PTF_WRITE_SOLUTIONS_                       \"MSK_IPAR_PTF_WRITE_SOLUTIONS\"\n#define MSK_IPAR_PTF_WRITE_TRANSFORM_                       \"MSK_IPAR_PTF_WRITE_TRANSFORM\"\n#define MSK_IPAR_READ_ASYNC_                                \"MSK_IPAR_READ_ASYNC\"\n#define MSK_IPAR_READ_DEBUG_                                \"MSK_IPAR_READ_DEBUG\"\n#define MSK_IPAR_READ_KEEP_FREE_CON_                        \"MSK_IPAR_READ_KEEP_FREE_CON\"\n#define MSK_IPAR_READ_MPS_FORMAT_                           \"MSK_IPAR_READ_MPS_FORMAT\"\n#define MSK_IPAR_READ_MPS_WIDTH_                            \"MSK_IPAR_READ_MPS_WIDTH\"\n#define MSK_IPAR_READ_TASK_IGNORE_PARAM_                    \"MSK_IPAR_READ_TASK_IGNORE_PARAM\"\n#define MSK_IPAR_REMOTE_USE_COMPRESSION_                    \"MSK_IPAR_REMOTE_USE_COMPRESSION\"\n#define MSK_IPAR_REMOVE_UNUSED_SOLUTIONS_                   \"MSK_IPAR_REMOVE_UNUSED_SOLUTIONS\"\n#define MSK_IPAR_SENSITIVITY_ALL_                           \"MSK_IPAR_SENSITIVITY_ALL\"\n#define MSK_IPAR_SENSITIVITY_TYPE_                          \"MSK_IPAR_SENSITIVITY_TYPE\"\n#define MSK_IPAR_SIM_BASIS_FACTOR_USE_                      \"MSK_IPAR_SIM_BASIS_FACTOR_USE\"\n#define MSK_IPAR_SIM_DEGEN_                                 \"MSK_IPAR_SIM_DEGEN\"\n#define MSK_IPAR_SIM_DETECT_PWL_                            \"MSK_IPAR_SIM_DETECT_PWL\"\n#define MSK_IPAR_SIM_DUAL_CRASH_                            \"MSK_IPAR_SIM_DUAL_CRASH\"\n#define MSK_IPAR_SIM_DUAL_PHASEONE_METHOD_                  \"MSK_IPAR_SIM_DUAL_PHASEONE_METHOD\"\n#define MSK_IPAR_SIM_DUAL_RESTRICT_SELECTION_               \"MSK_IPAR_SIM_DUAL_RESTRICT_SELECTION\"\n#define MSK_IPAR_SIM_DUAL_SELECTION_                        \"MSK_IPAR_SIM_DUAL_SELECTION\"\n#define MSK_IPAR_SIM_EXPLOIT_DUPVEC_                        \"MSK_IPAR_SIM_EXPLOIT_DUPVEC\"\n#define MSK_IPAR_SIM_HOTSTART_                              \"MSK_IPAR_SIM_HOTSTART\"\n#define MSK_IPAR_SIM_HOTSTART_LU_                           \"MSK_IPAR_SIM_HOTSTART_LU\"\n#define MSK_IPAR_SIM_MAX_ITERATIONS_                        \"MSK_IPAR_SIM_MAX_ITERATIONS\"\n#define MSK_IPAR_SIM_MAX_NUM_SETBACKS_                      \"MSK_IPAR_SIM_MAX_NUM_SETBACKS\"\n#define MSK_IPAR_SIM_NON_SINGULAR_                          \"MSK_IPAR_SIM_NON_SINGULAR\"\n#define MSK_IPAR_SIM_PRECISION_                             \"MSK_IPAR_SIM_PRECISION\"\n#define MSK_IPAR_SIM_PRECISION_BOOST_                       \"MSK_IPAR_SIM_PRECISION_BOOST\"\n#define MSK_IPAR_SIM_PRIMAL_CRASH_                          \"MSK_IPAR_SIM_PRIMAL_CRASH\"\n#define MSK_IPAR_SIM_PRIMAL_PHASEONE_METHOD_                \"MSK_IPAR_SIM_PRIMAL_PHASEONE_METHOD\"\n#define MSK_IPAR_SIM_PRIMAL_RESTRICT_SELECTION_             \"MSK_IPAR_SIM_PRIMAL_RESTRICT_SELECTION\"\n#define MSK_IPAR_SIM_PRIMAL_SELECTION_                      \"MSK_IPAR_SIM_PRIMAL_SELECTION\"\n#define MSK_IPAR_SIM_REFACTOR_FREQ_                         \"MSK_IPAR_SIM_REFACTOR_FREQ\"\n#define MSK_IPAR_SIM_REFORMULATION_                         \"MSK_IPAR_SIM_REFORMULATION\"\n#define MSK_IPAR_SIM_SAVE_LU_                               \"MSK_IPAR_SIM_SAVE_LU\"\n#define MSK_IPAR_SIM_SCALING_                               \"MSK_IPAR_SIM_SCALING\"\n#define MSK_IPAR_SIM_SCALING_METHOD_                        \"MSK_IPAR_SIM_SCALING_METHOD\"\n#define MSK_IPAR_SIM_SEED_                                  \"MSK_IPAR_SIM_SEED\"\n#define MSK_IPAR_SIM_SOLVE_FORM_                            \"MSK_IPAR_SIM_SOLVE_FORM\"\n#define MSK_IPAR_SIM_SWITCH_OPTIMIZER_                      \"MSK_IPAR_SIM_SWITCH_OPTIMIZER\"\n#define MSK_IPAR_SOL_FILTER_KEEP_BASIC_                     \"MSK_IPAR_SOL_FILTER_KEEP_BASIC\"\n#define MSK_IPAR_SOL_READ_NAME_WIDTH_                       \"MSK_IPAR_SOL_READ_NAME_WIDTH\"\n#define MSK_IPAR_SOL_READ_WIDTH_                            \"MSK_IPAR_SOL_READ_WIDTH\"\n#define MSK_IPAR_TIMING_LEVEL_                              \"MSK_IPAR_TIMING_LEVEL\"\n#define MSK_IPAR_WRITE_ASYNC_                               \"MSK_IPAR_WRITE_ASYNC\"\n#define MSK_IPAR_WRITE_BAS_CONSTRAINTS_                     \"MSK_IPAR_WRITE_BAS_CONSTRAINTS\"\n#define MSK_IPAR_WRITE_BAS_HEAD_                            \"MSK_IPAR_WRITE_BAS_HEAD\"\n#define MSK_IPAR_WRITE_BAS_VARIABLES_                       \"MSK_IPAR_WRITE_BAS_VARIABLES\"\n#define MSK_IPAR_WRITE_COMPRESSION_                         \"MSK_IPAR_WRITE_COMPRESSION\"\n#define MSK_IPAR_WRITE_FREE_CON_                            \"MSK_IPAR_WRITE_FREE_CON\"\n#define MSK_IPAR_WRITE_GENERIC_NAMES_                       \"MSK_IPAR_WRITE_GENERIC_NAMES\"\n#define MSK_IPAR_WRITE_IGNORE_INCOMPATIBLE_ITEMS_           \"MSK_IPAR_WRITE_IGNORE_INCOMPATIBLE_ITEMS\"\n#define MSK_IPAR_WRITE_INT_CONSTRAINTS_                     \"MSK_IPAR_WRITE_INT_CONSTRAINTS\"\n#define MSK_IPAR_WRITE_INT_HEAD_                            \"MSK_IPAR_WRITE_INT_HEAD\"\n#define MSK_IPAR_WRITE_INT_VARIABLES_                       \"MSK_IPAR_WRITE_INT_VARIABLES\"\n#define MSK_IPAR_WRITE_JSON_INDENTATION_                    \"MSK_IPAR_WRITE_JSON_INDENTATION\"\n#define MSK_IPAR_WRITE_LP_FULL_OBJ_                         \"MSK_IPAR_WRITE_LP_FULL_OBJ\"\n#define MSK_IPAR_WRITE_LP_LINE_WIDTH_                       \"MSK_IPAR_WRITE_LP_LINE_WIDTH\"\n#define MSK_IPAR_WRITE_MPS_FORMAT_                          \"MSK_IPAR_WRITE_MPS_FORMAT\"\n#define MSK_IPAR_WRITE_MPS_INT_                             \"MSK_IPAR_WRITE_MPS_INT\"\n#define MSK_IPAR_WRITE_SOL_BARVARIABLES_                    \"MSK_IPAR_WRITE_SOL_BARVARIABLES\"\n#define MSK_IPAR_WRITE_SOL_CONSTRAINTS_                     \"MSK_IPAR_WRITE_SOL_CONSTRAINTS\"\n#define MSK_IPAR_WRITE_SOL_HEAD_                            \"MSK_IPAR_WRITE_SOL_HEAD\"\n#define MSK_IPAR_WRITE_SOL_IGNORE_INVALID_NAMES_            \"MSK_IPAR_WRITE_SOL_IGNORE_INVALID_NAMES\"\n#define MSK_IPAR_WRITE_SOL_VARIABLES_                       \"MSK_IPAR_WRITE_SOL_VARIABLES\"\n\n#define MSK_IINF_ANA_PRO_NUM_CON_                           \"MSK_IINF_ANA_PRO_NUM_CON\"\n#define MSK_IINF_ANA_PRO_NUM_CON_EQ_                        \"MSK_IINF_ANA_PRO_NUM_CON_EQ\"\n#define MSK_IINF_ANA_PRO_NUM_CON_FR_                        \"MSK_IINF_ANA_PRO_NUM_CON_FR\"\n#define MSK_IINF_ANA_PRO_NUM_CON_LO_                        \"MSK_IINF_ANA_PRO_NUM_CON_LO\"\n#define MSK_IINF_ANA_PRO_NUM_CON_RA_                        \"MSK_IINF_ANA_PRO_NUM_CON_RA\"\n#define MSK_IINF_ANA_PRO_NUM_CON_UP_                        \"MSK_IINF_ANA_PRO_NUM_CON_UP\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_                           \"MSK_IINF_ANA_PRO_NUM_VAR\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_BIN_                       \"MSK_IINF_ANA_PRO_NUM_VAR_BIN\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_CONT_                      \"MSK_IINF_ANA_PRO_NUM_VAR_CONT\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_EQ_                        \"MSK_IINF_ANA_PRO_NUM_VAR_EQ\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_FR_                        \"MSK_IINF_ANA_PRO_NUM_VAR_FR\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_INT_                       \"MSK_IINF_ANA_PRO_NUM_VAR_INT\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_LO_                        \"MSK_IINF_ANA_PRO_NUM_VAR_LO\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_RA_                        \"MSK_IINF_ANA_PRO_NUM_VAR_RA\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_UP_                        \"MSK_IINF_ANA_PRO_NUM_VAR_UP\"\n#define MSK_IINF_FOLDING_APPLIED_                           \"MSK_IINF_FOLDING_APPLIED\"\n#define MSK_IINF_INTPNT_FACTOR_DIM_DENSE_                   \"MSK_IINF_INTPNT_FACTOR_DIM_DENSE\"\n#define MSK_IINF_INTPNT_ITER_                               \"MSK_IINF_INTPNT_ITER\"\n#define MSK_IINF_INTPNT_NUM_THREADS_                        \"MSK_IINF_INTPNT_NUM_THREADS\"\n#define MSK_IINF_INTPNT_SOLVE_DUAL_                         \"MSK_IINF_INTPNT_SOLVE_DUAL\"\n#define MSK_IINF_MIO_ABSGAP_SATISFIED_                      \"MSK_IINF_MIO_ABSGAP_SATISFIED\"\n#define MSK_IINF_MIO_CLIQUE_TABLE_SIZE_                     \"MSK_IINF_MIO_CLIQUE_TABLE_SIZE\"\n#define MSK_IINF_MIO_CONSTRUCT_SOLUTION_                    \"MSK_IINF_MIO_CONSTRUCT_SOLUTION\"\n#define MSK_IINF_MIO_FINAL_NUMBIN_                          \"MSK_IINF_MIO_FINAL_NUMBIN\"\n#define MSK_IINF_MIO_FINAL_NUMBINCONEVAR_                   \"MSK_IINF_MIO_FINAL_NUMBINCONEVAR\"\n#define MSK_IINF_MIO_FINAL_NUMCON_                          \"MSK_IINF_MIO_FINAL_NUMCON\"\n#define MSK_IINF_MIO_FINAL_NUMCONE_                         \"MSK_IINF_MIO_FINAL_NUMCONE\"\n#define MSK_IINF_MIO_FINAL_NUMCONEVAR_                      \"MSK_IINF_MIO_FINAL_NUMCONEVAR\"\n#define MSK_IINF_MIO_FINAL_NUMCONT_                         \"MSK_IINF_MIO_FINAL_NUMCONT\"\n#define MSK_IINF_MIO_FINAL_NUMCONTCONEVAR_                  \"MSK_IINF_MIO_FINAL_NUMCONTCONEVAR\"\n#define MSK_IINF_MIO_FINAL_NUMDEXPCONES_                    \"MSK_IINF_MIO_FINAL_NUMDEXPCONES\"\n#define MSK_IINF_MIO_FINAL_NUMDJC_                          \"MSK_IINF_MIO_FINAL_NUMDJC\"\n#define MSK_IINF_MIO_FINAL_NUMDPOWCONES_                    \"MSK_IINF_MIO_FINAL_NUMDPOWCONES\"\n#define MSK_IINF_MIO_FINAL_NUMINT_                          \"MSK_IINF_MIO_FINAL_NUMINT\"\n#define MSK_IINF_MIO_FINAL_NUMINTCONEVAR_                   \"MSK_IINF_MIO_FINAL_NUMINTCONEVAR\"\n#define MSK_IINF_MIO_FINAL_NUMPEXPCONES_                    \"MSK_IINF_MIO_FINAL_NUMPEXPCONES\"\n#define MSK_IINF_MIO_FINAL_NUMPPOWCONES_                    \"MSK_IINF_MIO_FINAL_NUMPPOWCONES\"\n#define MSK_IINF_MIO_FINAL_NUMQCONES_                       \"MSK_IINF_MIO_FINAL_NUMQCONES\"\n#define MSK_IINF_MIO_FINAL_NUMRQCONES_                      \"MSK_IINF_MIO_FINAL_NUMRQCONES\"\n#define MSK_IINF_MIO_FINAL_NUMVAR_                          \"MSK_IINF_MIO_FINAL_NUMVAR\"\n#define MSK_IINF_MIO_INITIAL_FEASIBLE_SOLUTION_             \"MSK_IINF_MIO_INITIAL_FEASIBLE_SOLUTION\"\n#define MSK_IINF_MIO_NODE_DEPTH_                            \"MSK_IINF_MIO_NODE_DEPTH\"\n#define MSK_IINF_MIO_NUM_ACTIVE_NODES_                      \"MSK_IINF_MIO_NUM_ACTIVE_NODES\"\n#define MSK_IINF_MIO_NUM_ACTIVE_ROOT_CUTS_                  \"MSK_IINF_MIO_NUM_ACTIVE_ROOT_CUTS\"\n#define MSK_IINF_MIO_NUM_BLOCKS_SOLVED_IN_BB_               \"MSK_IINF_MIO_NUM_BLOCKS_SOLVED_IN_BB\"\n#define MSK_IINF_MIO_NUM_BLOCKS_SOLVED_IN_PRESOLVE_         \"MSK_IINF_MIO_NUM_BLOCKS_SOLVED_IN_PRESOLVE\"\n#define MSK_IINF_MIO_NUM_BRANCH_                            \"MSK_IINF_MIO_NUM_BRANCH\"\n#define MSK_IINF_MIO_NUM_INT_SOLUTIONS_                     \"MSK_IINF_MIO_NUM_INT_SOLUTIONS\"\n#define MSK_IINF_MIO_NUM_RELAX_                             \"MSK_IINF_MIO_NUM_RELAX\"\n#define MSK_IINF_MIO_NUM_REPEATED_PRESOLVE_                 \"MSK_IINF_MIO_NUM_REPEATED_PRESOLVE\"\n#define MSK_IINF_MIO_NUM_RESTARTS_                          \"MSK_IINF_MIO_NUM_RESTARTS\"\n#define MSK_IINF_MIO_NUM_ROOT_CUT_ROUNDS_                   \"MSK_IINF_MIO_NUM_ROOT_CUT_ROUNDS\"\n#define MSK_IINF_MIO_NUM_SELECTED_CLIQUE_CUTS_              \"MSK_IINF_MIO_NUM_SELECTED_CLIQUE_CUTS\"\n#define MSK_IINF_MIO_NUM_SELECTED_CMIR_CUTS_                \"MSK_IINF_MIO_NUM_SELECTED_CMIR_CUTS\"\n#define MSK_IINF_MIO_NUM_SELECTED_GOMORY_CUTS_              \"MSK_IINF_MIO_NUM_SELECTED_GOMORY_CUTS\"\n#define MSK_IINF_MIO_NUM_SELECTED_IMPLIED_BOUND_CUTS_       \"MSK_IINF_MIO_NUM_SELECTED_IMPLIED_BOUND_CUTS\"\n#define MSK_IINF_MIO_NUM_SELECTED_KNAPSACK_COVER_CUTS_      \"MSK_IINF_MIO_NUM_SELECTED_KNAPSACK_COVER_CUTS\"\n#define MSK_IINF_MIO_NUM_SELECTED_LIPRO_CUTS_               \"MSK_IINF_MIO_NUM_SELECTED_LIPRO_CUTS\"\n#define MSK_IINF_MIO_NUM_SEPARATED_CLIQUE_CUTS_             \"MSK_IINF_MIO_NUM_SEPARATED_CLIQUE_CUTS\"\n#define MSK_IINF_MIO_NUM_SEPARATED_CMIR_CUTS_               \"MSK_IINF_MIO_NUM_SEPARATED_CMIR_CUTS\"\n#define MSK_IINF_MIO_NUM_SEPARATED_GOMORY_CUTS_             \"MSK_IINF_MIO_NUM_SEPARATED_GOMORY_CUTS\"\n#define MSK_IINF_MIO_NUM_SEPARATED_IMPLIED_BOUND_CUTS_      \"MSK_IINF_MIO_NUM_SEPARATED_IMPLIED_BOUND_CUTS\"\n#define MSK_IINF_MIO_NUM_SEPARATED_KNAPSACK_COVER_CUTS_     \"MSK_IINF_MIO_NUM_SEPARATED_KNAPSACK_COVER_CUTS\"\n#define MSK_IINF_MIO_NUM_SEPARATED_LIPRO_CUTS_              \"MSK_IINF_MIO_NUM_SEPARATED_LIPRO_CUTS\"\n#define MSK_IINF_MIO_NUM_SOLVED_NODES_                      \"MSK_IINF_MIO_NUM_SOLVED_NODES\"\n#define MSK_IINF_MIO_NUMBIN_                                \"MSK_IINF_MIO_NUMBIN\"\n#define MSK_IINF_MIO_NUMBINCONEVAR_                         \"MSK_IINF_MIO_NUMBINCONEVAR\"\n#define MSK_IINF_MIO_NUMCON_                                \"MSK_IINF_MIO_NUMCON\"\n#define MSK_IINF_MIO_NUMCONE_                               \"MSK_IINF_MIO_NUMCONE\"\n#define MSK_IINF_MIO_NUMCONEVAR_                            \"MSK_IINF_MIO_NUMCONEVAR\"\n#define MSK_IINF_MIO_NUMCONT_                               \"MSK_IINF_MIO_NUMCONT\"\n#define MSK_IINF_MIO_NUMCONTCONEVAR_                        \"MSK_IINF_MIO_NUMCONTCONEVAR\"\n#define MSK_IINF_MIO_NUMDEXPCONES_                          \"MSK_IINF_MIO_NUMDEXPCONES\"\n#define MSK_IINF_MIO_NUMDJC_                                \"MSK_IINF_MIO_NUMDJC\"\n#define MSK_IINF_MIO_NUMDPOWCONES_                          \"MSK_IINF_MIO_NUMDPOWCONES\"\n#define MSK_IINF_MIO_NUMINT_                                \"MSK_IINF_MIO_NUMINT\"\n#define MSK_IINF_MIO_NUMINTCONEVAR_                         \"MSK_IINF_MIO_NUMINTCONEVAR\"\n#define MSK_IINF_MIO_NUMPEXPCONES_                          \"MSK_IINF_MIO_NUMPEXPCONES\"\n#define MSK_IINF_MIO_NUMPPOWCONES_                          \"MSK_IINF_MIO_NUMPPOWCONES\"\n#define MSK_IINF_MIO_NUMQCONES_                             \"MSK_IINF_MIO_NUMQCONES\"\n#define MSK_IINF_MIO_NUMRQCONES_                            \"MSK_IINF_MIO_NUMRQCONES\"\n#define MSK_IINF_MIO_NUMVAR_                                \"MSK_IINF_MIO_NUMVAR\"\n#define MSK_IINF_MIO_OBJ_BOUND_DEFINED_                     \"MSK_IINF_MIO_OBJ_BOUND_DEFINED\"\n#define MSK_IINF_MIO_PRESOLVED_NUMBIN_                      \"MSK_IINF_MIO_PRESOLVED_NUMBIN\"\n#define MSK_IINF_MIO_PRESOLVED_NUMBINCONEVAR_               \"MSK_IINF_MIO_PRESOLVED_NUMBINCONEVAR\"\n#define MSK_IINF_MIO_PRESOLVED_NUMCON_                      \"MSK_IINF_MIO_PRESOLVED_NUMCON\"\n#define MSK_IINF_MIO_PRESOLVED_NUMCONE_                     \"MSK_IINF_MIO_PRESOLVED_NUMCONE\"\n#define MSK_IINF_MIO_PRESOLVED_NUMCONEVAR_                  \"MSK_IINF_MIO_PRESOLVED_NUMCONEVAR\"\n#define MSK_IINF_MIO_PRESOLVED_NUMCONT_                     \"MSK_IINF_MIO_PRESOLVED_NUMCONT\"\n#define MSK_IINF_MIO_PRESOLVED_NUMCONTCONEVAR_              \"MSK_IINF_MIO_PRESOLVED_NUMCONTCONEVAR\"\n#define MSK_IINF_MIO_PRESOLVED_NUMDEXPCONES_                \"MSK_IINF_MIO_PRESOLVED_NUMDEXPCONES\"\n#define MSK_IINF_MIO_PRESOLVED_NUMDJC_                      \"MSK_IINF_MIO_PRESOLVED_NUMDJC\"\n#define MSK_IINF_MIO_PRESOLVED_NUMDPOWCONES_                \"MSK_IINF_MIO_PRESOLVED_NUMDPOWCONES\"\n#define MSK_IINF_MIO_PRESOLVED_NUMINT_                      \"MSK_IINF_MIO_PRESOLVED_NUMINT\"\n#define MSK_IINF_MIO_PRESOLVED_NUMINTCONEVAR_               \"MSK_IINF_MIO_PRESOLVED_NUMINTCONEVAR\"\n#define MSK_IINF_MIO_PRESOLVED_NUMPEXPCONES_                \"MSK_IINF_MIO_PRESOLVED_NUMPEXPCONES\"\n#define MSK_IINF_MIO_PRESOLVED_NUMPPOWCONES_                \"MSK_IINF_MIO_PRESOLVED_NUMPPOWCONES\"\n#define MSK_IINF_MIO_PRESOLVED_NUMQCONES_                   \"MSK_IINF_MIO_PRESOLVED_NUMQCONES\"\n#define MSK_IINF_MIO_PRESOLVED_NUMRQCONES_                  \"MSK_IINF_MIO_PRESOLVED_NUMRQCONES\"\n#define MSK_IINF_MIO_PRESOLVED_NUMVAR_                      \"MSK_IINF_MIO_PRESOLVED_NUMVAR\"\n#define MSK_IINF_MIO_RELGAP_SATISFIED_                      \"MSK_IINF_MIO_RELGAP_SATISFIED\"\n#define MSK_IINF_MIO_TOTAL_NUM_SELECTED_CUTS_               \"MSK_IINF_MIO_TOTAL_NUM_SELECTED_CUTS\"\n#define MSK_IINF_MIO_TOTAL_NUM_SEPARATED_CUTS_              \"MSK_IINF_MIO_TOTAL_NUM_SEPARATED_CUTS\"\n#define MSK_IINF_MIO_USER_OBJ_CUT_                          \"MSK_IINF_MIO_USER_OBJ_CUT\"\n#define MSK_IINF_OPT_NUMCON_                                \"MSK_IINF_OPT_NUMCON\"\n#define MSK_IINF_OPT_NUMVAR_                                \"MSK_IINF_OPT_NUMVAR\"\n#define MSK_IINF_OPTIMIZE_RESPONSE_                         \"MSK_IINF_OPTIMIZE_RESPONSE\"\n#define MSK_IINF_PRESOLVE_NUM_PRIMAL_PERTURBATIONS_         \"MSK_IINF_PRESOLVE_NUM_PRIMAL_PERTURBATIONS\"\n#define MSK_IINF_PURIFY_DUAL_SUCCESS_                       \"MSK_IINF_PURIFY_DUAL_SUCCESS\"\n#define MSK_IINF_PURIFY_PRIMAL_SUCCESS_                     \"MSK_IINF_PURIFY_PRIMAL_SUCCESS\"\n#define MSK_IINF_RD_NUMBARVAR_                              \"MSK_IINF_RD_NUMBARVAR\"\n#define MSK_IINF_RD_NUMCON_                                 \"MSK_IINF_RD_NUMCON\"\n#define MSK_IINF_RD_NUMCONE_                                \"MSK_IINF_RD_NUMCONE\"\n#define MSK_IINF_RD_NUMINTVAR_                              \"MSK_IINF_RD_NUMINTVAR\"\n#define MSK_IINF_RD_NUMQ_                                   \"MSK_IINF_RD_NUMQ\"\n#define MSK_IINF_RD_NUMVAR_                                 \"MSK_IINF_RD_NUMVAR\"\n#define MSK_IINF_RD_PROTYPE_                                \"MSK_IINF_RD_PROTYPE\"\n#define MSK_IINF_SIM_DUAL_DEG_ITER_                         \"MSK_IINF_SIM_DUAL_DEG_ITER\"\n#define MSK_IINF_SIM_DUAL_HOTSTART_                         \"MSK_IINF_SIM_DUAL_HOTSTART\"\n#define MSK_IINF_SIM_DUAL_HOTSTART_LU_                      \"MSK_IINF_SIM_DUAL_HOTSTART_LU\"\n#define MSK_IINF_SIM_DUAL_INF_ITER_                         \"MSK_IINF_SIM_DUAL_INF_ITER\"\n#define MSK_IINF_SIM_DUAL_ITER_                             \"MSK_IINF_SIM_DUAL_ITER\"\n#define MSK_IINF_SIM_NUMCON_                                \"MSK_IINF_SIM_NUMCON\"\n#define MSK_IINF_SIM_NUMVAR_                                \"MSK_IINF_SIM_NUMVAR\"\n#define MSK_IINF_SIM_PRIMAL_DEG_ITER_                       \"MSK_IINF_SIM_PRIMAL_DEG_ITER\"\n#define MSK_IINF_SIM_PRIMAL_HOTSTART_                       \"MSK_IINF_SIM_PRIMAL_HOTSTART\"\n#define MSK_IINF_SIM_PRIMAL_HOTSTART_LU_                    \"MSK_IINF_SIM_PRIMAL_HOTSTART_LU\"\n#define MSK_IINF_SIM_PRIMAL_INF_ITER_                       \"MSK_IINF_SIM_PRIMAL_INF_ITER\"\n#define MSK_IINF_SIM_PRIMAL_ITER_                           \"MSK_IINF_SIM_PRIMAL_ITER\"\n#define MSK_IINF_SIM_SOLVE_DUAL_                            \"MSK_IINF_SIM_SOLVE_DUAL\"\n#define MSK_IINF_SOL_BAS_PROSTA_                            \"MSK_IINF_SOL_BAS_PROSTA\"\n#define MSK_IINF_SOL_BAS_SOLSTA_                            \"MSK_IINF_SOL_BAS_SOLSTA\"\n#define MSK_IINF_SOL_ITG_PROSTA_                            \"MSK_IINF_SOL_ITG_PROSTA\"\n#define MSK_IINF_SOL_ITG_SOLSTA_                            \"MSK_IINF_SOL_ITG_SOLSTA\"\n#define MSK_IINF_SOL_ITR_PROSTA_                            \"MSK_IINF_SOL_ITR_PROSTA\"\n#define MSK_IINF_SOL_ITR_SOLSTA_                            \"MSK_IINF_SOL_ITR_SOLSTA\"\n#define MSK_IINF_STO_NUM_A_REALLOC_                         \"MSK_IINF_STO_NUM_A_REALLOC\"\n\n#define MSK_DINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_DENSITY_ \"MSK_DINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_DENSITY\"\n#define MSK_DINF_BI_CLEAN_TIME_                             \"MSK_DINF_BI_CLEAN_TIME\"\n#define MSK_DINF_BI_DUAL_TIME_                              \"MSK_DINF_BI_DUAL_TIME\"\n#define MSK_DINF_BI_PRIMAL_TIME_                            \"MSK_DINF_BI_PRIMAL_TIME\"\n#define MSK_DINF_BI_TIME_                                   \"MSK_DINF_BI_TIME\"\n#define MSK_DINF_FOLDING_BI_OPTIMIZE_TIME_                  \"MSK_DINF_FOLDING_BI_OPTIMIZE_TIME\"\n#define MSK_DINF_FOLDING_BI_UNFOLD_DUAL_TIME_               \"MSK_DINF_FOLDING_BI_UNFOLD_DUAL_TIME\"\n#define MSK_DINF_FOLDING_BI_UNFOLD_INITIALIZE_TIME_         \"MSK_DINF_FOLDING_BI_UNFOLD_INITIALIZE_TIME\"\n#define MSK_DINF_FOLDING_BI_UNFOLD_PRIMAL_TIME_             \"MSK_DINF_FOLDING_BI_UNFOLD_PRIMAL_TIME\"\n#define MSK_DINF_FOLDING_BI_UNFOLD_TIME_                    \"MSK_DINF_FOLDING_BI_UNFOLD_TIME\"\n#define MSK_DINF_FOLDING_FACTOR_                            \"MSK_DINF_FOLDING_FACTOR\"\n#define MSK_DINF_FOLDING_TIME_                              \"MSK_DINF_FOLDING_TIME\"\n#define MSK_DINF_INTPNT_DUAL_FEAS_                          \"MSK_DINF_INTPNT_DUAL_FEAS\"\n#define MSK_DINF_INTPNT_DUAL_OBJ_                           \"MSK_DINF_INTPNT_DUAL_OBJ\"\n#define MSK_DINF_INTPNT_FACTOR_NUM_FLOPS_                   \"MSK_DINF_INTPNT_FACTOR_NUM_FLOPS\"\n#define MSK_DINF_INTPNT_OPT_STATUS_                         \"MSK_DINF_INTPNT_OPT_STATUS\"\n#define MSK_DINF_INTPNT_ORDER_TIME_                         \"MSK_DINF_INTPNT_ORDER_TIME\"\n#define MSK_DINF_INTPNT_PRIMAL_FEAS_                        \"MSK_DINF_INTPNT_PRIMAL_FEAS\"\n#define MSK_DINF_INTPNT_PRIMAL_OBJ_                         \"MSK_DINF_INTPNT_PRIMAL_OBJ\"\n#define MSK_DINF_INTPNT_TIME_                               \"MSK_DINF_INTPNT_TIME\"\n#define MSK_DINF_MIO_CLIQUE_SELECTION_TIME_                 \"MSK_DINF_MIO_CLIQUE_SELECTION_TIME\"\n#define MSK_DINF_MIO_CLIQUE_SEPARATION_TIME_                \"MSK_DINF_MIO_CLIQUE_SEPARATION_TIME\"\n#define MSK_DINF_MIO_CMIR_SELECTION_TIME_                   \"MSK_DINF_MIO_CMIR_SELECTION_TIME\"\n#define MSK_DINF_MIO_CMIR_SEPARATION_TIME_                  \"MSK_DINF_MIO_CMIR_SEPARATION_TIME\"\n#define MSK_DINF_MIO_CONSTRUCT_SOLUTION_OBJ_                \"MSK_DINF_MIO_CONSTRUCT_SOLUTION_OBJ\"\n#define MSK_DINF_MIO_DUAL_BOUND_AFTER_PRESOLVE_             \"MSK_DINF_MIO_DUAL_BOUND_AFTER_PRESOLVE\"\n#define MSK_DINF_MIO_GMI_SELECTION_TIME_                    \"MSK_DINF_MIO_GMI_SELECTION_TIME\"\n#define MSK_DINF_MIO_GMI_SEPARATION_TIME_                   \"MSK_DINF_MIO_GMI_SEPARATION_TIME\"\n#define MSK_DINF_MIO_IMPLIED_BOUND_SELECTION_TIME_          \"MSK_DINF_MIO_IMPLIED_BOUND_SELECTION_TIME\"\n#define MSK_DINF_MIO_IMPLIED_BOUND_SEPARATION_TIME_         \"MSK_DINF_MIO_IMPLIED_BOUND_SEPARATION_TIME\"\n#define MSK_DINF_MIO_INITIAL_FEASIBLE_SOLUTION_OBJ_         \"MSK_DINF_MIO_INITIAL_FEASIBLE_SOLUTION_OBJ\"\n#define MSK_DINF_MIO_KNAPSACK_COVER_SELECTION_TIME_         \"MSK_DINF_MIO_KNAPSACK_COVER_SELECTION_TIME\"\n#define MSK_DINF_MIO_KNAPSACK_COVER_SEPARATION_TIME_        \"MSK_DINF_MIO_KNAPSACK_COVER_SEPARATION_TIME\"\n#define MSK_DINF_MIO_LIPRO_SELECTION_TIME_                  \"MSK_DINF_MIO_LIPRO_SELECTION_TIME\"\n#define MSK_DINF_MIO_LIPRO_SEPARATION_TIME_                 \"MSK_DINF_MIO_LIPRO_SEPARATION_TIME\"\n#define MSK_DINF_MIO_OBJ_ABS_GAP_                           \"MSK_DINF_MIO_OBJ_ABS_GAP\"\n#define MSK_DINF_MIO_OBJ_BOUND_                             \"MSK_DINF_MIO_OBJ_BOUND\"\n#define MSK_DINF_MIO_OBJ_INT_                               \"MSK_DINF_MIO_OBJ_INT\"\n#define MSK_DINF_MIO_OBJ_REL_GAP_                           \"MSK_DINF_MIO_OBJ_REL_GAP\"\n#define MSK_DINF_MIO_PROBING_TIME_                          \"MSK_DINF_MIO_PROBING_TIME\"\n#define MSK_DINF_MIO_ROOT_CUT_SELECTION_TIME_               \"MSK_DINF_MIO_ROOT_CUT_SELECTION_TIME\"\n#define MSK_DINF_MIO_ROOT_CUT_SEPARATION_TIME_              \"MSK_DINF_MIO_ROOT_CUT_SEPARATION_TIME\"\n#define MSK_DINF_MIO_ROOT_OPTIMIZER_TIME_                   \"MSK_DINF_MIO_ROOT_OPTIMIZER_TIME\"\n#define MSK_DINF_MIO_ROOT_PRESOLVE_TIME_                    \"MSK_DINF_MIO_ROOT_PRESOLVE_TIME\"\n#define MSK_DINF_MIO_ROOT_TIME_                             \"MSK_DINF_MIO_ROOT_TIME\"\n#define MSK_DINF_MIO_SYMMETRY_DETECTION_TIME_               \"MSK_DINF_MIO_SYMMETRY_DETECTION_TIME\"\n#define MSK_DINF_MIO_SYMMETRY_FACTOR_                       \"MSK_DINF_MIO_SYMMETRY_FACTOR\"\n#define MSK_DINF_MIO_TIME_                                  \"MSK_DINF_MIO_TIME\"\n#define MSK_DINF_MIO_USER_OBJ_CUT_                          \"MSK_DINF_MIO_USER_OBJ_CUT\"\n#define MSK_DINF_OPTIMIZER_TICKS_                           \"MSK_DINF_OPTIMIZER_TICKS\"\n#define MSK_DINF_OPTIMIZER_TIME_                            \"MSK_DINF_OPTIMIZER_TIME\"\n#define MSK_DINF_PRESOLVE_ELI_TIME_                         \"MSK_DINF_PRESOLVE_ELI_TIME\"\n#define MSK_DINF_PRESOLVE_LINDEP_TIME_                      \"MSK_DINF_PRESOLVE_LINDEP_TIME\"\n#define MSK_DINF_PRESOLVE_TIME_                             \"MSK_DINF_PRESOLVE_TIME\"\n#define MSK_DINF_PRESOLVE_TOTAL_PRIMAL_PERTURBATION_        \"MSK_DINF_PRESOLVE_TOTAL_PRIMAL_PERTURBATION\"\n#define MSK_DINF_PRIMAL_REPAIR_PENALTY_OBJ_                 \"MSK_DINF_PRIMAL_REPAIR_PENALTY_OBJ\"\n#define MSK_DINF_QCQO_REFORMULATE_MAX_PERTURBATION_         \"MSK_DINF_QCQO_REFORMULATE_MAX_PERTURBATION\"\n#define MSK_DINF_QCQO_REFORMULATE_TIME_                     \"MSK_DINF_QCQO_REFORMULATE_TIME\"\n#define MSK_DINF_QCQO_REFORMULATE_WORST_CHOLESKY_COLUMN_SCALING_ \"MSK_DINF_QCQO_REFORMULATE_WORST_CHOLESKY_COLUMN_SCALING\"\n#define MSK_DINF_QCQO_REFORMULATE_WORST_CHOLESKY_DIAG_SCALING_ \"MSK_DINF_QCQO_REFORMULATE_WORST_CHOLESKY_DIAG_SCALING\"\n#define MSK_DINF_READ_DATA_TIME_                            \"MSK_DINF_READ_DATA_TIME\"\n#define MSK_DINF_REMOTE_TIME_                               \"MSK_DINF_REMOTE_TIME\"\n#define MSK_DINF_SIM_DUAL_TIME_                             \"MSK_DINF_SIM_DUAL_TIME\"\n#define MSK_DINF_SIM_FEAS_                                  \"MSK_DINF_SIM_FEAS\"\n#define MSK_DINF_SIM_OBJ_                                   \"MSK_DINF_SIM_OBJ\"\n#define MSK_DINF_SIM_PRIMAL_TIME_                           \"MSK_DINF_SIM_PRIMAL_TIME\"\n#define MSK_DINF_SIM_TIME_                                  \"MSK_DINF_SIM_TIME\"\n#define MSK_DINF_SOL_BAS_DUAL_OBJ_                          \"MSK_DINF_SOL_BAS_DUAL_OBJ\"\n#define MSK_DINF_SOL_BAS_DVIOLCON_                          \"MSK_DINF_SOL_BAS_DVIOLCON\"\n#define MSK_DINF_SOL_BAS_DVIOLVAR_                          \"MSK_DINF_SOL_BAS_DVIOLVAR\"\n#define MSK_DINF_SOL_BAS_NRM_BARX_                          \"MSK_DINF_SOL_BAS_NRM_BARX\"\n#define MSK_DINF_SOL_BAS_NRM_SLC_                           \"MSK_DINF_SOL_BAS_NRM_SLC\"\n#define MSK_DINF_SOL_BAS_NRM_SLX_                           \"MSK_DINF_SOL_BAS_NRM_SLX\"\n#define MSK_DINF_SOL_BAS_NRM_SUC_                           \"MSK_DINF_SOL_BAS_NRM_SUC\"\n#define MSK_DINF_SOL_BAS_NRM_SUX_                           \"MSK_DINF_SOL_BAS_NRM_SUX\"\n#define MSK_DINF_SOL_BAS_NRM_XC_                            \"MSK_DINF_SOL_BAS_NRM_XC\"\n#define MSK_DINF_SOL_BAS_NRM_XX_                            \"MSK_DINF_SOL_BAS_NRM_XX\"\n#define MSK_DINF_SOL_BAS_NRM_Y_                             \"MSK_DINF_SOL_BAS_NRM_Y\"\n#define MSK_DINF_SOL_BAS_PRIMAL_OBJ_                        \"MSK_DINF_SOL_BAS_PRIMAL_OBJ\"\n#define MSK_DINF_SOL_BAS_PVIOLCON_                          \"MSK_DINF_SOL_BAS_PVIOLCON\"\n#define MSK_DINF_SOL_BAS_PVIOLVAR_                          \"MSK_DINF_SOL_BAS_PVIOLVAR\"\n#define MSK_DINF_SOL_ITG_NRM_BARX_                          \"MSK_DINF_SOL_ITG_NRM_BARX\"\n#define MSK_DINF_SOL_ITG_NRM_XC_                            \"MSK_DINF_SOL_ITG_NRM_XC\"\n#define MSK_DINF_SOL_ITG_NRM_XX_                            \"MSK_DINF_SOL_ITG_NRM_XX\"\n#define MSK_DINF_SOL_ITG_PRIMAL_OBJ_                        \"MSK_DINF_SOL_ITG_PRIMAL_OBJ\"\n#define MSK_DINF_SOL_ITG_PVIOLACC_                          \"MSK_DINF_SOL_ITG_PVIOLACC\"\n#define MSK_DINF_SOL_ITG_PVIOLBARVAR_                       \"MSK_DINF_SOL_ITG_PVIOLBARVAR\"\n#define MSK_DINF_SOL_ITG_PVIOLCON_                          \"MSK_DINF_SOL_ITG_PVIOLCON\"\n#define MSK_DINF_SOL_ITG_PVIOLCONES_                        \"MSK_DINF_SOL_ITG_PVIOLCONES\"\n#define MSK_DINF_SOL_ITG_PVIOLDJC_                          \"MSK_DINF_SOL_ITG_PVIOLDJC\"\n#define MSK_DINF_SOL_ITG_PVIOLITG_                          \"MSK_DINF_SOL_ITG_PVIOLITG\"\n#define MSK_DINF_SOL_ITG_PVIOLVAR_                          \"MSK_DINF_SOL_ITG_PVIOLVAR\"\n#define MSK_DINF_SOL_ITR_DUAL_OBJ_                          \"MSK_DINF_SOL_ITR_DUAL_OBJ\"\n#define MSK_DINF_SOL_ITR_DVIOLACC_                          \"MSK_DINF_SOL_ITR_DVIOLACC\"\n#define MSK_DINF_SOL_ITR_DVIOLBARVAR_                       \"MSK_DINF_SOL_ITR_DVIOLBARVAR\"\n#define MSK_DINF_SOL_ITR_DVIOLCON_                          \"MSK_DINF_SOL_ITR_DVIOLCON\"\n#define MSK_DINF_SOL_ITR_DVIOLCONES_                        \"MSK_DINF_SOL_ITR_DVIOLCONES\"\n#define MSK_DINF_SOL_ITR_DVIOLVAR_                          \"MSK_DINF_SOL_ITR_DVIOLVAR\"\n#define MSK_DINF_SOL_ITR_NRM_BARS_                          \"MSK_DINF_SOL_ITR_NRM_BARS\"\n#define MSK_DINF_SOL_ITR_NRM_BARX_                          \"MSK_DINF_SOL_ITR_NRM_BARX\"\n#define MSK_DINF_SOL_ITR_NRM_SLC_                           \"MSK_DINF_SOL_ITR_NRM_SLC\"\n#define MSK_DINF_SOL_ITR_NRM_SLX_                           \"MSK_DINF_SOL_ITR_NRM_SLX\"\n#define MSK_DINF_SOL_ITR_NRM_SNX_                           \"MSK_DINF_SOL_ITR_NRM_SNX\"\n#define MSK_DINF_SOL_ITR_NRM_SUC_                           \"MSK_DINF_SOL_ITR_NRM_SUC\"\n#define MSK_DINF_SOL_ITR_NRM_SUX_                           \"MSK_DINF_SOL_ITR_NRM_SUX\"\n#define MSK_DINF_SOL_ITR_NRM_XC_                            \"MSK_DINF_SOL_ITR_NRM_XC\"\n#define MSK_DINF_SOL_ITR_NRM_XX_                            \"MSK_DINF_SOL_ITR_NRM_XX\"\n#define MSK_DINF_SOL_ITR_NRM_Y_                             \"MSK_DINF_SOL_ITR_NRM_Y\"\n#define MSK_DINF_SOL_ITR_PRIMAL_OBJ_                        \"MSK_DINF_SOL_ITR_PRIMAL_OBJ\"\n#define MSK_DINF_SOL_ITR_PVIOLACC_                          \"MSK_DINF_SOL_ITR_PVIOLACC\"\n#define MSK_DINF_SOL_ITR_PVIOLBARVAR_                       \"MSK_DINF_SOL_ITR_PVIOLBARVAR\"\n#define MSK_DINF_SOL_ITR_PVIOLCON_                          \"MSK_DINF_SOL_ITR_PVIOLCON\"\n#define MSK_DINF_SOL_ITR_PVIOLCONES_                        \"MSK_DINF_SOL_ITR_PVIOLCONES\"\n#define MSK_DINF_SOL_ITR_PVIOLVAR_                          \"MSK_DINF_SOL_ITR_PVIOLVAR\"\n#define MSK_DINF_TO_CONIC_TIME_                             \"MSK_DINF_TO_CONIC_TIME\"\n#define MSK_DINF_WRITE_DATA_TIME_                           \"MSK_DINF_WRITE_DATA_TIME\"\n\n#define MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_COLUMNS_ \"MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_COLUMNS\"\n#define MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_NZ_ \"MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_NZ\"\n#define MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_ROWS_ \"MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_ROWS\"\n#define MSK_LIINF_BI_CLEAN_ITER_                            \"MSK_LIINF_BI_CLEAN_ITER\"\n#define MSK_LIINF_BI_DUAL_ITER_                             \"MSK_LIINF_BI_DUAL_ITER\"\n#define MSK_LIINF_BI_PRIMAL_ITER_                           \"MSK_LIINF_BI_PRIMAL_ITER\"\n#define MSK_LIINF_FOLDING_BI_DUAL_ITER_                     \"MSK_LIINF_FOLDING_BI_DUAL_ITER\"\n#define MSK_LIINF_FOLDING_BI_OPTIMIZER_ITER_                \"MSK_LIINF_FOLDING_BI_OPTIMIZER_ITER\"\n#define MSK_LIINF_FOLDING_BI_PRIMAL_ITER_                   \"MSK_LIINF_FOLDING_BI_PRIMAL_ITER\"\n#define MSK_LIINF_INTPNT_FACTOR_NUM_NZ_                     \"MSK_LIINF_INTPNT_FACTOR_NUM_NZ\"\n#define MSK_LIINF_MIO_ANZ_                                  \"MSK_LIINF_MIO_ANZ\"\n#define MSK_LIINF_MIO_FINAL_ANZ_                            \"MSK_LIINF_MIO_FINAL_ANZ\"\n#define MSK_LIINF_MIO_INTPNT_ITER_                          \"MSK_LIINF_MIO_INTPNT_ITER\"\n#define MSK_LIINF_MIO_NUM_DUAL_ILLPOSED_CER_                \"MSK_LIINF_MIO_NUM_DUAL_ILLPOSED_CER\"\n#define MSK_LIINF_MIO_NUM_PRIM_ILLPOSED_CER_                \"MSK_LIINF_MIO_NUM_PRIM_ILLPOSED_CER\"\n#define MSK_LIINF_MIO_PRESOLVED_ANZ_                        \"MSK_LIINF_MIO_PRESOLVED_ANZ\"\n#define MSK_LIINF_MIO_SIMPLEX_ITER_                         \"MSK_LIINF_MIO_SIMPLEX_ITER\"\n#define MSK_LIINF_RD_NUMACC_                                \"MSK_LIINF_RD_NUMACC\"\n#define MSK_LIINF_RD_NUMANZ_                                \"MSK_LIINF_RD_NUMANZ\"\n#define MSK_LIINF_RD_NUMDJC_                                \"MSK_LIINF_RD_NUMDJC\"\n#define MSK_LIINF_RD_NUMQNZ_                                \"MSK_LIINF_RD_NUMQNZ\"\n#define MSK_LIINF_SIMPLEX_ITER_                             \"MSK_LIINF_SIMPLEX_ITER\"\n\n\n\n/* Typedefs */\n\ntypedef char       MSKchart;\ntypedef void     * MSKvoid_t;\n\n#ifdef  MSKINT64\ntypedef MSKINT64 __mskint64;\n#else\ntypedef long long __mskint64;\n#endif\n\n#if defined(LLONG_MAX) && LLONG_MAX <= INT_MAX\n#warning \"Expected (long long) to be a 64bit type. MOSEK API functions may not work.\"\n#endif\ntypedef int          __mskint32;\n\n/*\ntypedef unsigned int       __mskuint32;\ntypedef signed   int       __mskint32;\ntypedef unsigned long long __mskuint64;\ntypedef signed   long long __mskint64;\n*/\n\n/* Enumeration typedefs */\n#ifndef MSK_NO_ENUMS\ntypedef int                     MSKbasindtypee;\ntypedef enum MSKboundkey_enum        MSKboundkeye;\ntypedef int                     MSKbranchdire;\ntypedef enum MSKcallbackcode_enum    MSKcallbackcodee;\ntypedef enum MSKcompresstype_enum    MSKcompresstypee;\ntypedef enum MSKconetype_enum        MSKconetypee;\ntypedef enum MSKdataformat_enum      MSKdataformate;\ntypedef enum MSKdinfitem_enum        MSKdinfiteme;\ntypedef enum MSKdomaintype_enum      MSKdomaintypee;\ntypedef enum MSKdparam_enum          MSKdparame;\ntypedef enum MSKfeature_enum         MSKfeaturee;\ntypedef int                     MSKfoldingmodee;\ntypedef enum MSKiinfitem_enum        MSKiinfiteme;\ntypedef enum MSKinftype_enum         MSKinftypee;\ntypedef enum MSKintpnthotstart_enum  MSKintpnthotstarte;\ntypedef int                     MSKiomodee;\ntypedef enum MSKiparam_enum          MSKiparame;\ntypedef enum MSKliinfitem_enum       MSKliinfiteme;\ntypedef enum MSKmark_enum            MSKmarke;\ntypedef int                     MSKmiocontsoltypee;\ntypedef int                     MSKmiodatapermmethode;\ntypedef int                     MSKmiomodee;\ntypedef int                     MSKmionodeseltypee;\ntypedef int                     MSKmiovarseltypee;\ntypedef int                     MSKmiqcqoreformmethode;\ntypedef int                     MSKmpsformate;\ntypedef enum MSKnametype_enum        MSKnametypee;\ntypedef enum MSKobjsense_enum        MSKobjsensee;\ntypedef int                     MSKonoffkeye;\ntypedef int                     MSKoptimizertypee;\ntypedef int                     MSKorderingtypee;\ntypedef enum MSKparametertype_enum   MSKparametertypee;\ntypedef int                     MSKpresolvemodee;\ntypedef enum MSKproblemitem_enum     MSKproblemiteme;\ntypedef enum MSKproblemtype_enum     MSKproblemtypee;\ntypedef enum MSKprosta_enum          MSKprostae;\ntypedef enum MSKrescode_enum         MSKrescodee;\ntypedef enum MSKrescodetype_enum     MSKrescodetypee;\ntypedef int                     MSKscalingmethode;\ntypedef int                     MSKscalingtypee;\ntypedef int                     MSKsensitivitytypee;\ntypedef enum MSKsimdegen_enum        MSKsimdegene;\ntypedef enum MSKsimdupvec_enum       MSKsimdupvece;\ntypedef enum MSKsimhotstart_enum     MSKsimhotstarte;\ntypedef enum MSKsimprecision_enum    MSKsimprecisione;\ntypedef enum MSKsimreform_enum       MSKsimreforme;\ntypedef int                     MSKsimseltypee;\ntypedef enum MSKsolformat_enum       MSKsolformate;\ntypedef enum MSKsolitem_enum         MSKsoliteme;\ntypedef enum MSKsolsta_enum          MSKsolstae;\ntypedef enum MSKsoltype_enum         MSKsoltypee;\ntypedef int                     MSKsolveforme;\ntypedef enum MSKsparam_enum          MSKsparame;\ntypedef enum MSKstakey_enum          MSKstakeye;\ntypedef int                     MSKstartpointtypee;\ntypedef enum MSKstreamtype_enum      MSKstreamtypee;\ntypedef enum MSKsymmattype_enum      MSKsymmattypee;\ntypedef enum MSKtranspose_enum       MSKtransposee;\ntypedef enum MSKuplo_enum            MSKuploe;\ntypedef int                     MSKvaluee;\ntypedef enum MSKvariabletype_enum    MSKvariabletypee;\n#else\ntypedef int                     MSKbasindtypee;\ntypedef int                     MSKboundkeye;\ntypedef int                     MSKbranchdire;\ntypedef int                     MSKcallbackcodee;\ntypedef int                     MSKcompresstypee;\ntypedef int                     MSKconetypee;\ntypedef int                     MSKdataformate;\ntypedef int                     MSKdinfiteme;\ntypedef int                     MSKdomaintypee;\ntypedef int                     MSKdparame;\ntypedef int                     MSKfeaturee;\ntypedef int                     MSKfoldingmodee;\ntypedef int                     MSKiinfiteme;\ntypedef int                     MSKinftypee;\ntypedef int                     MSKintpnthotstarte;\ntypedef int                     MSKiomodee;\ntypedef int                     MSKiparame;\ntypedef int                     MSKliinfiteme;\ntypedef int                     MSKmarke;\ntypedef int                     MSKmiocontsoltypee;\ntypedef int                     MSKmiodatapermmethode;\ntypedef int                     MSKmiomodee;\ntypedef int                     MSKmionodeseltypee;\ntypedef int                     MSKmiovarseltypee;\ntypedef int                     MSKmiqcqoreformmethode;\ntypedef int                     MSKmpsformate;\ntypedef int                     MSKnametypee;\ntypedef int                     MSKobjsensee;\ntypedef int                     MSKonoffkeye;\ntypedef int                     MSKoptimizertypee;\ntypedef int                     MSKorderingtypee;\ntypedef int                     MSKparametertypee;\ntypedef int                     MSKpresolvemodee;\ntypedef int                     MSKproblemiteme;\ntypedef int                     MSKproblemtypee;\ntypedef int                     MSKprostae;\ntypedef int                     MSKrescodee;\ntypedef int                     MSKrescodetypee;\ntypedef int                     MSKscalingmethode;\ntypedef int                     MSKscalingtypee;\ntypedef int                     MSKsensitivitytypee;\ntypedef int                     MSKsimdegene;\ntypedef int                     MSKsimdupvece;\ntypedef int                     MSKsimhotstarte;\ntypedef int                     MSKsimprecisione;\ntypedef int                     MSKsimreforme;\ntypedef int                     MSKsimseltypee;\ntypedef int                     MSKsolformate;\ntypedef int                     MSKsoliteme;\ntypedef int                     MSKsolstae;\ntypedef int                     MSKsoltypee;\ntypedef int                     MSKsolveforme;\ntypedef int                     MSKsparame;\ntypedef int                     MSKstakeye;\ntypedef int                     MSKstartpointtypee;\ntypedef int                     MSKstreamtypee;\ntypedef int                     MSKsymmattypee;\ntypedef int                     MSKtransposee;\ntypedef int                     MSKuploe;\ntypedef int                     MSKvaluee;\ntypedef int                     MSKvariabletypee;\n#endif\n\n/* Simple typedefs */\nstruct mskenvt;\nstruct msktaskt;\ntypedef struct mskenvt MSKenv;\ntypedef struct msktaskt MSKtask;\ntypedef int MSKbooleant;\n\ntypedef MSKenv * MSKenv_t;\n\ntypedef int32_t MSKint32t;\n\ntypedef int64_t MSKint64t;\n\ntypedef double MSKrealt;\n\ntypedef char * MSKstring_t;\n\ntypedef MSKtask * MSKtask_t;\n\ntypedef void * MSKuserhandle_t;\n\ntypedef wchar_t MSKwchart;\n\n/* Function typedefs */\ntypedef MSKint32t  (MSKAPI * MSKcallbackfunc) (\n\tMSKtask_t task,\n\tMSKuserhandle_t usrptr,\n\tMSKcallbackcodee caller,\n\tconst MSKrealt * douinf,\n\tconst MSKint32t * intinf,\n\tconst MSKint64t * lintinf);\n\ntypedef void  (MSKAPI * MSKexitfunc) (\n\tMSKuserhandle_t usrptr,\n\tconst char * file,\n\tMSKint32t line,\n\tconst char * msg);\n\ntypedef size_t  (MSKAPI * MSKhreadfunc) (\n\tMSKuserhandle_t handle,\n\tvoid * dest,\n\tconst size_t count);\n\ntypedef size_t  (MSKAPI * MSKhwritefunc) (\n\tMSKuserhandle_t handle,\n\tconst void * src,\n\tconst size_t count);\n\ntypedef MSKrescodee  (MSKAPI * MSKresponsefunc) (\n\tMSKuserhandle_t handle,\n\tMSKrescodee r,\n\tconst char * msg);\n\ntypedef void  (MSKAPI * MSKstreamfunc) (\n\tMSKuserhandle_t handle,\n\tconst char * str);\n\n\n\n\n/* Functions */\n\n/* using __cplusplus */\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* MSK_analyzenames */\nMSKrescodee (MSKAPI MSK_analyzenames) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream,\n\tMSKnametypee nametype);\n\n/* MSK_analyzeproblem */\nMSKrescodee (MSKAPI MSK_analyzeproblem) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream);\n\n/* MSK_analyzesolution */\nMSKrescodee (MSKAPI MSK_analyzesolution) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream,\n\tMSKsoltypee whichsol);\n\n/* MSK_appendacc */\nMSKrescodee (MSKAPI MSK_appendacc) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidxlist,\n\tconst MSKrealt * b);\n\n/* MSK_appendaccs */\nMSKrescodee (MSKAPI MSK_appendaccs) (\n\tMSKtask_t task,\n\tMSKint64t numaccs,\n\tconst MSKint64t * domidxs,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidxlist,\n\tconst MSKrealt * b);\n\n/* MSK_appendaccseq */\nMSKrescodee (MSKAPI MSK_appendaccseq) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKint64t numafeidx,\n\tMSKint64t afeidxfirst,\n\tconst MSKrealt * b);\n\n/* MSK_appendaccsseq */\nMSKrescodee (MSKAPI MSK_appendaccsseq) (\n\tMSKtask_t task,\n\tMSKint64t numaccs,\n\tconst MSKint64t * domidxs,\n\tMSKint64t numafeidx,\n\tMSKint64t afeidxfirst,\n\tconst MSKrealt * b);\n\n/* MSK_appendafes */\nMSKrescodee (MSKAPI MSK_appendafes) (\n\tMSKtask_t task,\n\tMSKint64t num);\n\n/* MSK_appendbarvars */\nMSKrescodee (MSKAPI MSK_appendbarvars) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * dim);\n\n/* MSK_appendcone */\nMSKrescodee (MSKAPI MSK_appendcone) (\n\tMSKtask_t task,\n\tMSKconetypee ct,\n\tMSKrealt conepar,\n\tMSKint32t nummem,\n\tconst MSKint32t * submem);\n\n/* MSK_appendconeseq */\nMSKrescodee (MSKAPI MSK_appendconeseq) (\n\tMSKtask_t task,\n\tMSKconetypee ct,\n\tMSKrealt conepar,\n\tMSKint32t nummem,\n\tMSKint32t j);\n\n/* MSK_appendconesseq */\nMSKrescodee (MSKAPI MSK_appendconesseq) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKconetypee * ct,\n\tconst MSKrealt * conepar,\n\tconst MSKint32t * nummem,\n\tMSKint32t j);\n\n/* MSK_appendcons */\nMSKrescodee (MSKAPI MSK_appendcons) (\n\tMSKtask_t task,\n\tMSKint32t num);\n\n/* MSK_appenddjcs */\nMSKrescodee (MSKAPI MSK_appenddjcs) (\n\tMSKtask_t task,\n\tMSKint64t num);\n\n/* MSK_appenddualexpconedomain */\nMSKrescodee (MSKAPI MSK_appenddualexpconedomain) (\n\tMSKtask_t task,\n\tMSKint64t * domidx);\n\n/* MSK_appenddualgeomeanconedomain */\nMSKrescodee (MSKAPI MSK_appenddualgeomeanconedomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appenddualpowerconedomain */\nMSKrescodee (MSKAPI MSK_appenddualpowerconedomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t nleft,\n\tconst MSKrealt * alpha,\n\tMSKint64t * domidx);\n\n/* MSK_appendprimalexpconedomain */\nMSKrescodee (MSKAPI MSK_appendprimalexpconedomain) (\n\tMSKtask_t task,\n\tMSKint64t * domidx);\n\n/* MSK_appendprimalgeomeanconedomain */\nMSKrescodee (MSKAPI MSK_appendprimalgeomeanconedomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendprimalpowerconedomain */\nMSKrescodee (MSKAPI MSK_appendprimalpowerconedomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t nleft,\n\tconst MSKrealt * alpha,\n\tMSKint64t * domidx);\n\n/* MSK_appendquadraticconedomain */\nMSKrescodee (MSKAPI MSK_appendquadraticconedomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendrdomain */\nMSKrescodee (MSKAPI MSK_appendrdomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendrminusdomain */\nMSKrescodee (MSKAPI MSK_appendrminusdomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendrplusdomain */\nMSKrescodee (MSKAPI MSK_appendrplusdomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendrquadraticconedomain */\nMSKrescodee (MSKAPI MSK_appendrquadraticconedomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendrzerodomain */\nMSKrescodee (MSKAPI MSK_appendrzerodomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendsparsesymmat */\nMSKrescodee (MSKAPI MSK_appendsparsesymmat) (\n\tMSKtask_t task,\n\tMSKint32t dim,\n\tMSKint64t nz,\n\tconst MSKint32t * subi,\n\tconst MSKint32t * subj,\n\tconst MSKrealt * valij,\n\tMSKint64t * idx);\n\n/* MSK_appendsparsesymmatlist */\nMSKrescodee (MSKAPI MSK_appendsparsesymmatlist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * dims,\n\tconst MSKint64t * nz,\n\tconst MSKint32t * subi,\n\tconst MSKint32t * subj,\n\tconst MSKrealt * valij,\n\tMSKint64t * idx);\n\n/* MSK_appendsvecpsdconedomain */\nMSKrescodee (MSKAPI MSK_appendsvecpsdconedomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendvars */\nMSKrescodee (MSKAPI MSK_appendvars) (\n\tMSKtask_t task,\n\tMSKint32t num);\n\n/* MSK_asyncgetlog */\nMSKrescodee (MSKAPI MSK_asyncgetlog) (\n\tMSKtask_t task,\n\tconst char * addr,\n\tconst char * accesstoken,\n\tconst char * token);\n\n/* MSK_asyncgetresult */\nMSKrescodee (MSKAPI MSK_asyncgetresult) (\n\tMSKtask_t task,\n\tconst char * address,\n\tconst char * accesstoken,\n\tconst char * token,\n\tMSKbooleant * respavailable,\n\tMSKrescodee * resp,\n\tMSKrescodee * trm);\n\n/* MSK_asyncoptimize */\nMSKrescodee (MSKAPI MSK_asyncoptimize) (\n\tMSKtask_t task,\n\tconst char * address,\n\tconst char * accesstoken,\n\tchar * token);\n\n/* MSK_asyncpoll */\nMSKrescodee (MSKAPI MSK_asyncpoll) (\n\tMSKtask_t task,\n\tconst char * address,\n\tconst char * accesstoken,\n\tconst char * token,\n\tMSKbooleant * respavailable,\n\tMSKrescodee * resp,\n\tMSKrescodee * trm);\n\n/* MSK_asyncstop */\nMSKrescodee (MSKAPI MSK_asyncstop) (\n\tMSKtask_t task,\n\tconst char * address,\n\tconst char * accesstoken,\n\tconst char * token);\n\n/* MSK_basiscond */\nMSKrescodee (MSKAPI MSK_basiscond) (\n\tMSKtask_t task,\n\tMSKrealt * nrmbasis,\n\tMSKrealt * nrminvbasis);\n\n/* MSK_bktostr */\nMSKrescodee (MSKAPI MSK_bktostr) (\n\tMSKtask_t task,\n\tMSKboundkeye bk,\n\tchar * str);\n\n/* MSK_callocdbgtask */\nvoid * (MSKAPI MSK_callocdbgtask) (\n\tMSKtask_t task,\n\tconst size_t number,\n\tconst size_t size,\n\tconst char * file,\n\tconst unsigned line);\n\n/* MSK_calloctask */\nvoid * (MSKAPI MSK_calloctask) (\n\tMSKtask_t task,\n\tconst size_t number,\n\tconst size_t size);\n\n/* MSK_checkmemtask */\nMSKrescodee (MSKAPI MSK_checkmemtask) (\n\tMSKtask_t task,\n\tconst char * file,\n\tMSKint32t line);\n\n/* MSK_chgconbound */\nMSKrescodee (MSKAPI MSK_chgconbound) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t lower,\n\tMSKint32t finite,\n\tMSKrealt value);\n\n/* MSK_chgvarbound */\nMSKrescodee (MSKAPI MSK_chgvarbound) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKint32t lower,\n\tMSKint32t finite,\n\tMSKrealt value);\n\n/* MSK_clonetask */\nMSKrescodee (MSKAPI MSK_clonetask) (\n\tMSKtask_t task,\n\tMSKtask_t * clonedtask);\n\n/* MSK_commitchanges */\nMSKrescodee (MSKAPI MSK_commitchanges) (\n\tMSKtask_t task);\n\n/* MSK_conetypetostr */\nMSKrescodee (MSKAPI MSK_conetypetostr) (\n\tMSKtask_t task,\n\tMSKconetypee ct,\n\tchar * str);\n\n/* MSK_deletesolution */\nMSKrescodee (MSKAPI MSK_deletesolution) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol);\n\n/* MSK_deletetask */\nMSKrescodee (MSKAPI MSK_deletetask) (\n\tMSKtask_t * task);\n\n/* MSK_dualsensitivity */\nMSKrescodee (MSKAPI MSK_dualsensitivity) (\n\tMSKtask_t task,\n\tMSKint32t numj,\n\tconst MSKint32t * subj,\n\tMSKrealt * leftpricej,\n\tMSKrealt * rightpricej,\n\tMSKrealt * leftrangej,\n\tMSKrealt * rightrangej);\n\n/* MSK_echotask */\nMSKrescodee (MSKAPIVA MSK_echotask) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream,\n\tconst char * format,\n\t...);\n\n/* MSK_emptyafebarfrow */\nMSKrescodee (MSKAPI MSK_emptyafebarfrow) (\n\tMSKtask_t task,\n\tMSKint64t afeidx);\n\n/* MSK_emptyafebarfrowlist */\nMSKrescodee (MSKAPI MSK_emptyafebarfrowlist) (\n\tMSKtask_t task,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidxlist);\n\n/* MSK_emptyafefcol */\nMSKrescodee (MSKAPI MSK_emptyafefcol) (\n\tMSKtask_t task,\n\tMSKint32t varidx);\n\n/* MSK_emptyafefcollist */\nMSKrescodee (MSKAPI MSK_emptyafefcollist) (\n\tMSKtask_t task,\n\tMSKint64t numvaridx,\n\tconst MSKint32t * varidx);\n\n/* MSK_emptyafefrow */\nMSKrescodee (MSKAPI MSK_emptyafefrow) (\n\tMSKtask_t task,\n\tMSKint64t afeidx);\n\n/* MSK_emptyafefrowlist */\nMSKrescodee (MSKAPI MSK_emptyafefrowlist) (\n\tMSKtask_t task,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidx);\n\n/* MSK_evaluateacc */\nMSKrescodee (MSKAPI MSK_evaluateacc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint64t accidx,\n\tMSKrealt * activity);\n\n/* MSK_evaluateaccs */\nMSKrescodee (MSKAPI MSK_evaluateaccs) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * activity);\n\n/* MSK_freedbgtask */\nvoid (MSKAPI MSK_freedbgtask) (\n\tMSKtask_t task,\n\tvoid * buffer,\n\tconst char * file,\n\tconst unsigned line);\n\n/* MSK_freetask */\nvoid (MSKAPI MSK_freetask) (\n\tMSKtask_t task,\n\tvoid * buffer);\n\n/* MSK_generateaccnames */\nMSKrescodee (MSKAPI MSK_generateaccnames) (\n\tMSKtask_t task,\n\tMSKint64t num,\n\tconst MSKint64t * sub,\n\tconst char * fmt,\n\tMSKint32t ndims,\n\tconst MSKint32t * dims,\n\tconst MSKint64t * sp,\n\tMSKint32t numnamedaxis,\n\tconst MSKint32t * namedaxisidxs,\n\tMSKint64t numnames,\n\tconst char ** names);\n\n/* MSK_generatebarvarnames */\nMSKrescodee (MSKAPI MSK_generatebarvarnames) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subj,\n\tconst char * fmt,\n\tMSKint32t ndims,\n\tconst MSKint32t * dims,\n\tconst MSKint64t * sp,\n\tMSKint32t numnamedaxis,\n\tconst MSKint32t * namedaxisidxs,\n\tMSKint64t numnames,\n\tconst char ** names);\n\n/* MSK_generateconenames */\nMSKrescodee (MSKAPI MSK_generateconenames) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subk,\n\tconst char * fmt,\n\tMSKint32t ndims,\n\tconst MSKint32t * dims,\n\tconst MSKint64t * sp,\n\tMSKint32t numnamedaxis,\n\tconst MSKint32t * namedaxisidxs,\n\tMSKint64t numnames,\n\tconst char ** names);\n\n/* MSK_generateconnames */\nMSKrescodee (MSKAPI MSK_generateconnames) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subi,\n\tconst char * fmt,\n\tMSKint32t ndims,\n\tconst MSKint32t * dims,\n\tconst MSKint64t * sp,\n\tMSKint32t numnamedaxis,\n\tconst MSKint32t * namedaxisidxs,\n\tMSKint64t numnames,\n\tconst char ** names);\n\n/* MSK_generatedjcnames */\nMSKrescodee (MSKAPI MSK_generatedjcnames) (\n\tMSKtask_t task,\n\tMSKint64t num,\n\tconst MSKint64t * sub,\n\tconst char * fmt,\n\tMSKint32t ndims,\n\tconst MSKint32t * dims,\n\tconst MSKint64t * sp,\n\tMSKint32t numnamedaxis,\n\tconst MSKint32t * namedaxisidxs,\n\tMSKint64t numnames,\n\tconst char ** names);\n\n/* MSK_generatevarnames */\nMSKrescodee (MSKAPI MSK_generatevarnames) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subj,\n\tconst char * fmt,\n\tMSKint32t ndims,\n\tconst MSKint32t * dims,\n\tconst MSKint64t * sp,\n\tMSKint32t numnamedaxis,\n\tconst MSKint32t * namedaxisidxs,\n\tMSKint64t numnames,\n\tconst char ** names);\n\n/* MSK_getaccafeidxlist */\nMSKrescodee (MSKAPI MSK_getaccafeidxlist) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint64t * afeidxlist);\n\n/* MSK_getaccb */\nMSKrescodee (MSKAPI MSK_getaccb) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKrealt * b);\n\n/* MSK_getaccbarfblocktriplet */\nMSKrescodee (MSKAPI MSK_getaccbarfblocktriplet) (\n\tMSKtask_t task,\n\tMSKint64t maxnumtrip,\n\tMSKint64t * numtrip,\n\tMSKint64t * acc_afe,\n\tMSKint32t * bar_var,\n\tMSKint32t * blk_row,\n\tMSKint32t * blk_col,\n\tMSKrealt * blk_val);\n\n/* MSK_getaccbarfnumblocktriplets */\nMSKrescodee (MSKAPI MSK_getaccbarfnumblocktriplets) (\n\tMSKtask_t task,\n\tMSKint64t * numtrip);\n\n/* MSK_getaccdomain */\nMSKrescodee (MSKAPI MSK_getaccdomain) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint64t * domidx);\n\n/* MSK_getaccdoty */\nMSKrescodee (MSKAPI MSK_getaccdoty) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint64t accidx,\n\tMSKrealt * doty);\n\n/* MSK_getaccdotys */\nMSKrescodee (MSKAPI MSK_getaccdotys) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * doty);\n\n/* MSK_getaccfnumnz */\nMSKrescodee (MSKAPI MSK_getaccfnumnz) (\n\tMSKtask_t task,\n\tMSKint64t * accfnnz);\n\n/* MSK_getaccftrip */\nMSKrescodee (MSKAPI MSK_getaccftrip) (\n\tMSKtask_t task,\n\tMSKint64t * frow,\n\tMSKint32t * fcol,\n\tMSKrealt * fval);\n\n/* MSK_getaccgvector */\nMSKrescodee (MSKAPI MSK_getaccgvector) (\n\tMSKtask_t task,\n\tMSKrealt * g);\n\n/* MSK_getaccn */\nMSKrescodee (MSKAPI MSK_getaccn) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint64t * n);\n\n/* MSK_getaccname */\nMSKrescodee (MSKAPI MSK_getaccname) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint32t sizename,\n\tchar * name);\n\n/* MSK_getaccnamelen */\nMSKrescodee (MSKAPI MSK_getaccnamelen) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint32t * len);\n\n/* MSK_getaccntot */\nMSKrescodee (MSKAPI MSK_getaccntot) (\n\tMSKtask_t task,\n\tMSKint64t * n);\n\n/* MSK_getaccs */\nMSKrescodee (MSKAPI MSK_getaccs) (\n\tMSKtask_t task,\n\tMSKint64t * domidxlist,\n\tMSKint64t * afeidxlist,\n\tMSKrealt * b);\n\n/* MSK_getacol */\nMSKrescodee (MSKAPI MSK_getacol) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKint32t * nzj,\n\tMSKint32t * subj,\n\tMSKrealt * valj);\n\n/* MSK_getacolnumnz */\nMSKrescodee (MSKAPI MSK_getacolnumnz) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t * nzj);\n\n/* MSK_getacolslice */\nMSKrescodee (MSKAPI MSK_getacolslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint32t maxnumnz,\n\tMSKint32t * ptrb,\n\tMSKint32t * ptre,\n\tMSKint32t * sub,\n\tMSKrealt * val);\n\n/* MSK_getacolslice64 */\nMSKrescodee (MSKAPI MSK_getacolslice64) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t maxnumnz,\n\tMSKint64t * ptrb,\n\tMSKint64t * ptre,\n\tMSKint32t * sub,\n\tMSKrealt * val);\n\n/* MSK_getacolslicenumnz */\nMSKrescodee (MSKAPI MSK_getacolslicenumnz) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint32t * numnz);\n\n/* MSK_getacolslicenumnz64 */\nMSKrescodee (MSKAPI MSK_getacolslicenumnz64) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t * numnz);\n\n/* MSK_getacolslicetrip */\nMSKrescodee (MSKAPI MSK_getacolslicetrip) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t maxnumnz,\n\tMSKint32t * subi,\n\tMSKint32t * subj,\n\tMSKrealt * val);\n\n/* MSK_getafebarfblocktriplet */\nMSKrescodee (MSKAPI MSK_getafebarfblocktriplet) (\n\tMSKtask_t task,\n\tMSKint64t maxnumtrip,\n\tMSKint64t * numtrip,\n\tMSKint64t * afeidx,\n\tMSKint32t * barvaridx,\n\tMSKint32t * subk,\n\tMSKint32t * subl,\n\tMSKrealt * valkl);\n\n/* MSK_getafebarfnumblocktriplets */\nMSKrescodee (MSKAPI MSK_getafebarfnumblocktriplets) (\n\tMSKtask_t task,\n\tMSKint64t * numtrip);\n\n/* MSK_getafebarfnumrowentries */\nMSKrescodee (MSKAPI MSK_getafebarfnumrowentries) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t * numentr);\n\n/* MSK_getafebarfrow */\nMSKrescodee (MSKAPI MSK_getafebarfrow) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t * barvaridx,\n\tMSKint64t * ptrterm,\n\tMSKint64t * numterm,\n\tMSKint64t * termidx,\n\tMSKrealt * termweight);\n\n/* MSK_getafebarfrowinfo */\nMSKrescodee (MSKAPI MSK_getafebarfrowinfo) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t * numentr,\n\tMSKint64t * numterm);\n\n/* MSK_getafefnumnz */\nMSKrescodee (MSKAPI MSK_getafefnumnz) (\n\tMSKtask_t task,\n\tMSKint64t * numnz);\n\n/* MSK_getafefrow */\nMSKrescodee (MSKAPI MSK_getafefrow) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t * numnz,\n\tMSKint32t * varidx,\n\tMSKrealt * val);\n\n/* MSK_getafefrownumnz */\nMSKrescodee (MSKAPI MSK_getafefrownumnz) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t * numnz);\n\n/* MSK_getafeftrip */\nMSKrescodee (MSKAPI MSK_getafeftrip) (\n\tMSKtask_t task,\n\tMSKint64t * afeidx,\n\tMSKint32t * varidx,\n\tMSKrealt * val);\n\n/* MSK_getafeg */\nMSKrescodee (MSKAPI MSK_getafeg) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKrealt * g);\n\n/* MSK_getafegslice */\nMSKrescodee (MSKAPI MSK_getafegslice) (\n\tMSKtask_t task,\n\tMSKint64t first,\n\tMSKint64t last,\n\tMSKrealt * g);\n\n/* MSK_getaij */\nMSKrescodee (MSKAPI MSK_getaij) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t j,\n\tMSKrealt * aij);\n\n/* MSK_getapiecenumnz */\nMSKrescodee (MSKAPI MSK_getapiecenumnz) (\n\tMSKtask_t task,\n\tMSKint32t firsti,\n\tMSKint32t lasti,\n\tMSKint32t firstj,\n\tMSKint32t lastj,\n\tMSKint32t * numnz);\n\n/* MSK_getarow */\nMSKrescodee (MSKAPI MSK_getarow) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t * nzi,\n\tMSKint32t * subi,\n\tMSKrealt * vali);\n\n/* MSK_getarownumnz */\nMSKrescodee (MSKAPI MSK_getarownumnz) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t * nzi);\n\n/* MSK_getarowslice */\nMSKrescodee (MSKAPI MSK_getarowslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint32t maxnumnz,\n\tMSKint32t * ptrb,\n\tMSKint32t * ptre,\n\tMSKint32t * sub,\n\tMSKrealt * val);\n\n/* MSK_getarowslice64 */\nMSKrescodee (MSKAPI MSK_getarowslice64) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t maxnumnz,\n\tMSKint64t * ptrb,\n\tMSKint64t * ptre,\n\tMSKint32t * sub,\n\tMSKrealt * val);\n\n/* MSK_getarowslicenumnz */\nMSKrescodee (MSKAPI MSK_getarowslicenumnz) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint32t * numnz);\n\n/* MSK_getarowslicenumnz64 */\nMSKrescodee (MSKAPI MSK_getarowslicenumnz64) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t * numnz);\n\n/* MSK_getarowslicetrip */\nMSKrescodee (MSKAPI MSK_getarowslicetrip) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t maxnumnz,\n\tMSKint32t * subi,\n\tMSKint32t * subj,\n\tMSKrealt * val);\n\n/* MSK_getatrip */\nMSKrescodee (MSKAPI MSK_getatrip) (\n\tMSKtask_t task,\n\tMSKint64t maxnumnz,\n\tMSKint32t * subi,\n\tMSKint32t * subj,\n\tMSKrealt * val);\n\n/* MSK_getatruncatetol */\nMSKrescodee (MSKAPI MSK_getatruncatetol) (\n\tMSKtask_t task,\n\tMSKrealt * tolzero);\n\n/* MSK_getbarablocktriplet */\nMSKrescodee (MSKAPI MSK_getbarablocktriplet) (\n\tMSKtask_t task,\n\tMSKint64t maxnum,\n\tMSKint64t * num,\n\tMSKint32t * subi,\n\tMSKint32t * subj,\n\tMSKint32t * subk,\n\tMSKint32t * subl,\n\tMSKrealt * valijkl);\n\n/* MSK_getbaraidx */\nMSKrescodee (MSKAPI MSK_getbaraidx) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint64t maxnum,\n\tMSKint32t * i,\n\tMSKint32t * j,\n\tMSKint64t * num,\n\tMSKint64t * sub,\n\tMSKrealt * weights);\n\n/* MSK_getbaraidxij */\nMSKrescodee (MSKAPI MSK_getbaraidxij) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint32t * i,\n\tMSKint32t * j);\n\n/* MSK_getbaraidxinfo */\nMSKrescodee (MSKAPI MSK_getbaraidxinfo) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint64t * num);\n\n/* MSK_getbarasparsity */\nMSKrescodee (MSKAPI MSK_getbarasparsity) (\n\tMSKtask_t task,\n\tMSKint64t maxnumnz,\n\tMSKint64t * numnz,\n\tMSKint64t * idxij);\n\n/* MSK_getbarcblocktriplet */\nMSKrescodee (MSKAPI MSK_getbarcblocktriplet) (\n\tMSKtask_t task,\n\tMSKint64t maxnum,\n\tMSKint64t * num,\n\tMSKint32t * subj,\n\tMSKint32t * subk,\n\tMSKint32t * subl,\n\tMSKrealt * valjkl);\n\n/* MSK_getbarcidx */\nMSKrescodee (MSKAPI MSK_getbarcidx) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint64t maxnum,\n\tMSKint32t * j,\n\tMSKint64t * num,\n\tMSKint64t * sub,\n\tMSKrealt * weights);\n\n/* MSK_getbarcidxinfo */\nMSKrescodee (MSKAPI MSK_getbarcidxinfo) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint64t * num);\n\n/* MSK_getbarcidxj */\nMSKrescodee (MSKAPI MSK_getbarcidxj) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint32t * j);\n\n/* MSK_getbarcsparsity */\nMSKrescodee (MSKAPI MSK_getbarcsparsity) (\n\tMSKtask_t task,\n\tMSKint64t maxnumnz,\n\tMSKint64t * numnz,\n\tMSKint64t * idxj);\n\n/* MSK_getbarsj */\nMSKrescodee (MSKAPI MSK_getbarsj) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t j,\n\tMSKrealt * barsj);\n\n/* MSK_getbarsslice */\nMSKrescodee (MSKAPI MSK_getbarsslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t slicesize,\n\tMSKrealt * barsslice);\n\n/* MSK_getbarvarname */\nMSKrescodee (MSKAPI MSK_getbarvarname) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t sizename,\n\tchar * name);\n\n/* MSK_getbarvarnameindex */\nMSKrescodee (MSKAPI MSK_getbarvarnameindex) (\n\tMSKtask_t task,\n\tconst char * somename,\n\tMSKint32t * asgn,\n\tMSKint32t * index);\n\n/* MSK_getbarvarnamelen */\nMSKrescodee (MSKAPI MSK_getbarvarnamelen) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t * len);\n\n/* MSK_getbarxj */\nMSKrescodee (MSKAPI MSK_getbarxj) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t j,\n\tMSKrealt * barxj);\n\n/* MSK_getbarxslice */\nMSKrescodee (MSKAPI MSK_getbarxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t slicesize,\n\tMSKrealt * barxslice);\n\n/* MSK_getc */\nMSKrescodee (MSKAPI MSK_getc) (\n\tMSKtask_t task,\n\tMSKrealt * c);\n\n/* MSK_getcallbackfunc */\nMSKrescodee (MSKAPI MSK_getcallbackfunc) (\n\tMSKtask_t task,\n\tMSKcallbackfunc * func,\n\tMSKuserhandle_t * handle);\n\n/* MSK_getcfix */\nMSKrescodee (MSKAPI MSK_getcfix) (\n\tMSKtask_t task,\n\tMSKrealt * cfix);\n\n/* MSK_getcj */\nMSKrescodee (MSKAPI MSK_getcj) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKrealt * cj);\n\n/* MSK_getclist */\nMSKrescodee (MSKAPI MSK_getclist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subj,\n\tMSKrealt * c);\n\n/* MSK_getconbound */\nMSKrescodee (MSKAPI MSK_getconbound) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKboundkeye * bk,\n\tMSKrealt * bl,\n\tMSKrealt * bu);\n\n/* MSK_getconboundslice */\nMSKrescodee (MSKAPI MSK_getconboundslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKboundkeye * bk,\n\tMSKrealt * bl,\n\tMSKrealt * bu);\n\n/* MSK_getcone */\nMSKrescodee (MSKAPI MSK_getcone) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKconetypee * ct,\n\tMSKrealt * conepar,\n\tMSKint32t * nummem,\n\tMSKint32t * submem);\n\n/* MSK_getconeinfo */\nMSKrescodee (MSKAPI MSK_getconeinfo) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKconetypee * ct,\n\tMSKrealt * conepar,\n\tMSKint32t * nummem);\n\n/* MSK_getconename */\nMSKrescodee (MSKAPI MSK_getconename) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t sizename,\n\tchar * name);\n\n/* MSK_getconenameindex */\nMSKrescodee (MSKAPI MSK_getconenameindex) (\n\tMSKtask_t task,\n\tconst char * somename,\n\tMSKint32t * asgn,\n\tMSKint32t * index);\n\n/* MSK_getconenamelen */\nMSKrescodee (MSKAPI MSK_getconenamelen) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t * len);\n\n/* MSK_getconname */\nMSKrescodee (MSKAPI MSK_getconname) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t sizename,\n\tchar * name);\n\n/* MSK_getconnameindex */\nMSKrescodee (MSKAPI MSK_getconnameindex) (\n\tMSKtask_t task,\n\tconst char * somename,\n\tMSKint32t * asgn,\n\tMSKint32t * index);\n\n/* MSK_getconnamelen */\nMSKrescodee (MSKAPI MSK_getconnamelen) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t * len);\n\n/* MSK_getcslice */\nMSKrescodee (MSKAPI MSK_getcslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * c);\n\n/* MSK_getdimbarvarj */\nMSKrescodee (MSKAPI MSK_getdimbarvarj) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKint32t * dimbarvarj);\n\n/* MSK_getdjcafeidxlist */\nMSKrescodee (MSKAPI MSK_getdjcafeidxlist) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint64t * afeidxlist);\n\n/* MSK_getdjcb */\nMSKrescodee (MSKAPI MSK_getdjcb) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKrealt * b);\n\n/* MSK_getdjcdomainidxlist */\nMSKrescodee (MSKAPI MSK_getdjcdomainidxlist) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint64t * domidxlist);\n\n/* MSK_getdjcname */\nMSKrescodee (MSKAPI MSK_getdjcname) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint32t sizename,\n\tchar * name);\n\n/* MSK_getdjcnamelen */\nMSKrescodee (MSKAPI MSK_getdjcnamelen) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint32t * len);\n\n/* MSK_getdjcnumafe */\nMSKrescodee (MSKAPI MSK_getdjcnumafe) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint64t * numafe);\n\n/* MSK_getdjcnumafetot */\nMSKrescodee (MSKAPI MSK_getdjcnumafetot) (\n\tMSKtask_t task,\n\tMSKint64t * numafetot);\n\n/* MSK_getdjcnumdomain */\nMSKrescodee (MSKAPI MSK_getdjcnumdomain) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint64t * numdomain);\n\n/* MSK_getdjcnumdomaintot */\nMSKrescodee (MSKAPI MSK_getdjcnumdomaintot) (\n\tMSKtask_t task,\n\tMSKint64t * numdomaintot);\n\n/* MSK_getdjcnumterm */\nMSKrescodee (MSKAPI MSK_getdjcnumterm) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint64t * numterm);\n\n/* MSK_getdjcnumtermtot */\nMSKrescodee (MSKAPI MSK_getdjcnumtermtot) (\n\tMSKtask_t task,\n\tMSKint64t * numtermtot);\n\n/* MSK_getdjcs */\nMSKrescodee (MSKAPI MSK_getdjcs) (\n\tMSKtask_t task,\n\tMSKint64t * domidxlist,\n\tMSKint64t * afeidxlist,\n\tMSKrealt * b,\n\tMSKint64t * termsizelist,\n\tMSKint64t * numterms);\n\n/* MSK_getdjctermsizelist */\nMSKrescodee (MSKAPI MSK_getdjctermsizelist) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint64t * termsizelist);\n\n/* MSK_getdomainn */\nMSKrescodee (MSKAPI MSK_getdomainn) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKint64t * n);\n\n/* MSK_getdomainname */\nMSKrescodee (MSKAPI MSK_getdomainname) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKint32t sizename,\n\tchar * name);\n\n/* MSK_getdomainnamelen */\nMSKrescodee (MSKAPI MSK_getdomainnamelen) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKint32t * len);\n\n/* MSK_getdomaintype */\nMSKrescodee (MSKAPI MSK_getdomaintype) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKdomaintypee * domtype);\n\n/* MSK_getdouinf */\nMSKrescodee (MSKAPI MSK_getdouinf) (\n\tMSKtask_t task,\n\tMSKdinfiteme whichdinf,\n\tMSKrealt * dvalue);\n\n/* MSK_getdouparam */\nMSKrescodee (MSKAPI MSK_getdouparam) (\n\tMSKtask_t task,\n\tMSKdparame param,\n\tMSKrealt * parvalue);\n\n/* MSK_getdualobj */\nMSKrescodee (MSKAPI MSK_getdualobj) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * dualobj);\n\n/* MSK_getdualproblem */\nMSKrescodee (MSKAPI MSK_getdualproblem) (\n\tMSKtask_t task,\n\tMSKtask_t * dualtask);\n\n/* MSK_getdualsolutionnorms */\nMSKrescodee (MSKAPI MSK_getdualsolutionnorms) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * nrmy,\n\tMSKrealt * nrmslc,\n\tMSKrealt * nrmsuc,\n\tMSKrealt * nrmslx,\n\tMSKrealt * nrmsux,\n\tMSKrealt * nrmsnx,\n\tMSKrealt * nrmbars);\n\n/* MSK_getdviolacc */\nMSKrescodee (MSKAPI MSK_getdviolacc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint64t numaccidx,\n\tconst MSKint64t * accidxlist,\n\tMSKrealt * viol);\n\n/* MSK_getdviolbarvar */\nMSKrescodee (MSKAPI MSK_getdviolbarvar) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getdviolcon */\nMSKrescodee (MSKAPI MSK_getdviolcon) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getdviolcones */\nMSKrescodee (MSKAPI MSK_getdviolcones) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getdviolvar */\nMSKrescodee (MSKAPI MSK_getdviolvar) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getenv */\nMSKrescodee (MSKAPI MSK_getenv) (\n\tMSKtask_t task,\n\tMSKenv_t * env);\n\n/* MSK_getinfeasiblesubproblem */\nMSKrescodee (MSKAPI MSK_getinfeasiblesubproblem) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKtask_t * inftask);\n\n/* MSK_getinfindex */\nMSKrescodee (MSKAPI MSK_getinfindex) (\n\tMSKtask_t task,\n\tMSKinftypee inftype,\n\tconst char * infname,\n\tMSKint32t * infindex);\n\n/* MSK_getinfmax */\nMSKrescodee (MSKAPI MSK_getinfmax) (\n\tMSKtask_t task,\n\tMSKinftypee inftype,\n\tMSKint32t * infmax);\n\n/* MSK_getinfname */\nMSKrescodee (MSKAPI MSK_getinfname) (\n\tMSKtask_t task,\n\tMSKinftypee inftype,\n\tMSKint32t whichinf,\n\tchar * infname);\n\n/* MSK_getintinf */\nMSKrescodee (MSKAPI MSK_getintinf) (\n\tMSKtask_t task,\n\tMSKiinfiteme whichiinf,\n\tMSKint32t * ivalue);\n\n/* MSK_getintparam */\nMSKrescodee (MSKAPI MSK_getintparam) (\n\tMSKtask_t task,\n\tMSKiparame param,\n\tMSKint32t * parvalue);\n\n/* MSK_getlasterror */\nMSKrescodee (MSKAPI MSK_getlasterror) (\n\tMSKtask_t task,\n\tMSKrescodee * lastrescode,\n\tMSKint32t sizelastmsg,\n\tMSKint32t * lastmsglen,\n\tchar * lastmsg);\n\n/* MSK_getlasterror64 */\nMSKrescodee (MSKAPI MSK_getlasterror64) (\n\tMSKtask_t task,\n\tMSKrescodee * lastrescode,\n\tMSKint64t sizelastmsg,\n\tMSKint64t * lastmsglen,\n\tchar * lastmsg);\n\n/* MSK_getlenbarvarj */\nMSKrescodee (MSKAPI MSK_getlenbarvarj) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKint64t * lenbarvarj);\n\n/* MSK_getlintinf */\nMSKrescodee (MSKAPI MSK_getlintinf) (\n\tMSKtask_t task,\n\tMSKliinfiteme whichliinf,\n\tMSKint64t * ivalue);\n\n/* MSK_getlintparam */\nMSKrescodee (MSKAPI MSK_getlintparam) (\n\tMSKtask_t task,\n\tMSKiparame param,\n\tMSKint64t * parvalue);\n\n/* MSK_getmaxnamelen */\nMSKrescodee (MSKAPI MSK_getmaxnamelen) (\n\tMSKtask_t task,\n\tMSKint32t * maxlen);\n\n/* MSK_getmaxnumanz */\nMSKrescodee (MSKAPI MSK_getmaxnumanz) (\n\tMSKtask_t task,\n\tMSKint32t * maxnumanz);\n\n/* MSK_getmaxnumanz64 */\nMSKrescodee (MSKAPI MSK_getmaxnumanz64) (\n\tMSKtask_t task,\n\tMSKint64t * maxnumanz);\n\n/* MSK_getmaxnumbarvar */\nMSKrescodee (MSKAPI MSK_getmaxnumbarvar) (\n\tMSKtask_t task,\n\tMSKint32t * maxnumbarvar);\n\n/* MSK_getmaxnumcon */\nMSKrescodee (MSKAPI MSK_getmaxnumcon) (\n\tMSKtask_t task,\n\tMSKint32t * maxnumcon);\n\n/* MSK_getmaxnumcone */\nMSKrescodee (MSKAPI MSK_getmaxnumcone) (\n\tMSKtask_t task,\n\tMSKint32t * maxnumcone);\n\n/* MSK_getmaxnumqnz */\nMSKrescodee (MSKAPI MSK_getmaxnumqnz) (\n\tMSKtask_t task,\n\tMSKint32t * maxnumqnz);\n\n/* MSK_getmaxnumqnz64 */\nMSKrescodee (MSKAPI MSK_getmaxnumqnz64) (\n\tMSKtask_t task,\n\tMSKint64t * maxnumqnz);\n\n/* MSK_getmaxnumvar */\nMSKrescodee (MSKAPI MSK_getmaxnumvar) (\n\tMSKtask_t task,\n\tMSKint32t * maxnumvar);\n\n/* MSK_getmemusagetask */\nMSKrescodee (MSKAPI MSK_getmemusagetask) (\n\tMSKtask_t task,\n\tMSKint64t * meminuse,\n\tMSKint64t * maxmemuse);\n\n/* MSK_getnadouinf */\nMSKrescodee (MSKAPI MSK_getnadouinf) (\n\tMSKtask_t task,\n\tconst char * infitemname,\n\tMSKrealt * dvalue);\n\n/* MSK_getnadouparam */\nMSKrescodee (MSKAPI MSK_getnadouparam) (\n\tMSKtask_t task,\n\tconst char * paramname,\n\tMSKrealt * parvalue);\n\n/* MSK_getnaintinf */\nMSKrescodee (MSKAPI MSK_getnaintinf) (\n\tMSKtask_t task,\n\tconst char * infitemname,\n\tMSKint32t * ivalue);\n\n/* MSK_getnaintparam */\nMSKrescodee (MSKAPI MSK_getnaintparam) (\n\tMSKtask_t task,\n\tconst char * paramname,\n\tMSKint32t * parvalue);\n\n/* MSK_getnastrparam */\nMSKrescodee (MSKAPI MSK_getnastrparam) (\n\tMSKtask_t task,\n\tconst char * paramname,\n\tMSKint32t sizeparamname,\n\tMSKint32t * len,\n\tchar * parvalue);\n\n/* MSK_getnastrparamal */\nMSKrescodee (MSKAPI MSK_getnastrparamal) (\n\tMSKtask_t task,\n\tconst char * paramname,\n\tMSKint32t numaddchr,\n\tchar ** value);\n\n/* MSK_getnumacc */\nMSKrescodee (MSKAPI MSK_getnumacc) (\n\tMSKtask_t task,\n\tMSKint64t * num);\n\n/* MSK_getnumafe */\nMSKrescodee (MSKAPI MSK_getnumafe) (\n\tMSKtask_t task,\n\tMSKint64t * numafe);\n\n/* MSK_getnumanz */\nMSKrescodee (MSKAPI MSK_getnumanz) (\n\tMSKtask_t task,\n\tMSKint32t * numanz);\n\n/* MSK_getnumanz64 */\nMSKrescodee (MSKAPI MSK_getnumanz64) (\n\tMSKtask_t task,\n\tMSKint64t * numanz);\n\n/* MSK_getnumbarablocktriplets */\nMSKrescodee (MSKAPI MSK_getnumbarablocktriplets) (\n\tMSKtask_t task,\n\tMSKint64t * num);\n\n/* MSK_getnumbaranz */\nMSKrescodee (MSKAPI MSK_getnumbaranz) (\n\tMSKtask_t task,\n\tMSKint64t * nz);\n\n/* MSK_getnumbarcblocktriplets */\nMSKrescodee (MSKAPI MSK_getnumbarcblocktriplets) (\n\tMSKtask_t task,\n\tMSKint64t * num);\n\n/* MSK_getnumbarcnz */\nMSKrescodee (MSKAPI MSK_getnumbarcnz) (\n\tMSKtask_t task,\n\tMSKint64t * nz);\n\n/* MSK_getnumbarvar */\nMSKrescodee (MSKAPI MSK_getnumbarvar) (\n\tMSKtask_t task,\n\tMSKint32t * numbarvar);\n\n/* MSK_getnumcon */\nMSKrescodee (MSKAPI MSK_getnumcon) (\n\tMSKtask_t task,\n\tMSKint32t * numcon);\n\n/* MSK_getnumcone */\nMSKrescodee (MSKAPI MSK_getnumcone) (\n\tMSKtask_t task,\n\tMSKint32t * numcone);\n\n/* MSK_getnumconemem */\nMSKrescodee (MSKAPI MSK_getnumconemem) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKint32t * nummem);\n\n/* MSK_getnumdjc */\nMSKrescodee (MSKAPI MSK_getnumdjc) (\n\tMSKtask_t task,\n\tMSKint64t * num);\n\n/* MSK_getnumdomain */\nMSKrescodee (MSKAPI MSK_getnumdomain) (\n\tMSKtask_t task,\n\tMSKint64t * numdomain);\n\n/* MSK_getnumintvar */\nMSKrescodee (MSKAPI MSK_getnumintvar) (\n\tMSKtask_t task,\n\tMSKint32t * numintvar);\n\n/* MSK_getnumparam */\nMSKrescodee (MSKAPI MSK_getnumparam) (\n\tMSKtask_t task,\n\tMSKparametertypee partype,\n\tMSKint32t * numparam);\n\n/* MSK_getnumqconknz */\nMSKrescodee (MSKAPI MSK_getnumqconknz) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKint32t * numqcnz);\n\n/* MSK_getnumqconknz64 */\nMSKrescodee (MSKAPI MSK_getnumqconknz64) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKint64t * numqcnz);\n\n/* MSK_getnumqobjnz */\nMSKrescodee (MSKAPI MSK_getnumqobjnz) (\n\tMSKtask_t task,\n\tMSKint32t * numqonz);\n\n/* MSK_getnumqobjnz64 */\nMSKrescodee (MSKAPI MSK_getnumqobjnz64) (\n\tMSKtask_t task,\n\tMSKint64t * numqonz);\n\n/* MSK_getnumsymmat */\nMSKrescodee (MSKAPI MSK_getnumsymmat) (\n\tMSKtask_t task,\n\tMSKint64t * num);\n\n/* MSK_getnumvar */\nMSKrescodee (MSKAPI MSK_getnumvar) (\n\tMSKtask_t task,\n\tMSKint32t * numvar);\n\n/* MSK_getobjname */\nMSKrescodee (MSKAPI MSK_getobjname) (\n\tMSKtask_t task,\n\tMSKint32t sizeobjname,\n\tchar * objname);\n\n/* MSK_getobjnamelen */\nMSKrescodee (MSKAPI MSK_getobjnamelen) (\n\tMSKtask_t task,\n\tMSKint32t * len);\n\n/* MSK_getobjsense */\nMSKrescodee (MSKAPI MSK_getobjsense) (\n\tMSKtask_t task,\n\tMSKobjsensee * sense);\n\n/* MSK_getparammax */\nMSKrescodee (MSKAPI MSK_getparammax) (\n\tMSKtask_t task,\n\tMSKparametertypee partype,\n\tMSKint32t * parammax);\n\n/* MSK_getparamname */\nMSKrescodee (MSKAPI MSK_getparamname) (\n\tMSKtask_t task,\n\tMSKparametertypee partype,\n\tMSKint32t param,\n\tchar * parname);\n\n/* MSK_getpowerdomainalpha */\nMSKrescodee (MSKAPI MSK_getpowerdomainalpha) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKrealt * alpha);\n\n/* MSK_getpowerdomaininfo */\nMSKrescodee (MSKAPI MSK_getpowerdomaininfo) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKint64t * n,\n\tMSKint64t * nleft);\n\n/* MSK_getprimalobj */\nMSKrescodee (MSKAPI MSK_getprimalobj) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * primalobj);\n\n/* MSK_getprimalsolutionnorms */\nMSKrescodee (MSKAPI MSK_getprimalsolutionnorms) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * nrmxc,\n\tMSKrealt * nrmxx,\n\tMSKrealt * nrmbarx);\n\n/* MSK_getprobtype */\nMSKrescodee (MSKAPI MSK_getprobtype) (\n\tMSKtask_t task,\n\tMSKproblemtypee * probtype);\n\n/* MSK_getprosta */\nMSKrescodee (MSKAPI MSK_getprosta) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKprostae * problemsta);\n\n/* MSK_getpviolacc */\nMSKrescodee (MSKAPI MSK_getpviolacc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint64t numaccidx,\n\tconst MSKint64t * accidxlist,\n\tMSKrealt * viol);\n\n/* MSK_getpviolbarvar */\nMSKrescodee (MSKAPI MSK_getpviolbarvar) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getpviolcon */\nMSKrescodee (MSKAPI MSK_getpviolcon) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getpviolcones */\nMSKrescodee (MSKAPI MSK_getpviolcones) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getpvioldjc */\nMSKrescodee (MSKAPI MSK_getpvioldjc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint64t numdjcidx,\n\tconst MSKint64t * djcidxlist,\n\tMSKrealt * viol);\n\n/* MSK_getpviolvar */\nMSKrescodee (MSKAPI MSK_getpviolvar) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getqconk */\nMSKrescodee (MSKAPI MSK_getqconk) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKint32t maxnumqcnz,\n\tMSKint32t * numqcnz,\n\tMSKint32t * qcsubi,\n\tMSKint32t * qcsubj,\n\tMSKrealt * qcval);\n\n/* MSK_getqconk64 */\nMSKrescodee (MSKAPI MSK_getqconk64) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKint64t maxnumqcnz,\n\tMSKint64t * numqcnz,\n\tMSKint32t * qcsubi,\n\tMSKint32t * qcsubj,\n\tMSKrealt * qcval);\n\n/* MSK_getqobj */\nMSKrescodee (MSKAPI MSK_getqobj) (\n\tMSKtask_t task,\n\tMSKint32t maxnumqonz,\n\tMSKint32t * numqonz,\n\tMSKint32t * qosubi,\n\tMSKint32t * qosubj,\n\tMSKrealt * qoval);\n\n/* MSK_getqobj64 */\nMSKrescodee (MSKAPI MSK_getqobj64) (\n\tMSKtask_t task,\n\tMSKint64t maxnumqonz,\n\tMSKint64t * numqonz,\n\tMSKint32t * qosubi,\n\tMSKint32t * qosubj,\n\tMSKrealt * qoval);\n\n/* MSK_getqobjij */\nMSKrescodee (MSKAPI MSK_getqobjij) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t j,\n\tMSKrealt * qoij);\n\n/* MSK_getreducedcosts */\nMSKrescodee (MSKAPI MSK_getreducedcosts) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * redcosts);\n\n/* MSK_getskc */\nMSKrescodee (MSKAPI MSK_getskc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKstakeye * skc);\n\n/* MSK_getskcslice */\nMSKrescodee (MSKAPI MSK_getskcslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKstakeye * skc);\n\n/* MSK_getskn */\nMSKrescodee (MSKAPI MSK_getskn) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKstakeye * skn);\n\n/* MSK_getskx */\nMSKrescodee (MSKAPI MSK_getskx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKstakeye * skx);\n\n/* MSK_getskxslice */\nMSKrescodee (MSKAPI MSK_getskxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKstakeye * skx);\n\n/* MSK_getslc */\nMSKrescodee (MSKAPI MSK_getslc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * slc);\n\n/* MSK_getslcslice */\nMSKrescodee (MSKAPI MSK_getslcslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * slc);\n\n/* MSK_getslx */\nMSKrescodee (MSKAPI MSK_getslx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * slx);\n\n/* MSK_getslxslice */\nMSKrescodee (MSKAPI MSK_getslxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * slx);\n\n/* MSK_getsnx */\nMSKrescodee (MSKAPI MSK_getsnx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * snx);\n\n/* MSK_getsnxslice */\nMSKrescodee (MSKAPI MSK_getsnxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * snx);\n\n/* MSK_getsolsta */\nMSKrescodee (MSKAPI MSK_getsolsta) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKsolstae * solutionsta);\n\n/* MSK_getsolution */\nMSKrescodee (MSKAPI MSK_getsolution) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKprostae * problemsta,\n\tMSKsolstae * solutionsta,\n\tMSKstakeye * skc,\n\tMSKstakeye * skx,\n\tMSKstakeye * skn,\n\tMSKrealt * xc,\n\tMSKrealt * xx,\n\tMSKrealt * y,\n\tMSKrealt * slc,\n\tMSKrealt * suc,\n\tMSKrealt * slx,\n\tMSKrealt * sux,\n\tMSKrealt * snx);\n\n/* MSK_getsolutioninfo */\nMSKrescodee (MSKAPI MSK_getsolutioninfo) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * pobj,\n\tMSKrealt * pviolcon,\n\tMSKrealt * pviolvar,\n\tMSKrealt * pviolbarvar,\n\tMSKrealt * pviolcone,\n\tMSKrealt * pviolitg,\n\tMSKrealt * dobj,\n\tMSKrealt * dviolcon,\n\tMSKrealt * dviolvar,\n\tMSKrealt * dviolbarvar,\n\tMSKrealt * dviolcone);\n\n/* MSK_getsolutioninfonew */\nMSKrescodee (MSKAPI MSK_getsolutioninfonew) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * pobj,\n\tMSKrealt * pviolcon,\n\tMSKrealt * pviolvar,\n\tMSKrealt * pviolbarvar,\n\tMSKrealt * pviolcone,\n\tMSKrealt * pviolacc,\n\tMSKrealt * pvioldjc,\n\tMSKrealt * pviolitg,\n\tMSKrealt * dobj,\n\tMSKrealt * dviolcon,\n\tMSKrealt * dviolvar,\n\tMSKrealt * dviolbarvar,\n\tMSKrealt * dviolcone,\n\tMSKrealt * dviolacc);\n\n/* MSK_getsolutionnew */\nMSKrescodee (MSKAPI MSK_getsolutionnew) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKprostae * problemsta,\n\tMSKsolstae * solutionsta,\n\tMSKstakeye * skc,\n\tMSKstakeye * skx,\n\tMSKstakeye * skn,\n\tMSKrealt * xc,\n\tMSKrealt * xx,\n\tMSKrealt * y,\n\tMSKrealt * slc,\n\tMSKrealt * suc,\n\tMSKrealt * slx,\n\tMSKrealt * sux,\n\tMSKrealt * snx,\n\tMSKrealt * doty);\n\n/* MSK_getsolutionslice */\nMSKrescodee (MSKAPI MSK_getsolutionslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKsoliteme solitem,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * values);\n\n/* MSK_getsparsesymmat */\nMSKrescodee (MSKAPI MSK_getsparsesymmat) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint64t maxlen,\n\tMSKint32t * subi,\n\tMSKint32t * subj,\n\tMSKrealt * valij);\n\n/* MSK_getstrparam */\nMSKrescodee (MSKAPI MSK_getstrparam) (\n\tMSKtask_t task,\n\tMSKsparame param,\n\tMSKint32t maxlen,\n\tMSKint32t * len,\n\tchar * parvalue);\n\n/* MSK_getstrparamal */\nMSKrescodee (MSKAPI MSK_getstrparamal) (\n\tMSKtask_t task,\n\tMSKsparame param,\n\tMSKint32t numaddchr,\n\tchar ** value);\n\n/* MSK_getstrparamlen */\nMSKrescodee (MSKAPI MSK_getstrparamlen) (\n\tMSKtask_t task,\n\tMSKsparame param,\n\tMSKint32t * len);\n\n/* MSK_getsuc */\nMSKrescodee (MSKAPI MSK_getsuc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * suc);\n\n/* MSK_getsucslice */\nMSKrescodee (MSKAPI MSK_getsucslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * suc);\n\n/* MSK_getsux */\nMSKrescodee (MSKAPI MSK_getsux) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * sux);\n\n/* MSK_getsuxslice */\nMSKrescodee (MSKAPI MSK_getsuxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * sux);\n\n/* MSK_getsymbcon */\nMSKrescodee (MSKAPI MSK_getsymbcon) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t sizevalue,\n\tchar * name,\n\tMSKint32t * value);\n\n/* MSK_getsymmatinfo */\nMSKrescodee (MSKAPI MSK_getsymmatinfo) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint32t * dim,\n\tMSKint64t * nz,\n\tMSKsymmattypee * mattype);\n\n/* MSK_gettaskname */\nMSKrescodee (MSKAPI MSK_gettaskname) (\n\tMSKtask_t task,\n\tMSKint32t sizetaskname,\n\tchar * taskname);\n\n/* MSK_gettasknamelen */\nMSKrescodee (MSKAPI MSK_gettasknamelen) (\n\tMSKtask_t task,\n\tMSKint32t * len);\n\n/* MSK_getvarbound */\nMSKrescodee (MSKAPI MSK_getvarbound) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKboundkeye * bk,\n\tMSKrealt * bl,\n\tMSKrealt * bu);\n\n/* MSK_getvarboundslice */\nMSKrescodee (MSKAPI MSK_getvarboundslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKboundkeye * bk,\n\tMSKrealt * bl,\n\tMSKrealt * bu);\n\n/* MSK_getvarname */\nMSKrescodee (MSKAPI MSK_getvarname) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKint32t sizename,\n\tchar * name);\n\n/* MSK_getvarnameindex */\nMSKrescodee (MSKAPI MSK_getvarnameindex) (\n\tMSKtask_t task,\n\tconst char * somename,\n\tMSKint32t * asgn,\n\tMSKint32t * index);\n\n/* MSK_getvarnamelen */\nMSKrescodee (MSKAPI MSK_getvarnamelen) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t * len);\n\n/* MSK_getvartype */\nMSKrescodee (MSKAPI MSK_getvartype) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKvariabletypee * vartype);\n\n/* MSK_getvartypelist */\nMSKrescodee (MSKAPI MSK_getvartypelist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subj,\n\tMSKvariabletypee * vartype);\n\n/* MSK_getxc */\nMSKrescodee (MSKAPI MSK_getxc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * xc);\n\n/* MSK_getxcslice */\nMSKrescodee (MSKAPI MSK_getxcslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * xc);\n\n/* MSK_getxx */\nMSKrescodee (MSKAPI MSK_getxx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * xx);\n\n/* MSK_getxxslice */\nMSKrescodee (MSKAPI MSK_getxxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * xx);\n\n/* MSK_gety */\nMSKrescodee (MSKAPI MSK_gety) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * y);\n\n/* MSK_getyslice */\nMSKrescodee (MSKAPI MSK_getyslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * y);\n\n/* MSK_infeasibilityreport */\nMSKrescodee (MSKAPI MSK_infeasibilityreport) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream,\n\tMSKsoltypee whichsol);\n\n/* MSK_initbasissolve */\nMSKrescodee (MSKAPI MSK_initbasissolve) (\n\tMSKtask_t task,\n\tMSKint32t * basis);\n\n/* MSK_inputdata */\nMSKrescodee (MSKAPI MSK_inputdata) (\n\tMSKtask_t task,\n\tMSKint32t maxnumcon,\n\tMSKint32t maxnumvar,\n\tMSKint32t numcon,\n\tMSKint32t numvar,\n\tconst MSKrealt * c,\n\tMSKrealt cfix,\n\tconst MSKint32t * aptrb,\n\tconst MSKint32t * aptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval,\n\tconst MSKboundkeye * bkc,\n\tconst MSKrealt * blc,\n\tconst MSKrealt * buc,\n\tconst MSKboundkeye * bkx,\n\tconst MSKrealt * blx,\n\tconst MSKrealt * bux);\n\n/* MSK_inputdata64 */\nMSKrescodee (MSKAPI MSK_inputdata64) (\n\tMSKtask_t task,\n\tMSKint32t maxnumcon,\n\tMSKint32t maxnumvar,\n\tMSKint32t numcon,\n\tMSKint32t numvar,\n\tconst MSKrealt * c,\n\tMSKrealt cfix,\n\tconst MSKint64t * aptrb,\n\tconst MSKint64t * aptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval,\n\tconst MSKboundkeye * bkc,\n\tconst MSKrealt * blc,\n\tconst MSKrealt * buc,\n\tconst MSKboundkeye * bkx,\n\tconst MSKrealt * blx,\n\tconst MSKrealt * bux);\n\n/* MSK_isdouparname */\nMSKrescodee (MSKAPI MSK_isdouparname) (\n\tMSKtask_t task,\n\tconst char * parname,\n\tMSKdparame * param);\n\n/* MSK_isintparname */\nMSKrescodee (MSKAPI MSK_isintparname) (\n\tMSKtask_t task,\n\tconst char * parname,\n\tMSKiparame * param);\n\n/* MSK_isstrparname */\nMSKrescodee (MSKAPI MSK_isstrparname) (\n\tMSKtask_t task,\n\tconst char * parname,\n\tMSKsparame * param);\n\n/* MSK_linkfiletotaskstream */\nMSKrescodee (MSKAPI MSK_linkfiletotaskstream) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream,\n\tconst char * filename,\n\tMSKint32t append);\n\n/* MSK_linkfunctotaskstream */\nMSKrescodee (MSKAPI MSK_linkfunctotaskstream) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream,\n\tMSKuserhandle_t handle,\n\tMSKstreamfunc func);\n\n/* MSK_onesolutionsummary */\nMSKrescodee (MSKAPI MSK_onesolutionsummary) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream,\n\tMSKsoltypee whichsol);\n\n/* MSK_optimize */\nMSKrescodee (MSKAPI MSK_optimize) (\n\tMSKtask_t task);\n\n/* MSK_optimizermt */\nMSKrescodee (MSKAPI MSK_optimizermt) (\n\tMSKtask_t task,\n\tconst char * address,\n\tconst char * accesstoken,\n\tMSKrescodee * trmcode);\n\n/* MSK_optimizersummary */\nMSKrescodee (MSKAPI MSK_optimizersummary) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream);\n\n/* MSK_optimizetrm */\nMSKrescodee (MSKAPI MSK_optimizetrm) (\n\tMSKtask_t task,\n\tMSKrescodee * trmcode);\n\n/* MSK_primalrepair */\nMSKrescodee (MSKAPI MSK_primalrepair) (\n\tMSKtask_t task,\n\tconst MSKrealt * wlc,\n\tconst MSKrealt * wuc,\n\tconst MSKrealt * wlx,\n\tconst MSKrealt * wux);\n\n/* MSK_primalsensitivity */\nMSKrescodee (MSKAPI MSK_primalsensitivity) (\n\tMSKtask_t task,\n\tMSKint32t numi,\n\tconst MSKint32t * subi,\n\tconst MSKmarke * marki,\n\tMSKint32t numj,\n\tconst MSKint32t * subj,\n\tconst MSKmarke * markj,\n\tMSKrealt * leftpricei,\n\tMSKrealt * rightpricei,\n\tMSKrealt * leftrangei,\n\tMSKrealt * rightrangei,\n\tMSKrealt * leftpricej,\n\tMSKrealt * rightpricej,\n\tMSKrealt * leftrangej,\n\tMSKrealt * rightrangej);\n\n/* MSK_printparam */\nMSKrescodee (MSKAPI MSK_printparam) (\n\tMSKtask_t task);\n\n/* MSK_probtypetostr */\nMSKrescodee (MSKAPI MSK_probtypetostr) (\n\tMSKtask_t task,\n\tMSKproblemtypee probtype,\n\tchar * str);\n\n/* MSK_prostatostr */\nMSKrescodee (MSKAPI MSK_prostatostr) (\n\tMSKtask_t task,\n\tMSKprostae problemsta,\n\tchar * str);\n\n/* MSK_putacc */\nMSKrescodee (MSKAPI MSK_putacc) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint64t domidx,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidxlist,\n\tconst MSKrealt * b);\n\n/* MSK_putaccb */\nMSKrescodee (MSKAPI MSK_putaccb) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint64t lengthb,\n\tconst MSKrealt * b);\n\n/* MSK_putaccbj */\nMSKrescodee (MSKAPI MSK_putaccbj) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint64t j,\n\tMSKrealt bj);\n\n/* MSK_putaccdoty */\nMSKrescodee (MSKAPI MSK_putaccdoty) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint64t accidx,\n\tMSKrealt * doty);\n\n/* MSK_putacclist */\nMSKrescodee (MSKAPI MSK_putacclist) (\n\tMSKtask_t task,\n\tMSKint64t numaccs,\n\tconst MSKint64t * accidxs,\n\tconst MSKint64t * domidxs,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidxlist,\n\tconst MSKrealt * b);\n\n/* MSK_putaccname */\nMSKrescodee (MSKAPI MSK_putaccname) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tconst char * name);\n\n/* MSK_putacol */\nMSKrescodee (MSKAPI MSK_putacol) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKint32t nzj,\n\tconst MSKint32t * subj,\n\tconst MSKrealt * valj);\n\n/* MSK_putacollist */\nMSKrescodee (MSKAPI MSK_putacollist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tconst MSKint32t * ptrb,\n\tconst MSKint32t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putacollist64 */\nMSKrescodee (MSKAPI MSK_putacollist64) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tconst MSKint64t * ptrb,\n\tconst MSKint64t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putacolslice */\nMSKrescodee (MSKAPI MSK_putacolslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKint32t * ptrb,\n\tconst MSKint32t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putacolslice64 */\nMSKrescodee (MSKAPI MSK_putacolslice64) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKint64t * ptrb,\n\tconst MSKint64t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putafebarfblocktriplet */\nMSKrescodee (MSKAPI MSK_putafebarfblocktriplet) (\n\tMSKtask_t task,\n\tMSKint64t numtrip,\n\tconst MSKint64t * afeidx,\n\tconst MSKint32t * barvaridx,\n\tconst MSKint32t * subk,\n\tconst MSKint32t * subl,\n\tconst MSKrealt * valkl);\n\n/* MSK_putafebarfentry */\nMSKrescodee (MSKAPI MSK_putafebarfentry) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t barvaridx,\n\tMSKint64t numterm,\n\tconst MSKint64t * termidx,\n\tconst MSKrealt * termweight);\n\n/* MSK_putafebarfentrylist */\nMSKrescodee (MSKAPI MSK_putafebarfentrylist) (\n\tMSKtask_t task,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidx,\n\tconst MSKint32t * barvaridx,\n\tconst MSKint64t * numterm,\n\tconst MSKint64t * ptrterm,\n\tMSKint64t lenterm,\n\tconst MSKint64t * termidx,\n\tconst MSKrealt * termweight);\n\n/* MSK_putafebarfrow */\nMSKrescodee (MSKAPI MSK_putafebarfrow) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t numentr,\n\tconst MSKint32t * barvaridx,\n\tconst MSKint64t * numterm,\n\tconst MSKint64t * ptrterm,\n\tMSKint64t lenterm,\n\tconst MSKint64t * termidx,\n\tconst MSKrealt * termweight);\n\n/* MSK_putafefcol */\nMSKrescodee (MSKAPI MSK_putafefcol) (\n\tMSKtask_t task,\n\tMSKint32t varidx,\n\tMSKint64t numnz,\n\tconst MSKint64t * afeidx,\n\tconst MSKrealt * val);\n\n/* MSK_putafefentry */\nMSKrescodee (MSKAPI MSK_putafefentry) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t varidx,\n\tMSKrealt value);\n\n/* MSK_putafefentrylist */\nMSKrescodee (MSKAPI MSK_putafefentrylist) (\n\tMSKtask_t task,\n\tMSKint64t numentr,\n\tconst MSKint64t * afeidx,\n\tconst MSKint32t * varidx,\n\tconst MSKrealt * val);\n\n/* MSK_putafefrow */\nMSKrescodee (MSKAPI MSK_putafefrow) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t numnz,\n\tconst MSKint32t * varidx,\n\tconst MSKrealt * val);\n\n/* MSK_putafefrowlist */\nMSKrescodee (MSKAPI MSK_putafefrowlist) (\n\tMSKtask_t task,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidx,\n\tconst MSKint32t * numnzrow,\n\tconst MSKint64t * ptrrow,\n\tMSKint64t lenidxval,\n\tconst MSKint32t * varidx,\n\tconst MSKrealt * val);\n\n/* MSK_putafeg */\nMSKrescodee (MSKAPI MSK_putafeg) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKrealt g);\n\n/* MSK_putafeglist */\nMSKrescodee (MSKAPI MSK_putafeglist) (\n\tMSKtask_t task,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidx,\n\tconst MSKrealt * g);\n\n/* MSK_putafegslice */\nMSKrescodee (MSKAPI MSK_putafegslice) (\n\tMSKtask_t task,\n\tMSKint64t first,\n\tMSKint64t last,\n\tconst MSKrealt * slice);\n\n/* MSK_putaij */\nMSKrescodee (MSKAPI MSK_putaij) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t j,\n\tMSKrealt aij);\n\n/* MSK_putaijlist */\nMSKrescodee (MSKAPI MSK_putaijlist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subi,\n\tconst MSKint32t * subj,\n\tconst MSKrealt * valij);\n\n/* MSK_putaijlist64 */\nMSKrescodee (MSKAPI MSK_putaijlist64) (\n\tMSKtask_t task,\n\tMSKint64t num,\n\tconst MSKint32t * subi,\n\tconst MSKint32t * subj,\n\tconst MSKrealt * valij);\n\n/* MSK_putarow */\nMSKrescodee (MSKAPI MSK_putarow) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t nzi,\n\tconst MSKint32t * subi,\n\tconst MSKrealt * vali);\n\n/* MSK_putarowlist */\nMSKrescodee (MSKAPI MSK_putarowlist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tconst MSKint32t * ptrb,\n\tconst MSKint32t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putarowlist64 */\nMSKrescodee (MSKAPI MSK_putarowlist64) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tconst MSKint64t * ptrb,\n\tconst MSKint64t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putarowslice */\nMSKrescodee (MSKAPI MSK_putarowslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKint32t * ptrb,\n\tconst MSKint32t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putarowslice64 */\nMSKrescodee (MSKAPI MSK_putarowslice64) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKint64t * ptrb,\n\tconst MSKint64t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putatruncatetol */\nMSKrescodee (MSKAPI MSK_putatruncatetol) (\n\tMSKtask_t task,\n\tMSKrealt tolzero);\n\n/* MSK_putbarablocktriplet */\nMSKrescodee (MSKAPI MSK_putbarablocktriplet) (\n\tMSKtask_t task,\n\tMSKint64t num,\n\tconst MSKint32t * subi,\n\tconst MSKint32t * subj,\n\tconst MSKint32t * subk,\n\tconst MSKint32t * subl,\n\tconst MSKrealt * valijkl);\n\n/* MSK_putbaraij */\nMSKrescodee (MSKAPI MSK_putbaraij) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t j,\n\tMSKint64t num,\n\tconst MSKint64t * sub,\n\tconst MSKrealt * weights);\n\n/* MSK_putbaraijlist */\nMSKrescodee (MSKAPI MSK_putbaraijlist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subi,\n\tconst MSKint32t * subj,\n\tconst MSKint64t * alphaptrb,\n\tconst MSKint64t * alphaptre,\n\tconst MSKint64t * matidx,\n\tconst MSKrealt * weights);\n\n/* MSK_putbararowlist */\nMSKrescodee (MSKAPI MSK_putbararowlist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subi,\n\tconst MSKint64t * ptrb,\n\tconst MSKint64t * ptre,\n\tconst MSKint32t * subj,\n\tconst MSKint64t * nummat,\n\tconst MSKint64t * matidx,\n\tconst MSKrealt * weights);\n\n/* MSK_putbarcblocktriplet */\nMSKrescodee (MSKAPI MSK_putbarcblocktriplet) (\n\tMSKtask_t task,\n\tMSKint64t num,\n\tconst MSKint32t * subj,\n\tconst MSKint32t * subk,\n\tconst MSKint32t * subl,\n\tconst MSKrealt * valjkl);\n\n/* MSK_putbarcj */\nMSKrescodee (MSKAPI MSK_putbarcj) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKint64t num,\n\tconst MSKint64t * sub,\n\tconst MSKrealt * weights);\n\n/* MSK_putbarsj */\nMSKrescodee (MSKAPI MSK_putbarsj) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t j,\n\tconst MSKrealt * barsj);\n\n/* MSK_putbarvarname */\nMSKrescodee (MSKAPI MSK_putbarvarname) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tconst char * name);\n\n/* MSK_putbarxj */\nMSKrescodee (MSKAPI MSK_putbarxj) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t j,\n\tconst MSKrealt * barxj);\n\n/* MSK_putcallbackfunc */\nMSKrescodee (MSKAPI MSK_putcallbackfunc) (\n\tMSKtask_t task,\n\tMSKcallbackfunc func,\n\tMSKuserhandle_t handle);\n\n/* MSK_putcfix */\nMSKrescodee (MSKAPI MSK_putcfix) (\n\tMSKtask_t task,\n\tMSKrealt cfix);\n\n/* MSK_putcj */\nMSKrescodee (MSKAPI MSK_putcj) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKrealt cj);\n\n/* MSK_putclist */\nMSKrescodee (MSKAPI MSK_putclist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subj,\n\tconst MSKrealt * val);\n\n/* MSK_putconbound */\nMSKrescodee (MSKAPI MSK_putconbound) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKboundkeye bkc,\n\tMSKrealt blc,\n\tMSKrealt buc);\n\n/* MSK_putconboundlist */\nMSKrescodee (MSKAPI MSK_putconboundlist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tconst MSKboundkeye * bkc,\n\tconst MSKrealt * blc,\n\tconst MSKrealt * buc);\n\n/* MSK_putconboundlistconst */\nMSKrescodee (MSKAPI MSK_putconboundlistconst) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKboundkeye bkc,\n\tMSKrealt blc,\n\tMSKrealt buc);\n\n/* MSK_putconboundslice */\nMSKrescodee (MSKAPI MSK_putconboundslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKboundkeye * bkc,\n\tconst MSKrealt * blc,\n\tconst MSKrealt * buc);\n\n/* MSK_putconboundsliceconst */\nMSKrescodee (MSKAPI MSK_putconboundsliceconst) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKboundkeye bkc,\n\tMSKrealt blc,\n\tMSKrealt buc);\n\n/* MSK_putcone */\nMSKrescodee (MSKAPI MSK_putcone) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKconetypee ct,\n\tMSKrealt conepar,\n\tMSKint32t nummem,\n\tconst MSKint32t * submem);\n\n/* MSK_putconename */\nMSKrescodee (MSKAPI MSK_putconename) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tconst char * name);\n\n/* MSK_putconname */\nMSKrescodee (MSKAPI MSK_putconname) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tconst char * name);\n\n/* MSK_putconsolutioni */\nMSKrescodee (MSKAPI MSK_putconsolutioni) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKsoltypee whichsol,\n\tMSKstakeye sk,\n\tMSKrealt x,\n\tMSKrealt sl,\n\tMSKrealt su);\n\n/* MSK_putcslice */\nMSKrescodee (MSKAPI MSK_putcslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * slice);\n\n/* MSK_putdjc */\nMSKrescodee (MSKAPI MSK_putdjc) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint64t numdomidx,\n\tconst MSKint64t * domidxlist,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidxlist,\n\tconst MSKrealt * b,\n\tMSKint64t numterms,\n\tconst MSKint64t * termsizelist);\n\n/* MSK_putdjcname */\nMSKrescodee (MSKAPI MSK_putdjcname) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tconst char * name);\n\n/* MSK_putdjcslice */\nMSKrescodee (MSKAPI MSK_putdjcslice) (\n\tMSKtask_t task,\n\tMSKint64t idxfirst,\n\tMSKint64t idxlast,\n\tMSKint64t numdomidx,\n\tconst MSKint64t * domidxlist,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidxlist,\n\tconst MSKrealt * b,\n\tMSKint64t numterms,\n\tconst MSKint64t * termsizelist,\n\tconst MSKint64t * termsindjc);\n\n/* MSK_putdomainname */\nMSKrescodee (MSKAPI MSK_putdomainname) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tconst char * name);\n\n/* MSK_putdouparam */\nMSKrescodee (MSKAPI MSK_putdouparam) (\n\tMSKtask_t task,\n\tMSKdparame param,\n\tMSKrealt parvalue);\n\n/* MSK_putintparam */\nMSKrescodee (MSKAPI MSK_putintparam) (\n\tMSKtask_t task,\n\tMSKiparame param,\n\tMSKint32t parvalue);\n\n/* MSK_putlintparam */\nMSKrescodee (MSKAPI MSK_putlintparam) (\n\tMSKtask_t task,\n\tMSKiparame param,\n\tMSKint64t parvalue);\n\n/* MSK_putmaxnumacc */\nMSKrescodee (MSKAPI MSK_putmaxnumacc) (\n\tMSKtask_t task,\n\tMSKint64t maxnumacc);\n\n/* MSK_putmaxnumafe */\nMSKrescodee (MSKAPI MSK_putmaxnumafe) (\n\tMSKtask_t task,\n\tMSKint64t maxnumafe);\n\n/* MSK_putmaxnumanz */\nMSKrescodee (MSKAPI MSK_putmaxnumanz) (\n\tMSKtask_t task,\n\tMSKint64t maxnumanz);\n\n/* MSK_putmaxnumbarvar */\nMSKrescodee (MSKAPI MSK_putmaxnumbarvar) (\n\tMSKtask_t task,\n\tMSKint32t maxnumbarvar);\n\n/* MSK_putmaxnumcon */\nMSKrescodee (MSKAPI MSK_putmaxnumcon) (\n\tMSKtask_t task,\n\tMSKint32t maxnumcon);\n\n/* MSK_putmaxnumcone */\nMSKrescodee (MSKAPI MSK_putmaxnumcone) (\n\tMSKtask_t task,\n\tMSKint32t maxnumcone);\n\n/* MSK_putmaxnumdjc */\nMSKrescodee (MSKAPI MSK_putmaxnumdjc) (\n\tMSKtask_t task,\n\tMSKint64t maxnumdjc);\n\n/* MSK_putmaxnumdomain */\nMSKrescodee (MSKAPI MSK_putmaxnumdomain) (\n\tMSKtask_t task,\n\tMSKint64t maxnumdomain);\n\n/* MSK_putmaxnumqnz */\nMSKrescodee (MSKAPI MSK_putmaxnumqnz) (\n\tMSKtask_t task,\n\tMSKint64t maxnumqnz);\n\n/* MSK_putmaxnumvar */\nMSKrescodee (MSKAPI MSK_putmaxnumvar) (\n\tMSKtask_t task,\n\tMSKint32t maxnumvar);\n\n/* MSK_putnadouparam */\nMSKrescodee (MSKAPI MSK_putnadouparam) (\n\tMSKtask_t task,\n\tconst char * paramname,\n\tMSKrealt parvalue);\n\n/* MSK_putnaintparam */\nMSKrescodee (MSKAPI MSK_putnaintparam) (\n\tMSKtask_t task,\n\tconst char * paramname,\n\tMSKint32t parvalue);\n\n/* MSK_putnastrparam */\nMSKrescodee (MSKAPI MSK_putnastrparam) (\n\tMSKtask_t task,\n\tconst char * paramname,\n\tconst char * parvalue);\n\n/* MSK_putobjname */\nMSKrescodee (MSKAPI MSK_putobjname) (\n\tMSKtask_t task,\n\tconst char * objname);\n\n/* MSK_putobjsense */\nMSKrescodee (MSKAPI MSK_putobjsense) (\n\tMSKtask_t task,\n\tMSKobjsensee sense);\n\n/* MSK_putoptserverhost */\nMSKrescodee (MSKAPI MSK_putoptserverhost) (\n\tMSKtask_t task,\n\tconst char * host);\n\n/* MSK_putparam */\nMSKrescodee (MSKAPI MSK_putparam) (\n\tMSKtask_t task,\n\tconst char * parname,\n\tconst char * parvalue);\n\n/* MSK_putqcon */\nMSKrescodee (MSKAPI MSK_putqcon) (\n\tMSKtask_t task,\n\tMSKint32t numqcnz,\n\tconst MSKint32t * qcsubk,\n\tconst MSKint32t * qcsubi,\n\tconst MSKint32t * qcsubj,\n\tconst MSKrealt * qcval);\n\n/* MSK_putqconk */\nMSKrescodee (MSKAPI MSK_putqconk) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKint32t numqcnz,\n\tconst MSKint32t * qcsubi,\n\tconst MSKint32t * qcsubj,\n\tconst MSKrealt * qcval);\n\n/* MSK_putqobj */\nMSKrescodee (MSKAPI MSK_putqobj) (\n\tMSKtask_t task,\n\tMSKint32t numqonz,\n\tconst MSKint32t * qosubi,\n\tconst MSKint32t * qosubj,\n\tconst MSKrealt * qoval);\n\n/* MSK_putqobjij */\nMSKrescodee (MSKAPI MSK_putqobjij) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t j,\n\tMSKrealt qoij);\n\n/* MSK_putresponsefunc */\nMSKrescodee (MSKAPI MSK_putresponsefunc) (\n\tMSKtask_t task,\n\tMSKresponsefunc responsefunc,\n\tMSKuserhandle_t handle);\n\n/* MSK_putskc */\nMSKrescodee (MSKAPI MSK_putskc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKstakeye * skc);\n\n/* MSK_putskcslice */\nMSKrescodee (MSKAPI MSK_putskcslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKstakeye * skc);\n\n/* MSK_putskx */\nMSKrescodee (MSKAPI MSK_putskx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKstakeye * skx);\n\n/* MSK_putskxslice */\nMSKrescodee (MSKAPI MSK_putskxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKstakeye * skx);\n\n/* MSK_putslc */\nMSKrescodee (MSKAPI MSK_putslc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKrealt * slc);\n\n/* MSK_putslcslice */\nMSKrescodee (MSKAPI MSK_putslcslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * slc);\n\n/* MSK_putslx */\nMSKrescodee (MSKAPI MSK_putslx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKrealt * slx);\n\n/* MSK_putslxslice */\nMSKrescodee (MSKAPI MSK_putslxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * slx);\n\n/* MSK_putsnx */\nMSKrescodee (MSKAPI MSK_putsnx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKrealt * sux);\n\n/* MSK_putsnxslice */\nMSKrescodee (MSKAPI MSK_putsnxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * snx);\n\n/* MSK_putsolution */\nMSKrescodee (MSKAPI MSK_putsolution) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKstakeye * skc,\n\tconst MSKstakeye * skx,\n\tconst MSKstakeye * skn,\n\tconst MSKrealt * xc,\n\tconst MSKrealt * xx,\n\tconst MSKrealt * y,\n\tconst MSKrealt * slc,\n\tconst MSKrealt * suc,\n\tconst MSKrealt * slx,\n\tconst MSKrealt * sux,\n\tconst MSKrealt * snx);\n\n/* MSK_putsolutionnew */\nMSKrescodee (MSKAPI MSK_putsolutionnew) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKstakeye * skc,\n\tconst MSKstakeye * skx,\n\tconst MSKstakeye * skn,\n\tconst MSKrealt * xc,\n\tconst MSKrealt * xx,\n\tconst MSKrealt * y,\n\tconst MSKrealt * slc,\n\tconst MSKrealt * suc,\n\tconst MSKrealt * slx,\n\tconst MSKrealt * sux,\n\tconst MSKrealt * snx,\n\tconst MSKrealt * doty);\n\n/* MSK_putsolutionyi */\nMSKrescodee (MSKAPI MSK_putsolutionyi) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKsoltypee whichsol,\n\tMSKrealt y);\n\n/* MSK_putstrparam */\nMSKrescodee (MSKAPI MSK_putstrparam) (\n\tMSKtask_t task,\n\tMSKsparame param,\n\tconst char * parvalue);\n\n/* MSK_putsuc */\nMSKrescodee (MSKAPI MSK_putsuc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKrealt * suc);\n\n/* MSK_putsucslice */\nMSKrescodee (MSKAPI MSK_putsucslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * suc);\n\n/* MSK_putsux */\nMSKrescodee (MSKAPI MSK_putsux) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKrealt * sux);\n\n/* MSK_putsuxslice */\nMSKrescodee (MSKAPI MSK_putsuxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * sux);\n\n/* MSK_puttaskname */\nMSKrescodee (MSKAPI MSK_puttaskname) (\n\tMSKtask_t task,\n\tconst char * taskname);\n\n/* MSK_putvarbound */\nMSKrescodee (MSKAPI MSK_putvarbound) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKboundkeye bkx,\n\tMSKrealt blx,\n\tMSKrealt bux);\n\n/* MSK_putvarboundlist */\nMSKrescodee (MSKAPI MSK_putvarboundlist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tconst MSKboundkeye * bkx,\n\tconst MSKrealt * blx,\n\tconst MSKrealt * bux);\n\n/* MSK_putvarboundlistconst */\nMSKrescodee (MSKAPI MSK_putvarboundlistconst) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKboundkeye bkx,\n\tMSKrealt blx,\n\tMSKrealt bux);\n\n/* MSK_putvarboundslice */\nMSKrescodee (MSKAPI MSK_putvarboundslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKboundkeye * bkx,\n\tconst MSKrealt * blx,\n\tconst MSKrealt * bux);\n\n/* MSK_putvarboundsliceconst */\nMSKrescodee (MSKAPI MSK_putvarboundsliceconst) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKboundkeye bkx,\n\tMSKrealt blx,\n\tMSKrealt bux);\n\n/* MSK_putvarname */\nMSKrescodee (MSKAPI MSK_putvarname) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tconst char * name);\n\n/* MSK_putvarsolutionj */\nMSKrescodee (MSKAPI MSK_putvarsolutionj) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKsoltypee whichsol,\n\tMSKstakeye sk,\n\tMSKrealt x,\n\tMSKrealt sl,\n\tMSKrealt su,\n\tMSKrealt sn);\n\n/* MSK_putvartype */\nMSKrescodee (MSKAPI MSK_putvartype) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKvariabletypee vartype);\n\n/* MSK_putvartypelist */\nMSKrescodee (MSKAPI MSK_putvartypelist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subj,\n\tconst MSKvariabletypee * vartype);\n\n/* MSK_putxc */\nMSKrescodee (MSKAPI MSK_putxc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * xc);\n\n/* MSK_putxcslice */\nMSKrescodee (MSKAPI MSK_putxcslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * xc);\n\n/* MSK_putxx */\nMSKrescodee (MSKAPI MSK_putxx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKrealt * xx);\n\n/* MSK_putxxslice */\nMSKrescodee (MSKAPI MSK_putxxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * xx);\n\n/* MSK_puty */\nMSKrescodee (MSKAPI MSK_puty) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKrealt * y);\n\n/* MSK_putyslice */\nMSKrescodee (MSKAPI MSK_putyslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * y);\n\n/* MSK_readbsolution */\nMSKrescodee (MSKAPI MSK_readbsolution) (\n\tMSKtask_t task,\n\tconst char * filename,\n\tMSKcompresstypee compress);\n\n/* MSK_readdata */\nMSKrescodee (MSKAPI MSK_readdata) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_readdataautoformat */\nMSKrescodee (MSKAPI MSK_readdataautoformat) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_readdataformat */\nMSKrescodee (MSKAPI MSK_readdataformat) (\n\tMSKtask_t task,\n\tconst char * filename,\n\tMSKdataformate format,\n\tMSKcompresstypee compress);\n\n/* MSK_readdatahandle */\nMSKrescodee (MSKAPI MSK_readdatahandle) (\n\tMSKtask_t task,\n\tMSKhreadfunc hread,\n\tMSKuserhandle_t h,\n\tMSKdataformate format,\n\tMSKcompresstypee compress,\n\tconst char * path);\n\n/* MSK_readjsonsol */\nMSKrescodee (MSKAPI MSK_readjsonsol) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_readjsonstring */\nMSKrescodee (MSKAPI MSK_readjsonstring) (\n\tMSKtask_t task,\n\tconst char * data);\n\n/* MSK_readlpstring */\nMSKrescodee (MSKAPI MSK_readlpstring) (\n\tMSKtask_t task,\n\tconst char * data);\n\n/* MSK_readopfstring */\nMSKrescodee (MSKAPI MSK_readopfstring) (\n\tMSKtask_t task,\n\tconst char * data);\n\n/* MSK_readparamfile */\nMSKrescodee (MSKAPI MSK_readparamfile) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_readptfstring */\nMSKrescodee (MSKAPI MSK_readptfstring) (\n\tMSKtask_t task,\n\tconst char * data);\n\n/* MSK_readsolution */\nMSKrescodee (MSKAPI MSK_readsolution) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst char * filename);\n\n/* MSK_readsolutionfile */\nMSKrescodee (MSKAPI MSK_readsolutionfile) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_readsummary */\nMSKrescodee (MSKAPI MSK_readsummary) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream);\n\n/* MSK_readtask */\nMSKrescodee (MSKAPI MSK_readtask) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_removebarvars */\nMSKrescodee (MSKAPI MSK_removebarvars) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subset);\n\n/* MSK_removecones */\nMSKrescodee (MSKAPI MSK_removecones) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subset);\n\n/* MSK_removecons */\nMSKrescodee (MSKAPI MSK_removecons) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subset);\n\n/* MSK_removevars */\nMSKrescodee (MSKAPI MSK_removevars) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subset);\n\n/* MSK_resetdouparam */\nMSKrescodee (MSKAPI MSK_resetdouparam) (\n\tMSKtask_t task,\n\tMSKdparame param);\n\n/* MSK_resetintparam */\nMSKrescodee (MSKAPI MSK_resetintparam) (\n\tMSKtask_t task,\n\tMSKiparame param);\n\n/* MSK_resetparameters */\nMSKrescodee (MSKAPI MSK_resetparameters) (\n\tMSKtask_t task);\n\n/* MSK_resetstrparam */\nMSKrescodee (MSKAPI MSK_resetstrparam) (\n\tMSKtask_t task,\n\tMSKsparame param);\n\n/* MSK_resizetask */\nMSKrescodee (MSKAPI MSK_resizetask) (\n\tMSKtask_t task,\n\tMSKint32t maxnumcon,\n\tMSKint32t maxnumvar,\n\tMSKint32t maxnumcone,\n\tMSKint64t maxnumanz,\n\tMSKint64t maxnumqnz);\n\n/* MSK_sensitivityreport */\nMSKrescodee (MSKAPI MSK_sensitivityreport) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream);\n\n/* MSK_sktostr */\nMSKrescodee (MSKAPI MSK_sktostr) (\n\tMSKtask_t task,\n\tMSKstakeye sk,\n\tchar * str);\n\n/* MSK_solstatostr */\nMSKrescodee (MSKAPI MSK_solstatostr) (\n\tMSKtask_t task,\n\tMSKsolstae solutionsta,\n\tchar * str);\n\n/* MSK_solutiondef */\nMSKrescodee (MSKAPI MSK_solutiondef) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKbooleant * isdef);\n\n/* MSK_solutionsummary */\nMSKrescodee (MSKAPI MSK_solutionsummary) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream);\n\n/* MSK_solvewithbasis */\nMSKrescodee (MSKAPI MSK_solvewithbasis) (\n\tMSKtask_t task,\n\tMSKbooleant transp,\n\tMSKint32t numnz,\n\tMSKint32t * sub,\n\tMSKrealt * val,\n\tMSKint32t * numnzout);\n\n/* MSK_strtoconetype */\nMSKrescodee (MSKAPI MSK_strtoconetype) (\n\tMSKtask_t task,\n\tconst char * str,\n\tMSKconetypee * conetype);\n\n/* MSK_strtosk */\nMSKrescodee (MSKAPI MSK_strtosk) (\n\tMSKtask_t task,\n\tconst char * str,\n\tMSKstakeye * sk);\n\n/* MSK_toconic */\nMSKrescodee (MSKAPI MSK_toconic) (\n\tMSKtask_t task);\n\n/* MSK_unlinkfuncfromtaskstream */\nMSKrescodee (MSKAPI MSK_unlinkfuncfromtaskstream) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream);\n\n/* MSK_updatesolutioninfo */\nMSKrescodee (MSKAPI MSK_updatesolutioninfo) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol);\n\n/* MSK_whichparam */\nMSKrescodee (MSKAPI MSK_whichparam) (\n\tMSKtask_t task,\n\tconst char * parname,\n\tMSKparametertypee * partype,\n\tMSKint32t * param);\n\n/* MSK_writebsolution */\nMSKrescodee (MSKAPI MSK_writebsolution) (\n\tMSKtask_t task,\n\tconst char * filename,\n\tMSKcompresstypee compress);\n\n/* MSK_writebsolutionhandle */\nMSKrescodee (MSKAPI MSK_writebsolutionhandle) (\n\tMSKtask_t task,\n\tMSKhwritefunc func,\n\tMSKuserhandle_t handle,\n\tMSKcompresstypee compress);\n\n/* MSK_writedata */\nMSKrescodee (MSKAPI MSK_writedata) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_writedatahandle */\nMSKrescodee (MSKAPI MSK_writedatahandle) (\n\tMSKtask_t task,\n\tMSKhwritefunc func,\n\tMSKuserhandle_t handle,\n\tMSKdataformate format,\n\tMSKcompresstypee compress);\n\n/* MSK_writejsonsol */\nMSKrescodee (MSKAPI MSK_writejsonsol) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_writeparamfile */\nMSKrescodee (MSKAPI MSK_writeparamfile) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_writesolution */\nMSKrescodee (MSKAPI MSK_writesolution) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst char * filename);\n\n/* MSK_writesolutionfile */\nMSKrescodee (MSKAPI MSK_writesolutionfile) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_writetask */\nMSKrescodee (MSKAPI MSK_writetask) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_axpy */\nMSKrescodee (MSKAPI MSK_axpy) (\n\tMSKenv_t env,\n\tMSKint32t n,\n\tMSKrealt alpha,\n\tconst MSKrealt * x,\n\tMSKrealt * y);\n\n/* MSK_callbackcodetostr */\nMSKrescodee (MSKAPI MSK_callbackcodetostr) (\n\tMSKcallbackcodee code,\n\tchar * callbackcodestr);\n\n/* MSK_callocdbgenv */\nvoid * (MSKAPI MSK_callocdbgenv) (\n\tMSKenv_t env,\n\tconst size_t number,\n\tconst size_t size,\n\tconst char * file,\n\tconst unsigned line);\n\n/* MSK_callocenv */\nvoid * (MSKAPI MSK_callocenv) (\n\tMSKenv_t env,\n\tconst size_t number,\n\tconst size_t size);\n\n/* MSK_checkinall */\nMSKrescodee (MSKAPI MSK_checkinall) (\n\tMSKenv_t env);\n\n/* MSK_checkinlicense */\nMSKrescodee (MSKAPI MSK_checkinlicense) (\n\tMSKenv_t env,\n\tMSKfeaturee feature);\n\n/* MSK_checkmemenv */\nMSKrescodee (MSKAPI MSK_checkmemenv) (\n\tMSKenv_t env,\n\tconst char * file,\n\tMSKint32t line);\n\n/* MSK_checkoutlicense */\nMSKrescodee (MSKAPI MSK_checkoutlicense) (\n\tMSKenv_t env,\n\tMSKfeaturee feature);\n\n/* MSK_checkversion */\nMSKrescodee (MSKAPI MSK_checkversion) (\n\tMSKenv_t env,\n\tMSKint32t major,\n\tMSKint32t minor,\n\tMSKint32t revision);\n\n/* MSK_computesparsecholesky */\nMSKrescodee (MSKAPI MSK_computesparsecholesky) (\n\tMSKenv_t env,\n\tMSKint32t numthreads,\n\tMSKint32t ordermethod,\n\tMSKrealt tolsingular,\n\tMSKint32t n,\n\tconst MSKint32t * anzc,\n\tconst MSKint64t * aptrc,\n\tconst MSKint32t * asubc,\n\tconst MSKrealt * avalc,\n\tMSKint32t ** perm,\n\tMSKrealt ** diag,\n\tMSKint32t ** lnzc,\n\tMSKint64t ** lptrc,\n\tMSKint64t * lensubnval,\n\tMSKint32t ** lsubc,\n\tMSKrealt ** lvalc);\n\n/* MSK_deleteenv */\nMSKrescodee (MSKAPI MSK_deleteenv) (\n\tMSKenv_t * env);\n\n/* MSK_dinfitemtostr */\nMSKrescodee (MSKAPI MSK_dinfitemtostr) (\n\tMSKdinfiteme item,\n\tchar * str);\n\n/* MSK_dot */\nMSKrescodee (MSKAPI MSK_dot) (\n\tMSKenv_t env,\n\tMSKint32t n,\n\tconst MSKrealt * x,\n\tconst MSKrealt * y,\n\tMSKrealt * xty);\n\n/* MSK_echoenv */\nMSKrescodee (MSKAPIVA MSK_echoenv) (\n\tMSKenv_t env,\n\tMSKstreamtypee whichstream,\n\tconst char * format,\n\t...);\n\n/* MSK_echointro */\nMSKrescodee (MSKAPI MSK_echointro) (\n\tMSKenv_t env,\n\tMSKint32t longver);\n\n/* MSK_expirylicenses */\nMSKrescodee (MSKAPI MSK_expirylicenses) (\n\tMSKenv_t env,\n\tMSKint64t * expiry);\n\n/* MSK_freedbgenv */\nvoid (MSKAPI MSK_freedbgenv) (\n\tMSKenv_t env,\n\tvoid * buffer,\n\tconst char * file,\n\tconst unsigned line);\n\n/* MSK_freeenv */\nvoid (MSKAPI MSK_freeenv) (\n\tMSKenv_t env,\n\tvoid * buffer);\n\n/* MSK_gemm */\nMSKrescodee (MSKAPI MSK_gemm) (\n\tMSKenv_t env,\n\tMSKtransposee transa,\n\tMSKtransposee transb,\n\tMSKint32t m,\n\tMSKint32t n,\n\tMSKint32t k,\n\tMSKrealt alpha,\n\tconst MSKrealt * a,\n\tconst MSKrealt * b,\n\tMSKrealt beta,\n\tMSKrealt * c);\n\n/* MSK_gemv */\nMSKrescodee (MSKAPI MSK_gemv) (\n\tMSKenv_t env,\n\tMSKtransposee transa,\n\tMSKint32t m,\n\tMSKint32t n,\n\tMSKrealt alpha,\n\tconst MSKrealt * a,\n\tconst MSKrealt * x,\n\tMSKrealt beta,\n\tMSKrealt * y);\n\n/* MSK_getbuildinfo */\nMSKrescodee (MSKAPI MSK_getbuildinfo) (\n\tchar * buildstate,\n\tchar * builddate);\n\n/* MSK_getcodedesc */\nMSKrescodee (MSKAPI MSK_getcodedesc) (\n\tMSKrescodee code,\n\tchar * symname,\n\tchar * str);\n\n/* MSK_getresponseclass */\nMSKrescodee (MSKAPI MSK_getresponseclass) (\n\tMSKrescodee r,\n\tMSKrescodetypee * rc);\n\n/* MSK_getsymbcondim */\nMSKrescodee (MSKAPI MSK_getsymbcondim) (\n\tMSKenv_t env,\n\tMSKint32t * num,\n\tsize_t * maxlen);\n\n/* MSK_getversion */\nMSKrescodee (MSKAPI MSK_getversion) (\n\tMSKint32t * major,\n\tMSKint32t * minor,\n\tMSKint32t * revision);\n\n/* MSK_globalenvfinalize */\nMSKrescodee (MSKAPI MSK_globalenvfinalize) (\nvoid);\n\n/* MSK_globalenvinitialize */\nMSKrescodee (MSKAPI MSK_globalenvinitialize) (\n\tMSKint64t maxnumalloc,\n\tconst char * dbgfile);\n\n/* MSK_iinfitemtostr */\nMSKrescodee (MSKAPI MSK_iinfitemtostr) (\n\tMSKiinfiteme item,\n\tchar * str);\n\n/* MSK_iparvaltosymnam */\nMSKrescodee (MSKAPI MSK_iparvaltosymnam) (\n\tMSKenv_t env,\n\tMSKiparame whichparam,\n\tMSKint32t whichvalue,\n\tchar * symbolicname);\n\n/* MSK_isinfinity */\nMSKbooleant (MSKAPI MSK_isinfinity) (\n\tMSKrealt value);\n\n/* MSK_licensecleanup */\nMSKrescodee (MSKAPI MSK_licensecleanup) (\nvoid);\n\n/* MSK_liinfitemtostr */\nMSKrescodee (MSKAPI MSK_liinfitemtostr) (\n\tMSKliinfiteme item,\n\tchar * str);\n\n/* MSK_linkfiletoenvstream */\nMSKrescodee (MSKAPI MSK_linkfiletoenvstream) (\n\tMSKenv_t env,\n\tMSKstreamtypee whichstream,\n\tconst char * filename,\n\tMSKint32t append);\n\n/* MSK_linkfunctoenvstream */\nMSKrescodee (MSKAPI MSK_linkfunctoenvstream) (\n\tMSKenv_t env,\n\tMSKstreamtypee whichstream,\n\tMSKuserhandle_t handle,\n\tMSKstreamfunc func);\n\n/* MSK_makeemptytask */\nMSKrescodee (MSKAPI MSK_makeemptytask) (\n\tMSKenv_t env,\n\tMSKtask_t * task);\n\n/* MSK_makeenv */\nMSKrescodee (MSKAPI MSK_makeenv) (\n\tMSKenv_t * env,\n\tconst char * dbgfile);\n\n/* MSK_maketask */\nMSKrescodee (MSKAPI MSK_maketask) (\n\tMSKenv_t env,\n\tMSKint32t maxnumcon,\n\tMSKint32t maxnumvar,\n\tMSKtask_t * task);\n\n/* MSK_optimizebatch */\nMSKrescodee (MSKAPI MSK_optimizebatch) (\n\tMSKenv_t env,\n\tMSKbooleant israce,\n\tMSKrealt maxtime,\n\tMSKint32t numthreads,\n\tMSKint64t numtask,\n\tconst MSKtask_t * task,\n\tMSKrescodee * trmcode,\n\tMSKrescodee * rcode);\n\n/* MSK_potrf */\nMSKrescodee (MSKAPI MSK_potrf) (\n\tMSKenv_t env,\n\tMSKuploe uplo,\n\tMSKint32t n,\n\tMSKrealt * a);\n\n/* MSK_putexitfunc */\nMSKrescodee (MSKAPI MSK_putexitfunc) (\n\tMSKenv_t env,\n\tMSKexitfunc exitfunc,\n\tMSKuserhandle_t handle);\n\n/* MSK_putlicensecode */\nMSKrescodee (MSKAPI MSK_putlicensecode) (\n\tMSKenv_t env,\n\tconst MSKint32t * code);\n\n/* MSK_putlicensedebug */\nMSKrescodee (MSKAPI MSK_putlicensedebug) (\n\tMSKenv_t env,\n\tMSKint32t licdebug);\n\n/* MSK_putlicensepath */\nMSKrescodee (MSKAPI MSK_putlicensepath) (\n\tMSKenv_t env,\n\tconst char * licensepath);\n\n/* MSK_putlicensewait */\nMSKrescodee (MSKAPI MSK_putlicensewait) (\n\tMSKenv_t env,\n\tMSKint32t licwait);\n\n/* MSK_rescodetostr */\nMSKrescodee (MSKAPI MSK_rescodetostr) (\n\tMSKrescodee res,\n\tchar * str);\n\n/* MSK_resetexpirylicenses */\nMSKrescodee (MSKAPI MSK_resetexpirylicenses) (\n\tMSKenv_t env);\n\n/* MSK_sparsetriangularsolvedense */\nMSKrescodee (MSKAPI MSK_sparsetriangularsolvedense) (\n\tMSKenv_t env,\n\tMSKtransposee transposed,\n\tMSKint32t n,\n\tconst MSKint32t * lnzc,\n\tconst MSKint64t * lptrc,\n\tMSKint64t lensubnval,\n\tconst MSKint32t * lsubc,\n\tconst MSKrealt * lvalc,\n\tMSKrealt * b);\n\n/* MSK_syeig */\nMSKrescodee (MSKAPI MSK_syeig) (\n\tMSKenv_t env,\n\tMSKuploe uplo,\n\tMSKint32t n,\n\tconst MSKrealt * a,\n\tMSKrealt * w);\n\n/* MSK_syevd */\nMSKrescodee (MSKAPI MSK_syevd) (\n\tMSKenv_t env,\n\tMSKuploe uplo,\n\tMSKint32t n,\n\tMSKrealt * a,\n\tMSKrealt * w);\n\n/* MSK_symnamtovalue */\nMSKbooleant (MSKAPI MSK_symnamtovalue) (\n\tconst char * name,\n\tchar * value);\n\n/* MSK_syrk */\nMSKrescodee (MSKAPI MSK_syrk) (\n\tMSKenv_t env,\n\tMSKuploe uplo,\n\tMSKtransposee trans,\n\tMSKint32t n,\n\tMSKint32t k,\n\tMSKrealt alpha,\n\tconst MSKrealt * a,\n\tMSKrealt beta,\n\tMSKrealt * c);\n\n/* MSK_unlinkfuncfromenvstream */\nMSKrescodee (MSKAPI MSK_unlinkfuncfromenvstream) (\n\tMSKenv_t env,\n\tMSKstreamtypee whichstream);\n\n/* MSK_utf8towchar */\nMSKrescodee (MSKAPI MSK_utf8towchar) (\n\tconst size_t outputlen,\n\tsize_t * len,\n\tsize_t * conv,\n\tMSKwchart * output,\n\tconst char * input);\n\n/* MSK_wchartoutf8 */\nMSKrescodee (MSKAPI MSK_wchartoutf8) (\n\tconst size_t outputlen,\n\tsize_t * len,\n\tsize_t * conv,\n\tchar * output,\n\tconst MSKwchart * input);\n\n\n\n#ifdef __cplusplus\n}\n#endif\n\n\n#endif\n\n\n"
  },
  {
    "path": "thirdparty/solvers/mosek/mosek_win.h",
    "content": "#ifndef MOSEK_H\n#define MOSEK_H\n\n/******************************************************************************\n ** Module : mosek.h\n **\n ** Generated 2025\n **\n ** Copyright (c) MOSEK ApS, Denmark.\n **\n ** All rights reserved\n **\n ******************************************************************************/\n/*\n The content of this file is subject to copyright. However, it may free\n of charge be redistributed in identical form --- i.e. with no changes of\n the wording --- for any legitimate purpose.\n*/\n\n\n#include <stdlib.h>\n#include <stdio.h>\n#include <stdint.h>\n\n#define MSK_VERSION_MAJOR    11\n#define MSK_VERSION_MINOR    0\n#define MSK_VERSION_REVISION 4\n#define MSK_VERSION_STATE    \"\"\n\n#define MSK_INFINITY 1.0e30\n\n/* BEGIN PLATFORM SPECIFIC DEFINITIONS (win64x86) */\n#define MSKAPI   __stdcall\n#define MSKAPIVA __cdecl\n/* END   PLATFORM SPECIFIC DEFINITIONS (win64x86)*/\n\n\n/* Enums and constants */\n/* namespace mosek { */\nenum MSKbasindtype_enum {\n  MSK_BI_NEVER       = 0,\n  MSK_BI_ALWAYS      = 1,\n  MSK_BI_NO_ERROR    = 2,\n  MSK_BI_IF_FEASIBLE = 3,\n  MSK_BI_RESERVERED  = 4\n};\n#define MSK_BI_BEGIN MSK_BI_NEVER\n#define MSK_BI_END   (1+MSK_BI_RESERVERED)\n\n\nenum MSKboundkey_enum {\n  MSK_BK_LO = 0,\n  MSK_BK_UP = 1,\n  MSK_BK_FX = 2,\n  MSK_BK_FR = 3,\n  MSK_BK_RA = 4\n};\n#define MSK_BK_BEGIN MSK_BK_LO\n#define MSK_BK_END   (1+MSK_BK_RA)\n\n\nenum MSKmark_enum {\n  MSK_MARK_LO = 0,\n  MSK_MARK_UP = 1\n};\n#define MSK_MARK_BEGIN MSK_MARK_LO\n#define MSK_MARK_END   (1+MSK_MARK_UP)\n\n\nenum MSKsimprecision_enum {\n  MSK_SIM_PRECISION_NORMAL   = 0,\n  MSK_SIM_PRECISION_EXTENDED = 1\n};\n#define MSK_SIM_PRECISION_BEGIN MSK_SIM_PRECISION_NORMAL\n#define MSK_SIM_PRECISION_END   (1+MSK_SIM_PRECISION_EXTENDED)\n\n\nenum MSKsimdegen_enum {\n  MSK_SIM_DEGEN_NONE       = 0,\n  MSK_SIM_DEGEN_FREE       = 1,\n  MSK_SIM_DEGEN_AGGRESSIVE = 2,\n  MSK_SIM_DEGEN_MODERATE   = 3,\n  MSK_SIM_DEGEN_MINIMUM    = 4\n};\n#define MSK_SIM_DEGEN_BEGIN MSK_SIM_DEGEN_NONE\n#define MSK_SIM_DEGEN_END   (1+MSK_SIM_DEGEN_MINIMUM)\n\n\nenum MSKtranspose_enum {\n  MSK_TRANSPOSE_NO  = 0,\n  MSK_TRANSPOSE_YES = 1\n};\n#define MSK_TRANSPOSE_BEGIN MSK_TRANSPOSE_NO\n#define MSK_TRANSPOSE_END   (1+MSK_TRANSPOSE_YES)\n\n\nenum MSKuplo_enum {\n  MSK_UPLO_LO = 0,\n  MSK_UPLO_UP = 1\n};\n#define MSK_UPLO_BEGIN MSK_UPLO_LO\n#define MSK_UPLO_END   (1+MSK_UPLO_UP)\n\n\nenum MSKsimreform_enum {\n  MSK_SIM_REFORMULATION_OFF        = 0,\n  MSK_SIM_REFORMULATION_ON         = 1,\n  MSK_SIM_REFORMULATION_FREE       = 2,\n  MSK_SIM_REFORMULATION_AGGRESSIVE = 3\n};\n#define MSK_SIM_REFORMULATION_BEGIN MSK_SIM_REFORMULATION_OFF\n#define MSK_SIM_REFORMULATION_END   (1+MSK_SIM_REFORMULATION_AGGRESSIVE)\n\n\nenum MSKsimdupvec_enum {\n  MSK_SIM_EXPLOIT_DUPVEC_OFF  = 0,\n  MSK_SIM_EXPLOIT_DUPVEC_ON   = 1,\n  MSK_SIM_EXPLOIT_DUPVEC_FREE = 2\n};\n#define MSK_SIM_EXPLOIT_DUPVEC_BEGIN MSK_SIM_EXPLOIT_DUPVEC_OFF\n#define MSK_SIM_EXPLOIT_DUPVEC_END   (1+MSK_SIM_EXPLOIT_DUPVEC_FREE)\n\n\nenum MSKsimhotstart_enum {\n  MSK_SIM_HOTSTART_NONE        = 0,\n  MSK_SIM_HOTSTART_FREE        = 1,\n  MSK_SIM_HOTSTART_STATUS_KEYS = 2\n};\n#define MSK_SIM_HOTSTART_BEGIN MSK_SIM_HOTSTART_NONE\n#define MSK_SIM_HOTSTART_END   (1+MSK_SIM_HOTSTART_STATUS_KEYS)\n\n\nenum MSKintpnthotstart_enum {\n  MSK_INTPNT_HOTSTART_NONE        = 0,\n  MSK_INTPNT_HOTSTART_PRIMAL      = 1,\n  MSK_INTPNT_HOTSTART_DUAL        = 2,\n  MSK_INTPNT_HOTSTART_PRIMAL_DUAL = 3\n};\n#define MSK_INTPNT_HOTSTART_BEGIN MSK_INTPNT_HOTSTART_NONE\n#define MSK_INTPNT_HOTSTART_END   (1+MSK_INTPNT_HOTSTART_PRIMAL_DUAL)\n\n\nenum MSKcallbackcode_enum {\n  MSK_CALLBACK_BEGIN_BI                    = 0,\n  MSK_CALLBACK_BEGIN_CONIC                 = 1,\n  MSK_CALLBACK_BEGIN_DUAL_BI               = 2,\n  MSK_CALLBACK_BEGIN_DUAL_SENSITIVITY      = 3,\n  MSK_CALLBACK_BEGIN_DUAL_SETUP_BI         = 4,\n  MSK_CALLBACK_BEGIN_DUAL_SIMPLEX          = 5,\n  MSK_CALLBACK_BEGIN_DUAL_SIMPLEX_BI       = 6,\n  MSK_CALLBACK_BEGIN_FOLDING               = 7,\n  MSK_CALLBACK_BEGIN_FOLDING_BI            = 8,\n  MSK_CALLBACK_BEGIN_FOLDING_BI_DUAL       = 9,\n  MSK_CALLBACK_BEGIN_FOLDING_BI_INITIALIZE = 10,\n  MSK_CALLBACK_BEGIN_FOLDING_BI_OPTIMIZER  = 11,\n  MSK_CALLBACK_BEGIN_FOLDING_BI_PRIMAL     = 12,\n  MSK_CALLBACK_BEGIN_INFEAS_ANA            = 13,\n  MSK_CALLBACK_BEGIN_INITIALIZE_BI         = 14,\n  MSK_CALLBACK_BEGIN_INTPNT                = 15,\n  MSK_CALLBACK_BEGIN_LICENSE_WAIT          = 16,\n  MSK_CALLBACK_BEGIN_MIO                   = 17,\n  MSK_CALLBACK_BEGIN_OPTIMIZE_BI           = 18,\n  MSK_CALLBACK_BEGIN_OPTIMIZER             = 19,\n  MSK_CALLBACK_BEGIN_PRESOLVE              = 20,\n  MSK_CALLBACK_BEGIN_PRIMAL_BI             = 21,\n  MSK_CALLBACK_BEGIN_PRIMAL_REPAIR         = 22,\n  MSK_CALLBACK_BEGIN_PRIMAL_SENSITIVITY    = 23,\n  MSK_CALLBACK_BEGIN_PRIMAL_SETUP_BI       = 24,\n  MSK_CALLBACK_BEGIN_PRIMAL_SIMPLEX        = 25,\n  MSK_CALLBACK_BEGIN_PRIMAL_SIMPLEX_BI     = 26,\n  MSK_CALLBACK_BEGIN_QCQO_REFORMULATE      = 27,\n  MSK_CALLBACK_BEGIN_READ                  = 28,\n  MSK_CALLBACK_BEGIN_ROOT_CUTGEN           = 29,\n  MSK_CALLBACK_BEGIN_SIMPLEX               = 30,\n  MSK_CALLBACK_BEGIN_SOLVE_ROOT_RELAX      = 31,\n  MSK_CALLBACK_BEGIN_TO_CONIC              = 32,\n  MSK_CALLBACK_BEGIN_WRITE                 = 33,\n  MSK_CALLBACK_CONIC                       = 34,\n  MSK_CALLBACK_DECOMP_MIO                  = 35,\n  MSK_CALLBACK_DUAL_SIMPLEX                = 36,\n  MSK_CALLBACK_END_BI                      = 37,\n  MSK_CALLBACK_END_CONIC                   = 38,\n  MSK_CALLBACK_END_DUAL_BI                 = 39,\n  MSK_CALLBACK_END_DUAL_SENSITIVITY        = 40,\n  MSK_CALLBACK_END_DUAL_SETUP_BI           = 41,\n  MSK_CALLBACK_END_DUAL_SIMPLEX            = 42,\n  MSK_CALLBACK_END_DUAL_SIMPLEX_BI         = 43,\n  MSK_CALLBACK_END_FOLDING                 = 44,\n  MSK_CALLBACK_END_FOLDING_BI              = 45,\n  MSK_CALLBACK_END_FOLDING_BI_DUAL         = 46,\n  MSK_CALLBACK_END_FOLDING_BI_INITIALIZE   = 47,\n  MSK_CALLBACK_END_FOLDING_BI_OPTIMIZER    = 48,\n  MSK_CALLBACK_END_FOLDING_BI_PRIMAL       = 49,\n  MSK_CALLBACK_END_INFEAS_ANA              = 50,\n  MSK_CALLBACK_END_INITIALIZE_BI           = 51,\n  MSK_CALLBACK_END_INTPNT                  = 52,\n  MSK_CALLBACK_END_LICENSE_WAIT            = 53,\n  MSK_CALLBACK_END_MIO                     = 54,\n  MSK_CALLBACK_END_OPTIMIZE_BI             = 55,\n  MSK_CALLBACK_END_OPTIMIZER               = 56,\n  MSK_CALLBACK_END_PRESOLVE                = 57,\n  MSK_CALLBACK_END_PRIMAL_BI               = 58,\n  MSK_CALLBACK_END_PRIMAL_REPAIR           = 59,\n  MSK_CALLBACK_END_PRIMAL_SENSITIVITY      = 60,\n  MSK_CALLBACK_END_PRIMAL_SETUP_BI         = 61,\n  MSK_CALLBACK_END_PRIMAL_SIMPLEX          = 62,\n  MSK_CALLBACK_END_PRIMAL_SIMPLEX_BI       = 63,\n  MSK_CALLBACK_END_QCQO_REFORMULATE        = 64,\n  MSK_CALLBACK_END_READ                    = 65,\n  MSK_CALLBACK_END_ROOT_CUTGEN             = 66,\n  MSK_CALLBACK_END_SIMPLEX                 = 67,\n  MSK_CALLBACK_END_SIMPLEX_BI              = 68,\n  MSK_CALLBACK_END_SOLVE_ROOT_RELAX        = 69,\n  MSK_CALLBACK_END_TO_CONIC                = 70,\n  MSK_CALLBACK_END_WRITE                   = 71,\n  MSK_CALLBACK_FOLDING_BI_DUAL             = 72,\n  MSK_CALLBACK_FOLDING_BI_OPTIMIZER        = 73,\n  MSK_CALLBACK_FOLDING_BI_PRIMAL           = 74,\n  MSK_CALLBACK_HEARTBEAT                   = 75,\n  MSK_CALLBACK_IM_DUAL_SENSIVITY           = 76,\n  MSK_CALLBACK_IM_DUAL_SIMPLEX             = 77,\n  MSK_CALLBACK_IM_LICENSE_WAIT             = 78,\n  MSK_CALLBACK_IM_LU                       = 79,\n  MSK_CALLBACK_IM_MIO                      = 80,\n  MSK_CALLBACK_IM_MIO_DUAL_SIMPLEX         = 81,\n  MSK_CALLBACK_IM_MIO_INTPNT               = 82,\n  MSK_CALLBACK_IM_MIO_PRIMAL_SIMPLEX       = 83,\n  MSK_CALLBACK_IM_ORDER                    = 84,\n  MSK_CALLBACK_IM_PRIMAL_SENSIVITY         = 85,\n  MSK_CALLBACK_IM_PRIMAL_SIMPLEX           = 86,\n  MSK_CALLBACK_IM_READ                     = 87,\n  MSK_CALLBACK_IM_ROOT_CUTGEN              = 88,\n  MSK_CALLBACK_IM_SIMPLEX                  = 89,\n  MSK_CALLBACK_INTPNT                      = 90,\n  MSK_CALLBACK_NEW_INT_MIO                 = 91,\n  MSK_CALLBACK_OPTIMIZE_BI                 = 92,\n  MSK_CALLBACK_PRIMAL_SIMPLEX              = 93,\n  MSK_CALLBACK_QO_REFORMULATE              = 94,\n  MSK_CALLBACK_READ_OPF                    = 95,\n  MSK_CALLBACK_READ_OPF_SECTION            = 96,\n  MSK_CALLBACK_RESTART_MIO                 = 97,\n  MSK_CALLBACK_SOLVING_REMOTE              = 98,\n  MSK_CALLBACK_UPDATE_DUAL_BI              = 99,\n  MSK_CALLBACK_UPDATE_DUAL_SIMPLEX         = 100,\n  MSK_CALLBACK_UPDATE_DUAL_SIMPLEX_BI      = 101,\n  MSK_CALLBACK_UPDATE_PRESOLVE             = 102,\n  MSK_CALLBACK_UPDATE_PRIMAL_BI            = 103,\n  MSK_CALLBACK_UPDATE_PRIMAL_SIMPLEX       = 104,\n  MSK_CALLBACK_UPDATE_PRIMAL_SIMPLEX_BI    = 105,\n  MSK_CALLBACK_UPDATE_SIMPLEX              = 106,\n  MSK_CALLBACK_WRITE_OPF                   = 107\n};\n#define MSK_CALLBACK_BEGIN MSK_CALLBACK_BEGIN_BI\n#define MSK_CALLBACK_END   (1+MSK_CALLBACK_WRITE_OPF)\n\n\nenum MSKcompresstype_enum {\n  MSK_COMPRESS_NONE = 0,\n  MSK_COMPRESS_FREE = 1,\n  MSK_COMPRESS_GZIP = 2,\n  MSK_COMPRESS_ZSTD = 3\n};\n#define MSK_COMPRESS_BEGIN MSK_COMPRESS_NONE\n#define MSK_COMPRESS_END   (1+MSK_COMPRESS_ZSTD)\n\n\nenum MSKconetype_enum {\n  MSK_CT_QUAD  = 0,\n  MSK_CT_RQUAD = 1,\n  MSK_CT_PEXP  = 2,\n  MSK_CT_DEXP  = 3,\n  MSK_CT_PPOW  = 4,\n  MSK_CT_DPOW  = 5,\n  MSK_CT_ZERO  = 6\n};\n#define MSK_CT_BEGIN MSK_CT_QUAD\n#define MSK_CT_END   (1+MSK_CT_ZERO)\n\n\nenum MSKdomaintype_enum {\n  MSK_DOMAIN_R                    = 0,\n  MSK_DOMAIN_RZERO                = 1,\n  MSK_DOMAIN_RPLUS                = 2,\n  MSK_DOMAIN_RMINUS               = 3,\n  MSK_DOMAIN_QUADRATIC_CONE       = 4,\n  MSK_DOMAIN_RQUADRATIC_CONE      = 5,\n  MSK_DOMAIN_PRIMAL_EXP_CONE      = 6,\n  MSK_DOMAIN_DUAL_EXP_CONE        = 7,\n  MSK_DOMAIN_PRIMAL_POWER_CONE    = 8,\n  MSK_DOMAIN_DUAL_POWER_CONE      = 9,\n  MSK_DOMAIN_PRIMAL_GEO_MEAN_CONE = 10,\n  MSK_DOMAIN_DUAL_GEO_MEAN_CONE   = 11,\n  MSK_DOMAIN_SVEC_PSD_CONE        = 12\n};\n#define MSK_DOMAIN_BEGIN MSK_DOMAIN_R\n#define MSK_DOMAIN_END   (1+MSK_DOMAIN_SVEC_PSD_CONE)\n\n\nenum MSKnametype_enum {\n  MSK_NAME_TYPE_GEN = 0,\n  MSK_NAME_TYPE_MPS = 1,\n  MSK_NAME_TYPE_LP  = 2\n};\n#define MSK_NAME_TYPE_BEGIN MSK_NAME_TYPE_GEN\n#define MSK_NAME_TYPE_END   (1+MSK_NAME_TYPE_LP)\n\n\nenum MSKsymmattype_enum {\n  MSK_SYMMAT_TYPE_SPARSE = 0\n};\n#define MSK_SYMMAT_TYPE_BEGIN MSK_SYMMAT_TYPE_SPARSE\n#define MSK_SYMMAT_TYPE_END   (1+MSK_SYMMAT_TYPE_SPARSE)\n\n\nenum MSKdataformat_enum {\n  MSK_DATA_FORMAT_EXTENSION = 0,\n  MSK_DATA_FORMAT_MPS       = 1,\n  MSK_DATA_FORMAT_LP        = 2,\n  MSK_DATA_FORMAT_OP        = 3,\n  MSK_DATA_FORMAT_FREE_MPS  = 4,\n  MSK_DATA_FORMAT_TASK      = 5,\n  MSK_DATA_FORMAT_PTF       = 6,\n  MSK_DATA_FORMAT_CB        = 7,\n  MSK_DATA_FORMAT_JSON_TASK = 8\n};\n#define MSK_DATA_FORMAT_BEGIN MSK_DATA_FORMAT_EXTENSION\n#define MSK_DATA_FORMAT_END   (1+MSK_DATA_FORMAT_JSON_TASK)\n\n\nenum MSKsolformat_enum {\n  MSK_SOL_FORMAT_EXTENSION = 0,\n  MSK_SOL_FORMAT_B         = 1,\n  MSK_SOL_FORMAT_TASK      = 2,\n  MSK_SOL_FORMAT_JSON_TASK = 3\n};\n#define MSK_SOL_FORMAT_BEGIN MSK_SOL_FORMAT_EXTENSION\n#define MSK_SOL_FORMAT_END   (1+MSK_SOL_FORMAT_JSON_TASK)\n\n\nenum MSKdinfitem_enum {\n  MSK_DINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_DENSITY   = 0,\n  MSK_DINF_BI_CLEAN_TIME                                  = 1,\n  MSK_DINF_BI_DUAL_TIME                                   = 2,\n  MSK_DINF_BI_PRIMAL_TIME                                 = 3,\n  MSK_DINF_BI_TIME                                        = 4,\n  MSK_DINF_FOLDING_BI_OPTIMIZE_TIME                       = 5,\n  MSK_DINF_FOLDING_BI_UNFOLD_DUAL_TIME                    = 6,\n  MSK_DINF_FOLDING_BI_UNFOLD_INITIALIZE_TIME              = 7,\n  MSK_DINF_FOLDING_BI_UNFOLD_PRIMAL_TIME                  = 8,\n  MSK_DINF_FOLDING_BI_UNFOLD_TIME                         = 9,\n  MSK_DINF_FOLDING_FACTOR                                 = 10,\n  MSK_DINF_FOLDING_TIME                                   = 11,\n  MSK_DINF_INTPNT_DUAL_FEAS                               = 12,\n  MSK_DINF_INTPNT_DUAL_OBJ                                = 13,\n  MSK_DINF_INTPNT_FACTOR_NUM_FLOPS                        = 14,\n  MSK_DINF_INTPNT_OPT_STATUS                              = 15,\n  MSK_DINF_INTPNT_ORDER_TIME                              = 16,\n  MSK_DINF_INTPNT_PRIMAL_FEAS                             = 17,\n  MSK_DINF_INTPNT_PRIMAL_OBJ                              = 18,\n  MSK_DINF_INTPNT_TIME                                    = 19,\n  MSK_DINF_MIO_CLIQUE_SELECTION_TIME                      = 20,\n  MSK_DINF_MIO_CLIQUE_SEPARATION_TIME                     = 21,\n  MSK_DINF_MIO_CMIR_SELECTION_TIME                        = 22,\n  MSK_DINF_MIO_CMIR_SEPARATION_TIME                       = 23,\n  MSK_DINF_MIO_CONSTRUCT_SOLUTION_OBJ                     = 24,\n  MSK_DINF_MIO_DUAL_BOUND_AFTER_PRESOLVE                  = 25,\n  MSK_DINF_MIO_GMI_SELECTION_TIME                         = 26,\n  MSK_DINF_MIO_GMI_SEPARATION_TIME                        = 27,\n  MSK_DINF_MIO_IMPLIED_BOUND_SELECTION_TIME               = 28,\n  MSK_DINF_MIO_IMPLIED_BOUND_SEPARATION_TIME              = 29,\n  MSK_DINF_MIO_INITIAL_FEASIBLE_SOLUTION_OBJ              = 30,\n  MSK_DINF_MIO_KNAPSACK_COVER_SELECTION_TIME              = 31,\n  MSK_DINF_MIO_KNAPSACK_COVER_SEPARATION_TIME             = 32,\n  MSK_DINF_MIO_LIPRO_SELECTION_TIME                       = 33,\n  MSK_DINF_MIO_LIPRO_SEPARATION_TIME                      = 34,\n  MSK_DINF_MIO_OBJ_ABS_GAP                                = 35,\n  MSK_DINF_MIO_OBJ_BOUND                                  = 36,\n  MSK_DINF_MIO_OBJ_INT                                    = 37,\n  MSK_DINF_MIO_OBJ_REL_GAP                                = 38,\n  MSK_DINF_MIO_PROBING_TIME                               = 39,\n  MSK_DINF_MIO_ROOT_CUT_SELECTION_TIME                    = 40,\n  MSK_DINF_MIO_ROOT_CUT_SEPARATION_TIME                   = 41,\n  MSK_DINF_MIO_ROOT_OPTIMIZER_TIME                        = 42,\n  MSK_DINF_MIO_ROOT_PRESOLVE_TIME                         = 43,\n  MSK_DINF_MIO_ROOT_TIME                                  = 44,\n  MSK_DINF_MIO_SYMMETRY_DETECTION_TIME                    = 45,\n  MSK_DINF_MIO_SYMMETRY_FACTOR                            = 46,\n  MSK_DINF_MIO_TIME                                       = 47,\n  MSK_DINF_MIO_USER_OBJ_CUT                               = 48,\n  MSK_DINF_OPTIMIZER_TICKS                                = 49,\n  MSK_DINF_OPTIMIZER_TIME                                 = 50,\n  MSK_DINF_PRESOLVE_ELI_TIME                              = 51,\n  MSK_DINF_PRESOLVE_LINDEP_TIME                           = 52,\n  MSK_DINF_PRESOLVE_TIME                                  = 53,\n  MSK_DINF_PRESOLVE_TOTAL_PRIMAL_PERTURBATION             = 54,\n  MSK_DINF_PRIMAL_REPAIR_PENALTY_OBJ                      = 55,\n  MSK_DINF_QCQO_REFORMULATE_MAX_PERTURBATION              = 56,\n  MSK_DINF_QCQO_REFORMULATE_TIME                          = 57,\n  MSK_DINF_QCQO_REFORMULATE_WORST_CHOLESKY_COLUMN_SCALING = 58,\n  MSK_DINF_QCQO_REFORMULATE_WORST_CHOLESKY_DIAG_SCALING   = 59,\n  MSK_DINF_READ_DATA_TIME                                 = 60,\n  MSK_DINF_REMOTE_TIME                                    = 61,\n  MSK_DINF_SIM_DUAL_TIME                                  = 62,\n  MSK_DINF_SIM_FEAS                                       = 63,\n  MSK_DINF_SIM_OBJ                                        = 64,\n  MSK_DINF_SIM_PRIMAL_TIME                                = 65,\n  MSK_DINF_SIM_TIME                                       = 66,\n  MSK_DINF_SOL_BAS_DUAL_OBJ                               = 67,\n  MSK_DINF_SOL_BAS_DVIOLCON                               = 68,\n  MSK_DINF_SOL_BAS_DVIOLVAR                               = 69,\n  MSK_DINF_SOL_BAS_NRM_BARX                               = 70,\n  MSK_DINF_SOL_BAS_NRM_SLC                                = 71,\n  MSK_DINF_SOL_BAS_NRM_SLX                                = 72,\n  MSK_DINF_SOL_BAS_NRM_SUC                                = 73,\n  MSK_DINF_SOL_BAS_NRM_SUX                                = 74,\n  MSK_DINF_SOL_BAS_NRM_XC                                 = 75,\n  MSK_DINF_SOL_BAS_NRM_XX                                 = 76,\n  MSK_DINF_SOL_BAS_NRM_Y                                  = 77,\n  MSK_DINF_SOL_BAS_PRIMAL_OBJ                             = 78,\n  MSK_DINF_SOL_BAS_PVIOLCON                               = 79,\n  MSK_DINF_SOL_BAS_PVIOLVAR                               = 80,\n  MSK_DINF_SOL_ITG_NRM_BARX                               = 81,\n  MSK_DINF_SOL_ITG_NRM_XC                                 = 82,\n  MSK_DINF_SOL_ITG_NRM_XX                                 = 83,\n  MSK_DINF_SOL_ITG_PRIMAL_OBJ                             = 84,\n  MSK_DINF_SOL_ITG_PVIOLACC                               = 85,\n  MSK_DINF_SOL_ITG_PVIOLBARVAR                            = 86,\n  MSK_DINF_SOL_ITG_PVIOLCON                               = 87,\n  MSK_DINF_SOL_ITG_PVIOLCONES                             = 88,\n  MSK_DINF_SOL_ITG_PVIOLDJC                               = 89,\n  MSK_DINF_SOL_ITG_PVIOLITG                               = 90,\n  MSK_DINF_SOL_ITG_PVIOLVAR                               = 91,\n  MSK_DINF_SOL_ITR_DUAL_OBJ                               = 92,\n  MSK_DINF_SOL_ITR_DVIOLACC                               = 93,\n  MSK_DINF_SOL_ITR_DVIOLBARVAR                            = 94,\n  MSK_DINF_SOL_ITR_DVIOLCON                               = 95,\n  MSK_DINF_SOL_ITR_DVIOLCONES                             = 96,\n  MSK_DINF_SOL_ITR_DVIOLVAR                               = 97,\n  MSK_DINF_SOL_ITR_NRM_BARS                               = 98,\n  MSK_DINF_SOL_ITR_NRM_BARX                               = 99,\n  MSK_DINF_SOL_ITR_NRM_SLC                                = 100,\n  MSK_DINF_SOL_ITR_NRM_SLX                                = 101,\n  MSK_DINF_SOL_ITR_NRM_SNX                                = 102,\n  MSK_DINF_SOL_ITR_NRM_SUC                                = 103,\n  MSK_DINF_SOL_ITR_NRM_SUX                                = 104,\n  MSK_DINF_SOL_ITR_NRM_XC                                 = 105,\n  MSK_DINF_SOL_ITR_NRM_XX                                 = 106,\n  MSK_DINF_SOL_ITR_NRM_Y                                  = 107,\n  MSK_DINF_SOL_ITR_PRIMAL_OBJ                             = 108,\n  MSK_DINF_SOL_ITR_PVIOLACC                               = 109,\n  MSK_DINF_SOL_ITR_PVIOLBARVAR                            = 110,\n  MSK_DINF_SOL_ITR_PVIOLCON                               = 111,\n  MSK_DINF_SOL_ITR_PVIOLCONES                             = 112,\n  MSK_DINF_SOL_ITR_PVIOLVAR                               = 113,\n  MSK_DINF_TO_CONIC_TIME                                  = 114,\n  MSK_DINF_WRITE_DATA_TIME                                = 115\n};\n#define MSK_DINF_BEGIN MSK_DINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_DENSITY\n#define MSK_DINF_END   (1+MSK_DINF_WRITE_DATA_TIME)\n\n\nenum MSKfeature_enum {\n  MSK_FEATURE_PTS  = 0,\n  MSK_FEATURE_PTON = 1\n};\n#define MSK_FEATURE_BEGIN MSK_FEATURE_PTS\n#define MSK_FEATURE_END   (1+MSK_FEATURE_PTON)\n\n\nenum MSKdparam_enum {\n  MSK_DPAR_ANA_SOL_INFEAS_TOL                      = 0,\n  MSK_DPAR_BASIS_REL_TOL_S                         = 1,\n  MSK_DPAR_BASIS_TOL_S                             = 2,\n  MSK_DPAR_BASIS_TOL_X                             = 3,\n  MSK_DPAR_DATA_SYM_MAT_TOL                        = 4,\n  MSK_DPAR_DATA_SYM_MAT_TOL_HUGE                   = 5,\n  MSK_DPAR_DATA_SYM_MAT_TOL_LARGE                  = 6,\n  MSK_DPAR_DATA_TOL_AIJ_HUGE                       = 7,\n  MSK_DPAR_DATA_TOL_AIJ_LARGE                      = 8,\n  MSK_DPAR_DATA_TOL_BOUND_INF                      = 9,\n  MSK_DPAR_DATA_TOL_BOUND_WRN                      = 10,\n  MSK_DPAR_DATA_TOL_C_HUGE                         = 11,\n  MSK_DPAR_DATA_TOL_CJ_LARGE                       = 12,\n  MSK_DPAR_DATA_TOL_QIJ                            = 13,\n  MSK_DPAR_DATA_TOL_X                              = 14,\n  MSK_DPAR_FOLDING_TOL_EQ                          = 15,\n  MSK_DPAR_INTPNT_CO_TOL_DFEAS                     = 16,\n  MSK_DPAR_INTPNT_CO_TOL_INFEAS                    = 17,\n  MSK_DPAR_INTPNT_CO_TOL_MU_RED                    = 18,\n  MSK_DPAR_INTPNT_CO_TOL_NEAR_REL                  = 19,\n  MSK_DPAR_INTPNT_CO_TOL_PFEAS                     = 20,\n  MSK_DPAR_INTPNT_CO_TOL_REL_GAP                   = 21,\n  MSK_DPAR_INTPNT_QO_TOL_DFEAS                     = 22,\n  MSK_DPAR_INTPNT_QO_TOL_INFEAS                    = 23,\n  MSK_DPAR_INTPNT_QO_TOL_MU_RED                    = 24,\n  MSK_DPAR_INTPNT_QO_TOL_NEAR_REL                  = 25,\n  MSK_DPAR_INTPNT_QO_TOL_PFEAS                     = 26,\n  MSK_DPAR_INTPNT_QO_TOL_REL_GAP                   = 27,\n  MSK_DPAR_INTPNT_TOL_DFEAS                        = 28,\n  MSK_DPAR_INTPNT_TOL_DSAFE                        = 29,\n  MSK_DPAR_INTPNT_TOL_INFEAS                       = 30,\n  MSK_DPAR_INTPNT_TOL_MU_RED                       = 31,\n  MSK_DPAR_INTPNT_TOL_PATH                         = 32,\n  MSK_DPAR_INTPNT_TOL_PFEAS                        = 33,\n  MSK_DPAR_INTPNT_TOL_PSAFE                        = 34,\n  MSK_DPAR_INTPNT_TOL_REL_GAP                      = 35,\n  MSK_DPAR_INTPNT_TOL_REL_STEP                     = 36,\n  MSK_DPAR_INTPNT_TOL_STEP_SIZE                    = 37,\n  MSK_DPAR_LOWER_OBJ_CUT                           = 38,\n  MSK_DPAR_LOWER_OBJ_CUT_FINITE_TRH                = 39,\n  MSK_DPAR_MIO_CLIQUE_TABLE_SIZE_FACTOR            = 40,\n  MSK_DPAR_MIO_DJC_MAX_BIGM                        = 41,\n  MSK_DPAR_MIO_MAX_TIME                            = 42,\n  MSK_DPAR_MIO_REL_GAP_CONST                       = 43,\n  MSK_DPAR_MIO_TOL_ABS_GAP                         = 44,\n  MSK_DPAR_MIO_TOL_ABS_RELAX_INT                   = 45,\n  MSK_DPAR_MIO_TOL_FEAS                            = 46,\n  MSK_DPAR_MIO_TOL_REL_DUAL_BOUND_IMPROVEMENT      = 47,\n  MSK_DPAR_MIO_TOL_REL_GAP                         = 48,\n  MSK_DPAR_OPTIMIZER_MAX_TICKS                     = 49,\n  MSK_DPAR_OPTIMIZER_MAX_TIME                      = 50,\n  MSK_DPAR_PRESOLVE_TOL_ABS_LINDEP                 = 51,\n  MSK_DPAR_PRESOLVE_TOL_PRIMAL_INFEAS_PERTURBATION = 52,\n  MSK_DPAR_PRESOLVE_TOL_REL_LINDEP                 = 53,\n  MSK_DPAR_PRESOLVE_TOL_S                          = 54,\n  MSK_DPAR_PRESOLVE_TOL_X                          = 55,\n  MSK_DPAR_QCQO_REFORMULATE_REL_DROP_TOL           = 56,\n  MSK_DPAR_SEMIDEFINITE_TOL_APPROX                 = 57,\n  MSK_DPAR_SIM_LU_TOL_REL_PIV                      = 58,\n  MSK_DPAR_SIM_PRECISION_SCALING_EXTENDED          = 59,\n  MSK_DPAR_SIM_PRECISION_SCALING_NORMAL            = 60,\n  MSK_DPAR_SIMPLEX_ABS_TOL_PIV                     = 61,\n  MSK_DPAR_UPPER_OBJ_CUT                           = 62,\n  MSK_DPAR_UPPER_OBJ_CUT_FINITE_TRH                = 63\n};\n#define MSK_DPAR_BEGIN MSK_DPAR_ANA_SOL_INFEAS_TOL\n#define MSK_DPAR_END   (1+MSK_DPAR_UPPER_OBJ_CUT_FINITE_TRH)\n\n\nenum MSKliinfitem_enum {\n  MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_COLUMNS = 0,\n  MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_NZ      = 1,\n  MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_ROWS    = 2,\n  MSK_LIINF_BI_CLEAN_ITER                                    = 3,\n  MSK_LIINF_BI_DUAL_ITER                                     = 4,\n  MSK_LIINF_BI_PRIMAL_ITER                                   = 5,\n  MSK_LIINF_FOLDING_BI_DUAL_ITER                             = 6,\n  MSK_LIINF_FOLDING_BI_OPTIMIZER_ITER                        = 7,\n  MSK_LIINF_FOLDING_BI_PRIMAL_ITER                           = 8,\n  MSK_LIINF_INTPNT_FACTOR_NUM_NZ                             = 9,\n  MSK_LIINF_MIO_ANZ                                          = 10,\n  MSK_LIINF_MIO_FINAL_ANZ                                    = 11,\n  MSK_LIINF_MIO_INTPNT_ITER                                  = 12,\n  MSK_LIINF_MIO_NUM_DUAL_ILLPOSED_CER                        = 13,\n  MSK_LIINF_MIO_NUM_PRIM_ILLPOSED_CER                        = 14,\n  MSK_LIINF_MIO_PRESOLVED_ANZ                                = 15,\n  MSK_LIINF_MIO_SIMPLEX_ITER                                 = 16,\n  MSK_LIINF_RD_NUMACC                                        = 17,\n  MSK_LIINF_RD_NUMANZ                                        = 18,\n  MSK_LIINF_RD_NUMDJC                                        = 19,\n  MSK_LIINF_RD_NUMQNZ                                        = 20,\n  MSK_LIINF_SIMPLEX_ITER                                     = 21\n};\n#define MSK_LIINF_BEGIN MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_COLUMNS\n#define MSK_LIINF_END   (1+MSK_LIINF_SIMPLEX_ITER)\n\n\nenum MSKiinfitem_enum {\n  MSK_IINF_ANA_PRO_NUM_CON                       = 0,\n  MSK_IINF_ANA_PRO_NUM_CON_EQ                    = 1,\n  MSK_IINF_ANA_PRO_NUM_CON_FR                    = 2,\n  MSK_IINF_ANA_PRO_NUM_CON_LO                    = 3,\n  MSK_IINF_ANA_PRO_NUM_CON_RA                    = 4,\n  MSK_IINF_ANA_PRO_NUM_CON_UP                    = 5,\n  MSK_IINF_ANA_PRO_NUM_VAR                       = 6,\n  MSK_IINF_ANA_PRO_NUM_VAR_BIN                   = 7,\n  MSK_IINF_ANA_PRO_NUM_VAR_CONT                  = 8,\n  MSK_IINF_ANA_PRO_NUM_VAR_EQ                    = 9,\n  MSK_IINF_ANA_PRO_NUM_VAR_FR                    = 10,\n  MSK_IINF_ANA_PRO_NUM_VAR_INT                   = 11,\n  MSK_IINF_ANA_PRO_NUM_VAR_LO                    = 12,\n  MSK_IINF_ANA_PRO_NUM_VAR_RA                    = 13,\n  MSK_IINF_ANA_PRO_NUM_VAR_UP                    = 14,\n  MSK_IINF_FOLDING_APPLIED                       = 15,\n  MSK_IINF_INTPNT_FACTOR_DIM_DENSE               = 16,\n  MSK_IINF_INTPNT_ITER                           = 17,\n  MSK_IINF_INTPNT_NUM_THREADS                    = 18,\n  MSK_IINF_INTPNT_SOLVE_DUAL                     = 19,\n  MSK_IINF_MIO_ABSGAP_SATISFIED                  = 20,\n  MSK_IINF_MIO_CLIQUE_TABLE_SIZE                 = 21,\n  MSK_IINF_MIO_CONSTRUCT_SOLUTION                = 22,\n  MSK_IINF_MIO_FINAL_NUMBIN                      = 23,\n  MSK_IINF_MIO_FINAL_NUMBINCONEVAR               = 24,\n  MSK_IINF_MIO_FINAL_NUMCON                      = 25,\n  MSK_IINF_MIO_FINAL_NUMCONE                     = 26,\n  MSK_IINF_MIO_FINAL_NUMCONEVAR                  = 27,\n  MSK_IINF_MIO_FINAL_NUMCONT                     = 28,\n  MSK_IINF_MIO_FINAL_NUMCONTCONEVAR              = 29,\n  MSK_IINF_MIO_FINAL_NUMDEXPCONES                = 30,\n  MSK_IINF_MIO_FINAL_NUMDJC                      = 31,\n  MSK_IINF_MIO_FINAL_NUMDPOWCONES                = 32,\n  MSK_IINF_MIO_FINAL_NUMINT                      = 33,\n  MSK_IINF_MIO_FINAL_NUMINTCONEVAR               = 34,\n  MSK_IINF_MIO_FINAL_NUMPEXPCONES                = 35,\n  MSK_IINF_MIO_FINAL_NUMPPOWCONES                = 36,\n  MSK_IINF_MIO_FINAL_NUMQCONES                   = 37,\n  MSK_IINF_MIO_FINAL_NUMRQCONES                  = 38,\n  MSK_IINF_MIO_FINAL_NUMVAR                      = 39,\n  MSK_IINF_MIO_INITIAL_FEASIBLE_SOLUTION         = 40,\n  MSK_IINF_MIO_NODE_DEPTH                        = 41,\n  MSK_IINF_MIO_NUM_ACTIVE_NODES                  = 42,\n  MSK_IINF_MIO_NUM_ACTIVE_ROOT_CUTS              = 43,\n  MSK_IINF_MIO_NUM_BLOCKS_SOLVED_IN_BB           = 44,\n  MSK_IINF_MIO_NUM_BLOCKS_SOLVED_IN_PRESOLVE     = 45,\n  MSK_IINF_MIO_NUM_BRANCH                        = 46,\n  MSK_IINF_MIO_NUM_INT_SOLUTIONS                 = 47,\n  MSK_IINF_MIO_NUM_RELAX                         = 48,\n  MSK_IINF_MIO_NUM_REPEATED_PRESOLVE             = 49,\n  MSK_IINF_MIO_NUM_RESTARTS                      = 50,\n  MSK_IINF_MIO_NUM_ROOT_CUT_ROUNDS               = 51,\n  MSK_IINF_MIO_NUM_SELECTED_CLIQUE_CUTS          = 52,\n  MSK_IINF_MIO_NUM_SELECTED_CMIR_CUTS            = 53,\n  MSK_IINF_MIO_NUM_SELECTED_GOMORY_CUTS          = 54,\n  MSK_IINF_MIO_NUM_SELECTED_IMPLIED_BOUND_CUTS   = 55,\n  MSK_IINF_MIO_NUM_SELECTED_KNAPSACK_COVER_CUTS  = 56,\n  MSK_IINF_MIO_NUM_SELECTED_LIPRO_CUTS           = 57,\n  MSK_IINF_MIO_NUM_SEPARATED_CLIQUE_CUTS         = 58,\n  MSK_IINF_MIO_NUM_SEPARATED_CMIR_CUTS           = 59,\n  MSK_IINF_MIO_NUM_SEPARATED_GOMORY_CUTS         = 60,\n  MSK_IINF_MIO_NUM_SEPARATED_IMPLIED_BOUND_CUTS  = 61,\n  MSK_IINF_MIO_NUM_SEPARATED_KNAPSACK_COVER_CUTS = 62,\n  MSK_IINF_MIO_NUM_SEPARATED_LIPRO_CUTS          = 63,\n  MSK_IINF_MIO_NUM_SOLVED_NODES                  = 64,\n  MSK_IINF_MIO_NUMBIN                            = 65,\n  MSK_IINF_MIO_NUMBINCONEVAR                     = 66,\n  MSK_IINF_MIO_NUMCON                            = 67,\n  MSK_IINF_MIO_NUMCONE                           = 68,\n  MSK_IINF_MIO_NUMCONEVAR                        = 69,\n  MSK_IINF_MIO_NUMCONT                           = 70,\n  MSK_IINF_MIO_NUMCONTCONEVAR                    = 71,\n  MSK_IINF_MIO_NUMDEXPCONES                      = 72,\n  MSK_IINF_MIO_NUMDJC                            = 73,\n  MSK_IINF_MIO_NUMDPOWCONES                      = 74,\n  MSK_IINF_MIO_NUMINT                            = 75,\n  MSK_IINF_MIO_NUMINTCONEVAR                     = 76,\n  MSK_IINF_MIO_NUMPEXPCONES                      = 77,\n  MSK_IINF_MIO_NUMPPOWCONES                      = 78,\n  MSK_IINF_MIO_NUMQCONES                         = 79,\n  MSK_IINF_MIO_NUMRQCONES                        = 80,\n  MSK_IINF_MIO_NUMVAR                            = 81,\n  MSK_IINF_MIO_OBJ_BOUND_DEFINED                 = 82,\n  MSK_IINF_MIO_PRESOLVED_NUMBIN                  = 83,\n  MSK_IINF_MIO_PRESOLVED_NUMBINCONEVAR           = 84,\n  MSK_IINF_MIO_PRESOLVED_NUMCON                  = 85,\n  MSK_IINF_MIO_PRESOLVED_NUMCONE                 = 86,\n  MSK_IINF_MIO_PRESOLVED_NUMCONEVAR              = 87,\n  MSK_IINF_MIO_PRESOLVED_NUMCONT                 = 88,\n  MSK_IINF_MIO_PRESOLVED_NUMCONTCONEVAR          = 89,\n  MSK_IINF_MIO_PRESOLVED_NUMDEXPCONES            = 90,\n  MSK_IINF_MIO_PRESOLVED_NUMDJC                  = 91,\n  MSK_IINF_MIO_PRESOLVED_NUMDPOWCONES            = 92,\n  MSK_IINF_MIO_PRESOLVED_NUMINT                  = 93,\n  MSK_IINF_MIO_PRESOLVED_NUMINTCONEVAR           = 94,\n  MSK_IINF_MIO_PRESOLVED_NUMPEXPCONES            = 95,\n  MSK_IINF_MIO_PRESOLVED_NUMPPOWCONES            = 96,\n  MSK_IINF_MIO_PRESOLVED_NUMQCONES               = 97,\n  MSK_IINF_MIO_PRESOLVED_NUMRQCONES              = 98,\n  MSK_IINF_MIO_PRESOLVED_NUMVAR                  = 99,\n  MSK_IINF_MIO_RELGAP_SATISFIED                  = 100,\n  MSK_IINF_MIO_TOTAL_NUM_SELECTED_CUTS           = 101,\n  MSK_IINF_MIO_TOTAL_NUM_SEPARATED_CUTS          = 102,\n  MSK_IINF_MIO_USER_OBJ_CUT                      = 103,\n  MSK_IINF_OPT_NUMCON                            = 104,\n  MSK_IINF_OPT_NUMVAR                            = 105,\n  MSK_IINF_OPTIMIZE_RESPONSE                     = 106,\n  MSK_IINF_PRESOLVE_NUM_PRIMAL_PERTURBATIONS     = 107,\n  MSK_IINF_PURIFY_DUAL_SUCCESS                   = 108,\n  MSK_IINF_PURIFY_PRIMAL_SUCCESS                 = 109,\n  MSK_IINF_RD_NUMBARVAR                          = 110,\n  MSK_IINF_RD_NUMCON                             = 111,\n  MSK_IINF_RD_NUMCONE                            = 112,\n  MSK_IINF_RD_NUMINTVAR                          = 113,\n  MSK_IINF_RD_NUMQ                               = 114,\n  MSK_IINF_RD_NUMVAR                             = 115,\n  MSK_IINF_RD_PROTYPE                            = 116,\n  MSK_IINF_SIM_DUAL_DEG_ITER                     = 117,\n  MSK_IINF_SIM_DUAL_HOTSTART                     = 118,\n  MSK_IINF_SIM_DUAL_HOTSTART_LU                  = 119,\n  MSK_IINF_SIM_DUAL_INF_ITER                     = 120,\n  MSK_IINF_SIM_DUAL_ITER                         = 121,\n  MSK_IINF_SIM_NUMCON                            = 122,\n  MSK_IINF_SIM_NUMVAR                            = 123,\n  MSK_IINF_SIM_PRIMAL_DEG_ITER                   = 124,\n  MSK_IINF_SIM_PRIMAL_HOTSTART                   = 125,\n  MSK_IINF_SIM_PRIMAL_HOTSTART_LU                = 126,\n  MSK_IINF_SIM_PRIMAL_INF_ITER                   = 127,\n  MSK_IINF_SIM_PRIMAL_ITER                       = 128,\n  MSK_IINF_SIM_SOLVE_DUAL                        = 129,\n  MSK_IINF_SOL_BAS_PROSTA                        = 130,\n  MSK_IINF_SOL_BAS_SOLSTA                        = 131,\n  MSK_IINF_SOL_ITG_PROSTA                        = 132,\n  MSK_IINF_SOL_ITG_SOLSTA                        = 133,\n  MSK_IINF_SOL_ITR_PROSTA                        = 134,\n  MSK_IINF_SOL_ITR_SOLSTA                        = 135,\n  MSK_IINF_STO_NUM_A_REALLOC                     = 136\n};\n#define MSK_IINF_BEGIN MSK_IINF_ANA_PRO_NUM_CON\n#define MSK_IINF_END   (1+MSK_IINF_STO_NUM_A_REALLOC)\n\n\nenum MSKinftype_enum {\n  MSK_INF_DOU_TYPE  = 0,\n  MSK_INF_INT_TYPE  = 1,\n  MSK_INF_LINT_TYPE = 2\n};\n#define MSK_INF_BEGIN MSK_INF_DOU_TYPE\n#define MSK_INF_END   (1+MSK_INF_LINT_TYPE)\n\n\nenum MSKiomode_enum {\n  MSK_IOMODE_READ      = 0,\n  MSK_IOMODE_WRITE     = 1,\n  MSK_IOMODE_READWRITE = 2\n};\n#define MSK_IOMODE_BEGIN MSK_IOMODE_READ\n#define MSK_IOMODE_END   (1+MSK_IOMODE_READWRITE)\n\n\nenum MSKiparam_enum {\n  MSK_IPAR_ANA_SOL_BASIS                      = 0,\n  MSK_IPAR_ANA_SOL_PRINT_VIOLATED             = 1,\n  MSK_IPAR_AUTO_SORT_A_BEFORE_OPT             = 2,\n  MSK_IPAR_AUTO_UPDATE_SOL_INFO               = 3,\n  MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE           = 4,\n  MSK_IPAR_BI_CLEAN_OPTIMIZER                 = 5,\n  MSK_IPAR_BI_IGNORE_MAX_ITER                 = 6,\n  MSK_IPAR_BI_IGNORE_NUM_ERROR                = 7,\n  MSK_IPAR_BI_MAX_ITERATIONS                  = 8,\n  MSK_IPAR_CACHE_LICENSE                      = 9,\n  MSK_IPAR_COMPRESS_STATFILE                  = 10,\n  MSK_IPAR_FOLDING_USE                        = 11,\n  MSK_IPAR_GETDUAL_CONVERT_LMIS               = 12,\n  MSK_IPAR_HEARTBEAT_SIM_FREQ_TICKS           = 13,\n  MSK_IPAR_INFEAS_GENERIC_NAMES               = 14,\n  MSK_IPAR_INFEAS_REPORT_AUTO                 = 15,\n  MSK_IPAR_INFEAS_REPORT_LEVEL                = 16,\n  MSK_IPAR_INTPNT_BASIS                       = 17,\n  MSK_IPAR_INTPNT_DIFF_STEP                   = 18,\n  MSK_IPAR_INTPNT_HOTSTART                    = 19,\n  MSK_IPAR_INTPNT_MAX_ITERATIONS              = 20,\n  MSK_IPAR_INTPNT_MAX_NUM_COR                 = 21,\n  MSK_IPAR_INTPNT_OFF_COL_TRH                 = 22,\n  MSK_IPAR_INTPNT_ORDER_GP_NUM_SEEDS          = 23,\n  MSK_IPAR_INTPNT_ORDER_METHOD                = 24,\n  MSK_IPAR_INTPNT_REGULARIZATION_USE          = 25,\n  MSK_IPAR_INTPNT_SCALING                     = 26,\n  MSK_IPAR_INTPNT_SOLVE_FORM                  = 27,\n  MSK_IPAR_INTPNT_STARTING_POINT              = 28,\n  MSK_IPAR_LICENSE_DEBUG                      = 29,\n  MSK_IPAR_LICENSE_PAUSE_TIME                 = 30,\n  MSK_IPAR_LICENSE_SUPPRESS_EXPIRE_WRNS       = 31,\n  MSK_IPAR_LICENSE_TRH_EXPIRY_WRN             = 32,\n  MSK_IPAR_LICENSE_WAIT                       = 33,\n  MSK_IPAR_LOG                                = 34,\n  MSK_IPAR_LOG_ANA_PRO                        = 35,\n  MSK_IPAR_LOG_BI                             = 36,\n  MSK_IPAR_LOG_BI_FREQ                        = 37,\n  MSK_IPAR_LOG_CUT_SECOND_OPT                 = 38,\n  MSK_IPAR_LOG_EXPAND                         = 39,\n  MSK_IPAR_LOG_FEAS_REPAIR                    = 40,\n  MSK_IPAR_LOG_FILE                           = 41,\n  MSK_IPAR_LOG_INCLUDE_SUMMARY                = 42,\n  MSK_IPAR_LOG_INFEAS_ANA                     = 43,\n  MSK_IPAR_LOG_INTPNT                         = 44,\n  MSK_IPAR_LOG_LOCAL_INFO                     = 45,\n  MSK_IPAR_LOG_MIO                            = 46,\n  MSK_IPAR_LOG_MIO_FREQ                       = 47,\n  MSK_IPAR_LOG_ORDER                          = 48,\n  MSK_IPAR_LOG_PRESOLVE                       = 49,\n  MSK_IPAR_LOG_SENSITIVITY                    = 50,\n  MSK_IPAR_LOG_SENSITIVITY_OPT                = 51,\n  MSK_IPAR_LOG_SIM                            = 52,\n  MSK_IPAR_LOG_SIM_FREQ                       = 53,\n  MSK_IPAR_LOG_SIM_FREQ_GIGA_TICKS            = 54,\n  MSK_IPAR_LOG_STORAGE                        = 55,\n  MSK_IPAR_MAX_NUM_WARNINGS                   = 56,\n  MSK_IPAR_MIO_BRANCH_DIR                     = 57,\n  MSK_IPAR_MIO_CONFLICT_ANALYSIS_LEVEL        = 58,\n  MSK_IPAR_MIO_CONIC_OUTER_APPROXIMATION      = 59,\n  MSK_IPAR_MIO_CONSTRUCT_SOL                  = 60,\n  MSK_IPAR_MIO_CROSSOVER_MAX_NODES            = 61,\n  MSK_IPAR_MIO_CUT_CLIQUE                     = 62,\n  MSK_IPAR_MIO_CUT_CMIR                       = 63,\n  MSK_IPAR_MIO_CUT_GMI                        = 64,\n  MSK_IPAR_MIO_CUT_IMPLIED_BOUND              = 65,\n  MSK_IPAR_MIO_CUT_KNAPSACK_COVER             = 66,\n  MSK_IPAR_MIO_CUT_LIPRO                      = 67,\n  MSK_IPAR_MIO_CUT_SELECTION_LEVEL            = 68,\n  MSK_IPAR_MIO_DATA_PERMUTATION_METHOD        = 69,\n  MSK_IPAR_MIO_DUAL_RAY_ANALYSIS_LEVEL        = 70,\n  MSK_IPAR_MIO_FEASPUMP_LEVEL                 = 71,\n  MSK_IPAR_MIO_HEURISTIC_LEVEL                = 72,\n  MSK_IPAR_MIO_INDEPENDENT_BLOCK_LEVEL        = 73,\n  MSK_IPAR_MIO_MAX_NUM_BRANCHES               = 74,\n  MSK_IPAR_MIO_MAX_NUM_RELAXS                 = 75,\n  MSK_IPAR_MIO_MAX_NUM_RESTARTS               = 76,\n  MSK_IPAR_MIO_MAX_NUM_ROOT_CUT_ROUNDS        = 77,\n  MSK_IPAR_MIO_MAX_NUM_SOLUTIONS              = 78,\n  MSK_IPAR_MIO_MEMORY_EMPHASIS_LEVEL          = 79,\n  MSK_IPAR_MIO_MIN_REL                        = 80,\n  MSK_IPAR_MIO_MODE                           = 81,\n  MSK_IPAR_MIO_NODE_OPTIMIZER                 = 82,\n  MSK_IPAR_MIO_NODE_SELECTION                 = 83,\n  MSK_IPAR_MIO_NUMERICAL_EMPHASIS_LEVEL       = 84,\n  MSK_IPAR_MIO_OPT_FACE_MAX_NODES             = 85,\n  MSK_IPAR_MIO_PERSPECTIVE_REFORMULATE        = 86,\n  MSK_IPAR_MIO_PRESOLVE_AGGREGATOR_USE        = 87,\n  MSK_IPAR_MIO_PROBING_LEVEL                  = 88,\n  MSK_IPAR_MIO_PROPAGATE_OBJECTIVE_CONSTRAINT = 89,\n  MSK_IPAR_MIO_QCQO_REFORMULATION_METHOD      = 90,\n  MSK_IPAR_MIO_RENS_MAX_NODES                 = 91,\n  MSK_IPAR_MIO_RINS_MAX_NODES                 = 92,\n  MSK_IPAR_MIO_ROOT_OPTIMIZER                 = 93,\n  MSK_IPAR_MIO_SEED                           = 94,\n  MSK_IPAR_MIO_SYMMETRY_LEVEL                 = 95,\n  MSK_IPAR_MIO_VAR_SELECTION                  = 96,\n  MSK_IPAR_MIO_VB_DETECTION_LEVEL             = 97,\n  MSK_IPAR_MT_SPINCOUNT                       = 98,\n  MSK_IPAR_NG                                 = 99,\n  MSK_IPAR_NUM_THREADS                        = 100,\n  MSK_IPAR_OPF_WRITE_HEADER                   = 101,\n  MSK_IPAR_OPF_WRITE_HINTS                    = 102,\n  MSK_IPAR_OPF_WRITE_LINE_LENGTH              = 103,\n  MSK_IPAR_OPF_WRITE_PARAMETERS               = 104,\n  MSK_IPAR_OPF_WRITE_PROBLEM                  = 105,\n  MSK_IPAR_OPF_WRITE_SOL_BAS                  = 106,\n  MSK_IPAR_OPF_WRITE_SOL_ITG                  = 107,\n  MSK_IPAR_OPF_WRITE_SOL_ITR                  = 108,\n  MSK_IPAR_OPF_WRITE_SOLUTIONS                = 109,\n  MSK_IPAR_OPTIMIZER                          = 110,\n  MSK_IPAR_PARAM_READ_CASE_NAME               = 111,\n  MSK_IPAR_PARAM_READ_IGN_ERROR               = 112,\n  MSK_IPAR_PRESOLVE_ELIMINATOR_MAX_FILL       = 113,\n  MSK_IPAR_PRESOLVE_ELIMINATOR_MAX_NUM_TRIES  = 114,\n  MSK_IPAR_PRESOLVE_LINDEP_ABS_WORK_TRH       = 115,\n  MSK_IPAR_PRESOLVE_LINDEP_NEW                = 116,\n  MSK_IPAR_PRESOLVE_LINDEP_REL_WORK_TRH       = 117,\n  MSK_IPAR_PRESOLVE_LINDEP_USE                = 118,\n  MSK_IPAR_PRESOLVE_MAX_NUM_PASS              = 119,\n  MSK_IPAR_PRESOLVE_MAX_NUM_REDUCTIONS        = 120,\n  MSK_IPAR_PRESOLVE_USE                       = 121,\n  MSK_IPAR_PRIMAL_REPAIR_OPTIMIZER            = 122,\n  MSK_IPAR_PTF_WRITE_PARAMETERS               = 123,\n  MSK_IPAR_PTF_WRITE_SINGLE_PSD_TERMS         = 124,\n  MSK_IPAR_PTF_WRITE_SOLUTIONS                = 125,\n  MSK_IPAR_PTF_WRITE_TRANSFORM                = 126,\n  MSK_IPAR_READ_ASYNC                         = 127,\n  MSK_IPAR_READ_DEBUG                         = 128,\n  MSK_IPAR_READ_KEEP_FREE_CON                 = 129,\n  MSK_IPAR_READ_MPS_FORMAT                    = 130,\n  MSK_IPAR_READ_MPS_WIDTH                     = 131,\n  MSK_IPAR_READ_TASK_IGNORE_PARAM             = 132,\n  MSK_IPAR_REMOTE_USE_COMPRESSION             = 133,\n  MSK_IPAR_REMOVE_UNUSED_SOLUTIONS            = 134,\n  MSK_IPAR_SENSITIVITY_ALL                    = 135,\n  MSK_IPAR_SENSITIVITY_TYPE                   = 136,\n  MSK_IPAR_SIM_BASIS_FACTOR_USE               = 137,\n  MSK_IPAR_SIM_DEGEN                          = 138,\n  MSK_IPAR_SIM_DETECT_PWL                     = 139,\n  MSK_IPAR_SIM_DUAL_CRASH                     = 140,\n  MSK_IPAR_SIM_DUAL_PHASEONE_METHOD           = 141,\n  MSK_IPAR_SIM_DUAL_RESTRICT_SELECTION        = 142,\n  MSK_IPAR_SIM_DUAL_SELECTION                 = 143,\n  MSK_IPAR_SIM_EXPLOIT_DUPVEC                 = 144,\n  MSK_IPAR_SIM_HOTSTART                       = 145,\n  MSK_IPAR_SIM_HOTSTART_LU                    = 146,\n  MSK_IPAR_SIM_MAX_ITERATIONS                 = 147,\n  MSK_IPAR_SIM_MAX_NUM_SETBACKS               = 148,\n  MSK_IPAR_SIM_NON_SINGULAR                   = 149,\n  MSK_IPAR_SIM_PRECISION                      = 150,\n  MSK_IPAR_SIM_PRECISION_BOOST                = 151,\n  MSK_IPAR_SIM_PRIMAL_CRASH                   = 152,\n  MSK_IPAR_SIM_PRIMAL_PHASEONE_METHOD         = 153,\n  MSK_IPAR_SIM_PRIMAL_RESTRICT_SELECTION      = 154,\n  MSK_IPAR_SIM_PRIMAL_SELECTION               = 155,\n  MSK_IPAR_SIM_REFACTOR_FREQ                  = 156,\n  MSK_IPAR_SIM_REFORMULATION                  = 157,\n  MSK_IPAR_SIM_SAVE_LU                        = 158,\n  MSK_IPAR_SIM_SCALING                        = 159,\n  MSK_IPAR_SIM_SCALING_METHOD                 = 160,\n  MSK_IPAR_SIM_SEED                           = 161,\n  MSK_IPAR_SIM_SOLVE_FORM                     = 162,\n  MSK_IPAR_SIM_SWITCH_OPTIMIZER               = 163,\n  MSK_IPAR_SOL_FILTER_KEEP_BASIC              = 164,\n  MSK_IPAR_SOL_READ_NAME_WIDTH                = 165,\n  MSK_IPAR_SOL_READ_WIDTH                     = 166,\n  MSK_IPAR_TIMING_LEVEL                       = 167,\n  MSK_IPAR_WRITE_ASYNC                        = 168,\n  MSK_IPAR_WRITE_BAS_CONSTRAINTS              = 169,\n  MSK_IPAR_WRITE_BAS_HEAD                     = 170,\n  MSK_IPAR_WRITE_BAS_VARIABLES                = 171,\n  MSK_IPAR_WRITE_COMPRESSION                  = 172,\n  MSK_IPAR_WRITE_FREE_CON                     = 173,\n  MSK_IPAR_WRITE_GENERIC_NAMES                = 174,\n  MSK_IPAR_WRITE_IGNORE_INCOMPATIBLE_ITEMS    = 175,\n  MSK_IPAR_WRITE_INT_CONSTRAINTS              = 176,\n  MSK_IPAR_WRITE_INT_HEAD                     = 177,\n  MSK_IPAR_WRITE_INT_VARIABLES                = 178,\n  MSK_IPAR_WRITE_JSON_INDENTATION             = 179,\n  MSK_IPAR_WRITE_LP_FULL_OBJ                  = 180,\n  MSK_IPAR_WRITE_LP_LINE_WIDTH                = 181,\n  MSK_IPAR_WRITE_MPS_FORMAT                   = 182,\n  MSK_IPAR_WRITE_MPS_INT                      = 183,\n  MSK_IPAR_WRITE_SOL_BARVARIABLES             = 184,\n  MSK_IPAR_WRITE_SOL_CONSTRAINTS              = 185,\n  MSK_IPAR_WRITE_SOL_HEAD                     = 186,\n  MSK_IPAR_WRITE_SOL_IGNORE_INVALID_NAMES     = 187,\n  MSK_IPAR_WRITE_SOL_VARIABLES                = 188\n};\n#define MSK_IPAR_BEGIN MSK_IPAR_ANA_SOL_BASIS\n#define MSK_IPAR_END   (1+MSK_IPAR_WRITE_SOL_VARIABLES)\n\n\nenum MSKbranchdir_enum {\n  MSK_BRANCH_DIR_FREE       = 0,\n  MSK_BRANCH_DIR_UP         = 1,\n  MSK_BRANCH_DIR_DOWN       = 2,\n  MSK_BRANCH_DIR_NEAR       = 3,\n  MSK_BRANCH_DIR_FAR        = 4,\n  MSK_BRANCH_DIR_ROOT_LP    = 5,\n  MSK_BRANCH_DIR_GUIDED     = 6,\n  MSK_BRANCH_DIR_PSEUDOCOST = 7\n};\n#define MSK_BRANCH_DIR_BEGIN MSK_BRANCH_DIR_FREE\n#define MSK_BRANCH_DIR_END   (1+MSK_BRANCH_DIR_PSEUDOCOST)\n\n\nenum MSKmiqcqoreformmethod_enum {\n  MSK_MIO_QCQO_REFORMULATION_METHOD_FREE             = 0,\n  MSK_MIO_QCQO_REFORMULATION_METHOD_NONE             = 1,\n  MSK_MIO_QCQO_REFORMULATION_METHOD_LINEARIZATION    = 2,\n  MSK_MIO_QCQO_REFORMULATION_METHOD_EIGEN_VAL_METHOD = 3,\n  MSK_MIO_QCQO_REFORMULATION_METHOD_DIAG_SDP         = 4,\n  MSK_MIO_QCQO_REFORMULATION_METHOD_RELAX_SDP        = 5\n};\n#define MSK_MIO_QCQO_REFORMULATION_METHOD_BEGIN MSK_MIO_QCQO_REFORMULATION_METHOD_FREE\n#define MSK_MIO_QCQO_REFORMULATION_METHOD_END   (1+MSK_MIO_QCQO_REFORMULATION_METHOD_RELAX_SDP)\n\n\nenum MSKmiodatapermmethod_enum {\n  MSK_MIO_DATA_PERMUTATION_METHOD_NONE         = 0,\n  MSK_MIO_DATA_PERMUTATION_METHOD_CYCLIC_SHIFT = 1,\n  MSK_MIO_DATA_PERMUTATION_METHOD_RANDOM       = 2\n};\n#define MSK_MIO_DATA_PERMUTATION_METHOD_BEGIN MSK_MIO_DATA_PERMUTATION_METHOD_NONE\n#define MSK_MIO_DATA_PERMUTATION_METHOD_END   (1+MSK_MIO_DATA_PERMUTATION_METHOD_RANDOM)\n\n\nenum MSKmiocontsoltype_enum {\n  MSK_MIO_CONT_SOL_NONE    = 0,\n  MSK_MIO_CONT_SOL_ROOT    = 1,\n  MSK_MIO_CONT_SOL_ITG     = 2,\n  MSK_MIO_CONT_SOL_ITG_REL = 3\n};\n#define MSK_MIO_CONT_SOL_BEGIN MSK_MIO_CONT_SOL_NONE\n#define MSK_MIO_CONT_SOL_END   (1+MSK_MIO_CONT_SOL_ITG_REL)\n\n\nenum MSKmiomode_enum {\n  MSK_MIO_MODE_IGNORED   = 0,\n  MSK_MIO_MODE_SATISFIED = 1\n};\n#define MSK_MIO_MODE_BEGIN MSK_MIO_MODE_IGNORED\n#define MSK_MIO_MODE_END   (1+MSK_MIO_MODE_SATISFIED)\n\n\nenum MSKmionodeseltype_enum {\n  MSK_MIO_NODE_SELECTION_FREE   = 0,\n  MSK_MIO_NODE_SELECTION_FIRST  = 1,\n  MSK_MIO_NODE_SELECTION_BEST   = 2,\n  MSK_MIO_NODE_SELECTION_PSEUDO = 3\n};\n#define MSK_MIO_NODE_SELECTION_BEGIN MSK_MIO_NODE_SELECTION_FREE\n#define MSK_MIO_NODE_SELECTION_END   (1+MSK_MIO_NODE_SELECTION_PSEUDO)\n\n\nenum MSKmiovarseltype_enum {\n  MSK_MIO_VAR_SELECTION_FREE       = 0,\n  MSK_MIO_VAR_SELECTION_PSEUDOCOST = 1,\n  MSK_MIO_VAR_SELECTION_STRONG     = 2\n};\n#define MSK_MIO_VAR_SELECTION_BEGIN MSK_MIO_VAR_SELECTION_FREE\n#define MSK_MIO_VAR_SELECTION_END   (1+MSK_MIO_VAR_SELECTION_STRONG)\n\n\nenum MSKmpsformat_enum {\n  MSK_MPS_FORMAT_STRICT  = 0,\n  MSK_MPS_FORMAT_RELAXED = 1,\n  MSK_MPS_FORMAT_FREE    = 2,\n  MSK_MPS_FORMAT_CPLEX   = 3\n};\n#define MSK_MPS_FORMAT_BEGIN MSK_MPS_FORMAT_STRICT\n#define MSK_MPS_FORMAT_END   (1+MSK_MPS_FORMAT_CPLEX)\n\n\nenum MSKobjsense_enum {\n  MSK_OBJECTIVE_SENSE_MINIMIZE = 0,\n  MSK_OBJECTIVE_SENSE_MAXIMIZE = 1\n};\n#define MSK_OBJECTIVE_SENSE_BEGIN MSK_OBJECTIVE_SENSE_MINIMIZE\n#define MSK_OBJECTIVE_SENSE_END   (1+MSK_OBJECTIVE_SENSE_MAXIMIZE)\n\n\nenum MSKonoffkey_enum {\n  MSK_OFF = 0,\n  MSK_ON  = 1\n};\n#define MSK_BEGIN MSK_OFF\n#define MSK_END   (1+MSK_ON)\n\n\nenum MSKoptimizertype_enum {\n  MSK_OPTIMIZER_CONIC              = 0,\n  MSK_OPTIMIZER_DUAL_SIMPLEX       = 1,\n  MSK_OPTIMIZER_FREE               = 2,\n  MSK_OPTIMIZER_FREE_SIMPLEX       = 3,\n  MSK_OPTIMIZER_INTPNT             = 4,\n  MSK_OPTIMIZER_MIXED_INT          = 5,\n  MSK_OPTIMIZER_NEW_DUAL_SIMPLEX   = 6,\n  MSK_OPTIMIZER_NEW_PRIMAL_SIMPLEX = 7,\n  MSK_OPTIMIZER_PRIMAL_SIMPLEX     = 8\n};\n#define MSK_OPTIMIZER_BEGIN MSK_OPTIMIZER_CONIC\n#define MSK_OPTIMIZER_END   (1+MSK_OPTIMIZER_PRIMAL_SIMPLEX)\n\n\nenum MSKorderingtype_enum {\n  MSK_ORDER_METHOD_FREE           = 0,\n  MSK_ORDER_METHOD_APPMINLOC      = 1,\n  MSK_ORDER_METHOD_EXPERIMENTAL   = 2,\n  MSK_ORDER_METHOD_TRY_GRAPHPAR   = 3,\n  MSK_ORDER_METHOD_FORCE_GRAPHPAR = 4,\n  MSK_ORDER_METHOD_NONE           = 5\n};\n#define MSK_ORDER_METHOD_BEGIN MSK_ORDER_METHOD_FREE\n#define MSK_ORDER_METHOD_END   (1+MSK_ORDER_METHOD_NONE)\n\n\nenum MSKpresolvemode_enum {\n  MSK_PRESOLVE_MODE_OFF  = 0,\n  MSK_PRESOLVE_MODE_ON   = 1,\n  MSK_PRESOLVE_MODE_FREE = 2\n};\n#define MSK_PRESOLVE_MODE_BEGIN MSK_PRESOLVE_MODE_OFF\n#define MSK_PRESOLVE_MODE_END   (1+MSK_PRESOLVE_MODE_FREE)\n\n\nenum MSKfoldingmode_enum {\n  MSK_FOLDING_MODE_OFF               = 0,\n  MSK_FOLDING_MODE_FREE              = 1,\n  MSK_FOLDING_MODE_FREE_UNLESS_BASIC = 2,\n  MSK_FOLDING_MODE_FORCE             = 3\n};\n#define MSK_FOLDING_MODE_BEGIN MSK_FOLDING_MODE_OFF\n#define MSK_FOLDING_MODE_END   (1+MSK_FOLDING_MODE_FORCE)\n\n\nenum MSKparametertype_enum {\n  MSK_PAR_INVALID_TYPE = 0,\n  MSK_PAR_DOU_TYPE     = 1,\n  MSK_PAR_INT_TYPE     = 2,\n  MSK_PAR_STR_TYPE     = 3\n};\n#define MSK_PAR_BEGIN MSK_PAR_INVALID_TYPE\n#define MSK_PAR_END   (1+MSK_PAR_STR_TYPE)\n\n\nenum MSKproblemitem_enum {\n  MSK_PI_VAR  = 0,\n  MSK_PI_CON  = 1,\n  MSK_PI_CONE = 2\n};\n#define MSK_PI_BEGIN MSK_PI_VAR\n#define MSK_PI_END   (1+MSK_PI_CONE)\n\n\nenum MSKproblemtype_enum {\n  MSK_PROBTYPE_LO    = 0,\n  MSK_PROBTYPE_QO    = 1,\n  MSK_PROBTYPE_QCQO  = 2,\n  MSK_PROBTYPE_CONIC = 3,\n  MSK_PROBTYPE_MIXED = 4\n};\n#define MSK_PROBTYPE_BEGIN MSK_PROBTYPE_LO\n#define MSK_PROBTYPE_END   (1+MSK_PROBTYPE_MIXED)\n\n\nenum MSKprosta_enum {\n  MSK_PRO_STA_UNKNOWN                  = 0,\n  MSK_PRO_STA_PRIM_AND_DUAL_FEAS       = 1,\n  MSK_PRO_STA_PRIM_FEAS                = 2,\n  MSK_PRO_STA_DUAL_FEAS                = 3,\n  MSK_PRO_STA_PRIM_INFEAS              = 4,\n  MSK_PRO_STA_DUAL_INFEAS              = 5,\n  MSK_PRO_STA_PRIM_AND_DUAL_INFEAS     = 6,\n  MSK_PRO_STA_ILL_POSED                = 7,\n  MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED = 8\n};\n#define MSK_PRO_STA_BEGIN MSK_PRO_STA_UNKNOWN\n#define MSK_PRO_STA_END   (1+MSK_PRO_STA_PRIM_INFEAS_OR_UNBOUNDED)\n\n\nenum MSKrescode_enum {\n  MSK_RES_OK                                                   = 0,\n  MSK_RES_WRN_OPEN_PARAM_FILE                                  = 50,\n  MSK_RES_WRN_LARGE_BOUND                                      = 51,\n  MSK_RES_WRN_LARGE_LO_BOUND                                   = 52,\n  MSK_RES_WRN_LARGE_UP_BOUND                                   = 53,\n  MSK_RES_WRN_LARGE_CON_FX                                     = 54,\n  MSK_RES_WRN_LARGE_CJ                                         = 57,\n  MSK_RES_WRN_LARGE_AIJ                                        = 62,\n  MSK_RES_WRN_ZERO_AIJ                                         = 63,\n  MSK_RES_WRN_NAME_MAX_LEN                                     = 65,\n  MSK_RES_WRN_SPAR_MAX_LEN                                     = 66,\n  MSK_RES_WRN_MPS_SPLIT_RHS_VECTOR                             = 70,\n  MSK_RES_WRN_MPS_SPLIT_RAN_VECTOR                             = 71,\n  MSK_RES_WRN_MPS_SPLIT_BOU_VECTOR                             = 72,\n  MSK_RES_WRN_LP_OLD_QUAD_FORMAT                               = 80,\n  MSK_RES_WRN_LP_DROP_VARIABLE                                 = 85,\n  MSK_RES_WRN_NZ_IN_UPR_TRI                                    = 200,\n  MSK_RES_WRN_DROPPED_NZ_QOBJ                                  = 201,\n  MSK_RES_WRN_IGNORE_INTEGER                                   = 250,\n  MSK_RES_WRN_NO_GLOBAL_OPTIMIZER                              = 251,\n  MSK_RES_WRN_MIO_INFEASIBLE_FINAL                             = 270,\n  MSK_RES_WRN_SOL_FILTER                                       = 300,\n  MSK_RES_WRN_UNDEF_SOL_FILE_NAME                              = 350,\n  MSK_RES_WRN_SOL_FILE_IGNORED_CON                             = 351,\n  MSK_RES_WRN_SOL_FILE_IGNORED_VAR                             = 352,\n  MSK_RES_WRN_TOO_FEW_BASIS_VARS                               = 400,\n  MSK_RES_WRN_TOO_MANY_BASIS_VARS                              = 405,\n  MSK_RES_WRN_LICENSE_EXPIRE                                   = 500,\n  MSK_RES_WRN_LICENSE_SERVER                                   = 501,\n  MSK_RES_WRN_EMPTY_NAME                                       = 502,\n  MSK_RES_WRN_USING_GENERIC_NAMES                              = 503,\n  MSK_RES_WRN_INVALID_MPS_NAME                                 = 504,\n  MSK_RES_WRN_INVALID_MPS_OBJ_NAME                             = 505,\n  MSK_RES_WRN_LICENSE_FEATURE_EXPIRE                           = 509,\n  MSK_RES_WRN_PARAM_NAME_DOU                                   = 510,\n  MSK_RES_WRN_PARAM_NAME_INT                                   = 511,\n  MSK_RES_WRN_PARAM_NAME_STR                                   = 512,\n  MSK_RES_WRN_PARAM_STR_VALUE                                  = 515,\n  MSK_RES_WRN_PARAM_IGNORED_CMIO                               = 516,\n  MSK_RES_WRN_ZEROS_IN_SPARSE_ROW                              = 705,\n  MSK_RES_WRN_ZEROS_IN_SPARSE_COL                              = 710,\n  MSK_RES_WRN_INCOMPLETE_LINEAR_DEPENDENCY_CHECK               = 800,\n  MSK_RES_WRN_ELIMINATOR_SPACE                                 = 801,\n  MSK_RES_WRN_PRESOLVE_OUTOFSPACE                              = 802,\n  MSK_RES_WRN_PRESOLVE_PRIMAL_PERTURBATIONS                    = 803,\n  MSK_RES_WRN_WRITE_CHANGED_NAMES                              = 830,\n  MSK_RES_WRN_WRITE_DISCARDED_CFIX                             = 831,\n  MSK_RES_WRN_DUPLICATE_CONSTRAINT_NAMES                       = 850,\n  MSK_RES_WRN_DUPLICATE_VARIABLE_NAMES                         = 851,\n  MSK_RES_WRN_DUPLICATE_BARVARIABLE_NAMES                      = 852,\n  MSK_RES_WRN_DUPLICATE_CONE_NAMES                             = 853,\n  MSK_RES_WRN_ANA_LARGE_BOUNDS                                 = 900,\n  MSK_RES_WRN_ANA_C_ZERO                                       = 901,\n  MSK_RES_WRN_ANA_EMPTY_COLS                                   = 902,\n  MSK_RES_WRN_ANA_CLOSE_BOUNDS                                 = 903,\n  MSK_RES_WRN_ANA_ALMOST_INT_BOUNDS                            = 904,\n  MSK_RES_WRN_NO_INFEASIBILITY_REPORT_WHEN_MATRIX_VARIABLES    = 930,\n  MSK_RES_WRN_GETDUAL_IGNORES_INTEGRALITY                      = 940,\n  MSK_RES_WRN_NO_DUALIZER                                      = 950,\n  MSK_RES_WRN_SYM_MAT_LARGE                                    = 960,\n  MSK_RES_WRN_MODIFIED_DOUBLE_PARAMETER                        = 970,\n  MSK_RES_WRN_LARGE_FIJ                                        = 980,\n  MSK_RES_WRN_PTF_UNKNOWN_SECTION                              = 981,\n  MSK_RES_ERR_LICENSE                                          = 1000,\n  MSK_RES_ERR_LICENSE_EXPIRED                                  = 1001,\n  MSK_RES_ERR_LICENSE_VERSION                                  = 1002,\n  MSK_RES_ERR_LICENSE_OLD_SERVER_VERSION                       = 1003,\n  MSK_RES_ERR_SIZE_LICENSE                                     = 1005,\n  MSK_RES_ERR_PROB_LICENSE                                     = 1006,\n  MSK_RES_ERR_FILE_LICENSE                                     = 1007,\n  MSK_RES_ERR_MISSING_LICENSE_FILE                             = 1008,\n  MSK_RES_ERR_SIZE_LICENSE_CON                                 = 1010,\n  MSK_RES_ERR_SIZE_LICENSE_VAR                                 = 1011,\n  MSK_RES_ERR_SIZE_LICENSE_INTVAR                              = 1012,\n  MSK_RES_ERR_OPTIMIZER_LICENSE                                = 1013,\n  MSK_RES_ERR_FLEXLM                                           = 1014,\n  MSK_RES_ERR_LICENSE_SERVER                                   = 1015,\n  MSK_RES_ERR_LICENSE_MAX                                      = 1016,\n  MSK_RES_ERR_LICENSE_MOSEKLM_DAEMON                           = 1017,\n  MSK_RES_ERR_LICENSE_FEATURE                                  = 1018,\n  MSK_RES_ERR_PLATFORM_NOT_LICENSED                            = 1019,\n  MSK_RES_ERR_LICENSE_CANNOT_ALLOCATE                          = 1020,\n  MSK_RES_ERR_LICENSE_CANNOT_CONNECT                           = 1021,\n  MSK_RES_ERR_LICENSE_INVALID_HOSTID                           = 1025,\n  MSK_RES_ERR_LICENSE_SERVER_VERSION                           = 1026,\n  MSK_RES_ERR_LICENSE_NO_SERVER_SUPPORT                        = 1027,\n  MSK_RES_ERR_LICENSE_NO_SERVER_LINE                           = 1028,\n  MSK_RES_ERR_OLDER_DLL                                        = 1035,\n  MSK_RES_ERR_NEWER_DLL                                        = 1036,\n  MSK_RES_ERR_LINK_FILE_DLL                                    = 1040,\n  MSK_RES_ERR_THREAD_MUTEX_INIT                                = 1045,\n  MSK_RES_ERR_THREAD_MUTEX_LOCK                                = 1046,\n  MSK_RES_ERR_THREAD_MUTEX_UNLOCK                              = 1047,\n  MSK_RES_ERR_THREAD_CREATE                                    = 1048,\n  MSK_RES_ERR_THREAD_COND_INIT                                 = 1049,\n  MSK_RES_ERR_UNKNOWN                                          = 1050,\n  MSK_RES_ERR_SPACE                                            = 1051,\n  MSK_RES_ERR_FILE_OPEN                                        = 1052,\n  MSK_RES_ERR_FILE_READ                                        = 1053,\n  MSK_RES_ERR_FILE_WRITE                                       = 1054,\n  MSK_RES_ERR_DATA_FILE_EXT                                    = 1055,\n  MSK_RES_ERR_INVALID_FILE_NAME                                = 1056,\n  MSK_RES_ERR_INVALID_SOL_FILE_NAME                            = 1057,\n  MSK_RES_ERR_END_OF_FILE                                      = 1059,\n  MSK_RES_ERR_NULL_ENV                                         = 1060,\n  MSK_RES_ERR_NULL_TASK                                        = 1061,\n  MSK_RES_ERR_INVALID_STREAM                                   = 1062,\n  MSK_RES_ERR_NO_INIT_ENV                                      = 1063,\n  MSK_RES_ERR_INVALID_TASK                                     = 1064,\n  MSK_RES_ERR_NULL_POINTER                                     = 1065,\n  MSK_RES_ERR_LIVING_TASKS                                     = 1066,\n  MSK_RES_ERR_READ_GZIP                                        = 1067,\n  MSK_RES_ERR_READ_ZSTD                                        = 1068,\n  MSK_RES_ERR_READ_ASYNC                                       = 1069,\n  MSK_RES_ERR_BLANK_NAME                                       = 1070,\n  MSK_RES_ERR_DUP_NAME                                         = 1071,\n  MSK_RES_ERR_FORMAT_STRING                                    = 1072,\n  MSK_RES_ERR_SPARSITY_SPECIFICATION                           = 1073,\n  MSK_RES_ERR_MISMATCHING_DIMENSION                            = 1074,\n  MSK_RES_ERR_INVALID_OBJ_NAME                                 = 1075,\n  MSK_RES_ERR_INVALID_CON_NAME                                 = 1076,\n  MSK_RES_ERR_INVALID_VAR_NAME                                 = 1077,\n  MSK_RES_ERR_INVALID_CONE_NAME                                = 1078,\n  MSK_RES_ERR_INVALID_BARVAR_NAME                              = 1079,\n  MSK_RES_ERR_SPACE_LEAKING                                    = 1080,\n  MSK_RES_ERR_SPACE_NO_INFO                                    = 1081,\n  MSK_RES_ERR_DIMENSION_SPECIFICATION                          = 1082,\n  MSK_RES_ERR_AXIS_NAME_SPECIFICATION                          = 1083,\n  MSK_RES_ERR_READ_PREMATURE_EOF                               = 1089,\n  MSK_RES_ERR_READ_FORMAT                                      = 1090,\n  MSK_RES_ERR_WRITE_LP_INVALID_VAR_NAMES                       = 1091,\n  MSK_RES_ERR_WRITE_LP_DUPLICATE_VAR_NAMES                     = 1092,\n  MSK_RES_ERR_WRITE_LP_INVALID_CON_NAMES                       = 1093,\n  MSK_RES_ERR_WRITE_LP_DUPLICATE_CON_NAMES                     = 1094,\n  MSK_RES_ERR_MPS_FILE                                         = 1100,\n  MSK_RES_ERR_MPS_INV_FIELD                                    = 1101,\n  MSK_RES_ERR_MPS_INV_MARKER                                   = 1102,\n  MSK_RES_ERR_MPS_NULL_CON_NAME                                = 1103,\n  MSK_RES_ERR_MPS_NULL_VAR_NAME                                = 1104,\n  MSK_RES_ERR_MPS_UNDEF_CON_NAME                               = 1105,\n  MSK_RES_ERR_MPS_UNDEF_VAR_NAME                               = 1106,\n  MSK_RES_ERR_MPS_INVALID_CON_KEY                              = 1107,\n  MSK_RES_ERR_MPS_INVALID_BOUND_KEY                            = 1108,\n  MSK_RES_ERR_MPS_INVALID_SEC_NAME                             = 1109,\n  MSK_RES_ERR_MPS_NO_OBJECTIVE                                 = 1110,\n  MSK_RES_ERR_MPS_SPLITTED_VAR                                 = 1111,\n  MSK_RES_ERR_MPS_MUL_CON_NAME                                 = 1112,\n  MSK_RES_ERR_MPS_MUL_QSEC                                     = 1113,\n  MSK_RES_ERR_MPS_MUL_QOBJ                                     = 1114,\n  MSK_RES_ERR_MPS_INV_SEC_ORDER                                = 1115,\n  MSK_RES_ERR_MPS_MUL_CSEC                                     = 1116,\n  MSK_RES_ERR_MPS_CONE_TYPE                                    = 1117,\n  MSK_RES_ERR_MPS_CONE_OVERLAP                                 = 1118,\n  MSK_RES_ERR_MPS_CONE_REPEAT                                  = 1119,\n  MSK_RES_ERR_MPS_NON_SYMMETRIC_Q                              = 1120,\n  MSK_RES_ERR_MPS_DUPLICATE_Q_ELEMENT                          = 1121,\n  MSK_RES_ERR_MPS_INVALID_OBJSENSE                             = 1122,\n  MSK_RES_ERR_MPS_TAB_IN_FIELD2                                = 1125,\n  MSK_RES_ERR_MPS_TAB_IN_FIELD3                                = 1126,\n  MSK_RES_ERR_MPS_TAB_IN_FIELD5                                = 1127,\n  MSK_RES_ERR_MPS_INVALID_OBJ_NAME                             = 1128,\n  MSK_RES_ERR_MPS_INVALID_KEY                                  = 1129,\n  MSK_RES_ERR_MPS_INVALID_INDICATOR_CONSTRAINT                 = 1130,\n  MSK_RES_ERR_MPS_INVALID_INDICATOR_VARIABLE                   = 1131,\n  MSK_RES_ERR_MPS_INVALID_INDICATOR_VALUE                      = 1132,\n  MSK_RES_ERR_MPS_INVALID_INDICATOR_QUADRATIC_CONSTRAINT       = 1133,\n  MSK_RES_ERR_OPF_SYNTAX                                       = 1134,\n  MSK_RES_ERR_OPF_PREMATURE_EOF                                = 1136,\n  MSK_RES_ERR_OPF_MISMATCHED_TAG                               = 1137,\n  MSK_RES_ERR_OPF_DUPLICATE_BOUND                              = 1138,\n  MSK_RES_ERR_OPF_DUPLICATE_CONSTRAINT_NAME                    = 1139,\n  MSK_RES_ERR_OPF_INVALID_CONE_TYPE                            = 1140,\n  MSK_RES_ERR_OPF_INCORRECT_TAG_PARAM                          = 1141,\n  MSK_RES_ERR_OPF_INVALID_TAG                                  = 1142,\n  MSK_RES_ERR_OPF_DUPLICATE_CONE_ENTRY                         = 1143,\n  MSK_RES_ERR_OPF_TOO_LARGE                                    = 1144,\n  MSK_RES_ERR_OPF_DUAL_INTEGER_SOLUTION                        = 1146,\n  MSK_RES_ERR_LP_EMPTY                                         = 1151,\n  MSK_RES_ERR_WRITE_MPS_INVALID_NAME                           = 1153,\n  MSK_RES_ERR_LP_INVALID_VAR_NAME                              = 1154,\n  MSK_RES_ERR_WRITE_OPF_INVALID_VAR_NAME                       = 1156,\n  MSK_RES_ERR_LP_FILE_FORMAT                                   = 1157,\n  MSK_RES_ERR_LP_EXPECTED_NUMBER                               = 1158,\n  MSK_RES_ERR_READ_LP_MISSING_END_TAG                          = 1159,\n  MSK_RES_ERR_LP_INDICATOR_VAR                                 = 1160,\n  MSK_RES_ERR_LP_EXPECTED_OBJECTIVE                            = 1161,\n  MSK_RES_ERR_LP_EXPECTED_CONSTRAINT_RELATION                  = 1162,\n  MSK_RES_ERR_LP_AMBIGUOUS_CONSTRAINT_BOUND                    = 1163,\n  MSK_RES_ERR_LP_DUPLICATE_SECTION                             = 1164,\n  MSK_RES_ERR_READ_LP_DELAYED_ROWS_NOT_SUPPORTED               = 1165,\n  MSK_RES_ERR_WRITING_FILE                                     = 1166,\n  MSK_RES_ERR_WRITE_ASYNC                                      = 1167,\n  MSK_RES_ERR_INVALID_NAME_IN_SOL_FILE                         = 1170,\n  MSK_RES_ERR_JSON_SYNTAX                                      = 1175,\n  MSK_RES_ERR_JSON_STRING                                      = 1176,\n  MSK_RES_ERR_JSON_NUMBER_OVERFLOW                             = 1177,\n  MSK_RES_ERR_JSON_FORMAT                                      = 1178,\n  MSK_RES_ERR_JSON_DATA                                        = 1179,\n  MSK_RES_ERR_JSON_MISSING_DATA                                = 1180,\n  MSK_RES_ERR_PTF_INCOMPATIBILITY                              = 1181,\n  MSK_RES_ERR_PTF_UNDEFINED_ITEM                               = 1182,\n  MSK_RES_ERR_PTF_INCONSISTENCY                                = 1183,\n  MSK_RES_ERR_PTF_FORMAT                                       = 1184,\n  MSK_RES_ERR_ARGUMENT_LENNEQ                                  = 1197,\n  MSK_RES_ERR_ARGUMENT_TYPE                                    = 1198,\n  MSK_RES_ERR_NUM_ARGUMENTS                                    = 1199,\n  MSK_RES_ERR_IN_ARGUMENT                                      = 1200,\n  MSK_RES_ERR_ARGUMENT_DIMENSION                               = 1201,\n  MSK_RES_ERR_SHAPE_IS_TOO_LARGE                               = 1202,\n  MSK_RES_ERR_INDEX_IS_TOO_SMALL                               = 1203,\n  MSK_RES_ERR_INDEX_IS_TOO_LARGE                               = 1204,\n  MSK_RES_ERR_INDEX_IS_NOT_UNIQUE                              = 1205,\n  MSK_RES_ERR_PARAM_NAME                                       = 1206,\n  MSK_RES_ERR_PARAM_NAME_DOU                                   = 1207,\n  MSK_RES_ERR_PARAM_NAME_INT                                   = 1208,\n  MSK_RES_ERR_PARAM_NAME_STR                                   = 1209,\n  MSK_RES_ERR_PARAM_INDEX                                      = 1210,\n  MSK_RES_ERR_PARAM_IS_TOO_LARGE                               = 1215,\n  MSK_RES_ERR_PARAM_IS_TOO_SMALL                               = 1216,\n  MSK_RES_ERR_PARAM_VALUE_STR                                  = 1217,\n  MSK_RES_ERR_PARAM_TYPE                                       = 1218,\n  MSK_RES_ERR_INF_DOU_INDEX                                    = 1219,\n  MSK_RES_ERR_INF_INT_INDEX                                    = 1220,\n  MSK_RES_ERR_INDEX_ARR_IS_TOO_SMALL                           = 1221,\n  MSK_RES_ERR_INDEX_ARR_IS_TOO_LARGE                           = 1222,\n  MSK_RES_ERR_INF_LINT_INDEX                                   = 1225,\n  MSK_RES_ERR_ARG_IS_TOO_SMALL                                 = 1226,\n  MSK_RES_ERR_ARG_IS_TOO_LARGE                                 = 1227,\n  MSK_RES_ERR_INVALID_WHICHSOL                                 = 1228,\n  MSK_RES_ERR_INF_DOU_NAME                                     = 1230,\n  MSK_RES_ERR_INF_INT_NAME                                     = 1231,\n  MSK_RES_ERR_INF_TYPE                                         = 1232,\n  MSK_RES_ERR_INF_LINT_NAME                                    = 1234,\n  MSK_RES_ERR_INDEX                                            = 1235,\n  MSK_RES_ERR_WHICHSOL                                         = 1236,\n  MSK_RES_ERR_SOLITEM                                          = 1237,\n  MSK_RES_ERR_WHICHITEM_NOT_ALLOWED                            = 1238,\n  MSK_RES_ERR_MAXNUMCON                                        = 1240,\n  MSK_RES_ERR_MAXNUMVAR                                        = 1241,\n  MSK_RES_ERR_MAXNUMBARVAR                                     = 1242,\n  MSK_RES_ERR_MAXNUMQNZ                                        = 1243,\n  MSK_RES_ERR_TOO_SMALL_MAX_NUM_NZ                             = 1245,\n  MSK_RES_ERR_INVALID_IDX                                      = 1246,\n  MSK_RES_ERR_INVALID_MAX_NUM                                  = 1247,\n  MSK_RES_ERR_UNALLOWED_WHICHSOL                               = 1248,\n  MSK_RES_ERR_NUMCONLIM                                        = 1250,\n  MSK_RES_ERR_NUMVARLIM                                        = 1251,\n  MSK_RES_ERR_TOO_SMALL_MAXNUMANZ                              = 1252,\n  MSK_RES_ERR_INV_APTRE                                        = 1253,\n  MSK_RES_ERR_MUL_A_ELEMENT                                    = 1254,\n  MSK_RES_ERR_INV_BK                                           = 1255,\n  MSK_RES_ERR_INV_BKC                                          = 1256,\n  MSK_RES_ERR_INV_BKX                                          = 1257,\n  MSK_RES_ERR_INV_VAR_TYPE                                     = 1258,\n  MSK_RES_ERR_SOLVER_PROBTYPE                                  = 1259,\n  MSK_RES_ERR_OBJECTIVE_RANGE                                  = 1260,\n  MSK_RES_ERR_INV_RESCODE                                      = 1261,\n  MSK_RES_ERR_INV_IINF                                         = 1262,\n  MSK_RES_ERR_INV_LIINF                                        = 1263,\n  MSK_RES_ERR_INV_DINF                                         = 1264,\n  MSK_RES_ERR_BASIS                                            = 1266,\n  MSK_RES_ERR_INV_SKC                                          = 1267,\n  MSK_RES_ERR_INV_SKX                                          = 1268,\n  MSK_RES_ERR_INV_SK_STR                                       = 1269,\n  MSK_RES_ERR_INV_SK                                           = 1270,\n  MSK_RES_ERR_INV_CONE_TYPE_STR                                = 1271,\n  MSK_RES_ERR_INV_CONE_TYPE                                    = 1272,\n  MSK_RES_ERR_INV_SKN                                          = 1274,\n  MSK_RES_ERR_INVALID_SURPLUS                                  = 1275,\n  MSK_RES_ERR_INV_NAME_ITEM                                    = 1280,\n  MSK_RES_ERR_PRO_ITEM                                         = 1281,\n  MSK_RES_ERR_INVALID_FORMAT_TYPE                              = 1283,\n  MSK_RES_ERR_FIRSTI                                           = 1285,\n  MSK_RES_ERR_LASTI                                            = 1286,\n  MSK_RES_ERR_FIRSTJ                                           = 1287,\n  MSK_RES_ERR_LASTJ                                            = 1288,\n  MSK_RES_ERR_MAX_LEN_IS_TOO_SMALL                             = 1289,\n  MSK_RES_ERR_NONLINEAR_EQUALITY                               = 1290,\n  MSK_RES_ERR_NONCONVEX                                        = 1291,\n  MSK_RES_ERR_NONLINEAR_RANGED                                 = 1292,\n  MSK_RES_ERR_CON_Q_NOT_PSD                                    = 1293,\n  MSK_RES_ERR_CON_Q_NOT_NSD                                    = 1294,\n  MSK_RES_ERR_OBJ_Q_NOT_PSD                                    = 1295,\n  MSK_RES_ERR_OBJ_Q_NOT_NSD                                    = 1296,\n  MSK_RES_ERR_ARGUMENT_PERM_ARRAY                              = 1299,\n  MSK_RES_ERR_CONE_INDEX                                       = 1300,\n  MSK_RES_ERR_CONE_SIZE                                        = 1301,\n  MSK_RES_ERR_CONE_OVERLAP                                     = 1302,\n  MSK_RES_ERR_CONE_REP_VAR                                     = 1303,\n  MSK_RES_ERR_MAXNUMCONE                                       = 1304,\n  MSK_RES_ERR_CONE_TYPE                                        = 1305,\n  MSK_RES_ERR_CONE_TYPE_STR                                    = 1306,\n  MSK_RES_ERR_CONE_OVERLAP_APPEND                              = 1307,\n  MSK_RES_ERR_REMOVE_CONE_VARIABLE                             = 1310,\n  MSK_RES_ERR_APPENDING_TOO_BIG_CONE                           = 1311,\n  MSK_RES_ERR_CONE_PARAMETER                                   = 1320,\n  MSK_RES_ERR_SOL_FILE_INVALID_NUMBER                          = 1350,\n  MSK_RES_ERR_HUGE_C                                           = 1375,\n  MSK_RES_ERR_HUGE_AIJ                                         = 1380,\n  MSK_RES_ERR_DUPLICATE_AIJ                                    = 1385,\n  MSK_RES_ERR_LOWER_BOUND_IS_A_NAN                             = 1390,\n  MSK_RES_ERR_UPPER_BOUND_IS_A_NAN                             = 1391,\n  MSK_RES_ERR_INFINITE_BOUND                                   = 1400,\n  MSK_RES_ERR_INV_QOBJ_SUBI                                    = 1401,\n  MSK_RES_ERR_INV_QOBJ_SUBJ                                    = 1402,\n  MSK_RES_ERR_INV_QOBJ_VAL                                     = 1403,\n  MSK_RES_ERR_INV_QCON_SUBK                                    = 1404,\n  MSK_RES_ERR_INV_QCON_SUBI                                    = 1405,\n  MSK_RES_ERR_INV_QCON_SUBJ                                    = 1406,\n  MSK_RES_ERR_INV_QCON_VAL                                     = 1407,\n  MSK_RES_ERR_QCON_SUBI_TOO_SMALL                              = 1408,\n  MSK_RES_ERR_QCON_SUBI_TOO_LARGE                              = 1409,\n  MSK_RES_ERR_QOBJ_UPPER_TRIANGLE                              = 1415,\n  MSK_RES_ERR_QCON_UPPER_TRIANGLE                              = 1417,\n  MSK_RES_ERR_FIXED_BOUND_VALUES                               = 1420,\n  MSK_RES_ERR_TOO_SMALL_A_TRUNCATION_VALUE                     = 1421,\n  MSK_RES_ERR_INVALID_OBJECTIVE_SENSE                          = 1445,\n  MSK_RES_ERR_UNDEFINED_OBJECTIVE_SENSE                        = 1446,\n  MSK_RES_ERR_Y_IS_UNDEFINED                                   = 1449,\n  MSK_RES_ERR_NAN_IN_DOUBLE_DATA                               = 1450,\n  MSK_RES_ERR_INF_IN_DOUBLE_DATA                               = 1451,\n  MSK_RES_ERR_NAN_IN_BLC                                       = 1461,\n  MSK_RES_ERR_NAN_IN_BUC                                       = 1462,\n  MSK_RES_ERR_INVALID_CFIX                                     = 1469,\n  MSK_RES_ERR_NAN_IN_C                                         = 1470,\n  MSK_RES_ERR_NAN_IN_BLX                                       = 1471,\n  MSK_RES_ERR_NAN_IN_BUX                                       = 1472,\n  MSK_RES_ERR_INVALID_AIJ                                      = 1473,\n  MSK_RES_ERR_INVALID_CJ                                       = 1474,\n  MSK_RES_ERR_SYM_MAT_INVALID                                  = 1480,\n  MSK_RES_ERR_SYM_MAT_HUGE                                     = 1482,\n  MSK_RES_ERR_INV_PROBLEM                                      = 1500,\n  MSK_RES_ERR_MIXED_CONIC_AND_NL                               = 1501,\n  MSK_RES_ERR_GLOBAL_INV_CONIC_PROBLEM                         = 1503,\n  MSK_RES_ERR_INV_OPTIMIZER                                    = 1550,\n  MSK_RES_ERR_MIO_NO_OPTIMIZER                                 = 1551,\n  MSK_RES_ERR_NO_OPTIMIZER_VAR_TYPE                            = 1552,\n  MSK_RES_ERR_FINAL_SOLUTION                                   = 1560,\n  MSK_RES_ERR_FIRST                                            = 1570,\n  MSK_RES_ERR_LAST                                             = 1571,\n  MSK_RES_ERR_SLICE_SIZE                                       = 1572,\n  MSK_RES_ERR_NEGATIVE_SURPLUS                                 = 1573,\n  MSK_RES_ERR_NEGATIVE_APPEND                                  = 1578,\n  MSK_RES_ERR_POSTSOLVE                                        = 1580,\n  MSK_RES_ERR_OVERFLOW                                         = 1590,\n  MSK_RES_ERR_NO_BASIS_SOL                                     = 1600,\n  MSK_RES_ERR_BASIS_FACTOR                                     = 1610,\n  MSK_RES_ERR_BASIS_SINGULAR                                   = 1615,\n  MSK_RES_ERR_FACTOR                                           = 1650,\n  MSK_RES_ERR_FEASREPAIR_CANNOT_RELAX                          = 1700,\n  MSK_RES_ERR_FEASREPAIR_SOLVING_RELAXED                       = 1701,\n  MSK_RES_ERR_FEASREPAIR_INCONSISTENT_BOUND                    = 1702,\n  MSK_RES_ERR_REPAIR_INVALID_PROBLEM                           = 1710,\n  MSK_RES_ERR_REPAIR_OPTIMIZATION_FAILED                       = 1711,\n  MSK_RES_ERR_NAME_MAX_LEN                                     = 1750,\n  MSK_RES_ERR_NAME_IS_NULL                                     = 1760,\n  MSK_RES_ERR_INVALID_COMPRESSION                              = 1800,\n  MSK_RES_ERR_INVALID_IOMODE                                   = 1801,\n  MSK_RES_ERR_NO_PRIMAL_INFEAS_CER                             = 2000,\n  MSK_RES_ERR_NO_DUAL_INFEAS_CER                               = 2001,\n  MSK_RES_ERR_NO_SOLUTION_IN_CALLBACK                          = 2500,\n  MSK_RES_ERR_INV_MARKI                                        = 2501,\n  MSK_RES_ERR_INV_MARKJ                                        = 2502,\n  MSK_RES_ERR_INV_NUMI                                         = 2503,\n  MSK_RES_ERR_INV_NUMJ                                         = 2504,\n  MSK_RES_ERR_TASK_INCOMPATIBLE                                = 2560,\n  MSK_RES_ERR_TASK_INVALID                                     = 2561,\n  MSK_RES_ERR_TASK_WRITE                                       = 2562,\n  MSK_RES_ERR_READ_WRITE                                       = 2563,\n  MSK_RES_ERR_TASK_PREMATURE_EOF                               = 2564,\n  MSK_RES_ERR_LU_MAX_NUM_TRIES                                 = 2800,\n  MSK_RES_ERR_INVALID_UTF8                                     = 2900,\n  MSK_RES_ERR_INVALID_WCHAR                                    = 2901,\n  MSK_RES_ERR_NO_DUAL_FOR_ITG_SOL                              = 2950,\n  MSK_RES_ERR_NO_SNX_FOR_BAS_SOL                               = 2953,\n  MSK_RES_ERR_INTERNAL                                         = 3000,\n  MSK_RES_ERR_API_ARRAY_TOO_SMALL                              = 3001,\n  MSK_RES_ERR_API_CB_CONNECT                                   = 3002,\n  MSK_RES_ERR_API_FATAL_ERROR                                  = 3005,\n  MSK_RES_ERR_SEN_FORMAT                                       = 3050,\n  MSK_RES_ERR_SEN_UNDEF_NAME                                   = 3051,\n  MSK_RES_ERR_SEN_INDEX_RANGE                                  = 3052,\n  MSK_RES_ERR_SEN_BOUND_INVALID_UP                             = 3053,\n  MSK_RES_ERR_SEN_BOUND_INVALID_LO                             = 3054,\n  MSK_RES_ERR_SEN_INDEX_INVALID                                = 3055,\n  MSK_RES_ERR_SEN_INVALID_REGEXP                               = 3056,\n  MSK_RES_ERR_SEN_SOLUTION_STATUS                              = 3057,\n  MSK_RES_ERR_SEN_NUMERICAL                                    = 3058,\n  MSK_RES_ERR_SEN_UNHANDLED_PROBLEM_TYPE                       = 3080,\n  MSK_RES_ERR_UNB_STEP_SIZE                                    = 3100,\n  MSK_RES_ERR_IDENTICAL_TASKS                                  = 3101,\n  MSK_RES_ERR_AD_INVALID_CODELIST                              = 3102,\n  MSK_RES_ERR_INTERNAL_TEST_FAILED                             = 3500,\n  MSK_RES_ERR_INT64_TO_INT32_CAST                              = 3800,\n  MSK_RES_ERR_INFEAS_UNDEFINED                                 = 3910,\n  MSK_RES_ERR_NO_BARX_FOR_SOLUTION                             = 3915,\n  MSK_RES_ERR_NO_BARS_FOR_SOLUTION                             = 3916,\n  MSK_RES_ERR_BAR_VAR_DIM                                      = 3920,\n  MSK_RES_ERR_SYM_MAT_INVALID_ROW_INDEX                        = 3940,\n  MSK_RES_ERR_SYM_MAT_INVALID_COL_INDEX                        = 3941,\n  MSK_RES_ERR_SYM_MAT_NOT_LOWER_TRINGULAR                      = 3942,\n  MSK_RES_ERR_SYM_MAT_INVALID_VALUE                            = 3943,\n  MSK_RES_ERR_SYM_MAT_DUPLICATE                                = 3944,\n  MSK_RES_ERR_INVALID_SYM_MAT_DIM                              = 3950,\n  MSK_RES_ERR_API_INTERNAL                                     = 3999,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_SYM_MAT                  = 4000,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_CFIX                     = 4001,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_RANGED_CONSTRAINTS       = 4002,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_FREE_CONSTRAINTS         = 4003,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_CONES                    = 4005,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_QUADRATIC_TERMS          = 4006,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_NONLINEAR                = 4010,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_DISJUNCTIVE_CONSTRAINTS  = 4011,\n  MSK_RES_ERR_INVALID_FILE_FORMAT_FOR_AFFINE_CONIC_CONSTRAINTS = 4012,\n  MSK_RES_ERR_DUPLICATE_CONSTRAINT_NAMES                       = 4500,\n  MSK_RES_ERR_DUPLICATE_VARIABLE_NAMES                         = 4501,\n  MSK_RES_ERR_DUPLICATE_BARVARIABLE_NAMES                      = 4502,\n  MSK_RES_ERR_DUPLICATE_CONE_NAMES                             = 4503,\n  MSK_RES_ERR_DUPLICATE_DOMAIN_NAMES                           = 4504,\n  MSK_RES_ERR_DUPLICATE_DJC_NAMES                              = 4505,\n  MSK_RES_ERR_NON_UNIQUE_ARRAY                                 = 5000,\n  MSK_RES_ERR_ARGUMENT_IS_TOO_SMALL                            = 5004,\n  MSK_RES_ERR_ARGUMENT_IS_TOO_LARGE                            = 5005,\n  MSK_RES_ERR_MIO_INTERNAL                                     = 5010,\n  MSK_RES_ERR_INVALID_PROBLEM_TYPE                             = 6000,\n  MSK_RES_ERR_UNHANDLED_SOLUTION_STATUS                        = 6010,\n  MSK_RES_ERR_UPPER_TRIANGLE                                   = 6020,\n  MSK_RES_ERR_LAU_SINGULAR_MATRIX                              = 7000,\n  MSK_RES_ERR_LAU_NOT_POSITIVE_DEFINITE                        = 7001,\n  MSK_RES_ERR_LAU_INVALID_LOWER_TRIANGULAR_MATRIX              = 7002,\n  MSK_RES_ERR_LAU_UNKNOWN                                      = 7005,\n  MSK_RES_ERR_LAU_ARG_M                                        = 7010,\n  MSK_RES_ERR_LAU_ARG_N                                        = 7011,\n  MSK_RES_ERR_LAU_ARG_K                                        = 7012,\n  MSK_RES_ERR_LAU_ARG_TRANSA                                   = 7015,\n  MSK_RES_ERR_LAU_ARG_TRANSB                                   = 7016,\n  MSK_RES_ERR_LAU_ARG_UPLO                                     = 7017,\n  MSK_RES_ERR_LAU_ARG_TRANS                                    = 7018,\n  MSK_RES_ERR_LAU_INVALID_SPARSE_SYMMETRIC_MATRIX              = 7019,\n  MSK_RES_ERR_CBF_PARSE                                        = 7100,\n  MSK_RES_ERR_CBF_OBJ_SENSE                                    = 7101,\n  MSK_RES_ERR_CBF_NO_VARIABLES                                 = 7102,\n  MSK_RES_ERR_CBF_TOO_MANY_CONSTRAINTS                         = 7103,\n  MSK_RES_ERR_CBF_TOO_MANY_VARIABLES                           = 7104,\n  MSK_RES_ERR_CBF_NO_VERSION_SPECIFIED                         = 7105,\n  MSK_RES_ERR_CBF_SYNTAX                                       = 7106,\n  MSK_RES_ERR_CBF_DUPLICATE_OBJ                                = 7107,\n  MSK_RES_ERR_CBF_DUPLICATE_CON                                = 7108,\n  MSK_RES_ERR_CBF_DUPLICATE_VAR                                = 7110,\n  MSK_RES_ERR_CBF_DUPLICATE_INT                                = 7111,\n  MSK_RES_ERR_CBF_INVALID_VAR_TYPE                             = 7112,\n  MSK_RES_ERR_CBF_INVALID_CON_TYPE                             = 7113,\n  MSK_RES_ERR_CBF_INVALID_DOMAIN_DIMENSION                     = 7114,\n  MSK_RES_ERR_CBF_DUPLICATE_OBJACOORD                          = 7115,\n  MSK_RES_ERR_CBF_DUPLICATE_BCOORD                             = 7116,\n  MSK_RES_ERR_CBF_DUPLICATE_ACOORD                             = 7117,\n  MSK_RES_ERR_CBF_TOO_FEW_VARIABLES                            = 7118,\n  MSK_RES_ERR_CBF_TOO_FEW_CONSTRAINTS                          = 7119,\n  MSK_RES_ERR_CBF_TOO_FEW_INTS                                 = 7120,\n  MSK_RES_ERR_CBF_TOO_MANY_INTS                                = 7121,\n  MSK_RES_ERR_CBF_INVALID_INT_INDEX                            = 7122,\n  MSK_RES_ERR_CBF_UNSUPPORTED                                  = 7123,\n  MSK_RES_ERR_CBF_DUPLICATE_PSDVAR                             = 7124,\n  MSK_RES_ERR_CBF_INVALID_PSDVAR_DIMENSION                     = 7125,\n  MSK_RES_ERR_CBF_TOO_FEW_PSDVAR                               = 7126,\n  MSK_RES_ERR_CBF_INVALID_EXP_DIMENSION                        = 7127,\n  MSK_RES_ERR_CBF_DUPLICATE_POW_CONES                          = 7130,\n  MSK_RES_ERR_CBF_DUPLICATE_POW_STAR_CONES                     = 7131,\n  MSK_RES_ERR_CBF_INVALID_POWER                                = 7132,\n  MSK_RES_ERR_CBF_POWER_CONE_IS_TOO_LONG                       = 7133,\n  MSK_RES_ERR_CBF_INVALID_POWER_CONE_INDEX                     = 7134,\n  MSK_RES_ERR_CBF_INVALID_POWER_STAR_CONE_INDEX                = 7135,\n  MSK_RES_ERR_CBF_UNHANDLED_POWER_CONE_TYPE                    = 7136,\n  MSK_RES_ERR_CBF_UNHANDLED_POWER_STAR_CONE_TYPE               = 7137,\n  MSK_RES_ERR_CBF_POWER_CONE_MISMATCH                          = 7138,\n  MSK_RES_ERR_CBF_POWER_STAR_CONE_MISMATCH                     = 7139,\n  MSK_RES_ERR_CBF_INVALID_NUMBER_OF_CONES                      = 7140,\n  MSK_RES_ERR_CBF_INVALID_DIMENSION_OF_CONES                   = 7141,\n  MSK_RES_ERR_CBF_INVALID_NUM_OBJACOORD                        = 7150,\n  MSK_RES_ERR_CBF_INVALID_NUM_OBJFCOORD                        = 7151,\n  MSK_RES_ERR_CBF_INVALID_NUM_ACOORD                           = 7152,\n  MSK_RES_ERR_CBF_INVALID_NUM_BCOORD                           = 7153,\n  MSK_RES_ERR_CBF_INVALID_NUM_FCOORD                           = 7155,\n  MSK_RES_ERR_CBF_INVALID_NUM_HCOORD                           = 7156,\n  MSK_RES_ERR_CBF_INVALID_NUM_DCOORD                           = 7157,\n  MSK_RES_ERR_CBF_EXPECTED_A_KEYWORD                           = 7158,\n  MSK_RES_ERR_CBF_INVALID_NUM_PSDCON                           = 7200,\n  MSK_RES_ERR_CBF_DUPLICATE_PSDCON                             = 7201,\n  MSK_RES_ERR_CBF_INVALID_DIMENSION_OF_PSDCON                  = 7202,\n  MSK_RES_ERR_CBF_INVALID_PSDCON_INDEX                         = 7203,\n  MSK_RES_ERR_CBF_INVALID_PSDCON_VARIABLE_INDEX                = 7204,\n  MSK_RES_ERR_CBF_INVALID_PSDCON_BLOCK_INDEX                   = 7205,\n  MSK_RES_ERR_CBF_UNSUPPORTED_CHANGE                           = 7210,\n  MSK_RES_ERR_MIO_INVALID_ROOT_OPTIMIZER                       = 7700,\n  MSK_RES_ERR_MIO_INVALID_NODE_OPTIMIZER                       = 7701,\n  MSK_RES_ERR_MPS_WRITE_CPLEX_INVALID_CONE_TYPE                = 7750,\n  MSK_RES_ERR_TOCONIC_CONSTR_Q_NOT_PSD                         = 7800,\n  MSK_RES_ERR_TOCONIC_CONSTRAINT_FX                            = 7801,\n  MSK_RES_ERR_TOCONIC_CONSTRAINT_RA                            = 7802,\n  MSK_RES_ERR_TOCONIC_CONSTR_NOT_CONIC                         = 7803,\n  MSK_RES_ERR_TOCONIC_OBJECTIVE_NOT_PSD                        = 7804,\n  MSK_RES_ERR_GETDUAL_NOT_AVAILABLE                            = 7820,\n  MSK_RES_ERR_SERVER_CONNECT                                   = 8000,\n  MSK_RES_ERR_SERVER_PROTOCOL                                  = 8001,\n  MSK_RES_ERR_SERVER_STATUS                                    = 8002,\n  MSK_RES_ERR_SERVER_TOKEN                                     = 8003,\n  MSK_RES_ERR_SERVER_ADDRESS                                   = 8004,\n  MSK_RES_ERR_SERVER_CERTIFICATE                               = 8005,\n  MSK_RES_ERR_SERVER_TLS_CLIENT                                = 8006,\n  MSK_RES_ERR_SERVER_ACCESS_TOKEN                              = 8007,\n  MSK_RES_ERR_SERVER_PROBLEM_SIZE                              = 8008,\n  MSK_RES_ERR_SERVER_HARD_TIMEOUT                              = 8009,\n  MSK_RES_ERR_DUPLICATE_INDEX_IN_A_SPARSE_MATRIX               = 20050,\n  MSK_RES_ERR_DUPLICATE_INDEX_IN_AFEIDX_LIST                   = 20060,\n  MSK_RES_ERR_DUPLICATE_FIJ                                    = 20100,\n  MSK_RES_ERR_INVALID_FIJ                                      = 20101,\n  MSK_RES_ERR_HUGE_FIJ                                         = 20102,\n  MSK_RES_ERR_INVALID_G                                        = 20103,\n  MSK_RES_ERR_INVALID_B                                        = 20150,\n  MSK_RES_ERR_DOMAIN_INVALID_INDEX                             = 20400,\n  MSK_RES_ERR_DOMAIN_DIMENSION                                 = 20401,\n  MSK_RES_ERR_DOMAIN_DIMENSION_PSD                             = 20402,\n  MSK_RES_ERR_NOT_POWER_DOMAIN                                 = 20403,\n  MSK_RES_ERR_DOMAIN_POWER_INVALID_ALPHA                       = 20404,\n  MSK_RES_ERR_DOMAIN_POWER_NEGATIVE_ALPHA                      = 20405,\n  MSK_RES_ERR_DOMAIN_POWER_NLEFT                               = 20406,\n  MSK_RES_ERR_AFE_INVALID_INDEX                                = 20500,\n  MSK_RES_ERR_ACC_INVALID_INDEX                                = 20600,\n  MSK_RES_ERR_ACC_INVALID_ENTRY_INDEX                          = 20601,\n  MSK_RES_ERR_ACC_AFE_DOMAIN_MISMATCH                          = 20602,\n  MSK_RES_ERR_DJC_INVALID_INDEX                                = 20700,\n  MSK_RES_ERR_DJC_UNSUPPORTED_DOMAIN_TYPE                      = 20701,\n  MSK_RES_ERR_DJC_AFE_DOMAIN_MISMATCH                          = 20702,\n  MSK_RES_ERR_DJC_INVALID_TERM_SIZE                            = 20703,\n  MSK_RES_ERR_DJC_DOMAIN_TERMSIZE_MISMATCH                     = 20704,\n  MSK_RES_ERR_DJC_TOTAL_NUM_TERMS_MISMATCH                     = 20705,\n  MSK_RES_ERR_UNDEF_SOLUTION                                   = 22000,\n  MSK_RES_ERR_NO_DOTY                                          = 22010,\n  MSK_RES_TRM_MAX_ITERATIONS                                   = 100000,\n  MSK_RES_TRM_MAX_TIME                                         = 100001,\n  MSK_RES_TRM_OBJECTIVE_RANGE                                  = 100002,\n  MSK_RES_TRM_STALL                                            = 100006,\n  MSK_RES_TRM_USER_CALLBACK                                    = 100007,\n  MSK_RES_TRM_MIO_NUM_RELAXS                                   = 100008,\n  MSK_RES_TRM_MIO_NUM_BRANCHES                                 = 100009,\n  MSK_RES_TRM_NUM_MAX_NUM_INT_SOLUTIONS                        = 100015,\n  MSK_RES_TRM_MAX_NUM_SETBACKS                                 = 100020,\n  MSK_RES_TRM_NUMERICAL_PROBLEM                                = 100025,\n  MSK_RES_TRM_LOST_RACE                                        = 100027,\n  MSK_RES_TRM_INTERNAL                                         = 100030,\n  MSK_RES_TRM_INTERNAL_STOP                                    = 100031,\n  MSK_RES_TRM_SERVER_MAX_TIME                                  = 100032,\n  MSK_RES_TRM_SERVER_MAX_MEMORY                                = 100033\n};\n\n\nenum MSKrescodetype_enum {\n  MSK_RESPONSE_OK  = 0,\n  MSK_RESPONSE_WRN = 1,\n  MSK_RESPONSE_TRM = 2,\n  MSK_RESPONSE_ERR = 3,\n  MSK_RESPONSE_UNK = 4\n};\n#define MSK_RESPONSE_BEGIN MSK_RESPONSE_OK\n#define MSK_RESPONSE_END   (1+MSK_RESPONSE_UNK)\n\n\nenum MSKscalingtype_enum {\n  MSK_SCALING_FREE = 0,\n  MSK_SCALING_NONE = 1\n};\n#define MSK_SCALING_BEGIN MSK_SCALING_FREE\n#define MSK_SCALING_END   (1+MSK_SCALING_NONE)\n\n\nenum MSKscalingmethod_enum {\n  MSK_SCALING_METHOD_POW2 = 0,\n  MSK_SCALING_METHOD_FREE = 1\n};\n#define MSK_SCALING_METHOD_BEGIN MSK_SCALING_METHOD_POW2\n#define MSK_SCALING_METHOD_END   (1+MSK_SCALING_METHOD_FREE)\n\n\nenum MSKsensitivitytype_enum {\n  MSK_SENSITIVITY_TYPE_BASIS = 0\n};\n#define MSK_SENSITIVITY_TYPE_BEGIN MSK_SENSITIVITY_TYPE_BASIS\n#define MSK_SENSITIVITY_TYPE_END   (1+MSK_SENSITIVITY_TYPE_BASIS)\n\n\nenum MSKsimseltype_enum {\n  MSK_SIM_SELECTION_FREE    = 0,\n  MSK_SIM_SELECTION_FULL    = 1,\n  MSK_SIM_SELECTION_ASE     = 2,\n  MSK_SIM_SELECTION_DEVEX   = 3,\n  MSK_SIM_SELECTION_SE      = 4,\n  MSK_SIM_SELECTION_PARTIAL = 5\n};\n#define MSK_SIM_SELECTION_BEGIN MSK_SIM_SELECTION_FREE\n#define MSK_SIM_SELECTION_END   (1+MSK_SIM_SELECTION_PARTIAL)\n\n\nenum MSKsolitem_enum {\n  MSK_SOL_ITEM_XC  = 0,\n  MSK_SOL_ITEM_XX  = 1,\n  MSK_SOL_ITEM_Y   = 2,\n  MSK_SOL_ITEM_SLC = 3,\n  MSK_SOL_ITEM_SUC = 4,\n  MSK_SOL_ITEM_SLX = 5,\n  MSK_SOL_ITEM_SUX = 6,\n  MSK_SOL_ITEM_SNX = 7\n};\n#define MSK_SOL_ITEM_BEGIN MSK_SOL_ITEM_XC\n#define MSK_SOL_ITEM_END   (1+MSK_SOL_ITEM_SNX)\n\n\nenum MSKsolsta_enum {\n  MSK_SOL_STA_UNKNOWN            = 0,\n  MSK_SOL_STA_OPTIMAL            = 1,\n  MSK_SOL_STA_PRIM_FEAS          = 2,\n  MSK_SOL_STA_DUAL_FEAS          = 3,\n  MSK_SOL_STA_PRIM_AND_DUAL_FEAS = 4,\n  MSK_SOL_STA_PRIM_INFEAS_CER    = 5,\n  MSK_SOL_STA_DUAL_INFEAS_CER    = 6,\n  MSK_SOL_STA_PRIM_ILLPOSED_CER  = 7,\n  MSK_SOL_STA_DUAL_ILLPOSED_CER  = 8,\n  MSK_SOL_STA_INTEGER_OPTIMAL    = 9\n};\n#define MSK_SOL_STA_BEGIN MSK_SOL_STA_UNKNOWN\n#define MSK_SOL_STA_END   (1+MSK_SOL_STA_INTEGER_OPTIMAL)\n\n\nenum MSKsoltype_enum {\n  MSK_SOL_ITR = 0,\n  MSK_SOL_BAS = 1,\n  MSK_SOL_ITG = 2\n};\n#define MSK_SOL_BEGIN MSK_SOL_ITR\n#define MSK_SOL_END   (1+MSK_SOL_ITG)\n\n\nenum MSKsolveform_enum {\n  MSK_SOLVE_FREE   = 0,\n  MSK_SOLVE_PRIMAL = 1,\n  MSK_SOLVE_DUAL   = 2\n};\n#define MSK_SOLVE_BEGIN MSK_SOLVE_FREE\n#define MSK_SOLVE_END   (1+MSK_SOLVE_DUAL)\n\n\nenum MSKsparam_enum {\n  MSK_SPAR_BAS_SOL_FILE_NAME         = 0,\n  MSK_SPAR_DATA_FILE_NAME            = 1,\n  MSK_SPAR_DEBUG_FILE_NAME           = 2,\n  MSK_SPAR_INT_SOL_FILE_NAME         = 3,\n  MSK_SPAR_ITR_SOL_FILE_NAME         = 4,\n  MSK_SPAR_MIO_DEBUG_STRING          = 5,\n  MSK_SPAR_PARAM_COMMENT_SIGN        = 6,\n  MSK_SPAR_PARAM_READ_FILE_NAME      = 7,\n  MSK_SPAR_PARAM_WRITE_FILE_NAME     = 8,\n  MSK_SPAR_READ_MPS_BOU_NAME         = 9,\n  MSK_SPAR_READ_MPS_OBJ_NAME         = 10,\n  MSK_SPAR_READ_MPS_RAN_NAME         = 11,\n  MSK_SPAR_READ_MPS_RHS_NAME         = 12,\n  MSK_SPAR_REMOTE_OPTSERVER_HOST     = 13,\n  MSK_SPAR_REMOTE_TLS_CERT           = 14,\n  MSK_SPAR_REMOTE_TLS_CERT_PATH      = 15,\n  MSK_SPAR_SENSITIVITY_FILE_NAME     = 16,\n  MSK_SPAR_SENSITIVITY_RES_FILE_NAME = 17,\n  MSK_SPAR_SOL_FILTER_XC_LOW         = 18,\n  MSK_SPAR_SOL_FILTER_XC_UPR         = 19,\n  MSK_SPAR_SOL_FILTER_XX_LOW         = 20,\n  MSK_SPAR_SOL_FILTER_XX_UPR         = 21,\n  MSK_SPAR_STAT_KEY                  = 22,\n  MSK_SPAR_STAT_NAME                 = 23\n};\n#define MSK_SPAR_BEGIN MSK_SPAR_BAS_SOL_FILE_NAME\n#define MSK_SPAR_END   (1+MSK_SPAR_STAT_NAME)\n\n\nenum MSKstakey_enum {\n  MSK_SK_UNK    = 0,\n  MSK_SK_BAS    = 1,\n  MSK_SK_SUPBAS = 2,\n  MSK_SK_LOW    = 3,\n  MSK_SK_UPR    = 4,\n  MSK_SK_FIX    = 5,\n  MSK_SK_INF    = 6\n};\n#define MSK_SK_BEGIN MSK_SK_UNK\n#define MSK_SK_END   (1+MSK_SK_INF)\n\n\nenum MSKstartpointtype_enum {\n  MSK_STARTING_POINT_FREE     = 0,\n  MSK_STARTING_POINT_GUESS    = 1,\n  MSK_STARTING_POINT_CONSTANT = 2\n};\n#define MSK_STARTING_POINT_BEGIN MSK_STARTING_POINT_FREE\n#define MSK_STARTING_POINT_END   (1+MSK_STARTING_POINT_CONSTANT)\n\n\nenum MSKstreamtype_enum {\n  MSK_STREAM_LOG = 0,\n  MSK_STREAM_MSG = 1,\n  MSK_STREAM_ERR = 2,\n  MSK_STREAM_WRN = 3\n};\n#define MSK_STREAM_BEGIN MSK_STREAM_LOG\n#define MSK_STREAM_END   (1+MSK_STREAM_WRN)\n\n\nenum MSKvalue_enum {\n  MSK_LICENSE_BUFFER_LENGTH = 21,\n  MSK_MAX_STR_LEN           = 1024\n};\n\n\nenum MSKvariabletype_enum {\n  MSK_VAR_TYPE_CONT = 0,\n  MSK_VAR_TYPE_INT  = 1\n};\n#define MSK_VAR_BEGIN MSK_VAR_TYPE_CONT\n#define MSK_VAR_END   (1+MSK_VAR_TYPE_INT)\n\n\n/* } namespace mosek; */\n/**************************************************/\n#define MSK_FIRST_ERR_CODE 1000 \n#define MSK_LAST_ERR_CODE  9999 \n/**************************************************/\ntypedef enum MSK_whichenum_enum {\n  MSK_WHICHENUM_LANGUAGE,\n  MSK_WHICHENUM_BASINDTYPE,\n  MSK_WHICHENUM_BOUNDKEY,\n  MSK_WHICHENUM_MARK,\n  MSK_WHICHENUM_SIMPRECISION,\n  MSK_WHICHENUM_SIMDEGEN,\n  MSK_WHICHENUM_TRANSPOSE,\n  MSK_WHICHENUM_UPLO,\n  MSK_WHICHENUM_SIMREFORM,\n  MSK_WHICHENUM_SIMDUPVEC,\n  MSK_WHICHENUM_SIMHOTSTART,\n  MSK_WHICHENUM_INTPNTHOTSTART,\n  MSK_WHICHENUM_CALLBACKCODE,\n  MSK_WHICHENUM_COMPRESSTYPE,\n  MSK_WHICHENUM_CONETYPE,\n  MSK_WHICHENUM_DOMAINTYPE,\n  MSK_WHICHENUM_NAMETYPE,\n  MSK_WHICHENUM_SYMMATTYPE,\n  MSK_WHICHENUM_DATAFORMAT,\n  MSK_WHICHENUM_SOLFORMAT,\n  MSK_WHICHENUM_DINFITEM,\n  MSK_WHICHENUM_FEATURE,\n  MSK_WHICHENUM_DPARAM,\n  MSK_WHICHENUM_LIINFITEM,\n  MSK_WHICHENUM_INTERNAL_LIINF,\n  MSK_WHICHENUM_IINFITEM,\n  MSK_WHICHENUM_INFTYPE,\n  MSK_WHICHENUM_INTERNAL_DINF,\n  MSK_WHICHENUM_INTERNAL_IINF,\n  MSK_WHICHENUM_IOMODE,\n  MSK_WHICHENUM_IPARAM,\n  MSK_WHICHENUM_BRANCHDIR,\n  MSK_WHICHENUM_MIQCQOREFORMMETHOD,\n  MSK_WHICHENUM_MIODATAPERMMETHOD,\n  MSK_WHICHENUM_MIOCONTSOLTYPE,\n  MSK_WHICHENUM_MIOMODE,\n  MSK_WHICHENUM_MIONODESELTYPE,\n  MSK_WHICHENUM_MIOVARSELTYPE,\n  MSK_WHICHENUM_MPSFORMAT,\n  MSK_WHICHENUM_OBJSENSE,\n  MSK_WHICHENUM_ONOFFKEY,\n  MSK_WHICHENUM_OPTIMIZERTYPE,\n  MSK_WHICHENUM_ORDERINGTYPE,\n  MSK_WHICHENUM_PRESOLVEMODE,\n  MSK_WHICHENUM_FOLDINGMODE,\n  MSK_WHICHENUM_PARAMETERTYPE,\n  MSK_WHICHENUM_PROBLEMITEM,\n  MSK_WHICHENUM_PROBLEMTYPE,\n  MSK_WHICHENUM_PROSTA,\n  MSK_WHICHENUM_RESCODE,\n  MSK_WHICHENUM_RESCODETYPE,\n  MSK_WHICHENUM_SCALINGTYPE,\n  MSK_WHICHENUM_SCALINGMETHOD,\n  MSK_WHICHENUM_SENSITIVITYTYPE,\n  MSK_WHICHENUM_SIMSELTYPE,\n  MSK_WHICHENUM_SOLITEM,\n  MSK_WHICHENUM_SOLSTA,\n  MSK_WHICHENUM_SOLTYPE,\n  MSK_WHICHENUM_SOLVEFORM,\n  MSK_WHICHENUM_SPARAM,\n  MSK_WHICHENUM_STAKEY,\n  MSK_WHICHENUM_STARTPOINTTYPE,\n  MSK_WHICHENUM_STREAMTYPE,\n  MSK_WHICHENUM_VARIABLETYPE,\n  MSK_WHICHENUM_LAST\n} /* MSKwhichenum_enum */\nMSKwhichenume;\n\n\n\n#define MSK_SPAR_BAS_SOL_FILE_NAME_                         \"MSK_SPAR_BAS_SOL_FILE_NAME\"\n#define MSK_SPAR_DATA_FILE_NAME_                            \"MSK_SPAR_DATA_FILE_NAME\"\n#define MSK_SPAR_DEBUG_FILE_NAME_                           \"MSK_SPAR_DEBUG_FILE_NAME\"\n#define MSK_SPAR_INT_SOL_FILE_NAME_                         \"MSK_SPAR_INT_SOL_FILE_NAME\"\n#define MSK_SPAR_ITR_SOL_FILE_NAME_                         \"MSK_SPAR_ITR_SOL_FILE_NAME\"\n#define MSK_SPAR_MIO_DEBUG_STRING_                          \"MSK_SPAR_MIO_DEBUG_STRING\"\n#define MSK_SPAR_PARAM_COMMENT_SIGN_                        \"MSK_SPAR_PARAM_COMMENT_SIGN\"\n#define MSK_SPAR_PARAM_READ_FILE_NAME_                      \"MSK_SPAR_PARAM_READ_FILE_NAME\"\n#define MSK_SPAR_PARAM_WRITE_FILE_NAME_                     \"MSK_SPAR_PARAM_WRITE_FILE_NAME\"\n#define MSK_SPAR_READ_MPS_BOU_NAME_                         \"MSK_SPAR_READ_MPS_BOU_NAME\"\n#define MSK_SPAR_READ_MPS_OBJ_NAME_                         \"MSK_SPAR_READ_MPS_OBJ_NAME\"\n#define MSK_SPAR_READ_MPS_RAN_NAME_                         \"MSK_SPAR_READ_MPS_RAN_NAME\"\n#define MSK_SPAR_READ_MPS_RHS_NAME_                         \"MSK_SPAR_READ_MPS_RHS_NAME\"\n#define MSK_SPAR_REMOTE_OPTSERVER_HOST_                     \"MSK_SPAR_REMOTE_OPTSERVER_HOST\"\n#define MSK_SPAR_REMOTE_TLS_CERT_                           \"MSK_SPAR_REMOTE_TLS_CERT\"\n#define MSK_SPAR_REMOTE_TLS_CERT_PATH_                      \"MSK_SPAR_REMOTE_TLS_CERT_PATH\"\n#define MSK_SPAR_SENSITIVITY_FILE_NAME_                     \"MSK_SPAR_SENSITIVITY_FILE_NAME\"\n#define MSK_SPAR_SENSITIVITY_RES_FILE_NAME_                 \"MSK_SPAR_SENSITIVITY_RES_FILE_NAME\"\n#define MSK_SPAR_SOL_FILTER_XC_LOW_                         \"MSK_SPAR_SOL_FILTER_XC_LOW\"\n#define MSK_SPAR_SOL_FILTER_XC_UPR_                         \"MSK_SPAR_SOL_FILTER_XC_UPR\"\n#define MSK_SPAR_SOL_FILTER_XX_LOW_                         \"MSK_SPAR_SOL_FILTER_XX_LOW\"\n#define MSK_SPAR_SOL_FILTER_XX_UPR_                         \"MSK_SPAR_SOL_FILTER_XX_UPR\"\n#define MSK_SPAR_STAT_KEY_                                  \"MSK_SPAR_STAT_KEY\"\n#define MSK_SPAR_STAT_NAME_                                 \"MSK_SPAR_STAT_NAME\"\n\n#define MSK_DPAR_ANA_SOL_INFEAS_TOL_                        \"MSK_DPAR_ANA_SOL_INFEAS_TOL\"\n#define MSK_DPAR_BASIS_REL_TOL_S_                           \"MSK_DPAR_BASIS_REL_TOL_S\"\n#define MSK_DPAR_BASIS_TOL_S_                               \"MSK_DPAR_BASIS_TOL_S\"\n#define MSK_DPAR_BASIS_TOL_X_                               \"MSK_DPAR_BASIS_TOL_X\"\n#define MSK_DPAR_DATA_SYM_MAT_TOL_                          \"MSK_DPAR_DATA_SYM_MAT_TOL\"\n#define MSK_DPAR_DATA_SYM_MAT_TOL_HUGE_                     \"MSK_DPAR_DATA_SYM_MAT_TOL_HUGE\"\n#define MSK_DPAR_DATA_SYM_MAT_TOL_LARGE_                    \"MSK_DPAR_DATA_SYM_MAT_TOL_LARGE\"\n#define MSK_DPAR_DATA_TOL_AIJ_HUGE_                         \"MSK_DPAR_DATA_TOL_AIJ_HUGE\"\n#define MSK_DPAR_DATA_TOL_AIJ_LARGE_                        \"MSK_DPAR_DATA_TOL_AIJ_LARGE\"\n#define MSK_DPAR_DATA_TOL_BOUND_INF_                        \"MSK_DPAR_DATA_TOL_BOUND_INF\"\n#define MSK_DPAR_DATA_TOL_BOUND_WRN_                        \"MSK_DPAR_DATA_TOL_BOUND_WRN\"\n#define MSK_DPAR_DATA_TOL_C_HUGE_                           \"MSK_DPAR_DATA_TOL_C_HUGE\"\n#define MSK_DPAR_DATA_TOL_CJ_LARGE_                         \"MSK_DPAR_DATA_TOL_CJ_LARGE\"\n#define MSK_DPAR_DATA_TOL_QIJ_                              \"MSK_DPAR_DATA_TOL_QIJ\"\n#define MSK_DPAR_DATA_TOL_X_                                \"MSK_DPAR_DATA_TOL_X\"\n#define MSK_DPAR_FOLDING_TOL_EQ_                            \"MSK_DPAR_FOLDING_TOL_EQ\"\n#define MSK_DPAR_INTPNT_CO_TOL_DFEAS_                       \"MSK_DPAR_INTPNT_CO_TOL_DFEAS\"\n#define MSK_DPAR_INTPNT_CO_TOL_INFEAS_                      \"MSK_DPAR_INTPNT_CO_TOL_INFEAS\"\n#define MSK_DPAR_INTPNT_CO_TOL_MU_RED_                      \"MSK_DPAR_INTPNT_CO_TOL_MU_RED\"\n#define MSK_DPAR_INTPNT_CO_TOL_NEAR_REL_                    \"MSK_DPAR_INTPNT_CO_TOL_NEAR_REL\"\n#define MSK_DPAR_INTPNT_CO_TOL_PFEAS_                       \"MSK_DPAR_INTPNT_CO_TOL_PFEAS\"\n#define MSK_DPAR_INTPNT_CO_TOL_REL_GAP_                     \"MSK_DPAR_INTPNT_CO_TOL_REL_GAP\"\n#define MSK_DPAR_INTPNT_QO_TOL_DFEAS_                       \"MSK_DPAR_INTPNT_QO_TOL_DFEAS\"\n#define MSK_DPAR_INTPNT_QO_TOL_INFEAS_                      \"MSK_DPAR_INTPNT_QO_TOL_INFEAS\"\n#define MSK_DPAR_INTPNT_QO_TOL_MU_RED_                      \"MSK_DPAR_INTPNT_QO_TOL_MU_RED\"\n#define MSK_DPAR_INTPNT_QO_TOL_NEAR_REL_                    \"MSK_DPAR_INTPNT_QO_TOL_NEAR_REL\"\n#define MSK_DPAR_INTPNT_QO_TOL_PFEAS_                       \"MSK_DPAR_INTPNT_QO_TOL_PFEAS\"\n#define MSK_DPAR_INTPNT_QO_TOL_REL_GAP_                     \"MSK_DPAR_INTPNT_QO_TOL_REL_GAP\"\n#define MSK_DPAR_INTPNT_TOL_DFEAS_                          \"MSK_DPAR_INTPNT_TOL_DFEAS\"\n#define MSK_DPAR_INTPNT_TOL_DSAFE_                          \"MSK_DPAR_INTPNT_TOL_DSAFE\"\n#define MSK_DPAR_INTPNT_TOL_INFEAS_                         \"MSK_DPAR_INTPNT_TOL_INFEAS\"\n#define MSK_DPAR_INTPNT_TOL_MU_RED_                         \"MSK_DPAR_INTPNT_TOL_MU_RED\"\n#define MSK_DPAR_INTPNT_TOL_PATH_                           \"MSK_DPAR_INTPNT_TOL_PATH\"\n#define MSK_DPAR_INTPNT_TOL_PFEAS_                          \"MSK_DPAR_INTPNT_TOL_PFEAS\"\n#define MSK_DPAR_INTPNT_TOL_PSAFE_                          \"MSK_DPAR_INTPNT_TOL_PSAFE\"\n#define MSK_DPAR_INTPNT_TOL_REL_GAP_                        \"MSK_DPAR_INTPNT_TOL_REL_GAP\"\n#define MSK_DPAR_INTPNT_TOL_REL_STEP_                       \"MSK_DPAR_INTPNT_TOL_REL_STEP\"\n#define MSK_DPAR_INTPNT_TOL_STEP_SIZE_                      \"MSK_DPAR_INTPNT_TOL_STEP_SIZE\"\n#define MSK_DPAR_LOWER_OBJ_CUT_                             \"MSK_DPAR_LOWER_OBJ_CUT\"\n#define MSK_DPAR_LOWER_OBJ_CUT_FINITE_TRH_                  \"MSK_DPAR_LOWER_OBJ_CUT_FINITE_TRH\"\n#define MSK_DPAR_MIO_CLIQUE_TABLE_SIZE_FACTOR_              \"MSK_DPAR_MIO_CLIQUE_TABLE_SIZE_FACTOR\"\n#define MSK_DPAR_MIO_DJC_MAX_BIGM_                          \"MSK_DPAR_MIO_DJC_MAX_BIGM\"\n#define MSK_DPAR_MIO_MAX_TIME_                              \"MSK_DPAR_MIO_MAX_TIME\"\n#define MSK_DPAR_MIO_REL_GAP_CONST_                         \"MSK_DPAR_MIO_REL_GAP_CONST\"\n#define MSK_DPAR_MIO_TOL_ABS_GAP_                           \"MSK_DPAR_MIO_TOL_ABS_GAP\"\n#define MSK_DPAR_MIO_TOL_ABS_RELAX_INT_                     \"MSK_DPAR_MIO_TOL_ABS_RELAX_INT\"\n#define MSK_DPAR_MIO_TOL_FEAS_                              \"MSK_DPAR_MIO_TOL_FEAS\"\n#define MSK_DPAR_MIO_TOL_REL_DUAL_BOUND_IMPROVEMENT_        \"MSK_DPAR_MIO_TOL_REL_DUAL_BOUND_IMPROVEMENT\"\n#define MSK_DPAR_MIO_TOL_REL_GAP_                           \"MSK_DPAR_MIO_TOL_REL_GAP\"\n#define MSK_DPAR_OPTIMIZER_MAX_TICKS_                       \"MSK_DPAR_OPTIMIZER_MAX_TICKS\"\n#define MSK_DPAR_OPTIMIZER_MAX_TIME_                        \"MSK_DPAR_OPTIMIZER_MAX_TIME\"\n#define MSK_DPAR_PRESOLVE_TOL_ABS_LINDEP_                   \"MSK_DPAR_PRESOLVE_TOL_ABS_LINDEP\"\n#define MSK_DPAR_PRESOLVE_TOL_PRIMAL_INFEAS_PERTURBATION_   \"MSK_DPAR_PRESOLVE_TOL_PRIMAL_INFEAS_PERTURBATION\"\n#define MSK_DPAR_PRESOLVE_TOL_REL_LINDEP_                   \"MSK_DPAR_PRESOLVE_TOL_REL_LINDEP\"\n#define MSK_DPAR_PRESOLVE_TOL_S_                            \"MSK_DPAR_PRESOLVE_TOL_S\"\n#define MSK_DPAR_PRESOLVE_TOL_X_                            \"MSK_DPAR_PRESOLVE_TOL_X\"\n#define MSK_DPAR_QCQO_REFORMULATE_REL_DROP_TOL_             \"MSK_DPAR_QCQO_REFORMULATE_REL_DROP_TOL\"\n#define MSK_DPAR_SEMIDEFINITE_TOL_APPROX_                   \"MSK_DPAR_SEMIDEFINITE_TOL_APPROX\"\n#define MSK_DPAR_SIM_LU_TOL_REL_PIV_                        \"MSK_DPAR_SIM_LU_TOL_REL_PIV\"\n#define MSK_DPAR_SIM_PRECISION_SCALING_EXTENDED_            \"MSK_DPAR_SIM_PRECISION_SCALING_EXTENDED\"\n#define MSK_DPAR_SIM_PRECISION_SCALING_NORMAL_              \"MSK_DPAR_SIM_PRECISION_SCALING_NORMAL\"\n#define MSK_DPAR_SIMPLEX_ABS_TOL_PIV_                       \"MSK_DPAR_SIMPLEX_ABS_TOL_PIV\"\n#define MSK_DPAR_UPPER_OBJ_CUT_                             \"MSK_DPAR_UPPER_OBJ_CUT\"\n#define MSK_DPAR_UPPER_OBJ_CUT_FINITE_TRH_                  \"MSK_DPAR_UPPER_OBJ_CUT_FINITE_TRH\"\n\n#define MSK_IPAR_ANA_SOL_BASIS_                             \"MSK_IPAR_ANA_SOL_BASIS\"\n#define MSK_IPAR_ANA_SOL_PRINT_VIOLATED_                    \"MSK_IPAR_ANA_SOL_PRINT_VIOLATED\"\n#define MSK_IPAR_AUTO_SORT_A_BEFORE_OPT_                    \"MSK_IPAR_AUTO_SORT_A_BEFORE_OPT\"\n#define MSK_IPAR_AUTO_UPDATE_SOL_INFO_                      \"MSK_IPAR_AUTO_UPDATE_SOL_INFO\"\n#define MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE_                  \"MSK_IPAR_BASIS_SOLVE_USE_PLUS_ONE\"\n#define MSK_IPAR_BI_CLEAN_OPTIMIZER_                        \"MSK_IPAR_BI_CLEAN_OPTIMIZER\"\n#define MSK_IPAR_BI_IGNORE_MAX_ITER_                        \"MSK_IPAR_BI_IGNORE_MAX_ITER\"\n#define MSK_IPAR_BI_IGNORE_NUM_ERROR_                       \"MSK_IPAR_BI_IGNORE_NUM_ERROR\"\n#define MSK_IPAR_BI_MAX_ITERATIONS_                         \"MSK_IPAR_BI_MAX_ITERATIONS\"\n#define MSK_IPAR_CACHE_LICENSE_                             \"MSK_IPAR_CACHE_LICENSE\"\n#define MSK_IPAR_COMPRESS_STATFILE_                         \"MSK_IPAR_COMPRESS_STATFILE\"\n#define MSK_IPAR_FOLDING_USE_                               \"MSK_IPAR_FOLDING_USE\"\n#define MSK_IPAR_GETDUAL_CONVERT_LMIS_                      \"MSK_IPAR_GETDUAL_CONVERT_LMIS\"\n#define MSK_IPAR_HEARTBEAT_SIM_FREQ_TICKS_                  \"MSK_IPAR_HEARTBEAT_SIM_FREQ_TICKS\"\n#define MSK_IPAR_INFEAS_GENERIC_NAMES_                      \"MSK_IPAR_INFEAS_GENERIC_NAMES\"\n#define MSK_IPAR_INFEAS_REPORT_AUTO_                        \"MSK_IPAR_INFEAS_REPORT_AUTO\"\n#define MSK_IPAR_INFEAS_REPORT_LEVEL_                       \"MSK_IPAR_INFEAS_REPORT_LEVEL\"\n#define MSK_IPAR_INTPNT_BASIS_                              \"MSK_IPAR_INTPNT_BASIS\"\n#define MSK_IPAR_INTPNT_DIFF_STEP_                          \"MSK_IPAR_INTPNT_DIFF_STEP\"\n#define MSK_IPAR_INTPNT_HOTSTART_                           \"MSK_IPAR_INTPNT_HOTSTART\"\n#define MSK_IPAR_INTPNT_MAX_ITERATIONS_                     \"MSK_IPAR_INTPNT_MAX_ITERATIONS\"\n#define MSK_IPAR_INTPNT_MAX_NUM_COR_                        \"MSK_IPAR_INTPNT_MAX_NUM_COR\"\n#define MSK_IPAR_INTPNT_OFF_COL_TRH_                        \"MSK_IPAR_INTPNT_OFF_COL_TRH\"\n#define MSK_IPAR_INTPNT_ORDER_GP_NUM_SEEDS_                 \"MSK_IPAR_INTPNT_ORDER_GP_NUM_SEEDS\"\n#define MSK_IPAR_INTPNT_ORDER_METHOD_                       \"MSK_IPAR_INTPNT_ORDER_METHOD\"\n#define MSK_IPAR_INTPNT_REGULARIZATION_USE_                 \"MSK_IPAR_INTPNT_REGULARIZATION_USE\"\n#define MSK_IPAR_INTPNT_SCALING_                            \"MSK_IPAR_INTPNT_SCALING\"\n#define MSK_IPAR_INTPNT_SOLVE_FORM_                         \"MSK_IPAR_INTPNT_SOLVE_FORM\"\n#define MSK_IPAR_INTPNT_STARTING_POINT_                     \"MSK_IPAR_INTPNT_STARTING_POINT\"\n#define MSK_IPAR_LICENSE_DEBUG_                             \"MSK_IPAR_LICENSE_DEBUG\"\n#define MSK_IPAR_LICENSE_PAUSE_TIME_                        \"MSK_IPAR_LICENSE_PAUSE_TIME\"\n#define MSK_IPAR_LICENSE_SUPPRESS_EXPIRE_WRNS_              \"MSK_IPAR_LICENSE_SUPPRESS_EXPIRE_WRNS\"\n#define MSK_IPAR_LICENSE_TRH_EXPIRY_WRN_                    \"MSK_IPAR_LICENSE_TRH_EXPIRY_WRN\"\n#define MSK_IPAR_LICENSE_WAIT_                              \"MSK_IPAR_LICENSE_WAIT\"\n#define MSK_IPAR_LOG_                                       \"MSK_IPAR_LOG\"\n#define MSK_IPAR_LOG_ANA_PRO_                               \"MSK_IPAR_LOG_ANA_PRO\"\n#define MSK_IPAR_LOG_BI_                                    \"MSK_IPAR_LOG_BI\"\n#define MSK_IPAR_LOG_BI_FREQ_                               \"MSK_IPAR_LOG_BI_FREQ\"\n#define MSK_IPAR_LOG_CUT_SECOND_OPT_                        \"MSK_IPAR_LOG_CUT_SECOND_OPT\"\n#define MSK_IPAR_LOG_EXPAND_                                \"MSK_IPAR_LOG_EXPAND\"\n#define MSK_IPAR_LOG_FEAS_REPAIR_                           \"MSK_IPAR_LOG_FEAS_REPAIR\"\n#define MSK_IPAR_LOG_FILE_                                  \"MSK_IPAR_LOG_FILE\"\n#define MSK_IPAR_LOG_INCLUDE_SUMMARY_                       \"MSK_IPAR_LOG_INCLUDE_SUMMARY\"\n#define MSK_IPAR_LOG_INFEAS_ANA_                            \"MSK_IPAR_LOG_INFEAS_ANA\"\n#define MSK_IPAR_LOG_INTPNT_                                \"MSK_IPAR_LOG_INTPNT\"\n#define MSK_IPAR_LOG_LOCAL_INFO_                            \"MSK_IPAR_LOG_LOCAL_INFO\"\n#define MSK_IPAR_LOG_MIO_                                   \"MSK_IPAR_LOG_MIO\"\n#define MSK_IPAR_LOG_MIO_FREQ_                              \"MSK_IPAR_LOG_MIO_FREQ\"\n#define MSK_IPAR_LOG_ORDER_                                 \"MSK_IPAR_LOG_ORDER\"\n#define MSK_IPAR_LOG_PRESOLVE_                              \"MSK_IPAR_LOG_PRESOLVE\"\n#define MSK_IPAR_LOG_SENSITIVITY_                           \"MSK_IPAR_LOG_SENSITIVITY\"\n#define MSK_IPAR_LOG_SENSITIVITY_OPT_                       \"MSK_IPAR_LOG_SENSITIVITY_OPT\"\n#define MSK_IPAR_LOG_SIM_                                   \"MSK_IPAR_LOG_SIM\"\n#define MSK_IPAR_LOG_SIM_FREQ_                              \"MSK_IPAR_LOG_SIM_FREQ\"\n#define MSK_IPAR_LOG_SIM_FREQ_GIGA_TICKS_                   \"MSK_IPAR_LOG_SIM_FREQ_GIGA_TICKS\"\n#define MSK_IPAR_LOG_STORAGE_                               \"MSK_IPAR_LOG_STORAGE\"\n#define MSK_IPAR_MAX_NUM_WARNINGS_                          \"MSK_IPAR_MAX_NUM_WARNINGS\"\n#define MSK_IPAR_MIO_BRANCH_DIR_                            \"MSK_IPAR_MIO_BRANCH_DIR\"\n#define MSK_IPAR_MIO_CONFLICT_ANALYSIS_LEVEL_               \"MSK_IPAR_MIO_CONFLICT_ANALYSIS_LEVEL\"\n#define MSK_IPAR_MIO_CONIC_OUTER_APPROXIMATION_             \"MSK_IPAR_MIO_CONIC_OUTER_APPROXIMATION\"\n#define MSK_IPAR_MIO_CONSTRUCT_SOL_                         \"MSK_IPAR_MIO_CONSTRUCT_SOL\"\n#define MSK_IPAR_MIO_CROSSOVER_MAX_NODES_                   \"MSK_IPAR_MIO_CROSSOVER_MAX_NODES\"\n#define MSK_IPAR_MIO_CUT_CLIQUE_                            \"MSK_IPAR_MIO_CUT_CLIQUE\"\n#define MSK_IPAR_MIO_CUT_CMIR_                              \"MSK_IPAR_MIO_CUT_CMIR\"\n#define MSK_IPAR_MIO_CUT_GMI_                               \"MSK_IPAR_MIO_CUT_GMI\"\n#define MSK_IPAR_MIO_CUT_IMPLIED_BOUND_                     \"MSK_IPAR_MIO_CUT_IMPLIED_BOUND\"\n#define MSK_IPAR_MIO_CUT_KNAPSACK_COVER_                    \"MSK_IPAR_MIO_CUT_KNAPSACK_COVER\"\n#define MSK_IPAR_MIO_CUT_LIPRO_                             \"MSK_IPAR_MIO_CUT_LIPRO\"\n#define MSK_IPAR_MIO_CUT_SELECTION_LEVEL_                   \"MSK_IPAR_MIO_CUT_SELECTION_LEVEL\"\n#define MSK_IPAR_MIO_DATA_PERMUTATION_METHOD_               \"MSK_IPAR_MIO_DATA_PERMUTATION_METHOD\"\n#define MSK_IPAR_MIO_DUAL_RAY_ANALYSIS_LEVEL_               \"MSK_IPAR_MIO_DUAL_RAY_ANALYSIS_LEVEL\"\n#define MSK_IPAR_MIO_FEASPUMP_LEVEL_                        \"MSK_IPAR_MIO_FEASPUMP_LEVEL\"\n#define MSK_IPAR_MIO_HEURISTIC_LEVEL_                       \"MSK_IPAR_MIO_HEURISTIC_LEVEL\"\n#define MSK_IPAR_MIO_INDEPENDENT_BLOCK_LEVEL_               \"MSK_IPAR_MIO_INDEPENDENT_BLOCK_LEVEL\"\n#define MSK_IPAR_MIO_MAX_NUM_BRANCHES_                      \"MSK_IPAR_MIO_MAX_NUM_BRANCHES\"\n#define MSK_IPAR_MIO_MAX_NUM_RELAXS_                        \"MSK_IPAR_MIO_MAX_NUM_RELAXS\"\n#define MSK_IPAR_MIO_MAX_NUM_RESTARTS_                      \"MSK_IPAR_MIO_MAX_NUM_RESTARTS\"\n#define MSK_IPAR_MIO_MAX_NUM_ROOT_CUT_ROUNDS_               \"MSK_IPAR_MIO_MAX_NUM_ROOT_CUT_ROUNDS\"\n#define MSK_IPAR_MIO_MAX_NUM_SOLUTIONS_                     \"MSK_IPAR_MIO_MAX_NUM_SOLUTIONS\"\n#define MSK_IPAR_MIO_MEMORY_EMPHASIS_LEVEL_                 \"MSK_IPAR_MIO_MEMORY_EMPHASIS_LEVEL\"\n#define MSK_IPAR_MIO_MIN_REL_                               \"MSK_IPAR_MIO_MIN_REL\"\n#define MSK_IPAR_MIO_MODE_                                  \"MSK_IPAR_MIO_MODE\"\n#define MSK_IPAR_MIO_NODE_OPTIMIZER_                        \"MSK_IPAR_MIO_NODE_OPTIMIZER\"\n#define MSK_IPAR_MIO_NODE_SELECTION_                        \"MSK_IPAR_MIO_NODE_SELECTION\"\n#define MSK_IPAR_MIO_NUMERICAL_EMPHASIS_LEVEL_              \"MSK_IPAR_MIO_NUMERICAL_EMPHASIS_LEVEL\"\n#define MSK_IPAR_MIO_OPT_FACE_MAX_NODES_                    \"MSK_IPAR_MIO_OPT_FACE_MAX_NODES\"\n#define MSK_IPAR_MIO_PERSPECTIVE_REFORMULATE_               \"MSK_IPAR_MIO_PERSPECTIVE_REFORMULATE\"\n#define MSK_IPAR_MIO_PRESOLVE_AGGREGATOR_USE_               \"MSK_IPAR_MIO_PRESOLVE_AGGREGATOR_USE\"\n#define MSK_IPAR_MIO_PROBING_LEVEL_                         \"MSK_IPAR_MIO_PROBING_LEVEL\"\n#define MSK_IPAR_MIO_PROPAGATE_OBJECTIVE_CONSTRAINT_        \"MSK_IPAR_MIO_PROPAGATE_OBJECTIVE_CONSTRAINT\"\n#define MSK_IPAR_MIO_QCQO_REFORMULATION_METHOD_             \"MSK_IPAR_MIO_QCQO_REFORMULATION_METHOD\"\n#define MSK_IPAR_MIO_RENS_MAX_NODES_                        \"MSK_IPAR_MIO_RENS_MAX_NODES\"\n#define MSK_IPAR_MIO_RINS_MAX_NODES_                        \"MSK_IPAR_MIO_RINS_MAX_NODES\"\n#define MSK_IPAR_MIO_ROOT_OPTIMIZER_                        \"MSK_IPAR_MIO_ROOT_OPTIMIZER\"\n#define MSK_IPAR_MIO_SEED_                                  \"MSK_IPAR_MIO_SEED\"\n#define MSK_IPAR_MIO_SYMMETRY_LEVEL_                        \"MSK_IPAR_MIO_SYMMETRY_LEVEL\"\n#define MSK_IPAR_MIO_VAR_SELECTION_                         \"MSK_IPAR_MIO_VAR_SELECTION\"\n#define MSK_IPAR_MIO_VB_DETECTION_LEVEL_                    \"MSK_IPAR_MIO_VB_DETECTION_LEVEL\"\n#define MSK_IPAR_MT_SPINCOUNT_                              \"MSK_IPAR_MT_SPINCOUNT\"\n#define MSK_IPAR_NG_                                        \"MSK_IPAR_NG\"\n#define MSK_IPAR_NUM_THREADS_                               \"MSK_IPAR_NUM_THREADS\"\n#define MSK_IPAR_OPF_WRITE_HEADER_                          \"MSK_IPAR_OPF_WRITE_HEADER\"\n#define MSK_IPAR_OPF_WRITE_HINTS_                           \"MSK_IPAR_OPF_WRITE_HINTS\"\n#define MSK_IPAR_OPF_WRITE_LINE_LENGTH_                     \"MSK_IPAR_OPF_WRITE_LINE_LENGTH\"\n#define MSK_IPAR_OPF_WRITE_PARAMETERS_                      \"MSK_IPAR_OPF_WRITE_PARAMETERS\"\n#define MSK_IPAR_OPF_WRITE_PROBLEM_                         \"MSK_IPAR_OPF_WRITE_PROBLEM\"\n#define MSK_IPAR_OPF_WRITE_SOL_BAS_                         \"MSK_IPAR_OPF_WRITE_SOL_BAS\"\n#define MSK_IPAR_OPF_WRITE_SOL_ITG_                         \"MSK_IPAR_OPF_WRITE_SOL_ITG\"\n#define MSK_IPAR_OPF_WRITE_SOL_ITR_                         \"MSK_IPAR_OPF_WRITE_SOL_ITR\"\n#define MSK_IPAR_OPF_WRITE_SOLUTIONS_                       \"MSK_IPAR_OPF_WRITE_SOLUTIONS\"\n#define MSK_IPAR_OPTIMIZER_                                 \"MSK_IPAR_OPTIMIZER\"\n#define MSK_IPAR_PARAM_READ_CASE_NAME_                      \"MSK_IPAR_PARAM_READ_CASE_NAME\"\n#define MSK_IPAR_PARAM_READ_IGN_ERROR_                      \"MSK_IPAR_PARAM_READ_IGN_ERROR\"\n#define MSK_IPAR_PRESOLVE_ELIMINATOR_MAX_FILL_              \"MSK_IPAR_PRESOLVE_ELIMINATOR_MAX_FILL\"\n#define MSK_IPAR_PRESOLVE_ELIMINATOR_MAX_NUM_TRIES_         \"MSK_IPAR_PRESOLVE_ELIMINATOR_MAX_NUM_TRIES\"\n#define MSK_IPAR_PRESOLVE_LINDEP_ABS_WORK_TRH_              \"MSK_IPAR_PRESOLVE_LINDEP_ABS_WORK_TRH\"\n#define MSK_IPAR_PRESOLVE_LINDEP_NEW_                       \"MSK_IPAR_PRESOLVE_LINDEP_NEW\"\n#define MSK_IPAR_PRESOLVE_LINDEP_REL_WORK_TRH_              \"MSK_IPAR_PRESOLVE_LINDEP_REL_WORK_TRH\"\n#define MSK_IPAR_PRESOLVE_LINDEP_USE_                       \"MSK_IPAR_PRESOLVE_LINDEP_USE\"\n#define MSK_IPAR_PRESOLVE_MAX_NUM_PASS_                     \"MSK_IPAR_PRESOLVE_MAX_NUM_PASS\"\n#define MSK_IPAR_PRESOLVE_MAX_NUM_REDUCTIONS_               \"MSK_IPAR_PRESOLVE_MAX_NUM_REDUCTIONS\"\n#define MSK_IPAR_PRESOLVE_USE_                              \"MSK_IPAR_PRESOLVE_USE\"\n#define MSK_IPAR_PRIMAL_REPAIR_OPTIMIZER_                   \"MSK_IPAR_PRIMAL_REPAIR_OPTIMIZER\"\n#define MSK_IPAR_PTF_WRITE_PARAMETERS_                      \"MSK_IPAR_PTF_WRITE_PARAMETERS\"\n#define MSK_IPAR_PTF_WRITE_SINGLE_PSD_TERMS_                \"MSK_IPAR_PTF_WRITE_SINGLE_PSD_TERMS\"\n#define MSK_IPAR_PTF_WRITE_SOLUTIONS_                       \"MSK_IPAR_PTF_WRITE_SOLUTIONS\"\n#define MSK_IPAR_PTF_WRITE_TRANSFORM_                       \"MSK_IPAR_PTF_WRITE_TRANSFORM\"\n#define MSK_IPAR_READ_ASYNC_                                \"MSK_IPAR_READ_ASYNC\"\n#define MSK_IPAR_READ_DEBUG_                                \"MSK_IPAR_READ_DEBUG\"\n#define MSK_IPAR_READ_KEEP_FREE_CON_                        \"MSK_IPAR_READ_KEEP_FREE_CON\"\n#define MSK_IPAR_READ_MPS_FORMAT_                           \"MSK_IPAR_READ_MPS_FORMAT\"\n#define MSK_IPAR_READ_MPS_WIDTH_                            \"MSK_IPAR_READ_MPS_WIDTH\"\n#define MSK_IPAR_READ_TASK_IGNORE_PARAM_                    \"MSK_IPAR_READ_TASK_IGNORE_PARAM\"\n#define MSK_IPAR_REMOTE_USE_COMPRESSION_                    \"MSK_IPAR_REMOTE_USE_COMPRESSION\"\n#define MSK_IPAR_REMOVE_UNUSED_SOLUTIONS_                   \"MSK_IPAR_REMOVE_UNUSED_SOLUTIONS\"\n#define MSK_IPAR_SENSITIVITY_ALL_                           \"MSK_IPAR_SENSITIVITY_ALL\"\n#define MSK_IPAR_SENSITIVITY_TYPE_                          \"MSK_IPAR_SENSITIVITY_TYPE\"\n#define MSK_IPAR_SIM_BASIS_FACTOR_USE_                      \"MSK_IPAR_SIM_BASIS_FACTOR_USE\"\n#define MSK_IPAR_SIM_DEGEN_                                 \"MSK_IPAR_SIM_DEGEN\"\n#define MSK_IPAR_SIM_DETECT_PWL_                            \"MSK_IPAR_SIM_DETECT_PWL\"\n#define MSK_IPAR_SIM_DUAL_CRASH_                            \"MSK_IPAR_SIM_DUAL_CRASH\"\n#define MSK_IPAR_SIM_DUAL_PHASEONE_METHOD_                  \"MSK_IPAR_SIM_DUAL_PHASEONE_METHOD\"\n#define MSK_IPAR_SIM_DUAL_RESTRICT_SELECTION_               \"MSK_IPAR_SIM_DUAL_RESTRICT_SELECTION\"\n#define MSK_IPAR_SIM_DUAL_SELECTION_                        \"MSK_IPAR_SIM_DUAL_SELECTION\"\n#define MSK_IPAR_SIM_EXPLOIT_DUPVEC_                        \"MSK_IPAR_SIM_EXPLOIT_DUPVEC\"\n#define MSK_IPAR_SIM_HOTSTART_                              \"MSK_IPAR_SIM_HOTSTART\"\n#define MSK_IPAR_SIM_HOTSTART_LU_                           \"MSK_IPAR_SIM_HOTSTART_LU\"\n#define MSK_IPAR_SIM_MAX_ITERATIONS_                        \"MSK_IPAR_SIM_MAX_ITERATIONS\"\n#define MSK_IPAR_SIM_MAX_NUM_SETBACKS_                      \"MSK_IPAR_SIM_MAX_NUM_SETBACKS\"\n#define MSK_IPAR_SIM_NON_SINGULAR_                          \"MSK_IPAR_SIM_NON_SINGULAR\"\n#define MSK_IPAR_SIM_PRECISION_                             \"MSK_IPAR_SIM_PRECISION\"\n#define MSK_IPAR_SIM_PRECISION_BOOST_                       \"MSK_IPAR_SIM_PRECISION_BOOST\"\n#define MSK_IPAR_SIM_PRIMAL_CRASH_                          \"MSK_IPAR_SIM_PRIMAL_CRASH\"\n#define MSK_IPAR_SIM_PRIMAL_PHASEONE_METHOD_                \"MSK_IPAR_SIM_PRIMAL_PHASEONE_METHOD\"\n#define MSK_IPAR_SIM_PRIMAL_RESTRICT_SELECTION_             \"MSK_IPAR_SIM_PRIMAL_RESTRICT_SELECTION\"\n#define MSK_IPAR_SIM_PRIMAL_SELECTION_                      \"MSK_IPAR_SIM_PRIMAL_SELECTION\"\n#define MSK_IPAR_SIM_REFACTOR_FREQ_                         \"MSK_IPAR_SIM_REFACTOR_FREQ\"\n#define MSK_IPAR_SIM_REFORMULATION_                         \"MSK_IPAR_SIM_REFORMULATION\"\n#define MSK_IPAR_SIM_SAVE_LU_                               \"MSK_IPAR_SIM_SAVE_LU\"\n#define MSK_IPAR_SIM_SCALING_                               \"MSK_IPAR_SIM_SCALING\"\n#define MSK_IPAR_SIM_SCALING_METHOD_                        \"MSK_IPAR_SIM_SCALING_METHOD\"\n#define MSK_IPAR_SIM_SEED_                                  \"MSK_IPAR_SIM_SEED\"\n#define MSK_IPAR_SIM_SOLVE_FORM_                            \"MSK_IPAR_SIM_SOLVE_FORM\"\n#define MSK_IPAR_SIM_SWITCH_OPTIMIZER_                      \"MSK_IPAR_SIM_SWITCH_OPTIMIZER\"\n#define MSK_IPAR_SOL_FILTER_KEEP_BASIC_                     \"MSK_IPAR_SOL_FILTER_KEEP_BASIC\"\n#define MSK_IPAR_SOL_READ_NAME_WIDTH_                       \"MSK_IPAR_SOL_READ_NAME_WIDTH\"\n#define MSK_IPAR_SOL_READ_WIDTH_                            \"MSK_IPAR_SOL_READ_WIDTH\"\n#define MSK_IPAR_TIMING_LEVEL_                              \"MSK_IPAR_TIMING_LEVEL\"\n#define MSK_IPAR_WRITE_ASYNC_                               \"MSK_IPAR_WRITE_ASYNC\"\n#define MSK_IPAR_WRITE_BAS_CONSTRAINTS_                     \"MSK_IPAR_WRITE_BAS_CONSTRAINTS\"\n#define MSK_IPAR_WRITE_BAS_HEAD_                            \"MSK_IPAR_WRITE_BAS_HEAD\"\n#define MSK_IPAR_WRITE_BAS_VARIABLES_                       \"MSK_IPAR_WRITE_BAS_VARIABLES\"\n#define MSK_IPAR_WRITE_COMPRESSION_                         \"MSK_IPAR_WRITE_COMPRESSION\"\n#define MSK_IPAR_WRITE_FREE_CON_                            \"MSK_IPAR_WRITE_FREE_CON\"\n#define MSK_IPAR_WRITE_GENERIC_NAMES_                       \"MSK_IPAR_WRITE_GENERIC_NAMES\"\n#define MSK_IPAR_WRITE_IGNORE_INCOMPATIBLE_ITEMS_           \"MSK_IPAR_WRITE_IGNORE_INCOMPATIBLE_ITEMS\"\n#define MSK_IPAR_WRITE_INT_CONSTRAINTS_                     \"MSK_IPAR_WRITE_INT_CONSTRAINTS\"\n#define MSK_IPAR_WRITE_INT_HEAD_                            \"MSK_IPAR_WRITE_INT_HEAD\"\n#define MSK_IPAR_WRITE_INT_VARIABLES_                       \"MSK_IPAR_WRITE_INT_VARIABLES\"\n#define MSK_IPAR_WRITE_JSON_INDENTATION_                    \"MSK_IPAR_WRITE_JSON_INDENTATION\"\n#define MSK_IPAR_WRITE_LP_FULL_OBJ_                         \"MSK_IPAR_WRITE_LP_FULL_OBJ\"\n#define MSK_IPAR_WRITE_LP_LINE_WIDTH_                       \"MSK_IPAR_WRITE_LP_LINE_WIDTH\"\n#define MSK_IPAR_WRITE_MPS_FORMAT_                          \"MSK_IPAR_WRITE_MPS_FORMAT\"\n#define MSK_IPAR_WRITE_MPS_INT_                             \"MSK_IPAR_WRITE_MPS_INT\"\n#define MSK_IPAR_WRITE_SOL_BARVARIABLES_                    \"MSK_IPAR_WRITE_SOL_BARVARIABLES\"\n#define MSK_IPAR_WRITE_SOL_CONSTRAINTS_                     \"MSK_IPAR_WRITE_SOL_CONSTRAINTS\"\n#define MSK_IPAR_WRITE_SOL_HEAD_                            \"MSK_IPAR_WRITE_SOL_HEAD\"\n#define MSK_IPAR_WRITE_SOL_IGNORE_INVALID_NAMES_            \"MSK_IPAR_WRITE_SOL_IGNORE_INVALID_NAMES\"\n#define MSK_IPAR_WRITE_SOL_VARIABLES_                       \"MSK_IPAR_WRITE_SOL_VARIABLES\"\n\n#define MSK_IINF_ANA_PRO_NUM_CON_                           \"MSK_IINF_ANA_PRO_NUM_CON\"\n#define MSK_IINF_ANA_PRO_NUM_CON_EQ_                        \"MSK_IINF_ANA_PRO_NUM_CON_EQ\"\n#define MSK_IINF_ANA_PRO_NUM_CON_FR_                        \"MSK_IINF_ANA_PRO_NUM_CON_FR\"\n#define MSK_IINF_ANA_PRO_NUM_CON_LO_                        \"MSK_IINF_ANA_PRO_NUM_CON_LO\"\n#define MSK_IINF_ANA_PRO_NUM_CON_RA_                        \"MSK_IINF_ANA_PRO_NUM_CON_RA\"\n#define MSK_IINF_ANA_PRO_NUM_CON_UP_                        \"MSK_IINF_ANA_PRO_NUM_CON_UP\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_                           \"MSK_IINF_ANA_PRO_NUM_VAR\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_BIN_                       \"MSK_IINF_ANA_PRO_NUM_VAR_BIN\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_CONT_                      \"MSK_IINF_ANA_PRO_NUM_VAR_CONT\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_EQ_                        \"MSK_IINF_ANA_PRO_NUM_VAR_EQ\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_FR_                        \"MSK_IINF_ANA_PRO_NUM_VAR_FR\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_INT_                       \"MSK_IINF_ANA_PRO_NUM_VAR_INT\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_LO_                        \"MSK_IINF_ANA_PRO_NUM_VAR_LO\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_RA_                        \"MSK_IINF_ANA_PRO_NUM_VAR_RA\"\n#define MSK_IINF_ANA_PRO_NUM_VAR_UP_                        \"MSK_IINF_ANA_PRO_NUM_VAR_UP\"\n#define MSK_IINF_FOLDING_APPLIED_                           \"MSK_IINF_FOLDING_APPLIED\"\n#define MSK_IINF_INTPNT_FACTOR_DIM_DENSE_                   \"MSK_IINF_INTPNT_FACTOR_DIM_DENSE\"\n#define MSK_IINF_INTPNT_ITER_                               \"MSK_IINF_INTPNT_ITER\"\n#define MSK_IINF_INTPNT_NUM_THREADS_                        \"MSK_IINF_INTPNT_NUM_THREADS\"\n#define MSK_IINF_INTPNT_SOLVE_DUAL_                         \"MSK_IINF_INTPNT_SOLVE_DUAL\"\n#define MSK_IINF_MIO_ABSGAP_SATISFIED_                      \"MSK_IINF_MIO_ABSGAP_SATISFIED\"\n#define MSK_IINF_MIO_CLIQUE_TABLE_SIZE_                     \"MSK_IINF_MIO_CLIQUE_TABLE_SIZE\"\n#define MSK_IINF_MIO_CONSTRUCT_SOLUTION_                    \"MSK_IINF_MIO_CONSTRUCT_SOLUTION\"\n#define MSK_IINF_MIO_FINAL_NUMBIN_                          \"MSK_IINF_MIO_FINAL_NUMBIN\"\n#define MSK_IINF_MIO_FINAL_NUMBINCONEVAR_                   \"MSK_IINF_MIO_FINAL_NUMBINCONEVAR\"\n#define MSK_IINF_MIO_FINAL_NUMCON_                          \"MSK_IINF_MIO_FINAL_NUMCON\"\n#define MSK_IINF_MIO_FINAL_NUMCONE_                         \"MSK_IINF_MIO_FINAL_NUMCONE\"\n#define MSK_IINF_MIO_FINAL_NUMCONEVAR_                      \"MSK_IINF_MIO_FINAL_NUMCONEVAR\"\n#define MSK_IINF_MIO_FINAL_NUMCONT_                         \"MSK_IINF_MIO_FINAL_NUMCONT\"\n#define MSK_IINF_MIO_FINAL_NUMCONTCONEVAR_                  \"MSK_IINF_MIO_FINAL_NUMCONTCONEVAR\"\n#define MSK_IINF_MIO_FINAL_NUMDEXPCONES_                    \"MSK_IINF_MIO_FINAL_NUMDEXPCONES\"\n#define MSK_IINF_MIO_FINAL_NUMDJC_                          \"MSK_IINF_MIO_FINAL_NUMDJC\"\n#define MSK_IINF_MIO_FINAL_NUMDPOWCONES_                    \"MSK_IINF_MIO_FINAL_NUMDPOWCONES\"\n#define MSK_IINF_MIO_FINAL_NUMINT_                          \"MSK_IINF_MIO_FINAL_NUMINT\"\n#define MSK_IINF_MIO_FINAL_NUMINTCONEVAR_                   \"MSK_IINF_MIO_FINAL_NUMINTCONEVAR\"\n#define MSK_IINF_MIO_FINAL_NUMPEXPCONES_                    \"MSK_IINF_MIO_FINAL_NUMPEXPCONES\"\n#define MSK_IINF_MIO_FINAL_NUMPPOWCONES_                    \"MSK_IINF_MIO_FINAL_NUMPPOWCONES\"\n#define MSK_IINF_MIO_FINAL_NUMQCONES_                       \"MSK_IINF_MIO_FINAL_NUMQCONES\"\n#define MSK_IINF_MIO_FINAL_NUMRQCONES_                      \"MSK_IINF_MIO_FINAL_NUMRQCONES\"\n#define MSK_IINF_MIO_FINAL_NUMVAR_                          \"MSK_IINF_MIO_FINAL_NUMVAR\"\n#define MSK_IINF_MIO_INITIAL_FEASIBLE_SOLUTION_             \"MSK_IINF_MIO_INITIAL_FEASIBLE_SOLUTION\"\n#define MSK_IINF_MIO_NODE_DEPTH_                            \"MSK_IINF_MIO_NODE_DEPTH\"\n#define MSK_IINF_MIO_NUM_ACTIVE_NODES_                      \"MSK_IINF_MIO_NUM_ACTIVE_NODES\"\n#define MSK_IINF_MIO_NUM_ACTIVE_ROOT_CUTS_                  \"MSK_IINF_MIO_NUM_ACTIVE_ROOT_CUTS\"\n#define MSK_IINF_MIO_NUM_BLOCKS_SOLVED_IN_BB_               \"MSK_IINF_MIO_NUM_BLOCKS_SOLVED_IN_BB\"\n#define MSK_IINF_MIO_NUM_BLOCKS_SOLVED_IN_PRESOLVE_         \"MSK_IINF_MIO_NUM_BLOCKS_SOLVED_IN_PRESOLVE\"\n#define MSK_IINF_MIO_NUM_BRANCH_                            \"MSK_IINF_MIO_NUM_BRANCH\"\n#define MSK_IINF_MIO_NUM_INT_SOLUTIONS_                     \"MSK_IINF_MIO_NUM_INT_SOLUTIONS\"\n#define MSK_IINF_MIO_NUM_RELAX_                             \"MSK_IINF_MIO_NUM_RELAX\"\n#define MSK_IINF_MIO_NUM_REPEATED_PRESOLVE_                 \"MSK_IINF_MIO_NUM_REPEATED_PRESOLVE\"\n#define MSK_IINF_MIO_NUM_RESTARTS_                          \"MSK_IINF_MIO_NUM_RESTARTS\"\n#define MSK_IINF_MIO_NUM_ROOT_CUT_ROUNDS_                   \"MSK_IINF_MIO_NUM_ROOT_CUT_ROUNDS\"\n#define MSK_IINF_MIO_NUM_SELECTED_CLIQUE_CUTS_              \"MSK_IINF_MIO_NUM_SELECTED_CLIQUE_CUTS\"\n#define MSK_IINF_MIO_NUM_SELECTED_CMIR_CUTS_                \"MSK_IINF_MIO_NUM_SELECTED_CMIR_CUTS\"\n#define MSK_IINF_MIO_NUM_SELECTED_GOMORY_CUTS_              \"MSK_IINF_MIO_NUM_SELECTED_GOMORY_CUTS\"\n#define MSK_IINF_MIO_NUM_SELECTED_IMPLIED_BOUND_CUTS_       \"MSK_IINF_MIO_NUM_SELECTED_IMPLIED_BOUND_CUTS\"\n#define MSK_IINF_MIO_NUM_SELECTED_KNAPSACK_COVER_CUTS_      \"MSK_IINF_MIO_NUM_SELECTED_KNAPSACK_COVER_CUTS\"\n#define MSK_IINF_MIO_NUM_SELECTED_LIPRO_CUTS_               \"MSK_IINF_MIO_NUM_SELECTED_LIPRO_CUTS\"\n#define MSK_IINF_MIO_NUM_SEPARATED_CLIQUE_CUTS_             \"MSK_IINF_MIO_NUM_SEPARATED_CLIQUE_CUTS\"\n#define MSK_IINF_MIO_NUM_SEPARATED_CMIR_CUTS_               \"MSK_IINF_MIO_NUM_SEPARATED_CMIR_CUTS\"\n#define MSK_IINF_MIO_NUM_SEPARATED_GOMORY_CUTS_             \"MSK_IINF_MIO_NUM_SEPARATED_GOMORY_CUTS\"\n#define MSK_IINF_MIO_NUM_SEPARATED_IMPLIED_BOUND_CUTS_      \"MSK_IINF_MIO_NUM_SEPARATED_IMPLIED_BOUND_CUTS\"\n#define MSK_IINF_MIO_NUM_SEPARATED_KNAPSACK_COVER_CUTS_     \"MSK_IINF_MIO_NUM_SEPARATED_KNAPSACK_COVER_CUTS\"\n#define MSK_IINF_MIO_NUM_SEPARATED_LIPRO_CUTS_              \"MSK_IINF_MIO_NUM_SEPARATED_LIPRO_CUTS\"\n#define MSK_IINF_MIO_NUM_SOLVED_NODES_                      \"MSK_IINF_MIO_NUM_SOLVED_NODES\"\n#define MSK_IINF_MIO_NUMBIN_                                \"MSK_IINF_MIO_NUMBIN\"\n#define MSK_IINF_MIO_NUMBINCONEVAR_                         \"MSK_IINF_MIO_NUMBINCONEVAR\"\n#define MSK_IINF_MIO_NUMCON_                                \"MSK_IINF_MIO_NUMCON\"\n#define MSK_IINF_MIO_NUMCONE_                               \"MSK_IINF_MIO_NUMCONE\"\n#define MSK_IINF_MIO_NUMCONEVAR_                            \"MSK_IINF_MIO_NUMCONEVAR\"\n#define MSK_IINF_MIO_NUMCONT_                               \"MSK_IINF_MIO_NUMCONT\"\n#define MSK_IINF_MIO_NUMCONTCONEVAR_                        \"MSK_IINF_MIO_NUMCONTCONEVAR\"\n#define MSK_IINF_MIO_NUMDEXPCONES_                          \"MSK_IINF_MIO_NUMDEXPCONES\"\n#define MSK_IINF_MIO_NUMDJC_                                \"MSK_IINF_MIO_NUMDJC\"\n#define MSK_IINF_MIO_NUMDPOWCONES_                          \"MSK_IINF_MIO_NUMDPOWCONES\"\n#define MSK_IINF_MIO_NUMINT_                                \"MSK_IINF_MIO_NUMINT\"\n#define MSK_IINF_MIO_NUMINTCONEVAR_                         \"MSK_IINF_MIO_NUMINTCONEVAR\"\n#define MSK_IINF_MIO_NUMPEXPCONES_                          \"MSK_IINF_MIO_NUMPEXPCONES\"\n#define MSK_IINF_MIO_NUMPPOWCONES_                          \"MSK_IINF_MIO_NUMPPOWCONES\"\n#define MSK_IINF_MIO_NUMQCONES_                             \"MSK_IINF_MIO_NUMQCONES\"\n#define MSK_IINF_MIO_NUMRQCONES_                            \"MSK_IINF_MIO_NUMRQCONES\"\n#define MSK_IINF_MIO_NUMVAR_                                \"MSK_IINF_MIO_NUMVAR\"\n#define MSK_IINF_MIO_OBJ_BOUND_DEFINED_                     \"MSK_IINF_MIO_OBJ_BOUND_DEFINED\"\n#define MSK_IINF_MIO_PRESOLVED_NUMBIN_                      \"MSK_IINF_MIO_PRESOLVED_NUMBIN\"\n#define MSK_IINF_MIO_PRESOLVED_NUMBINCONEVAR_               \"MSK_IINF_MIO_PRESOLVED_NUMBINCONEVAR\"\n#define MSK_IINF_MIO_PRESOLVED_NUMCON_                      \"MSK_IINF_MIO_PRESOLVED_NUMCON\"\n#define MSK_IINF_MIO_PRESOLVED_NUMCONE_                     \"MSK_IINF_MIO_PRESOLVED_NUMCONE\"\n#define MSK_IINF_MIO_PRESOLVED_NUMCONEVAR_                  \"MSK_IINF_MIO_PRESOLVED_NUMCONEVAR\"\n#define MSK_IINF_MIO_PRESOLVED_NUMCONT_                     \"MSK_IINF_MIO_PRESOLVED_NUMCONT\"\n#define MSK_IINF_MIO_PRESOLVED_NUMCONTCONEVAR_              \"MSK_IINF_MIO_PRESOLVED_NUMCONTCONEVAR\"\n#define MSK_IINF_MIO_PRESOLVED_NUMDEXPCONES_                \"MSK_IINF_MIO_PRESOLVED_NUMDEXPCONES\"\n#define MSK_IINF_MIO_PRESOLVED_NUMDJC_                      \"MSK_IINF_MIO_PRESOLVED_NUMDJC\"\n#define MSK_IINF_MIO_PRESOLVED_NUMDPOWCONES_                \"MSK_IINF_MIO_PRESOLVED_NUMDPOWCONES\"\n#define MSK_IINF_MIO_PRESOLVED_NUMINT_                      \"MSK_IINF_MIO_PRESOLVED_NUMINT\"\n#define MSK_IINF_MIO_PRESOLVED_NUMINTCONEVAR_               \"MSK_IINF_MIO_PRESOLVED_NUMINTCONEVAR\"\n#define MSK_IINF_MIO_PRESOLVED_NUMPEXPCONES_                \"MSK_IINF_MIO_PRESOLVED_NUMPEXPCONES\"\n#define MSK_IINF_MIO_PRESOLVED_NUMPPOWCONES_                \"MSK_IINF_MIO_PRESOLVED_NUMPPOWCONES\"\n#define MSK_IINF_MIO_PRESOLVED_NUMQCONES_                   \"MSK_IINF_MIO_PRESOLVED_NUMQCONES\"\n#define MSK_IINF_MIO_PRESOLVED_NUMRQCONES_                  \"MSK_IINF_MIO_PRESOLVED_NUMRQCONES\"\n#define MSK_IINF_MIO_PRESOLVED_NUMVAR_                      \"MSK_IINF_MIO_PRESOLVED_NUMVAR\"\n#define MSK_IINF_MIO_RELGAP_SATISFIED_                      \"MSK_IINF_MIO_RELGAP_SATISFIED\"\n#define MSK_IINF_MIO_TOTAL_NUM_SELECTED_CUTS_               \"MSK_IINF_MIO_TOTAL_NUM_SELECTED_CUTS\"\n#define MSK_IINF_MIO_TOTAL_NUM_SEPARATED_CUTS_              \"MSK_IINF_MIO_TOTAL_NUM_SEPARATED_CUTS\"\n#define MSK_IINF_MIO_USER_OBJ_CUT_                          \"MSK_IINF_MIO_USER_OBJ_CUT\"\n#define MSK_IINF_OPT_NUMCON_                                \"MSK_IINF_OPT_NUMCON\"\n#define MSK_IINF_OPT_NUMVAR_                                \"MSK_IINF_OPT_NUMVAR\"\n#define MSK_IINF_OPTIMIZE_RESPONSE_                         \"MSK_IINF_OPTIMIZE_RESPONSE\"\n#define MSK_IINF_PRESOLVE_NUM_PRIMAL_PERTURBATIONS_         \"MSK_IINF_PRESOLVE_NUM_PRIMAL_PERTURBATIONS\"\n#define MSK_IINF_PURIFY_DUAL_SUCCESS_                       \"MSK_IINF_PURIFY_DUAL_SUCCESS\"\n#define MSK_IINF_PURIFY_PRIMAL_SUCCESS_                     \"MSK_IINF_PURIFY_PRIMAL_SUCCESS\"\n#define MSK_IINF_RD_NUMBARVAR_                              \"MSK_IINF_RD_NUMBARVAR\"\n#define MSK_IINF_RD_NUMCON_                                 \"MSK_IINF_RD_NUMCON\"\n#define MSK_IINF_RD_NUMCONE_                                \"MSK_IINF_RD_NUMCONE\"\n#define MSK_IINF_RD_NUMINTVAR_                              \"MSK_IINF_RD_NUMINTVAR\"\n#define MSK_IINF_RD_NUMQ_                                   \"MSK_IINF_RD_NUMQ\"\n#define MSK_IINF_RD_NUMVAR_                                 \"MSK_IINF_RD_NUMVAR\"\n#define MSK_IINF_RD_PROTYPE_                                \"MSK_IINF_RD_PROTYPE\"\n#define MSK_IINF_SIM_DUAL_DEG_ITER_                         \"MSK_IINF_SIM_DUAL_DEG_ITER\"\n#define MSK_IINF_SIM_DUAL_HOTSTART_                         \"MSK_IINF_SIM_DUAL_HOTSTART\"\n#define MSK_IINF_SIM_DUAL_HOTSTART_LU_                      \"MSK_IINF_SIM_DUAL_HOTSTART_LU\"\n#define MSK_IINF_SIM_DUAL_INF_ITER_                         \"MSK_IINF_SIM_DUAL_INF_ITER\"\n#define MSK_IINF_SIM_DUAL_ITER_                             \"MSK_IINF_SIM_DUAL_ITER\"\n#define MSK_IINF_SIM_NUMCON_                                \"MSK_IINF_SIM_NUMCON\"\n#define MSK_IINF_SIM_NUMVAR_                                \"MSK_IINF_SIM_NUMVAR\"\n#define MSK_IINF_SIM_PRIMAL_DEG_ITER_                       \"MSK_IINF_SIM_PRIMAL_DEG_ITER\"\n#define MSK_IINF_SIM_PRIMAL_HOTSTART_                       \"MSK_IINF_SIM_PRIMAL_HOTSTART\"\n#define MSK_IINF_SIM_PRIMAL_HOTSTART_LU_                    \"MSK_IINF_SIM_PRIMAL_HOTSTART_LU\"\n#define MSK_IINF_SIM_PRIMAL_INF_ITER_                       \"MSK_IINF_SIM_PRIMAL_INF_ITER\"\n#define MSK_IINF_SIM_PRIMAL_ITER_                           \"MSK_IINF_SIM_PRIMAL_ITER\"\n#define MSK_IINF_SIM_SOLVE_DUAL_                            \"MSK_IINF_SIM_SOLVE_DUAL\"\n#define MSK_IINF_SOL_BAS_PROSTA_                            \"MSK_IINF_SOL_BAS_PROSTA\"\n#define MSK_IINF_SOL_BAS_SOLSTA_                            \"MSK_IINF_SOL_BAS_SOLSTA\"\n#define MSK_IINF_SOL_ITG_PROSTA_                            \"MSK_IINF_SOL_ITG_PROSTA\"\n#define MSK_IINF_SOL_ITG_SOLSTA_                            \"MSK_IINF_SOL_ITG_SOLSTA\"\n#define MSK_IINF_SOL_ITR_PROSTA_                            \"MSK_IINF_SOL_ITR_PROSTA\"\n#define MSK_IINF_SOL_ITR_SOLSTA_                            \"MSK_IINF_SOL_ITR_SOLSTA\"\n#define MSK_IINF_STO_NUM_A_REALLOC_                         \"MSK_IINF_STO_NUM_A_REALLOC\"\n\n#define MSK_DINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_DENSITY_ \"MSK_DINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_DENSITY\"\n#define MSK_DINF_BI_CLEAN_TIME_                             \"MSK_DINF_BI_CLEAN_TIME\"\n#define MSK_DINF_BI_DUAL_TIME_                              \"MSK_DINF_BI_DUAL_TIME\"\n#define MSK_DINF_BI_PRIMAL_TIME_                            \"MSK_DINF_BI_PRIMAL_TIME\"\n#define MSK_DINF_BI_TIME_                                   \"MSK_DINF_BI_TIME\"\n#define MSK_DINF_FOLDING_BI_OPTIMIZE_TIME_                  \"MSK_DINF_FOLDING_BI_OPTIMIZE_TIME\"\n#define MSK_DINF_FOLDING_BI_UNFOLD_DUAL_TIME_               \"MSK_DINF_FOLDING_BI_UNFOLD_DUAL_TIME\"\n#define MSK_DINF_FOLDING_BI_UNFOLD_INITIALIZE_TIME_         \"MSK_DINF_FOLDING_BI_UNFOLD_INITIALIZE_TIME\"\n#define MSK_DINF_FOLDING_BI_UNFOLD_PRIMAL_TIME_             \"MSK_DINF_FOLDING_BI_UNFOLD_PRIMAL_TIME\"\n#define MSK_DINF_FOLDING_BI_UNFOLD_TIME_                    \"MSK_DINF_FOLDING_BI_UNFOLD_TIME\"\n#define MSK_DINF_FOLDING_FACTOR_                            \"MSK_DINF_FOLDING_FACTOR\"\n#define MSK_DINF_FOLDING_TIME_                              \"MSK_DINF_FOLDING_TIME\"\n#define MSK_DINF_INTPNT_DUAL_FEAS_                          \"MSK_DINF_INTPNT_DUAL_FEAS\"\n#define MSK_DINF_INTPNT_DUAL_OBJ_                           \"MSK_DINF_INTPNT_DUAL_OBJ\"\n#define MSK_DINF_INTPNT_FACTOR_NUM_FLOPS_                   \"MSK_DINF_INTPNT_FACTOR_NUM_FLOPS\"\n#define MSK_DINF_INTPNT_OPT_STATUS_                         \"MSK_DINF_INTPNT_OPT_STATUS\"\n#define MSK_DINF_INTPNT_ORDER_TIME_                         \"MSK_DINF_INTPNT_ORDER_TIME\"\n#define MSK_DINF_INTPNT_PRIMAL_FEAS_                        \"MSK_DINF_INTPNT_PRIMAL_FEAS\"\n#define MSK_DINF_INTPNT_PRIMAL_OBJ_                         \"MSK_DINF_INTPNT_PRIMAL_OBJ\"\n#define MSK_DINF_INTPNT_TIME_                               \"MSK_DINF_INTPNT_TIME\"\n#define MSK_DINF_MIO_CLIQUE_SELECTION_TIME_                 \"MSK_DINF_MIO_CLIQUE_SELECTION_TIME\"\n#define MSK_DINF_MIO_CLIQUE_SEPARATION_TIME_                \"MSK_DINF_MIO_CLIQUE_SEPARATION_TIME\"\n#define MSK_DINF_MIO_CMIR_SELECTION_TIME_                   \"MSK_DINF_MIO_CMIR_SELECTION_TIME\"\n#define MSK_DINF_MIO_CMIR_SEPARATION_TIME_                  \"MSK_DINF_MIO_CMIR_SEPARATION_TIME\"\n#define MSK_DINF_MIO_CONSTRUCT_SOLUTION_OBJ_                \"MSK_DINF_MIO_CONSTRUCT_SOLUTION_OBJ\"\n#define MSK_DINF_MIO_DUAL_BOUND_AFTER_PRESOLVE_             \"MSK_DINF_MIO_DUAL_BOUND_AFTER_PRESOLVE\"\n#define MSK_DINF_MIO_GMI_SELECTION_TIME_                    \"MSK_DINF_MIO_GMI_SELECTION_TIME\"\n#define MSK_DINF_MIO_GMI_SEPARATION_TIME_                   \"MSK_DINF_MIO_GMI_SEPARATION_TIME\"\n#define MSK_DINF_MIO_IMPLIED_BOUND_SELECTION_TIME_          \"MSK_DINF_MIO_IMPLIED_BOUND_SELECTION_TIME\"\n#define MSK_DINF_MIO_IMPLIED_BOUND_SEPARATION_TIME_         \"MSK_DINF_MIO_IMPLIED_BOUND_SEPARATION_TIME\"\n#define MSK_DINF_MIO_INITIAL_FEASIBLE_SOLUTION_OBJ_         \"MSK_DINF_MIO_INITIAL_FEASIBLE_SOLUTION_OBJ\"\n#define MSK_DINF_MIO_KNAPSACK_COVER_SELECTION_TIME_         \"MSK_DINF_MIO_KNAPSACK_COVER_SELECTION_TIME\"\n#define MSK_DINF_MIO_KNAPSACK_COVER_SEPARATION_TIME_        \"MSK_DINF_MIO_KNAPSACK_COVER_SEPARATION_TIME\"\n#define MSK_DINF_MIO_LIPRO_SELECTION_TIME_                  \"MSK_DINF_MIO_LIPRO_SELECTION_TIME\"\n#define MSK_DINF_MIO_LIPRO_SEPARATION_TIME_                 \"MSK_DINF_MIO_LIPRO_SEPARATION_TIME\"\n#define MSK_DINF_MIO_OBJ_ABS_GAP_                           \"MSK_DINF_MIO_OBJ_ABS_GAP\"\n#define MSK_DINF_MIO_OBJ_BOUND_                             \"MSK_DINF_MIO_OBJ_BOUND\"\n#define MSK_DINF_MIO_OBJ_INT_                               \"MSK_DINF_MIO_OBJ_INT\"\n#define MSK_DINF_MIO_OBJ_REL_GAP_                           \"MSK_DINF_MIO_OBJ_REL_GAP\"\n#define MSK_DINF_MIO_PROBING_TIME_                          \"MSK_DINF_MIO_PROBING_TIME\"\n#define MSK_DINF_MIO_ROOT_CUT_SELECTION_TIME_               \"MSK_DINF_MIO_ROOT_CUT_SELECTION_TIME\"\n#define MSK_DINF_MIO_ROOT_CUT_SEPARATION_TIME_              \"MSK_DINF_MIO_ROOT_CUT_SEPARATION_TIME\"\n#define MSK_DINF_MIO_ROOT_OPTIMIZER_TIME_                   \"MSK_DINF_MIO_ROOT_OPTIMIZER_TIME\"\n#define MSK_DINF_MIO_ROOT_PRESOLVE_TIME_                    \"MSK_DINF_MIO_ROOT_PRESOLVE_TIME\"\n#define MSK_DINF_MIO_ROOT_TIME_                             \"MSK_DINF_MIO_ROOT_TIME\"\n#define MSK_DINF_MIO_SYMMETRY_DETECTION_TIME_               \"MSK_DINF_MIO_SYMMETRY_DETECTION_TIME\"\n#define MSK_DINF_MIO_SYMMETRY_FACTOR_                       \"MSK_DINF_MIO_SYMMETRY_FACTOR\"\n#define MSK_DINF_MIO_TIME_                                  \"MSK_DINF_MIO_TIME\"\n#define MSK_DINF_MIO_USER_OBJ_CUT_                          \"MSK_DINF_MIO_USER_OBJ_CUT\"\n#define MSK_DINF_OPTIMIZER_TICKS_                           \"MSK_DINF_OPTIMIZER_TICKS\"\n#define MSK_DINF_OPTIMIZER_TIME_                            \"MSK_DINF_OPTIMIZER_TIME\"\n#define MSK_DINF_PRESOLVE_ELI_TIME_                         \"MSK_DINF_PRESOLVE_ELI_TIME\"\n#define MSK_DINF_PRESOLVE_LINDEP_TIME_                      \"MSK_DINF_PRESOLVE_LINDEP_TIME\"\n#define MSK_DINF_PRESOLVE_TIME_                             \"MSK_DINF_PRESOLVE_TIME\"\n#define MSK_DINF_PRESOLVE_TOTAL_PRIMAL_PERTURBATION_        \"MSK_DINF_PRESOLVE_TOTAL_PRIMAL_PERTURBATION\"\n#define MSK_DINF_PRIMAL_REPAIR_PENALTY_OBJ_                 \"MSK_DINF_PRIMAL_REPAIR_PENALTY_OBJ\"\n#define MSK_DINF_QCQO_REFORMULATE_MAX_PERTURBATION_         \"MSK_DINF_QCQO_REFORMULATE_MAX_PERTURBATION\"\n#define MSK_DINF_QCQO_REFORMULATE_TIME_                     \"MSK_DINF_QCQO_REFORMULATE_TIME\"\n#define MSK_DINF_QCQO_REFORMULATE_WORST_CHOLESKY_COLUMN_SCALING_ \"MSK_DINF_QCQO_REFORMULATE_WORST_CHOLESKY_COLUMN_SCALING\"\n#define MSK_DINF_QCQO_REFORMULATE_WORST_CHOLESKY_DIAG_SCALING_ \"MSK_DINF_QCQO_REFORMULATE_WORST_CHOLESKY_DIAG_SCALING\"\n#define MSK_DINF_READ_DATA_TIME_                            \"MSK_DINF_READ_DATA_TIME\"\n#define MSK_DINF_REMOTE_TIME_                               \"MSK_DINF_REMOTE_TIME\"\n#define MSK_DINF_SIM_DUAL_TIME_                             \"MSK_DINF_SIM_DUAL_TIME\"\n#define MSK_DINF_SIM_FEAS_                                  \"MSK_DINF_SIM_FEAS\"\n#define MSK_DINF_SIM_OBJ_                                   \"MSK_DINF_SIM_OBJ\"\n#define MSK_DINF_SIM_PRIMAL_TIME_                           \"MSK_DINF_SIM_PRIMAL_TIME\"\n#define MSK_DINF_SIM_TIME_                                  \"MSK_DINF_SIM_TIME\"\n#define MSK_DINF_SOL_BAS_DUAL_OBJ_                          \"MSK_DINF_SOL_BAS_DUAL_OBJ\"\n#define MSK_DINF_SOL_BAS_DVIOLCON_                          \"MSK_DINF_SOL_BAS_DVIOLCON\"\n#define MSK_DINF_SOL_BAS_DVIOLVAR_                          \"MSK_DINF_SOL_BAS_DVIOLVAR\"\n#define MSK_DINF_SOL_BAS_NRM_BARX_                          \"MSK_DINF_SOL_BAS_NRM_BARX\"\n#define MSK_DINF_SOL_BAS_NRM_SLC_                           \"MSK_DINF_SOL_BAS_NRM_SLC\"\n#define MSK_DINF_SOL_BAS_NRM_SLX_                           \"MSK_DINF_SOL_BAS_NRM_SLX\"\n#define MSK_DINF_SOL_BAS_NRM_SUC_                           \"MSK_DINF_SOL_BAS_NRM_SUC\"\n#define MSK_DINF_SOL_BAS_NRM_SUX_                           \"MSK_DINF_SOL_BAS_NRM_SUX\"\n#define MSK_DINF_SOL_BAS_NRM_XC_                            \"MSK_DINF_SOL_BAS_NRM_XC\"\n#define MSK_DINF_SOL_BAS_NRM_XX_                            \"MSK_DINF_SOL_BAS_NRM_XX\"\n#define MSK_DINF_SOL_BAS_NRM_Y_                             \"MSK_DINF_SOL_BAS_NRM_Y\"\n#define MSK_DINF_SOL_BAS_PRIMAL_OBJ_                        \"MSK_DINF_SOL_BAS_PRIMAL_OBJ\"\n#define MSK_DINF_SOL_BAS_PVIOLCON_                          \"MSK_DINF_SOL_BAS_PVIOLCON\"\n#define MSK_DINF_SOL_BAS_PVIOLVAR_                          \"MSK_DINF_SOL_BAS_PVIOLVAR\"\n#define MSK_DINF_SOL_ITG_NRM_BARX_                          \"MSK_DINF_SOL_ITG_NRM_BARX\"\n#define MSK_DINF_SOL_ITG_NRM_XC_                            \"MSK_DINF_SOL_ITG_NRM_XC\"\n#define MSK_DINF_SOL_ITG_NRM_XX_                            \"MSK_DINF_SOL_ITG_NRM_XX\"\n#define MSK_DINF_SOL_ITG_PRIMAL_OBJ_                        \"MSK_DINF_SOL_ITG_PRIMAL_OBJ\"\n#define MSK_DINF_SOL_ITG_PVIOLACC_                          \"MSK_DINF_SOL_ITG_PVIOLACC\"\n#define MSK_DINF_SOL_ITG_PVIOLBARVAR_                       \"MSK_DINF_SOL_ITG_PVIOLBARVAR\"\n#define MSK_DINF_SOL_ITG_PVIOLCON_                          \"MSK_DINF_SOL_ITG_PVIOLCON\"\n#define MSK_DINF_SOL_ITG_PVIOLCONES_                        \"MSK_DINF_SOL_ITG_PVIOLCONES\"\n#define MSK_DINF_SOL_ITG_PVIOLDJC_                          \"MSK_DINF_SOL_ITG_PVIOLDJC\"\n#define MSK_DINF_SOL_ITG_PVIOLITG_                          \"MSK_DINF_SOL_ITG_PVIOLITG\"\n#define MSK_DINF_SOL_ITG_PVIOLVAR_                          \"MSK_DINF_SOL_ITG_PVIOLVAR\"\n#define MSK_DINF_SOL_ITR_DUAL_OBJ_                          \"MSK_DINF_SOL_ITR_DUAL_OBJ\"\n#define MSK_DINF_SOL_ITR_DVIOLACC_                          \"MSK_DINF_SOL_ITR_DVIOLACC\"\n#define MSK_DINF_SOL_ITR_DVIOLBARVAR_                       \"MSK_DINF_SOL_ITR_DVIOLBARVAR\"\n#define MSK_DINF_SOL_ITR_DVIOLCON_                          \"MSK_DINF_SOL_ITR_DVIOLCON\"\n#define MSK_DINF_SOL_ITR_DVIOLCONES_                        \"MSK_DINF_SOL_ITR_DVIOLCONES\"\n#define MSK_DINF_SOL_ITR_DVIOLVAR_                          \"MSK_DINF_SOL_ITR_DVIOLVAR\"\n#define MSK_DINF_SOL_ITR_NRM_BARS_                          \"MSK_DINF_SOL_ITR_NRM_BARS\"\n#define MSK_DINF_SOL_ITR_NRM_BARX_                          \"MSK_DINF_SOL_ITR_NRM_BARX\"\n#define MSK_DINF_SOL_ITR_NRM_SLC_                           \"MSK_DINF_SOL_ITR_NRM_SLC\"\n#define MSK_DINF_SOL_ITR_NRM_SLX_                           \"MSK_DINF_SOL_ITR_NRM_SLX\"\n#define MSK_DINF_SOL_ITR_NRM_SNX_                           \"MSK_DINF_SOL_ITR_NRM_SNX\"\n#define MSK_DINF_SOL_ITR_NRM_SUC_                           \"MSK_DINF_SOL_ITR_NRM_SUC\"\n#define MSK_DINF_SOL_ITR_NRM_SUX_                           \"MSK_DINF_SOL_ITR_NRM_SUX\"\n#define MSK_DINF_SOL_ITR_NRM_XC_                            \"MSK_DINF_SOL_ITR_NRM_XC\"\n#define MSK_DINF_SOL_ITR_NRM_XX_                            \"MSK_DINF_SOL_ITR_NRM_XX\"\n#define MSK_DINF_SOL_ITR_NRM_Y_                             \"MSK_DINF_SOL_ITR_NRM_Y\"\n#define MSK_DINF_SOL_ITR_PRIMAL_OBJ_                        \"MSK_DINF_SOL_ITR_PRIMAL_OBJ\"\n#define MSK_DINF_SOL_ITR_PVIOLACC_                          \"MSK_DINF_SOL_ITR_PVIOLACC\"\n#define MSK_DINF_SOL_ITR_PVIOLBARVAR_                       \"MSK_DINF_SOL_ITR_PVIOLBARVAR\"\n#define MSK_DINF_SOL_ITR_PVIOLCON_                          \"MSK_DINF_SOL_ITR_PVIOLCON\"\n#define MSK_DINF_SOL_ITR_PVIOLCONES_                        \"MSK_DINF_SOL_ITR_PVIOLCONES\"\n#define MSK_DINF_SOL_ITR_PVIOLVAR_                          \"MSK_DINF_SOL_ITR_PVIOLVAR\"\n#define MSK_DINF_TO_CONIC_TIME_                             \"MSK_DINF_TO_CONIC_TIME\"\n#define MSK_DINF_WRITE_DATA_TIME_                           \"MSK_DINF_WRITE_DATA_TIME\"\n\n#define MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_COLUMNS_ \"MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_COLUMNS\"\n#define MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_NZ_ \"MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_NZ\"\n#define MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_ROWS_ \"MSK_LIINF_ANA_PRO_SCALARIZED_CONSTRAINT_MATRIX_NUM_ROWS\"\n#define MSK_LIINF_BI_CLEAN_ITER_                            \"MSK_LIINF_BI_CLEAN_ITER\"\n#define MSK_LIINF_BI_DUAL_ITER_                             \"MSK_LIINF_BI_DUAL_ITER\"\n#define MSK_LIINF_BI_PRIMAL_ITER_                           \"MSK_LIINF_BI_PRIMAL_ITER\"\n#define MSK_LIINF_FOLDING_BI_DUAL_ITER_                     \"MSK_LIINF_FOLDING_BI_DUAL_ITER\"\n#define MSK_LIINF_FOLDING_BI_OPTIMIZER_ITER_                \"MSK_LIINF_FOLDING_BI_OPTIMIZER_ITER\"\n#define MSK_LIINF_FOLDING_BI_PRIMAL_ITER_                   \"MSK_LIINF_FOLDING_BI_PRIMAL_ITER\"\n#define MSK_LIINF_INTPNT_FACTOR_NUM_NZ_                     \"MSK_LIINF_INTPNT_FACTOR_NUM_NZ\"\n#define MSK_LIINF_MIO_ANZ_                                  \"MSK_LIINF_MIO_ANZ\"\n#define MSK_LIINF_MIO_FINAL_ANZ_                            \"MSK_LIINF_MIO_FINAL_ANZ\"\n#define MSK_LIINF_MIO_INTPNT_ITER_                          \"MSK_LIINF_MIO_INTPNT_ITER\"\n#define MSK_LIINF_MIO_NUM_DUAL_ILLPOSED_CER_                \"MSK_LIINF_MIO_NUM_DUAL_ILLPOSED_CER\"\n#define MSK_LIINF_MIO_NUM_PRIM_ILLPOSED_CER_                \"MSK_LIINF_MIO_NUM_PRIM_ILLPOSED_CER\"\n#define MSK_LIINF_MIO_PRESOLVED_ANZ_                        \"MSK_LIINF_MIO_PRESOLVED_ANZ\"\n#define MSK_LIINF_MIO_SIMPLEX_ITER_                         \"MSK_LIINF_MIO_SIMPLEX_ITER\"\n#define MSK_LIINF_RD_NUMACC_                                \"MSK_LIINF_RD_NUMACC\"\n#define MSK_LIINF_RD_NUMANZ_                                \"MSK_LIINF_RD_NUMANZ\"\n#define MSK_LIINF_RD_NUMDJC_                                \"MSK_LIINF_RD_NUMDJC\"\n#define MSK_LIINF_RD_NUMQNZ_                                \"MSK_LIINF_RD_NUMQNZ\"\n#define MSK_LIINF_SIMPLEX_ITER_                             \"MSK_LIINF_SIMPLEX_ITER\"\n\n\n\n/* Typedefs */\n\ntypedef char       MSKchart;\ntypedef void     * MSKvoid_t;\n\n#ifdef  MSKINT64\ntypedef MSKINT64 __mskint64;\n#else\ntypedef long long __mskint64;\n#endif\n\n#if defined(LLONG_MAX) && LLONG_MAX <= INT_MAX\n#warning \"Expected (long long) to be a 64bit type. MOSEK API functions may not work.\"\n#endif\ntypedef int          __mskint32;\n\n/*\ntypedef unsigned int       __mskuint32;\ntypedef signed   int       __mskint32;\ntypedef unsigned long long __mskuint64;\ntypedef signed   long long __mskint64;\n*/\n\n/* Enumeration typedefs */\n#ifndef MSK_NO_ENUMS\ntypedef int                     MSKbasindtypee;\ntypedef enum MSKboundkey_enum        MSKboundkeye;\ntypedef int                     MSKbranchdire;\ntypedef enum MSKcallbackcode_enum    MSKcallbackcodee;\ntypedef enum MSKcompresstype_enum    MSKcompresstypee;\ntypedef enum MSKconetype_enum        MSKconetypee;\ntypedef enum MSKdataformat_enum      MSKdataformate;\ntypedef enum MSKdinfitem_enum        MSKdinfiteme;\ntypedef enum MSKdomaintype_enum      MSKdomaintypee;\ntypedef enum MSKdparam_enum          MSKdparame;\ntypedef enum MSKfeature_enum         MSKfeaturee;\ntypedef int                     MSKfoldingmodee;\ntypedef enum MSKiinfitem_enum        MSKiinfiteme;\ntypedef enum MSKinftype_enum         MSKinftypee;\ntypedef enum MSKintpnthotstart_enum  MSKintpnthotstarte;\ntypedef int                     MSKiomodee;\ntypedef enum MSKiparam_enum          MSKiparame;\ntypedef enum MSKliinfitem_enum       MSKliinfiteme;\ntypedef enum MSKmark_enum            MSKmarke;\ntypedef int                     MSKmiocontsoltypee;\ntypedef int                     MSKmiodatapermmethode;\ntypedef int                     MSKmiomodee;\ntypedef int                     MSKmionodeseltypee;\ntypedef int                     MSKmiovarseltypee;\ntypedef int                     MSKmiqcqoreformmethode;\ntypedef int                     MSKmpsformate;\ntypedef enum MSKnametype_enum        MSKnametypee;\ntypedef enum MSKobjsense_enum        MSKobjsensee;\ntypedef int                     MSKonoffkeye;\ntypedef int                     MSKoptimizertypee;\ntypedef int                     MSKorderingtypee;\ntypedef enum MSKparametertype_enum   MSKparametertypee;\ntypedef int                     MSKpresolvemodee;\ntypedef enum MSKproblemitem_enum     MSKproblemiteme;\ntypedef enum MSKproblemtype_enum     MSKproblemtypee;\ntypedef enum MSKprosta_enum          MSKprostae;\ntypedef enum MSKrescode_enum         MSKrescodee;\ntypedef enum MSKrescodetype_enum     MSKrescodetypee;\ntypedef int                     MSKscalingmethode;\ntypedef int                     MSKscalingtypee;\ntypedef int                     MSKsensitivitytypee;\ntypedef enum MSKsimdegen_enum        MSKsimdegene;\ntypedef enum MSKsimdupvec_enum       MSKsimdupvece;\ntypedef enum MSKsimhotstart_enum     MSKsimhotstarte;\ntypedef enum MSKsimprecision_enum    MSKsimprecisione;\ntypedef enum MSKsimreform_enum       MSKsimreforme;\ntypedef int                     MSKsimseltypee;\ntypedef enum MSKsolformat_enum       MSKsolformate;\ntypedef enum MSKsolitem_enum         MSKsoliteme;\ntypedef enum MSKsolsta_enum          MSKsolstae;\ntypedef enum MSKsoltype_enum         MSKsoltypee;\ntypedef int                     MSKsolveforme;\ntypedef enum MSKsparam_enum          MSKsparame;\ntypedef enum MSKstakey_enum          MSKstakeye;\ntypedef int                     MSKstartpointtypee;\ntypedef enum MSKstreamtype_enum      MSKstreamtypee;\ntypedef enum MSKsymmattype_enum      MSKsymmattypee;\ntypedef enum MSKtranspose_enum       MSKtransposee;\ntypedef enum MSKuplo_enum            MSKuploe;\ntypedef int                     MSKvaluee;\ntypedef enum MSKvariabletype_enum    MSKvariabletypee;\n#else\ntypedef int                     MSKbasindtypee;\ntypedef int                     MSKboundkeye;\ntypedef int                     MSKbranchdire;\ntypedef int                     MSKcallbackcodee;\ntypedef int                     MSKcompresstypee;\ntypedef int                     MSKconetypee;\ntypedef int                     MSKdataformate;\ntypedef int                     MSKdinfiteme;\ntypedef int                     MSKdomaintypee;\ntypedef int                     MSKdparame;\ntypedef int                     MSKfeaturee;\ntypedef int                     MSKfoldingmodee;\ntypedef int                     MSKiinfiteme;\ntypedef int                     MSKinftypee;\ntypedef int                     MSKintpnthotstarte;\ntypedef int                     MSKiomodee;\ntypedef int                     MSKiparame;\ntypedef int                     MSKliinfiteme;\ntypedef int                     MSKmarke;\ntypedef int                     MSKmiocontsoltypee;\ntypedef int                     MSKmiodatapermmethode;\ntypedef int                     MSKmiomodee;\ntypedef int                     MSKmionodeseltypee;\ntypedef int                     MSKmiovarseltypee;\ntypedef int                     MSKmiqcqoreformmethode;\ntypedef int                     MSKmpsformate;\ntypedef int                     MSKnametypee;\ntypedef int                     MSKobjsensee;\ntypedef int                     MSKonoffkeye;\ntypedef int                     MSKoptimizertypee;\ntypedef int                     MSKorderingtypee;\ntypedef int                     MSKparametertypee;\ntypedef int                     MSKpresolvemodee;\ntypedef int                     MSKproblemiteme;\ntypedef int                     MSKproblemtypee;\ntypedef int                     MSKprostae;\ntypedef int                     MSKrescodee;\ntypedef int                     MSKrescodetypee;\ntypedef int                     MSKscalingmethode;\ntypedef int                     MSKscalingtypee;\ntypedef int                     MSKsensitivitytypee;\ntypedef int                     MSKsimdegene;\ntypedef int                     MSKsimdupvece;\ntypedef int                     MSKsimhotstarte;\ntypedef int                     MSKsimprecisione;\ntypedef int                     MSKsimreforme;\ntypedef int                     MSKsimseltypee;\ntypedef int                     MSKsolformate;\ntypedef int                     MSKsoliteme;\ntypedef int                     MSKsolstae;\ntypedef int                     MSKsoltypee;\ntypedef int                     MSKsolveforme;\ntypedef int                     MSKsparame;\ntypedef int                     MSKstakeye;\ntypedef int                     MSKstartpointtypee;\ntypedef int                     MSKstreamtypee;\ntypedef int                     MSKsymmattypee;\ntypedef int                     MSKtransposee;\ntypedef int                     MSKuploe;\ntypedef int                     MSKvaluee;\ntypedef int                     MSKvariabletypee;\n#endif\n\n/* Simple typedefs */\nstruct mskenvt;\nstruct msktaskt;\ntypedef struct mskenvt MSKenv;\ntypedef struct msktaskt MSKtask;\ntypedef int MSKbooleant;\n\ntypedef MSKenv * MSKenv_t;\n\ntypedef int32_t MSKint32t;\n\ntypedef int64_t MSKint64t;\n\ntypedef double MSKrealt;\n\ntypedef char * MSKstring_t;\n\ntypedef MSKtask * MSKtask_t;\n\ntypedef void * MSKuserhandle_t;\n\ntypedef wchar_t MSKwchart;\n\n/* Function typedefs */\ntypedef MSKint32t  (MSKAPI * MSKcallbackfunc) (\n\tMSKtask_t task,\n\tMSKuserhandle_t usrptr,\n\tMSKcallbackcodee caller,\n\tconst MSKrealt * douinf,\n\tconst MSKint32t * intinf,\n\tconst MSKint64t * lintinf);\n\ntypedef void  (MSKAPI * MSKexitfunc) (\n\tMSKuserhandle_t usrptr,\n\tconst char * file,\n\tMSKint32t line,\n\tconst char * msg);\n\ntypedef size_t  (MSKAPI * MSKhreadfunc) (\n\tMSKuserhandle_t handle,\n\tvoid * dest,\n\tconst size_t count);\n\ntypedef size_t  (MSKAPI * MSKhwritefunc) (\n\tMSKuserhandle_t handle,\n\tconst void * src,\n\tconst size_t count);\n\ntypedef MSKrescodee  (MSKAPI * MSKresponsefunc) (\n\tMSKuserhandle_t handle,\n\tMSKrescodee r,\n\tconst char * msg);\n\ntypedef void  (MSKAPI * MSKstreamfunc) (\n\tMSKuserhandle_t handle,\n\tconst char * str);\n\n\n\n\n/* Functions */\n\n/* using __cplusplus */\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* MSK_analyzenames */\nMSKrescodee (MSKAPI MSK_analyzenames) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream,\n\tMSKnametypee nametype);\n\n/* MSK_analyzeproblem */\nMSKrescodee (MSKAPI MSK_analyzeproblem) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream);\n\n/* MSK_analyzesolution */\nMSKrescodee (MSKAPI MSK_analyzesolution) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream,\n\tMSKsoltypee whichsol);\n\n/* MSK_appendacc */\nMSKrescodee (MSKAPI MSK_appendacc) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidxlist,\n\tconst MSKrealt * b);\n\n/* MSK_appendaccs */\nMSKrescodee (MSKAPI MSK_appendaccs) (\n\tMSKtask_t task,\n\tMSKint64t numaccs,\n\tconst MSKint64t * domidxs,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidxlist,\n\tconst MSKrealt * b);\n\n/* MSK_appendaccseq */\nMSKrescodee (MSKAPI MSK_appendaccseq) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKint64t numafeidx,\n\tMSKint64t afeidxfirst,\n\tconst MSKrealt * b);\n\n/* MSK_appendaccsseq */\nMSKrescodee (MSKAPI MSK_appendaccsseq) (\n\tMSKtask_t task,\n\tMSKint64t numaccs,\n\tconst MSKint64t * domidxs,\n\tMSKint64t numafeidx,\n\tMSKint64t afeidxfirst,\n\tconst MSKrealt * b);\n\n/* MSK_appendafes */\nMSKrescodee (MSKAPI MSK_appendafes) (\n\tMSKtask_t task,\n\tMSKint64t num);\n\n/* MSK_appendbarvars */\nMSKrescodee (MSKAPI MSK_appendbarvars) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * dim);\n\n/* MSK_appendcone */\nMSKrescodee (MSKAPI MSK_appendcone) (\n\tMSKtask_t task,\n\tMSKconetypee ct,\n\tMSKrealt conepar,\n\tMSKint32t nummem,\n\tconst MSKint32t * submem);\n\n/* MSK_appendconeseq */\nMSKrescodee (MSKAPI MSK_appendconeseq) (\n\tMSKtask_t task,\n\tMSKconetypee ct,\n\tMSKrealt conepar,\n\tMSKint32t nummem,\n\tMSKint32t j);\n\n/* MSK_appendconesseq */\nMSKrescodee (MSKAPI MSK_appendconesseq) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKconetypee * ct,\n\tconst MSKrealt * conepar,\n\tconst MSKint32t * nummem,\n\tMSKint32t j);\n\n/* MSK_appendcons */\nMSKrescodee (MSKAPI MSK_appendcons) (\n\tMSKtask_t task,\n\tMSKint32t num);\n\n/* MSK_appenddjcs */\nMSKrescodee (MSKAPI MSK_appenddjcs) (\n\tMSKtask_t task,\n\tMSKint64t num);\n\n/* MSK_appenddualexpconedomain */\nMSKrescodee (MSKAPI MSK_appenddualexpconedomain) (\n\tMSKtask_t task,\n\tMSKint64t * domidx);\n\n/* MSK_appenddualgeomeanconedomain */\nMSKrescodee (MSKAPI MSK_appenddualgeomeanconedomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appenddualpowerconedomain */\nMSKrescodee (MSKAPI MSK_appenddualpowerconedomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t nleft,\n\tconst MSKrealt * alpha,\n\tMSKint64t * domidx);\n\n/* MSK_appendprimalexpconedomain */\nMSKrescodee (MSKAPI MSK_appendprimalexpconedomain) (\n\tMSKtask_t task,\n\tMSKint64t * domidx);\n\n/* MSK_appendprimalgeomeanconedomain */\nMSKrescodee (MSKAPI MSK_appendprimalgeomeanconedomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendprimalpowerconedomain */\nMSKrescodee (MSKAPI MSK_appendprimalpowerconedomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t nleft,\n\tconst MSKrealt * alpha,\n\tMSKint64t * domidx);\n\n/* MSK_appendquadraticconedomain */\nMSKrescodee (MSKAPI MSK_appendquadraticconedomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendrdomain */\nMSKrescodee (MSKAPI MSK_appendrdomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendrminusdomain */\nMSKrescodee (MSKAPI MSK_appendrminusdomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendrplusdomain */\nMSKrescodee (MSKAPI MSK_appendrplusdomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendrquadraticconedomain */\nMSKrescodee (MSKAPI MSK_appendrquadraticconedomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendrzerodomain */\nMSKrescodee (MSKAPI MSK_appendrzerodomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendsparsesymmat */\nMSKrescodee (MSKAPI MSK_appendsparsesymmat) (\n\tMSKtask_t task,\n\tMSKint32t dim,\n\tMSKint64t nz,\n\tconst MSKint32t * subi,\n\tconst MSKint32t * subj,\n\tconst MSKrealt * valij,\n\tMSKint64t * idx);\n\n/* MSK_appendsparsesymmatlist */\nMSKrescodee (MSKAPI MSK_appendsparsesymmatlist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * dims,\n\tconst MSKint64t * nz,\n\tconst MSKint32t * subi,\n\tconst MSKint32t * subj,\n\tconst MSKrealt * valij,\n\tMSKint64t * idx);\n\n/* MSK_appendsvecpsdconedomain */\nMSKrescodee (MSKAPI MSK_appendsvecpsdconedomain) (\n\tMSKtask_t task,\n\tMSKint64t n,\n\tMSKint64t * domidx);\n\n/* MSK_appendvars */\nMSKrescodee (MSKAPI MSK_appendvars) (\n\tMSKtask_t task,\n\tMSKint32t num);\n\n/* MSK_asyncgetlog */\nMSKrescodee (MSKAPI MSK_asyncgetlog) (\n\tMSKtask_t task,\n\tconst char * addr,\n\tconst char * accesstoken,\n\tconst char * token);\n\n/* MSK_asyncgetresult */\nMSKrescodee (MSKAPI MSK_asyncgetresult) (\n\tMSKtask_t task,\n\tconst char * address,\n\tconst char * accesstoken,\n\tconst char * token,\n\tMSKbooleant * respavailable,\n\tMSKrescodee * resp,\n\tMSKrescodee * trm);\n\n/* MSK_asyncoptimize */\nMSKrescodee (MSKAPI MSK_asyncoptimize) (\n\tMSKtask_t task,\n\tconst char * address,\n\tconst char * accesstoken,\n\tchar * token);\n\n/* MSK_asyncpoll */\nMSKrescodee (MSKAPI MSK_asyncpoll) (\n\tMSKtask_t task,\n\tconst char * address,\n\tconst char * accesstoken,\n\tconst char * token,\n\tMSKbooleant * respavailable,\n\tMSKrescodee * resp,\n\tMSKrescodee * trm);\n\n/* MSK_asyncstop */\nMSKrescodee (MSKAPI MSK_asyncstop) (\n\tMSKtask_t task,\n\tconst char * address,\n\tconst char * accesstoken,\n\tconst char * token);\n\n/* MSK_basiscond */\nMSKrescodee (MSKAPI MSK_basiscond) (\n\tMSKtask_t task,\n\tMSKrealt * nrmbasis,\n\tMSKrealt * nrminvbasis);\n\n/* MSK_bktostr */\nMSKrescodee (MSKAPI MSK_bktostr) (\n\tMSKtask_t task,\n\tMSKboundkeye bk,\n\tchar * str);\n\n/* MSK_callocdbgtask */\nvoid * (MSKAPI MSK_callocdbgtask) (\n\tMSKtask_t task,\n\tconst size_t number,\n\tconst size_t size,\n\tconst char * file,\n\tconst unsigned line);\n\n/* MSK_calloctask */\nvoid * (MSKAPI MSK_calloctask) (\n\tMSKtask_t task,\n\tconst size_t number,\n\tconst size_t size);\n\n/* MSK_checkmemtask */\nMSKrescodee (MSKAPI MSK_checkmemtask) (\n\tMSKtask_t task,\n\tconst char * file,\n\tMSKint32t line);\n\n/* MSK_chgconbound */\nMSKrescodee (MSKAPI MSK_chgconbound) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t lower,\n\tMSKint32t finite,\n\tMSKrealt value);\n\n/* MSK_chgvarbound */\nMSKrescodee (MSKAPI MSK_chgvarbound) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKint32t lower,\n\tMSKint32t finite,\n\tMSKrealt value);\n\n/* MSK_clonetask */\nMSKrescodee (MSKAPI MSK_clonetask) (\n\tMSKtask_t task,\n\tMSKtask_t * clonedtask);\n\n/* MSK_commitchanges */\nMSKrescodee (MSKAPI MSK_commitchanges) (\n\tMSKtask_t task);\n\n/* MSK_conetypetostr */\nMSKrescodee (MSKAPI MSK_conetypetostr) (\n\tMSKtask_t task,\n\tMSKconetypee ct,\n\tchar * str);\n\n/* MSK_deletesolution */\nMSKrescodee (MSKAPI MSK_deletesolution) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol);\n\n/* MSK_deletetask */\nMSKrescodee (MSKAPI MSK_deletetask) (\n\tMSKtask_t * task);\n\n/* MSK_dualsensitivity */\nMSKrescodee (MSKAPI MSK_dualsensitivity) (\n\tMSKtask_t task,\n\tMSKint32t numj,\n\tconst MSKint32t * subj,\n\tMSKrealt * leftpricej,\n\tMSKrealt * rightpricej,\n\tMSKrealt * leftrangej,\n\tMSKrealt * rightrangej);\n\n/* MSK_echotask */\nMSKrescodee (MSKAPIVA MSK_echotask) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream,\n\tconst char * format,\n\t...);\n\n/* MSK_emptyafebarfrow */\nMSKrescodee (MSKAPI MSK_emptyafebarfrow) (\n\tMSKtask_t task,\n\tMSKint64t afeidx);\n\n/* MSK_emptyafebarfrowlist */\nMSKrescodee (MSKAPI MSK_emptyafebarfrowlist) (\n\tMSKtask_t task,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidxlist);\n\n/* MSK_emptyafefcol */\nMSKrescodee (MSKAPI MSK_emptyafefcol) (\n\tMSKtask_t task,\n\tMSKint32t varidx);\n\n/* MSK_emptyafefcollist */\nMSKrescodee (MSKAPI MSK_emptyafefcollist) (\n\tMSKtask_t task,\n\tMSKint64t numvaridx,\n\tconst MSKint32t * varidx);\n\n/* MSK_emptyafefrow */\nMSKrescodee (MSKAPI MSK_emptyafefrow) (\n\tMSKtask_t task,\n\tMSKint64t afeidx);\n\n/* MSK_emptyafefrowlist */\nMSKrescodee (MSKAPI MSK_emptyafefrowlist) (\n\tMSKtask_t task,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidx);\n\n/* MSK_evaluateacc */\nMSKrescodee (MSKAPI MSK_evaluateacc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint64t accidx,\n\tMSKrealt * activity);\n\n/* MSK_evaluateaccs */\nMSKrescodee (MSKAPI MSK_evaluateaccs) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * activity);\n\n/* MSK_freedbgtask */\nvoid (MSKAPI MSK_freedbgtask) (\n\tMSKtask_t task,\n\tvoid * buffer,\n\tconst char * file,\n\tconst unsigned line);\n\n/* MSK_freetask */\nvoid (MSKAPI MSK_freetask) (\n\tMSKtask_t task,\n\tvoid * buffer);\n\n/* MSK_generateaccnames */\nMSKrescodee (MSKAPI MSK_generateaccnames) (\n\tMSKtask_t task,\n\tMSKint64t num,\n\tconst MSKint64t * sub,\n\tconst char * fmt,\n\tMSKint32t ndims,\n\tconst MSKint32t * dims,\n\tconst MSKint64t * sp,\n\tMSKint32t numnamedaxis,\n\tconst MSKint32t * namedaxisidxs,\n\tMSKint64t numnames,\n\tconst char ** names);\n\n/* MSK_generatebarvarnames */\nMSKrescodee (MSKAPI MSK_generatebarvarnames) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subj,\n\tconst char * fmt,\n\tMSKint32t ndims,\n\tconst MSKint32t * dims,\n\tconst MSKint64t * sp,\n\tMSKint32t numnamedaxis,\n\tconst MSKint32t * namedaxisidxs,\n\tMSKint64t numnames,\n\tconst char ** names);\n\n/* MSK_generateconenames */\nMSKrescodee (MSKAPI MSK_generateconenames) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subk,\n\tconst char * fmt,\n\tMSKint32t ndims,\n\tconst MSKint32t * dims,\n\tconst MSKint64t * sp,\n\tMSKint32t numnamedaxis,\n\tconst MSKint32t * namedaxisidxs,\n\tMSKint64t numnames,\n\tconst char ** names);\n\n/* MSK_generateconnames */\nMSKrescodee (MSKAPI MSK_generateconnames) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subi,\n\tconst char * fmt,\n\tMSKint32t ndims,\n\tconst MSKint32t * dims,\n\tconst MSKint64t * sp,\n\tMSKint32t numnamedaxis,\n\tconst MSKint32t * namedaxisidxs,\n\tMSKint64t numnames,\n\tconst char ** names);\n\n/* MSK_generatedjcnames */\nMSKrescodee (MSKAPI MSK_generatedjcnames) (\n\tMSKtask_t task,\n\tMSKint64t num,\n\tconst MSKint64t * sub,\n\tconst char * fmt,\n\tMSKint32t ndims,\n\tconst MSKint32t * dims,\n\tconst MSKint64t * sp,\n\tMSKint32t numnamedaxis,\n\tconst MSKint32t * namedaxisidxs,\n\tMSKint64t numnames,\n\tconst char ** names);\n\n/* MSK_generatevarnames */\nMSKrescodee (MSKAPI MSK_generatevarnames) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subj,\n\tconst char * fmt,\n\tMSKint32t ndims,\n\tconst MSKint32t * dims,\n\tconst MSKint64t * sp,\n\tMSKint32t numnamedaxis,\n\tconst MSKint32t * namedaxisidxs,\n\tMSKint64t numnames,\n\tconst char ** names);\n\n/* MSK_getaccafeidxlist */\nMSKrescodee (MSKAPI MSK_getaccafeidxlist) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint64t * afeidxlist);\n\n/* MSK_getaccb */\nMSKrescodee (MSKAPI MSK_getaccb) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKrealt * b);\n\n/* MSK_getaccbarfblocktriplet */\nMSKrescodee (MSKAPI MSK_getaccbarfblocktriplet) (\n\tMSKtask_t task,\n\tMSKint64t maxnumtrip,\n\tMSKint64t * numtrip,\n\tMSKint64t * acc_afe,\n\tMSKint32t * bar_var,\n\tMSKint32t * blk_row,\n\tMSKint32t * blk_col,\n\tMSKrealt * blk_val);\n\n/* MSK_getaccbarfnumblocktriplets */\nMSKrescodee (MSKAPI MSK_getaccbarfnumblocktriplets) (\n\tMSKtask_t task,\n\tMSKint64t * numtrip);\n\n/* MSK_getaccdomain */\nMSKrescodee (MSKAPI MSK_getaccdomain) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint64t * domidx);\n\n/* MSK_getaccdoty */\nMSKrescodee (MSKAPI MSK_getaccdoty) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint64t accidx,\n\tMSKrealt * doty);\n\n/* MSK_getaccdotys */\nMSKrescodee (MSKAPI MSK_getaccdotys) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * doty);\n\n/* MSK_getaccfnumnz */\nMSKrescodee (MSKAPI MSK_getaccfnumnz) (\n\tMSKtask_t task,\n\tMSKint64t * accfnnz);\n\n/* MSK_getaccftrip */\nMSKrescodee (MSKAPI MSK_getaccftrip) (\n\tMSKtask_t task,\n\tMSKint64t * frow,\n\tMSKint32t * fcol,\n\tMSKrealt * fval);\n\n/* MSK_getaccgvector */\nMSKrescodee (MSKAPI MSK_getaccgvector) (\n\tMSKtask_t task,\n\tMSKrealt * g);\n\n/* MSK_getaccn */\nMSKrescodee (MSKAPI MSK_getaccn) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint64t * n);\n\n/* MSK_getaccname */\nMSKrescodee (MSKAPI MSK_getaccname) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint32t sizename,\n\tchar * name);\n\n/* MSK_getaccnamelen */\nMSKrescodee (MSKAPI MSK_getaccnamelen) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint32t * len);\n\n/* MSK_getaccntot */\nMSKrescodee (MSKAPI MSK_getaccntot) (\n\tMSKtask_t task,\n\tMSKint64t * n);\n\n/* MSK_getaccs */\nMSKrescodee (MSKAPI MSK_getaccs) (\n\tMSKtask_t task,\n\tMSKint64t * domidxlist,\n\tMSKint64t * afeidxlist,\n\tMSKrealt * b);\n\n/* MSK_getacol */\nMSKrescodee (MSKAPI MSK_getacol) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKint32t * nzj,\n\tMSKint32t * subj,\n\tMSKrealt * valj);\n\n/* MSK_getacolnumnz */\nMSKrescodee (MSKAPI MSK_getacolnumnz) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t * nzj);\n\n/* MSK_getacolslice */\nMSKrescodee (MSKAPI MSK_getacolslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint32t maxnumnz,\n\tMSKint32t * ptrb,\n\tMSKint32t * ptre,\n\tMSKint32t * sub,\n\tMSKrealt * val);\n\n/* MSK_getacolslice64 */\nMSKrescodee (MSKAPI MSK_getacolslice64) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t maxnumnz,\n\tMSKint64t * ptrb,\n\tMSKint64t * ptre,\n\tMSKint32t * sub,\n\tMSKrealt * val);\n\n/* MSK_getacolslicenumnz */\nMSKrescodee (MSKAPI MSK_getacolslicenumnz) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint32t * numnz);\n\n/* MSK_getacolslicenumnz64 */\nMSKrescodee (MSKAPI MSK_getacolslicenumnz64) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t * numnz);\n\n/* MSK_getacolslicetrip */\nMSKrescodee (MSKAPI MSK_getacolslicetrip) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t maxnumnz,\n\tMSKint32t * subi,\n\tMSKint32t * subj,\n\tMSKrealt * val);\n\n/* MSK_getafebarfblocktriplet */\nMSKrescodee (MSKAPI MSK_getafebarfblocktriplet) (\n\tMSKtask_t task,\n\tMSKint64t maxnumtrip,\n\tMSKint64t * numtrip,\n\tMSKint64t * afeidx,\n\tMSKint32t * barvaridx,\n\tMSKint32t * subk,\n\tMSKint32t * subl,\n\tMSKrealt * valkl);\n\n/* MSK_getafebarfnumblocktriplets */\nMSKrescodee (MSKAPI MSK_getafebarfnumblocktriplets) (\n\tMSKtask_t task,\n\tMSKint64t * numtrip);\n\n/* MSK_getafebarfnumrowentries */\nMSKrescodee (MSKAPI MSK_getafebarfnumrowentries) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t * numentr);\n\n/* MSK_getafebarfrow */\nMSKrescodee (MSKAPI MSK_getafebarfrow) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t * barvaridx,\n\tMSKint64t * ptrterm,\n\tMSKint64t * numterm,\n\tMSKint64t * termidx,\n\tMSKrealt * termweight);\n\n/* MSK_getafebarfrowinfo */\nMSKrescodee (MSKAPI MSK_getafebarfrowinfo) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t * numentr,\n\tMSKint64t * numterm);\n\n/* MSK_getafefnumnz */\nMSKrescodee (MSKAPI MSK_getafefnumnz) (\n\tMSKtask_t task,\n\tMSKint64t * numnz);\n\n/* MSK_getafefrow */\nMSKrescodee (MSKAPI MSK_getafefrow) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t * numnz,\n\tMSKint32t * varidx,\n\tMSKrealt * val);\n\n/* MSK_getafefrownumnz */\nMSKrescodee (MSKAPI MSK_getafefrownumnz) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t * numnz);\n\n/* MSK_getafeftrip */\nMSKrescodee (MSKAPI MSK_getafeftrip) (\n\tMSKtask_t task,\n\tMSKint64t * afeidx,\n\tMSKint32t * varidx,\n\tMSKrealt * val);\n\n/* MSK_getafeg */\nMSKrescodee (MSKAPI MSK_getafeg) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKrealt * g);\n\n/* MSK_getafegslice */\nMSKrescodee (MSKAPI MSK_getafegslice) (\n\tMSKtask_t task,\n\tMSKint64t first,\n\tMSKint64t last,\n\tMSKrealt * g);\n\n/* MSK_getaij */\nMSKrescodee (MSKAPI MSK_getaij) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t j,\n\tMSKrealt * aij);\n\n/* MSK_getapiecenumnz */\nMSKrescodee (MSKAPI MSK_getapiecenumnz) (\n\tMSKtask_t task,\n\tMSKint32t firsti,\n\tMSKint32t lasti,\n\tMSKint32t firstj,\n\tMSKint32t lastj,\n\tMSKint32t * numnz);\n\n/* MSK_getarow */\nMSKrescodee (MSKAPI MSK_getarow) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t * nzi,\n\tMSKint32t * subi,\n\tMSKrealt * vali);\n\n/* MSK_getarownumnz */\nMSKrescodee (MSKAPI MSK_getarownumnz) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t * nzi);\n\n/* MSK_getarowslice */\nMSKrescodee (MSKAPI MSK_getarowslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint32t maxnumnz,\n\tMSKint32t * ptrb,\n\tMSKint32t * ptre,\n\tMSKint32t * sub,\n\tMSKrealt * val);\n\n/* MSK_getarowslice64 */\nMSKrescodee (MSKAPI MSK_getarowslice64) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t maxnumnz,\n\tMSKint64t * ptrb,\n\tMSKint64t * ptre,\n\tMSKint32t * sub,\n\tMSKrealt * val);\n\n/* MSK_getarowslicenumnz */\nMSKrescodee (MSKAPI MSK_getarowslicenumnz) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint32t * numnz);\n\n/* MSK_getarowslicenumnz64 */\nMSKrescodee (MSKAPI MSK_getarowslicenumnz64) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t * numnz);\n\n/* MSK_getarowslicetrip */\nMSKrescodee (MSKAPI MSK_getarowslicetrip) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t maxnumnz,\n\tMSKint32t * subi,\n\tMSKint32t * subj,\n\tMSKrealt * val);\n\n/* MSK_getatrip */\nMSKrescodee (MSKAPI MSK_getatrip) (\n\tMSKtask_t task,\n\tMSKint64t maxnumnz,\n\tMSKint32t * subi,\n\tMSKint32t * subj,\n\tMSKrealt * val);\n\n/* MSK_getatruncatetol */\nMSKrescodee (MSKAPI MSK_getatruncatetol) (\n\tMSKtask_t task,\n\tMSKrealt * tolzero);\n\n/* MSK_getbarablocktriplet */\nMSKrescodee (MSKAPI MSK_getbarablocktriplet) (\n\tMSKtask_t task,\n\tMSKint64t maxnum,\n\tMSKint64t * num,\n\tMSKint32t * subi,\n\tMSKint32t * subj,\n\tMSKint32t * subk,\n\tMSKint32t * subl,\n\tMSKrealt * valijkl);\n\n/* MSK_getbaraidx */\nMSKrescodee (MSKAPI MSK_getbaraidx) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint64t maxnum,\n\tMSKint32t * i,\n\tMSKint32t * j,\n\tMSKint64t * num,\n\tMSKint64t * sub,\n\tMSKrealt * weights);\n\n/* MSK_getbaraidxij */\nMSKrescodee (MSKAPI MSK_getbaraidxij) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint32t * i,\n\tMSKint32t * j);\n\n/* MSK_getbaraidxinfo */\nMSKrescodee (MSKAPI MSK_getbaraidxinfo) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint64t * num);\n\n/* MSK_getbarasparsity */\nMSKrescodee (MSKAPI MSK_getbarasparsity) (\n\tMSKtask_t task,\n\tMSKint64t maxnumnz,\n\tMSKint64t * numnz,\n\tMSKint64t * idxij);\n\n/* MSK_getbarcblocktriplet */\nMSKrescodee (MSKAPI MSK_getbarcblocktriplet) (\n\tMSKtask_t task,\n\tMSKint64t maxnum,\n\tMSKint64t * num,\n\tMSKint32t * subj,\n\tMSKint32t * subk,\n\tMSKint32t * subl,\n\tMSKrealt * valjkl);\n\n/* MSK_getbarcidx */\nMSKrescodee (MSKAPI MSK_getbarcidx) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint64t maxnum,\n\tMSKint32t * j,\n\tMSKint64t * num,\n\tMSKint64t * sub,\n\tMSKrealt * weights);\n\n/* MSK_getbarcidxinfo */\nMSKrescodee (MSKAPI MSK_getbarcidxinfo) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint64t * num);\n\n/* MSK_getbarcidxj */\nMSKrescodee (MSKAPI MSK_getbarcidxj) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint32t * j);\n\n/* MSK_getbarcsparsity */\nMSKrescodee (MSKAPI MSK_getbarcsparsity) (\n\tMSKtask_t task,\n\tMSKint64t maxnumnz,\n\tMSKint64t * numnz,\n\tMSKint64t * idxj);\n\n/* MSK_getbarsj */\nMSKrescodee (MSKAPI MSK_getbarsj) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t j,\n\tMSKrealt * barsj);\n\n/* MSK_getbarsslice */\nMSKrescodee (MSKAPI MSK_getbarsslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t slicesize,\n\tMSKrealt * barsslice);\n\n/* MSK_getbarvarname */\nMSKrescodee (MSKAPI MSK_getbarvarname) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t sizename,\n\tchar * name);\n\n/* MSK_getbarvarnameindex */\nMSKrescodee (MSKAPI MSK_getbarvarnameindex) (\n\tMSKtask_t task,\n\tconst char * somename,\n\tMSKint32t * asgn,\n\tMSKint32t * index);\n\n/* MSK_getbarvarnamelen */\nMSKrescodee (MSKAPI MSK_getbarvarnamelen) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t * len);\n\n/* MSK_getbarxj */\nMSKrescodee (MSKAPI MSK_getbarxj) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t j,\n\tMSKrealt * barxj);\n\n/* MSK_getbarxslice */\nMSKrescodee (MSKAPI MSK_getbarxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKint64t slicesize,\n\tMSKrealt * barxslice);\n\n/* MSK_getc */\nMSKrescodee (MSKAPI MSK_getc) (\n\tMSKtask_t task,\n\tMSKrealt * c);\n\n/* MSK_getcallbackfunc */\nMSKrescodee (MSKAPI MSK_getcallbackfunc) (\n\tMSKtask_t task,\n\tMSKcallbackfunc * func,\n\tMSKuserhandle_t * handle);\n\n/* MSK_getcfix */\nMSKrescodee (MSKAPI MSK_getcfix) (\n\tMSKtask_t task,\n\tMSKrealt * cfix);\n\n/* MSK_getcj */\nMSKrescodee (MSKAPI MSK_getcj) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKrealt * cj);\n\n/* MSK_getclist */\nMSKrescodee (MSKAPI MSK_getclist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subj,\n\tMSKrealt * c);\n\n/* MSK_getconbound */\nMSKrescodee (MSKAPI MSK_getconbound) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKboundkeye * bk,\n\tMSKrealt * bl,\n\tMSKrealt * bu);\n\n/* MSK_getconboundslice */\nMSKrescodee (MSKAPI MSK_getconboundslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKboundkeye * bk,\n\tMSKrealt * bl,\n\tMSKrealt * bu);\n\n/* MSK_getcone */\nMSKrescodee (MSKAPI MSK_getcone) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKconetypee * ct,\n\tMSKrealt * conepar,\n\tMSKint32t * nummem,\n\tMSKint32t * submem);\n\n/* MSK_getconeinfo */\nMSKrescodee (MSKAPI MSK_getconeinfo) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKconetypee * ct,\n\tMSKrealt * conepar,\n\tMSKint32t * nummem);\n\n/* MSK_getconename */\nMSKrescodee (MSKAPI MSK_getconename) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t sizename,\n\tchar * name);\n\n/* MSK_getconenameindex */\nMSKrescodee (MSKAPI MSK_getconenameindex) (\n\tMSKtask_t task,\n\tconst char * somename,\n\tMSKint32t * asgn,\n\tMSKint32t * index);\n\n/* MSK_getconenamelen */\nMSKrescodee (MSKAPI MSK_getconenamelen) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t * len);\n\n/* MSK_getconname */\nMSKrescodee (MSKAPI MSK_getconname) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t sizename,\n\tchar * name);\n\n/* MSK_getconnameindex */\nMSKrescodee (MSKAPI MSK_getconnameindex) (\n\tMSKtask_t task,\n\tconst char * somename,\n\tMSKint32t * asgn,\n\tMSKint32t * index);\n\n/* MSK_getconnamelen */\nMSKrescodee (MSKAPI MSK_getconnamelen) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t * len);\n\n/* MSK_getcslice */\nMSKrescodee (MSKAPI MSK_getcslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * c);\n\n/* MSK_getdimbarvarj */\nMSKrescodee (MSKAPI MSK_getdimbarvarj) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKint32t * dimbarvarj);\n\n/* MSK_getdjcafeidxlist */\nMSKrescodee (MSKAPI MSK_getdjcafeidxlist) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint64t * afeidxlist);\n\n/* MSK_getdjcb */\nMSKrescodee (MSKAPI MSK_getdjcb) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKrealt * b);\n\n/* MSK_getdjcdomainidxlist */\nMSKrescodee (MSKAPI MSK_getdjcdomainidxlist) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint64t * domidxlist);\n\n/* MSK_getdjcname */\nMSKrescodee (MSKAPI MSK_getdjcname) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint32t sizename,\n\tchar * name);\n\n/* MSK_getdjcnamelen */\nMSKrescodee (MSKAPI MSK_getdjcnamelen) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint32t * len);\n\n/* MSK_getdjcnumafe */\nMSKrescodee (MSKAPI MSK_getdjcnumafe) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint64t * numafe);\n\n/* MSK_getdjcnumafetot */\nMSKrescodee (MSKAPI MSK_getdjcnumafetot) (\n\tMSKtask_t task,\n\tMSKint64t * numafetot);\n\n/* MSK_getdjcnumdomain */\nMSKrescodee (MSKAPI MSK_getdjcnumdomain) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint64t * numdomain);\n\n/* MSK_getdjcnumdomaintot */\nMSKrescodee (MSKAPI MSK_getdjcnumdomaintot) (\n\tMSKtask_t task,\n\tMSKint64t * numdomaintot);\n\n/* MSK_getdjcnumterm */\nMSKrescodee (MSKAPI MSK_getdjcnumterm) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint64t * numterm);\n\n/* MSK_getdjcnumtermtot */\nMSKrescodee (MSKAPI MSK_getdjcnumtermtot) (\n\tMSKtask_t task,\n\tMSKint64t * numtermtot);\n\n/* MSK_getdjcs */\nMSKrescodee (MSKAPI MSK_getdjcs) (\n\tMSKtask_t task,\n\tMSKint64t * domidxlist,\n\tMSKint64t * afeidxlist,\n\tMSKrealt * b,\n\tMSKint64t * termsizelist,\n\tMSKint64t * numterms);\n\n/* MSK_getdjctermsizelist */\nMSKrescodee (MSKAPI MSK_getdjctermsizelist) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint64t * termsizelist);\n\n/* MSK_getdomainn */\nMSKrescodee (MSKAPI MSK_getdomainn) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKint64t * n);\n\n/* MSK_getdomainname */\nMSKrescodee (MSKAPI MSK_getdomainname) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKint32t sizename,\n\tchar * name);\n\n/* MSK_getdomainnamelen */\nMSKrescodee (MSKAPI MSK_getdomainnamelen) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKint32t * len);\n\n/* MSK_getdomaintype */\nMSKrescodee (MSKAPI MSK_getdomaintype) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKdomaintypee * domtype);\n\n/* MSK_getdouinf */\nMSKrescodee (MSKAPI MSK_getdouinf) (\n\tMSKtask_t task,\n\tMSKdinfiteme whichdinf,\n\tMSKrealt * dvalue);\n\n/* MSK_getdouparam */\nMSKrescodee (MSKAPI MSK_getdouparam) (\n\tMSKtask_t task,\n\tMSKdparame param,\n\tMSKrealt * parvalue);\n\n/* MSK_getdualobj */\nMSKrescodee (MSKAPI MSK_getdualobj) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * dualobj);\n\n/* MSK_getdualproblem */\nMSKrescodee (MSKAPI MSK_getdualproblem) (\n\tMSKtask_t task,\n\tMSKtask_t * dualtask);\n\n/* MSK_getdualsolutionnorms */\nMSKrescodee (MSKAPI MSK_getdualsolutionnorms) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * nrmy,\n\tMSKrealt * nrmslc,\n\tMSKrealt * nrmsuc,\n\tMSKrealt * nrmslx,\n\tMSKrealt * nrmsux,\n\tMSKrealt * nrmsnx,\n\tMSKrealt * nrmbars);\n\n/* MSK_getdviolacc */\nMSKrescodee (MSKAPI MSK_getdviolacc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint64t numaccidx,\n\tconst MSKint64t * accidxlist,\n\tMSKrealt * viol);\n\n/* MSK_getdviolbarvar */\nMSKrescodee (MSKAPI MSK_getdviolbarvar) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getdviolcon */\nMSKrescodee (MSKAPI MSK_getdviolcon) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getdviolcones */\nMSKrescodee (MSKAPI MSK_getdviolcones) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getdviolvar */\nMSKrescodee (MSKAPI MSK_getdviolvar) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getenv */\nMSKrescodee (MSKAPI MSK_getenv) (\n\tMSKtask_t task,\n\tMSKenv_t * env);\n\n/* MSK_getinfeasiblesubproblem */\nMSKrescodee (MSKAPI MSK_getinfeasiblesubproblem) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKtask_t * inftask);\n\n/* MSK_getinfindex */\nMSKrescodee (MSKAPI MSK_getinfindex) (\n\tMSKtask_t task,\n\tMSKinftypee inftype,\n\tconst char * infname,\n\tMSKint32t * infindex);\n\n/* MSK_getinfmax */\nMSKrescodee (MSKAPI MSK_getinfmax) (\n\tMSKtask_t task,\n\tMSKinftypee inftype,\n\tMSKint32t * infmax);\n\n/* MSK_getinfname */\nMSKrescodee (MSKAPI MSK_getinfname) (\n\tMSKtask_t task,\n\tMSKinftypee inftype,\n\tMSKint32t whichinf,\n\tchar * infname);\n\n/* MSK_getintinf */\nMSKrescodee (MSKAPI MSK_getintinf) (\n\tMSKtask_t task,\n\tMSKiinfiteme whichiinf,\n\tMSKint32t * ivalue);\n\n/* MSK_getintparam */\nMSKrescodee (MSKAPI MSK_getintparam) (\n\tMSKtask_t task,\n\tMSKiparame param,\n\tMSKint32t * parvalue);\n\n/* MSK_getlasterror */\nMSKrescodee (MSKAPI MSK_getlasterror) (\n\tMSKtask_t task,\n\tMSKrescodee * lastrescode,\n\tMSKint32t sizelastmsg,\n\tMSKint32t * lastmsglen,\n\tchar * lastmsg);\n\n/* MSK_getlasterror64 */\nMSKrescodee (MSKAPI MSK_getlasterror64) (\n\tMSKtask_t task,\n\tMSKrescodee * lastrescode,\n\tMSKint64t sizelastmsg,\n\tMSKint64t * lastmsglen,\n\tchar * lastmsg);\n\n/* MSK_getlenbarvarj */\nMSKrescodee (MSKAPI MSK_getlenbarvarj) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKint64t * lenbarvarj);\n\n/* MSK_getlintinf */\nMSKrescodee (MSKAPI MSK_getlintinf) (\n\tMSKtask_t task,\n\tMSKliinfiteme whichliinf,\n\tMSKint64t * ivalue);\n\n/* MSK_getlintparam */\nMSKrescodee (MSKAPI MSK_getlintparam) (\n\tMSKtask_t task,\n\tMSKiparame param,\n\tMSKint64t * parvalue);\n\n/* MSK_getmaxnamelen */\nMSKrescodee (MSKAPI MSK_getmaxnamelen) (\n\tMSKtask_t task,\n\tMSKint32t * maxlen);\n\n/* MSK_getmaxnumanz */\nMSKrescodee (MSKAPI MSK_getmaxnumanz) (\n\tMSKtask_t task,\n\tMSKint32t * maxnumanz);\n\n/* MSK_getmaxnumanz64 */\nMSKrescodee (MSKAPI MSK_getmaxnumanz64) (\n\tMSKtask_t task,\n\tMSKint64t * maxnumanz);\n\n/* MSK_getmaxnumbarvar */\nMSKrescodee (MSKAPI MSK_getmaxnumbarvar) (\n\tMSKtask_t task,\n\tMSKint32t * maxnumbarvar);\n\n/* MSK_getmaxnumcon */\nMSKrescodee (MSKAPI MSK_getmaxnumcon) (\n\tMSKtask_t task,\n\tMSKint32t * maxnumcon);\n\n/* MSK_getmaxnumcone */\nMSKrescodee (MSKAPI MSK_getmaxnumcone) (\n\tMSKtask_t task,\n\tMSKint32t * maxnumcone);\n\n/* MSK_getmaxnumqnz */\nMSKrescodee (MSKAPI MSK_getmaxnumqnz) (\n\tMSKtask_t task,\n\tMSKint32t * maxnumqnz);\n\n/* MSK_getmaxnumqnz64 */\nMSKrescodee (MSKAPI MSK_getmaxnumqnz64) (\n\tMSKtask_t task,\n\tMSKint64t * maxnumqnz);\n\n/* MSK_getmaxnumvar */\nMSKrescodee (MSKAPI MSK_getmaxnumvar) (\n\tMSKtask_t task,\n\tMSKint32t * maxnumvar);\n\n/* MSK_getmemusagetask */\nMSKrescodee (MSKAPI MSK_getmemusagetask) (\n\tMSKtask_t task,\n\tMSKint64t * meminuse,\n\tMSKint64t * maxmemuse);\n\n/* MSK_getnadouinf */\nMSKrescodee (MSKAPI MSK_getnadouinf) (\n\tMSKtask_t task,\n\tconst char * infitemname,\n\tMSKrealt * dvalue);\n\n/* MSK_getnadouparam */\nMSKrescodee (MSKAPI MSK_getnadouparam) (\n\tMSKtask_t task,\n\tconst char * paramname,\n\tMSKrealt * parvalue);\n\n/* MSK_getnaintinf */\nMSKrescodee (MSKAPI MSK_getnaintinf) (\n\tMSKtask_t task,\n\tconst char * infitemname,\n\tMSKint32t * ivalue);\n\n/* MSK_getnaintparam */\nMSKrescodee (MSKAPI MSK_getnaintparam) (\n\tMSKtask_t task,\n\tconst char * paramname,\n\tMSKint32t * parvalue);\n\n/* MSK_getnastrparam */\nMSKrescodee (MSKAPI MSK_getnastrparam) (\n\tMSKtask_t task,\n\tconst char * paramname,\n\tMSKint32t sizeparamname,\n\tMSKint32t * len,\n\tchar * parvalue);\n\n/* MSK_getnastrparamal */\nMSKrescodee (MSKAPI MSK_getnastrparamal) (\n\tMSKtask_t task,\n\tconst char * paramname,\n\tMSKint32t numaddchr,\n\tchar ** value);\n\n/* MSK_getnumacc */\nMSKrescodee (MSKAPI MSK_getnumacc) (\n\tMSKtask_t task,\n\tMSKint64t * num);\n\n/* MSK_getnumafe */\nMSKrescodee (MSKAPI MSK_getnumafe) (\n\tMSKtask_t task,\n\tMSKint64t * numafe);\n\n/* MSK_getnumanz */\nMSKrescodee (MSKAPI MSK_getnumanz) (\n\tMSKtask_t task,\n\tMSKint32t * numanz);\n\n/* MSK_getnumanz64 */\nMSKrescodee (MSKAPI MSK_getnumanz64) (\n\tMSKtask_t task,\n\tMSKint64t * numanz);\n\n/* MSK_getnumbarablocktriplets */\nMSKrescodee (MSKAPI MSK_getnumbarablocktriplets) (\n\tMSKtask_t task,\n\tMSKint64t * num);\n\n/* MSK_getnumbaranz */\nMSKrescodee (MSKAPI MSK_getnumbaranz) (\n\tMSKtask_t task,\n\tMSKint64t * nz);\n\n/* MSK_getnumbarcblocktriplets */\nMSKrescodee (MSKAPI MSK_getnumbarcblocktriplets) (\n\tMSKtask_t task,\n\tMSKint64t * num);\n\n/* MSK_getnumbarcnz */\nMSKrescodee (MSKAPI MSK_getnumbarcnz) (\n\tMSKtask_t task,\n\tMSKint64t * nz);\n\n/* MSK_getnumbarvar */\nMSKrescodee (MSKAPI MSK_getnumbarvar) (\n\tMSKtask_t task,\n\tMSKint32t * numbarvar);\n\n/* MSK_getnumcon */\nMSKrescodee (MSKAPI MSK_getnumcon) (\n\tMSKtask_t task,\n\tMSKint32t * numcon);\n\n/* MSK_getnumcone */\nMSKrescodee (MSKAPI MSK_getnumcone) (\n\tMSKtask_t task,\n\tMSKint32t * numcone);\n\n/* MSK_getnumconemem */\nMSKrescodee (MSKAPI MSK_getnumconemem) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKint32t * nummem);\n\n/* MSK_getnumdjc */\nMSKrescodee (MSKAPI MSK_getnumdjc) (\n\tMSKtask_t task,\n\tMSKint64t * num);\n\n/* MSK_getnumdomain */\nMSKrescodee (MSKAPI MSK_getnumdomain) (\n\tMSKtask_t task,\n\tMSKint64t * numdomain);\n\n/* MSK_getnumintvar */\nMSKrescodee (MSKAPI MSK_getnumintvar) (\n\tMSKtask_t task,\n\tMSKint32t * numintvar);\n\n/* MSK_getnumparam */\nMSKrescodee (MSKAPI MSK_getnumparam) (\n\tMSKtask_t task,\n\tMSKparametertypee partype,\n\tMSKint32t * numparam);\n\n/* MSK_getnumqconknz */\nMSKrescodee (MSKAPI MSK_getnumqconknz) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKint32t * numqcnz);\n\n/* MSK_getnumqconknz64 */\nMSKrescodee (MSKAPI MSK_getnumqconknz64) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKint64t * numqcnz);\n\n/* MSK_getnumqobjnz */\nMSKrescodee (MSKAPI MSK_getnumqobjnz) (\n\tMSKtask_t task,\n\tMSKint32t * numqonz);\n\n/* MSK_getnumqobjnz64 */\nMSKrescodee (MSKAPI MSK_getnumqobjnz64) (\n\tMSKtask_t task,\n\tMSKint64t * numqonz);\n\n/* MSK_getnumsymmat */\nMSKrescodee (MSKAPI MSK_getnumsymmat) (\n\tMSKtask_t task,\n\tMSKint64t * num);\n\n/* MSK_getnumvar */\nMSKrescodee (MSKAPI MSK_getnumvar) (\n\tMSKtask_t task,\n\tMSKint32t * numvar);\n\n/* MSK_getobjname */\nMSKrescodee (MSKAPI MSK_getobjname) (\n\tMSKtask_t task,\n\tMSKint32t sizeobjname,\n\tchar * objname);\n\n/* MSK_getobjnamelen */\nMSKrescodee (MSKAPI MSK_getobjnamelen) (\n\tMSKtask_t task,\n\tMSKint32t * len);\n\n/* MSK_getobjsense */\nMSKrescodee (MSKAPI MSK_getobjsense) (\n\tMSKtask_t task,\n\tMSKobjsensee * sense);\n\n/* MSK_getparammax */\nMSKrescodee (MSKAPI MSK_getparammax) (\n\tMSKtask_t task,\n\tMSKparametertypee partype,\n\tMSKint32t * parammax);\n\n/* MSK_getparamname */\nMSKrescodee (MSKAPI MSK_getparamname) (\n\tMSKtask_t task,\n\tMSKparametertypee partype,\n\tMSKint32t param,\n\tchar * parname);\n\n/* MSK_getpowerdomainalpha */\nMSKrescodee (MSKAPI MSK_getpowerdomainalpha) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKrealt * alpha);\n\n/* MSK_getpowerdomaininfo */\nMSKrescodee (MSKAPI MSK_getpowerdomaininfo) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tMSKint64t * n,\n\tMSKint64t * nleft);\n\n/* MSK_getprimalobj */\nMSKrescodee (MSKAPI MSK_getprimalobj) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * primalobj);\n\n/* MSK_getprimalsolutionnorms */\nMSKrescodee (MSKAPI MSK_getprimalsolutionnorms) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * nrmxc,\n\tMSKrealt * nrmxx,\n\tMSKrealt * nrmbarx);\n\n/* MSK_getprobtype */\nMSKrescodee (MSKAPI MSK_getprobtype) (\n\tMSKtask_t task,\n\tMSKproblemtypee * probtype);\n\n/* MSK_getprosta */\nMSKrescodee (MSKAPI MSK_getprosta) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKprostae * problemsta);\n\n/* MSK_getpviolacc */\nMSKrescodee (MSKAPI MSK_getpviolacc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint64t numaccidx,\n\tconst MSKint64t * accidxlist,\n\tMSKrealt * viol);\n\n/* MSK_getpviolbarvar */\nMSKrescodee (MSKAPI MSK_getpviolbarvar) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getpviolcon */\nMSKrescodee (MSKAPI MSK_getpviolcon) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getpviolcones */\nMSKrescodee (MSKAPI MSK_getpviolcones) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getpvioldjc */\nMSKrescodee (MSKAPI MSK_getpvioldjc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint64t numdjcidx,\n\tconst MSKint64t * djcidxlist,\n\tMSKrealt * viol);\n\n/* MSK_getpviolvar */\nMSKrescodee (MSKAPI MSK_getpviolvar) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKrealt * viol);\n\n/* MSK_getqconk */\nMSKrescodee (MSKAPI MSK_getqconk) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKint32t maxnumqcnz,\n\tMSKint32t * numqcnz,\n\tMSKint32t * qcsubi,\n\tMSKint32t * qcsubj,\n\tMSKrealt * qcval);\n\n/* MSK_getqconk64 */\nMSKrescodee (MSKAPI MSK_getqconk64) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKint64t maxnumqcnz,\n\tMSKint64t * numqcnz,\n\tMSKint32t * qcsubi,\n\tMSKint32t * qcsubj,\n\tMSKrealt * qcval);\n\n/* MSK_getqobj */\nMSKrescodee (MSKAPI MSK_getqobj) (\n\tMSKtask_t task,\n\tMSKint32t maxnumqonz,\n\tMSKint32t * numqonz,\n\tMSKint32t * qosubi,\n\tMSKint32t * qosubj,\n\tMSKrealt * qoval);\n\n/* MSK_getqobj64 */\nMSKrescodee (MSKAPI MSK_getqobj64) (\n\tMSKtask_t task,\n\tMSKint64t maxnumqonz,\n\tMSKint64t * numqonz,\n\tMSKint32t * qosubi,\n\tMSKint32t * qosubj,\n\tMSKrealt * qoval);\n\n/* MSK_getqobjij */\nMSKrescodee (MSKAPI MSK_getqobjij) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t j,\n\tMSKrealt * qoij);\n\n/* MSK_getreducedcosts */\nMSKrescodee (MSKAPI MSK_getreducedcosts) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * redcosts);\n\n/* MSK_getskc */\nMSKrescodee (MSKAPI MSK_getskc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKstakeye * skc);\n\n/* MSK_getskcslice */\nMSKrescodee (MSKAPI MSK_getskcslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKstakeye * skc);\n\n/* MSK_getskn */\nMSKrescodee (MSKAPI MSK_getskn) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKstakeye * skn);\n\n/* MSK_getskx */\nMSKrescodee (MSKAPI MSK_getskx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKstakeye * skx);\n\n/* MSK_getskxslice */\nMSKrescodee (MSKAPI MSK_getskxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKstakeye * skx);\n\n/* MSK_getslc */\nMSKrescodee (MSKAPI MSK_getslc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * slc);\n\n/* MSK_getslcslice */\nMSKrescodee (MSKAPI MSK_getslcslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * slc);\n\n/* MSK_getslx */\nMSKrescodee (MSKAPI MSK_getslx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * slx);\n\n/* MSK_getslxslice */\nMSKrescodee (MSKAPI MSK_getslxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * slx);\n\n/* MSK_getsnx */\nMSKrescodee (MSKAPI MSK_getsnx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * snx);\n\n/* MSK_getsnxslice */\nMSKrescodee (MSKAPI MSK_getsnxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * snx);\n\n/* MSK_getsolsta */\nMSKrescodee (MSKAPI MSK_getsolsta) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKsolstae * solutionsta);\n\n/* MSK_getsolution */\nMSKrescodee (MSKAPI MSK_getsolution) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKprostae * problemsta,\n\tMSKsolstae * solutionsta,\n\tMSKstakeye * skc,\n\tMSKstakeye * skx,\n\tMSKstakeye * skn,\n\tMSKrealt * xc,\n\tMSKrealt * xx,\n\tMSKrealt * y,\n\tMSKrealt * slc,\n\tMSKrealt * suc,\n\tMSKrealt * slx,\n\tMSKrealt * sux,\n\tMSKrealt * snx);\n\n/* MSK_getsolutioninfo */\nMSKrescodee (MSKAPI MSK_getsolutioninfo) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * pobj,\n\tMSKrealt * pviolcon,\n\tMSKrealt * pviolvar,\n\tMSKrealt * pviolbarvar,\n\tMSKrealt * pviolcone,\n\tMSKrealt * pviolitg,\n\tMSKrealt * dobj,\n\tMSKrealt * dviolcon,\n\tMSKrealt * dviolvar,\n\tMSKrealt * dviolbarvar,\n\tMSKrealt * dviolcone);\n\n/* MSK_getsolutioninfonew */\nMSKrescodee (MSKAPI MSK_getsolutioninfonew) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * pobj,\n\tMSKrealt * pviolcon,\n\tMSKrealt * pviolvar,\n\tMSKrealt * pviolbarvar,\n\tMSKrealt * pviolcone,\n\tMSKrealt * pviolacc,\n\tMSKrealt * pvioldjc,\n\tMSKrealt * pviolitg,\n\tMSKrealt * dobj,\n\tMSKrealt * dviolcon,\n\tMSKrealt * dviolvar,\n\tMSKrealt * dviolbarvar,\n\tMSKrealt * dviolcone,\n\tMSKrealt * dviolacc);\n\n/* MSK_getsolutionnew */\nMSKrescodee (MSKAPI MSK_getsolutionnew) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKprostae * problemsta,\n\tMSKsolstae * solutionsta,\n\tMSKstakeye * skc,\n\tMSKstakeye * skx,\n\tMSKstakeye * skn,\n\tMSKrealt * xc,\n\tMSKrealt * xx,\n\tMSKrealt * y,\n\tMSKrealt * slc,\n\tMSKrealt * suc,\n\tMSKrealt * slx,\n\tMSKrealt * sux,\n\tMSKrealt * snx,\n\tMSKrealt * doty);\n\n/* MSK_getsolutionslice */\nMSKrescodee (MSKAPI MSK_getsolutionslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKsoliteme solitem,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * values);\n\n/* MSK_getsparsesymmat */\nMSKrescodee (MSKAPI MSK_getsparsesymmat) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint64t maxlen,\n\tMSKint32t * subi,\n\tMSKint32t * subj,\n\tMSKrealt * valij);\n\n/* MSK_getstrparam */\nMSKrescodee (MSKAPI MSK_getstrparam) (\n\tMSKtask_t task,\n\tMSKsparame param,\n\tMSKint32t maxlen,\n\tMSKint32t * len,\n\tchar * parvalue);\n\n/* MSK_getstrparamal */\nMSKrescodee (MSKAPI MSK_getstrparamal) (\n\tMSKtask_t task,\n\tMSKsparame param,\n\tMSKint32t numaddchr,\n\tchar ** value);\n\n/* MSK_getstrparamlen */\nMSKrescodee (MSKAPI MSK_getstrparamlen) (\n\tMSKtask_t task,\n\tMSKsparame param,\n\tMSKint32t * len);\n\n/* MSK_getsuc */\nMSKrescodee (MSKAPI MSK_getsuc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * suc);\n\n/* MSK_getsucslice */\nMSKrescodee (MSKAPI MSK_getsucslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * suc);\n\n/* MSK_getsux */\nMSKrescodee (MSKAPI MSK_getsux) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * sux);\n\n/* MSK_getsuxslice */\nMSKrescodee (MSKAPI MSK_getsuxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * sux);\n\n/* MSK_getsymbcon */\nMSKrescodee (MSKAPI MSK_getsymbcon) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t sizevalue,\n\tchar * name,\n\tMSKint32t * value);\n\n/* MSK_getsymmatinfo */\nMSKrescodee (MSKAPI MSK_getsymmatinfo) (\n\tMSKtask_t task,\n\tMSKint64t idx,\n\tMSKint32t * dim,\n\tMSKint64t * nz,\n\tMSKsymmattypee * mattype);\n\n/* MSK_gettaskname */\nMSKrescodee (MSKAPI MSK_gettaskname) (\n\tMSKtask_t task,\n\tMSKint32t sizetaskname,\n\tchar * taskname);\n\n/* MSK_gettasknamelen */\nMSKrescodee (MSKAPI MSK_gettasknamelen) (\n\tMSKtask_t task,\n\tMSKint32t * len);\n\n/* MSK_getvarbound */\nMSKrescodee (MSKAPI MSK_getvarbound) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKboundkeye * bk,\n\tMSKrealt * bl,\n\tMSKrealt * bu);\n\n/* MSK_getvarboundslice */\nMSKrescodee (MSKAPI MSK_getvarboundslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKboundkeye * bk,\n\tMSKrealt * bl,\n\tMSKrealt * bu);\n\n/* MSK_getvarname */\nMSKrescodee (MSKAPI MSK_getvarname) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKint32t sizename,\n\tchar * name);\n\n/* MSK_getvarnameindex */\nMSKrescodee (MSKAPI MSK_getvarnameindex) (\n\tMSKtask_t task,\n\tconst char * somename,\n\tMSKint32t * asgn,\n\tMSKint32t * index);\n\n/* MSK_getvarnamelen */\nMSKrescodee (MSKAPI MSK_getvarnamelen) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t * len);\n\n/* MSK_getvartype */\nMSKrescodee (MSKAPI MSK_getvartype) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKvariabletypee * vartype);\n\n/* MSK_getvartypelist */\nMSKrescodee (MSKAPI MSK_getvartypelist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subj,\n\tMSKvariabletypee * vartype);\n\n/* MSK_getxc */\nMSKrescodee (MSKAPI MSK_getxc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * xc);\n\n/* MSK_getxcslice */\nMSKrescodee (MSKAPI MSK_getxcslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * xc);\n\n/* MSK_getxx */\nMSKrescodee (MSKAPI MSK_getxx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * xx);\n\n/* MSK_getxxslice */\nMSKrescodee (MSKAPI MSK_getxxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * xx);\n\n/* MSK_gety */\nMSKrescodee (MSKAPI MSK_gety) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * y);\n\n/* MSK_getyslice */\nMSKrescodee (MSKAPI MSK_getyslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKrealt * y);\n\n/* MSK_infeasibilityreport */\nMSKrescodee (MSKAPI MSK_infeasibilityreport) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream,\n\tMSKsoltypee whichsol);\n\n/* MSK_initbasissolve */\nMSKrescodee (MSKAPI MSK_initbasissolve) (\n\tMSKtask_t task,\n\tMSKint32t * basis);\n\n/* MSK_inputdata */\nMSKrescodee (MSKAPI MSK_inputdata) (\n\tMSKtask_t task,\n\tMSKint32t maxnumcon,\n\tMSKint32t maxnumvar,\n\tMSKint32t numcon,\n\tMSKint32t numvar,\n\tconst MSKrealt * c,\n\tMSKrealt cfix,\n\tconst MSKint32t * aptrb,\n\tconst MSKint32t * aptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval,\n\tconst MSKboundkeye * bkc,\n\tconst MSKrealt * blc,\n\tconst MSKrealt * buc,\n\tconst MSKboundkeye * bkx,\n\tconst MSKrealt * blx,\n\tconst MSKrealt * bux);\n\n/* MSK_inputdata64 */\nMSKrescodee (MSKAPI MSK_inputdata64) (\n\tMSKtask_t task,\n\tMSKint32t maxnumcon,\n\tMSKint32t maxnumvar,\n\tMSKint32t numcon,\n\tMSKint32t numvar,\n\tconst MSKrealt * c,\n\tMSKrealt cfix,\n\tconst MSKint64t * aptrb,\n\tconst MSKint64t * aptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval,\n\tconst MSKboundkeye * bkc,\n\tconst MSKrealt * blc,\n\tconst MSKrealt * buc,\n\tconst MSKboundkeye * bkx,\n\tconst MSKrealt * blx,\n\tconst MSKrealt * bux);\n\n/* MSK_isdouparname */\nMSKrescodee (MSKAPI MSK_isdouparname) (\n\tMSKtask_t task,\n\tconst char * parname,\n\tMSKdparame * param);\n\n/* MSK_isintparname */\nMSKrescodee (MSKAPI MSK_isintparname) (\n\tMSKtask_t task,\n\tconst char * parname,\n\tMSKiparame * param);\n\n/* MSK_isstrparname */\nMSKrescodee (MSKAPI MSK_isstrparname) (\n\tMSKtask_t task,\n\tconst char * parname,\n\tMSKsparame * param);\n\n/* MSK_linkfiletotaskstream */\nMSKrescodee (MSKAPI MSK_linkfiletotaskstream) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream,\n\tconst char * filename,\n\tMSKint32t append);\n\n/* MSK_linkfunctotaskstream */\nMSKrescodee (MSKAPI MSK_linkfunctotaskstream) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream,\n\tMSKuserhandle_t handle,\n\tMSKstreamfunc func);\n\n/* MSK_onesolutionsummary */\nMSKrescodee (MSKAPI MSK_onesolutionsummary) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream,\n\tMSKsoltypee whichsol);\n\n/* MSK_optimize */\nMSKrescodee (MSKAPI MSK_optimize) (\n\tMSKtask_t task);\n\n/* MSK_optimizermt */\nMSKrescodee (MSKAPI MSK_optimizermt) (\n\tMSKtask_t task,\n\tconst char * address,\n\tconst char * accesstoken,\n\tMSKrescodee * trmcode);\n\n/* MSK_optimizersummary */\nMSKrescodee (MSKAPI MSK_optimizersummary) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream);\n\n/* MSK_optimizetrm */\nMSKrescodee (MSKAPI MSK_optimizetrm) (\n\tMSKtask_t task,\n\tMSKrescodee * trmcode);\n\n/* MSK_primalrepair */\nMSKrescodee (MSKAPI MSK_primalrepair) (\n\tMSKtask_t task,\n\tconst MSKrealt * wlc,\n\tconst MSKrealt * wuc,\n\tconst MSKrealt * wlx,\n\tconst MSKrealt * wux);\n\n/* MSK_primalsensitivity */\nMSKrescodee (MSKAPI MSK_primalsensitivity) (\n\tMSKtask_t task,\n\tMSKint32t numi,\n\tconst MSKint32t * subi,\n\tconst MSKmarke * marki,\n\tMSKint32t numj,\n\tconst MSKint32t * subj,\n\tconst MSKmarke * markj,\n\tMSKrealt * leftpricei,\n\tMSKrealt * rightpricei,\n\tMSKrealt * leftrangei,\n\tMSKrealt * rightrangei,\n\tMSKrealt * leftpricej,\n\tMSKrealt * rightpricej,\n\tMSKrealt * leftrangej,\n\tMSKrealt * rightrangej);\n\n/* MSK_printparam */\nMSKrescodee (MSKAPI MSK_printparam) (\n\tMSKtask_t task);\n\n/* MSK_probtypetostr */\nMSKrescodee (MSKAPI MSK_probtypetostr) (\n\tMSKtask_t task,\n\tMSKproblemtypee probtype,\n\tchar * str);\n\n/* MSK_prostatostr */\nMSKrescodee (MSKAPI MSK_prostatostr) (\n\tMSKtask_t task,\n\tMSKprostae problemsta,\n\tchar * str);\n\n/* MSK_putacc */\nMSKrescodee (MSKAPI MSK_putacc) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint64t domidx,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidxlist,\n\tconst MSKrealt * b);\n\n/* MSK_putaccb */\nMSKrescodee (MSKAPI MSK_putaccb) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint64t lengthb,\n\tconst MSKrealt * b);\n\n/* MSK_putaccbj */\nMSKrescodee (MSKAPI MSK_putaccbj) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tMSKint64t j,\n\tMSKrealt bj);\n\n/* MSK_putaccdoty */\nMSKrescodee (MSKAPI MSK_putaccdoty) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint64t accidx,\n\tMSKrealt * doty);\n\n/* MSK_putacclist */\nMSKrescodee (MSKAPI MSK_putacclist) (\n\tMSKtask_t task,\n\tMSKint64t numaccs,\n\tconst MSKint64t * accidxs,\n\tconst MSKint64t * domidxs,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidxlist,\n\tconst MSKrealt * b);\n\n/* MSK_putaccname */\nMSKrescodee (MSKAPI MSK_putaccname) (\n\tMSKtask_t task,\n\tMSKint64t accidx,\n\tconst char * name);\n\n/* MSK_putacol */\nMSKrescodee (MSKAPI MSK_putacol) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKint32t nzj,\n\tconst MSKint32t * subj,\n\tconst MSKrealt * valj);\n\n/* MSK_putacollist */\nMSKrescodee (MSKAPI MSK_putacollist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tconst MSKint32t * ptrb,\n\tconst MSKint32t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putacollist64 */\nMSKrescodee (MSKAPI MSK_putacollist64) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tconst MSKint64t * ptrb,\n\tconst MSKint64t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putacolslice */\nMSKrescodee (MSKAPI MSK_putacolslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKint32t * ptrb,\n\tconst MSKint32t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putacolslice64 */\nMSKrescodee (MSKAPI MSK_putacolslice64) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKint64t * ptrb,\n\tconst MSKint64t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putafebarfblocktriplet */\nMSKrescodee (MSKAPI MSK_putafebarfblocktriplet) (\n\tMSKtask_t task,\n\tMSKint64t numtrip,\n\tconst MSKint64t * afeidx,\n\tconst MSKint32t * barvaridx,\n\tconst MSKint32t * subk,\n\tconst MSKint32t * subl,\n\tconst MSKrealt * valkl);\n\n/* MSK_putafebarfentry */\nMSKrescodee (MSKAPI MSK_putafebarfentry) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t barvaridx,\n\tMSKint64t numterm,\n\tconst MSKint64t * termidx,\n\tconst MSKrealt * termweight);\n\n/* MSK_putafebarfentrylist */\nMSKrescodee (MSKAPI MSK_putafebarfentrylist) (\n\tMSKtask_t task,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidx,\n\tconst MSKint32t * barvaridx,\n\tconst MSKint64t * numterm,\n\tconst MSKint64t * ptrterm,\n\tMSKint64t lenterm,\n\tconst MSKint64t * termidx,\n\tconst MSKrealt * termweight);\n\n/* MSK_putafebarfrow */\nMSKrescodee (MSKAPI MSK_putafebarfrow) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t numentr,\n\tconst MSKint32t * barvaridx,\n\tconst MSKint64t * numterm,\n\tconst MSKint64t * ptrterm,\n\tMSKint64t lenterm,\n\tconst MSKint64t * termidx,\n\tconst MSKrealt * termweight);\n\n/* MSK_putafefcol */\nMSKrescodee (MSKAPI MSK_putafefcol) (\n\tMSKtask_t task,\n\tMSKint32t varidx,\n\tMSKint64t numnz,\n\tconst MSKint64t * afeidx,\n\tconst MSKrealt * val);\n\n/* MSK_putafefentry */\nMSKrescodee (MSKAPI MSK_putafefentry) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t varidx,\n\tMSKrealt value);\n\n/* MSK_putafefentrylist */\nMSKrescodee (MSKAPI MSK_putafefentrylist) (\n\tMSKtask_t task,\n\tMSKint64t numentr,\n\tconst MSKint64t * afeidx,\n\tconst MSKint32t * varidx,\n\tconst MSKrealt * val);\n\n/* MSK_putafefrow */\nMSKrescodee (MSKAPI MSK_putafefrow) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKint32t numnz,\n\tconst MSKint32t * varidx,\n\tconst MSKrealt * val);\n\n/* MSK_putafefrowlist */\nMSKrescodee (MSKAPI MSK_putafefrowlist) (\n\tMSKtask_t task,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidx,\n\tconst MSKint32t * numnzrow,\n\tconst MSKint64t * ptrrow,\n\tMSKint64t lenidxval,\n\tconst MSKint32t * varidx,\n\tconst MSKrealt * val);\n\n/* MSK_putafeg */\nMSKrescodee (MSKAPI MSK_putafeg) (\n\tMSKtask_t task,\n\tMSKint64t afeidx,\n\tMSKrealt g);\n\n/* MSK_putafeglist */\nMSKrescodee (MSKAPI MSK_putafeglist) (\n\tMSKtask_t task,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidx,\n\tconst MSKrealt * g);\n\n/* MSK_putafegslice */\nMSKrescodee (MSKAPI MSK_putafegslice) (\n\tMSKtask_t task,\n\tMSKint64t first,\n\tMSKint64t last,\n\tconst MSKrealt * slice);\n\n/* MSK_putaij */\nMSKrescodee (MSKAPI MSK_putaij) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t j,\n\tMSKrealt aij);\n\n/* MSK_putaijlist */\nMSKrescodee (MSKAPI MSK_putaijlist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subi,\n\tconst MSKint32t * subj,\n\tconst MSKrealt * valij);\n\n/* MSK_putaijlist64 */\nMSKrescodee (MSKAPI MSK_putaijlist64) (\n\tMSKtask_t task,\n\tMSKint64t num,\n\tconst MSKint32t * subi,\n\tconst MSKint32t * subj,\n\tconst MSKrealt * valij);\n\n/* MSK_putarow */\nMSKrescodee (MSKAPI MSK_putarow) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t nzi,\n\tconst MSKint32t * subi,\n\tconst MSKrealt * vali);\n\n/* MSK_putarowlist */\nMSKrescodee (MSKAPI MSK_putarowlist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tconst MSKint32t * ptrb,\n\tconst MSKint32t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putarowlist64 */\nMSKrescodee (MSKAPI MSK_putarowlist64) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tconst MSKint64t * ptrb,\n\tconst MSKint64t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putarowslice */\nMSKrescodee (MSKAPI MSK_putarowslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKint32t * ptrb,\n\tconst MSKint32t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putarowslice64 */\nMSKrescodee (MSKAPI MSK_putarowslice64) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKint64t * ptrb,\n\tconst MSKint64t * ptre,\n\tconst MSKint32t * asub,\n\tconst MSKrealt * aval);\n\n/* MSK_putatruncatetol */\nMSKrescodee (MSKAPI MSK_putatruncatetol) (\n\tMSKtask_t task,\n\tMSKrealt tolzero);\n\n/* MSK_putbarablocktriplet */\nMSKrescodee (MSKAPI MSK_putbarablocktriplet) (\n\tMSKtask_t task,\n\tMSKint64t num,\n\tconst MSKint32t * subi,\n\tconst MSKint32t * subj,\n\tconst MSKint32t * subk,\n\tconst MSKint32t * subl,\n\tconst MSKrealt * valijkl);\n\n/* MSK_putbaraij */\nMSKrescodee (MSKAPI MSK_putbaraij) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t j,\n\tMSKint64t num,\n\tconst MSKint64t * sub,\n\tconst MSKrealt * weights);\n\n/* MSK_putbaraijlist */\nMSKrescodee (MSKAPI MSK_putbaraijlist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subi,\n\tconst MSKint32t * subj,\n\tconst MSKint64t * alphaptrb,\n\tconst MSKint64t * alphaptre,\n\tconst MSKint64t * matidx,\n\tconst MSKrealt * weights);\n\n/* MSK_putbararowlist */\nMSKrescodee (MSKAPI MSK_putbararowlist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subi,\n\tconst MSKint64t * ptrb,\n\tconst MSKint64t * ptre,\n\tconst MSKint32t * subj,\n\tconst MSKint64t * nummat,\n\tconst MSKint64t * matidx,\n\tconst MSKrealt * weights);\n\n/* MSK_putbarcblocktriplet */\nMSKrescodee (MSKAPI MSK_putbarcblocktriplet) (\n\tMSKtask_t task,\n\tMSKint64t num,\n\tconst MSKint32t * subj,\n\tconst MSKint32t * subk,\n\tconst MSKint32t * subl,\n\tconst MSKrealt * valjkl);\n\n/* MSK_putbarcj */\nMSKrescodee (MSKAPI MSK_putbarcj) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKint64t num,\n\tconst MSKint64t * sub,\n\tconst MSKrealt * weights);\n\n/* MSK_putbarsj */\nMSKrescodee (MSKAPI MSK_putbarsj) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t j,\n\tconst MSKrealt * barsj);\n\n/* MSK_putbarvarname */\nMSKrescodee (MSKAPI MSK_putbarvarname) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tconst char * name);\n\n/* MSK_putbarxj */\nMSKrescodee (MSKAPI MSK_putbarxj) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t j,\n\tconst MSKrealt * barxj);\n\n/* MSK_putcallbackfunc */\nMSKrescodee (MSKAPI MSK_putcallbackfunc) (\n\tMSKtask_t task,\n\tMSKcallbackfunc func,\n\tMSKuserhandle_t handle);\n\n/* MSK_putcfix */\nMSKrescodee (MSKAPI MSK_putcfix) (\n\tMSKtask_t task,\n\tMSKrealt cfix);\n\n/* MSK_putcj */\nMSKrescodee (MSKAPI MSK_putcj) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKrealt cj);\n\n/* MSK_putclist */\nMSKrescodee (MSKAPI MSK_putclist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subj,\n\tconst MSKrealt * val);\n\n/* MSK_putconbound */\nMSKrescodee (MSKAPI MSK_putconbound) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKboundkeye bkc,\n\tMSKrealt blc,\n\tMSKrealt buc);\n\n/* MSK_putconboundlist */\nMSKrescodee (MSKAPI MSK_putconboundlist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tconst MSKboundkeye * bkc,\n\tconst MSKrealt * blc,\n\tconst MSKrealt * buc);\n\n/* MSK_putconboundlistconst */\nMSKrescodee (MSKAPI MSK_putconboundlistconst) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKboundkeye bkc,\n\tMSKrealt blc,\n\tMSKrealt buc);\n\n/* MSK_putconboundslice */\nMSKrescodee (MSKAPI MSK_putconboundslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKboundkeye * bkc,\n\tconst MSKrealt * blc,\n\tconst MSKrealt * buc);\n\n/* MSK_putconboundsliceconst */\nMSKrescodee (MSKAPI MSK_putconboundsliceconst) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKboundkeye bkc,\n\tMSKrealt blc,\n\tMSKrealt buc);\n\n/* MSK_putcone */\nMSKrescodee (MSKAPI MSK_putcone) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKconetypee ct,\n\tMSKrealt conepar,\n\tMSKint32t nummem,\n\tconst MSKint32t * submem);\n\n/* MSK_putconename */\nMSKrescodee (MSKAPI MSK_putconename) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tconst char * name);\n\n/* MSK_putconname */\nMSKrescodee (MSKAPI MSK_putconname) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tconst char * name);\n\n/* MSK_putconsolutioni */\nMSKrescodee (MSKAPI MSK_putconsolutioni) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKsoltypee whichsol,\n\tMSKstakeye sk,\n\tMSKrealt x,\n\tMSKrealt sl,\n\tMSKrealt su);\n\n/* MSK_putcslice */\nMSKrescodee (MSKAPI MSK_putcslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * slice);\n\n/* MSK_putdjc */\nMSKrescodee (MSKAPI MSK_putdjc) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tMSKint64t numdomidx,\n\tconst MSKint64t * domidxlist,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidxlist,\n\tconst MSKrealt * b,\n\tMSKint64t numterms,\n\tconst MSKint64t * termsizelist);\n\n/* MSK_putdjcname */\nMSKrescodee (MSKAPI MSK_putdjcname) (\n\tMSKtask_t task,\n\tMSKint64t djcidx,\n\tconst char * name);\n\n/* MSK_putdjcslice */\nMSKrescodee (MSKAPI MSK_putdjcslice) (\n\tMSKtask_t task,\n\tMSKint64t idxfirst,\n\tMSKint64t idxlast,\n\tMSKint64t numdomidx,\n\tconst MSKint64t * domidxlist,\n\tMSKint64t numafeidx,\n\tconst MSKint64t * afeidxlist,\n\tconst MSKrealt * b,\n\tMSKint64t numterms,\n\tconst MSKint64t * termsizelist,\n\tconst MSKint64t * termsindjc);\n\n/* MSK_putdomainname */\nMSKrescodee (MSKAPI MSK_putdomainname) (\n\tMSKtask_t task,\n\tMSKint64t domidx,\n\tconst char * name);\n\n/* MSK_putdouparam */\nMSKrescodee (MSKAPI MSK_putdouparam) (\n\tMSKtask_t task,\n\tMSKdparame param,\n\tMSKrealt parvalue);\n\n/* MSK_putintparam */\nMSKrescodee (MSKAPI MSK_putintparam) (\n\tMSKtask_t task,\n\tMSKiparame param,\n\tMSKint32t parvalue);\n\n/* MSK_putlintparam */\nMSKrescodee (MSKAPI MSK_putlintparam) (\n\tMSKtask_t task,\n\tMSKiparame param,\n\tMSKint64t parvalue);\n\n/* MSK_putmaxnumacc */\nMSKrescodee (MSKAPI MSK_putmaxnumacc) (\n\tMSKtask_t task,\n\tMSKint64t maxnumacc);\n\n/* MSK_putmaxnumafe */\nMSKrescodee (MSKAPI MSK_putmaxnumafe) (\n\tMSKtask_t task,\n\tMSKint64t maxnumafe);\n\n/* MSK_putmaxnumanz */\nMSKrescodee (MSKAPI MSK_putmaxnumanz) (\n\tMSKtask_t task,\n\tMSKint64t maxnumanz);\n\n/* MSK_putmaxnumbarvar */\nMSKrescodee (MSKAPI MSK_putmaxnumbarvar) (\n\tMSKtask_t task,\n\tMSKint32t maxnumbarvar);\n\n/* MSK_putmaxnumcon */\nMSKrescodee (MSKAPI MSK_putmaxnumcon) (\n\tMSKtask_t task,\n\tMSKint32t maxnumcon);\n\n/* MSK_putmaxnumcone */\nMSKrescodee (MSKAPI MSK_putmaxnumcone) (\n\tMSKtask_t task,\n\tMSKint32t maxnumcone);\n\n/* MSK_putmaxnumdjc */\nMSKrescodee (MSKAPI MSK_putmaxnumdjc) (\n\tMSKtask_t task,\n\tMSKint64t maxnumdjc);\n\n/* MSK_putmaxnumdomain */\nMSKrescodee (MSKAPI MSK_putmaxnumdomain) (\n\tMSKtask_t task,\n\tMSKint64t maxnumdomain);\n\n/* MSK_putmaxnumqnz */\nMSKrescodee (MSKAPI MSK_putmaxnumqnz) (\n\tMSKtask_t task,\n\tMSKint64t maxnumqnz);\n\n/* MSK_putmaxnumvar */\nMSKrescodee (MSKAPI MSK_putmaxnumvar) (\n\tMSKtask_t task,\n\tMSKint32t maxnumvar);\n\n/* MSK_putnadouparam */\nMSKrescodee (MSKAPI MSK_putnadouparam) (\n\tMSKtask_t task,\n\tconst char * paramname,\n\tMSKrealt parvalue);\n\n/* MSK_putnaintparam */\nMSKrescodee (MSKAPI MSK_putnaintparam) (\n\tMSKtask_t task,\n\tconst char * paramname,\n\tMSKint32t parvalue);\n\n/* MSK_putnastrparam */\nMSKrescodee (MSKAPI MSK_putnastrparam) (\n\tMSKtask_t task,\n\tconst char * paramname,\n\tconst char * parvalue);\n\n/* MSK_putobjname */\nMSKrescodee (MSKAPI MSK_putobjname) (\n\tMSKtask_t task,\n\tconst char * objname);\n\n/* MSK_putobjsense */\nMSKrescodee (MSKAPI MSK_putobjsense) (\n\tMSKtask_t task,\n\tMSKobjsensee sense);\n\n/* MSK_putoptserverhost */\nMSKrescodee (MSKAPI MSK_putoptserverhost) (\n\tMSKtask_t task,\n\tconst char * host);\n\n/* MSK_putparam */\nMSKrescodee (MSKAPI MSK_putparam) (\n\tMSKtask_t task,\n\tconst char * parname,\n\tconst char * parvalue);\n\n/* MSK_putqcon */\nMSKrescodee (MSKAPI MSK_putqcon) (\n\tMSKtask_t task,\n\tMSKint32t numqcnz,\n\tconst MSKint32t * qcsubk,\n\tconst MSKint32t * qcsubi,\n\tconst MSKint32t * qcsubj,\n\tconst MSKrealt * qcval);\n\n/* MSK_putqconk */\nMSKrescodee (MSKAPI MSK_putqconk) (\n\tMSKtask_t task,\n\tMSKint32t k,\n\tMSKint32t numqcnz,\n\tconst MSKint32t * qcsubi,\n\tconst MSKint32t * qcsubj,\n\tconst MSKrealt * qcval);\n\n/* MSK_putqobj */\nMSKrescodee (MSKAPI MSK_putqobj) (\n\tMSKtask_t task,\n\tMSKint32t numqonz,\n\tconst MSKint32t * qosubi,\n\tconst MSKint32t * qosubj,\n\tconst MSKrealt * qoval);\n\n/* MSK_putqobjij */\nMSKrescodee (MSKAPI MSK_putqobjij) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKint32t j,\n\tMSKrealt qoij);\n\n/* MSK_putresponsefunc */\nMSKrescodee (MSKAPI MSK_putresponsefunc) (\n\tMSKtask_t task,\n\tMSKresponsefunc responsefunc,\n\tMSKuserhandle_t handle);\n\n/* MSK_putskc */\nMSKrescodee (MSKAPI MSK_putskc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKstakeye * skc);\n\n/* MSK_putskcslice */\nMSKrescodee (MSKAPI MSK_putskcslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKstakeye * skc);\n\n/* MSK_putskx */\nMSKrescodee (MSKAPI MSK_putskx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKstakeye * skx);\n\n/* MSK_putskxslice */\nMSKrescodee (MSKAPI MSK_putskxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKstakeye * skx);\n\n/* MSK_putslc */\nMSKrescodee (MSKAPI MSK_putslc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKrealt * slc);\n\n/* MSK_putslcslice */\nMSKrescodee (MSKAPI MSK_putslcslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * slc);\n\n/* MSK_putslx */\nMSKrescodee (MSKAPI MSK_putslx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKrealt * slx);\n\n/* MSK_putslxslice */\nMSKrescodee (MSKAPI MSK_putslxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * slx);\n\n/* MSK_putsnx */\nMSKrescodee (MSKAPI MSK_putsnx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKrealt * sux);\n\n/* MSK_putsnxslice */\nMSKrescodee (MSKAPI MSK_putsnxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * snx);\n\n/* MSK_putsolution */\nMSKrescodee (MSKAPI MSK_putsolution) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKstakeye * skc,\n\tconst MSKstakeye * skx,\n\tconst MSKstakeye * skn,\n\tconst MSKrealt * xc,\n\tconst MSKrealt * xx,\n\tconst MSKrealt * y,\n\tconst MSKrealt * slc,\n\tconst MSKrealt * suc,\n\tconst MSKrealt * slx,\n\tconst MSKrealt * sux,\n\tconst MSKrealt * snx);\n\n/* MSK_putsolutionnew */\nMSKrescodee (MSKAPI MSK_putsolutionnew) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKstakeye * skc,\n\tconst MSKstakeye * skx,\n\tconst MSKstakeye * skn,\n\tconst MSKrealt * xc,\n\tconst MSKrealt * xx,\n\tconst MSKrealt * y,\n\tconst MSKrealt * slc,\n\tconst MSKrealt * suc,\n\tconst MSKrealt * slx,\n\tconst MSKrealt * sux,\n\tconst MSKrealt * snx,\n\tconst MSKrealt * doty);\n\n/* MSK_putsolutionyi */\nMSKrescodee (MSKAPI MSK_putsolutionyi) (\n\tMSKtask_t task,\n\tMSKint32t i,\n\tMSKsoltypee whichsol,\n\tMSKrealt y);\n\n/* MSK_putstrparam */\nMSKrescodee (MSKAPI MSK_putstrparam) (\n\tMSKtask_t task,\n\tMSKsparame param,\n\tconst char * parvalue);\n\n/* MSK_putsuc */\nMSKrescodee (MSKAPI MSK_putsuc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKrealt * suc);\n\n/* MSK_putsucslice */\nMSKrescodee (MSKAPI MSK_putsucslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * suc);\n\n/* MSK_putsux */\nMSKrescodee (MSKAPI MSK_putsux) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKrealt * sux);\n\n/* MSK_putsuxslice */\nMSKrescodee (MSKAPI MSK_putsuxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * sux);\n\n/* MSK_puttaskname */\nMSKrescodee (MSKAPI MSK_puttaskname) (\n\tMSKtask_t task,\n\tconst char * taskname);\n\n/* MSK_putvarbound */\nMSKrescodee (MSKAPI MSK_putvarbound) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKboundkeye bkx,\n\tMSKrealt blx,\n\tMSKrealt bux);\n\n/* MSK_putvarboundlist */\nMSKrescodee (MSKAPI MSK_putvarboundlist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tconst MSKboundkeye * bkx,\n\tconst MSKrealt * blx,\n\tconst MSKrealt * bux);\n\n/* MSK_putvarboundlistconst */\nMSKrescodee (MSKAPI MSK_putvarboundlistconst) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * sub,\n\tMSKboundkeye bkx,\n\tMSKrealt blx,\n\tMSKrealt bux);\n\n/* MSK_putvarboundslice */\nMSKrescodee (MSKAPI MSK_putvarboundslice) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKboundkeye * bkx,\n\tconst MSKrealt * blx,\n\tconst MSKrealt * bux);\n\n/* MSK_putvarboundsliceconst */\nMSKrescodee (MSKAPI MSK_putvarboundsliceconst) (\n\tMSKtask_t task,\n\tMSKint32t first,\n\tMSKint32t last,\n\tMSKboundkeye bkx,\n\tMSKrealt blx,\n\tMSKrealt bux);\n\n/* MSK_putvarname */\nMSKrescodee (MSKAPI MSK_putvarname) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tconst char * name);\n\n/* MSK_putvarsolutionj */\nMSKrescodee (MSKAPI MSK_putvarsolutionj) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKsoltypee whichsol,\n\tMSKstakeye sk,\n\tMSKrealt x,\n\tMSKrealt sl,\n\tMSKrealt su,\n\tMSKrealt sn);\n\n/* MSK_putvartype */\nMSKrescodee (MSKAPI MSK_putvartype) (\n\tMSKtask_t task,\n\tMSKint32t j,\n\tMSKvariabletypee vartype);\n\n/* MSK_putvartypelist */\nMSKrescodee (MSKAPI MSK_putvartypelist) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subj,\n\tconst MSKvariabletypee * vartype);\n\n/* MSK_putxc */\nMSKrescodee (MSKAPI MSK_putxc) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKrealt * xc);\n\n/* MSK_putxcslice */\nMSKrescodee (MSKAPI MSK_putxcslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * xc);\n\n/* MSK_putxx */\nMSKrescodee (MSKAPI MSK_putxx) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKrealt * xx);\n\n/* MSK_putxxslice */\nMSKrescodee (MSKAPI MSK_putxxslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * xx);\n\n/* MSK_puty */\nMSKrescodee (MSKAPI MSK_puty) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst MSKrealt * y);\n\n/* MSK_putyslice */\nMSKrescodee (MSKAPI MSK_putyslice) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKint32t first,\n\tMSKint32t last,\n\tconst MSKrealt * y);\n\n/* MSK_readbsolution */\nMSKrescodee (MSKAPI MSK_readbsolution) (\n\tMSKtask_t task,\n\tconst char * filename,\n\tMSKcompresstypee compress);\n\n/* MSK_readdata */\nMSKrescodee (MSKAPI MSK_readdata) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_readdataautoformat */\nMSKrescodee (MSKAPI MSK_readdataautoformat) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_readdataformat */\nMSKrescodee (MSKAPI MSK_readdataformat) (\n\tMSKtask_t task,\n\tconst char * filename,\n\tMSKdataformate format,\n\tMSKcompresstypee compress);\n\n/* MSK_readdatahandle */\nMSKrescodee (MSKAPI MSK_readdatahandle) (\n\tMSKtask_t task,\n\tMSKhreadfunc hread,\n\tMSKuserhandle_t h,\n\tMSKdataformate format,\n\tMSKcompresstypee compress,\n\tconst char * path);\n\n/* MSK_readjsonsol */\nMSKrescodee (MSKAPI MSK_readjsonsol) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_readjsonstring */\nMSKrescodee (MSKAPI MSK_readjsonstring) (\n\tMSKtask_t task,\n\tconst char * data);\n\n/* MSK_readlpstring */\nMSKrescodee (MSKAPI MSK_readlpstring) (\n\tMSKtask_t task,\n\tconst char * data);\n\n/* MSK_readopfstring */\nMSKrescodee (MSKAPI MSK_readopfstring) (\n\tMSKtask_t task,\n\tconst char * data);\n\n/* MSK_readparamfile */\nMSKrescodee (MSKAPI MSK_readparamfile) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_readptfstring */\nMSKrescodee (MSKAPI MSK_readptfstring) (\n\tMSKtask_t task,\n\tconst char * data);\n\n/* MSK_readsolution */\nMSKrescodee (MSKAPI MSK_readsolution) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst char * filename);\n\n/* MSK_readsolutionfile */\nMSKrescodee (MSKAPI MSK_readsolutionfile) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_readsummary */\nMSKrescodee (MSKAPI MSK_readsummary) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream);\n\n/* MSK_readtask */\nMSKrescodee (MSKAPI MSK_readtask) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_removebarvars */\nMSKrescodee (MSKAPI MSK_removebarvars) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subset);\n\n/* MSK_removecones */\nMSKrescodee (MSKAPI MSK_removecones) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subset);\n\n/* MSK_removecons */\nMSKrescodee (MSKAPI MSK_removecons) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subset);\n\n/* MSK_removevars */\nMSKrescodee (MSKAPI MSK_removevars) (\n\tMSKtask_t task,\n\tMSKint32t num,\n\tconst MSKint32t * subset);\n\n/* MSK_resetdouparam */\nMSKrescodee (MSKAPI MSK_resetdouparam) (\n\tMSKtask_t task,\n\tMSKdparame param);\n\n/* MSK_resetintparam */\nMSKrescodee (MSKAPI MSK_resetintparam) (\n\tMSKtask_t task,\n\tMSKiparame param);\n\n/* MSK_resetparameters */\nMSKrescodee (MSKAPI MSK_resetparameters) (\n\tMSKtask_t task);\n\n/* MSK_resetstrparam */\nMSKrescodee (MSKAPI MSK_resetstrparam) (\n\tMSKtask_t task,\n\tMSKsparame param);\n\n/* MSK_resizetask */\nMSKrescodee (MSKAPI MSK_resizetask) (\n\tMSKtask_t task,\n\tMSKint32t maxnumcon,\n\tMSKint32t maxnumvar,\n\tMSKint32t maxnumcone,\n\tMSKint64t maxnumanz,\n\tMSKint64t maxnumqnz);\n\n/* MSK_sensitivityreport */\nMSKrescodee (MSKAPI MSK_sensitivityreport) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream);\n\n/* MSK_sktostr */\nMSKrescodee (MSKAPI MSK_sktostr) (\n\tMSKtask_t task,\n\tMSKstakeye sk,\n\tchar * str);\n\n/* MSK_solstatostr */\nMSKrescodee (MSKAPI MSK_solstatostr) (\n\tMSKtask_t task,\n\tMSKsolstae solutionsta,\n\tchar * str);\n\n/* MSK_solutiondef */\nMSKrescodee (MSKAPI MSK_solutiondef) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tMSKbooleant * isdef);\n\n/* MSK_solutionsummary */\nMSKrescodee (MSKAPI MSK_solutionsummary) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream);\n\n/* MSK_solvewithbasis */\nMSKrescodee (MSKAPI MSK_solvewithbasis) (\n\tMSKtask_t task,\n\tMSKbooleant transp,\n\tMSKint32t numnz,\n\tMSKint32t * sub,\n\tMSKrealt * val,\n\tMSKint32t * numnzout);\n\n/* MSK_strtoconetype */\nMSKrescodee (MSKAPI MSK_strtoconetype) (\n\tMSKtask_t task,\n\tconst char * str,\n\tMSKconetypee * conetype);\n\n/* MSK_strtosk */\nMSKrescodee (MSKAPI MSK_strtosk) (\n\tMSKtask_t task,\n\tconst char * str,\n\tMSKstakeye * sk);\n\n/* MSK_toconic */\nMSKrescodee (MSKAPI MSK_toconic) (\n\tMSKtask_t task);\n\n/* MSK_unlinkfuncfromtaskstream */\nMSKrescodee (MSKAPI MSK_unlinkfuncfromtaskstream) (\n\tMSKtask_t task,\n\tMSKstreamtypee whichstream);\n\n/* MSK_updatesolutioninfo */\nMSKrescodee (MSKAPI MSK_updatesolutioninfo) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol);\n\n/* MSK_whichparam */\nMSKrescodee (MSKAPI MSK_whichparam) (\n\tMSKtask_t task,\n\tconst char * parname,\n\tMSKparametertypee * partype,\n\tMSKint32t * param);\n\n/* MSK_writebsolution */\nMSKrescodee (MSKAPI MSK_writebsolution) (\n\tMSKtask_t task,\n\tconst char * filename,\n\tMSKcompresstypee compress);\n\n/* MSK_writebsolutionhandle */\nMSKrescodee (MSKAPI MSK_writebsolutionhandle) (\n\tMSKtask_t task,\n\tMSKhwritefunc func,\n\tMSKuserhandle_t handle,\n\tMSKcompresstypee compress);\n\n/* MSK_writedata */\nMSKrescodee (MSKAPI MSK_writedata) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_writedatahandle */\nMSKrescodee (MSKAPI MSK_writedatahandle) (\n\tMSKtask_t task,\n\tMSKhwritefunc func,\n\tMSKuserhandle_t handle,\n\tMSKdataformate format,\n\tMSKcompresstypee compress);\n\n/* MSK_writejsonsol */\nMSKrescodee (MSKAPI MSK_writejsonsol) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_writeparamfile */\nMSKrescodee (MSKAPI MSK_writeparamfile) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_writesolution */\nMSKrescodee (MSKAPI MSK_writesolution) (\n\tMSKtask_t task,\n\tMSKsoltypee whichsol,\n\tconst char * filename);\n\n/* MSK_writesolutionfile */\nMSKrescodee (MSKAPI MSK_writesolutionfile) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_writetask */\nMSKrescodee (MSKAPI MSK_writetask) (\n\tMSKtask_t task,\n\tconst char * filename);\n\n/* MSK_axpy */\nMSKrescodee (MSKAPI MSK_axpy) (\n\tMSKenv_t env,\n\tMSKint32t n,\n\tMSKrealt alpha,\n\tconst MSKrealt * x,\n\tMSKrealt * y);\n\n/* MSK_callbackcodetostr */\nMSKrescodee (MSKAPI MSK_callbackcodetostr) (\n\tMSKcallbackcodee code,\n\tchar * callbackcodestr);\n\n/* MSK_callocdbgenv */\nvoid * (MSKAPI MSK_callocdbgenv) (\n\tMSKenv_t env,\n\tconst size_t number,\n\tconst size_t size,\n\tconst char * file,\n\tconst unsigned line);\n\n/* MSK_callocenv */\nvoid * (MSKAPI MSK_callocenv) (\n\tMSKenv_t env,\n\tconst size_t number,\n\tconst size_t size);\n\n/* MSK_checkinall */\nMSKrescodee (MSKAPI MSK_checkinall) (\n\tMSKenv_t env);\n\n/* MSK_checkinlicense */\nMSKrescodee (MSKAPI MSK_checkinlicense) (\n\tMSKenv_t env,\n\tMSKfeaturee feature);\n\n/* MSK_checkmemenv */\nMSKrescodee (MSKAPI MSK_checkmemenv) (\n\tMSKenv_t env,\n\tconst char * file,\n\tMSKint32t line);\n\n/* MSK_checkoutlicense */\nMSKrescodee (MSKAPI MSK_checkoutlicense) (\n\tMSKenv_t env,\n\tMSKfeaturee feature);\n\n/* MSK_checkversion */\nMSKrescodee (MSKAPI MSK_checkversion) (\n\tMSKenv_t env,\n\tMSKint32t major,\n\tMSKint32t minor,\n\tMSKint32t revision);\n\n/* MSK_computesparsecholesky */\nMSKrescodee (MSKAPI MSK_computesparsecholesky) (\n\tMSKenv_t env,\n\tMSKint32t numthreads,\n\tMSKint32t ordermethod,\n\tMSKrealt tolsingular,\n\tMSKint32t n,\n\tconst MSKint32t * anzc,\n\tconst MSKint64t * aptrc,\n\tconst MSKint32t * asubc,\n\tconst MSKrealt * avalc,\n\tMSKint32t ** perm,\n\tMSKrealt ** diag,\n\tMSKint32t ** lnzc,\n\tMSKint64t ** lptrc,\n\tMSKint64t * lensubnval,\n\tMSKint32t ** lsubc,\n\tMSKrealt ** lvalc);\n\n/* MSK_deleteenv */\nMSKrescodee (MSKAPI MSK_deleteenv) (\n\tMSKenv_t * env);\n\n/* MSK_dinfitemtostr */\nMSKrescodee (MSKAPI MSK_dinfitemtostr) (\n\tMSKdinfiteme item,\n\tchar * str);\n\n/* MSK_dot */\nMSKrescodee (MSKAPI MSK_dot) (\n\tMSKenv_t env,\n\tMSKint32t n,\n\tconst MSKrealt * x,\n\tconst MSKrealt * y,\n\tMSKrealt * xty);\n\n/* MSK_echoenv */\nMSKrescodee (MSKAPIVA MSK_echoenv) (\n\tMSKenv_t env,\n\tMSKstreamtypee whichstream,\n\tconst char * format,\n\t...);\n\n/* MSK_echointro */\nMSKrescodee (MSKAPI MSK_echointro) (\n\tMSKenv_t env,\n\tMSKint32t longver);\n\n/* MSK_expirylicenses */\nMSKrescodee (MSKAPI MSK_expirylicenses) (\n\tMSKenv_t env,\n\tMSKint64t * expiry);\n\n/* MSK_freedbgenv */\nvoid (MSKAPI MSK_freedbgenv) (\n\tMSKenv_t env,\n\tvoid * buffer,\n\tconst char * file,\n\tconst unsigned line);\n\n/* MSK_freeenv */\nvoid (MSKAPI MSK_freeenv) (\n\tMSKenv_t env,\n\tvoid * buffer);\n\n/* MSK_gemm */\nMSKrescodee (MSKAPI MSK_gemm) (\n\tMSKenv_t env,\n\tMSKtransposee transa,\n\tMSKtransposee transb,\n\tMSKint32t m,\n\tMSKint32t n,\n\tMSKint32t k,\n\tMSKrealt alpha,\n\tconst MSKrealt * a,\n\tconst MSKrealt * b,\n\tMSKrealt beta,\n\tMSKrealt * c);\n\n/* MSK_gemv */\nMSKrescodee (MSKAPI MSK_gemv) (\n\tMSKenv_t env,\n\tMSKtransposee transa,\n\tMSKint32t m,\n\tMSKint32t n,\n\tMSKrealt alpha,\n\tconst MSKrealt * a,\n\tconst MSKrealt * x,\n\tMSKrealt beta,\n\tMSKrealt * y);\n\n/* MSK_getbuildinfo */\nMSKrescodee (MSKAPI MSK_getbuildinfo) (\n\tchar * buildstate,\n\tchar * builddate);\n\n/* MSK_getcodedesc */\nMSKrescodee (MSKAPI MSK_getcodedesc) (\n\tMSKrescodee code,\n\tchar * symname,\n\tchar * str);\n\n/* MSK_getresponseclass */\nMSKrescodee (MSKAPI MSK_getresponseclass) (\n\tMSKrescodee r,\n\tMSKrescodetypee * rc);\n\n/* MSK_getsymbcondim */\nMSKrescodee (MSKAPI MSK_getsymbcondim) (\n\tMSKenv_t env,\n\tMSKint32t * num,\n\tsize_t * maxlen);\n\n/* MSK_getversion */\nMSKrescodee (MSKAPI MSK_getversion) (\n\tMSKint32t * major,\n\tMSKint32t * minor,\n\tMSKint32t * revision);\n\n/* MSK_globalenvfinalize */\nMSKrescodee (MSKAPI MSK_globalenvfinalize) (\nvoid);\n\n/* MSK_globalenvinitialize */\nMSKrescodee (MSKAPI MSK_globalenvinitialize) (\n\tMSKint64t maxnumalloc,\n\tconst char * dbgfile);\n\n/* MSK_iinfitemtostr */\nMSKrescodee (MSKAPI MSK_iinfitemtostr) (\n\tMSKiinfiteme item,\n\tchar * str);\n\n/* MSK_iparvaltosymnam */\nMSKrescodee (MSKAPI MSK_iparvaltosymnam) (\n\tMSKenv_t env,\n\tMSKiparame whichparam,\n\tMSKint32t whichvalue,\n\tchar * symbolicname);\n\n/* MSK_isinfinity */\nMSKbooleant (MSKAPI MSK_isinfinity) (\n\tMSKrealt value);\n\n/* MSK_licensecleanup */\nMSKrescodee (MSKAPI MSK_licensecleanup) (\nvoid);\n\n/* MSK_liinfitemtostr */\nMSKrescodee (MSKAPI MSK_liinfitemtostr) (\n\tMSKliinfiteme item,\n\tchar * str);\n\n/* MSK_linkfiletoenvstream */\nMSKrescodee (MSKAPI MSK_linkfiletoenvstream) (\n\tMSKenv_t env,\n\tMSKstreamtypee whichstream,\n\tconst char * filename,\n\tMSKint32t append);\n\n/* MSK_linkfunctoenvstream */\nMSKrescodee (MSKAPI MSK_linkfunctoenvstream) (\n\tMSKenv_t env,\n\tMSKstreamtypee whichstream,\n\tMSKuserhandle_t handle,\n\tMSKstreamfunc func);\n\n/* MSK_makeemptytask */\nMSKrescodee (MSKAPI MSK_makeemptytask) (\n\tMSKenv_t env,\n\tMSKtask_t * task);\n\n/* MSK_makeenv */\nMSKrescodee (MSKAPI MSK_makeenv) (\n\tMSKenv_t * env,\n\tconst char * dbgfile);\n\n/* MSK_maketask */\nMSKrescodee (MSKAPI MSK_maketask) (\n\tMSKenv_t env,\n\tMSKint32t maxnumcon,\n\tMSKint32t maxnumvar,\n\tMSKtask_t * task);\n\n/* MSK_optimizebatch */\nMSKrescodee (MSKAPI MSK_optimizebatch) (\n\tMSKenv_t env,\n\tMSKbooleant israce,\n\tMSKrealt maxtime,\n\tMSKint32t numthreads,\n\tMSKint64t numtask,\n\tconst MSKtask_t * task,\n\tMSKrescodee * trmcode,\n\tMSKrescodee * rcode);\n\n/* MSK_potrf */\nMSKrescodee (MSKAPI MSK_potrf) (\n\tMSKenv_t env,\n\tMSKuploe uplo,\n\tMSKint32t n,\n\tMSKrealt * a);\n\n/* MSK_putexitfunc */\nMSKrescodee (MSKAPI MSK_putexitfunc) (\n\tMSKenv_t env,\n\tMSKexitfunc exitfunc,\n\tMSKuserhandle_t handle);\n\n/* MSK_putlicensecode */\nMSKrescodee (MSKAPI MSK_putlicensecode) (\n\tMSKenv_t env,\n\tconst MSKint32t * code);\n\n/* MSK_putlicensedebug */\nMSKrescodee (MSKAPI MSK_putlicensedebug) (\n\tMSKenv_t env,\n\tMSKint32t licdebug);\n\n/* MSK_putlicensepath */\nMSKrescodee (MSKAPI MSK_putlicensepath) (\n\tMSKenv_t env,\n\tconst char * licensepath);\n\n/* MSK_putlicensewait */\nMSKrescodee (MSKAPI MSK_putlicensewait) (\n\tMSKenv_t env,\n\tMSKint32t licwait);\n\n/* MSK_rescodetostr */\nMSKrescodee (MSKAPI MSK_rescodetostr) (\n\tMSKrescodee res,\n\tchar * str);\n\n/* MSK_resetexpirylicenses */\nMSKrescodee (MSKAPI MSK_resetexpirylicenses) (\n\tMSKenv_t env);\n\n/* MSK_sparsetriangularsolvedense */\nMSKrescodee (MSKAPI MSK_sparsetriangularsolvedense) (\n\tMSKenv_t env,\n\tMSKtransposee transposed,\n\tMSKint32t n,\n\tconst MSKint32t * lnzc,\n\tconst MSKint64t * lptrc,\n\tMSKint64t lensubnval,\n\tconst MSKint32t * lsubc,\n\tconst MSKrealt * lvalc,\n\tMSKrealt * b);\n\n/* MSK_syeig */\nMSKrescodee (MSKAPI MSK_syeig) (\n\tMSKenv_t env,\n\tMSKuploe uplo,\n\tMSKint32t n,\n\tconst MSKrealt * a,\n\tMSKrealt * w);\n\n/* MSK_syevd */\nMSKrescodee (MSKAPI MSK_syevd) (\n\tMSKenv_t env,\n\tMSKuploe uplo,\n\tMSKint32t n,\n\tMSKrealt * a,\n\tMSKrealt * w);\n\n/* MSK_symnamtovalue */\nMSKbooleant (MSKAPI MSK_symnamtovalue) (\n\tconst char * name,\n\tchar * value);\n\n/* MSK_syrk */\nMSKrescodee (MSKAPI MSK_syrk) (\n\tMSKenv_t env,\n\tMSKuploe uplo,\n\tMSKtransposee trans,\n\tMSKint32t n,\n\tMSKint32t k,\n\tMSKrealt alpha,\n\tconst MSKrealt * a,\n\tMSKrealt beta,\n\tMSKrealt * c);\n\n/* MSK_unlinkfuncfromenvstream */\nMSKrescodee (MSKAPI MSK_unlinkfuncfromenvstream) (\n\tMSKenv_t env,\n\tMSKstreamtypee whichstream);\n\n/* MSK_utf8towchar */\nMSKrescodee (MSKAPI MSK_utf8towchar) (\n\tconst size_t outputlen,\n\tsize_t * len,\n\tsize_t * conv,\n\tMSKwchart * output,\n\tconst char * input);\n\n/* MSK_wchartoutf8 */\nMSKrescodee (MSKAPI MSK_wchartoutf8) (\n\tconst size_t outputlen,\n\tsize_t * len,\n\tsize_t * conv,\n\tchar * output,\n\tconst MSKwchart * input);\n\n\n\n#ifdef __cplusplus\n}\n#endif\n\n\n#endif\n\n\n"
  },
  {
    "path": "thirdparty/solvers/xpress/function_list.txt",
    "content": "XPRSaddcols64\nXPRSaddcuts64\nXPRSaddmanagedcuts64\nXPRSaddmipsol\nXPRSaddnames\nXPRSaddqmatrix64\nXPRSaddrows64\nXPRSaddsets64\nXPRSbeginlicensing\nXPRSchgbounds\nXPRSchgcoef\nXPRSchgcoltype\nXPRSchgmqobj64\nXPRSchgobj\nXPRSchgobjsense\nXPRSchgrhs\nXPRSchgrowtype\nXPRScreateprob\nXPRSdelcols\nXPRSdelobj\nXPRSdelqmatrix\nXPRSdelrows\nXPRSdelsets\nXPRSdestroyprob\nXPRSendlicensing\nXPRSfree\nXPRSgetattribinfo\nXPRSgetbasisval\nXPRSgetcallbacksolution\nXPRSgetcoef\nXPRSgetcoltype\nXPRSgetcontrolinfo\nXPRSgetdblattrib\nXPRSgetdblcontrol\nXPRSgetdualray\nXPRSgetduals\nXPRSgetiisdata\nXPRSgetintattrib64\nXPRSgetintcontrol64\nXPRSgetlasterror\nXPRSgetlb\nXPRSgetlicerrmsg\nXPRSgetlpsol\nXPRSgetnamelist\nXPRSgetobj\nXPRSgetprimalray\nXPRSgetprobname\nXPRSgetredcosts\nXPRSgetrhs\nXPRSgetrowtype\nXPRSgetslacks\nXPRSgetsolution\nXPRSgetstrattrib\nXPRSgetstrcontrol\nXPRSgetstringattrib\nXPRSgetstringcontrol\nXPRSgetub\nXPRSgetversion\nXPRSgetversionnumbers\nXPRSiisall\nXPRSiisfirst\nXPRSinit\nXPRSinterrupt\nXPRSlicense\nXPRSnlpaddformulas\nXPRSnlploadformulas\nXPRSnlppostsolve\nXPRSoptimize\nXPRSpostsolve\nXPRSpresolverow\nXPRSsaveas\nXPRSsetdblcontrol\nXPRSsetintcontrol\nXPRSsetintcontrol64\nXPRSsetlogfile\nXPRSsetprobname\nXPRSsetstrcontrol\nXPRSwritebasis\nXPRSwritebinsol\nXPRSwriteprob\nXPRSwriteprtsol\nXPRSwriteslxsol\nXPRSwritesol\nXPRSaddcbbariteration\nXPRSaddcbbarlog\nXPRSaddcbafterobjective\nXPRSaddcbbeforeobjective\nXPRSaddcbpresolve\nXPRSaddcbchecktime\nXPRSaddcbchgbranchobject\nXPRSaddcbcutlog\nXPRSaddcbcutround\nXPRSaddcbdestroymt\nXPRSaddcbgapnotify\nXPRSaddcbmiplog\nXPRSaddcbinfnode\nXPRSaddcbintsol\nXPRSaddcblplog\nXPRSaddcbmessage\nXPRSaddcbmipthread\nXPRSaddcbnewnode\nXPRSaddcbnodecutoff\nXPRSaddcbnodelpsolved\nXPRSaddcboptnode\nXPRSaddcbpreintsol\nXPRSaddcbprenode\nXPRSaddcbusersolnotify\nXPRSremovecbbariteration\nXPRSremovecbbarlog\nXPRSremovecbafterobjective\nXPRSremovecbbeforeobjective\nXPRSremovecbpresolve\nXPRSremovecbchecktime\nXPRSremovecbchgbranchobject\nXPRSremovecbcutlog\nXPRSremovecbcutround\nXPRSremovecbdestroymt\nXPRSremovecbgapnotify\nXPRSremovecbmiplog\nXPRSremovecbinfnode\nXPRSremovecbintsol\nXPRSremovecblplog\nXPRSremovecbmessage\nXPRSremovecbmipthread\nXPRSremovecbnewnode\nXPRSremovecbnodecutoff\nXPRSremovecbnodelpsolved\nXPRSremovecboptnode\nXPRSremovecbpreintsol\nXPRSremovecbprenode\nXPRSremovecbusersolnotify\n"
  },
  {
    "path": "thirdparty/solvers/xpress/xpress_forward_decls.h",
    "content": "// Forward declarations for FICO Xpress Optimizer API\n// This header provides only the minimal declarations needed by PyOptInterface\n// to compile against the Xpress C API. Users must have Xpress installed\n// with proper libraries for linking and runtime.\n//\n// This is NOT a complete Xpress header file.\n\n#ifndef PYOPTINTERFACE_XPRESS_FORWARD_DECLS_H\n#define PYOPTINTERFACE_XPRESS_FORWARD_DECLS_H\n\n// Based on xprs.h version:\n#define POI_XPVERSION /* Same as POI_XPVERSION_MAJOR */ 46\n#define POI_XPVERSION_MAJOR 46\n#define POI_XPVERSION_MINOR 1\n#define POI_XPVERSION_BUILD 1\n#define POI_XPVERSION_FULL 460101\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n#if defined(_WIN32)\n#define XPRSint64 __int64\n#elif defined(__LP64__) || defined(_LP64) || defined(__ILP64__) || defined(_ILP64)\n#define XPRSint64 long\n#else\n#define XPRSint64 long long\n#endif\n\n#define POI_XPRS_PLUSINFINITY 1.0e+20\n#define POI_XPRS_MINUSINFINITY (-1.0e+20)\n#define POI_XPRS_MAXINT 2147483647\n#define POI_XPRS_MAXBANNERLENGTH 512\n#define POI_XPRS_MAXMESSAGELENGTH 512\n\n#define POI_XPRS_MPSRHSNAME 6001\n#define POI_XPRS_MPSOBJNAME 6002\n#define POI_XPRS_MPSRANGENAME 6003\n#define POI_XPRS_MPSBOUNDNAME 6004\n#define POI_XPRS_OUTPUTMASK 6005\n#define POI_XPRS_TUNERMETHODFILE 6017\n#define POI_XPRS_TUNEROUTPUTPATH 6018\n#define POI_XPRS_TUNERSESSIONNAME 6019\n#define POI_XPRS_COMPUTEEXECSERVICE 6022\n#define POI_XPRS_MAXCUTTIME 8149\n#define POI_XPRS_MAXSTALLTIME 8443\n#define POI_XPRS_TUNERMAXTIME 8364\n#define POI_XPRS_MATRIXTOL 7001\n#define POI_XPRS_PIVOTTOL 7002\n#define POI_XPRS_FEASTOL 7003\n#define POI_XPRS_OUTPUTTOL 7004\n#define POI_XPRS_SOSREFTOL 7005\n#define POI_XPRS_OPTIMALITYTOL 7006\n#define POI_XPRS_ETATOL 7007\n#define POI_XPRS_RELPIVOTTOL 7008\n#define POI_XPRS_MIPTOL 7009\n#define POI_XPRS_MIPTOLTARGET 7010\n#define POI_XPRS_BARPERTURB 7011\n#define POI_XPRS_MIPADDCUTOFF 7012\n#define POI_XPRS_MIPABSCUTOFF 7013\n#define POI_XPRS_MIPRELCUTOFF 7014\n#define POI_XPRS_PSEUDOCOST 7015\n#define POI_XPRS_PENALTY 7016\n#define POI_XPRS_BIGM 7018\n#define POI_XPRS_MIPABSSTOP 7019\n#define POI_XPRS_MIPRELSTOP 7020\n#define POI_XPRS_CROSSOVERACCURACYTOL 7023\n#define POI_XPRS_PRIMALPERTURB 7024\n#define POI_XPRS_DUALPERTURB 7025\n#define POI_XPRS_BAROBJSCALE 7026\n#define POI_XPRS_BARRHSSCALE 7027\n#define POI_XPRS_CHOLESKYTOL 7032\n#define POI_XPRS_BARGAPSTOP 7033\n#define POI_XPRS_BARDUALSTOP 7034\n#define POI_XPRS_BARPRIMALSTOP 7035\n#define POI_XPRS_BARSTEPSTOP 7036\n#define POI_XPRS_ELIMTOL 7042\n#define POI_XPRS_MARKOWITZTOL 7047\n#define POI_XPRS_MIPABSGAPNOTIFY 7064\n#define POI_XPRS_MIPRELGAPNOTIFY 7065\n#define POI_XPRS_BARLARGEBOUND 7067\n#define POI_XPRS_PPFACTOR 7069\n#define POI_XPRS_REPAIRINDEFINITEQMAX 7071\n#define POI_XPRS_BARGAPTARGET 7073\n#define POI_XPRS_DUMMYCONTROL 7075\n#define POI_XPRS_BARSTARTWEIGHT 7076\n#define POI_XPRS_BARFREESCALE 7077\n#define POI_XPRS_SBEFFORT 7086\n#define POI_XPRS_HEURDIVERANDOMIZE 7089\n#define POI_XPRS_HEURSEARCHEFFORT 7090\n#define POI_XPRS_CUTFACTOR 7091\n#define POI_XPRS_EIGENVALUETOL 7097\n#define POI_XPRS_INDLINBIGM 7099\n#define POI_XPRS_TREEMEMORYSAVINGTARGET 7100\n#define POI_XPRS_INDPRELINBIGM 7102\n#define POI_XPRS_RELAXTREEMEMORYLIMIT 7105\n#define POI_XPRS_MIPABSGAPNOTIFYOBJ 7108\n#define POI_XPRS_MIPABSGAPNOTIFYBOUND 7109\n#define POI_XPRS_PRESOLVEMAXGROW 7110\n#define POI_XPRS_HEURSEARCHTARGETSIZE 7112\n#define POI_XPRS_CROSSOVERRELPIVOTTOL 7113\n#define POI_XPRS_CROSSOVERRELPIVOTTOLSAFE 7114\n#define POI_XPRS_DETLOGFREQ 7116\n#define POI_XPRS_MAXIMPLIEDBOUND 7120\n#define POI_XPRS_FEASTOLTARGET 7121\n#define POI_XPRS_OPTIMALITYTOLTARGET 7122\n#define POI_XPRS_PRECOMPONENTSEFFORT 7124\n#define POI_XPRS_LPLOGDELAY 7127\n#define POI_XPRS_HEURDIVEITERLIMIT 7128\n#define POI_XPRS_BARKERNEL 7130\n#define POI_XPRS_FEASTOLPERTURB 7132\n#define POI_XPRS_CROSSOVERFEASWEIGHT 7133\n#define POI_XPRS_LUPIVOTTOL 7139\n#define POI_XPRS_MIPRESTARTGAPTHRESHOLD 7140\n#define POI_XPRS_NODEPROBINGEFFORT 7141\n#define POI_XPRS_INPUTTOL 7143\n#define POI_XPRS_MIPRESTARTFACTOR 7145\n#define POI_XPRS_BAROBJPERTURB 7146\n#define POI_XPRS_CPIALPHA 7149\n#define POI_XPRS_GLOBALSPATIALBRANCHPROPAGATIONEFFORT 7152\n#define POI_XPRS_GLOBALSPATIALBRANCHCUTTINGEFFORT 7153\n#define POI_XPRS_GLOBALBOUNDINGBOX 7154\n#define POI_XPRS_TIMELIMIT 7158\n#define POI_XPRS_SOLTIMELIMIT 7159\n#define POI_XPRS_REPAIRINFEASTIMELIMIT 7160\n#define POI_XPRS_BARHGEXTRAPOLATE 7166\n#define POI_XPRS_WORKLIMIT 7167\n#define POI_XPRS_CALLBACKCHECKTIMEWORKDELAY 7169\n#define POI_XPRS_PREROOTWORKLIMIT 7172\n#define POI_XPRS_PREROOTEFFORT 7173\n#define POI_XPRS_BARHGRELTOL 7177\n#define POI_XPRS_EXTRAROWS 8004\n#define POI_XPRS_EXTRACOLS 8005\n#define POI_XPRS_LPITERLIMIT 8007\n#define POI_XPRS_LPLOG 8009\n#define POI_XPRS_SCALING 8010\n#define POI_XPRS_PRESOLVE 8011\n#define POI_XPRS_CRASH 8012\n#define POI_XPRS_PRICINGALG 8013\n#define POI_XPRS_INVERTFREQ 8014\n#define POI_XPRS_INVERTMIN 8015\n#define POI_XPRS_MAXNODE 8018\n#define POI_XPRS_MAXMIPSOL 8021\n#define POI_XPRS_SIFTPASSES 8022\n#define POI_XPRS_DEFAULTALG 8023\n#define POI_XPRS_VARSELECTION 8025\n#define POI_XPRS_NODESELECTION 8026\n#define POI_XPRS_BACKTRACK 8027\n#define POI_XPRS_MIPLOG 8028\n#define POI_XPRS_KEEPNROWS 8030\n#define POI_XPRS_MPSECHO 8032\n#define POI_XPRS_MAXPAGELINES 8034\n#define POI_XPRS_OUTPUTLOG 8035\n#define POI_XPRS_BARSOLUTION 8038\n#define POI_XPRS_CROSSOVER 8044\n#define POI_XPRS_BARITERLIMIT 8045\n#define POI_XPRS_CHOLESKYALG 8046\n#define POI_XPRS_BAROUTPUT 8047\n#define POI_XPRS_EXTRAMIPENTS 8051\n#define POI_XPRS_REFACTOR 8052\n#define POI_XPRS_BARTHREADS 8053\n#define POI_XPRS_KEEPBASIS 8054\n#define POI_XPRS_CROSSOVEROPS 8060\n#define POI_XPRS_VERSION 8061\n#define POI_XPRS_CROSSOVERTHREADS 8065\n#define POI_XPRS_BIGMMETHOD 8068\n#define POI_XPRS_MPSNAMELENGTH 8071\n#define POI_XPRS_ELIMFILLIN 8073\n#define POI_XPRS_PRESOLVEOPS 8077\n#define POI_XPRS_MIPPRESOLVE 8078\n#define POI_XPRS_MIPTHREADS 8079\n#define POI_XPRS_BARORDER 8080\n#define POI_XPRS_BREADTHFIRST 8082\n#define POI_XPRS_AUTOPERTURB 8084\n#define POI_XPRS_DENSECOLLIMIT 8086\n#define POI_XPRS_CALLBACKFROMMAINTHREAD 8090\n#define POI_XPRS_MAXMCOEFFBUFFERELEMS 8091\n#define POI_XPRS_REFINEOPS 8093\n#define POI_XPRS_LPREFINEITERLIMIT 8094\n#define POI_XPRS_MIPREFINEITERLIMIT 8095\n#define POI_XPRS_DUALIZEOPS 8097\n#define POI_XPRS_CROSSOVERITERLIMIT 8104\n#define POI_XPRS_PREBASISRED 8106\n#define POI_XPRS_PRESORT 8107\n#define POI_XPRS_PREPERMUTE 8108\n#define POI_XPRS_PREPERMUTESEED 8109\n#define POI_XPRS_MAXMEMORYSOFT 8112\n#define POI_XPRS_CUTFREQ 8116\n#define POI_XPRS_SYMSELECT 8117\n#define POI_XPRS_SYMMETRY 8118\n#define POI_XPRS_MAXMEMORYHARD 8119\n#define POI_XPRS_MIQCPALG 8125\n#define POI_XPRS_QCCUTS 8126\n#define POI_XPRS_QCROOTALG 8127\n#define POI_XPRS_PRECONVERTSEPARABLE 8128\n#define POI_XPRS_ALGAFTERNETWORK 8129\n#define POI_XPRS_TRACE 8130\n#define POI_XPRS_MAXIIS 8131\n#define POI_XPRS_CPUTIME 8133\n#define POI_XPRS_COVERCUTS 8134\n#define POI_XPRS_GOMCUTS 8135\n#define POI_XPRS_LPFOLDING 8136\n#define POI_XPRS_MPSFORMAT 8137\n#define POI_XPRS_CUTSTRATEGY 8138\n#define POI_XPRS_CUTDEPTH 8139\n#define POI_XPRS_TREECOVERCUTS 8140\n#define POI_XPRS_TREEGOMCUTS 8141\n#define POI_XPRS_CUTSELECT 8142\n#define POI_XPRS_TREECUTSELECT 8143\n#define POI_XPRS_DUALIZE 8144\n#define POI_XPRS_DUALGRADIENT 8145\n#define POI_XPRS_SBITERLIMIT 8146\n#define POI_XPRS_SBBEST 8147\n#define POI_XPRS_BARINDEFLIMIT 8153\n#define POI_XPRS_HEURFREQ 8155\n#define POI_XPRS_HEURDEPTH 8156\n#define POI_XPRS_HEURMAXSOL 8157\n#define POI_XPRS_HEURNODES 8158\n#define POI_XPRS_LNPBEST 8160\n#define POI_XPRS_LNPITERLIMIT 8161\n#define POI_XPRS_BRANCHCHOICE 8162\n#define POI_XPRS_BARREGULARIZE 8163\n#define POI_XPRS_SBSELECT 8164\n#define POI_XPRS_IISLOG 8165\n#define POI_XPRS_LOCALCHOICE 8170\n#define POI_XPRS_LOCALBACKTRACK 8171\n#define POI_XPRS_DUALSTRATEGY 8174\n#define POI_XPRS_HEURDIVESTRATEGY 8177\n#define POI_XPRS_HEURSELECT 8178\n#define POI_XPRS_BARSTART 8180\n#define POI_XPRS_PRESOLVEPASSES 8183\n#define POI_XPRS_BARORDERTHREADS 8187\n#define POI_XPRS_EXTRASETS 8190\n#define POI_XPRS_FEASIBILITYPUMP 8193\n#define POI_XPRS_PRECOEFELIM 8194\n#define POI_XPRS_PREDOMCOL 8195\n#define POI_XPRS_HEURSEARCHFREQ 8196\n#define POI_XPRS_HEURDIVESPEEDUP 8197\n#define POI_XPRS_SBESTIMATE 8198\n#define POI_XPRS_BARCORES 8202\n#define POI_XPRS_MAXCHECKSONMAXTIME 8203\n#define POI_XPRS_MAXCHECKSONMAXCUTTIME 8204\n#define POI_XPRS_HISTORYCOSTS 8206\n#define POI_XPRS_ALGAFTERCROSSOVER 8208\n#define POI_XPRS_MUTEXCALLBACKS 8210\n#define POI_XPRS_BARCRASH 8211\n#define POI_XPRS_HEURDIVESOFTROUNDING 8215\n#define POI_XPRS_HEURSEARCHROOTSELECT 8216\n#define POI_XPRS_HEURSEARCHTREESELECT 8217\n#define POI_XPRS_MPS18COMPATIBLE 8223\n#define POI_XPRS_ROOTPRESOLVE 8224\n#define POI_XPRS_CROSSOVERDRP 8227\n#define POI_XPRS_FORCEOUTPUT 8229\n#define POI_XPRS_PRIMALOPS 8231\n#define POI_XPRS_DETERMINISTIC 8232\n#define POI_XPRS_PREPROBING 8238\n#define POI_XPRS_TREEMEMORYLIMIT 8242\n#define POI_XPRS_TREECOMPRESSION 8243\n#define POI_XPRS_TREEDIAGNOSTICS 8244\n#define POI_XPRS_MAXTREEFILESIZE 8245\n#define POI_XPRS_PRECLIQUESTRATEGY 8247\n#define POI_XPRS_IFCHECKCONVEXITY 8251\n#define POI_XPRS_PRIMALUNSHIFT 8252\n#define POI_XPRS_REPAIRINDEFINITEQ 8254\n#define POI_XPRS_MIPRAMPUP 8255\n#define POI_XPRS_MAXLOCALBACKTRACK 8257\n#define POI_XPRS_USERSOLHEURISTIC 8258\n#define POI_XPRS_PRECONVERTOBJTOCONS 8260\n#define POI_XPRS_FORCEPARALLELDUAL 8265\n#define POI_XPRS_BACKTRACKTIE 8266\n#define POI_XPRS_BRANCHDISJ 8267\n#define POI_XPRS_MIPFRACREDUCE 8270\n#define POI_XPRS_CONCURRENTTHREADS 8274\n#define POI_XPRS_MAXSCALEFACTOR 8275\n#define POI_XPRS_HEURTHREADS 8276\n#define POI_XPRS_THREADS 8278\n#define POI_XPRS_HEURBEFORELP 8280\n#define POI_XPRS_PREDOMROW 8281\n#define POI_XPRS_BRANCHSTRUCTURAL 8282\n#define POI_XPRS_QUADRATICUNSHIFT 8284\n#define POI_XPRS_BARPRESOLVEOPS 8286\n#define POI_XPRS_QSIMPLEXOPS 8288\n#define POI_XPRS_MIPRESTART 8290\n#define POI_XPRS_CONFLICTCUTS 8292\n#define POI_XPRS_PREPROTECTDUAL 8293\n#define POI_XPRS_CORESPERCPU 8296\n#define POI_XPRS_RESOURCESTRATEGY 8297\n#define POI_XPRS_CLAMPING 8301\n#define POI_XPRS_PREDUPROW 8307\n#define POI_XPRS_CPUPLATFORM 8312\n#define POI_XPRS_BARALG 8315\n#define POI_XPRS_SIFTING 8319\n#define POI_XPRS_BARKEEPLASTSOL 8323\n#define POI_XPRS_LPLOGSTYLE 8326\n#define POI_XPRS_RANDOMSEED 8328\n#define POI_XPRS_TREEQCCUTS 8331\n#define POI_XPRS_PRELINDEP 8333\n#define POI_XPRS_DUALTHREADS 8334\n#define POI_XPRS_PREOBJCUTDETECT 8336\n#define POI_XPRS_PREBNDREDQUAD 8337\n#define POI_XPRS_PREBNDREDCONE 8338\n#define POI_XPRS_PRECOMPONENTS 8339\n#define POI_XPRS_MAXMIPTASKS 8347\n#define POI_XPRS_MIPTERMINATIONMETHOD 8348\n#define POI_XPRS_PRECONEDECOMP 8349\n#define POI_XPRS_HEURFORCESPECIALOBJ 8350\n#define POI_XPRS_HEURSEARCHROOTCUTFREQ 8351\n#define POI_XPRS_PREELIMQUAD 8353\n#define POI_XPRS_PREIMPLICATIONS 8356\n#define POI_XPRS_TUNERMODE 8359\n#define POI_XPRS_TUNERMETHOD 8360\n#define POI_XPRS_TUNERTARGET 8362\n#define POI_XPRS_TUNERTHREADS 8363\n#define POI_XPRS_TUNERHISTORY 8365\n#define POI_XPRS_TUNERPERMUTE 8366\n#define POI_XPRS_TUNERVERBOSE 8370\n#define POI_XPRS_TUNEROUTPUT 8372\n#define POI_XPRS_PREANALYTICCENTER 8374\n#define POI_XPRS_LPFLAGS 8385\n#define POI_XPRS_MIPKAPPAFREQ 8386\n#define POI_XPRS_OBJSCALEFACTOR 8387\n#define POI_XPRS_TREEFILELOGINTERVAL 8389\n#define POI_XPRS_IGNORECONTAINERCPULIMIT 8390\n#define POI_XPRS_IGNORECONTAINERMEMORYLIMIT 8391\n#define POI_XPRS_MIPDUALREDUCTIONS 8392\n#define POI_XPRS_GENCONSDUALREDUCTIONS 8395\n#define POI_XPRS_PWLDUALREDUCTIONS 8396\n#define POI_XPRS_BARFAILITERLIMIT 8398\n#define POI_XPRS_AUTOSCALING 8406\n#define POI_XPRS_GENCONSABSTRANSFORMATION 8408\n#define POI_XPRS_COMPUTEJOBPRIORITY 8409\n#define POI_XPRS_PREFOLDING 8410\n#define POI_XPRS_COMPUTE 8411\n#define POI_XPRS_NETSTALLLIMIT 8412\n#define POI_XPRS_SERIALIZEPREINTSOL 8413\n#define POI_XPRS_NUMERICALEMPHASIS 8416\n#define POI_XPRS_PWLNONCONVEXTRANSFORMATION 8420\n#define POI_XPRS_MIPCOMPONENTS 8421\n#define POI_XPRS_MIPCONCURRENTNODES 8422\n#define POI_XPRS_MIPCONCURRENTSOLVES 8423\n#define POI_XPRS_OUTPUTCONTROLS 8424\n#define POI_XPRS_SIFTSWITCH 8425\n#define POI_XPRS_HEUREMPHASIS 8427\n#define POI_XPRS_BARREFITER 8431\n#define POI_XPRS_COMPUTELOG 8434\n#define POI_XPRS_SIFTPRESOLVEOPS 8435\n#define POI_XPRS_CHECKINPUTDATA 8436\n#define POI_XPRS_ESCAPENAMES 8440\n#define POI_XPRS_IOTIMEOUT 8442\n#define POI_XPRS_AUTOCUTTING 8446\n#define POI_XPRS_GLOBALNUMINITNLPCUTS 8449\n#define POI_XPRS_CALLBACKCHECKTIMEDELAY 8451\n#define POI_XPRS_MULTIOBJOPS 8457\n#define POI_XPRS_MULTIOBJLOG 8458\n#define POI_XPRS_BACKGROUNDMAXTHREADS 8461\n#define POI_XPRS_GLOBALLSHEURSTRATEGY 8464\n#define POI_XPRS_GLOBALSPATIALBRANCHIFPREFERORIG 8465\n#define POI_XPRS_PRECONFIGURATION 8470\n#define POI_XPRS_FEASIBILITYJUMP 8471\n#define POI_XPRS_IISOPS 8472\n#define POI_XPRS_RLTCUTS 8476\n#define POI_XPRS_ALTERNATIVEREDCOSTS 8478\n#define POI_XPRS_HEURSHIFTPROP 8479\n#define POI_XPRS_HEURSEARCHCOPYCONTROLS 8480\n#define POI_XPRS_GLOBALNLPCUTS 8481\n#define POI_XPRS_GLOBALTREENLPCUTS 8482\n#define POI_XPRS_BARHGOPS 8483\n#define POI_XPRS_BARHGMAXRESTARTS 8484\n#define POI_XPRS_MCFCUTSTRATEGY 8486\n#define POI_XPRS_PREROOTTHREADS 8490\n#define POI_XPRS_BARITERATIVE 8492\n#define POI_XPRS_GLOBALPRESOLVEOBBT 8494\n#define POI_XPRS_SDPCUTSTRATEGY 8497\n#define POI_XPRS_DETERMINISTICLOG 8505\n#define POI_XPRS_BARHGGPU 8506\n#define POI_XPRS_BARHGPRECISION 8507\n#define POI_XPRS_BARHGGPUBLOCKSIZE 8508\n#define POI_XPRS_GPUPLATFORM 8510\n#define POI_XPRS_EXTRAELEMS 8006\n#define POI_XPRS_EXTRASETELEMS 8191\n#define POI_XPRS_BACKGROUNDSELECT 8463\n#define POI_XPRS_HEURSEARCHBACKGROUNDSELECT 8477\n\n#define POI_XPRS_MATRIXNAME 3001\n#define POI_XPRS_BOUNDNAME 3002\n#define POI_XPRS_RHSNAME 3004\n#define POI_XPRS_RANGENAME 3005\n#define POI_XPRS_XPRESSVERSION 3010\n#define POI_XPRS_UUID 3011\n#define POI_XPRS_MIPSOLTIME 1371\n#define POI_XPRS_TIME 1122\n#define POI_XPRS_LPOBJVAL 2001\n#define POI_XPRS_SUMPRIMALINF 2002\n#define POI_XPRS_MIPOBJVAL 2003\n#define POI_XPRS_BESTBOUND 2004\n#define POI_XPRS_OBJRHS 2005\n#define POI_XPRS_MIPBESTOBJVAL 2006\n#define POI_XPRS_OBJSENSE 2008\n#define POI_XPRS_BRANCHVALUE 2009\n#define POI_XPRS_PENALTYVALUE 2061\n#define POI_XPRS_CURRMIPCUTOFF 2062\n#define POI_XPRS_BARCONDA 2063\n#define POI_XPRS_BARCONDD 2064\n#define POI_XPRS_MAXABSPRIMALINFEAS 2073\n#define POI_XPRS_MAXRELPRIMALINFEAS 2074\n#define POI_XPRS_MAXABSDUALINFEAS 2075\n#define POI_XPRS_MAXRELDUALINFEAS 2076\n#define POI_XPRS_PRIMALDUALINTEGRAL 2079\n#define POI_XPRS_MAXMIPINFEAS 2083\n#define POI_XPRS_ATTENTIONLEVEL 2097\n#define POI_XPRS_MAXKAPPA 2098\n#define POI_XPRS_TREECOMPLETION 2104\n#define POI_XPRS_PREDICTEDATTLEVEL 2105\n#define POI_XPRS_OBSERVEDPRIMALINTEGRAL 2106\n#define POI_XPRS_CPISCALEFACTOR 2117\n#define POI_XPRS_OBJVAL 2118\n#define POI_XPRS_WORK 2120\n#define POI_XPRS_BARPRIMALOBJ 4001\n#define POI_XPRS_BARDUALOBJ 4002\n#define POI_XPRS_BARPRIMALINF 4003\n#define POI_XPRS_BARDUALINF 4004\n#define POI_XPRS_BARCGAP 4005\n#define POI_XPRS_ROWS 1001\n#define POI_XPRS_SETS 1004\n#define POI_XPRS_PRIMALINFEAS 1007\n#define POI_XPRS_DUALINFEAS 1008\n#define POI_XPRS_SIMPLEXITER 1009\n#define POI_XPRS_LPSTATUS 1010\n#define POI_XPRS_MIPSTATUS 1011\n#define POI_XPRS_CUTS 1012\n#define POI_XPRS_NODES 1013\n#define POI_XPRS_NODEDEPTH 1014\n#define POI_XPRS_ACTIVENODES 1015\n#define POI_XPRS_MIPSOLNODE 1016\n#define POI_XPRS_MIPSOLS 1017\n#define POI_XPRS_COLS 1018\n#define POI_XPRS_SPAREROWS 1019\n#define POI_XPRS_SPARECOLS 1020\n#define POI_XPRS_SPAREMIPENTS 1022\n#define POI_XPRS_ERRORCODE 1023\n#define POI_XPRS_MIPINFEAS 1024\n#define POI_XPRS_PRESOLVESTATE 1026\n#define POI_XPRS_PARENTNODE 1027\n#define POI_XPRS_NAMELENGTH 1028\n#define POI_XPRS_QELEMS 1030\n#define POI_XPRS_NUMIIS 1031\n#define POI_XPRS_MIPENTS 1032\n#define POI_XPRS_BRANCHVAR 1036\n#define POI_XPRS_MIPTHREADID 1037\n#define POI_XPRS_ALGORITHM 1049\n#define POI_XPRS_CROSSOVERITER 1051\n#define POI_XPRS_SOLSTATUS 1053\n#define POI_XPRS_CUTROUNDS 1121\n#define POI_XPRS_ORIGINALROWS 1124\n#define POI_XPRS_CALLBACKCOUNT_OPTNODE 1136\n#define POI_XPRS_ORIGINALQELEMS 1157\n#define POI_XPRS_MAXPROBNAMELENGTH 1158\n#define POI_XPRS_STOPSTATUS 1179\n#define POI_XPRS_ORIGINALMIPENTS 1191\n#define POI_XPRS_ORIGINALSETS 1194\n#define POI_XPRS_SPARESETS 1203\n#define POI_XPRS_CHECKSONMAXTIME 1208\n#define POI_XPRS_CHECKSONMAXCUTTIME 1209\n#define POI_XPRS_ORIGINALCOLS 1214\n#define POI_XPRS_QCELEMS 1232\n#define POI_XPRS_QCONSTRAINTS 1234\n#define POI_XPRS_ORIGINALQCELEMS 1237\n#define POI_XPRS_ORIGINALQCONSTRAINTS 1239\n#define POI_XPRS_PEAKTOTALTREEMEMORYUSAGE 1240\n#define POI_XPRS_CURRENTNODE 1248\n#define POI_XPRS_TREEMEMORYUSAGE 1251\n#define POI_XPRS_TREEFILESIZE 1252\n#define POI_XPRS_TREEFILEUSAGE 1253\n#define POI_XPRS_INDICATORS 1254\n#define POI_XPRS_ORIGINALINDICATORS 1255\n#define POI_XPRS_CORESPERCPUDETECTED 1258\n#define POI_XPRS_CPUSDETECTED 1259\n#define POI_XPRS_CORESDETECTED 1260\n#define POI_XPRS_PHYSICALCORESDETECTED 1261\n#define POI_XPRS_PHYSICALCORESPERCPUDETECTED 1262\n#define POI_XPRS_OPTIMIZETYPEUSED 1268\n#define POI_XPRS_BARSING 1281\n#define POI_XPRS_BARSINGR 1282\n#define POI_XPRS_PRESOLVEINDEX 1284\n#define POI_XPRS_CONES 1307\n#define POI_XPRS_CONEELEMS 1308\n#define POI_XPRS_PWLCONS 1325\n#define POI_XPRS_GENCONS 1327\n#define POI_XPRS_TREERESTARTS 1335\n#define POI_XPRS_ORIGINALPWLS 1336\n#define POI_XPRS_ORIGINALGENCONS 1338\n#define POI_XPRS_COMPUTEEXECUTIONS 1356\n#define POI_XPRS_RESTARTS 1381\n#define POI_XPRS_SOLVESTATUS 1394\n#define POI_XPRS_GLOBALBOUNDINGBOXAPPLIED 1396\n#define POI_XPRS_OBJECTIVES 1397\n#define POI_XPRS_SOLVEDOBJS 1399\n#define POI_XPRS_OBJSTOSOLVE 1400\n#define POI_XPRS_GLOBALNLPINFEAS 1403\n#define POI_XPRS_IISSOLSTATUS 1406\n#define POI_XPRS_INPUTROWS 1408\n#define POI_XPRS_INPUTCOLS 1409\n#define POI_XPRS_BARITER 5001\n#define POI_XPRS_BARDENSECOL 5004\n#define POI_XPRS_BARCROSSOVER 5005\n#define POI_XPRS_IIS XPRS_NUMIIS\n#define POI_XPRS_SETMEMBERS 1005\n#define POI_XPRS_ELEMS 1006\n#define POI_XPRS_SPAREELEMS 1021\n#define POI_XPRS_SYSTEMMEMORY 1148\n#define POI_XPRS_ORIGINALSETMEMBERS 1195\n#define POI_XPRS_SPARESETELEMS 1204\n#define POI_XPRS_CURRENTMEMORY 1285\n#define POI_XPRS_PEAKMEMORY 1286\n#define POI_XPRS_TOTALMEMORY 1322\n#define POI_XPRS_AVAILABLEMEMORY 1324\n#define POI_XPRS_PWLPOINTS 1326\n#define POI_XPRS_GENCONCOLS 1328\n#define POI_XPRS_GENCONVALS 1329\n#define POI_XPRS_ORIGINALPWLPOINTS 1337\n#define POI_XPRS_ORIGINALGENCONCOLS 1339\n#define POI_XPRS_ORIGINALGENCONVALS 1340\n#define POI_XPRS_MEMORYLIMITDETECTED 1380\n#define POI_XPRS_BARAASIZE 5002\n#define POI_XPRS_BARLSIZE 5003\n\n#define POI_XPRS_NLPFUNCEVAL 12312\n#define POI_XPRS_NLPLOG 12316\n#define POI_XPRS_NLPKEEPEQUALSCOLUMN 12325\n#define POI_XPRS_NLPEVALUATE 12334\n#define POI_XPRS_NLPPRESOLVE 12344\n#define POI_XPRS_SLPLOG 12346\n#define POI_XPRS_LOCALSOLVER 12352\n#define POI_XPRS_NLPSTOPOUTOFRANGE 12354\n#define POI_XPRS_NLPTHREADSAFEUSERFUNC 12359\n#define POI_XPRS_NLPJACOBIAN 12360\n#define POI_XPRS_NLPHESSIAN 12361\n#define POI_XPRS_MULTISTART 12362\n#define POI_XPRS_MULTISTART_THREADS 12363\n#define POI_XPRS_MULTISTART_MAXSOLVES 12364\n#define POI_XPRS_MULTISTART_MAXTIME 12365\n#define POI_XPRS_NLPMAXTIME 12366\n#define POI_XPRS_NLPDERIVATIVES 12373\n#define POI_XPRS_NLPREFORMULATE 12392\n#define POI_XPRS_NLPPRESOLVEOPS 12393\n#define POI_XPRS_MULTISTART_LOG 12395\n#define POI_XPRS_MULTISTART_SEED 12396\n#define POI_XPRS_MULTISTART_POOLSIZE 12397\n#define POI_XPRS_NLPPOSTSOLVE 12398\n#define POI_XPRS_NLPDETERMINISTIC 12399\n#define POI_XPRS_NLPPRESOLVELEVEL 12402\n#define POI_XPRS_NLPPROBING 12403\n#define POI_XPRS_NLPCALCTHREADS 12405\n#define POI_XPRS_NLPTHREADS 12406\n#define POI_XPRS_NLPFINDIV 12413\n#define POI_XPRS_NLPLINQUADBR 12414\n#define POI_XPRS_NLPSOLVER 12417\n#define POI_XPRS_SLPALGORITHM 12301\n#define POI_XPRS_SLPAUGMENTATION 12302\n#define POI_XPRS_SLPBARLIMIT 12303\n#define POI_XPRS_SLPCASCADE 12304\n#define POI_XPRS_SLPCASCADENLIMIT 12306\n#define POI_XPRS_SLPDAMPSTART 12308\n#define POI_XPRS_SLPCUTSTRATEGY 12310\n#define POI_XPRS_SLPDELTAZLIMIT 12311\n#define POI_XPRS_SLPINFEASLIMIT 12314\n#define POI_XPRS_SLPITERLIMIT 12315\n#define POI_XPRS_SLPSAMECOUNT 12317\n#define POI_XPRS_SLPSAMEDAMP 12319\n#define POI_XPRS_SLPSBSTART 12320\n#define POI_XPRS_SLPXCOUNT 12321\n#define POI_XPRS_SLPXLIMIT 12322\n#define POI_XPRS_SLPDELAYUPDATEROWS 12329\n#define POI_XPRS_SLPAUTOSAVE 12330\n#define POI_XPRS_SLPANALYZE 12332\n#define POI_XPRS_SLPOCOUNT 12333\n#define POI_XPRS_SLPMIPALGORITHM 12336\n#define POI_XPRS_SLPMIPRELAXSTEPBOUNDS 12337\n#define POI_XPRS_SLPMIPFIXSTEPBOUNDS 12338\n#define POI_XPRS_SLPMIPITERLIMIT 12339\n#define POI_XPRS_SLPMIPCUTOFFLIMIT 12340\n#define POI_XPRS_SLPMIPOCOUNT 12341\n#define POI_XPRS_SLPMIPDEFAULTALGORITHM 12343\n#define POI_XPRS_SLPMIPLOG 12347\n#define POI_XPRS_SLPDELTAOFFSET 12348\n#define POI_XPRS_SLPUPDATEOFFSET 12349\n#define POI_XPRS_SLPERROROFFSET 12350\n#define POI_XPRS_SLPSBROWOFFSET 12351\n#define POI_XPRS_SLPVCOUNT 12356\n#define POI_XPRS_SLPVLIMIT 12357\n#define POI_XPRS_SLPSCALE 12367\n#define POI_XPRS_SLPSCALECOUNT 12368\n#define POI_XPRS_SLPECFCHECK 12369\n#define POI_XPRS_SLPMIPCUTOFFCOUNT 12370\n#define POI_XPRS_SLPWCOUNT 12374\n#define POI_XPRS_SLPUNFINISHEDLIMIT 12376\n#define POI_XPRS_SLPCONVERGENCEOPS 12377\n#define POI_XPRS_SLPZEROCRITERION 12378\n#define POI_XPRS_SLPZEROCRITERIONSTART 12379\n#define POI_XPRS_SLPZEROCRITERIONCOUNT 12380\n#define POI_XPRS_SLPLSPATTERNLIMIT 12381\n#define POI_XPRS_SLPLSITERLIMIT 12382\n#define POI_XPRS_SLPLSSTART 12383\n#define POI_XPRS_SLPPENALTYINFOSTART 12384\n#define POI_XPRS_SLPFILTER 12387\n#define POI_XPRS_SLPTRACEMASKOPS 12388\n#define POI_XPRS_SLPLSZEROLIMIT 12389\n#define POI_XPRS_SLPHEURSTRATEGY 12400\n#define POI_XPRS_SLPBARCROSSOVERSTART 12408\n#define POI_XPRS_SLPBARSTALLINGLIMIT 12409\n#define POI_XPRS_SLPBARSTALLINGOBJLIMIT 12410\n#define POI_XPRS_SLPBARSTARTOPS 12411\n#define POI_XPRS_SLPGRIDHEURSELECT 12412\n#define POI_XPRS_NLPINFINITY 12119\n#define POI_XPRS_NLPZERO 12123\n#define POI_XPRS_NLPDEFAULTIV 12145\n#define POI_XPRS_NLPOPTTIME 12147\n#define POI_XPRS_NLPVALIDATIONTOL_A 12165\n#define POI_XPRS_NLPVALIDATIONTOL_R 12166\n#define POI_XPRS_NLPVALIDATIONINDEX_A 12167\n#define POI_XPRS_NLPVALIDATIONINDEX_R 12168\n#define POI_XPRS_NLPPRIMALINTEGRALREF 12175\n#define POI_XPRS_NLPPRIMALINTEGRALALPHA 12176\n#define POI_XPRS_NLPOBJVAL 12179\n#define POI_XPRS_NLPPRESOLVEZERO 12193\n#define POI_XPRS_NLPMERITLAMBDA 12197\n#define POI_XPRS_MSMAXBOUNDRANGE 12204\n#define POI_XPRS_NLPVALIDATIONTOL_K 12205\n#define POI_XPRS_NLPPRESOLVE_ELIMTOL 12206\n#define POI_XPRS_NLPVALIDATIONTARGET_R 12209\n#define POI_XPRS_NLPVALIDATIONTARGET_K 12210\n#define POI_XPRS_NLPVALIDATIONFACTOR 12211\n#define POI_XPRS_NLPRELTOLBOUNDTHRESHOLD 12215\n#define POI_XPRS_SLPDAMP 12103\n#define POI_XPRS_SLPDAMPEXPAND 12104\n#define POI_XPRS_SLPDAMPSHRINK 12105\n#define POI_XPRS_SLPDELTA_A 12106\n#define POI_XPRS_SLPDELTA_R 12107\n#define POI_XPRS_SLPDELTA_Z 12108\n#define POI_XPRS_SLPDELTACOST 12109\n#define POI_XPRS_SLPDELTAMAXCOST 12110\n#define POI_XPRS_SLPDJTOL 12112\n#define POI_XPRS_SLPERRORCOST 12113\n#define POI_XPRS_SLPERRORMAXCOST 12114\n#define POI_XPRS_SLPERRORTOL_A 12116\n#define POI_XPRS_SLPEXPAND 12118\n#define POI_XPRS_SLPMAXWEIGHT 12120\n#define POI_XPRS_SLPMINWEIGHT 12121\n#define POI_XPRS_SLPSHRINK 12122\n#define POI_XPRS_SLPCTOL 12124\n#define POI_XPRS_SLPATOL_A 12125\n#define POI_XPRS_SLPATOL_R 12126\n#define POI_XPRS_SLPMTOL_A 12127\n#define POI_XPRS_SLPMTOL_R 12128\n#define POI_XPRS_SLPITOL_A 12129\n#define POI_XPRS_SLPITOL_R 12130\n#define POI_XPRS_SLPSTOL_A 12131\n#define POI_XPRS_SLPSTOL_R 12132\n#define POI_XPRS_SLPMVTOL 12133\n#define POI_XPRS_SLPXTOL_A 12134\n#define POI_XPRS_SLPXTOL_R 12135\n#define POI_XPRS_SLPDEFAULTSTEPBOUND 12136\n#define POI_XPRS_SLPDAMPMAX 12137\n#define POI_XPRS_SLPDAMPMIN 12138\n#define POI_XPRS_SLPDELTACOSTFACTOR 12139\n#define POI_XPRS_SLPERRORCOSTFACTOR 12140\n#define POI_XPRS_SLPERRORTOL_P 12141\n#define POI_XPRS_SLPCASCADETOL_PA 12142\n#define POI_XPRS_SLPCASCADETOL_PR 12143\n#define POI_XPRS_SLPCASCADETOL_Z 12144\n#define POI_XPRS_SLPOTOL_A 12150\n#define POI_XPRS_SLPOTOL_R 12151\n#define POI_XPRS_SLPDELTA_X 12152\n#define POI_XPRS_SLPERRORCOSTS 12153\n#define POI_XPRS_SLPGRANULARITY 12157\n#define POI_XPRS_SLPMIPCUTOFF_A 12158\n#define POI_XPRS_SLPMIPCUTOFF_R 12159\n#define POI_XPRS_SLPMIPOTOL_A 12160\n#define POI_XPRS_SLPMIPOTOL_R 12161\n#define POI_XPRS_SLPESCALATION 12169\n#define POI_XPRS_SLPOBJTOPENALTYCOST 12170\n#define POI_XPRS_SLPSHRINKBIAS 12171\n#define POI_XPRS_SLPFEASTOLTARGET 12172\n#define POI_XPRS_SLPOPTIMALITYTOLTARGET 12173\n#define POI_XPRS_SLPDELTA_INFINITY 12174\n#define POI_XPRS_SLPVTOL_A 12177\n#define POI_XPRS_SLPVTOL_R 12178\n#define POI_XPRS_SLPETOL_A 12180\n#define POI_XPRS_SLPETOL_R 12181\n#define POI_XPRS_SLPEVTOL_A 12182\n#define POI_XPRS_SLPEVTOL_R 12183\n#define POI_XPRS_SLPDELTA_ZERO 12184\n#define POI_XPRS_SLPMINSBFACTOR 12185\n#define POI_XPRS_SLPCLAMPVALIDATIONTOL_A 12186\n#define POI_XPRS_SLPCLAMPVALIDATIONTOL_R 12187\n#define POI_XPRS_SLPCLAMPSHRINK 12188\n#define POI_XPRS_SLPECFTOL_A 12189\n#define POI_XPRS_SLPECFTOL_R 12190\n#define POI_XPRS_SLPWTOL_A 12191\n#define POI_XPRS_SLPWTOL_R 12192\n#define POI_XPRS_SLPMATRIXTOL 12194\n#define POI_XPRS_SLPDRFIXRANGE 12195\n#define POI_XPRS_SLPDRCOLTOL 12196\n#define POI_XPRS_SLPMIPERRORTOL_A 12198\n#define POI_XPRS_SLPMIPERRORTOL_R 12199\n#define POI_XPRS_SLPCDTOL_A 12200\n#define POI_XPRS_SLPCDTOL_R 12201\n#define POI_XPRS_SLPENFORCEMAXCOST 12202\n#define POI_XPRS_SLPENFORCECOSTSHRINK 12203\n#define POI_XPRS_SLPDRCOLDJTOL 12208\n#define POI_XPRS_SLPBARSTALLINGTOL 12212\n#define POI_XPRS_SLPOBJTHRESHOLD 12213\n#define POI_XPRS_SLPBOUNDTHRESHOLD 12214\n#define POI_XPRS_NLPIVNAME 12453\n#define POI_XPRS_SLPDELTAFORMAT 12452\n#define POI_XPRS_SLPMINUSDELTAFORMAT 12456\n#define POI_XPRS_SLPMINUSERRORFORMAT 12457\n#define POI_XPRS_SLPPLUSDELTAFORMAT 12458\n#define POI_XPRS_SLPPLUSERRORFORMAT 12459\n#define POI_XPRS_SLPSBNAME 12460\n#define POI_XPRS_SLPTOLNAME 12461\n#define POI_XPRS_SLPUPDATEFORMAT 12462\n#define POI_XPRS_SLPPENALTYROWFORMAT 12463\n#define POI_XPRS_SLPPENALTYCOLFORMAT 12464\n#define POI_XPRS_SLPSBLOROWFORMAT 12467\n#define POI_XPRS_SLPSBUPROWFORMAT 12468\n#define POI_XPRS_SLPTRACEMASK 12472\n#define POI_XPRS_SLPITERFALLBACKOPS 12474\n#define POI_XPRS_NLPVALIDATIONSTATUS 11986\n#define POI_XPRS_NLPSOLSTATUS 11987\n#define POI_XPRS_NLPORIGINALROWS 11999\n#define POI_XPRS_NLPORIGINALCOLS 12000\n#define POI_XPRS_NLPUFS 12007\n#define POI_XPRS_NLPIFS 12008\n#define POI_XPRS_NLPEQUALSCOLUMN 12013\n#define POI_XPRS_NLPVARIABLES 12014\n#define POI_XPRS_NLPIMPLICITVARIABLES 12015\n#define POI_XPRS_NONLINEARCONSTRAINTS 12026\n#define POI_XPRS_NLPUSERFUNCCALLS 12031\n#define POI_XPRS_NLPUSEDERIVATIVES 12037\n#define POI_XPRS_NLPKEEPBESTITER 12042\n#define POI_XPRS_NLPSTATUS 12044\n#define POI_XPRS_LOCALSOLVERSELECTED 12075\n#define POI_XPRS_NLPMODELROWS 12079\n#define POI_XPRS_NLPMODELCOLS 12080\n#define POI_XPRS_NLPJOBID 12081\n#define POI_XPRS_MSJOBS 12082\n#define POI_XPRS_NLPSTOPSTATUS 12089\n#define POI_XPRS_NLPPRESOLVEELIMINATIONS 12090\n#define POI_XPRS_NLPTOTALEVALUATIONERRORS 12093\n#define POI_XPRS_SLPEXPLOREDELTAS 11993\n#define POI_XPRS_SLPSEMICONTDELTAS 11994\n#define POI_XPRS_SLPINTEGERDELTAS 11995\n#define POI_XPRS_SLPITER 12001\n#define POI_XPRS_SLPSTATUS 12002\n#define POI_XPRS_SLPUNCONVERGED 12003\n#define POI_XPRS_SLPSBXCONVERGED 12004\n#define POI_XPRS_SLPPENALTYDELTAROW 12009\n#define POI_XPRS_SLPPENALTYDELTACOLUMN 12010\n#define POI_XPRS_SLPPENALTYERRORROW 12011\n#define POI_XPRS_SLPPENALTYERRORCOLUMN 12012\n#define POI_XPRS_SLPCOEFFICIENTS 12016\n#define POI_XPRS_SLPPENALTYDELTAS 12017\n#define POI_XPRS_SLPPENALTYERRORS 12018\n#define POI_XPRS_SLPPLUSPENALTYERRORS 12019\n#define POI_XPRS_SLPMINUSPENALTYERRORS 12020\n#define POI_XPRS_SLPUCCONSTRAINEDCOUNT 12021\n#define POI_XPRS_SLPMIPNODES 12022\n#define POI_XPRS_SLPMIPITER 12023\n#define POI_XPRS_SLPTOLSETS 12028\n#define POI_XPRS_SLPECFCOUNT 12035\n#define POI_XPRS_SLPDELTAS 12041\n#define POI_XPRS_SLPZEROESRESET 12046\n#define POI_XPRS_SLPZEROESTOTAL 12047\n#define POI_XPRS_SLPZEROESRETAINED 12048\n#define POI_XPRS_SLPNONCONSTANTCOEFFS 12058\n#define POI_XPRS_SLPMIPSOLS 12088\n#define POI_XPRS_NLPVALIDATIONINDEX_K 12718\n#define POI_XPRS_NLPVALIDATIONNETOBJ 12722\n#define POI_XPRS_NLPPRIMALINTEGRAL 12726\n#define POI_XPRS_SLPCURRENTDELTACOST 12701\n#define POI_XPRS_SLPCURRENTERRORCOST 12702\n#define POI_XPRS_SLPPENALTYERRORTOTAL 12704\n#define POI_XPRS_SLPPENALTYERRORVALUE 12705\n#define POI_XPRS_SLPPENALTYDELTATOTAL 12706\n#define POI_XPRS_SLPPENALTYDELTAVALUE 12707\n\n#define POI_XPRS_TOK_EOF 0\n#define POI_XPRS_TOK_CON 1\n#define POI_XPRS_TOK_COL 10\n#define POI_XPRS_TOK_FUN 11\n#define POI_XPRS_TOK_IFUN 12\n#define POI_XPRS_TOK_LB 21\n#define POI_XPRS_TOK_RB 22\n#define POI_XPRS_TOK_DEL 24\n#define POI_XPRS_TOK_OP 31\n#define POI_XPRS_OP_UMINUS 1\n#define POI_XPRS_OP_EXPONENT 2\n#define POI_XPRS_OP_MULTIPLY 3\n#define POI_XPRS_OP_DIVIDE 4\n#define POI_XPRS_OP_PLUS 5\n#define POI_XPRS_OP_MINUS 6\n#define POI_XPRS_DEL_COMMA 1\n#define POI_XPRS_DEL_COLON 2\n#define POI_XPRS_IFUN_LOG10 14\n#define POI_XPRS_IFUN_LN 15\n#define POI_XPRS_IFUN_EXP 16\n#define POI_XPRS_IFUN_ABS 17\n#define POI_XPRS_IFUN_SQRT 18\n#define POI_XPRS_IFUN_SIN 27\n#define POI_XPRS_IFUN_COS 28\n#define POI_XPRS_IFUN_TAN 29\n#define POI_XPRS_IFUN_ARCSIN 30\n#define POI_XPRS_IFUN_ARCCOS 31\n#define POI_XPRS_IFUN_ARCTAN 32\n#define POI_XPRS_IFUN_MIN 33\n#define POI_XPRS_IFUN_MAX 34\n#define POI_XPRS_IFUN_PWL 35\n#define POI_XPRS_IFUN_SUM 36\n#define POI_XPRS_IFUN_PROD 37\n#define POI_XPRS_IFUN_SIGN 46\n#define POI_XPRS_IFUN_ERF 49\n#define POI_XPRS_IFUN_ERFC 50\n#define POI_XPRS_SLPTOLSET_TC 0\n#define POI_XPRS_SLPTOLSET_TA 1\n#define POI_XPRS_SLPTOLSET_RA 2\n#define POI_XPRS_SLPTOLSET_TM 3\n#define POI_XPRS_SLPTOLSET_RM 4\n#define POI_XPRS_SLPTOLSET_TI 5\n#define POI_XPRS_SLPTOLSET_RI 6\n#define POI_XPRS_SLPTOLSET_TS 7\n#define POI_XPRS_SLPTOLSET_RS 8\n#define POI_XPRS_SLPTOLSETBIT_TC 0x001\n#define POI_XPRS_SLPTOLSETBIT_TA 0x002\n#define POI_XPRS_SLPTOLSETBIT_RA 0x004\n#define POI_XPRS_SLPTOLSETBIT_TM 0x008\n#define POI_XPRS_SLPTOLSETBIT_RM 0x010\n#define POI_XPRS_SLPTOLSETBIT_TI 0x020\n#define POI_XPRS_SLPTOLSETBIT_RI 0x040\n#define POI_XPRS_SLPTOLSETBIT_TS 0x080\n#define POI_XPRS_SLPTOLSETBIT_RS 0x100\n#define POI_XPRS_SLPTOLSET_DELETE 0x10000\n#define POI_XPRS_SLPCONVERGEBIT_CTOL 0x1\n#define POI_XPRS_SLPCONVERGEBIT_ATOL 0x2\n#define POI_XPRS_SLPCONVERGEBIT_MTOL 0x4\n#define POI_XPRS_SLPCONVERGEBIT_ITOL 0x8\n#define POI_XPRS_SLPCONVERGEBIT_STOL 0x10\n#define POI_XPRS_SLPCONVERGEBIT_USER 0x20\n#define POI_XPRS_SLPCONVERGEBIT_VTOL 0x40\n#define POI_XPRS_SLPCONVERGEBIT_XTOL 0x80\n#define POI_XPRS_SLPCONVERGEBIT_OTOL 0x100\n#define POI_XPRS_SLPCONVERGEBIT_WTOL 0x200\n#define POI_XPRS_SLPCONVERGEBIT_EXTENDEDSCALING 0x400\n#define POI_XPRS_SLPCONVERGEBIT_VALIDATION 0x800\n#define POI_XPRS_SLPCONVERGEBIT_VALIDATION_K 0x1000\n#define POI_XPRS_SLPCONVERGEBIT_NOQUADCHECK 0x2000\n#define POI_XPRS_SLPCONVERGEBIT_REQUIRE_OTOL_R 0x8000\n#define POI_XPRS_SLPHASNOCOEFS 0x01\n#define POI_XPRS_SLPHASDELTA 0x02\n#define POI_XPRS_SLPHASIV 0x04\n#define POI_XPRS_SLPHASCALCIV 0x08\n#define POI_XPRS_SLPISDELTA 0x0100\n#define POI_XPRS_SLPISPLUSPENALTYDELTA 0x0200\n#define POI_XPRS_SLPISMINUSPENALTYDELTA 0x0400\n#define POI_XPRS_SLPISPENALTYDELTA 0x0600\n#define POI_XPRS_SLPISPLUSERRORVECTOR 0x0800\n#define POI_XPRS_SLPISMINUSERRORVECTOR 0x1000\n#define POI_XPRS_SLPISERRORVECTOR 0x1800\n#define POI_XPRS_SLPISMISCVECTOR 0x2000\n#define POI_XPRS_SLPISEQUALSCOLUMN 0x4000\n#define POI_XPRS_NLPPRESOLVEPROTECT 0x8000\n#define POI_XPRS_SLPHASCONVERGED 0x10000\n#define POI_XPRS_SLPACTIVESTEPBOUND 0x20000\n#define POI_XPRS_SLPACTIVESBROW 0x40000\n#define POI_XPRS_SLPELIMINATEDCOL 0x80000\n#define POI_XPRS_SLPISSTRUCTURALCOLUMN 0x200000\n#define POI_XPRS_SLPISINCOEFS 0x400000\n#define POI_XPRS_SLPISINGLOBAL 0x800000\n#define POI_XPRS_SLPHASZEROBOUND 0x1000000\n#define POI_XPRS_SLPFIXEDVAR 0x2000000\n#define POI_XPRS_SLPBOUNDSSET 0x4000000\n#define POI_XPRS_SLPUSEFULDELTA 0x8000000\n#define POI_XPRS_SLPNOUSEFULDELTA 0x8000000\n#define POI_XPRS_SLPISINTEGER 0x10000000\n#define POI_XPRS_SLPCASCADECONTRACTION 0x20000000\n#define POI_XPRS_SLPISUPDATEROW 0x02\n#define POI_XPRS_SLPISPENALTYROW 0x04\n#define POI_XPRS_SLPISMISCROW 0x40\n#define POI_XPRS_SLPISSBROW 0x80\n#define POI_XPRS_SLPHASPLUSERROR 0x100\n#define POI_XPRS_SLPHASMINUSERROR 0x200\n#define POI_XPRS_SLPHASERROR 0x300\n#define POI_XPRS_SLPISDETERMININGROW 0x400\n#define POI_XPRS_SLPNOERRORVECTORS 0x800\n#define POI_XPRS_SLPHASNONZEROCOEF 0x1000\n#define POI_XPRS_SLPREDUNDANTROW 0x2000\n#define POI_XPRS_SLPUNCONVERGEDROW 0x4000\n#define POI_XPRS_SLPACTIVEPENALTY 0x8000\n#define POI_XPRS_SLPHASSLPELEMENT 0x10000\n#define POI_XPRS_SLPTRANSFERROW 0x40000\n#define POI_XPRS_SLPMINIMUMAUGMENTATION 0x01\n#define POI_XPRS_SLPEVENHANDEDAUGMENTATION 0x02\n#define POI_XPRS_SLPEQUALITYERRORVECTORS 0x04\n#define POI_XPRS_SLPALLERRORVECTORS 0x08\n#define POI_XPRS_SLPPENALTYDELTAVECTORS 0x10\n#define POI_XPRS_SLPAMEANWEIGHT 0x20\n#define POI_XPRS_SLPSBFROMVALUES 0x40\n#define POI_XPRS_SLPSBFROMABSVALUES 0x80\n#define POI_XPRS_SLPSTEPBOUNDROWS 0x100\n#define POI_XPRS_SLPALLROWERRORVECTORS 0x200\n#define POI_XPRS_SLPNOUPDATEIFONLYIV 0x400\n#define POI_XPRS_SLPSKIPIVLPHEURISTICS 0x1000\n#define POI_XPRS_SLPNOSTEPBOUNDS 0x01\n#define POI_XPRS_SLPSTEPBOUNDSASREQUIRED 0x02\n#define POI_XPRS_SLPESTIMATESTEPBOUNDS 0x04\n#define POI_XPRS_SLPDYNAMICDAMPING 0x08\n#define POI_XPRS_SLPHOLDVALUES 0x10\n#define POI_XPRS_SLPRETAINPREVIOUSVALUE 0x20\n#define POI_XPRS_SLPRESETDELTAZ 0x40\n#define POI_XPRS_SLPQUICKCONVERGENCECHECK 0x80\n#define POI_XPRS_SLPESCALATEPENALTIES 0x100\n#define POI_XPRS_SLPSWITCHTOPRIMAL 0x200\n#define POI_XPRS_SLPNONZEROBOUND 0x400\n#define POI_XPRS_SLPMAXCOSTOPTION 0x800\n#define POI_XPRS_SLPRESIDUALERRORS 0x1000\n#define POI_XPRS_SLPNOLPPOLISHING 0x2000\n#define POI_XPRS_SLPCASCADEDBOUNDS 0x4000\n#define POI_XPRS_SLPCLAMPEXTENDEDACTIVESB 0x8000\n#define POI_XPRS_SLPCLAMPEXTENDEDALL 0x10000\n#define POI_XPRS_SLPMIPINITIALSLP 0x01\n#define POI_XPRS_SLPMIPINITIALRELAXSLP 0x04\n#define POI_XPRS_SLPMIPINITIALFIXSLP 0x08\n#define POI_XPRS_SLPMIPNODERELAXSLP 0x10\n#define POI_XPRS_SLPMIPNODEFIXSLP 0x20\n#define POI_XPRS_SLPMIPNODELIMITSLP 0x40\n#define POI_XPRS_SLPMIPFINALRELAXSLP 0x80\n#define POI_XPRS_SLPMIPFINALFIXSLP 0x100\n#define POI_XPRS_SLPMIPWITHINSLP 0x200\n#define POI_XPRS_SLPSLPTHENMIP 0x400\n#define POI_XPRS_SLPROOTMIPDRIVEN 0x1000\n#define POI_XPRS_SLPSTATUS_CONVERGEDOBJUCC 0x01\n#define POI_XPRS_SLPSTATUS_CONVERGEDOBJSBX 0x02\n#define POI_XPRS_SLPSTATUS_LPINFEASIBLE 0x04\n#define POI_XPRS_SLPSTATUS_LPUNFINISHED 0x08\n#define POI_XPRS_SLPSTATUS_MAXSLPITERATIONS 0x10\n#define POI_XPRS_SLPSTATUS_INTEGERINFEASIBLE 0x20\n#define POI_XPRS_SLPSTATUS_RESIDUALPENALTIES 0x40\n#define POI_XPRS_SLPSTATUS_CONVERGEDOBJOBJ 0x80\n#define POI_XPRS_SLPSTATUS_MAXTIME 0x200\n#define POI_XPRS_SLPSTATUS_USER 0x400\n#define POI_XPRS_SLPSTATUS_VARSLINKEDINACTIVE 0x800\n#define POI_XPRS_SLPSTATUS_NOVARSINACTIVE 0x1000\n#define POI_XPRS_SLPSTATUS_OTOL 0x2000\n#define POI_XPRS_SLPSTATUS_VTOL 0x4000\n#define POI_XPRS_SLPSTATUS_XTOL 0x8000\n#define POI_XPRS_SLPSTATUS_WTOL 0x10000\n#define POI_XPRS_SLPSTATUS_ERROTOL 0x20000\n#define POI_XPRS_SLPSTATUS_EVTOL 0x40000\n#define POI_XPRS_SLPSTATUS_POLISHED 0x80000\n#define POI_XPRS_SLPSTATUS_POLISH_FAILURE 0x100000\n#define POI_XPRS_SLPSTATUS_ENFORCED 0x200000\n#define POI_XPRS_SLPSTATUS_CONSECUTIVE_INFEAS 0x400000\n#define POI_XPRS_SLPSTATUS_KEEPBEST 0x800000\n#define POI_XPRS_SLPSTATUS_CLAMPING 0x1000000\n#define POI_XPRS_SLPSTATUS_ADAPTIVEITERS 0x2000000\n#define POI_XPRS_SLPSTATUS_OBJQNONCONVEX 0x4000000\n#define POI_XPRS_NLPSTATUS_UNSTARTED 0\n#define POI_XPRS_NLPSTATUS_SOLUTION 1\n#define POI_XPRS_NLPSTATUS_LOCALLY_OPTIMAL 1\n#define POI_XPRS_NLPSTATUS_OPTIMAL 2\n#define POI_XPRS_NLPSTATUS_NOSOLUTION 3\n#define POI_XPRS_NLPSTATUS_LOCALLY_INFEASIBLE 3\n#define POI_XPRS_NLPSTATUS_INFEASIBLE 4\n#define POI_XPRS_NLPSTATUS_UNBOUNDED 5\n#define POI_XPRS_NLPSTATUS_UNFINISHED 6\n#define POI_XPRS_NLPSTATUS_UNSOLVED 7\n#define POI_XPRS_NLPSOLSTATUS_NONE 0\n#define POI_XPRS_NLPSOLSTATUS_SOLUTION_NODUALS 1\n#define POI_XPRS_NLPSOLSTATUS_LOCALLYOPTIMAL_WITHDUALS 2\n#define POI_XPRS_NLPSOLSTATUS_GLOBALLYOPTIMAL_NODUALS 3\n#define POI_XPRS_NLPSOLSTATUS_GLOBALLYOPTIMAL_WITHDUALS 4\n#define POI_XPRS_SLPGRIDENUMERATE 1\n#define POI_XPRS_SLPGRIDCYCLIC 2\n#define POI_XPRS_SLPGRIDANNEALING 4\n#define POI_XPRS_NLPRECALC 0x08\n#define POI_XPRS_NLPTOLCALC 0x10\n#define POI_XPRS_NLPALLCALCS 0x20\n#define POI_XPRS_NLP2DERIVATIVE 0x40\n#define POI_XPRS_NLP1DERIVATIVE 0x80\n#define POI_XPRS_NLPALLDERIVATIVES 0x100\n#define POI_XPRS_NLPINSTANCEFUNCTION 0x200\n#define POI_XPRS_NLPPRESOLVEOPS_GENERAL 0x01\n#define POI_XPRS_NLPPRESOLVEFIXZERO 0x02\n#define POI_XPRS_NLPPRESOLVEFIXALL 0x04\n#define POI_XPRS_NLPPRESOLVESETBOUNDS 0x08\n#define POI_XPRS_NLPPRESOLVEINTBOUNDS 0x10\n#define POI_XPRS_NLPPRESOLVEDOMAIN 0x20\n#define POI_XPRS_SLPNOPRESOLVECOEFFICIENTS 0x100\n#define POI_XPRS_SLPNOPRESOLVEDELTAS 0x200\n#define POI_XPRS_NLPPRESOLVEOPS_NO_DUAL_SIDE 0x400\n#define POI_XPRS_NLPPRESOLVEOPS_ELIMINATIONS 0x800\n#define POI_XPRS_NLPPRESOLVEOPS_NOLINEAR 0x1000\n#define POI_XPRS_NLPPRESOLVEOPS_NOSIMPLIFIER 0x2000\n#define POI_XPRS_NLPPRESOLVELEVEL_LOCALIZED 1\n#define POI_XPRS_NLPPRESOLVELEVEL_BASIC 2\n#define POI_XPRS_NLPPRESOLVELEVEL_LINEAR 3\n#define POI_XPRS_NLPPRESOLVELEVEL_FULL 4\n#define POI_XPRS_SLPCASCADE_ALL 0x01\n#define POI_XPRS_SLPCASCADE_COEF_VAR 0x02\n#define POI_XPRS_SLPCASCADE_ALL_COEF_VAR 0x04\n#define POI_XPRS_SLPCASCADE_STRUCT_VAR 0x08\n#define POI_XPRS_SLPCASCADE_ALL_STRUCT_VAR 0x10\n#define POI_XPRS_SLPCASCADE_SECONDARY_GROUPS 0x20\n#define POI_XPRS_SLPCASCADE_DRCOL_PREVOUSVALUE 0x40\n#define POI_XPRS_SLPCASCADE_DRCOL_PVRANGE 0x80\n#define POI_XPRS_SLPCASCADE_AUTOAPPLY 0x100\n#define POI_XPRS_LOCALSOLVER_AUTO -1\n#define POI_XPRS_LOCALSOLVER_XSLP 0\n#define POI_XPRS_LOCALSOLVER_KNITRO 1\n#define POI_XPRS_LOCALSOLVER_OPTIMIZER 2\n#define POI_XPRS_MSSET_INITIALVALUES 0\n#define POI_XPRS_MSSET_SOLVERS 1\n#define POI_XPRS_MSSET_SLP_BASIC 2\n#define POI_XPRS_MSSET_SLP_EXTENDED 3\n#define POI_XPRS_MSSET_KNITRO_BASIC 4\n#define POI_XPRS_MSSET_KNITRO_EXTENDED 5\n#define POI_XPRS_MSSET_INITIALFILTERED 6\n#define POI_XPRS_KKT_CALCULATION_RECALCULATE_RDJ 0\n#define POI_XPRS_KKT_CALCULATION_MINIMZE_KKT_ERROR 1\n#define POI_XPRS_KKT_CALCULATION_MEASURE_BOTH 2\n#define POI_XPRS_KKT_CALCULATION_ACTIVITY_BASED 0\n#define POI_XPRS_KKT_CALCULATION_RESPECT_BASIS 1\n#define POI_XPRS_KKT_CALCULATION_ACTIVITY_BOTH 2\n#define POI_XPRS_KKT_JUST_CALCULATE 0\n#define POI_XPRS_KKT_UPDATE_MULTIPLIERS 1\n#define POI_XPRS_SLPTRACEMASK_GENERALFIT 0x1\n#define POI_XPRS_SLPTRACEMASK_ROWS 0x2\n#define POI_XPRS_SLPTRACEMASK_COLS 0x4\n#define POI_XPRS_SLPTRACEMASK_CASCADE 0x8\n#define POI_XPRS_SLPTRACEMASK_TYPE 0x10\n#define POI_XPRS_SLPTRACEMASK_SLACK 0x20\n#define POI_XPRS_SLPTRACEMASK_DUAL 0x40\n#define POI_XPRS_SLPTRACEMASK_WEIGHT 0x80\n#define POI_XPRS_SLPTRACEMASK_SOLUTION 0x100\n#define POI_XPRS_SLPTRACEMASK_REDUCEDCOST 0x200\n#define POI_XPRS_SLPTRACEMASK_SLPVALUE 0x400\n#define POI_XPRS_SLPTRACEMASK_STEPBOUND 0x800\n#define POI_XPRS_SLPTRACEMASK_CONVERGE 0x1000\n#define POI_XPRS_SLPTRACEMASK_LINESEARCH 0x2000\n#define POI_XPRS_SLPFILTER_KEEPBEST 0x1\n#define POI_XPRS_SLPFILTER_CASCADE 0x2\n#define POI_XPRS_SLPFILTER_ZEROLINESEARCH 0x4\n#define POI_XPRS_SLPFILTER_ZEROLINESEARCHTR 0x8\n#define POI_XPRS_SLPANALYZE_RECORDLINEARIZATION 0x1\n#define POI_XPRS_SLPANALYZE_RECORDCASCADE 0x2\n#define POI_XPRS_SLPANALYZE_RECORDLINESEARCH 0x4\n#define POI_XPRS_SLPANALYZE_EXTENDEDFINALSUMMARY 0x8\n#define POI_XPRS_SLPANALYZE_INFEASIBLE_ITERATION 0x10\n#define POI_XPRS_SLPANALYZE_AUTOSAVEPOOL 0x20\n#define POI_XPRS_SLPANALYZE_SAVELINEARIZATIONS 0x40\n#define POI_XPRS_SLPANALYZE_SAVEITERBASIS 0x80\n#define POI_XPRS_SLPANALYZE_SAVEFILE 0x100\n#define POI_XPRS_NLPREFORMULATE_SLP2QP 0x1\n#define POI_XPRS_NLPREFORMULATE_QP2SLP 0x2\n#define POI_XPRS_NLPREFORMULATE_SLP2QCQP 0x4\n#define POI_XPRS_NLPREFORMULATE_QCQP2SLP 0x8\n#define POI_XPRS_NLPREFORMULATE_SOCP2SLP 0x10\n#define POI_XPRS_NLPREFORMULATE_QPSOLVE 0x20\n#define POI_XPRS_NLPREFORMULATE_PWL 0x40\n#define POI_XPRS_NLPREFORMULATE_ABS 0x80\n#define POI_XPRS_NLPREFORMULATE_MINMAX 0x100\n#define POI_XPRS_NLPREFORMULATE_ALLABS 0x200\n#define POI_XPRS_NLPREFORMULATE_ALLMINMAX 0x400\n#define POI_XPRS_SLPDELTA_CONT 0\n#define POI_XPRS_SLPDELTA_SEMICONT 1\n#define POI_XPRS_SLPDELTA_INTEGER 2\n#define POI_XPRS_SLPDELTA_EXPLORE 3\n#define POI_XPRS_SLPROWINFO_SLACK 1\n#define POI_XPRS_SLPROWINFO_DUAL 2\n#define POI_XPRS_SLPROWINFO_NUMPENALTYERRORS 3\n#define POI_XPRS_SLPROWINFO_MAXPENALTYERROR 4\n#define POI_XPRS_SLPROWINFO_TOTALPENALTYERROR 5\n#define POI_XPRS_SLPROWINFO_CURRENTPENALTYERROR 6\n#define POI_XPRS_SLPROWINFO_CURRENTPENALTYFACTOR 7\n#define POI_XPRS_SLPROWINFO_PENALTYCOLUMNPLUS 8\n#define POI_XPRS_SLPROWINFO_PENALTYCOLUMNPLUSVALUE 9\n#define POI_XPRS_SLPROWINFO_PENALTYCOLUMNPLUSDJ 10\n#define POI_XPRS_SLPROWINFO_PENALTYCOLUMNMINUS 11\n#define POI_XPRS_SLPROWINFO_PENALTYCOLUMNMINUSVALUE 12\n#define POI_XPRS_SLPROWINFO_PENALTYCOLUMNMINUSDJ 13\n#define POI_XPRS_SLPCOLINFO_VALUE 1\n#define POI_XPRS_SLPCOLINFO_RDJ 2\n#define POI_XPRS_SLPCOLINFO_DELTAINDEX 3\n#define POI_XPRS_SLPCOLINFO_DELTA 4\n#define POI_XPRS_SLPCOLINFO_DELTADJ 5\n#define POI_XPRS_SLPCOLINFO_UPDATEROW 6\n#define POI_XPRS_SLPCOLINFO_SB 7\n#define POI_XPRS_SLPCOLINFO_SBDUAL 8\n#define POI_XPRS_SLPCOLINFO_LPVALUE 9\n#define POI_XPRS_SLPCOLINFO_DETROW 10\n#define POI_XPRS_SLPCOLINFO_CONVERGENCESTATUS 11\n#define POI_XPRS_USERFUNCTION_MAP 1\n#define POI_XPRS_USERFUNCTION_VECMAP 2\n#define POI_XPRS_USERFUNCTION_MULTIMAP 3\n#define POI_XPRS_USERFUNCTION_MAPDELTA 4\n#define POI_XPRS_USERFUNCTION_VECMAPDELTA 5\n#define POI_XPRS_USERFUNCTION_MULTIMAPDELTA 6\n#define POI_XPRS_NLPUSERFUNCNAMES 7\n#define POI_XPRS_NLPINTERNALFUNCNAMES 8\n#define POI_XPRS_NLPUSERFUNCNAMESNOCASE 9\n#define POI_XPRS_NLPINTERNALFUNCNAMESNOCASE 10\n#define POI_XPRS_NLPFORMULACOEFFCOLUMNINDEX -1000\n#define POI_XPRS_NLPOBJECTIVEROWINDEX -1\n#define POI_XPRS_NLPSOLVER_AUTOMATIC -1\n#define POI_XPRS_NLPSOLVER_LOCAL 1\n#define POI_XPRS_NLPSOLVER_GLOBAL 2\n\n#define POI_XPRS_SOLSTATUS_NOTFOUND 0\n#define POI_XPRS_SOLSTATUS_OPTIMAL 1\n#define POI_XPRS_SOLSTATUS_FEASIBLE 2\n#define POI_XPRS_SOLSTATUS_INFEASIBLE 3\n#define POI_XPRS_SOLSTATUS_UNBOUNDED 4\n\n#define POI_XPRS_SOLVESTATUS_UNSTARTED 0\n#define POI_XPRS_SOLVESTATUS_STOPPED 1\n#define POI_XPRS_SOLVESTATUS_FAILED 2\n#define POI_XPRS_SOLVESTATUS_COMPLETED 3\n\n#define POI_XPRS_LP_UNSTARTED 0\n#define POI_XPRS_LP_OPTIMAL 1\n#define POI_XPRS_LP_INFEAS 2\n#define POI_XPRS_LP_CUTOFF 3\n#define POI_XPRS_LP_UNFINISHED 4\n#define POI_XPRS_LP_UNBOUNDED 5\n#define POI_XPRS_LP_CUTOFF_IN_DUAL 6\n#define POI_XPRS_LP_UNSOLVED 7\n#define POI_XPRS_LP_NONCONVEX 8\n\n#define POI_XPRS_MIP_NOT_LOADED 0\n#define POI_XPRS_MIP_LP_NOT_OPTIMAL 1\n#define POI_XPRS_MIP_LP_OPTIMAL 2\n#define POI_XPRS_MIP_NO_SOL_FOUND 3\n#define POI_XPRS_MIP_SOLUTION 4\n#define POI_XPRS_MIP_INFEAS 5\n#define POI_XPRS_MIP_OPTIMAL 6\n#define POI_XPRS_MIP_UNBOUNDED 7\n\n#define POI_XPRS_IIS_UNSTARTED 0\n#define POI_XPRS_IIS_FEASIBLE 1\n#define POI_XPRS_IIS_COMPLETED 2\n#define POI_XPRS_IIS_UNFINISHED 3\n\n#define POI_XPRS_SOLAVAILABLE_NOTFOUND 0\n#define POI_XPRS_SOLAVAILABLE_OPTIMAL 1\n#define POI_XPRS_SOLAVAILABLE_FEASIBLE 2\n\n#define POI_XPRS_OPTIMIZETYPE_NONE -1\n#define POI_XPRS_OPTIMIZETYPE_LP 0\n#define POI_XPRS_OPTIMIZETYPE_MIP 1\n#define POI_XPRS_OPTIMIZETYPE_LOCAL 2\n#define POI_XPRS_OPTIMIZETYPE_GLOBAL 3\n\n#define POI_XPRS_TYPE_NOTDEFINED 0\n#define POI_XPRS_TYPE_INT 1\n#define POI_XPRS_TYPE_INT64 2\n#define POI_XPRS_TYPE_DOUBLE 3\n#define POI_XPRS_TYPE_STRING 4\n\n#define POI_XPRS_NAMES_ROW 1\n#define POI_XPRS_NAMES_COLUMN 2\n#define POI_XPRS_NAMES_SET 3\n#define POI_XPRS_NAMES_PWLCONS 4\n#define POI_XPRS_NAMES_GENCONS 5\n#define POI_XPRS_NAMES_OBJECTIVE 6\n#define POI_XPRS_NAMES_USERFUNC 7\n#define POI_XPRS_NAMES_INTERNALFUNC 8\n#define POI_XPRS_NAMES_USERFUNCNOCASE 9\n#define POI_XPRS_NAMES_INTERNALFUNCNOCASE 10\n\n#define POI_XPRS_BASISSTATUS_NONBASIC_LOWER 0\n#define POI_XPRS_BASISSTATUS_BASIC 1\n#define POI_XPRS_BASISSTATUS_NONBASIC_UPPER 2\n#define POI_XPRS_BASISSTATUS_SUPERBASIC 3\n\n#define POI_XPRS_STOP_NONE 0\n#define POI_XPRS_STOP_TIMELIMIT 1\n#define POI_XPRS_STOP_CTRLC 2\n#define POI_XPRS_STOP_NODELIMIT 3\n#define POI_XPRS_STOP_ITERLIMIT 4\n#define POI_XPRS_STOP_MIPGAP 5\n#define POI_XPRS_STOP_SOLLIMIT 6\n#define POI_XPRS_STOP_GENERICERROR 7\n#define POI_XPRS_STOP_MEMORYERROR 8\n#define POI_XPRS_STOP_USER 9\n#define POI_XPRS_STOP_SOLVECOMPLETE 10\n#define POI_XPRS_STOP_LICENSELOST 11\n#define POI_XPRS_STOP_NUMERICALERROR 13\n#define POI_XPRS_STOP_WORKLIMIT 14\n#define POI_XPRS_STOP_NEXTOBJECTIVE 15\n\n#define POI_XPRS_OBJ_MINIMIZE 1\n#define POI_XPRS_OBJ_MAXIMIZE -1\n\n#define POI_XPRS_KNITRO_PARAM_NEWPOINT 101001\n#define POI_XPRS_KNITRO_PARAM_HONORBNDS 101002\n#define POI_XPRS_KNITRO_PARAM_ALGORITHM 101003\n#define POI_XPRS_KNITRO_PARAM_BAR_MURULE 101004\n#define POI_XPRS_KNITRO_PARAM_BAR_FEASIBLE 101006\n#define POI_XPRS_KNITRO_PARAM_GRADOPT 101007\n#define POI_XPRS_KNITRO_PARAM_HESSOPT 101008\n#define POI_XPRS_KNITRO_PARAM_BAR_INITPT 101009\n#define POI_XPRS_KNITRO_PARAM_MAXCGIT 101013\n#define POI_XPRS_KNITRO_PARAM_MAXIT 101014\n#define POI_XPRS_KNITRO_PARAM_OUTLEV 101015\n#define POI_XPRS_KNITRO_PARAM_SCALE 101017\n#define POI_XPRS_KNITRO_PARAM_SOC 101019\n#define POI_XPRS_KNITRO_PARAM_DELTA 101020\n#define POI_XPRS_KNITRO_PARAM_BAR_FEASMODETOL 101021\n#define POI_XPRS_KNITRO_PARAM_FEASTOL 101022\n#define POI_XPRS_KNITRO_PARAM_FEASTOLABS 101023\n#define POI_XPRS_KNITRO_PARAM_BAR_INITMU 101025\n#define POI_XPRS_KNITRO_PARAM_OBJRANGE 101026\n#define POI_XPRS_KNITRO_PARAM_OPTTOL 101027\n#define POI_XPRS_KNITRO_PARAM_OPTTOLABS 101028\n#define POI_XPRS_KNITRO_PARAM_PIVOT 101029\n#define POI_XPRS_KNITRO_PARAM_XTOL 101030\n#define POI_XPRS_KNITRO_PARAM_DEBUG 101031\n#define POI_XPRS_KNITRO_PARAM_MULTISTART 101033\n#define POI_XPRS_KNITRO_PARAM_MSMAXSOLVES 101034\n#define POI_XPRS_KNITRO_PARAM_MSMAXBNDRANGE 101035\n#define POI_XPRS_KNITRO_PARAM_LMSIZE 101038\n#define POI_XPRS_KNITRO_PARAM_BAR_MAXCROSSIT 101039\n#define POI_XPRS_KNITRO_PARAM_BLASOPTION 101042\n#define POI_XPRS_KNITRO_PARAM_BAR_MAXREFACTOR 101043\n#define POI_XPRS_KNITRO_PARAM_BAR_MAXBACKTRACK 101044\n#define POI_XPRS_KNITRO_PARAM_BAR_PENRULE 101049\n#define POI_XPRS_KNITRO_PARAM_BAR_PENCONS 101050\n#define POI_XPRS_KNITRO_PARAM_MSNUMTOSAVE 101051\n#define POI_XPRS_KNITRO_PARAM_MSSAVETOL 101052\n#define POI_XPRS_KNITRO_PARAM_MSTERMINATE 101054\n#define POI_XPRS_KNITRO_PARAM_MSSTARTPTRANGE 101055\n#define POI_XPRS_KNITRO_PARAM_INFEASTOL 101056\n#define POI_XPRS_KNITRO_PARAM_LINSOLVER 101057\n#define POI_XPRS_KNITRO_PARAM_BAR_DIRECTINTERVAL 101058\n#define POI_XPRS_KNITRO_PARAM_PRESOLVE 101059\n#define POI_XPRS_KNITRO_PARAM_PRESOLVE_TOL 101060\n#define POI_XPRS_KNITRO_PARAM_BAR_SWITCHRULE 101061\n#define POI_XPRS_KNITRO_PARAM_MA_TERMINATE 101063\n#define POI_XPRS_KNITRO_PARAM_MSSEED 101066\n#define POI_XPRS_KNITRO_PARAM_BAR_RELAXCONS 101077\n#define POI_XPRS_KNITRO_PARAM_SOLTYPE 101161\n#define POI_XPRS_KNITRO_PARAM_MIP_METHOD 102001\n#define POI_XPRS_KNITRO_PARAM_MIP_BRANCHRULE 102002\n#define POI_XPRS_KNITRO_PARAM_MIP_SELECTRULE 102003\n#define POI_XPRS_KNITRO_PARAM_MIP_INTGAPABS 102004\n#define POI_XPRS_KNITRO_PARAM_MIP_INTGAPREL 102005\n#define POI_XPRS_KNITRO_PARAM_MIP_OUTLEVEL 102010\n#define POI_XPRS_KNITRO_PARAM_MIP_OUTINTERVAL 102011\n#define POI_XPRS_KNITRO_PARAM_MIP_DEBUG 102013\n#define POI_XPRS_KNITRO_PARAM_MIP_IMPLICATNS 102014\n#define POI_XPRS_KNITRO_PARAM_MIP_GUB_BRANCH 102015\n#define POI_XPRS_KNITRO_PARAM_MIP_KNAPSACK 102016\n#define POI_XPRS_KNITRO_PARAM_MIP_ROUNDING 102017\n#define POI_XPRS_KNITRO_PARAM_MIP_ROOTALG 102018\n#define POI_XPRS_KNITRO_PARAM_MIP_LPALG 102019\n#define POI_XPRS_KNITRO_PARAM_MIP_MAXNODES 102021\n#define POI_XPRS_KNITRO_PARAM_MIP_HEURISTIC 102022\n#define POI_XPRS_KNITRO_PARAM_MIP_HEUR_MAXIT 102023\n#define POI_XPRS_KNITRO_PARAM_MIP_PSEUDOINIT 102026\n#define POI_XPRS_KNITRO_PARAM_MIP_STRONG_MAXIT 102027\n#define POI_XPRS_KNITRO_PARAM_MIP_STRONG_CANDLIM 102028\n#define POI_XPRS_KNITRO_PARAM_MIP_STRONG_LEVEL 102029\n#define POI_XPRS_KNITRO_PARAM_PAR_NUMTHREADS 103001\n\n\ttypedef struct xo_prob_struct *XPRSprob;\n\ttypedef struct xo_user_branch_entity_s *XPRSbranchobject;\n\n\tint XPRSaddcols64(XPRSprob prob, int ncols, XPRSint64 ncoefs, const double objcoef[],\n\t                  const XPRSint64 start[], const int rowind[], const double rowcoef[],\n\t                  const double lb[], const double ub[]);\n\tint XPRSaddcuts64(XPRSprob prob, int ncuts, const int cuttype[], const char rowtype[],\n\t                  const double rhs[], const XPRSint64 start[], const int colind[],\n\t                  const double cutcoef[]);\n\tint XPRSaddmanagedcuts64(XPRSprob prob, int globalvalid, int ncuts, const char rowtype[],\n\t                         const double rhs[], const XPRSint64 start[], const int colind[],\n\t                         const double cutcoef[]);\n\tint XPRSaddmipsol(XPRSprob prob, int length, const double solval[], const int colind[],\n\t                  const char *name);\n\tint XPRSaddnames(XPRSprob prob, int type, const char names[], int first, int last);\n\tint XPRSaddqmatrix64(XPRSprob prob, int row, XPRSint64 ncoefs, const int rowqcol1[],\n\t                     const int rowqcol2[], const double rowqcoef[]);\n\tint XPRSaddrows64(XPRSprob prob, int nrows, XPRSint64 ncoefs, const char rowtype[],\n\t                  const double rhs[], const double rng[], const XPRSint64 start[],\n\t                  const int colind[], const double rowcoef[]);\n\tint XPRSaddsets64(XPRSprob prob, int nsets, XPRSint64 nelems, const char settype[],\n\t                  const XPRSint64 start[], const int colind[], const double refval[]);\n\tint XPRSbeginlicensing(int *p_notyet);\n\tint XPRSchgbounds(XPRSprob prob, int nbounds, const int colind[], const char bndtype[],\n\t                  const double bndval[]);\n\tint XPRSchgcoef(XPRSprob prob, int row, int col, double coef);\n\tint XPRSchgcoltype(XPRSprob prob, int ncols, const int colind[], const char coltype[]);\n\tint XPRSchgmqobj64(XPRSprob prob, XPRSint64 ncoefs, const int objqcol1[], const int objqcol2[],\n\t                   const double objqcoef[]);\n\tint XPRSchgobj(XPRSprob prob, int ncols, const int colind[], const double objcoef[]);\n\tint XPRSchgobjsense(XPRSprob prob, int objsense);\n\tint XPRSchgrhs(XPRSprob prob, int nrows, const int rowind[], const double rhs[]);\n\tint XPRSchgrowtype(XPRSprob prob, int nrows, const int rowind[], const char rowtype[]);\n\tint XPRScreateprob(XPRSprob *p_prob);\n\tint XPRSdelcols(XPRSprob prob, int ncols, const int colind[]);\n\tint XPRSdelobj(XPRSprob prob, int objidx);\n\tint XPRSdelqmatrix(XPRSprob prob, int row);\n\tint XPRSdelrows(XPRSprob prob, int nrows, const int rowind[]);\n\tint XPRSdelsets(XPRSprob prob, int nsets, const int setind[]);\n\tint XPRSdestroyprob(XPRSprob prob);\n\tint XPRSendlicensing(void);\n\tint XPRSfree(void);\n\tint XPRSgetattribinfo(XPRSprob prob, const char *name, int *p_id, int *p_type);\n\tint XPRSgetbasisval(XPRSprob prob, int row, int col, int *p_rowstat, int *p_colstat);\n\tint XPRSgetcallbacksolution(XPRSprob prob, int *p_available, double x[], int first, int last);\n\tint XPRSgetcoef(XPRSprob prob, int row, int col, double *p_coef);\n\tint XPRSgetcoltype(XPRSprob prob, char coltype[], int first, int last);\n\tint XPRSgetcontrolinfo(XPRSprob prob, const char *name, int *p_id, int *p_type);\n\tint XPRSgetdblattrib(XPRSprob prob, int attrib, double *p_value);\n\tint XPRSgetdblcontrol(XPRSprob prob, int control, double *p_value);\n\tint XPRSgetdualray(XPRSprob prob, double ray[], int *p_hasray);\n\tint XPRSgetduals(XPRSprob prob, int *status, double duals[], int first, int last);\n\tint XPRSgetiisdata(XPRSprob prob, int iis, int *p_nrows, int *p_ncols, int rowind[],\n\t                   int colind[], char contype[], char bndtype[], double duals[], double djs[],\n\t                   char isolationrows[], char isolationcols[]);\n\tint XPRSgetintattrib64(XPRSprob prob, int attrib, XPRSint64 *p_value);\n\tint XPRSgetintcontrol64(XPRSprob prob, int control, XPRSint64 *p_value);\n\tint XPRSgetlasterror(XPRSprob prob, char *errmsg);\n\tint XPRSgetlb(XPRSprob prob, double lb[], int first, int last);\n\tint XPRSgetlicerrmsg(char *buffer, int maxbytes);\n\tint XPRSgetlpsol(XPRSprob prob, double x[], double slack[], double duals[], double djs[]);\n\tint XPRSgetnamelist(XPRSprob prob, int type, char names[], int maxbytes, int *p_nbytes,\n\t                    int first, int last);\n\tint XPRSgetobj(XPRSprob prob, double objcoef[], int first, int last);\n\tint XPRSgetprimalray(XPRSprob prob, double ray[], int *p_hasray);\n\tint XPRSgetprobname(XPRSprob prob, char *name);\n\tint XPRSgetredcosts(XPRSprob prob, int *status, double djs[], int first, int last);\n\tint XPRSgetrhs(XPRSprob prob, double rhs[], int first, int last);\n\tint XPRSgetrowtype(XPRSprob prob, char rowtype[], int first, int last);\n\tint XPRSgetslacks(XPRSprob prob, int *status, double slacks[], int first, int last);\n\tint XPRSgetsolution(XPRSprob prob, int *status, double x[], int first, int last);\n\tint XPRSgetstrattrib(XPRSprob prob, int attrib, char *value);\n\tint XPRSgetstrcontrol(XPRSprob prob, int control, char *value);\n\tint XPRSgetstringattrib(XPRSprob prob, int attrib, char *value, int maxbytes, int *p_nbytes);\n\tint XPRSgetstringcontrol(XPRSprob prob, int control, char *value, int maxbytes, int *p_nbytes);\n\tint XPRSgetub(XPRSprob prob, double ub[], int first, int last);\n\tint XPRSgetversion(char *version);\n\tint XPRSgetversionnumbers(int *p_major, int *p_minor, int *p_build);\n\tint XPRSiisall(XPRSprob prob);\n\tint XPRSiisfirst(XPRSprob prob, int mode, int *p_status);\n\tint XPRSinit(const char *path);\n\tint XPRSinterrupt(XPRSprob prob, int reason);\n\tint XPRSlicense(int *p_i, char *p_c);\n\tint XPRSnlpaddformulas(XPRSprob prob, int ncoefs, const int rowind[], const int formulastart[],\n\t                       int parsed, const int type[], const double value[]);\n\tint XPRSnlploadformulas(XPRSprob prob, int nnlpcoefs, const int rowind[],\n\t                        const int formulastart[], int parsed, const int type[],\n\t                        const double value[]);\n\tint XPRSnlppostsolve(XPRSprob prob);\n\tint XPRSoptimize(XPRSprob prob, const char *flags, int *solvestatus, int *solstatus);\n\tint XPRSpostsolve(XPRSprob prob);\n\tint XPRSpresolverow(XPRSprob prob, char rowtype, int norigcoefs, const int origcolind[],\n\t                    const double origrowcoef[], double origrhs, int maxcoefs, int *p_ncoefs,\n\t                    int colind[], double rowcoef[], double *p_rhs, int *p_status);\n\tint XPRSsaveas(XPRSprob prob, const char *filename);\n\tint XPRSsetdblcontrol(XPRSprob prob, int control, double value);\n\tint XPRSsetintcontrol(XPRSprob prob, int control, int value);\n\tint XPRSsetintcontrol64(XPRSprob prob, int control, XPRSint64 value);\n\tint XPRSsetlogfile(XPRSprob prob, const char *filename);\n\tint XPRSsetprobname(XPRSprob prob, const char *probname);\n\tint XPRSsetstrcontrol(XPRSprob prob, int control, const char *value);\n\tint XPRSwritebasis(XPRSprob prob, const char *filename, const char *flags);\n\tint XPRSwritebinsol(XPRSprob prob, const char *filename, const char *flags);\n\tint XPRSwriteprob(XPRSprob prob, const char *filename, const char *flags);\n\tint XPRSwriteprtsol(XPRSprob prob, const char *filename, const char *flags);\n\tint XPRSwriteslxsol(XPRSprob prob, const char *filename, const char *flags);\n\tint XPRSwritesol(XPRSprob prob, const char *filename, const char *flags);\n\tint XPRSaddcbbariteration(XPRSprob prob,\n\t                          void (*bariteration)(XPRSprob cbprob, void *cbdata, int *p_action),\n\t                          void *data, int priority);\n\tint XPRSaddcbbarlog(XPRSprob prob, int (*barlog)(XPRSprob cbprob, void *cbdata), void *data,\n\t                    int priority);\n\tint XPRSaddcbafterobjective(XPRSprob prob,\n\t                            void (*afterobjective)(XPRSprob cbprob, void *cbdata), void *data,\n\t                            int priority);\n\tint XPRSaddcbbeforeobjective(XPRSprob prob,\n\t                             void (*beforeobjective)(XPRSprob cbprob, void *cbdata), void *data,\n\t                             int priority);\n\tint XPRSaddcbpresolve(XPRSprob prob, void (*presolve)(XPRSprob cbprob, void *cbdata),\n\t                      void *data, int priority);\n\tint XPRSaddcbchecktime(XPRSprob prob, int (*checktime)(XPRSprob cbprob, void *cbdata),\n\t                       void *data, int priority);\n\tint XPRSaddcbchgbranchobject(XPRSprob prob,\n\t                             void (*chgbranchobject)(XPRSprob cbprob, void *cbdata,\n\t                                                     XPRSbranchobject branch,\n\t                                                     XPRSbranchobject *p_newbranch),\n\t                             void *data, int priority);\n\tint XPRSaddcbcutlog(XPRSprob prob, int (*cutlog)(XPRSprob cbprob, void *cbdata), void *data,\n\t                    int priority);\n\tint XPRSaddcbcutround(XPRSprob prob,\n\t                      void (*cutround)(XPRSprob cbprob, void *cbdata, int ifxpresscuts,\n\t                                       int *p_action),\n\t                      void *data, int priority);\n\tint XPRSaddcbdestroymt(XPRSprob prob, void (*destroymt)(XPRSprob cbprob, void *cbdata),\n\t                       void *data, int priority);\n\tint XPRSaddcbgapnotify(XPRSprob prob,\n\t                       void (*gapnotify)(XPRSprob cbprob, void *cbdata,\n\t                                         double *p_relgapnotifytarget,\n\t                                         double *p_absgapnotifytarget,\n\t                                         double *p_absgapnotifyobjtarget,\n\t                                         double *p_absgapnotifyboundtarget),\n\t                       void *data, int priority);\n\tint XPRSaddcbmiplog(XPRSprob prob, int (*miplog)(XPRSprob cbprob, void *cbdata), void *data,\n\t                    int priority);\n\tint XPRSaddcbinfnode(XPRSprob prob, void (*infnode)(XPRSprob cbprob, void *cbdata), void *data,\n\t                     int priority);\n\tint XPRSaddcbintsol(XPRSprob prob, void (*intsol)(XPRSprob cbprob, void *cbdata), void *data,\n\t                    int priority);\n\tint XPRSaddcblplog(XPRSprob prob, int (*lplog)(XPRSprob cbprob, void *cbdata), void *data,\n\t                   int priority);\n\tint XPRSaddcbmessage(XPRSprob prob,\n\t                     void (*message)(XPRSprob cbprob, void *cbdata, const char *msg, int msglen,\n\t                                     int msgtype),\n\t                     void *data, int priority);\n\tint XPRSaddcbmipthread(XPRSprob prob,\n\t                       void (*mipthread)(XPRSprob cbprob, void *cbdata, XPRSprob threadprob),\n\t                       void *data, int priority);\n\tint XPRSaddcbnewnode(XPRSprob prob,\n\t                     void (*newnode)(XPRSprob cbprob, void *cbdata, int parentnode, int node,\n\t                                     int branch),\n\t                     void *data, int priority);\n\tint XPRSaddcbnodecutoff(XPRSprob prob,\n\t                        void (*nodecutoff)(XPRSprob cbprob, void *cbdata, int node), void *data,\n\t                        int priority);\n\tint XPRSaddcbnodelpsolved(XPRSprob prob, void (*nodelpsolved)(XPRSprob cbprob, void *cbdata),\n\t                          void *data, int priority);\n\tint XPRSaddcboptnode(XPRSprob prob,\n\t                     void (*optnode)(XPRSprob cbprob, void *cbdata, int *p_infeasible),\n\t                     void *data, int priority);\n\tint XPRSaddcbpreintsol(XPRSprob prob,\n\t                       void (*preintsol)(XPRSprob cbprob, void *cbdata, int soltype,\n\t                                         int *p_reject, double *p_cutoff),\n\t                       void *data, int priority);\n\tint XPRSaddcbprenode(XPRSprob prob,\n\t                     void (*prenode)(XPRSprob cbprob, void *cbdata, int *p_infeasible),\n\t                     void *data, int priority);\n\tint XPRSaddcbusersolnotify(XPRSprob prob,\n\t                           void (*usersolnotify)(XPRSprob cbprob, void *cbdata,\n\t                                                 const char *solname, int status),\n\t                           void *data, int priority);\n\tint XPRSremovecbbariteration(XPRSprob prob,\n\t                             void (*bariteration)(XPRSprob cbprob, void *cbdata, int *p_action),\n\t                             void *data);\n\tint XPRSremovecbbarlog(XPRSprob prob, int (*barlog)(XPRSprob cbprob, void *cbdata), void *data);\n\tint XPRSremovecbafterobjective(XPRSprob prob,\n\t                               void (*afterobjective)(XPRSprob cbprob, void *cbdata),\n\t                               void *data);\n\tint XPRSremovecbbeforeobjective(XPRSprob prob,\n\t                                void (*beforeobjective)(XPRSprob cbprob, void *cbdata),\n\t                                void *data);\n\tint XPRSremovecbpresolve(XPRSprob prob, void (*presolve)(XPRSprob cbprob, void *cbdata),\n\t                         void *data);\n\tint XPRSremovecbchecktime(XPRSprob prob, int (*checktime)(XPRSprob cbprob, void *cbdata),\n\t                          void *data);\n\tint XPRSremovecbchgbranchobject(XPRSprob prob,\n\t                                void (*chgbranchobject)(XPRSprob cbprob, void *cbdata,\n\t                                                        XPRSbranchobject branch,\n\t                                                        XPRSbranchobject *p_newbranch),\n\t                                void *data);\n\tint XPRSremovecbcutlog(XPRSprob prob, int (*cutlog)(XPRSprob cbprob, void *cbdata), void *data);\n\tint XPRSremovecbcutround(XPRSprob prob,\n\t                         void (*cutround)(XPRSprob cbprob, void *cbdata, int ifxpresscuts,\n\t                                          int *p_action),\n\t                         void *data);\n\tint XPRSremovecbdestroymt(XPRSprob prob, void (*destroymt)(XPRSprob cbprob, void *cbdata),\n\t                          void *data);\n\tint XPRSremovecbgapnotify(XPRSprob prob,\n\t                          void (*gapnotify)(XPRSprob cbprob, void *cbdata,\n\t                                            double *p_relgapnotifytarget,\n\t                                            double *p_absgapnotifytarget,\n\t                                            double *p_absgapnotifyobjtarget,\n\t                                            double *p_absgapnotifyboundtarget),\n\t                          void *data);\n\tint XPRSremovecbmiplog(XPRSprob prob, int (*miplog)(XPRSprob cbprob, void *cbdata), void *data);\n\tint XPRSremovecbinfnode(XPRSprob prob, void (*infnode)(XPRSprob cbprob, void *cbdata),\n\t                        void *data);\n\tint XPRSremovecbintsol(XPRSprob prob, void (*intsol)(XPRSprob cbprob, void *cbdata),\n\t                       void *data);\n\tint XPRSremovecblplog(XPRSprob prob, int (*lplog)(XPRSprob cbprob, void *cbdata), void *data);\n\tint XPRSremovecbmessage(XPRSprob prob,\n\t                        void (*message)(XPRSprob cbprob, void *cbdata, const char *msg,\n\t                                        int msglen, int msgtype),\n\t                        void *data);\n\tint XPRSremovecbmipthread(XPRSprob prob,\n\t                          void (*mipthread)(XPRSprob cbprob, void *cbdata, XPRSprob threadprob),\n\t                          void *data);\n\tint XPRSremovecbnewnode(XPRSprob prob,\n\t                        void (*newnode)(XPRSprob cbprob, void *cbdata, int parentnode, int node,\n\t                                        int branch),\n\t                        void *data);\n\tint XPRSremovecbnodecutoff(XPRSprob prob,\n\t                           void (*nodecutoff)(XPRSprob cbprob, void *cbdata, int node),\n\t                           void *data);\n\tint XPRSremovecbnodelpsolved(XPRSprob prob, void (*nodelpsolved)(XPRSprob cbprob, void *cbdata),\n\t                             void *data);\n\tint XPRSremovecboptnode(XPRSprob prob,\n\t                        void (*optnode)(XPRSprob cbprob, void *cbdata, int *p_infeasible),\n\t                        void *data);\n\tint XPRSremovecbpreintsol(XPRSprob prob,\n\t                          void (*preintsol)(XPRSprob cbprob, void *cbdata, int soltype,\n\t                                            int *p_reject, double *p_cutoff),\n\t                          void *data);\n\tint XPRSremovecbprenode(XPRSprob prob,\n\t                        void (*prenode)(XPRSprob cbprob, void *cbdata, int *p_infeasible),\n\t                        void *data);\n\tint XPRSremovecbusersolnotify(XPRSprob prob,\n\t                              void (*usersolnotify)(XPRSprob cbprob, void *cbdata,\n\t                                                    const char *solname, int status),\n\t                              void *data);\n#ifdef __cplusplus\n}\n#endif\n#endif // PYOPTINTERFACE_XPRESS_FORWARD_DECLS_H\n"
  },
  {
    "path": "thirdparty/tcc/libtcc.h",
    "content": "#ifndef LIBTCC_H\n#define LIBTCC_H\n\n#ifndef LIBTCCAPI\n# define LIBTCCAPI\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/*****************************/\n/* set custom allocator for all allocations (optional), NULL for default. */\ntypedef void *TCCReallocFunc(void *ptr, unsigned long size);\nLIBTCCAPI void tcc_set_realloc(TCCReallocFunc *my_realloc);\n\n/*****************************/\ntypedef struct TCCState TCCState;\n\n/* create a new TCC compilation context */\nLIBTCCAPI TCCState *tcc_new(void);\n\n/* free a TCC compilation context */\nLIBTCCAPI void tcc_delete(TCCState *s);\n\n/* set CONFIG_TCCDIR at runtime */\nLIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path);\n\n/* set error/warning callback (optional) */\ntypedef void TCCErrorFunc(void *opaque, const char *msg);\nLIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, TCCErrorFunc *error_func);\n\n/* set options as from command line (multiple supported) */\nLIBTCCAPI int tcc_set_options(TCCState *s, const char *str);\n\n/*****************************/\n/* preprocessor */\n\n/* add include path */\nLIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname);\n\n/* add in system include path */\nLIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname);\n\n/* define preprocessor symbol 'sym'. value can be NULL, sym can be \"sym=val\" */\nLIBTCCAPI void tcc_define_symbol(TCCState *s, const char *sym, const char *value);\n\n/* undefine preprocess symbol 'sym' */\nLIBTCCAPI void tcc_undefine_symbol(TCCState *s, const char *sym);\n\n/*****************************/\n/* compiling */\n\n/* add a file (C file, dll, object, library, ld script). Return -1 if error. */\nLIBTCCAPI int tcc_add_file(TCCState *s, const char *filename);\n\n/* compile a string containing a C source. Return -1 if error. */\nLIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);\n\n/* Tip: to have more specific errors/warnings from tcc_compile_string(),\n   you can prefix the string with \"#line <num> \\\"<filename>\\\"\\n\" */\n\n/*****************************/\n/* linking commands */\n\n/* set output type. MUST BE CALLED before any compilation */\nLIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);\n#define TCC_OUTPUT_MEMORY   1 /* output will be run in memory */\n#define TCC_OUTPUT_EXE      2 /* executable file */\n#define TCC_OUTPUT_DLL      4 /* dynamic library */\n#define TCC_OUTPUT_OBJ      3 /* object file */\n#define TCC_OUTPUT_PREPROCESS 5 /* only preprocess */\n\n/* equivalent to -Lpath option */\nLIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);\n\n/* the library name is the same as the argument of the '-l' option */\nLIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname);\n\n/* add a symbol to the compiled program */\nLIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val);\n\n/* output an executable, library or object file. DO NOT call\n   tcc_relocate() before. */\nLIBTCCAPI int tcc_output_file(TCCState *s, const char *filename);\n\n/* link and run main() function and return its value. DO NOT call\n   tcc_relocate() before. */\nLIBTCCAPI int tcc_run(TCCState *s, int argc, char **argv);\n\n/* do all relocations (needed before using tcc_get_symbol()) */\nLIBTCCAPI int tcc_relocate(TCCState *s1);\n\n/* return symbol value or NULL if not found */\nLIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name);\n\n/* list all (global) symbols and their values via 'symbol_cb()' */\nLIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,\n    void (*symbol_cb)(void *ctx, const char *name, const void *val));\n\n/* experimental/advanced section (see libtcc_test_mt.c for an example) */\n\n/* catch runtime exceptions (optionally limit backtraces at top_func),\n   when using tcc_set_options(\"-bt\") and when not using tcc_run() */\nLIBTCCAPI void *_tcc_setjmp(TCCState *s1, void *jmp_buf, void *top_func, void *longjmp);\n#define tcc_setjmp(s1,jb,f) setjmp(_tcc_setjmp(s1, jb, f, longjmp))\n\n/* custom error printer for runtime exceptions. Returning 0 stops backtrace */\ntypedef int TCCBtFunc(void *udata, void *pc, const char *file, int line, const char* func, const char *msg);\nLIBTCCAPI void tcc_set_backtrace_func(TCCState *s1, void* userdata, TCCBtFunc*);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  }
]