├── .bumpversion.cfg
├── .github
├── ISSUE_TEMPLATE.md
├── dependabot.yml
└── workflows
│ ├── build.yml
│ ├── build_mkl.yml
│ ├── build_openmp.yml
│ ├── buildpp.yml
│ ├── cmake.yml
│ ├── cmake_mkl.yml
│ ├── cmake_openmp.yml
│ ├── coverage.yml
│ ├── docs.yml
│ ├── gpu.yml
│ └── valgrind.yml
├── .gitignore
├── CITATION.cff
├── CMakeLists.txt
├── LICENSE.txt
├── Makefile
├── README.md
├── cmake
├── AddInstallRPATHSupport.cmake
├── AddUninstallTarget.cmake
├── InstallBasicPackageFiles.cmake
└── scs_types.h.in
├── docs
└── src
│ ├── Doxyfile
│ ├── Makefile
│ ├── _static
│ ├── css
│ │ └── scs_theme.css
│ ├── favicon.ico
│ ├── scs_logo.png
│ └── scs_logo_transparent.png
│ ├── algorithm
│ ├── acceleration.rst
│ ├── equilibration.rst
│ ├── index.rst
│ ├── relaxation.rst
│ ├── scale.rst
│ └── warm_start.rst
│ ├── api
│ ├── c.rst
│ ├── compile_flags.rst
│ ├── cones.rst
│ ├── exit_flags.rst
│ ├── index.rst
│ ├── info.rst
│ ├── javascript.rst
│ ├── julia.rst
│ ├── matlab.rst
│ ├── matrices.rst
│ ├── python.rst
│ ├── r.rst
│ ├── ruby.rst
│ └── settings.rst
│ ├── blas_lapack
│ └── index.rst
│ ├── citing
│ └── index.rst
│ ├── conf.py
│ ├── contributing
│ └── index.rst
│ ├── examples
│ ├── .gitignore
│ ├── c.rst
│ ├── index.rst
│ ├── javascript.rst
│ ├── javascript_disc.html
│ ├── julia.rst
│ ├── matlab.rst
│ ├── python.rst
│ ├── python
│ │ ├── basic_qp.rst
│ │ ├── entropy.py
│ │ ├── entropy.py.out
│ │ ├── entropy.rst
│ │ ├── lasso.py
│ │ ├── lasso.py.out
│ │ ├── lasso.rst
│ │ ├── mat_completion.py
│ │ ├── mat_completion.py.out
│ │ ├── mat_completion.rst
│ │ ├── mpc.py
│ │ ├── mpc.py.out
│ │ ├── mpc.rst
│ │ ├── qp.py
│ │ └── qp.py.out
│ ├── qp.c
│ ├── qp.c.out
│ ├── qp.m
│ ├── qp.m.out
│ ├── qp.prob
│ ├── r.rst
│ └── ruby.rst
│ ├── files
│ ├── qp_solvers_benchmark.png
│ ├── windows1.png
│ ├── windows2.png
│ └── windows3.png
│ ├── help
│ └── index.rst
│ ├── index.rst
│ ├── install
│ ├── c.rst
│ ├── index.rst
│ ├── javascript.rst
│ ├── julia.rst
│ ├── matlab.rst
│ ├── python.rst
│ ├── r.rst
│ └── ruby.rst
│ ├── linear_solver
│ └── index.rst
│ ├── make.bat
│ └── requirements.txt
├── include
├── aa.h
├── cones.h
├── ctrlc.h
├── glbopts.h
├── linalg.h
├── linsys.h
├── normalize.h
├── rw.h
├── scs.h
├── scs_blas.h
├── scs_types.h
├── scs_work.h
└── util.h
├── linsys
├── cpu
│ ├── direct
│ │ ├── private.c
│ │ └── private.h
│ └── indirect
│ │ ├── private.c
│ │ └── private.h
├── csparse.c
├── csparse.h
├── external
│ ├── amd
│ │ ├── LICENSE.txt
│ │ ├── SuiteSparse_config.c
│ │ ├── SuiteSparse_config.h
│ │ ├── amd.h
│ │ ├── amd_1.c
│ │ ├── amd_2.c
│ │ ├── amd_aat.c
│ │ ├── amd_control.c
│ │ ├── amd_defaults.c
│ │ ├── amd_dump.c
│ │ ├── amd_global.c
│ │ ├── amd_info.c
│ │ ├── amd_internal.h
│ │ ├── amd_order.c
│ │ ├── amd_post_tree.c
│ │ ├── amd_postorder.c
│ │ ├── amd_preprocess.c
│ │ ├── amd_valid.c
│ │ └── changes
│ └── qdldl
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── changes
│ │ ├── qdldl.c
│ │ ├── qdldl.h
│ │ └── qdldl_types.h
├── gpu
│ ├── gpu.c
│ ├── gpu.h
│ └── indirect
│ │ ├── private.c
│ │ └── private.h
├── mkl
│ └── direct
│ │ ├── private.c
│ │ └── private.h
├── scs_matrix.c
└── scs_matrix.h
├── scs.mk
├── src
├── aa.c
├── cones.c
├── ctrlc.c
├── exp_cone.c
├── linalg.c
├── normalize.c
├── rw.c
├── scs.c
├── scs_version.c
└── util.c
└── test
├── minunit.h
├── problem_utils.h
├── problems
├── degenerate.h
├── hs21_tiny_qp.h
├── hs21_tiny_qp_rw.h
├── infeasible_tiny_qp.h
├── max_ent
├── max_ent.h
├── mpc_bug.h
├── mpc_bug1
├── mpc_bug2
├── mpc_bug3
├── qafiro_tiny_qp.h
├── random_prob
├── random_prob.h
├── rob_gauss_cov_est.h
├── small_lp.h
├── small_qp.h
├── test_exp_cone.h
├── test_prob_from_data_file.h
├── test_validation.h
└── unbounded_tiny_qp.h
├── random_socp_prob.c
├── rng.h
├── run_from_file.c
└── run_tests.c
/.bumpversion.cfg:
--------------------------------------------------------------------------------
1 | [bumpversion]
2 | current_version = 3.2.7
3 |
4 | [bumpversion:file:README.md]
5 |
6 | [bumpversion:file:CITATION.cff]
7 |
8 | [bumpversion:file:include/glbopts.h]
9 |
10 | [bumpversion:file:CMakeLists.txt]
11 |
12 | [bumpversion:file:docs/src/conf.py]
13 |
14 | [bumpversion:file:docs/src/Doxyfile]
15 |
16 | [bumpversion:file:docs/src/citing/index.rst]
17 |
18 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | **Please read this first**
2 |
3 | If you are have a problem that SCS struggles with you can pass a string to the
4 | `write_data_filename` argument and SCS will dump a file containing the problem
5 | to disk. Zip the file and send it to us or attach it to this bug report for easy
6 | reproduction of the issue.
7 |
8 | A common cause of issues is not linking BLAS/LAPACK libraries correctly. If you
9 | are having this issue please search for resources on installing and linking
10 | these libraries first. You can try openblas if you need a BLAS library.
11 |
12 |
13 | ## Specifications
14 | - OS:
15 | - SCS Version:
16 | - Compiler:
17 |
18 | ## Description
19 | A clear and concise description of the problem.
20 |
21 | ## How to reproduce
22 | Ideally a minimal snippet of code that reproduces the problem if possible.
23 |
24 | ## Additional information
25 | Extra context.
26 |
27 | ## Output
28 | Entire SCS output including the entire stack trace if applicable.
29 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "github-actions" # See documentation for possible values
9 | directory: "/" # Location of package manifests
10 | schedule:
11 | interval: "weekly"
12 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Build and Test
3 |
4 | on: [push, pull_request]
5 |
6 | jobs:
7 | linux:
8 | strategy:
9 | fail-fast: false
10 | matrix:
11 | long: [0, 1]
12 | lapack: [0, 1]
13 |
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v4
17 | - run: sudo apt-get install libopenblas-dev liblapack-dev
18 | - run: make DLONG=${{ matrix.long }} USE_LAPACK=${{ matrix.lapack }}
19 | - run: make test DLONG=${{ matrix.long }} USE_LAPACK=${{ matrix.lapack }}
20 | - run: out/run_tests_direct # test direct solver
21 | - run: out/run_tests_indirect # test indirect solver
22 |
23 | # runs-on: windows-latest
24 | # steps:
25 | # - uses: actions/checkout@v4
26 | # - run: choco install clapack
27 | # - run: make
28 | # - run: make test
29 | # - run: test/run_tests
30 |
31 | mac:
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | long: [0, 1]
36 | lapack: [0, 1]
37 |
38 | runs-on: macos-latest
39 | steps:
40 | - uses: actions/checkout@v4
41 | - run: brew install openblas lapack
42 | - run: make DLONG=${{ matrix.long }} USE_LAPACK=${{ matrix.lapack }}
43 | - run: make test DLONG=${{ matrix.long }} USE_LAPACK=${{ matrix.lapack }}
44 | - run: out/run_tests_direct # test direct solver
45 | - run: out/run_tests_indirect # test indirect solver
46 |
--------------------------------------------------------------------------------
/.github/workflows/build_mkl.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Build and Test MKL
3 |
4 | on: [push, pull_request]
5 |
6 | jobs:
7 | linux:
8 | strategy:
9 | fail-fast: false
10 | matrix:
11 | long: [0, 1]
12 |
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - name: Intel Apt repository
17 | run: |
18 | wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
19 | sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
20 | rm GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
21 | echo "deb https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
22 | sudo apt-get update
23 |
24 | - name: Install Intel oneAPI
25 | run: sudo apt-get install intel-mkl
26 |
27 | - name: Setup Intel oneAPI environment
28 | run: |
29 | # TODO: hack to set MKLROOT for now
30 | echo "MKLROOT=/usr/lib/x86_64-linux-gnu" >> $GITHUB_ENV
31 | # source /opt/intel/mkl/bin/mklvars.sh
32 |
33 | - name: checkout project code
34 | uses: actions/checkout@v4
35 |
36 | - name: Build SCS MKL and test
37 | run: |
38 | make DLONG=${{ matrix.long }} mkl
39 | out/run_tests_mkl
40 |
--------------------------------------------------------------------------------
/.github/workflows/build_openmp.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Build and Test OpenMP
3 |
4 | on: [push, pull_request]
5 |
6 | jobs:
7 | linux:
8 | strategy:
9 | fail-fast: false
10 |
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - name: checkout project code
15 | uses: actions/checkout@v4
16 |
17 | - name: install deps
18 | run: sudo apt-get install libopenblas-dev liblapack-dev
19 |
20 | - name: Build SCS with OpenMP and test
21 | run: |
22 | make USE_OPENMP=1 test
23 | out/run_tests_direct
24 | out/run_tests_indirect
25 |
--------------------------------------------------------------------------------
/.github/workflows/buildpp.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Build C++ # test that we can compile SCS with C++ compiler
3 |
4 | on: [push, pull_request]
5 |
6 | jobs:
7 | linux:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v4
11 | - run: |
12 | sudo apt-get install libopenblas-dev liblapack-dev
13 | export CC=g++
14 | echo $CC
15 | make
16 | make test
17 | out/run_tests_direct # test direct solver
18 | out/run_tests_indirect # test indirect solver
19 |
20 | # runs-on: windows-latest
21 | # steps:
22 | # - uses: actions/checkout@v4
23 | # - run: choco install clapack
24 | # - run: make
25 | # - run: make test
26 | # - run: test/run_tests
27 |
28 | mac:
29 | runs-on: macos-latest
30 | steps:
31 | - uses: actions/checkout@v4
32 | - run: |
33 | brew install openblas lapack
34 | export CC=clang++
35 | echo $CC
36 | make
37 | make test
38 | out/run_tests_direct # test direct solver
39 | out/run_tests_indirect # test indirect solver
40 |
--------------------------------------------------------------------------------
/.github/workflows/cmake.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: CMake
3 |
4 | on: [push, pull_request]
5 |
6 | jobs:
7 | linux:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v4
11 | - run: |
12 | sudo apt-get install libopenblas-dev liblapack-dev
13 | mkdir out
14 | export INSTALL_DIR=$PWD/out
15 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$INSTALL_DIR/lib
16 | mkdir build
17 | cd build
18 | cmake -DBUILD_TESTING=ON -DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_DIR ..
19 | make
20 | make install
21 | ctest --output-on-failure
22 | cd ../docs/src/examples/
23 | gcc -I$INSTALL_DIR/include/scs -L$INSTALL_DIR/lib/ qp.c -o qp.out -lscsdir
24 | ./qp.out
25 |
26 | mac:
27 | runs-on: macos-latest
28 | steps:
29 | - uses: actions/checkout@v4
30 | - run: |
31 | brew install openblas lapack
32 | mkdir out
33 | export INSTALL_DIR=$PWD/out
34 | export DYLD_FALLBACK_LIBRARY_PATH=$DYLD_FALLBACK_LIBRARY_PATH:$INSTALL_DIR/lib
35 | mkdir build
36 | cd build
37 | cmake -DBUILD_TESTING=ON -DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_DIR ..
38 | make
39 | make install
40 | ctest --output-on-failure
41 | cd ../docs/src/examples/
42 | gcc -I$INSTALL_DIR/include/scs -L$INSTALL_DIR/lib/ qp.c -o qp.out -lscsdir
43 | ./qp.out
44 |
45 |
--------------------------------------------------------------------------------
/.github/workflows/cmake_mkl.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: CMake MKL
3 |
4 | on: [push, pull_request]
5 |
6 | jobs:
7 | linux:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - name: Intel Apt repository
11 | run: |
12 | wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
13 | sudo apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
14 | rm GPG-PUB-KEY-INTEL-SW-PRODUCTS-2023.PUB
15 | echo "deb https://apt.repos.intel.com/oneapi all main" | sudo tee /etc/apt/sources.list.d/oneAPI.list
16 | sudo apt-get update
17 |
18 | - name: Install Intel oneAPI
19 | run: sudo apt-get install intel-mkl
20 |
21 | - name: Setup Intel oneAPI environment
22 | run: |
23 | # TODO: hack to set MKLROOT for now
24 | echo "MKLROOT=/usr/lib/x86_64-linux-gnu" >> $GITHUB_ENV
25 | # source /opt/intel/mkl/bin/mklvars.sh
26 |
27 | - name: checkout project code
28 | uses: actions/checkout@v4
29 |
30 | - name: Build SCS MKL and test
31 | run: |
32 | mkdir out
33 | export INSTALL_DIR=$PWD/out
34 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$INSTALL_DIR/lib
35 | mkdir build
36 | cd build
37 | cmake -DBUILD_TESTING=ON -DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_DIR ..
38 | make
39 | make install
40 | ctest --output-on-failure
41 | cd ../docs/src/examples/
42 | gcc -I$INSTALL_DIR/include/scs -L$INSTALL_DIR/lib/ qp.c -o qp.out -lscsmkl
43 | ./qp.out
44 |
45 |
--------------------------------------------------------------------------------
/.github/workflows/cmake_openmp.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: CMake OpenMP
3 |
4 | on: [push, pull_request]
5 |
6 | jobs:
7 | linux:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v4
11 | - run: |
12 | sudo apt-get install libopenblas-dev liblapack-dev
13 | mkdir out
14 | export INSTALL_DIR=$PWD/out
15 | export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$INSTALL_DIR/lib
16 | mkdir build
17 | cd build
18 | cmake -DUSE_OPENMP=ON -DBUILD_TESTING=ON -DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_DIR ..
19 | make
20 | make install
21 | ctest --output-on-failure
22 | cd ../docs/src/examples/
23 | gcc -I$INSTALL_DIR/include/scs -L$INSTALL_DIR/lib/ qp.c -o qp.out -lscsdir
24 | ./qp.out
25 |
26 |
--------------------------------------------------------------------------------
/.github/workflows/coverage.yml:
--------------------------------------------------------------------------------
1 | name: Coveralls
2 |
3 | on: ["push", "pull_request"]
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - name: Check out
10 | uses: actions/checkout@v4
11 | with:
12 | submodules: 'recursive'
13 |
14 | - name: Set up
15 | run: sudo apt-get install -y libopenblas-dev liblapack-dev lcov
16 |
17 | - name: Make
18 | run: make test COVERAGE=1
19 |
20 | - name: Run tests
21 | run: out/run_tests_direct && out/run_tests_indirect
22 |
23 | - name: Process coverage
24 | uses: imciner2/run-lcov@v1
25 | with:
26 | input_directory: '${{ runner.workspace }}'
27 | exclude: '"$GITHUB_WORKSPACE/test/*" "$GITHUB_WORKSPACE/linsys/external/*" "/usr/include/x86_64-linux-gnu/bits/*"'
28 | output_file: '${{ runner.workspace }}/coverage.info'
29 |
30 | - name: Upload coverage
31 | uses: coverallsapp/github-action@master
32 | with:
33 | github-token: ${{ secrets.GITHUB_TOKEN }}
34 | path-to-lcov: '${{ runner.workspace }}/coverage.info'
35 |
36 |
--------------------------------------------------------------------------------
/.github/workflows/docs.yml:
--------------------------------------------------------------------------------
1 | name: Docs
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | build-and-deploy:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v4
14 | - name: Install OS dependencies
15 | run: |
16 | sudo apt-get install doxygen
17 | - name: Setup Python
18 | uses: actions/setup-python@v5
19 | - name: Install Python dependencies
20 | run: |
21 | pip install sphinx sphinx-rtd-theme breathe docutils
22 | - name: Build docs
23 | run: |
24 | cd docs/src && make docs && touch ../.nojekyll
25 | - name: Deploy
26 | uses: JamesIves/github-pages-deploy-action@v4.7.3
27 | with:
28 | branch: gh-pages # The branch the action should deploy to.
29 | folder: docs # The folder the action should deploy.
30 |
31 |
--------------------------------------------------------------------------------
/.github/workflows/gpu.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: GPU
3 | on:
4 | - push
5 | - pull_request
6 | jobs:
7 | linux:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v4
11 | - uses: Jimver/cuda-toolkit@v0.2.23
12 | id: cuda-toolkit
13 | with:
14 | method: network
15 | non-cuda-sub-packages: '["libcublas", "libcusparse", "libcudart"]'
16 | - run: sudo apt-get install libopenblas-dev liblapack-dev
17 | - run: make gpu
18 | - run: make test_gpu
19 | # - run: out/run_tests_gpu_indirect # gpus not available yet
20 |
--------------------------------------------------------------------------------
/.github/workflows/valgrind.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Valgrind
3 |
4 | on: [push, pull_request]
5 |
6 | jobs:
7 | linux:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v4
11 | - run: sudo apt-get update
12 | - run: sudo apt-get install libopenblas-dev liblapack-dev valgrind
13 | - run: make
14 | - run: make test
15 | - run: valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --show-reachable=yes --error-exitcode=1 out/run_tests_direct
16 | - run: valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --show-reachable=yes --error-exitcode=1 out/run_tests_indirect
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.gcno
2 | *.csv
3 | *.iml
4 | docs/*
5 | !docs/src
6 | examples/DIMACS/
7 | local.mk
8 | sftp-config.json
9 | .settings
10 | .cproject
11 | .project
12 | .pydevproject
13 | .idea
14 | *.pyc
15 | *dSYM
16 | *demo_direct
17 | *demo_indirect
18 | python/flags.tmp
19 | python/.coverage
20 | python/build/
21 | python/cover/
22 | python_dist
23 | linsys_dense/out
24 | out
25 | .swo
26 | *.o
27 | *.a
28 | *.DS_Store
29 | *.out
30 | *.nav
31 | *.dvi
32 | *.ps
33 | *.pdf
34 | *.aux
35 | *.log
36 | *.bbl
37 | *.blg
38 | *.toc
39 | *.swp
40 | *.m~
41 | *.mat
42 | *.mex*
43 | *.mexmaci
44 | *.mexa64
45 | *.mexmaci64
46 | *.dependencies
47 | *.classpath
48 | *.class
49 | *.dylib
50 | *.jar
51 | hs21_tiny_qp
52 | rob_gauss_cov_est
53 | build/
54 |
--------------------------------------------------------------------------------
/CITATION.cff:
--------------------------------------------------------------------------------
1 | cff-version: 1.2.0
2 | message: "If you use this software, please cite it as below."
3 | authors:
4 | - family-names: "O'Donoghue"
5 | given-names: "Brendan"
6 | - family-names: "Chu"
7 | given-names: "Eric"
8 | - family-names: "Parikh"
9 | given-names: "Neal"
10 | - family-names: "Boyd"
11 | given-names: "Stephen"
12 | title: "SCS: Spltting Conic Solver"
13 | version: 3.2.7
14 | date-released: 2023
15 | url: "https://github.com/cvxgrp/scs"
16 |
17 | # Original SCS paper:
18 | preferred-citation:
19 | type: article
20 | authors:
21 | - family-names: "O'Donoghue"
22 | given-names: "Brendan"
23 | - family-names: "Chu"
24 | given-names: "Eric"
25 | - family-names: "Parikh"
26 | given-names: "Neal"
27 | - family-names: "Boyd"
28 | given-names: "Stephen"
29 | journal: "Journal of Optimization Theory and Applications"
30 | month: 6
31 | start: 1042 # Start pages
32 | end: 1068 # End pages
33 | title: "Conic Optimization via Operator Splitting and Homogeneous Self-Dual Embedding"
34 | issue: 3
35 | volume: 169
36 | year: 2016
37 | doi: 10.1007/s10957-016-0892-3
38 | url: https://dx.doi.org/10.1007/s10957-016-0892-3
39 |
40 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2012 Brendan O'Donoghue (bodonoghue85@gmail.com)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | [](https://github.com/cvxgrp/scs/actions/workflows/build.yml)
6 | [](https://www.cvxgrp.org/scs/)
7 | [](https://coveralls.io/github/cvxgrp/scs?branch=master)
8 |
9 |
10 | SCS (`splitting conic solver`) is a numerical optimization package for solving
11 | large-scale convex cone problems. The current version is `3.2.7`.
12 |
13 | The full documentation is available [here](https://www.cvxgrp.org/scs/).
14 |
15 | If you wish to cite SCS please cite the papers listed [here](https://www.cvxgrp.org/scs/citing).
16 |
--------------------------------------------------------------------------------
/cmake/AddUninstallTarget.cmake:
--------------------------------------------------------------------------------
1 | #.rst:
2 | # AddUninstallTarget
3 | # ------------------
4 | #
5 | # Add the "uninstall" target for your project::
6 | #
7 | # include(AddUninstallTarget)
8 | #
9 | #
10 | # will create a file cmake_uninstall.cmake in the build directory and add a
11 | # custom target uninstall that will remove the files installed by your package
12 | # (using install_manifest.txt)
13 |
14 | #=============================================================================
15 | # Copyright 2008-2013 Kitware, Inc.
16 | # Copyright 2013 Istituto Italiano di Tecnologia (IIT)
17 | # Authors: Daniele E. Domenichelli
18 | #
19 | # Distributed under the OSI-approved BSD License (the "License");
20 | # see accompanying file Copyright.txt for details.
21 | #
22 | # This software is distributed WITHOUT ANY WARRANTY; without even the
23 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
24 | # See the License for more information.
25 | #=============================================================================
26 | # (To distribute this file outside of CMake, substitute the full
27 | # License text for the above reference.)
28 |
29 |
30 | if(DEFINED __ADD_UNINSTALL_TARGET_INCLUDED)
31 | return()
32 | endif()
33 | set(__ADD_UNINSTALL_TARGET_INCLUDED TRUE)
34 |
35 |
36 | set(_filename ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
37 |
38 | file(WRITE ${_filename}
39 | "if(NOT EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\")
40 | message(WARNING \"Cannot find install manifest: \\\"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\\\"\")
41 | return()
42 | endif()
43 |
44 | file(READ \"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\" files)
45 | string(STRIP \"\${files}\" files)
46 | string(REGEX REPLACE \"\\n\" \";\" files \"\${files}\")
47 | list(REVERSE files)
48 | foreach(file \${files})
49 | message(STATUS \"Uninstalling: \$ENV{DESTDIR}\${file}\")
50 | if(EXISTS \"\$ENV{DESTDIR}\${file}\")
51 | execute_process(
52 | COMMAND \${CMAKE_COMMAND} -E remove \"\$ENV{DESTDIR}\${file}\"
53 | OUTPUT_VARIABLE rm_out
54 | RESULT_VARIABLE rm_retval)
55 | if(NOT \"\${rm_retval}\" EQUAL 0)
56 | message(FATAL_ERROR \"Problem when removing \\\"\$ENV{DESTDIR}\${file}\\\"\")
57 | endif()
58 | else()
59 | message(STATUS \"File \\\"\$ENV{DESTDIR}\${file}\\\" does not exist.\")
60 | endif()
61 | endforeach(file)
62 | ")
63 |
64 | if("${CMAKE_GENERATOR}" MATCHES "^(Visual Studio|Xcode)")
65 | set(_uninstall "UNINSTALL")
66 | else()
67 | set(_uninstall "uninstall")
68 | endif()
69 | add_custom_target(${_uninstall} COMMAND "${CMAKE_COMMAND}" -P "${_filename}")
70 | set_property(TARGET ${_uninstall} PROPERTY FOLDER "CMakePredefinedTargets")
71 |
--------------------------------------------------------------------------------
/cmake/scs_types.h.in:
--------------------------------------------------------------------------------
1 | /*
2 | * GENERATED BY CMAKE
3 | */
4 |
5 | /*
6 | * Pulic header including definitions of primitive types used in SCS.
7 | * Make sure this file and `scs.h` are somewhere appropriate and then use
8 | * `#include "scs.h"` to access the SCS public API.
9 | */
10 |
11 | #ifndef SCS_TYPES_H_GUARD
12 | #define SCS_TYPES_H_GUARD
13 |
14 | #ifdef __cplusplus
15 | extern "C" {
16 | #endif
17 |
18 | typedef @SCS_INT_TYPE@ scs_int;
19 | typedef @SCS_FLOAT_TYPE@ scs_float;
20 |
21 | #ifdef __cplusplus
22 | }
23 | #endif
24 | #endif
25 |
--------------------------------------------------------------------------------
/docs/src/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = .
9 | BUILDDIR = _build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
22 | docs:
23 | @make html
24 | @cp -a _build/html/. ..
25 | @touch ../.nojekyll
26 | @rm -rf doxygen_out/*
27 | @make clean
28 |
29 |
--------------------------------------------------------------------------------
/docs/src/_static/css/scs_theme.css:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Open+Sans:400,400i,600,600i,700,700i);
2 |
3 | h1, h2, h3, h4, h5, h6 {
4 | font-family: "Open Sans", sans-serif;
5 | font-weight: 600;
6 | }
7 |
8 | body {
9 | font-family: 'Open Sans', sans-serif;
10 | }
11 |
12 | /* no box shadow on buttons */
13 | .btn {
14 | font-weight: normal;
15 | font-family: "Open Sans", sans-serif;
16 | box-shadow: none;
17 | }
18 |
19 | .wy-side-nav-search {
20 | background-color: rgb(245, 245, 245);
21 | }
22 |
23 | .wy-nav-side {
24 | background: rgb(245, 245, 245);
25 | }
26 |
27 | .wy-side-nav-search>div.version{
28 | color: rgb(0, 0, 0);
29 | }
30 |
31 | .wy-nav-top {
32 | color: rgb(245, 245, 245);
33 | background-color: rgb(245, 245, 245);
34 | }
35 |
36 | .wy-nav-top i{
37 | color: rgb(46, 118, 176);
38 | }
39 |
40 | /* Navigation bar text */
41 | .wy-menu-vertical header, .wy-menu-vertical p.caption {
42 | color: rgb(255, 255, 255); /* White text*/
43 | font-weight: 600;
44 | }
45 |
46 | .wy-menu-vertical a{
47 | color: rgb(178, 188, 200); /* Grey */
48 | }
49 |
50 | .wy-menu-vertical a:hover{
51 | background: rgb(46, 118, 176);
52 | color: rgb(255, 255, 255); /* White text*/
53 | }
54 |
55 | /* override table width restrictions */
56 | .wy-table-responsive table td, .wy-table-responsive table th {
57 | white-space: normal;
58 | }
59 |
60 | .wy-table-responsive {
61 | margin-bottom: 24px;
62 | max-width: 100%;
63 | overflow: visible;
64 | }
65 |
66 | .wy-nav-content-wrap, .wy-menu li.current > a {
67 | background-color: rgb(245, 245, 245);
68 | /* font-weight: 600; */
69 | }
70 |
71 | /* change page width */
72 | /*.wy-nav-content {
73 | * max-width: none;
74 | *}
75 | */
76 |
77 | /* Link Styling */
78 | a,a:visited, a:focus {
79 | color: rgb(46, 118, 176); /* Light blue */
80 | text-decoration: none;
81 | }
82 | a:hover, a:active {
83 | color: rgb(0, 32, 72); /* blue */
84 | text-decoration: none;
85 | }
86 |
87 | .wy-side-nav-search>a{
88 | color: rgb(0, 0, 0);
89 | }
90 | .wy-nav-top a{
91 | color: rgb(0, 0, 0);
92 | }
93 |
94 | /* Navigation bar text */
95 | .wy-menu-vertical header, .wy-menu-vertical p.caption {
96 | color: rgb(0, 0, 0);
97 | font-weight: 600;
98 | }
99 |
100 | .wy-menu-vertical a{
101 | color: rgb(0, 0, 0);
102 | }
103 |
104 |
--------------------------------------------------------------------------------
/docs/src/_static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cvxgrp/scs/8a739589e66f745d049fc838f55775d3e07f669b/docs/src/_static/favicon.ico
--------------------------------------------------------------------------------
/docs/src/_static/scs_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cvxgrp/scs/8a739589e66f745d049fc838f55775d3e07f669b/docs/src/_static/scs_logo.png
--------------------------------------------------------------------------------
/docs/src/_static/scs_logo_transparent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cvxgrp/scs/8a739589e66f745d049fc838f55775d3e07f669b/docs/src/_static/scs_logo_transparent.png
--------------------------------------------------------------------------------
/docs/src/algorithm/relaxation.rst:
--------------------------------------------------------------------------------
1 | .. _relaxation:
2 |
3 | Relaxation
4 | ==========
5 |
6 | The (unscaled, see :ref:`scaling`) SCS update equations are:
7 |
8 | .. math::
9 | \begin{align}
10 | \tilde u^{k+1} &= (I + \mathcal{Q})^{-1} w^k \\
11 | u^{k+1} &= (I + N_{\mathcal{C}_+})^{-1} (2 \tilde u^{k+1} - w^k) \\
12 | w^{k+1} &= w^k + \alpha (u^{k+1} - \tilde u^{k+1}) \\
13 | \end{align}
14 |
15 | where :math:`\alpha \in (0,2)` is the *relaxation* parameter. Vanilla
16 | Douglas-Rachford corresponds to setting :math:`\alpha = 1`. If :math:`\alpha <
17 | 1` it is referred to as under-relaxation, if :math:`\alpha > 1` it is
18 | over-relaxation. Typically values of :math:`\alpha \approx 1.5` work well. It
19 | is controlled by the :code:`alpha` :ref:`setting `. If :math:`\alpha
20 | = 2` the method reduces to Peaceman-Rachford splitting, which is not guaranteed
21 | to converge in general (but will if, for example, the operators in the problem
22 | are both maximal strongly monotone).
23 |
24 | Thankfully, there is no interaction between :math:`\alpha` and the scaling
25 | described in :ref:`scaling`, and they can be combined immediately.
26 |
--------------------------------------------------------------------------------
/docs/src/algorithm/warm_start.rst:
--------------------------------------------------------------------------------
1 | .. _warm_start:
2 |
3 | Caching the workspace and warm-starts
4 | -------------------------------------
5 |
6 | SCS supports reusing the workspace between solves so long as the data matrices
7 | :math:`A` and :math:`P` do not change. After an initial solve the workspace can
8 | be updated with new :math:`b` and :math:`c` vectors if desired. This can
9 | substantially speed up subsequent solve times since we can cache important
10 | quantities such as the matrix factorization and the data equilibration.
11 | Moreover, SCS supports warm-starting the solver with a guess of the solution,
12 | which can significantly reduce the total number of iterations required for
13 | convergence.
14 |
15 | Re-using the workspace and warm-starting can be useful, for example, when
16 | solving a sequence of related problems such as in :ref:`Model predictive control
17 | ` or solving for the entire regularization path in the :ref:`the Lasso
18 | `.
19 |
20 | In the :ref:`C API ` call :code:`scs_init` once to initialize the
21 | workspace, then use the :code:`scs_solve` in conjunction with
22 | :code:`scs_update` to solve a sequence of problems. Warm-starting can be done
23 | by setting the warm-start :ref:`setting ` to :code:`True` when calling
24 | :code:`scs_solve`, and then including the guess of the solution in the :code:`x,
25 | y, s` members of the :ref:`ScsSolution` struct, where those members correspond
26 | to the guess of the solution in the :ref:`standard form `. SCS will
27 | initialize the solver at those points and then overwrite the :ref:`ScsSolution`
28 | struct members with the real solution at termination.
29 |
30 | In other languages caching the workspace and warm-starting is documented in
31 | their respective :ref:`interfaces`.
32 |
33 |
--------------------------------------------------------------------------------
/docs/src/api/c.rst:
--------------------------------------------------------------------------------
1 | .. _c_interface:
2 |
3 | C / C++
4 | =======
5 |
6 |
7 | .. _C_main_API:
8 |
9 | Main solver API
10 | ---------------
11 |
12 | The C API is imported from the header :code:`scs.h`, available `here
13 | `_. This file
14 | and :code:`scs_types.h` are the only public header files required
15 | for downstream applications.
16 |
17 | .. doxygenfunction:: scs_init
18 | .. doxygenfunction:: scs_solve
19 | .. doxygenfunction:: scs_update
20 | .. doxygenfunction:: scs_finish
21 |
22 | Helper functions
23 | ^^^^^^^^^^^^^^^^
24 |
25 | This sets the :ref:`ScsSettings ` struct to the default values as
26 | specified in the :ref:`settings` page.
27 |
28 | .. doxygenfunction:: scs_set_default_settings
29 |
30 | If you only need to solve a single problem and not a series of related problems,
31 | then you can call the :code:`scs` function documented here, which simply calls
32 | the :code:`scs_init`, :code:`scs_solve`, :code:`scs_finish` sequence above.
33 |
34 | .. doxygenfunction:: scs
35 |
36 |
37 | ..
38 | Lower level
39 | ^^^^^^^^^^^
40 |
41 | Under the hood the :code:`scs` function above simply calls the three functions
42 | below in series. It can be useful to call :code:`scs_solve` many times for the
43 | same call to :code:`scs_init`. If you want to do this, for example because you
44 | want to cache the matrix factorization for many solves, please `contact us
45 | `_, because currently that
46 | functionality is disabled.
47 |
48 | .. doxygenfunction:: scs_init
49 |
50 | .. doxygenfunction:: scs_solve
51 |
52 | .. doxygenfunction:: scs_finish
53 |
54 |
55 | Primitive types
56 | ---------------
57 |
58 | These are defined in header file :code:`scs_types.h`.
59 |
60 | * :code:`scs_int`: is :code:`long` if the :ref:`compiler flag ` :code:`DLONG` is set, otherwise it is :code:`int`
61 | * :code:`scs_float`: is :code:`float` if the :ref:`compiler flag ` :code:`SFLOAT` is set, otherwise it is :code:`double`
62 |
63 |
64 | Input Types
65 | -----------
66 |
67 | The relevant input structs required by API are as follows.
68 |
69 | .. _ScsData:
70 |
71 | Data
72 | ^^^^
73 |
74 | .. doxygenstruct:: ScsData
75 | :members:
76 |
77 | .. _ScsMatrix:
78 |
79 | Data Matrices
80 | ^^^^^^^^^^^^^
81 |
82 | The matrices must be in `Compressed Sparse Column (CSC) format `_ using zero-based indexing.
83 | See :ref:`matrices` for more details on what SCS expects.
84 |
85 | .. doxygenstruct:: ScsMatrix
86 | :members:
87 |
88 | .. _ScsCone:
89 |
90 | Cone
91 | ^^^^
92 |
93 | See :ref:`cones` for more details.
94 |
95 | .. doxygenstruct:: ScsCone
96 | :members:
97 |
98 | .. _ScsSettings:
99 |
100 | Settings
101 | ^^^^^^^^
102 |
103 | See :ref:`settings` for details on each of these.
104 |
105 | .. doxygenstruct:: ScsSettings
106 | :members:
107 |
108 | Output Types
109 | ------------
110 |
111 | The relevant output structs returned by SCS are as follows.
112 |
113 | .. _ScsSolution:
114 |
115 | Solution
116 | ^^^^^^^^
117 |
118 | This will contain the solution as found by SCS *or* the certificate of primal or
119 | dual infeasibility (see :ref:`termination`). If the user wants to warm-start the
120 | solver, then the Solution struct is also used as an input to specify the
121 | warm-start points (see :ref:`warm_start`).
122 |
123 |
124 | .. doxygenstruct:: ScsSolution
125 | :members:
126 |
127 | .. _ScsInfo:
128 |
129 | Info
130 | ^^^^^
131 |
132 | See :ref:`info` for details on each of these.
133 |
134 | .. doxygenstruct:: ScsInfo
135 | :members:
136 |
137 | Workspace
138 | ---------
139 |
140 | The user should not need to interact with the :code:`ScsWork` struct,
141 | which contains the internal workspace allocated and maintained by SCS.
142 |
143 |
--------------------------------------------------------------------------------
/docs/src/api/compile_flags.rst:
--------------------------------------------------------------------------------
1 | .. _compile_flags:
2 |
3 | Compile flags
4 | -------------
5 |
6 | Typically the user will not need to interact with these flags, but we document them
7 | here for completeness. Note this list is not exhaustive, others are not exposed
8 | but defined in :code:`include/glbopts.h`. The list below are defined in
9 | :code:`scs.mk` and can be overridden via the command line when compiling by
10 | executing, e.g., :code:`make DLONG=1`, to set the :code:`DLONG` flag to True.
11 |
12 |
13 | .. list-table::
14 | :widths: 25 25 25 25
15 | :header-rows: 1
16 |
17 | * - Name
18 | - Description
19 | - Permitted values
20 | - Default
21 | * - :code:`DLONG`
22 | - If True use 64 bit integers, else 32 bit
23 | - True/False
24 | - 0
25 | * - :code:`SFLOAT`
26 | - If True use 32 bit floats, else 64 bit (WARNING: currently broken)
27 | - True/False
28 | - 0
29 | * - :code:`CTRLC`
30 | - Listen to CTRL-C interruptions
31 | - True/False
32 | - 1
33 | * - :code:`NO_TIMER`
34 | - Disables code timing
35 | - True/False
36 | - 0
37 | * - :code:`NO_VALIDATE`
38 | - Disables data validation
39 | - True/False
40 | - 0
41 | * - :code:`NO_PRINTING`
42 | - Disables all printing in compiled binary
43 | - True/False
44 | - 0
45 | * - :code:`NO_READ_WRITE`
46 | - Disables the read/write code
47 | - True/False
48 | - 0
49 | * - :code:`COPYAMATRIX`
50 | - Make a copy of A in memory
51 | - True/False
52 | - 1
53 | * - :code:`GPU_TRANSPOSE_MAT`
54 | - If on GPU store A transpose in memory
55 | - True/False
56 | - 1
57 | * - :code:`VALIDATE`
58 | - Whether to perform problem validation or not
59 | - True/False
60 | - 1
61 | * - :code:`VERBOSITY`
62 | - Verbosity level (for debugging)
63 | - :math:`\mathbf{N}`
64 | - 0
65 | * - :code:`USE_LAPACK`
66 | - Whether to link in :ref:`BLAS/LAPACK `
67 | - True/False
68 | - 1
69 | * - :code:`USE_OPENMP`
70 | - Use openmp to parallelize some computation
71 | - True/False
72 | - 0
73 | * - :code:`BLAS64`
74 | - The BLAS library is 64 bits
75 | - True/False
76 | - 0
77 | * - :code:`NOBLASSUFFIX`
78 | - The BLAS library has no function name suffix
79 | - True/False
80 | - 0
81 | * - :code:`BLASSUFFIX`
82 | - The BLAS library uses this suffix
83 | - String
84 | - '_'
85 | * - :code:`MATLAB_MEX_FILE`
86 | - If compiling for use in MATLAB
87 | - True/False
88 | - 0
89 | * - :code:`PYTHON`
90 | - If compiling for use in python
91 | - True/False
92 | - 0
93 | * - :code:`USING_R`
94 | - If compiling for use in R
95 | - True/False
96 | - 0
97 |
--------------------------------------------------------------------------------
/docs/src/api/exit_flags.rst:
--------------------------------------------------------------------------------
1 | .. _exit_flags:
2 |
3 | Exit flags
4 | -----------
5 | The integer values that SCS can return are documented below and are defined
6 | in the :code:`'include/scs.h` file.
7 |
8 | .. list-table::
9 | :widths: 50 10 40
10 | :header-rows: 1
11 |
12 | * - Status
13 | - Value
14 | - SCS constant name
15 | * - Solved to desired tolerance
16 | - 1
17 | - :code:`SCS_SOLVED`
18 | * - Did not reach desired accuracy, returning best guess of solution
19 | - 2
20 | - :code:`SCS_SOLVED_INACCURATE`
21 | * - Unfinished (never returned, only used internally)
22 | - 0
23 | - :code:`SCS_UNFINISHED`
24 | * - Primal unbounded / Dual infeasible (to desired tolerance)
25 | - -1
26 | - :code:`SCS_UNBOUNDED`
27 | * - Primal infeasible / Dual unbounded (to desired tolerance)
28 | - -2
29 | - :code:`SCS_INFEASIBLE`
30 | * - Indeterminate (numerical errors when recovering solution) DEPRECATED
31 | - -3
32 | - :code:`SCS_INDETERMINATE`
33 | * - Failed (usually a data input error)
34 | - -4
35 | - :code:`SCS_FAILED`
36 | * - Interrupted (received SIGINT)
37 | - -5
38 | - :code:`SCS_SIGINT`
39 | * - Did not reach desired accuracy, returning best guess of certificate of primal unboundedness
40 | - -6
41 | - :code:`SCS_UNBOUNDED_INACCURATE`
42 | * - Did not reach desired accuracy, returning best guess of certificate of primal infeasibility
43 | - -7
44 | - :code:`SCS_INFEASIBLE_INACCURATE`
45 |
46 |
--------------------------------------------------------------------------------
/docs/src/api/index.rst:
--------------------------------------------------------------------------------
1 | .. _api:
2 |
3 | API
4 | ===
5 |
6 | .. toctree::
7 | :maxdepth: 2
8 | :hidden:
9 |
10 | cones.rst
11 | matrices.rst
12 | settings.rst
13 | info.rst
14 | exit_flags.rst
15 | compile_flags.rst
16 |
17 | Loosely speaking, SCS takes data :math:`P, A, b, c, \mathcal{K}` and produces
18 | primal-dual :ref:`optimal ` points :math:`(x^\star, y^\star,
19 | s^\star)` or a certificate of primal or dual :ref:`infeasibility`. The
20 | supported cones are documented :ref:`here `. The input format for the
21 | data matrices is documented :ref:`here `. The behavior of SCS is
22 | controlled by the :ref:`settings `. As well as the :ref:`solution
23 | `, SCS also returns :ref:`information ` about the solve
24 | process and a status :ref:`exit flag `.
25 |
26 | .. _interfaces:
27 |
28 | Interfaces
29 | ----------
30 |
31 | SCS is written in raw C code, with interfaces for several other languages.
32 |
33 | :ref:`C/C++ `
34 |
35 | :ref:`Python `
36 |
37 | :ref:`MATLAB `
38 |
39 | :ref:`Julia `
40 |
41 | :ref:`R `
42 |
43 | :ref:`Ruby `
44 |
45 | :ref:`JavaScript / WebAssembly `
46 |
47 | .. toctree::
48 | :maxdepth: 2
49 | :hidden:
50 |
51 | c.rst
52 | python.rst
53 | matlab.rst
54 | julia.rst
55 | r.rst
56 | ruby.rst
57 | javascript.rst
58 |
--------------------------------------------------------------------------------
/docs/src/api/info.rst:
--------------------------------------------------------------------------------
1 | .. _info:
2 |
3 | Return information
4 | ------------------
5 | When SCS terminates it will return an :ref:`ScsInfo ` struct containing
6 | the following fields.
7 |
8 |
9 | .. list-table::
10 | :widths: 15 15 70
11 | :header-rows: 1
12 |
13 | * - Name
14 | - Type
15 | - Description
16 | * - :code:`iter`
17 | - :code:`scs_int`
18 | - Number of iterations taken
19 | * - :code:`status`
20 | - :code:`char *`
21 | - Status string (e.g., 'solved')
22 | * - :code:`lin_sys_solver`
23 | - :code:`char *`
24 | - Linear system solver used
25 | * - :code:`status_val`
26 | - :code:`scs_int`
27 | - Status integer :ref:`exit flag `
28 | * - :code:`scale_updates`
29 | - :code:`scs_int`
30 | - Number of updates to the scale parameter (see :ref:`updating_scale`)
31 | * - :code:`pobj`
32 | - :code:`scs_float`
33 | - Primal objective
34 | * - :code:`dobj`
35 | - :code:`scs_float`
36 | - Dual objective
37 | * - :code:`res_pri`
38 | - :code:`scs_float`
39 | - Primal residual (see :ref:`termination conditions `)
40 | * - :code:`res_dual`
41 | - :code:`scs_float`
42 | - Dual residual (see :ref:`termination conditions `)
43 | * - :code:`gap`
44 | - :code:`scs_float`
45 | - Absolute duality gap (see :ref:`termination conditions `)
46 | * - :code:`res_infeas`
47 | - :code:`scs_float`
48 | - Primal infeasibility residual (see :ref:`termination conditions `)
49 | * - :code:`res_unbdd_a`
50 | - :code:`scs_float`
51 | - Dual infeasibility residual involving :math:`A` (see :ref:`termination conditions `)
52 | * - :code:`res_unbdd_p`
53 | - :code:`scs_float`
54 | - Dual infeasibility residual involving :math:`P` (see :ref:`termination conditions `)
55 | * - :code:`comp_slack`
56 | - :code:`scs_float`
57 | - Complementary slackness (:math:`s^\top y`), should be very close to zero
58 | * - :code:`setup_time`
59 | - :code:`scs_float`
60 | - Time taken for setup (milliseconds)
61 | * - :code:`solve_time`
62 | - :code:`scs_float`
63 | - Time taken for solve (milliseconds)
64 | * - :code:`scale`
65 | - :code:`scs_float`
66 | - Final scale parameter, useful for initializing next solve (see :ref:`updating_scale`)
67 | * - :code:`rejected_accel_steps`
68 | - :code:`scs_int`
69 | - Number of times an AA update was rejected by the safeguarding check (see :ref:`acceleration`)
70 | * - :code:`accepted_accel_steps`
71 | - :code:`scs_int`
72 | - Number of times an AA update was accepted by the safeguarding check (see :ref:`acceleration`)
73 | * - :code:`lin_sys_time`
74 | - :code:`scs_float`
75 | - Total time (milliseconds) spent in the :ref:`linear system solver `
76 | * - :code:`cone_time`
77 | - :code:`scs_float`
78 | - Total time (milliseconds) spent in the :ref:`cone projection `
79 | * - :code:`accel_time`
80 | - :code:`scs_float`
81 | - Total time (milliseconds) spent in the :ref:`aceleration routine `
82 |
83 |
--------------------------------------------------------------------------------
/docs/src/api/julia.rst:
--------------------------------------------------------------------------------
1 | .. _julia_interface:
2 |
3 | Julia
4 | =====
5 |
6 | The recommended way to use `SCS.jl `_ is via
7 | `Convex.jl `_ or
8 | `JuMP `_.
9 |
10 | Read the `SCS.jl README `_ for more details.
11 |
--------------------------------------------------------------------------------
/docs/src/api/matlab.rst:
--------------------------------------------------------------------------------
1 | .. _matlab_interface:
2 |
3 | MATLAB
4 | ======
5 |
6 | After :ref:`installing ` you can call
7 |
8 | .. code:: matlab
9 |
10 | [x, y, s, info] = scs(data, cones, settings)
11 |
12 | where :code:`data` is a struct containing :code:`P, A, b, c`, :code:`P, A` must
13 | be sparse matrices, :code:`settings` is a struct containing solver
14 | :ref:`settings` (missing settings are set to the defaults), and :code:`cones` is
15 | a struct that contains the :ref:`cones` information. The :code:`cone` struct
16 | contains members corresponding to the cone type and values corresponding to either
17 | the cone length or the array that defines the cone (see the third column in
18 | :ref:`cones` for the keys and what the corresponding values represent). At
19 | termination :code:`x, y, s` contains the primal-dual :ref:`solution
20 | ` or the :ref:`certificate of infeasibility `, and
21 | info is a struct containing the solve :ref:`info`.
22 |
23 | Warm-starting
24 | -------------
25 |
26 | Warm-starting SCS with a guess of the primal-dual solution can reduce the total
27 | solve time. This is useful, for example, when solving several similar problems
28 | sequentially. To do this add to the :code:`data` struct passed to :code:`scs`
29 | the additional fields :code:`x`, :code:`y`, and :code:`s` (or any subset
30 | thereof) where :code:`x` and :code:`s` correspond to the primal solution guesses
31 | and :code:`y` corresponds to the dual solution guess.
32 |
--------------------------------------------------------------------------------
/docs/src/api/matrices.rst:
--------------------------------------------------------------------------------
1 | .. _matrices:
2 |
3 | Data matrices
4 | =============
5 |
6 | * Both matrices :math:`A` and :math:`P` must be in `Compressed Sparse Column (CSC) format `_ using zero-based indexing.
7 |
8 | * The order of the rows of :math:`A` must be in the order that the cones appear in the :ref:`cones table `.
9 |
10 | * The rows of :math:`A` corresponding to semidefinite cones (as well as the rows of :math:`b`) must be handled carefully, as described in :ref:`sdcone`.
11 |
12 | * The matrix :math:`P` must be symmetric positive semidefinite and only the **upper triangular** part of :math:`P` should be passed in.
13 |
14 | * If :math:`P = 0` for your problem then you can set the :code:`P` entry to NULL in the :ref:`ScsData` struct. :math:`A` must always be non-NULL.
15 |
16 | See the :ref:`ScsMatrix struct ` for the concrete implementation in
17 | the C api.
18 |
19 |
--------------------------------------------------------------------------------
/docs/src/api/python.rst:
--------------------------------------------------------------------------------
1 | .. _python_interface:
2 |
3 | Python
4 | ======
5 |
6 | After :ref:`installing ` you can import SCS using
7 |
8 | .. code:: python
9 |
10 | import scs
11 |
12 | This module provides the :code:`SCS` class which is initialized using:
13 |
14 | .. code:: python
15 |
16 | solver = scs.SCS(data,
17 | cone,
18 | use_indirect=False,
19 | mkl=False,
20 | gpu=False,
21 | verbose=True,
22 | normalize=True,
23 | max_iters=int(1e5),
24 | scale=0.1,
25 | adaptive_scale=True,
26 | eps_abs=1e-4,
27 | eps_rel=1e-4,
28 | eps_infeas=1e-7,
29 | alpha=1.5,
30 | rho_x=1e-6,
31 | acceleration_lookback=10,
32 | acceleration_interval=10,
33 | time_limit_secs=0,
34 | write_data_filename=None,
35 | log_csv_filename=None)
36 |
37 | where :code:`data` is a dict containing :code:`P, A, b, c`, and :code:`cone` is
38 | a dict that contains the :ref:`cones` information. The :code:`cone` dict
39 | contains keys corresponding to the cone type and values corresponding to either
40 | the cone length or the array that defines the cone (see the third column in
41 | :ref:`cones` for the keys and what the corresponding values represent). The
42 | :code:`b`, and :code:`c` entries must be 1d numpy arrays and the :code:`P` and
43 | :code:`A` entries must be scipy sparse matrices in CSC format; if they are not
44 | of the proper format, SCS will attempt to convert them. The
45 | :code:`use_indirect` setting switches between the sparse direct
46 | :ref:`linear_solver` (the default) or the sparse indirect solver. If the MKL
47 | Pardiso direct solver for SCS is :ref:`installed ` then it can
48 | be used by setting :code:`mkl=True`. If the GPU indirect solver for SCS is
49 | :ref:`installed ` and a GPU is available then it can be used by
50 | setting :code:`gpu=True`. The remaining fields are explained in
51 | :ref:`settings`.
52 |
53 | Then to solve the problem call:
54 |
55 | .. code:: python
56 |
57 | sol = solver.solve(warm_start=True, x=None, y=None, s=None)
58 |
59 | where :code:`warm_start` indicates whether the solve will reuse the previous
60 | solution as a warm-start (if this is the first solve it initializes at zero).
61 | A good warm-start can reduce the overall number of iterations required to solve
62 | a problem. 1d Numpy arrays :code:`x,y,s` are (optional) warm-start overrides if
63 | you wish to set these manually rather than use solution to the last problem as
64 | the warm-start.
65 |
66 | At termination :code:`sol` is a dict with fields :code:`x, y, s, info` where
67 | :code:`x, y, s` contains the primal-dual :ref:`solution ` or the
68 | :ref:`certificate of infeasibility `, and :code:`info` is a dict
69 | containing the solve :ref:`info`.
70 |
71 | To re-use the workspace and solve a similar problem with new :code:`b`
72 | and / or :code:`c` data, we can update the solver using:
73 |
74 | .. code:: python
75 |
76 | solver.update(b=new_b, c=new_c) # update b and c vectors (can be None)
77 | solver.solve() # solve new problem with updated b and c
78 |
79 |
80 |
--------------------------------------------------------------------------------
/docs/src/api/r.rst:
--------------------------------------------------------------------------------
1 | .. _r_interface:
2 |
3 | R
4 | =
5 |
6 | R interface source code available `here `_.
7 | After :ref:`installing ` you can load SCS using
8 |
9 | .. code:: r
10 |
11 | library("scs")
12 |
13 |
14 | Usage
15 | -----
16 |
17 | Use function `scs` to solve a given optimization problem. Additional information
18 | about the arguments can be found in the `R-Manual `_
19 | or the :ref:`matrices ` of the homepage.
20 |
21 | .. code-block:: r
22 |
23 | scs(A,
24 | b,
25 | obj,
26 | P = NULL,
27 | cone,
28 | initial = NULL,
29 | control = scs_control())
30 |
31 |
32 | The `scs_control` is used to define additional settings, additional information
33 | can be found in the R-Manual or the :ref:`settings ` section of the
34 | homepage.
35 |
36 | .. code-block:: r
37 |
38 | scs_control(max_iters = 100000L,
39 | eps_rel = 1e-04,
40 | eps_abs = 1e-04,
41 | eps_infeas = 1e-07,
42 | alpha = 1.5,
43 | rho_x = 1e-06,
44 | scale = 0.1,
45 | verbose = FALSE,
46 | normalize = TRUE,
47 | warm_start = FALSE,
48 | acceleration_lookback = 0L,
49 | acceleration_interval = 1L,
50 | adaptive_scale = TRUE,
51 | write_data_filename = NULL,
52 | log_csv_filename = NULL,
53 | time_limit_secs = 0)
54 |
55 |
--------------------------------------------------------------------------------
/docs/src/api/ruby.rst:
--------------------------------------------------------------------------------
1 | .. _ruby_interface:
2 |
3 | Ruby
4 | ====
5 |
6 | See documentation `here `_.
7 |
8 |
--------------------------------------------------------------------------------
/docs/src/api/settings.rst:
--------------------------------------------------------------------------------
1 | .. _settings:
2 |
3 | Settings
4 | --------
5 |
6 | These settings control how SCS behaves during a solve.
7 | They are set in the :ref:`ScsSettings ` struct.
8 |
9 | .. list-table::
10 | :widths: 20 20 20 20 20
11 | :header-rows: 1
12 |
13 | * - Name
14 | - Type
15 | - Description
16 | - Permitted values
17 | - Default
18 | * - :code:`normalize`
19 | - :code:`scs_int`
20 | - Whether to perform heuristic data rescaling. See :ref:`equilibration`.
21 | - True/False
22 | - 1
23 | * - :code:`scale`
24 | - :code:`scs_float`
25 | - Initial dual scale factor, updated if :code:`adaptive_scale` is True. See :ref:`scaling`.
26 | - :math:`(0, \infty)`
27 | - 0.1
28 | * - :code:`adaptive_scale`
29 | - :code:`scs_int`
30 | - Whether to heuristically adapt dual :code:`scale` through the solve. See :ref:`scaling`.
31 | - True/False
32 | - 1
33 | * - :code:`rho_x`
34 | - :code:`scs_float`
35 | - Primal scale factor. See :ref:`scaling`.
36 | - :math:`(0, \infty)`
37 | - 1e-6
38 | * - :code:`max_iters`
39 | - :code:`scs_int`
40 | - Maximum number of iterations to run.
41 | - :math:`\mathbf{N}`
42 | - 1e5
43 | * - :code:`eps_abs`
44 | - :code:`scs_float`
45 | - Absolute feasibility tolerance, see :ref:`termination`.
46 | - :math:`(0, \infty)`
47 | - 1e-4
48 | * - :code:`eps_rel`
49 | - :code:`scs_float`
50 | - Relative feasibility tolerance, see :ref:`termination`.
51 | - :math:`(0, \infty)`
52 | - 1e-4
53 | * - :code:`eps_infeas`
54 | - :code:`scs_float`
55 | - Infeasibility tolerance (primal and dual), see :ref:`infeasibility`.
56 | - :math:`(0, \infty)`
57 | - 1e-7
58 | * - :code:`alpha`
59 | - :code:`scs_float`
60 | - Douglas-Rachford relaxation parameter. See :ref:`relaxation`.
61 | - :math:`(0, 2)`
62 | - 1.5
63 | * - :code:`time_limit_secs`
64 | - :code:`scs_float`
65 | - Time limit for solve run in seconds (can be fractional). :code:`0` is interpreted as no limit.
66 | - :math:`[0, \infty)`
67 | - 0
68 | * - :code:`verbose`
69 | - :code:`scs_int`
70 | - Whether to print solver output to stdout.
71 | - True/False
72 | - 1
73 | * - :code:`warm_start`
74 | - :code:`scs_int`
75 | - Set to True if you initialize the solver with a guess of the solution. See :ref:`warm_start`. This is overridden by the argument passed to :code:`scs_solve`.
76 | - True/False
77 | - 0
78 | * - :code:`acceleration_lookback`
79 | - :code:`scs_int`
80 | - How much memory to use for Anderson acceleration. More memory requires more time to compute but can give more reliable steps. :code:`0` disables it. See :ref:`acceleration`.
81 | - :math:`\mathbf{N}`
82 | - 10
83 | * - :code:`acceleration_interval`
84 | - :code:`scs_int`
85 | - Run Anderson acceleration every :code:`acceleration_interval` iterations. See :ref:`acceleration`.
86 | - :math:`\mathbf{N}`
87 | - 10
88 | * - :code:`write_data_filename`
89 | - :code:`char *`
90 | - If this is set the problem data is dumped to this filename.
91 | - Any filename
92 | - NULL
93 | * - :code:`log_csv_filename`
94 | - :code:`char *`
95 | - If this is set SCS will write csv logs of various quantities through the solver (makes the solver much slower).
96 | - Any filename
97 | - NULL
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/docs/src/blas_lapack/index.rst:
--------------------------------------------------------------------------------
1 | .. _blas_lapack:
2 |
3 | BLAS and LAPACK
4 | ===============
5 | BLAS and LAPACK are dense numerical linear algebra packages. SCS uses these
6 | libraries in two places:
7 |
8 | * To compute the eigen-decomposition for the semidefinite :ref:`cone ` projection
9 | * To solve the linear system in :ref:`Anderson acceleration `
10 |
11 | Therefore compiling with BLAS / LAPACK **is optional**. If you are
12 | not interested in solving SDPs or using acceleration then there is no need to
13 | use these libraries. To compile without these libraries you can set the
14 | :ref:`compiler flag ` :code:`USE_LAPACK` to :code:`0`, e.g., if
15 | :ref:`installing ` using :code:`make`:
16 |
17 | .. code:: bash
18 |
19 | make USE_LAPACK=0
20 |
21 | If you do want to solve SDPs or use Anderson acceleration, then you will need
22 | to install BLAS and LAPACK libraries (these are pre-installed in most machines).
23 | If calling SCS from another language (Python, MATLAB etc.) then these libraries
24 | should be pre-installed and SCS will try to link against them. Otherwise
25 | you may need to install a copy yourself. A good library to start with is
26 | `OpenBLAS `_, which contains both BLAS and LAPACK.
27 |
28 | There are many different BLAS and LAPACK libraries that conform to the same API.
29 | Finding one that is optimized for your machine can make a big difference to
30 | the speed of the operations in practice. If the speed of the SDP projection
31 | or the acceleration step is a bottleneck you can experiment with faster
32 | libraries like `MKL `_
33 | or `ATLAS `_.
34 |
35 |
36 |
--------------------------------------------------------------------------------
/docs/src/citing/index.rst:
--------------------------------------------------------------------------------
1 | .. _citing :
2 |
3 | Citing SCS
4 | ===========
5 |
6 | If you wish to cite SCS, please use any of the following:
7 |
8 | .. glossary::
9 |
10 | Original paper
11 | Main algorithm description, derivation, and initial numerical results `paper `__.
12 |
13 | .. code:: latex
14 |
15 | @article{ocpb:16,
16 | author = {Brendan O'Donoghue and Eric Chu and Neal Parikh and Stephen Boyd},
17 | title = {Conic Optimization via Operator Splitting and Homogeneous Self-Dual Embedding},
18 | journal = {Journal of Optimization Theory and Applications},
19 | month = {June},
20 | year = {2016},
21 | volume = {169},
22 | number = {3},
23 | pages = {1042-1068},
24 | url = {http://stanford.edu/~boyd/papers/scs.html},
25 | }
26 |
27 | Latest extension
28 | The paper that derived the extension to quadratics and describes the latest version of the algorithm is available `here `__.
29 |
30 | .. code:: latex
31 |
32 | @article{odonoghue:21,
33 | author = {Brendan O'Donoghue},
34 | title = {Operator Splitting for a Homogeneous Embedding of the Linear Complementarity Problem},
35 | journal = {{SIAM} Journal on Optimization},
36 | month = {August},
37 | year = {2021},
38 | volume = {31},
39 | issue = {3},
40 | pages = {1999-2023},
41 | }
42 |
43 | Software
44 | If you need to cite a particular version of the SCS software (e.g., for replication purposes) the latest version can be cited as:
45 |
46 |
47 | .. code:: latex
48 |
49 | @misc{scs,
50 | author = {Brendan O'Donoghue and Eric Chu and Neal Parikh and Stephen Boyd},
51 | title = {{SCS}: Splitting Conic Solver, version 3.2.7},
52 | howpublished = {\url{https://github.com/cvxgrp/scs}},
53 | month = nov,
54 | year = 2023
55 | }
56 |
57 | Anderson Acceleration
58 | The acceleration scheme we use is described in the `paper `__.
59 |
60 | .. code:: latex
61 |
62 | @article{aa2020,
63 | title={Globally Convergent {type--I} {A}nderson Acceleration for Non-Smooth Fixed-Point Iterations},
64 | author={Junzi Zhang and Brendan O'Donoghue and Stephen Boyd},
65 | journal={{SIAM} Journal on Optimization},
66 | volume={30},
67 | number={4},
68 | pages={3170--3197},
69 | year={2020}
70 | }
71 |
72 |
--------------------------------------------------------------------------------
/docs/src/conf.py:
--------------------------------------------------------------------------------
1 | # Configuration file for the Sphinx documentation builder.
2 | #
3 | # This file only contains a selection of the most common options. For a full
4 | # list see the documentation:
5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html
6 |
7 | # -- Path setup --------------------------------------------------------------
8 |
9 | # If extensions (or modules to document with autodoc) are in another directory,
10 | # add these directories to sys.path here. If the directory is relative to the
11 | # documentation root, use os.path.abspath to make it absolute, like shown here.
12 | #
13 | # import os
14 | # import sys
15 | # sys.path.insert(0, os.path.abspath('.'))
16 |
17 | import subprocess
18 | import sphinx_rtd_theme
19 |
20 | # -- Project information -----------------------------------------------------
21 |
22 | project = "SCS"
23 | copyright = "2021, Brendan O'Donoghue"
24 | author = "Brendan O'Donoghue"
25 |
26 | # The full version, including alpha/beta/rc tags
27 | __version__ = "3.2.7"
28 |
29 | release = __version__
30 | version = __version__
31 |
32 | # -- General configuration ---------------------------------------------------
33 |
34 | # Add any Sphinx extension module names here, as strings. They can be
35 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
36 | # ones.
37 | extensions = ["sphinx.ext.mathjax", "breathe", "sphinx_rtd_theme"]
38 |
39 | # Add any paths that contain templates here, relative to this directory.
40 | templates_path = ["_templates"]
41 |
42 | # List of patterns, relative to source directory, that match files and
43 | # directories to ignore when looking for source files.
44 | # This pattern also affects html_static_path and html_extra_path.
45 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
46 |
47 | # sphinx pygments style uses ugly green boxes for code blocks
48 | # pygments_style = 'sphinx'
49 | pygments_style = "default"
50 |
51 | # html_sidebars = {
52 | # '**': [
53 | # 'about.html', 'navigation.html', 'searchbox.html',
54 | # ]
55 | # }
56 |
57 | # -- Options for HTML output -------------------------------------------------
58 |
59 | # The theme to use for HTML and HTML Help pages. See the documentation for
60 | # a list of builtin themes.
61 |
62 | # html_theme = 'alabaster'
63 | html_theme = "sphinx_rtd_theme"
64 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
65 |
66 |
67 | def setup(app):
68 | app.add_css_file("css/scs_theme.css")
69 |
70 |
71 | html_logo = "_static/scs_logo_transparent.png"
72 | html_favicon = "_static/favicon.ico"
73 | html_theme_options = {
74 | "logo_only": True,
75 | "display_version": True,
76 | #'github_banner': True,
77 | #'github_user': 'cvxgrp',
78 | #'github_repo': 'scs',
79 | #'logo': 'scs_logo_transparent.png',
80 | #'logo_name': False,
81 | #'github_button': False,
82 | #'github_type': 'star',
83 | "analytics_id": "G-9CY7R8S5N2",
84 | }
85 |
86 | rst_epilog = ".. |version| replace:: %s" % __version__
87 |
88 | # Breathe docs
89 | subprocess.call("doxygen Doxyfile", shell=True)
90 |
91 | breathe_projects = {"scs": "doxygen_out/xml/"}
92 | breathe_default_project = "scs"
93 |
94 | # Add any paths that contain custom static files (such as style sheets) here,
95 | # relative to this directory. They are copied after the builtin static files,
96 | # so a file named "default.css" will overwrite the builtin "default.css".
97 | html_static_path = ["_static"]
98 |
--------------------------------------------------------------------------------
/docs/src/contributing/index.rst:
--------------------------------------------------------------------------------
1 | .. _contributing:
2 |
3 | Contributing
4 | ===============
5 | There are many ways you can contribute to SCS, and we welcome all help!
6 | Here are some ideas (of varying difficulty):
7 |
8 | * Answer an open `GitHub issue `_
9 | * Improve the documentation (the website or in the code)
10 | * Add more :ref:`examples` to the docs
11 | * Improve the test coverage
12 | * Improve the :ref:`Anderson acceleration ` stability
13 | * Improve the :ref:`data equilibration `
14 | * Improve the :ref:`heuristic re-scaling `
15 | * Determine how to select the :code:`TAU_FACTOR` :ref:`term `
16 | * Implement a :ref:`GPU direct linear system solver `
17 | * Add other new :ref:`linear system solvers `
18 | * Refactor the :ref:`linear solvers ` to only compile a single binary with all solvers
19 | * Add :ref:`interfaces for other languages ` (or improve the current interfaces)
20 |
21 | If you are interested in helping out, please start by opening a `GitHub issue
22 | `_ so we can track progress and ensure
23 | that our priorities align.
24 |
--------------------------------------------------------------------------------
/docs/src/examples/.gitignore:
--------------------------------------------------------------------------------
1 | qp.out
2 |
--------------------------------------------------------------------------------
/docs/src/examples/c.rst:
--------------------------------------------------------------------------------
1 | .. _c_example:
2 |
3 | C/C++
4 | =====
5 |
6 | .. include:: qp.prob
7 |
8 | C code to solve this is below.
9 |
10 | .. literalinclude:: qp.c
11 | :language: c
12 |
13 | After following the CMake :ref:`install instructions `, we can
14 | compile the code (assuming the library was installed in :code:`/usr/local/` and
15 | the :code:`gcc` compiler is available) using:
16 |
17 | .. code::
18 |
19 | gcc -I/usr/local/include/scs -L/usr/local/lib/ qp.c -o qp.out -lscsdir
20 |
21 | .. ./qp.out > qp.c.out
22 |
23 | Then running the binary yields output:
24 |
25 | .. literalinclude:: qp.c.out
26 | :language: none
27 |
28 |
--------------------------------------------------------------------------------
/docs/src/examples/index.rst:
--------------------------------------------------------------------------------
1 | .. _examples:
2 |
3 | Examples
4 | ===============
5 |
6 | Here we present a few simple examples of calling SCS from different languages.
7 |
8 | :ref:`C/C++ `
9 |
10 | :ref:`Python `
11 |
12 | :ref:`MATLAB `
13 |
14 | :ref:`Julia `
15 |
16 | :ref:`R `
17 |
18 | :ref:`Ruby `
19 |
20 | :ref:`JavaScript / WebAssembly `
21 |
22 | .. toctree::
23 | :maxdepth: 2
24 | :hidden:
25 |
26 | c.rst
27 | python.rst
28 | matlab.rst
29 | julia.rst
30 | r.rst
31 | ruby.rst
32 | javascript.rst
33 |
34 |
--------------------------------------------------------------------------------
/docs/src/examples/julia.rst:
--------------------------------------------------------------------------------
1 | .. _julia_example:
2 |
3 | Julia
4 | ======
5 |
6 | The easiest way to use SCS in Julia is via JuMP:
7 |
8 | .. code:: julia
9 |
10 | using JuMP, SCS
11 | items = [:Gold, :Silver, :Bronze]
12 | values = Dict(:Gold => 5.0, :Silver => 3.0, :Bronze => 1.0)
13 | weight = Dict(:Gold => 2.0, :Silver => 1.5, :Bronze => 0.3)
14 | model = Model(SCS.Optimizer)
15 | @variable(model, 0 <= take[items] <= 1) # Define a variable for each item
16 | @objective(model, Max, sum(values[item] * take[item] for item in items))
17 | @constraint(model, sum(weight[item] * take[item] for item in items) <= 3)
18 | optimize!(model)
19 | println(value.(take))
20 | # 1-dimensional DenseAxisArray{Float64,1,...} with index sets:
21 | # Dimension 1, Symbol[:Gold, :Silver, :Bronze]
22 | # And data, a 3-element Vector{Float64}:
23 | # 1.0000002002226671
24 | # 0.4666659513182934
25 | # 1.0000007732744878
26 |
27 | Read the `JuMP documentation `_ and the
28 | `SCS.jl README `_ for more details.
29 |
--------------------------------------------------------------------------------
/docs/src/examples/matlab.rst:
--------------------------------------------------------------------------------
1 | .. _matlab_example:
2 |
3 | MATLAB
4 | ======
5 |
6 | .. include:: qp.prob
7 |
8 | Matlab code to solve this is below.
9 |
10 | .. literalinclude:: qp.m
11 | :language: matlab
12 |
13 | After following the matlab :ref:`install instructions `, we can
14 | run the code yielding output:
15 |
16 | .. /Applications/MATLAB_R2021a.app/bin/matlab -nodesktop -nojvm -nosplash \
17 | -nodisplay -r "run ~/git/scs/docs/src/examples/qp.m;exit" > qp.m.out
18 |
19 | .. literalinclude:: qp.m.out
20 | :language: none
21 |
22 |
--------------------------------------------------------------------------------
/docs/src/examples/python.rst:
--------------------------------------------------------------------------------
1 | .. _python_example:
2 |
3 | Python
4 | ======
5 |
6 | :ref:`Basic QP `
7 |
8 | :ref:`Lasso `
9 |
10 | :ref:`Low-rank matrix completion `
11 |
12 | :ref:`Maximum entropy `
13 |
14 | :ref:`Model predictive control `
15 |
16 |
17 | .. toctree::
18 | :maxdepth: 2
19 | :hidden:
20 |
21 | python/basic_qp.rst
22 | python/lasso.rst
23 | python/mat_completion.rst
24 | python/entropy.rst
25 | python/mpc.rst
26 |
--------------------------------------------------------------------------------
/docs/src/examples/python/basic_qp.rst:
--------------------------------------------------------------------------------
1 | .. _py_basic_qp:
2 |
3 | Basic QP
4 | ========
5 |
6 | .. include:: ../qp.prob
7 |
8 | Python code to solve this is below.
9 |
10 | .. literalinclude:: qp.py
11 | :language: python
12 |
13 | After following the python :ref:`install instructions `, we can
14 | run the code yielding output:
15 |
16 | .. python qp.py > qp.py.out
17 |
18 | .. literalinclude:: qp.py.out
19 | :language: none
20 |
--------------------------------------------------------------------------------
/docs/src/examples/python/entropy.py:
--------------------------------------------------------------------------------
1 | import scs
2 | import numpy as np
3 | from scipy import sparse
4 |
5 | # Generate problem data
6 | np.random.seed(1)
7 |
8 | # Matrix size parameters
9 | n = 50 # Number of variables
10 | p = 20 # Number of constraints
11 |
12 | # Generate random problem data
13 | tmp = np.random.rand(n)
14 | tmp /= np.sum(tmp)
15 | Ad = np.random.randn(p, n)
16 | bd = 0.5 * Ad.dot(tmp) + 0.01 * np.random.rand(p)
17 |
18 | # Build the A, b rows corresponding to the exponential cone
19 | A_exp = sparse.lil_matrix((3 * n, 2 * n))
20 | b_exp = np.zeros(3 * n)
21 | for i in range(n):
22 | A_exp[i * 3, i] = -1 # t
23 | A_exp[i * 3 + 1, i + n] = -1 # x
24 | b_exp[i * 3 + 2] = 1
25 |
26 | A = sparse.vstack(
27 | [
28 | # zero cone
29 | sparse.hstack([sparse.csc_matrix((1, n)), np.ones((1, n))]),
30 | # positive cone
31 | sparse.hstack([sparse.csc_matrix((p, n)), -Ad]),
32 | # exponential cones
33 | A_exp,
34 | ],
35 | format="csc",
36 | )
37 | b = np.hstack([1, -bd, b_exp])
38 | c = np.hstack([-np.ones(n), np.zeros(n)])
39 |
40 | # SCS data
41 | data = dict(A=A, b=b, c=c)
42 | # ep is exponential cone (primal), with n triples
43 | cone = dict(z=1, l=p, ep=n)
44 |
45 | # Setup workspace
46 | solver = scs.SCS(
47 | data,
48 | cone,
49 | )
50 | sol = solver.solve()
51 | x_scs = sol["x"][-n:]
52 |
53 | # Verify solution with CVXPY
54 | try:
55 | import cvxpy as cp
56 | except ModuleNotFoundError:
57 | print("This example requires CVXPY installed to run.")
58 | raise
59 |
60 | x = cp.Variable(shape=n)
61 | obj = cp.Maximize(cp.sum(cp.entr(x)))
62 | constraints = [cp.sum(x) == 1, Ad @ x >= bd]
63 | prob = cp.Problem(obj, constraints)
64 | prob.solve(solver=cp.ECOS)
65 | x_cvxpy = x.value
66 |
67 | print(f"CVXPY optimal value is:", prob.value)
68 | print(f"Solution norm difference: {np.linalg.norm(x_scs - x_cvxpy, np.inf)}")
69 |
--------------------------------------------------------------------------------
/docs/src/examples/python/entropy.py.out:
--------------------------------------------------------------------------------
1 | ------------------------------------------------------------------
2 | SCS v3.1.1 - Splitting Conic Solver
3 | (c) Brendan O'Donoghue, Stanford University, 2012
4 | ------------------------------------------------------------------
5 | problem: variables n: 100, constraints m: 171
6 | cones: z: primal zero / dual free vars: 1
7 | l: linear vars: 20
8 | e: exp vars: 150, dual exp vars: 0
9 | settings: eps_abs: 1.0e-04, eps_rel: 1.0e-04, eps_infeas: 1.0e-07
10 | alpha: 1.50, scale: 1.00e-01, adaptive_scale: 1
11 | max_iters: 100000, normalize: 1, rho_x: 1.00e-06
12 | acceleration_lookback: 10, acceleration_interval: 10
13 | lin-sys: sparse-direct
14 | nnz(A): 1150, nnz(P): 0
15 | ------------------------------------------------------------------
16 | iter | pri res | dua res | gap | obj | scale | time (s)
17 | ------------------------------------------------------------------
18 | 0| 1.11e+01 6.95e-01 5.59e+02 -3.06e+02 1.00e-01 9.02e-04
19 | 225| 8.91e-06 1.30e-05 3.24e-05 -3.89e+00 5.45e+00 1.43e-01
20 | ------------------------------------------------------------------
21 | status: solved
22 | timings: total: 1.44e-01s = setup: 5.53e-04s + solve: 1.43e-01s
23 | lin-sys: 1.06e-03s, cones: 1.42e-01s, accel: 4.26e-05s
24 | ------------------------------------------------------------------
25 | objective = -3.888803
26 | ------------------------------------------------------------------
27 | CVXPY optimal value is: 3.888784623785257
28 | Solution norm difference: 2.241074541050464e-06
29 |
--------------------------------------------------------------------------------
/docs/src/examples/python/entropy.rst:
--------------------------------------------------------------------------------
1 | .. _py_entropy:
2 |
3 | Maximum Entropy
4 | ===============
5 |
6 | This example demonstrates an instance of using the exponential :ref:`cone
7 | `. In this problem we want find the maximum entropy point inside a
8 | convex polytope, ie, to solve
9 |
10 | .. math::
11 |
12 | \begin{array}{ll}
13 | \mbox{maximize} & -\sum_i^n x_i \log x_i \\
14 | \mbox{subhect to} & {\bf 1}^T x = 1 \\
15 | & Ax - b \geq 0
16 | \end{array}
17 |
18 |
19 | over variable :math:`x \in \mathbf{R}^{n}`, where :math:`A \in
20 | \mathbf{R}^{m \times n}` and :math:`b \in \mathbf{R}^m` are data. The problem
21 | has the following equivalent form,
22 |
23 | .. math::
24 |
25 | \begin{array}{ll}
26 | \mbox{minimize} & -{\bf 1}^T t \\
27 | \mbox{subject to} & {\bf 1}^T x = 1 \\
28 | & Ax - b \geq 0 \\
29 | & \begin{bmatrix} t_i \\ x_i \\ 1 \end{bmatrix} \in \mathcal{K}_\mathrm{exp}, \quad i=1,\ldots,n,
30 | \end{array}
31 |
32 | over variables :math:`x \in \mathbf{R}^{n}`, :math:`t \in \mathbf{R}^{n}` and
33 | where :math:`\mathcal{K}_\mathrm{exp} \subset \mathbf{R}^3` denotes the
34 | exponential cone.
35 |
36 | Python code to solve this is below.
37 |
38 | .. literalinclude:: entropy.py
39 | :language: python
40 |
41 | After following the python :ref:`install instructions `, we can
42 | run the code yielding output:
43 |
44 | .. python entropy.py > entropy.py.out
45 |
46 | .. literalinclude:: entropy.py.out
47 | :language: none
48 |
--------------------------------------------------------------------------------
/docs/src/examples/python/lasso.py:
--------------------------------------------------------------------------------
1 | import scs
2 | import numpy as np
3 | import scipy as sp
4 | from scipy import sparse
5 |
6 | # Generate problem data
7 | sp.random.seed(1)
8 | np.random.seed(1)
9 |
10 | n = 200 # Variables
11 | m = 100 # Measurements
12 | Ad = sparse.random(m, n, density=0.5) # Measurement matrix
13 | x_true = sparse.random(n, 1, density=0.1) # True sparse vector
14 | x_true = np.array(x_true.todense()).squeeze()
15 |
16 | measurements = Ad @ x_true + 0.1 * np.random.randn(m)
17 | measurements = np.array(measurements).squeeze()
18 |
19 | # The smallest value of lambda with solution all-zeros
20 | lambda_max = np.linalg.norm(Ad.T @ measurements, np.inf)
21 |
22 | # Auxiliary data
23 | In = sparse.eye(n)
24 | Im = sparse.eye(m)
25 | On = sparse.csc_matrix((n, n))
26 | Onm = sparse.csc_matrix((n, m))
27 |
28 | # SCS data
29 | P = sparse.block_diag([On, sparse.eye(m), On], format="csc")
30 | q = np.zeros(2 * n + m)
31 | A = sparse.vstack(
32 | [
33 | # zero cone
34 | sparse.hstack([Ad, -Im, Onm.T]),
35 | # positive cones
36 | sparse.hstack([In, Onm, -In]),
37 | sparse.hstack([-In, Onm, -In]),
38 | ],
39 | format="csc",
40 | )
41 | b = np.hstack([measurements, np.zeros(n), np.zeros(n)])
42 | c = np.zeros(2 * n + m)
43 |
44 | data = dict(P=P, A=A, b=b, c=c)
45 | cone = dict(z=m, l=2 * n)
46 |
47 | print(f"Solving for lambda = 0")
48 | # Setup workspace
49 | solver = scs.SCS(
50 | data,
51 | cone,
52 | eps_abs=1e-6,
53 | eps_rel=1e-6,
54 | )
55 | sol = solver.solve() # lambda = 0
56 | x = sol["x"][:n]
57 | print(f"Error : {np.linalg.norm(x_true - x) / np.linalg.norm(x_true)}")
58 |
59 | # Solve for different values of lambda
60 | lambdas = np.logspace(-2, np.log10(lambda_max), 11)
61 | for lam in lambdas:
62 | print(f"Solving for lambda = {lam}")
63 | # Re-use workspace, just update the `c` vector
64 | c_new = np.hstack([np.zeros(n + m), lam * np.ones(n)])
65 | solver.update(c=c_new)
66 | # Solve updated problem
67 | sol = solver.solve() # will warm-start automatically
68 | x = sol["x"][:n]
69 | # What is the norm error?
70 | print(f"Error : {np.linalg.norm(x_true - x) / np.linalg.norm(x_true)}")
71 |
--------------------------------------------------------------------------------
/docs/src/examples/python/lasso.rst:
--------------------------------------------------------------------------------
1 | .. _py_lasso:
2 |
3 | Lasso
4 | =====
5 | This example demonstrates quadratic objectives, as well as reusing a
6 | :ref:`cached workspace and using warm-starting `.
7 |
8 | In the lasso the goal is to find a sparse vector that fits some measurements.
9 | The :math:`\ell_1` norm is used as a convex surrogate for sparsity, and
10 | a regularization parameter :math:`\lambda \geq 0` trades off sparsity and
11 | quality of fit. Concretely the lasso solves
12 |
13 | .. math::
14 |
15 | \begin{array}{ll}
16 | \mbox{minimize} & \frac{1}{2} \| Ax - b \|_2^2 + \lambda \| x \|_1
17 | \end{array}
18 |
19 |
20 | over variable :math:`x \in \mathbf{R}^{n}`, with data :math:`A \in
21 | \mathbf{R}^{m \times n}` and :math:`b \in \mathbf{R}^n`. The problem has the
22 | following equivalent form,
23 |
24 | .. math::
25 |
26 | \begin{array}{ll}
27 | \mbox{minimize} & \frac{1}{2} y^T y + \lambda {\bf 1}^T t \\
28 | \mbox{subject to} & y = Ax - b \\
29 | & -t \le x \le t
30 | \end{array}
31 |
32 | over variables :math:`x \in \mathbf{R}^{n}`, :math:`t \in \mathbf{R}^{n}`,
33 | :math:`y \in \mathbf{R}^{m}`. From this formulation it is straightforward to
34 | convert it into the standard form accepted by SCS. The regularization parameter
35 | :math:`\lambda \geq 0` trades off the sparsity of the solution and the quality
36 | of the fit, and so we solve the problem for many choices of :math:`\lambda`.
37 | Since :math:`\lambda` enters only in the linear part of the objective function,
38 | we can reuse the matrix factorization and use warm starting to reduce the
39 | computation time.
40 |
41 | Python code to solve this is below.
42 |
43 | .. literalinclude:: lasso.py
44 | :language: python
45 |
46 | After following the python :ref:`install instructions `, we can
47 | run the code yielding output:
48 |
49 | .. python lasso.py > lasso.py.out
50 |
51 | .. literalinclude:: lasso.py.out
52 | :language: none
53 |
--------------------------------------------------------------------------------
/docs/src/examples/python/mat_completion.py:
--------------------------------------------------------------------------------
1 | import scs
2 | import numpy as np
3 | import scipy as sp
4 | from scipy import sparse
5 |
6 | np.random.seed(1)
7 |
8 | # The vec function as documented in api/cones
9 | def vec(S):
10 | n = S.shape[0]
11 | S = np.copy(S)
12 | S *= np.sqrt(2)
13 | S[range(n), range(n)] /= np.sqrt(2)
14 | return S[np.triu_indices(n)]
15 |
16 |
17 | # The mat function as documented in api/cones
18 | def mat(s):
19 | n = int((np.sqrt(8 * len(s) + 1) - 1) / 2)
20 | S = np.zeros((n, n))
21 | S[np.triu_indices(n)] = s / np.sqrt(2)
22 | S = S + S.T
23 | S[range(n), range(n)] /= np.sqrt(2)
24 | return S
25 |
26 |
27 | dim = 15 # dim x dim matrix
28 | vlen = int(dim * (dim + 1) / 2) # length of vector x = vec(X)
29 |
30 | # Generate true matrix
31 | rank = dim // 5 # low rank
32 | X = np.random.randn(dim, rank)
33 | X = X @ X.T
34 |
35 | #############################################################################
36 |
37 | # Let's first do some basic sanity checks to ensure that mat, vec are working:
38 |
39 | # mat(vec( . )) should be identity
40 | print(f"Should be ~ 0: {np.linalg.norm(X - mat(vec(X)))}")
41 |
42 | # Trace( . ) should be vec(I)' vec( . )
43 | print(f"Should be ~ 0: {np.trace(X) - vec(np.eye(dim)) @ vec(X)}")
44 |
45 | #############################################################################
46 |
47 | num_measurements = vlen // 2 # how many measurements are revealed
48 |
49 | # Generate random measurement indices
50 | measurement_idxs = np.random.choice(
51 | np.arange(vlen), size=num_measurements, replace=False
52 | )
53 |
54 | # Create A matrix
55 | Ad = np.zeros((num_measurements, vlen))
56 | for i in range(num_measurements):
57 | Ad[i, measurement_idxs[i]] = 1.0
58 |
59 | # Noisy measurements of X
60 | measurements = Ad @ vec(X) + 0.01 * np.random.randn(num_measurements) # + noise
61 |
62 | # Auxiliary data
63 | In = sparse.eye(vlen)
64 | Im = sparse.eye(num_measurements)
65 | On = sparse.csc_matrix((vlen, vlen))
66 | Onm = sparse.csc_matrix((vlen, num_measurements))
67 |
68 | # SCS data
69 | P = sparse.block_diag([On, sparse.eye(num_measurements)], format="csc")
70 | A = sparse.vstack(
71 | [
72 | # zero cone
73 | sparse.hstack([Ad, -Im]),
74 | # positive semidefinite cone
75 | sparse.hstack([-In, Onm]),
76 | ],
77 | format="csc",
78 | )
79 | b = np.hstack([measurements, np.zeros(vlen)])
80 | c = np.hstack([np.zeros(vlen + num_measurements)])
81 |
82 | data = dict(P=P, A=A, b=b, c=c)
83 | cone = dict(z=num_measurements, s=dim)
84 | # Setup workspace
85 | solver = scs.SCS(data, cone, eps_abs=1e-6, eps_rel=1e-6)
86 | print(f"Solving for lambda = 0")
87 | sol = solver.solve() # lambda = 0
88 | X_hat = mat(sol["x"][:vlen])
89 | print(f"Error: {np.linalg.norm(X_hat - X) / np.linalg.norm(X)}")
90 |
91 | # Solve for different values of lambda
92 | lambdas = np.logspace(-6, 1, 11)
93 | for lam in lambdas:
94 | print(f"Solving for lambda = {lam}")
95 | # Re-use workspace, just update the `c` vector
96 | c_new = np.hstack([lam * vec(np.eye(dim)), np.zeros(num_measurements)])
97 | solver.update(c=c_new)
98 | # Solve updated problem
99 | sol = solver.solve() # will warm-start automatically
100 | X_hat = mat(sol["x"][:vlen])
101 | # What is the norm error?
102 | print(f"Error : {np.linalg.norm(X_hat - X) / np.linalg.norm(X)}")
103 |
--------------------------------------------------------------------------------
/docs/src/examples/python/mat_completion.rst:
--------------------------------------------------------------------------------
1 | .. _py_mat_completion:
2 |
3 | Low-Rank Matrix Completion
4 | ==========================
5 |
6 | This example demonstrates how to use the :ref:`positive semidefinite cone
7 | `, as well as reusing a :ref:`cached workspace and using warm-starting
8 | `.
9 |
10 | Matrix completion is the problem of filling in missing data into a partially
11 | observed matrix where the measurements we are given have been corrupted by
12 | Gaussian noise. In low-rank matrix completion we have the additional prior
13 | knowledge that the matrix we are completing is low-rank. For simplicity we
14 | shall also assume that the matrix we are reconstructing is symmetric positive
15 | definite. A famous instance of this problem is the `Netflix prize
16 | `__.
17 |
18 | Concretely, we denote by :math:`\hat X \in \mathbf{R}^{n \times n}` the true
19 | matrix corrupted by noise, and denote by :math:`\mathcal{I}` the set of indices
20 | (row and column pairs) from which we receive noisy observations. We shall use
21 | the nuclear norm, denoted :math:`\| \cdot \|_*`, as a convex surrogate for rank,
22 | which we shall trade off against the observations using regularization parameter
23 | :math:`\lambda \geq 0`. The low-rank matrix completion problem is given by
24 |
25 | .. math::
26 |
27 | \begin{array}{ll}
28 | \mbox{minimize} & \frac{1}{2} \sum_{i,j \in \mathcal{I_n}} (X_{ij} - \hat X_{ij})^2 + \lambda \|X \|_* \\
29 | \mbox{subject to} & X \succeq 0
30 | \end{array}
31 |
32 | over variable :math:`X \in \mathbf{R}^{n \times n}` (we use :math:`\cdot \succeq
33 | 0` to indicate membership in the symmetric positive semidefinite cone).
34 |
35 | We can convert this into a more standard form. First, let :math:`x =
36 | \mathrm{vec}(X)` be the semidefinite vectorization of :math:`X` described in
37 | :ref:`cones ` (and concretely implemented in the code that follows).
38 | Further, let :math:`A` be the linear operator that extracts the elements of
39 | :math:`x` for which we have (noisy) observations, and let :math:`b = A
40 | \mathrm{vec}(\hat X)`. Since the nuclear norm of a positive semidefinite matrix
41 | is given by its trace we obtain
42 |
43 | .. math::
44 |
45 | \begin{array}{ll}
46 | \mbox{minimize} & \frac{1}{2} y^T y + \lambda \mathrm{vec}(I_n)^\top x \\
47 | \mbox{subject to} & y = Ax - b \\
48 | & \mathrm{mat}(x) \succeq 0
49 | \end{array}
50 |
51 | over variable :math:`x \in \mathbf{R}^{n(n+1) /2}` and :math:`y \in
52 | \mathbf{R}^{|\mathcal{I}|}`, where :math:`I_n` is the :math:`n \times n`
53 | identity matrix. From this formulation it is straightforward to convert it into
54 | the standard form accepted by SCS. The regularization parameter :math:`\lambda
55 | \geq 0` trades off the rank of the solution and the quality of the fit, and so
56 | we solve the problem for many choices of :math:`\lambda`. Since :math:`\lambda`
57 | enters only in the linear part of the objective function, we can reuse the
58 | matrix factorization and use warm starting to reduce the computation time.
59 |
60 | Python code to solve this is below.
61 |
62 | .. literalinclude:: mat_completion.py
63 | :language: python
64 |
65 | After following the python :ref:`install instructions `, we can
66 | run the code yielding output:
67 |
68 | .. python mat_completion.py > mat_completion.py.out
69 |
70 | .. literalinclude:: mat_completion.py.out
71 | :language: none
72 |
--------------------------------------------------------------------------------
/docs/src/examples/python/mpc.py:
--------------------------------------------------------------------------------
1 | import scs
2 | import numpy as np
3 | import scipy as sp
4 | from scipy import sparse
5 |
6 | np.random.seed(1)
7 |
8 |
9 | class MPC(object):
10 | """Model Predictive Contoller using SCS."""
11 |
12 | def __init__(self, Ad, Bd, Q, R, q, QT, qT, xmin, xmax, umin, umax, T):
13 | # State and action dimension
14 | self.nx, self.nu = Bd.shape
15 |
16 | # Stack variables as follows:
17 | # [x_0, x_1, ..., x_{T-1}, x_T, u_0, u_1, ..., u_{T-1}]
18 |
19 | # Quadratic objective
20 | P = sparse.block_diag(
21 | [sparse.kron(sparse.eye(T), Q), QT, sparse.kron(sparse.eye(T), R)],
22 | format="csc",
23 | )
24 | # Linear objective
25 | c = np.hstack([np.kron(np.ones(T), q), qT, np.zeros(T * self.nu)])
26 | # Linear dynamics
27 | Ax = sparse.kron(sparse.eye(T + 1), -sparse.eye(self.nx)) + sparse.kron(
28 | sparse.eye(T + 1, k=-1), Ad
29 | )
30 | Bu = sparse.kron(
31 | sparse.vstack([sparse.csc_matrix((1, T)), sparse.eye(T)]), Bd
32 | )
33 | Aeq = sparse.hstack([Ax, Bu])
34 |
35 | # Will update this later with initial state
36 | beq = np.zeros((T + 1) * self.nx)
37 |
38 | # Box constraints on state and action
39 | Aineq = sparse.eye((T + 1) * self.nx + T * self.nu)
40 |
41 | box_lower = np.hstack(
42 | [np.kron(np.ones(T + 1), xmin), np.kron(np.ones(T), umin)]
43 | )
44 | box_upper = np.hstack(
45 | [np.kron(np.ones(T + 1), xmax), np.kron(np.ones(T), umax)]
46 | )
47 |
48 | A = sparse.vstack(
49 | [
50 | # zero cone
51 | Aeq,
52 | # Box cone {(t, s) | -t l <= s <= t u }
53 | sparse.csc_matrix((1, (T + 1) * self.nx + T * self.nu)),
54 | -Aineq,
55 | ],
56 | format="csc",
57 | )
58 |
59 | # Box cone add constraint t=1
60 | self.b = np.hstack([beq, 1, np.zeros((T + 1) * self.nx + T * self.nu)])
61 |
62 | data = dict(P=P, A=A, b=self.b, c=c)
63 | cone = dict(z=(T + 1) * self.nx, bu=box_upper, bl=box_lower)
64 | # Create an SCS object
65 | self.solver = scs.SCS(data, cone, eps_abs=1e-5, eps_rel=1e-5)
66 |
67 | def control(self, x0):
68 | # Overwrite b with new initial state
69 | self.b[: self.nx] = -x0
70 | # Update b
71 | self.solver.update(b=self.b)
72 | sol = self.solver.solve() # will warm-start automatically
73 | if sol["info"]["status"] != "solved":
74 | raise ValueError("SCS failed to solve the problem.")
75 |
76 | # Return first action
77 | return sol["x"][-T * self.nu : -(T - 1) * self.nu]
78 |
79 |
80 | # States dimension
81 | nx = 20
82 | # Control dimension
83 | nu = 5
84 |
85 | # State dynamics matrices
86 | Ad = 0.1 * np.random.randn(nx, nx) # State -> State
87 | Bd = np.random.randn(nx, nu) # Control -> State
88 |
89 | # Cost matrices
90 | Q = sparse.eye(nx) # State
91 | QT = 10 * Q # Terminal State
92 | R = 0.1 * sparse.eye(nu) # Control
93 |
94 | # Linear cost vector
95 | q = 0.1 * np.random.randn(nx)
96 | qT = q
97 |
98 | # Initial state
99 | x0 = 10 * np.random.randn(nx)
100 |
101 | # Prediction horizon
102 | T = 30
103 |
104 | # Bounds on state
105 | xmax = np.inf * np.ones(nx)
106 | xmin = -np.inf * np.ones(nx)
107 |
108 | # Bounds on control
109 | umax = np.ones(nu)
110 | umin = -np.ones(nu)
111 |
112 | # Initialize Model Predictive Controller
113 | mpc = MPC(Ad, Bd, Q, R, q, QT, qT, xmin, xmax, umin, umax, T)
114 |
115 | # Simulate in closed loop
116 | nsteps = 10 # Number of steps
117 | for i in range(nsteps):
118 | # Get control action
119 | u = mpc.control(x0)
120 | print(f"Control action: {u}")
121 |
122 | # Apply first control input and update to next state
123 | x0 = Ad @ x0 + Bd @ u + 0.01 * np.random.normal(nx, 1) # + noise
124 | x0 = np.maximum(np.minimum(x0, xmax), xmin) # Bound to xmin, xmax
125 |
--------------------------------------------------------------------------------
/docs/src/examples/python/mpc.rst:
--------------------------------------------------------------------------------
1 | .. _py_mpc:
2 |
3 | Model Predictive Control
4 | ========================
5 |
6 | In this example we shall demonstrate an instance of using the box :ref:`cone
7 | `, as well as reusing a :ref:`cached workspace and using warm-starting
8 | `.
9 |
10 | In model predictive control (MPC) the control action at each time-step is
11 | obtained by solving an optimization problem that simulates the dynamical system
12 | over some time horizon. Here, we consider the problem of controlling a linear,
13 | time-invariant dynamical systems with quadratic stage costs and box constraints
14 | on the state and action:
15 |
16 | .. math::
17 | \begin{array}{ll}
18 | \mbox{minimize} & x_T^T Q_T x_T + q_T^\top x_T + \sum_{t=0}^{T-1}\left( x_t^T Q x_t + u_t^T R u_t + q^\top x_t \right) \\
19 | \mbox{subject to} & x_{t+1} = A x_t + B u_t, \quad t = 0, \ldots T-1\\
20 | & x_{\rm min} \le x_t \le x_{\rm max}, \quad t = 0, \ldots T\\
21 | & u_{\rm min} \le u_t \le u_{\rm max}, \quad t = 0, \ldots T-1\\
22 | & x_0 = \bar{x}
23 | \end{array}
24 |
25 | over variables corresponding to the states :math:`x_t \in \mathbf{R}^{n}`,
26 | :math:`t=0,\ldots,T`, and the inputs :math:`u_t \in \mathbf{R}^{m}`,
27 | :math:`t=0,\ldots,T-1`, where :math:`A \in \mathbf{R}^{n \times n}`, :math:`B
28 | \in \mathbf{R}^{n \times m}` correspond to the linear dynamics and :math:`Q \in
29 | \mathbf{R}^{n \times n}`, :math:`R \in \mathbf{R}^{m \times m}`, :math:`q \in
30 | \mathbf{R}^{n}` correspond to the positive semidefinite quadratic cost functions
31 | with terminal cost defined by :math:`Q_T \in \mathbf{R}^{n \times n}` and
32 | :math:`q_T \in \mathbf{R}^{n}`.
33 |
34 | The problem is solved repeatedly for varying initial state :math:`\bar{x} \in
35 | \mathbf{R}^{n}`. The upper and lower bound constraints can be expressed in
36 | SCS using the box :ref:`cone `.
37 |
38 | Python code to solve this is below.
39 |
40 | .. literalinclude:: mpc.py
41 | :language: python
42 |
43 | After following the python :ref:`install instructions `, we can
44 | run the code yielding output:
45 |
46 | .. python mpc.py > mpc.py.out
47 |
48 | .. literalinclude:: mpc.py.out
49 | :language: none
50 |
--------------------------------------------------------------------------------
/docs/src/examples/python/qp.py:
--------------------------------------------------------------------------------
1 | import scipy
2 | import scs
3 | import numpy as np
4 |
5 | # Set up the problem data
6 | P = scipy.sparse.csc_matrix([[3.0, -1.0], [-1.0, 2.0]])
7 | A = scipy.sparse.csc_matrix([[-1.0, 1.0], [1.0, 0.0], [0.0, 1.0]])
8 | b = np.array([-1, 0.3, -0.5])
9 | c = np.array([-1.0, -1.0])
10 |
11 | # Populate dicts with data to pass into SCS
12 | data = dict(P=P, A=A, b=b, c=c)
13 | cone = dict(z=1, l=2)
14 |
15 | # Initialize solver
16 | solver = scs.SCS(data, cone, eps_abs=1e-9, eps_rel=1e-9)
17 | # Solve!
18 | sol = solver.solve()
19 |
20 | print(f"SCS took {sol['info']['iter']} iters")
21 | print("Optimal solution vector x*:")
22 | print(sol["x"])
23 |
24 | print("Optimal dual vector y*:")
25 | print(sol["y"])
26 |
--------------------------------------------------------------------------------
/docs/src/examples/python/qp.py.out:
--------------------------------------------------------------------------------
1 | ------------------------------------------------------------------
2 | SCS v3.2.0 - Splitting Conic Solver
3 | (c) Brendan O'Donoghue, Stanford University, 2012
4 | ------------------------------------------------------------------
5 | problem: variables n: 2, constraints m: 3
6 | cones: z: primal zero / dual free vars: 1
7 | l: linear vars: 2
8 | settings: eps_abs: 1.0e-09, eps_rel: 1.0e-09, eps_infeas: 1.0e-07
9 | alpha: 1.50, scale: 1.00e-01, adaptive_scale: 1
10 | max_iters: 100000, normalize: 1, rho_x: 1.00e-06
11 | acceleration_lookback: 10, acceleration_interval: 10
12 | lin-sys: sparse-direct
13 | nnz(A): 4, nnz(P): 3
14 | ------------------------------------------------------------------
15 | iter | pri res | dua res | gap | obj | scale | time (s)
16 | ------------------------------------------------------------------
17 | 0| 1.51e+00 1.00e+00 4.91e+00 1.14e+00 1.00e-01 8.39e-05
18 | 75| 4.09e-10 7.93e-10 1.07e-09 1.24e+00 1.00e-01 3.93e-04
19 | ------------------------------------------------------------------
20 | status: solved
21 | timings: total: 5.30e-04s = setup: 1.31e-04s + solve: 3.98e-04s
22 | lin-sys: 1.55e-05s, cones: 4.71e-06s, accel: 2.72e-04s
23 | ------------------------------------------------------------------
24 | objective = 1.235000
25 | ------------------------------------------------------------------
26 | SCS took 75 iters
27 | Optimal solution vector x*:
28 | [ 0.3 -0.7]
29 | Optimal dual vector y*:
30 | [2.7 2.1 0. ]
31 |
--------------------------------------------------------------------------------
/docs/src/examples/qp.c:
--------------------------------------------------------------------------------
1 | #include "scs.h" /* SCS API */
2 | #include /* printf */
3 | #include /* memory allocation */
4 |
5 | /* Set up and solve basic qp */
6 | int main(int argc, char **argv) {
7 | /* Set up the problem data */
8 | /* A and P must be in compressed sparse column format */
9 | double P_x[3] = {3., -1., 2.}; /* Upper triangular of P only */
10 | int P_i[3] = {0, 0, 1};
11 | int P_p[3] = {0, 1, 3};
12 | double A_x[4] = {-1., 1., 1., 1.};
13 | int A_i[4] = {0, 1, 0, 2};
14 | int A_p[3] = {0, 2, 4};
15 | double b[3] = {-1., 0.3, -0.5};
16 | double c[2] = {-1., -1.};
17 | /* data shapes */
18 | int n = 2; /* number of variables */
19 | int m = 3; /* number of constraints */
20 |
21 | /* Allocate SCS structs */
22 | ScsCone *k = (ScsCone *)calloc(1, sizeof(ScsCone));
23 | ScsData *d = (ScsData *)calloc(1, sizeof(ScsData));
24 | ScsSettings *stgs = (ScsSettings *)calloc(1, sizeof(ScsSettings));
25 | ScsSolution *sol = (ScsSolution *)calloc(1, sizeof(ScsSolution));
26 | ScsInfo *info = (ScsInfo *)calloc(1, sizeof(ScsInfo));
27 |
28 | /* Fill in data struct */
29 | d->m = m;
30 | d->n = n;
31 | d->b = b;
32 | d->c = c;
33 | d->A = &(ScsMatrix){A_x, A_i, A_p, m, n};
34 | d->P = &(ScsMatrix){P_x, P_i, P_p, n, n};
35 |
36 | /* Cone */
37 | k->z = 1;
38 | k->l = 2;
39 |
40 | /* Utility to set default settings */
41 | scs_set_default_settings(stgs);
42 |
43 | /* Modify tolerances */
44 | stgs->eps_abs = 1e-9;
45 | stgs->eps_rel = 1e-9;
46 |
47 | /* Initialize SCS workspace */
48 | ScsWork *scs_work = scs_init(d, k, stgs);
49 |
50 | /* Solve! */
51 | int exitflag = scs_solve(scs_work, sol, info, 0);
52 |
53 | /*
54 | * If we wanted to solve many related problems with different
55 | * b / c vectors we could update the SCS workspace as follows:
56 | *
57 | * int success = scs_update(scs_work, new_b, new_c)
58 | * int new_exitflag = scs_solve(scs_work, sol, info, 1);
59 | *
60 | */
61 |
62 | /* Free SCS workspace */
63 | scs_finish(scs_work);
64 |
65 | /* Verify that SCS solved the problem */
66 | printf("SCS solved successfully: %i\n", exitflag == SCS_SOLVED);
67 |
68 | /* Print some info about the solve */
69 | printf("SCS took %i iters, using the %s linear solver.\n", info->iter,
70 | info->lin_sys_solver);
71 |
72 | /* Print solution x */
73 | printf("Optimal solution vector x*:\n");
74 | for (int i = 0; i < n; ++i) {
75 | printf("x[%i] = %4f\n", i, sol->x[i]);
76 | }
77 |
78 | /* Print dual solution y */
79 | printf("Optimal dual vector y*:\n");
80 | for (int i = 0; i < m; ++i) {
81 | printf("y[%i] = %4f\n", i, sol->y[i]);
82 | }
83 |
84 | /* Free allocated memory */
85 | free(k);
86 | free(d);
87 | free(stgs);
88 | free(info);
89 | /* SCS allocates sol->x,y,s if NULL on entry, need to be freed */
90 | free(sol->x);
91 | free(sol->y);
92 | free(sol->s);
93 | free(sol);
94 | return 0; /* returning exitflag will set bash exit code to 1 */
95 | }
96 |
--------------------------------------------------------------------------------
/docs/src/examples/qp.c.out:
--------------------------------------------------------------------------------
1 | ------------------------------------------------------------------
2 | SCS v3.2.1 - Splitting Conic Solver
3 | (c) Brendan O'Donoghue, Stanford University, 2012
4 | ------------------------------------------------------------------
5 | problem: variables n: 2, constraints m: 3
6 | cones: z: primal zero / dual free vars: 1
7 | l: linear vars: 2
8 | settings: eps_abs: 1.0e-09, eps_rel: 1.0e-09, eps_infeas: 1.0e-07
9 | alpha: 1.50, scale: 1.00e-01, adaptive_scale: 1
10 | max_iters: 100000, normalize: 1, rho_x: 1.00e-06
11 | acceleration_lookback: 10, acceleration_interval: 10
12 | lin-sys: sparse-direct-amd-qdldl
13 | nnz(A): 4, nnz(P): 3
14 | ------------------------------------------------------------------
15 | iter | pri res | dua res | gap | obj | scale | time (s)
16 | ------------------------------------------------------------------
17 | 0| 1.51e+00 1.00e+00 4.91e+00 1.14e+00 1.00e-01 1.19e-04
18 | 75| 4.09e-10 7.93e-10 1.07e-09 1.24e+00 1.00e-01 2.10e-04
19 | ------------------------------------------------------------------
20 | status: solved
21 | timings: total: 2.11e-04s = setup: 9.88e-05s + solve: 1.13e-04s
22 | lin-sys: 1.48e-05s, cones: 3.92e-06s, accel: 5.06e-05s
23 | ------------------------------------------------------------------
24 | objective = 1.235000
25 | ------------------------------------------------------------------
26 | SCS solved successfully: 1
27 | SCS took 75 iters, using the sparse-direct-amd-qdldl linear solver.
28 | Optimal solution vector x*:
29 | x[0] = 0.300000
30 | x[1] = -0.700000
31 | Optimal dual vector y*:
32 | y[0] = 2.700000
33 | y[1] = 2.100000
34 | y[2] = 0.000000
35 |
--------------------------------------------------------------------------------
/docs/src/examples/qp.m:
--------------------------------------------------------------------------------
1 | % First, make sure SCS is in the path so MATLAB can call it
2 | addpath("/Users/bodonoghue/git/scs-matlab")
3 |
4 | % Set up data
5 | data.P = sparse([3., -1.; -1., 2.]);
6 | data.A = sparse([-1., 1.; 1., 0.; 0., 1.]);
7 | data.b = [-1; 0.3; -0.5];
8 | data.c = [-1.; -1.];
9 | cone.z = 1;
10 | cone.l = 2;
11 |
12 | % Optional solver settings
13 | settings = struct('eps_abs', 1e-9, 'eps_rel', 1e-9);
14 |
15 | % Solve!
16 | [x, y, s, info] = scs(data, cone, settings);
17 |
18 | disp(sprintf("SCS took %i iters", info.iter))
19 | disp("Optimal solution vector x*:");
20 | disp(x)
21 | disp("Optimal dual vector y*:");
22 | disp(y)
23 |
--------------------------------------------------------------------------------
/docs/src/examples/qp.m.out:
--------------------------------------------------------------------------------
1 | < M A T L A B (R) >
2 | Copyright 1984-2021 The MathWorks, Inc.
3 | R2021a Update 3 (9.10.0.1684407) 64-bit (maci64)
4 | May 27, 2021
5 |
6 |
7 | For online documentation, see https://www.mathworks.com/support
8 | For product information, visit www.mathworks.com.
9 |
10 | ------------------------------------------------------------------
11 | SCS v3.0.0 - Splitting Conic Solver
12 | (c) Brendan O'Donoghue, Stanford University, 2012
13 | ------------------------------------------------------------------
14 | problem: variables n: 2, constraints m: 3
15 | cones: z: primal zero / dual free vars: 1
16 | l: linear vars: 2
17 | settings: eps_abs: 1.0e-09, eps_rel: 1.0e-09, eps_infeas: 1.0e-07
18 | alpha: 1.50, scale: 1.00e-01, adaptive_scale: 1
19 | max_iters: 100000, normalize: 1, warm_start: 0
20 | acceleration_lookback: 10, acceleration_interval: 10
21 | lin-sys: sparse-direct
22 | nnz(A): 4, nnz(P): 3
23 | ------------------------------------------------------------------
24 | iter | pri res | dua res | gap | obj | scale | time (s)
25 | ------------------------------------------------------------------
26 | 0| 1.53e+00 1.00e+00 4.87e+00 1.10e+00 1.00e-01 1.53e-04
27 | 100| 6.18e-11 1.56e-12 1.30e-10 1.23e+00 1.00e-01 3.37e-04
28 | ------------------------------------------------------------------
29 | status: solved
30 | timings: total: 5.26e-03s = setup: 4.89e-03s + solve: 3.74e-04s
31 | lin-sys: 1.96e-05s, cones: 7.60e-06s, accel: 9.94e-05s
32 | ------------------------------------------------------------------
33 | objective = 1.235000
34 | ------------------------------------------------------------------
35 | SCS took 100 iters
36 | Optimal solution vector x*:
37 | 0.3000
38 | -0.7000
39 |
40 | Optimal dual vector y*:
41 | 2.7000
42 | 2.1000
43 | 0
44 |
45 |
--------------------------------------------------------------------------------
/docs/src/examples/qp.prob:
--------------------------------------------------------------------------------
1 |
2 | In this example we shall solve the following small quadratic program:
3 |
4 | .. math::
5 | \begin{array}{ll}
6 | \mbox{minimize} & (1/2) x^T \begin{bmatrix}3 & -1\\ -1 & 2 \end{bmatrix}
7 | x + \begin{bmatrix}-1 \\ -1\end{bmatrix}^T x \\
8 | \mbox{subject to} & \begin{bmatrix} -1 \\ 1 \end{bmatrix}^T x = -1 \\
9 | & \begin{bmatrix} 1 & 0\\ 0 & 1\end{bmatrix} x \leq \begin{bmatrix}0.3 \\ -0.5\end{bmatrix}
10 | \end{array}
11 |
12 | over variable :math:`x \in \mathbf{R}^2`. This problem corresponds to data:
13 |
14 | .. math::
15 | \begin{array}{cccc}
16 | P = \begin{bmatrix}3 & -1\\ -1 & 2 \end{bmatrix}, &
17 | A = \begin{bmatrix}-1 & 1\\ 1 & 0\\ 0 & 1\end{bmatrix}, &
18 | b = \begin{bmatrix}-1 \\ 0.3 \\ -0.5\end{bmatrix}, &
19 | c = \begin{bmatrix}-1 \\ -1\end{bmatrix}.
20 | \end{array}
21 |
22 | And the cone :math:`\mathcal{K}` consists of a zero cone (:code:`z`) of length 1
23 | and a positive cone (:code:`l`) of dimension 2. Note that the order of the
24 | rows in :math:`A` and :math:`b` corresponds to the order in :ref:`cones`, so
25 | the row corresponding to the zero cone comes first, followed by the rows for the
26 | positive cone.
27 |
--------------------------------------------------------------------------------
/docs/src/examples/r.rst:
--------------------------------------------------------------------------------
1 | .. _r_example:
2 |
3 | R
4 | =
5 |
6 | .. code:: r
7 |
8 | library("scs")
9 |
10 |
11 | Second-order cone programming
12 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
13 |
14 | .. math::
15 | \begin{array}{rr}
16 | \underset{x}{\text{maximize}}
17 | & x + y \\
18 | \text{subject to}
19 | & \sqrt{x^2 + y^2} \leq \sqrt{2} \\
20 | & x, y \geq 0
21 | \end{array}
22 |
23 |
24 | .. code:: r
25 |
26 | obj <- c(-1, -1)
27 | A <- rbind(c(-1, 0), # x >= 0
28 | c( 0, -1), # y >= 0
29 | c( 0, 0),
30 | c(-1, 0),
31 | c( 0, -1))
32 | b <- c(0, 0, sqrt(2), 0, 0)
33 | cone <- list(z = 0, l = 2, q = 3)
34 |
35 | solution <- scs(A, b, obj, cone = cone)
36 | str(solution)
37 | #R> List of 4
38 | #R> $ x : num [1:2] 1 1
39 | #R> $ y : num [1:5] 0 0 1.41 -1 -1
40 | #R> $ s : num [1:5] 1 1 1.41 1 1
41 | #R> $ info:List of 21
42 | #R> ..$ iter : int 50
43 | #R> ..$ status : chr "solved"
44 | #R> ..$ status_val : int 1
45 | #R> ..$ scale_updates : int 0
46 | #R> ..$ pobj : num -2
47 | #R> ..$ dobj : num -2
48 | #R> ..$ res_pri : num 4.86e-05
49 | #R> ..$ res_dual : num 1.98e-06
50 | #R> ..$ gap : num 0.000141
51 | #R> ..$ res_infeas : num NaN
52 | #R> ..$ res_unbdd_a : num 0.707
53 | #R> ..$ res_unbdd_p : num 0
54 | #R> ..$ setup_time : num 0.0236
55 | #R> ..$ solve_time : num 0.0237
56 | #R> ..$ scale : num 0.1
57 | #R> ..$ comp_slack : num 1.34e-14
58 | #R> ..$ rejected_accel_steps: int 0
59 | #R> ..$ accepted_accel_steps: int 0
60 | #R> ..$ lin_sys_time : num 0.00668
61 | #R> ..$ cone_time : num 0.00439
62 | #R> ..$ accel_time : num 0
63 |
64 |
65 |
66 | Primal exponential cone
67 | ^^^^^^^^^^^^^^^^^^^^^^^
68 |
69 | .. math::
70 | \begin{array}{rr}
71 | \underset{x}{\text{maximize}} & x + y + z \\
72 | \text{subject to} & y e^{\frac{x}{y}} \leq z \\
73 | & x \geq 0, y > 0, z \in [0, e]
74 | \end{array}
75 |
76 |
77 | .. code:: r
78 |
79 | obj <- c(-1, -1, -1)
80 | A <- rbind(-diag(3), # x, z >= 0, y >= 1e-12
81 | c(0, 0, 1), # z <= e
82 | -diag(3)) # K_exp
83 | b <- c(0, -1e-12, 0, exp(1), double(3))
84 | cone <- list(z = 0L, l = 4L, ep = 1L)
85 | solution <- scs(A, b, obj, cone = cone)
86 | str(solution)
87 | #R> List of 4
88 | #R> $ x : num [1:3] 8.46e-05 2.72 2.72
89 | #R> $ y : num [1:7] 1.17e-05 0.00 0.00 2.00 -1.00 ...
90 | #R> $ s : num [1:7] 0.00 2.72 2.72 0.00 5.68e-05 ...
91 | #R> $ info:List of 21
92 | #R> ..$ iter : int 75
93 | #R> ..$ status : chr "solved"
94 | #R> ..$ status_val : int 1
95 | #R> ..$ scale_updates : int 0
96 | #R> ..$ pobj : num -5.44
97 | #R> ..$ dobj : num -5.44
98 | #R> ..$ res_pri : num 0.000273
99 | #R> ..$ res_dual : num 2.02e-05
100 | #R> ..$ gap : num 0.000583
101 | #R> ..$ res_infeas : num NaN
102 | #R> ..$ res_unbdd_a : num 0.5
103 | #R> ..$ res_unbdd_p : num 0
104 | #R> ..$ setup_time : num 0.0273
105 | #R> ..$ solve_time : num 0.273
106 | #R> ..$ scale : num 0.1
107 | #R> ..$ comp_slack : num 8.54e-09
108 | #R> ..$ rejected_accel_steps: int 0
109 | #R> ..$ accepted_accel_steps: int 0
110 | #R> ..$ lin_sys_time : num 0.0118
111 | #R> ..$ cone_time : num 0.242
112 | #R> ..$ accel_time : num 0
113 |
--------------------------------------------------------------------------------
/docs/src/examples/ruby.rst:
--------------------------------------------------------------------------------
1 | .. _ruby_example:
2 |
3 | Ruby
4 | ====
5 |
6 | See examples `here `_.
7 |
8 |
--------------------------------------------------------------------------------
/docs/src/files/qp_solvers_benchmark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cvxgrp/scs/8a739589e66f745d049fc838f55775d3e07f669b/docs/src/files/qp_solvers_benchmark.png
--------------------------------------------------------------------------------
/docs/src/files/windows1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cvxgrp/scs/8a739589e66f745d049fc838f55775d3e07f669b/docs/src/files/windows1.png
--------------------------------------------------------------------------------
/docs/src/files/windows2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cvxgrp/scs/8a739589e66f745d049fc838f55775d3e07f669b/docs/src/files/windows2.png
--------------------------------------------------------------------------------
/docs/src/files/windows3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cvxgrp/scs/8a739589e66f745d049fc838f55775d3e07f669b/docs/src/files/windows3.png
--------------------------------------------------------------------------------
/docs/src/help/index.rst:
--------------------------------------------------------------------------------
1 | .. _help:
2 |
3 | Help
4 | ====
5 |
6 | Currently the easiest way to get support is to file a `GitHub issue
7 | `_ or to `email us
8 | `_ (which may be slower).
9 |
10 | If you are have a problem that SCS struggles to solve you can set the
11 | :code:`write_data_filename` field in the :ref:`settings ` and SCS will
12 | dump a file containing the problem data to disk under that filename. Zip the
13 | file and `email it to us `_ or attach
14 | it to a GitHub issue. This makes it much easier for us to reproduce the problem.
15 |
16 | A common cause of issues is not linking :ref:`BLAS/LAPACK libraries
17 | ` correctly. If you are having this issue please search for
18 | resources on installing and linking these libraries first. You can try `OpenBLAS
19 | `_ if you need a BLAS library.
20 |
21 |
--------------------------------------------------------------------------------
/docs/src/install/index.rst:
--------------------------------------------------------------------------------
1 | .. _install:
2 |
3 | Install
4 | =======
5 |
6 | Follow the links below for install instructions for each language.
7 |
8 | :ref:`C/C++ `
9 |
10 | :ref:`Python `
11 |
12 | :ref:`MATLAB `
13 |
14 | :ref:`Julia `
15 |
16 | :ref:`R `
17 |
18 | :ref:`Ruby `
19 |
20 | :ref:`JavaScript / WebAssembly `
21 |
22 | .. toctree::
23 | :maxdepth: 2
24 | :hidden:
25 |
26 | c.rst
27 | python.rst
28 | matlab.rst
29 | julia.rst
30 | r.rst
31 | ruby.rst
32 | javascript.rst
33 |
--------------------------------------------------------------------------------
/docs/src/install/javascript.rst:
--------------------------------------------------------------------------------
1 | .. _javascript_install:
2 |
3 | JavaScript / WebAssembly
4 | ========================
5 |
6 | SCS is available in `a WebAssembly version
7 | `_ that can be used with JavaScript.
8 | Note that the JavaScript version does not support compiling with BLAS
9 | and LAPACK, so it does not support solving SDPs.
10 |
11 | For building the WebAssembly version from source, see the `scs.wasm
12 | `_ repository.
13 |
14 | The page on the :ref:`JS interface ` provides more
15 | information on how to use SCS in JavaScript environments once loaded or installed.
16 |
17 | Install with npm
18 | ----------------
19 |
20 | The package can be installed using `npm `_:
21 |
22 | .. code:: bash
23 |
24 | npm install scs-solver
25 |
26 | It can be used in Node.js and in the browser.
27 |
28 | Loading from a CDN in the browser
29 | ---------------------------------
30 |
31 | The package can also directly be included in a webpage using a CDN, by
32 | using one of the following script tags:
33 |
34 | .. code:: html
35 |
36 |
37 |
38 |
39 | It can also be imported in JavaScript code using ES6 modules:
40 |
41 | .. code:: html
42 |
43 |
47 |
48 | You can also host the files yourself, by `downloading the files
49 | `_, and putting ``scs.js`` (or
50 | ``scs.mjs``) and ``scs.wasm`` in the same directory.
--------------------------------------------------------------------------------
/docs/src/install/julia.rst:
--------------------------------------------------------------------------------
1 | .. _julia_install:
2 |
3 | Julia
4 | =====
5 |
6 | Install SCS via the Julia package manager:
7 |
8 | .. code:: julia
9 |
10 | import Pkg
11 | Pkg.add("SCS")
12 |
13 | This will install the `SCS.jl `_
14 | package, along with the necessary SCS binary for your system.
15 |
16 | For instructions on how to use a custom version of SCS, consult the
17 | `SCS.jl README `_.
18 |
19 | Note that SCS.jl is a third-party package maintained by the
20 | `JuMP-dev community `_.
21 |
--------------------------------------------------------------------------------
/docs/src/install/matlab.rst:
--------------------------------------------------------------------------------
1 | .. _matlab_install:
2 |
3 | MATLAB
4 | ======
5 |
6 | To install SCS in Matlab from source:
7 |
8 | .. code:: bash
9 |
10 | git clone --recursive https://github.com/bodono/scs-matlab.git
11 |
12 | Then in a Matlab session
13 |
14 | .. code:: matlab
15 |
16 | cd
17 | make_scs
18 |
19 | Remember to include the scs-matlab directory in your Matlab path if you wish to
20 | use the mex file in your Matlab code.
21 |
22 | .. code:: matlab
23 |
24 | addpath(pwd)
25 | savepath
26 |
27 | See :ref:`here ` for the API.
28 |
29 |
--------------------------------------------------------------------------------
/docs/src/install/python.rst:
--------------------------------------------------------------------------------
1 | .. _python_install:
2 |
3 | Python
4 | ======
5 |
6 | The easiest way to install the python version is using `pip `_:
7 |
8 | .. code:: bash
9 |
10 | pip install scs
11 |
12 | You can also install directly from source
13 |
14 | .. code:: bash
15 |
16 | git clone --recursive https://github.com/bodono/scs-python.git
17 | cd scs-python
18 | python -m pip install --verbose .
19 |
20 | If you have MKL, you can install the MKL Pardiso interface using
21 |
22 | .. code:: bash
23 |
24 | python -m pip install --verbose -Csetup-args=-Dlink_mkl=true .
25 |
26 | See :ref:`here ` for how to enable MKL when solving. MKL is typically
27 | faster than the built-in linear system solver.
28 |
29 | To test that SCS installed correctly, and you have pytest installed, run
30 |
31 | .. code:: bash
32 |
33 | python -m pytest .
34 |
35 | See :ref:`here ` for the full SCS python API.
36 |
37 | Legacy options
38 | --------------
39 |
40 | You can install with OpenMP parallelization support using
41 |
42 | .. code:: bash
43 |
44 | python legacy_setup.py install --scs --openmp
45 |
46 | You can install the GPU interface using (the GPU solver is no longer recommended)
47 |
48 | .. code:: bash
49 |
50 | python legacy_setup.py install --scs --gpu
51 |
52 |
--------------------------------------------------------------------------------
/docs/src/install/r.rst:
--------------------------------------------------------------------------------
1 | .. _r_install:
2 |
3 | R
4 | =
5 |
6 | Since the **R** interface is available on **CRAN**, the package can
7 | be installed by running the following code in **R**.
8 |
9 | .. code:: r
10 |
11 | install.packages("scs")
12 |
--------------------------------------------------------------------------------
/docs/src/install/ruby.rst:
--------------------------------------------------------------------------------
1 | .. _ruby_install:
2 |
3 | Ruby
4 | ====
5 |
6 | See instructions `here `_.
7 |
8 |
--------------------------------------------------------------------------------
/docs/src/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=.
11 | set BUILDDIR=_build
12 |
13 | if "%1" == "" goto help
14 |
15 | %SPHINXBUILD% >NUL 2>NUL
16 | if errorlevel 9009 (
17 | echo.
18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
19 | echo.installed, then set the SPHINXBUILD environment variable to point
20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
21 | echo.may add the Sphinx directory to PATH.
22 | echo.
23 | echo.If you don't have Sphinx installed, grab it from
24 | echo.http://sphinx-doc.org/
25 | exit /b 1
26 | )
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/docs/src/requirements.txt:
--------------------------------------------------------------------------------
1 | sphinx
2 | sphinx-rtd-theme
3 | alabaster
4 | breathe
5 |
--------------------------------------------------------------------------------
/include/aa.h:
--------------------------------------------------------------------------------
1 | #ifndef AA_H_GUARD
2 | #define AA_H_GUARD
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 |
8 | #include "glbopts.h"
9 | #include
10 | #include
11 | #include
12 |
13 | typedef scs_float aa_float;
14 | typedef scs_int aa_int;
15 |
16 | typedef struct ACCEL_WORK AaWork;
17 |
18 | /**
19 | * Initialize Anderson Acceleration, allocates memory.
20 | *
21 | * @param dim the dimension of the variable for AA
22 | * @param mem the memory (number of past iterations used) for AA
23 | * @param type1 if True use type 1 AA, otherwise use type 2
24 | * @param regularization type-I and type-II different, for type-I: 1e-8 works
25 | * well, type-II: more stable can use 1e-12 often
26 | * @param relaxation float in [0,2], mixing parameter (1.0 is vanilla)
27 | * @param safeguard_factor factor that controls safeguarding checks
28 | * larger is more aggressive but less stable
29 | * @param max_weight_norm float, maximum norm of AA weights
30 | * @param verbosity if greater than 0 prints out various info
31 | *
32 | * @return pointer to AA workspace
33 | *
34 | */
35 | AaWork *aa_init(aa_int dim, aa_int mem, aa_int type1, aa_float regularization,
36 | aa_float relaxation, aa_float safeguard_factor,
37 | aa_float max_weight_norm, aa_int verbosity);
38 | /**
39 | * Apply Anderson Acceleration. The usage pattern should be as follows:
40 | *
41 | * - for i = 0 .. N:
42 | * - if (i > 0): aa_apply(x, x_prev, a)
43 | * - x_prev = x.copy()
44 | * - x = F(x)
45 | * - aa_safeguard(x, x_prev, a) // optional but helps stability
46 | *
47 | * Here F is the map we are trying to find the fixed point for. We put the AA
48 | * before the map so that any properties of the map are maintained at the end.
49 | * Eg if the map contains a projection onto a set then the output is guaranteed
50 | * to be in the set.
51 | *
52 | *
53 | * @param f output of map at current iteration, overwritten with AA output
54 | * @param x input to map at current iteration
55 | * @param a workspace from aa_init
56 | *
57 | * @return (+ or -) norm of AA weights vector. If positive then update
58 | * was accepted and f contains new point, if negative then update was
59 | * rejected and f is unchanged
60 | *
61 | */
62 | aa_float aa_apply(aa_float *f, const aa_float *x, AaWork *a);
63 |
64 | /**
65 | * Apply safeguarding.
66 | *
67 | * This step is optional but can improve stability.
68 | *
69 | * @param f_new output of map after AA step
70 | * @param x_new AA output that is input to the map
71 | * @param a workspace from aa_init
72 | *
73 | * @returns 0 if AA step is accepted otherwise -1, if AA step is rejected then
74 | * this overwrites f_new and x_new with previous values
75 | *
76 | */
77 | aa_int aa_safeguard(aa_float *f_new, aa_float *x_new, AaWork *a);
78 |
79 | /**
80 | * Finish Anderson Acceleration, clears memory.
81 | *
82 | * @param a AA workspace from aa_init
83 | *
84 | */
85 | void aa_finish(AaWork *a);
86 |
87 | /**
88 | * Reset Anderson Acceleration.
89 | *
90 | * Resets AA as if at the first iteration, reuses original memory allocations.
91 | *
92 | * @param a AA workspace from aa_init
93 | *
94 | */
95 | void aa_reset(AaWork *a);
96 |
97 | #ifdef __cplusplus
98 | }
99 | #endif
100 | #endif
101 |
--------------------------------------------------------------------------------
/include/cones.h:
--------------------------------------------------------------------------------
1 | #ifndef CONES_H_GUARD
2 | #define CONES_H_GUARD
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 |
8 | #include "glbopts.h"
9 | #include "scs.h"
10 | #include "scs_blas.h"
11 | #include "scs_work.h"
12 | #include
13 |
14 | /* private data to help cone projection step */
15 | struct SCS_CONE_WORK {
16 | /*
17 | * cone_boundaries will contain array of indices of rows of A corresponding to
18 | * cone boundaries, boundaries[0] is starting index for cones of size larger
19 | * than 1
20 | */
21 | ScsCone *k; /* original cone information */
22 | scs_int *cone_boundaries;
23 | scs_int cone_boundaries_len;
24 | scs_int scaled_cones; /* boolean, whether the cones have been scaled */
25 | scs_float *s; /* used for Moreau decomposition in projection */
26 | scs_int m; /* total length of cone */
27 | /* box cone quantities */
28 | scs_float box_t_warm_start;
29 | #ifdef USE_LAPACK
30 | /* workspace for eigenvector decompositions: */
31 | scs_float *Xs, *Z, *e, *work;
32 | blas_int lwork;
33 | #endif
34 | };
35 |
36 | void SCS(free_cone)(ScsCone *k);
37 | void SCS(deep_copy_cone)(ScsCone *dest, const ScsCone *src);
38 | ScsConeWork *SCS(init_cone)(ScsCone *k, scs_int m);
39 | char *SCS(get_cone_header)(const ScsCone *k);
40 | scs_int SCS(validate_cones)(const ScsData *d, const ScsCone *k);
41 | scs_int SCS(proj_dual_cone)(scs_float *x, ScsConeWork *c, ScsScaling *scal,
42 | scs_float *r_y);
43 | void SCS(finish_cone)(ScsConeWork *c);
44 | void SCS(set_r_y)(const ScsConeWork *c, scs_float scale, scs_float *r_y);
45 | void SCS(enforce_cone_boundaries)(const ScsConeWork *c, scs_float *vec,
46 | scs_float (*f)(const scs_float *, scs_int));
47 |
48 | #ifdef __cplusplus
49 | }
50 | #endif
51 | #endif
52 |
--------------------------------------------------------------------------------
/include/ctrlc.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Interface for SCS signal handling.
3 | */
4 |
5 | #ifndef CTRLC_H_GUARD
6 | #define CTRLC_H_GUARD
7 |
8 | #ifdef __cplusplus
9 | extern "C" {
10 | #endif
11 |
12 | #if CTRLC > 0
13 |
14 | void scs_start_interrupt_listener(void);
15 | void scs_end_interrupt_listener(void);
16 | int scs_is_interrupted(void);
17 |
18 | #else /* CTRLC = 0 */
19 |
20 | /* Simply to suppress empty translation unit warnings. */
21 | typedef int scs_make_iso_compilers_happy;
22 |
23 | /* No signal handling. */
24 | #define scs_start_interrupt_listener()
25 | #define scs_end_interrupt_listener()
26 | #define scs_is_interrupted() 0
27 |
28 | #endif /* END IF CTRLC > 0 */
29 |
30 | #ifdef __cplusplus
31 | }
32 | #endif
33 | #endif
34 |
--------------------------------------------------------------------------------
/include/linalg.h:
--------------------------------------------------------------------------------
1 | #ifndef LINALG_H_GUARD
2 | #define LINALG_H_GUARD
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 |
8 | #include "glbopts.h"
9 | #include
10 |
11 | void SCS(scale_array)(scs_float *a, const scs_float b, scs_int len);
12 | scs_float SCS(dot)(const scs_float *x, const scs_float *y, scs_int len);
13 | scs_float SCS(norm_sq)(const scs_float *v, scs_int len);
14 | scs_float SCS(norm_2)(const scs_float *v, scs_int len);
15 | scs_float SCS(norm_inf)(const scs_float *a, scs_int l);
16 | void SCS(add_scaled_array)(scs_float *a, const scs_float *b, scs_int n,
17 | const scs_float sc);
18 | scs_float SCS(norm_diff)(const scs_float *a, const scs_float *b, scs_int l);
19 | scs_float SCS(norm_inf_diff)(const scs_float *a, const scs_float *b, scs_int l);
20 | scs_float SCS(mean)(const scs_float *x, scs_int l);
21 |
22 | #ifdef __cplusplus
23 | }
24 | #endif
25 | #endif
26 |
--------------------------------------------------------------------------------
/include/linsys.h:
--------------------------------------------------------------------------------
1 | #ifndef LINSYS_H_GUARD
2 | #define LINSYS_H_GUARD
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 |
8 | #include "glbopts.h"
9 | #include "scs.h"
10 |
11 | /* This is the API that any new linear system solver must implement */
12 |
13 | /* Struct containing linear system workspace. Implemented by linear solver. */
14 | /* This typedef is in scs.h */
15 | /* typedef struct SCS_LIN_SYS_WORK ScsLinSysWork; */
16 |
17 | /**
18 | * Initialize `ScsLinSysWork` structure and perform any necessary preprocessing.
19 | *
20 | * @param A `A` data matrix, `m x n`.
21 | * @param P `P` data matrix, `n x n`.
22 | * @param diag_r `R > 0` diagonal entries of length `m + n`.
23 | * @return Linear system solver workspace.
24 | *
25 | */
26 | ScsLinSysWork *scs_init_lin_sys_work(const ScsMatrix *A, const ScsMatrix *P,
27 | const scs_float *diag_r);
28 |
29 | /**
30 | * Frees `ScsLinSysWork` structure and associated allocated memory.
31 | *
32 | * @param w Linear system private workspace.
33 | */
34 | void scs_free_lin_sys_work(ScsLinSysWork *w);
35 |
36 | /**
37 | * Solves the linear system as required by SCS at each iteration:
38 | * \f[
39 | * \begin{bmatrix}
40 | * (R_x + P) & A^\top \\
41 | * A & -R_y \\
42 | * \end{bmatrix} x = b
43 | * \f]
44 | *
45 | * for `x`, where `diag(R_x, R_y) = R`. Overwrites `b` with result.
46 | *
47 | * @param w Linear system private workspace.
48 | * @param b Right hand side, contains solution at the end.
49 | * @param s Contains warm-start (may be NULL).
50 | * @param tol Tolerance required for the system solve.
51 | * @return status != 0 indicates failure.
52 | *
53 | */
54 | scs_int scs_solve_lin_sys(ScsLinSysWork *w, scs_float *b, const scs_float *s,
55 | scs_float tol);
56 | /**
57 | * Update the linsys workspace when `R` is changed. For example, a
58 | * direct method for solving the linear system might need to update the
59 | * factorization of the matrix.
60 | *
61 | * @param w Linear system private workspace.
62 | * @param new_diag_r Updated `diag_r`, diagonal entries of R.
63 | *
64 | */
65 | void scs_update_lin_sys_diag_r(ScsLinSysWork *w, const scs_float *new_diag_r);
66 |
67 | /**
68 | * Name of the linear solver.
69 | *
70 | * @return name of method.
71 | */
72 | const char *scs_get_lin_sys_method(void);
73 |
74 | #ifdef __cplusplus
75 | }
76 | #endif
77 |
78 | #endif
79 |
--------------------------------------------------------------------------------
/include/normalize.h:
--------------------------------------------------------------------------------
1 | #ifndef NORMALIZE_H_GUARD
2 | #define NORMALIZE_H_GUARD
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 |
8 | #include "glbopts.h"
9 | #include "scs_work.h"
10 |
11 | void SCS(normalize_b_c)(ScsScaling *scal, scs_float *b, scs_float *c);
12 | void SCS(normalize_sol)(ScsScaling *scal, ScsSolution *sol);
13 | void SCS(un_normalize_sol)(ScsScaling *scal, ScsSolution *sol);
14 | void SCS(un_normalize_primal)(ScsScaling *scal, scs_float *r);
15 | void SCS(un_normalize_dual)(ScsScaling *scal, scs_float *r);
16 |
17 | #ifdef __cplusplus
18 | }
19 | #endif
20 | #endif
21 |
--------------------------------------------------------------------------------
/include/rw.h:
--------------------------------------------------------------------------------
1 | #ifndef RW_H_GUARD
2 | #define RW_H_GUARD
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 |
8 | #include "glbopts.h"
9 | #include "scs.h"
10 | #include "util.h"
11 |
12 | void SCS(write_data)(const ScsData *d, const ScsCone *k,
13 | const ScsSettings *stgs);
14 | scs_int SCS(read_data)(const char *filename, ScsData **d, ScsCone **k,
15 | ScsSettings **stgs);
16 | void SCS(log_data_to_csv)(const ScsCone *k, const ScsSettings *stgs,
17 | const ScsWork *w, scs_int iter,
18 | SCS(timer) * solve_timer);
19 |
20 | #ifdef __cplusplus
21 | }
22 | #endif
23 | #endif
24 |
--------------------------------------------------------------------------------
/include/scs_blas.h:
--------------------------------------------------------------------------------
1 | #ifndef SCS_BLAS_H_GUARD
2 | #define SCS_BLAS_H_GUARD
3 |
4 | #ifdef USE_LAPACK
5 |
6 | #ifdef __cplusplus
7 | extern "C" {
8 | #endif
9 |
10 | /* Default to underscore for blas / lapack */
11 | #ifndef BLASSUFFIX
12 | #define BLASSUFFIX _
13 | #endif
14 |
15 | /* annoying hack because some preprocessors can't handle empty macros */
16 | #if defined(NOBLASSUFFIX) && NOBLASSUFFIX > 0
17 | /* single or double precision */
18 | #ifndef SFLOAT
19 | #define BLAS(x) d##x
20 | #define BLASI(x) id##x
21 | #else
22 | #define BLAS(x) s##x
23 | #define BLASI(x) is##x
24 | #endif
25 | #else
26 | /* this extra indirection is needed for BLASSUFFIX to work correctly as a
27 | * variable */
28 | #define stitch_(pre, x, post) pre##x##post
29 | #define stitch__(pre, x, post) stitch_(pre, x, post)
30 | /* single or double precision */
31 | #ifndef SFLOAT
32 | #define BLAS(x) stitch__(d, x, BLASSUFFIX)
33 | #define BLASI(x) stitch__(id, x, BLASSUFFIX)
34 | #else
35 | #define BLAS(x) stitch__(s, x, BLASSUFFIX)
36 | #define BLASI(x) stitch__(is, x, BLASSUFFIX)
37 | #endif
38 | #endif
39 |
40 | #ifdef MATLAB_MEX_FILE
41 | typedef ptrdiff_t blas_int;
42 | #elif defined BLAS64
43 | #include
44 | typedef int64_t blas_int;
45 | #else
46 | typedef int blas_int;
47 | #endif
48 |
49 | #ifdef __cplusplus
50 | }
51 | #endif
52 |
53 | #endif /* USE_LAPACK */
54 |
55 | #endif /* SCS_BLAS_H_GUARD */
56 |
--------------------------------------------------------------------------------
/include/scs_types.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Pulic header including definitions of primitive types used in SCS.
3 | * Make sure this file and `scs.h` are somewhere appropriate and then use
4 | * `#include "scs.h"` to access the SCS public API.
5 | */
6 |
7 | #ifndef SCS_TYPES_H_GUARD
8 | #define SCS_TYPES_H_GUARD
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | #ifdef DLONG
15 | /*#ifdef _WIN64
16 | #include
17 | typedef int64_t scs_int;
18 | #else
19 | typedef long scs_int;
20 | #endif
21 | */
22 | typedef long long scs_int;
23 | #else
24 | typedef int scs_int;
25 | #endif
26 |
27 | #ifndef SFLOAT
28 | typedef double scs_float;
29 | #else
30 | typedef float scs_float;
31 | #endif
32 |
33 | #ifdef __cplusplus
34 | }
35 | #endif
36 | #endif
37 |
--------------------------------------------------------------------------------
/include/scs_work.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Define ScsWork and related internal-only structs (not part of external API).
3 | */
4 |
5 | #ifndef SCS_WORK_H_GUARD
6 | #define SCS_WORK_H_GUARD
7 |
8 | #ifdef __cplusplus
9 | extern "C" {
10 | #endif
11 |
12 | #include "scs.h"
13 |
14 | /** Contains normalization variables. */
15 | typedef struct {
16 | scs_float *D, *E; /* for normalization */
17 | scs_int m; /* Length of D */
18 | scs_int n; /* Length of E */
19 | scs_float primal_scale, dual_scale;
20 | } ScsScaling;
21 |
22 | /** Holds residual information. */
23 | typedef struct {
24 | scs_int last_iter;
25 | scs_float xt_p_x; /* x' P x */
26 | scs_float xt_p_x_tau; /* x'Px * tau^2 *not* divided out */
27 | scs_float ctx;
28 | scs_float ctx_tau; /* tau *not* divided out */
29 | scs_float bty;
30 | scs_float bty_tau; /* tau *not* divided out */
31 | scs_float pobj; /* primal objective */
32 | scs_float dobj; /* dual objective */
33 | scs_float gap; /* pobj - dobj */
34 | scs_float tau;
35 | scs_float kap;
36 | scs_float res_pri;
37 | scs_float res_dual;
38 | scs_float res_infeas;
39 | scs_float res_unbdd_p;
40 | scs_float res_unbdd_a;
41 | /* tau NOT divided out */
42 | scs_float *ax, *ax_s, *px, *aty, *ax_s_btau, *px_aty_ctau;
43 | } ScsResiduals;
44 |
45 | /** Workspace for SCS. */
46 | struct SCS_WORK {
47 | /* x_prev = x from previous iteration */
48 | scs_float setup_time; /* time taken for setup phase (milliseconds) */
49 | scs_int time_limit_reached; /* boolean, if the time-limit is reached */
50 | scs_float *u, *u_t;
51 | scs_float *v, *v_prev;
52 | scs_float *rsk; /* rsk [ r; s; kappa ] */
53 | scs_float *h; /* h = [c; b] */
54 | scs_float *g; /* g = (I + M)^{-1} h */
55 | scs_float *lin_sys_warm_start; /* linear system warm-start (indirect only) */
56 | scs_float *diag_r; /* vector of R matrix diagonals (affects cone proj) */
57 | scs_float *b_orig, *c_orig; /* original unnormalized b and c vectors */
58 | scs_float nm_b_orig, nm_c_orig; /* unnormalized NORM(b), NORM(c) */
59 | AaWork *accel; /* struct for acceleration workspace */
60 | ScsData *d; /* Problem data deep copy NORMALIZED */
61 | ScsCone *k; /* Problem cone deep copy */
62 | ScsSettings *stgs; /* contains solver settings specified by user */
63 | ScsLinSysWork *p; /* struct populated by linear system solver */
64 | ScsScaling *scal; /* contains the re-scaling data */
65 | ScsConeWork *cone_work; /* workspace for the cone projection step */
66 | /* normalized and unnormalized residuals */
67 | ScsResiduals *r_orig, *r_normalized;
68 | /* track x,y,s as alg progresses, tau *not* divided out */
69 | ScsSolution *xys_orig, *xys_normalized;
70 | /* Scale updating workspace */
71 | scs_float sum_log_scale_factor;
72 | scs_int last_scale_update_iter, n_log_scale_factor, scale_updates;
73 | /* AA stats */
74 | scs_float aa_norm;
75 | scs_int rejected_accel_steps, accepted_accel_steps;
76 | };
77 |
78 | #ifdef __cplusplus
79 | }
80 | #endif
81 | #endif
82 |
--------------------------------------------------------------------------------
/include/util.h:
--------------------------------------------------------------------------------
1 | #ifndef UTIL_H_GUARD
2 | #define UTIL_H_GUARD
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 |
8 | #include "cones.h"
9 | #include "scs.h"
10 | #include
11 | #include
12 |
13 | /* timing code courtesy of A. Domahidi */
14 | #if (defined NO_TIMER)
15 | typedef void *SCS(timer);
16 | #elif (defined _WIN32 || defined _WIN64 || defined _WINDLL)
17 | /* Use Windows QueryPerformanceCounter for timing */
18 | #include
19 | typedef struct SCS(timer) {
20 | LARGE_INTEGER tic;
21 | LARGE_INTEGER toc;
22 | LARGE_INTEGER freq;
23 | } SCS(timer);
24 |
25 | #elif (defined __APPLE__)
26 | /* Use MAC OSX mach_time for timing */
27 | #include
28 | typedef struct SCS(timer) {
29 | uint64_t tic;
30 | uint64_t toc;
31 | mach_timebase_info_data_t tinfo;
32 | } SCS(timer);
33 |
34 | #else
35 | /* Use POSIX clock_gettime() for timing on other machines */
36 | #include
37 | typedef struct SCS(timer) {
38 | struct timespec tic;
39 | struct timespec toc;
40 | } SCS(timer);
41 |
42 | #endif
43 |
44 | /* these all return milli-seconds */
45 | void SCS(tic)(SCS(timer) * t);
46 | scs_float SCS(tocq)(SCS(timer) * t);
47 | void SCS(free_sol)(ScsSolution *sol);
48 | void SCS(deep_copy_data)(ScsData *dest, const ScsData *src);
49 | void SCS(deep_copy_stgs)(ScsSettings *dest, const ScsSettings *src);
50 | void SCS(free_data)(ScsData *d);
51 |
52 | #ifdef __cplusplus
53 | }
54 | #endif
55 | #endif
56 |
--------------------------------------------------------------------------------
/linsys/cpu/direct/private.h:
--------------------------------------------------------------------------------
1 | #ifndef PRIV_H_GUARD
2 | #define PRIV_H_GUARD
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 |
8 | #include "csparse.h"
9 | #include "external/amd/amd.h"
10 | #include "external/qdldl/qdldl.h"
11 | #include "glbopts.h"
12 | #include "linsys.h"
13 | #include "scs_matrix.h"
14 |
15 | struct SCS_LIN_SYS_WORK {
16 | scs_int m, n; /* linear system dimensions */
17 | ScsMatrix *kkt, *L; /* KKT, and factorization matrix L resp. */
18 | scs_float *Dinv; /* inverse diagonal matrix of factorization */
19 | scs_int *perm; /* permutation of KKT matrix for factorization */
20 | scs_float *bp; /* workspace memory for solves */
21 | scs_int *diag_r_idxs;
22 | scs_int factorizations;
23 | /* ldl factorization workspace */
24 | scs_float *D, *fwork;
25 | scs_int *etree, *iwork, *Lnz, *bwork;
26 | scs_float *diag_p;
27 | };
28 |
29 | #ifdef __cplusplus
30 | }
31 | #endif
32 | #endif
33 |
--------------------------------------------------------------------------------
/linsys/cpu/indirect/private.h:
--------------------------------------------------------------------------------
1 | #ifndef PRIV_H_GUARD
2 | #define PRIV_H_GUARD
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 |
8 | #include "csparse.h"
9 | #include "glbopts.h"
10 | #include "linalg.h"
11 | #include "linsys.h"
12 | #include "scs_matrix.h"
13 | #include "util.h" /* timer */
14 | #include
15 |
16 | struct SCS_LIN_SYS_WORK {
17 | scs_int n, m; /* linear system dimensions */
18 | scs_float *p; /* cg iterate */
19 | scs_float *r; /* cg residual */
20 | scs_float *Gp;
21 | scs_float *tmp;
22 | const ScsMatrix *A; /* does *not* own this memory */
23 | const ScsMatrix *P; /* does *not* own this memory */
24 | ScsMatrix *At; /* does own this memory */
25 | /* preconditioning */
26 | scs_float *z;
27 | scs_float *M;
28 | /* reporting */
29 | scs_int tot_cg_its;
30 | const scs_float *diag_r;
31 | };
32 |
33 | #ifdef __cplusplus
34 | }
35 | #endif
36 | #endif
37 |
--------------------------------------------------------------------------------
/linsys/csparse.h:
--------------------------------------------------------------------------------
1 | /* Routines modified from CSparse, T. Davis et al */
2 |
3 | #ifndef CS_H_GUARD
4 | #define CS_H_GUARD
5 |
6 | #ifdef __cplusplus
7 | extern "C" {
8 | #endif
9 |
10 | #include "glbopts.h"
11 | #include "scs.h"
12 |
13 | ScsMatrix *SCS(cs_spalloc)(scs_int m, scs_int n, scs_int nzmax, scs_int values,
14 | scs_int triplet);
15 | ScsMatrix *SCS(cs_done)(ScsMatrix *C, void *w, void *x, scs_int ok);
16 | ScsMatrix *SCS(cs_compress)(const ScsMatrix *T, scs_int nz,
17 | scs_int *idx_mapping);
18 | ScsMatrix *SCS(cs_spfree)(ScsMatrix *A);
19 | scs_float SCS(cumsum)(scs_int *p, scs_int *c, scs_int n);
20 | /* Forms KKT matrix */
21 | ScsMatrix *SCS(form_kkt)(const ScsMatrix *A, const ScsMatrix *P,
22 | scs_float *diag_p, const scs_float *diag_r,
23 | scs_int *diag_r_idxs, scs_int upper);
24 | #ifdef __cplusplus
25 | }
26 | #endif
27 | #endif
28 |
--------------------------------------------------------------------------------
/linsys/external/amd/LICENSE.txt:
--------------------------------------------------------------------------------
1 | ==> AMD/Doc/License.txt <==
2 |
3 | AMD, Copyright (c), 1996-2015, Timothy A. Davis,
4 | Patrick R. Amestoy, and Iain S. Duff. All Rights Reserved.
5 |
6 | Availability:
7 |
8 | http://www.suitesparse.com
9 |
10 | -------------------------------------------------------------------------------
11 | AMD License: BSD 3-clause:
12 | -------------------------------------------------------------------------------
13 |
14 | Redistribution and use in source and binary forms, with or without
15 | modification, are permitted provided that the following conditions are met:
16 | * Redistributions of source code must retain the above copyright
17 | notice, this list of conditions and the following disclaimer.
18 | * Redistributions in binary form must reproduce the above copyright
19 | notice, this list of conditions and the following disclaimer in the
20 | documentation and/or other materials provided with the distribution.
21 | * Neither the name of the organizations to which the authors are
22 | affiliated, nor the names of its contributors may be used to endorse
23 | or promote products derived from this software without specific prior
24 | written permission.
25 |
26 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
30 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
36 | DAMAGE.
37 |
38 |
--------------------------------------------------------------------------------
/linsys/external/amd/amd_control.c:
--------------------------------------------------------------------------------
1 | /* ========================================================================= */
2 | /* === AMD_control ========================================================= */
3 | /* ========================================================================= */
4 |
5 | /* ------------------------------------------------------------------------- */
6 | /* AMD, Copyright (c) Timothy A. Davis, */
7 | /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */
8 | /* email: DrTimothyAldenDavis@gmail.com */
9 | /* ------------------------------------------------------------------------- */
10 |
11 | /* User-callable. Prints the control parameters for AMD. See amd.h
12 | * for details. If the Control array is not present, the defaults are
13 | * printed instead.
14 | */
15 |
16 | #include "amd_internal.h"
17 |
18 | GLOBAL void AMD_control
19 | (
20 | scs_float Control [ ]
21 | )
22 | {
23 | scs_float alpha ;
24 | Int aggressive ;
25 |
26 | if (Control != (scs_float *) NULL)
27 | {
28 | alpha = Control [AMD_DENSE] ;
29 | aggressive = Control [AMD_AGGRESSIVE] != 0 ;
30 | }
31 | else
32 | {
33 | alpha = AMD_DEFAULT_DENSE ;
34 | aggressive = AMD_DEFAULT_AGGRESSIVE ;
35 | }
36 |
37 | SUITESPARSE_PRINTF ((
38 | "\nAMD version %d.%d.%d, %s: approximate minimum degree ordering\n"
39 | " dense row parameter: %g\n", AMD_MAIN_VERSION, AMD_SUB_VERSION,
40 | AMD_SUBSUB_VERSION, AMD_DATE, alpha)) ;
41 |
42 | if (alpha < 0)
43 | {
44 | SUITESPARSE_PRINTF ((" no rows treated as dense\n")) ;
45 | }
46 | else
47 | {
48 | SUITESPARSE_PRINTF ((
49 | " (rows with more than max (%g * sqrt (n), 16) entries are\n"
50 | " considered \"dense\", and placed last in output permutation)\n",
51 | alpha)) ;
52 | }
53 |
54 | if (aggressive)
55 | {
56 | SUITESPARSE_PRINTF ((" aggressive absorption: yes\n")) ;
57 | }
58 | else
59 | {
60 | SUITESPARSE_PRINTF ((" aggressive absorption: no\n")) ;
61 | }
62 |
63 | SUITESPARSE_PRINTF ((" size of AMD integer: %d\n\n", sizeof (Int))) ;
64 | }
65 |
--------------------------------------------------------------------------------
/linsys/external/amd/amd_defaults.c:
--------------------------------------------------------------------------------
1 | /* ========================================================================= */
2 | /* === AMD_defaults ======================================================== */
3 | /* ========================================================================= */
4 |
5 | /* ------------------------------------------------------------------------- */
6 | /* AMD, Copyright (c) Timothy A. Davis, */
7 | /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */
8 | /* email: DrTimothyAldenDavis@gmail.com */
9 | /* ------------------------------------------------------------------------- */
10 |
11 | /* User-callable. Sets default control parameters for AMD. See amd.h
12 | * for details.
13 | */
14 |
15 | #include "amd_internal.h"
16 |
17 | /* ========================================================================= */
18 | /* === AMD defaults ======================================================== */
19 | /* ========================================================================= */
20 |
21 | GLOBAL void AMD_defaults
22 | (
23 | scs_float Control [ ]
24 | )
25 | {
26 | Int i ;
27 |
28 | if (Control != (scs_float *) NULL)
29 | {
30 | for (i = 0 ; i < AMD_CONTROL ; i++)
31 | {
32 | Control [i] = 0 ;
33 | }
34 | Control [AMD_DENSE] = AMD_DEFAULT_DENSE ;
35 | Control [AMD_AGGRESSIVE] = AMD_DEFAULT_AGGRESSIVE ;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/linsys/external/amd/amd_global.c:
--------------------------------------------------------------------------------
1 | /* ========================================================================= */
2 | /* === amd_global ========================================================== */
3 | /* ========================================================================= */
4 |
5 | /* ------------------------------------------------------------------------- */
6 | /* AMD, Copyright (c) Timothy A. Davis, */
7 | /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */
8 | /* email: DrTimothyAldenDavis@gmail.com */
9 | /* ------------------------------------------------------------------------- */
10 |
11 | /* In prior versions of AMD, this file declared the amd_malloc, amd_free,
12 | amd_realloc, amd_calloc, and amd_printf functions. They are now replaced
13 | by functions defined in SuiteSparse_config/SuiteSparse_config.c.
14 | */
15 | /* Simply to suppress empty translation unit warnings. */
16 | typedef int scs_amd_make_iso_compilers_happy;
17 |
--------------------------------------------------------------------------------
/linsys/external/amd/amd_post_tree.c:
--------------------------------------------------------------------------------
1 | /* ========================================================================= */
2 | /* === AMD_post_tree ======================================================= */
3 | /* ========================================================================= */
4 |
5 | /* ------------------------------------------------------------------------- */
6 | /* AMD, Copyright (c) Timothy A. Davis, */
7 | /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */
8 | /* email: DrTimothyAldenDavis@gmail.com */
9 | /* ------------------------------------------------------------------------- */
10 |
11 | /* Post-ordering of a supernodal elimination tree. */
12 |
13 | #include "amd_internal.h"
14 |
15 | GLOBAL Int AMD_post_tree
16 | (
17 | Int root, /* root of the tree */
18 | Int k, /* start numbering at k */
19 | Int Child [ ], /* input argument of size nn, undefined on
20 | * output. Child [i] is the head of a link
21 | * list of all nodes that are children of node
22 | * i in the tree. */
23 | const Int Sibling [ ], /* input argument of size nn, not modified.
24 | * If f is a node in the link list of the
25 | * children of node i, then Sibling [f] is the
26 | * next child of node i.
27 | */
28 | Int Order [ ], /* output order, of size nn. Order [i] = k
29 | * if node i is the kth node of the reordered
30 | * tree. */
31 | Int Stack [ ] /* workspace of size nn */
32 | #ifndef NDEBUG
33 | , Int nn /* nodes are in the range 0..nn-1. */
34 | #endif
35 | )
36 | {
37 | Int f, head, h, i ;
38 |
39 | #if 0
40 | /* --------------------------------------------------------------------- */
41 | /* recursive version (Stack [ ] is not used): */
42 | /* --------------------------------------------------------------------- */
43 |
44 | /* this is simple, but can caouse stack overflow if nn is large */
45 | i = root ;
46 | for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
47 | {
48 | k = AMD_post_tree (f, k, Child, Sibling, Order, Stack, nn) ;
49 | }
50 | Order [i] = k++ ;
51 | return (k) ;
52 | #endif
53 |
54 | /* --------------------------------------------------------------------- */
55 | /* non-recursive version, using an explicit stack */
56 | /* --------------------------------------------------------------------- */
57 |
58 | /* push root on the stack */
59 | head = 0 ;
60 | Stack [0] = root ;
61 |
62 | while (head >= 0)
63 | {
64 | /* get head of stack */
65 | ASSERT (head < nn) ;
66 | i = Stack [head] ;
67 | AMD_DEBUG1 (("head of stack "ID" \n", i)) ;
68 | ASSERT (i >= 0 && i < nn) ;
69 |
70 | if (Child [i] != EMPTY)
71 | {
72 | /* the children of i are not yet ordered */
73 | /* push each child onto the stack in reverse order */
74 | /* so that small ones at the head of the list get popped first */
75 | /* and the biggest one at the end of the list gets popped last */
76 | for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
77 | {
78 | head++ ;
79 | ASSERT (head < nn) ;
80 | ASSERT (f >= 0 && f < nn) ;
81 | }
82 | h = head ;
83 | ASSERT (head < nn) ;
84 | for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
85 | {
86 | ASSERT (h > 0) ;
87 | Stack [h--] = f ;
88 | AMD_DEBUG1 (("push "ID" on stack\n", f)) ;
89 | ASSERT (f >= 0 && f < nn) ;
90 | }
91 | ASSERT (Stack [h] == i) ;
92 |
93 | /* delete child list so that i gets ordered next time we see it */
94 | Child [i] = EMPTY ;
95 | }
96 | else
97 | {
98 | /* the children of i (if there were any) are already ordered */
99 | /* remove i from the stack and order it. Front i is kth front */
100 | head-- ;
101 | AMD_DEBUG1 (("pop "ID" order "ID"\n", i, k)) ;
102 | Order [i] = k++ ;
103 | ASSERT (k <= nn) ;
104 | }
105 |
106 | #ifndef NDEBUG
107 | AMD_DEBUG1 (("\nStack:")) ;
108 | for (h = head ; h >= 0 ; h--)
109 | {
110 | Int j = Stack [h] ;
111 | AMD_DEBUG1 ((" "ID, j)) ;
112 | ASSERT (j >= 0 && j < nn) ;
113 | }
114 | AMD_DEBUG1 (("\n\n")) ;
115 | ASSERT (head < nn) ;
116 | #endif
117 |
118 | }
119 | return (k) ;
120 | }
121 |
--------------------------------------------------------------------------------
/linsys/external/amd/amd_preprocess.c:
--------------------------------------------------------------------------------
1 | /* ========================================================================= */
2 | /* === AMD_preprocess ====================================================== */
3 | /* ========================================================================= */
4 |
5 | /* ------------------------------------------------------------------------- */
6 | /* AMD, Copyright (c) Timothy A. Davis, */
7 | /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */
8 | /* email: DrTimothyAldenDavis@gmail.com */
9 | /* ------------------------------------------------------------------------- */
10 |
11 | /* Sorts, removes duplicate entries, and transposes from the nonzero pattern of
12 | * a column-form matrix A, to obtain the matrix R. The input matrix can have
13 | * duplicate entries and/or unsorted columns (AMD_valid (n,Ap,Ai) must not be
14 | * AMD_INVALID).
15 | *
16 | * This input condition is NOT checked. This routine is not user-callable.
17 | */
18 |
19 | #include "amd_internal.h"
20 |
21 | /* ========================================================================= */
22 | /* === AMD_preprocess ====================================================== */
23 | /* ========================================================================= */
24 |
25 | /* AMD_preprocess does not check its input for errors or allocate workspace.
26 | * On input, the condition (AMD_valid (n,n,Ap,Ai) != AMD_INVALID) must hold.
27 | */
28 |
29 | GLOBAL void AMD_preprocess
30 | (
31 | Int n, /* input matrix: A is n-by-n */
32 | const Int Ap [ ], /* size n+1 */
33 | const Int Ai [ ], /* size nz = Ap [n] */
34 |
35 | /* output matrix R: */
36 | Int Rp [ ], /* size n+1 */
37 | Int Ri [ ], /* size nz (or less, if duplicates present) */
38 |
39 | Int W [ ], /* workspace of size n */
40 | Int Flag [ ] /* workspace of size n */
41 | )
42 | {
43 |
44 | /* --------------------------------------------------------------------- */
45 | /* local variables */
46 | /* --------------------------------------------------------------------- */
47 |
48 | Int i, j, p, p2 ;
49 |
50 | ASSERT (AMD_valid (n, n, Ap, Ai) != AMD_INVALID) ;
51 |
52 | /* --------------------------------------------------------------------- */
53 | /* count the entries in each row of A (excluding duplicates) */
54 | /* --------------------------------------------------------------------- */
55 |
56 | for (i = 0 ; i < n ; i++)
57 | {
58 | W [i] = 0 ; /* # of nonzeros in row i (excl duplicates) */
59 | Flag [i] = EMPTY ; /* Flag [i] = j if i appears in column j */
60 | }
61 | for (j = 0 ; j < n ; j++)
62 | {
63 | p2 = Ap [j+1] ;
64 | for (p = Ap [j] ; p < p2 ; p++)
65 | {
66 | i = Ai [p] ;
67 | if (Flag [i] != j)
68 | {
69 | /* row index i has not yet appeared in column j */
70 | W [i]++ ; /* one more entry in row i */
71 | Flag [i] = j ; /* flag row index i as appearing in col j*/
72 | }
73 | }
74 | }
75 |
76 | /* --------------------------------------------------------------------- */
77 | /* compute the row pointers for R */
78 | /* --------------------------------------------------------------------- */
79 |
80 | Rp [0] = 0 ;
81 | for (i = 0 ; i < n ; i++)
82 | {
83 | Rp [i+1] = Rp [i] + W [i] ;
84 | }
85 | for (i = 0 ; i < n ; i++)
86 | {
87 | W [i] = Rp [i] ;
88 | Flag [i] = EMPTY ;
89 | }
90 |
91 | /* --------------------------------------------------------------------- */
92 | /* construct the row form matrix R */
93 | /* --------------------------------------------------------------------- */
94 |
95 | /* R = row form of pattern of A */
96 | for (j = 0 ; j < n ; j++)
97 | {
98 | p2 = Ap [j+1] ;
99 | for (p = Ap [j] ; p < p2 ; p++)
100 | {
101 | i = Ai [p] ;
102 | if (Flag [i] != j)
103 | {
104 | /* row index i has not yet appeared in column j */
105 | Ri [W [i]++] = j ; /* put col j in row i */
106 | Flag [i] = j ; /* flag row index i as appearing in col j*/
107 | }
108 | }
109 | }
110 |
111 | #ifndef NDEBUG
112 | ASSERT (AMD_valid (n, n, Rp, Ri) == AMD_OK) ;
113 | for (j = 0 ; j < n ; j++)
114 | {
115 | ASSERT (W [j] == Rp [j+1]) ;
116 | }
117 | #endif
118 | }
119 |
--------------------------------------------------------------------------------
/linsys/external/amd/amd_valid.c:
--------------------------------------------------------------------------------
1 | /* ========================================================================= */
2 | /* === AMD_valid =========================================================== */
3 | /* ========================================================================= */
4 |
5 | /* ------------------------------------------------------------------------- */
6 | /* AMD, Copyright (c) Timothy A. Davis, */
7 | /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */
8 | /* email: DrTimothyAldenDavis@gmail.com */
9 | /* ------------------------------------------------------------------------- */
10 |
11 | /* Check if a column-form matrix is valid or not. The matrix A is
12 | * n_row-by-n_col. The row indices of entries in column j are in
13 | * Ai [Ap [j] ... Ap [j+1]-1]. Required conditions are:
14 | *
15 | * n_row >= 0
16 | * n_col >= 0
17 | * nz = Ap [n_col] >= 0 number of entries in the matrix
18 | * Ap [0] == 0
19 | * Ap [j] <= Ap [j+1] for all j in the range 0 to n_col.
20 | * Ai [0 ... nz-1] must be in the range 0 to n_row-1.
21 | *
22 | * If any of the above conditions hold, AMD_INVALID is returned. If the
23 | * following condition holds, AMD_OK_BUT_JUMBLED is returned (a warning,
24 | * not an error):
25 | *
26 | * row indices in Ai [Ap [j] ... Ap [j+1]-1] are not sorted in ascending
27 | * order, and/or duplicate entries exist.
28 | *
29 | * Otherwise, AMD_OK is returned.
30 | *
31 | * In v1.2 and earlier, this function returned TRUE if the matrix was valid
32 | * (now returns AMD_OK), or FALSE otherwise (now returns AMD_INVALID or
33 | * AMD_OK_BUT_JUMBLED).
34 | */
35 |
36 | #include "amd_internal.h"
37 |
38 | GLOBAL Int AMD_valid
39 | (
40 | /* inputs, not modified on output: */
41 | Int n_row, /* A is n_row-by-n_col */
42 | Int n_col,
43 | const Int Ap [ ], /* column pointers of A, of size n_col+1 */
44 | const Int Ai [ ] /* row indices of A, of size nz = Ap [n_col] */
45 | )
46 | {
47 | Int nz, j, p1, p2, ilast, i, p, result = AMD_OK ;
48 |
49 | if (n_row < 0 || n_col < 0 || Ap == NULL || Ai == NULL)
50 | {
51 | return (AMD_INVALID) ;
52 | }
53 | nz = Ap [n_col] ;
54 | if (Ap [0] != 0 || nz < 0)
55 | {
56 | /* column pointers must start at Ap [0] = 0, and Ap [n] must be >= 0 */
57 | AMD_DEBUG0 (("column 0 pointer bad or nz < 0\n")) ;
58 | return (AMD_INVALID) ;
59 | }
60 | for (j = 0 ; j < n_col ; j++)
61 | {
62 | p1 = Ap [j] ;
63 | p2 = Ap [j+1] ;
64 | AMD_DEBUG2 (("\nColumn: "ID" p1: "ID" p2: "ID"\n", j, p1, p2)) ;
65 | if (p1 > p2)
66 | {
67 | /* column pointers must be ascending */
68 | AMD_DEBUG0 (("column "ID" pointer bad\n", j)) ;
69 | return (AMD_INVALID) ;
70 | }
71 | ilast = EMPTY ;
72 | for (p = p1 ; p < p2 ; p++)
73 | {
74 | i = Ai [p] ;
75 | AMD_DEBUG3 (("row: "ID"\n", i)) ;
76 | if (i < 0 || i >= n_row)
77 | {
78 | /* row index out of range */
79 | AMD_DEBUG0 (("index out of range, col "ID" row "ID"\n", j, i));
80 | return (AMD_INVALID) ;
81 | }
82 | if (i <= ilast)
83 | {
84 | /* row index unsorted, or duplicate entry present */
85 | AMD_DEBUG1 (("index unsorted/dupl col "ID" row "ID"\n", j, i));
86 | result = AMD_OK_BUT_JUMBLED ;
87 | }
88 | ilast = i ;
89 | }
90 | }
91 | return (result) ;
92 | }
93 |
--------------------------------------------------------------------------------
/linsys/external/amd/changes:
--------------------------------------------------------------------------------
1 | Flatten out all .c and .h to single dir.
2 | All files: double -> scs_float.
3 | git grep -l 'double' | xargs sed -i 's/double/scs_float/g'
4 | SuiteSparse_config.h: add '#include "scs.h"'
5 | add '#include "ctrlc.h"'
6 | add '#define SuiteSparse_long scs_int'
7 | disable timer #define NTIMER
8 | SuiteSparse_config.c: replace *alloc and printf in 2 structs.
9 | amd_internal.h: remove all refs to long version, int -> scs_int
10 | amd_global.c: add typedef to rm warning
11 | amd.h: int -> scs_int.h
12 |
--------------------------------------------------------------------------------
/linsys/external/qdldl/changes:
--------------------------------------------------------------------------------
1 | Last qdldl commit: a00d500906621fbf014b39e42a3304d1143eb65f
2 |
3 | flatten into one dir
4 | create qdldl_types.h from template file
5 | add 'include "glbopts.h"' to qdldl_types.h
6 | manually insert scs types into qdldl_types.h
7 |
--------------------------------------------------------------------------------
/linsys/external/qdldl/qdldl_types.h:
--------------------------------------------------------------------------------
1 | #ifndef QDLDL_TYPES_H
2 | # define QDLDL_TYPES_H
3 |
4 | # ifdef __cplusplus
5 | extern "C" {
6 | # endif /* ifdef __cplusplus */
7 |
8 | #include "glbopts.h"
9 | #include //for the QDLDL_INT_TYPE_MAX
10 |
11 | /* QDLDL integer and float types */
12 |
13 | #define QDLDL_int scs_int
14 | #define QDLDL_float scs_float
15 | #define QDLDL_bool scs_int
16 |
17 | /* Maximum value of the signed type QDLDL_int */
18 | #ifdef DLONG
19 | #define QDLDL_INT_MAX LLONG_MAX
20 | #else
21 | #define QDLDL_INT_MAX INT_MAX
22 | #endif
23 |
24 | # ifdef __cplusplus
25 | }
26 | # endif /* ifdef __cplusplus */
27 |
28 | #endif /* ifndef QDLDL_TYPES_H */
29 |
30 |
--------------------------------------------------------------------------------
/linsys/gpu/gpu.c:
--------------------------------------------------------------------------------
1 | #include "gpu.h"
2 |
3 | void SCS(accum_by_atrans_gpu)(const ScsGpuMatrix *Ag,
4 | const cusparseDnVecDescr_t x,
5 | cusparseDnVecDescr_t y,
6 | cusparseHandle_t cusparse_handle,
7 | size_t *buffer_size, void **buffer) {
8 | /* y += A'*x
9 | x and y MUST be on GPU already
10 | */
11 | const scs_float onef = 1.0;
12 | size_t new_buffer_size = 0;
13 |
14 | CUSPARSE_GEN(SpMV_bufferSize)
15 | (cusparse_handle, CUSPARSE_OPERATION_NON_TRANSPOSE, &onef, Ag->descr, x,
16 | &onef, y, SCS_CUDA_FLOAT, SCS_CSRMV_ALG, &new_buffer_size);
17 |
18 | if (new_buffer_size > *buffer_size) {
19 | if (*buffer != SCS_NULL) {
20 | cudaFree(*buffer);
21 | }
22 | cudaMalloc(buffer, new_buffer_size);
23 | *buffer_size = new_buffer_size;
24 | }
25 |
26 | CUSPARSE_GEN(SpMV)
27 | (cusparse_handle, CUSPARSE_OPERATION_NON_TRANSPOSE, &onef, Ag->descr, x,
28 | &onef, y, SCS_CUDA_FLOAT, SCS_CSRMV_ALG, *buffer);
29 | }
30 |
31 | /* this is slow, use trans routine if possible */
32 | void SCS(accum_by_a_gpu)(const ScsGpuMatrix *Ag, const cusparseDnVecDescr_t x,
33 | cusparseDnVecDescr_t y,
34 | cusparseHandle_t cusparse_handle, size_t *buffer_size,
35 | void **buffer) {
36 | /* y += A*x
37 | x and y MUST be on GPU already
38 | */
39 | const scs_float onef = 1.0;
40 | size_t new_buffer_size = 0;
41 |
42 | /* The A matrix idx pointers must be ORDERED */
43 | CUSPARSE_GEN(SpMV_bufferSize)
44 | (cusparse_handle, CUSPARSE_OPERATION_TRANSPOSE, &onef, Ag->descr, x, &onef, y,
45 | SCS_CUDA_FLOAT, SCS_CSRMV_ALG, &new_buffer_size);
46 |
47 | if (new_buffer_size > *buffer_size) {
48 | if (*buffer != SCS_NULL) {
49 | cudaFree(*buffer);
50 | }
51 | cudaMalloc(buffer, new_buffer_size);
52 | *buffer_size = new_buffer_size;
53 | }
54 |
55 | CUSPARSE_GEN(SpMV)
56 | (cusparse_handle, CUSPARSE_OPERATION_TRANSPOSE, &onef, Ag->descr, x, &onef, y,
57 | SCS_CUDA_FLOAT, SCS_CSRMV_ALG, *buffer);
58 | }
59 |
60 | /* This assumes that P has been made full (ie not triangular) and uses the
61 | * fact that the GPU is faster for general sparse matrices than for symmetric
62 | */
63 | /* y += P*x
64 | x and y MUST be on GPU already
65 | */
66 | void SCS(accum_by_p_gpu)(const ScsGpuMatrix *Pg, const cusparseDnVecDescr_t x,
67 | cusparseDnVecDescr_t y,
68 | cusparseHandle_t cusparse_handle, size_t *buffer_size,
69 | void **buffer) {
70 | SCS(accum_by_atrans_gpu)(Pg, x, y, cusparse_handle, buffer_size, buffer);
71 | }
72 |
73 | void SCS(free_gpu_matrix)(ScsGpuMatrix *A) {
74 | cudaFree(A->x);
75 | cudaFree(A->i);
76 | cudaFree(A->p);
77 | cusparseDestroySpMat(A->descr);
78 | }
79 |
--------------------------------------------------------------------------------
/linsys/gpu/gpu.h:
--------------------------------------------------------------------------------
1 | #ifndef SCS_GPU_H_GUARD
2 | #define SCS_GPU_H_GUARD
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 |
8 | /* TODO: Do we need this?
9 |
10 | #include
11 |
12 | */
13 |
14 | #include
15 | #include
16 | #include
17 |
18 | #include "glbopts.h"
19 | #include "linalg.h"
20 | #include "linsys.h"
21 | #include "scs.h"
22 | #include "scs_matrix.h"
23 | #include "util.h"
24 |
25 | #define CUDA_CHECK_ERR \
26 | do { \
27 | cudaDeviceSynchronize(); \
28 | cudaError_t err = cudaGetLastError(); \
29 | if (err != cudaSuccess) { \
30 | scs_printf("%s:%d:%s\n ERROR_CUDA (#): %s\n", __FILE__, __LINE__, \
31 | __func__, cudaGetErrorString(err)); \
32 | } \
33 | } while (0)
34 |
35 | #if VERBOSITY == 0
36 | #ifndef SFLOAT
37 | #define CUBLAS(x) cublasD##x
38 | #define CUBLASI(x) cublasId##x
39 | #else
40 | #define CUBLAS(x) cublasS##x
41 | #define CUBLASI(x) cublasIs##x
42 | #endif
43 | #define CUSPARSE_GEN(x) cusparse##x
44 | #else
45 | #ifndef SFLOAT
46 | #define CUBLAS(x) \
47 | CUDA_CHECK_ERR; \
48 | cublasD##x
49 | #define CUBLASI(x) \
50 | CUDA_CHECK_ERR; \
51 | cublasId##x
52 | #else
53 | #define CUBLAS(x) \
54 | CUDA_CHECK_ERR; \
55 | cublasS##x
56 | #define CUBLASI(x) \
57 | CUDA_CHECK_ERR; \
58 | cublasIs##x
59 | #endif
60 | #define CUSPARSE_GEN(x) \
61 | CUDA_CHECK_ERR; \
62 | cusparse##x
63 | #endif
64 |
65 | #ifndef SFLOAT
66 | #define SCS_CUDA_FLOAT CUDA_R_64F
67 | #else
68 | #define SCS_CUDA_FLOAT CUDA_R_32F
69 | #endif
70 |
71 | #ifndef DLONG
72 | #define SCS_CUSPARSE_INDEX CUSPARSE_INDEX_32I
73 | #else
74 | #define SCS_CUSPARSE_INDEX CUSPARSE_INDEX_64I
75 | #endif
76 |
77 | #define SCS_CSRMV_ALG CUSPARSE_SPMV_CSR_ALG1
78 | #define SCS_CSR2CSC_ALG CUSPARSE_CSR2CSC_ALG1
79 |
80 | /*
81 | CUDA matrix routines only for CSR, not CSC matrices:
82 | CSC CSR GPU Mult
83 | A (m x n) A' (n x m) Ag accum_by_a_trans_gpu
84 | A'(n x m) A (m x n) Agt accum_by_a_gpu
85 | */
86 |
87 | /* this struct defines the data matrix on GPU */
88 | typedef struct SCS_GPU_DATA_MATRIX {
89 | /* A is supplied in column compressed format */
90 | scs_float *x; /* values, size: NNZ */
91 | scs_int *i; /* row index, size: NNZ */
92 | scs_int *p; /* column pointer, size: n+1 */
93 | scs_int m, n; /* m rows, n cols */
94 | scs_int nnz; /* num non-zeros in matrix */
95 | /* CUDA */
96 | cusparseSpMatDescr_t descr;
97 | } ScsGpuMatrix;
98 |
99 | void SCS(accum_by_atrans_gpu)(const ScsGpuMatrix *A,
100 | const cusparseDnVecDescr_t x,
101 | cusparseDnVecDescr_t y,
102 | cusparseHandle_t cusparse_handle,
103 | size_t *buffer_size, void **buffer);
104 |
105 | void SCS(accum_by_a_gpu)(const ScsGpuMatrix *A, const cusparseDnVecDescr_t x,
106 | cusparseDnVecDescr_t y,
107 | cusparseHandle_t cusparse_handle, size_t *buffer_size,
108 | void **buffer);
109 |
110 | void SCS(accum_by_p_gpu)(const ScsGpuMatrix *P, const cusparseDnVecDescr_t x,
111 | cusparseDnVecDescr_t y,
112 | cusparseHandle_t cusparse_handle, size_t *buffer_size,
113 | void **buffer);
114 |
115 | void SCS(free_gpu_matrix)(ScsGpuMatrix *A);
116 |
117 | #ifdef __cplusplus
118 | }
119 | #endif
120 | #endif
121 |
--------------------------------------------------------------------------------
/linsys/gpu/indirect/private.h:
--------------------------------------------------------------------------------
1 | #ifndef PRIV_H_GUARD
2 | #define PRIV_H_GUARD
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 |
8 | #include "csparse.h"
9 | #include "glbopts.h"
10 | #include "gpu.h"
11 | #include "linalg.h"
12 | #include "scs.h"
13 |
14 | struct SCS_LIN_SYS_WORK {
15 | scs_int n, m; /* linear system dimensions */
16 | /* reporting */
17 | scs_int tot_cg_its;
18 | scs_float *M; /* preconditioner on cpu */
19 | /* ALL BELOW HOSTED ON THE GPU */
20 | scs_float *p; /* cg iterate, n */
21 | scs_float *r; /* cg residual, n */
22 | scs_float *Gp; /* G * p, n */
23 | scs_float *bg; /* b, n */
24 | scs_float *tmp_m; /* m, used in mat_vec */
25 | scs_float *z; /* preconditioned */
26 | scs_float *M_gpu; /* preconditioner */
27 | const ScsMatrix *A; /* does *not* own this memory */
28 | const ScsMatrix *P; /* does *not* own this memory */
29 | ScsGpuMatrix *Ag; /* A matrix on GPU */
30 | ScsGpuMatrix *Agt; /* A trans matrix on GPU */
31 | ScsGpuMatrix *Pg; /* P matrix on GPU */
32 | /* CUDA */
33 | cublasHandle_t cublas_handle;
34 | cusparseHandle_t cusparse_handle;
35 | /* CUSPARSE */
36 | size_t buffer_size;
37 | void *buffer;
38 | cusparseDnVecDescr_t dn_vec_m; /* Dense vector of length m */
39 | cusparseDnVecDescr_t dn_vec_n; /* Dense vector of length n */
40 | cusparseDnVecDescr_t dn_vec_n_p; /* Dense vector of length n */
41 |
42 | /* rho terms */
43 | scs_float *r_x_gpu;
44 | scs_float *inv_r_y; /* inverse R_y */
45 | scs_float *inv_r_y_gpu; /* inverse R_y on GPU */
46 | };
47 |
48 | #ifdef __cplusplus
49 | }
50 | #endif
51 | #endif
52 |
--------------------------------------------------------------------------------
/linsys/mkl/direct/private.h:
--------------------------------------------------------------------------------
1 | #ifndef PRIV_H_GUARD
2 | #define PRIV_H_GUARD
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 |
8 | #include "csparse.h"
9 | #include "linsys.h"
10 |
11 | struct SCS_LIN_SYS_WORK {
12 | ScsMatrix *kkt; /* Upper triangular KKT matrix (in CSR format) */
13 | scs_float *sol; /* solution to the KKT system */
14 | scs_int n; /* number of QP variables */
15 | scs_int m; /* number of QP constraints */
16 |
17 | /* Pardiso variables */
18 | void *pt[64]; /* internal solver memory pointer pt */
19 | scs_int iparm[64]; /* Pardiso control parameters */
20 | scs_int n_plus_m; /* dimension of the linear system */
21 | scs_int mtype; /* matrix type (-2 for real and symmetric indefinite) */
22 | scs_int nrhs; /* number of right-hand sides (1) */
23 | scs_int maxfct; /* maximum number of factors (1) */
24 | scs_int mnum; /* indicates matrix for the solution phase (1) */
25 | scs_int phase; /* control the execution phases of the solver */
26 | scs_int error; /* the error indicator (0 for no error) */
27 | scs_int msglvl; /* Message level information (0 for no output) */
28 |
29 | /* These are required for matrix updates */
30 | scs_int *diag_r_idxs; /* indices where R appears */
31 | scs_float *diag_p; /* Diagonal values of P */
32 | };
33 |
34 | #ifdef __cplusplus
35 | }
36 | #endif
37 |
38 | #endif
39 |
--------------------------------------------------------------------------------
/linsys/scs_matrix.h:
--------------------------------------------------------------------------------
1 | #ifndef SCS_MATRIX_H_GUARD
2 | #define SCS_MATRIX_H_GUARD
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 |
8 | #include "glbopts.h"
9 | #include "scs.h"
10 | #include "scs_work.h"
11 |
12 | /* Normalization routines, used if d->NORMALIZE is true */
13 | /* normalizes A matrix, sets scal->E and scal->D diagonal scaling matrices,
14 | * A -> D*A*E. D and E must be all positive entries, D must satisfy cone
15 | * boundaries */
16 | ScsScaling *SCS(normalize_a_p)(ScsMatrix *P, ScsMatrix *A, ScsConeWork *cone);
17 |
18 | /* unnormalizes A matrix, unnormalizes by w->D and w->E */
19 | /* void SCS(un_normalize_a_p)(ScsMatrix *A, ScsMatrix *P, const ScsScaling
20 | * *scal);
21 | */
22 |
23 | /* to free the memory allocated in a ScsMatrix (called on A and P at finish) */
24 | void SCS(free_scs_matrix)(ScsMatrix *A);
25 |
26 | /* copies A (instead of in-place normalization), returns 0 for failure,
27 | * allocates memory for dstp */
28 | scs_int SCS(copy_matrix)(ScsMatrix **dstp, const ScsMatrix *src);
29 |
30 | scs_float SCS(cumsum)(scs_int *p, scs_int *c, scs_int n);
31 |
32 | /**
33 | * Validate the linear system inputs, returns < 0 if not valid inputs.
34 | *
35 | * @param A A data matrix
36 | * @param P P data matrix
37 | * @return status < 0 indicates failure
38 | */
39 | scs_int SCS(validate_lin_sys)(const ScsMatrix *A, const ScsMatrix *P);
40 |
41 | /**
42 | * Forms y += A^T * x
43 | *
44 | * @param A A data matrix
45 | * @param x Input
46 | * @param y Output
47 | */
48 | void SCS(accum_by_atrans)(const ScsMatrix *A, const scs_float *x, scs_float *y);
49 |
50 | /**
51 | * Forms y += A * x
52 | *
53 | * @param A Data matrix
54 | * @param x Input
55 | * @param y Output
56 | */
57 | void SCS(accum_by_a)(const ScsMatrix *A, const scs_float *x, scs_float *y);
58 |
59 | /**
60 | * Forms y += P * x
61 | *
62 | * @param P P data matrix
63 | * @param x Input
64 | * @param y Output
65 | */
66 | void SCS(accum_by_p)(const ScsMatrix *P, const scs_float *x, scs_float *y);
67 |
68 | #ifdef __cplusplus
69 | }
70 | #endif
71 | #endif
72 |
--------------------------------------------------------------------------------
/src/ctrlc.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Implements signal handling (ctrl-c) for SCS.
3 | *
4 | * Under Windows, we use SetConsoleCtrlHandler.
5 | * Under Unix systems, we use sigaction.
6 | * For Mex files, we use utSetInterruptEnabled/utIsInterruptPending.
7 | *
8 | */
9 |
10 | #include "ctrlc.h"
11 |
12 | #if CTRLC > 0
13 |
14 | #ifdef MATLAB_MEX_FILE
15 | #include
16 |
17 | extern bool utIsInterruptPending(void);
18 | extern bool utSetInterruptEnabled(bool);
19 |
20 | static int istate;
21 | void scs_start_interrupt_listener(void) {
22 | istate = (int)utSetInterruptEnabled(true);
23 | }
24 |
25 | void scs_end_interrupt_listener(void) {
26 | utSetInterruptEnabled((bool)istate);
27 | }
28 |
29 | int scs_is_interrupted(void) {
30 | return (int)utIsInterruptPending();
31 | }
32 |
33 | #elif (defined _WIN32 || _WIN64 || defined _WINDLL)
34 | #include
35 |
36 | static int int_detected;
37 | static BOOL WINAPI scs_handle_ctrlc(DWORD dwCtrlType) {
38 | if (dwCtrlType != CTRL_C_EVENT) {
39 | return FALSE;
40 | }
41 | int_detected = 1;
42 | return TRUE;
43 | }
44 |
45 | void scs_start_interrupt_listener(void) {
46 | int_detected = 0;
47 | SetConsoleCtrlHandler(scs_handle_ctrlc, TRUE);
48 | }
49 |
50 | void scs_end_interrupt_listener(void) {
51 | SetConsoleCtrlHandler(scs_handle_ctrlc, FALSE);
52 | }
53 |
54 | int scs_is_interrupted(void) {
55 | return int_detected;
56 | }
57 |
58 | #else /* Unix */
59 |
60 | #include
61 | static int int_detected;
62 | struct sigaction oact;
63 | static void scs_handle_ctrlc(int dummy) {
64 | int_detected = dummy ? dummy : -1;
65 | }
66 |
67 | void scs_start_interrupt_listener(void) {
68 | struct sigaction act;
69 | int_detected = 0;
70 | act.sa_flags = 0;
71 | sigemptyset(&act.sa_mask);
72 | act.sa_handler = scs_handle_ctrlc;
73 | sigaction(SIGINT, &act, &oact);
74 | }
75 |
76 | void scs_end_interrupt_listener(void) {
77 | struct sigaction act;
78 | sigaction(SIGINT, &oact, &act);
79 | }
80 |
81 | int scs_is_interrupted(void) {
82 | return int_detected;
83 | }
84 |
85 | #endif /* END IF MATLAB_MEX_FILE / WIN32 */
86 |
87 | #endif /* END IF CTRLC > 0 */
88 |
--------------------------------------------------------------------------------
/src/normalize.c:
--------------------------------------------------------------------------------
1 | #include "normalize.h"
2 |
3 | #include "linalg.h"
4 | #include "scs.h"
5 |
6 | /* copied from linsys/scs_matrix.c */
7 | #define MIN_NORMALIZATION_FACTOR (1e-4)
8 | #define MAX_NORMALIZATION_FACTOR (1e4)
9 |
10 | /* Given D, E in scaling normalize b, c and compute primal / dual scales.
11 | *
12 | * Recall that the normalization routine is performing:
13 | *
14 | * [P A' c] with [E 0 0] on both sides (D, E diagonal)
15 | * [A 0 b] [0 D 0]
16 | * [c' b' 0] [0 0 s]
17 | *
18 | * which results in:
19 | *
20 | * [ EPE EA'D sEc ]
21 | * [ DAE 0 sDb ]
22 | * [ sc'E sb'D 0 ]
23 | *
24 | * `s` is incorporated into dual_scale and primal_scale
25 | *
26 | */
27 | void SCS(normalize_b_c)(ScsScaling *scal, scs_float *b, scs_float *c) {
28 | scs_int i;
29 | scs_float sigma, nm_c, nm_b;
30 |
31 | /* scale c */
32 | for (i = 0; i < scal->n; ++i) {
33 | c[i] *= scal->E[i];
34 | }
35 | /* scale b */
36 | for (i = 0; i < scal->m; ++i) {
37 | b[i] *= scal->D[i];
38 | }
39 |
40 | /* calculate primal and dual scales */
41 | nm_c = SCS(norm_inf)(c, scal->n);
42 | nm_b = SCS(norm_inf)(b, scal->m);
43 | sigma = MAX(nm_c, nm_b);
44 | sigma = sigma < MIN_NORMALIZATION_FACTOR ? 1.0 : sigma;
45 | sigma = sigma > MAX_NORMALIZATION_FACTOR ? MAX_NORMALIZATION_FACTOR : sigma;
46 | sigma = SAFEDIV_POS(1.0, sigma);
47 |
48 | /* Scale b, c */
49 | SCS(scale_array)(c, sigma, scal->n);
50 | SCS(scale_array)(b, sigma, scal->m);
51 |
52 | /* We assume that primal_scale = dual_scale, otherwise need to refactorize */
53 | scal->primal_scale = sigma;
54 | scal->dual_scale = sigma;
55 | }
56 |
57 | /* needed for normalizing the warm-start */
58 | void SCS(normalize_sol)(ScsScaling *scal, ScsSolution *sol) {
59 | scs_int i;
60 | scs_float *D = scal->D;
61 | scs_float *E = scal->E;
62 | for (i = 0; i < scal->n; ++i) {
63 | sol->x[i] /= (E[i] / scal->dual_scale);
64 | }
65 | for (i = 0; i < scal->m; ++i) {
66 | sol->y[i] /= (D[i] / scal->primal_scale);
67 | }
68 | for (i = 0; i < scal->m; ++i) {
69 | sol->s[i] *= (D[i] * scal->dual_scale);
70 | }
71 | }
72 |
73 | void SCS(un_normalize_sol)(ScsScaling *scal, ScsSolution *sol) {
74 | scs_int i;
75 | scs_float *D = scal->D;
76 | scs_float *E = scal->E;
77 | for (i = 0; i < scal->n; ++i) {
78 | sol->x[i] *= (E[i] / scal->dual_scale);
79 | }
80 | for (i = 0; i < scal->m; ++i) {
81 | sol->y[i] *= (D[i] / scal->primal_scale);
82 | }
83 | for (i = 0; i < scal->m; ++i) {
84 | sol->s[i] /= (D[i] * scal->dual_scale);
85 | }
86 | }
87 |
88 | void SCS(un_normalize_primal)(ScsScaling *scal, scs_float *r) {
89 | scs_int i;
90 | scs_float *D = scal->D;
91 | for (i = 0; i < scal->m; ++i) {
92 | r[i] /= (D[i] * scal->dual_scale);
93 | }
94 | }
95 |
96 | void SCS(un_normalize_dual)(ScsScaling *scal, scs_float *r) {
97 | scs_int i;
98 | scs_float *E = scal->E;
99 | for (i = 0; i < scal->n; ++i) {
100 | r[i] /= (E[i] * scal->primal_scale);
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/scs_version.c:
--------------------------------------------------------------------------------
1 | #ifdef __cplusplus
2 | extern "C" {
3 | #endif
4 |
5 | #include "glbopts.h"
6 |
7 | const char *scs_version(void) {
8 | return SCS_VERSION;
9 | }
10 |
11 | #ifdef __cplusplus
12 | }
13 | #endif
14 |
--------------------------------------------------------------------------------
/src/util.c:
--------------------------------------------------------------------------------
1 | #include "util.h"
2 |
3 | #include "glbopts.h"
4 | #include "linsys.h"
5 | #include "scs_matrix.h"
6 |
7 | /* return milli-seconds */
8 | #if (defined NO_TIMER)
9 |
10 | void SCS(tic)(SCS(timer) * t) {
11 | }
12 | scs_float SCS(tocq)(SCS(timer) * t) {
13 | return NAN;
14 | }
15 |
16 | #elif (defined _WIN32 || _WIN64 || defined _WINDLL)
17 |
18 | void SCS(tic)(SCS(timer) * t) {
19 | QueryPerformanceFrequency(&t->freq);
20 | QueryPerformanceCounter(&t->tic);
21 | }
22 |
23 | scs_float SCS(tocq)(SCS(timer) * t) {
24 | QueryPerformanceCounter(&t->toc);
25 | return (1e3 * (t->toc.QuadPart - t->tic.QuadPart) /
26 | (scs_float)t->freq.QuadPart);
27 | }
28 |
29 | #elif (defined __APPLE__)
30 | #include
31 |
32 | void SCS(tic)(SCS(timer) * t) {
33 | /* read current clock cycles */
34 | t->tic = mach_absolute_time();
35 | }
36 |
37 | scs_float SCS(tocq)(SCS(timer) * t) {
38 | uint64_t duration; /* elapsed time in clock cycles*/
39 |
40 | t->toc = mach_absolute_time();
41 | duration = t->toc - t->tic;
42 |
43 | /*conversion from clock cycles to nanoseconds*/
44 | mach_timebase_info(&(t->tinfo));
45 | duration *= t->tinfo.numer;
46 | duration /= t->tinfo.denom;
47 |
48 | return (scs_float)duration / 1e6;
49 | }
50 |
51 | #else
52 |
53 | void SCS(tic)(SCS(timer) * t) {
54 | clock_gettime(CLOCK_MONOTONIC, &t->tic);
55 | }
56 |
57 | scs_float SCS(tocq)(SCS(timer) * t) {
58 | struct timespec temp;
59 |
60 | clock_gettime(CLOCK_MONOTONIC, &t->toc);
61 |
62 | if ((t->toc.tv_nsec - t->tic.tv_nsec) < 0) {
63 | temp.tv_sec = t->toc.tv_sec - t->tic.tv_sec - 1;
64 | temp.tv_nsec = 1e9 + t->toc.tv_nsec - t->tic.tv_nsec;
65 | } else {
66 | temp.tv_sec = t->toc.tv_sec - t->tic.tv_sec;
67 | temp.tv_nsec = t->toc.tv_nsec - t->tic.tv_nsec;
68 | }
69 | return (scs_float)temp.tv_sec * 1e3 + (scs_float)temp.tv_nsec / 1e6;
70 | }
71 |
72 | #endif
73 |
74 | void SCS(deep_copy_data)(ScsData *dest, const ScsData *src) {
75 | dest->n = src->n;
76 | dest->m = src->m;
77 | SCS(copy_matrix)(&(dest->A), src->A);
78 | SCS(copy_matrix)(&(dest->P), src->P);
79 | dest->b = (scs_float *)scs_calloc(dest->m, sizeof(scs_float));
80 | memcpy(dest->b, src->b, dest->m * sizeof(scs_float));
81 | dest->c = (scs_float *)scs_calloc(dest->n, sizeof(scs_float));
82 | memcpy(dest->c, src->c, dest->n * sizeof(scs_float));
83 | }
84 |
85 | void SCS(deep_copy_stgs)(ScsSettings *dest, const ScsSettings *src) {
86 | memcpy(dest, src, sizeof(ScsSettings));
87 | /* MATLAB does something weird with strdup, so use strcpy instead */
88 | char *tmp;
89 | if (src->write_data_filename) {
90 | /* sizeof(char) = 1 */
91 | tmp = (char *)scs_malloc(strlen(src->write_data_filename) + 1);
92 | strcpy(tmp, src->write_data_filename);
93 | dest->write_data_filename = tmp;
94 | } else {
95 | dest->write_data_filename = SCS_NULL;
96 | }
97 | /* MATLAB does something weird with strdup, so use strcpy instead */
98 | if (src->log_csv_filename) {
99 | /* sizeof(char) = 1 */
100 | tmp = (char *)scs_malloc(strlen(src->log_csv_filename) + 1);
101 | strcpy(tmp, src->log_csv_filename);
102 | dest->log_csv_filename = tmp;
103 | } else {
104 | dest->log_csv_filename = SCS_NULL;
105 | }
106 | }
107 |
108 | void SCS(free_data)(ScsData *d) {
109 | if (d) {
110 | scs_free(d->b);
111 | scs_free(d->c);
112 | if (d->A) {
113 | SCS(free_scs_matrix)(d->A);
114 | }
115 | if (d->P) {
116 | SCS(free_scs_matrix)(d->P);
117 | }
118 | scs_free(d);
119 | }
120 | }
121 |
122 | void SCS(free_sol)(ScsSolution *sol) {
123 | if (sol) {
124 | scs_free(sol->x);
125 | scs_free(sol->y);
126 | scs_free(sol->s);
127 | scs_free(sol);
128 | }
129 | }
130 |
131 | /* assumes stgs already allocated memory */
132 | void scs_set_default_settings(ScsSettings *stgs) {
133 | /* These constants are defined in include/glbopts.h */
134 | stgs->max_iters = MAX_ITERS;
135 | stgs->eps_abs = EPS_ABS;
136 | stgs->eps_rel = EPS_REL;
137 | stgs->eps_infeas = EPS_INFEAS;
138 | stgs->alpha = ALPHA;
139 | stgs->rho_x = RHO_X;
140 | stgs->scale = SCALE;
141 | stgs->verbose = VERBOSE;
142 | stgs->normalize = NORMALIZE;
143 | stgs->warm_start = WARM_START;
144 | stgs->acceleration_lookback = ACCELERATION_LOOKBACK;
145 | stgs->acceleration_interval = ACCELERATION_INTERVAL;
146 | stgs->adaptive_scale = ADAPTIVE_SCALE;
147 | stgs->write_data_filename = WRITE_DATA_FILENAME;
148 | stgs->log_csv_filename = LOG_CSV_FILENAME;
149 | stgs->time_limit_secs = TIME_LIMIT_SECS;
150 | }
151 |
--------------------------------------------------------------------------------
/test/minunit.h:
--------------------------------------------------------------------------------
1 | /* Taken from http://www.jera.com/techinfo/jtns/jtn002.html */
2 |
3 | /* Simple Macros for testing */
4 | #define mu_assert_less(message, a, b) \
5 | do { \
6 | if (a > b) { \
7 | scs_printf("%s: %1.3e > %1.3e\n", message, a, b); \
8 | return message; \
9 | } \
10 | } while (0)
11 |
12 | #define mu_assert(message, test) \
13 | do { \
14 | if (!(test)) \
15 | return message; \
16 | } while (0)
17 |
18 | #define mu_run_test(test) _mu_run_test(#test, test)
19 |
20 | #define _mu_run_test(name, test) \
21 | do { \
22 | scs_printf("*********************************************************\n"); \
23 | scs_printf("Running test: %s\n", name); \
24 | const char *message = test(); \
25 | tests_run++; \
26 | if (message) \
27 | return message; \
28 | } while (0)
29 |
--------------------------------------------------------------------------------
/test/problems/degenerate.h:
--------------------------------------------------------------------------------
1 | #include "glbopts.h"
2 | #include "linalg.h"
3 | #include "minunit.h"
4 | #include "problem_utils.h"
5 | #include "scs.h"
6 | #include "scs_matrix.h"
7 | #include "util.h"
8 |
9 | /* test degenerate cones */
10 | static const char *degenerate(void) {
11 | ScsCone *k = (ScsCone *)scs_calloc(1, sizeof(ScsCone));
12 | ScsData *d = (ScsData *)scs_calloc(1, sizeof(ScsData));
13 | ScsSettings *stgs = (ScsSettings *)scs_calloc(1, sizeof(ScsSettings));
14 | ScsSolution *sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
15 | ScsInfo info = {0};
16 | scs_int exitflag, success;
17 | scs_float tpobj, tdobj, perr, derr;
18 | const char *fail;
19 |
20 | /* data */
21 | scs_float Ax[] = {-10., -1., 1., -1.};
22 | scs_int Ai[] = {1, 2, 1, 3};
23 | scs_int Ap[] = {0, 2, 4};
24 |
25 | scs_float Px[] = {0.02, 2.};
26 | scs_int Pi[] = {0, 1};
27 | scs_int Pp[] = {0, 1, 2};
28 |
29 | scs_float b[] = {1., -1., 2., -0.5};
30 | scs_float c[] = {1., 2.};
31 |
32 | scs_int m = 4;
33 | scs_int n = 2;
34 |
35 | /* used later: */
36 | scs_int sq[] = {1};
37 |
38 | /* end data */
39 |
40 | d->m = m;
41 | d->n = n;
42 | d->b = b;
43 | d->c = c;
44 |
45 | d->A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
46 | d->P = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
47 |
48 | d->A->m = m;
49 | d->A->n = n;
50 |
51 | d->A->x = Ax;
52 | d->A->i = Ai;
53 | d->A->p = Ap;
54 |
55 | d->P->m = n;
56 | d->P->n = n;
57 |
58 | d->P->x = Px;
59 | d->P->i = Pi;
60 | d->P->p = Pp;
61 |
62 | scs_set_default_settings(stgs);
63 | stgs->eps_abs = 1e-6;
64 | stgs->eps_rel = 1e-6;
65 | stgs->eps_infeas = 1e-9;
66 |
67 | /* positive orthants */
68 | k->l = 4;
69 | exitflag = scs(d, k, stgs, sol, &info);
70 | fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
71 | if (fail) {
72 | return fail;
73 | }
74 | mu_assert("bsize: SCS failed to produce outputflag SCS_SOLVED",
75 | exitflag == SCS_SOLVED);
76 |
77 | tpobj = info.pobj;
78 | tdobj = info.dobj;
79 |
80 | /* degenerate box cone */
81 | k->bsize = 1;
82 | k->l = 3;
83 | exitflag = scs(d, k, stgs, sol, &info);
84 | fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
85 | if (fail) {
86 | return fail;
87 | }
88 | perr = info.pobj - tpobj;
89 | derr = info.dobj - tdobj;
90 | success = ABS(perr) < 1e-8 && ABS(derr) < 1e-8 && exitflag == SCS_SOLVED;
91 | mu_assert("degenerate box cone failure", success);
92 |
93 | /* degenerate SOC cone */
94 | k->bsize = 0;
95 | k->q = sq;
96 | k->qsize = 1;
97 | k->l = 3;
98 | exitflag = scs(d, k, stgs, sol, &info);
99 | fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
100 | if (fail) {
101 | return fail;
102 | }
103 | perr = info.pobj - tpobj;
104 | derr = info.dobj - tdobj;
105 | success = ABS(perr) < 1e-8 && ABS(derr) < 1e-8 && exitflag == SCS_SOLVED;
106 | mu_assert("degenerate SOC cone failure", success);
107 |
108 | /* degenerate PSD cone */
109 | k->q = 0;
110 | k->qsize = 0;
111 | k->s = sq;
112 | k->ssize = 1;
113 | k->l = 3;
114 | exitflag = scs(d, k, stgs, sol, &info);
115 | fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
116 | if (fail) {
117 | return fail;
118 | }
119 | perr = info.pobj - tpobj;
120 | derr = info.dobj - tdobj;
121 | success = ABS(perr) < 1e-8 && ABS(derr) < 1e-8 && exitflag == SCS_SOLVED;
122 | mu_assert("degenerate PSD cone failure", success);
123 |
124 | SCS(free_sol)(sol);
125 | scs_free(d->A);
126 | scs_free(d->P);
127 | scs_free(k);
128 | scs_free(stgs);
129 | scs_free(d);
130 | return fail;
131 | }
132 |
--------------------------------------------------------------------------------
/test/problems/hs21_tiny_qp.h:
--------------------------------------------------------------------------------
1 | #include "glbopts.h"
2 | #include "linalg.h"
3 | #include "minunit.h"
4 | #include "problem_utils.h"
5 | #include "scs.h"
6 | #include "scs_matrix.h"
7 | #include "util.h"
8 |
9 | static const char *hs21_tiny_qp(void) {
10 | ScsCone *k = (ScsCone *)scs_calloc(1, sizeof(ScsCone));
11 | ScsData *d = (ScsData *)scs_calloc(1, sizeof(ScsData));
12 | ScsSettings *stgs = (ScsSettings *)scs_calloc(1, sizeof(ScsSettings));
13 | ScsSolution *sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
14 | ScsInfo info = {0};
15 | scs_int exitflag;
16 | scs_float perr, derr;
17 | scs_int success;
18 | const char *fail;
19 |
20 | /* data */
21 | scs_float Ax[] = {-10., -1., 1., -1.};
22 | scs_int Ai[] = {1, 2, 1, 3};
23 | scs_int Ap[] = {0, 2, 4};
24 |
25 | scs_float Px[] = {0.02, 2.};
26 | scs_int Pi[] = {0, 1};
27 | scs_int Pp[] = {0, 1, 2};
28 |
29 | scs_float b[] = {1., 0., 0., 0.};
30 | scs_float c[] = {0., 0.};
31 |
32 | scs_int m = 4;
33 | scs_int n = 2;
34 |
35 | scs_float bl[] = {10.0, 2.0, -50.0};
36 | scs_float bu[] = {1e+20, 50.0, 50.0};
37 | scs_int bsize = 4;
38 |
39 | scs_float opt = 0.04000000000000625;
40 | /* end data */
41 |
42 | d->m = m;
43 | d->n = n;
44 | d->b = b;
45 | d->c = c;
46 |
47 | d->A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
48 | d->P = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
49 |
50 | d->A->m = m;
51 | d->A->n = n;
52 |
53 | d->A->x = Ax;
54 | d->A->i = Ai;
55 | d->A->p = Ap;
56 |
57 | d->P->m = n;
58 | d->P->n = n;
59 |
60 | d->P->x = Px;
61 | d->P->i = Pi;
62 | d->P->p = Pp;
63 |
64 | k->bsize = bsize;
65 | k->bl = bl;
66 | k->bu = bu;
67 |
68 | scs_set_default_settings(stgs);
69 | stgs->eps_abs = 1e-6;
70 | stgs->eps_rel = 1e-6;
71 | stgs->eps_infeas = 0.; /* disable due to gpu test finding cert */
72 |
73 | exitflag = scs(d, k, stgs, sol, &info);
74 |
75 | perr = info.pobj - opt;
76 | derr = info.dobj - opt;
77 |
78 | scs_printf("primal obj error %4e\n", perr);
79 | scs_printf("dual obj error %4e\n", derr);
80 |
81 | success = ABS(perr) < 1e-4 && ABS(derr) < 1e-4 && exitflag == SCS_SOLVED;
82 |
83 | mu_assert("hs21_tiny_qp: SCS failed to produce outputflag SCS_SOLVED",
84 | success);
85 | fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
86 |
87 | /* test warm-starting */
88 | stgs->warm_start = 1;
89 | exitflag = scs(d, k, stgs, sol, &info);
90 | /* 25 iters should be enough if warm-started */
91 | mu_assert("hs21_tiny_qp: warm-start failure", info.iter <= 25);
92 | success = ABS(perr) < 1e-4 && ABS(derr) < 1e-4 && exitflag == SCS_SOLVED;
93 |
94 | mu_assert("hs21_tiny_qp: SCS failed to produce outputflag SCS_SOLVED",
95 | success);
96 |
97 | /* test other settings */
98 | stgs->warm_start = 0;
99 | stgs->normalize = 0;
100 | stgs->adaptive_scale = 0;
101 | stgs->acceleration_lookback = 10;
102 | stgs->acceleration_interval = 10;
103 | stgs->log_csv_filename = "hs21_tiny_qp.csv";
104 |
105 | exitflag = scs(d, k, stgs, sol, &info);
106 |
107 | perr = info.pobj - opt;
108 | derr = info.dobj - opt;
109 |
110 | scs_printf("primal obj error %4e\n", perr);
111 | scs_printf("dual obj error %4e\n", derr);
112 |
113 | success = ABS(perr) < 1e-4 && ABS(derr) < 1e-4 && exitflag == SCS_SOLVED;
114 |
115 | mu_assert("hs21_tiny_qp: SCS failed to produce outputflag SCS_SOLVED",
116 | success);
117 |
118 | SCS(free_sol)(sol);
119 | scs_free(d->A);
120 | scs_free(d->P);
121 | scs_free(k);
122 | scs_free(stgs);
123 | scs_free(d);
124 | return fail;
125 | }
126 |
--------------------------------------------------------------------------------
/test/problems/hs21_tiny_qp_rw.h:
--------------------------------------------------------------------------------
1 | #include "glbopts.h"
2 | #include "linalg.h"
3 | #include "minunit.h"
4 | #include "problem_utils.h"
5 | #include "rw.h"
6 | #include "scs.h"
7 | #include "scs_matrix.h"
8 | #include "util.h"
9 |
10 | /* test read / write logic */
11 | static const char *hs21_tiny_qp_rw(void) {
12 | ScsCone *k = (ScsCone *)scs_calloc(1, sizeof(ScsCone));
13 | ScsData *d = (ScsData *)scs_calloc(1, sizeof(ScsData));
14 | ScsSettings *stgs = (ScsSettings *)scs_calloc(1, sizeof(ScsSettings));
15 | ScsSolution *sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
16 | ScsInfo info = {0};
17 | scs_int exitflag;
18 | scs_float perr, derr;
19 | scs_int success, read_status;
20 | const char *fail;
21 |
22 | /* data */
23 | scs_float Ax[] = {-10., -1., 1., -1.};
24 | scs_int Ai[] = {1, 2, 1, 3};
25 | scs_int Ap[] = {0, 2, 4};
26 |
27 | scs_float Px[] = {0.02, 2.};
28 | scs_int Pi[] = {0, 1};
29 | scs_int Pp[] = {0, 1, 2};
30 |
31 | scs_float b[] = {1., 0., 0., 0.};
32 | scs_float c[] = {0., 0.};
33 |
34 | scs_int m = 4;
35 | scs_int n = 2;
36 |
37 | scs_float bl[] = {10.0, 2.0, -50.0};
38 | scs_float bu[] = {1e+20, 50.0, 50.0};
39 | scs_int bsize = 4;
40 |
41 | scs_float opt = 0.04000000000000625;
42 | /* end data */
43 |
44 | d->m = m;
45 | d->n = n;
46 | d->b = b;
47 | d->c = c;
48 |
49 | d->A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
50 | d->P = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
51 |
52 | d->A->m = m;
53 | d->A->n = n;
54 |
55 | d->A->x = Ax;
56 | d->A->i = Ai;
57 | d->A->p = Ap;
58 |
59 | d->P->m = n;
60 | d->P->n = n;
61 |
62 | d->P->x = Px;
63 | d->P->i = Pi;
64 | d->P->p = Pp;
65 |
66 | k->bsize = bsize;
67 | k->bl = bl;
68 | k->bu = bu;
69 |
70 | scs_set_default_settings(stgs);
71 | stgs->eps_abs = 1e-6;
72 | stgs->eps_rel = 1e-6;
73 | stgs->eps_infeas = 0.; /* disable due to gpu test finding cert */
74 |
75 | stgs->write_data_filename = "hs21_tiny_qp";
76 | stgs->max_iters = 1;
77 |
78 | exitflag = scs(d, k, stgs, sol, &info);
79 |
80 | /* kill the data */
81 | scs_free(d->A);
82 | scs_free(d->P);
83 | scs_free(k);
84 | scs_free(stgs);
85 | scs_free(d);
86 |
87 | read_status = SCS(read_data)("hs21_tiny_qp", &d, &k, &stgs);
88 |
89 | if (read_status < 0) {
90 | return "Data read failure, exit.\n";
91 | }
92 |
93 | stgs->max_iters = 1000;
94 | /* solve with read data */
95 | exitflag = scs(d, k, stgs, sol, &info);
96 |
97 | perr = info.pobj - opt;
98 | derr = info.dobj - opt;
99 |
100 | scs_printf("primal obj error %4e\n", perr);
101 | scs_printf("dual obj error %4e\n", derr);
102 |
103 | success = ABS(perr) < 1e-4 && ABS(derr) < 1e-4 && exitflag == SCS_SOLVED;
104 |
105 | mu_assert("hs21_tiny_qp: SCS failed to produce outputflag SCS_SOLVED",
106 | success);
107 | fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
108 |
109 | /* test warm-starting */
110 | stgs->warm_start = 1;
111 | exitflag = scs(d, k, stgs, sol, &info);
112 | /* 25 iters should be enough if warm-started */
113 | mu_assert("hs21_tiny_qp: warm-start failure", info.iter <= 25);
114 | success = ABS(perr) < 1e-4 && ABS(derr) < 1e-4 && exitflag == SCS_SOLVED;
115 |
116 | mu_assert("hs21_tiny_qp: SCS failed to produce outputflag SCS_SOLVED",
117 | success);
118 |
119 | SCS(free_data)(d);
120 | SCS(free_cone)(k);
121 | SCS(free_sol)(sol);
122 | scs_free(stgs);
123 |
124 | return fail;
125 | }
126 |
--------------------------------------------------------------------------------
/test/problems/infeasible_tiny_qp.h:
--------------------------------------------------------------------------------
1 | #include "glbopts.h"
2 | #include "linalg.h"
3 | #include "minunit.h"
4 | #include "problem_utils.h"
5 | #include "scs.h"
6 | #include "scs_matrix.h"
7 | #include "util.h"
8 |
9 | static const char *infeasible_tiny_qp(void) {
10 | ScsCone *k = (ScsCone *)scs_calloc(1, sizeof(ScsCone));
11 | ScsData *d = (ScsData *)scs_calloc(1, sizeof(ScsData));
12 | ScsSettings *stgs = (ScsSettings *)scs_calloc(1, sizeof(ScsSettings));
13 | ScsSolution *sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
14 | ScsInfo info = {0};
15 | scs_int exitflag;
16 | const char *fail;
17 |
18 | /* data */
19 | scs_float Ax[] = {
20 | 4.51689976e-01, 3.06592046e-03, 5.17304192e-01, -3.03038477e+00,
21 | -1.40509892e+00, 7.94277342e-04, 2.39454841e+00, -7.60957360e-01,
22 | -1.18946302e+00, 3.98797701e-01, 1.01386914e+00, -2.53921734e+00,
23 | -3.21202445e-01, 9.25735134e-01, -2.54046934e-01, 1.28211442e-01,
24 | -1.65155072e-01, -4.53308401e-01, -4.66709068e-01, -2.24298562e-01,
25 | -4.92029627e-01, 8.05750411e-01, -1.72920210e+00, -1.45633836e-01,
26 | 6.39086786e-01, 1.20509649e-01, 4.19672104e-01, -2.29274817e-01,
27 | 3.30125838e-01, 4.12874191e-01, 1.05357823e+00, 2.10587878e+00,
28 | 5.54934230e-01, 2.42617608e+00, -8.33596918e-01, -6.83444334e-01,
29 | 8.23856780e-01, -4.14240741e-01, -7.24051659e-01, 1.06144329e-01,
30 | 6.92857027e-01, 1.64822980e+00, 1.94603528e-01, -7.58318366e-01,
31 | 1.42948833e+00, -2.49039902e-01, 2.15319490e-01, -1.52651434e+00,
32 | -3.94761305e-01, -5.24305949e-01};
33 | scs_int Ai[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
34 | 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
35 | 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
36 | scs_int Ap[] = {0, 10, 20, 30, 40, 50};
37 |
38 | scs_float Px[] = {0.40113649, 0.15897142, 0.37369516, -0.05899464,
39 | 0.0772996, 0.37333677, -0.02994108, 0.04870077,
40 | 0.32221413, 0.28665235, -0.27383424, 0.04842465,
41 | 0.07832219, 0.0660133, 0.49993284};
42 | scs_int Pi[] = {0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4};
43 | scs_int Pp[] = {0, 1, 3, 6, 10, 15};
44 |
45 | scs_float b[] = {-0.057279, 0.10451534, -0.10459346, -0.18452294,
46 | 0.18609658, 0.15795524, -0.00562746, -0.85852899,
47 | -0.48271335, 0.61951655};
48 | scs_float c[] = {-0.16566256, -1.33116808, -0.1767858, -1.0940148,
49 | 1.15348983};
50 |
51 | scs_int m = 10;
52 | scs_int n = 5;
53 |
54 | scs_int l = m;
55 |
56 | /* end data */
57 |
58 | d->m = m;
59 | d->n = n;
60 | d->b = b;
61 | d->c = c;
62 |
63 | d->A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
64 | d->P = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
65 |
66 | d->A->m = m;
67 | d->A->n = n;
68 |
69 | d->A->x = Ax;
70 | d->A->i = Ai;
71 | d->A->p = Ap;
72 |
73 | d->P->m = n;
74 | d->P->n = n;
75 |
76 | d->P->x = Px;
77 | d->P->i = Pi;
78 | d->P->p = Pp;
79 |
80 | k->l = l;
81 |
82 | scs_set_default_settings(stgs);
83 | stgs->eps_abs = 1e-6;
84 | stgs->eps_rel = 1e-6;
85 | stgs->eps_infeas = 1e-9;
86 |
87 | exitflag = scs(d, k, stgs, sol, &info);
88 |
89 | mu_assert(
90 | "infeasible_tiny_qp: SCS failed to produce outputflag SCS_INFEASIBLE",
91 | exitflag == SCS_INFEASIBLE);
92 | fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
93 |
94 | SCS(free_sol)(sol);
95 | scs_free(d->A);
96 | scs_free(d->P);
97 | scs_free(k);
98 | scs_free(stgs);
99 | scs_free(d);
100 | return fail;
101 | }
102 |
--------------------------------------------------------------------------------
/test/problems/max_ent:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cvxgrp/scs/8a739589e66f745d049fc838f55775d3e07f669b/test/problems/max_ent
--------------------------------------------------------------------------------
/test/problems/max_ent.h:
--------------------------------------------------------------------------------
1 | #include "glbopts.h"
2 | #include "problems/test_prob_from_data_file.h"
3 | #include "scs.h"
4 |
5 | static const char *max_ent(void) {
6 | scs_float OPT = -6.067087663361563; /* from ecos */
7 | return _test_prob_from_data("test/problems/max_ent", OPT);
8 | }
9 |
--------------------------------------------------------------------------------
/test/problems/mpc_bug.h:
--------------------------------------------------------------------------------
1 | #include "glbopts.h"
2 | #include "problems/test_prob_from_data_file.h"
3 | #include "scs.h"
4 |
5 | static const char *mpc_bug(void) {
6 | const char *fail;
7 | scs_float OPT1 = -0.473957794500; /* from scs */
8 | scs_float OPT2 = -0.029336830816; /* from scs */
9 | scs_float OPT3 = -0.002215217478; /* from scs */
10 | fail = _test_prob_from_data("test/problems/mpc_bug1", OPT1);
11 | if (fail) {
12 | return fail;
13 | }
14 | fail = _test_prob_from_data("test/problems/mpc_bug2", OPT2);
15 | if (fail) {
16 | return fail;
17 | }
18 | return _test_prob_from_data("test/problems/mpc_bug3", OPT3);
19 | }
20 |
--------------------------------------------------------------------------------
/test/problems/mpc_bug1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cvxgrp/scs/8a739589e66f745d049fc838f55775d3e07f669b/test/problems/mpc_bug1
--------------------------------------------------------------------------------
/test/problems/mpc_bug2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cvxgrp/scs/8a739589e66f745d049fc838f55775d3e07f669b/test/problems/mpc_bug2
--------------------------------------------------------------------------------
/test/problems/mpc_bug3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cvxgrp/scs/8a739589e66f745d049fc838f55775d3e07f669b/test/problems/mpc_bug3
--------------------------------------------------------------------------------
/test/problems/random_prob:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cvxgrp/scs/8a739589e66f745d049fc838f55775d3e07f669b/test/problems/random_prob
--------------------------------------------------------------------------------
/test/problems/random_prob.h:
--------------------------------------------------------------------------------
1 | #include "glbopts.h"
2 | #include "problems/test_prob_from_data_file.h"
3 | #include "scs.h"
4 |
5 | static const char *random_prob(void) {
6 | scs_float OPT = 5.751458006385587;
7 | return _test_prob_from_data("test/problems/random_prob", OPT);
8 | }
9 |
--------------------------------------------------------------------------------
/test/problems/small_lp.h:
--------------------------------------------------------------------------------
1 | #include "glbopts.h"
2 | #include "minunit.h"
3 | #include "problem_utils.h"
4 | #include "scs.h"
5 | #include "util.h"
6 |
7 | static const char *small_lp(void) {
8 | ScsCone *k = (ScsCone *)scs_calloc(1, sizeof(ScsCone));
9 | ScsData *d = (ScsData *)scs_calloc(1, sizeof(ScsData));
10 | ScsSettings *stgs = (ScsSettings *)scs_calloc(1, sizeof(ScsSettings));
11 | ScsSolution *sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
12 | ScsSolution *opt_sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
13 | ScsInfo info = {0};
14 | scs_float p_f = 0.1;
15 | int seed = 1234;
16 | scs_int n = 100;
17 | scs_int m = 300;
18 | scs_int col_nnz = (scs_int)ceil(sqrt(n));
19 | scs_int nnz = n * col_nnz;
20 | scs_int exitflag;
21 | scs_float perr, derr;
22 | scs_int success;
23 | const char *fail;
24 |
25 | k->z = (scs_int)floor(m * p_f);
26 | k->l = m - k->z;
27 |
28 | d->m = m;
29 | d->n = n;
30 | gen_random_prob_data(nnz, col_nnz, d, k, opt_sol, seed);
31 | scs_set_default_settings(stgs);
32 | stgs->eps_abs = 1e-5;
33 | stgs->eps_rel = 1e-5;
34 |
35 | exitflag = scs(d, k, stgs, sol, &info);
36 |
37 | perr = SCS(dot)(d->c, sol->x, d->n) - SCS(dot)(d->c, opt_sol->x, d->n);
38 | derr = -SCS(dot)(d->b, sol->y, d->m) + SCS(dot)(d->b, opt_sol->y, d->m);
39 | scs_printf("true obj %4e\n", SCS(dot)(d->c, opt_sol->x, d->n));
40 | scs_printf("primal obj error %4e\n", perr);
41 | scs_printf("dual obj error %4e\n", derr);
42 |
43 | success = ABS(perr) < 1e-4 && ABS(derr) < 1e-4 && exitflag == SCS_SOLVED;
44 |
45 | mu_assert("small_lp: SCS failed to produce outputflag SCS_SOLVED", success);
46 | fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
47 | SCS(free_data)(d);
48 | SCS(free_cone)(k);
49 | SCS(free_sol)(sol);
50 | SCS(free_sol)(opt_sol);
51 | scs_free(stgs);
52 |
53 | return fail;
54 | }
55 |
--------------------------------------------------------------------------------
/test/problems/test_exp_cone.h:
--------------------------------------------------------------------------------
1 | #include "glbopts.h"
2 | #include "linalg.h"
3 | #include "minunit.h"
4 | #include "scs.h"
5 |
6 | /* Forward declare exponential cone projection routine.
7 | * Implemented in exp_cone.c.
8 | */
9 | scs_float SCS(proj_pd_exp_cone)(scs_float *v0, scs_int primal);
10 |
11 | static scs_int _run_exp_cone_test(scs_float *v0, scs_float *vp_true,
12 | scs_float *vd_true) {
13 | scs_int success = 1;
14 | scs_float vp[3], vd[3];
15 | const scs_float TOL = 1e-6;
16 |
17 | memcpy(vp, v0, 3 * sizeof(scs_float));
18 | memcpy(vd, v0, 3 * sizeof(scs_float));
19 |
20 | /* inefficient, but just for testing */
21 | SCS(proj_pd_exp_cone)(vp, 1);
22 | SCS(proj_pd_exp_cone)(vd, 0);
23 |
24 | scs_printf("*******************************\n");
25 | scs_printf("v0: (%f, %f, %f)\n", v0[0], v0[1], v0[2]);
26 | scs_printf("vp: (%f, %f, %f)\n", vp[0], vp[1], vp[2]);
27 | scs_printf("vp_true: (%f, %f, %f)\n", vp_true[0], vp_true[1], vp_true[2]);
28 | scs_printf("vd: (%f, %f, %f)\n", vd[0], vd[1], vd[2]);
29 | scs_printf("vd_true: (%f, %f, %f)\n", vd_true[0], vd_true[1], vd_true[2]);
30 |
31 | success &= (SCS(norm_diff)(vp, vp_true, 3) <= TOL);
32 | success &= (SCS(norm_diff)(vd, vd_true, 3) <= TOL);
33 | /* Moreau decomposition holds only for polar */
34 | /*
35 | success &= (SCS(dot)(vp, vd, 3) <= TOL);
36 | success &= (ABS(v0[0] - vp[0] + vd[0]) <= TOL);
37 | success &= (ABS(v0[1] - vp[1] + vd[1]) <= TOL);
38 | success &= (ABS(v0[2] - vp[2] + vd[2]) <= TOL);
39 | */
40 |
41 | if (!success) {
42 | scs_printf("Failed.\n");
43 | }
44 |
45 | return success;
46 | }
47 |
48 | static const char *test_exp_cone(void) {
49 | scs_int success = 1;
50 | scs_int i;
51 | /* test points */
52 | scs_float v0[6][3] = {
53 | {1, 2, 3},
54 | {0.14814832, 1.04294573, 0.67905585},
55 | {-0.78301134, 1.82790084, -1.05417044},
56 | {1.3282585, -0.43277314, 1.7468072},
57 | {0.67905585, 0.14814832, 1.04294573},
58 | {0.50210027, 0.12314491, -1.77568921},
59 | };
60 | /* primal projections */
61 | scs_float vp[6][3] = {
62 | {0.8899428, 1.94041881, 3.06957226},
63 | {-0.02001571, 0.8709169, 0.85112944},
64 | {-1.17415616, 0.9567094, 0.280399},
65 | {0.53160512, 0.2804836, 1.86652094},
66 | {0.38322814, 0.27086569, 1.11482228},
67 | {0., 0., 0.},
68 | };
69 | /* dual projections */
70 | scs_float vd[6][3] = {
71 | {-0., 2., 3.},
72 | {-0., 1.04294573, 0.67905585},
73 | {-0.68541419, 1.85424082, 0.01685653},
74 | {-0.02277033, -0.12164823, 1.75085347},
75 | {-0., 0.14814832, 1.04294573},
76 | {-0., 0.12314491, -0.},
77 | };
78 |
79 | for (i = 0; i < 6; ++i) {
80 | success &= _run_exp_cone_test(v0[i], vp[i], vd[i]);
81 | }
82 | mu_assert("test_exp_cone: Failure", success);
83 | return 0;
84 | }
85 |
--------------------------------------------------------------------------------
/test/problems/test_prob_from_data_file.h:
--------------------------------------------------------------------------------
1 | #ifndef _SCS_FILE_TEST_CHASSIS
2 | #define _SCS_FILE_TEST_CHASSIS
3 |
4 | #include "glbopts.h"
5 | #include "minunit.h"
6 | #include "problem_utils.h"
7 | #include "rw.h"
8 | #include "scs.h"
9 | #include "util.h"
10 |
11 | static const char *_test_prob_from_data(const char *file, scs_float OPT) {
12 | scs_int read_status;
13 | ScsData *d;
14 | ScsCone *k;
15 | ScsSettings *stgs;
16 | ScsSolution *sol;
17 | ScsInfo info = {0};
18 | scs_int exitflag;
19 | scs_float perr, derr;
20 | scs_int success;
21 | const char *fail;
22 | scs_float xt_p_x;
23 | scs_float *px = SCS_NULL;
24 |
25 | read_status = SCS(read_data)(file, &d, &k, &stgs);
26 |
27 | if (read_status < 0) {
28 | return "Data read failure, exit.\n";
29 | }
30 |
31 | stgs->eps_abs = 1e-6;
32 | stgs->eps_rel = 1e-6;
33 | /* Force verbosity for the test */
34 | stgs->verbose = 1;
35 |
36 | sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
37 | exitflag = scs(d, k, stgs, sol, &info);
38 |
39 | if (d->P) {
40 | /* px = Px */
41 | px = (scs_float *)scs_calloc(d->n, sizeof(scs_float));
42 | memset(px, 0, d->n * sizeof(scs_float));
43 | SCS(accum_by_p)(d->P, sol->x, px);
44 | xt_p_x = SCS(dot)(px, sol->x, d->n);
45 | } else {
46 | xt_p_x = 0.;
47 | }
48 |
49 | perr = 0.5 * xt_p_x + SCS(dot)(d->c, sol->x, d->n) - OPT;
50 | derr = -0.5 * xt_p_x - SCS(dot)(d->b, sol->y, d->m) - OPT;
51 | scs_printf("primal obj error %4e\n", perr);
52 | scs_printf("dual obj error %4e\n", derr);
53 |
54 | success = ABS(perr) < 1e-4 && ABS(derr) < 1e-4 && exitflag == SCS_SOLVED;
55 | if (!success) {
56 | scs_printf("%s: FAILED\n", file);
57 | }
58 | mu_assert(file, success);
59 | fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
60 | SCS(free_data)(d);
61 | SCS(free_cone)(k);
62 | SCS(free_sol)(sol);
63 | scs_free(stgs);
64 | if (px) {
65 | scs_free(px);
66 | }
67 | if (fail) {
68 | scs_printf("%s: FAILED\n", file);
69 | }
70 | return fail;
71 | }
72 |
73 | #endif
74 |
--------------------------------------------------------------------------------
/test/problems/test_validation.h:
--------------------------------------------------------------------------------
1 | #include "glbopts.h"
2 | #include "minunit.h"
3 | #include "problem_utils.h"
4 | #include "scs.h"
5 | #include "util.h"
6 |
7 | static const char *test_validation(void) {
8 | scs_printf("Testing that SCS handles bad inputs correctly:\n");
9 |
10 | ScsCone *k = (ScsCone *)scs_calloc(1, sizeof(ScsCone));
11 | ScsData *d = (ScsData *)scs_calloc(1, sizeof(ScsData));
12 | ScsSettings *stgs = (ScsSettings *)scs_calloc(1, sizeof(ScsSettings));
13 | ScsSolution *sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
14 | ScsSolution *opt_sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
15 | ScsInfo info = {0};
16 | scs_float p_f = 0.1;
17 | int seed = 1234;
18 | scs_int n = 1;
19 | scs_int m = 3;
20 | scs_int col_nnz = (scs_int)ceil(sqrt(n));
21 | scs_int nnz = n * col_nnz;
22 | scs_int exitflag;
23 |
24 | k->z = (scs_int)floor(m * p_f);
25 | k->l = m - k->z;
26 |
27 | d->m = m;
28 | d->n = n;
29 | gen_random_prob_data(nnz, col_nnz, d, k, opt_sol, seed);
30 | scs_set_default_settings(stgs);
31 |
32 | /* TODO test more failure modes */
33 | stgs->eps_abs = -1;
34 |
35 | exitflag = scs(d, k, stgs, sol, &info);
36 |
37 | mu_assert("test_fails: SCS failed to produce outputflag SCS_FAILED",
38 | exitflag == SCS_FAILED);
39 | SCS(free_data)(d);
40 | SCS(free_cone)(k);
41 | SCS(free_sol)(sol);
42 | SCS(free_sol)(opt_sol);
43 | scs_free(stgs);
44 |
45 | return 0;
46 | }
47 |
--------------------------------------------------------------------------------
/test/problems/unbounded_tiny_qp.h:
--------------------------------------------------------------------------------
1 | #include "glbopts.h"
2 | #include "linalg.h"
3 | #include "minunit.h"
4 | #include "problem_utils.h"
5 | #include "scs.h"
6 | #include "scs_matrix.h"
7 | #include "util.h"
8 |
9 | static const char *unbounded_tiny_qp(void) {
10 | ScsCone *k = (ScsCone *)scs_calloc(1, sizeof(ScsCone));
11 | ScsData *d = (ScsData *)scs_calloc(1, sizeof(ScsData));
12 | ScsSettings *stgs = (ScsSettings *)scs_calloc(1, sizeof(ScsSettings));
13 | ScsSolution *sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
14 | ScsInfo info = {0};
15 | scs_int exitflag;
16 | const char *fail;
17 |
18 | /* data */
19 | scs_float Ax[] = {
20 | -0.04101197, 1.68314201, 0.5543439, -0.96712378, 0.19370457,
21 | -1.15055711, 1.13315795, -1.05910693, 1.24512977, -0.70999048,
22 | -0.89976326, -0.41373294, -0.73848186, 0.08663554, -0.1681749,
23 | -0.42711619, -0.90501247, -0.490446, -0.67124734, 1.67772257,
24 | 0.39924394, 0.16330292, 0.55609205, -1.22088238, -0.25891675,
25 | -3.07159984, -1.84102417, 1.5621635, -1.13771529, 0.56067264,
26 | -0.0854747, 0.31024722, -0.07437118, -0.20711534, -0.35241366,
27 | -0.98965142, -1.91488894, 1.01591507, 0.45387459, 1.43709968,
28 | -0.0482982, -0.32447, -0.91433399, 0.49750765, 0.09150015,
29 | 0.69164184, 0.51064936, -1.35009809, -1.35403213, 1.51897627};
30 | scs_int Ai[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6,
31 | 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
32 | 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
33 | scs_int Ap[] = {0, 10, 20, 30, 40, 50};
34 |
35 | scs_float b[] = {1.4672744, 0.36190605, -0.5548082, -0.35039932,
36 | -1.12765224, 0.51012137, -0.24927975, -1.45270362,
37 | -1.94080389, -0.0189713};
38 | scs_float c[] = {0.17547329, -0.11983635, -0.11791039, 0.12099476,
39 | 0.61931906};
40 |
41 | scs_int m = 10;
42 | scs_int n = 5;
43 |
44 | scs_int l = m;
45 |
46 | /* end data */
47 |
48 | d->m = m;
49 | d->n = n;
50 | d->b = b;
51 | d->c = c;
52 |
53 | d->A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
54 |
55 | d->A->m = m;
56 | d->A->n = n;
57 |
58 | d->A->x = Ax;
59 | d->A->i = Ai;
60 | d->A->p = Ap;
61 |
62 | k->l = l;
63 |
64 | scs_set_default_settings(stgs);
65 | stgs->eps_abs = 1e-6;
66 | stgs->eps_rel = 1e-6;
67 | stgs->eps_infeas = 1e-7;
68 |
69 | exitflag = scs(d, k, stgs, sol, &info);
70 |
71 | mu_assert("unbounded_tiny_qp: SCS failed to produce outputflag SCS_UNBOUNDED",
72 | exitflag == SCS_UNBOUNDED);
73 |
74 | fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
75 |
76 | SCS(free_sol)(sol);
77 | SCS(free_cone)(k);
78 | scs_free(stgs);
79 | scs_free(d->A);
80 | scs_free(d);
81 | return fail;
82 | }
83 |
--------------------------------------------------------------------------------
/test/rng.h:
--------------------------------------------------------------------------------
1 | /* This program by D E Knuth is in the public domain and freely copyable
2 | * AS LONG AS YOU MAKE ABSOLUTELY NO CHANGES!
3 | * It is explained in Seminumerical Algorithms, 3rd edition, Section 3.6
4 | * (or in the errata to the 2nd edition --- see
5 | * http://www-cs-faculty.stanford.edu/~knuth/taocp.html
6 | * in the changes to Volume 2 on pages 171 and following). */
7 |
8 | /* N.B. The MODIFICATIONS introduced in the 9th printing (2002) are
9 | included here; there's no backwards compatibility with the original. */
10 |
11 | /* This version also adopts Brendan McKay's suggestion to
12 | accommodate naive users who forget to call ran_start(seed). */
13 |
14 | /* If you find any bugs, please report them immediately to
15 | * taocp@cs.stanford.edu
16 | * (and you will be rewarded if the bug is genuine). Thanks! */
17 |
18 | /************ see the book for explanations and caveats! *******************/
19 | /************ in particular, you need two's complement arithmetic **********/
20 |
21 | #define KK 100 /* the long lag */
22 | #define LL 37 /* the short lag */
23 | #define MM (1L << 30) /* the modulus */
24 | #define mod_diff(x, y) (((x) - (y)) & (MM - 1)) /* subtraction mod MM */
25 |
26 | long ran_x[KK]; /* the generator state */
27 |
28 | #ifdef __STDC__
29 | void ran_array(long aa[], int n)
30 | #else
31 | void ran_array(aa, n) /* put n new random numbers in aa */
32 | long *aa; /* destination */
33 | int n; /* array length (must be at least KK) */
34 | #endif
35 | {
36 | register int i, j;
37 | for (j = 0; j < KK; j++)
38 | aa[j] = ran_x[j];
39 | for (; j < n; j++)
40 | aa[j] = mod_diff(aa[j - KK], aa[j - LL]);
41 | for (i = 0; i < LL; i++, j++)
42 | ran_x[i] = mod_diff(aa[j - KK], aa[j - LL]);
43 | for (; i < KK; i++, j++)
44 | ran_x[i] = mod_diff(aa[j - KK], ran_x[i - LL]);
45 | }
46 |
47 | /* the following routines are from exercise 3.6--15 */
48 | /* after calling ran_start, get new randoms by, e.g., "x=ran_arr_next()" */
49 |
50 | #define QUALITY 1009 /* recommended quality level for high-res use */
51 | long ran_arr_buf[QUALITY];
52 | long ran_arr_dummy = -1, ran_arr_started = -1;
53 | long *ran_arr_ptr = &ran_arr_dummy; /* the next random number, or -1 */
54 |
55 | #define TT 70 /* guaranteed separation between streams */
56 | #define is_odd(x) ((x)&1) /* units bit of x */
57 |
58 | #ifdef __STDC__
59 | void ran_start(long seed)
60 | #else
61 | void ran_start(seed) /* do this before using ran_array */
62 | long seed; /* selector for different streams */
63 | #endif
64 | {
65 | register int t, j;
66 | long x[KK + KK - 1]; /* the preparation buffer */
67 | register long ss = (seed + 2) & (MM - 2);
68 | for (j = 0; j < KK; j++) {
69 | x[j] = ss; /* bootstrap the buffer */
70 | ss <<= 1;
71 | if (ss >= MM)
72 | ss -= MM - 2; /* cyclic shift 29 bits */
73 | }
74 | x[1]++; /* make x[1] (and only x[1]) odd */
75 | for (ss = seed & (MM - 1), t = TT - 1; t;) {
76 | for (j = KK - 1; j > 0; j--)
77 | x[j + j] = x[j], x[j + j - 1] = 0; /* "square" */
78 | for (j = KK + KK - 2; j >= KK; j--)
79 | x[j - (KK - LL)] = mod_diff(x[j - (KK - LL)], x[j]),
80 | x[j - KK] = mod_diff(x[j - KK], x[j]);
81 | if (is_odd(ss)) { /* "multiply by z" */
82 | for (j = KK; j > 0; j--)
83 | x[j] = x[j - 1];
84 | x[0] = x[KK]; /* shift the buffer cyclically */
85 | x[LL] = mod_diff(x[LL], x[KK]);
86 | }
87 | if (ss)
88 | ss >>= 1;
89 | else
90 | t--;
91 | }
92 | for (j = 0; j < LL; j++)
93 | ran_x[j + KK - LL] = x[j];
94 | for (; j < KK; j++)
95 | ran_x[j - LL] = x[j];
96 | for (j = 0; j < 10; j++)
97 | ran_array(x, KK + KK - 1); /* warm things up */
98 | ran_arr_ptr = &ran_arr_started;
99 | }
100 |
101 | #define ran_arr_next() (*ran_arr_ptr >= 0 ? *ran_arr_ptr++ : ran_arr_cycle())
102 | long ran_arr_cycle(void) {
103 | if (ran_arr_ptr == &ran_arr_dummy)
104 | ran_start(314159L); /* the user forgot to initialize */
105 | ran_array(ran_arr_buf, QUALITY);
106 | ran_arr_buf[KK] = -1;
107 | ran_arr_ptr = ran_arr_buf + 1;
108 | return ran_arr_buf[0];
109 | }
110 |
--------------------------------------------------------------------------------
/test/run_from_file.c:
--------------------------------------------------------------------------------
1 | #include "rw.h"
2 | #include "scs.h"
3 | #include "util.h"
4 |
5 | scs_int override_setting(ScsSettings *s, char *param, char *val) {
6 | scs_printf("Attempting to override %s with value %s.\n", param, val);
7 | if (strcmp(param, "normalize") == 0) {
8 | s->normalize = atoi(val);
9 | } else if (strcmp(param, "scale") == 0) {
10 | s->scale = atof(val);
11 | } else if (strcmp(param, "rho_x") == 0) {
12 | s->rho_x = atof(val);
13 | } else if (strcmp(param, "max_iters") == 0) {
14 | s->max_iters = atoi(val);
15 | } else if (strcmp(param, "eps_abs") == 0) {
16 | s->eps_abs = atof(val);
17 | } else if (strcmp(param, "eps_rel") == 0) {
18 | s->eps_rel = atof(val);
19 | } else if (strcmp(param, "eps_infeas") == 0) {
20 | s->eps_infeas = atof(val);
21 | } else if (strcmp(param, "alpha") == 0) {
22 | s->alpha = atof(val);
23 | } else if (strcmp(param, "verbose") == 0) {
24 | s->verbose = atoi(val);
25 | } else if (strcmp(param, "acceleration_lookback") == 0) {
26 | s->acceleration_lookback = atoi(val);
27 | } else if (strcmp(param, "acceleration_interval") == 0) {
28 | s->acceleration_interval = atoi(val);
29 | } else if (strcmp(param, "adaptive_scale") == 0) {
30 | s->adaptive_scale = atoi(val);
31 | } else if (strcmp(param, "log_csv_filename") == 0) {
32 | s->log_csv_filename = val;
33 | } else {
34 | return -1;
35 | }
36 | scs_printf("Success.\n");
37 | return 0;
38 | }
39 |
40 | /* Simple helper function to run problems from data files */
41 | /* Mostly useful for debugging */
42 | int main(int argc, char **argv) {
43 | char *filename;
44 | scs_int read_status;
45 | ScsData *d;
46 | ScsCone *k;
47 | ScsSettings *stgs;
48 | ScsSolution *sol;
49 | ScsInfo info = {0};
50 | scs_int i;
51 | if (argc < 2) {
52 | scs_printf("Need to specify a filename, exit.\n");
53 | return -1;
54 | }
55 | filename = argv[1];
56 | read_status = SCS(read_data)(filename, &d, &k, &stgs);
57 | if (read_status < 0) {
58 | scs_printf("Data read failure, exit.\n");
59 | return -1;
60 | }
61 | for (i = 2; i < argc; i += 2) {
62 | if (argc < i + 2) {
63 | scs_printf("Incorrect number of arguments supplied.\n");
64 |
65 | SCS(free_data)(d);
66 | SCS(free_cone)(k);
67 | scs_free(stgs);
68 |
69 | return -1;
70 | }
71 | if (override_setting(stgs, argv[i], argv[i + 1]) < 0) {
72 | scs_printf("Unrecognized setting %s\n", argv[i]);
73 |
74 | SCS(free_data)(d);
75 | SCS(free_cone)(k);
76 | scs_free(stgs);
77 |
78 | return -1;
79 | }
80 | }
81 | if (!stgs->verbose) {
82 | scs_printf(
83 | "File data set `verbose` to 0, SCS will not output information. Add "
84 | "`verbose 1` to call to override.\n");
85 | }
86 | scs_printf("Solving problem.\n");
87 | sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
88 | scs(d, k, stgs, sol, &info);
89 |
90 | SCS(free_data)(d);
91 | SCS(free_cone)(k);
92 | SCS(free_sol)(sol);
93 | scs_free(stgs);
94 |
95 | return 0;
96 | }
97 |
--------------------------------------------------------------------------------
/test/run_tests.c:
--------------------------------------------------------------------------------
1 | /* Taken from http://www.jera.com/techinfo/jtns/jtn002.html */
2 | #include
3 |
4 | #include "minunit.h"
5 | #include "problem_utils.h"
6 | #include "scs.h"
7 |
8 | /* Include Tests */
9 | #include "problems/degenerate.h"
10 | #include "problems/hs21_tiny_qp.h"
11 | #include "problems/infeasible_tiny_qp.h"
12 | #include "problems/qafiro_tiny_qp.h"
13 | #include "problems/small_lp.h"
14 | #include "problems/small_qp.h"
15 | #include "problems/test_exp_cone.h"
16 | #include "problems/unbounded_tiny_qp.h"
17 |
18 | int tests_run = 0;
19 |
20 | /* decrement tests_run since mu_unit will increment it, so this cancels */
21 | #define _SKIP(problem) \
22 | char *problem(void) { \
23 | scs_printf("skipped\n"); \
24 | tests_run--; \
25 | return 0; \
26 | }
27 |
28 | #if NO_VALIDATE == 0
29 | #include "problems/test_validation.h"
30 | #else
31 | _SKIP(test_validation)
32 | #endif
33 |
34 | /* solve SDPs, requires blas / lapack */
35 | #if defined(USE_LAPACK) && NO_READ_WRITE == 0
36 | #include "problems/random_prob.h"
37 | #include "problems/rob_gauss_cov_est.h"
38 | #else
39 | _SKIP(rob_gauss_cov_est)
40 | _SKIP(random_prob)
41 | #endif
42 |
43 | #if NO_READ_WRITE == 0 /* reads / writes */
44 | #include "problems/hs21_tiny_qp_rw.h"
45 | #include "problems/max_ent.h"
46 | #include "problems/mpc_bug.h"
47 | #else
48 | _SKIP(hs21_tiny_qp_rw)
49 | _SKIP(max_ent)
50 | _SKIP(mpc_bug)
51 | #endif
52 |
53 | static const char *all_tests(void) {
54 | mu_run_test(test_validation);
55 | mu_run_test(degenerate);
56 | mu_run_test(small_lp);
57 | mu_run_test(small_qp);
58 | mu_run_test(rob_gauss_cov_est);
59 | mu_run_test(hs21_tiny_qp);
60 | mu_run_test(hs21_tiny_qp_rw);
61 | mu_run_test(qafiro_tiny_qp);
62 | mu_run_test(infeasible_tiny_qp);
63 | mu_run_test(unbounded_tiny_qp);
64 | mu_run_test(random_prob);
65 | mu_run_test(max_ent);
66 | mu_run_test(mpc_bug);
67 | mu_run_test(test_exp_cone);
68 | return 0;
69 | }
70 | int main(void) {
71 | const char *result = all_tests();
72 | if (result != 0) {
73 | scs_printf("%s\n", result);
74 | scs_printf("TEST FAILED!\n");
75 | } else {
76 | scs_printf("ALL TESTS PASSED\n");
77 | }
78 | scs_printf("Tests run: %d\n", tests_run);
79 |
80 | return result != 0;
81 | }
82 |
--------------------------------------------------------------------------------